summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFisher Cheng2013-05-24 16:54:08 +0800
committerJulien Lacour2013-10-01 12:12:48 +0200
commit8c1eb022607c0aba81d93b961abbfb47a2dcc325 (patch)
tree13b1cd55172e93b3d1e5baa7141ba259fd71b0af
parent9e4d9d72dcac9686f1b4720e46e3bb88f6375a1e (diff)
cleo/devkit: add MTK MT7601U drv source code, refs #4011
- Enable Wireless LAN and Wireless extension in linux26.config
-rw-r--r--cleopatre/buildroot/target/device/Spidcom/targets/mpr520e/linux26.config.part130
-rw-r--r--cleopatre/devkit/mt7601udrv/.gitignore9
-rw-r--r--cleopatre/devkit/mt7601udrv/Makefile547
-rw-r--r--cleopatre/devkit/mt7601udrv/RT2870AP.dat119
-rw-r--r--cleopatre/devkit/mt7601udrv/RT2870APCard.dat19
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap.c2485
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_apcli.c2230
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_apcli_inf.c266
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_assoc.c1637
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_auth.c627
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_autoChSel.c1091
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_cfg.c12072
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_connect.c1044
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_data.c6452
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_dls.c345
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_ftkd.c80
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_ids.c459
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_mbss.c378
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_mbss_inf.c273
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_mlme.c592
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_qload.c916
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_sanity.c477
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_sync.c1422
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_wds.c1359
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_wds_inf.c156
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/ap_wpa.c1614
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/apcli_assoc.c806
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/apcli_auth.c570
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/apcli_ctrl.c875
-rw-r--r--cleopatre/devkit/mt7601udrv/ap/apcli_sync.c576
-rw-r--r--cleopatre/devkit/mt7601udrv/ate/chips/mt7601_ate.c921
-rw-r--r--cleopatre/devkit/mt7601udrv/ate/common/ate_usb.c627
-rw-r--r--cleopatre/devkit/mt7601udrv/ate/common/rt_ate.c6298
-rw-r--r--cleopatre/devkit/mt7601udrv/ate/common/rt_qa.c2497
-rw-r--r--cleopatre/devkit/mt7601udrv/ate/include/rt_ate.h808
-rw-r--r--cleopatre/devkit/mt7601udrv/ate/include/rt_qa.h181
-rw-r--r--cleopatre/devkit/mt7601udrv/chips/mt7601.c3382
-rw-r--r--cleopatre/devkit/mt7601udrv/chips/rtmp_chip.c1041
-rw-r--r--cleopatre/devkit/mt7601udrv/common/action.c1126
-rw-r--r--cleopatre/devkit/mt7601udrv/common/ba_action.c2190
-rw-r--r--cleopatre/devkit/mt7601udrv/common/client_wds.c197
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_aes.c1142
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_asic.c2699
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_cfg.c1494
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_cmd.c169
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_cs.c763
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_data.c3569
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_data_usb.c1312
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_dfs.c3136
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_info.c6151
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_mac_usb.c2159
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_mat.c443
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_mat_iparp.c694
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_mat_ipv6.c824
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_mat_pppoe.c1062
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_profile.c5059
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_radar.c329
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_sanity.c2162
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_sync.c494
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_tkip.c923
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_video.c168
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_wep.c365
-rw-r--r--cleopatre/devkit/mt7601udrv/common/cmm_wpa.c4728
-rw-r--r--cleopatre/devkit/mt7601udrv/common/crypt_aes.c1605
-rw-r--r--cleopatre/devkit/mt7601udrv/common/crypt_arc4.c139
-rw-r--r--cleopatre/devkit/mt7601udrv/common/crypt_biginteger.c1116
-rw-r--r--cleopatre/devkit/mt7601udrv/common/crypt_dh.c227
-rw-r--r--cleopatre/devkit/mt7601udrv/common/crypt_hmac.c282
-rw-r--r--cleopatre/devkit/mt7601udrv/common/crypt_md5.c356
-rw-r--r--cleopatre/devkit/mt7601udrv/common/crypt_sha2.c555
-rw-r--r--cleopatre/devkit/mt7601udrv/common/ee_efuse.c1893
-rw-r--r--cleopatre/devkit/mt7601udrv/common/ee_prom.c265
-rw-r--r--cleopatre/devkit/mt7601udrv/common/eeprom.c85
-rw-r--r--cleopatre/devkit/mt7601udrv/common/frq_cal.c28
-rw-r--r--cleopatre/devkit/mt7601udrv/common/igmp_snoop.c1511
-rw-r--r--cleopatre/devkit/mt7601udrv/common/image.binbin0 -> 67936 bytes
-rw-r--r--cleopatre/devkit/mt7601udrv/common/misc.c35
-rw-r--r--cleopatre/devkit/mt7601udrv/common/mlme.c4000
-rw-r--r--cleopatre/devkit/mt7601udrv/common/multi_channel.c1012
-rw-r--r--cleopatre/devkit/mt7601udrv/common/netif_block.c121
-rw-r--r--cleopatre/devkit/mt7601udrv/common/ps.c370
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rt2860.bin.dfsbin0 -> 8192 bytes
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rt2860.bin.oldbin0 -> 8192 bytes
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rt2870_wow.binbin0 -> 12288 bytes
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rt_channel.c2057
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rt_os_util.c161
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rt_rf.c33
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rtmp_init.c3849
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rtmp_init_inf.c1094
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rtmp_timer.c358
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rtusb_bulk.c1693
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rtusb_data.c31
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rtusb_dev_id.c48
-rw-r--r--cleopatre/devkit/mt7601udrv/common/rtusb_io.c2021
-rw-r--r--cleopatre/devkit/mt7601udrv/common/scan.c415
-rw-r--r--cleopatre/devkit/mt7601udrv/common/spectrum.c2393
-rw-r--r--cleopatre/devkit/mt7601udrv/common/txpower.c1172
-rw-r--r--cleopatre/devkit/mt7601udrv/common/uapsd.c2074
-rw-r--r--cleopatre/devkit/mt7601udrv/common/vht.c400
-rw-r--r--cleopatre/devkit/mt7601udrv/common/wapi.c1185
-rw-r--r--cleopatre/devkit/mt7601udrv/common/wfd.c823
-rw-r--r--cleopatre/devkit/mt7601udrv/common/wsc.c9058
-rw-r--r--cleopatre/devkit/mt7601udrv/common/wsc_tlv.c4002
-rw-r--r--cleopatre/devkit/mt7601udrv/common/wsc_ufd.c598
-rw-r--r--cleopatre/devkit/mt7601udrv/common/wsc_v2.c408
-rw-r--r--cleopatre/devkit/mt7601udrv/include/action.h54
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ags.h102
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap.h454
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_apcli.h275
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_autoChSel.h76
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_autoChSel_cmm.h61
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_cfg.h167
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_diversity.h142
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_ids.h76
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_mbss.h86
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ap_wds.h220
-rw-r--r--cleopatre/devkit/mt7601udrv/include/br_ftph.h81
-rw-r--r--cleopatre/devkit/mt7601udrv/include/cfg80211.h78
-rw-r--r--cleopatre/devkit/mt7601udrv/include/cfg80211extr.h201
-rw-r--r--cleopatre/devkit/mt7601udrv/include/chip/chip_id.h73
-rw-r--r--cleopatre/devkit/mt7601udrv/include/chip/mt7601.h268
-rw-r--r--cleopatre/devkit/mt7601udrv/include/chip/rt28xx.h39
-rw-r--r--cleopatre/devkit/mt7601udrv/include/chip/rt3290.h114
-rw-r--r--cleopatre/devkit/mt7601udrv/include/chip/rt6590.h137
-rw-r--r--cleopatre/devkit/mt7601udrv/include/chip/rtmp_phy.h693
-rw-r--r--cleopatre/devkit/mt7601udrv/include/chlist.h150
-rw-r--r--cleopatre/devkit/mt7601udrv/include/client_wds.h59
-rw-r--r--cleopatre/devkit/mt7601udrv/include/client_wds_cmm.h46
-rw-r--r--cleopatre/devkit/mt7601udrv/include/crypt_aes.h176
-rw-r--r--cleopatre/devkit/mt7601udrv/include/crypt_arc4.h57
-rw-r--r--cleopatre/devkit/mt7601udrv/include/crypt_biginteger.h134
-rw-r--r--cleopatre/devkit/mt7601udrv/include/crypt_dh.h65
-rw-r--r--cleopatre/devkit/mt7601udrv/include/crypt_hmac.h68
-rw-r--r--cleopatre/devkit/mt7601udrv/include/crypt_md5.h63
-rw-r--r--cleopatre/devkit/mt7601udrv/include/crypt_sha2.h92
-rw-r--r--cleopatre/devkit/mt7601udrv/include/cs.h172
-rw-r--r--cleopatre/devkit/mt7601udrv/include/dfs.h571
-rw-r--r--cleopatre/devkit/mt7601udrv/include/dot11ac_vht.h479
-rw-r--r--cleopatre/devkit/mt7601udrv/include/dot11i_wpa.h291
-rw-r--r--cleopatre/devkit/mt7601udrv/include/drs_extr.h326
-rw-r--r--cleopatre/devkit/mt7601udrv/include/eeprom.h321
-rw-r--r--cleopatre/devkit/mt7601udrv/include/firmware.h2396
-rw-r--r--cleopatre/devkit/mt7601udrv/include/frq_cal.h107
-rw-r--r--cleopatre/devkit/mt7601udrv/include/iface/iface_util.h69
-rw-r--r--cleopatre/devkit/mt7601udrv/include/iface/rtmp_reg_pcirbs.h384
-rw-r--r--cleopatre/devkit/mt7601udrv/include/iface/rtmp_usb.h89
-rw-r--r--cleopatre/devkit/mt7601udrv/include/igmp_snoop.h155
-rw-r--r--cleopatre/devkit/mt7601udrv/include/ipv6.h205
-rw-r--r--cleopatre/devkit/mt7601udrv/include/link_list.h182
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/fce.h70
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/mac_pci.h405
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/mac_usb.h490
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac.h782
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pbf.h139
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pci.h368
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_rxwi.h117
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_txwi.h249
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_usb.h144
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac.h168
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pbf.h104
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pci.h270
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rf_ctrl.h92
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rxwi.h147
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_txwi.h143
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_usb.h70
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/pbf.h93
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/rf_ctrl.h146
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mac_ral/rtmp_mac.h2379
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mat.h208
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mcu/MT7601_firmware.h2844
-rw-r--r--cleopatre/devkit/mt7601udrv/include/misc.h32
-rw-r--r--cleopatre/devkit/mt7601udrv/include/misc_cmm.h32
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mlme.h1515
-rw-r--r--cleopatre/devkit/mt7601udrv/include/mlme_sys.h9
-rw-r--r--cleopatre/devkit/mt7601udrv/include/netif_block.h31
-rw-r--r--cleopatre/devkit/mt7601udrv/include/oid.h1320
-rw-r--r--cleopatre/devkit/mt7601udrv/include/os/rt_drv.h1061
-rw-r--r--cleopatre/devkit/mt7601udrv/include/os/rt_linux.h1575
-rw-r--r--cleopatre/devkit/mt7601udrv/include/os/rt_linux_cmm.h412
-rw-r--r--cleopatre/devkit/mt7601udrv/include/os/rt_os.h83
-rw-r--r--cleopatre/devkit/mt7601udrv/include/phy/rlt_phy.h275
-rw-r--r--cleopatre/devkit/mt7601udrv/include/radar.h89
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rt_config.h211
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rt_os_net.h583
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rt_os_util.h1003
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rt_txbf.h215
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp.h9018
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_M51.h53
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_and.h137
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_chip.h1095
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_cmd.h683
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_comm.h502
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_def.h1948
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_dot11.h98
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_iface.h57
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_mcu.h90
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_os.h135
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_osabl.h65
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_timer.h182
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtmp_type.h192
-rw-r--r--cleopatre/devkit/mt7601udrv/include/rtusb_io.h195
-rw-r--r--cleopatre/devkit/mt7601udrv/include/spectrum.h215
-rw-r--r--cleopatre/devkit/mt7601udrv/include/spectrum_def.h249
-rw-r--r--cleopatre/devkit/mt7601udrv/include/sta_cfg.h72
-rw-r--r--cleopatre/devkit/mt7601udrv/include/uapsd.h725
-rw-r--r--cleopatre/devkit/mt7601udrv/include/vht.h28
-rw-r--r--cleopatre/devkit/mt7601udrv/include/video.h12
-rw-r--r--cleopatre/devkit/mt7601udrv/include/vr_ikans.h59
-rw-r--r--cleopatre/devkit/mt7601udrv/include/vrut_ubm.h42
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wapi.h183
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wapi_def.h179
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wapi_sms4.h12
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wfd.h149
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wfd_cmm.h293
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wpa.h506
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wpa_cmm.h211
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wsc.h820
-rw-r--r--cleopatre/devkit/mt7601udrv/include/wsc_tlv.h280
-rw-r--r--cleopatre/devkit/mt7601udrv/load3
-rw-r--r--cleopatre/devkit/mt7601udrv/mac/ral_nmac.c31
-rw-r--r--cleopatre/devkit/mt7601udrv/mac/ral_omac.c67
-rw-r--r--cleopatre/devkit/mt7601udrv/mac/rtmp_mac.c607
-rw-r--r--cleopatre/devkit/mt7601udrv/mcu/bin/MT7601.binbin0 -> 45412 bytes
-rw-r--r--cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5.binbin0 -> 45412 bytes
-rw-r--r--cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5_Debug.binbin0 -> 49784 bytes
-rw-r--r--cleopatre/devkit/mt7601udrv/mcu/rtmp_M51.c710
-rw-r--r--cleopatre/devkit/mt7601udrv/mcu/rtmp_and.c2071
-rw-r--r--cleopatre/devkit/mt7601udrv/mcu/rtmp_mcu.c77
-rw-r--r--cleopatre/devkit/mt7601udrv/mgmt/mgmt_dev.c58
-rw-r--r--cleopatre/devkit/mt7601udrv/mgmt/mgmt_entrytb.c729
-rw-r--r--cleopatre/devkit/mt7601udrv/mgmt/mgmt_ht.c747
-rw-r--r--cleopatre/devkit/mt7601udrv/mgmt/mgmt_hw.c37
-rw-r--r--cleopatre/devkit/mt7601udrv/mgmt/mgmt_vht.c39
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.soc159
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.usb111
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Kconfig.sta.soc89
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.4291
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.netif103
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.util82
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.6652
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.netif99
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.util72
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.soc394
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.usb334
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.clean58
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.libautoprovision.69
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.423
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.611
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/Makefile.sta.soc275
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/ap_ioctl.c441
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/br_ftph.c195
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/cfg80211.c1576
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/cfg80211drv.c1675
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/config.mk1125
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/config.mk.bak1637
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/inf_ppa.c62
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/load6
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_linux.c5258
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_linux_symb.c287
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_main_dev.c840
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_proc.c539
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_profile.c857
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_rbus_pci_drv.c16
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_symb.c9
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_usb.c1314
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/rt_usb_util.c603
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/unload2
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/usb_main_dev.c846
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/vr_bdlt.c63
-rw-r--r--cleopatre/devkit/mt7601udrv/os/linux/vr_ikans.c363
-rw-r--r--cleopatre/devkit/mt7601udrv/phy/rlt_phy.c436
-rw-r--r--cleopatre/devkit/mt7601udrv/phy/rlt_rf.c182
-rw-r--r--cleopatre/devkit/mt7601udrv/phy/rtmp_phy.c629
-rw-r--r--cleopatre/devkit/mt7601udrv/rate_ctrl/alg_ags.c1181
-rw-r--r--cleopatre/devkit/mt7601udrv/rate_ctrl/alg_grp.c1661
-rw-r--r--cleopatre/devkit/mt7601udrv/rate_ctrl/alg_legacy.c907
-rw-r--r--cleopatre/devkit/mt7601udrv/rate_ctrl/ra_ctrl.c1977
-rw-r--r--cleopatre/devkit/mt7601udrv/tools/Makefile6
-rw-r--r--cleopatre/devkit/mt7601udrv/tools/bin2h.c175
-rw-r--r--cleopatre/devkit/mt7601udrv/unload2
280 files changed, 225433 insertions, 0 deletions
diff --git a/cleopatre/buildroot/target/device/Spidcom/targets/mpr520e/linux26.config.part b/cleopatre/buildroot/target/device/Spidcom/targets/mpr520e/linux26.config.part
index 83fff557ae..d4eadf5ff3 100644
--- a/cleopatre/buildroot/target/device/Spidcom/targets/mpr520e/linux26.config.part
+++ b/cleopatre/buildroot/target/device/Spidcom/targets/mpr520e/linux26.config.part
@@ -17,3 +17,133 @@ CONFIG_SUSPEND_FREEZER=y
CONFIG_REALTEK_PHY=y
CONFIG_NETDEV_1000=y
+
+#
+# Kernel Features
+#
+# CONFIG_AEABI is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_BLK_DEV_UB is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_HOSTAP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# Security options
+#
+# CONFIG_SECURITY_ROOTPLUG is not set
+
diff --git a/cleopatre/devkit/mt7601udrv/.gitignore b/cleopatre/devkit/mt7601udrv/.gitignore
new file mode 100644
index 0000000000..0f23620383
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/.gitignore
@@ -0,0 +1,9 @@
+*.ko
+*.ko.cmd
+*.mod.c
+*.o
+*.o.cmd
+*.tmp
+.tmp_versions/
+Module.symvers
+modules.order
diff --git a/cleopatre/devkit/mt7601udrv/Makefile b/cleopatre/devkit/mt7601udrv/Makefile
new file mode 100644
index 0000000000..589631947e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/Makefile
@@ -0,0 +1,547 @@
+ifeq ($(WIFI_MODE),)
+RT28xx_MODE = AP
+else
+RT28xx_MODE = $(WIFI_MODE)
+endif
+
+ifeq ($(TARGET),)
+TARGET = LINUX
+endif
+
+ifeq ($(CHIPSET),)
+CHIPSET = 7601U
+endif
+
+MODULE = $(word 1, $(CHIPSET))
+
+#OS ABL - YES or NO
+OSABL = NO
+
+ifneq ($(TARGET),THREADX)
+#RT28xx_DIR = home directory of RT28xx source code
+RT28xx_DIR = $(shell pwd)
+endif
+
+include $(RT28xx_DIR)/os/linux/config.mk
+
+RTMP_SRC_DIR = $(RT28xx_DIR)/RT$(MODULE)
+
+#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 = BL23570
+#PLATFORM = BLUBB
+#PLATFORM = BLPMP
+#PLATFORM = MT85XX
+#PLATFORM = NXP_TV550
+#PLATFORM = MVL5
+#PLATFORM = RALINK_3352
+#PLATFORM = UBICOM_IPX8
+#PLATFORM = INTELP6
+#PLATFORM = MT7620
+PLATFORM = MSTARPLC
+
+#APSOC
+ifeq ($(MODULE),3050)
+PLATFORM = RALINK_3050
+endif
+ifeq ($(MODULE),3052)
+PLATFORM = RALINK_3052
+endif
+ifeq ($(MODULE),3350)
+PLATFORM = RALINK_3050
+endif
+ifeq ($(MODULE),3352)
+PLATFORM = RALINK_3352
+endif
+
+
+#RELEASE Package
+RELEASE = DPA
+
+
+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),UBICOM_IPX8)
+LINUX_SRC = /home/sample/Customers/UBICOM/ubicom-linux-dist-2.1.1/linux-2.6.x
+CROSS_COMPILE = ubicom32-elf-
+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),BL23570)
+LINUX_SRC = /home/FIBERHOME/linux-2.6.34.8
+CROSS_COMPILE = mips-wrs-linux-gnu-mips_74k_softfp-glibc_small-
+ARCH:=mips
+export $ARCH
+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),INTELP6)
+LINUX_SRC = /tftpboot/IntelCE-20.0.11052.243193/project_build_i686/IntelCE/kernel-20.0.11024.238456/linux-2.6.35
+CROSS_COMPILE = /tftpboot/IntelCE-20.0.11052.243193/build_i686/i686-linux-elf/bin/i686-cm-linux-
+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
+
+ifeq ($(PLATFORM),MT7620)
+LINUX_SRC = /home/share/src/MT7601/AP/RT288x_SDK/source/linux-2.6.36.x
+CROSS_COMPILE = /opt/buildroot-gcc342/bin/mipsel-linux-
+endif
+
+ifeq ($(PLATFORM),MSTARPLC)
+LINUX_SRC ?= $(shell pwd)/../../linux-2.6.25.10-spc300
+CROSS_COMPILE = arm-linux-
+export ARCH=arm
+endif
+
+export OSABL RT28xx_DIR RT28xx_MODE LINUX_SRC CROSS_COMPILE CROSS_COMPILE_INCLUDE PLATFORM RELEASE CHIPSET MODULE RTMP_SRC_DIR LINUX_SRC_MODULE TARGET HAS_WOW_SUPPORT
+
+# 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$(MODULE)ap.o /tftpboot
+ifeq ($(OSABL),YES)
+ cp -f $(RT28xx_DIR)/os/linux/rtutil$(MODULE)ap.o /tftpboot
+ cp -f $(RT28xx_DIR)/os/linux/rtnet$(MODULE)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$(MODULE)apsta.o /tftpboot
+ifeq ($(OSABL),YES)
+ cp -f $(RT28xx_DIR)/os/linux/rtutil$(MODULE)apsta.o /tftpboot
+ cp -f $(RT28xx_DIR)/os/linux/rtnet$(MODULE)apsta.o /tftpboot
+endif
+else
+ cp -f $(RT28xx_DIR)/os/linux/rt$(MODULE)sta.o /tftpboot
+ifeq ($(OSABL),YES)
+ cp -f $(RT28xx_DIR)/os/linux/rtutil$(MODULE)sta.o /tftpboot
+ cp -f $(RT28xx_DIR)/os/linux/rtnet$(MODULE)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)
+ifneq ($(findstring 7601,$(CHIPSET)),)
+ @echo cp -f $(RT28xx_DIR)/os/linux/mt$(MODULE)ap.ko /tftpboot
+else
+ cp -f $(RT28xx_DIR)/os/linux/rt$(MODULE)ap.ko /tftpboot
+endif
+ifeq ($(OSABL),YES)
+ cp -f $(RT28xx_DIR)/os/linux/rtutil$(MODULE)ap.ko /tftpboot
+ cp -f $(RT28xx_DIR)/os/linux/rtnet$(MODULE)ap.ko /tftpboot
+endif
+ @echo rm -f os/linux/rt$(MODULE)ap.ko.lzma
+else
+ifeq ($(RT28xx_MODE),APSTA)
+ cp -f $(RT28xx_DIR)/os/linux/rt$(MODULE)apsta.ko /tftpboot
+ifeq ($(OSABL),YES)
+ cp -f $(RT28xx_DIR)/os/linux/rtutil$(MODULE)apsta.ko /tftpboot
+ cp -f $(RT28xx_DIR)/os/linux/rtnet$(MODULE)apsta.ko /tftpboot
+endif
+else
+ifneq ($(findstring 7601,$(CHIPSET)),)
+ cp -f $(RT28xx_DIR)/os/linux/mt$(MODULE)sta.ko /tftpboot
+else
+ cp -f $(RT28xx_DIR)/os/linux/rt$(MODULE)sta.ko /tftpboot
+endif
+ifeq ($(OSABL),YES)
+ifneq ($(findstring 7601,$(CHIPSET)),)
+ cp -f $(RT28xx_DIR)/os/linux/mtutil$(MODULE)sta.ko /tftpboot
+ cp -f $(RT28xx_DIR)/os/linux/mtnet$(MODULE)sta.ko /tftpboot
+else
+ cp -f $(RT28xx_DIR)/os/linux/rtutil$(MODULE)sta.ko /tftpboot
+ cp -f $(RT28xx_DIR)/os/linux/rtnet$(MODULE)sta.ko /tftpboot
+endif
+endif
+endif
+endif
+endif
+
+
+release: build_tools
+ $(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 ($(MODULE), 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)
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/RT2870AP.dat b/cleopatre/devkit/mt7601udrv/RT2870AP.dat
new file mode 100644
index 0000000000..c5f4951575
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/RT2870AP.dat
@@ -0,0 +1,119 @@
+#The word of "Default" must not be removed
+Default
+CountryRegion=5
+CountryRegionABand=7
+CountryCode=TW
+BssidNum=1
+SSID=RT2860AP
+WirelessMode=9
+TxRate=0
+Channel=11
+BasicRate=15
+BeaconPeriod=100
+DtimPeriod=1
+TxPower=100
+DisableOLBC=0
+BGProtection=0
+TxAntenna=
+RxAntenna=
+TxPreamble=0
+RTSThreshold=2347
+FragThreshold=2346
+TxBurst=1
+PktAggregate=0
+TurboRate=0
+WmmCapable=0
+APSDCapable=0
+DLSCapable=0
+APAifsn=3;7;1;1
+APCwmin=4;4;3;2
+APCwmax=6;10;4;3
+APTxop=0;0;94;47
+APACM=0;0;0;0
+BSSAifsn=3;7;2;2
+BSSCwmin=4;4;3;2
+BSSCwmax=10;10;4;3
+BSSTxop=0;0;94;47
+BSSACM=0;0;0;0
+AckPolicy=0;0;0;0
+NoForwarding=0
+NoForwardingBTNBSSID=0
+HideSSID=0
+StationKeepAlive=0
+ShortSlot=1
+AutoChannelSelect=0
+IEEE8021X=0
+IEEE80211H=0
+CSPeriod=10
+WirelessEvent=0
+IdsEnable=0
+AuthFloodThreshold=32
+AssocReqFloodThreshold=32
+ReassocReqFloodThreshold=32
+ProbeReqFloodThreshold=32
+DisassocFloodThreshold=32
+DeauthFloodThreshold=32
+EapReqFooldThreshold=32
+PreAuth=0
+AuthMode=OPEN
+EncrypType=NONE
+RekeyInterval=0
+RekeyMethod=DISABLE
+PMKCachePeriod=10
+WPAPSK=
+DefaultKeyID=1
+Key1Type=0
+Key1Str=
+Key2Type=0
+Key2Str=
+Key3Type=0
+Key3Str=
+Key4Type=0
+Key4Str=
+HSCounter=0
+AccessPolicy0=0
+AccessControlList0=
+AccessPolicy1=0
+AccessControlList1=
+AccessPolicy2=0
+AccessControlList2=
+AccessPolicy3=0
+AccessControlList3=
+WdsEnable=0
+WdsEncrypType=NONE
+WdsList=
+WdsKey=
+RADIUS_Server=192.168.2.3
+RADIUS_Port=1812
+RADIUS_Key=ralink
+own_ip_addr=192.168.5.234
+EAPifname=br0
+PreAuthifname=br0
+HT_HTC=0
+HT_RDG=0
+HT_EXTCHA=0
+HT_LinkAdapt=0
+HT_OpMode=0
+HT_MpduDensity=5
+HT_BW=1
+HT_AutoBA=1
+HT_AMSDU=0
+HT_BAWinSize=64
+HT_GI=1
+HT_MCS=33
+MeshId=MESH
+MeshAutoLink=1
+MeshAuthMode=OPEN
+MeshEncrypType=NONE
+MeshWPAKEY=
+MeshDefaultkey=1
+MeshWEPKEY=
+WscManufacturer=
+WscModelName=
+WscDeviceName=
+WscModelNumber=
+WscSerialNumber=
+RadioOn=1
+PMFMFPC=0
+PMFMFPR=0
+PMFSHA256=0 \ No newline at end of file
diff --git a/cleopatre/devkit/mt7601udrv/RT2870APCard.dat b/cleopatre/devkit/mt7601udrv/RT2870APCard.dat
new file mode 100644
index 0000000000..3d1a1a8371
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/RT2870APCard.dat
@@ -0,0 +1,19 @@
+#The word of "Default" must not be removed, maximum 32 cards, 00 ~ 31
+Default
+
+#CARDID, MAC, CARDTYPE
+SELECT=CARDTYPE
+
+00CARDID=/etc/Wireless/RT2870AP/RT2870AP1.dat
+01CARDID=/etc/Wireless/RT2870AP/RT2870AP2.dat
+02CARDID=/etc/Wireless/RT2870AP/RT2870AP3.dat
+
+00MAC00:0E:2E:C3:D0:48=/etc/Wireless/RT2870AP/RT2870AP1.dat
+01MAC00:40:F4:FF:AA:40=/etc/Wireless/RT2870AP/RT2870AP2.dat
+02MAC00:0C:43:10:11:5C=/etc/Wireless/RT2870AP/RT2870AP3.dat
+
+00CARDTYPEbgn=/etc/Wireless/RT2870AP/RT2870AP1.dat
+01CARDTYPEbgn=/etc/Wireless/RT2870AP/RT2870AP2.dat
+02CARDTYPEabgn=/etc/Wireless/RT2870AP/RT2870AP3.dat
+
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap.c b/cleopatre/devkit/mt7601udrv/ap/ap.c
new file mode 100644
index 0000000000..08748216fa
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap.c
@@ -0,0 +1,2485 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ soft_ap.c
+
+ Abstract:
+ Access Point specific routines and MAC table maintenance routines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 08-04-2003 created for 11g soft-AP
+
+ */
+
+#include "rt_config.h"
+
+BOOLEAN ApCheckLongPreambleSTA(
+ IN PRTMP_ADAPTER pAd);
+
+char const *pEventText[EVENT_MAX_EVENT_TYPE] = {
+ "restart access point",
+ "successfully associated",
+ "has disassociated",
+ "has been aged-out and disassociated" ,
+ "active countermeasures",
+ "has disassociated with invalid PSK password"};
+
+/*
+ ==========================================================================
+ Description:
+ Initialize AP specific data especially the NDIS packet pool that's
+ used for wireless client bridging.
+ ==========================================================================
+ */
+NDIS_STATUS APInitialize(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ INT i;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("---> APInitialize\n"));
+
+ /* Init Group key update timer, and countermeasures timer */
+ for (i = 0; i < MAX_MBSSID_NUM(pAd); i++)
+ RTMPInitTimer(pAd, &pAd->ApCfg.MBSSID[i].REKEYTimer, GET_TIMER_FUNCTION(GREKEYPeriodicExec), pAd, TRUE);
+
+ RTMPInitTimer(pAd, &pAd->ApCfg.CounterMeasureTimer, GET_TIMER_FUNCTION(CMTimerExec), pAd, FALSE);
+#ifdef RTMP_MAC_USB
+ RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
+ /*RTUSBBssBeaconInit(pAd); */
+#endif /* RTMP_MAC_USB */
+
+#ifdef IDS_SUPPORT
+ /* Init intrusion detection timer */
+ RTMPInitTimer(pAd, &pAd->ApCfg.IDSTimer, GET_TIMER_FUNCTION(RTMPIdsPeriodicExec), pAd, FALSE);
+ pAd->ApCfg.IDSTimerRunning = FALSE;
+#endif /* IDS_SUPPORT */
+
+#ifdef WAPI_SUPPORT
+ /* Init WAPI rekey timer */
+ RTMPInitWapiRekeyTimerAction(pAd, NULL);
+#endif /* WAPI_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ APWdsInitialize(pAd);
+#endif /* WDS_SUPPORT */
+
+#ifdef IGMP_SNOOP_SUPPORT
+ MulticastFilterTableInit(pAd, &pAd->pMulticastFilterTable);
+#endif /* IGMP_SNOOP_SUPPORT */
+
+
+#ifdef WDS_SUPPORT
+ NdisAllocateSpinLock(pAd, &pAd->WdsTabLock);
+#endif /* WDS_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- APInitialize\n"));
+ return Status;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Shutdown AP and free AP specific resources
+ ==========================================================================
+ */
+VOID APShutdown(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("---> APShutdown\n"));
+/* if (pAd->OpMode == OPMODE_AP) */
+
+ MlmeRadioOff(pAd);
+
+#ifdef IGMP_SNOOP_SUPPORT
+ MultiCastFilterTableReset(&pAd->pMulticastFilterTable);
+#endif /* IGMP_SNOOP_SUPPORT */
+
+
+ NdisFreeSpinLock(&pAd->MacTabLock);
+
+#ifdef WDS_SUPPORT
+ NdisFreeSpinLock(&pAd->WdsTabLock);
+#endif /* WDS_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- APShutdown\n"));
+}
+
+/*
+ ==========================================================================
+ Description:
+ Start AP service. If any vital AP parameter is changed, a STOP-START
+ sequence is required to disassociate all STAs.
+
+ IRQL = DISPATCH_LEVEL.(from SetInformationHandler)
+ IRQL = PASSIVE_LEVEL. (from InitializeHandler)
+
+ Note:
+ Can't call NdisMIndicateStatus on this routine.
+
+ RT61 is a serialized driver on Win2KXP and is a deserialized on Win9X
+ Serialized callers of NdisMIndicateStatus must run at IRQL = DISPATCH_LEVEL.
+
+ ==========================================================================
+ */
+VOID APStartUp(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 offset, i;
+ UINT32 Value = 0;
+ BOOLEAN bWmmCapable = FALSE;
+ UCHAR apidx;
+ BOOLEAN TxPreamble, SpectrumMgmt = FALSE;
+ UCHAR phy_mode = pAd->CommonCfg.cfg_wmode;
+#ifdef DOT1X_SUPPORT
+ /* BOOLEAN bDot1xReload = FALSE; */
+#endif /* DOT1X_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> APStartUp\n"));
+
+#ifdef INF_AMAZON_SE
+ for (i=0;i<NUM_OF_TX_RING;i++)
+ {
+ pAd->BulkOutDataSizeLimit[i]=24576;
+ }
+#endif /* INF_AMAZON_SE */
+
+ AsicDisableSync(pAd);
+
+ TxPreamble = (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1);
+
+#ifdef A_BAND_SUPPORT
+ /* Decide the Capability information field */
+ /* In IEEE Std 802.1h-2003, the spectrum management bit is enabled in the 5 GHz band */
+ if ((pAd->CommonCfg.Channel > 14) && pAd->CommonCfg.bIEEE80211H == TRUE)
+ SpectrumMgmt = TRUE;
+#endif /* A_BAND_SUPPORT */
+
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ MULTISSID_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+ if ((pMbss->SsidLen <= 0) || (pMbss->SsidLen > MAX_LEN_OF_SSID))
+ {
+ NdisMoveMemory(pMbss->Ssid, "HT_AP", 5);
+ pMbss->Ssid[5] = '0'+apidx;
+ pMbss->SsidLen = 6;
+ }
+
+ /* re-copy the MAC to virtual interface to avoid these MAC = all zero,
+ when re-open the ra0,
+ i.e. ifconfig ra0 down, ifconfig ra0 up, ifconfig ra0 down, ifconfig up ... */
+ COPY_MAC_ADDR(pMbss->Bssid, pAd->CurrentAddress);
+
+ if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
+ {
+ if (apidx > 0)
+ {
+ /*
+ Refer to HW definition -
+ Bit1 of MAC address Byte0 is local administration bit
+ and should be set to 1 in extended multiple BSSIDs'
+ Bit3~ of MAC address Byte0 is extended multiple BSSID index.
+ */
+ pMbss->Bssid[0] += 2;
+ pMbss->Bssid[0] += ((apidx - 1) << 2);
+ }
+ }
+ else
+ pMbss->Bssid[5] += apidx;
+
+ if (pMbss->MSSIDDev != NULL)
+ {
+ NdisMoveMemory(RTMP_OS_NETDEV_GET_PHYADDR(pMbss->MSSIDDev),
+ pMbss->Bssid, MAC_ADDR_LEN);
+ }
+
+ if (pMbss->bWmmCapable)
+ bWmmCapable = TRUE;
+
+ pMbss->CapabilityInfo = CAP_GENERATE(1, 0, (pMbss->WepStatus != Ndis802_11EncryptionDisabled),
+ TxPreamble, pAd->CommonCfg.bUseShortSlotTime,
+ SpectrumMgmt);
+
+
+ if (bWmmCapable == TRUE)
+ {
+ /*
+ In WMM spec v1.1, A WMM-only AP or STA does not set the "QoS"
+ bit in the capability field of association, beacon and probe
+ management frames.
+ */
+/* pMbss->CapabilityInfo |= 0x0200; */
+ }
+
+#ifdef UAPSD_SUPPORT
+ if (pMbss->UapsdInfo.bAPSDCapable == TRUE)
+ {
+ /*
+ QAPs set the APSD subfield to 1 within the Capability
+ Information field when the MIB attribute
+ dot11APSDOptionImplemented is true and set it to 0 otherwise.
+ STAs always set this subfield to 0.
+ */
+ pMbss->CapabilityInfo |= 0x0800;
+ }
+#endif /* UAPSD_SUPPORT */
+
+
+ /* decide the mixed WPA cipher combination */
+ if (pMbss->WepStatus == Ndis802_11Encryption4Enabled)
+ {
+ switch ((UCHAR)pMbss->AuthMode)
+ {
+ /* WPA mode */
+ case Ndis802_11AuthModeWPA:
+ case Ndis802_11AuthModeWPAPSK:
+ pMbss->WpaMixPairCipher = WPA_TKIPAES_WPA2_NONE;
+ break;
+
+ /* WPA2 mode */
+ case Ndis802_11AuthModeWPA2:
+ case Ndis802_11AuthModeWPA2PSK:
+ pMbss->WpaMixPairCipher = WPA_NONE_WPA2_TKIPAES;
+ break;
+
+ /* WPA and WPA2 both mode */
+ case Ndis802_11AuthModeWPA1WPA2:
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+
+ /* In WPA-WPA2 and TKIP-AES mixed mode, it shall use the maximum */
+ /* cipher capability unless users assign the desired setting. */
+ if (pMbss->WpaMixPairCipher == MIX_CIPHER_NOTUSE ||
+ pMbss->WpaMixPairCipher == WPA_TKIPAES_WPA2_NONE ||
+ pMbss->WpaMixPairCipher == WPA_NONE_WPA2_TKIPAES)
+ pMbss->WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIPAES;
+ break;
+ }
+
+ }
+ else
+ pMbss->WpaMixPairCipher = MIX_CIPHER_NOTUSE;
+
+ /* Generate the corresponding RSNIE */
+ RTMPMakeRSNIE(pAd, pMbss->AuthMode, pMbss->WepStatus, apidx);
+
+#ifdef WSC_V2_SUPPORT
+ if (pMbss->WscControl.WscV2Info.bEnableWpsV2)
+ {
+ /* WPS V2 doesn't support WEP and WPA/WPAPSK-TKIP. */
+ if ((pMbss->WepStatus == Ndis802_11WEPEnabled) ||
+ (pMbss->WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pMbss->bHideSsid))
+ WscOnOff(pAd, apidx, TRUE);
+ else
+ WscOnOff(pAd, apidx, FALSE);
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (phy_mode != pAd->CommonCfg.PhyMode)
+ RTMPSetPhyMode(pAd, phy_mode);
+
+ SetCommonHT(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ COPY_MAC_ADDR(pAd->CommonCfg.Bssid, pAd->CurrentAddress);
+
+ /* Select DAC according to HT or Legacy, write to BBP R1(bit4:3) */
+ /* In HT mode and two stream mode, both DACs are selected. */
+ /* In legacy mode or one stream mode, DAC-0 is selected. */
+ {
+#ifdef DOT11_N_SUPPORT
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) && (pAd->Antenna.field.TxPath == 2))
+ rtmp_bbp_set_txdac(pAd, 2);
+ else
+#endif /* DOT11_N_SUPPORT */
+ rtmp_bbp_set_txdac(pAd, 0);
+ }
+
+ /* Receiver Antenna selection */
+ rtmp_bbp_set_rxpath(pAd, pAd->Antenna.field.RxPath);
+
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) || bWmmCapable)
+ {
+ /* 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; /*96; */
+ pAd->CommonCfg.APEdcaParm.Txop[3] = 47; /*48; */
+ }
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+ /* EDCA parameters to be annouced in outgoing BEACON, used by WMM STA */
+ if (pAd->ApCfg.BssEdcaParm.bValid == FALSE)
+ {
+ pAd->ApCfg.BssEdcaParm.bValid = TRUE;
+ pAd->ApCfg.BssEdcaParm.Aifsn[0] = 3;
+ pAd->ApCfg.BssEdcaParm.Aifsn[1] = 7;
+ pAd->ApCfg.BssEdcaParm.Aifsn[2] = 2;
+ pAd->ApCfg.BssEdcaParm.Aifsn[3] = 2;
+
+ pAd->ApCfg.BssEdcaParm.Cwmin[0] = 4;
+ pAd->ApCfg.BssEdcaParm.Cwmin[1] = 4;
+ pAd->ApCfg.BssEdcaParm.Cwmin[2] = 3;
+ pAd->ApCfg.BssEdcaParm.Cwmin[3] = 2;
+
+ pAd->ApCfg.BssEdcaParm.Cwmax[0] = 10;
+ pAd->ApCfg.BssEdcaParm.Cwmax[1] = 10;
+ pAd->ApCfg.BssEdcaParm.Cwmax[2] = 4;
+ pAd->ApCfg.BssEdcaParm.Cwmax[3] = 3;
+
+ pAd->ApCfg.BssEdcaParm.Txop[0] = 0;
+ pAd->ApCfg.BssEdcaParm.Txop[1] = 0;
+ pAd->ApCfg.BssEdcaParm.Txop[2] = 94; /*96; */
+ pAd->ApCfg.BssEdcaParm.Txop[3] = 47; /*48; */
+ }
+ }
+ else
+ AsicSetEdcaParm(pAd, NULL);
+
+#ifdef DOT11_N_SUPPORT
+ if (!WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ /* Patch UI */
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = BW_20;
+ }
+
+ /* init */
+ if (pAd->CommonCfg.bRdg)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
+ AsicEnableRDG(pAd);
+ }
+ else
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
+ AsicDisableRDG(pAd);
+ }
+
+ if (pAd->CommonCfg.bRalinkBurstMode)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE);
+ AsicEnableRalinkBurstMode(pAd);
+ }
+ else
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE);
+ AsicDisableRalinkBurstMode(pAd);
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ COPY_MAC_ADDR(pAd->ApCfg.MBSSID[BSS0].Bssid, pAd->CurrentAddress);
+ AsicSetBssid(pAd, pAd->CurrentAddress);
+ AsicSetMcastWC(pAd);
+
+
+ /*@!RELEASE
+ Reset WCID table
+
+ In AP mode, First WCID Table in ASIC will never be used.
+ To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
+
+ p.s ASIC use all 0xff as termination of WCID table search.
+ */
+#ifdef MT7601U
+ {
+ UINT32 MACValue[128 * 2];
+ UINT32 Index;
+
+ for (Index = 0; Index < 128 * 2; Index+=2)
+ {
+ MACValue[Index] = 0;
+ MACValue[Index + 1] = 0;
+ }
+
+ AndesBurstWrite(pAd, MAC_WCID_BASE, MACValue, 128 * 2);
+
+
+ }
+#else
+ for (i=0; i<255; i++)
+ AsicDelWcidTab(pAd, i);
+#endif /* MT7601U */
+
+#ifdef FIFO_EXT_SUPPORT
+ AsicFifoExtSet(pAd);
+#endif /* FIFO_EXT_SUPPORT */
+
+ pAd->MacTab.MsduLifeTime = 5; /* default 5 seconds */
+
+ pAd->MacTab.Content[0].Addr[0] = 0x01;
+ pAd->MacTab.Content[0].HTPhyMode.field.MODE = MODE_OFDM;
+ pAd->MacTab.Content[0].HTPhyMode.field.MCS = 3;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+
+ AsicBBPAdjust(pAd);
+
+ /* Clear BG-Protection flag */
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+#ifdef DOT11_VHT_AC
+ if (pAd->CommonCfg.BBPCurrentBW == BW_80)
+ pAd->hw_cfg.cent_ch = pAd->CommonCfg.vht_cent_ch;
+ else
+#endif /* DOT11_VHT_AC */
+ pAd->hw_cfg.cent_ch = pAd->CommonCfg.CentralChannel;
+ AsicSwitchChannel(pAd, pAd->hw_cfg.cent_ch, FALSE);
+ AsicLockChannel(pAd, pAd->hw_cfg.cent_ch);
+
+#ifdef DOT11_VHT_AC
+//+++Add by shiang for debug
+DBGPRINT(RT_DEBUG_OFF, ("%s(): AP Set CentralFreq at %d(Prim=%d, HT-CentCh=%d, VHT-CentCh=%d, BBP_BW=%d)\n",
+ __FUNCTION__, pAd->hw_cfg.cent_ch, pAd->CommonCfg.Channel,
+ pAd->CommonCfg.CentralChannel, pAd->CommonCfg.vht_cent_ch,
+ pAd->CommonCfg.BBPCurrentBW));
+//---Add by shiang for debug
+#endif /* DOT11_VHT_AC */
+
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+ if (pAd->ApCfg.bGreenAPEnable == TRUE)
+ {
+ RTMP_CHIP_ENABLE_AP_MIMOPS(pAd,TRUE);
+ pAd->ApCfg.GreenAPLevel=GREENAP_WITHOUT_ANY_STAS_CONNECT;
+ }
+#endif /* GREENAP_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+ MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble);
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ MlmeUpdateTxRates(pAd, FALSE, apidx);
+#ifdef DOT11_N_SUPPORT
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ MlmeUpdateHtTxRates(pAd, apidx);
+#endif /* DOT11_N_SUPPORT */
+ }
+
+ /* Set the RadarDetect Mode as Normal, bc the APUpdateAllBeaconFram() will refer this parameter. */
+ pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
+
+ /* Disable Protection first. */
+ AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
+
+ APUpdateCapabilityAndErpIe(pAd);
+#ifdef DOT11_N_SUPPORT
+ APUpdateOperationMode(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef LED_CONTROL_SUPPORT
+ /* Set LED */
+ RTMPSetLED(pAd, LED_LINK_UP);
+#endif /* LED_CONTROL_SUPPORT */
+
+
+ /* Initialize security variable per entry,
+ 1. pairwise key table, re-set all WCID entry as NO-security mode.
+ 2. access control port status
+ */
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pAd->MacTab.Content[i].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ AsicRemovePairwiseKeyEntry(pAd, (UCHAR)i);
+ }
+
+ /* Init Security variables */
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ USHORT Wcid = 0;
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+ pMbss->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+ if (IS_WPA_CAPABILITY(pMbss->AuthMode))
+ {
+ pMbss->DefaultKeyId = 1;
+ }
+
+ /* Get a specific WCID to record this MBSS key attribute */
+ GET_GroupKey_WCID(pAd, Wcid, apidx);
+
+ /* When WEP, TKIP or AES is enabled, set group key info to Asic */
+ if (pMbss->WepStatus == Ndis802_11WEPEnabled)
+ {
+ UCHAR CipherAlg, idx;
+
+ for (idx=0; idx < SHARE_KEY_NUM; idx++)
+ {
+ CipherAlg = pAd->SharedKey[apidx][idx].CipherAlg;
+
+ if (pAd->SharedKey[apidx][idx].KeyLen > 0)
+ {
+ /* Set key material to Asic */
+ AsicAddSharedKeyEntry(pAd, apidx, idx, &pAd->SharedKey[apidx][idx]);
+
+ if (idx == pMbss->DefaultKeyId)
+ {
+ /* Generate 3-bytes IV randomly for software encryption using */
+ for(i = 0; i < LEN_WEP_TSC; i++)
+ pAd->SharedKey[apidx][idx].TxTsc[i] = RandomByte(pAd);
+
+ /* Update WCID attribute table and IVEIV table */
+ RTMPSetWcidSecurityInfo(pAd,
+ apidx,
+ idx,
+ CipherAlg,
+ Wcid,
+ SHAREDKEYTABLE);
+ }
+ }
+ }
+ }
+ else if ((pMbss->WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pMbss->WepStatus == Ndis802_11Encryption3Enabled) ||
+ (pMbss->WepStatus == Ndis802_11Encryption4Enabled))
+ {
+ /* Generate GMK and GNonce randomly per MBSS */
+ GenRandom(pAd, pMbss->Bssid, pMbss->GMK);
+ GenRandom(pAd, pMbss->Bssid, pMbss->GNonce);
+
+ /* Derive GTK per BSSID */
+ WpaDeriveGTK(pMbss->GMK,
+ (UCHAR*)pMbss->GNonce,
+ pMbss->Bssid,
+ pMbss->GTK,
+ LEN_TKIP_GTK);
+
+ /* Install Shared key */
+ WPAInstallSharedKey(pAd,
+ pMbss->GroupKeyWepStatus,
+ apidx,
+ pMbss->DefaultKeyId,
+ Wcid,
+ TRUE,
+ pMbss->GTK,
+ LEN_TKIP_GTK);
+
+ }
+#ifdef WAPI_SUPPORT
+ else if (pMbss->WepStatus == Ndis802_11EncryptionSMS4Enabled)
+ {
+ INT cnt;
+
+ /* Initial the related variables */
+ pMbss->DefaultKeyId = 0;
+ NdisMoveMemory(pMbss->key_announce_flag, AE_BCAST_PN, LEN_WAPI_TSC);
+ if (IS_HW_WAPI_SUPPORT(pAd))
+ pMbss->sw_wpi_encrypt = FALSE;
+ else
+ pMbss->sw_wpi_encrypt = TRUE;
+
+ /* Generate NMK randomly */
+ for (cnt = 0; cnt < LEN_WAPI_NMK; cnt++)
+ pMbss->NMK[cnt] = RandomByte(pAd);
+
+ /* Count GTK for this BSSID */
+ RTMPDeriveWapiGTK(pMbss->NMK, pMbss->GTK);
+
+ /* Install Shared key */
+ WAPIInstallSharedKey(pAd,
+ pMbss->GroupKeyWepStatus,
+ apidx,
+ pMbss->DefaultKeyId,
+ Wcid,
+ pMbss->GTK);
+
+ }
+#endif /* WAPI_SUPPORT */
+
+#ifdef DOT1X_SUPPORT
+ /* Send singal to daemon to indicate driver had restarted */
+ if ((pMbss->AuthMode == Ndis802_11AuthModeWPA) || (pMbss->AuthMode == Ndis802_11AuthModeWPA2)
+ || (pMbss->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pMbss->IEEE8021X == TRUE))
+ {
+ ;/*bDot1xReload = TRUE; */
+ }
+#endif /* DOT1X_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("### BSS(%d) AuthMode(%d)=%s, WepStatus(%d)=%s , AccessControlList.Policy=%ld\n", apidx, pMbss->AuthMode, GetAuthMode(pMbss->AuthMode),
+ pMbss->WepStatus, GetEncryptType(pMbss->WepStatus), pMbss->AccessControlList.Policy));
+ }
+
+
+ /* Disable Protection first. */
+ /*AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE); */
+#ifdef PIGGYBACK_SUPPORT
+ RTMPSetPiggyBack(pAd, pAd->CommonCfg.bPiggyBackCapable);
+#endif /* PIGGYBACK_SUPPORT */
+
+ ApLogEvent(pAd, pAd->CurrentAddress, EVENT_RESET_ACCESS_POINT);
+ pAd->Mlme.PeriodicRound = 0;
+ pAd->Mlme.OneSecPeriodicRound = 0;
+
+ OPSTATUS_SET_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
+
+ RTMP_IndicateMediaState(pAd, NdisMediaStateConnected);
+
+
+ /*
+ NOTE!!!:
+ All timer setting shall be set after following flag be cleared
+ fRTMP_ADAPTER_HALT_IN_PROGRESS
+ */
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+#ifdef RTMP_MAC_USB
+ RTUSBBssBeaconInit(pAd);
+#endif /* RTMP_MAC_USB */
+ /* start sending BEACON out */
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+
+#ifdef A_BAND_SUPPORT
+ if ( (pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ pAd->Dot11_H.RDMode = RD_SILENCE_MODE;
+ pAd->Dot11_H.RDCount = 0;
+ pAd->Dot11_H.InServiceMonitorCount = 0;
+#ifdef DFS_SUPPORT
+ NewRadarDetectionStart(pAd);
+#endif /* DFS_SUPPORT */
+ }
+ else
+#endif /* A_BAND_SUPPORT */
+ {
+ pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
+ AsicEnableBssSync(pAd);
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT
+#ifdef A_BAND_SUPPORT
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ if ((pAd->CommonCfg.CarrierDetect.Enable == FALSE)
+ && ((pAd->CommonCfg.RDDurRegion == JAP)
+ || (pAd->CommonCfg.RDDurRegion == JAP_W53)
+ || (pAd->CommonCfg.RDDurRegion == JAP_W56)))
+ {
+ pAd->CommonCfg.CarrierDetect.Enable = 1;
+ }
+ }
+ else
+#endif /* A_BAND_SUPPORT */
+ {
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ {
+ if ((pAd->CommonCfg.CarrierDetect.Enable == FALSE)
+ && ((pAd->CommonCfg.RDDurRegion == JAP)
+ || (pAd->CommonCfg.RDDurRegion == JAP_W53)
+ || (pAd->CommonCfg.RDDurRegion == JAP_W56)))
+ {
+ pAd->CommonCfg.CarrierDetect.Enable = TRUE;
+ }
+ }
+ }
+
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ CarrierDetectionStart(pAd);
+ }
+#endif /* CARRIER_DETECTION_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ /* Pre-tbtt interrupt setting. */
+ AsicSetPreTbttInt(pAd, TRUE);
+
+#ifdef WAPI_SUPPORT
+ RTMPStartWapiRekeyTimerAction(pAd, NULL);
+#endif /* WAPI_SUPPORT */
+
+ /*
+ Set group re-key timer if necessary.
+ It must be processed after clear flag "fRTMP_ADAPTER_HALT_IN_PROGRESS"
+ */
+ WPA_APSetGroupRekeyAction(pAd);
+
+#ifdef WDS_SUPPORT
+ /* Prepare WEP key */
+ WdsPrepareWepKeyFromMainBss(pAd);
+
+ /* Add wds key infomation to ASIC */
+ AsicUpdateWdsRxWCIDTable(pAd);
+
+ AsicUpdateMulTestRxWCIDTable(pAd);
+#endif /* WDS_SUPPORT */
+
+#ifdef IDS_SUPPORT
+ /* Start IDS timer */
+ if (pAd->ApCfg.IdsEnable)
+ {
+#ifdef SYSTEM_LOG_SUPPORT
+ if (pAd->CommonCfg.bWirelessEvent == FALSE)
+ DBGPRINT(RT_DEBUG_WARN, ("!!! WARNING !!! The WirelessEvent parameter doesn't be enabled \n"));
+#endif /* SYSTEM_LOG_SUPPORT */
+
+ RTMPIdsStart(pAd);
+ }
+#endif /* IDS_SUPPORT */
+
+#ifdef RTMP_MAC_USB
+ /* */
+ /* Support multiple BulkIn IRP, */
+ /* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. */
+ /* */
+ for(i=0; i<pAd->CommonCfg.NumOfBulkInIRP; i++)
+ {
+ RTUSBBulkReceive(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
+ }
+#endif /* RTMP_MAC_USB */
+
+
+
+
+#if MT7601
+ if ( IS_MT7601(pAd) )
+ {
+#ifdef DPD_CALIBRATION_SUPPORT
+ /* DPD-Calibration */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_DPD, pAd->chipCap.CurrentTemperature);
+#endif /* DPD_CALIBRATION_SUPPORT */
+
+ // MT7601_RXDC_CAL
+ MT7601_RXDC_CAL(pAd);
+ }
+#endif /* MT7601 */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<=== APStartUp\n"));
+}
+
+/*
+ ==========================================================================
+ Description:
+ disassociate all STAs and stop AP service.
+ Note:
+ ==========================================================================
+ */
+VOID APStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN Cancelled;
+ UINT32 Value;
+ INT apidx;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! APStop !!!\n"));
+
+#ifdef DFS_SUPPORT
+ NewRadarDetectionStop(pAd);
+#endif /* DFS_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ /* make sure CarrierDetect wont send CTS */
+ CarrierDetectionStop(pAd);
+ }
+#endif /* CARRIER_DETECTION_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef WDS_SUPPORT
+ WdsDown(pAd);
+#endif /* WDS_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+ ApCliIfDown(pAd);
+#endif /* APCLI_SUPPORT */
+
+ MacTableReset(pAd);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+ /* Disable pre-tbtt interrupt */
+ RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
+ Value &=0xe;
+ RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
+ /* Disable piggyback */
+ RTMPSetPiggyBack(pAd, FALSE);
+
+ AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ /*RTMP_ASIC_INTERRUPT_DISABLE(pAd); */
+ AsicDisableSync(pAd);
+
+#ifdef LED_CONTROL_SUPPORT
+ /* Set LED */
+ RTMPSetLED(pAd, LED_LINK_DOWN);
+#endif /* LED_CONTROL_SUPPORT */
+ }
+
+#ifdef RTMP_MAC_USB
+ /* For RT2870, we need to clear the beacon sync buffer. */
+ RTUSBBssBeaconExit(pAd);
+#endif /* RTMP_MAC_USB */
+
+
+ for (apidx = 0; apidx < MAX_MBSSID_NUM(pAd); apidx++)
+ {
+ if (pAd->ApCfg.MBSSID[apidx].REKEYTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pAd->ApCfg.MBSSID[apidx].REKEYTimer, &Cancelled);
+ pAd->ApCfg.MBSSID[apidx].REKEYTimerRunning = FALSE;
+ }
+ }
+
+ if (pAd->ApCfg.CMTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled);
+ pAd->ApCfg.CMTimerRunning = FALSE;
+ }
+
+#ifdef WAPI_SUPPORT
+ RTMPCancelWapiRekeyTimerAction(pAd, NULL);
+#endif /* WAPI_SUPPORT */
+
+ /* */
+ /* Cancel the Timer, to make sure the timer was not queued. */
+ /* */
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
+ RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected);
+
+#ifdef IDS_SUPPORT
+ /* if necessary, cancel IDS timer */
+ RTMPIdsStop(pAd);
+#endif /* IDS_SUPPORT */
+
+
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is used to clean up a specified power-saving queue. It's
+ used whenever a wireless client is deleted.
+ ==========================================================================
+ */
+VOID APCleanupPsQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_HEADER pQueue)
+{
+ PQUEUE_ENTRY pEntry;
+ PNDIS_PACKET pPacket;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): (0x%08lx)...\n", __FUNCTION__, (ULONG)pQueue));
+
+ while (pQueue->Head)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():%ld...\n", __FUNCTION__, pQueue->Number));
+
+ pEntry = RemoveHeadQueue(pQueue);
+ /*pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx); */
+ pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is called by APMlmePeriodicExec() every second to check if
+ 1. any associated client in PSM. If yes, then TX MCAST/BCAST should be
+ out in DTIM only
+ 2. any client being idle for too long and should be aged-out from MAC table
+ 3. garbage collect PSQ
+ ==========================================================================
+*/
+VOID MacTableMaintenance(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+#ifdef DOT11_N_SUPPORT
+ ULONG MinimumAMPDUSize = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor; /*Default set minimum AMPDU Size to 2, i.e. 32K */
+ BOOLEAN bRdgActive;
+ BOOLEAN bRalinkBurstMode;
+#endif /* DOT11_N_SUPPORT */
+ UINT fAnyStationPortSecured[HW_BEACON_MAX_NUM];
+ UINT bss_index;
+ MAC_TABLE *pMacTable;
+#if defined(PRE_ANT_SWITCH) || defined(CFO_TRACK)
+ int lastClient=0;
+#endif /* defined(PRE_ANT_SWITCH) || defined(CFO_TRACK) */
+
+ for (bss_index = BSS0; bss_index < MAX_MBSSID_NUM(pAd); bss_index++)
+ fAnyStationPortSecured[bss_index] = 0;
+
+ pMacTable = &pAd->MacTab;
+ pMacTable->fAnyStationInPsm = FALSE;
+ pMacTable->fAnyStationBadAtheros = FALSE;
+ pMacTable->fAnyTxOPForceDisable = FALSE;
+ pMacTable->fAllStationAsRalink = TRUE;
+#ifdef DOT11_N_SUPPORT
+ pMacTable->fAnyStationNonGF = FALSE;
+ pMacTable->fAnyStation20Only = FALSE;
+ pMacTable->fAnyStationIsLegacy = FALSE;
+ pMacTable->fAnyStationMIMOPSDynamic = FALSE;
+#ifdef GREENAP_SUPPORT
+ /*Support Green AP */
+ pMacTable->fAnyStationIsHT=FALSE;
+#endif /* GREENAP_SUPPORT */
+
+#ifdef DOT11N_DRAFT3
+ pMacTable->fAnyStaFortyIntolerant = FALSE;
+#endif /* DOT11N_DRAFT3 */
+ pMacTable->fAllStationGainGoodMCS = TRUE;
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef WAPI_SUPPORT
+ pMacTable->fAnyWapiStation = FALSE;
+#endif /* WAPI_SUPPORT */
+
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[i];
+ BOOLEAN bDisconnectSta = FALSE;
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if(IS_ENTRY_APCLI(pEntry) && pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
+ {
+ if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
+ {
+ /* use Null or QoS Null to detect the ACTIVE station*/
+ BOOLEAN ApclibQosNull = FALSE;
+
+ if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ ApclibQosNull = TRUE;
+
+ ApCliRTMPSendNullFrame(pAd,pEntry->CurrTxRate, ApclibQosNull, pEntry);
+
+ continue;
+ }
+ }
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif /* APCLI_SUPPORT */
+
+ if (!IS_ENTRY_CLIENT(pEntry))
+ continue;
+
+ if (pEntry->NoDataIdleCount == 0)
+ pEntry->StationKeepAliveCount = 0;
+
+ pEntry->NoDataIdleCount ++;
+ pEntry->StaConnectTime ++;
+
+ /* 0. STA failed to complete association should be removed to save MAC table space. */
+ if ((pEntry->Sst != SST_ASSOC) && (pEntry->NoDataIdleCount >= pEntry->AssocDeadLine))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x fail to complete ASSOC in %d sec\n",
+ pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
+ pEntry->Addr[4],pEntry->Addr[5],MAC_TABLE_ASSOC_TIMEOUT));
+#ifdef WSC_AP_SUPPORT
+ if (NdisEqualMemory(pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, MAC_ADDR_LEN))
+ NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, MAC_ADDR_LEN);
+#endif /* WSC_AP_SUPPORT */
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ continue;
+ }
+
+ /* 1. check if there's any associated STA in power-save mode. this affects outgoing */
+ /* MCAST/BCAST frames should be stored in PSQ till DtimCount=0 */
+ if (pEntry->PsMode == PWR_SAVE)
+ pMacTable->fAnyStationInPsm = TRUE;
+
+#ifdef DOT11_N_SUPPORT
+ if (pEntry->MmpsMode == MMPS_DYNAMIC)
+ {
+ pMacTable->fAnyStationMIMOPSDynamic = TRUE;
+ }
+
+ if (pEntry->MaxHTPhyMode.field.BW == BW_20)
+ pMacTable->fAnyStation20Only = TRUE;
+
+ if (pEntry->MaxHTPhyMode.field.MODE != MODE_HTGREENFIELD)
+ pMacTable->fAnyStationNonGF = TRUE;
+
+ if ((pEntry->MaxHTPhyMode.field.MODE == MODE_OFDM) || (pEntry->MaxHTPhyMode.field.MODE == MODE_CCK))
+ pMacTable->fAnyStationIsLegacy = TRUE;
+#ifdef GREENAP_SUPPORT
+ else
+ pMacTable->fAnyStationIsHT=TRUE;
+#endif /* GREENAP_SUPPORT */
+
+#ifdef DOT11N_DRAFT3
+ if (pEntry->bForty_Mhz_Intolerant)
+ pMacTable->fAnyStaFortyIntolerant = TRUE;
+#endif /* DOT11N_DRAFT3 */
+
+ /* Get minimum AMPDU size from STA */
+ if (MinimumAMPDUSize > pEntry->MaxRAmpduFactor)
+ MinimumAMPDUSize = pEntry->MaxRAmpduFactor;
+#endif /* DOT11_N_SUPPORT */
+
+ if (pEntry->bIAmBadAtheros)
+ {
+ pMacTable->fAnyStationBadAtheros = TRUE;
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == FALSE)
+ AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, pMacTable->fAnyStationNonGF);
+#endif /* DOT11_N_SUPPORT */
+ }
+
+ /* detect the station alive status */
+ /* detect the station alive status */
+ if ((pAd->ApCfg.MBSSID[pEntry->apidx].StationKeepAliveTime > 0) &&
+ (pEntry->NoDataIdleCount >= pAd->ApCfg.MBSSID[pEntry->apidx].StationKeepAliveTime))
+ {
+ MULTISSID_STRUCT *pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx];
+
+ /*
+ If no any data success between ap and the station for
+ StationKeepAliveTime, try to detect whether the station is
+ still alive.
+
+ Note: Just only keepalive station function, no disassociation
+ function if too many no response.
+ */
+
+ /*
+ For example as below:
+
+ 1. Station in ACTIVE mode,
+
+ ......
+ sam> tx ok!
+ sam> count = 1! ==> 1 second after the Null Frame is acked
+ sam> count = 2! ==> 2 second after the Null Frame is acked
+ sam> count = 3!
+ sam> count = 4!
+ sam> count = 5!
+ sam> count = 6!
+ sam> count = 7!
+ sam> count = 8!
+ sam> count = 9!
+ sam> count = 10!
+ sam> count = 11!
+ sam> count = 12!
+ sam> count = 13!
+ sam> count = 14!
+ sam> count = 15! ==> 15 second after the Null Frame is acked
+ sam> tx ok! ==> (KeepAlive Mechanism) send a Null Frame to
+ detect the STA life status
+ sam> count = 1! ==> 1 second after the Null Frame is acked
+ sam> count = 2!
+ sam> count = 3!
+ sam> count = 4!
+ ......
+
+ If the station acknowledges the QoS Null Frame,
+ the NoDataIdleCount will be reset to 0.
+
+
+ 2. Station in legacy PS mode,
+
+ We will set TIM bit after 15 seconds, the station will send a
+ PS-Poll frame and we will send a QoS Null frame to it.
+ If the station acknowledges the QoS Null Frame, the
+ NoDataIdleCount will be reset to 0.
+
+
+ 3. Station in legacy UAPSD mode,
+
+ Currently we do not support the keep alive mechanism.
+ So if your station is in UAPSD mode, the station will be
+ kicked out after 300 seconds.
+
+ Note: the rate of QoS Null frame can not be 1M of 2.4GHz or
+ 6M of 5GHz, or no any statistics count will occur.
+ */
+
+ if (pEntry->StationKeepAliveCount++ == 0)
+ {
+ if (pEntry->PsMode == PWR_SAVE)
+ {
+ /* use TIM bit to detect the PS station */
+ WLAN_MR_TIM_BIT_SET(pAd, pEntry->apidx, pEntry->Aid);
+ }
+ else
+ {
+ /* use Null or QoS Null to detect the ACTIVE station */
+ BOOLEAN bQosNull = FALSE;
+
+ if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ bQosNull = TRUE;
+
+ ApEnqueueNullFrame(pAd, pEntry->Addr, pEntry->CurrTxRate,
+ pEntry->Aid, pEntry->apidx, bQosNull, TRUE, 0);
+ }
+ }
+ else
+ {
+ if (pEntry->StationKeepAliveCount >= pMbss->StationKeepAliveTime)
+ pEntry->StationKeepAliveCount = 0;
+ }
+ }
+
+ /* 2. delete those MAC entry that has been idle for a long time */
+ if (pEntry->NoDataIdleCount >= pEntry->StaIdleTimeout)
+ {
+ bDisconnectSta = TRUE;
+ DBGPRINT(RT_DEBUG_WARN, ("ageout %02x:%02x:%02x:%02x:%02x:%02x after %d-sec silence\n",
+ PRINT_MAC(pEntry->Addr), pEntry->StaIdleTimeout));
+ ApLogEvent(pAd, pEntry->Addr, EVENT_AGED_OUT);
+ }
+ else if (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck)
+ {
+ /*
+ AP have no way to know that the PwrSaving STA is leaving or not.
+ So do not disconnect for PwrSaving STA.
+ */
+ if (pEntry->PsMode != PWR_SAVE)
+ {
+ bDisconnectSta = TRUE;
+ DBGPRINT(RT_DEBUG_WARN, ("STA-%02x:%02x:%02x:%02x:%02x:%02x had left (%d %lu)\n",
+ PRINT_MAC(pEntry->Addr),
+ pEntry->ContinueTxFailCnt, pAd->ApCfg.EntryLifeCheck));
+ }
+ }
+
+ if (bDisconnectSta)
+ {
+ /* send wireless event - for ageout */
+ RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0);
+
+ if (pEntry->Sst == SST_ASSOC)
+ {
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ HEADER_802_11 DeAuthHdr;
+ USHORT Reason;
+
+ /* send out a DISASSOC request frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n"));
+ /*NdisReleaseSpinLock(&pAd->MacTabLock); */
+ continue;
+ }
+ Reason = REASON_DEAUTH_STA_LEAVING;
+ DBGPRINT(RT_DEBUG_WARN, ("Send DEAUTH - Reason = %d frame TO %x %x %x %x %x %x \n",
+ Reason, PRINT_MAC(pEntry->Addr)));
+ MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->Addr,
+ pAd->ApCfg.MBSSID[pEntry->apidx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DeAuthHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ continue;
+ }
+
+ /* 3. garbage collect the PsQueue if the STA has being idle for a while */
+ if (pEntry->PsQueue.Head)
+ {
+ pEntry->PsQIdleCount ++;
+ if (pEntry->PsQIdleCount > 2)
+ {
+ NdisAcquireSpinLock(&pAd->irq_lock);
+ APCleanupPsQueue(pAd, &pEntry->PsQueue);
+ NdisReleaseSpinLock(&pAd->irq_lock);
+ pEntry->PsQIdleCount = 0;
+ WLAN_MR_TIM_BIT_CLEAR(pAd, pEntry->apidx, pEntry->Aid);
+ }
+ }
+ else
+ pEntry->PsQIdleCount = 0;
+
+#ifdef UAPSD_SUPPORT
+ UAPSD_QueueMaintenance(pAd, pEntry);
+#endif /* UAPSD_SUPPORT */
+
+ /* check if this STA is Ralink-chipset */
+ if (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))
+ pMacTable->fAllStationAsRalink = FALSE;
+
+ /* Check if the port is secured */
+ if (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
+ fAnyStationPortSecured[pEntry->apidx]++;
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if ((pEntry->BSS2040CoexistenceMgmtSupport)
+ && (pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_INFO_NOTIFY)
+ && (pAd->CommonCfg.bBssCoexEnable == TRUE)
+ )
+ {
+ SendNotifyBWActionFrame(pAd, pEntry->Aid, pEntry->apidx);
+ }
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+#ifdef WAPI_SUPPORT
+ if (pEntry->WepStatus == Ndis802_11EncryptionSMS4Enabled)
+ pMacTable->fAnyWapiStation = TRUE;
+#endif /* WAPI_SUPPORT */
+
+#if defined(PRE_ANT_SWITCH) || defined(CFO_TRACK)
+ lastClient = i;
+#endif /* defined(PRE_ANT_SWITCH) || defined(CFO_TRACK) */
+
+ /* only apply burst when run in MCS0,1,8,9,16,17, not care about phymode */
+ if ((pEntry->HTPhyMode.field.MCS != 32) &&
+ ((pEntry->HTPhyMode.field.MCS % 8 == 0) || (pEntry->HTPhyMode.field.MCS % 8 == 1)))
+ {
+ pMacTable->fAllStationGainGoodMCS = FALSE;
+ }
+ }
+
+#ifdef RT8592
+ // TODO: shiang-6590, fix me after chip fix this issue !!
+ if (0)//IS_RT8592(pAd))
+ {
+ if (pMacTable->Size == 1)
+ {
+ UINT32 bbp_reg, bbp_val;
+
+ RTMP_BBP_IO_READ32(pAd, AGC1_R20, &bbp_reg);
+ if ((bbp_reg & 0xff) > 0xE5)
+ bbp_val = 0x132C38C0;
+ else
+ bbp_val = 0x132C40C0;
+ RTMP_BBP_IO_WRITE32(pAd, AGC1_R8, bbp_val);
+
+ if (((bbp_reg & 0xff00) >> 8) > 0xE5)
+ bbp_val = 0x132C38C0;
+ else
+ bbp_val = 0x132C40C0;
+ RTMP_BBP_IO_WRITE32(pAd, AGC1_R9, bbp_val);
+ }
+ }
+#endif /* RT8592 */
+
+#ifdef PRE_ANT_SWITCH
+#endif /* PRE_ANT_SWITCH */
+
+#ifdef CFO_TRACK
+#endif /* CFO_TRACK */
+
+ /* Update the state of port per MBSS */
+ for (bss_index = BSS0; bss_index < MAX_MBSSID_NUM(pAd); bss_index++)
+ {
+ if (fAnyStationPortSecured[bss_index] > 0)
+ pAd->ApCfg.MBSSID[bss_index].PortSecured = WPA_802_1X_PORT_SECURED;
+ else
+ pAd->ApCfg.MBSSID[bss_index].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_INFO_NOTIFY)
+ pAd->CommonCfg.Bss2040CoexistFlag &= (~BSS_2040_COEXIST_INFO_NOTIFY);
+#endif /* DOT11N_DRAFT3 */
+
+ /* If all associated STAs are Ralink-chipset, AP shall enable RDG. */
+ if (pAd->CommonCfg.bRdg && pMacTable->fAllStationAsRalink)
+ {
+ bRdgActive = TRUE;
+ }
+ else
+ {
+ bRdgActive = FALSE;
+ }
+
+ if (pAd->CommonCfg.bRalinkBurstMode && pMacTable->fAllStationGainGoodMCS)
+ {
+ bRalinkBurstMode = TRUE;
+ }
+ else
+ {
+ bRalinkBurstMode = FALSE;
+ }
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ if(pAd->MacTab.fAnyStationIsHT == FALSE
+ && pAd->ApCfg.bGreenAPEnable == TRUE)
+ {
+ if (pAd->ApCfg.GreenAPLevel!=GREENAP_ONLY_11BG_STAS)
+ {
+ RTMP_CHIP_ENABLE_AP_MIMOPS(pAd,FALSE);
+ pAd->ApCfg.GreenAPLevel=GREENAP_ONLY_11BG_STAS;
+ }
+ }
+ else
+ {
+ if (pAd->ApCfg.GreenAPLevel!=GREENAP_11BGN_STAS)
+ {
+ RTMP_CHIP_DISABLE_AP_MIMOPS(pAd);
+ pAd->ApCfg.GreenAPLevel=GREENAP_11BGN_STAS;
+ }
+ }
+ }
+#endif /* GREENAP_SUPPORT */
+
+ if (bRdgActive != RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE))
+ {
+ if (bRdgActive)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
+ AsicEnableRDG(pAd);
+ }
+ else
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
+ AsicDisableRDG(pAd);
+ }
+ }
+
+ if (bRalinkBurstMode != RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE))
+ {
+ if (bRalinkBurstMode)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE);
+ AsicEnableRalinkBurstMode(pAd);
+ }
+ else
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE);
+ AsicDisableRalinkBurstMode(pAd);
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+
+
+ if ((pMacTable->fAnyStationBadAtheros == FALSE) && (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == TRUE))
+ {
+ AsicUpdateProtect(pAd, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, pMacTable->fAnyStationNonGF);
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ /* 4. garbage collect pAd->MacTab.McastPsQueue if backlogged MCAST/BCAST frames */
+ /* stale in queue. Since MCAST/BCAST frames always been sent out whenever */
+ /* DtimCount==0, the only case to let them stale is surprise removal of the NIC, */
+ /* so that ASIC-based Tbcn interrupt stops and DtimCount dead. */
+ if (pMacTable->McastPsQueue.Head)
+ {
+ UINT bss_index;
+
+ pMacTable->PsQIdleCount ++;
+ if (pMacTable->PsQIdleCount > 1)
+ {
+
+ /*NdisAcquireSpinLock(&pAd->MacTabLock); */
+ APCleanupPsQueue(pAd, &pMacTable->McastPsQueue);
+ /*NdisReleaseSpinLock(&pAd->MacTabLock); */
+ pMacTable->PsQIdleCount = 0;
+
+ /* sanity check */
+ if (pAd->ApCfg.BssidNum > MAX_MBSSID_NUM(pAd))
+ pAd->ApCfg.BssidNum = MAX_MBSSID_NUM(pAd);
+ /* End of if */
+
+ /* clear MCAST/BCAST backlog bit for all BSS */
+ for(bss_index=BSS0; bss_index<pAd->ApCfg.BssidNum; bss_index++)
+ WLAN_MR_TIM_BCMC_CLEAR(bss_index);
+ /* End of for */
+ }
+ }
+ else
+ pMacTable->PsQIdleCount = 0;
+}
+
+
+UINT32 MacTableAssocStaNumGet(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 num = 0;
+ UINT32 i;
+
+
+ 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 (pEntry->Sst == SST_ASSOC)
+ num ++;
+ }
+
+ return num;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Look up a STA MAC table. Return its Sst to decide if an incoming
+ frame from this STA or an outgoing frame to this STA is permitted.
+ Return:
+ ==========================================================================
+*/
+MAC_TABLE_ENTRY *APSsPsInquiry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ OUT SST *Sst,
+ OUT USHORT *Aid,
+ OUT UCHAR *PsMode,
+ OUT UCHAR *Rate)
+{
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ if (MAC_ADDR_IS_GROUP(pAddr)) /* mcast & broadcast address */
+ {
+ *Sst = SST_ASSOC;
+ *Aid = MCAST_WCID; /* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */
+ *PsMode = PWR_ACTIVE;
+ *Rate = pAd->CommonCfg.MlmeRate;
+ }
+ else /* unicast address */
+ {
+ pEntry = MacTableLookup(pAd, pAddr);
+ if (pEntry)
+ {
+ *Sst = pEntry->Sst;
+ *Aid = pEntry->Aid;
+ *PsMode = pEntry->PsMode;
+ if ((pEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pEntry->GTKState != REKEY_ESTABLISHED))
+ *Rate = pAd->CommonCfg.MlmeRate;
+ else
+ *Rate = pEntry->CurrTxRate;
+ }
+ else
+ {
+ *Sst = SST_NOT_AUTH;
+ *Aid = MCAST_WCID;
+ *PsMode = PWR_ACTIVE;
+ *Rate = pAd->CommonCfg.MlmeRate;
+ }
+ }
+ return pEntry;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Update the station current power save mode. Calling this routine also
+ prove the specified client is still alive. Otherwise AP will age-out
+ this client once IdleCount exceeds a threshold.
+ ==========================================================================
+ */
+BOOLEAN APPsIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN ULONG Wcid,
+ IN UCHAR Psm)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR old_psmode;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ return PWR_ACTIVE;
+ }
+
+ pEntry = &pAd->MacTab.Content[Wcid];
+ old_psmode = pEntry->PsMode;
+/* if (pEntry) */
+ {
+ /*
+ Change power save mode first because we will call
+ RTMPDeQueuePacket() in APHandleRxPsPoll().
+
+ Or when Psm = PWR_ACTIVE, we will not do Aggregation in
+ RTMPDeQueuePacket().
+ */
+ pEntry->NoDataIdleCount = 0;
+ pEntry->PsMode = Psm;
+
+ if ((old_psmode == PWR_SAVE) && (Psm == PWR_ACTIVE))
+ {
+ /* TODO: For RT2870, how to handle about the BA when STA in PS mode???? */
+ DBGPRINT(RT_DEBUG_INFO, ("APPsIndicate - %02x:%02x:%02x:%02x:%02x:%02x wakes up, act like rx PS-POLL\n", pAddr[0],pAddr[1],pAddr[2],pAddr[3],pAddr[4],pAddr[5]));
+ /* sleep station awakes, move all pending frames from PSQ to TXQ if any */
+ APHandleRxPsPoll(pAd, pAddr, pEntry->Aid, TRUE);
+ }
+
+ /* move to above section */
+/* pEntry->NoDataIdleCount = 0; */
+/* pEntry->PsMode = Psm; */
+ }
+/* else */
+/* { */
+ /* not in table, try to learn it ???? why bother? */
+/* } */
+ return old_psmode;
+}
+
+#ifdef SYSTEM_LOG_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ This routine is called to log a specific event into the event table.
+ The table is a QUERY-n-CLEAR array that stop at full.
+ ==========================================================================
+ */
+VOID ApLogEvent(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN USHORT Event)
+{
+ if (pAd->EventTab.Num < MAX_NUM_OF_EVENT)
+ {
+ RT_802_11_EVENT_LOG *pLog = &pAd->EventTab.Log[pAd->EventTab.Num];
+ RTMP_GetCurrentSystemTime(&pLog->SystemTime);
+ COPY_MAC_ADDR(pLog->Addr, pAddr);
+ pLog->Event = Event;
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("LOG#%ld %02x:%02x:%02x:%02x:%02x:%02x %s\n",
+ pAd->EventTab.Num, pAddr[0], pAddr[1], pAddr[2],
+ pAddr[3], pAddr[4], pAddr[5], pEventText[Event]));
+ pAd->EventTab.Num += 1;
+ }
+}
+#endif /* SYSTEM_LOG_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Operationg mode is as defined at 802.11n for how proteciton in this BSS operates.
+ Ap broadcast the operation mode at Additional HT Infroamtion Element Operating Mode fields.
+ 802.11n D1.0 might has bugs so this operating mode use EWC MAC 1.24 definition first.
+
+ Called when receiving my bssid beacon or beaconAtJoin to update protection mode.
+ 40MHz or 20MHz protection mode in HT 40/20 capabale BSS.
+ As STA, this obeys the operation mode in ADDHT IE.
+ As AP, update protection when setting ADDHT IE and after new STA joined.
+ ==========================================================================
+*/
+VOID APUpdateOperationMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
+
+ if ((pAd->ApCfg.LastNoneHTOLBCDetectTime + (5 * OS_HZ)) > pAd->Mlme.Now32) /* non HT BSS exist within 5 sec */
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 1;
+ AsicUpdateProtect(pAd, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
+ }
+
+ /* If I am 40MHz BSS, and there exist HT-20MHz station. */
+ /* Update to 2 when it's zero. Because OperaionMode = 1 or 3 has more protection. */
+ if ((pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode == 0) && (pAd->MacTab.fAnyStation20Only) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == 1))
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 2;
+ AsicUpdateProtect(pAd, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode, (ALLN_SETPROTECT), TRUE, pAd->MacTab.fAnyStationNonGF);
+ }
+
+ if (pAd->MacTab.fAnyStationIsLegacy)
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 3;
+ AsicUpdateProtect(pAd, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode, (ALLN_SETPROTECT), TRUE, pAd->MacTab.fAnyStationNonGF);
+ }
+
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = pAd->MacTab.fAnyStationNonGF;
+}
+#endif /* DOT11_N_SUPPORT */
+
+/*
+ ==========================================================================
+ Description:
+ Update ERP IE and CapabilityInfo based on STA association status.
+ The result will be auto updated into the next outgoing BEACON in next
+ TBTT interrupt service routine
+ ==========================================================================
+ */
+VOID APUpdateCapabilityAndErpIe(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i, ErpIeContent = 0;
+ BOOLEAN ShortSlotCapable = pAd->CommonCfg.bUseShortSlotTime;
+ UCHAR apidx;
+ BOOLEAN bUseBGProtection;
+ BOOLEAN LegacyBssExist;
+
+
+ if (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+ return;
+
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (!IS_ENTRY_CLIENT(pEntry) || (pEntry->Sst != SST_ASSOC))
+ continue;
+
+ /* at least one 11b client associated, turn on ERP.NonERPPresent bit */
+ /* almost all 11b client won't support "Short Slot" time, turn off for maximum compatibility */
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ ShortSlotCapable = FALSE;
+ ErpIeContent |= 0x01;
+ }
+
+ /* at least one client can't support short slot */
+ if ((pEntry->CapabilityInfo & 0x0400) == 0)
+ ShortSlotCapable = FALSE;
+ }
+
+ /* legacy BSS exist within 5 sec */
+ if ((pAd->ApCfg.LastOLBCDetectTime + (5 * OS_HZ)) > pAd->Mlme.Now32)
+ {
+ LegacyBssExist = TRUE;
+ }
+ else
+ {
+ LegacyBssExist = FALSE;
+ }
+
+ /* decide ErpIR.UseProtection bit, depending on pAd->CommonCfg.UseBGProtection
+ AUTO (0): UseProtection = 1 if any 11b STA associated
+ ON (1): always USE protection
+ OFF (2): always NOT USE protection
+ */
+ if (pAd->CommonCfg.UseBGProtection == 0)
+ {
+ ErpIeContent = (ErpIeContent)? 0x03 : 0x00;
+ /*if ((pAd->ApCfg.LastOLBCDetectTime + (5 * OS_HZ)) > pAd->Mlme.Now32) // legacy BSS exist within 5 sec */
+ if (LegacyBssExist)
+ {
+ ErpIeContent |= 0x02; /* set Use_Protection bit */
+ }
+ }
+ else if (pAd->CommonCfg.UseBGProtection == 1)
+ ErpIeContent |= 0x02;
+ else
+ ;
+
+ bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || /* always use */
+ ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(ErpIeContent));
+
+#ifdef A_BAND_SUPPORT
+ /* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */
+ if (pAd->CommonCfg.Channel > 14)
+ bUseBGProtection = FALSE;
+#endif /* A_BAND_SUPPORT */
+
+ if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ USHORT OperationMode = 0;
+ BOOLEAN bNonGFExist = 0;
+
+#ifdef DOT11_N_SUPPORT
+ OperationMode = pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode;
+ bNonGFExist = pAd->MacTab.fAnyStationNonGF;
+#endif /* DOT11_N_SUPPORT */
+ if (bUseBGProtection)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+ AsicUpdateProtect(pAd, OperationMode, (OFDMSETPROTECT), FALSE, bNonGFExist);
+ }
+ else
+ {
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+ AsicUpdateProtect(pAd, OperationMode, (OFDMSETPROTECT), TRUE, bNonGFExist);
+ }
+ }
+
+ /* Decide Barker Preamble bit of ERP IE */
+ if ((pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong) || (ApCheckLongPreambleSTA(pAd) == TRUE))
+ pAd->ApCfg.ErpIeContent = (ErpIeContent | 0x04);
+ else
+ pAd->ApCfg.ErpIeContent = ErpIeContent;
+
+#ifdef A_BAND_SUPPORT
+ /* Force to use ShortSlotTime at A-band */
+ if (pAd->CommonCfg.Channel > 14)
+ ShortSlotCapable = TRUE;
+#endif /* A_BAND_SUPPORT */
+
+ /* deicide CapabilityInfo.ShortSlotTime bit */
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ USHORT *pCapInfo = &(pAd->ApCfg.MBSSID[apidx].CapabilityInfo);
+
+ /* In A-band, the ShortSlotTime bit should be ignored. */
+ if (ShortSlotCapable
+#ifdef A_BAND_SUPPORT
+ && (pAd->CommonCfg.Channel <= 14)
+#endif /* A_BAND_SUPPORT */
+ )
+ (*pCapInfo) |= 0x0400;
+ else
+ (*pCapInfo) &= 0xfbff;
+
+
+ if (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong)
+ (*pCapInfo) &= (~0x020);
+ else
+ (*pCapInfo) |= 0x020;
+
+ }
+
+ AsicSetSlotTime(pAd, ShortSlotCapable);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check to see the exist of long preamble STA in associated list
+ ==========================================================================
+ */
+BOOLEAN ApCheckLongPreambleSTA(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (!IS_ENTRY_CLIENT(pEntry) || (pEntry->Sst != SST_ASSOC))
+ continue;
+
+ if (!CAP_IS_SHORT_PREAMBLE_ON(pEntry->CapabilityInfo))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check if the specified STA pass the Access Control List checking.
+ If fails to pass the checking, then no authentication nor association
+ is allowed
+ Return:
+ MLME_SUCCESS - this STA passes ACL checking
+
+ ==========================================================================
+*/
+BOOLEAN ApCheckAccessControlList(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR Apidx)
+{
+ BOOLEAN Result = TRUE;
+
+ if (pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy == 0) /* ACL is disabled */
+ Result = TRUE;
+ else
+ {
+ ULONG i;
+ if (pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy == 1) /* ACL is a positive list */
+ Result = FALSE;
+ else /* ACL is a negative list */
+ Result = TRUE;
+ for (i=0; i<pAd->ApCfg.MBSSID[Apidx].AccessControlList.Num; i++)
+ {
+ if (MAC_ADDR_EQUAL(pAddr, pAd->ApCfg.MBSSID[Apidx].AccessControlList.Entry[i].Addr))
+ {
+ Result = !Result;
+ break;
+ }
+ }
+ }
+
+ if (Result == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x failed in ACL checking\n",
+ pAddr[0],pAddr[1],pAddr[2],pAddr[3],pAddr[4],pAddr[5]));
+ }
+
+ return Result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine update the current MAC table based on the current ACL.
+ If ACL change causing an associated STA become un-authorized. This STA
+ will be kicked out immediately.
+ ==========================================================================
+*/
+VOID ApUpdateAccessControlList(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Apidx)
+{
+ USHORT AclIdx, MacIdx;
+ BOOLEAN Matched;
+
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ HEADER_802_11 DisassocHdr;
+ USHORT Reason;
+
+
+ /*Apidx = pObj->ioctl_if; */
+ ASSERT(Apidx < MAX_MBSSID_NUM(pAd));
+ if (Apidx >= MAX_MBSSID_NUM(pAd))
+ return;
+ DBGPRINT(RT_DEBUG_TRACE, ("ApUpdateAccessControlList : Apidx = %d\n", Apidx));
+
+ /* ACL is disabled. Do nothing about the MAC table. */
+ if (pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy == 0)
+ return;
+
+ for (MacIdx=0; MacIdx < MAX_LEN_OF_MAC_TABLE; MacIdx++)
+ {
+ if (!IS_ENTRY_CLIENT(&pAd->MacTab.Content[MacIdx]))
+ continue;
+
+ /* We only need to update associations related to ACL of MBSSID[Apidx]. */
+ if (pAd->MacTab.Content[MacIdx].apidx != Apidx)
+ continue;
+
+ Matched = FALSE;
+ for (AclIdx = 0; AclIdx < pAd->ApCfg.MBSSID[Apidx].AccessControlList.Num; AclIdx++)
+ {
+ if (MAC_ADDR_EQUAL(&pAd->MacTab.Content[MacIdx].Addr, pAd->ApCfg.MBSSID[Apidx].AccessControlList.Entry[AclIdx].Addr))
+ {
+ Matched = TRUE;
+ break;
+ }
+ }
+
+ if ((Matched == FALSE) && (pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy == 1))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Apidx = %d\n", Apidx));
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->ApCfg.MBSSID[%d].AccessControlList.Policy = %ld\n", Apidx,
+ pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy));
+ DBGPRINT(RT_DEBUG_TRACE, ("STA not on positive ACL. remove it...\n"));
+
+ /* Before delete the entry from MacTable, send disassociation packet to client. */
+ if (pAd->MacTab.Content[MacIdx].Sst == SST_ASSOC)
+ {
+ /* send out a DISASSOC frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n"));
+ return;
+ }
+
+ Reason = REASON_DECLINED;
+ DBGPRINT(RT_DEBUG_ERROR, ("ASSOC - Send DISASSOC Reason = %d frame TO %x %x %x %x %x %x \n",Reason,pAd->MacTab.Content[MacIdx].Addr[0],
+ pAd->MacTab.Content[MacIdx].Addr[1],pAd->MacTab.Content[MacIdx].Addr[2],pAd->MacTab.Content[MacIdx].Addr[3],pAd->MacTab.Content[MacIdx].Addr[4],pAd->MacTab.Content[MacIdx].Addr[5]));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAd->MacTab.Content[MacIdx].Addr,
+ pAd->ApCfg.MBSSID[pAd->MacTab.Content[MacIdx].apidx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DisassocHdr, 2, &Reason, END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPusecDelay(5000);
+ }
+ MacTableDeleteEntry(pAd, pAd->MacTab.Content[MacIdx].Aid, pAd->MacTab.Content[MacIdx].Addr);
+ }
+ else if ((Matched == TRUE) && (pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy == 2))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Apidx = %d\n", Apidx));
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->ApCfg.MBSSID[%d].AccessControlList.Policy = %ld\n", Apidx,
+ pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy));
+ DBGPRINT(RT_DEBUG_TRACE, ("STA on negative ACL. remove it...\n"));
+
+ /* Before delete the entry from MacTable, send disassociation packet to client. */
+ if (pAd->MacTab.Content[MacIdx].Sst == SST_ASSOC)
+ {
+ /* send out a DISASSOC frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n"));
+ return;
+ }
+
+ Reason = REASON_DECLINED;
+ DBGPRINT(RT_DEBUG_ERROR, ("ASSOC - Send DISASSOC Reason = %d frame TO %x %x %x %x %x %x \n",Reason,pAd->MacTab.Content[MacIdx].Addr[0],
+ pAd->MacTab.Content[MacIdx].Addr[1],pAd->MacTab.Content[MacIdx].Addr[2],pAd->MacTab.Content[MacIdx].Addr[3],pAd->MacTab.Content[MacIdx].Addr[4],pAd->MacTab.Content[MacIdx].Addr[5]));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAd->MacTab.Content[MacIdx].Addr,
+ pAd->ApCfg.MBSSID[pAd->MacTab.Content[MacIdx].apidx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DisassocHdr, 2, &Reason, END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPusecDelay(5000);
+ }
+ MacTableDeleteEntry(pAd, pAd->MacTab.Content[MacIdx].Aid, pAd->MacTab.Content[MacIdx].Addr);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Send out a NULL frame to a specified STA at a higher TX rate. The
+ purpose is to ensure the designated client is okay to received at this
+ rate.
+ ==========================================================================
+ */
+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)
+{
+ NDIS_STATUS NState;
+ PHEADER_802_11 pNullFr;
+ PUCHAR pFrame;
+ ULONG Length;
+
+
+ /* since TxRate may change, we have to change Duration each time */
+ NState = MlmeAllocateMemory(pAd, (PUCHAR *)&pFrame);
+ pNullFr = (PHEADER_802_11) pFrame;
+ Length = sizeof(HEADER_802_11);
+
+ if (NState == NDIS_STATUS_SUCCESS)
+ {
+/* if ((PID & 0x3f) < WDS_PAIRWISE_KEY_OFFSET) // send to client */
+ {
+ MgtMacHeaderInit(pAd, pNullFr, SUBTYPE_NULL_FUNC, 0, pAddr,
+ pAd->ApCfg.MBSSID[apidx].Bssid);
+ pNullFr->FC.Type = BTYPE_DATA;
+ pNullFr->FC.FrDs = 1;
+ pNullFr->Duration = RTMPCalcDuration(pAd, TxRate, 14);
+
+#ifdef UAPSD_SUPPORT
+ if (bQosNull)
+ {
+ UCHAR *qos_p = ((UCHAR *)pNullFr) + Length;
+
+ pNullFr->FC.SubType = SUBTYPE_QOS_NULL;
+
+ /* copy QOS control bytes */
+ qos_p[0] = ((bEOSP) ? (1 << 4) : 0) | OldUP;
+ qos_p[1] = 0;
+ Length += 2;
+ } /* End of if */
+#endif /* UAPSD_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_INFO, ("send NULL Frame @%d Mbps to AID#%d...\n", RateIdToMbps[TxRate], PID & 0x3f));
+ MiniportMMRequest(pAd, MapUserPriorityToAccessCategory[7], (PUCHAR)pNullFr, Length);
+ }
+
+ MlmeFreeMemory(pAd, pFrame);
+ }
+}
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+/*
+ Depends on the 802.11n Draft 4.0, Before the HT AP start a BSS, it should scan some specific channels to
+collect information of existing BSSs, then depens on the collected channel information, adjust the primary channel
+and secondary channel setting.
+
+ For 5GHz,
+ Rule 1: If the AP chooses to start a 20/40 MHz BSS in 5GHz and that occupies the same two channels
+ as any existing 20/40 MHz BSSs, then the AP shall ensure that the primary channel of the
+ new BSS is identical to the primary channel of the existing 20/40 MHz BSSs and that the
+ secondary channel of the new 20/40 MHz BSS is identical to the secondary channel of the
+ existing 20/40 MHz BSSs, unless the AP discoverr that on those two channels are existing
+ 20/40 MHz BSSs with different primary and secondary channels.
+ Rule 2: If the AP chooses to start a 20/40MHz BSS in 5GHz, the selected secondary channel should
+ correspond to a channel on which no beacons are detected during the overlapping BSS
+ scan time performed by the AP, unless there are beacons detected on both the selected
+ primary and secondary channels.
+ Rule 3: An HT AP should not start a 20 MHz BSS in 5GHz on a channel that is the secondary channel
+ of a 20/40 MHz BSS.
+ For 2.4GHz,
+ Rule 1: The AP shall not start a 20/40 MHz BSS in 2.4GHz if the value of the local variable "20/40
+ Operation Permitted" is FALSE.
+
+ 20/40OperationPermitted = (P == OPi for all values of i) AND
+ (P == OTi for all values of i) AND
+ (S == OSi for all values if i)
+ where
+ P is the operating or intended primary channel of the 20/40 MHz BSS
+ S is the operating or intended secondary channel of the 20/40 MHz BSS
+ OPi is member i of the set of channels that are members of the channel set C and that are the
+ primary operating channel of at least one 20/40 MHz BSS that is detected within the AP's
+ BSA during the previous X seconds
+ OSi is member i of the set of channels that are members of the channel set C and that are the
+ secondary operating channel of at least one 20/40 MHz BSS that is detected within AP's
+ BSA during the previous X seconds
+ OTi is member i of the set of channels that comparises all channels that are members of the
+ channel set C that were listed once in the Channel List fields of 20/40 BSS Intolerant Channel
+ Report elements receved during the previous X seconds and all channels that are members
+ of the channel set C and that are the primary operating channel of at least one 20/40 MHz
+ BSS that were detected within the AP's BSA during the previous X seconds.
+ C is the set of all channels that are allowed operating channels within the current operational
+ regulatory domain and whose center frequency falls within the 40 MHz affected channel
+ range given by following equation:
+ Fp + Fs Fp + Fs
+ 40MHz affected channel range = [ ------ - 25MHz, ------- + 25MHz ]
+ 2 2
+ Where
+ Fp = the center frequency of channel P
+ Fs = the center frequency of channel S
+
+ "==" means that the values on either side of the "==" are to be tested for equaliy with a resulting
+ Boolean value.
+ =>When the value of OPi is the empty set, then the expression (P == OPi for all values of i)
+ is defined to be TRUE
+ =>When the value of OTi is the empty set, then the expression (P == OTi for all values of i)
+ is defined to be TRUE
+ =>When the value of OSi is the empty set, then the expression (S == OSi for all values of i)
+ is defined to be TRUE
+*/
+
+
+INT GetBssCoexEffectedChRange(
+ IN RTMP_ADAPTER *pAd,
+ IN BSS_COEX_CH_RANGE *pCoexChRange)
+{
+ INT index, cntrCh = 0;
+
+ memset(pCoexChRange, 0, sizeof(BSS_COEX_CH_RANGE));
+
+ /* Build the effected channel list, if something wrong, return directly. */
+#ifdef A_BAND_SUPPORT
+ if (pAd->CommonCfg.Channel > 14)
+ { /* For 5GHz band */
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ {
+ if(pAd->ChannelList[index].Channel == pAd->CommonCfg.Channel)
+ break;
+ }
+
+ if (index < pAd->ChannelListNum)
+ {
+ /* First get the primary channel */
+ pCoexChRange->primaryCh = pAd->ChannelList[index].Channel;
+
+ /* Now check about the secondary and central channel */
+ if(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ pCoexChRange->effectChStart = pCoexChRange->primaryCh;
+ pCoexChRange->effectChEnd = pCoexChRange->primaryCh + 4;
+ pCoexChRange->secondaryCh = pCoexChRange->effectChEnd;
+ }
+ else
+ {
+ pCoexChRange->effectChStart = pCoexChRange->primaryCh -4;
+ pCoexChRange->effectChEnd = pCoexChRange->primaryCh;
+ pCoexChRange->secondaryCh = pCoexChRange->effectChStart;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("5.0GHz: Found CtrlCh idx(%d) from the ChList, ExtCh=%s, PriCh=[Idx:%d, CH:%d], SecCh=[Idx:%d, CH:%d], effected Ch=[CH:%d~CH:%d]!\n",
+ index,
+ ((pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) ? "ABOVE" : "BELOW"),
+ pCoexChRange->primaryCh, pAd->ChannelList[pCoexChRange->primaryCh].Channel,
+ pCoexChRange->secondaryCh, pAd->ChannelList[pCoexChRange->secondaryCh].Channel,
+ pAd->ChannelList[pCoexChRange->effectChStart].Channel,
+ pAd->ChannelList[pCoexChRange->effectChEnd].Channel));
+ return TRUE;
+ }
+ else
+ {
+ /* It should not happened! */
+ DBGPRINT(RT_DEBUG_ERROR, ("5GHz: Cannot found the CtrlCh(%d) in ChList, something wrong?\n",
+ pAd->CommonCfg.Channel));
+ }
+ }
+ else
+#endif /* A_BAND_SUPPORT */
+ { /* For 2.4GHz band */
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ {
+ if(pAd->ChannelList[index].Channel == pAd->CommonCfg.Channel)
+ break;
+ }
+
+ if (index < pAd->ChannelListNum)
+ {
+ /* First get the primary channel */
+ pCoexChRange->primaryCh = index;
+
+ /* Now check about the secondary and central channel */
+ if(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ if ((index + 4) < pAd->ChannelListNum)
+ {
+ cntrCh = index + 2;
+ pCoexChRange->secondaryCh = index + 4;
+ }
+ }
+ else
+ {
+ if ((index - 4) >=0)
+ {
+ cntrCh = index - 2;
+ pCoexChRange->secondaryCh = index - 4;
+ }
+ }
+
+ if (cntrCh)
+ {
+ pCoexChRange->effectChStart = (cntrCh - 5) > 0 ? (cntrCh - 5) : 0;
+ pCoexChRange->effectChEnd= (cntrCh + 5) > 0 ? (cntrCh + 5) : 0;
+ DBGPRINT(RT_DEBUG_TRACE,("2.4GHz: Found CtrlCh idx(%d) from the ChList, ExtCh=%s, PrimaryCh=[Idx:%d, CH:%d], SecondaryCh=[Idx:%d, CH:%d], effected Ch=[CH:%d~CH:%d]!\n",
+ index,
+ ((pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) ? "ABOVE" : "BELOW"),
+ pCoexChRange->primaryCh, pAd->ChannelList[pCoexChRange->primaryCh].Channel,
+ pCoexChRange->secondaryCh, pAd->ChannelList[pCoexChRange->secondaryCh].Channel,
+ pAd->ChannelList[pCoexChRange->effectChStart].Channel,
+ pAd->ChannelList[pCoexChRange->effectChEnd].Channel));
+ }
+ return TRUE;
+ }
+
+ /* It should not happened! */
+ DBGPRINT(RT_DEBUG_ERROR, ("2.4GHz: Didn't found valid channel range, Ch index=%d, ChListNum=%d, CtrlCh=%d\n",
+ index, pAd->ChannelListNum, pAd->CommonCfg.Channel));
+ }
+
+ return FALSE;
+}
+
+
+VOID APOverlappingBSSScan(
+ IN RTMP_ADAPTER *pAd)
+{
+ BOOLEAN needFallBack = FALSE;
+ UCHAR Channel = pAd->CommonCfg.Channel;
+ INT chStartIdx, chEndIdx, index,curPriChIdx, curSecChIdx;
+
+
+ /* We just care BSS who operating in 40MHz N Mode. */
+ if ((!WMODE_CAP_N(pAd->CommonCfg.PhyMode)) ||
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_20)
+ || (pAd->CommonCfg.Channel > 14)
+ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The pAd->PhyMode=%d, BW=%d, didn't need channel adjustment!\n",
+ pAd->CommonCfg.PhyMode, pAd->CommonCfg.RegTransmitSetting.field.BW));
+ return;
+ }
+
+ /* Build the effected channel list, if something wrong, return directly. */
+#ifdef A_BAND_SUPPORT
+ if (pAd->CommonCfg.Channel > 14)
+ { /* For 5GHz band */
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ {
+ if(pAd->ChannelList[index].Channel == pAd->CommonCfg.Channel)
+ break;
+ }
+
+ if (index < pAd->ChannelListNum)
+ {
+ curPriChIdx = index;
+ if(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ chStartIdx = index;
+ chEndIdx = chStartIdx + 1;
+ curSecChIdx = chEndIdx;
+ }
+ else
+ {
+ chStartIdx = index - 1;
+ chEndIdx = index;
+ curSecChIdx = chStartIdx;
+ }
+ }
+ else
+ {
+ /* It should not happened! */
+ DBGPRINT(RT_DEBUG_ERROR, ("5GHz: Cannot found the ControlChannel(%d) in ChannelList, something wrong?\n",
+ pAd->CommonCfg.Channel));
+ return;
+ }
+ }
+ else
+#endif /* A_BAND_SUPPORT */
+ { /* For 2.4GHz band */
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ {
+ if(pAd->ChannelList[index].Channel == pAd->CommonCfg.Channel)
+ break;
+ }
+
+ if (index < pAd->ChannelListNum)
+ {
+
+ if(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ curPriChIdx = index;
+ curSecChIdx = ((index + 4) < pAd->ChannelListNum) ? (index + 4) : (pAd->ChannelListNum - 1);
+
+ chStartIdx = (curPriChIdx >= 3) ? (curPriChIdx - 3) : 0;
+ chEndIdx = ((curSecChIdx + 3) < pAd->ChannelListNum) ? (curSecChIdx + 3) : (pAd->ChannelListNum - 1);
+ }
+ else
+ {
+ curPriChIdx = index;
+ curSecChIdx = ((index - 4) >=0 ) ? (index - 4) : 0;
+ chStartIdx =(curSecChIdx >= 3) ? (curSecChIdx - 3) : 0;
+ chEndIdx = ((curPriChIdx + 3) < pAd->ChannelListNum) ? (curPriChIdx + 3) : (pAd->ChannelListNum - 1);;
+ }
+ }
+ else
+ {
+ /* It should not happened! */
+ DBGPRINT(RT_DEBUG_ERROR, ("2.4GHz: Cannot found the Control Channel(%d) in ChannelList, something wrong?\n",
+ pAd->CommonCfg.Channel));
+ return;
+ }
+ }
+
+{
+ BSS_COEX_CH_RANGE coexChRange;
+ GetBssCoexEffectedChRange(pAd, &coexChRange);
+}
+
+ /* Before we do the scanning, clear the bEffectedChannel as zero for latter use. */
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ pAd->ChannelList[index].bEffectedChannel = 0;
+
+ pAd->CommonCfg.BssCoexApCnt = 0;
+
+ /* If we are not ready for Tx/Rx Pakcet, enable it now for receiving Beacons. */
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP) == 0)
+ {
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Card still not enable Tx/Rx, enable it now!\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; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
+ {
+ RTUSBBulkReceive(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
+ }
+#endif /* RTMP_MAC_USB */
+
+ /* Now Enable RxTx */
+ RTMPEnableRxTx(pAd);
+
+ /* APRxDoneInterruptHandle API will check this flag to decide accept incoming packet or not. */
+ /* Set the flag be ready to receive Beacon frame for autochannel select. */
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Ready to do passive scanning for Channel[%d] to Channel[%d]!\n",
+ pAd->ChannelList[chStartIdx].Channel, pAd->ChannelList[chEndIdx].Channel));
+
+ /* Now start to do the passive scanning. */
+ pAd->CommonCfg.bOverlapScanning = TRUE;
+ for (index = chStartIdx; index<=chEndIdx; index++)
+ {
+ Channel = pAd->ChannelList[index].Channel;
+
+ AsicSetChannel(pAd, Channel, BW_20, EXTCHA_NONE, TRUE);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("SYNC - BBP R4 to 20MHz.l\n"));
+ /*DBGPRINT(RT_DEBUG_TRACE, ("Passive scanning for Channel %d.....\n", Channel)); */
+ OS_WAIT(300); /* wait for 200 ms at each channel. */
+ }
+ pAd->CommonCfg.bOverlapScanning = FALSE;
+
+
+ /* After scan all relate channels, now check the scan result to find out if we need fallback to 20MHz. */
+ for (index = chStartIdx; index <= chEndIdx; index++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel[Idx=%d, Ch=%d].bEffectedChannel=0x%x!\n",
+ index, pAd->ChannelList[index].Channel, pAd->ChannelList[index].bEffectedChannel));
+ if ((pAd->ChannelList[index].bEffectedChannel & (EFFECTED_CH_PRIMARY | EFFECTED_CH_LEGACY)) && (index != curPriChIdx) )
+ {
+ needFallBack = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("needFallBack=TRUE due to OP/OT!\n"));
+ }
+ if ((pAd->ChannelList[index].bEffectedChannel & EFFECTED_CH_SECONDARY) && (index != curSecChIdx))
+ {
+ needFallBack = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("needFallBack=TRUE due to OS!\n"));
+ }
+ }
+
+ /* If need fallback, now do it. */
+ if ((needFallBack == TRUE)
+ && (pAd->CommonCfg.BssCoexApCnt > pAd->CommonCfg.BssCoexApCntThr)
+ )
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
+ pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq = 1;
+ pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC;
+ }
+
+ return;
+}
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT1X_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ Send Leyer 2 Frame to notify 802.1x daemon. This is a internal command
+
+ Arguments:
+
+ Return Value:
+ TRUE - send successfully
+ FAIL - send fail
+
+ Note:
+ ========================================================================
+*/
+BOOLEAN DOT1X_InternalCmdAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UINT8 cmd)
+{
+ INT apidx = MAIN_MBSSID;
+ UCHAR RalinkIe[9] = {221, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00};
+ UCHAR s_addr[MAC_ADDR_LEN];
+ UCHAR EAPOL_IE[] = {0x88, 0x8e};
+ UINT8 frame_len = LENGTH_802_3 + sizeof(RalinkIe);
+ UCHAR FrameBuf[frame_len];
+ UINT8 offset = 0;
+
+ /* Init the frame buffer */
+ NdisZeroMemory(FrameBuf, frame_len);
+
+ if (pEntry)
+ {
+ apidx = pEntry->apidx;
+ NdisMoveMemory(s_addr, pEntry->Addr, MAC_ADDR_LEN);
+ }
+ else
+ {
+ /* Fake a Source Address for transmission */
+ NdisMoveMemory(s_addr, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LENGTH);
+ s_addr[0] |= 0x80;
+ }
+
+ /* Assign internal command for Ralink dot1x daemon */
+ RalinkIe[5] = cmd;
+
+ /* Prepare the 802.3 header */
+ MAKE_802_3_HEADER(FrameBuf,
+ pAd->ApCfg.MBSSID[apidx].Bssid,
+ s_addr,
+ EAPOL_IE);
+ offset += LENGTH_802_3;
+
+ /* Prepare the specific header of internal command */
+ NdisMoveMemory(&FrameBuf[offset], RalinkIe, sizeof(RalinkIe));
+
+ /* Report to upper layer */
+ if (RTMP_L2_FRAME_TX_ACTION(pAd, apidx, FrameBuf, frame_len) == FALSE)
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s done. (cmd=%d)\n", __FUNCTION__, cmd));
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Send Leyer 2 Frame to trigger 802.1x EAP state machine.
+
+ Arguments:
+
+ Return Value:
+ TRUE - send successfully
+ FAIL - send fail
+
+ Note:
+ ========================================================================
+*/
+BOOLEAN DOT1X_EapTriggerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ INT apidx = MAIN_MBSSID;
+ UCHAR eapol_start_1x_hdr[4] = {0x01, 0x01, 0x00, 0x00};
+ UINT8 frame_len = LENGTH_802_3 + sizeof(eapol_start_1x_hdr);
+ UCHAR FrameBuf[frame_len];
+ UINT8 offset = 0;
+
+ if((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pAd->ApCfg.MBSSID[apidx].IEEE8021X == TRUE))
+ {
+ /* Init the frame buffer */
+ NdisZeroMemory(FrameBuf, frame_len);
+
+ /* Assign apidx */
+ apidx = pEntry->apidx;
+
+ /* Prepare the 802.3 header */
+ MAKE_802_3_HEADER(FrameBuf, pAd->ApCfg.MBSSID[apidx].Bssid, pEntry->Addr, EAPOL);
+ offset += LENGTH_802_3;
+
+ /* Prepare a fake eapol-start body */
+ NdisMoveMemory(&FrameBuf[offset], eapol_start_1x_hdr, sizeof(eapol_start_1x_hdr));
+
+ /* Report to upper layer */
+ if (RTMP_L2_FRAME_TX_ACTION(pAd, apidx, FrameBuf, frame_len) == FALSE)
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Notify 8021.x daemon to trigger EAP-SM for this sta(%02x:%02x:%02x:%02x:%02x:%02x)\n", PRINT_MAC(pEntry->Addr)));
+
+ }
+
+ return TRUE;
+}
+
+#endif /* DOT1X_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_apcli.c b/cleopatre/devkit/mt7601udrv/ap/ap_apcli.c
new file mode 100644
index 0000000000..c145bc18bd
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_apcli.c
@@ -0,0 +1,2230 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_apcli.c
+
+ Abstract:
+ Support AP-Client function.
+
+ Note:
+ 1. Call RT28xx_ApCli_Init() in init function and
+ call RT28xx_ApCli_Remove() in close function
+
+ 2. MAC of ApCli-interface is initialized in RT28xx_ApCli_Init()
+
+ 3. ApCli index (0) of different rx packet is got in
+ APHandleRxDoneInterrupt() by using FromWhichBSSID = pEntry->apidx;
+ Or FromWhichBSSID = BSS0;
+
+ 4. ApCli index (0) of different tx packet is assigned in
+ MBSS_VirtualIF_PacketSend() by using RTMP_SET_PACKET_NET_DEVICE_MBSSID()
+ 5. ApCli index (0) of different interface is got in APHardTransmit() by using
+ RTMP_GET_PACKET_IF()
+
+ 6. ApCli index (0) of IOCTL command is put in pAd->OS_Cookie->ioctl_if
+
+ 8. The number of ApCli only can be 1
+
+ 9. apcli convert engine subroutines, we should just take care data packet.
+ Revision History:
+ Who When What
+ -------------- ---------- ----------------------------------------------
+ Shiang, Fonchi 02-13-2007 created
+*/
+
+#ifdef APCLI_SUPPORT
+
+#include "rt_config.h"
+
+
+
+/* --------------------------------- Public -------------------------------- */
+/*
+========================================================================
+Routine Description:
+ Close ApCli network interface.
+
+Arguments:
+ ad_p points to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28xx_ApCli_Close(
+ IN PRTMP_ADAPTER ad_p)
+{
+ UINT index;
+
+
+ for(index = 0; index < MAX_APCLI_NUM; index++)
+ {
+ if (ad_p->ApCfg.ApCliTab[index].dev)
+ RtmpOSNetDevClose(ad_p->ApCfg.ApCliTab[index].dev);
+ }
+
+}
+
+
+
+
+/* --------------------------------- Private -------------------------------- */
+INT ApCliIfLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr)
+{
+ SHORT i;
+ SHORT ifIndex = -1;
+
+ do
+ {
+ for(i = 0; i < MAX_APCLI_NUM; i++)
+ {
+ if( MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[i].CurrentAddress, pAddr))
+ {
+ ifIndex = i;
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCliIfIndex = %d\n", __FUNCTION__, ifIndex));
+ break;
+ }
+ }
+ } while (FALSE);
+
+ return ifIndex;
+}
+
+BOOLEAN isValidApCliIf(
+ SHORT ifIndex)
+{
+ if((ifIndex >= 0) && (ifIndex < MAX_APCLI_NUM))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*! \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->UserCfg
+ * - bssid
+ * - station address
+ * \post
+ * \note this function initializes the following field
+ */
+VOID ApCliMgtMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid,
+ IN USHORT ifIndex)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SubType;
+ pHdr80211->FC.ToDs = ToDs;
+ COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->ApCfg.ApCliTab[ifIndex].CurrentAddress);
+ COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
+}
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ========================================================================
+
+ 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 ApCliCheckHt(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT IfIndex,
+ INOUT HT_CAPABILITY_IE *pHtCapability,
+ INOUT ADD_HT_INFO_IE *pAddHtInfo)
+{
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ HT_CAPABILITY_IE *aux_ht_cap;
+ RT_HT_CAPABILITY *rt_ht_cap = &pAd->CommonCfg.DesiredHtPhy;
+
+ if (IfIndex >= MAX_APCLI_NUM)
+ return FALSE;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[IfIndex];
+
+ /* If use AMSDU, set flag. */
+ if (rt_ht_cap->AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pApCliEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ /* Save Peer Capability */
+ if (pHtCapability->HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pApCliEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pHtCapability->HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pApCliEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pHtCapability->HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pApCliEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pHtCapability->HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pApCliEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pApCliEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ pApCliEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+
+
+ aux_ht_cap = &pAd->ApCliMlmeAux.HtCapability;
+ aux_ht_cap->MCSSet[0] = 0xff;
+ aux_ht_cap->MCSSet[4] = 0x1;
+ switch (pAd->CommonCfg.RxStream)
+ {
+ case 1:
+ aux_ht_cap->MCSSet[0] = 0xff;
+ aux_ht_cap->MCSSet[1] = 0x00;
+ aux_ht_cap->MCSSet[2] = 0x00;
+ aux_ht_cap->MCSSet[3] = 0x00;
+ break;
+ case 2:
+ aux_ht_cap->MCSSet[0] = 0xff;
+ aux_ht_cap->MCSSet[1] = 0xff;
+ aux_ht_cap->MCSSet[2] = 0x00;
+ aux_ht_cap->MCSSet[3] = 0x00;
+ break;
+ case 3:
+ aux_ht_cap->MCSSet[0] = 0xff;
+ aux_ht_cap->MCSSet[1] = 0xff;
+ aux_ht_cap->MCSSet[2] = 0xff;
+ aux_ht_cap->MCSSet[3] = 0x00;
+ break;
+ }
+
+ /* Record the RxMcs of AP */
+ NdisMoveMemory(pApCliEntry->RxMcsSet, pHtCapability->MCSSet, 16);
+
+
+
+ /* choose smaller setting */
+ aux_ht_cap->HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & rt_ht_cap->ChannelWidth;
+ aux_ht_cap->HtCapInfo.GF = pHtCapability->HtCapInfo.GF & rt_ht_cap->GF;
+
+ /* Send Assoc Req with my HT capability. */
+ aux_ht_cap->HtCapInfo.AMsduSize = rt_ht_cap->AmsduSize;
+ aux_ht_cap->HtCapInfo.MimoPs = pHtCapability->HtCapInfo.MimoPs;
+ aux_ht_cap->HtCapInfo.ShortGIfor20 = (rt_ht_cap->ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
+ aux_ht_cap->HtCapInfo.ShortGIfor40 = (rt_ht_cap->ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
+ aux_ht_cap->HtCapInfo.TxSTBC = (rt_ht_cap->TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
+ aux_ht_cap->HtCapInfo.RxSTBC = (rt_ht_cap->RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
+ aux_ht_cap->HtCapParm.MaxRAmpduFactor = rt_ht_cap->MaxRAmpduFactor;
+ aux_ht_cap->HtCapParm.MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+ aux_ht_cap->ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
+ if (pAd->CommonCfg.bRdg)
+ {
+ aux_ht_cap->ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
+ }
+
+ /*COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability); */
+ return TRUE;
+}
+#endif /* DOT11_N_SUPPORT */
+
+/*
+ ==========================================================================
+
+ Routine Description:
+ Connected to the BSSID
+
+ Arguments:
+ pAd - Pointer to our adapter
+ ApCliIdx - Which ApCli interface
+ Return Value:
+ FALSE: fail to alloc Mac entry.
+
+ Note:
+
+ ==========================================================================
+*/
+BOOLEAN ApCliLinkUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ifIndex)
+{
+ BOOLEAN result = FALSE;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+ APCLI_STRUCT *wdev = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ do
+ {
+ if (ifIndex < MAX_APCLI_NUM)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! APCLI LINK UP - IF(apcli%d) AuthMode(%d)=%s, WepStatus(%d)=%s !!!\n",
+ ifIndex,
+ wdev->AuthMode, GetAuthMode(wdev->AuthMode),
+ wdev->WepStatus, GetEncryptType(wdev->WepStatus)));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!! ERROR : APCLI LINK UP - IF(apcli%d)!!!\n", ifIndex));
+ result = FALSE;
+ break;
+ }
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ /* Sanity check: This link had existed. */
+ if (pApCliEntry->Valid)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!! ERROR : This link had existed - IF(apcli%d)!!!\n", ifIndex));
+ result = FALSE;
+ break;
+ }
+
+ /* Insert the Remote AP to our MacTable. */
+ /*pMacEntry = MacTableInsertApCliEntry(pAd, (PUCHAR)(pAd->ApCliMlmeAux.Bssid)); */
+ pMacEntry = MacTableInsertEntry(pAd, (PUCHAR)(pAd->ApCliMlmeAux.Bssid), (ifIndex + MIN_NET_DEVICE_FOR_APCLI), OPMODE_AP, TRUE);
+ if (pMacEntry)
+ {
+ UCHAR Rates[MAX_LEN_OF_SUPPORTED_RATES];
+ PUCHAR pRates = Rates;
+ UCHAR RatesLen;
+ UCHAR MaxSupportedRate = 0;
+
+ pMacEntry->Sst = SST_ASSOC;
+
+ pApCliEntry->Valid = TRUE;
+ pApCliEntry->MacTabWCID = pMacEntry->Aid;
+
+ COPY_MAC_ADDR(APCLI_ROOT_BSSID_GET(pAd, pApCliEntry->MacTabWCID), pAd->ApCliMlmeAux.Bssid);
+ pApCliEntry->SsidLen = pAd->ApCliMlmeAux.SsidLen;
+ NdisMoveMemory(pApCliEntry->Ssid, pAd->ApCliMlmeAux.Ssid, pApCliEntry->SsidLen);
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ /*
+ If ApCli connects to different AP, ApCli couldn't send EAPOL_Start for WpaSupplicant.
+ */
+ if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) &&
+ (NdisEqualMemory(pAd->MlmeAux.Bssid, pApCliEntry->LastBssid, MAC_ADDR_LEN) == FALSE) &&
+ (pApCliEntry->bLostAp == TRUE))
+ {
+ pApCliEntry->bLostAp = FALSE;
+ }
+
+ COPY_MAC_ADDR(pApCliEntry->LastBssid, pAd->MlmeAux.Bssid);
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+
+ if (pMacEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ pMacEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+ {
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pApCliEntry->WpaSupplicantUP &&
+ (pMacEntry->WepStatus == Ndis802_11WEPEnabled) &&
+ (pApCliEntry->IEEE8021X == TRUE))
+ pMacEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+ pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ }
+ NdisGetSystemUpTime(&pApCliEntry->ApCliLinkUpTime);
+ /* Store appropriate RSN_IE for WPA SM negotiation later */
+ /* If WPAPSK/WPA2SPK mix mode, driver just stores either WPAPSK or WPA2PSK */
+ /* RSNIE. It depends on the AP-Client's authentication mode to store the corresponding RSNIE. */
+ if ((pMacEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ApCliMlmeAux.VarIELen != 0))
+ {
+ PUCHAR pVIE;
+ UCHAR len;
+ PEID_STRUCT pEid;
+
+ pVIE = pAd->ApCliMlmeAux.VarIEs;
+ len = pAd->ApCliMlmeAux.VarIELen;
+
+ while (len > 0)
+ {
+ pEid = (PEID_STRUCT) pVIE;
+ /* For WPA/WPAPSK */
+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+ && (pMacEntry->AuthMode == Ndis802_11AuthModeWPA || pMacEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ NdisMoveMemory(pMacEntry->RSN_IE, pVIE, (pEid->Len + 2));
+ pMacEntry->RSNIE_Len = (pEid->Len + 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliLinkUp: Store RSN_IE for WPA SM negotiation \n"));
+ }
+ /* For WPA2/WPA2PSK */
+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+ && (pMacEntry->AuthMode == Ndis802_11AuthModeWPA2 || pMacEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ NdisMoveMemory(pMacEntry->RSN_IE, pVIE, (pEid->Len + 2));
+ pMacEntry->RSNIE_Len = (pEid->Len + 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliLinkUp: Store RSN_IE for WPA2 SM negotiation \n"));
+ }
+
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+ }
+ }
+
+ if (pMacEntry->RSNIE_Len == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliLinkUp: root-AP has no RSN_IE \n"));
+ }
+ else
+ {
+ hex_dump("The RSN_IE of root-AP", pMacEntry->RSN_IE, pMacEntry->RSNIE_Len);
+ }
+
+ SupportRate(pAd->ApCliMlmeAux.SupRate, pAd->ApCliMlmeAux.SupRateLen, pAd->ApCliMlmeAux.ExtRate,
+ pAd->ApCliMlmeAux.ExtRateLen, &pRates, &RatesLen, &MaxSupportedRate);
+
+ pMacEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+ pMacEntry->RateLen = RatesLen;
+ set_entry_phy_cfg(pAd, pMacEntry);
+
+ pMacEntry->CapabilityInfo = pAd->ApCliMlmeAux.CapabilityInfo;
+
+ if ((wdev->WepStatus == Ndis802_11WEPEnabled)
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ && (pApCliEntry->WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+ )
+ {
+ PCIPHER_KEY pKey;
+ INT idx, BssIdx;
+
+ BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + ifIndex;
+
+ for (idx=0; idx < SHARE_KEY_NUM; idx++)
+ {
+ pKey = &pApCliEntry->SharedKey[idx];
+
+ if (pKey->KeyLen > 0)
+ {
+ /* Set key material and cipherAlg to Asic */
+ RTMP_ASIC_SHARED_KEY_TABLE(pAd,
+ BssIdx,
+ idx,
+ pKey);
+
+ if (idx == wdev->DefaultKeyId)
+ {
+ INT cnt;
+
+ /* Generate 3-bytes IV randomly for software encryption using */
+ for(cnt = 0; cnt < LEN_WEP_TSC; cnt++)
+ pKey->TxTsc[cnt] = RandomByte(pAd);
+
+ RTMP_SET_WCID_SEC_INFO(pAd,
+ BssIdx,
+ idx,
+ pKey->CipherAlg,
+ pMacEntry->Aid,
+ SHAREDKEYTABLE);
+ }
+ }
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ /* If this Entry supports 802.11n, upgrade to HT rate. */
+ if (pAd->ApCliMlmeAux.HtCapabilityLen != 0)
+ {
+ PHT_CAPABILITY_IE pHtCapability = (PHT_CAPABILITY_IE)&pAd->ApCliMlmeAux.HtCapability;
+
+ ht_mode_adjust(pAd, pMacEntry, pHtCapability, &pAd->CommonCfg.DesiredHtPhy);
+
+ /* find max fixed rate */
+ pMacEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &wdev->DesiredHtPhyInfo.MCSSet[0],
+ &pHtCapability->MCSSet[0]);
+
+ if (pAd->ApCfg.ApCliTab[ifIndex].DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF-apcli%d : Desired MCS = %d\n", ifIndex,
+ wdev->DesiredTransmitSetting.field.MCS));
+
+ set_ht_fixed_mcs(pAd, pMacEntry, wdev->DesiredTransmitSetting.field.MCS, wdev->HTPhyMode.field.MCS);
+ }
+
+ pMacEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pMacEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+ pMacEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
+ pMacEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
+ pMacEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
+ pMacEntry->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word;
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ if (pHtCapability->HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pHtCapability->HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pHtCapability->HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pHtCapability->HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pHtCapability->ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+ NdisMoveMemory(&pMacEntry->HTCapability, &pAd->ApCliMlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
+ NdisMoveMemory(pMacEntry->HTCapability.MCSSet, pApCliEntry->RxMcsSet, 16);
+ }
+ else
+ {
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliLinkUp - MaxSupRate=%d Mbps\n",
+ RateIdToMbps[pMacEntry->MaxSupportedRate]));
+ }
+
+#endif /* DOT11_N_SUPPORT */
+
+ pMacEntry->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word;
+ pMacEntry->CurrTxRate = pMacEntry->MaxSupportedRate;
+
+ if (pAd->ApCfg.ApCliTab[ifIndex].bAutoTxRateSwitch == FALSE)
+ {
+ pMacEntry->bAutoTxRateSwitch = FALSE;
+ /* If the legacy mode is set, overwrite the transmit setting of this entry. */
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->ApCfg.ApCliTab[ifIndex].DesiredTransmitSetting.field.FixedTxMode, pMacEntry);
+ }
+ else
+ {
+ UCHAR TableSize = 0;
+
+ pMacEntry->bAutoTxRateSwitch = TRUE;
+ MlmeSelectTxRateTable(pAd, pMacEntry, &pMacEntry->pTable, &TableSize, &pMacEntry->CurrTxRateIndex);
+ }
+
+ /* It had been set in APStartUp. Don't set again. */
+ /*AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); */
+
+ /* set this entry WMM capable or not */
+ if ((pAd->ApCliMlmeAux.APEdcaParm.bValid)
+#ifdef DOT11_N_SUPPORT
+ || IS_HT_STA(pMacEntry)
+#endif /* DOT11_N_SUPPORT */
+ )
+ {
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->ApCliMlmeAux.APRalinkIe & 0x00000003) == 3)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ RTMPSetPiggyBack(pAd, TRUE);
+ DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
+ }
+ else if (pAd->ApCliMlmeAux.APRalinkIe & 0x00000001)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink Aggregation\n"));
+ }
+ }
+
+ /* Set falg to identify if peer AP is Ralink chipset */
+ if (pAd->ApCliMlmeAux.APRalinkIe != 0x0)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET);
+ else
+ CLIENT_STATUS_CLEAR_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET);
+
+ /* set the apcli interface be valid. */
+ pApCliEntry->Valid = TRUE;
+ result = TRUE;
+
+ pAd->ApCfg.ApCliInfRunned++;
+
+ break;
+ }
+ result = FALSE;
+
+ } while(FALSE);
+
+
+#ifdef APCLI_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 ((pMacEntry->AuthMode == Ndis802_11AuthModeWPA2) &&
+ (NdisEqualMemory(pAd->MlmeAux.Bssid, pAd->ApCfg.ApCliTab[ifIndex].LastBssid, MAC_ADDR_LEN)) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].bLostAp == TRUE))
+ {
+ ApcliWpaSendEapolStart(pAd, pAd->MlmeAux.Bssid,pMacEntry,&pAd->ApCfg.ApCliTab[ifIndex]);
+ pAd->ApCfg.ApCliTab[ifIndex].bLostAp = FALSE;
+ }
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT */
+
+ RTMPSetSupportMCS(pAd,
+ OPMODE_AP,
+ pMacEntry,
+ pAd->ApCliMlmeAux.SupRate,
+ pAd->ApCliMlmeAux.SupRateLen,
+ pAd->ApCliMlmeAux.ExtRate,
+ pAd->ApCliMlmeAux.ExtRateLen,
+#ifdef DOT11_VHT_AC
+ pAd->ApCliMlmeAux.vht_cap_len,
+ &pAd->ApCliMlmeAux.vht_cap,
+#endif /* DOT11_VHT_AC */
+ &pAd->ApCliMlmeAux.HtCapability,
+ pAd->ApCliMlmeAux.HtCapabilityLen);
+
+#ifdef WSC_AP_SUPPORT
+ /* WSC initial connect to AP, jump to Wsc start action and set the correct parameters */
+ if ((result == TRUE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_ENROLLEE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE))
+ {
+ pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscState = WSC_STATE_LINK_UP;
+ pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscStatus = WSC_STATE_LINK_UP;
+ pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfStatus = WSC_SCSTATE_UNCONFIGURED;
+ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].WscControl.EntryAddr, MAC_ADDR_LEN);
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].WscControl.EntryAddr, pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ WscSendEapolStart(pAd, pMacEntry->Addr, AP_MODE);
+ }
+ else
+ {
+ WscStop(pAd, TRUE, &pAd->ApCfg.ApCliTab[ifIndex].WscControl);
+ }
+#endif /* WSC_AP_SUPPORT */
+
+ return result;
+}
+
+/*
+ ==========================================================================
+
+ Routine Description:
+ Disconnect current BSSID
+
+ Arguments:
+ pAd - Pointer to our adapter
+ ApCliIdx - Which ApCli interface
+ Return Value:
+ None
+
+ Note:
+
+ ==========================================================================
+*/
+VOID ApCliLinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ifIndex)
+{
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ if (ifIndex < MAX_APCLI_NUM)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! APCLI LINK DOWN - IF(apcli%d)!!!\n", ifIndex));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! ERROR : APCLI LINK DOWN - IF(apcli%d)!!!\n", ifIndex));
+ return;
+ }
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if (pApCliEntry->Valid == FALSE)
+ return;
+
+ pAd->ApCfg.ApCliInfRunned--;
+ MacTableDeleteEntry(pAd, pApCliEntry->MacTabWCID, APCLI_ROOT_BSSID_GET(pAd, pApCliEntry->MacTabWCID));
+
+ pApCliEntry->Valid = FALSE; /* This link doesn't associated with any remote-AP */
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pApCliEntry->WpaSupplicantUP)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] Send RT_DISASSOC_EVENT_FLAG.\n", __FUNCTION__, ifIndex));
+ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
+ }
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI Interface Up.
+ ==========================================================================
+ */
+VOID ApCliIfUp(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry;
+
+ /* 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) ||
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ return;
+
+ /* sanity check whether the interface is initialized. */
+ if (pAd->flg_apcli_init != TRUE)
+ return;
+
+ for(ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if (APCLI_IF_UP_CHECK(pAd, ifIndex)
+ && (pApCliEntry->Enable == TRUE)
+ && (pApCliEntry->Valid == FALSE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] startup.\n", __FUNCTION__, ifIndex));
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_JOIN_REQ, 0, NULL, ifIndex);
+ }
+ }
+
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ APCLI Interface Down.
+ ==========================================================================
+ */
+VOID ApCliIfDown(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry;
+
+ for(ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] startdown.\n", __FUNCTION__, ifIndex));
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex);
+ }
+
+ return;
+}
+
+
+
+/*
+ ==========================================================================
+ Description:
+ APCLI Interface Monitor.
+ ==========================================================================
+ */
+VOID ApCliIfMonitor(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR index;
+ PAPCLI_STRUCT pApCliEntry;
+
+ /* 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) ||
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ return;
+
+ /* sanity check whether the interface is initialized. */
+ if (pAd->flg_apcli_init != TRUE)
+ return;
+
+ for(index = 0; index < MAX_APCLI_NUM; index++)
+ {
+ UCHAR Wcid;
+ PMAC_TABLE_ENTRY pMacEntry;
+ BOOLEAN bForceBrocken = FALSE;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[index];
+ if (pApCliEntry->Valid == TRUE)
+ {
+ Wcid = pAd->ApCfg.ApCliTab[index].MacTabWCID;
+ if (!VALID_WCID(Wcid))
+ continue;
+ pMacEntry = &pAd->MacTab.Content[Wcid];
+
+ if ((pMacEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ && (pMacEntry->PortSecured != WPA_802_1X_PORT_SECURED)
+ && (RTMP_TIME_AFTER(pAd->Mlme.Now32 , (pApCliEntry->ApCliLinkUpTime + (30 * OS_HZ)))))
+ bForceBrocken = TRUE;
+
+ if (RTMP_TIME_AFTER(pAd->Mlme.Now32 , (pApCliEntry->ApCliRcvBeaconTime + (4 * OS_HZ))))
+ bForceBrocken = TRUE;
+ }
+ else
+ continue;
+
+ if (bForceBrocken == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliIfMonitor: IF(apcli%d) - no Beancon is received from root-AP.\n", index));
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliIfMonitor: Reconnect the Root-Ap again.\n"));
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, index);
+ RTMP_MLME_HANDLER(pAd);
+ }
+ }
+
+ return;
+}
+
+/*! \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
+ */
+BOOLEAN ApCliMsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType)
+{
+ USHORT Seq;
+ UCHAR EAPType;
+ BOOLEAN Return = FALSE;
+#ifdef WSC_AP_SUPPORT
+ UCHAR EAPCode;
+ PMAC_TABLE_ENTRY pEntry;
+#endif /* WSC_AP_SUPPORT */
+
+
+ /* only PROBE_REQ can be broadcast, all others must be unicast-to-me && is_mybssid; otherwise, */
+ /* ignore this frame */
+
+ /* WPA EAPOL PACKET */
+ if (pFrame->Hdr.FC.Type == BTYPE_DATA)
+ {
+#ifdef WSC_AP_SUPPORT
+ /*WSC EAPOL PACKET */
+ pEntry = MacTableLookup(pAd, pFrame->Hdr.Addr2);
+ if (pEntry && IS_ENTRY_APCLI(pEntry) && pAd->ApCfg.ApCliTab[pEntry->apidx].WscControl.WscConfMode == WSC_ENROLLEE)
+ {
+ *Machine = WSC_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ EAPCode = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 4);
+ Return = WscMsgTypeSubst(EAPType, EAPCode, MsgType);
+ }
+ if (!Return)
+#endif /* WSC_AP_SUPPORT */
+ {
+ *Machine = WPA_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ Return = WpaMsgTypeSubst(EAPType, MsgType);
+ }
+ return Return;
+ }
+ else if (pFrame->Hdr.FC.Type == BTYPE_MGMT)
+ {
+ switch (pFrame->Hdr.FC.SubType)
+ {
+ case SUBTYPE_ASSOC_RSP:
+ *Machine = APCLI_ASSOC_STATE_MACHINE;
+ *MsgType = APCLI_MT2_PEER_ASSOC_RSP;
+ break;
+
+ case SUBTYPE_DISASSOC:
+ *Machine = APCLI_ASSOC_STATE_MACHINE;
+ *MsgType = APCLI_MT2_PEER_DISASSOC_REQ;
+ break;
+
+ case SUBTYPE_DEAUTH:
+ *Machine = APCLI_AUTH_STATE_MACHINE;
+ *MsgType = APCLI_MT2_PEER_DEAUTH;
+ break;
+
+ case SUBTYPE_AUTH:
+ /* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */
+ NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
+ if (Seq == 2 || Seq == 4)
+ {
+ *Machine = APCLI_AUTH_STATE_MACHINE;
+ *MsgType = APCLI_MT2_PEER_AUTH_EVEN;
+ }
+ else
+ {
+ return FALSE;
+ }
+ 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;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN preCheckMsgTypeSubset(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType)
+{
+ if (pFrame->Hdr.FC.Type == BTYPE_MGMT)
+ {
+ switch (pFrame->Hdr.FC.SubType)
+ {
+ /* Beacon must be processed be AP Sync state machine. */
+ case SUBTYPE_BEACON:
+ *Machine = AP_SYNC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_BEACON;
+ break;
+
+ /* Only Sta have chance to receive Probe-Rsp. */
+ case SUBTYPE_PROBE_RSP:
+ *Machine = APCLI_SYNC_STATE_MACHINE;
+ *MsgType = APCLI_MT2_PEER_PROBE_RSP;
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN ApCliPeerAssocRspSanity(
+ 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 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 = (CHAR *) 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, ("%s(): fail - wrong SupportedRates IE\n", __FUNCTION__));
+ 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;
+#ifdef DOT11_N_SUPPORT
+ 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, ("%s():wrong IE_HT_CAP\n", __FUNCTION__));
+ }
+
+ break;
+ 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));
+ *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s():wrong IE_ADD_HT\n", __FUNCTION__));
+ }
+ break;
+ case IE_SECONDARY_CH_OFFSET:
+ if (pEid->Len == 1)
+ {
+ *pNewExtChannelOffset = pEid->Octet[0];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s():wrong IE_SECONDARY_CH_OFFSET\n", __FUNCTION__));
+ }
+ break;
+#endif /* DOT11_N_SUPPORT */
+ /* CCX2, WMM use the same IE value */
+ /* case IE_CCX_V2: */
+ 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->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80; */
+ 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;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():ignore unrecognized EID = %d\n", __FUNCTION__, pEid->Eid));
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len;
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ return TRUE;
+}
+
+
+MAC_TABLE_ENTRY *ApCliTableLookUpByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddrs)
+{
+ ULONG ApCliIndex;
+ PMAC_TABLE_ENTRY pCurEntry = NULL;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ if (wcid <=0 || wcid >= MAX_LEN_OF_MAC_TABLE )
+ return NULL;
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ do
+ {
+ pCurEntry = &pAd->MacTab.Content[wcid];
+
+ ApCliIndex = 0xff;
+ if ((pCurEntry) && IS_ENTRY_APCLI(pCurEntry))
+ {
+ ApCliIndex = pCurEntry->MatchAPCLITabIdx;
+ }
+
+ if ((ApCliIndex == 0xff) || (ApCliIndex >= MAX_APCLI_NUM))
+ break;
+
+ if (pAd->ApCfg.ApCliTab[ApCliIndex].Valid != TRUE)
+ break;
+
+ if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddrs))
+ {
+ pEntry = pCurEntry;
+ break;
+ }
+ } while(FALSE);
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ return pEntry;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check the WDS Entry is valid or not.
+ ==========================================================================
+ */
+static inline BOOLEAN ValidApCliEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apCliIdx)
+{
+ BOOLEAN result;
+ PMAC_TABLE_ENTRY pMacEntry;
+ APCLI_STRUCT *pApCliEntry;
+ do
+ {
+ if ((apCliIdx < 0) || (apCliIdx >= MAX_APCLI_NUM))
+ {
+ result = FALSE;
+ break;
+ }
+
+ pApCliEntry = (APCLI_STRUCT *)&pAd->ApCfg.ApCliTab[apCliIdx];
+ if (pApCliEntry->Valid != TRUE)
+ {
+ result = FALSE;
+ break;
+ }
+
+ if ((pApCliEntry->MacTabWCID <= 0)
+ || (pApCliEntry->MacTabWCID >= MAX_LEN_OF_MAC_TABLE))
+ {
+ result = FALSE;
+ break;
+ }
+
+ pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID];
+ if (!IS_ENTRY_APCLI(pMacEntry))
+ {
+ result = FALSE;
+ break;
+ }
+
+ result = TRUE;
+ } while(FALSE);
+
+ return result;
+}
+
+
+BOOLEAN ApCliAllowToSendPacket(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pPacket,
+ OUT UCHAR *pWcid)
+{
+ UCHAR apCliIdx;
+ BOOLEAN allowed;
+
+ /*DBGPRINT(RT_DEBUG_TRACE, ("ApCliAllowToSendPacket():Packet to ApCli interface!\n")); */
+ apCliIdx = RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_APCLI;
+ if (ValidApCliEntry(pAd, apCliIdx))
+ {
+ /*DBGPRINT(RT_DEBUG_TRACE, ("ApCliAllowToSendPacket(): Set the WCID as %d!\n", pAd->ApCfg.ApCliTab[apCliIdx].MacTabWCID)); */
+
+ *pWcid = pAd->ApCfg.ApCliTab[apCliIdx].MacTabWCID;
+ /*RTMP_SET_PACKET_WCID(pPacket, pAd->ApCfg.ApCliTab[apCliIdx].MacTabWCID); // to ApClient links. */
+
+ allowed = TRUE;
+ }
+ else
+ {
+ allowed = FALSE;
+ }
+
+ return allowed;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Validate the security configuration against the RSN information
+ element
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ eid_ptr Pointer to VIE
+
+ Return Value:
+ TRUE for configuration match
+ FALSE for otherwise
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN ApCliValidateRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT pEid_ptr,
+ IN USHORT eid_len,
+ IN USHORT idx)
+{
+ PUCHAR pVIE;
+ PUCHAR pTmp;
+ UCHAR len;
+ PEID_STRUCT pEid;
+ CIPHER_SUITE WPA; /* AP announced WPA cipher suite */
+ CIPHER_SUITE WPA2; /* AP announced WPA2 cipher suite */
+ USHORT Count;
+ UCHAR Sanity;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ PRSN_IE_HEADER_STRUCT pRsnHeader;
+ NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
+ NDIS_802_11_AUTHENTICATION_MODE TmpAuthMode;
+ NDIS_802_11_AUTHENTICATION_MODE WPA_AuthMode;
+ NDIS_802_11_AUTHENTICATION_MODE WPA_AuthModeAux;
+ NDIS_802_11_AUTHENTICATION_MODE WPA2_AuthMode;
+ NDIS_802_11_AUTHENTICATION_MODE WPA2_AuthModeAux;
+
+ pVIE = (PUCHAR) pEid_ptr;
+ len = eid_len;
+
+ /*if (len >= MAX_LEN_OF_RSNIE || len <= MIN_LEN_OF_RSNIE) */
+ /* return FALSE; */
+
+ /* Init WPA setting */
+ WPA.PairCipher = Ndis802_11WEPDisabled;
+ WPA.PairCipherAux = Ndis802_11WEPDisabled;
+ WPA.GroupCipher = Ndis802_11WEPDisabled;
+ WPA.RsnCapability = 0;
+ WPA.bMixMode = FALSE;
+ WPA_AuthMode = Ndis802_11AuthModeOpen;
+ WPA_AuthModeAux = Ndis802_11AuthModeOpen;
+
+ /* Init WPA2 setting */
+ WPA2.PairCipher = Ndis802_11WEPDisabled;
+ WPA2.PairCipherAux = Ndis802_11WEPDisabled;
+ WPA2.GroupCipher = Ndis802_11WEPDisabled;
+ WPA2.RsnCapability = 0;
+ WPA2.bMixMode = FALSE;
+ WPA2_AuthMode = Ndis802_11AuthModeOpen;
+ WPA2_AuthModeAux = Ndis802_11AuthModeOpen;
+
+ Sanity = 0;
+
+ /* 1. Parse Cipher this received RSNIE */
+ while (len > 0)
+ {
+ pTmp = pVIE;
+ pEid = (PEID_STRUCT) pTmp;
+
+ switch(pEid->Eid)
+ {
+ case IE_WPA:
+ if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
+ {
+ /* if unsupported vendor specific IE */
+ break;
+ }
+ /* Skip OUI ,version and multicast suite OUI */
+ 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:
+ case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
+ WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ WPA.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ WPA.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+
+ /* number of unicast suite */
+ pTmp += 1;
+
+ /* Store unicast cipher count */
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ /* pointer to unicast cipher */
+ pTmp += sizeof(USHORT);
+
+ /* Parsing all unicast cipher suite */
+ while (Count > 0)
+ {
+ /* Skip cipher suite 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 > WPA.PairCipher)
+ {
+ /* Move the lower cipher suite to PairCipherAux */
+ WPA.PairCipherAux = WPA.PairCipher;
+ WPA.PairCipher = TmpCipher;
+ }
+ else
+ {
+ WPA.PairCipherAux = TmpCipher;
+ }
+ pTmp++;
+ Count--;
+ }
+
+ /* Get AKM suite counts */
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ pTmp += sizeof(USHORT);
+
+ /* Parse AKM ciphers */
+ /* Parsing all AKM cipher suite */
+ while (Count > 0)
+ {
+ /* Skip cipher suite OUI */
+ pTmp += 3;
+ TmpAuthMode = Ndis802_11AuthModeOpen;
+ switch (*pTmp)
+ {
+ case 1:
+ /* WPA-enterprise */
+ TmpAuthMode = Ndis802_11AuthModeWPA;
+ break;
+ case 2:
+ /* WPA-personal */
+ TmpAuthMode = Ndis802_11AuthModeWPAPSK;
+ break;
+ default:
+ break;
+ }
+ if (TmpAuthMode > WPA_AuthMode)
+ {
+ /* Move the lower AKM suite to WPA_AuthModeAux */
+ WPA_AuthModeAux = WPA_AuthMode;
+ WPA_AuthMode = TmpAuthMode;
+ }
+ else
+ {
+ WPA_AuthModeAux = TmpAuthMode;
+ }
+ pTmp++;
+ Count--;
+ }
+
+ /* ToDo - Support WPA-None ? */
+
+ /* Check the Pair & Group, if different, turn on mixed mode flag */
+ if (WPA.GroupCipher != WPA.PairCipher)
+ WPA.bMixMode = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliValidateRSNIE - RSN-WPA1 PairWiseCipher(%s), GroupCipher(%s), AuthMode(%s)\n",
+ ((WPA.bMixMode) ? "Mix" : GetEncryptType(WPA.PairCipher)),
+ GetEncryptType(WPA.GroupCipher),
+ GetAuthMode(WPA_AuthMode)));
+
+ Sanity |= 0x1;
+ break; /* End of case IE_WPA */
+ case IE_RSN:
+ pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
+
+ /* 0. Version must be 1 */
+ /* The pRsnHeader->Version exists in native little-endian order, so we may need swap it for RT_BIG_ENDIAN systems. */
+ if (le2cpu16(pRsnHeader->Version) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - RSN Version isn't 1(%d) \n", pRsnHeader->Version));
+ break;
+ }
+
+ pTmp += sizeof(RSN_IE_HEADER_STRUCT);
+
+ /* 1. Check cipher OUI */
+ if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+ {
+ /* if unsupported vendor specific IE */
+ break;
+ }
+
+ /* Skip cipher suite OUI */
+ pTmp += 3;
+
+ /* Parse group cipher */
+ switch (*pTmp)
+ {
+ case 1:
+ case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
+ WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+
+ /* number of unicast suite */
+ pTmp += 1;
+
+ /* Get pairwise cipher counts */
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ pTmp += sizeof(USHORT);
+
+ /* 3. Get pairwise cipher */
+ /* 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 > WPA2.PairCipher)
+ {
+ /* Move the lower cipher suite to PairCipherAux */
+ WPA2.PairCipherAux = WPA2.PairCipher;
+ WPA2.PairCipher = TmpCipher;
+ }
+ else
+ {
+ WPA2.PairCipherAux = TmpCipher;
+ }
+ pTmp ++;
+ Count--;
+ }
+
+ /* Get AKM suite counts */
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ pTmp += sizeof(USHORT);
+
+ /* Parse AKM ciphers */
+ /* Parsing all AKM cipher suite */
+ while (Count > 0)
+ {
+ /* Skip cipher suite OUI */
+ pTmp += 3;
+ TmpAuthMode = Ndis802_11AuthModeOpen;
+ switch (*pTmp)
+ {
+ case 1:
+ /* WPA2-enterprise */
+ TmpAuthMode = Ndis802_11AuthModeWPA2;
+ break;
+ case 2:
+ /* WPA2-personal */
+ TmpAuthMode = Ndis802_11AuthModeWPA2PSK;
+ break;
+ default:
+ break;
+ }
+ if (TmpAuthMode > WPA2_AuthMode)
+ {
+ /* Move the lower AKM suite to WPA2_AuthModeAux */
+ WPA2_AuthModeAux = WPA2_AuthMode;
+ WPA2_AuthMode = TmpAuthMode;
+ }
+ else
+ {
+ WPA2_AuthModeAux = TmpAuthMode;
+ }
+ pTmp++;
+ Count--;
+ }
+
+ /* Check the Pair & Group, if different, turn on mixed mode flag */
+ if (WPA2.GroupCipher != WPA2.PairCipher)
+ WPA2.bMixMode = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliValidateRSNIE - RSN-WPA2 PairWiseCipher(%s), GroupCipher(%s), AuthMode(%s)\n",
+ (WPA2.bMixMode ? "Mix" : GetEncryptType(WPA2.PairCipher)), GetEncryptType(WPA2.GroupCipher),
+ GetAuthMode(WPA2_AuthMode)));
+
+ Sanity |= 0x2;
+ break; /* End of case IE_RSN */
+ default:
+ DBGPRINT(RT_DEBUG_WARN, ("ApCliValidateRSNIE - Unknown pEid->Eid(%d) \n", pEid->Eid));
+ break;
+ }
+
+ /* skip this Eid */
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+
+ }
+
+ /* 2. Validate this RSNIE with mine */
+ pApCliEntry = &pAd->ApCfg.ApCliTab[idx];
+
+ /* Peer AP doesn't include WPA/WPA2 capable */
+ if (Sanity == 0)
+ {
+ /* Check the authenticaton mode */
+ if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s - The authentication mode doesn't match \n", __FUNCTION__));
+ return FALSE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - The pre-RSNA authentication mode is used. \n", __FUNCTION__));
+ return TRUE;
+ }
+ }
+ else if (pApCliEntry->AuthMode < Ndis802_11AuthModeWPA)
+ {
+ /* Peer AP has RSN capability, but our AP-Client is pre-RSNA. Discard this */
+ DBGPRINT(RT_DEBUG_ERROR, ("%s - The authentication mode doesn't match. AP is WPA security but APCLI is not. \n", __FUNCTION__));
+ return FALSE;
+ }
+
+
+ /* Recovery user-defined cipher suite */
+ pApCliEntry->PairCipher = pApCliEntry->WepStatus;
+ pApCliEntry->GroupCipher = pApCliEntry->WepStatus;
+ pApCliEntry->bMixCipher = FALSE;
+
+ Sanity = 0;
+
+ /* Check AuthMode and WPA_AuthModeAux for matching, in case AP support dual-AuthMode */
+ /* WPAPSK */
+ if ((WPA_AuthMode == pApCliEntry->AuthMode) ||
+ ((WPA_AuthModeAux != Ndis802_11AuthModeOpen) && (WPA_AuthModeAux == pApCliEntry->AuthMode)))
+ {
+ /* Check cipher suite, AP must have more secured cipher than station setting */
+ if (WPA.bMixMode == FALSE)
+ {
+ if (pApCliEntry->WepStatus != WPA.GroupCipher)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - WPA validate cipher suite error \n"));
+ return FALSE;
+ }
+ }
+
+ /* check group cipher */
+ if (pApCliEntry->WepStatus < WPA.GroupCipher)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - WPA validate group cipher error \n"));
+ return FALSE;
+ }
+
+ /*
+ 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 ((pApCliEntry->WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pApCliEntry->WepStatus != WPA.PairCipher) &&
+ (pApCliEntry->WepStatus != WPA.PairCipherAux))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - WPA validate pairwise cipher error \n"));
+ return FALSE;
+ }
+
+ Sanity |= 0x1;
+ }
+ /* WPA2PSK */
+ else if ((WPA2_AuthMode == pApCliEntry->AuthMode) ||
+ ((WPA2_AuthModeAux != Ndis802_11AuthModeOpen) && (WPA2_AuthModeAux == pApCliEntry->AuthMode)))
+ {
+ /* Check cipher suite, AP must have more secured cipher than station setting */
+ if (WPA2.bMixMode == FALSE)
+ {
+ if (pApCliEntry->WepStatus != WPA2.GroupCipher)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - WPA2 validate cipher suite error \n"));
+ return FALSE;
+ }
+ }
+
+ /* check group cipher */
+ if (pApCliEntry->WepStatus < WPA2.GroupCipher)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - WPA2 validate group cipher error \n"));
+ return FALSE;
+ }
+
+ /*
+ 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 ((pApCliEntry->WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pApCliEntry->WepStatus != WPA2.PairCipher) &&
+ (pApCliEntry->WepStatus != WPA2.PairCipherAux))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - WPA2 validate pairwise cipher error \n"));
+ return FALSE;
+ }
+
+ Sanity |= 0x2;
+ }
+
+ if (Sanity == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliValidateRSNIE - Validate RSIE Failure \n"));
+ return FALSE;
+ }
+
+ /*Re-assign pairwise-cipher and group-cipher. Re-build RSNIE. */
+ if ((pApCliEntry->AuthMode == Ndis802_11AuthModeWPA) || (pApCliEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ pApCliEntry->GroupCipher = WPA.GroupCipher;
+
+ if (pApCliEntry->WepStatus == WPA.PairCipher)
+ pApCliEntry->PairCipher = WPA.PairCipher;
+ else if (WPA.PairCipherAux != Ndis802_11WEPDisabled)
+ pApCliEntry->PairCipher = WPA.PairCipherAux;
+ else /* There is no PairCipher Aux, downgrade our capability to TKIP */
+ pApCliEntry->PairCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if ((pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pApCliEntry->GroupCipher = WPA2.GroupCipher;
+
+ if (pApCliEntry->WepStatus == WPA2.PairCipher)
+ pApCliEntry->PairCipher = WPA2.PairCipher;
+ else if (WPA2.PairCipherAux != Ndis802_11WEPDisabled)
+ pApCliEntry->PairCipher = WPA2.PairCipherAux;
+ else /* There is no PairCipher Aux, downgrade our capability to TKIP */
+ pApCliEntry->PairCipher = Ndis802_11Encryption2Enabled;
+ }
+
+ /* Set Mix cipher flag */
+ if (pApCliEntry->PairCipher != pApCliEntry->GroupCipher)
+ {
+ pApCliEntry->bMixCipher = TRUE;
+
+ /* re-build RSNIE */
+ /*RTMPMakeRSNIE(pAd, pApCliEntry->AuthMode, pApCliEntry->WepStatus, (idx + MIN_NET_DEVICE_FOR_APCLI)); */
+ }
+
+ /* re-build RSNIE */
+ RTMPMakeRSNIE(pAd, pApCliEntry->AuthMode, pApCliEntry->WepStatus, (idx + MIN_NET_DEVICE_FOR_APCLI));
+
+ return TRUE;
+}
+
+BOOLEAN ApCliHandleRxBroadcastFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR FromWhichBSSID)
+{
+ RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo;
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ APCLI_STRUCT *pApCliEntry = NULL;
+
+ /*
+ It is possible to receive the multicast packet when in AP Client mode
+ ex: broadcast from remote AP to AP-client,
+ addr1=ffffff, addr2=remote AP's bssid, addr3=sta4_mac_addr
+ */
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx];
+
+ /* Filter out Bcast frame which AP relayed for us */
+ /* Multicast packet send from AP1 , received by AP2 and send back to AP1, drop this frame */
+ if (MAC_ADDR_EQUAL(pHeader->Addr3, pApCliEntry->CurrentAddress))
+ return FALSE; /* give up this frame */
+
+ if (pEntry->PrivacyFilter != Ndis802_11PrivFilterAcceptAll)
+ return FALSE; /* give up this frame */
+
+
+ /* skip the 802.11 header */
+ pRxBlk->pData += LENGTH_802_11;
+ pRxBlk->DataSize -= LENGTH_802_11;
+
+ /* Use software to decrypt the encrypted frame. */
+ /* Because this received frame isn't my BSS frame, Asic passed to driver without decrypting it. */
+ /* If receiving an "encrypted" unicast packet(its WEP bit as 1) and doesn't match my BSSID, it */
+ /* pass to driver with "Decrypted" marked as 0 in RxD. */
+ if ((pRxInfo->MyBss == 0) && (pRxInfo->Decrypted == 0) && (pHeader->FC.Wep == 1))
+ {
+ if (RTMPSoftDecryptionAction(pAd,
+ (PUCHAR)pHeader, 0,
+ &pApCliEntry->SharedKey[pRxWI->RxWIKeyIndex],
+ pRxBlk->pData,
+ &(pRxBlk->DataSize)) == NDIS_STATUS_FAILURE)
+ {
+ return FALSE; /* give up this frame */
+ }
+ }
+ pRxInfo->MyBss = 1;
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+
+ return TRUE;
+}
+
+
+VOID APCliInstallPairwiseKey(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ UCHAR IfIdx;
+ UINT8 BssIdx;
+
+ IfIdx = pEntry->MatchAPCLITabIdx;
+ BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + IfIdx;
+
+ WPAInstallPairwiseKey(pAd,
+ BssIdx,
+ pEntry,
+ FALSE);
+}
+
+
+BOOLEAN APCliInstallSharedKey(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyLen,
+ IN UCHAR DefaultKeyIdx,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ UCHAR IfIdx;
+ UCHAR GTK_len = 0;
+
+ if (!pEntry || !IS_ENTRY_APCLI(pEntry))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : This Entry doesn't exist!!! \n", __FUNCTION__));
+ return FALSE;
+ }
+
+ IfIdx = pEntry->MatchAPCLITabIdx;
+
+ if (pAd->ApCfg.ApCliTab[IfIdx].GroupCipher == Ndis802_11Encryption2Enabled && KeyLen >= LEN_TKIP_GTK)
+ {
+ GTK_len = LEN_TKIP_GTK;
+ }
+ else if (pAd->ApCfg.ApCliTab[IfIdx].GroupCipher == Ndis802_11Encryption3Enabled &&
+ KeyLen >= LEN_AES_GTK)
+ {
+ GTK_len = LEN_AES_GTK;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : GTK is invalid (GroupCipher=%d, DataLen=%d) !!! \n",
+ __FUNCTION__, pAd->ApCfg.ApCliTab[IfIdx].GroupCipher, KeyLen));
+ return FALSE;
+ }
+
+ /* Update GTK */
+ /* set key material, TxMic and RxMic for WPAPSK */
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[IfIdx].GTK, pKey, GTK_len);
+ pAd->ApCfg.ApCliTab[IfIdx].DefaultKeyId = DefaultKeyIdx;
+
+ /* Update shared key table */
+ NdisZeroMemory(&pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx], sizeof(CIPHER_KEY));
+ pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx].KeyLen = GTK_len;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx].Key, pKey, LEN_TK);
+ if (GTK_len == LEN_TKIP_GTK)
+ {
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx].RxMic, pKey + 16, LEN_TKIP_MIC);
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx].TxMic, pKey + 24, LEN_TKIP_MIC);
+ }
+
+ /* Update Shared Key CipherAlg */
+ pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx].CipherAlg = CIPHER_NONE;
+ if (pAd->ApCfg.ApCliTab[IfIdx].GroupCipher == Ndis802_11Encryption2Enabled)
+ pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx].CipherAlg = CIPHER_TKIP;
+ else if (pAd->ApCfg.ApCliTab[IfIdx].GroupCipher == Ndis802_11Encryption3Enabled)
+ pAd->ApCfg.ApCliTab[IfIdx].SharedKey[DefaultKeyIdx].CipherAlg = CIPHER_AES;
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Verify the support rate for different PHY type
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+// TODO: shiang-6590, modify this due to it's really a duplication of "RTMPUpdateMlmeRate()" in common/mlme.c
+VOID ApCliUpdateMlmeRate(
+ 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 (WMODE_B):
+ ProperMlmeRate = RATE_11;
+ MinimumRate = RATE_1;
+ break;
+ case (WMODE_B | WMODE_G):
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_A |WMODE_B | WMODE_G | WMODE_GN | WMODE_AN):
+ case (WMODE_B | WMODE_G | WMODE_GN):
+#endif /* DOT11_N_SUPPORT */
+ if ((pAd->ApCliMlmeAux.SupRateLen == 4) &&
+ (pAd->ApCliMlmeAux.ExtRateLen == 0))
+ /* B only AP */
+ ProperMlmeRate = RATE_11;
+ else
+ ProperMlmeRate = RATE_24;
+
+ if (pAd->ApCliMlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ break;
+ case (WMODE_A):
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_GN): /* rt2860 need to check mlmerate for 802.11n */
+ case (WMODE_G | WMODE_GN):
+ case (WMODE_A | WMODE_G | WMODE_AN | WMODE_GN):
+ case (WMODE_A | WMODE_AN):
+ case (WMODE_AN):
+#endif /* DOT11_N_SUPPORT */
+ ProperMlmeRate = RATE_24;
+ MinimumRate = RATE_6;
+ break;
+ case (WMODE_B | WMODE_A | WMODE_G):
+ ProperMlmeRate = RATE_24;
+ if (pAd->ApCliMlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ break;
+ default: /* error */
+ ProperMlmeRate = RATE_1;
+ MinimumRate = RATE_1;
+ break;
+ }
+
+ for (i = 0; i < pAd->ApCliMlmeAux.SupRateLen; i++)
+ {
+ for (j = 0; j < RateIdx; j++)
+ {
+ if ((pAd->ApCliMlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ {
+ if (j == ProperMlmeRate)
+ {
+ bMatch = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (bMatch)
+ break;
+ }
+
+ if (bMatch == FALSE)
+ {
+ for (i = 0; i < pAd->ApCliMlmeAux.ExtRateLen; i++)
+ {
+ for (j = 0; j < RateIdx; j++)
+ {
+ if ((pAd->ApCliMlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ {
+ if (j == ProperMlmeRate)
+ {
+ bMatch = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (bMatch)
+ break;
+ }
+ }
+
+ if (bMatch == FALSE)
+ {
+ ProperMlmeRate = MinimumRate;
+ }
+
+ if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ 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));
+}
+
+VOID APCli_Init(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_OS_NETDEV_OP_HOOK *pNetDevOps)
+{
+#define APCLI_MAX_DEV_NUM 32
+ PNET_DEV new_dev_p;
+/* VIRTUAL_ADAPTER *apcli_pAd; */
+ INT apcli_index;
+/* RTMP_OS_NETDEV_OP_HOOK netDevOpHook; */
+ APCLI_STRUCT *pApCliEntry;
+
+ /* sanity check to avoid redundant virtual interfaces are created */
+ if (pAd->flg_apcli_init != FALSE)
+ return;
+
+
+ /* init */
+ for(apcli_index = 0; apcli_index < MAX_APCLI_NUM; apcli_index++)
+ pAd->ApCfg.ApCliTab[apcli_index].dev = NULL;
+
+ /* create virtual network interface */
+ for(apcli_index = 0; apcli_index < MAX_APCLI_NUM; apcli_index++)
+ {
+ UINT32 MC_RowID = 0, IoctlIF = 0;
+#ifdef MULTIPLE_CARD_SUPPORT
+ MC_RowID = pAd->MC_RowID;
+#endif /* MULTIPLE_CARD_SUPPORT */
+#ifdef HOSTAPD_SUPPORT
+ IoctlIF = pAd->IoctlIF;
+#endif /* HOSTAPD_SUPPORT */
+ new_dev_p = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_APCLI, apcli_index, sizeof(PRTMP_ADAPTER), INF_APCLI_DEV_NAME);
+#ifdef HOSTAPD_SUPPORT
+ pAd->IoctlIF = IoctlIF;
+#endif /* HOSTAPD_SUPPORT */
+ RTMP_OS_NETDEV_SET_PRIV(new_dev_p, pAd);
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[apcli_index];
+ /* init MAC address of virtual network interface */
+ COPY_MAC_ADDR(pApCliEntry->CurrentAddress, pAd->CurrentAddress);
+
+ if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
+ {
+ if (pAd->ApCfg.BssidNum > 0 || MAX_MESH_NUM > 0)
+ {
+ /*
+ Refer to HW definition -
+ Bit1 of MAC address Byte0 is local administration bit
+ and should be set to 1 in extended multiple BSSIDs'
+ Bit3~ of MAC address Byte0 is extended multiple BSSID index.
+ */
+ pApCliEntry->CurrentAddress[0] += 2;
+ pApCliEntry->CurrentAddress[0] += (((pAd->ApCfg.BssidNum + MAX_MESH_NUM) - 1) << 2);
+ }
+ }
+ else
+ {
+ pApCliEntry->CurrentAddress[ETH_LENGTH_OF_ADDRESS - 1] =
+ (pApCliEntry->CurrentAddress[ETH_LENGTH_OF_ADDRESS - 1] + pAd->ApCfg.BssidNum + MAX_MESH_NUM) & 0xFF;
+ }
+
+
+ pNetDevOps->priv_flags = INT_APCLI; /* we are virtual interface */
+ pNetDevOps->needProtcted = TRUE;
+ NdisMoveMemory(pNetDevOps->devAddr, &pApCliEntry->CurrentAddress[0], MAC_ADDR_LEN);
+
+ /* register this device to OS */
+ RtmpOSNetDevAttach(pAd->OpMode, new_dev_p, pNetDevOps);
+
+ /* backup our virtual network interface */
+ pApCliEntry->dev = new_dev_p;
+ } /* End of for */
+
+ pAd->flg_apcli_init = TRUE;
+
+}
+
+
+VOID ApCli_Remove(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT index;
+
+ for(index = 0; index < MAX_APCLI_NUM; index++)
+ {
+ if (pAd->ApCfg.ApCliTab[index].dev)
+ {
+ RtmpOSNetDevDetach(pAd->ApCfg.ApCliTab[index].dev);
+
+ RtmpOSNetDevFree(pAd->ApCfg.ApCliTab[index].dev);
+
+ /* Clear it as NULL to prevent latter access error. */
+ pAd->flg_apcli_init = FALSE;
+ pAd->ApCfg.ApCliTab[index].dev = NULL;
+ }
+ }
+}
+
+
+BOOLEAN ApCli_Open(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV dev_p)
+{
+ UCHAR ifIndex;
+
+
+ for (ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++)
+ {
+ if (pAd->ApCfg.ApCliTab[ifIndex].dev == dev_p)
+ {
+ RTMP_OS_NETDEV_START_QUEUE(dev_p);
+ ApCliIfUp(pAd);
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_INTERFACE_UP, NULL, NULL, 0);
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+} /* End of ApCli_Open */
+
+
+BOOLEAN ApCli_Close(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV dev_p)
+{
+ UCHAR ifIndex;
+
+
+ for (ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++)
+ {
+ if (pAd->ApCfg.ApCliTab[ifIndex].dev == dev_p)
+ {
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_INTERFACE_DOWN, NULL, NULL, 0);
+
+ if (pAd->ApCfg.ApCliTab[ifIndex].pWpaAssocIe)
+ {
+ os_free_mem(NULL, pAd->ApCfg.ApCliTab[ifIndex].pWpaAssocIe);
+ pAd->ApCfg.ApCliTab[ifIndex].pWpaAssocIe = NULL;
+ pAd->ApCfg.ApCliTab[ifIndex].WpaAssocIeLen = 0;
+ }
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+ RTMP_OS_NETDEV_STOP_QUEUE(dev_p);
+
+ /* send disconnect-req to sta State Machine. */
+ if (pAd->ApCfg.ApCliTab[ifIndex].Enable)
+ {
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex);
+ RTMP_MLME_HANDLER(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] startdown.\n", __FUNCTION__, ifIndex));
+ }
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+} /* End of ApCli_Close */
+
+
+int APC_PacketSend(
+ IN PNDIS_PACKET skb_p,
+ IN PNET_DEV dev_p,
+ IN RTMP_NET_PACKET_TRANSMIT Func)
+{
+ RTMP_ADAPTER *pAd;
+ PAPCLI_STRUCT pApCli;
+ INT apcliIndex;
+
+
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(dev_p);
+ ASSERT(pAd);
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ RELEASE_NDIS_PACKET(pAd, skb_p, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+#endif /* RALINK_ATE */
+
+ if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
+ {
+ /* wlan is scanning/disabled/reset */
+ RELEASE_NDIS_PACKET(pAd, skb_p, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+
+ pApCli = (PAPCLI_STRUCT)&pAd->ApCfg.ApCliTab;
+
+ for(apcliIndex = 0; apcliIndex < MAX_APCLI_NUM; apcliIndex++)
+ {
+ if (pApCli[apcliIndex].Valid != TRUE)
+ continue;
+
+ /* find the device in our ApCli list */
+ if (pApCli[apcliIndex].dev == dev_p)
+ {
+ /* ya! find it */
+ pAd->RalinkCounters.PendingNdisPacketCount ++;
+ RTMP_SET_PACKET_SOURCE(skb_p, PKTSRC_NDIS);
+ RTMP_SET_PACKET_MOREDATA(skb_p, FALSE);
+ RTMP_SET_PACKET_NET_DEVICE_APCLI(skb_p, apcliIndex);
+ SET_OS_PKT_NETDEV(skb_p, pAd->net_dev);
+
+
+ /* transmit the packet */
+ return Func(skb_p);
+ }
+ }
+
+ RELEASE_NDIS_PACKET(pAd, skb_p, NDIS_STATUS_FAILURE);
+
+ return 0;
+}
+
+#endif /* APCLI_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_apcli_inf.c b/cleopatre/devkit/mt7601udrv/ap/ap_apcli_inf.c
new file mode 100644
index 0000000000..75f27e821c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_apcli_inf.c
@@ -0,0 +1,266 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_apcli.c
+
+ Abstract:
+ Support AP-Client function.
+
+ Note:
+ 1. Call RT28xx_ApCli_Init() in init function and
+ call RT28xx_ApCli_Remove() in close function
+
+ 2. MAC of ApCli-interface is initialized in RT28xx_ApCli_Init()
+
+ 3. ApCli index (0) of different rx packet is got in
+ APHandleRxDoneInterrupt() by using FromWhichBSSID = pEntry->apidx;
+ Or FromWhichBSSID = BSS0;
+
+ 4. ApCli index (0) of different tx packet is assigned in
+ MBSS_VirtualIF_PacketSend() by using RTMP_SET_PACKET_NET_DEVICE_MBSSID()
+ 5. ApCli index (0) of different interface is got in APHardTransmit() by using
+ RTMP_GET_PACKET_IF()
+
+ 6. ApCli index (0) of IOCTL command is put in pAd->OS_Cookie->ioctl_if
+
+ 8. The number of ApCli only can be 1
+
+ 9. apcli convert engine subroutines, we should just take care data packet.
+ Revision History:
+ Who When What
+ -------------- ---------- ----------------------------------------------
+ Shiang, Fonchi 02-13-2007 created
+*/
+#define RTMP_MODULE_OS
+
+#ifdef APCLI_SUPPORT
+
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rt_os_net.h"
+
+
+/*
+========================================================================
+Routine Description:
+ Init AP-Client function.
+
+Arguments:
+ pAd points to our adapter
+ main_dev_p points to the main BSS network interface
+
+Return Value:
+ None
+
+Note:
+ 1. Only create and initialize virtual network interfaces.
+ 2. No main network interface here.
+========================================================================
+*/
+VOID RT28xx_ApCli_Init(
+ IN VOID *pAd,
+ IN PNET_DEV main_dev_p)
+{
+
+ RTMP_OS_NETDEV_OP_HOOK netDevOpHook;
+
+ /* init operation functions */
+ NdisZeroMemory(&netDevOpHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
+ netDevOpHook.open = ApCli_VirtualIF_Open;
+ netDevOpHook.stop = ApCli_VirtualIF_Close;
+ netDevOpHook.xmit = ApCli_VirtualIF_PacketSend;
+ netDevOpHook.ioctl = ApCli_VirtualIF_Ioctl;
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_APC_INIT,
+ 0, &netDevOpHook, 0);
+}
+
+/*
+========================================================================
+Routine Description:
+ Open a virtual network interface.
+
+Arguments:
+ dev_p which WLAN network interface
+
+Return Value:
+ 0: open successfully
+ otherwise: open fail
+
+Note:
+========================================================================
+*/
+INT ApCli_VirtualIF_Open(
+ IN PNET_DEV dev_p)
+{
+/* UCHAR ifIndex; */
+ VOID *pAd;
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(dev_p);
+ ASSERT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: ===> %s\n", __FUNCTION__, RTMP_OS_NETDEV_GET_DEVNAME(dev_p)));
+
+ if (VIRTUAL_IF_UP(pAd) != 0)
+ return -1;
+
+ /* increase MODULE use count */
+ RT_MOD_INC_USE_COUNT();
+
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_APC_OPEN, 0, dev_p, 0);
+
+ return 0;
+} /* End of ApCli_VirtualIF_Open */
+
+
+/*
+========================================================================
+Routine Description:
+ Close a virtual network interface.
+
+Arguments:
+ dev_p which WLAN network interface
+
+Return Value:
+ 0: close successfully
+ otherwise: close fail
+
+Note:
+========================================================================
+*/
+INT ApCli_VirtualIF_Close(
+ IN PNET_DEV dev_p)
+{
+/* UCHAR ifIndex; */
+ VOID *pAd;
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(dev_p);
+ ASSERT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: ===> %s\n", __FUNCTION__, RTMP_OS_NETDEV_GET_DEVNAME(dev_p)));
+
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_APC_CLOSE, 0, dev_p, 0);
+
+ VIRTUAL_IF_DOWN(pAd);
+
+ RT_MOD_DEC_USE_COUNT();
+
+ return 0;
+} /* End of ApCli_VirtualIF_Close */
+
+
+/*
+========================================================================
+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:
+========================================================================
+*/
+INT ApCli_VirtualIF_PacketSend(
+ IN PNDIS_PACKET pPktSrc,
+ IN PNET_DEV pDev)
+{
+
+ MEM_DBG_PKT_ALLOC_INC(pPktSrc);
+
+ if(!(RTMP_OS_NETDEV_STATE_RUNNING(pDev)))
+ {
+ /* the interface is down */
+ RELEASE_NDIS_PACKET(NULL, pPktSrc, NDIS_STATUS_FAILURE);
+ return 0;
+ } /* End of if */
+
+ return APC_PacketSend(pPktSrc, pDev, rt28xx_packet_xmit);
+} /* End of ApCli_VirtualIF_PacketSend */
+
+
+/*
+========================================================================
+Routine Description:
+ IOCTL to WLAN.
+
+Arguments:
+ dev_p which WLAN network interface
+ rq_p command information
+ cmd command ID
+
+Return Value:
+ 0: IOCTL successfully
+ otherwise: IOCTL fail
+
+Note:
+ SIOCETHTOOL 8946 New drivers use this ETHTOOL interface to
+ report link failure activity.
+========================================================================
+*/
+INT ApCli_VirtualIF_Ioctl(
+ IN PNET_DEV dev_p,
+ IN OUT VOID *rq_p,
+ IN INT cmd)
+{
+ VOID *pAd;
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(dev_p);
+ ASSERT(pAd);
+
+/* if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */
+ if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) != NDIS_STATUS_SUCCESS)
+ return -ENETDOWN;
+
+ /* do real IOCTL */
+ return (rt28xx_ioctl(dev_p, rq_p, cmd));
+} /* End of ApCli_VirtualIF_Ioctl */
+
+
+/*
+========================================================================
+Routine Description:
+ Remove ApCli-BSS network interface.
+
+Arguments:
+ pAd points to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28xx_ApCli_Remove(
+ IN VOID *pAd)
+{
+/* UINT index; */
+
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_APC_REMOVE, 0, NULL, 0);
+
+
+}
+
+#endif /* APCLI_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_assoc.c b/cleopatre/devkit/mt7601udrv/ap/ap_assoc.c
new file mode 100644
index 0000000000..a6e682d0c7
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_assoc.c
@@ -0,0 +1,1637 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ assoc.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 08-04-2003 created for 11g soft-AP
+ */
+
+#include "rt_config.h"
+
+
+static void ap_assoc_info_debugshow(
+ IN RTMP_ADAPTER *pAd,
+ IN BOOLEAN isReassoc,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN IE_LISTS *ie_list)
+{
+#ifdef DBG
+ PUCHAR sAssoc = isReassoc ? (PUCHAR)"ReASSOC" : (PUCHAR)"ASSOC";
+#endif /* DBG */
+ MULTISSID_STRUCT *wdev;
+
+
+ wdev = &pAd->ApCfg.MBSSID[pEntry->apidx];
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - \n\tAssign AID=%d to STA %02x:%02x:%02x:%02x:%02x:%02x\n",
+ sAssoc, pEntry->Aid, PRINT_MAC(pEntry->Addr)));
+
+#ifdef DOT11_N_SUPPORT
+ if (ie_list->ht_cap_len && WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ assoc_ht_info_debugshow(pAd, pEntry, ie_list->ht_cap_len, &ie_list->HTCapability);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\n%s - Update AP OperaionMode=%d , fAnyStationIsLegacy=%d, fAnyStation20Only=%d, fAnyStationNonGF=%d\n\n",
+ sAssoc,
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode,
+ pAd->MacTab.fAnyStationIsLegacy,
+ pAd->MacTab.fAnyStation20Only,
+ pAd->MacTab.fAnyStationNonGF));
+
+#ifdef DOT11N_DRAFT3
+ DBGPRINT(RT_DEBUG_TRACE, ("\tExt Cap Info: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tBss2040CoexistMgmt=%d\n", pEntry->BSS2040CoexistenceMgmtSupport));
+#endif /* DOT11N_DRAFT3 */
+#ifdef DOT11_VHT_AC
+ if ((ie_list->vht_cap_len) &&
+ WMODE_CAP_N(pAd->CommonCfg.PhyMode) &&
+ (pAd->CommonCfg.Channel > 14))
+ {
+ assoc_vht_info_debugshow(pAd, pEntry, &ie_list->vht_cap, NULL);
+ }
+#endif /* DOT11_VHT_AC */
+ }
+ else
+#endif /* DOT11_N_SUPPORT */
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - legacy STA\n", sAssoc));
+ DBGPRINT(RT_DEBUG_TRACE, ("\n%s - MODE=%d, MCS=%d\n", sAssoc,
+ pEntry->HTPhyMode.field.MODE, pEntry->HTPhyMode.field.MCS));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\tAuthMode=%d, WepStatus=%d, WpaState=%d, GroupKeyWepStatus=%d\n",
+ pEntry->AuthMode, pEntry->WepStatus, pEntry->WpaState, wdev->GroupKeyWepStatus));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\tWMMCap=%d, RalinkAgg=%d, PiggyBack=%d, RDG=%d, TxAMSDU=%d, IdleTimeout=%d\n",
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE),
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE),
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE),
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE),
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED),
+ pEntry->StaIdleTimeout));
+
+}
+
+
+static USHORT update_associated_mac_entry(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN IE_LISTS *ie_list,
+ IN UCHAR MaxSupportedRate)
+{
+ MULTISSID_STRUCT *wdev;
+#ifdef TXBF_SUPPORT
+ BOOLEAN supportsETxBF = FALSE;
+#endif // TXBF_SUPPORT //
+
+
+ wdev = &pAd->ApCfg.MBSSID[pEntry->apidx];
+
+ /* Update auth, wep, legacy transmit rate setting . */
+ pEntry->Sst = SST_ASSOC;
+
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+ set_entry_phy_cfg(pAd, pEntry);
+
+ pEntry->CapabilityInfo = ie_list->CapabilityInfo;
+
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->WpaState = AS_INITPSK;
+ }
+#ifdef DOT1X_SUPPORT
+ else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) ||
+ (pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+ (wdev->IEEE8021X == TRUE))
+ {
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->WpaState = AS_AUTHENTICATION;
+ }
+#endif /* DOT1X_SUPPORT */
+#ifdef WAPI_SUPPORT
+ else if ((pEntry->AuthMode == Ndis802_11AuthModeWAICERT) ||
+ (pEntry->AuthMode == Ndis802_11AuthModeWAIPSK))
+ {
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->WpaState = AS_AUTHENTICATION2;
+ }
+#endif /* WAPI_SUPPORT */
+
+ /*if (ClientRalinkIe & 0x00000004) */
+ if (ie_list->RalinkIe != 0x0)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET);
+ else
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET);
+
+
+ /* Ralink proprietary Piggyback and Aggregation support for legacy RT61 chip */
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+#ifdef AGGREGATION_SUPPORT
+ if ((pAd->CommonCfg.bAggregationCapable) && (ie_list->RalinkIe & 0x00000001))
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -RaAggregate= 1\n"));
+ }
+#endif /* AGGREGATION_SUPPORT */
+#ifdef PIGGYBACK_SUPPORT
+ if ((pAd->CommonCfg.bPiggyBackCapable) && (ie_list->RalinkIe & 0x00000002))
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -PiggyBack= 1\n"));
+ }
+#endif /* PIGGYBACK_SUPPORT */
+
+ /* In WPA or 802.1x mode, the port is not secured, otherwise is secued. */
+ if ((pEntry->AuthMode >= Ndis802_11AuthModeWPA)
+#ifdef DOT1X_SUPPORT
+ || (wdev->IEEE8021X == TRUE)
+#endif /* DOT1X_SUPPORT */
+ )
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+#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.
+ */
+#ifdef WAPI_SUPPORT
+ if (!(IS_HW_WAPI_SUPPORT(pAd))
+ && (pEntry->WepStatus == Ndis802_11EncryptionSMS4Enabled))
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SOFTWARE_ENCRYPT);
+ }
+#endif /* WAPI_SUPPORT */
+
+#endif /* SOFT_ENCRYPT */
+
+#ifdef DOT11_N_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(pEntry->WepStatus))
+ {
+ /* Force to None-HT mode due to WiFi 11n policy */
+ ie_list->ht_cap_len = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : Force the STA as Non-HT mode\n", __FUNCTION__));
+ }
+
+ /* If this Entry supports 802.11n, upgrade to HT rate. */
+ if ((ie_list->ht_cap_len != 0) &&
+ (wdev->DesiredHtPhyInfo.bHtEnable) &&
+ WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ ht_mode_adjust(pAd, pEntry, &ie_list->HTCapability, &pAd->CommonCfg.DesiredHtPhy);
+
+#ifdef DOT11N_DRAFT3
+ if (ie_list->ExtCapInfo.BssCoexistMgmtSupport)
+ pEntry->BSS2040CoexistenceMgmtSupport = 1;
+#endif /* DOT11N_DRAFT3 */
+
+
+ /* 40Mhz BSS Width Trigger events */
+ if (ie_list->HTCapability.HtCapInfo.Forty_Mhz_Intolerant)
+ {
+#ifdef DOT11N_DRAFT3
+ pEntry->bForty_Mhz_Intolerant = TRUE;
+ pAd->MacTab.fAnyStaFortyIntolerant = TRUE;
+ if(((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.Channel <=14)) &&
+ ((pAd->CommonCfg.bBssCoexEnable == TRUE) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0))
+ )
+ {
+ pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq = 1;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
+ pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("pEntry set 40MHz Intolerant as 1\n"));
+#endif /* DOT11N_DRAFT3 */
+ Handle_BSS_Width_Trigger_Events(pAd);
+ }
+
+#ifdef TXBF_SUPPORT
+ supportsETxBF = clientSupportsETxBF(pAd, &ie_list->HtCapability.TxBFCap);
+#endif /* TXBF_SUPPORT */
+
+ /* find max fixed rate */
+ pEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &wdev->DesiredHtPhyInfo.MCSSet[0],
+ &ie_list->HTCapability.MCSSet[0]);
+
+ if (wdev->DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("@@@ IF-ra%d DesiredTransmitSetting.field.MCS = %d\n",
+ pEntry->apidx,
+ wdev->DesiredTransmitSetting.field.MCS));
+
+ set_ht_fixed_mcs(pAd, pEntry, wdev->DesiredTransmitSetting.field.MCS, wdev->HTPhyMode.field.MCS);
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (ie_list->HTCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ // TODO: shiang-6590, check if this is necessary here, perforce didn't have this
+ if (ie_list->HTCapability.HtCapParm.MpduDensity < 5)
+ ie_list->HTCapability.HtCapParm.MpduDensity = 5;
+
+ pEntry->MpduDensity = ie_list->HTCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = ie_list->HTCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)ie_list->HTCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)ie_list->HTCapability.HtCapInfo.AMsduSize;
+
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ if (ie_list->HTCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (ie_list->HTCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (ie_list->HTCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (ie_list->HTCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (ie_list->HTCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && ie_list->HTCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (ie_list->HTCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ /* Record the received capability from association request */
+ NdisMoveMemory(&pEntry->HTCapability, &ie_list->HTCapability, sizeof(HT_CAPABILITY_IE));
+
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) &&
+ (pAd->CommonCfg.Channel > 14) &&
+ ie_list->vht_cap_len)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_VHT;
+ if ((pEntry->MaxHTPhyMode.field.BW== BW_40) && (wdev->DesiredHtPhyInfo.vht_bw))
+ pEntry->MaxHTPhyMode.field.BW = BW_80;
+
+ NdisMoveMemory(&pEntry->vht_cap_ie, &ie_list->vht_cap, sizeof(VHT_CAP_IE));
+ }
+#endif /* DOT11_VHT_AC */
+ }
+ else
+ {
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE));
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+
+#ifdef MFB_SUPPORT
+ pEntry->lastLegalMfb = 0;
+ pEntry->isMfbChanged = FALSE;
+ pEntry->fLastChangeAccordingMfb = FALSE;
+
+ pEntry->toTxMrq = TRUE;
+ pEntry->msiToTx = 0;/*has to increment whenever a mrq is sent */
+ pEntry->mrqCnt = 0;
+
+ pEntry->pendingMfsi = 0;
+
+ pEntry->toTxMfb = FALSE;
+ pEntry->mfbToTx = 0;
+ pEntry->mfb0 = 0;
+ pEntry->mfb1 = 0;
+#endif /* MFB_SUPPORT */
+
+ pEntry->freqOffsetValid = FALSE;
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ TxBFInit(pAd, pEntry, supportsETxBF);
+#endif // TXBF_SUPPORT //
+
+ // Initialize Rate Adaptation
+ MlmeRAInit(pAd, pEntry);
+
+ /* Set asic auto fall back */
+ if (wdev->bAutoTxRateSwitch == TRUE)
+ {
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pEntry->pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ MlmeNewTxRate(pAd, pEntry);
+
+ pEntry->bAutoTxRateSwitch = TRUE;
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (! ADAPT_RATE_TABLE(pEntry->pTable))
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ pEntry->HTPhyMode.field.ShortGI = GI_800;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MCS = wdev->HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ /* If the legacy mode is set, overwrite the transmit setting of this entry. */
+ RTMPUpdateLegacyTxSetting((UCHAR)wdev->DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+
+
+ if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
+ ApLogEvent(pAd, pEntry->Addr, EVENT_ASSOCIATED);
+
+ APUpdateCapabilityAndErpIe(pAd);
+#ifdef DOT11_N_SUPPORT
+ APUpdateOperationMode(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+
+#ifdef HOSTAPD_SUPPORT
+ if((wdev->Hostapd == TRUE) &&
+ ((wdev->AuthMode >= Ndis802_11AuthModeWPA) || wdev->IEEE8021X))
+ {
+ RtmpOSWrielessEventSendExt(pAd->net_dev, RT_WLAN_EVENT_EXPIRED,
+ -1, pEntry->Addr, NULL, 0,
+ ((pEntry->CapabilityInfo & 0x0010) == 0 ? 0xFFFD : 0xFFFC));
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+ return MLME_SUCCESS;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ assign a new AID to the newly associated/re-associated STA and
+ decide its MaxSupportedRate and CurrTxRate. Both rates should not
+ exceed AP's capapbility
+ Return:
+ MLME_SUCCESS - association successfully built
+ others - association failed due to resource issue
+ ==========================================================================
+ */
+static USHORT APBuildAssociation(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN IE_LISTS *ie_list,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ OUT USHORT *pAid)
+{
+ USHORT StatusCode = MLME_SUCCESS;
+ UCHAR MaxSupportedRate = RATE_11;
+ MULTISSID_STRUCT *wdev;
+
+
+ MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps);
+
+ if ((WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_G)
+#ifdef DOT11_N_SUPPORT
+ || WMODE_EQUAL(pAd->CommonCfg.PhyMode, (WMODE_G | WMODE_GN))
+#endif /* DOT11_N_SUPPORT */
+ )
+ && (MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ )
+ return MLME_ASSOC_REJ_DATA_RATE;
+
+#ifdef DOT11_N_SUPPORT
+ /* 11n only */
+ if (WMODE_HT_ONLY(pAd->CommonCfg.PhyMode)&& (ie_list->ht_cap_len == 0))
+ return MLME_ASSOC_REJ_DATA_RATE;
+#endif /* DOT11_N_SUPPORT */
+
+ if (!pEntry)
+ return MLME_UNSPECIFY_FAIL;
+
+ if (pEntry && ((pEntry->Sst == SST_AUTH) || (pEntry->Sst == SST_ASSOC)))
+ {
+ /* TODO: */
+ /* should qualify other parameters, for example - capablity, supported rates, listen interval, ... etc */
+ /* to decide the Status Code */
+ /**pAid = APAssignAid(pAd, pEntry); */
+ /*pEntry->Aid = *pAid; */
+ *pAid = pEntry->Aid;
+ pEntry->NoDataIdleCount = 0;
+ pEntry->StaConnectTime = 0;
+
+#ifdef WSC_AP_SUPPORT
+ if (pEntry->bWscCapable == FALSE)
+#endif /* WSC_AP_SUPPORT */
+ {
+ /* check the validity of the received RSNIE */
+ if ((StatusCode = APValidateRSNIE(pAd, pEntry, &ie_list->RSN_IE[0], ie_list->RSNIE_Len)) != MLME_SUCCESS)
+ return StatusCode;
+ }
+
+ NdisMoveMemory(pEntry->RSN_IE, &ie_list->RSN_IE[0], ie_list->RSNIE_Len);
+ pEntry->RSNIE_Len = ie_list->RSNIE_Len;
+
+
+ wdev = &pAd->ApCfg.MBSSID[pEntry->apidx];
+ if (*pAid == 0)
+ StatusCode = MLME_ASSOC_REJ_UNABLE_HANDLE_STA;
+ else if ((pEntry->RSNIE_Len == 0) &&
+ (wdev->AuthMode >= Ndis802_11AuthModeWPA)
+#ifdef HOSTAPD_SUPPORT
+ && (wdev->Hostapd == TRUE)
+#endif
+ )
+ {
+#ifdef WSC_AP_SUPPORT
+ if (((wdev->WscControl.WscConfMode != WSC_DISABLE) &&
+ pEntry->bWscCapable
+#ifdef WSC_V2_SUPPORT
+ && (wdev->WscControl.WscV2Info.bWpsEnable ||
+ (wdev->WscControl.WscV2Info.bEnableWpsV2 == FALSE))
+#endif /* WSC_V2_SUPPORT */
+ )
+#ifdef HOSTAPD_SUPPORT
+ || wdev->Hostapd == TRUE
+#endif /*HOSTAPD_SUPPORT*/
+ )
+ {
+ pEntry->Sst = SST_ASSOC;
+ StatusCode = MLME_SUCCESS;
+ /* In WPA or 802.1x mode, the port is not secured. */
+ if ((pEntry->AuthMode >= Ndis802_11AuthModeWPA)
+#ifdef DOT1X_SUPPORT
+ || (wdev->IEEE8021X == TRUE)
+#endif /* DOT1X_SUPPORT */
+ )
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->WpaState = AS_INITPSK;
+ }
+#ifdef DOT1X_SUPPORT
+ else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) ||
+ (pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+ (wdev->IEEE8021X == TRUE))
+ {
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->WpaState = AS_AUTHENTICATION;
+ }
+#endif /* DOT1X_SUPPORT */
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - WSC_STATE_MACHINE is OFF.<WscConfMode = %d, apidx =%d>\n",
+ wdev->WscControl.WscConfMode,
+ pEntry->apidx));
+ StatusCode = MLME_ASSOC_DENY_OUT_SCOPE;
+ }
+#else /* WSC_AP_SUPPORT */
+ StatusCode = MLME_ASSOC_DENY_OUT_SCOPE;
+#endif /* WSC_AP_SUPPORT */
+
+#ifdef HOSTAPD_SUPPORT
+ if(wdev->Hostapd == TRUE
+ && (wdev->AuthMode >= Ndis802_11AuthModeWPA
+ || wdev->IEEE8021X))
+ {
+
+ RtmpOSWrielessEventSendExt(pAd->net_dev, RT_WLAN_EVENT_EXPIRED,
+ -1, pEntry->Addr, NULL, 0,
+ ((pEntry->CapabilityInfo & 0x0010) == 0 ? 0xFFFD : 0xFFFC));
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+ }
+ else
+ {
+ StatusCode = update_associated_mac_entry(pAd, pEntry, ie_list, MaxSupportedRate);
+ }
+ }
+ else /* CLASS 3 error should have been handled beforehand; here should be MAC table full */
+ StatusCode = MLME_ASSOC_REJ_UNABLE_HANDLE_STA;
+
+ if (StatusCode == MLME_SUCCESS)
+ {
+ if (ie_list->bWmmCapable)
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+ }
+
+ return StatusCode;
+}
+
+
+#ifdef IAPP_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ Send Leyer 2 Update Frame to update forwarding table in Layer 2 devices.
+
+ Arguments:
+ *mac_p - the STATION MAC address pointer
+
+ Return Value:
+ TRUE - send successfully
+ FAIL - send fail
+
+ Note:
+ ========================================================================
+*/
+static BOOLEAN IAPP_L2_Update_Frame_Send(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 *mac_p,
+ IN INT bssid)
+{
+
+ NDIS_PACKET *pNetBuf;
+
+ pNetBuf = RtmpOsPktIappMakeUp(get_netdev_from_bssid(pAd, bssid), mac_p);
+ if (pNetBuf == NULL)
+ return FALSE;
+
+ /* UCOS: update the built-in bridge, too (don't use gmac.xmit()) */
+ announce_802_3_packet(pAd, pNetBuf, OPMODE_AP);
+
+ IAPP_L2_UpdatePostCtrl(pAd, mac_p, bssid);
+
+ return TRUE;
+} /* End of IAPP_L2_Update_Frame_Send */
+#endif /* IAPP_SUPPORT */
+
+
+VOID ap_cmm_peer_assoc_req_action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN BOOLEAN isReassoc)
+{
+ IE_LISTS *ie_list = NULL;
+ HEADER_802_11 AssocRspHdr;
+ USHORT CapabilityInfoForAssocResp;
+ USHORT StatusCode = MLME_SUCCESS;
+ USHORT Aid;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ UCHAR MaxSupportedRate = 0;
+ UCHAR SupRateLen, PhyMode, FlgIs11bSta;
+ UCHAR i;
+ MAC_TABLE_ENTRY *pEntry;
+#ifdef DBG
+ UCHAR *sAssoc = isReassoc ? (PUCHAR)"ReASSOC" : (PUCHAR)"ASSOC";
+#endif /* DBG */
+ UCHAR SubType;
+ BOOLEAN bACLReject = FALSE;
+#ifdef DOT1X_SUPPORT
+ PUINT8 pPmkid = NULL;
+ UINT8 pmkid_count = 0;
+#endif /* DOT1X_SUPPORT */
+ MULTISSID_STRUCT *wdev;
+
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(IE_LISTS));
+ if (ie_list == NULL) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): mem alloc failed\n", __FUNCTION__));
+ return;
+ }
+ NdisZeroMemory(ie_list, sizeof(IE_LISTS));
+
+ if (!PeerAssocReqCmmSanity(pAd, isReassoc, Elem->Msg, Elem->MsgLen, ie_list))
+ goto LabelOK;
+
+ /* check if AP address is same as us */
+ /* TODO */
+ /* goto label_err; */
+
+ pEntry = MacTableLookup(pAd, ie_list->Addr2);
+ if (!pEntry) {
+ DBGPRINT(RT_DEBUG_ERROR, ("NoAuth MAC - %02x:%02x:%02x:%02x:%02x:%02x\n",
+ PRINT_MAC(ie_list->Addr2)));
+ goto LabelOK;
+ }
+
+ if (!VALID_MBSS(pAd, pEntry->apidx)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():pEntry bounding invalid wdev(apidx=%d)\n",
+ __FUNCTION__, pEntry->apidx));
+ goto LabelOK;
+ }
+
+ wdev = &pAd->ApCfg.MBSSID[pEntry->apidx];
+ PhyMode = wdev->PhyMode;
+
+ FlgIs11bSta = 1;
+ for(i=0; i<ie_list->SupportedRatesLen; i++)
+ {
+ if (((ie_list->SupportedRates[i] & 0x7F) != 2) &&
+ ((ie_list->SupportedRates[i] & 0x7F) != 4) &&
+ ((ie_list->SupportedRates[i] & 0x7F) != 11) &&
+ ((ie_list->SupportedRates[i] & 0x7F) != 22))
+ {
+ FlgIs11bSta = 0;
+ break;
+ }
+ }
+
+
+ /* clear the previous Pairwise key table */
+ if(pEntry->Aid != 0 &&
+ (pEntry->WepStatus >= Ndis802_11Encryption2Enabled
+#ifdef DOT1X_SUPPORT
+ || wdev->IEEE8021X
+#endif /* DOT1X_SUPPORT */
+ ))
+ {
+ /* clear GTK state */
+ pEntry->GTKState = REKEY_NEGOTIATING;
+
+ NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
+
+ /* clear this entry as no-security mode */
+ AsicRemovePairwiseKeyEntry(pAd, pEntry->Aid);
+
+#ifdef DOT1X_SUPPORT
+ /* Notify 802.1x daemon to clear this sta info */
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA ||
+ pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+ wdev->IEEE8021X)
+ DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY);
+#endif /* DOT1X_SUPPORT */
+
+#ifdef WAPI_SUPPORT
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_DISCONNECT);
+
+ RTMPCancelWapiRekeyTimerAction(pAd, pEntry);
+#endif /* WAPI_SUPPORT */
+ }
+
+#ifdef WSC_AP_SUPPORT
+ /* since sta has been left, ap should receive EapolStart and EapRspId again. */
+ pEntry->Receive_EapolStart_EapRspId = 0;
+ pEntry->bWscCapable = ie_list->bWscCapable;
+#ifdef WSC_V2_SUPPORT
+ if ((wdev->WscControl.WscV2Info.bEnableWpsV2) &&
+ (wdev->WscControl.WscV2Info.bWpsEnable == FALSE))
+ ;
+ else
+#endif /* WSC_V2_SUPPORT */
+ {
+ if (pEntry->apidx < pAd->ApCfg.BssidNum)
+ {
+ if (MAC_ADDR_EQUAL(pEntry->Addr, wdev->WscControl.EntryAddr))
+ {
+ BOOLEAN Cancelled;
+ RTMPZeroMemory(wdev->WscControl.EntryAddr, MAC_ADDR_LEN);
+ RTMPCancelTimer(&wdev->WscControl.EapolTimer, &Cancelled);
+ wdev->WscControl.EapolTimerRunning = FALSE;
+ }
+ }
+
+ if ((ie_list->RSNIE_Len == 0) &&
+ (wdev->AuthMode >= Ndis802_11AuthModeWPA) &&
+ (wdev->WscControl.WscConfMode != WSC_DISABLE))
+ pEntry->bWscCapable = TRUE;
+ }
+#endif /* WSC_AP_SUPPORT */
+
+ /* for hidden SSID sake, SSID in AssociateRequest should be fully verified */
+ if ((ie_list->SsidLen != wdev->SsidLen) ||
+ (NdisEqualMemory(ie_list->Ssid, wdev->Ssid, ie_list->SsidLen)==0))
+ goto LabelOK;
+
+#ifdef WSC_V2_SUPPORT
+ /* Do not check ACL when WPS V2 is enabled and ACL policy is positive. */
+ if ((pEntry->bWscCapable) &&
+ (wdev->WscControl.WscConfMode != WSC_DISABLE) &&
+ (wdev->WscControl.WscV2Info.bEnableWpsV2) &&
+ (wdev->WscControl.WscV2Info.bWpsEnable) &&
+ (MAC_ADDR_EQUAL(wdev->WscControl.EntryAddr, ZERO_MAC_ADDR)))
+ ;
+ else
+#endif /* WSC_V2_SUPPORT */
+ /* set a flag for sending Assoc-Fail response to unwanted STA later. */
+ if (! ApCheckAccessControlList(pAd, ie_list->Addr2, pEntry->apidx))
+ bACLReject = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - MBSS(%d), receive %s request from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ sAssoc, pEntry->apidx, sAssoc, PRINT_MAC(ie_list->Addr2)));
+
+ /* supported rates array may not be sorted. sort it and find the maximum rate */
+ for (i=0; i<ie_list->SupportedRatesLen; i++)
+ {
+ if (MaxSupportedRate < (ie_list->SupportedRates[i] & 0x7f))
+ MaxSupportedRate = ie_list->SupportedRates[i] & 0x7f;
+ }
+
+ /*
+ Assign RateLen here or we will select wrong rate table in
+ APBuildAssociation() when 11N compile option is disabled.
+ */
+ pEntry->RateLen = ie_list->SupportedRatesLen;
+
+ RTMPSetSupportMCS(pAd,
+ OPMODE_AP,
+ pEntry,
+ ie_list->SupportedRates,
+ ie_list->SupportedRatesLen,
+ NULL,
+ 0,
+#ifdef DOT11_VHT_AC
+ ie_list->vht_cap_len,
+ &ie_list->vht_cap,
+#endif /* DOT11_VHT_AC */
+ &ie_list->HTCapability,
+ ie_list->ht_cap_len);
+
+ /* 2. qualify this STA's auth_asoc status in the MAC table, decide StatusCode */
+ StatusCode = APBuildAssociation(pAd, pEntry, ie_list, MaxSupportedRate, &Aid);
+
+
+
+#ifdef DOT11_VHT_AC
+ if (ie_list->vht_cap_len)
+ {
+ VHT_CAP_INFO *vht_cap = &ie_list->vht_cap.vht_cap;
+
+//+++Add by shiang for debug
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():Peer is VHT capable device!\n", __FUNCTION__));
+ //dump_vht_cap(pAd, &ie_list->vht_cap);
+ }
+//---Add by shiang for debug
+ }
+#endif /* DOT11_VHT_AC */
+
+ if (StatusCode == MLME_ASSOC_REJ_DATA_RATE)
+ RTMPSendWirelessEvent(pAd, IW_STA_MODE_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ /* 3. send Association Response */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ goto LabelOK;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - Send %s response (Status=%d)...\n", sAssoc, sAssoc, StatusCode));
+ Aid |= 0xc000; /* 2 most significant bits should be ON */
+
+ SubType = isReassoc ? SUBTYPE_REASSOC_RSP : SUBTYPE_ASSOC_RSP;
+
+ CapabilityInfoForAssocResp = wdev->CapabilityInfo; /*use AP's cability */
+#ifdef WSC_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((wdev->WscControl.WscV2Info.bEnableWpsV2) &&
+ (wdev->WscControl.WscV2Info.bWpsEnable == FALSE))
+ ;
+ else
+#endif /* WSC_V2_SUPPORT */
+ {
+ if ((wdev->WscControl.WscConfMode != WSC_DISABLE) &&
+ (ie_list->CapabilityInfo & 0x0010))
+ {
+ CapabilityInfoForAssocResp |= 0x0010;
+ }
+ }
+#endif /* WSC_AP_SUPPORT */
+
+ /* fail in ACL checking => send an Assoc-Fail resp. */
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+
+ /* TODO: need to check rate in support rate element, not number */
+ if (FlgIs11bSta == 1)
+ SupRateLen = 4;
+
+ if (bACLReject == TRUE)
+ {
+ MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2,
+ wdev->Bssid);
+ StatusCode = MLME_UNSPECIFY_FAIL;
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AssocRspHdr,
+ 2, &CapabilityInfoForAssocResp,
+ 2, &StatusCode,
+ 2, &Aid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, pAd->CommonCfg.SupRate,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, (PVOID) pOutBuffer);
+
+ RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, ie_list->Addr2, pEntry->apidx, 0);
+
+#ifdef WSC_V2_SUPPORT
+ /* If this STA exists, delete it. */
+ if (pEntry)
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+#endif /* WSC_V2_SUPPORT */
+
+ goto LabelOK;
+ }
+
+ MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2,
+ wdev->Bssid);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AssocRspHdr,
+ 2, &CapabilityInfoForAssocResp,
+ 2, &StatusCode,
+ 2, &Aid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, pAd->CommonCfg.SupRate,
+ END_OF_ARGS);
+
+ if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B) && (FlgIs11bSta == 0))
+ {
+ ULONG TmpLen;
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &ExtRateIe,
+ 1, &pAd->CommonCfg.ExtRateLen,
+ pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+
+
+ /* add WMM IE here */
+ if (wdev->bWmmCapable && CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ {
+ ULONG TmpLen;
+ UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0};
+
+ WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f;
+#ifdef UAPSD_SUPPORT
+ UAPSD_MR_IE_FILL(WmeParmIe[8], &wdev->UapsdInfo);
+#endif /* UAPSD_SUPPORT */
+ for (i=QID_AC_BE; i<=QID_AC_VO; i++)
+ {
+ WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */
+ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */
+ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */
+ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */
+ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */
+ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */
+ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */
+ }
+
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 26, WmeParmIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+
+#ifdef DOT11_N_SUPPORT
+ /* HT capability in AssocRsp frame. */
+ if ((ie_list->ht_cap_len > 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
+ HT_CAPABILITY_IE HtCapabilityRsp;
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+ ADD_HT_INFO_IE addHTInfoTmp;
+#endif
+
+ NdisMoveMemory(&HtCapabilityRsp, &pAd->CommonCfg.HtCapability, ie_list->ht_cap_len);
+
+ /* add HT Capability IE */
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &ie_list->ht_cap_len,
+ ie_list->ht_cap_len, &HtCapabilityRsp,
+ 1, &AddHtInfoIe,
+ 1, &HtLen1,
+ HtLen1, &pAd->CommonCfg.AddHTInfo,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &HtCapabilityRsp, ie_list->ht_cap_len);
+ *(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) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+#endif /* UNALIGNMENT_SUPPORT */
+
+ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &ie_list->ht_cap_len,
+ ie_list->ht_cap_len, &HtCapabilityTmp,
+ 1, &AddHtInfoIe,
+ 1, &HtLen1,
+ HtLen1, &addHTInfoTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen += TmpLen;
+
+ if ((ie_list->RalinkIe) == 0 || (pAd->bBroadComHT == TRUE))
+ {
+ UCHAR epigram_ie_len;
+ UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33};
+ UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34};
+
+
+ epigram_ie_len = ie_list->ht_cap_len + 4;
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_HTC[0],
+ ie_list->ht_cap_len, &HtCapabilityRsp,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_HTC[0],
+ ie_list->ht_cap_len, &HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+
+ FrameLen += TmpLen;
+ epigram_ie_len = HtLen1 + 4;
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_AHTINFO[0],
+ HtLen1, &pAd->CommonCfg.AddHTInfo,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_AHTINFO[0],
+ HtLen1, &addHTInfoTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen += TmpLen;
+ }
+
+#ifdef DOT11N_DRAFT3
+ /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) &&
+ (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
+ {
+ OVERLAP_BSS_SCAN_IE OverlapScanParam;
+ ULONG TmpLen;
+ UCHAR OverlapScanIE, ScanIELen;
+
+ OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM;
+ ScanIELen = 14;
+ OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell);
+ OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell);
+ OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt);
+ OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel);
+ OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel);
+ OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
+ OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre);
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &OverlapScanIE,
+ 1, &ScanIELen,
+ ScanIELen, &OverlapScanParam,
+ END_OF_ARGS);
+
+ FrameLen += TmpLen;
+ }
+#endif /* DOT11N_DRAFT3 */
+
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) &&
+ (pAd->CommonCfg.Channel > 14) &&
+ (ie_list->vht_cap_len))
+ {
+ FrameLen += build_vht_ies(pAd, pOutBuffer + FrameLen, SUBTYPE_ASSOC_RSP);
+ }
+#endif /* DOT11_VHT_AC */
+ }
+#endif /* DOT11_N_SUPPORT */
+
+
+ /* 7.3.2.27 Extended Capabilities IE */
+ {
+ ULONG TmpLen, infoPos;
+ PUCHAR pInfo;
+ UCHAR extInfoLen;
+ BOOLEAN bNeedAppendExtIE = FALSE;
+ EXT_CAP_INFO_ELEMENT extCapInfo;
+
+
+ extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT);
+ NdisZeroMemory(&extCapInfo, extInfoLen);
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ /* P802.11n_D1.10, HT Information Exchange Support */
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)
+ && (pAd->CommonCfg.Channel <= 14)
+ && (pAd->CommonCfg.bBssCoexEnable == TRUE)
+ )
+ {
+ extCapInfo.BssCoexistMgmtSupport = 1;
+ }
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+
+ pInfo = (PUCHAR)(&extCapInfo);
+ for (infoPos = 0; infoPos < extInfoLen; infoPos++)
+ {
+ if (pInfo[infoPos] != 0)
+ {
+ bNeedAppendExtIE = TRUE;
+ break;
+ }
+ }
+
+ if (bNeedAppendExtIE == TRUE)
+ {
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &ExtCapIe,
+ 1, &extInfoLen,
+ extInfoLen, &extCapInfo,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ }
+
+ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back */
+{
+ ULONG TmpLen;
+ UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00};
+
+ if (pAd->CommonCfg.bAggregationCapable)
+ RalinkSpecificIe[5] |= 0x1;
+ if (pAd->CommonCfg.bPiggyBackCapable)
+ RalinkSpecificIe[5] |= 0x2;
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.bRdg)
+ RalinkSpecificIe[5] |= 0x4;
+#endif /* DOT11_N_SUPPORT */
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkSpecificIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+
+}
+
+#ifdef WSC_AP_SUPPORT
+ if (pEntry->bWscCapable)
+ {
+ UCHAR *pWscBuf = NULL, WscIeLen = 0;
+ ULONG WscTmpLen = 0;
+
+ os_alloc_mem(NULL, (UCHAR **)&pWscBuf, 512);
+ if(pWscBuf)
+ {
+ NdisZeroMemory(pWscBuf, 512);
+ WscBuildAssocRespIE(pAd, pEntry->apidx, 0, pWscBuf, &WscIeLen);
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen,
+ WscIeLen, pWscBuf,
+ END_OF_ARGS);
+
+ FrameLen += WscTmpLen;
+ os_free_mem(NULL, pWscBuf);
+ }
+ }
+#endif /* WSC_AP_SUPPORT */
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, (PVOID) pOutBuffer);
+
+
+ /* set up BA session */
+ if (StatusCode == MLME_SUCCESS)
+ {
+ pEntry->PsMode = PWR_ACTIVE;
+
+#ifdef IAPP_SUPPORT
+ /*PFRAME_802_11 Fr = (PFRAME_802_11)Elem->Msg; */
+/* POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; */
+
+ /* send association ok message to IAPPD */
+
+ IAPP_L2_Update_Frame_Send(pAd, pEntry->Addr, pEntry->apidx);
+ DBGPRINT(RT_DEBUG_TRACE, ("####### Send L2 Frame Mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ PRINT_MAC(pEntry->Addr)));
+
+/* SendSingalToDaemon(SIGUSR2, pObj->IappPid); */
+
+
+#endif /* IAPP_SUPPORT */
+
+ ap_assoc_info_debugshow(pAd, isReassoc, pEntry, ie_list);
+
+ /* send wireless event - for association */
+ RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pEntry->Addr, 0, 0);
+
+ /* This is a reassociation procedure */
+ pEntry->IsReassocSta = isReassoc;
+
+#ifdef DOT11_N_SUPPORT
+ /* clear txBA bitmap */
+ pEntry->TXBAbitmap = 0;
+ if (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ if ((pAd->CommonCfg.Channel <=14) &&
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset &&
+ (ie_list->HTCapability.HtCapInfo.ChannelWidth==BW_40))
+ {
+ SendBeaconRequest(pAd, pEntry->Aid);
+ }
+ /*BAOriSessionSetUp(pAd, pEntry, 0, 0, 3000, FALSE); */
+ }
+#endif /* DOT11_N_SUPPORT */
+
+
+ /* enqueue a EAPOL_START message to trigger EAP state machine doing the authentication */
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+#ifdef WSC_AP_SUPPORT
+ /*
+ In WPA-PSK mode,
+ If Association Request of station has RSN/SSN, WPS AP Must Not send EAP-Request/Identity to station
+ no matter WPS AP does receive EAPoL-Start from STA or not.
+ Marvell WPS test bed(v2.1.1.5) will send AssocReq with WPS IE and RSN/SSN IE.
+ */
+ if (pEntry->bWscCapable || (ie_list->RSNIE_Len == 0))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - IF(ra%d) This is a WPS Client.\n\n", pEntry->apidx));
+ goto LabelOK;
+ }
+ else
+ {
+ pEntry->bWscCapable = FALSE;
+ pEntry->Receive_EapolStart_EapRspId = (WSC_ENTRY_GET_EAPOL_START | WSC_ENTRY_GET_EAP_RSP_ID);
+ /* This STA is not a WPS STA */
+ NdisZeroMemory(wdev->WscControl.EntryAddr, 6);
+ }
+#endif /* WSC_AP_SUPPORT */
+
+ /* Enqueue a EAPOL-start message with the pEntry for WPAPSK State Machine */
+ if ((pEntry->EnqueueEapolStartTimerRunning == EAPOL_START_DISABLE
+#ifdef HOSTAPD_SUPPORT
+ && wdev->Hostapd == FALSE
+#endif/*HOSTAPD_SUPPORT*/
+ )
+#ifdef WSC_AP_SUPPORT
+ && !pEntry->bWscCapable
+#endif /* WSC_AP_SUPPORT */
+ )
+ {
+ /* Enqueue a EAPOL-start message with the pEntry */
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_PSK;
+ RTMPSetTimer(&pEntry->EnqueueStartForPSKTimer, ENQUEUE_EAPOL_START_TIMER);
+ }
+ }
+#ifdef DOT1X_SUPPORT
+ /*else if (isReassoc && */
+ else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) &&
+ ((pPmkid = WPA_ExtractSuiteFromRSNIE(ie_list->RSN_IE, ie_list->RSNIE_Len, PMKID_LIST, &pmkid_count)) != NULL))
+ { /* Key cache */
+ INT CacheIdx;
+
+ if (((CacheIdx = RTMPSearchPMKIDCache(pAd, pEntry->apidx, pEntry->Addr)) != -1)
+ && (RTMPEqualMemory(pPmkid, &wdev->PMKIDCache.BSSIDInfo[CacheIdx].PMKID, LEN_PMKID)))
+ {
+ /* Enqueue a EAPOL-start message with the pEntry for WPAPSK State Machine */
+ if ((pEntry->EnqueueEapolStartTimerRunning == EAPOL_START_DISABLE
+#ifdef HOSTAPD_SUPPORT
+ && wdev->Hostapd == FALSE
+#endif /*HOSTAPD_SUPPORT*/
+ )
+#ifdef WSC_AP_SUPPORT
+ && !pEntry->bWscCapable
+#endif /* WSC_AP_SUPPORT */
+ )
+ {
+ /* Enqueue a EAPOL-start message with the pEntry */
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_PSK;
+ RTMPSetTimer(&pEntry->EnqueueStartForPSKTimer, ENQUEUE_EAPOL_START_TIMER);
+ }
+
+ pEntry->PMKID_CacheIdx = CacheIdx;
+ DBGPRINT(RT_DEBUG_ERROR, ("ASSOC - 2.PMKID matched and start key cache algorithm\n"));
+ }
+ else
+ {
+ pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
+ DBGPRINT(RT_DEBUG_ERROR, ("ASSOC - 2.PMKID not found \n"));
+ }
+ }
+ else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) ||
+ (pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+ ((wdev->IEEE8021X)
+#ifdef WSC_AP_SUPPORT
+ && (!pEntry->bWscCapable)
+#endif /* WSC_AP_SUPPORT */
+ )
+ )
+ {
+ /* Enqueue a EAPOL-start message to trigger EAP SM */
+ if (pEntry->EnqueueEapolStartTimerRunning == EAPOL_START_DISABLE
+#ifdef HOSTAPD_SUPPORT
+ && wdev->Hostapd == FALSE
+#endif/*HOSTAPD_SUPPORT*/
+ )
+ {
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_1X;
+ RTMPSetTimer(&pEntry->EnqueueStartForPSKTimer, ENQUEUE_EAPOL_START_TIMER);
+ }
+ }
+#endif /* DOT1X_SUPPORT */
+#ifdef WAPI_SUPPORT
+ else if (pEntry->AuthMode == Ndis802_11AuthModeWAICERT)
+ {
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_CERT_AUTH_START);
+
+ RTMPInitWapiRekeyTimerAction(pAd, pEntry);
+ }
+ else if (pEntry->AuthMode == Ndis802_11AuthModeWAIPSK)
+ {
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_KEY_HS_START);
+ RTMPInitWapiRekeyTimerAction(pAd, pEntry);
+ }
+#endif /* WAPI_SUPPORT */
+ else
+ {
+ if (pEntry->WepStatus == Ndis802_11WEPEnabled)
+ {
+ /* Set WEP key to ASIC */
+ UCHAR KeyIdx = 0;
+ UCHAR CipherAlg = 0;
+
+ KeyIdx = wdev->DefaultKeyId;
+ CipherAlg = pAd->SharedKey[pEntry->apidx][KeyIdx].CipherAlg;
+
+ /*
+ If WEP is used, set pair-wise cipherAlg into WCID
+ attribute table for this entry.
+ */
+ RTMP_SET_WCID_SEC_INFO(pAd,
+ pEntry->apidx,
+ KeyIdx,
+ CipherAlg,
+ pEntry->Aid,
+ SHAREDKEYTABLE);
+ }
+ }
+
+ }
+
+LabelOK:
+ if (ie_list != NULL)
+ os_free_mem(NULL, ie_list);
+
+ return;
+}
+
+
+
+/*
+ ==========================================================================
+ Description:
+ peer assoc req handling procedure
+ Parameters:
+ Adapter - Adapter pointer
+ Elem - MLME Queue Element
+ Pre:
+ the station has been authenticated and the following information is stored
+ Post :
+ -# An association response frame is generated and sent to the air
+ ==========================================================================
+ */
+VOID APPeerAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ ap_cmm_peer_assoc_req_action(pAd, Elem, 0);
+}
+
+/*
+ ==========================================================================
+ Description:
+ mlme reassoc req handling procedure
+ Parameters:
+ Elem -
+ Pre:
+ -# SSID (Adapter->ApCfg.ssid[])
+ -# BSSID (AP address, Adapter->ApCfg.bssid)
+ -# Supported rates (Adapter->ApCfg.supported_rates[])
+ -# Supported rates length (Adapter->ApCfg.supported_rates_len)
+ -# Tx power (Adapter->ApCfg.tx_power)
+ ==========================================================================
+ */
+VOID APPeerReassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ ap_cmm_peer_assoc_req_action(pAd, Elem, 1);
+}
+
+/*
+ ==========================================================================
+ Description:
+ left part of IEEE 802.11/1999 p.374
+ Parameters:
+ Elem - MLME message containing the received frame
+ ==========================================================================
+ */
+VOID APPeerDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Reason;
+ UINT16 SeqNum;
+ MAC_TABLE_ENTRY *pEntry;
+ MULTISSID_STRUCT *wdev;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - 1 receive DIS-ASSOC request \n"));
+ if (! PeerDisassocReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &SeqNum, &Reason))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive DIS-ASSOC(seq-%d) request from %02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n",
+ SeqNum, Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5],Reason));
+
+ pEntry = MacTableLookup(pAd, Addr2);
+
+ if (pEntry == NULL)
+ return;
+
+ if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+
+#ifdef DOT1X_SUPPORT
+ wdev = &pAd->ApCfg.MBSSID[pEntry->apidx];
+ /* Notify 802.1x daemon to clear this sta info */
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA ||
+ pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+ wdev->IEEE8021X)
+ DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY);
+#endif /* DOT1X_SUPPORT */
+
+#ifdef WAPI_SUPPORT
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_DISCONNECT);
+#endif /* WAPI_SUPPORT */
+
+ /* send wireless event - for disassociation */
+ RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, Addr2, 0, 0);
+ ApLogEvent(pAd, Addr2, EVENT_DISASSOCIATED);
+
+ MacTableDeleteEntry(pAd, Elem->Wcid, Addr2);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ delete it from STA and disassoc s STA
+ Parameters:
+ Elem -
+ ==========================================================================
+ */
+VOID MbssKickOutStas(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN USHORT Reason)
+{
+ INT i;
+ PMAC_TABLE_ENTRY pEntry;
+
+ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (pEntry && IS_ENTRY_CLIENT(pEntry) && pEntry->apidx == apidx)
+ APMlmeKickOutSta(pAd, pEntry->Addr, pEntry->Aid, Reason);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ delete it from STA and disassoc s STA
+ Parameters:
+ Elem -
+ ==========================================================================
+ */
+VOID APMlmeKickOutSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pStaAddr,
+ IN UCHAR Wcid,
+ IN USHORT Reason)
+{
+ HEADER_802_11 DisassocHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR Aid;
+ UCHAR ApIdx;
+
+ pEntry = MacTableLookup(pAd, pStaAddr);
+
+ if (pEntry == NULL)
+ {
+ return;
+ }
+ Aid = pEntry->Aid;
+ ApIdx = pEntry->apidx;
+
+ ASSERT(Aid == Wcid);
+
+ if (ApIdx >= pAd->ApCfg.BssidNum)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Invalid Apidx=%d\n",
+ __FUNCTION__, ApIdx));
+ return;
+ }
+
+ if (Aid < MAX_LEN_OF_MAC_TABLE)
+ {
+ /* send wireless event - for disassocation */
+ RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pStaAddr, 0, 0);
+ ApLogEvent(pAd, pStaAddr, EVENT_DISASSOCIATED);
+
+ /* 2. send out a DISASSOC request frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MLME disassociates %02x:%02x:%02x:%02x:%02x:%02x; Send DISASSOC request\n",
+ pStaAddr[0],pStaAddr[1],pStaAddr[2], pStaAddr[3],pStaAddr[4],pStaAddr[5]));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pStaAddr,
+ pAd->ApCfg.MBSSID[ApIdx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DisassocHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ MacTableDeleteEntry(pAd, Aid, pStaAddr);
+ }
+}
+
+
+
+
+/*
+ ==========================================================================
+ Description:
+ Upper layer orders to disassoc s STA
+ Parameters:
+ Elem -
+ ==========================================================================
+ */
+VOID APMlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DISASSOC_REQ_STRUCT *DisassocReq = (MLME_DISASSOC_REQ_STRUCT *)(Elem->Msg);
+
+ APMlmeKickOutSta(pAd, DisassocReq->Addr, Elem->Wcid, DisassocReq->Reason);
+}
+
+
+/*
+ ==========================================================================
+ 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.
+ ==========================================================================
+ */
+VOID APCls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader)
+{
+ HEADER_802_11 DisassocHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ USHORT Reason = REASON_CLS3ERR;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ pEntry = &(pAd->MacTab.Content[Wcid]);
+ }
+
+ if (pEntry)
+ {
+ /*ApLogEvent(pAd, pAddr, EVENT_DISASSOCIATED); */
+ MacTableDeleteEntry(pAd, pEntry->Aid, pHeader->Addr2);
+ }
+
+ /* 2. send out a DISASSOC request frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame to %02x:%02x:%02x:%02x:%02x:%02x\n",
+ PRINT_MAC(pHeader->Addr2)));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pHeader->Addr2,
+ pHeader->Addr1);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DisassocHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+
+/*
+ ==========================================================================
+ 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
+
+ AP_ASSOC_IDLE
+ APMT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
+ APMT2_PEER_DISASSOC_REQ peer_disassoc_action
+ APMT2_PEER_ASSOC_REQ drop
+ APMT2_PEER_REASSOC_REQ drop
+ APMT2_CLS3ERR cls3err_action
+ ==========================================================================
+ */
+VOID APAssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, AP_MAX_ASSOC_STATE, AP_MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, AP_ASSOC_IDLE, AP_ASSOC_MACHINE_BASE);
+
+ StateMachineSetAction(S, AP_ASSOC_IDLE, APMT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)APMlmeDisassocReqAction);
+ StateMachineSetAction(S, AP_ASSOC_IDLE, APMT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)APPeerDisassocReqAction);
+ StateMachineSetAction(S, AP_ASSOC_IDLE, APMT2_PEER_ASSOC_REQ, (STATE_MACHINE_FUNC)APPeerAssocReqAction);
+ StateMachineSetAction(S, AP_ASSOC_IDLE, APMT2_PEER_REASSOC_REQ, (STATE_MACHINE_FUNC)APPeerReassocReqAction);
+/* StateMachineSetAction(S, AP_ASSOC_IDLE, APMT2_CLS3ERR, APCls3errAction); */
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_auth.c b/cleopatre/devkit/mt7601udrv/ap/ap_auth.c
new file mode 100644
index 0000000000..a276991163
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_auth.c
@@ -0,0 +1,627 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ auth.c
+
+ Abstract:
+ Handle de-auth request from local MLME
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 08-04-2003 created for 11g soft-AP
+ */
+
+#include "rt_config.h"
+
+static VOID APMlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID APPeerDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID APPeerAuthReqAtIdleAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID APPeerAuthConfirmAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID APPeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr80211,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT StatusCode);
+
+/*
+ ==========================================================================
+ 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
+
+ AP_AUTH_REQ_IDLE
+ APMT2_MLME_DEAUTH_REQ mlme_deauth_req_action
+ ==========================================================================
+ */
+void APAuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, (STATE_MACHINE_FUNC *)Trans, AP_MAX_AUTH_STATE,
+ AP_MAX_AUTH_MSG, (STATE_MACHINE_FUNC)Drop,
+ AP_AUTH_REQ_IDLE, AP_AUTH_MACHINE_BASE);
+
+ /* the first column */
+ StateMachineSetAction(Sm, AP_AUTH_REQ_IDLE, APMT2_MLME_DEAUTH_REQ,
+ (STATE_MACHINE_FUNC)APMlmeDeauthReqAction);
+ StateMachineSetAction(Sm, AP_AUTH_REQ_IDLE, APMT2_PEER_DEAUTH,
+ (STATE_MACHINE_FUNC)APPeerDeauthReqAction);
+ StateMachineSetAction(Sm, AP_AUTH_REQ_IDLE, APMT2_PEER_AUTH_REQ,
+ (STATE_MACHINE_FUNC)APPeerAuthReqAtIdleAction);
+ StateMachineSetAction(Sm, AP_AUTH_REQ_IDLE, APMT2_PEER_AUTH_CONFIRM,
+ (STATE_MACHINE_FUNC)APPeerAuthConfirmAction);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Upper Layer request to kick out a STA
+ ==========================================================================
+ */
+static VOID APMlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DEAUTH_REQ_STRUCT *pInfo;
+ HEADER_802_11 Hdr;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR apidx;
+
+
+ pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg;
+
+ if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ pEntry = &pAd->MacTab.Content[Elem->Wcid];
+ if (!pEntry)
+ return;
+
+#ifdef WAPI_SUPPORT
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_DISCONNECT);
+#endif /* WAPI_SUPPORT */
+
+ /* send wireless event - for deauthentication */
+ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pInfo->Addr, 0, 0);
+ ApLogEvent(pAd, pInfo->Addr, EVENT_DISASSOCIATED);
+
+ apidx = pEntry->apidx;
+
+ /* 1. remove this STA from MAC table */
+ MacTableDeleteEntry(pAd, Elem->Wcid, pInfo->Addr);
+
+ /* 2. send out DE-AUTH request frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("AUTH - Send DE-AUTH req to %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pInfo->Addr[0], pInfo->Addr[1], pInfo->Addr[2],
+ pInfo->Addr[3], pInfo->Addr[4], pInfo->Addr[5]));
+
+ MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pInfo->Addr,
+ pAd->ApCfg.MBSSID[apidx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr,
+ 2, &pInfo->Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+}
+
+
+static VOID APPeerDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMLME_QUEUE_ELEM Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Reason;
+ UINT16 SeqNum;
+ MAC_TABLE_ENTRY *pEntry;
+
+
+
+ if (! PeerDeauthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &SeqNum, &Reason))
+ return;
+
+ pEntry = NULL;
+
+ /*pEntry = MacTableLookup(pAd, Addr2); */
+ if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ pEntry = &pAd->MacTab.Content[Elem->Wcid];
+
+#ifdef DOT1X_SUPPORT
+ /* Notify 802.1x daemon to clear this sta info */
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA ||
+ pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+ pAd->ApCfg.MBSSID[pEntry->apidx].IEEE8021X)
+ DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY);
+#endif /* DOT1X_SUPPORT */
+
+#ifdef WAPI_SUPPORT
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_DISCONNECT);
+#endif /* WAPI_SUPPORT */
+
+ /* send wireless event - for deauthentication */
+ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, Addr2, 0, 0);
+ ApLogEvent(pAd, Addr2, EVENT_DISASSOCIATED);
+
+ if (pEntry->CMTimerRunning == TRUE)
+ {
+ /*
+ If one who initilized Counter Measure deauth itself,
+ AP doesn't log the MICFailTime
+ */
+ pAd->ApCfg.aMICFailTime = pAd->ApCfg.PrevaMICFailTime;
+ }
+
+ MacTableDeleteEntry(pAd, Elem->Wcid, Addr2);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("AUTH - receive DE-AUTH(seq-%d) from "
+ "%02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n", SeqNum,
+ Addr2[0], Addr2[1], Addr2[2], Addr2[3], Addr2[4], Addr2[5], Reason));
+ }
+}
+
+
+static VOID APPeerAuthReqAtIdleAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ INT i;
+ USHORT Seq, Alg, RspReason, Status;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ CHAR Chtxt[CIPHER_TEXT_LEN];
+ UINT32 apidx;
+
+ PHEADER_802_11 pRcvHdr;
+ HEADER_802_11 AuthHdr;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN;
+
+
+
+ if (! APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1,
+ Addr2, &Alg, &Seq, &Status, Chtxt
+ ))
+ return;
+
+
+ /* Find which MBSSID to be authenticate */
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ if (RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN))
+ break;
+ }
+
+ if (apidx >= pAd->ApCfg.BssidNum)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n"));
+ return;
+ }
+
+ if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) &&
+ !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n"));
+ return;
+ } /* End of if */
+
+
+ pEntry = MacTableLookup(pAd, Addr2);
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ {
+
+ if (!RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, MAC_ADDR_LEN))
+ {
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n"));
+ }
+ else
+ {
+ if (pEntry->bIAmBadAtheros == TRUE)
+ {
+ AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE);
+ DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n"));
+ pEntry->bIAmBadAtheros = FALSE;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ BASessionTearDownALL(pAd, pEntry->Aid);
+#endif /* DOT11_N_SUPPORT */
+ ASSERT(pEntry->Aid == Elem->Wcid);
+ }
+ }
+
+
+ pRcvHdr = (PHEADER_802_11)(Elem->Msg);
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from "
+ "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n",
+ apidx, Seq, Alg, Status, Elem->Wcid, PRINT_MAC(Addr2)));
+
+
+#ifdef WSC_V2_SUPPORT
+ /* Do not check ACL when WPS V2 is enabled and ACL policy is positive. */
+ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) &&
+ (pAd->ApCfg.MBSSID[apidx].WscControl.WscV2Info.bEnableWpsV2) &&
+ (pAd->ApCfg.MBSSID[apidx].WscControl.WscV2Info.bWpsEnable) &&
+ (pAd->ApCfg.MBSSID[apidx].AccessControlList.Policy == 1))
+ ;
+ else
+#endif /* WSC_V2_SUPPORT */
+ /* fail in ACL checking => send an AUTH-Fail seq#2. */
+ if (! ApCheckAccessControlList(pAd, Addr2, apidx))
+ {
+ ASSERT(Seq == 1);
+ ASSERT(pEntry == NULL);
+ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL);
+
+ /* If this STA exists, delete it. */
+ if (pEntry)
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+
+ RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("Failed in ACL checking => send an AUTH seq#2 with "
+ "Status code = %d\n", MLME_UNSPECIFY_FAIL));
+ return;
+ }
+
+ if ((Alg == AUTH_MODE_OPEN) &&
+ (pAd->ApCfg.MBSSID[apidx].AuthMode != Ndis802_11AuthModeShared))
+ {
+ if (!pEntry)
+ pEntry = MacTableInsertEntry(pAd, Addr2, apidx, OPMODE_AP, TRUE);
+
+ if (pEntry)
+ {
+ {
+ pEntry->AuthState = AS_AUTH_OPEN;
+ pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */
+ }
+ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_SUCCESS);
+
+ }
+ else
+ ; /* MAC table full, what should we respond ????? */
+ }
+ else if ((Alg == AUTH_MODE_KEY) &&
+ ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeShared)
+ || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeAutoSwitch)))
+ {
+ if (!pEntry)
+ pEntry = MacTableInsertEntry(pAd, Addr2, apidx, OPMODE_AP, TRUE);
+
+ if (pEntry)
+ {
+ pEntry->AuthState = AS_AUTHENTICATING;
+ pEntry->Sst = SST_NOT_AUTH; /* what if it already in SST_ASSOC ??????? */
+
+ /* log this STA in AuthRspAux machine, only one STA is stored. If two STAs using */
+ /* SHARED_KEY authentication mingled together, then the late comer will win. */
+ COPY_MAC_ADDR(&pAd->ApMlmeAux.Addr, Addr2);
+ for(i=0; i<CIPHER_TEXT_LEN; i++)
+ pAd->ApMlmeAux.Challenge[i] = RandomByte(pAd);
+
+ RspReason = 0;
+ Seq++;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ return; /* if no memory, can't do anything */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH seq#2 (Challenge)\n"));
+
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2,
+ pAd->ApCfg.MBSSID[apidx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AuthHdr,
+ 2, &Alg,
+ 2, &Seq,
+ 2, &RspReason,
+ 1, &ChTxtIe,
+ 1, &ChTxtLen,
+ CIPHER_TEXT_LEN, pAd->ApMlmeAux.Challenge,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ else
+ ; /* MAC table full, what should we respond ???? */
+ }
+ else
+ {
+ /* wrong algorithm */
+ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_ALG_NOT_SUPPORT);
+
+ /* If this STA exists, delete it. */
+ if (pEntry)
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Alg=%d, Seq=%d, AuthMode=%d\n",
+ Alg, Seq, pAd->ApCfg.MBSSID[apidx].AuthMode));
+ }
+}
+
+
+static VOID APPeerAuthConfirmAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Seq, Alg, Status;
+ UCHAR Addr2[MAC_ADDR_LEN];
+ PHEADER_802_11 pRcvHdr;
+ CHAR Chtxt[CIPHER_TEXT_LEN];
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UINT32 apidx;
+
+
+
+
+ if (! APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1,
+ Addr2, &Alg, &Seq, &Status, Chtxt
+ ))
+ return;
+
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ if (RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN))
+ break;
+ }
+
+ if (apidx >= pAd->ApCfg.BssidNum)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n"));
+ return;
+ }
+
+ if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) &&
+ !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n"));
+ return;
+ } /* End of if */
+
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("AUTH - Invalid wcid (%d).\n", Elem->Wcid));
+ return;
+ }
+
+ pEntry = &pAd->MacTab.Content[Elem->Wcid];
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ {
+ if (!RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, MAC_ADDR_LEN))
+ {
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n"));
+ }
+ else
+ {
+ if (pEntry->bIAmBadAtheros == TRUE)
+ {
+ AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE);
+ DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n"));
+ pEntry->bIAmBadAtheros = FALSE;
+ }
+#ifdef DOT11_N_SUPPORT
+ BASessionTearDownALL(pAd, pEntry->Aid);
+#endif /* DOT11_N_SUPPORT */
+ ASSERT(pEntry->Aid == Elem->Wcid);
+ }
+ }
+
+ pRcvHdr = (PHEADER_802_11)(Elem->Msg);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from "
+ "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n",
+ apidx, Seq, Alg, Status, Elem->Wcid, PRINT_MAC(Addr2)));
+
+ if (pEntry && MAC_ADDR_EQUAL(Addr2, pAd->ApMlmeAux.Addr))
+ {
+ if ((pRcvHdr->FC.Wep == 1) &&
+ NdisEqualMemory(Chtxt, pAd->ApMlmeAux.Challenge, CIPHER_TEXT_LEN))
+ {
+ /* Successful */
+ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_SUCCESS);
+ pEntry->AuthState = AS_AUTH_KEY;
+ pEntry->Sst = SST_AUTH;
+ }
+ else
+ {
+
+ /* send wireless event - Authentication rejected because of challenge failure */
+ RTMPSendWirelessEvent(pAd, IW_AUTH_REJECT_CHALLENGE_FAILURE, pEntry->Addr, 0, 0);
+
+ /* fail - wep bit is not set or challenge text is not equal */
+ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_REJ_CHALLENGE_FAILURE);
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+
+ /*Chtxt[127]='\0'; */
+ /*pAd->ApMlmeAux.Challenge[127]='\0'; */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("%s\n", ((pRcvHdr->FC.Wep == 1) ? "challenge text is not equal" : "wep bit is not set")));
+ /*DBGPRINT(RT_DEBUG_TRACE, ("Sent Challenge = %s\n",&pAd->ApMlmeAux.Challenge[100])); */
+ /*DBGPRINT(RT_DEBUG_TRACE, ("Rcv Challenge = %s\n",&Chtxt[100])); */
+ }
+ }
+ else
+ {
+ /* fail for unknown reason. most likely is AuthRspAux machine be overwritten by another */
+ /* STA also using SHARED_KEY authentication */
+ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL);
+
+ /* If this STA exists, delete it. */
+ if (pEntry)
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ }
+}
+
+
+/*
+ ==========================================================================
+ 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
+ ==========================================================================
+ */
+VOID APCls2errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader)
+{
+ HEADER_802_11 Hdr;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT Reason = REASON_CLS2ERR;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ pEntry = &(pAd->MacTab.Content[Wcid]);
+ }
+
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ {
+ /*ApLogEvent(pAd, pAddr, EVENT_DISASSOCIATED); */
+ MacTableDeleteEntry(pAd, pEntry->Aid, pHeader->Addr2);
+ }
+ else
+ {
+ UCHAR bssid[MAC_ADDR_LEN];
+
+ NdisMoveMemory(bssid, pHeader->Addr1, MAC_ADDR_LEN);
+ bssid[5] &= pAd->ApCfg.MacMask;
+
+ if (NdisEqualMemory(pAd->CurrentAddress, bssid, MAC_ADDR_LEN) == 0)
+ return;
+ }
+
+ /* send out DEAUTH request frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("AUTH - Class 2 error, Send DEAUTH frame to "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ PRINT_MAC(pHeader->Addr2)));
+
+ MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pHeader->Addr2,
+ pHeader->Addr1);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Send out a Authentication (response) frame
+ ==========================================================================
+*/
+VOID APPeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT StatusCode)
+{
+ HEADER_802_11 AuthHdr;
+ ULONG FrameLen = 0;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ if (StatusCode == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH_RSP - Send AUTH response (SUCCESS)...\n"));
+ }
+ else
+ {
+ /* For MAC wireless client(Macintosh), need to send AUTH_RSP with Status Code (fail reason code) to reject it. */
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH_RSP - Peer AUTH fail (Status = %d)...\n", StatusCode));
+ }
+
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr->Addr2,
+ pHdr->Addr1);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AuthHdr,
+ 2, &Alg,
+ 2, &Seq,
+ 2, &StatusCode,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/* End of ap_auth.c */
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_autoChSel.c b/cleopatre/devkit/mt7601udrv/ap/ap_autoChSel.c
new file mode 100644
index 0000000000..016224bfcc
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_autoChSel.c
@@ -0,0 +1,1091 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+
+ Abstract:
+*/
+
+
+#include "rt_config.h"
+#include "ap_autoChSel.h"
+
+
+extern UCHAR ZeroSsid[32];
+
+static inline INT GetABandChOffset(
+ IN INT Channel)
+{
+#ifdef A_BAND_SUPPORT
+ if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
+ (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
+ {
+ return 1;
+ }
+ else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
+ (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
+ {
+ return -1;
+ }
+#endif /* A_BAND_SUPPORT */
+ return 0;
+}
+
+ULONG AutoChBssSearchWithSSID(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR Bssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+ PBSSINFO pBssInfoTab = pAd->pBssInfoTab;
+
+ if(pBssInfoTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pBssInfoTab equal NULL.\n"));
+ return (ULONG)BSS_NOT_FOUND;
+ }
+
+ for (i = 0; i < pBssInfoTab->BssNr; i++)
+ {
+ if ((((pBssInfoTab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((pBssInfoTab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(&(pBssInfoTab->BssEntry[i].Bssid), Bssid) &&
+ (SSID_EQUAL(pSsid, SsidLen, pBssInfoTab->BssEntry[i].Ssid, pBssInfoTab->BssEntry[i].SsidLen) ||
+ (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
+ (NdisEqualMemory(pBssInfoTab->BssEntry[i].Ssid, ZeroSsid, pBssInfoTab->BssEntry[i].SsidLen))))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+static inline VOID AutoChBssEntrySet(
+ OUT BSSENTRY *pBss,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR Channel,
+ IN UCHAR ExtChOffset,
+ IN CHAR Rssi)
+{
+ COPY_MAC_ADDR(pBss->Bssid, pBssid);
+ 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)
+ {
+ NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
+ pBss->SsidLen = SsidLen;
+ }
+ }
+
+ pBss->Channel = Channel;
+ pBss->ExtChOffset = ExtChOffset;
+ pBss->Rssi = Rssi;
+
+ return;
+}
+
+static inline VOID AutoChBssTableReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->pBssInfoTab)
+ NdisZeroMemory(pAd->pBssInfoTab, sizeof(BSSINFO));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pBssInfoTab equal NULL.\n"));
+
+ return;
+}
+
+static VOID ChannelInfoReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->pChannelInfo)
+ NdisZeroMemory(pAd->pChannelInfo, sizeof(CHANNELINFO));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pChannelInfo equal NULL.\n"));
+
+ return;
+}
+
+VOID UpdateChannelInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN int ch_index,
+ IN ChannelSel_Alg Alg)
+{
+ if(pAd->pChannelInfo != NULL)
+ {
+ UINT32 BusyTime;
+
+ if ( Alg == ChannelAlgCCA )
+ {
+ RX_STA_CNT1_STRUC RxStaCnt1;
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
+ pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
+ pAd->pChannelInfo->FalseCCA[ch_index] = RxStaCnt1.field.FalseCca;
+ }
+
+
+ /*
+ do busy time statistics for primary channel
+ scan time 400ms, beacon interval 100 ms
+ */
+
+ RTMP_IO_READ32(pAd, CH_BUSY_STA, &BusyTime);
+#ifdef AP_QLOAD_SUPPORT
+ pAd->pChannelInfo->chanbusytime[ch_index] = (BusyTime * 100) / AUTO_CHANNEL_SEL_TIMEOUT;
+#endif /* AP_QLOAD_SUPPORT */
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pChannelInfo equal NULL.\n"));
+
+ return;
+}
+
+static inline INT GetChIdx(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ INT Idx;
+
+ Idx = -1;
+ for (Idx = 0; Idx < pAd->ChannelListNum; Idx++)
+ {
+ if (Channel == pAd->ChannelList[Idx].Channel)
+ break;
+ }
+
+ return Idx;
+}
+
+static inline VOID AutoChannelSkipListSetDirty(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+ for (i=0; i < pAd->ApCfg.AutoChannelSkipListNum ; i++)
+ {
+ UCHAR channel_idx = GetChIdx(pAd, pAd->ApCfg.AutoChannelSkipList[i]);
+ if ( channel_idx != pAd->ChannelListNum )
+ {
+ pAd->pChannelInfo->SkipList[channel_idx] = TRUE;
+ }
+ }
+}
+
+static inline BOOLEAN AutoChannelSkipListCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ch)
+{
+ UCHAR i;
+ BOOLEAN result = FALSE;
+
+ for (i=0; i < pAd->ApCfg.AutoChannelSkipListNum ; i++)
+ {
+ if (Ch == pAd->ApCfg.AutoChannelSkipList[i])
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ return result;
+}
+
+static inline BOOLEAN BW40_ChannelCheck(
+ IN UCHAR ch)
+{
+ INT i;
+ BOOLEAN result = TRUE;
+ UCHAR NorBW40_CH[] = {140, 165};
+ UCHAR NorBW40ChNum = sizeof(NorBW40_CH) / sizeof(UCHAR);
+
+ for (i=0; i<NorBW40ChNum; i++)
+ {
+ if (ch == NorBW40_CH[i])
+ {
+ result = FALSE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+static inline UCHAR SelectClearChannelRandom(
+ IN PRTMP_ADAPTER pAd
+ )
+{
+ UCHAR cnt, ch = 0, i, RadomIdx;
+ /*BOOLEAN bFindIt = FALSE;*/
+ UINT8 TempChList[MAX_NUM_OF_CHANNELS] = {0};
+
+ if (pAd->CommonCfg.bIEEE80211H)
+ {
+ cnt = 0;
+
+ /* Filter out an available channel list */
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ /* Check DFS channel RemainingTimeForUse */
+ if (pAd->ChannelList[i].RemainingTimeForUse)
+ continue;
+
+ /* Check skip channel list */
+ if (AutoChannelSkipListCheck(pAd, pAd->ChannelList[i].Channel) == TRUE)
+ continue;
+
+#ifdef DOT11_N_SUPPORT
+ /* Check N-group of BW40 */
+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+ !(pAd->ChannelList[i].Flags & CHANNEL_40M_CAP))
+ continue;
+#endif /* DOT11_N_SUPPORT */
+
+ /* Store available channel to temp list */
+ TempChList[cnt++] = pAd->ChannelList[i].Channel;
+ }
+
+ /* Randomly select a channel from temp list */
+ if (cnt)
+ {
+ RadomIdx = RandomByte2(pAd)%cnt;
+ ch = TempChList[RadomIdx];
+ }
+ else
+ {
+ ch = FirstChannel(pAd);
+ }
+
+ }
+ else
+ {
+ ch = pAd->ChannelList[RandomByte2(pAd)%pAd->ChannelListNum].Channel;
+ if (ch == 0)
+ ch = FirstChannel(pAd);
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("%s(): Select Channel %d\n", __FUNCTION__, ch));
+ return ch;
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine calaulates the dirtyness of all channels by the
+ CCA value and Rssi. Store dirtyness to pChannelInfo strcut.
+ This routine is called at iwpriv cmmand or initialization. It chooses and returns
+ a good channel whith less interference.
+ Return:
+ ch - channel number that
+ NOTE:
+ ==========================================================================
+ */
+static inline UCHAR SelectClearChannelCCA(
+ IN PRTMP_ADAPTER pAd
+ )
+{
+ #define CCA_THRESHOLD (100)
+
+ PBSSINFO pBssInfoTab = pAd->pBssInfoTab;
+ PCHANNELINFO pChannelInfo = pAd->pChannelInfo;
+ INT ch = 1, channel_idx, BssTab_idx;
+ BSSENTRY *pBss;
+ UINT32 min_dirty, min_falsecca;
+ int candidate_ch;
+ UCHAR ExChannel[2] = {0}, candidate_ExChannel[2] = {0};
+ UCHAR base;
+
+ if(pBssInfoTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pBssInfoTab equal NULL.\n"));
+ return (FirstChannel(pAd));
+ }
+
+ if(pChannelInfo == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pChannelInfo equal NULL.\n"));
+ return (FirstChannel(pAd));
+ }
+
+ for (BssTab_idx = 0; BssTab_idx < pBssInfoTab->BssNr; BssTab_idx++)
+ {
+ pBss = &(pBssInfoTab->BssEntry[BssTab_idx]);
+ channel_idx = GetChIdx(pAd, pBss->Channel);
+ if (channel_idx < 0 )
+ continue;
+
+
+ if (pBss->Rssi >= RSSI_TO_DBM_OFFSET-50)
+ {
+ /* high signal >= -50 dbm */
+ pChannelInfo->dirtyness[channel_idx] += 50;
+ }
+ else if (pBss->Rssi <= RSSI_TO_DBM_OFFSET-80)
+ {
+ /* low signal <= -80 dbm */
+ pChannelInfo->dirtyness[channel_idx] += 30;
+ }
+ else
+ {
+ /* mid signal -50 ~ -80 dbm */
+ pChannelInfo->dirtyness[channel_idx] += 40;
+ }
+
+ pChannelInfo->dirtyness[channel_idx] += 40;
+
+ {
+ INT BelowBound;
+ INT AboveBound;
+ INT loop;
+
+ switch(pBss->ExtChOffset)
+ {
+ case EXTCHA_ABOVE:
+ BelowBound = pChannelInfo->IsABand ? 1 : 4;
+ AboveBound = pChannelInfo->IsABand ? 2 : 8;
+ break;
+
+ case EXTCHA_BELOW:
+ BelowBound = pChannelInfo->IsABand ? 2 : 8;
+ AboveBound = pChannelInfo->IsABand ? 1 : 4;
+ break;
+
+ default:
+ BelowBound = pChannelInfo->IsABand ? 1 : 4;
+ AboveBound = pChannelInfo->IsABand ? 1 : 4;
+ break;
+ }
+
+ /* check neighbor channel */
+ for (loop = (channel_idx+1); loop <= (channel_idx+AboveBound); loop++)
+ {
+ if (loop >= MAX_NUM_OF_CHANNELS)
+ break;
+
+ if (pAd->ChannelList[loop].Channel - pAd->ChannelList[loop-1].Channel > 4)
+ break;
+
+ pChannelInfo->dirtyness[loop] += ((9 - (loop - channel_idx)) * 4);
+ }
+ /* check neighbor channel */
+ for (loop=(channel_idx-1); loop >= (channel_idx-BelowBound); loop--)
+ {
+ if (loop < 0)
+ break;
+
+ if (pAd->ChannelList[loop+1].Channel - pAd->ChannelList[loop].Channel > 4)
+ continue;
+
+ pChannelInfo->dirtyness[loop] +=
+ ((9 - (channel_idx - loop)) * 4);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,(" ch%d bssid=%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]));
+ }
+
+ AutoChannelSkipListSetDirty(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("=====================================================\n"));
+ for (channel_idx = 0; channel_idx < pAd->ChannelListNum; channel_idx++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel %d : Dirty = %ld, False CCA = %u, Busy Time = %u, Skip Channel = %s\n",
+ pAd->ChannelList[channel_idx].Channel,
+ pChannelInfo->dirtyness[channel_idx],
+ pChannelInfo->FalseCCA[channel_idx],
+#ifdef AP_QLOAD_SUPPORT
+ pChannelInfo->chanbusytime[channel_idx],
+#else
+ 0,
+#endif /* AP_QLOAD_SUPPORT */
+ (pChannelInfo->SkipList[channel_idx] == TRUE) ? "TRUE" : "FALSE"));
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("=====================================================\n"));
+
+ min_dirty = min_falsecca = 0xFFFFFFFF;
+
+ /*
+ * Rule 1. Pick up a good channel that False_CCA =< CCA_THRESHOLD
+ * by dirtyness
+ */
+ candidate_ch = -1;
+
+ for (channel_idx = 0; channel_idx < pAd->ChannelListNum; channel_idx++)
+ {
+ if (pChannelInfo->SkipList[channel_idx] == TRUE)
+ continue;
+
+ if (pChannelInfo->FalseCCA[channel_idx] <= CCA_THRESHOLD)
+ {
+ UINT32 dirtyness = pChannelInfo->dirtyness[channel_idx];
+ ch = pAd->ChannelList[channel_idx].Channel;
+
+#ifdef AP_QLOAD_SUPPORT
+ /* QLOAD ALARM */
+ /* when busy time of a channel > threshold, skip it */
+ /* TODO: Use weight for different references to do channel selection */
+ if (QBSS_LoadIsBusyTimeAccepted(pAd,
+ pChannelInfo->chanbusytime[channel_idx]) == FALSE)
+ {
+ /* check next one */
+ continue;
+ }
+#endif /* AP_QLOAD_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ /*
+ User require 40MHz Bandwidth.
+ In the case, ignor all channel
+ doesn't support 40MHz Bandwidth.
+ */
+ if ((pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ && (pChannelInfo->IsABand && (GetABandChOffset(ch) == 0)))
+ continue;
+
+ /*
+ Need to Consider the dirtyness of extending channel
+ in 40 MHz bandwidth channel.
+ */
+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ if (pAd->pChannelInfo->IsABand)
+ {
+ if (((channel_idx + GetABandChOffset(ch)) >=0)
+ && ((channel_idx + GetABandChOffset(ch)) < pAd->ChannelListNum))
+ {
+ INT ChOffsetIdx = channel_idx + GetABandChOffset(ch);
+ dirtyness += pChannelInfo->dirtyness[ChOffsetIdx];
+ }
+ }
+ else
+ {
+ UCHAR ExChannel_idx = 0;
+ if (pAd->ChannelList[channel_idx].Channel == 14)
+ {
+ dirtyness = 0xFFFFFFFF;
+ break;
+ }
+ else
+ {
+ NdisZeroMemory(ExChannel, sizeof(ExChannel));
+ if (((channel_idx - 4) >=0) && ((channel_idx - 4) < pAd->ChannelListNum))
+ {
+ dirtyness += pChannelInfo->dirtyness[channel_idx - 4];
+ ExChannel[ExChannel_idx++] = pAd->ChannelList[channel_idx - 4].Channel;
+ }
+
+ if (((channel_idx + 4) >=0) && ((channel_idx + 4) < pAd->ChannelListNum))
+ {
+ dirtyness += pChannelInfo->dirtyness[channel_idx + 4];
+ ExChannel[ExChannel_idx++] = pAd->ChannelList[channel_idx + 4].Channel;
+ }
+ }
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ if ((min_dirty > dirtyness))
+ {
+ min_dirty = dirtyness;
+ candidate_ch = channel_idx;
+ NdisMoveMemory(candidate_ExChannel, ExChannel, 2);
+ }
+ }
+ }
+
+ if (candidate_ch >= 0)
+ {
+ ch = pAd->ChannelList[candidate_ch].Channel;
+ DBGPRINT(RT_DEBUG_TRACE, ("Rule 1 CCA value : Min Dirtiness (Include extension channel) ==> Select Channel %d \n", ch));
+ DBGPRINT(RT_DEBUG_TRACE, ("Min Dirty = %u\n", min_dirty));
+ DBGPRINT(RT_DEBUG_TRACE, ("ExChannel = %d , %d\n", candidate_ExChannel[0], candidate_ExChannel[1]));
+ DBGPRINT(RT_DEBUG_TRACE, ("BW = %s\n", (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)? "40" : "20"));
+ return ch;
+ }
+
+ /*
+ * Rule 2. Pick up a good channel that False_CCA > CCA_THRESHOLD
+ * by FalseCCA (FalseCCA + Dirtyness)
+ */
+ candidate_ch = -1;
+ for (channel_idx = 0; channel_idx < pAd->ChannelListNum; channel_idx++)
+ {
+ if (pChannelInfo->SkipList[channel_idx] == TRUE)
+ continue;
+
+ if (pChannelInfo->FalseCCA[channel_idx] > CCA_THRESHOLD)
+ {
+ UINT32 falsecca = pChannelInfo->FalseCCA[channel_idx] + pChannelInfo->dirtyness[channel_idx];
+ ch = pAd->ChannelList[channel_idx].Channel;
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ && (pChannelInfo->IsABand && (GetABandChOffset(ch) == 0)))
+ continue;
+#endif /* DOT11_N_SUPPORT */
+
+ if ((GetABandChOffset(ch) != 0)
+ && ((channel_idx + GetABandChOffset(ch)) >=0)
+ && ((channel_idx + GetABandChOffset(ch)) < pAd->ChannelListNum))
+ {
+ INT ChOffsetIdx = channel_idx + GetABandChOffset(ch);
+ falsecca += (pChannelInfo->FalseCCA[ChOffsetIdx] +
+ pChannelInfo->dirtyness[ChOffsetIdx]);
+ }
+
+#ifdef AP_QLOAD_SUPPORT
+ /* QLOAD ALARM */
+ /* when busy time of a channel > threshold, skip it */
+ /* TODO: Use weight for different references to do channel selection */
+ if (QBSS_LoadIsBusyTimeAccepted(pAd,
+ pChannelInfo->chanbusytime[channel_idx]) == FALSE)
+ {
+ /* check next one */
+ continue;
+ }
+#endif /* AP_QLOAD_SUPPORT */
+
+ if ((min_falsecca > falsecca))
+ {
+ min_falsecca = falsecca;
+ candidate_ch = channel_idx;
+ }
+ }
+ }
+
+ if (candidate_ch >= 0)
+ {
+ ch = pAd->ChannelList[candidate_ch].Channel;
+ DBGPRINT(RT_DEBUG_TRACE, ("Rule 2 CCA value : Min False CCA value ==> Select Channel %d, min falsecca = %d \n", ch, min_falsecca));
+ return ch;
+ }
+
+ base = RandomByte2(pAd);
+ for (channel_idx=0 ; channel_idx < pAd->ChannelListNum ; channel_idx++)
+ {
+ ch = pAd->ChannelList[(base + channel_idx) % pAd->ChannelListNum].Channel;
+
+ if (AutoChannelSkipListCheck(pAd, ch))
+ continue;
+
+ if ((pAd->ApCfg.bAvoidDfsChannel == TRUE)
+ && (pChannelInfo->IsABand == TRUE)
+ && RadarChannelCheck(pAd, ch))
+ continue;
+
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Rule 3 CCA value : Randomly Select ==> Select Channel %d\n", ch));
+ return ch;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine calaulates the dirtyness of all channels by the dirtiness value and
+ number of AP in each channel and stores in pChannelInfo strcut.
+ This routine is called at iwpriv cmmand or initialization. It chooses and returns
+ a good channel whith less interference.
+ Return:
+ ch - channel number that
+ NOTE:
+ ==========================================================================
+ */
+
+static inline UCHAR SelectClearChannelApCnt(
+ IN PRTMP_ADAPTER pAd
+ )
+{
+ /*PBSSINFO pBssInfoTab = pAd->pBssInfoTab; */
+ PCHANNELINFO pChannelInfo = pAd->pChannelInfo;
+ /*BSSENTRY *pBss; */
+ UCHAR channel_index = 0,dirty,base = 0;
+ UCHAR final_channel = 0;
+
+
+ if(pChannelInfo == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pChannelInfo equal NULL.\n"));
+ return (FirstChannel(pAd));
+ }
+
+ /* Calculate Dirtiness */
+
+ for (channel_index=0 ; channel_index < pAd->ChannelListNum ; channel_index++)
+ {
+ if (pChannelInfo->ApCnt[channel_index] > 0)
+ {
+ INT ll;
+ pChannelInfo->dirtyness[channel_index] += 30;
+
+ /*5G */
+ if (pChannelInfo->IsABand)
+ {
+ int Channel = pAd->ChannelList[channel_index].Channel;
+
+ /*Make secondary channel dirty */
+ if(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))
+ {
+ if (channel_index + 1 < MAX_NUM_OF_CHANNELS)
+ if(pAd->ChannelList[channel_index+1].Channel - pAd->ChannelList[channel_index].Channel == 4)
+ pChannelInfo->dirtyness[channel_index+1] += 1;
+ }
+ else if ((Channel == 40) || (Channel == 48) || (Channel == 56) ||
+ (Channel == 64) || (Channel == 104) || (Channel == 112) ||
+ (Channel == 120) || (Channel == 128) || (Channel == 136) ||
+ (Channel== 153) || (Channel == 161))
+ {
+ if(channel_index - 1 >= 0)
+ if(pAd->ChannelList[channel_index].Channel - pAd->ChannelList[channel_index-1].Channel == 4)
+ pChannelInfo->dirtyness[channel_index-1] += 1;
+ }
+ }
+ }
+ }
+ /*2.4G */
+ if (!pChannelInfo->IsABand)
+ {
+ int ChanOffset = 0;
+
+ if((pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)&&
+ (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW))
+ {
+ /*
+ BW is 40Mhz
+ the distance between two channel to prevent interference
+ is 4 channel width plus 4 channel width (secondary channel)
+ */
+ ChanOffset = 8;
+ }
+ else
+ {
+ /*
+ BW is 20Mhz
+ The channel width of 2.4G band is 5Mhz.
+ The distance between two channel to prevent interference is 4 channel width
+ */
+ ChanOffset = 4;
+ }
+
+ for (ll = channel_index + 1; ll < (channel_index + ChanOffset + 1); ll++)
+ {
+ if (ll < MAX_NUM_OF_CHANNELS)
+ pChannelInfo->dirtyness[ll]++;
+ }
+
+ if((pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)&&
+ (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE))
+ {
+ /* BW is 40Mhz */
+ ChanOffset = 8;
+ }
+ else
+ {
+ /* BW is 20Mhz */
+ ChanOffset = 4;
+ }
+
+ for (ll = channel_index - 1; ll > (channel_index - ChanOffset - 1); ll--)
+ {
+ if (ll >= 0)
+ pChannelInfo->dirtyness[ll]++;
+ }
+ }
+ }
+ }/* Calculate Dirtiness */
+
+ AutoChannelSkipListSetDirty(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("=====================================================\n"));
+ for (channel_index=0 ; channel_index < pAd->ChannelListNum ; channel_index++)
+ /* debug messages */
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel %d : Dirty = %ld, ApCnt=%ld, Busy Time = %d, Skip Channel = %s\n",
+ pAd->ChannelList[channel_index].Channel,
+ pChannelInfo->dirtyness[channel_index],
+ pChannelInfo->ApCnt[channel_index],
+#ifdef AP_QLOAD_SUPPORT
+ pChannelInfo->chanbusytime[channel_index],
+#else
+ 0,
+#endif /* AP_QLOAD_SUPPORT */
+ (pChannelInfo->SkipList[channel_index] == TRUE) ? "TRUE" : "FALSE"));
+ DBGPRINT(RT_DEBUG_TRACE, ("=====================================================\n"));
+
+ pAd->ApCfg.AutoChannel_Channel = 0;
+
+ /* RULE 1. pick up a good channel that no one used */
+
+ for (channel_index=0 ; channel_index < pAd->ChannelListNum ; channel_index++)
+ {
+ if (pChannelInfo->SkipList[channel_index] == TRUE)
+ continue;
+
+ if ((pAd->ApCfg.bAvoidDfsChannel == TRUE)
+ &&(pChannelInfo->IsABand == TRUE)
+ && RadarChannelCheck(pAd, pAd->ChannelList[channel_index].Channel))
+ continue;
+
+#ifdef AP_QLOAD_SUPPORT
+ /* QLOAD ALARM */
+ if (QBSS_LoadIsBusyTimeAccepted(pAd,
+ pChannelInfo->chanbusytime[channel_index]) == FALSE)
+ continue;
+#endif /* AP_QLOAD_SUPPORT */
+
+ if (pChannelInfo->dirtyness[channel_index] == 0) break;
+ }
+ if (channel_index < pAd->ChannelListNum)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Rule 1 APCnt : dirtiness == 0 (no one used and no interference) ==> Select Channel %d\n", pAd->ChannelList[channel_index].Channel));
+
+ return pAd->ChannelList[channel_index].Channel;
+ }
+
+ /* RULE 2. if not available, then co-use a channel that's no interference (dirtyness=30) */
+ /* RULE 3. if not available, then co-use a channel that has minimum interference (dirtyness=31,32) */
+ for (dirty = 30; dirty <= 32; dirty++)
+ {
+ BOOLEAN candidate[MAX_NUM_OF_CHANNELS+1], candidate_num=0;
+ UCHAR min_ApCnt = 255;
+ final_channel = 0;
+
+ NdisZeroMemory(candidate, MAX_NUM_OF_CHANNELS+1);
+ for (channel_index=0 ; channel_index < pAd->ChannelListNum ; channel_index++)
+ {
+ if (pChannelInfo->SkipList[channel_index] == TRUE)
+ continue;
+
+ if (pChannelInfo->dirtyness[channel_index] == dirty)
+ {
+ candidate[channel_index]=TRUE;
+ candidate_num++;
+ }
+ }
+ /* if there's more than 1 candidate, pick up the channel with minimum RSSI */
+ if (candidate_num)
+ {
+ for (channel_index=0 ; channel_index < pAd->ChannelListNum ; channel_index++)
+ {
+
+#ifdef AP_QLOAD_SUPPORT
+ /* QLOAD ALARM */
+ /* when busy time of a channel > threshold, skip it */
+ /* TODO: Use weight for different references to do channel selection */
+ if (QBSS_LoadIsBusyTimeAccepted(pAd,
+ pChannelInfo->chanbusytime[channel_index]) == FALSE)
+ {
+ /* check next one */
+ continue;
+ }
+#endif /* AP_QLOAD_SUPPORT */
+
+ if (candidate[channel_index] && (pChannelInfo->ApCnt[channel_index] < min_ApCnt))
+ {
+
+ if((pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ && (BW40_ChannelCheck(pAd->ChannelList[channel_index].Channel) == FALSE))
+ continue;
+
+ if ((pAd->ApCfg.bAvoidDfsChannel == TRUE)
+ &&(pChannelInfo->IsABand == TRUE)
+ && RadarChannelCheck(pAd, pAd->ChannelList[channel_index].Channel))
+ continue;
+
+ final_channel = pAd->ChannelList[channel_index].Channel;
+ min_ApCnt = pChannelInfo->ApCnt[channel_index];
+ }
+ }
+ if (final_channel != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Rule 2 APCnt : minimum APCnt with minimum interference(dirtiness: 30~32) ==> Select Channel %d\n", final_channel));
+ DBGPRINT(RT_DEBUG_TRACE,(" Dirtiness = %d , Min ApCnt = %d\n", dirty, min_ApCnt));
+ return final_channel;
+ }
+ }
+ }
+ /* RULE 3. still not available, pick up the random channel */
+ base = RandomByte2(pAd);
+
+ for (channel_index=0 ; channel_index < pAd->ChannelListNum ; channel_index++)
+ {
+ final_channel = pAd->ChannelList[(base + channel_index) % pAd->ChannelListNum].Channel;
+
+ if (AutoChannelSkipListCheck(pAd, final_channel))
+ continue;
+
+ if ((pAd->ApCfg.bAvoidDfsChannel == TRUE)
+ &&(pChannelInfo->IsABand == TRUE)
+ && RadarChannelCheck(pAd, final_channel))
+ continue;
+
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("Rule 3 APCnt : Randomly Select ==> Select Channel %d\n",final_channel));
+ return final_channel;
+
+}
+
+ULONG AutoChBssInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR ChannelNo,
+ IN UCHAR ExtChOffset,
+ IN CHAR Rssi)
+{
+ ULONG Idx;
+ PBSSINFO pBssInfoTab = pAd->pBssInfoTab;
+
+ if(pBssInfoTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->pBssInfoTab equal NULL.\n"));
+ return BSS_NOT_FOUND;
+ }
+
+ Idx = AutoChBssSearchWithSSID(pAd, pBssid, (PUCHAR)Ssid, SsidLen, ChannelNo);
+ if (Idx == BSS_NOT_FOUND)
+ {
+ if (pBssInfoTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+ return BSS_NOT_FOUND;
+ Idx = pBssInfoTab->BssNr;
+ AutoChBssEntrySet(&pBssInfoTab->BssEntry[Idx], pBssid, Ssid, SsidLen,
+ ChannelNo, ExtChOffset, Rssi);
+ pBssInfoTab->BssNr++;
+ }
+ else
+ {
+ AutoChBssEntrySet(&pBssInfoTab->BssEntry[Idx], pBssid, Ssid, SsidLen,
+ ChannelNo, ExtChOffset, Rssi);
+ }
+
+ return Idx;
+}
+
+
+void AutoChBssTableInit(
+ IN PRTMP_ADAPTER pAd)
+{
+/* pAd->pBssInfoTab = (PBSSINFO)kmalloc(sizeof(BSSINFO), GFP_ATOMIC); */
+ os_alloc_mem(pAd, (UCHAR **)&pAd->pBssInfoTab, sizeof(BSSINFO));
+ if (pAd->pBssInfoTab)
+ NdisZeroMemory(pAd->pBssInfoTab, sizeof(BSSINFO));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->pBssInfoTab", __FUNCTION__));
+
+ return;
+}
+
+void ChannelInfoInit(
+ IN PRTMP_ADAPTER pAd)
+{
+/* pAd->pChannelInfo = (PCHANNELINFO)kmalloc(sizeof(CHANNELINFO), GFP_ATOMIC); */
+ os_alloc_mem(pAd, (UCHAR **)&pAd->pChannelInfo, sizeof(CHANNELINFO));
+ if (pAd->pChannelInfo)
+ NdisZeroMemory(pAd->pChannelInfo, sizeof(CHANNELINFO));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->pChannelInfo", __FUNCTION__));
+
+
+ return;
+}
+
+void AutoChBssTableDestroy(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->pBssInfoTab)
+ {
+/* kfree(pAd->pBssInfoTab); */
+ os_free_mem(NULL, pAd->pBssInfoTab);
+ pAd->pBssInfoTab = NULL;
+ }
+
+ return;
+}
+
+void ChannelInfoDestroy(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->pChannelInfo)
+ {
+/* kfree(pAd->pChannelInfo); */
+ os_free_mem(NULL, pAd->pChannelInfo);
+ pAd->pChannelInfo = NULL;
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine sets the current PhyMode for calculating
+ the dirtyness.
+ Return:
+ none
+ NOTE:
+ ==========================================================================
+ */
+void CheckPhyModeIsABand(
+ IN PRTMP_ADAPTER pAd)
+{
+
+ pAd->pChannelInfo->IsABand = (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) ? TRUE : FALSE;
+
+ return;
+}
+
+
+UCHAR SelectBestChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN ChannelSel_Alg Alg)
+{
+ UCHAR ch = 0;
+
+ /* init pAd->pChannelInfo->IsABand */
+ CheckPhyModeIsABand(pAd);
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ if (Alg == ChannelAlgCCA)
+ pAd->CommonCfg.MO_Cfg.bEnable = TRUE;
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ switch ( Alg )
+ {
+ case ChannelAlgRandom:
+ case ChannelAlgApCnt:
+ ch = SelectClearChannelApCnt(pAd);
+ break;
+ case ChannelAlgCCA:
+ ch = SelectClearChannelCCA(pAd);
+ break;
+ default:
+ ch = SelectClearChannelCCA(pAd);
+ break;
+ }
+
+ RTMPSendWirelessEvent(pAd, IW_CHANNEL_CHANGE_EVENT_FLAG, 0, 0, ch);
+
+ return ch;
+
+}
+
+VOID APAutoChannelInit(IN PRTMP_ADAPTER pAd)
+{
+ UINT32 BusyTime;
+
+ /* reset bss table */
+ AutoChBssTableReset(pAd);
+
+ /* clear Channel Info */
+ ChannelInfoReset(pAd);
+
+ /* init pAd->pChannelInfo->IsABand */
+ CheckPhyModeIsABand(pAd);
+
+ pAd->ApCfg.current_channel_index = 0;
+
+ /* read clear for primary channel */
+ RTMP_IO_READ32(pAd, CH_BUSY_STA, &BusyTime);
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is called at initialization. It returns a channel number
+ that complies to regulation domain and less interference with current
+ enviornment.
+ Return:
+ ch - channel number that
+ NOTE:
+ The retruned channel number is guaranteed to comply to current regulation
+ domain that recorded in pAd->CommonCfg.CountryRegion
+ Usage:
+ 1.) iwpriv ra0 set AutoChannelSel=1
+ Ues the number of AP and inference status to choose
+ 2.) iwpriv ra0 set AutoChannelSel=2
+ Ues the False CCA count and Rssi to choose
+ ==========================================================================
+ */
+UCHAR APAutoSelectChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN ChannelSel_Alg Alg)
+{
+ UCHAR ch = 0, i;
+
+ /* passive scan channel 1-14. collect statistics */
+
+ /*
+ In the autochannel select case. AP didn't get channel yet.
+ So have no way to determine which Band AP used by channel number.
+ */
+
+ /* Init some structures before doing AutoChannelSelect() */
+ APAutoChannelInit(pAd);
+
+ if (( Alg == ChannelAlgRandom ) && (pAd->pChannelInfo->IsABand == TRUE))
+ { /*for Dfs */
+ ch = SelectClearChannelRandom(pAd);
+ }
+ else
+ {
+#ifdef MICROWAVE_OVEN_SUPPORT
+ pAd->CommonCfg.MO_Cfg.bEnable = FALSE;
+ ASIC_MEASURE_FALSE_CCA(pAd);
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ /*find RSSI in each channel */
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ AsicSwitchChannel(pAd, pAd->ChannelList[i].Channel, TRUE);
+ AsicLockChannel(pAd, pAd->ChannelList[i].Channel);/*do nothing */
+ pAd->ApCfg.current_channel_index = i;
+
+ pAd->ApCfg.AutoChannel_Channel = pAd->ChannelList[i].Channel;
+
+#ifdef AP_QLOAD_SUPPORT
+ if (QLOAD_DOES_ALARM_OCCUR(pAd))
+ { /* QLOAD ALARM, ever alarm from QLOAD module */
+ OS_WAIT(400); /* wait for 400 ms at each channel. */
+ }
+ else
+#endif /* AP_QLOAD_SUPPORT */
+ {
+ OS_WAIT(200); /* wait for 200 ms at each channel. */
+ }
+
+ UpdateChannelInfo(pAd, i,Alg);
+ }
+
+ ch = SelectBestChannel(pAd, Alg);
+ }
+
+ return ch;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_cfg.c b/cleopatre/devkit/mt7601udrv/ap/ap_cfg.c
new file mode 100644
index 0000000000..e90f7776d3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_cfg.c
@@ -0,0 +1,12072 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ap_cfg.c
+
+ Abstract:
+ IOCTL related subroutines
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+*/
+
+
+#include "rt_config.h"
+
+
+#define A_BAND_REGION_0 0
+#define A_BAND_REGION_1 1
+#define A_BAND_REGION_2 2
+#define A_BAND_REGION_3 3
+#define A_BAND_REGION_4 4
+#define A_BAND_REGION_5 5
+#define A_BAND_REGION_6 6
+#define A_BAND_REGION_7 7
+#define A_BAND_REGION_8 8
+#define A_BAND_REGION_9 9
+#define A_BAND_REGION_10 10
+
+#define G_BAND_REGION_0 0
+#define G_BAND_REGION_1 1
+#define G_BAND_REGION_2 2
+#define G_BAND_REGION_3 3
+#define G_BAND_REGION_4 4
+#define G_BAND_REGION_5 5
+#define G_BAND_REGION_6 6
+
+COUNTRY_CODE_TO_COUNTRY_REGION allCountry[] = {
+ /* {Country Number, ISO Name, Country Name, Support 11A, 11A Country Region, Support 11G, 11G Country Region} */
+ {0, "DB", "Debug", TRUE, A_BAND_REGION_7, TRUE, G_BAND_REGION_5},
+ {8, "AL", "ALBANIA", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {12, "DZ", "ALGERIA", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {32, "AR", "ARGENTINA", TRUE, A_BAND_REGION_3, TRUE, G_BAND_REGION_1},
+ {51, "AM", "ARMENIA", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {36, "AU", "AUSTRALIA", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {40, "AT", "AUSTRIA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {31, "AZ", "AZERBAIJAN", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {48, "BH", "BAHRAIN", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {112, "BY", "BELARUS", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {56, "BE", "BELGIUM", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {84, "BZ", "BELIZE", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {68, "BO", "BOLIVIA", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {76, "BR", "BRAZIL", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {96, "BN", "BRUNEI DARUSSALAM", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {100, "BG", "BULGARIA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {124, "CA", "CANADA", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {152, "CL", "CHILE", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {156, "CN", "CHINA", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {170, "CO", "COLOMBIA", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {188, "CR", "COSTA RICA", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {191, "HR", "CROATIA", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {196, "CY", "CYPRUS", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {203, "CZ", "CZECH REPUBLIC", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {208, "DK", "DENMARK", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {214, "DO", "DOMINICAN REPUBLIC", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {218, "EC", "ECUADOR", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {818, "EG", "EGYPT", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {222, "SV", "EL SALVADOR", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {233, "EE", "ESTONIA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {246, "FI", "FINLAND", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {250, "FR", "FRANCE", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {268, "GE", "GEORGIA", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {276, "DE", "GERMANY", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {300, "GR", "GREECE", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {320, "GT", "GUATEMALA", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {340, "HN", "HONDURAS", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {344, "HK", "HONG KONG", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {348, "HU", "HUNGARY", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {352, "IS", "ICELAND", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {356, "IN", "INDIA", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {360, "ID", "INDONESIA", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {364, "IR", "IRAN", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {372, "IE", "IRELAND", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {376, "IL", "ISRAEL", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {380, "IT", "ITALY", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {392, "JP", "JAPAN", TRUE, A_BAND_REGION_9, TRUE, G_BAND_REGION_1},
+ {400, "JO", "JORDAN", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {398, "KZ", "KAZAKHSTAN", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {408, "KP", "KOREA DEMOCRATIC PEOPLE'S REPUBLIC OF",TRUE, A_BAND_REGION_5, TRUE, G_BAND_REGION_1},
+ {410, "KR", "KOREA REPUBLIC OF", TRUE, A_BAND_REGION_5, TRUE, G_BAND_REGION_1},
+ {414, "KW", "KUWAIT", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {428, "LV", "LATVIA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {422, "LB", "LEBANON", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {438, "LI", "LIECHTENSTEIN", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {440, "LT", "LITHUANIA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {442, "LU", "LUXEMBOURG", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {446, "MO", "MACAU", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {807, "MK", "MACEDONIA", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {458, "MY", "MALAYSIA", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {484, "MX", "MEXICO", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {492, "MC", "MONACO", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {504, "MA", "MOROCCO", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {528, "NL", "NETHERLANDS", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {554, "NZ", "NEW ZEALAND", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {578, "NO", "NORWAY", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {512, "OM", "OMAN", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {586, "PK", "PAKISTAN", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {591, "PA", "PANAMA", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {604, "PE", "PERU", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {608, "PH", "PHILIPPINES", TRUE, A_BAND_REGION_4, TRUE, G_BAND_REGION_1},
+ {616, "PL", "POLAND", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {620, "PT", "PORTUGAL", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {630, "PR", "PUERTO RICO", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {634, "QA", "QATAR", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {642, "RO", "ROMANIA", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {643, "RU", "RUSSIA FEDERATION", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {682, "SA", "SAUDI ARABIA", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {702, "SG", "SINGAPORE", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {703, "SK", "SLOVAKIA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {705, "SI", "SLOVENIA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {710, "ZA", "SOUTH AFRICA", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {724, "ES", "SPAIN", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {752, "SE", "SWEDEN", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {756, "CH", "SWITZERLAND", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {760, "SY", "SYRIAN ARAB REPUBLIC", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {158, "TW", "TAIWAN", TRUE, A_BAND_REGION_3, TRUE, G_BAND_REGION_0},
+ {764, "TH", "THAILAND", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {780, "TT", "TRINIDAD AND TOBAGO", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {788, "TN", "TUNISIA", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {792, "TR", "TURKEY", TRUE, A_BAND_REGION_2, TRUE, G_BAND_REGION_1},
+ {804, "UA", "UKRAINE", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {784, "AE", "UNITED ARAB EMIRATES", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {826, "GB", "UNITED KINGDOM", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_1},
+ {840, "US", "UNITED STATES", TRUE, A_BAND_REGION_0, TRUE, G_BAND_REGION_0},
+ {858, "UY", "URUGUAY", TRUE, A_BAND_REGION_5, TRUE, G_BAND_REGION_1},
+ {860, "UZ", "UZBEKISTAN", TRUE, A_BAND_REGION_1, TRUE, G_BAND_REGION_0},
+ {862, "VE", "VENEZUELA", TRUE, A_BAND_REGION_5, TRUE, G_BAND_REGION_1},
+ {704, "VN", "VIET NAM", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {887, "YE", "YEMEN", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {716, "ZW", "ZIMBABWE", FALSE, A_BAND_REGION_0, TRUE, G_BAND_REGION_1},
+ {999, "", "", 0, 0, 0, 0}
+};
+
+#define NUM_OF_COUNTRIES (sizeof(allCountry)/sizeof(COUNTRY_CODE_TO_COUNTRY_REGION))
+
+
+INT Set_CountryString_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CountryCode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_ChGeography_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+INT Set_AP_SSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_TxRate_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+
+INT Set_OLBCDetection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AP_MaxStaNum_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AP_IdleTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef IAPP_SUPPORT
+INT Set_IappPID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* IAPP_SUPPORT */
+
+INT Set_AP_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_WpaMixPairCipher_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_RekeyInterval_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_RekeyMethod_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_PMKCachePeriod_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_Key1_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_Key2_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_Key3_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_Key4_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_BasicRate_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_BeaconPeriod_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_DtimPeriod_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_NoForwarding_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_NoForwardingBTNSSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_HideSSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_VLANID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_VLANPriority_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_VLAN_TAG_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AccessPolicy_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+
+INT Set_ACLAddEntry_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_ACLDelEntry_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_ACLShowAll_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_ACLClearAll_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_RadioOn_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_SiteSurvey_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AutoChannelSel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_BADecline_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Show_StaCount_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Show_StaSecurityInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Show_DriverInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef DOT11_N_SUPPORT
+INT Show_BaTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* DOT11_N_SUPPORT */
+
+INT Show_Sat_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Show_RAInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+INT Show_Sat_Reset_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Show_MATTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef DOT1X_SUPPORT
+VOID RTMPIoctlQueryRadiusConf(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+INT Set_IEEE8021X_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_PreAuth_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_RADIUS_Server_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RADIUS_Port_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RADIUS_Key_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* DOT1X_SUPPORT */
+
+INT Set_DisConnectSta_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DisConnectAllSta_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+#ifdef APCLI_SUPPORT
+INT Set_ApCli_Enable_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_Ssid_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_Bssid_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_DefaultKeyID_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_WPAPSK_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_Key1_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_Key2_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_Key3_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_Key4_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_TxMode_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_TxMcs_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+INT Set_ApCli_Wpa_Support(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_ApCli_IEEE8021X_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+
+#ifdef WSC_AP_SUPPORT
+INT Set_AP_WscSsid_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+#endif /* WSC_AP_SUPPORT */
+#endif /* APCLI_SUPPORT */
+#ifdef UAPSD_SUPPORT
+INT Set_UAPSD_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* UAPSD_SUPPORT */
+
+#ifdef WSC_AP_SUPPORT
+INT Set_WscStatus_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+VOID RTMPIoctlWscProfile(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlWscPINCode(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlWscStatus(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlGetWscDynInfo(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlGetWscRegsDynInfo(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+BOOLEAN WscCheckEnrolleeNonceFromUpnp(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING pData,
+ IN USHORT Length,
+ IN PWSC_CTRL pWscControl);
+
+UCHAR WscRxMsgTypeFromUpnp(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING pData,
+ IN USHORT Length);
+
+INT WscGetConfForUpnp(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl);
+
+INT Set_AP_WscConfMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AP_WscConfStatus_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AP_WscMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AP_WscGetConf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AP_WscPinCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AP_WscSecurityMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_AP_WscMultiByteCheck_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+INT Set_WscVersion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef WSC_V2_SUPPORT
+INT Set_WscV2Support_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscVersion2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscExtraTlvTag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscExtraTlvType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscExtraTlvData_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscSetupLock_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscFragment_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscFragmentSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscMaxPinAttack_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscSetupLockTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* WSC_V2_SUPPORT */
+
+#endif /* WSC_AP_SUPPORT */
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MCAST_RATE_SPECIFIC
+INT Set_McastPhyMode(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_McastMcs(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Show_McastRate(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+#endif /* MCAST_RATE_SPECIFIC */
+
+#ifdef DOT11N_DRAFT3
+INT Set_OBSSScanParam_Proc(RTMP_ADAPTER *pAd, PSTRING arg);
+INT Set_AP2040ReScan_Proc(RTMP_ADAPTER *pAd, PSTRING arg);
+#endif /* DOT11N_DRAFT3 */
+
+INT Set_EntryLifeCheck_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+#ifdef AP_QLOAD_SUPPORT
+INT Set_QloadClr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+/* QLOAD ALARM */
+INT Set_QloadAlarmTimeThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING Arg);
+
+INT Set_QloadAlarmNumThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING Arg);
+#endif /* AP_QLOAD_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+INT Set_MemDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef CONFIG_AP_SUPPORT
+INT Set_PowerSaveLifeTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+INT Set_LoopBackFlag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TestTxFrameProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TestTxFrame1Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TestTxFrame2Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TestTxFrame3Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TestTxFrame4Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+INT Set_DumpBeaconBuffer_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_InsertWAPIKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TestWAPIFrameProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TestMultiMacAddrProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_HwTxLookupRate_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[] = {
+ {"RateAlg", Set_RateAlg_Proc},
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ {"PerThrdAdj", Set_PerThrdAdj_Proc},
+ {"LowTrafficThrd", Set_LowTrafficThrd_Proc},
+ {"TrainUpRule", Set_TrainUpRule_Proc},
+ {"TrainUpRuleRSSI", Set_TrainUpRuleRSSI_Proc},
+ {"TrainUpLowThrd", Set_TrainUpLowThrd_Proc},
+ {"TrainUpHighThrd", Set_TrainUpHighThrd_Proc},
+ {"RateTable", Set_RateTable_Proc},
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ {"DriverVersion", Set_DriverVersion_Proc},
+ {"CountryRegion", Set_CountryRegion_Proc},
+ {"CountryRegionABand", Set_CountryRegionABand_Proc},
+ {"CountryString", Set_CountryString_Proc},
+ {"CountryCode", Set_CountryCode_Proc},
+#ifdef EXT_BUILD_CHANNEL_LIST
+ {"ChGeography", Set_ChGeography_Proc},
+#endif /* EXT_BUILD_CHANNEL_LIST */
+ {"SSID", Set_AP_SSID_Proc},
+ {"WirelessMode", Set_WirelessMode_Proc},
+ {"BasicRate", Set_BasicRate_Proc},
+ {"ShortSlot", Set_ShortSlot_Proc},
+ {"Channel", Set_Channel_Proc},
+ {"BeaconPeriod", Set_BeaconPeriod_Proc},
+ {"DtimPeriod", Set_DtimPeriod_Proc},
+ {"TxPower", Set_TxPower_Proc},
+ {"BGProtection", Set_BGProtection_Proc},
+ {"DisableOLBC", Set_OLBCDetection_Proc},
+ {"TxPreamble", Set_TxPreamble_Proc},
+ {"RTSThreshold", Set_RTSThreshold_Proc},
+ {"FragThreshold", Set_FragThreshold_Proc},
+ {"TxBurst", Set_TxBurst_Proc},
+ {"MaxStaNum", Set_AP_MaxStaNum_Proc},
+ {"IdleTimeout", Set_AP_IdleTimeout_Proc},
+#ifdef DOT11_N_SUPPORT
+ {"BASetup", Set_BASetup_Proc},
+ {"BADecline", Set_BADecline_Proc},
+ {"SendMIMOPS", Set_SendPSMPAction_Proc},
+ {"BAOriTearDown", Set_BAOriTearDown_Proc},
+ {"BARecTearDown", Set_BARecTearDown_Proc},
+ {"HtBw", Set_HtBw_Proc},
+ {"HtMcs", Set_HtMcs_Proc},
+ {"HtGi", Set_HtGi_Proc},
+ {"HtOpMode", Set_HtOpMode_Proc},
+ {"HtStbc", Set_HtStbc_Proc},
+ {"HtHtc", Set_HtHtc_Proc},
+ {"HtExtcha", Set_HtExtcha_Proc},
+ {"HtMpduDensity", Set_HtMpduDensity_Proc},
+ {"HtBaWinSize", Set_HtBaWinSize_Proc},
+ {"HtMIMOPS", Set_HtMIMOPSmode_Proc},
+ {"HtRdg", Set_HtRdg_Proc},
+ {"HtLinkAdapt", Set_HtLinkAdapt_Proc},
+ {"HtAmsdu", Set_HtAmsdu_Proc},
+ {"HtAutoBa", Set_HtAutoBa_Proc},
+ {"HtProtect", Set_HtProtect_Proc},
+ {"HtMimoPs", Set_HtMimoPs_Proc},
+ {"HtTxStream", Set_HtTxStream_Proc},
+ {"HtRxStream", Set_HtRxStream_Proc},
+ {"ForceShortGI", Set_ForceShortGI_Proc},
+ {"ForceGF", Set_ForceGF_Proc},
+ {"HtTxBASize", Set_HtTxBASize_Proc},
+ {"BurstMode", Set_BurstMode_Proc},
+#ifdef GREENAP_SUPPORT
+ {"GreenAP", Set_GreenAP_Proc},
+#endif /* GREENAP_SUPPORT */
+ {"HtDisallowTKIP", Set_HtDisallowTKIP_Proc},
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_VHT_AC
+ {"VhtBw", Set_VhtBw_Proc},
+ {"VhtStbc", Set_VhtStbc_Proc},
+#endif /* DOT11_VHT_AC */
+
+#ifdef IAPP_SUPPORT
+ {"IappPID", Set_IappPID_Proc},
+#endif /* IAPP_SUPPORT */
+
+#ifdef AGGREGATION_SUPPORT
+ {"PktAggregate", Set_PktAggregate_Proc},
+#endif /* AGGREGATION_SUPPORT */
+
+#ifdef INF_PPA_SUPPORT
+ {"INF_AMAZON_SE_PPA", Set_INF_AMAZON_SE_PPA_Proc},
+#endif /* INF_PPA_SUPPORT */
+
+#ifdef WMM_SUPPORT
+ {"WmmCapable", Set_AP_WmmCapable_Proc},
+#endif /* WMM_SUPPORT */
+ {"NoForwarding", Set_NoForwarding_Proc},
+ {"NoForwardingBTNBSSID", Set_NoForwardingBTNSSID_Proc},
+ {"HideSSID", Set_HideSSID_Proc},
+ {"IEEE80211H", Set_IEEE80211H_Proc},
+ {"VLANID", Set_VLANID_Proc},
+ {"VLANPriority", Set_VLANPriority_Proc},
+ {"VLANTag", Set_VLAN_TAG_Proc},
+ {"AuthMode", Set_AP_AuthMode_Proc},
+ {"EncrypType", Set_AP_EncrypType_Proc},
+ {"WpaMixPairCipher", Set_AP_WpaMixPairCipher_Proc},
+ {"RekeyInterval", Set_AP_RekeyInterval_Proc},
+ {"RekeyMethod", Set_AP_RekeyMethod_Proc},
+ {"DefaultKeyID", Set_AP_DefaultKeyID_Proc},
+ {"Key1", Set_AP_Key1_Proc},
+ {"Key2", Set_AP_Key2_Proc},
+ {"Key3", Set_AP_Key3_Proc},
+ {"Key4", Set_AP_Key4_Proc},
+ {"AccessPolicy", Set_AccessPolicy_Proc},
+ {"ACLAddEntry", Set_ACLAddEntry_Proc},
+ {"ACLDelEntry", Set_ACLDelEntry_Proc},
+ {"ACLShowAll", Set_ACLShowAll_Proc},
+ {"ACLClearAll", Set_ACLClearAll_Proc},
+ {"WPAPSK", Set_AP_WPAPSK_Proc},
+ {"RadioOn", Set_RadioOn_Proc},
+#ifdef AP_SCAN_SUPPORT
+ {"SiteSurvey", Set_SiteSurvey_Proc},
+ {"AutoChannelSel", Set_AutoChannelSel_Proc},
+#endif /* AP_SCAN_SUPPORT */
+ {"ResetCounter", Set_ResetStatCounter_Proc},
+ {"DisConnectSta", Set_DisConnectSta_Proc},
+ {"DisConnectAllSta", Set_DisConnectAllSta_Proc},
+#ifdef DOT1X_SUPPORT
+ {"IEEE8021X", Set_IEEE8021X_Proc},
+ {"PreAuth", Set_PreAuth_Proc},
+ {"PMKCachePeriod", Set_AP_PMKCachePeriod_Proc},
+ {"own_ip_addr", Set_OwnIPAddr_Proc},
+ {"EAPifname", Set_EAPIfName_Proc},
+ {"PreAuthifname", Set_PreAuthIfName_Proc},
+ {"RADIUS_Server", Set_RADIUS_Server_Proc},
+ {"RADIUS_Port", Set_RADIUS_Port_Proc},
+ {"RADIUS_Key", Set_RADIUS_Key_Proc},
+#endif /* DOT1X_SUPPORT */
+#ifdef DBG
+ {"Debug", Set_Debug_Proc},
+ {"DebugFunc", Set_DebugFunc_Proc},
+#endif /* DBG */
+
+#if defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT)
+ {"RadarShow", Set_RadarShow_Proc},
+#ifdef DFS_SUPPORT
+ {"RadarDebug", Set_RadarDebug_Proc},
+ /*{"RadarHit", Set_RadarHit_Proc},*/
+ {"CSPeriod", Set_CSPeriod_Proc},
+ {"ResetRadarHwDetect", Set_ResetRadarHwDetect_Proc},
+ {"DfsSwDisable", Set_DfsSwDisable_Proc},
+ {"DfsEvDropAdjTime", Set_DfsEnvtDropAdjTime_Proc},
+ {"RadarStart", Set_RadarStart_Proc},
+ {"RadarStop", Set_RadarStop_Proc},
+ {"RadarT1", Set_RadarSetTbl1_Proc},
+ {"RadarT2", Set_RadarSetTbl2_Proc},
+ {"Fcc5Thrd", Set_Fcc5Thrd_Proc},
+ {"ChBusyThrd", Set_ChBusyThrd_Proc},
+ {"RssiThrd", Set_RssiThrd_Proc},
+ {"PollTime", Set_PollTime_Proc},
+ {"CEPrint", Set_CEPrint_Proc},
+ {"RadarSim", Set_RadarSim_Proc},
+ {"PrintBusyIdle", Set_PrintBusyIdle_Proc},
+ {"BusyIdleRatio", Set_BusyIdleRatio_Proc},
+ {"DfsRssiHigh", Set_DfsRssiHigh_Proc},
+ {"DfsRssiLow", Set_DfsRssiLow_Proc},
+ {"EventExpire", Set_EventExpire_Proc},
+ {"Ch0LErr", Set_Ch0LErr_Proc},
+ {"PeriodErr", Set_PeriodErr_Proc},
+ {"MaxPeriod", Set_MaxPeriod_Proc},
+ {"Ch0HErr", Set_Ch0HErr_Proc},
+ {"Ch1Shift", Set_Ch1Shift_Proc},
+ {"Ch2Shift", Set_Ch2Shift_Proc},
+ {"CheckLoop", Set_CheckLoop_Proc},
+ {"DeclareThres", Set_DeclareThres_Proc},
+ {"ChMovTime", Set_ChMovingTime_Proc},
+ {"BlockChReset", Set_BlockChReset_Proc},
+ {"RfReg", Set_RfReg_Proc},
+#ifdef DFS_DEBUG
+ {"DfsLowerLimit", Set_DfsLowerLimit_Proc},
+ {"DfsUpperLimit", Set_DfsUpperLimit_Proc},
+ /*{"FixDfsLimit", Set_FixDfsLimit_Proc},*/
+ /*{"AvgRssiReq", Set_AvgRssiReq_Proc},*/
+ {"CEPrintDebug", Set_CEPrintDebug_Proc},
+#endif /* DFS_DEBUG */
+#endif /* DFS_SUPPORT */
+#ifdef CARRIER_DETECTION_SUPPORT
+ {"CarrierDetect", Set_CarrierDetect_Proc},
+ {"CarrierCriteria", Set_CarrierCriteria_Proc},
+ {"CarrierReCheck", Set_CarrierReCheck_Proc},
+ {"CarrierGoneThreshold", Set_CarrierGoneThreshold_Proc},
+ {"CarrierDebug", Set_CarrierDebug_Proc},
+ {"Delta", Set_CarrierDelta_Proc},
+ {"DivFlag", Set_CarrierDivFlag_Proc},
+ {"CarrThrd", Set_CarrierThrd_Proc},
+ /* v2 functions */
+ {"SymRund", Set_CarrierSymRund_Proc},
+ {"CarrMask", Set_CarrierMask_Proc},
+#endif /* CARRIER_DETECTION_SUPPORT */
+#endif /* defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT) */
+
+
+#ifdef RALINK_ATE
+ {"ATE", Set_ATE_Proc},
+ {"ATEDA", Set_ATE_DA_Proc},
+ {"ATESA", Set_ATE_SA_Proc},
+ {"ADCDump", Set_ADCDump_Proc},
+ {"ATEBSSID", Set_ATE_BSSID_Proc},
+ {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
+ {"ATEINITCHAN", Set_ATE_INIT_CHAN_Proc},
+#ifdef RTMP_INTERNAL_TX_ALC
+ {"ATETSSICBA", Set_ATE_TSSI_CALIBRATION_Proc},
+ {"ATETSSICBAEX", Set_ATE_TSSI_CALIBRATION_EX_Proc},
+#if defined(RT3350) || defined(RT3352)
+ {"ATETSSICALBRENABLE", RT335x_Set_ATE_TSSI_CALIBRATION_ENABLE_Proc},
+#endif /* defined(RT3350) || defined(RT3352) */
+#endif /* RTMP_INTERNAL_TX_ALC */
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+ {"ATEREADEXTSSI", Set_ATE_READ_EXTERNAL_TSSI_Proc},
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+ {"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},
+#ifdef RT3350
+ {"ATEPABIAS", Set_ATE_PA_Bias_Proc},
+#endif /* RT3350 */
+ {"ATETXFREQOFFSET", Set_ATE_TX_FREQ_OFFSET_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},
+ {"ATEWRF1", Set_ATE_Write_RF1_Proc},
+ {"ATEWRF2", Set_ATE_Write_RF2_Proc},
+ {"ATEWRF3", Set_ATE_Write_RF3_Proc},
+ {"ATEWRF4", Set_ATE_Write_RF4_Proc},
+ {"ATELDE2P", Set_ATE_Load_E2P_Proc},
+#ifdef RTMP_EFUSE_SUPPORT
+ {"bufferWriteBack", Set_ATE_Load_E2P_From_Buf_Proc},
+ {"bufferLoadFromEfuse", Set_LoadEepromBufferFromEfuse_Proc},
+ {"ATECALFREEINFO", Set_ATE_Cal_Free_Info_Proc},
+#endif /* RTMP_EFUSE_SUPPORT */
+ {"ATERE2P", Set_ATE_Read_E2P_Proc},
+#ifdef LED_CONTROL_SUPPORT
+#endif /* LED_CONTROL_SUPPORT */
+ {"ATEAUTOALC", Set_ATE_AUTO_ALC_Proc},
+ {"ATEIPG", Set_ATE_IPG_Proc},
+ {"ATEPAYLOAD", Set_ATE_Payload_Proc},
+#ifdef TXBF_SUPPORT
+ {"ATETXBF", Set_ATE_TXBF_Proc},
+ {"ATETXSOUNDING", Set_ATE_TXSOUNDING_Proc},
+ {"ATETXBFDIVCAL", Set_ATE_TXBF_DIVCAL_Proc},
+ {"ATETXBFLNACAL", Set_ATE_TXBF_LNACAL_Proc},
+ {"ATETxBfInit", Set_ATE_TXBF_INIT_Proc},
+ {"ATETxBfCal", Set_ATE_TXBF_CAL_Proc},
+ {"ATETxBfGolden", Set_ATE_TXBF_GOLDEN_Proc},
+ {"ATETxBfVerify", Set_ATE_TXBF_VERIFY_Proc},
+ {"ATETxBfVerifyN", Set_ATE_TXBF_VERIFY_NoComp_Proc},
+ {"ATEForceBBP", Set_ATE_ForceBBP_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},
+#ifdef DBG
+ {"EERead", Set_EERead_Proc},
+ {"EEWrite", Set_EEWrite_Proc},
+ {"BBPRead", Set_BBPRead_Proc},
+ {"BBPWrite", Set_BBPWrite_Proc},
+#endif /* DBG */
+
+#ifdef MT7601
+ {"ATETEMP", Set_ATE_Read_Temperature_Proc},
+ {"ATETSSIDC", Set_ATE_Read_TSSI_DC_Proc},
+#endif /* MT7601 */
+#endif /* RALINK_QA */
+#endif /* RALINK_ATE */
+
+#ifdef APCLI_SUPPORT
+ {"ApCliEnable", Set_ApCli_Enable_Proc},
+ {"ApCliSsid", Set_ApCli_Ssid_Proc},
+ {"ApCliBssid", Set_ApCli_Bssid_Proc},
+ {"ApCliAuthMode", Set_ApCli_AuthMode_Proc},
+ {"ApCliEncrypType", Set_ApCli_EncrypType_Proc},
+ {"ApCliDefaultKeyID", Set_ApCli_DefaultKeyID_Proc},
+ {"ApCliWPAPSK", Set_ApCli_WPAPSK_Proc},
+ {"ApCliKey1", Set_ApCli_Key1_Proc},
+ {"ApCliKey2", Set_ApCli_Key2_Proc},
+ {"ApCliKey3", Set_ApCli_Key3_Proc},
+ {"ApCliKey4", Set_ApCli_Key4_Proc},
+ {"ApCliTxMode", Set_ApCli_TxMode_Proc},
+ {"ApCliTxMcs", Set_ApCli_TxMcs_Proc},
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ {"ApCliWpaSupport", Set_ApCli_Wpa_Support},
+ {"ApCliIEEE1X", Set_ApCli_IEEE8021X_Proc},
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+#ifdef WSC_AP_SUPPORT
+ {"ApCliWscSsid", Set_AP_WscSsid_Proc},
+#endif /* WSC_AP_SUPPORT */
+#endif /* APCLI_SUPPORT */
+#ifdef WSC_AP_SUPPORT
+ {"WscConfMode", Set_AP_WscConfMode_Proc},
+ {"WscConfStatus", Set_AP_WscConfStatus_Proc},
+ {"WscMode", Set_AP_WscMode_Proc},
+ {"WscStatus", Set_WscStatus_Proc},
+ {"WscGetConf", Set_AP_WscGetConf_Proc},
+ {"WscPinCode", Set_AP_WscPinCode_Proc},
+ {"WscStop", Set_WscStop_Proc},
+ {"WscGenPinCode", Set_WscGenPinCode_Proc},
+ {"WscVendorPinCode", Set_WscVendorPinCode_Proc},
+ {"WscSecurityMode", Set_AP_WscSecurityMode_Proc},
+ {"WscMultiByteCheck", Set_AP_WscMultiByteCheck_Proc},
+ {"WscVersion", Set_WscVersion_Proc},
+#ifdef WSC_V2_SUPPORT
+ {"WscV2Support", Set_WscV2Support_Proc},
+ {"WscVersion2", Set_WscVersion2_Proc},
+ {"WscExtraTlvTag", Set_WscExtraTlvTag_Proc},
+ {"WscExtraTlvType", Set_WscExtraTlvType_Proc},
+ {"WscExtraTlvData", Set_WscExtraTlvData_Proc},
+ {"WscSetupLock", Set_WscSetupLock_Proc},
+ {"WscFragment", Set_WscFragment_Proc},
+ {"WscFragmentSize", Set_WscFragmentSize_Proc},
+ {"WscMaxPinAttack", Set_WscMaxPinAttack_Proc},
+ {"WscSetupLockTime", Set_WscSetupLockTime_Proc},
+#endif /* WSC_V2_SUPPORT */
+#endif /* WSC_AP_SUPPORT */
+#ifdef UAPSD_SUPPORT
+ {"UAPSDCapable", Set_UAPSD_Proc},
+#endif /* UAPSD_SUPPORT */
+#ifdef IGMP_SNOOP_SUPPORT
+ {"IgmpSnEnable", Set_IgmpSn_Enable_Proc},
+ {"IgmpAdd", Set_IgmpSn_AddEntry_Proc},
+ {"IgmpDel", Set_IgmpSn_DelEntry_Proc},
+#endif /* IGMP_SNOOP_SUPPORT */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MCAST_RATE_SPECIFIC
+ {"McastPhyMode", Set_McastPhyMode},
+ {"McastMcs", Set_McastMcs},
+#endif /* MCAST_RATE_SPECIFIC */
+#endif /* CONFIG_AP_SUPPORT */
+ {"FixedTxMode", Set_FixedTxMode_Proc},
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ {"OpMode", Set_OpMode_Proc},
+#endif /* CONFIG_APSTA_MIXED_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ {"TxBfTag", Set_TxBfTag_Proc},
+ {"ReadITxBf", Set_ReadITxBf_Proc},
+ {"WriteITxBf", Set_WriteITxBf_Proc},
+ {"StatITxBf", Set_StatITxBf_Proc},
+ {"ReadETxBf", Set_ReadETxBf_Proc},
+ {"WriteETxBf", Set_WriteETxBf_Proc},
+ {"StatETxBf", Set_StatETxBf_Proc},
+ {"ITxBfTimeout", Set_ITxBfTimeout_Proc},
+ {"ETxBfTimeout", Set_ETxBfTimeout_Proc},
+ {"InvTxBfTag", Set_InvTxBfTag_Proc},
+ {"ITxBfCal", Set_ITxBfCal_Proc},
+ {"ITxBfDivCal", Set_ITxBfDivCal_Proc},
+ {"ITxBfLnaCal", Set_ITxBfLnaCal_Proc},
+
+ {"ITxBfEn", Set_ITxBfEn_Proc},
+ {"ETxBfEnCond", Set_ETxBfEnCond_Proc},
+ {"ETxBfCodebook", Set_ETxBfCodebook_Proc},
+ {"ETxBfCoefficient", Set_ETxBfCoefficient_Proc},
+ {"ETxBfGrouping", Set_ETxBfGrouping_Proc},
+ {"ETxBfNoncompress", Set_ETxBfNoncompress_Proc},
+ {"ETxBfIncapable", Set_ETxBfIncapable_Proc},
+ {"NoSndgCntThrd", Set_NoSndgCntThrd_Proc},
+ {"NdpSndgStreams", Set_NdpSndgStreams_Proc},
+ {"TriggerSounding", Set_Trigger_Sounding_Proc},
+#endif /* TXBF_SUPPORT */
+
+
+#ifdef PRE_ANT_SWITCH
+ {"PreAntSwitch", Set_PreAntSwitch_Proc},
+ {"PreAntSwitchRSSI", Set_PreAntSwitchRSSI_Proc},
+ {"PreAntSwitchTimeout", Set_PreAntSwitchTimeout_Proc},
+#endif /* PRE_ANT_SWITCH */
+
+#ifdef CFO_TRACK
+ {"CFOTrack", Set_CFOTrack_Proc},
+#endif /* CFO_TRACK */
+
+#ifdef STREAM_MODE_SUPPORT
+ {"StreamMode", Set_StreamMode_Proc},
+ {"StreamModeMac", Set_StreamModeMac_Proc},
+ {"StreamModeMCS", Set_StreamModeMCS_Proc},
+#endif /* STREAM_MODE_SUPPORT */
+
+#ifdef DBG_CTRL_SUPPORT
+ {"DebugFlags", Set_DebugFlags_Proc},
+#ifdef INCLUDE_DEBUG_QUEUE
+ {"DebugQueue", Set_DebugQueue_Proc},
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ {"LongRetry", Set_LongRetryLimit_Proc},
+ {"ShortRetry", Set_ShortRetryLimit_Proc},
+ {"AutoFallBack", Set_AutoFallBack_Proc},
+
+ {"MeasureReq", Set_MeasureReq_Proc},
+ {"TpcReq", Set_TpcReq_Proc},
+ {"PwrConstraint", Set_PwrConstraint},
+#ifdef DOT11N_DRAFT3
+ {"OBSSScanParam", Set_OBSSScanParam_Proc},
+ {"AP2040Rescan", Set_AP2040ReScan_Proc},
+ {"HtBssCoex", Set_HT_BssCoex_Proc},
+ {"HtBssCoexApCntThr", Set_HT_BssCoexApCntThr_Proc},
+#endif /* DOT11N_DRAFT3 */
+ {"EntryLifeCheck", Set_EntryLifeCheck_Proc},
+
+#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 */
+
+
+
+
+#ifdef AP_QLOAD_SUPPORT
+ {"qloadclr", Set_QloadClr_Proc},
+ {"qloadalarmtimethres", Set_QloadAlarmTimeThreshold_Proc}, /* QLOAD ALARM */
+ {"qloadalarmnumthres", Set_QloadAlarmNumThreshold_Proc}, /* QLOAD ALARM */
+#endif /* AP_QLOAD_SUPPORT */
+
+ {"ra_interval", Set_RateAdaptInterval},
+
+
+ {"memdebug", Set_MemDebug_Proc},
+
+#ifdef CONFIG_AP_SUPPORT
+ {"pslifetime", Set_PowerSaveLifeTime_Proc},
+
+#ifdef MBSS_SUPPORT
+ {"MBSSWirelessMode", Set_MBSS_WirelessMode_Proc},
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ {"VcoPeriod", Set_VcoPeriod_Proc},
+
+#ifdef SINGLE_SKU
+ {"ModuleTxpower", Set_ModuleTxpower_Proc},
+#endif /* SINGLE_SKU */
+
+
+#ifdef FPGA_MODE
+ {"fpga_on", set_fpga_mode}, /* 1 = manual mode, 2 = fix phy/mode/rate/mcs */
+ {"dataphy", set_data_phy_mode}, /* 0 = CCK, 1 = OFDM, 2 = MODE_HTMIX, 3 = HT-GF, 4 = VHT */
+ {"databw", set_data_bw}, /* 0 = 20M, 1 = 40M, 2 = 80M */
+ {"datamcs", set_data_mcs}, /* 0~ 15 */
+ {"databasize", set_data_basize},
+ {"datagi", set_data_gi},
+ {"txcnt", set_tx_kickcnt},
+#endif /* FPGA_MODE */
+#ifdef WFA_VHT_PF
+ {"force_amsdu", set_force_amsdu},
+#endif /* WFA_VHT_PF */
+
+#ifdef RLT_RF
+ {"rf", set_rf},
+#endif /* RLT_RF */
+
+ {"LoopBackFlag", Set_LoopBackFlag_Proc},
+ {"TestTxFrame", Set_TestTxFrameProc},
+ {"TestTxFrame1", Set_TestTxFrame1Proc},
+ {"TestTxFrame2", Set_TestTxFrame2Proc},
+ {"TestTxFrame3", Set_TestTxFrame3Proc},
+ {"TestTxFrame4", Set_TestTxFrame4Proc},
+ {"DumpBeaconBuffer", Set_DumpBeaconBuffer_Proc},
+ {"InsertWAPIKey", Set_InsertWAPIKeyProc},
+ {"TestWAPIFrame", Set_TestWAPIFrameProc},
+ {"TestMultiMacAddr", Set_TestMultiMacAddrProc},
+ {"HwTxLookupRate", Set_HwTxLookupRate_Proc},
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ {"MO_FalseCCATh", Set_MO_FalseCCATh_Proc},
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ {NULL,}
+};
+
+
+static struct {
+ PSTRING name;
+ INT (*set_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg);
+} *PRTMP_PRIVATE_SHOW_PROC, RTMP_PRIVATE_SHOW_SUPPORT_PROC[] = {
+ {"stainfo", Show_MacTable_Proc},
+ {"stacountinfo", Show_StaCount_Proc},
+ {"stasecinfo", Show_StaSecurityInfo_Proc},
+ {"descinfo", Show_DescInfo_Proc},
+ {"driverinfo", Show_DriverInfo_Proc},
+ {"devinfo", show_devinfo_proc},
+#ifdef WDS_SUPPORT
+ {"wdsinfo", Show_WdsTable_Proc},
+#endif /* WDS_SUPPORT */
+#ifdef DOT11_N_SUPPORT
+ {"bainfo", Show_BaTable_Proc},
+#endif /* DOT11_N_SUPPORT */
+ {"stat", Show_Sat_Proc},
+#ifdef DBG_DIAGNOSE
+ {"diag", Show_Diag_Proc},
+#endif /* DBG_DIAGNOSE */
+ {"stat_reset", Show_Sat_Reset_Proc},
+#ifdef IGMP_SNOOP_SUPPORT
+ {"igmpinfo", Set_IgmpSn_TabDisplay_Proc},
+#endif /* IGMP_SNOOP_SUPPORT */
+#ifdef MCAST_RATE_SPECIFIC
+ {"mcastrate", Show_McastRate},
+#endif /* MCAST_RATE_SPECIFIC */
+#ifdef MAT_SUPPORT
+ {"matinfo", Show_MATTable_Proc},
+#endif /* MAT_SUPPORT */
+#ifdef DFS_SUPPORT
+ {"blockch", Show_BlockCh_Proc},
+#endif /* DFS_SUPPORT */
+#ifdef AP_QLOAD_SUPPORT
+ {"qload", Show_QoSLoad_Proc},
+#endif /* AP_QLOAD_SUPPORT */
+#ifdef APCLI_SUPPORT
+ {"connStatus", RTMPIoctlConnStatus},
+#endif
+
+ {"rainfo", Show_RAInfo_Proc},
+
+#ifdef MBSS_SUPPORT
+ {"mbss", Show_MbssInfo_Display_Proc},
+#endif /* MBSS_SUPPORT */
+#ifdef WSC_AP_SUPPORT
+ {"WscPeerList", WscApShowPeerList},
+#endif /* WSC_AP_SUPPORT */
+ {NULL,}
+};
+
+
+INT RTMPAPPrivIoctlSet(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr)
+{
+ PSTRING this_char;
+ PSTRING value;
+ INT Status = NDIS_STATUS_SUCCESS;
+
+ while ((this_char = strsep((char **)&pIoctlCmdStr->u.data.pointer, ",")) != NULL)
+ {
+ if (!*this_char)
+ continue;
+
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value
+#ifdef WSC_AP_SUPPORT
+ && (
+ (strcmp(this_char, "WscStop") != 0) &&
+ (strcmp(this_char, "WscGenPinCode")!= 0)
+ )
+#endif /* WSC_AP_SUPPORT */
+ )
+ continue;
+
+ for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
+ {
+ if (!strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name))
+ {
+ if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAd, value))
+ { /*FALSE:Set private failed then return Invalid argument */
+ Status = -EINVAL;
+ }
+ break; /*Exit for loop. */
+ }
+ }
+
+ if(PRTMP_PRIVATE_SET_PROC->name == NULL)
+ { /*Not found argument */
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::(iwpriv) Command not Support [%s=%s]\n", this_char, value));
+ break;
+ }
+ }
+
+ return Status;
+}
+
+
+INT RTMPAPPrivIoctlShow(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr)
+{
+ PSTRING this_char;
+ PSTRING value = NULL;
+ INT Status = NDIS_STATUS_SUCCESS;
+
+ while ((this_char = strsep((char **)&pIoctlCmdStr->u.data.pointer, ",")) != NULL)
+ {
+ if (!*this_char)
+ continue;
+
+ for (PRTMP_PRIVATE_SHOW_PROC = RTMP_PRIVATE_SHOW_SUPPORT_PROC; PRTMP_PRIVATE_SHOW_PROC->name; PRTMP_PRIVATE_SHOW_PROC++)
+ {
+ if (!strcmp(this_char, PRTMP_PRIVATE_SHOW_PROC->name))
+ {
+ if(!PRTMP_PRIVATE_SHOW_PROC->set_proc(pAd, value))
+ { /*FALSE:Set private failed then return Invalid argument */
+ Status = -EINVAL;
+ }
+ break; /*Exit for loop. */
+ }
+ }
+
+ if(PRTMP_PRIVATE_SHOW_PROC->name == NULL)
+ { /*Not found argument */
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::(iwpriv) Command not Support [%s=%s]\n", this_char, value));
+ break;
+ }
+ }
+
+ return Status;
+
+}
+
+#ifdef INF_AR9
+#ifdef AR9_MAPI_SUPPORT
+INT RTMPAPPrivIoctlAR9Show(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr)
+{
+ INT Status = NDIS_STATUS_SUCCESS;
+
+ if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_mac_table"))
+ {
+ RTMPAR9IoctlGetMacTable(pAd,pIoctlCmdStr);
+ }
+ else if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_stat2"))
+ {
+ RTMPIoctlGetSTAT2(pAd,pIoctlCmdStr);
+ }
+ else if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_radio_dyn_info"))
+ {
+ RTMPIoctlGetRadioDynInfo(pAd,pIoctlCmdStr);
+ }
+#ifdef WSC_AP_SUPPORT
+ else if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_wsc_profile"))
+ {
+ RTMPAR9IoctlWscProfile(pAd,pIoctlCmdStr);
+ }
+ else if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_wsc_pincode"))
+ {
+ RTMPIoctlWscPINCode(pAd,pIoctlCmdStr);
+ }
+ else if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_wsc_status"))
+ {
+ RTMPIoctlWscStatus(pAd,pIoctlCmdStr);
+ }
+ else if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_wps_dyn_info"))
+ {
+ RTMPIoctlGetWscDynInfo(pAd,pIoctlCmdStr);
+ }
+ else if(!strcmp(pIoctlCmdStr->u.data.pointer, "get_wps_regs_dyn_info"))
+ {
+ RTMPIoctlGetWscRegsDynInfo(pAd,pIoctlCmdStr);
+ }
+#endif
+ return Status;
+}
+#endif /*AR9_MAPI_SUPPORT*/
+#endif/*AR9_INF*/
+
+INT RTMPAPSetInformation(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT RTMP_IOCTL_INPUT_STRUCT *rq,
+ IN INT cmd)
+{
+ RTMP_IOCTL_INPUT_STRUCT *wrq = (RTMP_IOCTL_INPUT_STRUCT *) rq;
+ UCHAR Addr[MAC_ADDR_LEN];
+ INT Status = NDIS_STATUS_SUCCESS;
+
+#ifdef SNMP_SUPPORT
+ /*snmp */
+ UINT KeyIdx = 0;
+ PNDIS_AP_802_11_KEY pKey = NULL;
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ ULONG ShortRetryLimit, LongRetryLimit;
+ UCHAR ctmp;
+#endif /* SNMP_SUPPORT */
+
+
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
+ NDIS_802_11_SSID Ssid;
+
+#ifdef HOSTAPD_SUPPORT
+ MAC_TABLE_ENTRY *pEntry;
+ struct ieee80211req_mlme mlme;
+
+ struct ieee80211req_key Key;
+ struct ieee80211req_del_key delkey;
+ UINT8 Wcid;
+ PMULTISSID_STRUCT pMbss ;
+ WSC_LV_INFO WscIEBeacon;
+ WSC_LV_INFO WscIEProbeResp;
+ int i;
+#endif /*HOSTAPD_SUPPORT*/
+
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ UCHAR ifIndex;
+ BOOLEAN apcliEn=FALSE;
+ PNDIS_APCLI_802_11_PMKID pPmkId = NULL;
+ BOOLEAN IEEE8021xState = FALSE;
+ BOOLEAN IEEE8021x_required_keys = FALSE;
+ UCHAR wpa_supplicant_enable = 0;
+ PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
+ INT BssIdx, i;
+ PNDIS_802_11_WEP pWepKey =NULL;
+ PAPCLI_STRUCT pApCliEntry=NULL;
+ MAC_TABLE_ENTRY *pMacEntry=(MAC_TABLE_ENTRY *)NULL;
+ PNDIS_APCLI_802_11_KEY pApCliKey = NULL;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+ MLME_DEAUTH_REQ_STRUCT DeAuthFrame;
+ PULONG pCurrState;
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
+
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ switch(cmd & 0x7FFF)
+ {
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ case OID_802_11_SET_IEEE8021X:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+
+ if(apcliEn == TRUE )
+ {
+ Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
+ pAd->ApCfg.ApCliTab[ifIndex].IEEE8021X = IEEE8021xState;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set Apcli(%d)::OID_802_11_SET_IEEE8021X (=%d)\n",ifIndex, IEEE8021xState));
+ }
+ else
+ Status = -EINVAL;
+ }
+ break;
+
+ case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ if(apcliEn == TRUE )
+ {
+ Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
+ pAd->ApCfg.ApCliTab[ifIndex].IEEE8021x_required_keys = IEEE8021x_required_keys;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set Apcli(%d)::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n",ifIndex, IEEE8021x_required_keys));
+ }
+ else
+ Status = -EINVAL;
+ }
+ break;
+
+ case OID_802_11_PMKID:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ os_alloc_mem(NULL, (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->ApCfg.ApCliTab[ifIndex].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->ApCfg.ApCliTab[ifIndex].SavedPMKNum; CachedIdx++)
+ {
+ /* compare the BSSID */
+ if (NdisEqualMemory(pBssIdInfo->BSSID, pAd->ApCfg.ApCliTab[ifIndex].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->ApCfg.ApCliTab[ifIndex].SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+ pAd->ApCfg.ApCliTab[ifIndex].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->ApCfg.ApCliTab[ifIndex].SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+ }
+ }
+ }
+ if(pPmkId)
+ os_free_mem(NULL, pPmkId);
+ break;
+
+ case RT_OID_WPA_SUPPLICANT_SUPPORT:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ 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->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP |= WPA_SUPPLICANT_ENABLE_WPS;
+ else
+ {
+ pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP = wpa_supplicant_enable;
+ pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP &= 0x7F;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=0x%02X)\n", pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP));
+ }
+ break;
+
+ case OID_802_11_REMOVE_KEY:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ os_alloc_mem(NULL, (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->ApCfg.ApCliTab[ifIndex].AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ RTMPWPARemoveKeyProc(pAd, pRemoveKey);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
+ }
+ else
+ {
+ UINT KeyIdx;
+ BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + ifIndex;
+ 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->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx].KeyLen = 0;
+ pAd->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAd, BssIdx, (UCHAR)KeyIdx);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
+ }
+ }
+ }
+ }
+ if (pRemoveKey)
+ os_free_mem(NULL, pRemoveKey);
+ break;
+ case OID_802_11_ADD_WEP:
+
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ os_alloc_mem(NULL, (UCHAR **)&pWepKey, wrq->u.data.length);
+ if(pWepKey == NULL)
+ {
+ Status = -ENOMEM;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set Apcli::OID_802_11_ADD_WEP, Failed!!\n"));
+ break;
+ }
+ BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + ifIndex;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID];
+
+ 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
+ {
+ UINT KeyIdx;
+ KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+ /* KeyIdx must be 0 ~ 3 */
+ if (KeyIdx > 4)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set ApCli::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->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx], sizeof(CIPHER_KEY));
+
+ /* set key material and key length */
+ pAd->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].SharedKey[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->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx].CipherAlg = CipherAlg;
+
+ /* Default key for tx (shared key) */
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+
+ NdisZeroMemory(&pAd->ApCfg.ApCliTab[ifIndex].DesireSharedKey[KeyIdx], sizeof(CIPHER_KEY));
+
+ /* set key material and key length */
+ pAd->ApCfg.ApCliTab[ifIndex].DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+ pAd->ApCfg.ApCliTab[ifIndex].DesireSharedKeyId = KeyIdx;
+ pAd->ApCfg.ApCliTab[ifIndex].DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
+
+ pAd->ApCfg.ApCliTab[ifIndex].DefaultKeyId = (UCHAR) KeyIdx;
+ }
+
+
+ if ((pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ Key = pWepKey->KeyMaterial;
+
+ /* Set Group key material to Asic */
+ AsicAddSharedKeyEntry(pAd, BssIdx, KeyIdx, &pAd->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx]);
+
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+ RTMPSetWcidSecurityInfo(pAd, BssIdx, KeyIdx, CipherAlg, pApCliEntry->MacTabWCID, SHAREDKEYTABLE);
+ }
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ }
+ else if ((pAd->ApCfg.ApCliTab[ifIndex].Valid == TRUE)
+ && (pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED))
+ {
+ Key = pAd->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx].Key;
+
+ /* Set key material and cipherAlg to Asic */
+ AsicAddSharedKeyEntry(pAd, BssIdx, KeyIdx, &pAd->ApCfg.ApCliTab[ifIndex].SharedKey[KeyIdx]);
+
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+ /* Assign pairwise key info */
+ RTMPSetWcidSecurityInfo(pAd,
+ BssIdx,
+ KeyIdx,
+ CipherAlg,
+ pApCliEntry->MacTabWCID,
+ SHAREDKEYTABLE);
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set ApCli::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED ? "Port Secured":"Port NOT Secured"));
+ }
+ }
+ if (pWepKey)
+ os_free_mem(NULL, pWepKey);
+ break;
+
+ case OID_802_11_ADD_KEY:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + ifIndex;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID];
+
+ os_alloc_mem(NULL, (UCHAR **)&pApCliKey, wrq->u.data.length);
+ if(pApCliKey == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+ Status = copy_from_user(pApCliKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (pApCliKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
+ }
+ else
+ {
+ RTMPApCliAddKey(pAd, ifIndex, pApCliKey);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pApCliKey->KeyIndex, pApCliKey->KeyLength));
+ }
+ if (pApCliKey)
+ os_free_mem(NULL, pApCliKey);
+ break;
+
+ case OID_802_11_DISASSOCIATE:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ if (!apcliEn || ifIndex >= MAX_APCLI_NUM)
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
+
+ DisassocParmFill(pAd, &DisassocReq, pAd->MlmeAux.Bssid, REASON_DISASSOC_STA_LEAVING);
+
+ MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq, ifIndex);
+
+ if (pApCliEntry->Valid)
+ ApCliLinkDown(pAd, ifIndex);
+
+ /* set the apcli interface be invalid. */
+ pApCliEntry->Valid = FALSE;
+
+ /* clear MlmeAux.Ssid and Bssid. */
+ NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->MlmeAux.SsidLen = 0;
+ NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pAd->MlmeAux.Rssi = 0;
+
+ *pCurrState = APCLI_CTRL_DEASSOC;
+ break;
+
+ case OID_802_11_DROP_UNENCRYPTED:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID];
+
+ if (!apcliEn)
+ return FALSE;
+
+ 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)
+ {
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pMacEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ }
+ else
+ {
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set ApCLi::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
+ }
+ break;
+
+ case OID_SET_COUNTERMEASURES:
+
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID];
+
+ if (!apcliEn)
+ return FALSE;
+
+ 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)
+ pApCliEntry->bBlockAssoc = TRUE;
+ else
+ /* WPA MIC error should block association attempt for 60 seconds */
+ pApCliEntry->bBlockAssoc = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set ApCli::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pApCliEntry->bBlockAssoc ? "TRUE":"FALSE"));
+ }
+ break;
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
+
+ case OID_802_11_DEAUTHENTICATION:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION\n"));
+ if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
+ Status = -EINVAL;
+ else
+ {
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ MLME_DEAUTH_REQ_STRUCT *pInfo = NULL;
+ 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));
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+ if (ifIndex >= MAX_APCLI_NUM)
+ return FALSE;
+
+ os_alloc_mem(pAd, (UCHAR **)&pInfo, sizeof(MLME_DEAUTH_REQ_STRUCT));
+ Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
+ /* Fill in the related information */
+ DeAuthFrame.Reason = (USHORT)pInfo->Reason;
+ COPY_MAC_ADDR(DeAuthFrame.Addr, pInfo->Addr);
+
+ MlmeEnqueue(pAd,
+ APCLI_AUTH_STATE_MACHINE,
+ APCLI_MT2_MLME_DEAUTH_REQ,
+ sizeof(MLME_DEAUTH_REQ_STRUCT),
+ &DeAuthFrame,
+ ifIndex);
+
+ if (pApCliEntry->Valid)
+ ApCliLinkDown(pAd, ifIndex);
+
+ /* set the apcli interface be invalid.*/
+ pApCliEntry->Valid = FALSE;
+
+ /* clear MlmeAux.Ssid and Bssid.*/
+ NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->MlmeAux.SsidLen = 0;
+ NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pAd->MlmeAux.Rssi = 0;
+
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ if(pInfo)
+ os_free_mem(NULL, pInfo);
+
+ }
+ else
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif/*APCLI_SUPPORT*/
+ {
+ if (Elem)
+ {
+ pInfo = (MLME_DEAUTH_REQ_STRUCT *) Elem->Msg;
+ Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
+
+ if ((pEntry = MacTableLookup(pAd, pInfo->Addr)) != NULL)
+ {
+ Elem->Wcid = pEntry->Aid;
+ MlmeEnqueue(pAd, AP_AUTH_STATE_MACHINE, APMT2_MLME_DEAUTH_REQ,
+ sizeof(MLME_DEAUTH_REQ_STRUCT), Elem, 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
+ }
+ /* kfree(Elem); */
+ os_free_mem(NULL, Elem);
+ }
+ else
+ Status = -EFAULT;
+ }
+ }
+
+ break;
+#ifdef IAPP_SUPPORT
+ case RT_SET_IAPP_PID:
+ {
+ unsigned long IappPid;
+ if (copy_from_user(&IappPid, wrq->u.data.pointer, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ else
+ {
+ RTMP_GET_OS_PID(pObj->IappPid, IappPid);
+ pObj->IappPid_nr = IappPid;
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_SET_APD_PID::(IappPid=%lu(0x%x))\n", IappPid, pObj->IappPid));
+ }
+ }
+ break;
+#endif /* IAPP_SUPPORT */
+
+ case RT_SET_APD_PID:
+ {
+ unsigned long apd_pid;
+ if (copy_from_user(&apd_pid, wrq->u.data.pointer, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ else
+ {
+ RTMP_GET_OS_PID(pObj->apd_pid, apd_pid);
+ pObj->apd_pid_nr = apd_pid;
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_SET_APD_PID::(ApdPid=%lu(0x%x))\n", apd_pid, pObj->apd_pid));
+ }
+ }
+ break;
+ case RT_SET_DEL_MAC_ENTRY:
+ if (copy_from_user(Addr, wrq->u.data.pointer, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ else
+ {
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_SET_DEL_MAC_ENTRY::(%02x:%02x:%02x:%02x:%02x:%02x)\n", Addr[0],Addr[1],Addr[2],Addr[3],Addr[4],Addr[5]));
+
+ pEntry = MacTableLookup(pAd, Addr);
+ if (pEntry)
+ {
+ MlmeDeAuthAction(pAd, pEntry, REASON_DISASSOC_STA_LEAVING, FALSE);
+/* MacTableDeleteEntry(pAd, pEntry->Aid, Addr); */
+ }
+ }
+ break;
+#ifdef WSC_AP_SUPPORT
+ case RT_OID_WSC_SET_SELECTED_REGISTRAR:
+ {
+ PUCHAR upnpInfo;
+ UCHAR apidx = pObj->ioctl_if;
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ Status = -EINVAL;
+ }
+ else
+ {
+#endif /*HOSTAPD_SUPPORT*/
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WSC::RT_OID_WSC_SET_SELECTED_REGISTRAR, wrq->u.data.length=%d!\n", wrq->u.data.length));
+/* upnpInfo = kmalloc(wrq->u.data.length, GFP_KERNEL); */
+ os_alloc_mem(pAd, (UCHAR **)&upnpInfo, wrq->u.data.length);
+ if(upnpInfo)
+ {
+ int len, Status;
+
+ Status = copy_from_user(upnpInfo, wrq->u.data.pointer, wrq->u.data.length);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ len = wrq->u.data.length;
+
+ if((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode & WSC_PROXY))
+ {
+ WscSelectedRegistrar(pAd, upnpInfo, len, apidx);
+ if (pAd->ApCfg.MBSSID[apidx].WscControl.Wsc2MinsTimerRunning == TRUE)
+ {
+ BOOLEAN Cancelled;
+ RTMPCancelTimer(&pAd->ApCfg.MBSSID[apidx].WscControl.Wsc2MinsTimer, &Cancelled);
+ }
+ /* 2mins time-out timer */
+ RTMPSetTimer(&pAd->ApCfg.MBSSID[apidx].WscControl.Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT);
+ pAd->ApCfg.MBSSID[apidx].WscControl.Wsc2MinsTimerRunning = TRUE;
+ }
+ }
+/* kfree(upnpInfo); */
+ os_free_mem(NULL, upnpInfo);
+ }
+ else
+ {
+ Status = -EINVAL;
+ }
+#ifdef HOSTAPD_SUPPORT
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+ }
+ break;
+ case RT_OID_WSC_EAPMSG:
+ {
+ RTMP_WSC_U2KMSG_HDR *msgHdr = NULL;
+ PUCHAR pUPnPMsg = NULL;
+ UINT msgLen = 0, Machine = 0, msgType = 0;
+ int retVal, senderID = 0;
+#ifdef HOSTAPD_SUPPORT
+ UCHAR apidx = pObj->ioctl_if;
+
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ Status = -EINVAL;
+ }
+ else
+ {
+#endif /*HOSTAPD_SUPPORT*/
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WSC::RT_OID_WSC_EAPMSG, wrq->u.data.length=%d, ioctl_if=%d\n", wrq->u.data.length, pObj->ioctl_if));
+
+ msgLen = wrq->u.data.length;
+ os_alloc_mem(pAd, (UCHAR **)&pUPnPMsg, msgLen);
+/* if((pUPnPMsg = kmalloc(msgLen, GFP_KERNEL)) == NULL) */
+ if (pUPnPMsg == NULL)
+ Status = -EINVAL;
+ else
+ {
+ int HeaderLen;
+ PSTRING pWpsMsg;
+ UINT WpsMsgLen;
+ PWSC_CTRL pWscControl;
+ BOOLEAN bGetDeviceInfo = FALSE;
+
+ NdisZeroMemory(pUPnPMsg, msgLen);
+ retVal = copy_from_user(pUPnPMsg, wrq->u.data.pointer, msgLen);
+
+ msgHdr = (RTMP_WSC_U2KMSG_HDR *)pUPnPMsg;
+ senderID = get_unaligned((INT32 *)(&msgHdr->Addr2[0]));
+ /*senderID = *((int *)&msgHdr->Addr2); */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_WSC_EAPMSG++++++++\n\n"));
+ hex_dump("MAC::", &msgHdr->Addr3[0], MAC_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_WSC_EAPMSG++++++++\n\n"));
+
+ HeaderLen = LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME);
+ pWpsMsg = (PSTRING) &pUPnPMsg[HeaderLen];
+ WpsMsgLen = msgLen - HeaderLen;
+
+ /*assign the STATE_MACHINE type */
+ Machine = WSC_STATE_MACHINE;
+ msgType = WSC_EAPOL_UPNP_MSG;
+
+ pWscControl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl;
+ /* If AP is unconfigured, WPS state machine will be triggered after received M2. */
+ if ((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED)
+#ifdef WSC_V2_SUPPORT
+ && (pWscControl->WscV2Info.bWpsEnable || (pWscControl->WscV2Info.bEnableWpsV2 == FALSE))
+#endif /* WSC_V2_SUPPORT */
+ )
+ {
+ if (strstr(pWpsMsg, "SimpleConfig") &&
+ !pWscControl->EapMsgRunning &&
+ !pWscControl->WscUPnPNodeInfo.bUPnPInProgress)
+ {
+ /* GetDeviceInfo */
+ WscInit(pAd, FALSE, pObj->ioctl_if);
+ /* trigger wsc re-generate public key */
+ pWscControl->RegData.ReComputePke = 1;
+ bGetDeviceInfo = TRUE;
+ }
+ else if (WscRxMsgTypeFromUpnp(pAd, pWpsMsg, WpsMsgLen) == WSC_MSG_M2 &&
+ !pWscControl->EapMsgRunning &&
+ !pWscControl->WscUPnPNodeInfo.bUPnPInProgress)
+ {
+ /* Check Enrollee Nonce of M2 */
+ if (WscCheckEnrolleeNonceFromUpnp(pAd, pWpsMsg, WpsMsgLen, pWscControl))
+ {
+ WscGetConfWithoutTrigger(pAd, pWscControl, TRUE);
+ pWscControl->WscState = WSC_STATE_SENT_M1;
+ }
+ }
+ }
+
+ retVal = MlmeEnqueueForWsc(pAd, msgHdr->envID, senderID, Machine, msgType, msgLen, pUPnPMsg);
+ if((retVal == FALSE) && (msgHdr->envID != 0))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeEnqueuForWsc return False and envID=0x%x!\n", msgHdr->envID));
+ Status = -EINVAL;
+ }
+
+ os_free_mem(NULL, pUPnPMsg);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_WSC_EAPMSG finished!\n"));
+#ifdef HOSTAPD_SUPPORT
+ }
+#endif /*HOSTAPD_SUPPORT*/
+ }
+ break;
+
+ case RT_OID_WSC_READ_UFD_FILE:
+ if (wrq->u.data.length > 0)
+ {
+ STRING *pWscUfdFileName = NULL;
+ UCHAR apIdx = pObj->ioctl_if;
+ PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[apIdx].WscControl;
+/* pWscUfdFileName = (PSTRING)kmalloc(wrq->u.data.length+1, MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&pWscUfdFileName, wrq->u.data.length+1);
+ if (pWscUfdFileName)
+ {
+ RTMPZeroMemory(pWscUfdFileName, wrq->u.data.length+1);
+ if (copy_from_user(pWscUfdFileName, wrq->u.data.pointer, wrq->u.data.length))
+ Status = -EFAULT;
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_WSC_READ_UFD_FILE (WscUfdFileName=%s)\n", pWscUfdFileName));
+ if (pWscCtrl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED)
+ {
+ if (WscReadProfileFromUfdFile(pAd, apIdx, pWscUfdFileName))
+ {
+ pWscCtrl->WscConfStatus = WSC_SCSTATE_CONFIGURED;
+ APStop(pAd);
+ APStartUp(pAd);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_WSC_READ_UFD_FILE: AP is configured.\n"));
+ Status = -EINVAL;
+ }
+ }
+/* kfree(pWscUfdFileName); */
+ os_free_mem(NULL, pWscUfdFileName);
+ }
+ else
+ Status = -ENOMEM;
+ }
+ else
+ Status = -EINVAL;
+ break;
+
+ case RT_OID_WSC_WRITE_UFD_FILE:
+ if (wrq->u.data.length > 0)
+ {
+ STRING *pWscUfdFileName = NULL;
+ UCHAR apIdx = pObj->ioctl_if;
+ PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[apIdx].WscControl;
+/* pWscUfdFileName = (PSTRING)kmalloc(wrq->u.data.length+1, MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&pWscUfdFileName, wrq->u.data.length+1);
+ if (pWscUfdFileName)
+ {
+ RTMPZeroMemory(pWscUfdFileName, wrq->u.data.length+1);
+ if (copy_from_user(pWscUfdFileName, wrq->u.data.pointer, wrq->u.data.length))
+ Status = -EFAULT;
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_WSC_WRITE_UFD_FILE (WscUfdFileName=%s)\n", pWscUfdFileName));
+ if (pWscCtrl->WscConfStatus == WSC_SCSTATE_CONFIGURED)
+ {
+ WscWriteProfileToUfdFile(pAd, apIdx, pWscUfdFileName);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_WSC_WRITE_UFD_FILE: AP is un-configured.\n"));
+ Status = -EINVAL;
+ }
+ }
+/* kfree(pWscUfdFileName); */
+ os_free_mem(NULL, pWscUfdFileName);
+ }
+ else
+ Status = -ENOMEM;
+ }
+ else
+ Status = -EINVAL;
+ break;
+
+ case RT_OID_WSC_UUID:
+ if (wrq->u.data.length == (UUID_LEN_STR-1))
+ {
+ UCHAR apIdx = pObj->ioctl_if;
+ pAd->ApCfg.MBSSID[apIdx].WscControl.Wsc_Uuid_Str[0] = '\0';
+ Status = copy_from_user(&pAd->ApCfg.MBSSID[apIdx].WscControl.Wsc_Uuid_Str[0],
+ wrq->u.data.pointer,
+ wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("UUID ASCII string: %s\n",
+ pAd->ApCfg.MBSSID[apIdx].WscControl.Wsc_Uuid_Str));
+ }
+ else if (wrq->u.data.length == UUID_LEN_HEX)
+ {
+ UCHAR apIdx = pObj->ioctl_if, ii;
+ Status = copy_from_user(&pAd->ApCfg.MBSSID[apIdx].WscControl.Wsc_Uuid_E[0],
+ wrq->u.data.pointer,
+ wrq->u.data.length);
+
+ for (ii=0; ii< 16; ii++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02x", (pAd->ApCfg.MBSSID[apIdx].WscControl.Wsc_Uuid_E[ii] & 0xff)));
+ }
+ }
+ else
+ Status = -EINVAL;
+ break;
+#endif /* WSC_AP_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:
+ {
+ UINT KeyIdx;
+ 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;
+ 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[pObj->ioctl_if][pAd->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
+ NdisMoveMemory(&pAd->SharedKey[pObj->ioctl_if][pAd->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ /* Default key for tx (shared key) */
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId = (UCHAR) KeyIdx;
+ }
+ /*RestartAPIsRequired = TRUE; */
+ }
+ 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->ApCfg.MBSSID[pObj->ioctl_if].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 WAPI_SUPPORT
+ case OID_802_11_WAPI_PID:
+ {
+ unsigned long wapi_pid;
+ if (copy_from_user(&wapi_pid, wrq->u.data.pointer, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ else
+ {
+ RTMP_GET_OS_PID(pObj->wapi_pid, wapi_pid);
+ pObj->wapi_pid_nr = wapi_pid;
+ DBGPRINT(RT_DEBUG_TRACE, ("OID_802_11_WAPI_PID::(WapiPid=%lu(0x%x))\n", wapi_pid, pObj->wapi_pid));
+ }
+ }
+ break;
+
+ case OID_802_11_PORT_SECURE_STATE:
+ if (wrq->u.data.length != sizeof(WAPI_PORT_SECURE_STRUCT))
+ Status = -EINVAL;
+ else
+ {
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ WAPI_PORT_SECURE_STRUCT wapi_port;
+
+ Status = copy_from_user(&wapi_port, wrq->u.data.pointer, wrq->u.data.length);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if ((pEntry = MacTableLookup(pAd, wapi_port.Addr)) != NULL)
+ {
+ switch (wapi_port.state)
+ {
+ case WAPI_PORT_SECURED:
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ break;
+
+ default:
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_PORT_SECURE_STATE (state=%d)\n", wapi_port.state));
+ }
+ }
+ break;
+
+ case OID_802_11_UCAST_KEY_INFO:
+ if (wrq->u.data.length != sizeof(WAPI_UCAST_KEY_STRUCT))
+ Status = -EINVAL;
+ else
+ {
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ WAPI_UCAST_KEY_STRUCT wapi_ukey;
+
+ Status = copy_from_user(&wapi_ukey, wrq->u.data.pointer, wrq->u.data.length);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ if ((pEntry = MacTableLookup(pAd, wapi_ukey.Addr)) != NULL)
+ {
+ pEntry->usk_id = wapi_ukey.key_id;
+ NdisMoveMemory(pEntry->PTK, wapi_ukey.PTK, 64);
+
+ /* Install pairwise key */
+ WAPIInstallPairwiseKey(pAd, pEntry, TRUE);
+
+ /* Start or re-start USK rekey mechanism, if necessary. */
+ RTMPCancelWapiRekeyTimerAction(pAd, pEntry);
+ RTMPStartWapiRekeyTimerAction(pAd, pEntry);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_UCAST_KEY_INFO complete\n"));
+ hex_dump("WAPI UCAST KEY", pEntry->PTK, 64);
+ }
+ }
+ break;
+
+#endif /* WAPI_SUPPORT */
+
+#ifdef DOT1X_SUPPORT
+ case OID_802_DOT1X_PMKID_CACHE:
+ RTMPIoctlAddPMKIDCache(pAd, wrq);
+ break;
+
+ case OID_802_DOT1X_RADIUS_DATA:
+ RTMPIoctlRadiusData(pAd, wrq);
+ break;
+
+ case OID_802_DOT1X_WPA_KEY:
+ RTMPIoctlAddWPAKey(pAd, wrq);
+ break;
+
+ case OID_802_DOT1X_STATIC_WEP_COPY:
+ RTMPIoctlStaticWepCopy(pAd, wrq);
+ break;
+
+ case OID_802_DOT1X_IDLE_TIMEOUT:
+ RTMPIoctlSetIdleTimeout(pAd, wrq);
+ break;
+#endif /* DOT1X_SUPPORT */
+
+ 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;
+ }
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+ if(apcliEn)
+ {
+ if (pAd->ApCfg.ApCliTab[ifIndex].AuthMode != AuthMode)
+ {
+ /* Config has changed */
+ pAd->ApCfg.ApCliTab[ifIndex].bConfigChanged = TRUE;
+ }
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = AuthMode;
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[i]))
+ {
+ pAd->MacTab.Content[i].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ }
+
+ RTMPMakeRSNIE(pAd, pAd->ApCfg.ApCliTab[ifIndex].AuthMode, pAd->ApCfg.ApCliTab[ifIndex].WepStatus, (ifIndex + MIN_NET_DEVICE_FOR_APCLI));
+ pAd->ApCfg.ApCliTab[ifIndex].DefaultKeyId = 0;
+
+ if(pAd->ApCfg.ApCliTab[ifIndex].AuthMode >= Ndis802_11AuthModeWPA)
+ pAd->ApCfg.ApCliTab[ifIndex].DefaultKeyId = 1;
+ }
+ }
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+ else
+ {
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].AuthMode != AuthMode)
+ {
+ /* Config has changed */
+ pAd->bConfigChanged = TRUE;
+ }
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].AuthMode = AuthMode;
+ }
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAd->ApCfg.MBSSID[0].AuthMode));
+ }
+ APStop(pAd);
+ APStartUp(pAd);
+ 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);
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+ if (ifIndex >= MAX_APCLI_NUM)
+ return FALSE;
+
+ if(apcliEn)
+ {
+ if (WepStatus <= Ndis802_11GroupWEP104Enabled)
+ {
+ if (pAd->ApCfg.ApCliTab[ifIndex].WepStatus != WepStatus)
+ {
+ /* Config has changed */
+ pAd->ApCfg.ApCliTab[ifIndex].bConfigChanged = TRUE;
+ }
+ pAd->ApCfg.ApCliTab[ifIndex].WepStatus = WepStatus;
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[i]))
+ {
+ pAd->MacTab.Content[i].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ }
+
+ pApCliEntry->PairCipher = pApCliEntry->WepStatus;
+ pApCliEntry->GroupCipher = pApCliEntry->WepStatus;
+ pApCliEntry->bMixCipher = FALSE;
+
+ if (pApCliEntry->WepStatus >= Ndis802_11Encryption2Enabled)
+ pApCliEntry->DefaultKeyId = 1;
+
+ RTMPMakeRSNIE(pAd, pAd->ApCfg.ApCliTab[ifIndex].AuthMode, pAd->ApCfg.ApCliTab[ifIndex].WepStatus, (ifIndex + MIN_NET_DEVICE_FOR_APCLI));
+
+ }
+ }
+
+ }
+ else
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+ {
+ /* Since TKIP, AES, WEP are all supported. It should not have any invalid setting */
+ if (WepStatus <= Ndis802_11GroupWEP104Enabled)
+ {
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].WepStatus != WepStatus)
+ {
+ /* Config has changed */
+ pAd->bConfigChanged = TRUE;
+ }
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WepStatus = WepStatus;
+
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].WepStatus == Ndis802_11Encryption4Enabled){
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].GroupKeyWepStatus = Ndis802_11Encryption2Enabled;
+ }
+ else{
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].GroupKeyWepStatus = WepStatus;
+ }
+ }
+ else
+ {
+ Status = -EINVAL;
+ break;
+ }
+ APStop(pAd);
+ APStartUp(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
+ }
+ }
+
+ 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);
+
+ if (Ssid.SsidLength > MAX_LEN_OF_SSID)
+ Status = -EINVAL;
+ else
+ {
+ if (Ssid.SsidLength == 0)
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ os_alloc_mem(NULL, (UCHAR **)&pSsidString, MAX_LEN_OF_SSID+1);
+ if (pSsidString)
+ {
+ NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+ NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ ifIndex = pObj->ioctl_if;
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+ if(apcliEn)
+ {
+ Set_ApCli_Ssid_Proc(pAd,pSsidString);
+ }
+ }
+ else
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+ {
+ NdisZeroMemory((PCHAR)pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid,MAX_LEN_OF_SSID);
+ strcpy((PCHAR)pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid,pSsidString);
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen=strlen(pSsidString);
+ }
+ os_free_mem(NULL, pSsidString);
+ }
+ else
+ Status = -ENOMEM;
+ }
+ }
+ }
+ break;
+
+#ifdef HOSTAPD_SUPPORT
+ case HOSTAPD_OID_SET_802_1X:/*pure 1x is enabled. */
+ Set_IEEE8021X_Proc(pAd,"1");
+ break;
+
+ case HOSTAPD_OID_SET_KEY:
+ {
+ UINT KeyIdx;
+ Status = -EINVAL;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UINT apidx = pObj->ioctl_if;
+ if(wrq->u.data.length != sizeof(struct ieee80211req_key) || !wrq->u.data.pointer)
+ break;
+ Status = copy_from_user(&Key, wrq->u.data.pointer, wrq->u.data.length);
+ pEntry = MacTableLookup(pAd, Key.ik_macaddr);
+
+
+ if((Key.ik_type == CIPHER_WEP64) ||(Key.ik_type == CIPHER_WEP128))/*dynamic wep with 1x */
+ {
+ if (pEntry)/*pairwise key */
+ {
+ pEntry->PairwiseKey.KeyLen = Key.ik_keylen;
+ NdisMoveMemory(pEntry->PairwiseKey.Key, Key.ik_keydata, Key.ik_keylen);
+ pEntry->PairwiseKey.CipherAlg = Key.ik_type;
+ KeyIdx=pAd->ApCfg.MBSSID[pEntry->apidx].DefaultKeyId;
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ (UCHAR)pEntry->Aid,
+ &pEntry->PairwiseKey);
+
+ RTMPAddWcidAttributeEntry(
+ pAd,
+ pEntry->apidx,
+ KeyIdx, /* The value may be not zero */
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry);
+ }
+ else/*group key */
+ {
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+ printk("Key.ik_keyix=%x\n",Key.ik_keyix);
+ KeyIdx = Key.ik_keyix& 0x0fff;
+ printk("ra%d KeyIdx=%d\n",apidx,KeyIdx);
+ printk("Key.ik_keyix=%x\n",Key.ik_keyix);
+ /* it is a shared key */
+ if (KeyIdx < 4)
+ {
+ pAd->SharedKey[apidx][KeyIdx].KeyLen = (UCHAR) Key.ik_keylen;
+ NdisMoveMemory(pAd->SharedKey[apidx][KeyIdx].Key, &Key.ik_keydata, Key.ik_keylen);
+ if (Key.ik_keyix & 0x8000)
+ {
+ /* Default key for tx (shared key) */
+ printk("ra%d DefaultKeyId=%d\n",apidx,KeyIdx);
+ pMbss->DefaultKeyId = (UCHAR) KeyIdx;
+ }
+ /*pMbss->DefaultKeyId=1; */
+
+ pAd->SharedKey[apidx][KeyIdx].CipherAlg = Key.ik_type;
+ AsicAddSharedKeyEntry(
+ pAd,
+ apidx,
+ KeyIdx,
+ &pAd->SharedKey[apidx][KeyIdx]
+ );
+
+ RTMPAddWcidAttributeEntry(
+ pAd,
+ apidx,
+ KeyIdx,
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].CipherAlg,
+ NULL);
+ }
+ }
+ }
+ else if (pEntry)
+ {
+ KeyIdx = Key.ik_keyix& 0x0fff;
+ if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+ {
+ pEntry->PairwiseKey.KeyLen = LEN_TK;
+ NdisMoveMemory(&pEntry->PTK[OFFSET_OF_PTK_TK], Key.ik_keydata, Key.ik_keylen);
+ NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[OFFSET_OF_PTK_TK], Key.ik_keylen);
+ }
+
+ if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ pEntry->PairwiseKey.KeyLen = LEN_TK;
+ NdisMoveMemory(&pEntry->PTK[OFFSET_OF_PTK_TK], Key.ik_keydata, OFFSET_OF_PTK_TK);
+ NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[OFFSET_OF_PTK_TK], Key.ik_keylen);
+ }
+
+
+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+ if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
+ else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
+
+ pEntry->PairwiseKey.CipherAlg = Key.ik_type;
+
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ (UCHAR)pEntry->Aid,
+ &pEntry->PairwiseKey);
+
+ RTMPSetWcidSecurityInfo(pAd,
+ pEntry->apidx,
+ (UINT8)KeyIdx,
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry->Aid,
+ PAIRWISEKEYTABLE);
+ }
+ else
+ {
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+ KeyIdx = Key.ik_keyix& 0x0fff;
+
+ /*if (Key.ik_keyix & 0x8000) */
+ {
+ pMbss->DefaultKeyId = (UCHAR) KeyIdx;
+ }
+
+ if (pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11Encryption2Enabled)
+ {
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].KeyLen= LEN_TK;
+ NdisMoveMemory(pAd->SharedKey[apidx][pMbss->DefaultKeyId].Key, Key.ik_keydata, 16);
+ NdisMoveMemory(pAd->SharedKey[apidx][pMbss->DefaultKeyId].RxMic, (Key.ik_keydata+16+8), 8);
+ NdisMoveMemory(pAd->SharedKey[apidx][pMbss->DefaultKeyId].TxMic, (Key.ik_keydata+16), 8);
+ }
+
+ if(pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].KeyLen= LEN_TK;
+ NdisMoveMemory(pAd->SharedKey[apidx][pMbss->DefaultKeyId].Key, Key.ik_keydata, 16);
+ NdisMoveMemory(pAd->SharedKey[apidx][pMbss->DefaultKeyId].RxMic, (Key.ik_keydata+16+8), 8);
+ NdisMoveMemory(pAd->SharedKey[apidx][pMbss->DefaultKeyId].TxMic, (Key.ik_keydata+16), 8);
+ }
+
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ hex_dump("Key.ik_keydata,", (unsigned char*) Key.ik_keydata, 32);
+
+ AsicAddSharedKeyEntry(
+ pAd,
+ apidx,
+ pMbss->DefaultKeyId,
+ &pAd->SharedKey[apidx][pMbss->DefaultKeyId]
+ );
+ GET_GroupKey_WCID(pAd, Wcid, apidx);
+
+ RTMPSetWcidSecurityInfo(pAd, apidx,(UINT8)KeyIdx,
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].CipherAlg, Wcid, SHAREDKEYTABLE);
+
+ /*RTMPAddWcidAttributeEntry(
+ pAd,
+ apidx,
+ pMbss->DefaultKeyId,
+ pAd->SharedKey[apidx][pMbss->DefaultKeyId].CipherAlg,
+ NULL);*/
+ }
+ break;
+ }
+ case HOSTAPD_OID_DEL_KEY:
+
+ Status = -EINVAL;
+ if(wrq->u.data.length != sizeof(struct ieee80211req_del_key) || !wrq->u.data.pointer)
+ break;
+ Status = copy_from_user(&delkey, wrq->u.data.pointer, wrq->u.data.length);
+ pEntry = MacTableLookup(pAd, delkey.idk_macaddr);
+ if (pEntry){
+ /* clear the previous Pairwise key table */
+ if(pEntry->Aid != 0)
+ {
+ NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
+ AsicRemovePairwiseKeyEntry(pAd,(UCHAR)pEntry->Aid);
+ }
+ }
+ else if((delkey.idk_macaddr == NULL) && (delkey.idk_keyix < 4))
+ /* remove group key */
+ AsicRemoveSharedKeyEntry(pAd, pEntry->apidx, delkey.idk_keyix);
+ break;
+
+ case HOSTAPD_OID_SET_STA_AUTHORIZED:/*for portsecured flag. */
+
+ if (wrq->u.data.length != sizeof(struct ieee80211req_mlme))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ Status = copy_from_user(&mlme, wrq->u.data.pointer, wrq->u.data.length);
+ pEntry = MacTableLookup(pAd, mlme.im_macaddr);
+ if (!pEntry){
+ Status = -EINVAL;
+ }
+ else
+ {
+ switch (mlme.im_op)
+ {
+ case IEEE80211_MLME_AUTHORIZE:
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ pEntry->WpaState = AS_PTKINITDONE;/*wpa state machine is not in use. */
+ /*pAd->StaCfg.PortSecured= WPA_802_1X_PORT_SECURED; */
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ break;
+ case IEEE80211_MLME_UNAUTHORIZE:
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ break;
+ default:
+ Status = -EINVAL;
+ }
+ }
+ }
+ break;
+
+ case HOSTAPD_OID_STATIC_WEP_COPY:
+ {
+ UINT KeyIdx;
+ INT apidx;
+ if (wrq->u.data.length != sizeof(struct ieee80211req_mlme))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ Status = copy_from_user(&mlme, wrq->u.data.pointer, wrq->u.data.length);
+ pEntry = MacTableLookup(pAd, mlme.im_macaddr);
+ if (!pEntry){
+ Status = -EINVAL;
+ }
+ else{
+ /*Status = -EINVAL; */
+ printk("Woody HOSTAPD_OID_STATIC_WEP_COPY IEEE8021X=%d WepStatus=%d\n",pAd->ApCfg.MBSSID[pObj->ioctl_if].IEEE8021X, pEntry->WepStatus);
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].IEEE8021X != TRUE) break;
+ if (pEntry->WepStatus != Ndis802_11Encryption1Enabled) break;
+
+ apidx = pObj->ioctl_if;
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+ KeyIdx=pMbss->DefaultKeyId;
+ printk("Woody HOSTAPD_OID_STATIC_WEP_COPY=%d\n",KeyIdx);
+ pEntry->AuthMode=pAd->ApCfg.MBSSID[apidx].AuthMode;
+ pEntry->PairwiseKey.KeyLen = pAd->SharedKey[apidx][KeyIdx].KeyLen;
+ NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[apidx][KeyIdx].Key, pAd->SharedKey[apidx][KeyIdx].KeyLen);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[apidx][KeyIdx].CipherAlg;
+
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ (UCHAR)pEntry->Aid,
+ &pEntry->PairwiseKey);
+
+ RTMPAddWcidAttributeEntry(
+ pAd,
+ pEntry->apidx,
+ KeyIdx, /* The value may be not zero */
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry);
+
+ }
+ }
+ break;
+ }
+ case HOSTAPD_OID_SET_STA_DEAUTH:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::HOSTAPD_OID_SET_STA_DEAUTH\n"));
+ MLME_DEAUTH_REQ_STRUCT *pInfo;
+ 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)
+ {
+ pInfo = (MLME_DEAUTH_REQ_STRUCT *) Elem->Msg;
+
+ if (wrq->u.data.length != sizeof(struct ieee80211req_mlme))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ Status = copy_from_user(&mlme, wrq->u.data.pointer, wrq->u.data.length);
+ NdisMoveMemory(pInfo->Addr, mlme.im_macaddr, MAC_ADDR_LEN);
+ if ((pEntry = MacTableLookup(pAd, pInfo->Addr)) != NULL)
+ {
+ pInfo->Reason = mlme.im_reason;
+ Elem->Wcid = pEntry->Aid;
+ MlmeEnqueue(pAd, AP_AUTH_STATE_MACHINE, APMT2_MLME_DEAUTH_REQ, sizeof(MLME_DEAUTH_REQ_STRUCT), Elem,0);
+ }
+ }
+ os_free_mem(NULL, Elem);
+ }
+ break;
+
+ case HOSTAPD_OID_SET_STA_DISASSOC:/*hostapd request to disassoc the station. */
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::HOSTAPD_OID_SET_STA_DISASSOC\n"));
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+ if (wrq->u.data.length != sizeof(struct ieee80211req_mlme))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ Status = copy_from_user(&mlme, wrq->u.data.pointer, wrq->u.data.length);
+ NdisMoveMemory(DisassocReq.Addr, mlme.im_macaddr, MAC_ADDR_LEN);
+ DisassocReq.Reason = mlme.im_reason;
+ MlmeEnqueue(pAd, AP_ASSOC_STATE_MACHINE, APMT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq,0);
+ }
+ break;
+
+ case OID_HOSTAPD_SUPPORT:/*notify the driver to support hostapd. */
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ BOOLEAN hostapd_enable;
+ int v, apidx;
+ apidx = pObj->ioctl_if;
+ Status = copy_from_user(&hostapd_enable, wrq->u.data.pointer, wrq->u.data.length);
+ printk("OID_HOSTAPD_SUPPORT apidx=%d\n",apidx);
+ pAd->ApCfg.MBSSID[apidx].Hostapd = hostapd_enable;
+ MULTISSID_STRUCT *pMBSSStruct;
+
+ for(v=0;v<MAX_MBSSID_NUM(pAd);v++)
+ {
+ if(pAd->ApCfg.MBSSID[v].Hostapd == TRUE)
+ printk("ApCfg->MBSSID[%d].Hostapd == TURE\n",v);
+ else
+ printk("ApCfg->MBSSID[%d].Hostapd == FALSE\n",v);
+ pMBSSStruct = &pAd->ApCfg.MBSSID[v];
+ pMBSSStruct->WPAREKEY.ReKeyInterval = 0;
+ pMBSSStruct->WPAREKEY.ReKeyMethod = DISABLE_REKEY;
+ }
+ }
+ break;
+
+ case HOSTAPD_OID_COUNTERMEASURES:/*report txtsc to hostapd. */
+
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ BOOLEAN countermeasures_enable;
+ Status = copy_from_user(&countermeasures_enable, wrq->u.data.pointer, wrq->u.data.length);
+
+ if(countermeasures_enable)
+ {
+
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>> \n"));
+
+ /* send wireless event - for counter measures */
+ pAd->ApCfg.CMTimerRunning = FALSE;
+
+ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
+ /* happened twice within 60 sec, AP SENDS disaccociate all associated STAs. All STA's transition to State 2 */
+ if (IS_ENTRY_CLIENT(pEntry))
+ {
+ MlmeDeAuthAction(pAd, &pAd->MacTab.Content[i], REASON_MIC_FAILURE,FALSE);
+ }
+ }
+
+ /* Further, ban all Class 3 DATA transportation for a period 0f 60 sec */
+ /* disallow new association , too */
+ pAd->ApCfg.BANClass3Data = TRUE;
+
+ }
+
+
+ }
+ else
+ {
+ pAd->ApCfg.BANClass3Data = FALSE;
+ }
+ }
+ break;
+
+ case HOSTAPD_OID_SET_WPS_BEACON_IE:/*pure 1x is enabled. */
+ DBGPRINT(RT_DEBUG_TRACE,("HOSTAPD_OID_SET_WPS_BEACON_IE\n"));
+ if (wrq->u.data.length != sizeof(WSC_LV_INFO))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ INT apidx;
+ apidx = pObj->ioctl_if;
+ pAd->ApCfg.MBSSID[apidx].HostapdWPS = TRUE;
+ MULTISSID_STRUCT *pMBSSStruct;
+ NdisZeroMemory(&WscIEBeacon,sizeof(WSC_LV_INFO));
+ Status = copy_from_user(&WscIEBeacon, wrq->u.data.pointer, wrq->u.data.length);
+ pMBSSStruct = &pAd->ApCfg.MBSSID[apidx];
+ NdisMoveMemory(pMBSSStruct->WscIEBeacon.Value,WscIEBeacon.Value, WscIEBeacon.ValueLen);
+ pMBSSStruct->WscIEBeacon.ValueLen=WscIEBeacon.ValueLen;
+ APUpdateBeaconFrame(pAd, apidx);
+ }
+
+ break;
+
+ case HOSTAPD_OID_SET_WPS_PROBE_RESP_IE:/*pure 1x is enabled. */
+ apidx = pObj->ioctl_if;
+ DBGPRINT(RT_DEBUG_TRACE,("HOSTAPD_OID_SET_WPS_PROBE_RESP_IE\n"));
+ if (wrq->u.data.length != sizeof(WSC_LV_INFO))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("HOSTAPD_OID_SET_WPS_PROBE_RESP_IE failed\n"));
+ Status = -EINVAL;
+ }
+ else
+ {
+ INT apidx;
+ apidx = pObj->ioctl_if;
+ pAd->ApCfg.MBSSID[apidx].HostapdWPS = TRUE;
+ MULTISSID_STRUCT *pMBSSStruct;
+ NdisZeroMemory(&WscIEProbeResp,sizeof(WSC_LV_INFO));
+ Status = copy_from_user(&WscIEProbeResp, wrq->u.data.pointer, wrq->u.data.length);
+ pMBSSStruct = &pAd->ApCfg.MBSSID[apidx];
+ NdisMoveMemory(pMBSSStruct->WscIEProbeResp.Value,WscIEProbeResp.Value, WscIEProbeResp.ValueLen);
+ pMBSSStruct->WscIEProbeResp.ValueLen=WscIEProbeResp.ValueLen;
+ APUpdateBeaconFrame(pAd, apidx);
+
+ }
+ break;
+#endif /*HOSTAPD_SUPPORT*/
+
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+
+
+ return Status;
+}
+
+
+INT RTMPAPQueryInformation(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT RTMP_IOCTL_INPUT_STRUCT *rq,
+ IN INT cmd)
+{
+ RTMP_IOCTL_INPUT_STRUCT *wrq = (RTMP_IOCTL_INPUT_STRUCT *) rq;
+ INT Status = NDIS_STATUS_SUCCESS;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ STRING driverVersion[8];
+
+#if defined(DBG) || defined(WSC_AP_SUPPORT)
+ UCHAR apidx = pObj->ioctl_if;
+#endif
+#ifdef WSC_AP_SUPPORT
+ UINT WscPinCode = 0;
+ PWSC_PROFILE pProfile;
+ PWSC_CTRL pWscControl;
+#endif /* WSC_AP_SUPPORT */
+
+#ifdef SNMP_SUPPORT
+ ULONG ulInfo;
+ DefaultKeyIdxValue *pKeyIdxValue;
+ INT valueLen;
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ ULONG ShortRetryLimit, LongRetryLimit;
+ UCHAR snmp_tmp[64];
+#endif /* SNMP_SUPPORT */
+
+#ifdef HOSTAPD_SUPPORT
+ struct default_group_key group_key;
+ struct ieee80211req_key ik;
+ unsigned char *p;
+ MAC_TABLE_ENTRY *pEntry=(MAC_TABLE_ENTRY *)NULL;
+ struct ieee80211req_wpaie wpaie;
+ PMULTISSID_STRUCT pMbss ;
+#endif /*HOSTAPD_SUPPORT*/
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ UCHAR ifIndex;
+ BOOLEAN apcliEn=FALSE;
+ INT i,Padding = 0;;
+ ULONG BssBufSize;
+ PUCHAR pBuf = NULL, pPtr=NULL;
+ NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
+ USHORT BssLen = 0;
+ PNDIS_WLAN_BSSID_EX pBss;
+ MAC_TABLE_ENTRY *pMacEntry=(MAC_TABLE_ENTRY *)NULL;
+ PAPCLI_STRUCT pApCliEntry=NULL;
+ NDIS_802_11_SSID Ssid;
+ UINT we_version_compiled;
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
+
+ NDIS_802_11_STATISTICS *pStatistics;
+
+
+
+
+ INT IEEE8021X = 0;
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
+ switch(cmd)
+ {
+#ifdef DOT1X_SUPPORT
+ case OID_802_11_SET_IEEE8021X:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SET_IEEE8021X \n"));
+ wrq->u.data.length = sizeof(INT);
+ if(pAd->ApCfg.MBSSID[pObj->ioctl_if].IEEE8021X == TRUE)
+ IEEE8021X=1;
+ else
+ IEEE8021X=0;
+
+ Status = copy_to_user(wrq->u.data.pointer, &IEEE8021X, wrq->u.data.length);
+ break;
+#endif /* DOT1X_SUPPORT */
+ case OID_802_11_AUTHENTICATION_MODE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE \n"));
+ wrq->u.data.length = sizeof(NDIS_802_11_AUTHENTICATION_MODE);
+ AuthMode=pAd->ApCfg.MBSSID[pObj->ioctl_if].AuthMode;
+ Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
+ break;
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_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 apcli::RT_OID_NEW_DRIVER (=%d)\n", enabled));
+ 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 OID_802_11_BSSID_LIST:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ pMacEntry = &pAd->MacTab.Content[pAd->ApCfg.ApCliTab[ifIndex].MacTabWCID];
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ /*
+ * Still scanning, indicate the caller should try again.
+ */
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
+ return -EAGAIN;
+ }
+ if ((pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP & 0x7F) == WPA_SUPPLICANT_ENABLE)
+ {
+ pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantScanCount = 0;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAd->ScanTab.BssNr));
+ BssBufSize = sizeof(ULONG);
+
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAd->ScanTab.BssEntry[i].VarIELen + Padding);
+ }
+
+ BssBufSize += 256;
+ os_alloc_mem(pAd, (UCHAR **)&pBuf, BssBufSize);
+ if(pBuf == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+ NdisZeroMemory(pBuf, BssBufSize);
+ pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
+ pBssidList->NumberOfItems = pAd->ScanTab.BssNr;
+
+ BssLen = 4; /* Consist of NumberOfItems */
+ 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))
+ {
+ /*
+ 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->ApCfg.ApCliTab[ifIndex].AuthMode >= Ndis802_11AuthModeWPA) && (pMacEntry->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->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;
+
+ 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 WIRELESS_EXT < 17
+ if ((BssLen + pBss->Length) < wrq->u.data.length)
+ BssLen += pBss->Length;
+ else
+ {
+ pBssidList->NumberOfItems = i;
+ break;
+ }
+#else
+ BssLen += pBss->Length;
+#endif
+ }
+
+#if WIRELESS_EXT < 17
+ wrq->u.data.length = BssLen;
+#else
+ if (BssLen > wrq->u.data.length)
+ {
+ os_free_mem(NULL, pBssidList);
+ return -E2BIG;
+ }
+ else
+ wrq->u.data.length = BssLen;
+#endif
+ Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
+ os_free_mem(NULL, pBssidList);
+ break;
+ case OID_802_3_CURRENT_ADDRESS:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry=&pAd->ApCfg.ApCliTab[ifIndex];
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ pMacEntry = &pAd->MacTab.Content[pAd->ApCfg.ApCliTab[ifIndex].MacTabWCID];
+
+ wrq->u.data.length = MAC_ADDR_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, pApCliEntry->CurrentAddress, wrq->u.data.length);
+ break;
+
+ case OID_802_11_BSSID:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry=&pAd->ApCfg.ApCliTab[ifIndex];
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+ {
+ Status = copy_to_user(wrq->u.data.pointer, pApCliEntry->CfgApCliBssid, sizeof(NDIS_802_11_MAC_ADDRESS));
+
+
+ DBGPRINT(RT_DEBUG_INFO, ("IOCTL::SIOCGIWAP(=%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ pApCliEntry->CfgApCliBssid[0],pApCliEntry->CfgApCliBssid[1],pApCliEntry->CfgApCliBssid[2],
+ pApCliEntry->CfgApCliBssid[3],pApCliEntry->CfgApCliBssid[4],pApCliEntry->CfgApCliBssid[5]));
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
+ Status = -ENOTCONN;
+ }
+ break;
+ case OID_802_11_SSID:
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry=&pAd->ApCfg.ApCliTab[ifIndex];
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ if (!apcliEn)
+ return FALSE;
+
+ NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+ NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
+ Ssid.SsidLength = pApCliEntry->CfgSsidLen;
+ NdisMoveMemory(Ssid.Ssid, pApCliEntry->CfgSsid,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 Apcli::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
+ break;
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
+
+ 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", AP_DRIVER_VERSION);
+ driverVersion[7] = '\0';
+ if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+
+ case OID_802_11_NETWORK_TYPES_SUPPORTED:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ if (copy_to_user(wrq->u.data.pointer, &pAd->RfIcType, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+
+#ifdef IAPP_SUPPORT
+ case RT_QUERY_SIGNAL_CONTEXT:
+ {
+ BOOLEAN FlgIs11rSup = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_SIGNAL_CONTEXT \n"));
+
+
+ if (FlgIs11rSup == FALSE)
+ {
+ {
+ Status = -EFAULT;
+ }
+ }
+ }
+ break;
+
+
+#endif /* IAPP_SUPPORT */
+
+
+#ifdef WSC_AP_SUPPORT
+ case RT_OID_WSC_QUERY_STATUS:
+ {
+ INT WscStatus;
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_QUERY_STATUS \n"));
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ INT ApCliIdx = pObj->ioctl_if;
+ APCLI_MR_APIDX_SANITY_CHECK(ApCliIdx);
+ WscStatus = pAd->ApCfg.ApCliTab[ApCliIdx].WscControl.WscStatus;
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ WscStatus = pAd->ApCfg.MBSSID[apidx].WscControl.WscStatus;
+ }
+
+ wrq->u.data.length = sizeof(INT);
+ if (copy_to_user(wrq->u.data.pointer, &WscStatus, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ }
+ case RT_OID_WSC_PIN_CODE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_PIN_CODE \n"));
+ wrq->u.data.length = sizeof(UINT);
+ /*WscPinCode = GenerateWpsPinCode(pAd, FALSE, apidx); */
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+
+ WscPinCode = pWscControl->WscEnrolleePinCode;
+ if (copy_to_user(wrq->u.data.pointer, &WscPinCode, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+#ifdef APCLI_SUPPORT
+ case RT_OID_APCLI_WSC_PIN_CODE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_APCLI_WSC_PIN_CODE \n"));
+ wrq->u.data.length = sizeof(UINT);
+ /*WscPinCode = GenerateWpsPinCode(pAd, TRUE, apidx); */
+ WscPinCode = pAd->ApCfg.ApCliTab[0].WscControl.WscEnrolleePinCode;
+
+ if (copy_to_user(wrq->u.data.pointer, &WscPinCode, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+#endif /* APCLI_SUPPORT */
+ case RT_OID_WSC_UUID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_QUERY_UUID \n"));
+ wrq->u.data.length = UUID_LEN_STR;
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ if (copy_to_user(wrq->u.data.pointer, &pWscControl->Wsc_Uuid_Str[0], UUID_LEN_STR))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_WSC_MAC_ADDRESS:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_MAC_ADDRESS \n"));
+ wrq->u.data.length = MAC_ADDR_LEN;
+ if (copy_to_user(wrq->u.data.pointer, pAd->ApCfg.MBSSID[apidx].Bssid, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_WSC_CONFIG_STATUS:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_CONFIG_STATUS \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ if (copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].WscControl.WscConfStatus, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+
+ case RT_OID_WSC_QUERY_PEER_INFO_ON_RUNNING:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_QUERY_PEER_INFO_ON_RUNNING \n"));
+
+ if (pAd->ApCfg.MBSSID[apidx].WscControl.WscState > WSC_STATE_WAIT_M2)
+ {
+ wrq->u.data.length = sizeof(WSC_PEER_DEV_INFO);
+ if (copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].WscControl.WscPeerInfo, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ }
+ else
+ {
+ Status = -EFAULT;
+ }
+ break;
+
+ case RT_OID_802_11_WSC_QUERY_PROFILE:
+ wrq->u.data.length = sizeof(WSC_PROFILE);
+/* pProfile = kmalloc(sizeof(WSC_PROFILE), MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&pProfile, sizeof(WSC_PROFILE));
+ if (pProfile == NULL)
+ {
+ Status = -EFAULT;
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_WSC_QUERY_PROFILE fail!\n"));
+ break;
+ }
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+
+ RTMPZeroMemory(pProfile, sizeof(WSC_PROFILE));
+ NdisMoveMemory(pProfile, &pWscControl->WscProfile, sizeof(WSC_PROFILE));
+ if ((pProfile->Profile[0].AuthType == WSC_AUTHTYPE_OPEN) && (pProfile->Profile[0].EncrType == WSC_ENCRTYPE_NONE))
+ {
+ pProfile->Profile[0].KeyLength = 0;
+ NdisZeroMemory(pProfile->Profile[0].Key, 64);
+ }
+ if (copy_to_user(wrq->u.data.pointer, pProfile, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+
+ os_free_mem(NULL, pProfile);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WSC_QUERY_PROFILE \n"));
+ break;
+#ifdef WSC_V2_SUPPORT
+ case RT_OID_WSC_V2_SUPPORT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_V2_SUPPORT (=%d)\n", pAd->ApCfg.MBSSID[apidx].WscControl.WscV2Info.bEnableWpsV2));
+ wrq->u.data.length = sizeof(BOOLEAN);
+ if (copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].WscControl.WscV2Info.bEnableWpsV2, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_WSC_FRAGMENT_SIZE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WSC_FRAGMENT_SIZE (=%d)\n", pAd->ApCfg.MBSSID[apidx].WscControl.WscFragSize));
+ wrq->u.data.length = sizeof(USHORT);
+ if (copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].WscControl.WscFragSize, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+#endif /* WSC_V2_SUPPORT */
+#endif /* WSC_AP_SUPPORT */
+#ifdef LLTD_SUPPORT
+ case RT_OID_GET_LLTD_ASSO_TABLE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::Get LLTD association table\n"));
+ if ((wrq->u.data.pointer == NULL) || (apidx != MAIN_MBSSID))
+ {
+ Status = -EFAULT;
+ }
+ else
+ {
+ INT i;
+ RT_LLTD_ASSOICATION_TABLE AssocTab;
+
+ AssocTab.Num = 0;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]) && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
+ {
+ COPY_MAC_ADDR(AssocTab.Entry[AssocTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
+ AssocTab.Entry[AssocTab.Num].phyMode = pAd->CommonCfg.PhyMode;
+ AssocTab.Entry[AssocTab.Num].MOR = RateIdToMbps[pAd->ApCfg.MBSSID[apidx].MaxTxRate] * 2;
+ AssocTab.Num += 1;
+ }
+ }
+ wrq->u.data.length = sizeof(RT_LLTD_ASSOICATION_TABLE);
+ if (copy_to_user(wrq->u.data.pointer, &AssocTab, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ Status = -EFAULT;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocTab.Num = %d \n", AssocTab.Num));
+ }
+ break;
+#ifdef APCLI_SUPPORT
+ case RT_OID_GET_REPEATER_AP_LINEAGE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Not Support : Get repeater AP lineage.\n"));
+ break;
+#endif /* APCLI_SUPPORT */
+
+#endif /* LLTD_SUPPORT */
+#ifdef DOT1X_SUPPORT
+ case OID_802_DOT1X_CONFIGURATION:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::Get Radius setting(%d)\n", sizeof(DOT1X_CMM_CONF)));
+ RTMPIoctlQueryRadiusConf(pAd, wrq);
+ break;
+#endif /* DOT1X_SUPPORT */
+
+ case RT_OID_802_11_MAC_ADDRESS:
+ wrq->u.data.length = MAC_ADDR_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].Bssid, wrq->u.data.length);
+ break;
+
+#ifdef SNMP_SUPPORT
+ 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:
+ {
+ ULONG ulInfo;
+ 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:
+ {
+ ULONG ulInfo;
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
+ ulInfo = 1; /* 1 is power active else 2 is power save. */
+ 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"));
+ pKeyIdxValue = wrq->u.data.pointer;
+ DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
+
+ valueLen = pAd->SharedKey[pObj->ioctl_if][pAd->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId].KeyLen;
+ NdisMoveMemory(pKeyIdxValue->Value,
+ &pAd->SharedKey[pObj->ioctl_if][pAd->ApCfg.MBSSID[pObj->ioctl_if].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->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId, wrq->u.data.length, pAd->SharedKey[pObj->ioctl_if][pAd->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId].KeyLen,
+ pAd->SharedKey[pObj->ioctl_if][0].Key[0],
+ pAd->SharedKey[pObj->ioctl_if][1].Key[0],
+ pAd->SharedKey[pObj->ioctl_if][2].Key[0],
+ pAd->SharedKey[pObj->ioctl_if][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->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAd->ApCfg.MBSSID[pObj->ioctl_if].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[pObj->ioctl_if][pAd->ApCfg.MBSSID[pObj->ioctl_if].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)snmp_tmp, sizeof(snmp_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) snmp_tmp);
+ Status = copy_to_user(wrq->u.data.pointer, snmp_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_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);*/
+
+ pStatistics->TransmittedFragmentCount.QuadPart = pAd->WlanCounters.TransmittedFragmentCount.QuadPart + pAd->WlanCounters.MulticastTransmittedFrameCount.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
+ pStatistics->TransmittedFrameCount.QuadPart = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
+ pStatistics->WEPUndecryptableCount.QuadPart = pAd->WlanCounters.WEPUndecryptableCount.QuadPart;
+ 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 RT_OID_802_11_PER_BSS_STATISTICS:
+ {
+ PMBSS_STATISTICS pMbssStat;
+ INT apidx = pObj->ioctl_if;
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+ os_alloc_mem(pAd, (UCHAR * *) &pMbssStat, sizeof(MBSS_STATISTICS));
+ NdisZeroMemory(pMbssStat, sizeof(MBSS_STATISTICS));
+
+ pMbssStat->TransmittedByteCount = pMbss->TransmittedByteCount;
+ pMbssStat->ReceivedByteCount = pMbss->ReceivedByteCount;
+ pMbssStat->TxCount = pMbss->TxCount;
+ pMbssStat->RxCount = pMbss->RxCount;
+ pMbssStat->RxErrorCount = pMbss->RxErrorCount;
+ pMbssStat->RxDropCount = pMbss->RxDropCount;
+ pMbssStat->TxErrorCount = pMbss->TxErrorCount;
+ pMbssStat->TxDropCount = pMbss->TxDropCount;
+ pMbssStat->ucPktsTx = pMbss->ucPktsTx;
+ pMbssStat->ucPktsRx = pMbss->ucPktsRx;
+ pMbssStat->mcPktsTx = pMbss->mcPktsTx;
+ pMbssStat->mcPktsRx = pMbss->mcPktsRx;
+ pMbssStat->bcPktsTx= pMbss->bcPktsTx;
+ pMbssStat->bcPktsRx= pMbss->bcPktsRx;
+ wrq->u.data.length = sizeof(MBSS_STATISTICS);
+ copy_to_user(wrq->u.data.pointer, pMbssStat, wrq->u.data.length);
+ os_free_mem(pAd, pMbssStat);
+ }
+ break;
+
+#ifdef DOT11_N_SUPPORT
+#ifdef TXBF_SUPPORT
+ case RT_OID_802_11_QUERY_TXBF_TABLE:
+ if (!pAd->chipCap.FlgHwTxBfCap)
+ Status = -EFAULT;
+ else
+ {
+ INT i;
+ RT_802_11_TXBF_TABLE MacTab;
+
+ MacTab.Num = 0;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]) && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
+ {
+ memcpy(&MacTab.Entry[MacTab.Num], &pAd->MacTab.Content[i].TxBFCounters, sizeof(RT_COUNTER_TXBF));
+ MacTab.Num++;
+ }
+ }
+
+ wrq->u.data.length = sizeof(RT_802_11_TXBF_TABLE);
+ Status = copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length);
+ }
+ break;
+#endif /* TXBF_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef WAPI_SUPPORT
+ case OID_802_11_MCAST_TXIV:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MCAST_TXIV \n"));
+ Status = -EINVAL;
+ break;
+ case OID_802_11_WAPI_CONFIGURATION:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::Get WAPI Configuration(%d)\n", sizeof(WAPI_CONF)));
+ RTMPIoctlQueryWapiConf(pAd, wrq);
+ break;
+ case OID_802_11_WAPI_IE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WAPI_IE\n"));
+ if (wrq->u.data.length != sizeof(WAPI_WIE_STRUCT))
+ Status = -EINVAL;
+ else
+ {
+ WAPI_WIE_STRUCT wapi_ie;
+ MAC_TABLE_ENTRY *pWapiEntry;
+
+ NdisZeroMemory(&wapi_ie, sizeof(WAPI_WIE_STRUCT));
+ NdisMoveMemory(wapi_ie.addr, wrq->u.data.pointer, MAC_ADDR_LEN);
+
+ pWapiEntry = MacTableLookup(pAd, wapi_ie.addr);
+
+ if (pWapiEntry && IS_ENTRY_CLIENT(pWapiEntry) && (pWapiEntry->RSNIE_Len > 0))
+ {
+ wapi_ie.wie_len = pWapiEntry->RSNIE_Len;
+ NdisMoveMemory(wapi_ie.wie, pWapiEntry->RSN_IE, pWapiEntry->RSNIE_Len);
+ }
+
+ if (copy_to_user(wrq->u.data.pointer, &wapi_ie, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+ }
+ break;
+
+ case OID_802_11_MCAST_KEY_INFO:
+ {
+ PMULTISSID_STRUCT pMbss;
+ WAPI_MCAST_KEY_STRUCT wapi_mkey;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_MCAST_KEY_INFO\n"));
+
+ pMbss = &pAd->ApCfg.MBSSID[pObj->ioctl_if];
+ NdisZeroMemory(&wapi_mkey, sizeof(WAPI_MCAST_KEY_STRUCT));
+
+ if (pMbss->sw_wpi_encrypt)
+ {
+ NdisMoveMemory(wapi_mkey.m_tx_iv,
+ pAd->SharedKey[pObj->ioctl_if][pMbss->DefaultKeyId].TxTsc,
+ LEN_WAPI_TSC);
+ }
+ else
+ {
+ INT m_wcid;
+
+ GET_GroupKey_WCID(pAd, m_wcid, apidx);
+ RTMPGetWapiTxTscFromAsic(pAd, m_wcid, wapi_mkey.m_tx_iv);
+ }
+ wapi_mkey.key_id = pMbss->DefaultKeyId;
+ NdisMoveMemory(wapi_mkey.key_announce, pMbss->key_announce_flag, LEN_WAPI_TSC);
+ NdisMoveMemory(wapi_mkey.NMK, pMbss->NMK, 16);
+
+ wrq->u.data.length = sizeof(WAPI_MCAST_KEY_STRUCT);
+ Status = copy_to_user(wrq->u.data.pointer, &wapi_mkey, wrq->u.data.length);
+ }
+ break;
+
+#endif /* WAPI_SUPPORT */
+
+#ifdef HOSTAPD_SUPPORT
+
+ case HOSTAPD_OID_GETWPAIE:/*report wpa ie of the new station to hostapd. */
+
+ if (wrq->u.data.length != sizeof(wpaie))
+ {
+ Status = -EINVAL;
+ }
+ else if (copy_from_user(&wpaie, wrq->u.data.pointer, IEEE80211_ADDR_LEN))
+ {
+ Status = -EFAULT;
+ }
+ else
+ {
+ pEntry = MacTableLookup(pAd, wpaie.wpa_macaddr);
+ if (!pEntry){
+ Status = -EINVAL;
+ break;
+ }
+ NdisZeroMemory(wpaie.rsn_ie,sizeof(wpaie.rsn_ie));
+ /* For WPA1, RSN_IE=221 */
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
+ ||(pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+ || (pEntry->AuthMode == Ndis802_11AuthModeWPA1WPA2) ||(pEntry->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ )
+ {
+ int ielen = pEntry->RSNIE_Len;
+ DBGPRINT(RT_DEBUG_TRACE, ("pEntry->RSNIE_Len=%d\n",pEntry->RSNIE_Len));
+ if (ielen > sizeof(wpaie.rsn_ie))
+ ielen = sizeof(wpaie.rsn_ie)-1;
+ p = wpaie.rsn_ie;
+ hex_dump("HOSTAPD_OID_GETWPAIE woody==>pEntry->RSN_IE", (unsigned char*)pEntry->RSN_IE,ielen);
+ NdisMoveMemory(p, pEntry->RSN_IE, ielen);
+ }
+ }
+ if(copy_to_user(wrq->u.data.pointer, &wpaie, sizeof(wpaie)))
+ Status = -EFAULT;
+ break;
+
+
+ case HOSTAPD_OID_GET_SEQ:/*report txtsc to hostapd. */
+
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+ if (wrq->u.data.length != sizeof(ik))
+ {
+ Status = -EINVAL;
+ }
+ else if (copy_from_user(&ik, wrq->u.data.pointer, IEEE80211_ADDR_LEN))
+ {
+ Status = -EFAULT;
+ }
+ else
+ {
+ NdisZeroMemory(&ik.ik_keytsc, sizeof(ik.ik_keytsc));
+ p = (unsigned char *)&ik.ik_keytsc;
+ NdisMoveMemory(p+2, pAd->SharedKey[apidx][ pMbss->DefaultKeyId].TxTsc, 6);
+ if(copy_to_user(wrq->u.data.pointer, &ik, sizeof(ik)))
+ Status = -EFAULT;
+ }
+ break;
+
+
+ case HOSTAPD_OID_GET_1X_GROUP_KEY:/*report default group key to hostapd. */
+
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+ if (wrq->u.data.length != sizeof(group_key))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ if(pAd->SharedKey[apidx][ pMbss->DefaultKeyId].KeyLen!=0 && pAd->SharedKey[apidx][ pMbss->DefaultKeyId].Key!=NULL)
+ {
+ group_key.ik_keyix = pMbss->DefaultKeyId;
+ group_key.ik_keylen = pAd->SharedKey[apidx][ pMbss->DefaultKeyId].KeyLen;
+ NdisMoveMemory(group_key.ik_keydata, pAd->SharedKey[apidx][ pMbss->DefaultKeyId].Key,pAd->SharedKey[apidx][ pMbss->DefaultKeyId].KeyLen);
+ if(copy_to_user(wrq->u.data.pointer, &group_key, sizeof(group_key)))
+ Status = -EFAULT;
+ }
+ }
+ break;
+
+#endif/*HOSTAPD_SUPPORT*/
+
+#ifdef APCLI_SUPPORT
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ {
+ ULONG ApCliIdx = pObj->ioctl_if;
+
+ NDIS_MEDIA_STATE MediaState;
+ PMAC_TABLE_ENTRY pEntry;
+ PAPCLI_STRUCT pApCliEntry;
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ {
+ Status = -EOPNOTSUPP;
+ break;
+ }
+ else
+ {
+ APCLI_MR_APIDX_SANITY_CHECK(ApCliIdx);
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ApCliIdx];
+ pEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID];
+
+ if (!IS_ENTRY_APCLI(pEntry))
+ {
+ Status = -EOPNOTSUPP;
+ break;
+ }
+
+ if ((pAd->ApCfg.ApCliTab[ApCliIdx].Valid == TRUE)
+ && (pEntry->PortSecured == WPA_802_1X_PORT_SECURED))
+ 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;
+#endif /* APCLI_SUPPORT */
+
+
+
+
+ case OID_802_11_ACL_LIST:
+ if (wrq->u.data.length < sizeof(RT_802_11_ACL))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ Status = copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL));
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x, apidx=%d\n", cmd, apidx));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+
+ return Status;
+}
+
+
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Country Code.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_CountryCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ /* reset temp table status */
+ pAd->CommonCfg.pChDesp = NULL;
+ pAd->CommonCfg.DfsType = MAX_RD_REGION;
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+ if(strlen(arg) == 2)
+ {
+ NdisMoveMemory(pAd->CommonCfg.CountryCode, arg, 2);
+ pAd->CommonCfg.bCountryFlag = TRUE;
+ }
+ else
+ {
+ NdisZeroMemory(pAd->CommonCfg.CountryCode, 3);
+ pAd->CommonCfg.bCountryFlag = FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryCode_Proc::(bCountryFlag=%d, CountryCode=%s)\n", pAd->CommonCfg.bCountryFlag, pAd->CommonCfg.CountryCode));
+
+ return TRUE;
+}
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_ChGeography_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG Geography;
+
+ Geography = simple_strtol(arg, 0, 10);
+ if (Geography <= BOTH)
+ pAd->CommonCfg.Geography = Geography;
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ChannelGeography_Proc::(wrong setting. 0: Out-door, 1: in-door, 2: both)\n"));
+
+ pAd->CommonCfg.CountryCode[2] =
+ (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
+
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ChannelGeography_Proc:: Geography = %s\n", pAd->CommonCfg.Geography == ODOR ? "out-door" : (pAd->CommonCfg.Geography == IDOR ? "in-door" : "both")));
+
+ /* After Set ChGeography need invoke SSID change procedural again for Beacon update. */
+ /* it's no longer necessary since APStartUp will rebuild channel again. */
+ /*BuildChannelListEx(pAd); */
+
+ return TRUE;
+}
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Country String.
+ 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_CountryString_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT index = 0;
+ INT success = TRUE;
+ STRING name_buffer[40] = {0};
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ return -EOPNOTSUPP;
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+ if(strlen(arg) <= 38)
+ {
+ if (strlen(arg) < 4)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryString_Proc::Parameter of CountryString are too short !\n"));
+ return FALSE;
+ }
+
+ for (index = 0; index < strlen(arg); index++)
+ {
+ if ((arg[index] >= 'a') && (arg[index] <= 'z'))
+ arg[index] = toupper(arg[index]);
+ }
+
+ for (index = 0; index < NUM_OF_COUNTRIES; index++)
+ {
+ NdisZeroMemory(name_buffer, 40);
+ snprintf(name_buffer, sizeof(name_buffer), "\"%s\"", (PSTRING) allCountry[index].pCountryName);
+
+ if (strncmp((PSTRING) allCountry[index].pCountryName, arg, strlen(arg)) == 0)
+ break;
+ else if (strncmp(name_buffer, arg, strlen(arg)) == 0)
+ break;
+ }
+
+ if (index == NUM_OF_COUNTRIES)
+ success = FALSE;
+ }
+ else
+ {
+ success = FALSE;
+ }
+
+ if (success == TRUE)
+ {
+ if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode))
+ {
+ if (pAd->CommonCfg.CountryRegionForABand & 0x80)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryString_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+ success = FALSE;
+ }
+ else
+ {
+ if (allCountry[index].SupportGBand == TRUE)
+ {
+ NdisZeroMemory(pAd->CommonCfg.CountryCode, 3);
+ NdisMoveMemory(pAd->CommonCfg.CountryCode, allCountry[index].IsoName, 2);
+ pAd->CommonCfg.CountryCode[2] = ' ';
+
+ pAd->CommonCfg.bCountryFlag = TRUE;
+
+ pAd->CommonCfg.CountryRegion = (UCHAR) allCountry[index].RegDomainNum11G;
+
+ /* After Set ChGeography need invoke SSID change procedural again for Beacon update. */
+ /* it's no longer necessary since APStartUp will rebuild channel again. */
+ /*BuildChannelList(pAd); */
+
+ success = TRUE;
+ }
+ else
+ {
+ success = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("The Country are not Support G Band Channel\n"));
+ }
+ }
+ }
+ else if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ {
+ if (pAd->CommonCfg.CountryRegion & 0x80)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryString_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+ success = FALSE;
+ }
+ else
+ {
+ if (allCountry[index].SupportABand == TRUE)
+ {
+ NdisZeroMemory(pAd->CommonCfg.CountryCode, 3);
+ NdisMoveMemory(pAd->CommonCfg.CountryCode, allCountry[index].IsoName, 2);
+ pAd->CommonCfg.CountryCode[2] = ' ';
+
+ pAd->CommonCfg.bCountryFlag = TRUE;
+
+ pAd->CommonCfg.CountryRegionForABand = (UCHAR) allCountry[index].RegDomainNum11A;
+
+ /* After Set ChGeography need invoke SSID change procedural again for Beacon update. */
+ /* it's no longer necessary since APStartUp will rebuild channel again. */
+ /*BuildChannelList(pAd); */
+
+ success = TRUE;
+ }
+ else
+ {
+ success = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("The Country are not Support A Band Channel\n"));
+ }
+ }
+ }
+ else
+ success = FALSE;
+ }
+
+ if (success == TRUE)
+ {
+ /* if set country string, driver needs to be reset */
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryString_Proc::(CountryString=%s CountryRegin=%d CountryCode=%s)\n",
+ allCountry[index].pCountryName, pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryCode));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryString_Proc::Parameters out of range\n"));
+ }
+
+ return success;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set SSID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_SSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg)
+{
+ INT success = FALSE;
+ POS_COOKIE pObj = (POS_COOKIE) pAdapter->OS_Cookie;
+
+ if(strlen(arg) <= MAX_LEN_OF_SSID)
+ {
+ NdisZeroMemory(pAdapter->ApCfg.MBSSID[pObj->ioctl_if].Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAdapter->ApCfg.MBSSID[pObj->ioctl_if].Ssid, arg, strlen(arg));
+ pAdapter->ApCfg.MBSSID[pObj->ioctl_if].SsidLen = (UCHAR)strlen(arg);
+ success = TRUE;
+
+
+ {
+ /* If in detection mode, need to stop detect first. */
+ if (pAdapter->CommonCfg.bIEEE80211H == FALSE)
+ {
+ APStop(pAdapter);
+ APStartUp(pAdapter);
+ }
+ else
+ {
+ /* each mode has different restart method */
+ if (pAdapter->Dot11_H.RDMode == RD_SILENCE_MODE)
+ {
+ APStop(pAdapter);
+ APStartUp(pAdapter);
+ }
+ else if (pAdapter->Dot11_H.RDMode == RD_SWITCHING_MODE)
+ {
+ }
+ else if (pAdapter->Dot11_H.RDMode == RD_NORMAL_MODE)
+ {
+ APStop(pAdapter);
+ APStartUp(pAdapter);
+ AsicEnableBssSync(pAdapter);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Set_SSID_Proc::(Len=%d,Ssid=%s)\n", pObj->ioctl_if,
+ pAdapter->ApCfg.MBSSID[pObj->ioctl_if].SsidLen, pAdapter->ApCfg.MBSSID[pObj->ioctl_if].Ssid));
+ }
+ }
+ else
+ success = FALSE;
+
+ return success;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set TxRate
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_TxRate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ NdisZeroMemory(pAd->ApCfg.MBSSID[pObj->ioctl_if].DesiredRates, MAX_LEN_OF_SUPPORTED_RATES);
+
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].DesiredRatesIndex = simple_strtol(arg, 0, 10);
+ /* todo RTMPBuildDesireRate(pAd, pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].DesiredRatesIndex); */
+
+ /*todo MlmeUpdateTxRates(pAd); */
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set BasicRate
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_BasicRate_Proc(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ ULONG BasicRateBitmap;
+
+ BasicRateBitmap = (ULONG) simple_strtol(arg, 0, 10);
+
+ if (BasicRateBitmap > 4095) /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+ return FALSE;
+
+ pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap;
+ pAd->CommonCfg.BasicRateBitmapOld = BasicRateBitmap;
+
+ MlmeUpdateTxRates(pAd, FALSE, (UCHAR)pObj->ioctl_if);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BasicRate_Proc::(BasicRateBitmap=0x%08lx)\n", pAd->CommonCfg.BasicRateBitmap));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Beacon Period
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_BeaconPeriod_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ USHORT BeaconPeriod;
+ INT success = FALSE;
+
+ BeaconPeriod = (USHORT) simple_strtol(arg, 0, 10);
+ if((BeaconPeriod >= 20) && (BeaconPeriod < 1024))
+ {
+ pAd->CommonCfg.BeaconPeriod = BeaconPeriod;
+ success = TRUE;
+
+#ifdef AP_QLOAD_SUPPORT
+ /* re-calculate QloadBusyTimeThreshold */
+ QBSS_LoadAlarmReset(pAd);
+#endif /* AP_QLOAD_SUPPORT */
+ }
+ else
+ success = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BeaconPeriod_Proc::(BeaconPeriod=%d)\n", pAd->CommonCfg.BeaconPeriod));
+
+ return success;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Dtim Period
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_DtimPeriod_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ USHORT DtimPeriod;
+ INT success = FALSE;
+
+ DtimPeriod = (USHORT) simple_strtol(arg, 0, 10);
+ if((DtimPeriod >= 1) && (DtimPeriod <= 255))
+ {
+ pAd->ApCfg.DtimPeriod = DtimPeriod;
+ success = TRUE;
+ }
+ else
+ success = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_DtimPeriod_Proc::(DtimPeriod=%d)\n", pAd->ApCfg.DtimPeriod));
+
+ return success;
+}
+
+
+
+/*
+ ==========================================================================
+ Description:
+ Disable/enable OLBC detection manually
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_OLBCDetection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ switch (simple_strtol(arg, 0, 10))
+ {
+ case 0: /*enable OLBC detect */
+ pAd->CommonCfg.DisableOLBCDetect = 0;
+ break;
+ case 1: /*disable OLBC detect */
+ pAd->CommonCfg.DisableOLBCDetect = 1;
+ break;
+ default: /*Invalid argument */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+#ifdef WMM_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set WmmCapable Enable or Disable
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ BOOLEAN bWmmCapable;
+ POS_COOKIE pObj= (POS_COOKIE)pAd->OS_Cookie;
+
+ bWmmCapable = simple_strtol(arg, 0, 10);
+
+ if (bWmmCapable == 1)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].bWmmCapable = TRUE;
+ else if (bWmmCapable == 0)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].bWmmCapable = FALSE;
+ else
+ return FALSE; /*Invalid argument */
+
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].bWmmCapableOrg = \
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].bWmmCapable;
+
+#ifdef RTL865X_FAST_PATH
+ if (!isFastPathCapable(pAd)) {
+ rtlairgo_fast_tx_unregister();
+ rtl865x_extDev_unregisterUcastTxDev(pAd->net_dev);
+ }
+#endif
+
+#ifdef DOT11_N_SUPPORT
+ /*Sync with the HT relate info. In N mode, we should re-enable it */
+ SetCommonHT(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
+ pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].bWmmCapable));
+
+ return TRUE;
+}
+#endif /* WMM_SUPPORT */
+
+
+INT Set_AP_MaxStaNum_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ INT apidx = pObj->ioctl_if;
+
+ return ApCfg_Set_MaxStaNum_Proc(pAd, apidx, arg);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set session idle timeout
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_IdleTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ return ApCfg_Set_IdleTimeout_Proc(pAd, arg);
+}
+/*
+ ==========================================================================
+ Description:
+ Set No Forwarding Enable or Disable
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_NoForwarding_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG NoForwarding;
+
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ NoForwarding = simple_strtol(arg, 0, 10);
+
+ if (NoForwarding == 1)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].IsolateInterStaTraffic = TRUE;
+ else if (NoForwarding == 0)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].IsolateInterStaTraffic = FALSE;
+ else
+ return FALSE; /*Invalid argument */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_NoForwarding_Proc::(NoForwarding=%ld)\n",
+ pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].IsolateInterStaTraffic));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set No Forwarding between each SSID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_NoForwardingBTNSSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG NoForwarding;
+
+ NoForwarding = simple_strtol(arg, 0, 10);
+
+ if (NoForwarding == 1)
+ pAd->ApCfg.IsolateInterStaTrafficBTNBSSID = TRUE;
+ else if (NoForwarding == 0)
+ pAd->ApCfg.IsolateInterStaTrafficBTNBSSID = FALSE;
+ else
+ return FALSE; /*Invalid argument */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_NoForwardingBTNSSID_Proc::(NoForwarding=%ld)\n", pAd->ApCfg.IsolateInterStaTrafficBTNBSSID));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Hide SSID Enable or Disable
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_HideSSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ BOOLEAN bHideSsid;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ bHideSsid = simple_strtol(arg, 0, 10);
+
+ if (bHideSsid == 1)
+ bHideSsid = TRUE;
+ else if (bHideSsid == 0)
+ bHideSsid = FALSE;
+ else
+ return FALSE; /*Invalid argument */
+
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].bHideSsid != bHideSsid)
+ {
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].bHideSsid = bHideSsid;
+ }
+
+#ifdef WSC_V2_SUPPORT
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.WscV2Info.bEnableWpsV2)
+ WscOnOff(pAd, pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].bHideSsid);
+#endif /* WSC_V2_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_HideSSID_Proc::(HideSSID=%d)\n", pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].bHideSsid));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set VLAN's ID field
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_VLANID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].VLAN_VID = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_VLANID_Proc::(VLAN_VID=%d)\n", pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].VLAN_VID));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set VLAN's priority field
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_VLANPriority_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].VLAN_Priority = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_VLANPriority_Proc::(VLAN_Priority=%d)\n", pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].VLAN_Priority));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set enable or disable carry VLAN in the air
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_VLAN_TAG_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ BOOLEAN bVLAN_Tag;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ bVLAN_Tag = simple_strtol(arg, 0, 10);
+
+ if (bVLAN_Tag == 1)
+ bVLAN_Tag = TRUE;
+ else if (bVLAN_Tag == 0)
+ bVLAN_Tag = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].bVLAN_Tag != bVLAN_Tag)
+ {
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].bVLAN_Tag = bVLAN_Tag;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_VLAN_TAG_Proc::(VLAN_Tag=%d)\n", pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].bVLAN_Tag));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Authentication mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG i;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+ if (apidx >= pAd->ApCfg.BssidNum)
+ return FALSE;
+
+ /* Set Authentication mode */
+ ApCfg_Set_AuthMode_Proc(pAd, apidx, arg);
+
+ /* reset the portSecure for all entries */
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]))
+ {
+ pAd->MacTab.Content[i].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ }
+
+ /* reset the PortSecure this BSS */
+ pAd->ApCfg.MBSSID[apidx].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+ /* Default key index is always 2 in WPA mode */
+ if(pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 1;
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Encryption Type
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+ if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPDisabled;
+ else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPEnabled;
+ else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption2Enabled;
+ else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption3Enabled;
+ else if ((strcmp(arg, "TKIPAES") == 0) || (strcmp(arg, "tkipaes") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption4Enabled;
+#ifdef WAPI_SUPPORT
+ else if ((strcmp(arg, "SMS4") == 0) || (strcmp(arg, "sms4") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11EncryptionSMS4Enabled;
+#endif /* WAPI_SUPPORT */
+ else
+ return FALSE;
+
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus >= Ndis802_11Encryption2Enabled)
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 1;
+
+ /* decide the group key encryption type */
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus = Ndis802_11Encryption2Enabled;
+ else
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus;
+
+ /* move to ap.c::APStartUp to process */
+ /*RTMPMakeRSNIE(pAd, pAd->ApCfg.MBSSID[apidx].AuthMode, pAd->ApCfg.MBSSID[apidx].WepStatus, apidx); */
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_EncrypType_Proc::(EncrypType=%d)\n", apidx, pAd->ApCfg.MBSSID[apidx].WepStatus));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WPA pairwise mix-cipher combination
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_WpaMixPairCipher_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+ /*
+ In WPA-WPA2 mix mode, it provides a more flexible cipher combination.
+ - WPA-AES and WPA2-TKIP
+ - WPA-AES and WPA2-TKIPAES
+ - WPA-TKIP and WPA2-AES
+ - WPA-TKIP and WPA2-TKIPAES
+ - WPA-TKIPAES and WPA2-AES
+ - WPA-TKIPAES and WPA2-TKIP
+ - WPA-TKIPAES and WPA2-TKIPAES (default)
+ */
+ if ((strncmp(arg, "WPA_AES_WPA2_TKIPAES", 20) == 0) || (strncmp(arg, "wpa_aes_wpa2_tkipaes", 20) == 0))
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = WPA_AES_WPA2_TKIPAES;
+ else if ((strncmp(arg, "WPA_AES_WPA2_TKIP", 17) == 0) || (strncmp(arg, "wpa_aes_wpa2_tkip", 17) == 0))
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = WPA_AES_WPA2_TKIP;
+ else if ((strncmp(arg, "WPA_TKIP_WPA2_AES", 17) == 0) || (strncmp(arg, "wpa_tkip_wpa2_aes", 17) == 0))
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = WPA_TKIP_WPA2_AES;
+ else if ((strncmp(arg, "WPA_TKIP_WPA2_TKIPAES", 21) == 0) || (strncmp(arg, "wpa_tkip_wpa2_tkipaes", 21) == 0))
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = WPA_TKIP_WPA2_TKIPAES;
+ else if ((strncmp(arg, "WPA_TKIPAES_WPA2_AES", 20) == 0) || (strncmp(arg, "wpa_tkipaes_wpa2_aes", 20) == 0))
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = WPA_TKIPAES_WPA2_AES;
+ else if ((strncmp(arg, "WPA_TKIPAES_WPA2_TKIPAES", 24) == 0) || (strncmp(arg, "wpa_tkipaes_wpa2_tkipaes", 24) == 0))
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIPAES;
+ else if ((strncmp(arg, "WPA_TKIPAES_WPA2_TKIP", 21) == 0) || (strncmp(arg, "wpa_tkipaes_wpa2_tkip", 21) == 0))
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIP;
+ else
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Set_AP_WpaMixPairCipher_Proc=0x%02x\n", apidx, pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set WPA rekey interval value
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_RekeyInterval_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ INT32 val;
+
+ val = simple_strtol(arg, 0, 10);
+
+ if((val >= 10) && (val < MAX_REKEY_INTER))
+ pAd->ApCfg.MBSSID[apidx].WPAREKEY.ReKeyInterval = val;
+ else /* Default */
+ pAd->ApCfg.MBSSID[apidx].WPAREKEY.ReKeyInterval = 3600;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Set_AP_RekeyInterval_Proc=%ld\n",
+ apidx, pAd->ApCfg.MBSSID[apidx].WPAREKEY.ReKeyInterval));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set WPA rekey method
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_RekeyMethod_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ PRT_WPA_REKEY pInfo = &pAd->ApCfg.MBSSID[apidx].WPAREKEY;
+
+ if ((strcmp(arg, "TIME") == 0) || (strcmp(arg, "time") == 0))
+ pInfo->ReKeyMethod = TIME_REKEY;
+ else if ((strcmp(arg, "PKT") == 0) || (strcmp(arg, "pkt") == 0))
+ pInfo->ReKeyMethod = PKT_REKEY;
+ else if ((strcmp(arg, "DISABLE") == 0) || (strcmp(arg, "disable") == 0))
+ pInfo->ReKeyMethod = DISABLE_REKEY;
+ else
+ pInfo->ReKeyMethod = DISABLE_REKEY;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Set_AP_RekeyMethod_Proc=%ld\n",
+ apidx, pInfo->ReKeyMethod));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set PMK-cache period
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_PMKCachePeriod_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ UINT32 val = simple_strtol(arg, 0, 10);
+
+ pAd->ApCfg.MBSSID[apidx].PMKCachePeriod = val * 60 * OS_HZ;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Set_AP_PMKCachePeriod_Proc=%ld\n",
+ apidx, pAd->ApCfg.MBSSID[apidx].PMKCachePeriod));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Default Key ID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG KeyIdx;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+
+ KeyIdx = simple_strtol(arg, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = (UCHAR) (KeyIdx - 1 );
+ else
+ return FALSE; /* Invalid argument */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_DefaultKeyID_Proc::(DefaultKeyID(0~3)=%d)\n", apidx, pAd->ApCfg.MBSSID[apidx].DefaultKeyId));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY1
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_Key1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ UCHAR apidx;
+ CIPHER_KEY *pSharedKey;
+ INT retVal;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ apidx = pObj->ioctl_if;
+ pSharedKey = &pAd->SharedKey[apidx][0];
+ retVal = RT_CfgSetWepKey(pAd, arg, pSharedKey, 0);
+ if (retVal == TRUE)
+ {
+ /* Set keys (into ASIC) */
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
+ ; /* not support */
+ else /* Old WEP stuff */
+ {
+ AsicAddSharedKeyEntry(pAd, apidx, 0, pSharedKey);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_Key1_Proc::(Key1=%s) success!\n", apidx, arg));
+ }
+
+ return retVal;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY2
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_Key2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ UCHAR apidx;
+ CIPHER_KEY *pSharedKey;
+ INT retVal;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ apidx = pObj->ioctl_if;
+ pSharedKey = &pAd->SharedKey[apidx][1];
+ retVal = RT_CfgSetWepKey(pAd, arg, pSharedKey, 1);
+ if (retVal == TRUE)
+ {
+ /* Set keys (into ASIC) */
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
+ ; /* not support */
+ else /* Old WEP stuff */
+ {
+ AsicAddSharedKeyEntry(pAd, apidx, 1, pSharedKey);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_Key2_Proc::(Key2=%s) success!\n", apidx, arg));
+ }
+
+ return retVal;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY3
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_Key3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ UCHAR apidx;
+ CIPHER_KEY *pSharedKey;
+ INT retVal;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ apidx = pObj->ioctl_if;
+ pSharedKey = &pAd->SharedKey[apidx][2];
+ retVal = RT_CfgSetWepKey(pAd, arg, pSharedKey, 2);
+ if (retVal == TRUE)
+ {
+ /* Set keys (into ASIC) */
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
+ ; /* not support */
+ else /* Old WEP stuff */
+ {
+ AsicAddSharedKeyEntry(pAd, apidx, 2, pSharedKey);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_Key3_Proc::(Key3=%s) success!\n", apidx, arg));
+ }
+
+ return retVal;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY4
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_Key4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+
+ POS_COOKIE pObj;
+ UCHAR apidx;
+ CIPHER_KEY *pSharedKey;
+ INT retVal;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ apidx = pObj->ioctl_if;
+ pSharedKey = &pAd->SharedKey[apidx][3];
+ retVal = RT_CfgSetWepKey(pAd, arg, pSharedKey, 3);
+ if (retVal == TRUE)
+ {
+ /* Set keys (into ASIC) */
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
+ ; /* not support */
+ else /* Old WEP stuff */
+ {
+ AsicAddSharedKeyEntry(pAd, apidx, 3, pSharedKey);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_Key4_Proc::(Key4=%s) success!\n", apidx, arg));
+ }
+
+ return retVal;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Access ctrol policy
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AccessPolicy_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ switch (simple_strtol(arg, 0, 10))
+ {
+ case 0: /*Disable */
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy = 0;
+ break;
+ case 1: /* Allow All, and ACL is positive. */
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy = 1;
+ break;
+ case 2: /* Reject All, and ACL is negative. */
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy = 2;
+ break;
+ default: /*Invalid argument */
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_AccessPolicy_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+
+ /* check if the change in ACL affects any existent association */
+ ApUpdateAccessControlList(pAd, pObj->ioctl_if);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_AccessPolicy_Proc::(AccessPolicy=%ld)\n", pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy));
+
+ return TRUE;
+}
+
+
+/* Replaced by Set_ACLAddEntry_Proc() and Set_ACLClearAll_Proc() */
+
+/*
+ ==========================================================================
+ Description:
+ Add one entry or several entries(if allowed to)
+ into Access control mac table list
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ACLAddEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR macAddr[MAC_ADDR_LEN];
+/* RT_802_11_ACL acl; */
+ RT_802_11_ACL *pacl = NULL;
+ PSTRING this_char;
+ PSTRING value;
+ INT i, j;
+ BOOLEAN isDuplicate=FALSE;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num >= (MAX_NUM_OF_ACL_LIST - 1))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("The AccessControlList is full, and no more entry can join the list!\n"));
+ return FALSE;
+ }
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&pacl, sizeof(RT_802_11_ACL));
+ if (pacl == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ NdisZeroMemory(pacl, sizeof(RT_802_11_ACL));
+ NdisMoveMemory(pacl, &pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL));
+
+ while ((this_char = strsep((char **)&arg, ";")) != NULL)
+ {
+ if (*this_char == '\0')
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("An unnecessary delimiter entered!\n"));
+ continue;
+ }
+ if (strlen(this_char) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("illegal MAC address length!\n"));
+ continue;
+ }
+ for (i=0, value = rstrtok(this_char,":"); value; value = rstrtok(NULL,":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("illegal MAC address format or octet!\n"));
+ /* Do not use "continue" to replace "break" */
+ break;
+ }
+ AtoH(value, &macAddr[i++], 1);
+ }
+
+ if (i != MAC_ADDR_LEN)
+ {
+ continue;
+ }
+
+ /* Check if this entry is duplicate. */
+ isDuplicate = FALSE;
+ for (j=0; j<pacl->Num; j++)
+ {
+ if (memcmp(pacl->Entry[j].Addr, &macAddr, 6) == 0)
+ {
+ isDuplicate = TRUE;
+ DBGPRINT(RT_DEBUG_WARN, ("You have added an entry before :\n"));
+ DBGPRINT(RT_DEBUG_WARN, ("The duplicate entry is %02x:%02x:%02x:%02x:%02x:%02x\n",
+ macAddr[0],macAddr[1],macAddr[2],macAddr[3],macAddr[4],macAddr[5]));
+ }
+ }
+
+ if (!isDuplicate)
+ {
+ NdisMoveMemory(pacl->Entry[pacl->Num++].Addr, &macAddr, MAC_ADDR_LEN);
+ }
+
+ if (pacl->Num == MAX_NUM_OF_ACL_LIST)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("The AccessControlList is full, and no more entry can join the list!\n"));
+ DBGPRINT(RT_DEBUG_WARN, ("The last entry of ACL is %02x:%02x:%02x:%02x:%02x:%02x\n",
+ macAddr[0],macAddr[1],macAddr[2],macAddr[3],macAddr[4],macAddr[5]));
+ break;
+ }
+ }
+
+ ASSERT(pacl->Num < MAX_NUM_OF_ACL_LIST);
+
+ NdisZeroMemory(&pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL));
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, pacl, sizeof(RT_802_11_ACL));
+
+ /* check if the change in ACL affects any existent association */
+ ApUpdateAccessControlList(pAd, pObj->ioctl_if);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::%s(Policy=%ld, Entry#=%ld)\n",
+ __FUNCTION__ , pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy, pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num));
+
+#ifdef DBG
+ DBGPRINT(RT_DEBUG_TRACE, ("=============== Entry ===============\n"));
+ for (i=0; i<pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num; i++)
+ {
+ printk("Entry #%02d: ", i+1);
+ for (j=0; j<MAC_ADDR_LEN; j++)
+ printk("%02X ", pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Entry[i].Addr[j]);
+ printk("\n");
+ }
+#endif
+
+ if (pacl != NULL)
+ os_free_mem(NULL, pacl);
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Delete one entry or several entries(if allowed to)
+ from Access control mac table list
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ACLDelEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR macAddr[MAC_ADDR_LEN];
+ UCHAR nullAddr[MAC_ADDR_LEN];
+ RT_802_11_ACL acl;
+ PSTRING this_char;
+ PSTRING value;
+ INT i, j;
+ BOOLEAN isFound=FALSE;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ NdisZeroMemory(&acl, sizeof(RT_802_11_ACL));
+ NdisMoveMemory(&acl, &pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL));
+ NdisZeroMemory(nullAddr, MAC_ADDR_LEN);
+
+ while ((this_char = strsep((char **)&arg, ";")) != NULL)
+ {
+ if (*this_char == '\0')
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("An unnecessary delimiter entered!\n"));
+ continue;
+ }
+ if (strlen(this_char) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("illegal MAC address length!\n"));
+ continue;
+ }
+
+ for (i=0, value = rstrtok(this_char,":"); value; value = rstrtok(NULL,":"))
+ {
+ if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("illegal MAC address format or octet!\n"));
+ /* Do not use "continue" to replace "break" */
+ break;
+ }
+ AtoH(value, &macAddr[i++], 1);
+ }
+
+ if (i != MAC_ADDR_LEN)
+ {
+ continue;
+ }
+
+ /* Check if this entry existed. */
+ isFound = FALSE;
+ for (j=0; j<acl.Num; j++)
+ {
+ if (memcmp(acl.Entry[j].Addr, &macAddr, MAC_ADDR_LEN) == 0)
+ {
+ isFound = TRUE;
+ NdisZeroMemory(acl.Entry[j].Addr, MAC_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("The entry %02x:%02x:%02x:%02x:%02x:%02x founded will be deleted!\n",
+ macAddr[0],macAddr[1],macAddr[2],macAddr[3],macAddr[4],macAddr[5]));
+ }
+ }
+
+ if (!isFound)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The entry %02x:%02x:%02x:%02x:%02x:%02x is not in the list!\n",
+ macAddr[0],macAddr[1],macAddr[2],macAddr[3],macAddr[4],macAddr[5]));
+ }
+ }
+
+ NdisZeroMemory(&pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL));
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy = acl.Policy;
+ ASSERT(pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num == 0);
+ i = 0;
+
+ for (j=0; j<acl.Num; j++)
+ {
+ if (memcmp(acl.Entry[j].Addr, &nullAddr, MAC_ADDR_LEN) == 0)
+ {
+ continue;
+ }
+ else
+ {
+ NdisMoveMemory(&(pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Entry[i++]), acl.Entry[j].Addr, MAC_ADDR_LEN);
+ }
+ }
+
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num = i;
+ ASSERT(acl.Num >= pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num);
+
+ /* check if the change in ACL affects any existent association */
+ ApUpdateAccessControlList(pAd, pObj->ioctl_if);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::%s(Policy=%ld, Entry#=%ld)\n",
+ __FUNCTION__ , pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy, pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num));
+
+#ifdef DBG
+ DBGPRINT(RT_DEBUG_TRACE, ("=============== Entry ===============\n"));
+ for (i=0; i<pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num; i++)
+ {
+ printk("Entry #%02d: ", i+1);
+ for (j=0; j<MAC_ADDR_LEN; j++)
+ printk("%02X ", pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Entry[i].Addr[j]);
+ printk("\n");
+ }
+#endif
+ return TRUE;
+}
+
+
+/* for ACL policy message */
+#define ACL_POLICY_TYPE_NUM 3
+char const *pACL_PolicyMessage[ACL_POLICY_TYPE_NUM] = {
+ "the Access Control feature is disabled", /* 0 : Disable */
+ "only the following entries are allowed to join this BSS", /* 1 : Allow */
+ "all the following entries are rejected to join this BSS", /* 2 : Reject */
+};
+
+
+/*
+ ==========================================================================
+ Description:
+ Dump all the entries in the Access control
+ mac table list of a specified BSS
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ACLShowAll_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ RT_802_11_ACL acl;
+ BOOLEAN bDumpAll=FALSE;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ INT i, j;
+
+ bDumpAll = simple_strtol(arg, 0, 10);
+
+ if (bDumpAll == 1)
+ {
+ bDumpAll = TRUE;
+ }
+ else if (bDumpAll == 0)
+ {
+ bDumpAll = FALSE;
+ DBGPRINT(RT_DEBUG_WARN, ("Your input is 0!\n"));
+ DBGPRINT(RT_DEBUG_WARN, ("The Access Control List will not be dumped!\n"));
+ return TRUE;
+ }
+ else
+ {
+ return FALSE; /* Invalid argument */
+ }
+
+ NdisZeroMemory(&acl, sizeof(RT_802_11_ACL));
+ NdisMoveMemory(&acl, &pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL));
+
+ /* Check if the list is already empty. */
+ if (acl.Num == 0)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("The Access Control List is empty!\n"));
+ return TRUE;
+ }
+
+ ASSERT(((bDumpAll == 1) && (acl.Num > 0)));
+
+ /* Show the corresponding policy first. */
+ printk("=============== Access Control Policy ===============\n");
+ printk("Policy is %ld : ", acl.Policy);
+ printk("%s\n", pACL_PolicyMessage[acl.Policy]);
+
+ /* Dump the entry in the list one by one */
+ printk("=============== Access Control List ===============\n");
+ for (i=0; i<acl.Num; i++)
+ {
+ printk("Entry #%02d: ", i+1);
+ for (j=0; j<MAC_ADDR_LEN; j++)
+ printk("%02X ", acl.Entry[i].Addr[j]);
+ printk("\n");
+ }
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Clear all the entries in the Access control
+ mac table list of a specified BSS
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ACLClearAll_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+/* RT_802_11_ACL acl; */
+ RT_802_11_ACL *pacl = NULL;
+ BOOLEAN bClearAll=FALSE;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ bClearAll = simple_strtol(arg, 0, 10);
+
+ if (bClearAll == 1)
+ {
+ bClearAll = TRUE;
+ }
+ else if (bClearAll == 0)
+ {
+ bClearAll = FALSE;
+ DBGPRINT(RT_DEBUG_WARN, ("Your input is 0!\n"));
+ DBGPRINT(RT_DEBUG_WARN, ("The Access Control List will be kept unchanged!\n"));
+ return TRUE;
+ }
+ else
+ {
+ return FALSE; /* Invalid argument */
+ }
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&pacl, sizeof(RT_802_11_ACL));
+ if (pacl == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ NdisZeroMemory(pacl, sizeof(RT_802_11_ACL));
+ NdisMoveMemory(pacl, &pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL));
+
+ /* Check if the list is already empty. */
+ if (pacl->Num == 0)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("The Access Control List is empty!\n"));
+ DBGPRINT(RT_DEBUG_WARN, ("No need to clear the Access Control List!\n"));
+ return TRUE;
+ }
+
+ ASSERT(((bClearAll == 1) && (pacl->Num > 0)));
+
+ /* Clear the entry in the list one by one */
+ /* Keep the corresponding policy unchanged. */
+ do
+ {
+ NdisZeroMemory(pacl->Entry[pacl->Num - 1].Addr, MAC_ADDR_LEN);
+ pacl->Num -= 1;
+ }while (pacl->Num > 0);
+
+ ASSERT(pacl->Num == 0);
+
+ NdisZeroMemory(&(pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList), sizeof(RT_802_11_ACL));
+ NdisMoveMemory(&(pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList), pacl, sizeof(RT_802_11_ACL));
+
+ /* check if the change in ACL affects any existent association */
+ ApUpdateAccessControlList(pAd, pObj->ioctl_if);
+
+ if (pacl != NULL)
+ os_free_mem(NULL, pacl);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::%s(Policy=%ld, Entry#=%ld)\n",
+ __FUNCTION__, pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy, pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num));
+
+ return TRUE;
+}
+
+#ifdef DBG
+static void _rtmp_hexdump(int level, const char *title, const UINT8 *buf,
+ size_t len, int show)
+{
+ size_t i;
+ if (level < RTDebugLevel)
+ return;
+ printk("%s - hexdump(len=%lu):", title, (unsigned long) len);
+ if (show) {
+ for (i = 0; i < len; i++)
+ printk(" %02x", buf[i]);
+ } else {
+ printk(" [REMOVED]");
+ }
+ printk("\n");
+}
+
+void rtmp_hexdump(int level, const char *title, const UINT8 *buf, size_t len)
+{
+ _rtmp_hexdump(level, title, buf, len, 1);
+}
+#endif
+
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WPA PSK key
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ arg WPA pre-shared key string
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ INT retval;
+ MULTISSID_STRUCT *pMBSSStruct;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
+
+ pMBSSStruct = &pAd->ApCfg.MBSSID[apidx];
+ retval = RT_CfgSetWPAPSKKey(pAd, arg, strlen(arg), (PUCHAR)pMBSSStruct->Ssid, pMBSSStruct->SsidLen, pMBSSStruct->PMK);
+ if (retval == FALSE)
+ return FALSE;
+
+#ifdef WSC_AP_SUPPORT
+ NdisZeroMemory(pMBSSStruct->WscControl.WpaPsk, 64);
+ pMBSSStruct->WscControl.WpaPskLen = 0;
+ pMBSSStruct->WscControl.WpaPskLen = strlen(arg);
+ NdisMoveMemory(pMBSSStruct->WscControl.WpaPsk, arg, pMBSSStruct->WscControl.WpaPskLen);
+#endif /* WSC_AP_SUPPORT */
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Reset statistics counter
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ arg
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+
+INT Set_RadioOn_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR radio;
+
+ radio = simple_strtol(arg, 0, 10);
+
+ if (radio)
+ {
+ MlmeRadioOn(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("==>Set_RadioOn_Proc (ON)\n"));
+ }
+ else
+ {
+ MlmeRadioOff(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("==>Set_RadioOn_Proc (OFF)\n"));
+ }
+
+ return TRUE;
+}
+
+#ifdef AP_SCAN_SUPPORT
+/*
+ ==========================================================================
+ 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
+ ==========================================================================
+*/
+
+/*
+ ==========================================================================
+ Description:
+ Issue a Auto-Channel Selection command to driver
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 set AutoChannelSel=1
+ Ues the number of AP to choose
+ 2.) iwpriv ra0 set AutoChannelSel=2
+ Ues the False CCA count to choose
+ ==========================================================================
+*/
+INT Set_AutoChannelSel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ NDIS_802_11_SSID Ssid;
+
+
+ NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+ if (strlen(arg) <= MAX_LEN_OF_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);
+ }
+ }
+ if (strcmp(arg,"1") == 0)
+ pAd->ApCfg.AutoChannelAlg = ChannelAlgApCnt;
+ else if (strcmp(arg,"2") == 0)
+ pAd->ApCfg.AutoChannelAlg = ChannelAlgCCA;
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_AutoChannelSel_Proc Alg isn't defined\n"));
+ return FALSE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_AutoChannelSel_Proc Alg=%d \n", pAd->ApCfg.AutoChannelAlg));
+ if (Ssid.SsidLength == 0)
+ ApSiteSurvey(pAd, &Ssid, SCAN_PASSIVE, TRUE);
+ else
+ ApSiteSurvey(pAd, &Ssid, SCAN_ACTIVE, TRUE);
+
+ return TRUE;
+
+}
+
+#endif /* AP_SCAN_SUPPORT */
+
+INT Show_DriverInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ printk("Driver version: %s (%s %s) .\n", AP_DRIVER_VERSION, __DATE__, __TIME__);
+
+ return TRUE;
+}
+
+
+INT Show_StaCount_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;/*, QueIdx=0; */
+ UINT32 RegValue;
+
+ printk("\n");
+ RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+ printk("BackOff Slot : %s slot time, BKOFF_SLOT_CFG(0x1104) = 0x%08x\n",
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED) ? "short" : "long",
+ RegValue);
+
+#ifdef DOT11_N_SUPPORT
+ printk("HT Operating Mode : %d\n", pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
+ printk("\n");
+#endif /* DOT11_N_SUPPORT */
+
+ printk("\n%-19s%-4s%-12s%-12s%-12s%-12s\n",
+ "MAC", "AID","TxPackets","RxPackets","TxBytes","RxBytes");
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if ((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry))
+ && (pEntry->Sst == SST_ASSOC))
+ {
+ printk("%02X:%02X:%02X:%02X:%02X:%02X ",
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+ printk("%-4d", (int)pEntry->Aid);
+ printk("%-12ld",(ULONG)pEntry->TxPackets.QuadPart);
+ printk("%-12ld", (ULONG)pEntry->RxPackets.QuadPart);
+ printk("%-12ld", (ULONG)pEntry->TxBytes);
+ printk("%-12ld", (ULONG)pEntry->RxBytes);
+ printk("\n");
+ }
+ }
+
+ return TRUE;
+}
+
+INT Show_StaSecurityInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+ UCHAR apidx;
+
+ printk("\n");
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ printk(" BSS(%d) AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s, WPAMixPairCipher(0x%02X)\n",
+ apidx,
+ pAd->ApCfg.MBSSID[apidx].AuthMode,
+ GetAuthMode(pAd->ApCfg.MBSSID[apidx].AuthMode),
+ pAd->ApCfg.MBSSID[apidx].WepStatus,
+ GetEncryptType(pAd->ApCfg.MBSSID[apidx].WepStatus),
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus,
+ GetEncryptType(pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus),
+ pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher);
+ }
+ printk("\n");
+
+ printk("\n%-19s%-4s%-4s%-15s%-12s\n",
+ "MAC", "AID", "BSS", "Auth", "Encrypt");
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (pEntry && IS_ENTRY_CLIENT(pEntry) && pEntry->Sst == SST_ASSOC)
+ {
+ printk("%02X:%02X:%02X:%02X:%02X:%02X ",
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+ printk("%-4d", (int)pEntry->Aid);
+ printk("%-4d", (int)pEntry->apidx);
+ printk("%-15s", GetAuthMode(pEntry->AuthMode));
+ printk("%-12s", GetEncryptType(pEntry->WepStatus));
+ printk("\n");
+ }
+ }
+
+ return TRUE;
+}
+
+
+#ifdef DOT11_N_SUPPORT
+INT Show_BaTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i, j;
+ BA_ORI_ENTRY *pOriBAEntry;
+ BA_REC_ENTRY *pRecBAEntry;
+ STRING tmpBuf[6];
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (IS_ENTRY_NONE(pEntry))
+ continue;
+
+ if ((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry))
+ && (pEntry->Sst != SST_ASSOC))
+ continue;
+
+ if (IS_ENTRY_APCLI(pEntry))
+ strcpy(tmpBuf, "ApCli");
+ else if (IS_ENTRY_WDS(pEntry))
+ strcpy(tmpBuf, "WDS");
+ else if (IS_ENTRY_MESH(pEntry))
+ strcpy(tmpBuf, "Mesh");
+ else
+ strcpy(tmpBuf, "STA");
+
+ printk("%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (%s) -\n",
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid, tmpBuf);
+
+ printk("[Recipient]\n");
+ for (j=0; j < NUM_OF_TID; j++)
+ {
+ if (pEntry->BARecWcidArray[j] != 0)
+ {
+ pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
+ printk("TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
+ }
+ }
+ printk("\n");
+
+ printk("[Originator]\n");
+ for (j=0; j < NUM_OF_TID; j++)
+ {
+ if (pEntry->BAOriWcidArray[j] != 0)
+ {
+ pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
+ printk("TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
+ }
+ }
+ printk("\n\n");
+ }
+
+ return TRUE;
+}
+#endif /* DOT11_N_SUPPORT */
+
+
+INT Show_RAInfo_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+#ifdef PRE_ANT_SWITCH
+ DBGPRINT(RT_DEBUG_OFF, ("PreAntSwitch: %d\n", pAd->CommonCfg.PreAntSwitch));
+ DBGPRINT(RT_DEBUG_OFF, ("PreAntSwitchRSSI: %d\n", pAd->CommonCfg.PreAntSwitchRSSI));
+#endif /* PRE_ANT_SWITCH */
+
+#ifdef CFO_TRACK
+ DBGPRINT(RT_DEBUG_OFF, ("CFOTrack: %d\n", pAd->CommonCfg.CFOTrack));
+#endif /* CFO_TRACK */
+
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ DBGPRINT(RT_DEBUG_OFF, ("LowTrafficThrd: %d\n", pAd->CommonCfg.lowTrafficThrd));
+ DBGPRINT(RT_DEBUG_OFF, ("TrainUpRule: %d\n", pAd->CommonCfg.TrainUpRule));
+ DBGPRINT(RT_DEBUG_OFF, ("TrainUpRuleRSSI: %d\n", pAd->CommonCfg.TrainUpRuleRSSI));
+ DBGPRINT(RT_DEBUG_OFF, ("TrainUpLowThrd: %d\n", pAd->CommonCfg.TrainUpLowThrd));
+ DBGPRINT(RT_DEBUG_OFF, ("TrainUpHighThrd: %d\n", pAd->CommonCfg.TrainUpHighThrd));
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef STREAM_MODE_SUPPORT
+ DBGPRINT(RT_DEBUG_OFF, ("StreamMode: %d\n", pAd->CommonCfg.StreamMode));
+ DBGPRINT(RT_DEBUG_OFF, ("StreamModeMCS: 0x%04x\n", pAd->CommonCfg.StreamModeMCS));
+#endif /* STREAM_MODE_SUPPORT */
+#ifdef TXBF_SUPPORT
+ DBGPRINT(RT_DEBUG_OFF, ("ITxBfEn: %d\n", pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn));
+ DBGPRINT(RT_DEBUG_OFF, ("ITxBfTimeout: %ld\n", pAd->CommonCfg.ITxBfTimeout));
+ DBGPRINT(RT_DEBUG_OFF, ("ETxBfTimeout: %ld\n", pAd->CommonCfg.ETxBfTimeout));
+ DBGPRINT(RT_DEBUG_OFF, ("ETxBfEnCond: %ld\n", pAd->CommonCfg.ETxBfEnCond));
+ DBGPRINT(RT_DEBUG_OFF, ("ETxBfNoncompress: %d\n", pAd->CommonCfg.ETxBfNoncompress));
+ DBGPRINT(RT_DEBUG_OFF, ("ETxBfIncapable: %d\n", pAd->CommonCfg.ETxBfIncapable));
+#endif /* TXBF_SUPPORT */
+
+#ifdef DBG_CTRL_SUPPORT
+ DBGPRINT(RT_DEBUG_OFF, ("DebugFlags: 0x%lx\n", pAd->CommonCfg.DebugFlags));
+#endif /* DBG_CTRL_SUPPORT */
+
+ return TRUE;
+}
+
+
+
+INT Show_Sat_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ /* Sanity check for calculation of sucessful count */
+ printk("TransmitCountFromOS = %d\n", pAd->WlanCounters.TransmitCountFrmOs.u.LowPart);
+ printk("TransmittedFragmentCount = %d\n", pAd->WlanCounters.TransmittedFragmentCount.u.LowPart + pAd->WlanCounters.MulticastTransmittedFrameCount.QuadPart);
+ printk("MulticastTransmittedFrameCount = %d\n", pAd->WlanCounters.MulticastTransmittedFrameCount.u.LowPart);
+ printk("FailedCount = %d\n", pAd->WlanCounters.FailedCount.u.LowPart);
+ printk("RetryCount = %d\n", pAd->WlanCounters.RetryCount.u.LowPart);
+ printk("MultipleRetryCount = %d\n", pAd->WlanCounters.MultipleRetryCount.u.LowPart);
+ printk("RTSSuccessCount = %d\n", pAd->WlanCounters.RTSSuccessCount.u.LowPart);
+ printk("RTSFailureCount = %d\n", pAd->WlanCounters.RTSFailureCount.u.LowPart);
+ printk("ACKFailureCount = %d\n", pAd->WlanCounters.ACKFailureCount.u.LowPart);
+ printk("FrameDuplicateCount = %d\n", pAd->WlanCounters.FrameDuplicateCount.u.LowPart);
+ printk("ReceivedFragmentCount = %d\n", pAd->WlanCounters.ReceivedFragmentCount.u.LowPart);
+ printk("MulticastReceivedFrameCount = %d\n", pAd->WlanCounters.MulticastReceivedFrameCount.u.LowPart);
+ printk("Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
+#ifdef DBG
+ printk("RealFcsErrCount = %d\n", pAd->RalinkCounters.RealFcsErrCount.u.LowPart);
+#else
+ printk("FCSErrorCount = %d\n", pAd->WlanCounters.FCSErrorCount.u.LowPart);
+ printk("FrameDuplicateCount.LowPart = %d\n", pAd->WlanCounters.FrameDuplicateCount.u.LowPart / 100);
+#endif
+ printk("TransmittedFrameCount = %d\n", pAd->WlanCounters.TransmittedFragmentCount.u.LowPart);
+ printk("WEPUndecryptableCount = %d\n", pAd->WlanCounters.WEPUndecryptableCount.u.LowPart);
+
+#ifdef DOT11_N_SUPPORT
+ printk("\n===Some 11n statistics variables: \n");
+ /* Some 11n statistics variables */
+ printk("TransmittedAMSDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart);
+ printk("TransmittedOctetsInAMSDU = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart);
+ printk("ReceivedAMSDUCount = %ld\n", (ULONG)pAd->RalinkCounters.ReceivedAMSDUCount.u.LowPart);
+ printk("ReceivedOctesInAMSDUCount = %ld\n", (ULONG)pAd->RalinkCounters.ReceivedOctesInAMSDUCount.QuadPart);
+ printk("TransmittedAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart);
+ printk("TransmittedMPDUsInAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart);
+ printk("TransmittedOctetsInAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.u.LowPart);
+ printk("MPDUInReceivedAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.MPDUInReceivedAMPDUCount.u.LowPart);
+#ifdef DOT11N_DRAFT3
+ printk("fAnyStaFortyIntolerant=%d\n", pAd->MacTab.fAnyStaFortyIntolerant);
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+{
+ int apidx;
+
+ for (apidx=0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ printk("-- IF-ra%d -- \n", apidx);
+ printk("Packets Received = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].RxCount);
+ printk("Packets Sent = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].TxCount);
+ printk("Bytes Received = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].ReceivedByteCount);
+ printk("Byte Sent = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].TransmittedByteCount);
+ printk("Error Packets Received = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].RxErrorCount);
+ printk("Drop Received Packets = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].RxDropCount);
+
+#ifdef WSC_INCLUDED
+ if (pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE)
+ {
+ WSC_CTRL *pWscCtrl;
+
+ pWscCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ printk("WscInfo:\n"
+ "\tWscConfMode=%d\n"
+ "\tWscMode=%s\n"
+ "\tWscConfStatus=%d\n"
+ "\tWscPinCode=%d\n"
+ "\tWscState=0x%x\n"
+ "\tWscStatus=0x%x\n",
+ pWscCtrl->WscConfMode,
+ ((pWscCtrl->WscMode == WSC_PIN_MODE) ? "PIN" : "PBC"),
+ pWscCtrl->WscConfStatus, pWscCtrl->WscEnrolleePinCode,
+ pWscCtrl->WscState, pWscCtrl->WscStatus);
+ }
+#endif /* WSC_INCLUDED */
+
+ printk("-- IF-ra%d end -- \n", apidx);
+ }
+}
+
+{
+ int i, j, k, maxMcs = MAX_MCS_SET -1;
+ PMAC_TABLE_ENTRY pEntry;
+
+#ifdef DOT11N_SS3_SUPPORT
+ if (IS_RT2883(pAd) || IS_RT3883(pAd))
+ maxMcs = 23;
+#endif /* DOT11N_SS3_SUPPORT */
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC))
+ {
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x - ", PRINT_MAC(pEntry->Addr));
+ printk("%-4d\n", (int)pEntry->Aid);
+
+ for (j=maxMcs; j>=0; j--)
+ {
+ if ((pEntry->TXMCSExpected[j] != 0) || (pEntry->TXMCSFailed[j] !=0))
+ {
+ printk("MCS[%02d]: Expected %u, Successful %u (%d%%), Failed %u\n",
+ j, pEntry->TXMCSExpected[j], pEntry->TXMCSSuccessful[j],
+ pEntry->TXMCSExpected[j] ? (100*pEntry->TXMCSSuccessful[j])/pEntry->TXMCSExpected[j] : 0,
+ pEntry->TXMCSFailed[j]);
+ for(k=maxMcs; k>=0; k--)
+ {
+ if (pEntry->TXMCSAutoFallBack[j][k] != 0)
+ {
+ printk("\t\t\tAutoMCS[%02d]: %u (%d%%)\n", k, pEntry->TXMCSAutoFallBack[j][k],
+ (100*pEntry->TXMCSAutoFallBack[j][k])/pEntry->TXMCSExpected[j]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
+
+#ifdef DOT11_N_SUPPORT
+ /* Display Tx Aggregation statistics */
+ DisplayTxAgg(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ return TRUE;
+}
+
+
+
+INT Show_Sat_Reset_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ /* Sanity check for calculation of sucessful count */
+
+ printk("TransmittedFragmentCount = %d\n", pAd->WlanCounters.TransmittedFragmentCount.u.LowPart + pAd->WlanCounters.MulticastTransmittedFrameCount.QuadPart);
+ printk("MulticastTransmittedFrameCount = %d\n", pAd->WlanCounters.MulticastTransmittedFrameCount.u.LowPart);
+ printk("FailedCount = %d\n", pAd->WlanCounters.FailedCount.u.LowPart);
+ printk("RetryCount = %d\n", pAd->WlanCounters.RetryCount.u.LowPart);
+ printk("MultipleRetryCount = %d\n", pAd->WlanCounters.MultipleRetryCount.u.LowPart);
+ printk("RTSSuccessCount = %d\n", pAd->WlanCounters.RTSSuccessCount.u.LowPart);
+ printk("RTSFailureCount = %d\n", pAd->WlanCounters.RTSFailureCount.u.LowPart);
+ printk("ACKFailureCount = %d\n", pAd->WlanCounters.ACKFailureCount.u.LowPart);
+ printk("FrameDuplicateCount = %d\n", pAd->WlanCounters.FrameDuplicateCount.u.LowPart);
+ printk("ReceivedFragmentCount = %d\n", pAd->WlanCounters.ReceivedFragmentCount.u.LowPart);
+ printk("MulticastReceivedFrameCount = %d\n", pAd->WlanCounters.MulticastReceivedFrameCount.u.LowPart);
+ printk("Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
+#ifdef DBG
+ printk("RealFcsErrCount = %d\n", pAd->RalinkCounters.RealFcsErrCount.u.LowPart);
+#else
+ printk("FCSErrorCount = %d\n", pAd->WlanCounters.FCSErrorCount.u.LowPart);
+ printk("FrameDuplicateCount.LowPart = %d\n", pAd->WlanCounters.FrameDuplicateCount.u.LowPart / 100);
+#endif
+ printk("TransmittedFrameCount = %d\n", pAd->WlanCounters.TransmittedFrameCount.u.LowPart);
+ printk("WEPUndecryptableCount = %d\n", pAd->WlanCounters.WEPUndecryptableCount.u.LowPart);
+
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart = 0;
+ pAd->WlanCounters.MulticastTransmittedFrameCount.u.LowPart = 0;
+ pAd->WlanCounters.FailedCount.u.LowPart = 0;
+ pAd->WlanCounters.RetryCount.u.LowPart = 0;
+ pAd->WlanCounters.MultipleRetryCount.u.LowPart = 0;
+ pAd->WlanCounters.RTSSuccessCount.u.LowPart = 0;
+ pAd->WlanCounters.RTSFailureCount.u.LowPart = 0;
+ pAd->WlanCounters.ACKFailureCount.u.LowPart = 0;
+ pAd->WlanCounters.FrameDuplicateCount.u.LowPart = 0;
+ pAd->WlanCounters.ReceivedFragmentCount.u.LowPart = 0;
+ pAd->WlanCounters.MulticastReceivedFrameCount.u.LowPart = 0;
+ pAd->Counters8023.RxNoBuffer = 0;
+#ifdef DBG
+ pAd->RalinkCounters.RealFcsErrCount.u.LowPart = 0;
+#else
+ pAd->WlanCounters.FCSErrorCount.u.LowPart = 0;
+ pAd->WlanCounters.FrameDuplicateCount.u.LowPart = 0;
+#endif
+
+ pAd->WlanCounters.TransmittedFrameCount.u.LowPart = 0;
+ pAd->WlanCounters.WEPUndecryptableCount.u.LowPart = 0;
+
+ {
+ int i, j, k, maxMcs = 15;
+ PMAC_TABLE_ENTRY pEntry;
+
+#ifdef DOT11N_SS3_SUPPORT
+ if (IS_RT2883(pAd) || IS_RT3883(pAd))
+ maxMcs = 23;
+#endif /* DOT11N_SS3_SUPPORT */
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC))
+ {
+
+ printk("\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]);
+ printk("%-4d\n", (int)pEntry->Aid);
+
+ for (j = maxMcs; j >= 0; j--)
+ {
+ if ((pEntry->TXMCSExpected[j] != 0) || (pEntry->TXMCSFailed[j] !=0))
+ {
+ printk("MCS[%02d]: Expected %u, Successful %u (%d%%), Failed %u\n",
+ j, pEntry->TXMCSExpected[j], pEntry->TXMCSSuccessful[j],
+ pEntry->TXMCSExpected[j] ? (100*pEntry->TXMCSSuccessful[j])/pEntry->TXMCSExpected[j] : 0,
+ pEntry->TXMCSFailed[j]
+ );
+ for(k = maxMcs; k >= 0; k--)
+ {
+ if (pEntry->TXMCSAutoFallBack[j][k] != 0)
+ {
+ printk("\t\t\tAutoMCS[%02d]: %u (%d%%)\n", k, pEntry->TXMCSAutoFallBack[j][k],
+ (100*pEntry->TXMCSAutoFallBack[j][k])/pEntry->TXMCSExpected[j]);
+ }
+ }
+ }
+ }
+ }
+ for (j = 0; j < (maxMcs + 1); j++)
+ {
+ pEntry->TXMCSExpected[j] = 0;
+ pEntry->TXMCSSuccessful[j] = 0;
+ pEntry->TXMCSFailed[j] = 0;
+ for(k = maxMcs; k >= 0; k--)
+ {
+ pEntry->TXMCSAutoFallBack[j][k] = 0;
+ }
+ }
+ }
+ }
+#ifdef DOT11_N_SUPPORT
+ /* Display Tx Aggregation statistics */
+ DisplayTxAgg(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ return TRUE;
+}
+
+
+#ifdef MAT_SUPPORT
+INT Show_MATTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ extern VOID dumpIPMacTb(MAT_STRUCT *pMatCfg, int index);
+ extern NDIS_STATUS dumpSesMacTb(MAT_STRUCT *pMatCfg, int hashIdx);
+ extern NDIS_STATUS dumpUidMacTb(MAT_STRUCT *pMatCfg, int hashIdx);
+ extern NDIS_STATUS dumpIPv6MacTb(MAT_STRUCT *pMatCfg, int hashIdx);
+
+ dumpIPMacTb(&pAd->MatCfg, -1);
+ dumpSesMacTb(&pAd->MatCfg, -1);
+ dumpUidMacTb(&pAd->MatCfg, -1);
+ dumpIPv6MacTb(&pAd->MatCfg, -1);
+
+ printk("Default BroadCast Address=%02x:%02x:%02x:%02x:%02x:%02x!\n", BROADCAST_ADDR[0], BROADCAST_ADDR[1],
+ BROADCAST_ADDR[2], BROADCAST_ADDR[3], BROADCAST_ADDR[4], BROADCAST_ADDR[5]);
+ return TRUE;
+}
+#endif /* MAT_SUPPORT */
+
+
+#ifdef DOT1X_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ It only shall be queried by 802.1x daemon for querying radius configuration.
+ Arguments:
+ pAd Pointer to our adapter
+ wrq Pointer to the ioctl argument
+ ==========================================================================
+*/
+VOID RTMPIoctlQueryRadiusConf(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ UCHAR apidx, srv_idx, keyidx, KeyLen = 0;
+ UCHAR *mpool;
+ PDOT1X_CMM_CONF pConf;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlQueryRadiusConf==>\n"));
+
+ /* Allocate memory */
+ os_alloc_mem(NULL, (PUCHAR *)&mpool, sizeof(DOT1X_CMM_CONF));
+ if (mpool == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!%s: out of resource!!!\n", __FUNCTION__));
+ return;
+ }
+ NdisZeroMemory(mpool, sizeof(DOT1X_CMM_CONF));
+
+ pConf = (PDOT1X_CMM_CONF)mpool;
+
+ /* get MBSS number */
+ pConf->mbss_num = pAd->ApCfg.BssidNum;
+
+ /* get own ip address */
+ pConf->own_ip_addr = pAd->ApCfg.own_ip_addr;
+
+ /* get retry interval */
+ pConf->retry_interval = pAd->ApCfg.retry_interval;
+
+ /* get session timeout interval */
+ pConf->session_timeout_interval = pAd->ApCfg.session_timeout_interval;
+
+ /* Get the quiet interval */
+ pConf->quiet_interval = pAd->ApCfg.quiet_interval;
+
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[apidx];
+ PDOT1X_BSS_INFO p1xBssInfo = &pConf->Dot1xBssInfo[apidx];
+
+ p1xBssInfo->radius_srv_num = pMbss->radius_srv_num;
+
+ /* prepare radius ip, port and key */
+ for (srv_idx = 0; srv_idx < pMbss->radius_srv_num; srv_idx++)
+ {
+ if (pMbss->radius_srv_info[srv_idx].radius_ip != 0)
+ {
+ p1xBssInfo->radius_srv_info[srv_idx].radius_ip = pMbss->radius_srv_info[srv_idx].radius_ip;
+ p1xBssInfo->radius_srv_info[srv_idx].radius_port = pMbss->radius_srv_info[srv_idx].radius_port;
+ p1xBssInfo->radius_srv_info[srv_idx].radius_key_len = pMbss->radius_srv_info[srv_idx].radius_key_len;
+ if (pMbss->radius_srv_info[srv_idx].radius_key_len > 0)
+ {
+ NdisMoveMemory(p1xBssInfo->radius_srv_info[srv_idx].radius_key,
+ pMbss->radius_srv_info[srv_idx].radius_key,
+ pMbss->radius_srv_info[srv_idx].radius_key_len);
+ }
+ }
+ }
+
+ p1xBssInfo->ieee8021xWEP = (pMbss->IEEE8021X) ? 1 : 0;
+
+ if (p1xBssInfo->ieee8021xWEP)
+ {
+ /* Default Key index, length and material */
+ keyidx = pMbss->DefaultKeyId;
+ p1xBssInfo->key_index = keyidx;
+
+ /* Determine if the key is valid. */
+ KeyLen = pAd->SharedKey[apidx][keyidx].KeyLen;
+ if (KeyLen == 5 || KeyLen == 13)
+ {
+ p1xBssInfo->key_length = KeyLen;
+ NdisMoveMemory(p1xBssInfo->key_material, pAd->SharedKey[apidx][keyidx].Key, KeyLen);
+ }
+ }
+
+ /* Get NAS-ID per BSS */
+ if (pMbss->NasIdLen > 0)
+ {
+ p1xBssInfo->nasId_len = pMbss->NasIdLen;
+ NdisMoveMemory(p1xBssInfo->nasId, pMbss->NasId, pMbss->NasIdLen);
+ }
+
+ /* get EAPifname */
+ if (pAd->ApCfg.EAPifname_len[apidx] > 0)
+ {
+ pConf->EAPifname_len[apidx] = pAd->ApCfg.EAPifname_len[apidx];
+ NdisMoveMemory(pConf->EAPifname[apidx], pAd->ApCfg.EAPifname[apidx], pAd->ApCfg.EAPifname_len[apidx]);
+ }
+
+ /* get PreAuthifname */
+ if (pAd->ApCfg.PreAuthifname_len[apidx] > 0)
+ {
+ pConf->PreAuthifname_len[apidx] = pAd->ApCfg.PreAuthifname_len[apidx];
+ NdisMoveMemory(pConf->PreAuthifname[apidx], pAd->ApCfg.PreAuthifname[apidx], pAd->ApCfg.PreAuthifname_len[apidx]);
+ }
+
+ }
+
+ wrq->u.data.length = sizeof(DOT1X_CMM_CONF);
+ if (copy_to_user(wrq->u.data.pointer, pConf, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+
+ os_free_mem(NULL, mpool);
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ UI should not call this function, it only used by 802.1x daemon
+ Arguments:
+ pAd Pointer to our adapter
+ wrq Pointer to the ioctl argument
+ ==========================================================================
+*/
+VOID RTMPIoctlRadiusData(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if ((pAd->ApCfg.MBSSID[pObj->ioctl_if].AuthMode == Ndis802_11AuthModeWPA)
+ || (pAd->ApCfg.MBSSID[pObj->ioctl_if].AuthMode == Ndis802_11AuthModeWPA2)
+ || (pAd->ApCfg.MBSSID[pObj->ioctl_if].AuthMode == Ndis802_11AuthModeWPA1WPA2)
+ || (pAd->ApCfg.MBSSID[pObj->ioctl_if].IEEE8021X == TRUE))
+ WpaSend(pAd, (PUCHAR)wrq->u.data.pointer, wrq->u.data.length);
+}
+
+/*
+ ==========================================================================
+ Description:
+ UI should not call this function, it only used by 802.1x daemon
+ Arguments:
+ pAd Pointer to our adapter
+ wrq Pointer to the ioctl argument
+ ==========================================================================
+*/
+VOID RTMPIoctlAddWPAKey(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ NDIS_AP_802_11_KEY *pKey;
+ ULONG KeyIdx;
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR apidx;
+
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ apidx = (UCHAR) pObj->ioctl_if;
+
+
+ pKey = (PNDIS_AP_802_11_KEY) wrq->u.data.pointer;
+
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ if ((pKey->KeyLength == 32) || (pKey->KeyLength == 64))
+ {
+ if ((pEntry = MacTableLookup(pAd, pKey->addr)) != NULL)
+ {
+ INT k_offset = 0;
+
+
+ NdisMoveMemory(pAd->ApCfg.MBSSID[apidx].PMK, pKey->KeyMaterial + k_offset, 32);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlAddWPAKey-IF(ra%d) : Add PMK=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x....\n", apidx,
+ pAd->ApCfg.MBSSID[apidx].PMK[0],pAd->ApCfg.MBSSID[apidx].PMK[1],pAd->ApCfg.MBSSID[apidx].PMK[2],pAd->ApCfg.MBSSID[apidx].PMK[3],
+ pAd->ApCfg.MBSSID[apidx].PMK[4],pAd->ApCfg.MBSSID[apidx].PMK[5],pAd->ApCfg.MBSSID[apidx].PMK[6],pAd->ApCfg.MBSSID[apidx].PMK[7]));
+ }
+ }
+ }
+ else /* Old WEP stuff */
+ {
+ UCHAR CipherAlg;
+ PUCHAR Key;
+
+ if(pKey->KeyLength > 16)
+ return;
+
+ KeyIdx = pKey->KeyIndex & 0x0fffffff;
+
+ if (KeyIdx < 4)
+ {
+ /* it is a shared key */
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ UINT8 Wcid;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlAddWPAKey-IF(ra%d) : Set Group Key\n", apidx));
+
+ /* Default key for tx (shared key) */
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = (UCHAR) KeyIdx;
+
+ /* set key material and key length */
+ if (pKey->KeyLength > 16)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlAddWPAKey-IF(ra%d) : Key length too long %d\n", apidx, pKey->KeyLength));
+ pKey->KeyLength = 16;
+ }
+ pAd->SharedKey[apidx][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
+ NdisMoveMemory(pAd->SharedKey[apidx][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ /* Set Ciper type */
+ if (pKey->KeyLength == 5)
+ pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_WEP64;
+ else
+ pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_WEP128;
+
+ CipherAlg = pAd->SharedKey[apidx][KeyIdx].CipherAlg;
+ Key = pAd->SharedKey[apidx][KeyIdx].Key;
+
+ /* Set Group key material to Asic */
+ AsicAddSharedKeyEntry(pAd, apidx, (UINT8)KeyIdx, &pAd->SharedKey[apidx][KeyIdx]);
+
+ /* Get a specific WCID to record this MBSS key attribute */
+ GET_GroupKey_WCID(pAd, Wcid, apidx);
+
+ RTMPSetWcidSecurityInfo(pAd, apidx,(UINT8)KeyIdx,
+ CipherAlg, Wcid, SHAREDKEYTABLE);
+ }
+ else /* For Pairwise key setting */
+ {
+ pEntry = MacTableLookup(pAd, pKey->addr);
+ if (pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlAddWPAKey-IF(ra%d) : Set Pair-wise Key\n", apidx));
+
+ /* 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,
+ pEntry->apidx,
+ (UINT8)KeyIdx,
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry->Aid,
+ PAIRWISEKEYTABLE);
+
+ }
+ }
+ }
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ UI should not call this function, it only used by 802.1x daemon
+ Arguments:
+ pAd Pointer to our adapter
+ wrq Pointer to the ioctl argument
+ ==========================================================================
+*/
+VOID RTMPIoctlAddPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ UCHAR apidx;
+ NDIS_AP_802_11_KEY *pKey;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ apidx = (UCHAR) pObj->ioctl_if;
+
+ pKey = (PNDIS_AP_802_11_KEY) wrq->u.data.pointer;
+
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA2)
+ {
+ if(pKey->KeyLength == 32)
+ {
+ UCHAR digest[80], PMK_key[20], macaddr[MAC_ADDR_LEN];
+
+ /* Calculate PMKID */
+ NdisMoveMemory(&PMK_key[0], "PMK Name", 8);
+ NdisMoveMemory(&PMK_key[8], pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN);
+ NdisMoveMemory(&PMK_key[14], pKey->addr, MAC_ADDR_LEN);
+ RT_HMAC_SHA1(pKey->KeyMaterial, PMK_LEN, PMK_key, 20, digest, SHA1_DIGEST_SIZE);
+
+ NdisMoveMemory(macaddr, pKey->addr, MAC_ADDR_LEN);
+ RTMPAddPMKIDCache(pAd, apidx, macaddr, digest, pKey->KeyMaterial);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WPA2(pre-auth):(%02x:%02x:%02x:%02x:%02x:%02x)Calc PMKID=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pKey->addr[0],pKey->addr[1],pKey->addr[2],pKey->addr[3],pKey->addr[4],pKey->addr[5],digest[0],digest[1],digest[2],digest[3],digest[4],digest[5]));
+ DBGPRINT(RT_DEBUG_TRACE, ("PMK =%02x:%02x:%02x:%02x-%02x:%02x:%02x:%02x\n",pKey->KeyMaterial[0],pKey->KeyMaterial[1],
+ pKey->KeyMaterial[2],pKey->KeyMaterial[3],pKey->KeyMaterial[4],pKey->KeyMaterial[5],pKey->KeyMaterial[6],pKey->KeyMaterial[7]));
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("Set::RT_OID_802_11_WPA2_ADD_PMKID_CACHE ERROR or is wep key \n"));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPIoctlAddPMKIDCache\n"));
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ UI should not call this function, it only used by 802.1x daemon
+ Arguments:
+ pAd Pointer to our adapter
+ wrq Pointer to the ioctl argument
+ ==========================================================================
+*/
+VOID RTMPIoctlStaticWepCopy(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR MacAddr[MAC_ADDR_LEN];
+ UCHAR apidx;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ apidx = (UCHAR) pObj->ioctl_if;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlStaticWepCopy-IF(ra%d)\n", apidx));
+
+ if (wrq->u.data.length != sizeof(MacAddr))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPIoctlStaticWepCopy: the length isn't match (%d)\n", wrq->u.data.length));
+ return;
+ }
+ else
+ {
+ UINT32 len;
+
+ len = copy_from_user(&MacAddr, wrq->u.data.pointer, wrq->u.data.length);
+ pEntry = MacTableLookup(pAd, MacAddr);
+ if (!pEntry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPIoctlStaticWepCopy: the mac address isn't match\n"));
+ return;
+ }
+ else
+ {
+ UCHAR KeyIdx;
+
+ KeyIdx = pAd->ApCfg.MBSSID[apidx].DefaultKeyId;
+
+ /* need to copy the default shared-key to pairwise key table for this entry in 802.1x mode */
+ if (pAd->SharedKey[apidx][KeyIdx].KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: Can not get Default shared-key (index-%d)\n", KeyIdx));
+ return;
+ }
+ else
+ {
+ pEntry->PairwiseKey.KeyLen = pAd->SharedKey[apidx][KeyIdx].KeyLen;
+ NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[apidx][KeyIdx].Key, pEntry->PairwiseKey.KeyLen);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[apidx][KeyIdx].CipherAlg;
+
+ /* 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,
+ pEntry->apidx,
+ (UINT8)KeyIdx,
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry->Aid,
+ PAIRWISEKEYTABLE);
+ }
+
+ }
+ }
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ UI should not call this function, it only used by 802.1x daemon
+ Arguments:
+ pAd Pointer to our adapter
+ wrq Pointer to the ioctl argument
+ ==========================================================================
+*/
+VOID RTMPIoctlSetIdleTimeout(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ PDOT1X_IDLE_TIMEOUT pIdleTime;
+
+ if (wrq->u.data.length != sizeof(DOT1X_IDLE_TIMEOUT))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : the length is mis-match\n", __FUNCTION__));
+ return;
+ }
+
+ pIdleTime = (PDOT1X_IDLE_TIMEOUT)wrq->u.data.pointer;
+
+ if ((pEntry = MacTableLookup(pAd, pIdleTime->StaAddr)) == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : the entry is empty\n", __FUNCTION__));
+ return;
+ }
+ else
+ {
+ pEntry->NoDataIdleCount = 0;
+ pEntry->StaIdleTimeout = pIdleTime->idle_timeout;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : Update Idle-Timeout(%d) from dot1x daemon\n",
+ __FUNCTION__, pEntry->StaIdleTimeout));
+ }
+
+ return;
+}
+#endif /* DOT1X_SUPPORT */
+
+#ifdef DBG
+
+#ifdef RT65xx
+VOID RTMPAPIoctlBBP32(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ PSTRING this_char;
+ PSTRING value;
+ UINT32 regBBP = 0;
+ PSTRING mpool, msg; /*msg[2048]; */
+ PSTRING arg; /*arg[255]; */
+ PSTRING ptr;
+ INT bbpId;
+ LONG bbpValue;
+ BOOLEAN bIsPrintAllBBP = FALSE, bAllowDump, bCopyMsg;
+ INT argLen;
+
+
+
+ os_alloc_mem(NULL, (UCHAR **)&mpool, sizeof(CHAR)*(MAX_BBP_MSG_SIZE * 2 +256+12));
+ if (mpool == NULL) {
+ return;
+ }
+
+ NdisZeroMemory(mpool, MAX_BBP_MSG_SIZE * 2 +256+12);
+ msg = (PSTRING)((ULONG)(mpool+3) & (ULONG)~0x03);
+ arg = (PSTRING)((ULONG)(msg+MAX_BBP_MSG_SIZE * 2+3) & (ULONG)~0x03);
+
+ bAllowDump = ((wrq->u.data.flags & RTPRIV_IOCTL_FLAG_NODUMPMSG) == RTPRIV_IOCTL_FLAG_NODUMPMSG) ? FALSE : TRUE;
+ bCopyMsg = ((wrq->u.data.flags & RTPRIV_IOCTL_FLAG_NOSPACE) == RTPRIV_IOCTL_FLAG_NOSPACE) ? FALSE : TRUE;
+ argLen = strlen((char *)(wrq->u.data.pointer));
+
+ if (argLen > 0)
+ {
+ NdisMoveMemory(arg, wrq->u.data.pointer, (argLen > 255) ? 255 : argLen);
+ ptr = arg;
+ sprintf(msg, "\n");
+ /* Parsing Read or Write */
+ while ((this_char = strsep((char **)&ptr, ",")) != NULL)
+ {
+ if (!*this_char)
+ continue;
+
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ {
+ /*Read */
+ if (sscanf(this_char, "%x", &(bbpId)) == 1)
+ {
+ if ((bbpId <= 0x2fff) && (bbpId >= 0x2000))
+ {
+ /* according to Andy, Gary, David require. */
+ /* the command bbp shall read BBP register directly for dubug. */
+ RTMP_BBP_IO_READ32(pAdapter, bbpId, &regBBP);
+ sprintf(msg+strlen(msg), "BBP[0x%04x]:%08x \n", bbpId, regBBP);
+ }
+ else
+ {
+ /*Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ /*Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ else
+ { /* Write */
+ if ((sscanf(this_char, "%x", &(bbpId)) == 1) && (sscanf(value, "%lx", &(bbpValue)) == 1))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("bbpID=%04x, value=0x%lx\n", bbpId, bbpValue));
+ if ((bbpId <= 0x2fff) && (bbpId >= 0x2000))
+ {
+ /* according to Andy, Gary, David require. */
+ /* the command bbp shall read/write BBP register directly for dubug. */
+ RTMP_BBP_IO_WRITE32(pAdapter, bbpId, bbpValue);
+ /*Read it back for showing */
+ RTMP_BBP_IO_READ32(pAdapter, bbpId, &regBBP);
+ sprintf(msg+strlen(msg), "BBP[0x%04x]:%08x\n", bbpId, regBBP);
+ }
+ else
+ {
+ /* Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ /* Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ else
+ bIsPrintAllBBP = TRUE;
+
+ if (bIsPrintAllBBP)
+ {
+ static RTMP_REG_PAIR bbp_regs[]={
+ {CORE_R0, CORE_R44},
+ {IBI_R0, IBI_R11},
+ {AGC1_R0, AGC1_R63},
+ {TXC_R1, TXC_R1},
+ {RXC_R1, RXC_R4},
+ {TXO_R8, TXO_R8},
+ {TXBE_R0, TXBE_R17},
+ {RXFE_R0, RXFE_R4},
+ {RXO_R13, RXO_R29},
+ };
+ UINT32 reg, i;
+
+ memset(msg, 0x00, MAX_BBP_MSG_SIZE * 2);
+ sprintf(msg, "\n");
+ for (i = 0; i < sizeof(bbp_regs) / sizeof(RTMP_REG_PAIR); i++)
+ {
+ for (reg = bbp_regs[i].Register; reg <= bbp_regs[i].Value; reg += 4)
+ {
+ RTMP_BBP_IO_READ32(pAdapter, reg, &regBBP);
+ if (strlen(msg) >= (MAX_BBP_MSG_SIZE * 2 - 25))
+ break;
+ sprintf(msg+strlen(msg), "BBP[0x%04x]:%08x\n", reg, regBBP);
+ if (bbpId%5 == 4)
+ sprintf(msg+strlen(msg), "\n");
+ }
+ }
+ }
+
+#ifdef LINUX
+ 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__));
+ }
+#endif /* LINUX */
+
+ if (!bAllowDump)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s\n", msg));
+ }
+
+ os_free_mem(NULL, mpool);
+ if (!bAllowDump)
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlBBP\n\n"));
+}
+#endif /* RT65xx */
+
+
+/*
+ ==========================================================================
+ Description:
+ Read / Write BBP
+Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 bbp ==> read all BBP
+ 2.) iwpriv ra0 bbp 1 ==> read BBP where RegID=1
+ 3.) iwpriv ra0 bbp 1=10 ==> write BBP R1=0x10
+ ==========================================================================
+*/
+VOID RTMPAPIoctlBBP(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ PSTRING this_char;
+ PSTRING value;
+ UCHAR regBBP = 0;
+ PSTRING mpool, msg; /*msg[2048]; */
+ PSTRING arg; /*arg[255]; */
+ PSTRING ptr;
+ INT bbpId;
+ LONG bbpValue;
+ BOOLEAN bIsPrintAllBBP = FALSE, bAllowDump, bCopyMsg;
+ INT argLen;
+
+
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAdapter)) {
+ RTMPAPIoctlBBP32(pAdapter, wrq);
+ return;
+ }
+#endif /* RT65xx */
+
+ os_alloc_mem(NULL, (UCHAR **)&mpool, sizeof(CHAR)*(MAX_BBP_MSG_SIZE+256+12));
+ if (mpool == NULL) {
+ return;
+ }
+
+ NdisZeroMemory(mpool, MAX_BBP_MSG_SIZE+256+12);
+ msg = (PSTRING)((ULONG)(mpool+3) & (ULONG)~0x03);
+ arg = (PSTRING)((ULONG)(msg+MAX_BBP_MSG_SIZE+3) & (ULONG)~0x03);
+
+ bAllowDump = ((wrq->u.data.flags & RTPRIV_IOCTL_FLAG_NODUMPMSG) == RTPRIV_IOCTL_FLAG_NODUMPMSG) ? FALSE : TRUE;
+ bCopyMsg = ((wrq->u.data.flags & RTPRIV_IOCTL_FLAG_NOSPACE) == RTPRIV_IOCTL_FLAG_NOSPACE) ? FALSE : TRUE;
+ argLen = strlen((char *)(wrq->u.data.pointer));
+
+
+ if (argLen > 0)
+ {
+ NdisMoveMemory(arg, wrq->u.data.pointer, (argLen > 255) ? 255 : argLen);
+ ptr = arg;
+ sprintf(msg, "\n");
+ /* Parsing Read or Write */
+ while ((this_char = strsep((char **)&ptr, ",")) != NULL)
+ {
+ if (!*this_char)
+ continue;
+
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { /*Read */
+ if (sscanf(this_char, "%d", &(bbpId)) == 1)
+ {
+ if (bbpId <= pAdapter->chipCap.MaxNumOfBbpId)
+ {
+#ifdef RALINK_ATE
+ /*
+ In RT2860 ATE mode, we do not load 8051 firmware.
+ We must access BBP directly.
+ For RT2870 ATE mode, ATE_BBP_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
+ */
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ /* Sync with QA for comparation */
+ sprintf(msg+strlen(msg), "%03d = %02X\n", bbpId, regBBP);
+ }
+ else
+#endif /* RALINK_ATE */
+ {
+ /* according to Andy, Gary, David require. */
+ /* the command bbp shall read BBP register directly for dubug. */
+ BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ sprintf(msg+strlen(msg), "R%02d[0x%02x]:%02X ", bbpId, bbpId, regBBP);
+ }
+ }
+ else
+ {
+ /*Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ /*Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ else
+ { /* Write */
+ if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%lx", &(bbpValue)) == 1))
+ {
+ if (bbpId <= pAdapter->chipCap.MaxNumOfBbpId)
+ {
+#ifdef RALINK_ATE
+ /*
+ In RT2860 ATE mode, we do not load 8051 firmware.
+ We must access BBP directly.
+ For RT2870 ATE mode, ATE_BBP_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
+ */
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
+
+ /*Read it back for showing */
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ /* Sync with QA for comparation */
+ sprintf(msg+strlen(msg), "%03d = %02X\n", bbpId, regBBP);
+ }
+ else
+#endif /* RALINK_ATE */
+ {
+ /* according to Andy, Gary, David require. */
+ /* the command bbp shall read/write BBP register directly for dubug. */
+ BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
+ /*Read it back for showing */
+ BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", bbpId, bbpId, regBBP);
+ }
+ }
+ else
+ {
+ /* Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ /* Invalid parametes, so default printk all bbp */
+ bIsPrintAllBBP = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ else
+ bIsPrintAllBBP = TRUE;
+
+ if (bIsPrintAllBBP)
+ {
+ memset(msg, 0x00, MAX_BBP_MSG_SIZE);
+ sprintf(msg, "\n");
+ for (bbpId = 0; bbpId <= pAdapter->chipCap.MaxNumOfBbpId; bbpId++)
+ {
+#ifdef RALINK_ATE
+ /*
+ In RT2860 ATE mode, we do not load 8051 firmware.
+ We must access BBP directly.
+ For RT2870 ATE mode, ATE_BBP_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
+ */
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ /* Sync with QA for comparation */
+ sprintf(msg+strlen(msg), "%03d = %02X\n", bbpId, regBBP);
+ }
+ else
+#endif /* RALINK_ATE */
+ {
+ /* according to Andy, Gary, David require. */
+ /* the command bbp shall read/write BBP register directly for dubug. */
+ BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X ", bbpId, bbpId, regBBP);
+ if (bbpId%5 == 4)
+ sprintf(msg+strlen(msg), "\n");
+ }
+ }
+ }
+
+#ifdef LINUX
+ 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__));
+ }
+#endif /* LINUX */
+
+ if (!bAllowDump)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Dump BBP msg[%d]=\n", (UINT32)strlen(msg)));
+ DBGPRINT(RT_DEBUG_OFF, ("%s\n", msg));
+ }
+
+/* kfree(mpool); */
+ os_free_mem(NULL, mpool);
+ if (!bAllowDump)
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlBBP\n\n"));
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Read / Write MAC
+Arguments:
+ pAdapter 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 RTMPAPIoctlMAC(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ PSTRING this_char, value;
+ INT j = 0, k = 0;
+ PSTRING mpool, msg;
+ PSTRING arg, ptr;
+ UINT32 macAddr = 0;
+ UCHAR temp[16];
+ STRING temp2[16];
+ UINT32 macValue;
+ BOOLEAN bIsPrintAllMAC = FALSE, bFromUI;
+
+
+
+ os_alloc_mem(NULL, (UCHAR **)&mpool, sizeof(CHAR)*(4096+256+12));
+ if (!mpool)
+ return;
+
+ bFromUI = ((wrq->u.data.flags & RTPRIV_IOCTL_FLAG_UI) == RTPRIV_IOCTL_FLAG_UI) ? TRUE : FALSE;
+
+ msg = (PSTRING)((ULONG)(mpool+3) & (ULONG)~0x03);
+ arg = (PSTRING)((ULONG)(msg+4096+3) & (ULONG)~0x03);
+
+ memset(msg, 0x00, 4096);
+ memset(arg, 0x00, 256);
+ //DBGPRINT(RT_DEBUG_OFF, ("%s():wrq->u.data.length=%d, wrq->u.data.pointer=%s!\n", __FUNCTION__, wrq->u.data.length, wrq->u.data.pointer));
+ if ((wrq->u.data.length > 1)
+ )
+ {
+ NdisMoveMemory(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ ptr = arg;
+ sprintf(msg, "\n");
+ /*Parsing Read or Write */
+ while ((this_char = strsep((char **)&ptr, ",")) != NULL)
+ {
+ if (!*this_char)
+ continue;
+
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { /*Read */
+ /* Sanity check */
+ if(strlen(this_char) > 4)
+ break;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ goto done;
+ }
+
+ /* Mac register */
+ 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);
+ if (!bFromUI)
+ DBGPRINT(RT_DEBUG_INFO, ("MacReg=0x%x, MacValue=0x%x\n", macAddr, macValue));
+ sprintf(msg+strlen(msg), "[0x%04x]:%08x ", macAddr , macValue);
+ }
+ else
+ {
+ /*Invalid parametes, so default printk all bbp */
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*Write */
+ NdisMoveMemory(&temp2, value, strlen(value));
+ temp2[strlen(value)] = '\0';
+
+ /* Sanity check */
+ if((strlen(this_char) > 4) || strlen(temp2) > 8)
+ break;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ goto done;
+ }
+
+ j = strlen(temp2);
+ while(j-- > 0)
+ {
+ if(temp2[j] > 'f' || temp2[j] < '0')
+ goto done;
+ }
+
+ /* MAC register */
+ 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 R66 tuning, 0: disable R66 tuning */
+ if (macValue & 0x000000ff)
+ {
+ pAd->BbpTuning.bEnable = TRUE;
+ DBGPRINT(RT_DEBUG_ERROR, ("turn on R17 tuning\n"));
+ }
+ else
+ {
+ UCHAR R66;
+ pAd->BbpTuning.bEnable = FALSE;
+ R66 = 0x26 + GET_LNA_GAIN(pAd);
+ /* todo rtmp_bbp_set_agc(pAd, (0x26 + GET_LNA_GAIN(pAd)), RX_CHAIN_ALL); */
+ if (!bFromUI)
+ DBGPRINT(RT_DEBUG_OFF, ("turn off R66 tuning, restore to 0x%02x\n", R66));
+ }
+ return;
+ }
+ if (!bFromUI)
+ DBGPRINT(RT_DEBUG_INFO, ("MacAddr=%02x, MacValue=0x%x\n", macAddr, macValue));
+
+ RTMP_IO_WRITE32(pAd, macAddr, macValue);
+
+ sprintf(msg+strlen(msg), "[0x%04x]:%08x ", macAddr, macValue);
+ }
+ }
+ }
+ }
+ else
+ {
+ bIsPrintAllMAC = TRUE;
+ }
+
+
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+#ifdef LINUX
+ if (bIsPrintAllMAC)
+ {
+ UINT32 *pBufMac = NULL, *pBuf;
+ UINT32 AddrStart = 0x1000, AddrEnd = 0x1800;
+ UINT32 IdAddr;
+
+#if defined(RT65xx) || defined(MT7601)
+ if (IS_RT65XX(pAd) || IS_MT7601(pAd))
+ {
+ AddrStart = 0x0; AddrEnd = 0x1800;
+ }
+#endif /* defined(RT65xx) || defined(MT7601) */
+
+ ASSERT((AddrEnd >= AddrStart));
+ /* *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);
+ }
+ }
+ else
+ {
+ /* Copy the information into the user buffer */
+ 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__));
+ }
+ }
+#endif /* LINUX */
+
+
+
+
+done:
+/* kfree(mpool); */
+ os_free_mem(NULL, mpool);
+ if (!bFromUI)
+ DBGPRINT(RT_DEBUG_INFO, ("<==RTMPIoctlMAC\n\n"));
+}
+
+#ifdef RLT_RF
+VOID RTMPAPIoctlRF(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ PSTRING this_char;
+ PSTRING value;
+ UCHAR regRF = 0, rf_bank = 0;
+ PSTRING mpool, msg;
+ PSTRING arg;
+ PSTRING ptr;
+ INT rfId, maxRFIdx, bank_Id;
+ LONG rfValue;
+ BOOLEAN bIsPrintAllRF = TRUE, bFromUI;
+ INT memLen = sizeof(CHAR) * (2048+256+12);
+ INT argLen;
+
+ maxRFIdx = pAdapter->chipCap.MaxNumOfRfId;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==>RTMPIoctlRF (maxRFIdx = %d)\n", maxRFIdx));
+
+ memLen = 12*(maxRFIdx+1)*MAC_RF_BANK;
+ os_alloc_mem(NULL, (UCHAR **)&mpool, memLen);
+ if (mpool == NULL) {
+ return;
+ }
+
+ bFromUI = ((wrq->u.data.flags & RTPRIV_IOCTL_FLAG_UI) == RTPRIV_IOCTL_FLAG_UI) ? TRUE : FALSE;
+
+ NdisZeroMemory(mpool, memLen);
+ msg = (PSTRING)((ULONG)(mpool+3) & (ULONG)~0x03);
+ arg = (PSTRING)((ULONG)(msg+2048+3) & (ULONG)~0x03);
+ argLen = strlen((char *)(wrq->u.data.pointer));
+ if (bIsPrintAllRF)
+ {
+ RTMPZeroMemory(msg, memLen);
+ sprintf(msg, "\n");
+ for (bank_Id = 0; bank_Id <= MAC_RF_BANK; bank_Id++)
+ {
+ if (IS_RT6590(pAdapter))
+ {
+ if ((bank_Id <=4) && (bank_Id >=1))
+ continue;
+ }
+ for (rfId = 0; rfId <= maxRFIdx; rfId++)
+ {
+ rlt_rf_read(pAdapter, bank_Id, rfId, &regRF);
+ sprintf(msg+strlen(msg), "%d %03d %02X\n", bank_Id, rfId, regRF);
+ }
+ }
+ RtmpDrvAllRFPrint(NULL, msg, strlen(msg));
+ /* Copy the information into the user buffer */
+
+#ifdef LINUX
+ wrq->u.data.length = strlen("Dump to RFDump.txt");
+ if (copy_to_user(wrq->u.data.pointer, "Dump to RFDump.txt", wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+#endif /* LINUX */
+ }
+
+ os_free_mem(NULL, mpool);
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n"));
+}
+#endif /* RLT_RF */
+
+#endif /*#ifdef DBG */
+
+/*
+ ==========================================================================
+ Description:
+ Read / Write E2PROM
+Arguments:
+ pAdapter 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 RTMPAPIoctlE2PROM(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ PSTRING this_char;
+ PSTRING value;
+ INT j = 0, k = 0;
+ PSTRING mpool, msg;/*msg[1024]; */
+ PSTRING arg; /*arg[255]; */
+ PSTRING ptr;
+ USHORT eepAddr = 0;
+ UCHAR temp[16];
+ STRING temp2[16];
+ USHORT eepValue;
+ BOOLEAN bIsPrintAllE2PROM = FALSE;
+
+/* mpool = (PSTRING)kmalloc(sizeof(CHAR)*(4096+256+12), MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&mpool, sizeof(CHAR)*(4096+256+12));
+
+ if (mpool == NULL) {
+ return;
+ }
+
+ msg = (PSTRING)((ULONG)(mpool+3) & (ULONG)~0x03);
+ arg = (PSTRING)((ULONG)(msg+4096+3) & (ULONG)~0x03);
+
+
+ memset(msg, 0x00, 4096);
+ memset(arg, 0x00, 256);
+
+ if (
+#ifdef LINUX
+ (wrq->u.data.length > 1) /* If no parameter, dump all e2p. */
+#endif /* LINUX */
+ )
+ {
+ NdisMoveMemory(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ ptr = arg;
+ sprintf(msg, "\n");
+ /*Parsing Read or Write */
+ while ((this_char = strsep((char **)&ptr, ",")) != NULL)
+ {
+ if (!*this_char)
+ continue;
+
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { /*Read */
+
+ /* Sanity check */
+ if(strlen(this_char) > 4)
+ break;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ goto done; /*return; */
+ }
+
+ /* 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(pAdapter, eepAddr, eepValue);
+ sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
+ }
+ else
+ {/*Invalid parametes, so default printk all bbp */
+ break;
+ }
+ }
+ }
+ else
+ { /*Write */
+ NdisMoveMemory(&temp2, value, strlen(value));
+ temp2[strlen(value)] = '\0';
+
+ /* Sanity check */
+ if((strlen(this_char) > 4) || strlen(temp2) > 8)
+ break;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ goto done; /* return; */
+ }
+ j = strlen(temp2);
+ while(j-- > 0)
+ {
+ if(temp2[j] > 'f' || temp2[j] < '0')
+ goto done; /* return; */
+ }
+
+ /* 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(pAdapter, eepAddr, eepValue);
+ sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
+ }
+ }
+ }
+ else
+ {
+ bIsPrintAllE2PROM = TRUE;
+ }
+
+ if (bIsPrintAllE2PROM)
+ {
+ sprintf(msg, "\n");
+
+ /* E2PROM Registers */
+ for (eepAddr = 0x00; eepAddr < 0x200; eepAddr += 2)
+ {
+ RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
+ sprintf(msg+strlen(msg), "[0x%04X]:%04X ", eepAddr , eepValue);
+ if ((eepAddr & 0x6) == 0x6)
+ sprintf(msg+strlen(msg), "\n");
+ }
+ }
+
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+ /* Copy the information into the user buffer */
+
+ AP_E2PROM_IOCTL_PostCtrl(wrq, msg);
+
+done:
+/* kfree(mpool); */
+ os_free_mem(NULL, mpool);
+ if (wrq->u.data.flags != RT_OID_802_11_HARDWARE_REGISTER)
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
+}
+
+
+//#define ENHANCED_STAT_DISPLAY // Display PER and PLR statistics
+
+
+/*
+ ==========================================================================
+ Description:
+ Read statistics counter
+Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 stat 0 ==> Read statistics counter
+ ==========================================================================
+*/
+VOID RTMPIoctlStatistics(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ INT Status;
+ PSTRING msg;
+#ifdef WSC_AP_SUPPORT
+ UCHAR idx = 0;
+#endif /* WSC_AP_SUPPORT */
+ ULONG txCount = 0;
+#ifdef ENHANCED_STAT_DISPLAY
+ ULONG per, plr;
+ INT i;
+#endif
+#ifdef RTMP_EFUSE_SUPPORT
+ UINT efusefreenum=0;
+#endif /* RTMP_EFUSE_SUPPORT */
+
+/* msg = (PSTRING)kmalloc(sizeof(CHAR)*(2048), MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&msg, sizeof(CHAR)*(2048));
+ if (msg == NULL) {
+ return;
+ }
+
+
+ memset(msg, 0x00, 1600);
+ sprintf(msg, "\n");
+
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ txCount = pAd->ate.TxDoneCount;
+ }
+ else
+#endif /* RALINK_ATE */
+ {
+ txCount = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
+ }
+
+ sprintf(msg+strlen(msg), "Tx success = %ld\n", txCount);
+#ifdef ENHANCED_STAT_DISPLAY
+ per = txCount==0? 0: 1000*(pAd->WlanCounters.RetryCount.u.LowPart+pAd->WlanCounters.FailedCount.u.LowPart)/(pAd->WlanCounters.RetryCount.u.LowPart+pAd->WlanCounters.FailedCount.u.LowPart+txCount);
+ sprintf(msg+strlen(msg), "Tx retry count = %ld, PER=%ld.%1ld%%\n",
+ (ULONG)pAd->WlanCounters.RetryCount.u.LowPart,
+ per/10, per % 10);
+ plr = txCount==0? 0: 10000*pAd->WlanCounters.FailedCount.u.LowPart/(pAd->WlanCounters.FailedCount.u.LowPart+txCount);
+ sprintf(msg+strlen(msg), "Tx fail to Rcv ACK after retry = %ld, PLR=%ld.%02ld%%\n",
+ (ULONG)pAd->WlanCounters.FailedCount.u.LowPart, plr/100, plr%100);
+
+ sprintf(msg+strlen(msg), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
+ per = pAd->WlanCounters.ReceivedFragmentCount.u.LowPart==0? 0: 1000*(pAd->WlanCounters.FCSErrorCount.u.LowPart)/(pAd->WlanCounters.FCSErrorCount.u.LowPart+pAd->WlanCounters.ReceivedFragmentCount.u.LowPart);
+ sprintf(msg+strlen(msg), "Rx with CRC = %ld, PER=%ld.%1ld%%\n",
+ (ULONG)pAd->WlanCounters.FCSErrorCount.u.LowPart, per/10, per % 10);
+ sprintf(msg+strlen(msg), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
+ sprintf(msg+strlen(msg), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.u.LowPart);
+
+ sprintf(msg+strlen(msg), "False CCA = %ld\n", (ULONG)pAd->RalinkCounters.FalseCCACnt);
+#else
+ sprintf(msg+strlen(msg), "Tx retry count = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.u.LowPart);
+ sprintf(msg+strlen(msg), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.u.LowPart);
+ sprintf(msg+strlen(msg), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.u.LowPart);
+ sprintf(msg+strlen(msg), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.u.LowPart);
+
+ sprintf(msg+strlen(msg), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
+ sprintf(msg+strlen(msg), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.u.LowPart);
+ sprintf(msg+strlen(msg), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
+ sprintf(msg+strlen(msg), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.u.LowPart);
+
+ sprintf(msg+strlen(msg), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
+#endif /* ENHANCED_STAT_DISPLAY */
+
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ if (pAd->ate.RxAntennaSel == 0)
+ {
+ sprintf(msg+strlen(msg), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ sprintf(msg+strlen(msg), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
+ sprintf(msg+strlen(msg), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
+ }
+ else
+ {
+ sprintf(msg+strlen(msg), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ }
+ }
+ else
+#endif /* RALINK_ATE */
+ {
+#ifdef ENHANCED_STAT_DISPLAY
+ sprintf(msg+strlen(msg), "RSSI = %ld %ld %ld\n",
+ (LONG)(pAd->ApCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta),
+ (LONG)(pAd->ApCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta),
+ (LONG)(pAd->ApCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
+
+ /* Display Last Rx Rate and BF SNR of first Associated entry in MAC table */
+ if (pAd->MacTab.Size > 0)
+ {
+ static char *phyMode[5] = {"CCK", "OFDM", "MM", "GF", "VHT"};
+#ifdef RT65xx
+ static char *bw[3] = {"20M", "40M", "80M"};
+#endif /* RT65xx */
+
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &(pAd->MacTab.Content[i]);
+ if (IS_ENTRY_CLIENT(pEntry) && pEntry->Sst==SST_ASSOC)
+ {
+ UINT32 lastRxRate = pEntry->LastRxRate;
+#ifndef RT65xx
+ sprintf(msg+strlen(msg), "Last RX Rate = MCS %d, %2dM, %cGI, %s%s\n",
+ lastRxRate & 0x7F, ((lastRxRate>>7) & 0x1)? 40: 20,
+ ((lastRxRate>>8) & 0x1)? 'S': 'L',
+ phyMode[(lastRxRate>>14) & 0x3],
+ ((lastRxRate>>9) & 0x3)? ", STBC": " ");
+#else
+ sprintf(msg+strlen(msg), "Last RX Rate = MCS %d, %s, %cGI, %s%s\n",
+ lastRxRate & 0x7F,
+ bw[((lastRxRate>>7) & 0x3)],
+ ((lastRxRate>>9) & 0x1)? 'S': 'L',
+ phyMode[(lastRxRate>>14) & 0x7],
+ ((lastRxRate>>10) & 0x3)? ", STBC": " ");
+#endif
+
+ break;
+ }
+ }
+ }
+#else
+ sprintf(msg+strlen(msg), "RSSI-A = %ld\n", (LONG)(pAd->ApCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ sprintf(msg+strlen(msg), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ApCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
+ sprintf(msg+strlen(msg), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ApCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
+#endif /* ENHANCED_STAT_DISPLAY */
+ }
+
+#ifdef WSC_AP_SUPPORT
+ sprintf(msg+strlen(msg), "WPS Information:\n");
+ {
+ for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++)
+ {
+ /* display pin code */
+ if (pAd->ApCfg.MBSSID[idx].WscControl.WscEnrolleePinCodeLen == 8)
+ sprintf(msg+strlen(msg), "Enrollee PinCode(ra%d) %08u\n", idx, pAd->ApCfg.MBSSID[idx].WscControl.WscEnrolleePinCode);
+ else
+ sprintf(msg+strlen(msg), "Enrollee PinCode(ra%d) %04u\n", idx, pAd->ApCfg.MBSSID[idx].WscControl.WscEnrolleePinCode);
+ }
+ }
+#ifdef APCLI_SUPPORT
+ sprintf(msg+strlen(msg), "\n");
+ if (pAd->ApCfg.ApCliTab[0].WscControl.WscEnrolleePinCodeLen == 8)
+ sprintf(msg+strlen(msg), "Enrollee PinCode(ApCli0) %08u\n", pAd->ApCfg.ApCliTab[0].WscControl.WscEnrolleePinCode);
+ else
+ sprintf(msg+strlen(msg), "Enrollee PinCode(ApCli0) %04u\n", pAd->ApCfg.ApCliTab[0].WscControl.WscEnrolleePinCode);
+ sprintf(msg+strlen(msg), "Ap Client WPS Profile Count = %d\n", pAd->ApCfg.ApCliTab[0].WscControl.WscProfile.ProfileCnt);
+ for (idx = 0; idx < pAd->ApCfg.ApCliTab[0].WscControl.WscProfile.ProfileCnt ; idx++)
+ {
+ PWSC_CREDENTIAL pCredential = &pAd->ApCfg.ApCliTab[0].WscControl.WscProfile.Profile[idx];
+ sprintf(msg+strlen(msg), "Profile[%d]:\n", idx);
+ sprintf(msg+strlen(msg), "SSID = %s\n", pCredential->SSID.Ssid);
+ sprintf(msg+strlen(msg), "AuthType = %s\n", WscGetAuthTypeStr(pCredential->AuthType));
+ sprintf(msg+strlen(msg), "EncrypType = %s\n", WscGetEncryTypeStr(pCredential->EncrType));
+ sprintf(msg+strlen(msg), "KeyIndex = %d\n", pCredential->KeyIndex);
+ if (pCredential->KeyLength != 0)
+ {
+ sprintf(msg+strlen(msg), "Key = %s\n", pCredential->Key);
+ }
+ }
+ sprintf(msg+strlen(msg), "\n");
+#endif /* APCLI_SUPPORT */
+#endif /* WSC_AP_SUPPORT */
+#ifdef RTMP_EFUSE_SUPPORT
+ if (pAd->bUseEfuse == FALSE && pAd->bFroceEEPROMBuffer == FALSE)
+ {
+ ;
+ }
+ else
+ {
+ eFuseGetFreeBlockCount(pAd, &efusefreenum);
+ sprintf(msg+strlen(msg), "efuseFreeNumber = %d\n", efusefreenum);
+ }
+#endif /* RTMP_EFUSE_SUPPORT */
+ /* 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);
+
+ os_free_mem(NULL, msg);
+/* kfree(msg); */
+
+#if defined(TXBF_SUPPORT) && defined(ENHANCED_STAT_DISPLAY)
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug code to display BF statistics */
+ if (pAd->CommonCfg.DebugFlags & DBF_SHOW_BF_STATS)
+ {
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++) {
+ PMAC_TABLE_ENTRY pEntry = &(pAd->MacTab.Content[i]);
+ COUNTER_TXBF *pCnt;
+ ULONG totalNBF, totalEBF, totalIBF, totalTx, totalRetry, totalSuccess;
+
+ if (!IS_ENTRY_CLIENT(pEntry) || pEntry->Sst!=SST_ASSOC)
+ continue;
+
+ pCnt = &pEntry->TxBFCounters;
+
+ totalNBF = pCnt->TxSuccessCount + pCnt->TxFailCount;
+ totalEBF = pCnt->ETxSuccessCount + pCnt->ETxFailCount;
+ totalIBF = pCnt->ITxSuccessCount + pCnt->ITxFailCount;
+
+ totalTx = totalNBF + totalEBF + totalIBF;
+ totalRetry = pCnt->TxRetryCount + pCnt->ETxRetryCount + pCnt->ITxRetryCount;
+ totalSuccess = pCnt->TxSuccessCount + pCnt->ETxSuccessCount + pCnt->ITxSuccessCount;
+
+ DBGPRINT(RT_DEBUG_OFF, ("MacTable[%d] Success Retry/PER Fail/PLR\n", i) );
+ if (totalTx==0) {
+ DBGPRINT(RT_DEBUG_OFF, (" Total = 0\n") );
+ continue;
+ }
+
+ if (totalNBF!=0) {
+ DBGPRINT(RT_DEBUG_OFF, (" NonBF (%3lu%%): %7lu %7lu (%2lu%%) %5lu (%1lu%%)\n",
+ 100*totalNBF/totalTx, pCnt->TxSuccessCount,
+ pCnt->TxRetryCount, 100*pCnt->TxRetryCount/(pCnt->TxSuccessCount+pCnt->TxRetryCount),
+ pCnt->TxFailCount, 100*pCnt->TxFailCount/totalNBF) );
+ }
+
+ if (totalEBF!=0) {
+ DBGPRINT(RT_DEBUG_OFF, (" ETxBF (%3lu%%): %7lu %7lu (%2lu%%) %5lu (%1lu%%)\n",
+ 100*totalEBF/totalTx, pCnt->ETxSuccessCount,
+ pCnt->ETxRetryCount, 100*pCnt->ETxRetryCount/(pCnt->ETxSuccessCount+pCnt->ETxRetryCount),
+ pCnt->ETxFailCount, 100*pCnt->ETxFailCount/totalEBF) );
+ }
+
+ if (totalIBF!=0) {
+ DBGPRINT(RT_DEBUG_OFF, (" ITxBF (%3lu%%): %7lu %7lu (%2lu%%) %5lu (%1lu%%)\n",
+ 100*totalIBF/totalTx, pCnt->ITxSuccessCount,
+ pCnt->ITxRetryCount, 100*pCnt->ITxRetryCount/(pCnt->ITxSuccessCount+pCnt->ITxRetryCount),
+ pCnt->ITxFailCount, 100*pCnt->ITxFailCount/totalIBF) );
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, (" Total %7lu %7lu (%2lu%%) %5lu (%1lu%%)\n",
+ totalSuccess, totalRetry, 100*totalRetry/(totalSuccess + totalRetry),
+ pCnt->TxFailCount+pCnt->ETxFailCount+pCnt->ITxFailCount,
+ 100*(pCnt->TxFailCount+pCnt->ETxFailCount+pCnt->ITxFailCount)/totalTx) );
+ }
+ }
+#endif /* DBG_CTRL_SUPPORT */
+#endif /* defined(TXBF_SUPPORT) && defined(ENHANCED_STAT_DISPLAY) */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlStatistics\n"));
+}
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Get Block ACK Table
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 get_ba_table
+ 3.) UI needs to prepare at least 4096bytes to get the results
+ ==========================================================================
+*/
+VOID RTMPIoctlQueryBaTable(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ /*char *msg; */
+ UCHAR TotalEntry, i, j, index;
+ QUERYBA_TABLE *BAT;
+
+ BAT = vmalloc(sizeof(QUERYBA_TABLE));
+
+ RTMPZeroMemory(BAT, sizeof(QUERYBA_TABLE));
+
+ TotalEntry = pAd->MacTab.Size;
+ index = 0;
+ for (i=0; ((i < MAX_LEN_OF_MAC_TABLE) && (TotalEntry > 0)); i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+
+ if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC) && (pEntry->TXBAbitmap))
+ {
+ NdisMoveMemory(BAT->BAOriEntry[index].MACAddr, pEntry->Addr, 6);
+ for (j=0;j<8;j++)
+ {
+ if (pEntry->BAOriWcidArray[j] != 0)
+ BAT->BAOriEntry[index].BufSize[j] = pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]].BAWinSize;
+ else
+ BAT->BAOriEntry[index].BufSize[j] = 0;
+ }
+
+ TotalEntry--;
+ index++;
+ BAT->OriNum++;
+ }
+ }
+
+ TotalEntry = pAd->MacTab.Size;
+ index = 0;
+ for (i=0; ((i < MAX_LEN_OF_MAC_TABLE) && (TotalEntry > 0)); i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+
+ if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC) && (pEntry->RXBAbitmap))
+ {
+ NdisMoveMemory(BAT->BARecEntry[index].MACAddr, pEntry->Addr, 6);
+ BAT->BARecEntry[index].BaBitmap = (UCHAR)pEntry->RXBAbitmap;
+ for (j = 0; j < 8; j++)
+ {
+ if (pEntry->BARecWcidArray[j] != 0)
+ BAT->BARecEntry[index].BufSize[j] = pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]].BAWinSize;
+ else
+ BAT->BARecEntry[index].BufSize[j] = 0;
+ }
+
+ TotalEntry--;
+ index++;
+ BAT->RecNum++;
+ }
+ }
+
+ wrq->u.data.length = sizeof(QUERYBA_TABLE);
+
+ if (copy_to_user(wrq->u.data.pointer, BAT, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+
+ vfree(BAT);
+
+}
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef APCLI_SUPPORT
+INT Set_ApCli_Enable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT Enable;
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+
+ Enable = simple_strtol(arg, 0, 16);
+
+ pAd->ApCfg.ApCliTab[ifIndex].Enable = (Enable > 0) ? TRUE : FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) Set_ApCli_Enable_Proc::(enable = %d)\n", ifIndex, pAd->ApCfg.ApCliTab[ifIndex].Enable));
+
+ ApCliIfDown(pAd);
+
+ return TRUE;
+}
+
+INT Set_ApCli_Ssid_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+ BOOLEAN apcliEn;
+ INT success = FALSE;
+ /*UCHAR keyMaterial[40]; */
+ UCHAR PskKey[100];
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+
+ if(strlen(arg) <= MAX_LEN_OF_SSID)
+ {
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ /* bring apcli interface down first */
+ if(apcliEn == TRUE )
+ {
+ pAd->ApCfg.ApCliTab[ifIndex].Enable = FALSE;
+ ApCliIfDown(pAd);
+ }
+
+ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgSsid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgSsid, arg, strlen(arg));
+ pAd->ApCfg.ApCliTab[ifIndex].CfgSsidLen = (UCHAR)strlen(arg);
+ success = TRUE;
+
+ /* Upadte PMK and restart WPAPSK state machine for ApCli link */
+ if (((pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
+ pAd->ApCfg.ApCliTab[ifIndex].PSKLen > 0)
+ {
+ NdisZeroMemory(PskKey, 100);
+ NdisMoveMemory(PskKey, pAd->ApCfg.ApCliTab[ifIndex].PSK, pAd->ApCfg.ApCliTab[ifIndex].PSKLen);
+
+ RT_CfgSetWPAPSKKey(pAd, (PSTRING)PskKey,
+ pAd->ApCfg.ApCliTab[ifIndex].PSKLen,
+ (PUCHAR)pAd->ApCfg.ApCliTab[ifIndex].CfgSsid,
+ pAd->ApCfg.ApCliTab[ifIndex].CfgSsidLen,
+ pAd->ApCfg.ApCliTab[ifIndex].PMK);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) Set_ApCli_Ssid_Proc::(Len=%d,Ssid=%s)\n", ifIndex,
+ pAd->ApCfg.ApCliTab[ifIndex].CfgSsidLen, pAd->ApCfg.ApCliTab[ifIndex].CfgSsid));
+
+ pAd->ApCfg.ApCliTab[ifIndex].Enable = apcliEn;
+ }
+ else
+ success = FALSE;
+
+ return success;
+}
+
+
+INT Set_ApCli_Bssid_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+ PSTRING value;
+ UCHAR ifIndex;
+ BOOLEAN apcliEn;
+ POS_COOKIE pObj;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+
+ apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable;
+
+ /* bring apcli interface down first */
+ if(apcliEn == TRUE )
+ {
+ pAd->ApCfg.ApCliTab[ifIndex].Enable = FALSE;
+ ApCliIfDown(pAd);
+ }
+
+ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, MAC_ADDR_LEN);
+
+ if(strlen(arg) == 17) /* Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ {
+ for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"), i++)
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; /* Invalid */
+
+ AtoH(value, &pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid[i], 1);
+ }
+
+ if(i != 6)
+ return FALSE; /* Invalid */
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ApCli_Bssid_Proc (%2X:%2X:%2X:%2X:%2X:%2X)\n",
+ pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid[0],
+ pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid[1],
+ pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid[2],
+ pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid[3],
+ pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid[4],
+ pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid[5]));
+
+ pAd->ApCfg.ApCliTab[ifIndex].Enable = apcliEn;
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set ApCli-IF Authentication mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG i;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR ifIndex;
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+
+ if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = Ndis802_11AuthModeShared;
+ else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0) || (strcmp(arg, "WPAPSKWPA2PSK") == 0))
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = Ndis802_11AuthModeWPA2PSK;
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = Ndis802_11AuthModeWPA;
+ else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = Ndis802_11AuthModeWPA2;
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT */
+
+ else
+ pAd->ApCfg.ApCliTab[ifIndex].AuthMode = Ndis802_11AuthModeOpen;
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[i]))
+ {
+ pAd->MacTab.Content[i].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ }
+
+ RTMPMakeRSNIE(pAd, pAd->ApCfg.ApCliTab[ifIndex].AuthMode, pAd->ApCfg.ApCliTab[ifIndex].WepStatus, (ifIndex + MIN_NET_DEVICE_FOR_APCLI));
+
+ pAd->ApCfg.ApCliTab[ifIndex].DefaultKeyId = 0;
+
+ if(pAd->ApCfg.ApCliTab[ifIndex].AuthMode >= Ndis802_11AuthModeWPA)
+ pAd->ApCfg.ApCliTab[ifIndex].DefaultKeyId = 1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_ApCli_AuthMode_Proc::(AuthMode=%d)\n", ifIndex, pAd->ApCfg.ApCliTab[ifIndex].AuthMode));
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set ApCli-IF Encryption Type
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ pApCliEntry->WepStatus = Ndis802_11WEPDisabled;
+ if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
+ {
+ if (pApCliEntry->AuthMode < Ndis802_11AuthModeWPA)
+ pApCliEntry->WepStatus = Ndis802_11WEPEnabled;
+ }
+ else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
+ {
+ if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ pApCliEntry->WepStatus = Ndis802_11Encryption2Enabled;
+ }
+ else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0) || (strcmp(arg, "TKIPAES") == 0))
+ {
+ if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ pApCliEntry->WepStatus = Ndis802_11Encryption3Enabled;
+ }
+ else
+ {
+ pApCliEntry->WepStatus = Ndis802_11WEPDisabled;
+ }
+
+ pApCliEntry->PairCipher = pApCliEntry->WepStatus;
+ pApCliEntry->GroupCipher = pApCliEntry->WepStatus;
+ pApCliEntry->bMixCipher = FALSE;
+
+ if (pApCliEntry->WepStatus >= Ndis802_11Encryption2Enabled)
+ pApCliEntry->DefaultKeyId = 1;
+
+ RTMPMakeRSNIE(pAd, pApCliEntry->AuthMode, pApCliEntry->WepStatus, (ifIndex + MIN_NET_DEVICE_FOR_APCLI));
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_ApCli_EncrypType_Proc::(EncrypType=%d)\n", ifIndex, pApCliEntry->WepStatus));
+
+ return TRUE;
+}
+
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Default Key ID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG KeyIdx;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ KeyIdx = simple_strtol(arg, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pApCliEntry->DefaultKeyId = (UCHAR) (KeyIdx - 1 );
+ else
+ return FALSE; /* Invalid argument */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_DefaultKeyID_Proc::(DefaultKeyID(0~3)=%d)\n", ifIndex, pApCliEntry->DefaultKeyId));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set WPA PSK key for ApCli link
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ arg WPA pre-shared key string
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR ifIndex;
+ POS_COOKIE pObj;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ INT retval;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ApCli_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
+
+ retval = RT_CfgSetWPAPSKKey(pAd, arg, strlen(arg), (PUCHAR)pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, pApCliEntry->PMK);
+ if (retval == FALSE)
+ return FALSE;
+
+ NdisMoveMemory(pApCliEntry->PSK, arg, strlen(arg));
+ pApCliEntry->PSKLen = strlen(arg);
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY1 for ApCli-IF
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_Key1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ UCHAR ifIndex;
+ INT retVal;
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ retVal = RT_CfgSetWepKey(pAd, arg, &pApCliEntry->SharedKey[0], 0);
+ if(retVal == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_ApCli_Key1_Proc::(Key1=%s) success!\n", ifIndex, arg));
+
+ return retVal;
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY2 for ApCli-IF
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_Key2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ UCHAR ifIndex;
+ INT retVal;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ retVal = RT_CfgSetWepKey(pAd, arg, &pApCliEntry->SharedKey[1], 1);
+ if(retVal == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_ApCli_Key2_Proc::(Key2=%s) success!\n", ifIndex, arg));
+
+ return retVal;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY3 for ApCli-IF
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_Key3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ UCHAR ifIndex;
+ INT retVal;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ retVal = RT_CfgSetWepKey(pAd, arg, &pApCliEntry->SharedKey[2], 2);
+ if(retVal == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_ApCli_Key3_Proc::(Key3=%s) success!\n", ifIndex, arg));
+
+ return retVal;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY4 for ApCli-IF
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ApCli_Key4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ UCHAR ifIndex;
+ INT retVal;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ retVal = RT_CfgSetWepKey(pAd, arg, &pApCliEntry->SharedKey[3], 3);
+ if(retVal == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_ApCli_Key4_Proc::(Key4=%s) success!\n", ifIndex, arg));
+
+ return retVal;
+}
+
+INT Set_ApCli_TxMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ pApCliEntry->DesiredTransmitSetting.field.FixedTxMode = RT_CfgSetFixedTxPhyMode(arg);
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) Set_ApCli_TxMode_Proc = %d\n", ifIndex,
+ pApCliEntry->DesiredTransmitSetting.field.FixedTxMode));
+
+ return TRUE;
+}
+
+INT Set_ApCli_TxMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ pApCliEntry->DesiredTransmitSetting.field.MCS =
+ RT_CfgSetTxMCSProc(arg, &pApCliEntry->bAutoTxRateSwitch);
+
+ if (pApCliEntry->DesiredTransmitSetting.field.MCS == MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) Set_ApCli_TxMcs_Proc = AUTO\n", ifIndex));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) Set_ApCli_TxMcs_Proc = %d\n", ifIndex,
+ pApCliEntry->DesiredTransmitSetting.field.MCS));
+ }
+
+ return TRUE;
+}
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+INT Set_ApCli_Wpa_Support(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ if ( simple_strtol(arg, 0, 10) == 0)
+ pApCliEntry->WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+ else if ( simple_strtol(arg, 0, 10) == 1)
+ pApCliEntry->WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+ else if ( simple_strtol(arg, 0, 10) == 2)
+ pApCliEntry->WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
+ else
+ pApCliEntry->WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ApCli_Wpa_Support::(WpaSupplicantUP=%d)\n", pApCliEntry->WpaSupplicantUP));
+
+ return TRUE;
+}
+
+INT Set_ApCli_IEEE8021X_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG ieee8021x;
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ ifIndex = pObj->ioctl_if;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ ieee8021x = simple_strtol(arg, 0, 10);
+
+ if (ieee8021x == 1)
+ pApCliEntry->IEEE8021X = TRUE;
+ else if (ieee8021x == 0)
+ pApCliEntry->IEEE8021X = FALSE;
+ else
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_ApCli_IEEE8021X_Proc::(IEEE8021X=%d)\n", pObj->ioctl_if, pApCliEntry->IEEE8021X));
+
+ return TRUE;
+}
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+
+#ifdef WSC_AP_SUPPORT
+INT Set_AP_WscSsid_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR ifIndex = pObj->ioctl_if;
+ PWSC_CTRL pWscControl = &pAd->ApCfg.ApCliTab[ifIndex].WscControl;
+
+ if (pObj->ioctl_if_type != INT_APCLI)
+ return FALSE;
+
+ NdisZeroMemory(&pWscControl->WscSsid, sizeof(NDIS_802_11_SSID));
+
+ if( (strlen(arg) > 0) && (strlen(arg) <= MAX_LEN_OF_SSID))
+ {
+ NdisMoveMemory(pWscControl->WscSsid.Ssid, arg, strlen(arg));
+ pWscControl->WscSsid.SsidLength = strlen(arg);
+
+ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgSsid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgSsid, arg, strlen(arg));
+ pAd->ApCfg.ApCliTab[ifIndex].CfgSsidLen = (UCHAR)strlen(arg);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscSsid_Proc:: (Select SsidLen=%d,Ssid=%s)\n",
+ pWscControl->WscSsid.SsidLength, pWscControl->WscSsid.Ssid));
+ }
+ else
+ return FALSE; /*Invalid argument */
+
+ return TRUE;
+
+}
+#endif /* WSC_AP_SUPPORT */
+#endif /* APCLI_SUPPORT */
+
+
+#ifdef WSC_AP_SUPPORT
+INT Set_AP_WscConfMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT ConfModeIdx;
+ /*INT IsAPConfigured; */
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if, mac_addr[MAC_ADDR_LEN];
+ BOOLEAN bFromApCli = FALSE;
+ PWSC_CTRL pWscControl;
+
+ ConfModeIdx = simple_strtol(arg, 0, 10);
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return FALSE;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ bFromApCli = TRUE;
+ pWscControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscConfMode_Proc:: This command is from apcli interface now.\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ bFromApCli = FALSE;
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscConfMode_Proc:: This command is from ra interface now.\n", apidx));
+ }
+
+ pWscControl->bWscTrigger = FALSE;
+ if ((ConfModeIdx & WSC_ENROLLEE_PROXY_REGISTRAR) == WSC_DISABLE)
+ {
+ pWscControl->WscConfMode = WSC_DISABLE;
+ pWscControl->WscStatus = STATUS_WSC_NOTUSED;
+ if (bFromApCli)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscConfMode_Proc:: WPS is disabled.\n", apidx));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscConfMode_Proc:: WPS is disabled.\n", apidx));
+ /* Clear WPS IE in Beacon and ProbeResp */
+ pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen = 0;
+ pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen = 0;
+ APUpdateBeaconFrame(pAd, apidx);
+ }
+ }
+ else
+ {
+#ifdef APCLI_SUPPORT
+ if (bFromApCli)
+ {
+ if (ConfModeIdx == WSC_ENROLLEE)
+ {
+ pWscControl->WscConfMode = WSC_ENROLLEE;
+ WscInit(pAd, TRUE, apidx);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscConfMode_Proc:: Ap Client only supports Enrollee mode.(ConfModeIdx=%d)\n", apidx, ConfModeIdx));
+ return FALSE;
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ pWscControl->WscConfMode = (ConfModeIdx & WSC_ENROLLEE_PROXY_REGISTRAR);
+ WscInit(pAd, FALSE, apidx);
+ }
+ pWscControl->WscStatus = STATUS_WSC_IDLE;
+ }
+
+#ifdef APCLI_SUPPORT
+ if (bFromApCli)
+ {
+ memcpy(mac_addr, &pAd->ApCfg.ApCliTab[apidx].CurrentAddress[0], MAC_ADDR_LEN);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ memcpy(mac_addr, &pAd->ApCfg.MBSSID[apidx].Bssid[0], MAC_ADDR_LEN);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscConfMode_Proc::(WscConfMode(0~7)=%d)\n",
+ mac_addr[0],
+ mac_addr[1],
+ mac_addr[2],
+ mac_addr[3],
+ mac_addr[4],
+ mac_addr[5],
+ pWscControl->WscConfMode));
+ return TRUE;
+}
+
+INT Set_AP_WscConfStatus_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR IsAPConfigured = 0;
+ INT IsSelectedRegistrar;
+ USHORT WscMode;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return FALSE;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscConfStatus_Proc:: Ap Client doesn't need this command.\n", apidx));
+ return FALSE;
+ }
+#endif /* APCLI_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscV2Info.bWpsEnable == FALSE) &&
+ (pAd->ApCfg.MBSSID[apidx].WscControl.WscV2Info.bEnableWpsV2))
+ {
+ pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen = 0;
+ pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen = 0;
+ return FALSE;
+ }
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ IsAPConfigured = (UCHAR)simple_strtol(arg, 0, 10);
+ IsSelectedRegistrar = pAd->ApCfg.MBSSID[apidx].WscControl.WscSelReg;
+ if (pAd->ApCfg.MBSSID[apidx].WscControl.WscMode == 1)
+ WscMode = DEV_PASS_ID_PIN;
+ else
+ WscMode = DEV_PASS_ID_PBC;
+
+ if ((IsAPConfigured > 0) && (IsAPConfigured <= 2))
+ {
+ pAd->ApCfg.MBSSID[apidx].WscControl.WscConfStatus = IsAPConfigured;
+ /* Change SC State of WPS IE in Beacon and ProbeResp */
+ WscBuildBeaconIE(pAd, IsAPConfigured, IsSelectedRegistrar, WscMode, 0, apidx, NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, IsSelectedRegistrar, WscMode, 0, apidx, NULL, 0, AP_MODE);
+ APUpdateBeaconFrame(pAd, apidx);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscConfStatus_Proc:: Set failed!!(WscConfStatus=%s), WscConfStatus is 1 or 2 \n", apidx, arg));
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscConfStatus_Proc:: WscConfStatus is not changed (%d) \n", apidx, pAd->ApCfg.MBSSID[apidx].WscControl.WscConfStatus));
+ return FALSE; /*Invalid argument */
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscConfStatus_Proc::(WscConfStatus=%d)\n",
+ pAd->ApCfg.MBSSID[apidx].Bssid[0],
+ pAd->ApCfg.MBSSID[apidx].Bssid[1],
+ pAd->ApCfg.MBSSID[apidx].Bssid[2],
+ pAd->ApCfg.MBSSID[apidx].Bssid[3],
+ pAd->ApCfg.MBSSID[apidx].Bssid[4],
+ pAd->ApCfg.MBSSID[apidx].Bssid[5],
+ pAd->ApCfg.MBSSID[apidx].WscControl.WscConfStatus));
+
+ return TRUE;
+}
+
+INT Set_AP_WscMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT WscMode;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if, mac_addr[MAC_ADDR_LEN];
+ PWSC_CTRL pWscControl;
+ BOOLEAN bFromApCli = FALSE;
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return FALSE;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ bFromApCli = TRUE;
+ pWscControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscMode_Proc:: This command is from apcli interface now.\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ bFromApCli = FALSE;
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscMode_Proc:: This command is from ra interface now.\n", apidx));
+ }
+
+ WscMode = simple_strtol(arg, 0, 10);
+
+ if ((WscMode > 0) && (WscMode <= 2))
+ {
+ pWscControl->WscMode = WscMode;
+ if (WscMode == WSC_PBC_MODE)
+ {
+ WscGetRegDataPIN(pAd, pWscControl->WscPinCode, pWscControl);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscMode_Proc:: Set failed!!(Set_WscMode_Proc=%s), WscConfStatus is 1 or 2 \n", arg));
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscMode_Proc:: WscMode is not changed (%d) \n", pWscControl->WscMode));
+ return FALSE; /*Invalid argument */
+ }
+
+#ifdef APCLI_SUPPORT
+ if (bFromApCli)
+ {
+ memcpy(mac_addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, MAC_ADDR_LEN);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ memcpy(mac_addr, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscMode_Proc::(WscMode=%d)\n",
+ mac_addr[0],
+ mac_addr[1],
+ mac_addr[2],
+ mac_addr[3],
+ mac_addr[4],
+ mac_addr[5],
+ pWscControl->WscMode));
+
+ return TRUE;
+}
+
+INT Set_WscStatus_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscStatus_Proc::(WscStatus=%d)\n", apidx, pAd->ApCfg.MBSSID[apidx].WscControl.WscStatus));
+ return TRUE;
+}
+
+#define WSC_GET_CONF_MODE_EAP 1
+#define WSC_GET_CONF_MODE_UPNP 2
+INT Set_AP_WscGetConf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT WscMode, wscGetConfMode = 0;
+ INT IsAPConfigured;
+ PWSC_CTRL pWscControl;
+ PWSC_UPNP_NODE_INFO pWscUPnPNodeInfo;
+ INT idx;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if, mac_addr[MAC_ADDR_LEN];
+ BOOLEAN bFromApCli = FALSE;
+#ifdef APCLI_SUPPORT
+ BOOLEAN apcliEn = pAd->ApCfg.ApCliTab[apidx].Enable;
+#endif /* APCLI_SUPPORT */
+#ifdef WSC_V2_SUPPORT
+ PWSC_V2_INFO pWscV2Info = NULL;
+#endif /* WSC_V2_SUPPORT */
+#ifdef WSC_LED_SUPPORT
+ UCHAR WPSLEDStatus;
+#endif /* WSC_LED_SUPPORT */
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return FALSE;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ if (apcliEn == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_AP_WscGetConf_Proc:: ApCli is disabled.\n", apidx));
+ return FALSE;
+ }
+ bFromApCli = TRUE;
+ apidx &= (~MIN_NET_DEVICE_FOR_APCLI);
+ pWscControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_AP_WscGetConf_Proc:: This command is from apcli interface now.\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ bFromApCli = FALSE;
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_AP_WscGetConf_Proc:: This command is from ra interface now.\n", apidx));
+ }
+
+ NdisZeroMemory(mac_addr, MAC_ADDR_LEN);
+
+#ifdef WSC_V2_SUPPORT
+ pWscV2Info = &pWscControl->WscV2Info;
+#endif /* WSC_V2_SUPPORT */
+ wscGetConfMode = simple_strtol(arg, 0, 10);
+
+ IsAPConfigured = pWscControl->WscConfStatus;
+ pWscUPnPNodeInfo = &pWscControl->WscUPnPNodeInfo;
+
+ if ((pWscControl->WscConfMode == WSC_DISABLE)
+#ifdef WSC_V2_SUPPORT
+ || ((pWscV2Info->bWpsEnable == FALSE) && (pWscV2Info->bEnableWpsV2))
+#endif /* WSC_V2_SUPPORT */
+ )
+ {
+ pWscControl->bWscTrigger = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscGetConf_Proc: WPS is disabled.\n"));
+ return FALSE;
+ }
+
+ WscStop(pAd, bFromApCli, pWscControl);
+
+ /* trigger wsc re-generate public key */
+ pWscControl->RegData.ReComputePke = 1;
+
+ if (pWscControl->WscMode == 1)
+ WscMode = DEV_PASS_ID_PIN;
+ else
+ {
+ WscMode = DEV_PASS_ID_PBC;
+ }
+ WscInitRegistrarPair(pAd, pWscControl, apidx);
+ /* Enrollee 192 random bytes for DH key generation */
+ for (idx = 0; idx < 192; idx++)
+ pWscControl->RegData.EnrolleeRandom[idx] = RandomByte(pAd);
+
+#ifdef APCLI_SUPPORT
+ if (bFromApCli)
+ {
+ /* bring apcli interface down first */
+ pAd->ApCfg.ApCliTab[apidx].Enable = FALSE;
+ ApCliIfDown(pAd);
+
+ if (WscMode == DEV_PASS_ID_PIN)
+ {
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr,
+ pAd->ApCfg.ApCliTab[apidx].CurrentAddress,
+ 6);
+
+ pAd->ApCfg.ApCliTab[apidx].Enable = apcliEn;
+ NdisMoveMemory(mac_addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, MAC_ADDR_LEN);
+ }
+ else
+ {
+ pWscControl->WscSsid.SsidLength = 0;
+ NdisZeroMemory(&pWscControl->WscSsid, sizeof(NDIS_802_11_SSID));
+ pWscControl->WscPBCBssCount = 0;
+ /* WPS - SW PBC */
+ WscPushPBCAction(pAd, pWscControl);
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ WscBuildBeaconIE(pAd, IsAPConfigured, TRUE, WscMode, pWscControl->WscConfigMethods, apidx, NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, TRUE, WscMode, pWscControl->WscConfigMethods, apidx, NULL, 0, AP_MODE);
+ APUpdateBeaconFrame(pAd, apidx);
+ NdisMoveMemory(mac_addr, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN);
+ }
+
+#ifdef APCLI_SUPPORT
+ if (bFromApCli && (WscMode == DEV_PASS_ID_PBC))
+ ;
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ /* 2mins time-out timer */
+ RTMPSetTimer(&pWscControl->Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT);
+ pWscControl->Wsc2MinsTimerRunning = TRUE;
+ pWscControl->WscStatus = STATUS_WSC_LINK_UP;
+ pWscControl->bWscTrigger = TRUE;
+ }
+ pWscControl->bWscAutoTigeer = FALSE;
+
+ if (!bFromApCli)
+ {
+ if (WscMode == DEV_PASS_ID_PIN)
+ {
+ WscAssignEntryMAC(pAd, pWscControl);
+ WscSendUPnPConfReqMsg(pAd, pWscControl->EntryIfIdx,
+ (PUCHAR)pAd->ApCfg.MBSSID[pWscControl->EntryIfIdx].Ssid,
+ pAd->ApCfg.MBSSID[apidx].Bssid, 3, 0, AP_MODE);
+ }
+ else
+ {
+ RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock);
+ WscClearPeerList(&pWscControl->WscPeerList);
+ RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock);
+ }
+ }
+
+#ifdef WSC_LED_SUPPORT
+ WPSLEDStatus = LED_WPS_IN_PROCESS;
+ RTMPSetLED(pAd, WPSLEDStatus);
+#endif /* WSC_LED_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscGetConf_Proc trigger WSC state machine, wscGetConfMode=%d\n",
+ mac_addr[0],
+ mac_addr[1],
+ mac_addr[2],
+ mac_addr[3],
+ mac_addr[4],
+ mac_addr[5],
+ wscGetConfMode));
+
+ return TRUE;
+}
+
+INT Set_AP_WscPinCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT PinCode = 0;
+ BOOLEAN validatePin, bFromApCli = FALSE;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if, mac_addr[MAC_ADDR_LEN];
+ PWSC_CTRL pWscControl;
+#define IsZero(c) ('0' == (c) ? TRUE:FALSE)
+ PinCode = simple_strtol(arg, 0, 10); /* When PinCode is 03571361, return value is 3571361. */
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return FALSE;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ bFromApCli = TRUE;
+ pWscControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscPinCode_Proc:: This command is from apcli interface now.\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ bFromApCli = FALSE;
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscPinCode_Proc:: This command is from ra interface now.\n", apidx));
+ }
+
+ if (strlen(arg) == 4)
+ validatePin = TRUE;
+ else
+ validatePin = ValidateChecksum(PinCode);
+
+ if ( validatePin )
+ {
+ if (pWscControl->WscRejectSamePinFromEnrollee &&
+ (PinCode == pWscControl->WscLastPinFromEnrollee))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PIN authentication or communication error occurs!!\n"
+ "Registrar does NOT accept the same PIN again!(PIN:%s)\n", arg));
+ return FALSE;
+ }
+ else
+ {
+ pWscControl->WscPinCode = PinCode;
+ pWscControl->WscLastPinFromEnrollee = pWscControl->WscPinCode;
+ pWscControl->WscRejectSamePinFromEnrollee = FALSE;
+ /* PIN Code */
+ if (strlen(arg) == 4)
+ {
+ pWscControl->WscPinCodeLen = 4;
+ pWscControl->RegData.PinCodeLen = 4;
+ NdisMoveMemory(pWscControl->RegData.PIN, arg, 4);
+ }
+ else
+ {
+ pWscControl->WscPinCodeLen = 8;
+
+ if (IsZero(*arg))
+ {
+ pWscControl->RegData.PinCodeLen = 8;
+ NdisMoveMemory(pWscControl->RegData.PIN, arg, 8);
+ }
+ else
+ WscGetRegDataPIN(pAd, pWscControl->WscPinCode, pWscControl);
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(Set_WscPinCode_Proc=%s), PinCode Checksum invalid \n", arg));
+ return FALSE; /*Invalid argument */
+ }
+
+#ifdef APCLI_SUPPORT
+ if (bFromApCli)
+ {
+ memcpy(mac_addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, MAC_ADDR_LEN);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ memcpy(mac_addr, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscPinCode_Proc::(PinCode=%d)\n",
+ mac_addr[0],
+ mac_addr[1],
+ mac_addr[2],
+ mac_addr[3],
+ mac_addr[4],
+ mac_addr[5],
+ pWscControl->WscPinCode));
+
+ return TRUE;
+}
+
+INT Set_WscOOB_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ char *pTempSsid = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return FALSE;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscPinCode_Proc:: Ap Client doesn't need this command.\n", apidx));
+ return FALSE;
+ }
+#endif /* APCLI_SUPPORT */
+
+ Set_AP_WscConfStatus_Proc(pAd, "1");
+ Set_AP_AuthMode_Proc(pAd, "WPA2PSK");
+ Set_AP_EncrypType_Proc(pAd, "AES");
+ pTempSsid = vmalloc(33);
+ if (pTempSsid)
+ {
+ memset(pTempSsid, 0, 33);
+ snprintf(pTempSsid, 33,"RalinkInitialAP%02X%02X%02X", pAd->ApCfg.MBSSID[apidx].Bssid[3],
+ pAd->ApCfg.MBSSID[apidx].Bssid[4],
+ pAd->ApCfg.MBSSID[apidx].Bssid[5]);
+ Set_AP_SSID_Proc(pAd, pTempSsid);
+ vfree(pTempSsid);
+ }
+ Set_AP_WPAPSK_Proc(pAd, "RalinkInitialAPxx1234");
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscOOB_Proc\n", apidx));
+ return TRUE;
+}
+
+INT Set_WscStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ PWSC_CTRL pWscControl;
+ BOOLEAN bFromApCli = FALSE;
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return FALSE;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ bFromApCli = TRUE;
+ pWscControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscStop_Proc:: This command is from apcli interface now.\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ bFromApCli = FALSE;
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscStop_Proc:: This command is from ra interface now.\n", apidx));
+ }
+
+#ifdef APCLI_SUPPORT
+ if (bFromApCli)
+ {
+ WscStop(pAd, TRUE, pWscControl);
+ pWscControl->WscConfMode = WSC_DISABLE;
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ INT IsAPConfigured = pWscControl->WscConfStatus;
+ WscBuildBeaconIE(pAd, IsAPConfigured, FALSE, 0, 0, apidx, NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, apidx, NULL, 0, AP_MODE);
+ APUpdateBeaconFrame(pAd, apidx);
+ WscStop(pAd, FALSE, pWscControl);
+ }
+
+ pWscControl->bWscTrigger = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("<===== Set_WscStop_Proc"));
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get WSC Profile
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 get_wsc_profile
+ 3.) UI needs to prepare at least 4096bytes to get the results
+ ==========================================================================
+*/
+VOID RTMPIoctlWscProfile(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ WSC_CONFIGURED_VALUE Profile;
+ PSTRING msg;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ return;
+ }
+#endif /*HOSTAPD_SUPPORT*/
+
+
+ memset(&Profile, 0x00, sizeof(WSC_CONFIGURED_VALUE));
+ Profile.WscConfigured = pAd->ApCfg.MBSSID[apidx].WscControl.WscConfStatus;
+ NdisZeroMemory(Profile.WscSsid, 32 + 1);
+ NdisMoveMemory(Profile.WscSsid, pAd->ApCfg.MBSSID[apidx].Ssid,
+ pAd->ApCfg.MBSSID[apidx].SsidLen);
+ Profile.WscSsid[pAd->ApCfg.MBSSID[apidx].SsidLen] = '\0';
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ Profile.WscAuthMode = WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK;
+ else
+ Profile.WscAuthMode = WscGetAuthType(pAd->ApCfg.MBSSID[apidx].AuthMode);
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ Profile.WscEncrypType = WSC_ENCRTYPE_TKIP |WSC_ENCRTYPE_AES;
+ else
+ Profile.WscEncrypType = WscGetEncryType(pAd->ApCfg.MBSSID[apidx].WepStatus);
+ NdisZeroMemory(Profile.WscWPAKey, 64 + 1);
+
+ if (Profile.WscEncrypType == 2)
+ {
+ Profile.DefaultKeyIdx = pAd->ApCfg.MBSSID[apidx].DefaultKeyId + 1;
+ {
+ int i;
+ for (i=0; i<pAd->SharedKey[apidx][pAd->ApCfg.MBSSID[apidx].DefaultKeyId].KeyLen; i++)
+ {
+ snprintf((PSTRING) Profile.WscWPAKey, sizeof(Profile.WscWPAKey),
+ "%s%02x", Profile.WscWPAKey,
+ pAd->SharedKey[apidx][pAd->ApCfg.MBSSID[apidx].DefaultKeyId].Key[i]);
+ }
+ Profile.WscWPAKey[(pAd->SharedKey[apidx][pAd->ApCfg.MBSSID[apidx].DefaultKeyId].KeyLen)*2] = '\0';
+ }
+ }
+ else if (Profile.WscEncrypType >= 4)
+ {
+ Profile.DefaultKeyIdx = 2;
+ NdisMoveMemory(Profile.WscWPAKey, pAd->ApCfg.MBSSID[apidx].WscControl.WpaPsk,
+ pAd->ApCfg.MBSSID[apidx].WscControl.WpaPskLen);
+ Profile.WscWPAKey[pAd->ApCfg.MBSSID[apidx].WscControl.WpaPskLen] = '\0';
+ }
+ else
+ {
+ Profile.DefaultKeyIdx = 1;
+ }
+
+ wrq->u.data.length = sizeof(Profile);
+
+ if (copy_to_user(wrq->u.data.pointer, &Profile, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+
+/* msg = (PSTRING)kmalloc(sizeof(CHAR)*(2048), MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&msg, sizeof(CHAR)*(2048));
+ if (msg == NULL) {
+ return;
+ }
+
+ memset(msg, 0x00, 2048);
+ sprintf(msg,"%s","\n");
+
+ if (Profile.WscEncrypType == 1)
+ {
+ sprintf(msg+strlen(msg),"%-12s%-33s%-12s%-12s\n", "Configured", "SSID", "AuthMode", "EncrypType");
+ }
+ else if (Profile.WscEncrypType == 2)
+ {
+ sprintf(msg+strlen(msg),"%-12s%-33s%-12s%-12s%-13s%-26s\n", "Configured", "SSID", "AuthMode", "EncrypType", "DefaultKeyID", "Key");
+ }
+ else
+ {
+ sprintf(msg+strlen(msg),"%-12s%-33s%-12s%-12s%-64s\n", "Configured", "SSID", "AuthMode", "EncrypType", "Key");
+ }
+
+ if (Profile.WscConfigured == 1)
+ sprintf(msg+strlen(msg),"%-12s", "No");
+ else
+ sprintf(msg+strlen(msg),"%-12s", "Yes");
+ sprintf(msg+strlen(msg), "%-33s", Profile.WscSsid);
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ sprintf(msg+strlen(msg), "%-12s", "WPAPSKWPA2PSK");
+ else
+ sprintf(msg+strlen(msg), "%-12s", WscGetAuthTypeStr(Profile.WscAuthMode));
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ sprintf(msg+strlen(msg), "%-12s", "TKIPAES");
+ else
+ sprintf(msg+strlen(msg), "%-12s", WscGetEncryTypeStr(Profile.WscEncrypType));
+
+ if (Profile.WscEncrypType == 1)
+ {
+ sprintf(msg+strlen(msg), "%s\n", "");
+ }
+ else if (Profile.WscEncrypType == 2)
+ {
+ sprintf(msg+strlen(msg), "%-13d",Profile.DefaultKeyIdx);
+ sprintf(msg+strlen(msg), "%-26s\n",Profile.WscWPAKey);
+ }
+ else if (Profile.WscEncrypType >= 4)
+ {
+ sprintf(msg+strlen(msg), "%-64s\n",Profile.WscWPAKey);
+ }
+#ifdef INF_AR9
+ wrq->u.data.length = strlen(msg);
+ copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+#endif/* INF_AR9 */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
+/* kfree(msg); */
+ os_free_mem(NULL, msg);
+}
+
+#ifdef INF_AR9
+#ifdef AR9_MAPI_SUPPORT
+
+/*
+ ==========================================================================
+ Description:
+ Get WSC Profile
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 ar9_show get_wsc_profile
+ 3.) UI needs to prepare at least 4096bytes to get the results
+ ==========================================================================
+*/
+VOID RTMPAR9IoctlWscProfile(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ WSC_CONFIGURED_VALUE Profile;
+ PSTRING msg;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+ memset(&Profile, 0x00, sizeof(WSC_CONFIGURED_VALUE));
+ Profile.WscConfigured = pAd->ApCfg.MBSSID[apidx].WscControl.WscConfStatus;
+ NdisZeroMemory(Profile.WscSsid, 32 + 1);
+ NdisMoveMemory(Profile.WscSsid, pAd->ApCfg.MBSSID[apidx].Ssid,
+ pAd->ApCfg.MBSSID[apidx].SsidLen);
+ Profile.WscSsid[pAd->ApCfg.MBSSID[apidx].SsidLen] = '\0';
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ Profile.WscAuthMode = WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK;
+ else
+ Profile.WscAuthMode = WscGetAuthType(pAd->ApCfg.MBSSID[apidx].AuthMode);
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ Profile.WscEncrypType = WSC_ENCRTYPE_TKIP |WSC_ENCRTYPE_AES;
+ else
+ Profile.WscEncrypType = WscGetEncryType(pAd->ApCfg.MBSSID[apidx].WepStatus);
+ NdisZeroMemory(Profile.WscWPAKey, 64 + 1);
+
+ if (Profile.WscEncrypType == 2)
+ {
+ Profile.DefaultKeyIdx = pAd->ApCfg.MBSSID[apidx].DefaultKeyId + 1;
+ {
+ int i;
+ for (i=0; i<pAd->SharedKey[apidx][pAd->ApCfg.MBSSID[apidx].DefaultKeyId].KeyLen; i++)
+ {
+ snprintf((PSTRING) Profile.WscWPAKey, sizeof(Profile.WscWPAKey),
+ "%s%02x", Profile.WscWPAKey,
+ pAd->SharedKey[apidx][pAd->ApCfg.MBSSID[apidx].DefaultKeyId].Key[i]);
+ }
+ Profile.WscWPAKey[(pAd->SharedKey[apidx][pAd->ApCfg.MBSSID[apidx].DefaultKeyId].KeyLen)*2] = '\0';
+ }
+ }
+ else if (Profile.WscEncrypType >= 4)
+ {
+ Profile.DefaultKeyIdx = 2;
+ NdisMoveMemory(Profile.WscWPAKey, pAd->ApCfg.MBSSID[apidx].WscControl.WpaPsk,
+ pAd->ApCfg.MBSSID[apidx].WscControl.WpaPskLen);
+ Profile.WscWPAKey[pAd->ApCfg.MBSSID[apidx].WscControl.WpaPskLen] = '\0';
+ }
+ else
+ {
+ Profile.DefaultKeyIdx = 1;
+ }
+
+
+/* msg = (PSTRING)kmalloc(sizeof(CHAR)*(2048), MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&msg, sizeof(CHAR)*(2048));
+ if (msg == NULL) {
+ return;
+ }
+
+ memset(msg, 0x00, 2048);
+ sprintf(msg,"%s","\n");
+
+ if (Profile.WscEncrypType == 1)
+ {
+ sprintf(msg+strlen(msg),"%-12s%-33s%-12s%-12s\n", "Configured", "SSID", "AuthMode", "EncrypType");
+ }
+ else if (Profile.WscEncrypType == 2)
+ {
+ sprintf(msg+strlen(msg),"%-12s%-33s%-12s%-12s%-13s%-26s\n", "Configured", "SSID", "AuthMode", "EncrypType", "DefaultKeyID", "Key");
+ }
+ else
+ {
+ sprintf(msg+strlen(msg),"%-12s%-33s%-12s%-12s%-64s\n", "Configured", "SSID", "AuthMode", "EncrypType", "Key");
+ }
+
+ if (Profile.WscConfigured == 1)
+ sprintf(msg+strlen(msg),"%-12s", "No");
+ else
+ sprintf(msg+strlen(msg),"%-12s", "Yes");
+ sprintf(msg+strlen(msg), "%-33s", Profile.WscSsid);
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ sprintf(msg+strlen(msg), "%-12s", "WPAPSKWPA2PSK");
+ else
+ sprintf(msg+strlen(msg), "%-12s", WscGetAuthTypeStr(Profile.WscAuthMode));
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ sprintf(msg+strlen(msg), "%-12s", "TKIPAES");
+ else
+ sprintf(msg+strlen(msg), "%-12s", WscGetEncryTypeStr(Profile.WscEncrypType));
+
+ if (Profile.WscEncrypType == 1)
+ {
+ sprintf(msg+strlen(msg), "%s\n", "");
+ }
+ else if (Profile.WscEncrypType == 2)
+ {
+ sprintf(msg+strlen(msg), "%-13d",Profile.DefaultKeyIdx);
+ sprintf(msg+strlen(msg), "%-26s\n",Profile.WscWPAKey);
+ }
+ else if (Profile.WscEncrypType >= 4)
+ {
+ sprintf(msg+strlen(msg), "%-64s\n",Profile.WscWPAKey);
+ }
+
+ wrq->u.data.length = strlen(msg);
+ copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
+ }
+/* kfree(msg); */
+ os_free_mem(NULL, msg);
+}
+
+VOID RTMPIoctlWscPINCode(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ PSTRING msg;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ UCHAR tempPIN[9]={0};
+
+/* msg = (PSTRING)kmalloc(sizeof(CHAR)*(128), MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR)*(128));
+ if (msg == NULL) {
+ return;
+ }
+
+ memset(msg, 0x00, 128);
+ sprintf(msg,"%s","\n");
+ sprintf(msg+strlen(msg),"WSC_PINCode=");
+ if(pAd->ApCfg.MBSSID[apidx].WscControl.WscEnrolleePinCode)
+ {
+ if (pAd->ApCfg.MBSSID[apidx].WscControl.WscEnrolleePinCodeLen == 8)
+ sprintf((PSTRING) tempPIN, "%08u", pAd->ApCfg.MBSSID[apidx].WscControl.WscEnrolleePinCode);
+ else
+ sprintf((PSTRING) tempPIN, "%04u", pAd->ApCfg.MBSSID[apidx].WscControl.WscEnrolleePinCode);
+ sprintf(msg,"%s%s\n",msg,tempPIN);
+ }
+ wrq->u.data.length = strlen(msg);
+ copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
+ }
+/* kfree(msg); */
+ os_free_mem(NULL, msg);
+}
+
+VOID RTMPIoctlWscStatus(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ PSTRING msg;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+/* msg = (PSTRING)kmalloc(sizeof(CHAR)*(128), MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR)*(128));
+ if (msg == NULL) {
+ return;
+ }
+
+ memset(msg, 0x00, 128);
+ sprintf(msg,"%s","\n");
+ sprintf(msg+strlen(msg),"WSC_Status=");
+ sprintf(msg,"%s%d\n",msg,pAd->ApCfg.MBSSID[apidx].WscControl.WscStatus);
+ wrq->u.data.length = strlen(msg);
+ copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
+ }
+/* kfree(msg); */
+ os_free_mem(NULL, msg);
+}
+
+VOID RTMPIoctlGetWscDynInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ char *msg;
+ PMULTISSID_STRUCT pMbss;
+ INT apidx,configstate;
+
+
+/* msg = kmalloc(sizeof(CHAR)*(pAd->ApCfg.BssidNum*(14*128)), MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR)*(pAd->ApCfg.BssidNum*(14*128)));
+ if (msg == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
+ return;
+ }
+ memset(msg, 0 ,pAd->ApCfg.BssidNum*(14*128));
+ sprintf(msg,"%s","\n");
+
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ pMbss=&pAd->ApCfg.MBSSID[apidx];
+
+ if(pMbss->WscControl.WscConfStatus == WSC_SCSTATE_UNCONFIGURED)
+ configstate = 0;
+ else
+ configstate = 1;
+
+ sprintf(msg+strlen(msg),"ra%d\n",apidx);
+ sprintf(msg+strlen(msg),"UUID = %s\n",(pMbss->WscControl.Wsc_Uuid_Str));
+ sprintf(msg+strlen(msg),"wpsVersion = 0x%x\n",WSC_VERSION);
+ sprintf(msg+strlen(msg),"setuoLockedState = %d\n",0);
+ sprintf(msg+strlen(msg),"configstate = %d\n",configstate);
+ sprintf(msg+strlen(msg),"lastConfigError = %d\n",0);
+
+ }
+
+ wrq->u.data.length = strlen(msg);
+ if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s", msg));
+ }
+
+/* kfree(msg); */
+ os_free_mem(NULL, msg);
+}
+
+VOID RTMPIoctlGetWscRegsDynInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ char *msg;
+ PMULTISSID_STRUCT pMbss;
+ INT apidx;
+
+
+/* msg = kmalloc(sizeof(CHAR)*(pAd->ApCfg.BssidNum*(14*128)), MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR)*(pAd->ApCfg.BssidNum*(14*128)));
+ if (msg == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
+ return;
+ }
+ memset(msg, 0 ,pAd->ApCfg.BssidNum*(14*128));
+ sprintf(msg,"%s","\n");
+
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ pMbss=&pAd->ApCfg.MBSSID[apidx];
+ sprintf(msg+strlen(msg),"ra%d\n",apidx);
+ sprintf(msg+strlen(msg),"UUID_R = %s\n",(pMbss->WscControl.RegData.PeerInfo.Uuid));
+ }
+
+ wrq->u.data.length = strlen(msg);
+ if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s", msg));
+ }
+
+/* kfree(msg); */
+ os_free_mem(NULL, msg);
+}
+#endif /*AR9_MAPI_SUPPORT*/
+#endif/* INF_AR9 */
+BOOLEAN WscCheckEnrolleeNonceFromUpnp(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING pData,
+ IN USHORT Length,
+ IN PWSC_CTRL pWscControl)
+{
+ USHORT WscType, WscLen;
+ USHORT WscId = WSC_ID_ENROLLEE_NONCE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("check Enrollee Nonce\n"));
+
+ /* We have to look for WSC_IE_MSG_TYPE to classify M2 ~ M8, the remain size must large than 4 */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ char ZeroNonce[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ if (WscType == WscId)
+ {
+ if (RTMPCompareMemory(pWscControl->RegData.SelfNonce, pData, 16) == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Nonce match!!\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n"));
+ return TRUE;
+ }
+ else if (NdisEqualMemory(pData, ZeroNonce, 16))
+ {
+ /* Intel external registrar will send WSC_NACK with enrollee nonce */
+ /* "10 1A 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" */
+ /* when AP is configured and user selects not to configure AP. */
+ DBGPRINT(RT_DEBUG_TRACE, ("Zero Enrollee Nonce!!\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n"));
+ return TRUE;
+ }
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Nonce mismatch!!\n"));
+ return FALSE;
+}
+
+UCHAR WscRxMsgTypeFromUpnp(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING pData,
+ IN USHORT Length)
+{
+
+ USHORT WscType, WscLen;
+
+ { /* Eap-Esp(Messages) */
+ /* the first TLV item in EAP Messages must be WSC_IE_VERSION */
+ NdisMoveMemory(&WscType, pData, 2);
+ if (ntohs(WscType) != WSC_ID_VERSION)
+ goto out;
+
+ /* Not Wsc Start, We have to look for WSC_IE_MSG_TYPE to classify M2 ~ M8, the remain size must large than 4 */
+ while (Length > 4)
+ {
+ /* arm-cpu has packet alignment issue, it's better to use memcpy to retrieve data */
+ NdisMoveMemory(&WscType, pData, 2);
+ NdisMoveMemory(&WscLen, pData + 2, 2);
+ WscLen = ntohs(WscLen);
+ if (ntohs(WscType) == WSC_ID_MSG_TYPE)
+ {
+ return(*(pData + 4)); /* Found the message type */
+ }
+ else
+ {
+ pData += (WscLen + 4);
+ Length -= (WscLen + 4);
+ }
+ }
+ }
+
+out:
+ return WSC_MSG_UNKNOWN;
+}
+
+VOID RTMPIoctlSetWSCOOB(
+ IN PRTMP_ADAPTER pAd)
+{
+ char *pTempSsid = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscPinCode_Proc:: Ap Client doesn't need this command.\n", apidx));
+ return;
+ }
+#endif /* APCLI_SUPPORT */
+
+ Set_AP_WscConfStatus_Proc(pAd, "1");
+ Set_AP_AuthMode_Proc(pAd, "WPAPSK");
+ Set_AP_EncrypType_Proc(pAd, "TKIP");
+ pTempSsid = vmalloc(33);
+ if (pTempSsid)
+ {
+ memset(pTempSsid, 0, 33);
+ snprintf(pTempSsid, 33, "RalinkInitialAP%02X%02X%02X", pAd->ApCfg.MBSSID[apidx].Bssid[3],
+ pAd->ApCfg.MBSSID[apidx].Bssid[4],
+ pAd->ApCfg.MBSSID[apidx].Bssid[5]);
+ Set_AP_SSID_Proc(pAd, pTempSsid);
+ vfree(pTempSsid);
+ }
+ Set_AP_WPAPSK_Proc(pAd, "RalinkInitialAPxx1234");
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscOOB_Proc\n", apidx));
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Wsc Security Mode
+ 0 : WPA2PSK AES
+ 1 : WPA2PSK TKIP
+ 2 : WPAPSK AES
+ 3 : WPAPSK TKIP
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AP_WscSecurityMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+ if (strcmp(arg, "0") == 0)
+ pAd->ApCfg.MBSSID[apidx].WscSecurityMode = WPA2PSKAES;
+ else if (strcmp(arg, "1") == 0)
+ pAd->ApCfg.MBSSID[apidx].WscSecurityMode = WPA2PSKTKIP;
+ else if (strcmp(arg, "2") == 0)
+ pAd->ApCfg.MBSSID[apidx].WscSecurityMode = WPAPSKAES;
+ else if (strcmp(arg, "3") == 0)
+ pAd->ApCfg.MBSSID[apidx].WscSecurityMode = WPAPSKTKIP;
+ else
+ return FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscSecurityMode_Proc::(WscSecurityMode=%d)\n",
+ apidx, pAd->ApCfg.MBSSID[apidx].WscSecurityMode ));
+
+ return TRUE;
+}
+
+INT Set_AP_WscMultiByteCheck_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ BOOLEAN bEnable = FALSE;
+ PWSC_CTRL pWpsCtrl = NULL;
+ BOOLEAN bFromApCli = FALSE;
+
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ bFromApCli = TRUE;
+ pWpsCtrl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscConfMode_Proc:: This command is from apcli interface now.\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ bFromApCli = FALSE;
+ pWpsCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscConfMode_Proc:: This command is from ra interface now.\n", apidx));
+ }
+
+ if (strcmp(arg, "0") == 0)
+ bEnable = FALSE;
+ else if (strcmp(arg, "1") == 0)
+ bEnable = TRUE;
+ else
+ return FALSE;
+
+ if (pWpsCtrl->bCheckMultiByte != bEnable)
+ {
+ pWpsCtrl->bCheckMultiByte = bEnable;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_AP_WscMultiByteCheck_Proc::(bCheckMultiByte=%d)\n",
+ apidx, pWpsCtrl->bCheckMultiByte));
+
+ return TRUE;
+}
+
+INT Set_WscVersion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR version = (UCHAR)simple_strtol(arg, 0, 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscVersion_Proc::(version=%x)\n",version));
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.RegData.SelfInfo.Version = version;
+ return TRUE;
+}
+
+#ifdef WSC_V2_SUPPORT
+INT Set_WscFragment_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR bool_flag = (UCHAR)simple_strtol(arg, 0, 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscFragment_Proc::(bool_flag=%d)\n",bool_flag));
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.bWscFragment = bool_flag;
+ return TRUE;
+}
+
+INT Set_WscFragmentSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ USHORT WscFragSize = (USHORT)simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscFragmentSize_Proc::(WscFragSize=%d)\n", WscFragSize));
+ if ((WscFragSize >=128) && (WscFragSize <=300))
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.WscFragSize = WscFragSize;
+ return TRUE;
+}
+
+INT Set_WscSetupLock_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR bEnable = (UCHAR)simple_strtol(arg, 0, 10);
+ PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl;
+
+ if (bEnable == 0)
+ {
+ BOOLEAN bCancelled = FALSE;
+ if (pWscControl->WscSetupLockTimerRunning)
+ {
+ RTMPCancelTimer(&pWscControl->WscSetupLockTimer, &bCancelled);
+ }
+ WscSetupLockTimeout(NULL, pWscControl, NULL, NULL);
+ }
+ else
+ {
+ pWscControl->bSetupLock = TRUE;
+ WscBuildBeaconIE(pAd,
+ pWscControl->WscConfStatus,
+ FALSE,
+ 0,
+ 0,
+ pObj->ioctl_if,
+ NULL,
+ 0,
+ AP_MODE);
+ WscBuildProbeRespIE(pAd,
+ WSC_MSGTYPE_AP_WLAN_MGR,
+ pWscControl->WscConfStatus,
+ FALSE,
+ 0,
+ 0,
+ pObj->ioctl_if,
+ NULL,
+ 0,
+ AP_MODE);
+ APUpdateBeaconFrame(pAd, pObj->ioctl_if);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscSetupLock_Proc::(bSetupLock=%d)\n",
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.bSetupLock));
+ return TRUE;
+}
+
+INT Set_WscV2Support_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR bEnable = (UCHAR)simple_strtol(arg, 0, 10);
+ PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl;
+ INT IsAPConfigured = pWscControl->WscConfStatus;
+
+ if (bEnable == 0)
+ pWscControl->WscV2Info.bEnableWpsV2 = FALSE;
+ else
+ pWscControl->WscV2Info.bEnableWpsV2 = TRUE;
+
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /*
+ WPS V2 doesn't support WEP and WPA/WPAPSK-TKIP.
+ */
+ if ((pAd->ApCfg.MBSSID[pObj->ioctl_if].WepStatus == Ndis802_11WEPEnabled) ||
+ (pAd->ApCfg.MBSSID[pObj->ioctl_if].WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->ApCfg.MBSSID[pObj->ioctl_if].bHideSsid))
+ WscOnOff(pAd, pObj->ioctl_if, TRUE);
+ else
+ WscOnOff(pAd, pObj->ioctl_if, FALSE);
+
+ APUpdateBeaconFrame(pAd, pObj->ioctl_if);
+ }
+ else
+ {
+ WscInit(pAd, FALSE, pObj->ioctl_if);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscV2Support_Proc::(bEnableWpsV2=%d)\n",
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.WscV2Info.bEnableWpsV2));
+ return TRUE;
+}
+
+INT Set_WscVersion2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR version = (UCHAR)simple_strtol(arg, 0, 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscVersion2_Proc::(version=%x)\n",version));
+ if (version >= 0x20)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.RegData.SelfInfo.Version2 = version;
+ else
+ return FALSE;
+ return TRUE;
+}
+
+INT Set_WscExtraTlvTag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ USHORT new_tag = (USHORT)simple_strtol(arg, 0, 16);
+
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.WscV2Info.ExtraTlv.TlvTag = new_tag;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscExtraTlvTag_Proc::(new_tag=0x%04X)\n",new_tag));
+ return TRUE;
+}
+
+INT Set_WscExtraTlvType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR type = (UCHAR)simple_strtol(arg, 0, 10);
+
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.WscV2Info.ExtraTlv.TlvType = type;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscExtraTlvType_Proc::(type=%d)\n",type));
+ return TRUE;
+}
+
+INT Set_WscExtraTlvData_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UINT DataLen = (UINT)strlen(arg);
+ PWSC_TLV pWscTLV = &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.WscV2Info.ExtraTlv;
+ INT i;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscExtraTlvData_Proc::(DataLen = %d)\n", DataLen));
+
+ if ((DataLen != 0) && (pWscTLV->TlvType == TLV_HEX))
+ {
+ for(i=0; i < DataLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; /*Not Hex value; */
+ }
+ }
+
+ if (pWscTLV->pTlvData)
+ {
+ os_free_mem(NULL, pWscTLV->pTlvData);
+ pWscTLV->pTlvData = NULL;
+ }
+
+ if (DataLen == 0)
+ return TRUE;
+
+ pWscTLV->TlvLen = 0;
+ os_alloc_mem(NULL, &pWscTLV->pTlvData, DataLen);
+ if (pWscTLV->pTlvData)
+ {
+ if (pWscTLV->TlvType == TLV_ASCII)
+ {
+ NdisMoveMemory(pWscTLV->pTlvData, arg, DataLen);
+ pWscTLV->TlvLen = DataLen;
+ }
+ else
+ {
+ pWscTLV->TlvLen = DataLen/2;
+ AtoH(arg, pWscTLV->pTlvData, pWscTLV->TlvLen);
+ }
+ return TRUE;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscExtraTlvData_Proc::os_alloc_mem fail\n"));
+
+ return FALSE;
+}
+
+INT Set_WscMaxPinAttack_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR MaxPinAttack = (UCHAR)simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscMaxPinAttack_Proc::(MaxPinAttack=%d)\n", MaxPinAttack));
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.MaxPinAttack = MaxPinAttack;
+ return TRUE;
+}
+
+
+INT Set_WscSetupLockTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UINT SetupLockTime = (UINT)simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscSetupLockTime_Proc::(SetupLockTime=%d)\n", SetupLockTime));
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.SetupLockTime = SetupLockTime;
+ return TRUE;
+}
+
+#endif /* WSC_V2_SUPPORT */
+#endif /* WSC_AP_SUPPORT */
+
+
+
+#ifdef IAPP_SUPPORT
+INT Set_IappPID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ unsigned long IappPid;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IappPid = simple_strtol(arg, 0, 10);
+ RTMP_GET_OS_PID(pObj->IappPid, IappPid);
+ pObj->IappPid_nr = IappPid;
+
+/* DBGPRINT(RT_DEBUG_TRACE, ("pObj->IappPid = %d", GET_PID_NUMBER(pObj->IappPid))); */
+ return TRUE;
+} /* End of Set_IappPID_Proc */
+#endif /* IAPP_SUPPORT */
+
+
+INT Set_DisConnectSta_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR macAddr[MAC_ADDR_LEN];
+ PSTRING value;
+ INT i;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ 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++], 1);
+ }
+
+ pEntry = MacTableLookup(pAd, macAddr);
+ if (pEntry)
+ {
+ MlmeDeAuthAction(pAd, pEntry, REASON_DISASSOC_STA_LEAVING, FALSE);
+/* MacTableDeleteEntry(pAd, pEntry->Aid, Addr); */
+ }
+
+ return TRUE;
+}
+
+INT Set_DisConnectAllSta_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ {
+ MacTableReset(pAd);
+ }
+
+ return TRUE;
+}
+
+
+#ifdef DOT1X_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set IEEE8021X.
+ This parameter is 1 when 802.1x-wep turn on, otherwise 0
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_IEEE8021X_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG ieee8021x;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ ieee8021x = simple_strtol(arg, 0, 10);
+
+ if (ieee8021x == 1)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].IEEE8021X = TRUE;
+ else if (ieee8021x == 0)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].IEEE8021X = FALSE;
+ else
+ return FALSE; /*Invalid argument */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_IEEE8021X_Proc::(IEEE8021X=%d)\n", pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].IEEE8021X));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set pre-authentication enable or disable when WPA/WPA2 turn on
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_PreAuth_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG PreAuth;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ PreAuth = simple_strtol(arg, 0, 10);
+
+ if (PreAuth == 1)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].PreAuth = TRUE;
+ else if (PreAuth == 0)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].PreAuth = FALSE;
+ else
+ return FALSE; /*Invalid argument */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_PreAuth_Proc::(PreAuth=%d)\n", pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].PreAuth));
+
+ return TRUE;
+}
+
+INT Set_OwnIPAddr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT32 ip_addr;
+
+ if (rtinet_aton(arg, &ip_addr))
+ {
+ pAd->ApCfg.own_ip_addr = ip_addr;
+ DBGPRINT(RT_DEBUG_TRACE, ("own_ip_addr=%s(%x)\n", arg, pAd->ApCfg.own_ip_addr));
+ }
+ return TRUE;
+}
+
+INT Set_EAPIfName_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+ PSTRING macptr;
+
+ for (i=0, macptr = rstrtok(arg,";"); (macptr && i < MAX_MBSSID_NUM(pAd)); macptr = rstrtok(NULL,";"), i++)
+ {
+ if (strlen(macptr) > 0)
+ {
+ pAd->ApCfg.EAPifname_len[i] = strlen(macptr);
+ NdisMoveMemory(pAd->ApCfg.EAPifname[i], macptr, strlen(macptr));
+ DBGPRINT(RT_DEBUG_TRACE, ("NO.%d EAPifname=%s, len=%d\n", i,
+ pAd->ApCfg.EAPifname[i],
+ pAd->ApCfg.EAPifname_len[i]));
+ }
+ }
+ return TRUE;
+}
+
+INT Set_PreAuthIfName_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+ PSTRING macptr;
+
+ for (i=0, macptr = rstrtok(arg,";"); (macptr && i < MAX_MBSSID_NUM(pAd)); macptr = rstrtok(NULL,";"), i++)
+ {
+ if (strlen(macptr) > 0)
+ {
+ pAd->ApCfg.PreAuthifname_len[i] = strlen(macptr);
+ NdisMoveMemory(pAd->ApCfg.PreAuthifname[i], macptr, strlen(macptr));
+ DBGPRINT(RT_DEBUG_TRACE, ("NO.%d PreAuthifname=%s, len=%d\n", i,
+ pAd->ApCfg.PreAuthifname[i],
+ pAd->ApCfg.PreAuthifname_len[i]));
+ }
+ }
+ return TRUE;
+
+}
+
+INT Set_RADIUS_Server_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ PSTRING macptr;
+ INT count;
+ UINT32 ip_addr;
+ INT srv_cnt = 0;
+
+ for (count = 0, macptr = rstrtok(arg,";"); (macptr && count < MAX_RADIUS_SRV_NUM); macptr = rstrtok(NULL,";"), count++)
+ {
+ if (rtinet_aton(macptr, &ip_addr))
+ {
+ PRADIUS_SRV_INFO pSrvInfo = &pAd->ApCfg.MBSSID[apidx].radius_srv_info[srv_cnt];
+
+ pSrvInfo->radius_ip = ip_addr;
+ srv_cnt++;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), radius_ip(seq-%d)=%s(%x)\n",
+ apidx, srv_cnt, macptr,
+ pSrvInfo->radius_ip));
+ }
+ }
+
+ if (srv_cnt > 0)
+ pAd->ApCfg.MBSSID[apidx].radius_srv_num = srv_cnt;
+
+ return TRUE;
+}
+
+INT Set_RADIUS_Port_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ PSTRING macptr;
+ INT count;
+ INT srv_cnt = 0;
+
+ for (count = 0, macptr = rstrtok(arg,";"); (macptr && count < MAX_RADIUS_SRV_NUM); macptr = rstrtok(NULL,";"), count++)
+ {
+ if (srv_cnt < pAd->ApCfg.MBSSID[apidx].radius_srv_num)
+ {
+ PRADIUS_SRV_INFO pSrvInfo = &pAd->ApCfg.MBSSID[apidx].radius_srv_info[srv_cnt];
+
+ pSrvInfo->radius_port = (UINT32) simple_strtol(macptr, 0, 10);
+ srv_cnt ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), radius_port(seq-%d)=%d\n",
+ apidx, srv_cnt, pSrvInfo->radius_port));
+ }
+ }
+
+ return TRUE;
+}
+
+INT Set_RADIUS_Key_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ PSTRING macptr;
+ INT count;
+ INT srv_cnt = 0;
+
+ for (count = 0, macptr = rstrtok(arg,";"); (macptr && count < MAX_RADIUS_SRV_NUM); macptr = rstrtok(NULL,";"), count++)
+ {
+ if (strlen(macptr) > 0 && srv_cnt < pAd->ApCfg.MBSSID[apidx].radius_srv_num)
+ {
+ PRADIUS_SRV_INFO pSrvInfo = &pAd->ApCfg.MBSSID[apidx].radius_srv_info[srv_cnt];
+
+ pSrvInfo->radius_key_len = strlen(macptr);
+ NdisMoveMemory(pSrvInfo->radius_key, macptr, pSrvInfo->radius_key_len);
+ srv_cnt ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), radius_key(seq-%d)=%s, len=%d\n",
+ apidx, srv_cnt,
+ pSrvInfo->radius_key,
+ pSrvInfo->radius_key_len));
+ }
+ }
+ return TRUE;
+}
+#endif /* DOT1X_SUPPORT */
+
+#ifdef UAPSD_SUPPORT
+INT Set_UAPSD_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR IdMbss = pObj->ioctl_if;
+
+ if (simple_strtol(arg, 0, 10) != 0)
+ pAd->ApCfg.MBSSID[IdMbss].UapsdInfo.bAPSDCapable = TRUE;
+ else
+ pAd->ApCfg.MBSSID[IdMbss].UapsdInfo.bAPSDCapable = FALSE;
+ /* End of if */
+
+ return TRUE;
+} /* End of Set_UAPSD_Proc */
+#endif /* UAPSD_SUPPORT */
+
+
+
+#ifdef MCAST_RATE_SPECIFIC
+INT Set_McastPhyMode(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR PhyMode = simple_strtol(arg, 0, 10);
+
+ pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
+ switch (PhyMode)
+ {
+ case MCAST_DISABLE: /* disable */
+ NdisMoveMemory(&pAd->CommonCfg.MCastPhyMode, &pAd->MacTab.Content[MCAST_WCID].HTPhyMode, sizeof(HTTRANSMIT_SETTING));
+ break;
+
+ case MCAST_CCK: /* CCK */
+ pAd->CommonCfg.MCastPhyMode.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MCastPhyMode.field.BW = BW_20;
+ break;
+
+ case MCAST_OFDM: /* OFDM */
+ pAd->CommonCfg.MCastPhyMode.field.MODE = MODE_OFDM;
+ break;
+#ifdef DOT11_N_SUPPORT
+ case MCAST_HTMIX: /* HTMIX */
+ pAd->CommonCfg.MCastPhyMode.field.MODE = MODE_HTMIX;
+ break;
+#endif /* DOT11_N_SUPPORT */
+ default:
+ printk("unknow Muticast PhyMode %d.\n", PhyMode);
+ printk("0:Disable 1:CCK, 2:OFDM, 3:HTMIX.\n");
+ break;
+ }
+
+ return TRUE;
+}
+
+INT Set_McastMcs(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR Mcs = simple_strtol(arg, 0, 10);
+
+ if (Mcs > 15)
+ printk("Mcs must in range of 0 to 15\n");
+
+ switch(pAd->CommonCfg.MCastPhyMode.field.MODE)
+ {
+ case MODE_CCK:
+ if ((Mcs <= 3) || (Mcs >= 8 && Mcs <= 11))
+ pAd->CommonCfg.MCastPhyMode.field.MCS = Mcs;
+ else
+ printk("MCS must in range of 0 ~ 3 and 8 ~ 11 for CCK Mode.\n");
+ break;
+
+ case MODE_OFDM:
+ if (Mcs > 7)
+ printk("MCS must in range from 0 to 7 for CCK Mode.\n");
+ else
+ pAd->CommonCfg.MCastPhyMode.field.MCS = Mcs;
+ break;
+
+ default:
+ pAd->CommonCfg.MCastPhyMode.field.MCS = Mcs;
+ break;
+ }
+
+ return TRUE;
+}
+
+INT Show_McastRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ printk("Mcast PhyMode =%d\n", pAd->CommonCfg.MCastPhyMode.field.MODE);
+ printk("Mcast Mcs =%d\n", pAd->CommonCfg.MCastPhyMode.field.MCS);
+ return TRUE;
+}
+#endif /* MCAST_RATE_SPECIFIC */
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+INT Set_OBSSScanParam_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT ObssScanValue;
+ UINT Idx;
+ PSTRING thisChar;
+
+ Idx = 0;
+ while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+ {
+ ObssScanValue = (INT) simple_strtol(thisChar, 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;
+ }
+ Idx++;
+ }
+
+ if (Idx != 7)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong OBSSScanParamtetrs format in ioctl cmd!!!!! 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));
+
+ return TRUE;
+}
+
+
+INT Set_AP2040ReScan_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ APOverlappingBSSScan(pAd);
+
+ /* apply setting */
+ SetCommonHT(pAd);
+ AsicBBPAdjust(pAd);
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_AP2040ReScan_Proc() Trigger AP ReScan !!!\n"));
+
+ return TRUE;
+}
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+INT Set_EntryLifeCheck_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG LifeCheckCnt = (ULONG) simple_strtol(arg, 0, 10);
+
+ if (LifeCheckCnt <= 65535)
+ pAd->ApCfg.EntryLifeCheck = LifeCheckCnt;
+ else
+ printk("LifeCheckCnt must in range of 0 to 65535\n");
+
+ printk("EntryLifeCheck Cnt = %ld.\n", pAd->ApCfg.EntryLifeCheck);
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Authentication mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT ApCfg_Set_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PSTRING arg)
+{
+ if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen;
+ else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeShared;
+ else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA2PSK;
+ else if ((strcmp(arg, "WPAPSKWPA2PSK") == 0) || (strcmp(arg, "wpapskwpa2psk") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA1PSKWPA2PSK;
+#ifdef DOT1X_SUPPORT
+ else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA;
+ else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA2;
+ else if ((strcmp(arg, "WPA1WPA2") == 0) || (strcmp(arg, "wpa1wpa2") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA1WPA2;
+#endif /* DOT1X_SUPPORT */
+#ifdef WAPI_SUPPORT
+ else if ((strcmp(arg, "WAICERT") == 0) || (strcmp(arg, "waicert") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWAICERT;
+ else if ((strcmp(arg, "WAIPSK") == 0) || (strcmp(arg, "waipsk") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWAIPSK;
+#endif /* WAPI_SUPPORT */
+ else
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d)::AuthMode=%d\n", apidx, pAd->ApCfg.MBSSID[apidx].AuthMode));
+
+ return TRUE;
+}
+
+INT ApCfg_Set_MaxStaNum_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PSTRING arg)
+{
+ pAd->ApCfg.MBSSID[apidx].MaxStaNum = (UCHAR)simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) %s::(MaxStaNum=%d)\n",
+ apidx, __FUNCTION__, pAd->ApCfg.MBSSID[apidx].MaxStaNum));
+ return TRUE;
+}
+
+INT ApCfg_Set_IdleTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ LONG idle_time;
+
+ idle_time = simple_strtol(arg, 0, 10);
+
+ if (idle_time < MAC_TABLE_MIN_AGEOUT_TIME)
+ pAd->ApCfg.StaIdleTimeout = MAC_TABLE_MIN_AGEOUT_TIME;
+ else
+ pAd->ApCfg.StaIdleTimeout = idle_time;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : IdleTimeout=%d\n", __FUNCTION__, pAd->ApCfg.StaIdleTimeout));
+
+ return TRUE;
+}
+
+
+
+
+
+
+INT Set_MemDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+#ifdef VENDOR_FEATURE2_SUPPORT
+ printk("Number of Packet Allocated = %lu\n", OS_NumOfPktAlloc);
+ printk("Number of Packet Freed = %lu\n", OS_NumOfPktFree);
+ printk("Offset of Packet Allocated/Freed = %lu\n", OS_NumOfPktAlloc - OS_NumOfPktFree);
+#endif /* VENDOR_FEATURE2_SUPPORT */
+ return TRUE;
+}
+
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+VOID RTMPApCliAddKey(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PNDIS_APCLI_802_11_KEY pKey)
+{
+ ULONG KeyIdx;
+ MAC_TABLE_ENTRY *pEntry;
+ INT ifIndex,BssIdx;
+ PAPCLI_STRUCT pApCliEntry;
+ MAC_TABLE_ENTRY *pMacEntry=(MAC_TABLE_ENTRY *)NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPApCliAddKey ------>\n"));
+
+ ifIndex=apidx;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID];
+ BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + ifIndex;
+
+ if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ if (pApCliEntry->AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ NdisZeroMemory(pApCliEntry->PMK, 32);
+ NdisMoveMemory(pApCliEntry->PMK, pKey->KeyMaterial, pKey->KeyLength);
+ goto end;
+ }
+ /* Update PTK */
+ NdisZeroMemory(&pMacEntry->PairwiseKey, sizeof(CIPHER_KEY));
+ pMacEntry->PairwiseKey.KeyLen = LEN_TK;
+ NdisMoveMemory(pMacEntry->PairwiseKey.Key, pKey->KeyMaterial, LEN_TK);
+
+ if (pApCliEntry->PairCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pMacEntry->PairwiseKey.RxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC);
+ NdisMoveMemory(pMacEntry->PairwiseKey.TxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC);
+ }
+ else
+
+ {
+ NdisMoveMemory(pMacEntry->PairwiseKey.TxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC);
+ NdisMoveMemory(pMacEntry->PairwiseKey.RxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC);
+ }
+
+ /* Decide its ChiperAlg */
+ if (pApCliEntry->PairCipher == Ndis802_11Encryption2Enabled)
+ pMacEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
+ else if (pApCliEntry->PairCipher == Ndis802_11Encryption3Enabled)
+ pMacEntry->PairwiseKey.CipherAlg = CIPHER_AES;
+ else
+ pMacEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ (UCHAR)pMacEntry->Aid,
+ &pMacEntry->PairwiseKey);
+
+ RTMPSetWcidSecurityInfo(pAd,
+ BssIdx,
+ 0,
+ pMacEntry->PairwiseKey.CipherAlg,
+ (UCHAR)pMacEntry->Aid,
+ PAIRWISEKEYTABLE);
+
+ if (pMacEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ /* set 802.1x port control */
+ pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ pMacEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ }
+ }
+ else
+ {
+ /* Update GTK */
+ pApCliEntry->DefaultKeyId = (pKey->KeyIndex & 0xFF);
+ NdisZeroMemory(&pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId], sizeof(CIPHER_KEY));
+ pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].KeyLen = LEN_TK;
+ NdisMoveMemory(pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].Key, pKey->KeyMaterial, LEN_TK);
+
+ if (pApCliEntry->GroupCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC);
+ NdisMoveMemory(pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC);
+ }
+ else
+
+ {
+ NdisMoveMemory(pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TK, LEN_TKIP_MIC);
+ NdisMoveMemory(pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TK + LEN_TKIP_MIC, LEN_TKIP_MIC);
+ }
+
+ /* Update Shared Key CipherAlg */
+ pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pApCliEntry->GroupCipher == Ndis802_11Encryption2Enabled)
+ pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pApCliEntry->GroupCipher == Ndis802_11Encryption3Enabled)
+ pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ /* Update group key information to ASIC Shared Key Table */
+ AsicAddSharedKeyEntry(pAd,
+ BssIdx,
+ pApCliEntry->DefaultKeyId,
+ &pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId]);
+
+
+
+ /* Update ASIC WCID attribute table and IVEIV table */
+ RTMPAddWcidAttributeEntry(pAd,
+ BssIdx,
+ pApCliEntry->DefaultKeyId,
+ pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].CipherAlg,
+ NULL);
+
+
+ /* set 802.1x port control */
+ if (pMacEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ /* set 802.1x port control */
+ pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ pMacEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ }
+ }
+ }
+ 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 && IS_ENTRY_APCLI(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,
+ BssIdx,
+ KeyIdx,
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry->Aid,
+ PAIRWISEKEYTABLE);
+ }
+ }
+ else
+ {
+ /* Default key for tx (shared key) */
+ pApCliEntry->DefaultKeyId = (UCHAR) KeyIdx;
+
+ /*/ set key material and key length */
+ pApCliEntry->SharedKey[KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
+ NdisMoveMemory(pApCliEntry->SharedKey[KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ /* Set Ciper type */
+ if (pKey->KeyLength == 5)
+ pApCliEntry->SharedKey[KeyIdx].CipherAlg = CIPHER_WEP64;
+ else
+ pApCliEntry->SharedKey[KeyIdx].CipherAlg = CIPHER_WEP128;
+
+ CipherAlg = pApCliEntry->SharedKey[KeyIdx].CipherAlg;
+ Key = pApCliEntry->SharedKey[KeyIdx].Key;
+
+ /* Set Group key material to Asic */
+ AsicAddSharedKeyEntry(pAd, BssIdx, KeyIdx, &pApCliEntry->SharedKey[KeyIdx]);
+
+ /* STA doesn't need to set WCID attribute for group key */
+
+ /* Update WCID attribute table and IVEIV table for this group key table */
+ RTMPAddWcidAttributeEntry(pAd, BssIdx, KeyIdx, CipherAlg, NULL);
+
+ }
+ }
+ }
+end:
+
+ DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPApCliAddKey\n"));
+
+ return;
+}
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Set power save life time.
+
+Arguments:
+ pAd - WLAN control block pointer
+ Arg - Input arguments
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+INT Set_PowerSaveLifeTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->MacTab.MsduLifeTime = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set new life time = %d\n", pAd->MacTab.MsduLifeTime));
+ return TRUE;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef MBSS_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Show MBSS information.
+
+Arguments:
+ pAd - WLAN control block pointer
+ Arg - Input arguments
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+INT Show_MbssInfo_Display_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT32 IdBss;
+ UCHAR PhyMode;
+
+
+ DBGPRINT(RT_DEBUG_ERROR, ("\n\tBSS Idx\t\tPhy Mode\n"));
+
+ for(IdBss=0; IdBss<=pAd->ApCfg.BssidNum; IdBss++)
+ {
+ if (IdBss == 0)
+ {
+ PhyMode = pAd->CommonCfg.PhyMode;
+ DBGPRINT(RT_DEBUG_ERROR, ("\tMAX\t\t"));
+ }
+ else
+ {
+ PhyMode = pAd->ApCfg.MBSSID[IdBss-1].PhyMode;
+ DBGPRINT(RT_DEBUG_ERROR, ("\t%d\t\t", IdBss-1));
+ } /* End of if */
+
+ switch(PhyMode)
+ {
+ case (WMODE_B | WMODE_G):
+ DBGPRINT(RT_DEBUG_ERROR, ("BG Mixed\n"));
+ break;
+
+ case (WMODE_B):
+ DBGPRINT(RT_DEBUG_ERROR, ("B Only\n"));
+ break;
+
+ case (WMODE_A):
+ DBGPRINT(RT_DEBUG_ERROR, ("A Only\n"));
+ break;
+
+ case (WMODE_A | WMODE_B | WMODE_G):
+ DBGPRINT(RT_DEBUG_ERROR, ("ABG Mixed ==> BG Mixed\n"));
+ break;
+
+ case (WMODE_G):
+ DBGPRINT(RT_DEBUG_ERROR, ("G Only\n"));
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_A | WMODE_B | WMODE_G | WMODE_AN | WMODE_GN):
+ DBGPRINT(RT_DEBUG_ERROR, ("ABGN Mixed ==> BGN Mixed\n"));
+ break;
+
+ case (WMODE_GN):
+ DBGPRINT(RT_DEBUG_ERROR, ("2.4G N Only\n"));
+ break;
+
+ case (WMODE_G | WMODE_GN):
+ DBGPRINT(RT_DEBUG_ERROR, ("GN Mixed\n"));
+ break;
+
+ case (WMODE_A | WMODE_AN):
+ DBGPRINT(RT_DEBUG_ERROR, ("AN Mixed\n"));
+ break;
+
+ case (WMODE_B | WMODE_G | WMODE_GN):
+ DBGPRINT(RT_DEBUG_ERROR, ("BGN Mixed\n"));
+ break;
+
+ case (WMODE_A | WMODE_G | WMODE_GN | WMODE_AN):
+ DBGPRINT(RT_DEBUG_ERROR, ("AGN Mixed\n"));
+ break;
+
+ case (WMODE_AN):
+ DBGPRINT(RT_DEBUG_ERROR, ("5G N Only\n"));
+ break;
+#endif /* DOT11_N_SUPPORT */
+ } /* End of switch */
+ } /* End of for */
+
+ DBGPRINT(RT_DEBUG_ERROR, ("\n"));
+
+ return TRUE;
+} /* End of Show_MbssInfo_Display_Proc */
+#endif /* MBSS_SUPPORT */
+
+
+#ifdef HOSTAPD_SUPPORT
+VOID RtmpHostapdSecuritySet(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrqin)
+{
+ if(wrqin->u.data.length > 20 && MAX_LEN_OF_RSNIE > wrqin->u.data.length && wrqin->u.data.pointer)
+ {
+ UCHAR RSNIE_Len[2];
+ UCHAR RSNIe[2];
+ int offset_next_ie=0;
+
+ DBGPRINT(RT_DEBUG_TRACE,("ioctl SIOCSIWGENIE pAd->IoctlIF=%d\n",apidx));
+
+ RSNIe[0]=*(UINT8 *)wrqin->u.data.pointer;
+ if(IE_WPA != RSNIe[0] && IE_RSN != RSNIe[0] )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("IE %02x != 0x30/0xdd\n",RSNIe[0]));
+ Status = -EINVAL;
+ break;
+ }
+ RSNIE_Len[0]=*((UINT8 *)wrqin->u.data.pointer + 1);
+ if(wrqin->u.data.length != RSNIE_Len[0]+2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("IE use WPA1 WPA2\n"));
+ NdisZeroMemory(pAd->ApCfg.MBSSID[apidx].RSN_IE[1], MAX_LEN_OF_RSNIE);
+ RSNIe[1]=*(UINT8 *)wrqin->u.data.pointer;
+ RSNIE_Len[1]=*((UINT8 *)wrqin->u.data.pointer + 1);
+ DBGPRINT(RT_DEBUG_TRACE,( "IE1 %02x %02x\n",RSNIe[1],RSNIE_Len[1]));
+ pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1] = RSNIE_Len[1];
+ NdisMoveMemory(pAd->ApCfg.MBSSID[apidx].RSN_IE[1], (UCHAR *)(wrqin->u.data.pointer)+2, RSNIE_Len[1]);
+ offset_next_ie=RSNIE_Len[1]+2;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE,("IE use only %02x\n",RSNIe[0]));
+
+ NdisZeroMemory(pAd->ApCfg.MBSSID[apidx].RSN_IE[0], MAX_LEN_OF_RSNIE);
+ RSNIe[0]=*(((UINT8 *)wrqin->u.data.pointer)+offset_next_ie);
+ RSNIE_Len[0]=*(((UINT8 *)wrqin->u.data.pointer) + offset_next_ie + 1);
+ if(IE_WPA != RSNIe[0] && IE_RSN != RSNIe[0] )
+ {
+ Status = -EINVAL;
+ break;
+ }
+ pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0] = RSNIE_Len[0];
+ NdisMoveMemory(pAd->ApCfg.MBSSID[apidx].RSN_IE[0], ((UCHAR *)(wrqin->u.data.pointer))+2+offset_next_ie, RSNIE_Len[0]);
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+ }
+}
+#endif /* HOSTAPD_SUPPORT */
+
+
+/*
+========================================================================
+Routine Description:
+ Driver Ioctl for AP.
+
+Arguments:
+ pAdSrc - WLAN control block pointer
+ wrq - the IOCTL parameters
+ cmd - the command ID
+ subcmd - the sub-command ID
+ pData - the IOCTL private data pointer
+ Data - the IOCTL private data
+
+Return Value:
+ NDIS_STATUS_SUCCESS - IOCTL OK
+ Otherwise - IOCTL fail
+
+Note:
+========================================================================
+*/
+INT RTMP_AP_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;
+
+
+ switch(cmd)
+ {
+ case CMD_RTPRIV_IOCTL_SET:
+ Status = RTMPAPPrivIoctlSet(pAd, wrq);
+ break;
+
+ case CMD_RT_PRIV_IOCTL:
+ if (subcmd & OID_GET_SET_TOGGLE)
+ Status = RTMPAPSetInformation(pAd, wrq, (INT)subcmd);
+ else
+ {
+#ifdef LLTD_SUPPORT
+ if (subcmd == RT_OID_GET_PHY_MODE)
+ {
+ if(pData != NULL)
+ {
+ UINT modetmp = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::Get phy mode (%02X) \n", pAd->CommonCfg.PhyMode));
+ modetmp = (UINT) pAd->CommonCfg.PhyMode;
+ wrq->u.data.length = 1;
+ /**(ULONG *)pData = (ULONG)pAd->CommonCfg.PhyMode; */
+ if (copy_to_user(pData, &modetmp, wrq->u.data.length))
+ Status = -EFAULT;
+ }
+ else
+ Status = -EFAULT;
+ }
+ else
+#endif /* LLTD_SUPPORT */
+ Status = RTMPAPQueryInformation(pAd, wrq, (INT)subcmd);
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_SHOW:
+ Status = RTMPAPPrivIoctlShow(pAd, wrq);
+ break;
+
+#ifdef WSC_AP_SUPPORT
+ case CMD_RTPRIV_IOCTL_SET_WSCOOB:
+ RTMPIoctlSetWSCOOB(pAd);
+ break;
+#endif/*WSC_AP_SUPPORT*/
+
+ case CMD_RTPRIV_IOCTL_GET_MAC_TABLE:
+ RTMPIoctlGetMacTable(pAd,wrq);
+ break;
+
+#if defined (AP_SCAN_SUPPORT) || defined (CONFIG_STA_SUPPORT)
+ case CMD_RTPRIV_IOCTL_GSITESURVEY:
+ RTMPIoctlGetSiteSurvey(pAd,wrq);
+ break;
+#endif /* AP_SCAN_SUPPORT */
+
+ case CMD_RTPRIV_IOCTL_STATISTICS:
+ RTMPIoctlStatistics(pAd, wrq);
+ break;
+
+#ifdef WSC_AP_SUPPORT
+ case CMD_RTPRIV_IOCTL_WSC_PROFILE:
+ RTMPIoctlWscProfile(pAd, wrq);
+ break;
+#endif /* WSC_AP_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ case CMD_RTPRIV_IOCTL_QUERY_BATABLE:
+ RTMPIoctlQueryBaTable(pAd, wrq);
+ break;
+#endif /* DOT11_N_SUPPORT */
+
+ case CMD_RTPRIV_IOCTL_E2P:
+ RTMPAPIoctlE2PROM(pAd, wrq);
+ break;
+
+#ifdef DBG
+ case CMD_RTPRIV_IOCTL_BBP:
+ RTMPAPIoctlBBP(pAd, wrq);
+ break;
+
+ case CMD_RTPRIV_IOCTL_MAC:
+ RTMPAPIoctlMAC(pAd, wrq);
+ break;
+
+ case CMD_RTPRIV_IOCTL_RF:
+ RTMPAPIoctlRF(pAd, wrq);
+ break;
+#endif /* DBG */
+
+#ifdef INF_AR9
+#ifdef AR9_MAPI_SUPPORT
+ case CMD_RTPRIV_IOCTL_GET_AR9_SHOW:
+ Status = RTMPAPPrivIoctlAR9Show(pAd, wrq);
+ break;
+#endif /*AR9_MAPI_SUPPORT*/
+#endif/* INF_AR9 */
+
+ case CMD_RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT:
+ break;
+
+ case CMD_RTPRIV_IOCTL_AP_SIOCGIFHWADDR:
+ if (pObj->ioctl_if < MAX_MBSSID_NUM(pAd))
+ NdisCopyMemory((PSTRING) wrq->u.name, (PSTRING) pAd->ApCfg.MBSSID[pObj->ioctl_if].Bssid, 6);
+ break;
+
+ case CMD_RTPRIV_IOCTL_AP_SIOCGIWESSID:
+ {
+ RT_CMD_AP_IOCTL_SSID *pSSID = (RT_CMD_AP_IOCTL_SSID *)pData;
+
+#ifdef APCLI_SUPPORT
+ if (pSSID->priv_flags == INT_APCLI)
+ {
+ if (pAd->ApCfg.ApCliTab[pObj->ioctl_if].Valid == TRUE)
+ {
+ pSSID->length = pAd->ApCfg.ApCliTab[pObj->ioctl_if].SsidLen;
+ pSSID->pSsidStr = (char *)&pAd->ApCfg.ApCliTab[pObj->ioctl_if].Ssid;
+ }
+ else {
+ pSSID->length = 0;
+ pSSID->pSsidStr = NULL;
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ pSSID->length = pAd->ApCfg.MBSSID[pSSID->apidx].SsidLen;
+ pSSID->pSsidStr = (char *)pAd->ApCfg.MBSSID[pSSID->apidx].Ssid;
+ }
+ }
+ break;
+
+#ifdef MBSS_SUPPORT
+ case CMD_RTPRIV_IOCTL_MBSS_BEACON_UPDATE:
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+ break;
+
+ case CMD_RTPRIV_IOCTL_MBSS_OPEN:
+ if (MBSS_Open(pData) != 0)
+ return NDIS_STATUS_FAILURE;
+ break;
+
+ case CMD_RTPRIV_IOCTL_MBSS_CLOSE:
+ MBSS_Close(pData);
+ break;
+
+ case CMD_RTPRIV_IOCTL_MBSS_INIT:
+ MBSS_Init(pAd, pData);
+ break;
+
+ case CMD_RTPRIV_IOCTL_MBSS_REMOVE:
+ MBSS_Remove(pAd);
+ break;
+#endif /* MBSS_SUPPORT */
+
+ case CMD_RTPRIV_IOCTL_WSC_INIT:
+ {
+#ifdef APCLI_SUPPORT
+#ifdef WSC_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ PWSC_V2_INFO pWscV2Info;
+#endif /* WSC_V2_SUPPORT */
+ APCLI_STRUCT *pApCliEntry = (APCLI_STRUCT *)pData;
+ WscGenerateUUID(pAd, &pApCliEntry->WscControl.Wsc_Uuid_E[0],
+ &pApCliEntry->WscControl.Wsc_Uuid_Str[0], 0, FALSE);
+ pApCliEntry->WscControl.bWscFragment = FALSE;
+ pApCliEntry->WscControl.WscFragSize = 128;
+ pApCliEntry->WscControl.WscRxBufLen = 0;
+ pApCliEntry->WscControl.pWscRxBuf = NULL;
+ os_alloc_mem(pAd, &pApCliEntry->WscControl.pWscRxBuf, MGMT_DMA_BUFFER_SIZE);
+ if (pApCliEntry->WscControl.pWscRxBuf)
+ NdisZeroMemory(pApCliEntry->WscControl.pWscRxBuf, MGMT_DMA_BUFFER_SIZE);
+ pApCliEntry->WscControl.WscTxBufLen = 0;
+ pApCliEntry->WscControl.pWscTxBuf = NULL;
+ os_alloc_mem(pAd, &pApCliEntry->WscControl.pWscTxBuf, MGMT_DMA_BUFFER_SIZE);
+ if (pApCliEntry->WscControl.pWscTxBuf)
+ NdisZeroMemory(pApCliEntry->WscControl.pWscTxBuf, MGMT_DMA_BUFFER_SIZE);
+ initList(&pApCliEntry->WscControl.WscPeerList);
+ NdisAllocateSpinLock(pAd, &pApCliEntry->WscControl.WscPeerListSemLock);
+ pApCliEntry->WscControl.PinAttackCount = 0;
+ pApCliEntry->WscControl.bSetupLock = FALSE;
+#ifdef WSC_V2_SUPPORT
+ pWscV2Info = &pApCliEntry->WscControl.WscV2Info;
+ pWscV2Info->bWpsEnable = TRUE;
+ pWscV2Info->ExtraTlv.TlvLen = 0;
+ pWscV2Info->ExtraTlv.TlvTag = 0;
+ pWscV2Info->ExtraTlv.pTlvData = NULL;
+ pWscV2Info->ExtraTlv.TlvType = TLV_ASCII;
+ pWscV2Info->bEnableWpsV2 = TRUE;
+#endif /* WSC_V2_SUPPORT */
+ WscInit(pAd, TRUE, Data);
+#endif /* WSC_AP_SUPPORT */
+#endif /* APCLI_SUPPORT */
+ }
+ break;
+
+#ifdef APCLI_SUPPORT
+ case CMD_RTPRIV_IOCTL_APC_UP:
+ ApCliIfUp(pAd);
+ break;
+
+ case CMD_RTPRIV_IOCTL_APC_DISCONNECT:
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, Data);
+ RTMP_MLME_HANDLER(pAd);
+ break;
+
+ case CMD_RTPRIV_IOCTL_APC_INIT:
+ APCli_Init(pAd, pData);
+ break;
+
+ case CMD_RTPRIV_IOCTL_APC_OPEN:
+ if (ApCli_Open(pAd, pData) != TRUE)
+ return NDIS_STATUS_FAILURE;
+ break;
+
+ case CMD_RTPRIV_IOCTL_APC_CLOSE:
+ if (ApCli_Close(pAd, pData) != TRUE)
+ return NDIS_STATUS_FAILURE;
+ break;
+
+ case CMD_RTPRIV_IOCTL_APC_REMOVE:
+ ApCli_Remove(pAd);
+ break;
+#endif /* APCLI_SUPPORT */
+
+ case CMD_RTPRIV_IOCTL_MAIN_OPEN:
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE;
+ break;
+
+ case CMD_RTPRIV_IOCTL_PREPARE:
+ {
+ RT_CMD_AP_IOCTL_CONFIG *pConfig = (RT_CMD_AP_IOCTL_CONFIG *)pData;
+ pConfig->Status = RTMP_AP_IoctlPrepare(pAd, pData);
+ if (pConfig->Status != 0)
+ return NDIS_STATUS_FAILURE;
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_AP_SIOCGIWAP:
+ {
+ UCHAR *pBssidDest = (UCHAR *)pData;
+ PCHAR pBssidStr;
+
+#ifdef APCLI_SUPPORT
+ if (Data == INT_APCLI)
+ {
+ if (pAd->ApCfg.ApCliTab[pObj->ioctl_if].Valid == TRUE)
+ pBssidStr = (PCHAR)&APCLI_ROOT_BSSID_GET(pAd, pAd->ApCfg.ApCliTab[pObj->ioctl_if].MacTabWCID);
+ else
+ pBssidStr = NULL;
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ pBssidStr = (PCHAR) &pAd->ApCfg.MBSSID[pObj->ioctl_if].Bssid[0];
+ }
+
+ if (pBssidStr != NULL)
+ {
+ memcpy(pBssidDest, pBssidStr, ETH_ALEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ pBssidStr[0],pBssidStr[1],pBssidStr[2], pBssidStr[3],pBssidStr[4],pBssidStr[5]));
+ }
+ else
+ {
+ memset(pBssidDest, 0, ETH_ALEN);
+ }
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_AP_SIOCGIWRATEQ:
+ /* handle for SIOCGIWRATEQ */
+ {
+ RT_CMD_IOCTL_RATE *pRate = (RT_CMD_IOCTL_RATE *)pData;
+ HTTRANSMIT_SETTING HtPhyMode;
+
+#ifdef APCLI_SUPPORT
+ if (pRate->priv_flags == INT_APCLI)
+ HtPhyMode = pAd->ApCfg.ApCliTab[pObj->ioctl_if].HTPhyMode;
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (pRate->priv_flags == INT_WDS)
+ HtPhyMode = pAd->WdsTab.WdsEntry[pObj->ioctl_if].HTPhyMode;
+ else
+#endif /* WDS_SUPPORT */
+ {
+ HtPhyMode = pAd->ApCfg.MBSSID[pObj->ioctl_if].HTPhyMode;
+
+#ifdef MBSS_SUPPORT
+ /* reset phy mode for MBSS */
+ MBSS_PHY_MODE_RESET(pObj->ioctl_if, HtPhyMode);
+#endif /* MBSS_SUPPORT */
+ }
+
+ RtmpDrvMaxRateGet(pAd, HtPhyMode.field.MODE, HtPhyMode.field.ShortGI,
+ HtPhyMode.field.BW, HtPhyMode.field.MCS,
+ (UINT32 *)&pRate->BitRate);
+ }
+ break;
+
+#ifdef HOSTAPD_SUPPORT
+ case CMD_RTPRIV_IOCTL_AP_SIOCGIWRATEQ:
+ RtmpHostapdSecuritySet(pAd, wrq);
+ break;
+#endif /* HOSTAPD_SUPPORT */
+
+ default:
+ Status = RTMP_COM_IoctlHandle(pAd, wrq, cmd, subcmd, pData, Data);
+ break;
+ }
+
+ return Status;
+}
+
+
+INT Set_LoopBackFlag_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+ pAd->bloopBackTest = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("LoopBackFlag = %d \n", pAd->bloopBackTest));
+
+ return TRUE;
+}
+
+INT Set_TestTxFrameProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ LONG WirelessMode;
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+ UINT32 Value1 = 0;
+ UCHAR tempMAC[MAC_ADDR_LEN] = {0x00,0x11,0x22,0x33,0x44,0x55};
+
+ WirelessMode = simple_strtol(arg, 0, 10);
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value1);
+ if (Value1 == 0x2c)
+ pAd->bloopBackTest = 1;
+ else
+ pAd->bloopBackTest = 0;
+
+ // allocate one MAC entry
+ pMacEntry = MacTableLookup(pAd, tempMAC);
+ if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry))
+ DBGPRINT(RT_DEBUG_ERROR,("MacTable Entry exist !!!\n"));
+ else
+ pMacEntry = MacTableInsertEntry(pAd, tempMAC, BSS0, OPMODE_AP, TRUE);
+
+ if (pMacEntry)
+ {
+ pMacEntry->AuthMode = Ndis802_11AuthModeOpen;
+ pMacEntry->WepStatus = Ndis802_11WEPDisabled;
+ pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ pMacEntry->Sst = SST_ASSOC;
+
+ pMacEntry->MaxSupportedRate = RATE_54;
+
+ if (pMacEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pMacEntry->MaxHTPhyMode.field.MCS = pMacEntry->MaxSupportedRate;
+ pMacEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pMacEntry->MinHTPhyMode.field.MCS = pMacEntry->MaxSupportedRate;
+ pMacEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pMacEntry->HTPhyMode.field.MCS = pMacEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pMacEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pMacEntry->MaxSupportedRate];
+ pMacEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pMacEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pMacEntry->MaxSupportedRate];
+ pMacEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pMacEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pMacEntry->MaxSupportedRate];
+ }
+
+ // Set WMM capability
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) || (pAd->CommonCfg.bWmmCapable))
+ {
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ UCHAR j, bitmask; /*k,bitmask; */
+ CHAR i;
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pMacEntry->MaxHTPhyMode.field.BW= BW_40;
+ pMacEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pMacEntry->MaxHTPhyMode.field.BW = BW_20;
+ pMacEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pAd->CommonCfg.HtCapability.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->ApCfg.MBSSID[pMacEntry->apidx].DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pAd->CommonCfg.HtCapability.MCSSet[j] & bitmask))
+ {
+ pMacEntry->MaxHTPhyMode.field.MCS = i;
+ break;
+ }
+ if (i==0)
+ break;
+ }
+
+
+ if (pAd->ApCfg.MBSSID[pMacEntry->apidx].DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("@@@ IF-ra%d DesiredTransmitSetting.field.MCS = %d\n", pMacEntry->apidx,
+ pAd->ApCfg.MBSSID[pMacEntry->apidx].DesiredTransmitSetting.field.MCS));
+ if (pAd->ApCfg.MBSSID[pMacEntry->apidx].DesiredTransmitSetting.field.MCS == 32)
+ {
+ /* Fix MCS as HT Duplicated Mode */
+ pMacEntry->MaxHTPhyMode.field.BW = 1;
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pMacEntry->MaxHTPhyMode.field.STBC = 0;
+ pMacEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pMacEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pMacEntry->MaxHTPhyMode.field.MCS > pAd->ApCfg.MBSSID[pMacEntry->apidx].HTPhyMode.field.MCS)
+ {
+ /* STA supports fixed MCS */
+ pMacEntry->MaxHTPhyMode.field.MCS = pAd->ApCfg.MBSSID[pMacEntry->apidx].HTPhyMode.field.MCS;
+ }
+ }
+
+ pMacEntry->MaxHTPhyMode.field.STBC = (pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ if (pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity < 5)
+ pMacEntry->MpduDensity = 5;
+ else
+ pMacEntry->MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+ pMacEntry->MaxRAmpduFactor = pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor;
+ pMacEntry->MmpsMode = (UCHAR)pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs;
+ pMacEntry->AMsduSize = (UCHAR)pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize;
+ pMacEntry->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word;
+
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ /* Record the received capability from association request */
+ NdisMoveMemory(&pMacEntry->HTCapability, &pAd->CommonCfg.HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+ else
+ {
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ NdisZeroMemory(&pMacEntry->HTCapability, sizeof(HT_CAPABILITY_IE));
+ }
+
+ pMacEntry->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word;
+ pMacEntry->CurrTxRate = pMacEntry->MaxSupportedRate;
+ }
+
+ {
+ UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d};
+ UCHAR Header802_3[14];
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ ULONG TempLen;
+ UCHAR idxCount;
+ ULONG TmpLen1 = 0;
+ UCHAR RalinkIe[10] = {0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf};
+ NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS;
+
+ MAKE_802_3_HEADER(Header802_3, tempMAC, pAd->CurrentAddress, TDLS_ETHERTYPE);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ for (idxCount = 0; idxCount < WirelessMode; idxCount++)
+ {
+ //ULONG TmpLen1 = 0;
+ //UCHAR RalinkIe[10] = {0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5};
+ TmpLen1 = 0;
+
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen1,
+ 10, RalinkIe,
+ END_OF_ARGS);
+
+ FrameLen = FrameLen + TmpLen1;
+ }
+
+ RTMPToWirelessSta(pAd, pMacEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ return TRUE;
+
+}
+
+INT Set_TestTxFrame1Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+ UCHAR tempMAC[MAC_ADDR_LEN] = {0x00,0x0C,0x43,0x33,0x52,0xb8};
+ PSTRING value;
+ INT i;
+ UINT32 Value1 = 0;
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value1);
+ if (Value1 == 0x2c)
+ pAd->bloopBackTest = 1;
+ else
+ pAd->bloopBackTest = 0;
+
+ 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, &tempMAC[i++], 1);
+ }
+
+ // allocate one MAC entry
+ pMacEntry = MacTableLookup(pAd, tempMAC);
+ if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry))
+ DBGPRINT(RT_DEBUG_ERROR,("MacTable Entry exist !!!\n"));
+ else
+ pMacEntry = MacTableInsertEntry(pAd, tempMAC, BSS0, OPMODE_AP, TRUE);
+
+ if (pMacEntry)
+ {
+ pMacEntry->AuthMode = Ndis802_11AuthModeOpen;
+ pMacEntry->WepStatus = Ndis802_11WEPDisabled;
+ pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ pMacEntry->Sst = SST_ASSOC;
+
+ pMacEntry->MaxSupportedRate = RATE_54;
+
+ if (pMacEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pMacEntry->MaxHTPhyMode.field.MCS = pMacEntry->MaxSupportedRate;
+ pMacEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pMacEntry->MinHTPhyMode.field.MCS = pMacEntry->MaxSupportedRate;
+ pMacEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pMacEntry->HTPhyMode.field.MCS = pMacEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pMacEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pMacEntry->MaxSupportedRate];
+ pMacEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pMacEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pMacEntry->MaxSupportedRate];
+ pMacEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pMacEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pMacEntry->MaxSupportedRate];
+ }
+
+ // Set WMM capability
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) || (pAd->CommonCfg.bWmmCapable))
+ {
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ UCHAR j, bitmask; /*k,bitmask; */
+ CHAR i;
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pMacEntry->MaxHTPhyMode.field.BW= BW_40;
+ pMacEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pMacEntry->MaxHTPhyMode.field.BW = BW_20;
+ pMacEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pAd->CommonCfg.HtCapability.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->ApCfg.MBSSID[pMacEntry->apidx].DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pAd->CommonCfg.HtCapability.MCSSet[j] & bitmask))
+ {
+ pMacEntry->MaxHTPhyMode.field.MCS = i;
+ break;
+ }
+ if (i==0)
+ break;
+ }
+
+
+ if (pAd->ApCfg.MBSSID[pMacEntry->apidx].DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("@@@ IF-ra%d DesiredTransmitSetting.field.MCS = %d\n", pMacEntry->apidx,
+ pAd->ApCfg.MBSSID[pMacEntry->apidx].DesiredTransmitSetting.field.MCS));
+ if (pAd->ApCfg.MBSSID[pMacEntry->apidx].DesiredTransmitSetting.field.MCS == 32)
+ {
+ /* Fix MCS as HT Duplicated Mode */
+ pMacEntry->MaxHTPhyMode.field.BW = 1;
+ pMacEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pMacEntry->MaxHTPhyMode.field.STBC = 0;
+ pMacEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pMacEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pMacEntry->MaxHTPhyMode.field.MCS > pAd->ApCfg.MBSSID[pMacEntry->apidx].HTPhyMode.field.MCS)
+ {
+ /* STA supports fixed MCS */
+ pMacEntry->MaxHTPhyMode.field.MCS = pAd->ApCfg.MBSSID[pMacEntry->apidx].HTPhyMode.field.MCS;
+ }
+ }
+
+ pMacEntry->MaxHTPhyMode.field.STBC = (pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ if (pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity < 5)
+ pMacEntry->MpduDensity = 5;
+ else
+ pMacEntry->MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+ pMacEntry->MaxRAmpduFactor = pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor;
+ pMacEntry->MmpsMode = (UCHAR)pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs;
+ pMacEntry->AMsduSize = (UCHAR)pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize;
+ pMacEntry->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word;
+
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pMacEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ /* Record the received capability from association request */
+ NdisMoveMemory(&pMacEntry->HTCapability, &pAd->CommonCfg.HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+ else
+ {
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ NdisZeroMemory(&pMacEntry->HTCapability, sizeof(HT_CAPABILITY_IE));
+ }
+
+ pMacEntry->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word;
+ pMacEntry->CurrTxRate = pMacEntry->MaxSupportedRate;
+ }
+
+ {
+ UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d};
+ UCHAR Header802_3[14];
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ ULONG TempLen;
+ UCHAR RemoteFrameType = 0xaf;
+ NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS;
+
+ MAKE_802_3_HEADER(Header802_3, tempMAC, pAd->CurrentAddress, TDLS_ETHERTYPE);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ MakeOutgoingFrame(pOutBuffer, &TempLen,
+ 1, &RemoteFrameType,
+ END_OF_ARGS);
+
+ FrameLen = FrameLen + TempLen;
+
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ RTMPToWirelessSta(pAd, pMacEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ return TRUE;
+
+}
+
+INT Set_TestTxFrame2Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+ UCHAR tempMAC[MAC_ADDR_LEN] = {0x00,0x0C,0x43,0x33,0x52,0xb8};
+ PSTRING value;
+ INT i;
+ UINT32 Value1 = 0;
+
+ 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, &tempMAC[i++], 1);
+ }
+
+ // allocate one MAC entry
+ pMacEntry = MacTableLookup(pAd, tempMAC);
+ if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry))
+ DBGPRINT(RT_DEBUG_ERROR,("MacTable Entry exist !!!\n"));
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Entry non exist !!!\n"));
+ return FALSE;
+ }
+
+ {
+ UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d};
+ UCHAR Header802_3[14];
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ ULONG TempLen;
+ UCHAR RemoteFrameType = 0xaf;
+ NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS;
+
+ MAKE_802_3_HEADER(Header802_3, tempMAC, pAd->CurrentAddress, TDLS_ETHERTYPE);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ MakeOutgoingFrame(pOutBuffer, &TempLen,
+ 1, &RemoteFrameType,
+ END_OF_ARGS);
+
+ FrameLen = FrameLen + TempLen;
+
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ RTMPToWirelessSta(pAd, pMacEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ return TRUE;
+}
+
+INT Set_TestTxFrame3Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+ UCHAR tempMAC[MAC_ADDR_LEN] = {0x00,0x0C,0x43,0x33,0x52,0xb8};
+ UCHAR CurrentAddress[MAC_ADDR_LEN] = {0x00,0x0C,0x43,0x33,0x52,0x41};
+ PSTRING value;
+ INT i;
+ UINT32 Value1 = 0;
+
+ 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, &tempMAC[i++], 1);
+ }
+
+ // allocate one MAC entry
+ pMacEntry = MacTableLookup(pAd, tempMAC);
+ if (pMacEntry && (IS_ENTRY_CLIENT(pMacEntry) || IS_ENTRY_APCLI(pMacEntry)))
+ DBGPRINT(RT_DEBUG_ERROR,("MacTable Entry exist !!!\n"));
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Entry non exist !!!\n"));
+ return FALSE;
+ }
+
+ {
+ UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d};
+ UCHAR Header802_3[14];
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ ULONG TempLen;
+ UCHAR RemoteFrameType = 0xaf;
+ NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS;
+
+ MAKE_802_3_HEADER(Header802_3, tempMAC, CurrentAddress, TDLS_ETHERTYPE);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ MakeOutgoingFrame(pOutBuffer, &TempLen,
+ 1, &RemoteFrameType,
+ END_OF_ARGS);
+
+ FrameLen = FrameLen + TempLen;
+
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ RTMPToWirelessSta(pAd, pMacEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ return TRUE;
+}
+
+INT Set_TestTxFrame4Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+ UCHAR tempMAC[MAC_ADDR_LEN] = {0x00,0x0C,0x43,0x33,0x52,0xb8};
+ UCHAR CurrentAddress[MAC_ADDR_LEN] = {0x00,0x0C,0x43,0x77,0x88,0x99};
+ PSTRING value;
+ INT i;
+ UINT32 Value1 = 0;
+
+ 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, &tempMAC[i++], 1);
+ }
+
+ // allocate one MAC entry
+ pMacEntry = MacTableLookup(pAd, tempMAC);
+ if (pMacEntry && (IS_ENTRY_CLIENT(pMacEntry) || IS_ENTRY_APCLI(pMacEntry)))
+ DBGPRINT(RT_DEBUG_ERROR,("MacTable Entry exist !!!\n"));
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Entry non exist !!!\n"));
+ return FALSE;
+ }
+
+ {
+ UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d};
+ UCHAR Header802_3[14];
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ ULONG TempLen;
+ UCHAR RemoteFrameType = 0xaf;
+ NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS;
+
+ MAKE_802_3_HEADER(Header802_3, tempMAC, CurrentAddress, TDLS_ETHERTYPE);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ MakeOutgoingFrame(pOutBuffer, &TempLen,
+ 1, &RemoteFrameType,
+ END_OF_ARGS);
+
+ FrameLen = FrameLen + TempLen;
+
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ pAd->TestMulMac = TRUE;
+ RTMPToWirelessSta(pAd, pMacEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ return TRUE;
+}
+
+INT Set_DumpBeaconBuffer_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+ LONG count;
+ UINT32 IdMac;
+ UINT32 macValue;
+
+ count = simple_strtol(arg, 0, 10);
+
+ for(IdMac=0x7800; IdMac<=0x7e00; IdMac+=4)
+ {
+ if ((IdMac & 0x0f) == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("\n0x%04x: ", IdMac));
+ }
+
+ RTMP_IO_READ32(pAd, IdMac, &macValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("%08x ", macValue));
+ }
+
+ return TRUE;
+}
+
+INT Set_InsertWAPIKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ return TRUE;
+}
+
+INT Set_TestWAPIFrameProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+ UCHAR tempMAC[MAC_ADDR_LEN] = {0x00,0x0C,0x43,0x33,0x52,0xb8};
+ PSTRING value;
+ INT i;
+
+ 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, &tempMAC[i++], 1);
+ }
+
+ // allocate one MAC entry
+ pMacEntry = MacTableLookup(pAd, tempMAC);
+ if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry))
+ DBGPRINT(RT_DEBUG_ERROR,("MacTable Entry exist !!!\n"));
+ else
+ pMacEntry = MacTableInsertEntry(pAd, tempMAC, BSS0, OPMODE_AP, TRUE);
+
+ {
+ UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d};
+ UCHAR Header802_3[14];
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ ULONG TempLen;
+ UCHAR RemoteFrameType = 0xaf;
+ NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS;
+
+ MAKE_802_3_HEADER(Header802_3, tempMAC, pAd->CurrentAddress, TDLS_ETHERTYPE);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ MakeOutgoingFrame(pOutBuffer, &TempLen,
+ 1, &RemoteFrameType,
+ END_OF_ARGS);
+
+ FrameLen = FrameLen + TempLen;
+
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ RTMPToWirelessSta(pAd, pMacEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ return TRUE;
+}
+
+INT Set_TestMultiMacAddrProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR tempMAC[6], tid;
+ PSTRING token;
+ STRING sepValue[] = ":", DASH = '-';
+ INT i;
+
+ 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);
+
+ if (tid > 15)
+ 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, (&tempMAC[i]), 1);
+ }
+
+ if(i != 6)
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_OFF, ("\n%s:%02x:%02x:%02x:%02x:%02x:%02x-%02x\n",
+ __FUNCTION__, tempMAC[0], tempMAC[1], tempMAC[2], tempMAC[3], tempMAC[4], tempMAC[5], tid));
+
+ //AsicUpdateRxWCIDTable(pAd, BSSID_WCID + 111 + tid, tempMAC);
+
+ {
+ ULONG offset;
+ ULONG Addr;
+
+ offset = 0x1480 + (HW_WCID_ENTRY_SIZE * tid);
+ Addr = tempMAC[0] + (tempMAC[1] << 8) +(tempMAC[2] << 16) +(tempMAC[3] << 24);
+ RTMP_IO_WRITE32(pAd, offset, Addr);
+ Addr = tempMAC[4] + (tempMAC[5] << 8);
+ RTMP_IO_WRITE32(pAd, offset + 4, Addr);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+INT Set_HwTxLookupRate_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+ pAd->bHwTxLookupRate = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_WARN, ("HwTxLookupRate = %d \n", pAd->bHwTxLookupRate));
+
+ return TRUE;
+}
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_connect.c b/cleopatre/devkit/mt7601udrv/ap/ap_connect.c
new file mode 100644
index 0000000000..98e9fd28d5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_connect.c
@@ -0,0 +1,1044 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ connect.c
+
+ Abstract:
+ Routines to deal Link UP/DOWN and build/update BEACON frame contents
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 08-04-2003 created for 11g soft-AP
+ */
+
+#include "rt_config.h"
+
+UCHAR PowerConstraintIE[3] = {IE_POWER_CONSTRAINT, 1, 3};
+
+
+/*
+ ==========================================================================
+ Description:
+ Used to check the necessary to send Beancon.
+ return value
+ 0: mean no necessary.
+ 0: mean need to send Beacon for the service.
+ ==========================================================================
+*/
+BOOLEAN BeaconTransmitRequired(
+ IN RTMP_ADAPTER *pAd,
+ IN INT apidx,
+ IN MULTISSID_STRUCT *pMbss)
+{
+#ifdef WDS_SUPPORT
+ UCHAR idx;
+#endif /* WDS_SUPPORT */
+ BOOLEAN result = FALSE;
+
+ do
+ {
+#ifdef WDS_SUPPORT
+ if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
+ break;
+#endif /* WDS_SUPPORT */
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ if (isCarrierDetectExist(pAd) == TRUE)
+ break;
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+
+ if (apidx == MAIN_MBSSID)
+ {
+ if (pMbss->bBcnSntReq == TRUE)
+ {
+ result = TRUE;
+ break;
+ }
+#ifdef WDS_SUPPORT
+ for (idx = 0; idx < MAX_WDS_ENTRY; idx++)
+ {
+ if ((pAd->WdsTab.WdsEntry[idx].dev != NULL)
+ && (RTMP_OS_NETDEV_STATE_RUNNING(pAd->WdsTab.WdsEntry[idx].dev)))
+ {
+ result = TRUE;
+ break;
+ }
+ }
+#endif /* WDS_SUPPORT */
+ }
+ else
+ {
+ if (pMbss->bBcnSntReq == TRUE)
+ result = TRUE;
+ }
+ }
+ while (FALSE);
+
+ return result;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Pre-build a BEACON frame in the shared memory
+ ==========================================================================
+*/
+VOID APMakeBssBeacon(RTMP_ADAPTER *pAd, INT apidx)
+{
+ UCHAR DsLen = 1, SsidLen;
+ HEADER_802_11 BcnHdr;
+ LARGE_INTEGER FakeTimestamp;
+ ULONG FrameLen = 0;
+ PUCHAR pBeaconFrame = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf;
+ UCHAR *ptr;
+ UINT i;
+ UINT32 longValue, reg_base;
+ HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */
+ UCHAR PhyMode, SupRateLen;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ if(!BeaconTransmitRequired(pAd, apidx, &pAd->ApCfg.MBSSID[apidx]))
+ return;
+
+ PhyMode = pAd->ApCfg.MBSSID[apidx].PhyMode;
+
+ if (pAd->ApCfg.MBSSID[apidx].bHideSsid)
+ SsidLen = 0;
+ else
+ SsidLen = pAd->ApCfg.MBSSID[apidx].SsidLen;
+
+ MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR,
+ pAd->ApCfg.MBSSID[apidx].Bssid);
+
+ /* for update framelen to TxWI later. */
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+ if (PhyMode == WMODE_B)
+ SupRateLen = 4;
+
+ MakeOutgoingFrame(pBeaconFrame, &FrameLen,
+ sizeof(HEADER_802_11), &BcnHdr,
+ TIMESTAMP_LEN, &FakeTimestamp,
+ 2, &pAd->CommonCfg.BeaconPeriod,
+ 2, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo,
+ 1, &SsidIe,
+ 1, &SsidLen,
+ SsidLen, pAd->ApCfg.MBSSID[apidx].Ssid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, pAd->CommonCfg.SupRate,
+ 1, &DsIe,
+ 1, &DsLen,
+ 1, &pAd->CommonCfg.Channel,
+ END_OF_ARGS);
+
+ if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B))
+ {
+ ULONG TmpLen;
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &ExtRateIe,
+ 1, &pAd->CommonCfg.ExtRateLen,
+ pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+
+ /* add country IE, power constraint IE */
+ if (pAd->CommonCfg.bCountryFlag)
+ {
+ ULONG TmpLen, TmpLen2=0;
+ UCHAR *TmpFrame = NULL;
+ UCHAR CountryIe = IE_COUNTRY;
+
+ os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256);
+ if (TmpFrame != NULL)
+ {
+ NdisZeroMemory(TmpFrame, 256);
+
+ /* prepare channel information */
+#ifdef EXT_BUILD_CHANNEL_LIST
+ BuildBeaconChList(pAd, TmpFrame, &TmpLen2);
+#else
+ {
+ UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
+ MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen,
+ 1, &pAd->ChannelList[0].Channel,
+ 1, &pAd->ChannelListNum,
+ 1, &MaxTxPower,
+ END_OF_ARGS);
+ TmpLen2 += TmpLen;
+ }
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+
+ /* need to do the padding bit check, and concatenate it */
+ if ((TmpLen2%2) == 0)
+ {
+ UCHAR TmpLen3 = TmpLen2+4;
+ MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
+ 1, &CountryIe,
+ 1, &TmpLen3,
+ 3, pAd->CommonCfg.CountryCode,
+ TmpLen2+1, TmpFrame,
+ END_OF_ARGS);
+ }
+ else
+ {
+ UCHAR TmpLen3 = TmpLen2+3;
+ MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
+ 1, &CountryIe,
+ 1, &TmpLen3,
+ 3, pAd->CommonCfg.CountryCode,
+ TmpLen2, TmpFrame,
+ END_OF_ARGS);
+ }
+ FrameLen += TmpLen;
+
+ os_free_mem(NULL, TmpFrame);
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ }
+
+
+#ifdef DOT11_N_SUPPORT
+ /* AP Channel Report */
+ {
+ UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT;
+ ULONG TmpLen;
+
+ /*
+ 802.11n D2.0 Annex J, USA regulatory
+ class 32, channel set 1~7
+ class 33, channel set 5-11
+ */
+ UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7};
+ UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11};
+ UCHAR rclasslen = 8; /*sizeof(rclass32); */
+ if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN))
+ {
+ MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
+ 1, &APChannelReportIe,
+ 1, &rclasslen,
+ rclasslen, rclass32,
+ 1, &APChannelReportIe,
+ 1, &rclasslen,
+ rclasslen, rclass33,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ }
+
+#endif /* DOT11_N_SUPPORT */
+
+
+ RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS0Mcast_WCID,
+ FrameLen, PID_MGMT, 0, 0,IFS_HTTXOP, FALSE, &BeaconTransmit);
+
+ /*
+ step 6. move BEACON TXD and frame content to on-chip memory
+ */
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pAd, ptr, TYPE_TXWI);
+#endif
+
+
+ reg_base = pAd->BeaconOffset[pAd->ApCfg.MBSSID[apidx].BcnBufIdx];
+ for (i=0; i < TXWISize; i+=4)
+ {
+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4);
+ ptr += 4;
+ }
+
+ /* update BEACON frame content. start right after the TXWI field. */
+ ptr = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf;
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
+#endif
+
+ reg_base = pAd->BeaconOffset[pAd->ApCfg.MBSSID[apidx].BcnBufIdx] + TXWISize;
+ for (i= 0; i< FrameLen; i+=4)
+ {
+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4);
+ ptr += 4;
+ }
+
+ pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon = (UCHAR)FrameLen;
+ pAd->ApCfg.MBSSID[apidx].CapabilityInfoLocationInBeacon = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Update the BEACON frame in the shared memory. Because TIM IE is variable
+ length. other IEs after TIM has to shift and total frame length may change
+ for each BEACON period.
+ Output:
+ pAd->ApCfg.MBSSID[apidx].CapabilityInfo
+ pAd->ApCfg.ErpIeContent
+ ==========================================================================
+*/
+VOID APUpdateBeaconFrame(RTMP_ADAPTER *pAd, INT apidx)
+{
+ UCHAR *pBeaconFrame = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf;
+ UCHAR *ptr;
+ ULONG FrameLen = pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon;
+ ULONG UpdatePos = pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon;
+ UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2;
+ UCHAR ID_1B, TimFirst, TimLast, *pTim;
+ MULTISSID_STRUCT *pMbss;
+ COMMON_CONFIG *pComCfg;
+ UCHAR PhyMode;
+ BOOLEAN bHasWpsIE = FALSE;
+ UINT i;
+ HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */
+
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+ pComCfg = &pAd->CommonCfg;
+ PhyMode = pMbss->PhyMode;
+
+ if(!BeaconTransmitRequired(pAd, apidx, pMbss))
+ return;
+
+ /*
+ step 1 - update BEACON's Capability
+ */
+ ptr = pBeaconFrame + pMbss->CapabilityInfoLocationInBeacon;
+ *ptr = (UCHAR)(pMbss->CapabilityInfo & 0x00ff);
+ *(ptr+1) = (UCHAR)((pMbss->CapabilityInfo & 0xff00) >> 8);
+
+ /*
+ step 2 - update TIM IE
+ TODO: enlarge TIM bitmap to support up to 64 STAs
+ TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time
+ */
+ ptr = pBeaconFrame + pMbss->TimIELocationInBeacon;
+ *ptr = IE_TIM;
+ *(ptr + 2) = pAd->ApCfg.DtimCount;
+ *(ptr + 3) = pAd->ApCfg.DtimPeriod;
+
+ /* find the smallest AID (PS mode) */
+ TimFirst = 0; /* record first TIM byte != 0x00 */
+ TimLast = 0; /* record last TIM byte != 0x00 */
+ pTim = pMbss->TimBitmaps;
+
+ for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++)
+ {
+ /* get the TIM indicating PS packets for 8 stations */
+ UCHAR tim_1B = pTim[ID_1B];
+
+ if (ID_1B == 0)
+ tim_1B &= 0xfe; /* skip bit0 bc/mc */
+
+ if (tim_1B == 0)
+ continue; /* find next 1B */
+
+ if (TimFirst == 0)
+ TimFirst = ID_1B;
+
+ TimLast = ID_1B;
+ }
+
+ /* fill TIM content to beacon buffer */
+ if (TimFirst & 0x01)
+ TimFirst --; /* find the even offset byte */
+
+ *(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */
+ *(ptr + 4) = TimFirst;
+
+ for(i=TimFirst; i<=TimLast; i++)
+ *(ptr + 5 + i - TimFirst) = pTim[i];
+
+ /* bit0 means backlogged mcast/bcast */
+ if (pAd->ApCfg.DtimCount == 0)
+ *(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01);
+
+ /* adjust BEACON length according to the new TIM */
+ FrameLen += (2 + *(ptr+1));
+
+#ifdef HOSTAPD_SUPPORT
+ if ( pAd->ApCfg.MBSSID[apidx].HostapdWPS && (pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen))
+ bHasWpsIE = TRUE;
+#endif
+
+#ifdef WSC_AP_SUPPORT
+ /* add Simple Config Information Element */
+ if (((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode >= 1) && (pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen)))
+ {
+ bHasWpsIE = TRUE;
+ }
+#endif /* WSC_AP_SUPPORT */
+
+ if (bHasWpsIE)
+ {
+ ULONG WscTmpLen = 0;
+
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &WscTmpLen,
+ pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen, pAd->ApCfg.MBSSID[apidx].WscIEBeacon.Value,
+ END_OF_ARGS);
+ FrameLen += WscTmpLen;
+ }
+
+#ifdef WSC_AP_SUPPORT
+ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) &&
+#ifdef DOT1X_SUPPORT
+ (pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) &&
+#endif /* DOT1X_SUPPORT */
+ (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled))
+ {
+ /*
+ Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based
+ or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP
+ network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't
+ receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and
+ prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">>
+ A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network.
+ The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero)
+ http:msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp
+ */
+ ULONG TempLen = 0;
+ UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00};
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TempLen,
+ 7, PROVISION_SERVICE_IE,
+ END_OF_ARGS);
+ FrameLen += TempLen;
+ }
+#endif /* WSC_AP_SUPPORT */
+
+
+ /* Update ERP */
+ if ((pComCfg->ExtRateLen) && (PhyMode != WMODE_B))
+ {
+ /* fill ERP IE */
+ ptr = (UCHAR *)pBeaconFrame + FrameLen; /* pTxD->DataByteCnt; */
+ *ptr = IE_ERP;
+ *(ptr + 1) = 1;
+ *(ptr + 2) = pAd->ApCfg.ErpIeContent;
+ FrameLen += 3;
+ }
+
+#ifdef A_BAND_SUPPORT
+ /* fill up Channel Switch Announcement Element */
+ if ((pComCfg->Channel > 14)
+ && (pComCfg->bIEEE80211H == 1)
+ && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE))
+ {
+ ptr = pBeaconFrame + FrameLen;
+ *ptr = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+ *(ptr + 1) = 3;
+ *(ptr + 2) = 1;
+ *(ptr + 3) = pComCfg->Channel;
+ *(ptr + 4) = (pAd->Dot11_H.CSPeriod - pAd->Dot11_H.CSCount - 1);
+ ptr += 5;
+ FrameLen += 5;
+
+#ifdef DOT11_N_SUPPORT
+ /* Extended Channel Switch Announcement Element */
+ if (pComCfg->bExtChannelSwitchAnnouncement)
+ {
+ HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe;
+ build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe);
+ NdisMoveMemory(ptr, &HtExtChannelSwitchIe, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE));
+ ptr += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE);
+ FrameLen += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE);
+ }
+#endif /* DOT11_N_SUPPORT */
+ }
+#endif /* A_BAND_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ /* step 5. Update HT. Since some fields might change in the same BSS. */
+ if (WMODE_CAP_N(PhyMode) && (pMbss->DesiredHtPhyInfo.bHtEnable))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen, HtLen1;
+ /*UCHAR i; */
+
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+ ADD_HT_INFO_IE addHTInfoTmp;
+/* USHORT b2lTmp, b2lTmp2; // no use */
+#endif
+
+ /* add HT Capability IE */
+ HtLen = sizeof(pComCfg->HtCapability);
+ HtLen1 = sizeof(pComCfg->AddHTInfo);
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pComCfg->HtCapability,
+ 1, &AddHtInfoIe,
+ 1, &HtLen1,
+ HtLen1, &pComCfg->AddHTInfo,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen);
+ *(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) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+#endif /* UNALIGNMENT_SUPPORT */
+
+ NdisMoveMemory(&addHTInfoTmp, &pComCfg->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;
+
+#ifdef DOT11N_DRAFT3
+ /*
+ P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE
+ */
+ if ((pComCfg->Channel <= 14) &&
+ (pComCfg->HtCapability.HtCapInfo.ChannelWidth == 1))
+ {
+ OVERLAP_BSS_SCAN_IE OverlapScanParam;
+ ULONG TmpLen;
+ UCHAR OverlapScanIE, ScanIELen;
+
+ OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM;
+ ScanIELen = 14;
+ OverlapScanParam.ScanPassiveDwell = cpu2le16(pComCfg->Dot11OBssScanPassiveDwell);
+ OverlapScanParam.ScanActiveDwell = cpu2le16(pComCfg->Dot11OBssScanActiveDwell);
+ OverlapScanParam.TriggerScanInt = cpu2le16(pComCfg->Dot11BssWidthTriggerScanInt);
+ OverlapScanParam.PassiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanPassiveTotalPerChannel);
+ OverlapScanParam.ActiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanActiveTotalPerChannel);
+ OverlapScanParam.DelayFactor = cpu2le16(pComCfg->Dot11BssWidthChanTranDelayFactor);
+ OverlapScanParam.ScanActThre = cpu2le16(pComCfg->Dot11OBssScanActivityThre);
+
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
+ 1, &OverlapScanIE,
+ 1, &ScanIELen,
+ ScanIELen, &OverlapScanParam,
+ END_OF_ARGS);
+
+ FrameLen += TmpLen;
+ }
+#endif /* DOT11N_DRAFT3 */
+
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(PhyMode) && (pComCfg->Channel > 14))
+ {
+ int _len = build_vht_ies(pAd, (UCHAR *)(pBeaconFrame+FrameLen), SUBTYPE_BEACON);
+ FrameLen += _len;
+ }
+#endif /* DOT11_VHT_AC */
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#if defined(DOT11N_DRAFT3) || defined(DOT11V_WNM_SUPPORT)
+ /* 7.3.2.27 Extended Capabilities IE */
+ {
+ ULONG TmpLen, infoPos;
+ PUCHAR pInfo;
+ UCHAR extInfoLen;
+ BOOLEAN bNeedAppendExtIE = FALSE;
+ EXT_CAP_INFO_ELEMENT extCapInfo;
+
+
+ extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT);
+ NdisZeroMemory(&extCapInfo, extInfoLen);
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ /* P802.11n_D1.10, HT Information Exchange Support */
+ if (WMODE_CAP_N(PhyMode) && (pComCfg->Channel <= 14) &&
+ (pMbss->DesiredHtPhyInfo.bHtEnable) &&
+ (pComCfg->bBssCoexEnable == TRUE)
+ )
+ {
+ extCapInfo.BssCoexistMgmtSupport = 1;
+ }
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+
+ pInfo = (PUCHAR)(&extCapInfo);
+ for (infoPos = 0; infoPos < extInfoLen; infoPos++)
+ {
+ if (pInfo[infoPos] != 0)
+ {
+ bNeedAppendExtIE = TRUE;
+ break;
+ }
+ }
+
+ if (bNeedAppendExtIE == TRUE)
+ {
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &ExtCapIe,
+ 1, &extInfoLen,
+ extInfoLen, &extCapInfo,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ }
+#endif /* defined(DOT11N_DRAFT3) || defined(DOT11V_WNM_SUPPORT) */
+
+
+ if ((pMbss->AuthMode == Ndis802_11AuthModeWPA) ||
+ (pMbss->AuthMode == Ndis802_11AuthModeWPAPSK))
+ RSNIe = IE_WPA;
+ else if ((pMbss->AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pMbss->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ RSNIe = IE_WPA2;
+#ifdef WAPI_SUPPORT
+ else if ((pMbss->AuthMode == Ndis802_11AuthModeWAICERT) ||
+ (pMbss->AuthMode == Ndis802_11AuthModeWAIPSK))
+ RSNIe = IE_WAPI;
+#endif /* WAPI_SUPPORT */
+
+ /* Append RSN_IE when WPA OR WPAPSK, */
+ if ((pMbss->AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+ (pMbss->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ {
+ ULONG TmpLen;
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &RSNIe,
+ 1, &pMbss->RSNIE_Len[0],
+ pMbss->RSNIE_Len[0], pMbss->RSN_IE[0],
+ 1, &RSNIe2,
+ 1, &pMbss->RSNIE_Len[1],
+ pMbss->RSNIE_Len[1], pMbss->RSN_IE[1],
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ else if (pMbss->AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ ULONG TmpLen;
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &RSNIe,
+ 1, &pMbss->RSNIE_Len[0],
+ pMbss->RSNIE_Len[0], pMbss->RSN_IE[0],
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ /* add WMM IE here */
+ if (pMbss->bWmmCapable)
+ {
+ ULONG TmpLen;
+ UCHAR i;
+ UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0};
+ UINT8 AIFSN[4];
+
+ WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f;
+
+#ifdef UAPSD_SUPPORT
+ UAPSD_MR_IE_FILL(WmeParmIe[8], &pMbss->UapsdInfo);
+#endif /* UAPSD_SUPPORT */
+
+ NdisMoveMemory(AIFSN, pAd->ApCfg.BssEdcaParm.Aifsn, sizeof(AIFSN));
+
+
+ for (i=QID_AC_BE; i<=QID_AC_VO; i++)
+ {
+ WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */
+ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */
+ (AIFSN[i] & 0x0f); /* b0-3 is AIFSN */
+ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */
+ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */
+ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */
+ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */
+ }
+
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 26, WmeParmIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+#ifdef AP_QLOAD_SUPPORT
+ if (pAd->FlgQloadEnable != 0)
+ {
+ FrameLen += QBSS_LoadElementAppend(pAd, pBeaconFrame+FrameLen);
+ }
+#endif /* AP_QLOAD_SUPPORT */
+
+#ifdef A_BAND_SUPPORT
+ /*
+ Only 802.11a APs that comply with 802.11h are required to include a
+ Power Constrint Element(IE=32) in beacons and probe response frames
+ */
+ if (((pComCfg->Channel > 14) && pComCfg->bIEEE80211H == TRUE)
+ )
+ {
+ ULONG TmpLen;
+ UINT8 PwrConstraintIE = IE_POWER_CONSTRAINT;
+ UINT8 PwrConstraintLen = 1;
+ UINT8 PwrConstraint = pComCfg->PwrConstraint;
+
+ /* prepare power constraint IE */
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &PwrConstraintIE,
+ 1, &PwrConstraintLen,
+ 1, &PwrConstraint,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+#endif /* A_BAND_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+ if (WMODE_CAP_N(PhyMode) &&
+ (pMbss->DesiredHtPhyInfo.bHtEnable))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen, HtLen1;
+ /*UCHAR i; */
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+ ADD_HT_INFO_IE addHTInfoTmp;
+/* USHORT b2lTmp, b2lTmp2;*/ /* no use */
+#endif
+ /* add HT Capability IE */
+ HtLen = sizeof(pComCfg->HtCapability);
+ HtLen1 = sizeof(pComCfg->AddHTInfo);
+
+ if (pAd->bBroadComHT == TRUE)
+ {
+ UCHAR epigram_ie_len;
+ UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33};
+ UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34};
+
+
+ epigram_ie_len = HtLen + 4;
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_HTC[0],
+ HtLen, &pComCfg->HtCapability,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen);
+ *(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) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+#endif /* UNALIGNMENT_SUPPORT */
+
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_HTC[0],
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+
+ FrameLen += TmpLen;
+
+ epigram_ie_len = HtLen1 + 4;
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_AHTINFO[0],
+ HtLen1, &pComCfg->AddHTInfo,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1);
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
+
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_AHTINFO[0],
+ HtLen1, &addHTInfoTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen += TmpLen;
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back */
+{
+ ULONG TmpLen;
+ UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00};
+
+ if (pComCfg->bAggregationCapable)
+ RalinkSpecificIe[5] |= 0x1;
+ if (pComCfg->bPiggyBackCapable)
+ RalinkSpecificIe[5] |= 0x2;
+#ifdef DOT11_N_SUPPORT
+ if (pComCfg->bRdg)
+ RalinkSpecificIe[5] |= 0x4;
+#endif /* DOT11_N_SUPPORT */
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 9, RalinkSpecificIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+
+}
+
+
+ /* step 6. Since FrameLen may change, update TXWI. */
+#ifdef A_BAND_SUPPORT
+ if (pAd->CommonCfg.Channel > 14) {
+ BeaconTransmit.field.MODE = MODE_OFDM;
+ BeaconTransmit.field.MCS = MCS_RATE_6;
+ }
+#endif /* A_BAND_SUPPORT */
+ RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff,
+ FrameLen, PID_MGMT, QID_MGMT, 0, IFS_HTTXOP, FALSE, &BeaconTransmit);
+
+ /* step 7. move BEACON TXWI and frame content to on-chip memory */
+ RT28xx_UpdateBeaconToAsic(pAd, apidx, FrameLen, UpdatePos);
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Pre-build All BEACON frame in the shared memory
+ ==========================================================================
+*/
+static UCHAR GetBcnNum(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+ int NumBcn;
+
+ NumBcn = 0;
+ for (i=0; i<pAd->ApCfg.BssidNum; i++)
+ {
+ if (pAd->ApCfg.MBSSID[i].bBcnSntReq)
+ {
+ pAd->ApCfg.MBSSID[i].BcnBufIdx = NumBcn;
+ NumBcn ++;
+ }
+ }
+
+
+ return NumBcn;
+}
+
+VOID APMakeAllBssBeacon(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ UINT32 regValue;
+ UCHAR NumOfMacs;
+ UCHAR NumOfBcns;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ /* before MakeBssBeacon, clear all beacon TxD's valid bit */
+ /* Note: can not use MAX_MBSSID_NUM here, or
+ 1. when MBSS_SUPPORT is enabled;
+ 2. MAX_MBSSID_NUM will be 8;
+ 3. if HW_BEACON_OFFSET is 0x0200,
+ we will overwrite other shared memory SRAM of chip */
+ /* use pAd->ApCfg.BssidNum to avoid the case is best */
+
+ /* choose the Beacon number */
+ NumOfBcns = GetBcnNum(pAd);
+
+ for (i=0; i<HW_BEACON_MAX_COUNT(pAd); i++)
+ {
+ for (j=0; j < TXWISize; j+=4)
+ {
+ RTMP_CHIP_UPDATE_BEACON(pAd, pAd->BeaconOffset[i] + j, 0, 4);
+ }
+ }
+
+#ifdef RTMP_MAC_USB
+ RTUSBBssBeaconStop(pAd);
+#endif /* RTMP_MAC_USB */
+
+ for(i=0; i<pAd->ApCfg.BssidNum; i++)
+ {
+ APMakeBssBeacon(pAd, i);
+ }
+
+ RTMP_IO_READ32(pAd, MAC_BSSID_DW1, &regValue);
+ regValue &= 0x0000FFFF;
+
+
+ /*
+ Note:
+ 1.The MAC address of Mesh and AP-Client link are different from Main BSSID.
+ 2.If the Mesh link is included, its MAC address shall follow the last MBSSID's MAC by increasing 1.
+ 3.If the AP-Client link is included, its MAC address shall follow the Mesh interface MAC by increasing 1.
+ */
+ NumOfMacs = pAd->ApCfg.BssidNum + MAX_MESH_NUM + MAX_APCLI_NUM;
+
+
+ /* set Multiple BSSID mode */
+ if (NumOfMacs <= 1)
+ {
+ pAd->ApCfg.MacMask = ~(1-1);
+ /*regValue |= 0x0; */
+ }
+ else if (NumOfMacs <= 2)
+ {
+ if ((pAd->CurrentAddress[5] % 2 != 0)
+ )
+ DBGPRINT(RT_DEBUG_ERROR, ("The 2-BSSID mode is enabled, the BSSID byte5 MUST be the multiple of 2\n"));
+
+ regValue |= (1<<16);
+ pAd->ApCfg.MacMask = ~(2-1);
+ }
+ else if (NumOfMacs <= 4)
+ {
+ if (pAd->CurrentAddress[5] % 4 != 0)
+ DBGPRINT(RT_DEBUG_ERROR, ("The 4-BSSID mode is enabled, the BSSID byte5 MUST be the multiple of 4\n"));
+
+ regValue |= (2<<16);
+ pAd->ApCfg.MacMask = ~(4-1);
+ }
+ else if (NumOfMacs <= 8)
+ {
+ if (pAd->CurrentAddress[5] % 8 != 0)
+ DBGPRINT(RT_DEBUG_ERROR, ("The 8-BSSID mode is enabled, the BSSID byte5 MUST be the multiple of 8\n"));
+
+ regValue |= (3<<16);
+ pAd->ApCfg.MacMask = ~(8-1);
+ }
+
+ /* set Multiple BSSID Beacon number */
+ if (NumOfBcns > 1)
+ {
+ regValue |= (((NumOfBcns - 1) & 0x7) << 18);
+ }
+
+ /* set as 0/1 bit-21 of MAC_BSSID_DW1(offset: 0x1014)
+ to disable/enable the new MAC address assignment. */
+ if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
+ regValue |= (1 << 21);
+
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, regValue);
+
+#ifdef HDR_TRANS_SUPPORT
+ /*
+ point WCID MAC table to 0x1800
+ This is for debug.
+ But HDR_TRANS doesn't work if you remove it.
+ Check after IC formal release.
+ */
+ regValue |= 0x18000000;
+ RTMP_IO_WRITE32(pAd, HT_MAC_BSSID_DW1, regValue);
+#endif /* HDR_TRANS_SUPPORT */
+
+#ifdef RTMP_MAC_USB
+ RTUSBBssBeaconStart(pAd);
+#endif /* RTMP_MAC_USB */
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Pre-build All BEACON frame in the shared memory
+ ==========================================================================
+*/
+VOID APUpdateAllBeaconFrame(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ BOOLEAN FlgQloadIsAlarmIssued = FALSE;
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+ if (pAd->ApCfg.DtimCount == 0)
+ pAd->ApCfg.DtimCount = pAd->ApCfg.DtimPeriod - 1;
+ else
+ pAd->ApCfg.DtimCount -= 1;
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ /* QLOAD ALARM */
+#ifdef AP_QLOAD_SUPPORT
+ FlgQloadIsAlarmIssued = QBSS_LoadIsAlarmIssued(pAd);
+#endif /* AP_QLOAD_SUPPORT */
+
+ if ((pAd->ApCfg.DtimCount == 0) &&
+ (((pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_INFO_SYNC) &&
+ (pAd->CommonCfg.bForty_Mhz_Intolerant == FALSE)) ||
+ (FlgQloadIsAlarmIssued == TRUE)))
+ {
+ UCHAR prevBW, prevExtChOffset;
+ DBGPRINT(RT_DEBUG_TRACE, ("DTIM Period reached, BSS20WidthReq=%d, Intolerant40=%d!\n",
+ pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq, pAd->CommonCfg.LastBSSCoexist2040.field.Intolerant40));
+ pAd->CommonCfg.Bss2040CoexistFlag &= (~BSS_2040_COEXIST_INFO_SYNC);
+
+ prevBW = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+ prevExtChOffset = pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset;
+
+ if (pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq ||
+ pAd->CommonCfg.LastBSSCoexist2040.field.Intolerant40 ||
+ (pAd->MacTab.fAnyStaFortyIntolerant == TRUE) ||
+ (FlgQloadIsAlarmIssued == TRUE))
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
+ }
+ else
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = pAd->CommonCfg.RegTransmitSetting.field.BW;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("\tNow RecomWidth=%d, ExtChanOffset=%d, prevBW=%d, prevExtOffset=%d\n",
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth,
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset,
+ prevBW, prevExtChOffset));
+ pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_NOTIFY;
+ }
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+ for(i=0; i<pAd->ApCfg.BssidNum; i++)
+ {
+ APUpdateBeaconFrame(pAd, i);
+ }
+}
+
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_data.c b/cleopatre/devkit/mt7601udrv/ap/ap_data.c
new file mode 100644
index 0000000000..e3cf945ceb
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_data.c
@@ -0,0 +1,6452 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_data.c
+
+ Abstract:
+ Data path subroutines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+ Paul Lin 07-01-2003 add encryption/decryption data flow
+ John Chang 08-05-2003 modify 802.11 header for AP purpose
+ John Chang 12-20-2004 modify for 2561/2661. merge into STA driver
+ Jan Lee 1-20-2006 modify for 2860.
+*/
+#include "rt_config.h"
+
+#define IS_MULTICAST_MAC_ADDR(Addr) ((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff))
+#define IS_BROADCAST_MAC_ADDR(Addr) ((((Addr[0]) & 0xff) == 0xff))
+
+
+static VOID APFindCipherAlgorithm(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk);
+
+#ifdef DOT11_N_SUPPORT
+VOID RTMP_BASetup(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pMacEntry,
+ IN UINT8 UserPriority)
+{
+ if (pMacEntry && (pMacEntry->NoBADataCountDown == 0) && IS_HT_STA(pMacEntry))
+ {
+ /* Don't care the status of the portSecured status. */
+ if (((pMacEntry->TXBAbitmap & (1<<UserPriority)) == 0) /*&& (pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED)*/
+ /*
+ For IOT compatibility, BA session can be bulit when following conditions matched
+ 1. It is Ralink chip or
+ 2. It is OPEN or AES mode,
+ */
+ && ((IS_ENTRY_CLIENT(pMacEntry) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) ||
+ IS_ENTRY_MESH(pMacEntry) || IS_ENTRY_WDS(pMacEntry) ||
+ (IS_ENTRY_APCLI(pMacEntry) && (pAd->MlmeAux.APRalinkIe != 0x0) && (pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED)) ||
+ (pMacEntry->WepStatus == Ndis802_11WEPDisabled ||
+ pMacEntry->WepStatus == Ndis802_11Encryption3Enabled
+#ifdef WAPI_SUPPORT
+ || pMacEntry->WepStatus == Ndis802_11EncryptionSMS4Enabled
+#endif /* WAPI_SUPPORT */
+ ))
+ )
+ {
+ BAOriSessionSetUp(pAd, pMacEntry, UserPriority, 0, 10, FALSE);
+ }
+ }
+}
+#endif /* DOT11_N_SUPPORT */
+
+static inline BOOLEAN ApAllowToSendPacket(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pPacket,
+ OUT UCHAR *pWcid)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+ SST Sst;
+ USHORT Aid;
+ UCHAR PsMode, Rate;
+ BOOLEAN allowed;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+#ifdef CLIENT_WDS
+ {
+ PUCHAR pEntryAddr;
+ pEntry = APSsPsInquiry(pAd, pSrcBufVA, &Sst, &Aid, &PsMode, &Rate);
+ if ((pEntry == NULL)
+ && (pEntryAddr = CliWds_ProxyLookup(pAd, pSrcBufVA)) != NULL)
+ {
+ pEntry = APSsPsInquiry(pAd, pEntryAddr, &Sst, &Aid, &PsMode, &Rate);
+ }
+ }
+#else
+ pEntry = APSsPsInquiry(pAd, pSrcBufVA, &Sst, &Aid, &PsMode, &Rate);
+#endif /* CLIENT_WDS */
+
+
+ if ((pEntry && (Sst == SST_ASSOC)) || (*pSrcBufVA & 0x01))
+ {
+ /*
+ Record that orignal packet source is from NDIS layer,so that
+ later on driver knows how to release this NDIS PACKET
+ */
+ *pWcid = (UCHAR)Aid; /*RTMP_SET_PACKET_WCID(pPacket, (UCHAR)Aid); */
+ allowed = TRUE;
+ }
+ else
+ {
+ allowed = FALSE;
+ }
+
+ return allowed;
+
+}
+
+
+
+/*
+========================================================================
+Routine Description:
+ Early checking and OS-depened parsing for Tx packet to AP device.
+
+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 & AP related code in here.
+========================================================================
+*/
+VOID APSendPackets(NDIS_HANDLE dev_hnd, PPNDIS_PACKET pkt_list, UINT pkt_cnt)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *) dev_hnd;
+ PNDIS_PACKET pPacket;
+ BOOLEAN allowToSend;
+ UCHAR wcid = MCAST_WCID;
+ UINT Index;
+
+
+
+ for (Index = 0; Index < pkt_cnt; Index++)
+ {
+ pPacket = pkt_list[Index];
+
+ if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF))
+ )
+ {
+ /* Drop send request since hardware is in reset state */
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ /* The following code do comparison must base on the following sequence:
+ MIN_NET_DEVICE_FOR_APCLI> MIN_NET_DEVICE_FOR_WDS > Normal
+ */
+#ifdef APCLI_SUPPORT
+ if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_APCLI)
+ allowToSend = ApCliAllowToSendPacket(pAd, pPacket, &wcid);
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
+ allowToSend = ApWdsAllowToSendPacket(pAd, pPacket, &wcid);
+ else
+#endif /* WDS_SUPPORT */
+ allowToSend = ApAllowToSendPacket(pAd, pPacket, &wcid);
+
+ if (allowToSend)
+ {
+ /* For packet send from OS, we need to set the wcid here, it will used directly in APSendPacket. */
+ RTMP_SET_PACKET_WCID(pPacket, wcid);
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+ NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
+ pAd->RalinkCounters.PendingNdisPacketCount++;
+
+ APSendPacket(pAd, pPacket);
+ }
+ else
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ }
+
+ /* Dequeue outgoing frames from TxSwQueue0..3 queue 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 AP 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.
+
+ pre: Before calling this routine, caller should have filled the following fields
+
+ pPacket->MiniportReserved[6] - contains packet source
+ pPacket->MiniportReserved[5] - contains RA's WDS index (if RA on WDS link) or AID
+ (if RA directly associated to this AP)
+ post:This routine should decide the remaining pPacket->MiniportReserved[] fields
+ before calling APHardTransmit(), such as:
+
+ pPacket->MiniportReserved[4] - Fragment # and User PRiority
+ pPacket->MiniportReserved[7] - RTS/CTS-to-self protection method and TX rate
+
+ Note:
+ You only can put OS-indepened & AP related code in here.
+
+
+========================================================================
+*/
+NDIS_STATUS APSendPacket(RTMP_ADAPTER *pAd, PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ UCHAR *pSrcBufVA;
+ UINT SrcBufLen;
+ UINT AllowFragSize;
+ UCHAR NumberOfFrag;
+ UCHAR RTSRequired;
+ UCHAR QueIdx, UserPriority, apidx = MAIN_MBSSID;
+ SST Sst = SST_ASSOC;
+ UCHAR PsMode = PWR_ACTIVE, Rate;
+ USHORT Wcid;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+ unsigned long IrqFlags;
+#ifdef IGMP_SNOOP_SUPPORT
+ INT InIgmpGroup = IGMP_NONE;
+ MULTICAST_FILTER_TABLE_ENTRY *pGroupEntry = NULL;
+#endif /* IGMP_SNOOP_SUPPORT */
+ MULTISSID_STRUCT *pMbss = NULL;
+
+
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ if (pSrcBufVA == NULL)
+ {
+ /*
+ 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,("APSendPacket --> Ndis Packet buffer error !!!\n"));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return (NDIS_STATUS_FAILURE);
+ }
+
+ Wcid = RTMP_GET_PACKET_WCID(pPacket);
+ pMacEntry = &pAd->MacTab.Content[Wcid];
+
+ /*
+ 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;
+ if (RTMPCheckEtherType(pAd, pPacket, pMacEntry, OPMODE_AP, &UserPriority, &QueIdx) == FALSE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+
+#ifdef APCLI_SUPPORT
+ if(IS_ENTRY_APCLI(pMacEntry))
+ {
+ Rate = pMacEntry->CurrTxRate;
+ if ((pMacEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ && (pMacEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+ && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return (NDIS_STATUS_FAILURE);
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(pMacEntry))
+ {
+ /*b7 as WDS bit, b0-6 as WDS index when b7==1 */
+ Rate = pMacEntry->CurrTxRate;
+ }
+ else
+#endif /* WDS_SUPPORT */
+ if (IS_ENTRY_CLIENT(pMacEntry) || (Wcid == MCAST_WCID))
+ {
+ /*USHORT Aid; */
+ PsMode = pMacEntry->PsMode;
+ Rate = pMacEntry->CurrTxRate;
+ Sst = pMacEntry->Sst;
+
+ if (Wcid == MCAST_WCID)
+ {
+ /* if (pAd->MacTab.Size == 0) */
+ if (pAd->ApCfg.EntryClientCount == 0)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ apidx = RTMP_GET_PACKET_NET_DEVICE_MBSSID(pPacket);
+ MBSS_MR_APIDX_SANITY_CHECK(pAd, apidx);
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+ }
+ else
+ {
+ apidx = pMacEntry->apidx;
+ pMbss = pMacEntry->pMbss;
+ }
+
+ /* AP does not send packets before port secured. */
+ if (pMbss != NULL)
+ {
+ if (((pMbss->AuthMode >= Ndis802_11AuthModeWPA)
+#ifdef DOT1X_SUPPORT
+ || (pMbss->IEEE8021X == TRUE)
+#endif /* DOT1X_SUPPORT */
+ ) &&
+ (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE)
+#ifdef WAPI_SUPPORT
+ && (RTMP_GET_PACKET_WAI(pPacket) == FALSE)
+#endif /* WAPI_SUPPORT */
+ )
+ {
+ /* Process for multicast or broadcast frame */
+ if ((Wcid == MCAST_WCID) && (pMbss->PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ /* Process for unicast frame */
+ if ((Wcid != MCAST_WCID) && pMacEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) APSendPacket --> Drop unknow packet !!!\n", apidx));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ if (pMbss == NULL)
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+#ifdef IGMP_SNOOP_SUPPORT
+ if (pAd->ApCfg.IgmpSnoopEnable)
+ {
+ UCHAR FromWhichBSSID, checkIgmpPkt = TRUE;
+
+ if (IS_ENTRY_WDS(pMacEntry))
+ FromWhichBSSID = pMacEntry->MatchWDSTabIdx + MIN_NET_DEVICE_FOR_WDS;
+ else if ((Wcid == MCAST_WCID) || IS_ENTRY_CLIENT(pMacEntry))
+ FromWhichBSSID = apidx;
+ else
+ checkIgmpPkt = FALSE;
+
+ if (checkIgmpPkt)
+ {
+ if (IgmpPktInfoQuery(pAd, pSrcBufVA, pPacket, FromWhichBSSID,
+ &InIgmpGroup, &pGroupEntry) != NDIS_STATUS_SUCCESS)
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+#endif /* IGMP_SNOOP_SUPPORT */
+
+ /*
+ 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 */
+#ifdef IGMP_SNOOP_SUPPORT
+ /* multicast packets in IgmpSn table should never send to Power-Saving queue. */
+ && (!InIgmpGroup)
+#endif /* IGMP_SNOOP_SUPPORT */
+ )
+ NumberOfFrag = 1;
+ else if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)
+ && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE))
+ {
+ NumberOfFrag = 1; /* Aggregation overwhelms fragmentation */
+ }
+ 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.
+ */
+ UINT32 Size;
+
+ AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+ Size = PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H;
+ if (Size >= AllowFragSize)
+ NumberOfFrag = (Size / AllowFragSize) + 1;
+ else
+ NumberOfFrag = 1;
+ }
+
+ /* Save fragment number to Ndis packet reserved field */
+ RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
+
+ /*
+ STEP 2. Check the requirement of RTS; decide packet TX rate
+ If multiple fragment required, RTS is required only for the first fragment
+ if the fragment size large than RTS threshold
+ */
+
+ if (NumberOfFrag > 1)
+ RTSRequired = (pAd->CommonCfg.FragmentThreshold > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
+ else
+ RTSRequired = (PacketInfo.TotalPacketLength > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
+
+ /* RTS/CTS may also be required in order to protect OFDM frame */
+ if ((Rate >= RATE_FIRST_OFDM_RATE) &&
+ (Rate <= RATE_LAST_OFDM_RATE) &&
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ RTSRequired = 1;
+
+ /* Save RTS requirement to Ndis packet reserved field */
+ RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
+ RTMP_SET_PACKET_TXRATE(pPacket, Rate);
+
+
+
+ /* detect AC Category of tx packets to tune AC0(BE) TX_OP (MAC reg 0x1300) */
+ detect_wmm_traffic(pAd, UserPriority, 1);
+
+ RTMP_SET_PACKET_UP(pPacket, UserPriority);
+
+ RTMP_SET_PACKET_MGMT_PKT(pPacket, 0x00); /* mark as non-management frame */
+
+#ifdef INF_AMAZON_SE
+ pAd->BulkOutDataSizeCount[QueIdx]+=SrcBufLen;
+#endif /* INF_AMAZON_SE */
+
+ /*
+ 4. put to corrsponding TxSwQueue or Power-saving queue
+ */
+
+ /* WDS and ApClient link should never go into power-save mode; just send out the frame */
+ if (pMacEntry && (IS_ENTRY_WDS(pMacEntry) || IS_ENTRY_APCLI(pMacEntry) || IS_ENTRY_MESH(pMacEntry)))
+ {
+#ifdef WDS_SUPPORT
+ ULONG Now32;
+ NdisGetSystemUpTime(&Now32);
+#endif /* WDS_SUPPORT */
+
+ if (pAd->TxSwQueue[QueIdx].Number >= pAd->TxSwQMaxLen)
+ {
+#ifdef BLOCK_NET_IF
+ StopNetIfQueue(pAd, QueIdx, pPacket);
+#endif /* BLOCK_NET_IF */
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+#ifdef WDS_SUPPORT
+ else if(IS_ENTRY_WDS(pMacEntry) /* when WDS Jam happen, drop following 1min to SWQueue Pkts */
+ && (pMacEntry->LockEntryTx == TRUE)
+ && RTMP_TIME_BEFORE(Now32, pMacEntry->TimeStamp_toTxRing + WDS_ENTRY_RETRY_INTERVAL))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+#endif /* WDS_SUPPORT */
+ else
+ {
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+ }
+ }
+ /* M/BCAST frames are put to PSQ as long as there's any associated STA in power-save mode */
+ else if ((*pSrcBufVA & 0x01) && pAd->MacTab.fAnyStationInPsm
+#ifdef IGMP_SNOOP_SUPPORT
+ /* multicast packets in IgmpSn table should never send to Power-Saving queue. */
+ && (!InIgmpGroup)
+#endif /* IGMP_SNOOP_SUPPORT */
+ )
+ {
+ /*
+ we don't want too many MCAST/BCAST backlog frames to eat up all buffers.
+ So in case number of backlog MCAST/BCAST frames exceeds a pre-defined
+ watermark within a DTIM period, simply drop coming new MCAST/BCAST frames.
+ This design is similiar to "BROADCAST throttling in most manageable
+ Ethernet Switch chip.
+ */
+ if (pAd->MacTab.McastPsQueue.Number >= MAX_PACKETS_IN_MCAST_PS_QUEUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ DBGPRINT(RT_DEBUG_TRACE, ("M/BCAST PSQ(=%ld) full, drop it!\n", pAd->MacTab.McastPsQueue.Number));
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ InsertHeadQueue(&pAd->MacTab.McastPsQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+ WLAN_MR_TIM_BCMC_SET(apidx); /* mark MCAST/BCAST TIM bit */
+ }
+ }
+ /* else if the associted STA in power-save mode, frame also goes to PSQ */
+ else if ((PsMode == PWR_SAVE) && pMacEntry &&
+ IS_ENTRY_CLIENT(pMacEntry) && (Sst == SST_ASSOC))
+ {
+ if (APInsertPsQueue(pAd, pPacket, pMacEntry, QueIdx)
+ != NDIS_STATUS_SUCCESS)
+ return NDIS_STATUS_FAILURE;
+ }
+ /* 3. otherwise, transmit the frame */
+ else /* (PsMode == PWR_ACTIVE) || (PsMode == PWR_UNKNOWN) */
+ {
+
+
+#ifdef IGMP_SNOOP_SUPPORT
+ /* if it's a mcast packet in igmp gourp. */
+ /* ucast clone it for all members in the gourp. */
+ if (((InIgmpGroup == IGMP_IN_GROUP)
+ && pGroupEntry
+ && (IgmpMemberCnt(&pGroupEntry->MemberList) > 0))
+ || (InIgmpGroup == IGMP_PKT))
+ {
+ NDIS_STATUS PktCloneResult = IgmpPktClone(pAd, pPacket, InIgmpGroup, pGroupEntry,
+ QueIdx, UserPriority, GET_OS_PKT_NETDEV(pPacket));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+ if (PktCloneResult != NDIS_STATUS_SUCCESS)
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+#endif /* IGMP_SNOOP_SUPPORT */
+ {
+
+ if (pAd->TxSwQueue[QueIdx].Number >= pAd->TxSwQMaxLen)
+ {
+
+#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
+ {
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+ }
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ RTMP_BASetup(pAd, pMacEntry, UserPriority);
+#endif /* DOT11_N_SUPPORT */
+
+/* TODO: for debug only. to be removed */
+/* pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; */
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+ --------------------------------------------------------
+ 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.
+*/
+static inline VOID APFindCipherAlgorithm(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ CIPHER_KEY *pKey = NULL;
+ UCHAR KeyIdx = 0, CipherAlg = CIPHER_NONE;
+ UCHAR apidx = pTxBlk->apidx;
+ UCHAR RAWcid = pTxBlk->Wcid;
+ MAC_TABLE_ENTRY *pMacEntry = pTxBlk->pMacEntry;
+ MULTISSID_STRUCT *pMbss;
+
+
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+#ifdef APCLI_SUPPORT
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bApCliPacket))
+ {
+ APCLI_STRUCT *pApCliEntry = pTxBlk->pApCliEntry;
+
+ if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+ {
+ /* These EAPoL frames must be clear before 4-way handshaking is completed. */
+ if ((!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame))) &&
+ (pMacEntry->PairwiseKey.CipherAlg) &&
+ (pMacEntry->PairwiseKey.KeyLen))
+ {
+ CipherAlg = pMacEntry->PairwiseKey.CipherAlg;
+ if (CipherAlg)
+ pKey = &pMacEntry->PairwiseKey;
+ }
+ else
+ {
+ CipherAlg = CIPHER_NONE;
+ pKey = NULL;
+ }
+ }
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ else if ( pApCliEntry->WpaSupplicantUP &&
+ (pMacEntry->WepStatus == Ndis802_11Encryption1Enabled) &&
+ (pApCliEntry->IEEE8021X == TRUE) &&
+ (pMacEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ CipherAlg = CIPHER_NONE;
+ }
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+ else if (pMacEntry->WepStatus == Ndis802_11Encryption1Enabled)
+ {
+ CipherAlg = pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId].CipherAlg;
+ if (CipherAlg)
+ pKey = &pApCliEntry->SharedKey[pApCliEntry->DefaultKeyId];
+ }
+ else if (pMacEntry->WepStatus == Ndis802_11Encryption2Enabled ||
+ pMacEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ CipherAlg = pMacEntry->PairwiseKey.CipherAlg;
+ if (CipherAlg)
+ pKey = &pMacEntry->PairwiseKey;
+ }
+ else
+ {
+ CipherAlg = CIPHER_NONE;
+ pKey = NULL;
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (TX_BLK_TEST_FLAG(pTxBlk,fTX_bWDSEntry))
+ {
+ if (pAd->WdsTab.WdsEntry[pMacEntry->MatchWDSTabIdx].WepStatus == Ndis802_11Encryption1Enabled ||
+ pAd->WdsTab.WdsEntry[pMacEntry->MatchWDSTabIdx].WepStatus == Ndis802_11Encryption2Enabled ||
+ pAd->WdsTab.WdsEntry[pMacEntry->MatchWDSTabIdx].WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ CipherAlg = pAd->WdsTab.WdsEntry[pMacEntry->MatchWDSTabIdx].WdsKey.CipherAlg;
+ if (CipherAlg)
+ pKey = &pAd->WdsTab.WdsEntry[pMacEntry->MatchWDSTabIdx].WdsKey;
+ }
+ else
+ {
+ CipherAlg = CIPHER_NONE;
+ pKey = NULL;
+ }
+ }
+ else
+#endif /* WDS_SUPPORT */
+#ifdef WAPI_SUPPORT
+ if (pMbss->WepStatus == Ndis802_11EncryptionSMS4Enabled)
+ {
+ if (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))
+ {
+ /* WAI negotiation packet is always clear. */
+ CipherAlg = CIPHER_NONE;
+ pKey = NULL;
+ }
+ else if (!pMacEntry)
+ {
+ KeyIdx = pMbss->DefaultKeyId; /* MSK ID */
+ CipherAlg = pAd->SharedKey[apidx][KeyIdx].CipherAlg;
+ if (CipherAlg == CIPHER_SMS4)
+ {
+ pKey = &pAd->SharedKey[apidx][KeyIdx];
+#ifdef SOFT_ENCRYPT
+ if (pMbss->sw_wpi_encrypt)
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bSwEncrypt);
+ /* TSC increment pre encryption transmittion */
+ inc_iv_byte(pKey->TxTsc, LEN_WAPI_TSC, 1);
+ }
+#endif /* SOFT_ENCRYPT */
+ }
+ }
+ else
+ {
+ KeyIdx = pTxBlk->pMacEntry->usk_id; /* USK ID */
+ CipherAlg = pAd->MacTab.Content[RAWcid].PairwiseKey.CipherAlg;
+ if (CipherAlg == CIPHER_SMS4)
+ {
+ pKey = &pAd->MacTab.Content[RAWcid].PairwiseKey;
+#ifdef SOFT_ENCRYPT
+ if (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_SOFTWARE_ENCRYPT))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bSwEncrypt);
+ /* TSC increment pre encryption transmittion */
+ inc_iv_byte(pKey->TxTsc, LEN_WAPI_TSC, 2);
+ }
+#endif /* SOFT_ENCRYPT */
+ }
+ }
+ }
+ else
+#endif /* WAPI_SUPPORT */
+ if ((RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) ||
+#ifdef DOT1X_SUPPORT
+ ((pMbss->WepStatus == Ndis802_11Encryption1Enabled) && (pMbss->IEEE8021X == TRUE)) ||
+#endif /* DOT1X_SUPPORT */
+ (pMbss->WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pMbss->WepStatus == Ndis802_11Encryption3Enabled) ||
+ (pMbss->WepStatus == Ndis802_11Encryption4Enabled))
+ {
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("APHardTransmit --> clear eap frame !!!\n"));
+ CipherAlg = CIPHER_NONE;
+ pKey = NULL;
+ }
+ else if (!pMacEntry) /* M/BCAST to local BSS, use default key in shared key table */
+ {
+ KeyIdx = pMbss->DefaultKeyId;
+ CipherAlg = pAd->SharedKey[apidx][KeyIdx].CipherAlg;
+ if (CipherAlg)
+ pKey = &pAd->SharedKey[apidx][KeyIdx];
+ }
+ else /* unicast to local BSS */
+ {
+ CipherAlg = pAd->MacTab.Content[RAWcid].PairwiseKey.CipherAlg;
+ if (CipherAlg)
+ pKey = &pAd->MacTab.Content[RAWcid].PairwiseKey;
+
+#ifdef SOFT_ENCRYPT
+ if (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_SOFTWARE_ENCRYPT))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bSwEncrypt);
+
+ /* TSC increment pre encryption transmittion */
+ if (pKey == NULL)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s pKey == NULL!\n", __FUNCTION__));
+ else
+ {
+ INC_TX_TSC(pKey->TxTsc, LEN_WPA_TSC);
+ }
+ }
+#endif /* SOFT_ENCRYPT */
+ }
+ }
+ else if (pMbss->WepStatus == Ndis802_11Encryption1Enabled) /* WEP always uses shared key table */
+ {
+ KeyIdx = pMbss->DefaultKeyId;
+ CipherAlg = pAd->SharedKey[apidx][KeyIdx].CipherAlg;
+ if (CipherAlg)
+ pKey = &pAd->SharedKey[apidx][KeyIdx];
+ }
+ else
+ {
+ CipherAlg = CIPHER_NONE;
+ pKey = NULL;
+ }
+
+ pTxBlk->CipherAlg = CipherAlg;
+ pTxBlk->pKey = pKey;
+ pTxBlk->KeyIdx = KeyIdx;
+}
+
+#ifdef DOT11_N_SUPPORT
+static inline VOID APBuildCache802_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;
+
+ /* SA */
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS)
+ if (FALSE
+#ifdef WDS_SUPPORT
+ || TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry)
+#endif /* WDS_SUPPORT */
+#ifdef CLIENT_WDS
+ || TX_BLK_TEST_FLAG(pTxBlk, fTX_bClientWDSFrame)
+#endif /* CLIENT_WDS */
+ )
+ { /* The addr3 of WDS packet is Destination Mac address and Addr4 is the Source Mac address. */
+ COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
+ COPY_MAC_ADDR(pHeader80211->Octet, pTxBlk->pSrcBufHeader + MAC_ADDR_LEN);
+ pTxBlk->MpduHeaderLen += MAC_ADDR_LEN;
+ }
+ else
+#endif /* WDS_SUPPORT || CLIENT_WDS */
+#ifdef APCLI_SUPPORT
+ if(IS_ENTRY_APCLI(pMacEntry))
+ { /* The addr3 of Ap-client packet is Destination Mac address. */
+ COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ { /* The addr3 of normal packet send from DS is Src Mac address. */
+ COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader + MAC_ADDR_LEN);
+ }
+
+
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+static inline VOID APBuildCacheWifiInfo(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR *pWiInfo)
+{
+ MAC_TABLE_ENTRY *pMacEntry;
+
+ PWIFI_INFO_STRUC pWI;
+
+ pWI = (PWIFI_INFO_STRUC)pWiInfo;
+ pMacEntry = pTxBlk->pMacEntry;
+
+ /* WIFI INFO size : 4 octets */
+ pTxBlk->MpduHeaderLen = WIFI_INFO_SIZE;
+
+ /* More Bit */
+ pWI->field.More_Data = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+ /* Sequence */
+ pWI->field.Seq_Num = pMacEntry->TxSeq[pTxBlk->UserPriority];
+ pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+
+}
+#endif /* HDR_TRANS_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef HDR_TRANS_SUPPORT
+static inline VOID APBuildWifiInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ PWIFI_INFO_STRUC pWI;
+
+
+ /* WIFI INFO size : 4 octets */
+ pTxBlk->MpduHeaderLen = WIFI_INFO_SIZE;
+
+ pWI =
+ (WIFI_INFO_STRUC *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize];
+
+ NdisZeroMemory(pWI, WIFI_INFO_SIZE);
+
+ pWI->field.Mode = 1; /* AP */
+ pWI->field.QoS = (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? 1 : 0;
+
+ if (pTxBlk->pMacEntry)
+ {
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
+ {
+ pWI->field.Seq_Num = pTxBlk->pMacEntry->NonQosDataSeq;
+ pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
+ }
+ else
+ {
+ pWI->field.Seq_Num = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
+ pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+ }
+ }
+ else
+ {
+ pWI->field.Seq_Num = pAd->Sequence;
+ pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; /* next sequence */
+ }
+
+ pWI->field.More_Data = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+ if (pTxBlk->CipherAlg != CIPHER_NONE)
+ pWI->field.WEP = 1;
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+static inline VOID APBuildCommon802_11Header(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *wifi_hdr;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ /*
+ MAKE A COMMON 802.11 HEADER
+ */
+
+ /* normal wlan header size : 24 octets */
+ pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+ wifi_hdr = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize + TSO_SIZE];
+ NdisZeroMemory(wifi_hdr, sizeof(HEADER_802_11));
+
+ wifi_hdr->FC.FrDs = 1;
+ wifi_hdr->FC.Type = BTYPE_DATA;
+ wifi_hdr->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
+
+ if (pTxBlk->pMacEntry)
+ {
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
+ {
+ wifi_hdr->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
+ pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
+ }
+ else
+ {
+ wifi_hdr->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
+ pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+ }
+ }
+ else
+ {
+ wifi_hdr->Sequence = pAd->Sequence;
+ pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; /* next sequence */
+ }
+
+ wifi_hdr->Frag = 0;
+ wifi_hdr->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+#ifdef APCLI_SUPPORT
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bApCliPacket))
+ {
+ wifi_hdr->FC.ToDs = 1;
+ wifi_hdr->FC.FrDs = 0;
+ COPY_MAC_ADDR(wifi_hdr->Addr1, APCLI_ROOT_BSSID_GET(pAd, pTxBlk->Wcid)); /* to AP2 */
+ COPY_MAC_ADDR(wifi_hdr->Addr2, pTxBlk->pApCliEntry->CurrentAddress); /* from AP1 */
+ COPY_MAC_ADDR(wifi_hdr->Addr3, pTxBlk->pSrcBufHeader); /* DA */
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS)
+ if (FALSE
+#ifdef WDS_SUPPORT
+ || TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry)
+#endif /* WDS_SUPPORT */
+#ifdef CLIENT_WDS
+ || TX_BLK_TEST_FLAG(pTxBlk, fTX_bClientWDSFrame)
+#endif /* CLIENT_WDS */
+ )
+ {
+ wifi_hdr->FC.ToDs = 1;
+ if (pTxBlk->pMacEntry == NULL)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s pTxBlk->pMacEntry == NULL!\n", __FUNCTION__));
+ else
+ COPY_MAC_ADDR(wifi_hdr->Addr1, pTxBlk->pMacEntry->Addr); /* to AP2 */
+
+ COPY_MAC_ADDR(wifi_hdr->Addr2, pAd->CurrentAddress); /* from AP1 */
+ COPY_MAC_ADDR(wifi_hdr->Addr3, pTxBlk->pSrcBufHeader); /* DA */
+ COPY_MAC_ADDR(&wifi_hdr->Octet[0], pTxBlk->pSrcBufHeader + MAC_ADDR_LEN);/* ADDR4 = SA */
+ pTxBlk->MpduHeaderLen += MAC_ADDR_LEN;
+ }
+ else
+#endif /* WDS_SUPPORT || CLIENT_WDS */
+ {
+ /* TODO: how about "MoreData" bit? AP need to set this bit especially for PS-POLL response */
+#ifdef IGMP_SNOOP_SUPPORT
+ if (pTxBlk->Wcid != MCAST_WCID)
+ {
+ COPY_MAC_ADDR(wifi_hdr->Addr1, pTxBlk->pMacEntry->Addr); /* DA */
+ }
+ else
+#endif /* IGMP_SNOOP_SUPPORT */
+ {
+ COPY_MAC_ADDR(wifi_hdr->Addr1, pTxBlk->pSrcBufHeader); /* DA */
+ }
+ COPY_MAC_ADDR(wifi_hdr->Addr2, pAd->ApCfg.MBSSID[pTxBlk->apidx].Bssid); /* BSSID */
+ COPY_MAC_ADDR(wifi_hdr->Addr3, pTxBlk->pSrcBufHeader + MAC_ADDR_LEN); /* SA */
+ }
+
+ if (pTxBlk->CipherAlg != CIPHER_NONE)
+ wifi_hdr->FC.Wep = 1;
+}
+
+
+static inline PUCHAR AP_Build_ARalink_Frame_Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;/*, pSaveBufPtr; */
+ HEADER_802_11 *pHeader_802_11;
+ PNDIS_PACKET pNextPacket;
+ UINT32 nextBufLen;
+ PQUEUE_ENTRY pQEntry;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ APFindCipherAlgorithm(pAd, pTxBlk);
+ APBuildCommon802_11Header(pAd, pTxBlk);
+
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize];
+ 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);
+#ifdef UAPSD_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+#ifdef WDS_SUPPORT
+ && (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry) == FALSE)
+#endif /* WDS_SUPPORT */
+ )
+ {
+ /*
+ * we can not use bMoreData bit to get EOSP bit because
+ * maybe bMoreData = 1 & EOSP = 1 when Max SP Length != 0
+ */
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ *pHeaderBufPtr |= (1 << 4);
+ }
+#endif /* UAPSD_SUPPORT */
+
+ *(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 BOOLEAN BuildHtcField(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN MAC_TABLE_ENTRY *pMacEntry,
+ IN PUCHAR pHeaderBufPtr)
+{
+ BOOLEAN bHTCPlus = FALSE;
+
+
+ return bHTCPlus;
+}
+
+
+static inline PUCHAR AP_Build_AMSDU_Frame_Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ UCHAR *pHeaderBufPtr;
+ HEADER_802_11 *pHeader_802_11;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ APFindCipherAlgorithm(pAd, pTxBlk);
+ APBuildCommon802_11Header(pAd, pTxBlk);
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize];
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ /* skip common header */
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ /* build QOS Control bytes */
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+#ifdef UAPSD_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+#ifdef WDS_SUPPORT
+ && (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry) == FALSE)
+#endif /* WDS_SUPPORT */
+ )
+ {
+ /*
+ * we can not use bMoreData bit to get EOSP bit because
+ * maybe bMoreData = 1 & EOSP = 1 when Max SP Length != 0
+ */
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ *pHeaderBufPtr |= (1 << 4);
+ }
+#endif /* UAPSD_SUPPORT */
+
+
+ /* A-MSDU packet */
+ *pHeaderBufPtr |= 0x80;
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+
+#ifdef TXBF_SUPPORT
+ if (pTxBlk->pMacEntry && pAd->chipCap.FlgHwTxBfCap)
+ {
+ MAC_TABLE_ENTRY *pMacEntry = pTxBlk->pMacEntry;
+ BOOLEAN bHTCPlus = FALSE;
+
+ pTxBlk->TxSndgPkt = SNDG_TYPE_DISABLE;
+
+ NdisAcquireSpinLock(&pMacEntry->TxSndgLock);
+ if (pMacEntry->TxSndgType >= SNDG_TYPE_SOUNDING)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+
+ if (pMacEntry->TxSndgType == SNDG_TYPE_SOUNDING)
+ {
+ /* Select compress if supported. Otherwise select noncompress */
+ if (pAd->CommonCfg.ETxBfNoncompress==0 &&
+ (pMacEntry->HTCapability.TxBFCap.ExpComBF>0) )
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 3;
+ else
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 2;
+
+ }
+ else if (pMacEntry->TxSndgType == SNDG_TYPE_NDP)
+ {
+ /* Select compress if supported. Otherwise select noncompress */
+ if (pAd->CommonCfg.ETxBfNoncompress==0 &&
+ (pMacEntry->HTCapability.TxBFCap.ExpComBF>0) &&
+ (pMacEntry->HTCapability.TxBFCap.ComSteerBFAntSup >= (pMacEntry->sndgMcs/8))
+ )
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 3;
+ else
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 2;
+
+ /* Set NDP Announcement */
+ ((PHT_CONTROL)pHeaderBufPtr)->NDPAnnounce = 1;
+
+ pTxBlk->TxNDPSndgBW = pMacEntry->sndgBW;
+ pTxBlk->TxNDPSndgMcs = pMacEntry->sndgMcs;
+ }
+
+ pTxBlk->TxSndgPkt = pMacEntry->TxSndgType;
+ /* arvin add for julian request send NDP */
+ pMacEntry->TxSndgType = SNDG_TYPE_DISABLE;
+ bHTCPlus = TRUE;
+ }
+ NdisReleaseSpinLock(&pMacEntry->TxSndgLock);
+
+#ifdef MFB_SUPPORT
+#if defined(MRQ_FORCE_TX) /* have to replace this by the correct condition!!! */
+ pMacEntry->HTCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_MRQ;
+#endif
+
+ /*
+ Ignore sounding frame because the signal format of sounding frmae may
+ be different from normal data frame, which may result in different MFB
+ */
+ if ((pMacEntry->HTCapability.ExtHtCapInfo.MCSFeedback >=MCSFBK_MRQ) &&
+ (pTxBlk->TxSndgPkt == SNDG_TYPE_DISABLE))
+ {
+ if (bHTCPlus == FALSE)
+ {
+ bHTCPlus = TRUE;
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ }
+
+ MFB_PerPareMRQ(pAd, pHeaderBufPtr, pMacEntry);
+ }
+
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback >=MCSFBK_MRQ && pMacEntry->toTxMfb == 1)
+ {
+ if (bHTCPlus == FALSE)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ bHTCPlus = TRUE;
+ }
+
+ MFB_PerPareMFB(pAd, pHeaderBufPtr, pMacEntry); /* not complete yet!!! */
+ pMacEntry->toTxMfb = 0;
+ }
+#endif /* MFB_SUPPORT */
+
+ if (bHTCPlus == TRUE)
+ {
+ pHeader_802_11->FC.Order = 1;
+ pHeaderBufPtr += 4;
+ pTxBlk->MpduHeaderLen += 4;
+ }
+ }
+#endif /* TXBF_SUPPORT */
+
+ /*
+ 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 AP_AMPDU_Frame_Tx(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ UCHAR *pHeaderBufPtr;
+ USHORT freeCnt = 1;
+ MAC_TABLE_ENTRY *pMacEntry;
+ PQUEUE_ENTRY pQEntry;
+ BOOLEAN bHTCPlus = FALSE;
+ UINT hdr_offset;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ ASSERT(pTxBlk);
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+#ifdef STATS_COUNT_SUPPORT
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+ if (pMbss != NULL)
+ pMbss->TxDropCount ++;
+#endif /* STATS_COUNT_SUPPORT */
+
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ hdr_offset = TXINFO_SIZE + TXWISize + TSO_SIZE;
+ pMacEntry = pTxBlk->pMacEntry;
+ if ((pMacEntry->isCached)
+#ifdef TXBF_SUPPORT
+ && (pMacEntry->TxSndgType == SNDG_TYPE_DISABLE)
+#endif /* TXBF_SUPPORT */
+ )
+ {
+#ifndef VENDOR_FEATURE1_SUPPORT
+ NdisMoveMemory((PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (PUCHAR)(&pMacEntry->CachedBuf[0]), TXWISize + sizeof(HEADER_802_11));
+#else
+ pTxBlk->HeaderBuf = (UCHAR *)(pMacEntry->HeaderBuf);
+#endif /* VENDOR_FEATURE1_SUPPORT */
+ pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[hdr_offset]);
+ APBuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
+
+#ifdef SOFT_ENCRYPT
+ RTMPUpdateSwCacheCipherInfo(pAd, pTxBlk, pHeaderBufPtr);
+#endif /* SOFT_ENCRYPT */
+ }
+ else
+ {
+ APFindCipherAlgorithm(pAd, pTxBlk);
+ APBuildCommon802_11Header(pAd, pTxBlk);
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[hdr_offset];
+ }
+
+#ifdef SOFT_ENCRYPT
+ 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 */
+
+#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 */
+#ifdef TXBF_SUPPORT
+ && (pMacEntry->TxSndgType == SNDG_TYPE_DISABLE)
+#endif /* TXBF_SUPPORT */
+ )
+ {
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ /* skip common header */
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ /* build QOS Control bytes */
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+#ifdef UAPSD_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+#ifdef WDS_SUPPORT
+ && (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry) == FALSE)
+#endif /* WDS_SUPPORT */
+ )
+ {
+ /*
+ * we can not use bMoreData bit to get EOSP bit because
+ * maybe bMoreData = 1 & EOSP = 1 when Max SP Length != 0
+ */
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ *pHeaderBufPtr |= (1 << 4);
+ }
+#endif /* UAPSD_SUPPORT */
+ 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);
+#ifdef UAPSD_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+#ifdef WDS_SUPPORT
+ && (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry) == FALSE)
+#endif /* WDS_SUPPORT */
+ )
+ {
+ /*
+ * we can not use bMoreData bit to get EOSP bit because
+ * maybe bMoreData = 1 & EOSP = 1 when Max SP Length != 0
+ */
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ *pHeaderBufPtr |= (1 << 4);
+ }
+#endif /* UAPSD_SUPPORT */
+
+ *(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))
+#ifdef TXBF_SUPPORT
+ && (pMacEntry->TxSndgType != SNDG_TYPE_NDP)
+#endif /* TXBF_SUPPORT */
+ )
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ ((PHT_CONTROL)pHeaderBufPtr)->RDG = 1;
+ bHTCPlus = TRUE;
+ }
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ {
+ pTxBlk->TxSndgPkt = SNDG_TYPE_DISABLE;
+
+ NdisAcquireSpinLock(&pMacEntry->TxSndgLock);
+ if (pMacEntry->TxSndgType >= SNDG_TYPE_SOUNDING)
+ {
+ if (bHTCPlus == FALSE)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ bHTCPlus = TRUE;
+ }
+
+ if (pMacEntry->TxSndgType == SNDG_TYPE_SOUNDING)
+ {
+ /* Select compress if supported. Otherwise select noncompress */
+ if (pAd->CommonCfg.ETxBfNoncompress==0 &&
+ (pMacEntry->HTCapability.TxBFCap.ExpComBF>0) )
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 3;
+ else
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 2;
+
+ }
+ else if (pMacEntry->TxSndgType == SNDG_TYPE_NDP)
+ {
+ /* Select compress if supported. Otherwise select noncompress */
+ if ((pAd->CommonCfg.ETxBfNoncompress==0) &&
+ (pMacEntry->HTCapability.TxBFCap.ExpComBF>0) &&
+ (pMacEntry->HTCapability.TxBFCap.ComSteerBFAntSup >= (pMacEntry->sndgMcs/8))
+ )
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 3;
+ else
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 2;
+
+ /* Set NDP Announcement */
+ ((PHT_CONTROL)pHeaderBufPtr)->NDPAnnounce = 1;
+
+ pTxBlk->TxNDPSndgBW = pMacEntry->sndgBW;
+ pTxBlk->TxNDPSndgMcs = pMacEntry->sndgMcs;
+ }
+
+ pTxBlk->TxSndgPkt = pMacEntry->TxSndgType;
+ pMacEntry->TxSndgType = SNDG_TYPE_DISABLE;
+ }
+
+ NdisReleaseSpinLock(&pMacEntry->TxSndgLock);
+
+#ifdef MFB_SUPPORT
+#if defined(MRQ_FORCE_TX) /* have to replace this by the correct condition!!! */
+ pMacEntry->HTCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_MRQ;
+#endif
+
+ /*
+ Ignore sounding frame because the signal format of sounding frmae may
+ be different from normal data frame, which may result in different MFB
+ */
+ if ((pMacEntry->HTCapability.ExtHtCapInfo.MCSFeedback >=MCSFBK_MRQ) &&
+ (pTxBlk->TxSndgPkt == SNDG_TYPE_DISABLE))
+ {
+ if (bHTCPlus == FALSE)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ bHTCPlus = TRUE;
+ }
+ MFB_PerPareMRQ(pAd, pHeaderBufPtr, pMacEntry);
+ }
+
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback >=MCSFBK_MRQ &&
+ pMacEntry->toTxMfb == 1)
+ {
+ if (bHTCPlus == FALSE)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ bHTCPlus = TRUE;
+ }
+ MFB_PerPareMFB(pAd, pHeaderBufPtr, pMacEntry);/* not complete yet!!! */
+ pMacEntry->toTxMfb = 0;
+ }
+#endif /* MFB_SUPPORT */
+ }
+#endif /* TXBF_SUPPORT */
+
+ if (bHTCPlus == TRUE)
+ {
+ /* mark HTC bit */
+ pHeader_802_11->FC.Order = 1;
+ pHeaderBufPtr += 4;
+ pTxBlk->MpduHeaderLen += 4;
+ }
+
+ /*pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; */
+ ASSERT(pTxBlk->MpduHeaderLen >= 24);
+
+ /* 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;
+ }
+
+ /*
+ The remaining content of MPDU 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)
+#ifdef TXBF_SUPPORT
+ && (pTxBlk->TxSndgPkt == SNDG_TYPE_DISABLE)
+#endif /* TXBF_SUPPORT */
+ )
+ {
+ RTMPWriteTxWI_Cache(pAd, (TXWI_STRUC *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+ }
+ else
+ {
+ RTMPWriteTxWI_Data(pAd, (TXWI_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 TXBF_SUPPORT
+ if (pTxBlk->TxSndgPkt != SNDG_TYPE_DISABLE)
+ pMacEntry->isCached = FALSE;
+#endif /* TXBF_SUPPORT */
+
+#ifdef STATS_COUNT_SUPPORT
+ /* calculate Transmitted AMPDU count and ByteCount */
+ {
+ pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
+ pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
+ }
+
+ /* calculate Tx count and ByteCount per BSS */
+#ifdef WAPI_SUPPORT
+ if (IS_ENTRY_CLIENT(pMacEntry))
+#endif /* WAPI_SUPPORT */
+ {
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+#ifdef WAPI_SUPPORT
+ if (pMacEntry->WapiUskRekeyTimerRunning &&
+ pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ pMacEntry->wapi_usk_rekey_cnt += pTxBlk->SrcBufLen;
+#endif /* WAPI_SUPPORT */
+
+ if (pMbss != NULL)
+ {
+ pMbss->TransmittedByteCount += pTxBlk->SrcBufLen;
+ pMbss->TxCount ++;
+
+#ifdef STATS_COUNT_SUPPORT
+ if(IS_MULTICAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->mcPktsTx++;
+ else if(IS_BROADCAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->bcPktsTx++;
+ else
+ pMbss->ucPktsTx++;
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ if(pMacEntry->Sst == SST_ASSOC)
+ {
+ INC_COUNTER64(pMacEntry->TxPackets);
+ pMacEntry->TxBytes+=pTxBlk->SrcBufLen;
+ }
+ }
+
+#ifdef WDS_SUPPORT
+ if (pMacEntry && IS_ENTRY_WDS(pMacEntry))
+ {
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedFragmentCount);
+ pAd->WdsTab.WdsEntry[pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedByteCount+= pTxBlk->SrcBufLen;
+ }
+#endif /* WDS_SUPPORT */
+#endif /* STATS_COUNT_SUPPORT */
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &freeCnt);
+
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFRAME)
+ dbQueueEnqueueTxFrame((UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (UCHAR *)pHeader_802_11);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ /*
+ Kick out Tx
+ */
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+VOID AP_AMPDU_Frame_Tx_Hdr_Trns(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pWiBufPtr;
+/* UCHAR QueIdx = pTxBlk->QueIdx; */
+ USHORT FreeNumber = 1; /* no use */
+ MAC_TABLE_ENTRY *pMacEntry;
+ PQUEUE_ENTRY pQEntry;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ PWIFI_INFO_STRUC pWI;
+
+ ASSERT(pTxBlk);
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+#ifdef STATS_COUNT_SUPPORT
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+ if (pMbss != NULL)
+ pMbss->TxDropCount ++;
+#endif /* STATS_COUNT_SUPPORT */
+
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+/*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_2[index]));
+ }
+*/
+
+ pMacEntry = pTxBlk->pMacEntry;
+ if ((pMacEntry->isCached)
+ )
+ {
+ /* It should be cleared!!! */
+ /*NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), sizeof(pTxBlk->HeaderBuf)); */
+ NdisMoveMemory((PUCHAR)
+ (&pTxBlk->HeaderBuf[TXINFO_SIZE]),
+ (PUCHAR) (&pMacEntry->CachedBuf[0]),
+ TXWISize + WIFI_INFO_SIZE);
+
+ pWiBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize]);
+ APBuildCacheWifiInfo(pAd, pTxBlk, pWiBufPtr);
+ }
+ else
+ {
+ APFindCipherAlgorithm(pAd, pTxBlk);
+ APBuildWifiInfo(pAd, pTxBlk);
+
+ pWiBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize];
+ }
+
+ pWI = (PWIFI_INFO_STRUC)pWiBufPtr;
+
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader;
+
+ if (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket))
+ pWI->field.VLAN = TRUE;
+
+ pWI->field.TID = (pTxBlk->UserPriority & 0x0F);
+#ifdef UAPSD_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+ && TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ pWI->field.EOSP = TRUE;
+#endif /* UAPSD_SUPPORT */
+
+ if (pTxBlk->pMbss)
+ pWI->field.BssIdx = pMacEntry->apidx;
+
+
+ {
+
+ /*
+ build HTC+
+ HTC control filed following QoS field
+ */
+ if ((pAd->CommonCfg.bRdg == TRUE)
+ && (CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
+ )
+ {
+ pWI->field.RDG = 1;
+ }
+
+ }
+
+/*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_3[index]));
+ }
+*/
+
+ if ((pMacEntry->isCached)
+ )
+ {
+ RTMPWriteTxWI_Cache(pAd, (TXWI_STRUC *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+ }
+ else
+ {
+ RTMPWriteTxWI_Data(pAd, (TXWI_STRUC *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
+ NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]),
+ (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]),
+ TXWISize + WIFI_INFO_SIZE);
+
+
+ pMacEntry->isCached = TRUE;
+
+ }
+
+
+#ifdef STATS_COUNT_SUPPORT
+ /* calculate Transmitted AMPDU count and ByteCount */
+ {
+ pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
+ pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
+ }
+
+ /* calculate Tx count and ByteCount per BSS */
+#ifdef WAPI_SUPPORT
+ if (IS_ENTRY_CLIENT(pMacEntry))
+#endif /* WAPI_SUPPORT */
+ {
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+#ifdef WAPI_SUPPORT
+ if (pMacEntry->WapiUskRekeyTimerRunning &&
+ pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ pMacEntry->wapi_usk_rekey_cnt += pTxBlk->SrcBufLen;
+#endif /* WAPI_SUPPORT */
+
+ if (pMbss != NULL)
+ {
+ pMbss->TransmittedByteCount += pTxBlk->SrcBufLen;
+ pMbss->TxCount ++;
+
+#ifdef STATS_COUNT_SUPPORT
+ if(IS_MULTICAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->mcPktsTx++;
+ else if(IS_BROADCAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->bcPktsTx++;
+ else
+ pMbss->ucPktsTx++;
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ if(pMacEntry->Sst == SST_ASSOC)
+ {
+ INC_COUNTER64(pMacEntry->TxPackets);
+ pMacEntry->TxBytes+=pTxBlk->SrcBufLen;
+ }
+ }
+
+#endif /* STATS_COUNT_SUPPORT */
+
+ /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+
+
+ /*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_4[index]));
+ }
+*/
+
+ /*
+ Kick out Tx
+ */
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+/*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_5[index]));
+ if ( pAd->debug_index < 201 )
+ {
+ pAd->debug_index ++;
+ } else {
+ pAd->debug_on = 0;
+ }
+ }
+*/
+
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+VOID AP_AMSDU_Frame_Tx(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;
+ USHORT freeCnt = 1; /* no use */
+ USHORT subFramePayloadLen = 0; /* AMSDU Subframe length without AMSDU-Header / Padding. */
+ USHORT totalMPDUSize=0;
+ UCHAR *subFrameHeader;
+ UCHAR padding = 0;
+ USHORT FirstTx = 0, LastTxIdx = 0;
+ int frameNum = 0;
+ PQUEUE_ENTRY pQEntry;
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ PAPCLI_STRUCT pApCliEntry = NULL;
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ 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)
+ {
+#ifdef STATS_COUNT_SUPPORT
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+ if (pMbss != NULL)
+ pMbss->TxDropCount++;
+#endif /* STATS_COUNT_SUPPORT */
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ /* 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;
+ }
+
+ if (frameNum == 0)
+ {
+ pHeaderBufPtr = AP_Build_AMSDU_Frame_Header(pAd, pTxBlk);
+
+ /* NOTE: TxWI->TxWIMPDUByteCnt will be updated after final frame was handled. */
+ RTMPWriteTxWI_Data(pAd, (TXWI_STRUC *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+ }
+ else
+ {
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE];
+ padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
+ NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
+ pHeaderBufPtr += padding;
+ pTxBlk->MpduHeaderLen = padding;
+ pTxBlk->HdrPadLen += padding;
+ }
+
+ /*
+ A-MSDU subframe
+ DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
+ */
+ subFrameHeader = pHeaderBufPtr;
+ subFramePayloadLen = pTxBlk->SrcBufLen;
+
+ NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
+
+#ifdef APCLI_SUPPORT
+ if(TX_BLK_TEST_FLAG(pTxBlk, fTX_bApCliPacket))
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[pTxBlk->pMacEntry->MatchAPCLITabIdx];
+ if (pApCliEntry->Valid)
+ NdisMoveMemory(&subFrameHeader[6] , pApCliEntry->CurrentAddress, 6);
+ }
+#endif /* APCLI_SUPPORT */
+
+
+ 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, &freeCnt);
+ else
+ LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &freeCnt);
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFRAME)
+ dbQueueEnqueueTxFrame((UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), NULL);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ frameNum++;
+
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+#ifdef STATS_COUNT_SUPPORT
+ {
+ /* calculate Transmitted AMSDU Count and ByteCount */
+ pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
+ pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
+ }
+
+ /* calculate Tx count and ByteCount per BSS */
+#ifdef WAPI_SUPPORT
+ if (IS_ENTRY_CLIENT(pTxBlk->pMacEntry))
+#endif /* WAPI_SUPPORT */
+ {
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+ MAC_TABLE_ENTRY *pMacEntry = pTxBlk->pMacEntry;
+
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry->WapiUskRekeyTimerRunning && pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ pTxBlk->pMacEntry->wapi_usk_rekey_cnt += totalMPDUSize;
+#endif /* WAPI_SUPPORT */
+
+ if (pMbss != NULL)
+ {
+ pMbss->TransmittedByteCount += totalMPDUSize;
+ pMbss->TxCount ++;
+
+#ifdef STATS_COUNT_SUPPORT
+ if(IS_MULTICAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->mcPktsTx++;
+ else if(IS_BROADCAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->bcPktsTx++;
+ else
+ pMbss->ucPktsTx++;
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ if(pMacEntry->Sst == SST_ASSOC)
+ {
+ INC_COUNTER64(pMacEntry->TxPackets);
+ pMacEntry->TxBytes+=pTxBlk->SrcBufLen;
+ }
+ }
+
+#ifdef WDS_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_WDS(pTxBlk->pMacEntry))
+ {
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedFragmentCount);
+ pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedByteCount+= pTxBlk->SrcBufLen;
+ }
+#endif /* WDS_SUPPORT */
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+ HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+ /*
+ Kick out Tx
+ */
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+#endif /* DOT11_N_SUPPORT */
+
+
+VOID AP_Legacy_Frame_Tx(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *wifi_hdr;
+ UCHAR *pHeaderBufPtr;
+ USHORT freeCnt = 1;
+ BOOLEAN bVLANPkt;
+ QUEUE_ENTRY *pQEntry;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ ASSERT(pTxBlk);
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+#ifdef STATS_COUNT_SUPPORT
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+ if (pMbss != NULL)
+ pMbss->TxDropCount++;
+#endif /* STATS_COUNT_SUPPORT */
+ 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 */
+
+
+ APFindCipherAlgorithm(pAd, pTxBlk);
+ APBuildCommon802_11Header(pAd, pTxBlk);
+
+#ifdef SOFT_ENCRYPT
+ 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 */
+
+ /* skip 802.3 header */
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ /* skip vlan tag */
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ /* record these MCAST_TX frames for group key rekey */
+ if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
+ {
+ INT idx;
+
+ for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++)
+ {
+ if (pAd->ApCfg.MBSSID[idx].REKEYTimerRunning &&
+ pAd->ApCfg.MBSSID[idx].WPAREKEY.ReKeyMethod == PKT_REKEY)
+ {
+ pAd->ApCfg.MBSSID[idx].REKEYCOUNTER += (pTxBlk->SrcBufLen);
+ }
+ }
+#ifdef WAPI_SUPPORT
+ if (pAd->CommonCfg.WapiMskRekeyTimerRunning &&
+ pAd->CommonCfg.wapi_msk_rekey_method == REKEY_METHOD_PKT)
+ {
+ pAd->CommonCfg.wapi_msk_rekey_cnt += (pTxBlk->SrcBufLen);
+ }
+#endif /* WAPI_SUPPORT */
+ }
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize + TSO_SIZE];
+ wifi_hdr = (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));
+#ifdef UAPSD_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+#ifdef WDS_SUPPORT
+ && (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry) == FALSE)
+#endif /* WDS_SUPPORT */
+ )
+ {
+ /*
+ * we can not use bMoreData bit to get EOSP bit because
+ * maybe bMoreData = 1 & EOSP = 1 when Max SP Length != 0
+ */
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ *pHeaderBufPtr |= (1 << 4);
+ }
+#endif /* UAPSD_SUPPORT */
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap &&
+ (pTxBlk->pMacEntry) &&
+ (pTxBlk->pTransmit->field.MODE >= MODE_HTMIX))
+ {
+ MAC_TABLE_ENTRY *pMacEntry = pTxBlk->pMacEntry;
+ BOOLEAN bHTCPlus = FALSE;
+
+ pTxBlk->TxSndgPkt = SNDG_TYPE_DISABLE;
+
+ NdisAcquireSpinLock(&pMacEntry->TxSndgLock);
+ if (pMacEntry->TxSndgType >= SNDG_TYPE_SOUNDING)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+
+ if (pMacEntry->TxSndgType == SNDG_TYPE_SOUNDING)
+ {
+ /* Select compress if supported. Otherwise select noncompress */
+ if ((pAd->CommonCfg.ETxBfNoncompress==0) &&
+ (pMacEntry->HTCapability.TxBFCap.ExpComBF>0))
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 3;
+ else
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 2;
+
+ }
+ else if (pMacEntry->TxSndgType == SNDG_TYPE_NDP)
+ {
+ /* Select compress if supported. Otherwise select noncompress */
+ if ((pAd->CommonCfg.ETxBfNoncompress == 0) &&
+ (pMacEntry->HTCapability.TxBFCap.ExpComBF>0) &&
+ (pMacEntry->HTCapability.TxBFCap.ComSteerBFAntSup >= (pMacEntry->sndgMcs/8))
+ )
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 3;
+ else
+ ((PHT_CONTROL)pHeaderBufPtr)->CSISTEERING = 2;
+
+ /* Set NDP Announcement */
+ ((PHT_CONTROL)pHeaderBufPtr)->NDPAnnounce = 1;
+
+ pTxBlk->TxNDPSndgBW = pMacEntry->sndgBW;
+ pTxBlk->TxNDPSndgMcs = pMacEntry->sndgMcs;
+ }
+
+ pTxBlk->TxSndgPkt = pMacEntry->TxSndgType;
+ pMacEntry->TxSndgType = SNDG_TYPE_DISABLE;
+ bHTCPlus = TRUE;
+ }
+ NdisReleaseSpinLock(&pMacEntry->TxSndgLock);
+
+#ifdef MFB_SUPPORT
+#if defined(MRQ_FORCE_TX)
+ /* have to replace this by the correct condition!!! */
+ pMacEntry->HTCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_MRQ;
+#endif
+
+ /*
+ Because the signal format of sounding frmae may be different
+ from normal data frame, which may result in different MFB
+ */
+ if ((pMacEntry->HTCapability.ExtHtCapInfo.MCSFeedback >=MCSFBK_MRQ) &&
+ (pTxBlk->TxSndgPkt == SNDG_TYPE_DISABLE))
+ {
+ if (bHTCPlus == FALSE)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ bHTCPlus = TRUE;
+ }
+ MFB_PerPareMRQ(pAd, pHeaderBufPtr, pMacEntry);
+ }
+
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback >=MCSFBK_MRQ && pMacEntry->toTxMfb == 1)
+ {
+ if (bHTCPlus == FALSE)
+ {
+ NdisZeroMemory(pHeaderBufPtr, sizeof(HT_CONTROL));
+ bHTCPlus = TRUE;
+ }
+
+ MFB_PerPareMFB(pAd, pHeaderBufPtr, pMacEntry);/* not complete yet!!!*/
+ pMacEntry->toTxMfb = 0;
+ }
+#endif /* MFB_SUPPORT */
+
+ if (bHTCPlus == TRUE)
+ {
+ /* mark HTC bit */
+ pHeader_802_11->FC.Order = 1;
+ pHeaderBufPtr += 4;
+ pTxBlk->MpduHeaderLen += 4;
+ }
+ }
+#endif /* TXBF_SUPPORT */
+ }
+
+ /* 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)wifi_hdr,
+ 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;
+ }
+ }
+
+#ifdef STATS_COUNT_SUPPORT
+ /* calculate Tx count and ByteCount per BSS */
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_CLIENT(pTxBlk->pMacEntry))
+#endif /* WAPI_SUPPORT */
+ {
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+ MAC_TABLE_ENTRY *pMacEntry=pTxBlk->pMacEntry;
+
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry->WapiUskRekeyTimerRunning && pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ pTxBlk->pMacEntry->wapi_usk_rekey_cnt += pTxBlk->SrcBufLen;
+#endif /* WAPI_SUPPORT */
+
+ if (pMbss != NULL)
+ {
+ pMbss->TransmittedByteCount += pTxBlk->SrcBufLen;
+ pMbss->TxCount ++;
+
+#ifdef STATS_COUNT_SUPPORT
+ if(IS_MULTICAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->mcPktsTx++;
+ else if(IS_BROADCAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->bcPktsTx++;
+ else
+ pMbss->ucPktsTx++;
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ if(pMacEntry && pMacEntry->Sst == SST_ASSOC)
+ {
+ INC_COUNTER64(pMacEntry->TxPackets);
+ pMacEntry->TxBytes+=pTxBlk->SrcBufLen;
+ }
+ }
+
+#ifdef WDS_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_WDS(pTxBlk->pMacEntry))
+ {
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedFragmentCount);
+ pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedByteCount+= pTxBlk->SrcBufLen;
+ }
+#endif /* WDS_SUPPORT */
+#endif /* STATS_COUNT_SUPPORT */
+
+ /*
+ prepare for TXWI
+ */
+
+ /* update Hardware Group Key Index */
+ if (!pTxBlk->pMacEntry)
+ {
+ /* use Wcid as Hardware Key Index */
+ GET_GroupKey_WCID(pAd, pTxBlk->Wcid, pTxBlk->apidx);
+ }
+
+ RTMPWriteTxWI_Data(pAd, (TXWI_STRUC *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &freeCnt);
+
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFRAME)
+ dbQueueEnqueueTxFrame((UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (UCHAR *)wifi_hdr);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ /*
+ Kick out Tx
+ */
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+VOID AP_Legacy_Frame_Tx_Hdr_Trns(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+/* UCHAR QueIdx = pTxBlk->QueIdx; */
+ USHORT FreeNumber = 1; /* no use */
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ PWIFI_INFO_STRUC pWI;
+
+ ASSERT(pTxBlk);
+
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+#ifdef STATS_COUNT_SUPPORT
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+ if (pMbss != NULL)
+ pMbss->TxDropCount++;
+#endif /* STATS_COUNT_SUPPORT */
+ 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 */
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ APFindCipherAlgorithm(pAd, pTxBlk);
+
+/*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_2[index]));
+ }
+*/
+
+ APBuildWifiInfo(pAd, pTxBlk);
+
+ pWI = (PWIFI_INFO_STRUC)&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWISize];
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader;
+ if (bVLANPkt)
+ pWI->field.VLAN = TRUE;
+
+ pWI->field.TID = (pTxBlk->UserPriority & 0x0F);
+#ifdef UAPSD_SUPPORT
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)
+ && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+ && TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ pWI->field.EOSP = TRUE;
+#endif /* UAPSD_SUPPORT */
+
+ if (pTxBlk->pMbss)
+ pWI->field.BssIdx = pTxBlk->pMacEntry->apidx;
+
+
+#ifdef STATS_COUNT_SUPPORT
+ /* calculate Tx count and ByteCount per BSS */
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_CLIENT(pTxBlk->pMacEntry))
+#endif /* WAPI_SUPPORT */
+ {
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+ MAC_TABLE_ENTRY *pMacEntry=pTxBlk->pMacEntry;
+
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry->WapiUskRekeyTimerRunning && pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ pTxBlk->pMacEntry->wapi_usk_rekey_cnt += pTxBlk->SrcBufLen;
+#endif /* WAPI_SUPPORT */
+
+ if (pMbss != NULL)
+ {
+ pMbss->TransmittedByteCount += pTxBlk->SrcBufLen;
+ pMbss->TxCount ++;
+
+#ifdef STATS_COUNT_SUPPORT
+ if(IS_MULTICAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->mcPktsTx++;
+ else if(IS_BROADCAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->bcPktsTx++;
+ else
+ pMbss->ucPktsTx++;
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ if(pMacEntry && pMacEntry->Sst == SST_ASSOC)
+ {
+ INC_COUNTER64(pMacEntry->TxPackets);
+ pMacEntry->TxBytes+=pTxBlk->SrcBufLen;
+ }
+ }
+
+#endif /* STATS_COUNT_SUPPORT */
+
+ /*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_3[index]));
+ }
+*/
+
+ /*
+ prepare for TXWI
+ */
+
+ /* update Hardware Group Key Index */
+ if (!pTxBlk->pMacEntry)
+ {
+ /* use Wcid as Hardware Key Index */
+ GET_GroupKey_WCID(pAd, pTxBlk->Wcid, pTxBlk->apidx);
+ }
+
+ RTMPWriteTxWI_Data(pAd, (TXWI_STRUC *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFRAME)
+ dbQueueEnqueueTxFrame((UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (UCHAR *)pHeader_802_11);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ /*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_4[index]));
+ }
+*/
+
+ /*
+ Kick out Tx
+ */
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+
+/*
+ if ( pAd->debug_on )
+ {
+ UCHAR index = RTMP_GET_DEBUG_INDEX(pTxBlk->pPacket);
+ do_gettimeofday(&(pAd->debug_time_5[index]));
+ if ( pAd->debug_index < 201 )
+ {
+ pAd->debug_index ++;
+ } else {
+ pAd->debug_on = 0;
+ }
+
+ }
+*/
+
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+VOID AP_Fragment_Frame_Tx(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ UCHAR *pHeaderBufPtr;
+ USHORT freeCnt = 1; /* no use */
+ UCHAR fragNum = 0;
+ USHORT EncryptionOverhead = 0;
+ UINT32 FreeMpduSize, SrcRemainingBytes;
+ USHORT AckDuration;
+ UINT NextMpduSize;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+ PACKET_INFO PacketInfo;
+#ifdef SOFT_ENCRYPT
+ UCHAR *tmp_ptr = NULL;
+ UINT32 buf_offset = 0;
+#endif /* SOFT_ENCRYPT */
+ HTTRANSMIT_SETTING *pTransmit;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ ASSERT(pTxBlk);
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+
+ if(RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+#ifdef STATS_COUNT_SUPPORT
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+ if (pMbss != NULL)
+ pMbss->TxDropCount++;
+#endif /* STATS_COUNT_SUPPORT */
+ 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);
+
+ APFindCipherAlgorithm(pAd, pTxBlk);
+ APBuildCommon802_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 + TXWISize];
+ 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);
+#ifdef UAPSD_SUPPORT
+ if (pTxBlk->pMacEntry &&
+ CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_APSD_CAPABLE)
+#ifdef WDS_SUPPORT
+ && (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWDSEntry) == FALSE)
+#endif /* WDS_SUPPORT */
+ )
+ {
+ /*
+ * we can not use bMoreData bit to get EOSP bit because
+ * maybe bMoreData = 1 & EOSP = 1 when Max SP Length != 0
+ */
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP))
+ *pHeaderBufPtr |= (1 << 4);
+ }
+#endif /* UAPSD_SUPPORT */
+
+ *(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;
+
+ /*
+ 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;
+ }
+ }
+
+ /* 1. If TKIP is used and fragmentation is required. Driver has to
+ append TKIP MIC at tail of the scatter buffer
+ 2. When TXWI->FRAG is set as 1 in TKIP mode,
+ MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC */
+ /* TKIP appends the computed MIC to the MSDU data prior to fragmentation into MPDUs. */
+ if (pTxBlk->CipherAlg == CIPHER_TKIP)
+ {
+ RTMPCalculateMICValue(pAd, pTxBlk->pPacket, pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, pTxBlk->apidx);
+
+ /*
+ 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;
+ }
+
+#ifdef STATS_COUNT_SUPPORT
+ /* calculate Tx count and ByteCount per BSS */
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_CLIENT(pTxBlk->pMacEntry))
+#endif /* WAPI_SUPPORT */
+ {
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+ MAC_TABLE_ENTRY *pMacEntry=pTxBlk->pMacEntry;
+
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry->WapiUskRekeyTimerRunning && pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ pTxBlk->pMacEntry->wapi_usk_rekey_cnt += pTxBlk->SrcBufLen;
+#endif /* WAPI_SUPPORT */
+
+ if (pMbss != NULL)
+ {
+ pMbss->TransmittedByteCount += pTxBlk->SrcBufLen;
+ pMbss->TxCount ++;
+
+#ifdef STATS_COUNT_SUPPORT
+ if(IS_MULTICAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->mcPktsTx++;
+ else if(IS_BROADCAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->bcPktsTx++;
+ else
+ pMbss->ucPktsTx++;
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ if(pMacEntry && pMacEntry->Sst == SST_ASSOC)
+ {
+ INC_COUNTER64(pMacEntry->TxPackets);
+ pMacEntry->TxBytes+=pTxBlk->SrcBufLen;
+ }
+ }
+
+#ifdef WDS_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_WDS(pTxBlk->pMacEntry))
+ {
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedFragmentCount);
+ pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedByteCount+= pTxBlk->SrcBufLen;
+ }
+#endif /* WDS_SUPPORT */
+#endif /* STATS_COUNT_SUPPORT */
+
+ /*
+ 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] */
+#ifdef WAPI_SUPPORT
+ else if (pTxBlk->CipherAlg == CIPHER_SMS4)
+ EncryptionOverhead = 16; /* SMS4: MIC[16] */
+#endif /* WAPI_SUPPORT */
+ 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);
+ /*DBGPRINT(RT_DEBUG_INFO, ("!!!Fragment AckDuration(%d), TxRate(%d)!!!\n", AckDuration, pTxBlk->TxRate)); */
+
+ /* 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, (TXWI_STRUC *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &freeCnt);
+
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFRAME)
+ dbQueueEnqueueTxFrame((UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (UCHAR *)pHeader_802_11);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+#ifdef SOFT_ENCRYPT
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt))
+ {
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->CipherAlg == CIPHER_SMS4)
+ {
+ /* incease WPI IV for next MPDU */
+ inc_iv_byte(pTxBlk->pKey->TxTsc, LEN_WAPI_TSC, 2);
+ /* Construct and insert WPI-SMS4 IV header to MPDU header */
+ RTMPConstructWPIIVHdr(pTxBlk->KeyIdx, pTxBlk->pKey->TxTsc,
+ pHeaderBufPtr - (LEN_WPI_IV_HDR));
+ }
+ else
+#endif /* WAPI_SUPPORT */
+ 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 */
+ {
+ /* Update the frame number, remaining size of the NDIS packet payload. */
+ if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
+ pTxBlk->MpduHeaderLen -= LENGTH_802_1_H; /* space for 802.11 header. */
+ }
+
+ 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
+ */
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+}
+
+
+VOID AP_ARalink_Frame_Tx(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ UCHAR *pHeaderBufPtr;
+ USHORT freeCnt = 1; /* no use */
+ 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)
+ {
+#ifdef STATS_COUNT_SUPPORT
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+
+ if (pMbss != NULL)
+ pMbss->TxDropCount++;
+#endif /* STATS_COUNT_SUPPORT */
+
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ /* skip 802.3 header */
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ /* skip vlan tag */
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+ 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 = AP_Build_ARalink_Frame_Header(pAd, pTxBlk);
+
+ /*
+ It's ok write the TxWI here, because the TxWI->TxWIMPDUByteCnt
+ will be updated after final frame was handled.
+ */
+ RTMPWriteTxWI_Data(pAd, (TXWI_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;
+
+ if (frameNum ==0)
+ FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &freeCnt);
+ else
+ LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &freeCnt);
+
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFRAME)
+ dbQueueEnqueueTxFrame((UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), NULL);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ frameNum++;
+
+ pAd->RalinkCounters.OneSecTxAggregationCount++;
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+#ifdef STATS_COUNT_SUPPORT
+ /* calculate Tx count and ByteCount per BSS */
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_CLIENT(pTxBlk->pMacEntry))
+#endif /* WAPI_SUPPORT */
+ {
+ MULTISSID_STRUCT *pMbss = pTxBlk->pMbss;
+ MAC_TABLE_ENTRY *pMacEntry=pTxBlk->pMacEntry;
+
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->pMacEntry->WapiUskRekeyTimerRunning && pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ pTxBlk->pMacEntry->wapi_usk_rekey_cnt += totalMPDUSize;
+#endif /* WAPI_SUPPORT */
+
+ if (pMbss != NULL)
+ {
+ pMbss->TransmittedByteCount += totalMPDUSize;
+ pMbss->TxCount ++;
+
+#ifdef STATS_COUNT_SUPPORT
+ if(IS_MULTICAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->mcPktsTx++;
+ else if(IS_BROADCAST_MAC_ADDR(pTxBlk->pSrcBufHeader))
+ pMbss->bcPktsTx++;
+ else
+ pMbss->ucPktsTx++;
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ if(pMacEntry && pMacEntry->Sst == SST_ASSOC)
+ {
+ INC_COUNTER64(pMacEntry->TxPackets);
+ pMacEntry->TxBytes+=pTxBlk->SrcBufLen;
+ }
+
+ }
+
+#ifdef WDS_SUPPORT
+ if (pTxBlk->pMacEntry && IS_ENTRY_WDS(pTxBlk->pMacEntry))
+ {
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedFragmentCount);
+ pAd->WdsTab.WdsEntry[pTxBlk->pMacEntry->MatchWDSTabIdx].WdsCounter.TransmittedByteCount+= pTxBlk->SrcBufLen;
+ }
+#endif /* WDS_SUPPORT */
+
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+
+ HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+ HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+
+ /*
+ Kick out Tx
+ */
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+}
+
+
+/*
+ ========================================================================
+ 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
+ pTxBlk Pointer to outgoing TxBlk structure.
+ QueIdx Queue index for processing
+
+ Return Value:
+ None
+ ========================================================================
+*/
+NDIS_STATUS APHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx)
+{
+ PQUEUE_ENTRY pQEntry;
+ PNDIS_PACKET pPacket;
+ UCHAR apidx;
+
+/* PQUEUE_HEADER pQueue; */
+
+#ifdef CONFIG_MULTI_CHANNEL
+ if (P2P_CLI_ON(pAd) && (pAd->LatchRfRegs.Channel != pAd->ApCliMlmeAux.Channel)
+ && (pAd->LatchRfRegs.Channel != pAd->ApCliMlmeAux.CentralChannel))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("APHardTransmit fail pAd->LatchRfRegs.Channel=%d pAd->ApCliMlmeAux.Channel=%d pAd->ApCliMlmeAux.CentralChannel=%d\n",
+ pAd->LatchRfRegs.Channel,pAd->ApCliMlmeAux.Channel,pAd->ApCliMlmeAux.CentralChannel));
+
+ return NDIS_STATUS_FAILURE;
+ }
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+
+ if ((pAd->Dot11_H.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+ ||(isCarrierDetectExist(pAd) == TRUE)
+#endif /* CARRIER_DETECTION_SUPPORT */
+ )
+ {
+ while(pTxBlk->TxPacketList.Head)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (pPacket)
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ return NDIS_STATUS_FAILURE;
+ }
+
+ apidx = RTMP_GET_PACKET_NET_DEVICE_MBSSID(pTxBlk->pPacket);
+ if (apidx < pAd->ApCfg.BssidNum)
+ {
+ /* carry VLAN in the air */
+ if (pAd->ApCfg.MBSSID[apidx].bVLAN_Tag == TRUE)
+ {
+ RTMP_SET_PACKET_VLAN(pTxBlk->pPacket, FALSE);
+ }
+ }
+
+
+ switch (pTxBlk->TxFrameType)
+ {
+#ifdef DOT11_N_SUPPORT
+ case TX_AMPDU_FRAME:
+ AP_AMPDU_Frame_Tx(pAd, pTxBlk);
+
+ break;
+#endif /* DOT11_N_SUPPORT */
+ case TX_LEGACY_FRAME:
+ AP_Legacy_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_MCAST_FRAME:
+ AP_Legacy_Frame_Tx(pAd, pTxBlk);
+ break;
+#ifdef DOT11_N_SUPPORT
+ case TX_AMSDU_FRAME:
+ AP_AMSDU_Frame_Tx(pAd, pTxBlk);
+ break;
+#endif /* DOT11_N_SUPPORT */
+ case TX_RALINK_FRAME:
+ AP_ARalink_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_FRAG_FRAME:
+ AP_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.Head)
+ {
+ 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);
+
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Check Rx descriptor, return NDIS_STATUS_FAILURE if any error found
+ ========================================================================
+*/
+NDIS_STATUS APCheckRxError(
+ IN RTMP_ADAPTER *pAd,
+ IN RXINFO_STRUC *pRxInfo,
+ IN UCHAR Wcid)
+{
+ if (pRxInfo->Crc || pRxInfo->CipherErr)
+ {
+ /*
+ WCID equal to 255 mean MAC couldn't find any matched entry in Asic-MAC table.
+ The incoming packet mays come from WDS or AP-Client link.
+ We need them for further process. Can't drop the packet here.
+ */
+ if ((pRxInfo->U2M)
+ && (pRxInfo->CipherErr)
+ && (Wcid == 255)
+#ifdef WDS_SUPPORT
+ && (pAd->WdsTab.Mode == WDS_LAZY_MODE)
+#endif /* WDS_SUPPORT */
+ )
+ {
+ /* pass those packet for further process. */
+ return NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s(): pRxInfo:Crc=%d, CipherErr=%d, U2M=%d, Wcid=%d\n",
+ __FUNCTION__, pRxInfo->Crc, pRxInfo->CipherErr, pRxInfo->U2M, Wcid));
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ return NDIS_STATUS_SUCCESS;
+ }
+}
+
+
+/*
+ ========================================================================
+ Description:
+ This routine checks if a received frame causes class 2 or class 3
+ error, and perform error action (DEAUTH or DISASSOC) accordingly
+ ========================================================================
+*/
+BOOLEAN APCheckClass2Class3Error(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader)
+{
+ /* software MAC table might be smaller than ASIC on-chip total size. */
+ /* If no mathed wcid index in ASIC on chip, do we need more check??? need to check again. 06-06-2006 */
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+
+ DBGPRINT(RT_DEBUG_WARN, ("%s():Rx a frame from %02x:%02x:%02x:%02x:%02x:%02x with WCID(%ld) > %d\n",
+ __FUNCTION__, PRINT_MAC(pHeader->Addr2),
+ Wcid, MAX_LEN_OF_MAC_TABLE));
+//+++Add by shiang for debug
+// hex_dump("Class2ErrPkt", (UCHAR *)pHeader, sizeof(HEADER_802_11));
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+ if (pEntry)
+ {
+ if ((pEntry->Sst == SST_ASSOC) && IS_ENTRY_CLIENT(pEntry))
+ {
+ }
+ return FALSE;
+ }
+//---Add by shiang for debug
+
+ APCls2errAction(pAd, MAX_LEN_OF_MAC_TABLE, pHeader);
+ return TRUE;
+ }
+
+ if (pAd->MacTab.Content[Wcid].Sst == SST_ASSOC)
+ ; /* okay to receive this DATA frame */
+ else if (pAd->MacTab.Content[Wcid].Sst == SST_AUTH)
+ {
+ APCls3errAction(pAd, Wcid, pHeader);
+ return TRUE;
+ }
+ else
+ {
+ APCls2errAction(pAd, Wcid, pHeader);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ ========================================================================
+ Description:
+ This routine frees all packets in PSQ that's destined to a specific DA.
+ BCAST/MCAST in DTIMCount=0 case is also handled here, just like a PS-POLL
+ is received from a WSTA which has MAC address FF:FF:FF:FF:FF:FF
+ ========================================================================
+*/
+VOID APHandleRxPsPoll(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN USHORT Aid,
+ IN BOOLEAN isActive)
+{
+ PQUEUE_ENTRY pEntry;
+ PMAC_TABLE_ENTRY pMacEntry;
+ unsigned long IrqFlags;
+
+ /*DBGPRINT(RT_DEBUG_TRACE,("rcv PS-POLL (AID=%d) from %02x:%02x:%02x:%02x:%02x:%02x\n", */
+ /* Aid, pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5])); */
+
+ pMacEntry = &pAd->MacTab.Content[Aid];
+ if (RTMPEqualMemory(pMacEntry->Addr, pAddr, MAC_ADDR_LEN))
+ {
+ /*
+ Sta is change to Power Active stat.
+ Reset ContinueTxFailCnt
+ */
+ pMacEntry->ContinueTxFailCnt = 0;
+
+#ifdef UAPSD_SUPPORT
+ if (UAPSD_MR_IS_ALL_AC_UAPSD(isActive, pMacEntry))
+ {
+ /*
+ IEEE802.11e spec.
+ 11.2.1.7 Receive operation for STAs in PS mode during the CP
+ When a non-AP QSTA that is using U-APSD and has all ACs
+ delivery-enabled detects that the bit corresponding to its AID
+ is set in the TIM, the non-AP QSTA shall issue a trigger frame
+ or a PS-Poll frame to retrieve the buffered MSDU or management
+ frames.
+
+ WMM Spec. v1.1a 070601
+ 3.6.2 U-APSD STA Operation
+ 3.6.2.3 In case one or more ACs are not
+ delivery-enabled ACs, the WMM STA may retrieve MSDUs and
+ MMPDUs belonging to those ACs by sending PS-Polls to the WMM AP.
+ In case all ACs are delivery enabled ACs, WMM STA should only
+ use trigger frames to retrieve MSDUs and MMPDUs belonging to
+ those ACs, and it should not send PS-Poll frames.
+
+ Different definitions in IEEE802.11e and WMM spec.
+ But we follow the WiFi WMM Spec.
+ */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("All AC are UAPSD, can not use PS-Poll\n"));
+ return; /* all AC are U-APSD, can not use PS-Poll */
+ } /* End of if */
+#endif /* UAPSD_SUPPORT */
+
+ /*NdisAcquireSpinLock(&pAd->MacTabLock); */
+ /*NdisAcquireSpinLock(&pAd->TxSwQueueLock); */
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ if (isActive == FALSE)
+ {
+ if (pMacEntry->PsQueue.Head)
+ {
+#ifdef UAPSD_SUPPORT
+ UINT32 NumOfOldPsPkt;
+ NumOfOldPsPkt = pAd->TxSwQueue[QID_AC_BE].Number;
+#endif /* UAPSD_SUPPORT */
+
+ pEntry = RemoveHeadQueue(&pMacEntry->PsQueue);
+ if ( pMacEntry->PsQueue.Number >=1 )
+ RTMP_SET_PACKET_MOREDATA(RTPKT_TO_OSPKT(pEntry), TRUE);
+ InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QID_AC_BE], pEntry);
+
+#ifdef UAPSD_SUPPORT
+ /* we need to call RTMPDeQueuePacket() immediately as below */
+ if (NumOfOldPsPkt != pAd->TxSwQueue[QID_AC_BE].Number)
+ {
+ if (RTMP_GET_PACKET_DHCP(RTPKT_TO_OSPKT(pEntry)) ||
+ RTMP_GET_PACKET_EAPOL(RTPKT_TO_OSPKT(pEntry)) ||
+ RTMP_GET_PACKET_WAI(RTPKT_TO_OSPKT(pEntry)))
+ {
+ /*
+ These packets will use 1M/6M rate to send.
+ If you use 1M(2.4G)/6M(5G) to send, no statistics
+ count in NICUpdateFifoStaCounters().
+
+ So we can not count it for UAPSD; Or the SP will
+ not closed until timeout.
+ */
+ ;
+ }
+ else
+ UAPSD_MR_MIX_PS_POLL_RCV(pAd, pMacEntry);
+ }
+#endif /* UAPSD_SUPPORT */
+ }
+ else
+ {
+ /*
+ or transmit a (QoS) Null Frame;
+
+ In addtion, in Station Keep Alive mechanism, we need to
+ send a QoS Null frame to detect the station live status.
+ */
+ BOOLEAN bQosNull = FALSE;
+
+ if (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ bQosNull = TRUE;
+
+ ApEnqueueNullFrame(pAd, pMacEntry->Addr, pMacEntry->CurrTxRate,
+ Aid, pMacEntry->apidx, bQosNull, TRUE, 0);
+ }
+ }
+ else
+ {
+#ifdef UAPSD_SUPPORT
+ /* deliver all queued UAPSD packets */
+ UAPSD_AllPacketDeliver(pAd, pMacEntry);
+
+ /* end the SP if exists */
+ UAPSD_MR_ENTRY_RESET(pAd, pMacEntry);
+#endif /* UAPSD_SUPPORT */
+
+ while(pMacEntry->PsQueue.Head)
+ {
+ pEntry = RemoveHeadQueue(&pMacEntry->PsQueue);
+ InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QID_AC_BE], pEntry);
+ } /* End of while */
+ } /* End of if */
+
+ /*NdisReleaseSpinLock(&pAd->TxSwQueueLock); */
+ /*NdisReleaseSpinLock(&pAd->MacTabLock); */
+
+ if ((Aid > 0) && (Aid < MAX_LEN_OF_MAC_TABLE) &&
+ (pMacEntry->PsQueue.Number == 0))
+ {
+ /* clear corresponding TIM bit because no any PS packet */
+ WLAN_MR_TIM_BIT_CLEAR(pAd, pMacEntry->apidx, Aid);
+ pMacEntry->PsQIdleCount = 0;
+ }
+
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+ /*
+ Dequeue outgoing frames from TxSwQueue0..3 queue and process it
+ TODO: 2004-12-27 it's not a good idea to handle "More Data" bit here.
+ because the RTMPDeQueue process doesn't guarantee to de-queue the
+ desired MSDU from the corresponding TxSwQueue/PsQueue when QOS
+ in-used. We should consider "HardTransmt" this MPDU using MGMT
+ queue or things like that.
+ */
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("rcv PS-POLL (AID=%d not match) from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ Aid, PRINT_MAC(pAddr)));
+
+ }
+}
+
+
+/*
+ detect AC Category of trasmitting packets
+ to turn AC0(BE) TX_OP (MAC reg 0x1300)
+*/
+/*static UCHAR is_on; */
+VOID detect_wmm_traffic(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR UserPriority,
+ IN UCHAR FlgIsOutput)
+{
+ /* For BE & BK case and TxBurst function is disabled */
+ if ((pAd->CommonCfg.bEnableTxBurst == FALSE)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->CommonCfg.bRdg == FALSE)
+ && (pAd->CommonCfg.bRalinkBurstMode == FALSE)
+#endif /* DOT11_N_SUPPORT */
+ && (FlgIsOutput == 1)
+ )
+ {
+ if (MapUserPriorityToAccessCategory[UserPriority] == QID_AC_BK)
+ {
+ /* has any BK traffic */
+ if (pAd->flg_be_adjust == 0)
+ {
+ /* yet adjust */
+#ifdef RTMP_MAC_USB
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_AP_ENABLE_TX_BURST, NULL, 0);
+#endif /* RTMP_MAC_USB */
+ pAd->flg_be_adjust = 1;
+ NdisGetSystemUpTime(&pAd->be_adjust_last_time);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("wmm> adjust be!\n"));
+ }
+ }
+ else
+ {
+ if (pAd->flg_be_adjust != 0)
+ {
+ PQUEUE_HEADER pQueue;
+
+ /* has adjusted */
+ pQueue = &pAd->TxSwQueue[QID_AC_BK];
+
+ if ((pQueue == NULL) ||
+ ((pQueue != NULL) && (pQueue->Head == NULL)))
+ {
+ ULONG now;
+ NdisGetSystemUpTime(&now);
+ if ((now - pAd->be_adjust_last_time) > TIME_ONE_SECOND)
+ {
+ /* no any BK traffic */
+#ifdef RTMP_MAC_USB
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_AP_DISABLE_TX_BURST, NULL, 0);
+#endif /* RTMP_MAC_USB */
+ pAd->flg_be_adjust = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("wmm> recover be!\n"));
+ }
+ }
+ else
+ NdisGetSystemUpTime(&pAd->be_adjust_last_time);
+ }
+ }
+ }
+
+ /* count packets which priority is more than BE */
+ if (UserPriority > 3)
+ {
+ pAd->OneSecondnonBEpackets++;
+
+ if (pAd->OneSecondnonBEpackets > 100
+#ifdef DOT11_N_SUPPORT
+ && pAd->MacTab.fAnyStationMIMOPSDynamic
+#endif /* DOT11_N_SUPPORT */
+ )
+ {
+ if (!pAd->is_on)
+ {
+#ifdef RTMP_MAC_USB
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_AP_ADJUST_EXP_ACK_TIME, NULL, 0);
+#endif /* RTMP_MAC_USB */
+ pAd->is_on = 1;
+ }
+ }
+ else
+ {
+ if (pAd->is_on)
+ {
+#ifdef RTMP_MAC_USB
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_AP_RECOVER_EXP_ACK_TIME, NULL, 0);
+#endif /* RTMP_MAC_USB */
+ pAd->is_on = 0;
+ }
+ }
+ }
+}
+
+/*
+ Wirte non-zero value to AC0 TXOP to boost performace
+ To pass WMM, AC0 TXOP must be zero.
+ It is necessary to turn AC0 TX_OP dynamically.
+*/
+
+VOID dynamic_tune_be_tx_op(RTMP_ADAPTER *pAd, ULONG nonBEpackets)
+{
+ UINT32 RegValue;
+ AC_TXOP_CSR0_STRUC csr0;
+
+ if (pAd->CommonCfg.bEnableTxBurst
+#ifdef DOT11_N_SUPPORT
+ || pAd->CommonCfg.bRdg
+ || pAd->CommonCfg.bRalinkBurstMode
+#endif /* DOT11_N_SUPPORT */
+ )
+ {
+
+ if (
+#ifdef DOT11_N_SUPPORT
+ (pAd->WIFItestbed.bGreenField && pAd->MacTab.fAnyStationNonGF == TRUE) ||
+ ((pAd->OneSecondnonBEpackets > nonBEpackets) || pAd->MacTab.fAnyStationMIMOPSDynamic) ||
+#endif /* DOT11_N_SUPPORT */
+ (pAd->MacTab.fAnyTxOPForceDisable))
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE))
+ {
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &RegValue);
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE))
+ {
+ RegValue = pAd->CommonCfg.RestoreBurstMode;
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE);
+ }
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE))
+ {
+ TX_LINK_CFG_STRUC TxLinkCfg;
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+ TxLinkCfg.field.TxRDGEn = 0;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
+ }
+ /* disable AC0(BE) TX_OP */
+ RegValue &= 0xFFFFFF00; /* for WMM test */
+ /*if ((RegValue & 0x0000FF00) == 0x00004300) */
+ /* RegValue += 0x00001100; */
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, RegValue);
+ if (pAd->CommonCfg.APEdcaParm.Txop[QID_AC_VO] != 102)
+ {
+ csr0.field.Ac0Txop = 0; /* QID_AC_BE */
+ }
+ else
+ {
+ /* for legacy b mode STA */
+ csr0.field.Ac0Txop = 10; /* QID_AC_BE */
+ }
+ csr0.field.Ac1Txop = 0; /* QID_AC_BK */
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE);
+ }
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)==0)
+ {
+ /* enable AC0(BE) TX_OP */
+ UCHAR txop_value_burst = 0x20; /* default txop for Tx-Burst */
+ UCHAR txop_value;
+
+#ifdef LINUX
+#endif /* LINUX */
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &RegValue);
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE))
+ txop_value = 0x80;
+ else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE))
+ txop_value = 0x80;
+ else if (pAd->CommonCfg.bEnableTxBurst)
+ txop_value = txop_value_burst;
+ else
+ txop_value = 0;
+
+ RegValue &= 0xFFFFFF00;
+ /*if ((RegValue & 0x0000FF00) == 0x00005400)
+ RegValue -= 0x00001100; */
+ /*txop_value = 0; */
+ RegValue |= txop_value; /* for performance, set the TXOP to non-zero */
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, RegValue);
+ csr0.field.Ac0Txop = txop_value; /* QID_AC_BE */
+ csr0.field.Ac1Txop = 0; /* QID_AC_BK */
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE);
+ }
+ }
+ }
+ pAd->OneSecondnonBEpackets = 0;
+}
+
+
+VOID APRxDErrorHandle(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo;
+
+ if (pRxInfo->CipherErr)
+ INC_COUNTER64(pAd->WlanCounters.WEPUndecryptableCount);
+
+ if (pRxInfo->U2M && pRxInfo->CipherErr)
+ {
+ if (pRxWI->RxWIWirelessCliID < MAX_LEN_OF_MAC_TABLE)
+ {
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ PCIPHER_KEY pWpaKey;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR FromWhichBSSID = BSS0;
+ UCHAR Wcid;
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+
+ Wcid = pRxWI->RxWIWirelessCliID;
+ if (VALID_WCID(Wcid))
+ pEntry = ApCliTableLookUpByWcid(pAd, Wcid, pHeader->Addr2);
+ else
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ {
+ FromWhichBSSID = pEntry->MatchAPCLITabIdx + MIN_NET_DEVICE_FOR_APCLI;
+
+
+
+ if (pRxInfo->CipherErr == 2)
+ {
+ pWpaKey = &pEntry->PairwiseKey;
+
+ if (pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].WpaSupplicantUP)
+ WpaSendMicFailureToWpaSupplicant(pAd->net_dev,
+ (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
+ if (((pRxInfo->CipherErr & 2) == 2) && INFRA_ON(pAd))
+ RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pEntry->Addr, FromWhichBSSID, 0);
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
+ }
+ }
+ else
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif /* APCLI_SUPPORT */
+ {
+ pEntry = &pAd->MacTab.Content[pRxWI->RxWIWirelessCliID];
+
+ /*
+ MIC error
+ Before verifying the MIC, the receiver shall check FCS, ICV and TSC.
+ This avoids unnecessary MIC failure events.
+ */
+ if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+ && (pRxInfo->CipherErr == 2))
+ {
+#ifdef HOSTAPD_SUPPORT
+ if(pAd->ApCfg.MBSSID[pEntry->apidx].Hostapd == TRUE)
+ {
+ ieee80211_notify_michael_failure(pAd, pRxBlk->pHeader, (UINT32) pRxWI->RxWIKeyIndex, 0);
+ }
+ else
+#endif/*HOSTAPD_SUPPORT*/
+ {
+ RTMP_HANDLE_COUNTER_MEASURE(pAd, pEntry);
+ }
+
+ }
+
+ /* send wireless event - for icv error */
+ if ((pRxInfo->CipherErr & 1) == 1)
+ RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pEntry->Addr, 0, 0);
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx u2me Cipher Err(MPDUsize=%d, WCID=%d, CipherErr=%d)\n",
+ pRxWI->RxWIMPDUByteCnt, pRxWI->RxWIWirelessCliID, pRxInfo->CipherErr));
+
+ }
+
+ pAd->Counters8023.RxErrors++;
+ /* DBGPRINT(RT_DEBUG_TRACE, ("<--APRxDErrorHandle\n")); */
+}
+
+static int dump_next_valid = 0;
+BOOLEAN APCheckVaildDataFrame(
+ IN RTMP_ADAPTER *pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ BOOLEAN isVaild = FALSE;
+
+ do
+ {
+#ifndef APCLI_SUPPORT
+ /* should not drop Ap-Client packet. */
+ if (pHeader->FC.ToDs == 0)
+ break; /* give up this frame */
+#endif /* APCLI_SUPPORT */
+
+ /* check if Class2 or 3 error */
+ if ((pHeader->FC.FrDs == 0) && (APCheckClass2Class3Error(pAd, pRxWI->RxWIWirelessCliID, pHeader)))
+ break; /* give up this frame */
+
+//+++Add by shiang for debug
+ if (pRxWI->RxWIWirelessCliID >= MAX_LEN_OF_MAC_TABLE) {
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+#ifdef RLT_MAC
+#ifndef MT7601
+ DBGPRINT(RT_DEBUG_OFF, ("ErrWcidPkt: seq=%d, ts=0x%02x%02x%02x%02x\n",
+ pHeader->Sequence,
+ pRxBlk->pRxWI->RXWI_N.rssi[0],
+ pRxBlk->pRxWI->RXWI_N.rssi[1],
+ pRxBlk->pRxWI->RXWI_N.rssi[2],
+ pRxBlk->pRxWI->RXWI_N.rssi[3]));
+#endif /* MT7601 */
+#endif /* RLT_MAC */
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+ if (pEntry && (pEntry->Sst == SST_ASSOC) && IS_ENTRY_CLIENT(pEntry))
+ pRxWI->RxWIWirelessCliID = pEntry->Aid;
+
+ dump_next_valid = 1;
+ }
+ else if (dump_next_valid)
+ {
+#ifdef RLT_MAC
+#ifndef MT7601
+ DBGPRINT(RT_DEBUG_OFF, ("NextValidWcidPkt: seq=%d, ts=0x%02x%02x%02x%02x\n",
+ pHeader->Sequence,
+ pRxBlk->pRxWI->RXWI_N.rssi[0],
+ pRxBlk->pRxWI->RXWI_N.rssi[1],
+ pRxBlk->pRxWI->RXWI_N.rssi[2],
+ pRxBlk->pRxWI->RXWI_N.rssi[3]));
+#endif /* MT7601 */
+#endif /* RLT_MAC */
+ dump_next_valid = 0;
+ }
+//---Add by shiang for debug
+
+ if(pAd->ApCfg.BANClass3Data == TRUE)
+ break; /* give up this frame */
+
+ isVaild = TRUE;
+ } while (0);
+
+ return isVaild;
+}
+
+/* For TKIP frame, calculate the MIC value */
+BOOLEAN APCheckTkipMICValue(
+ 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 = &pEntry->PairwiseKey;
+
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_WDS))
+ {
+ pDA = pHeader->Addr3;
+ pSA = (PUCHAR)pHeader + sizeof(HEADER_802_11);
+ }
+ else if (RX_BLK_TEST_FLAG(pRxBlk, fRX_APCLI))
+ {
+ pDA = pHeader->Addr1;
+ pSA = pHeader->Addr3;
+ }
+ else
+ {
+ pDA = pHeader->Addr3;
+ 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 APCLI_WPA_SUPPLICANT_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry) && pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].WpaSupplicantUP)
+ {
+ WpaSendMicFailureToWpaSupplicant(pAd->net_dev,
+ (pWpaKey->Type ==
+ PAIRWISEKEY) ? TRUE :
+ FALSE);
+ }
+ else
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+ {
+ RTMP_HANDLE_COUNTER_MEASURE(pAd, pEntry);
+ }
+
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+VOID APHandleRxMgmtFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo;
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+
+ do
+ {
+
+
+#ifdef IDS_SUPPORT
+ /* Check if a rogue AP impersonats our mgmt frame to spoof clients */
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ if (RTMPSpoofedMgmtDetection(pAd, pHeader, pRxWI->RxWISNR2, 0, 0, pRxWI->RxWISNR1))
+ {
+ /* This is a spoofed frame, so give up it. */
+ break;
+ }
+ else
+#endif /* MT7601 */
+ if (RTMPSpoofedMgmtDetection(pAd, pHeader, pRxWI->RxWIRSSI0, pRxWI->RxWIRSSI1, pRxWI->RxWIRSSI2, 0))
+ {
+ /* This is a spoofed frame, so give up it. */
+ break;
+ }
+#endif /* IDS_SUPPORT */
+
+#ifdef IDS_SUPPORT
+ /* update sta statistics for traffic flooding detection later */
+ RTMPUpdateStaMgmtCounter(pAd, pHeader->FC.SubType);
+#endif /* IDS_SUPPORT */
+
+ if (!pRxInfo->U2M)
+ {
+ if ((pHeader->FC.SubType != SUBTYPE_BEACON) && (pHeader->FC.SubType != SUBTYPE_PROBE_REQ))
+ {
+ break;
+ }
+ }
+
+ if (pAd->ApCfg.BANClass3Data == TRUE)
+ {
+ /* disallow new association */
+ if ((pHeader->FC.SubType == SUBTYPE_ASSOC_REQ) || (pHeader->FC.SubType == SUBTYPE_AUTH))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Disallow new Association\n"));
+ break;
+ }
+ }
+
+ /* Software decrypts WEP data during shared WEP negotiation */
+ if ((pHeader->FC.SubType == SUBTYPE_AUTH) &&
+ (pHeader->FC.Wep == 1) && (pRxInfo->Decrypted == 0))
+ {
+ PUCHAR pMgmt = (PUCHAR)pHeader;
+ UINT16 mgmt_len = pRxWI->RxWIMPDUByteCnt;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ /* Skip 802.11 headre */
+ pMgmt += LENGTH_802_11;
+ mgmt_len -= LENGTH_802_11;
+
+ if (pRxWI->RxWIWirelessCliID < MAX_LEN_OF_MAC_TABLE)
+ pEntry = &pAd->MacTab.Content[pRxWI->RxWIWirelessCliID];
+
+ if (pEntry == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: SW decrypt WEP data fails - the Entry is empty.\n"));
+ break;
+ }
+
+ /* handle WEP decryption */
+ if (RTMPSoftDecryptWEP(pAd,
+ &pAd->SharedKey[pEntry->apidx][pRxWI->RxWIKeyIndex],
+ pMgmt,
+ &mgmt_len) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: SW decrypt WEP data fails.\n"));
+ /* give up this frame */
+ break;
+ }
+#ifdef RT_BIG_ENDIAN
+ /* swap 16 bit fields - Auth Alg No. field */
+ *(USHORT *)pMgmt = SWAP16(*(USHORT *)pMgmt);
+
+ /* swap 16 bit fields - Auth Seq No. field */
+ *(USHORT *)(pMgmt + 2) = SWAP16(*(USHORT *)(pMgmt + 2));
+
+ /* swap 16 bit fields - Status Code field */
+ *(USHORT *)(pMgmt + 4) = SWAP16(*(USHORT *)(pMgmt + 4));
+#endif /* RT_BIG_ENDIAN */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Decrypt AUTH seq#3 successfully\n"));
+
+ /* Update the total length */
+ pRxWI->RxWIMPDUByteCnt -= (LEN_WEP_IV_HDR + LEN_ICV);
+ }
+
+ if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("DataSize=%d\n", pRxBlk->DataSize));
+ hex_dump("MGMT ???", (UCHAR *)pHeader, pRxBlk->pData - (UCHAR *) pHeader);
+ break;
+ }
+
+ if (pHeader->FC.SubType == SUBTYPE_ACTION)
+ {
+ /* only PM bit of ACTION frame can be set */
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ pEntry = PACInquiry(pAd, pRxWI->RxWIWirelessCliID);
+ if (pEntry != NULL)
+ APPsIndicate(pAd, pHeader->Addr2, pEntry->Aid, pHeader->FC.PwrMgmt);
+
+ /*
+ In IEEE802.11, 11.2.1.1 STA Power Management modes,
+ The Power Managment bit shall not be set in any management
+ frame, except an Action frame.
+ */
+ /* In IEEE802.11e, 11.2.1.4 Power management with APSD,
+ If there is no unscheduled SP in progress, the unscheduled SP
+ begins when the QAP receives a trigger frame from a non-AP QSTA,
+ which is a QoS data or QoS Null frame associated with an AC the
+ STA has configured to be trigger-enabled. */
+ /* So a management action frame is not trigger frame */
+ }
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->RxWIWirelessCliID, pHeader,
+ pRxWI->RxWIMPDUByteCnt,
+ pRxWI->RxWISNR2, 0,
+ 0, 0, pRxWI->RxWISNR1, OPMODE_AP);
+ }
+ else
+#endif /* MT7601 */
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->RxWIWirelessCliID, pHeader,
+ pRxWI->RxWIMPDUByteCnt,
+ pRxWI->RxWIRSSI0, pRxWI->RxWIRSSI1,
+ pRxWI->RxWIRSSI2, 0, 0, OPMODE_AP);
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ {
+ pRxBlk->pData += LENGTH_802_11;
+ pRxBlk->DataSize -= LENGTH_802_11;
+ if (pHeader->FC.Order)
+ {
+ handleHtcField(pAd, pRxBlk);
+ pRxBlk->pData += 4;
+ pRxBlk->DataSize -= 4;
+ }
+
+ /* Check for compressed or non-compressed Sounding Response */
+ if (((pHeader->FC.SubType == SUBTYPE_ACTION) || (pHeader->FC.SubType == SUBTYPE_ACTION_NO_ACK))
+ && (pRxBlk ->pData)[0] == CATEGORY_HT
+ && ((pRxBlk ->pData)[1] == MIMO_N_BEACONFORM || (pRxBlk ->pData)[1] == MIMO_BEACONFORM)
+ )
+ {
+ handleBfFb(pAd, pRxBlk);
+ }
+ }
+#endif /* TXBF_SUPPORT */
+ } while (0);
+
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ return;
+}
+
+VOID APHandleRxControlFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+
+ switch (pHeader->FC.SubType)
+ {
+#ifdef DOT11_N_SUPPORT
+ case SUBTYPE_BLOCK_ACK_REQ:
+ {
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ CntlEnqueueForRecv(pAd, pRxWI->RxWIWirelessCliID, (pRxWI->RxWIMPDUByteCnt), (PFRAME_BA_REQ)pHeader);
+ }
+ break;
+#endif /* DOT11_N_SUPPORT */
+ /* handle PS-POLL here */
+ case SUBTYPE_PS_POLL:
+ {
+ USHORT Aid = pHeader->Duration & 0x3fff;
+ PUCHAR pAddr = pHeader->Addr2;
+
+ if (Aid < MAX_LEN_OF_MAC_TABLE)
+ APHandleRxPsPoll(pAd, pAddr, Aid, FALSE);
+ }
+ break;
+#ifdef DOT11_N_SUPPORT
+ case SUBTYPE_BLOCK_ACK:
+#endif /* DOT11_N_SUPPORT */
+ case SUBTYPE_ACK:
+ default:
+ break;
+ }
+
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ return;
+}
+
+VOID APRxEAPOLFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ BOOLEAN CheckPktSanity = TRUE;
+ UCHAR *pTmpBuf;
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ INT eapcode;
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif /* APCLI_SUPPORT */
+ do
+ {
+ } while (FALSE);
+
+ /* Sanity Check */
+ if(pRxBlk->DataSize < (LENGTH_802_1_H + LENGTH_EAPOL_H))
+ {
+ CheckPktSanity = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("Total pkts size is too small.\n"));
+ }
+ else if (!RTMPEqualMemory(SNAP_802_1H, pRxBlk->pData, 6))
+ {
+ CheckPktSanity = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("Can't find SNAP_802_1H parameter.\n"));
+ }
+ else if (!RTMPEqualMemory(EAPOL, pRxBlk->pData+6, 2))
+ {
+ CheckPktSanity = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("Can't find EAPOL parameter.\n"));
+ }
+ else if(*(pRxBlk->pData+9) > EAPOLASFAlert)
+ {
+ CheckPktSanity = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("Unknown EAP type(%d).\n", *(pRxBlk->pData+9)));
+ }
+
+ if(CheckPktSanity == FALSE)
+ {
+ goto done;
+ }
+
+
+
+#ifdef HOSTAPD_SUPPORT
+ if ((pEntry) && pAd->ApCfg.MBSSID[pEntry->apidx].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Indicate_Legacy_Packet\n"));
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+#endif/*HOSTAPD_SUPPORT*/
+
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ eapcode=ApcliWpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H);
+ printk("eapcode=%d\n",eapcode);
+ if ( pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].WpaSupplicantUP &&
+ pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].IEEE8021X == TRUE &&
+ (EAP_CODE_SUCCESS == eapcode))
+ {
+ PUCHAR Key;
+ UCHAR CipherAlg;
+ int idx = 0;
+ int BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + pEntry->MatchAPCLITabIdx;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
+ /* pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
+ /* STA_PORT_SECURED(pAd); */
+ pEntry->PortSecured=WPA_802_1X_PORT_SECURED;
+ pEntry->PrivacyFilter=Ndis802_11PrivFilterAcceptAll;
+ if (pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].IEEE8021x_required_keys == FALSE)
+ {
+ idx = pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKeyId;
+ CipherAlg = pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKey[idx].CipherAlg;
+ Key = pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKey[idx].Key;
+
+ if (pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKey[idx].KeyLen > 0)
+ {
+ /* Set key material and cipherAlg to Asic */
+ RTMP_ASIC_SHARED_KEY_TABLE(pAd,BssIdx, idx, &pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKey[idx]);
+
+ /* STA doesn't need to set WCID attribute for group key */
+ /* Assign pairwise key info */
+ RTMP_SET_WCID_SEC_INFO(pAd, BssIdx, idx, CipherAlg, pEntry->Aid, SHAREDKEYTABLE);
+
+ /* RTMP_IndicateMediaState(pAd, NdisMediaStateConnected); */
+ /* pAd->ExtraInfo = GENERAL_LINK_UP; */
+
+ /* For Preventing ShardKey Table is cleared by remove key procedure. */
+ pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].SharedKey[idx].CipherAlg = CipherAlg;
+ pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].SharedKey[idx].KeyLen = pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKey[idx].KeyLen;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].SharedKey[idx].Key,
+ pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKey[idx].Key,
+ pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesireSharedKey[idx].KeyLen);
+ }
+ }
+ }
+
+ if(pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].WpaSupplicantUP &&
+ ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2) || pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].IEEE8021X == TRUE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Indicate_Legacy_Packet\n"));
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ }
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
+#ifdef DOT1X_SUPPORT
+ /* sent this frame to upper layer TCPIP */
+ if ((pEntry) && (pEntry->WpaState < AS_INITPMK) &&
+ ((pEntry->AuthMode == Ndis802_11AuthModeWPA) ||
+ ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (pEntry->PMKID_CacheIdx == ENTRY_NOT_FOUND)) ||
+ pAd->ApCfg.MBSSID[pEntry->apidx].IEEE8021X == TRUE))
+ {
+#ifdef WSC_AP_SUPPORT
+ if ((pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscConfMode != WSC_DISABLE) &&
+ (!MAC_ADDR_EQUAL(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, ZERO_MAC_ADDR)))
+ {
+ pTmpBuf = pRxBlk->pData - LENGTH_802_11;
+ NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->RxWIWirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RxWISNR2, 0, 0, 0, pRxWI->RxWISNR1, OPMODE_AP);
+ }
+ else
+#endif /* MT7601 */
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->RxWIWirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RxWIRSSI0, pRxWI->RxWIRSSI1, pRxWI->RxWIRSSI2, 0, 0, OPMODE_AP);
+ pRxBlk->pHeader = (PHEADER_802_11)pTmpBuf;
+ }
+#endif /* WSC_AP_SUPPORT */
+
+
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ else /* sent this frame to WPA state machine */
+#endif /* DOT1X_SUPPORT */
+ {
+ pTmpBuf = pRxBlk->pData - LENGTH_802_11;
+ NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->RxWIWirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RxWISNR2, 0, 0, 0, pRxWI->RxWISNR1, OPMODE_AP);
+ }
+ else
+#endif /* MT7601 */
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->RxWIWirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RxWIRSSI0, pRxWI->RxWIRSSI1, pRxWI->RxWIRSSI2, 0, 0, OPMODE_AP);
+ }
+
+done:
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+
+}
+
+VOID Announce_or_Forward_802_3_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID)
+{
+ if (APFowardWirelessStaToWirelessSta(pAd, pPacket, FromWhichBSSID))
+ {
+ announce_802_3_packet(pAd, pPacket,OPMODE_AP);
+ }
+ else
+ {
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+}
+
+
+VOID APRxDataFrameAnnounce(
+ IN RTMP_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))
+ {
+#ifdef WAPI_SUPPORT
+ /* report to upper layer if the received frame is WAI frame */
+ if (RTMPCheckWAIframe(pRxBlk->pData, pRxBlk->DataSize))
+ {
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+#endif /* WAPI_SUPPORT */
+
+ /*
+ drop all non-EAP DATA frame before
+ this client's Port-Access-Control is secured
+ */
+ if (pEntry->PrivacyFilter == Ndis802_11PrivFilter8021xWEP)
+ {
+ /*
+ If 1) no any EAP frame is received within 5 sec and
+ 2) an encrypted non-EAP frame from peer associated STA is received,
+ AP would send de-authentication to this STA.
+ */
+ if (IS_ENTRY_CLIENT(pEntry) && pRxBlk->pHeader->FC.Wep &&
+ pEntry->StaConnectTime > 5 && pEntry->WpaState < AS_AUTHENTICATION2)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("==> De-Auth this STA(%02x:%02x:%02x:%02x:%02x:%02x)\n", PRINT_MAC(pEntry->Addr)));
+ MlmeDeAuthAction(pAd, pEntry, REASON_NO_LONGER_VALID, FALSE);
+ }
+
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+
+#ifdef IGMP_SNOOP_SUPPORT
+ if (pEntry
+ && (IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_WDS(pEntry))
+ && (pAd->ApCfg.IgmpSnoopEnable)
+ && IS_MULTICAST_MAC_ADDR(pRxBlk->pHeader->Addr3))
+ {
+ PUCHAR pDA = pRxBlk->pHeader->Addr3;
+ PUCHAR pSA = pRxBlk->pHeader->Addr2;
+ PUCHAR pData = NdisEqualMemory(SNAP_802_1H, pRxBlk->pData, 6) ? (pRxBlk->pData + 6) : pRxBlk->pData;
+ UINT16 protoType = OS_NTOHS(*((UINT16 *)(pData)));
+
+ if (protoType == ETH_P_IP)
+ IGMPSnooping(pAd, pDA, pSA, pData, get_netdev_from_bssid(pAd, FromWhichBSSID));
+ else if (protoType == ETH_P_IPV6)
+ MLDSnooping(pAd, pDA, pSA, pData, get_netdev_from_bssid(pAd, FromWhichBSSID));
+ }
+#endif /* IGMP_SNOOP_SUPPORT */
+
+#ifdef STATS_COUNT_SUPPORT
+ if (pEntry
+ && (IS_ENTRY_CLIENT(pEntry))
+ && (pEntry->pMbss))
+ {
+ MULTISSID_STRUCT *pMbss = pEntry->pMbss;
+ if(IS_MULTICAST_MAC_ADDR(pRxBlk->pHeader->Addr3) || IS_MULTICAST_MAC_ADDR(pRxBlk->pHeader->Addr1))
+ {
+ pMbss->mcPktsRx++;
+ }
+ else if(IS_BROADCAST_MAC_ADDR(pRxBlk->pHeader->Addr3) || IS_BROADCAST_MAC_ADDR(pRxBlk->pHeader->Addr1))
+ {
+ pMbss->bcPktsRx++;
+ }
+ else
+ {
+ pMbss->ucPktsRx++;
+ }
+ }
+#endif /* STATS_COUNT_SUPPORT */
+ 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);
+ }
+ }
+ else
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
+
+ /* Update the WPA STATE to indicate the EAP handshaking is started */
+ if (pEntry->WpaState == AS_AUTHENTICATION)
+ pEntry->WpaState = AS_AUTHENTICATION2;
+
+#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 */
+ APRxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+ }
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+VOID APRxDataFrameAnnounce_Hdr_Trns(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+
+ /* non-EAP frame */
+ if (!RTMPCheckWPAframe_Hdr_Trns(pAd, pEntry, pRxBlk->pTransData, pRxBlk->TransDataSize, FromWhichBSSID))
+ {
+#ifdef WAPI_SUPPORT
+ /* report to upper layer if the received frame is WAI frame */
+ if (RTMPCheckWAIframe(pRxBlk->pData, pRxBlk->DataSize))
+ {
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+#endif /* WAPI_SUPPORT */
+
+ /*
+ drop all non-EAP DATA frame before
+ this client's Port-Access-Control is secured
+ */
+ if (pEntry->PrivacyFilter == Ndis802_11PrivFilter8021xWEP)
+ {
+ /*
+ If 1) no any EAP frame is received within 5 sec and
+ 2) an encrypted non-EAP frame from peer associated STA is received,
+ AP would send de-authentication to this STA.
+ */
+ if (IS_ENTRY_CLIENT(pEntry) && pRxBlk->pHeader->FC.Wep &&
+ pEntry->StaConnectTime > 5 && pEntry->WpaState < AS_AUTHENTICATION2)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("==> De-Auth this STA(%02x:%02x:%02x:%02x:%02x:%02x)\n", PRINT_MAC(pEntry->Addr)));
+ MlmeDeAuthAction(pAd, pEntry, REASON_NO_LONGER_VALID, FALSE);
+ }
+
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+
+#ifdef IGMP_SNOOP_SUPPORT
+ if (pEntry
+ && (IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_WDS(pEntry))
+ && (pAd->ApCfg.IgmpSnoopEnable)
+ && IS_MULTICAST_MAC_ADDR(pRxBlk->pHeader->Addr3))
+ {
+ PUCHAR pDA = pRxBlk->pHeader->Addr3;
+ PUCHAR pSA = pRxBlk->pHeader->Addr2;
+ PUCHAR pData = NdisEqualMemory(SNAP_802_1H, pRxBlk->pData, 6) ? (pRxBlk->pData + 6) : pRxBlk->pData;
+ UINT16 protoType = OS_NTOHS(*((UINT16 *)(pData)));
+
+ if (protoType == ETH_P_IP)
+ IGMPSnooping(pAd, pDA, pSA, pData, get_netdev_from_bssid(pAd, FromWhichBSSID));
+ else if (protoType == ETH_P_IPV6)
+ MLDSnooping(pAd, pDA, pSA, pData, get_netdev_from_bssid(pAd, FromWhichBSSID));
+ }
+#endif /* IGMP_SNOOP_SUPPORT */
+
+#ifdef STATS_COUNT_SUPPORT
+ if (pEntry
+ && (IS_ENTRY_CLIENT(pEntry))
+ && (pEntry->pMbss))
+ {
+ MULTISSID_STRUCT *pMbss = pEntry->pMbss;
+ if(IS_MULTICAST_MAC_ADDR(pRxBlk->pHeader->Addr3) || IS_MULTICAST_MAC_ADDR(pRxBlk->pHeader->Addr1))
+ {
+ pMbss->mcPktsRx++;
+ }
+ else if(IS_BROADCAST_MAC_ADDR(pRxBlk->pHeader->Addr3) || IS_BROADCAST_MAC_ADDR(pRxBlk->pHeader->Addr1))
+ {
+ pMbss->bcPktsRx++;
+ }
+ else
+ {
+ pMbss->ucPktsRx++;
+ }
+ }
+#endif /* STATS_COUNT_SUPPORT */
+ RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
+ {
+ /* Normal legacy, AMPDU or AMSDU */
+ CmmRxnonRalinkFrameIndicate_Hdr_Trns(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+ {
+ /* ARALINK */
+ CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+ }
+ else
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
+
+ /* Update the WPA STATE to indicate the EAP handshaking is started */
+ if (pEntry->WpaState == AS_AUTHENTICATION)
+ pEntry->WpaState = AS_AUTHENTICATION2;
+
+#ifdef DOT11_N_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ Indicate_AMPDU_Packet_Hdr_Trns(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+#endif /* DOT11_N_SUPPORT */
+ {
+ /* Determin the destination of the EAP frame */
+ /* to WPA state machine or upper layer */
+ APRxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+ }
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+
+/*
+ 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 APHandleRxDataFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo;
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ HEADER_802_11 *pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ BOOLEAN bFragment = FALSE;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR FromWhichBSSID = BSS0;
+ UCHAR OldPwrMgmt = PWR_ACTIVE; /* UAPSD AP SUPPORT */
+ UCHAR UserPriority = 0;
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS)
+ BOOLEAN bWdsPacket = FALSE;
+#endif /* WDS_SUPPORT || CLIENT_WDS */
+ FRAME_CONTROL *pFmeCtrl = &pHeader->FC;
+ COUNTER_RALINK *pCounter = &pAd->RalinkCounters;
+
+//+++Add by shiang for debug
+if (0 /*!(pRxInfo->Mcast || pRxInfo->Bcast)*/){
+ DBGPRINT(RT_DEBUG_OFF, ("-->%s(%d): Dump Related Info!\n", __FUNCTION__, __LINE__));
+ dump_rxinfo(pAd, pRxInfo);
+ hex_dump("DataFrameHeader", (UCHAR *)pHeader, sizeof(HEADER_802_11));
+ hex_dump("DataFramePayload", pRxBlk->pData , pRxBlk->DataSize);
+}
+//---Add by shiangf for debug
+
+ if (APCheckVaildDataFrame(pAd, pRxBlk) != TRUE)
+ {
+ goto err;
+ }
+
+#ifdef IDS_SUPPORT
+ /*
+ Replay attack detection
+ Detect a spoofed data frame from a rogue AP, ignore it.
+ */
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ if (pFmeCtrl->FrDs == 1 &&
+ (RTMPReplayAttackDetection(pAd, pHeader->Addr2, pRxWI->RxWISNR2, 0, 0, pRxWI->RxWISNR1, pRxWI->RxWIBW) == TRUE))
+ {
+ goto err;
+ }
+ else
+#endif /* MT7601 */
+ if (pFmeCtrl->FrDs == 1 &&
+ (RTMPReplayAttackDetection(pAd, pHeader->Addr2, pRxWI->RxWIRSSI0, pRxWI->RxWIRSSI1, pRxWI->RxWIRSSI2, 0, 0) == TRUE))
+ {
+ goto err;
+ }
+#endif /* IDS_SUPPORT */
+
+ /* handle WDS */
+ if ((pFmeCtrl->FrDs == 1) && (pFmeCtrl->ToDs == 1))
+ {
+ do
+ {
+#ifdef CLIENT_WDS
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+ if (pEntry != NULL)
+ {
+ if (IS_ENTRY_CLIWDS(pEntry))
+ ;
+ else if (IS_ENTRY_CLIENT(pEntry)
+ && (pEntry->Sst == SST_ASSOC))
+ SET_ENTRY_CLIWDS(pEntry);
+ else
+ pEntry = NULL;
+ }
+
+ if (pEntry != NULL)
+ {
+ FromWhichBSSID = pEntry->apidx;
+
+ /* Increase received byte counter per BSS */
+ if (FromWhichBSSID < pAd->ApCfg.BssidNum)
+ {
+ MULTISSID_STRUCT *pMbss = pEntry->pMbss;
+ if (pMbss != NULL)
+ {
+ pMbss->ReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ pMbss->RxCount ++;
+ }
+ }
+ RX_BLK_SET_FLAG(pRxBlk, fRX_WDS);
+ bWdsPacket = TRUE;
+ CliWds_ProxyTabUpdate(pAd, pEntry->Aid, pHeader->Octet);
+ break;
+ }
+#endif /* CLIENT_WDS */
+
+
+#ifdef WDS_SUPPORT
+ /* handle WDS */
+ {
+ bWdsPacket = TRUE;
+ if (MAC_ADDR_EQUAL(pHeader->Addr1, pAd->CurrentAddress))
+ pEntry = FindWdsEntry(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2, pRxWI->RxWIPhyMode);
+ else
+ pEntry = NULL;
+
+
+ /* have no valid wds entry exist, then discard the incoming packet.*/
+ if (!(pEntry && WDS_IF_UP_CHECK(pAd, pEntry->MatchWDSTabIdx)))
+ {
+ /* drop the packet */
+ goto err;
+ }
+
+ /*receive corresponding WDS packet, disable TX lock state (fix WDS jam issue) */
+ if(pEntry && (pEntry->LockEntryTx == TRUE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive WDS packet, disable TX lock state!\n"));
+ pEntry->ContinueTxFailCnt = 0;
+ pEntry->LockEntryTx = FALSE;
+ }
+
+ RX_BLK_SET_FLAG(pRxBlk, fRX_WDS);
+ FromWhichBSSID = pEntry->MatchWDSTabIdx + MIN_NET_DEVICE_FOR_WDS;
+ break;
+ }
+#endif /* WDS_SUPPORT */
+ } while(FALSE);
+
+ if (pEntry == NULL)
+ {
+ /* have no WDS or MESH support */
+ /* drop the packet */
+ goto err;
+ }
+ }
+ /* handle APCLI. */
+ else if ((pFmeCtrl->FrDs == 1) && (pFmeCtrl->ToDs == 0))
+ {
+#ifdef APCLI_SUPPORT
+ if (VALID_WCID(pRxWI->RxWIWirelessCliID))
+ {
+ pEntry = ApCliTableLookUpByWcid(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2);
+ }
+ else
+ {
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+ }
+
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ {
+ if (!(pEntry && APCLI_IF_UP_CHECK(pAd, pEntry->MatchAPCLITabIdx)))
+ {
+ goto err;
+ }
+ FromWhichBSSID = pEntry->MatchAPCLITabIdx + MIN_NET_DEVICE_FOR_APCLI;
+ RX_BLK_SET_FLAG(pRxBlk, fRX_APCLI);
+
+ /* Process broadcast packets */
+ if (pRxInfo->Mcast || pRxInfo->Bcast)
+ {
+ /* Process the received broadcast frame for AP-Client. */
+ if (!ApCliHandleRxBroadcastFrame(pAd, pRxBlk, pEntry, FromWhichBSSID))
+ {
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ return;
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ /* no APCLI support */
+ /* release packet */
+ goto err;
+ }
+ }
+ else
+ {
+ pEntry = PACInquiry(pAd, pRxWI->RxWIWirelessCliID);
+
+ /* can't find associated STA entry then filter invlid data frame */
+ if (!pEntry)
+ {
+ goto err;
+ }
+
+ FromWhichBSSID = pEntry->apidx;
+
+#ifdef STATS_COUNT_SUPPORT
+ /* Increase received byte counter per BSS */
+ if (pHeader->FC.FrDs == 0 &&
+ pRxInfo->U2M &&
+ FromWhichBSSID < pAd->ApCfg.BssidNum)
+ {
+ MULTISSID_STRUCT *pMbss = pEntry->pMbss;
+ if (pMbss != NULL)
+ {
+ pMbss->ReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ pMbss->RxCount ++;
+ }
+ }
+
+ /* update multicast counter */
+ if (IS_MULTICAST_MAC_ADDR(pHeader->Addr3))
+ INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ ASSERT(pEntry->Aid == pRxWI->RxWIWirelessCliID);
+
+
+
+#ifdef DOT11_N_SUPPORT
+ /* check Atheros Client */
+ if (!pEntry->bIAmBadAtheros && (pFmeCtrl->Retry )
+ && (pRxInfo->AMPDU == 1) && (pAd->CommonCfg.bHTProtect == TRUE)
+ )
+ {
+ if (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == FALSE)
+ RTMP_UPDATE_PROTECT(pAd, 8 , ALLN_SETPROTECT, FALSE, FALSE);
+ pEntry->bIAmBadAtheros = TRUE;
+
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ /* update rssi sample */
+ Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
+
+ if (pRxInfo->U2M)
+ {
+#ifdef RT65xx
+ pEntry->LastRxRate = (ULONG)((pRxWI->RxWIMCS) + (pRxWI->RxWIBW <<7) +
+ (pRxWI->RxWISGI <<9) + (pRxWI->RxWISTBC <<10) +
+ (pRxWI->RxWIPhyMode <<14));
+#else
+ pEntry->LastRxRate = (ULONG)((pRxWI->RxWIMCS) + (pRxWI->RxWIBW <<7) +
+ (pRxWI->RxWISGI <<8) + (pRxWI->RxWISTBC <<9) +
+ (pRxWI->RxWIPhyMode <<14));
+#endif
+
+#ifdef TXBF_SUPPORT
+ if (pRxWI->RxWISGI)
+ pEntry->OneSecRxSGICount++;
+ else
+ pEntry->OneSecRxLGICount++;
+#endif // TXBF_SUPPORT //
+ }
+
+ pAd->ApCfg.LastSNR0 = (UCHAR)(pRxWI->RxWISNR0);
+ pAd->ApCfg.LastSNR1 = (UCHAR)(pRxWI->RxWISNR1);
+#ifdef DOT11N_SS3_SUPPORT
+ pAd->ApCfg.LastSNR2 = (UCHAR)(pRxWI->RxWISNR2);
+#endif /* DOT11N_SS3_SUPPORT */
+ pEntry->freqOffset = (CHAR)(pRxWI->RxWIFOFFSET);
+ pEntry->freqOffsetValid = TRUE;
+
+
+ /* Gather PowerSave information from all valid DATA frames. IEEE 802.11/1999 p.461 */
+ /* must be here, before no DATA check */
+
+
+ pRxBlk->pData = (UCHAR *)pHeader;
+
+
+ /* 1: PWR_SAVE, 0: PWR_ACTIVE */
+ OldPwrMgmt = APPsIndicate(pAd, pHeader->Addr2, pEntry->Aid, pFmeCtrl->PwrMgmt);
+#ifdef UAPSD_SUPPORT
+ if (pFmeCtrl->PwrMgmt)
+ {
+ if ((CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE)) &&
+ (pFmeCtrl->SubType & 0x08))
+ {
+ /*
+ In IEEE802.11e, 11.2.1.4 Power management with APSD,
+ If there is no unscheduled SP in progress, the unscheduled SP begins
+ when the QAP receives a trigger frame from a non-AP QSTA, which is a
+ QoS data or QoS Null frame associated with an AC the STA has
+ configured to be trigger-enabled.
+ */
+ /*
+ In WMM v1.1, A QoS Data or QoS Null frame that indicates transition
+ to/from Power Save Mode is not considered to be a Trigger Frame and
+ the AP shall not respond with a QoS Null frame.
+ */
+ /* Trigger frame must be QoS data or QoS Null frame */
+ UCHAR OldUP;
+
+ OldUP = (*(pRxBlk->pData+LENGTH_802_11) & 0x07);
+ if (OldPwrMgmt == PWR_SAVE)
+ UAPSD_TriggerFrameHandle(pAd, pEntry, OldUP);
+ /* End of if */
+ }
+ } /* End of if */
+#endif /* UAPSD_SUPPORT */
+
+ /* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */
+ if ((pFmeCtrl->SubType & 0x04) && (pFmeCtrl->Order == 0)) /* bit 2 : no DATA */
+ {
+ /* Increase received drop packet counter per BSS */
+ if (pFmeCtrl->FrDs == 0 &&
+ pRxInfo->U2M &&
+ pRxWI->RxWIBSSID < pAd->ApCfg.BssidNum)
+ {
+ pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID].RxDropCount ++;
+ }
+
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ /*
+ update RxBlk->pData, DataSize
+ 802.11 Header, QOS, HTC, Hw Padding
+ */
+
+ /* 1. skip 802.11 HEADER */
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS) || defined(MESH_SUPPORT)
+ if (FALSE
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS)
+ || bWdsPacket
+#endif /* WDS_SUPPORT || CLIENT_WDS */
+ )
+ {
+ pRxBlk->pData += LENGTH_802_11_WITH_ADDR4;
+ pRxBlk->DataSize -= LENGTH_802_11_WITH_ADDR4;
+ }
+ else
+#endif /* WDS_SUPPORT || CLIENT_WDS || MESH_SUPPORT */
+ {
+ pRxBlk->pData += LENGTH_802_11;
+ pRxBlk->DataSize -= LENGTH_802_11;
+ }
+
+ /* 2. QOS */
+ if (pFmeCtrl->SubType & 0x08)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
+ UserPriority = *(pRxBlk->pData) & 0x0f;
+
+
+ /* count packets priroity more than BE */
+ detect_wmm_traffic(pAd, UserPriority, 0);
+ /* bit 7 in QoS Control field signals the HT A-MSDU format */
+ if ((*pRxBlk->pData) & 0x80)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
+
+ /* calculate received AMSDU count and ByteCount */
+ pCounter->ReceivedAMSDUCount.u.LowPart ++;
+
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS) || defined(MESH_SUPPORT)
+ if (FALSE
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS)
+ || bWdsPacket
+#endif /* WDS_SUPPORT || CLIENT_WDS*/
+ )
+ {
+ pCounter->ReceivedOctesInAMSDUCount.QuadPart += (pRxBlk->DataSize + LENGTH_802_11_WITH_ADDR4);
+ }
+ else
+#endif /* WDS_SUPPORT || CLIENT_WDS || MESH_SUPPORT */
+ {
+ pCounter->ReceivedOctesInAMSDUCount.QuadPart += (pRxBlk->DataSize + LENGTH_802_11);
+ }
+ }
+
+ /* skip QOS contorl field */
+ pRxBlk->pData += 2;
+ pRxBlk->DataSize -=2;
+ }
+ pRxBlk->UserPriority = UserPriority;
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap &&
+ (pHeader->FC.SubType & 0x08) && pHeader->FC.Order)
+ {
+ handleHtcField(pAd, pRxBlk);
+ }
+#endif /* TXBF_SUPPORT */
+
+ /* 3. Order bit: A-Ralink or HTC+ */
+ if (pFmeCtrl->Order)
+ {
+#ifdef AGGREGATION_SUPPORT
+ if (
+#ifdef DOT11_N_SUPPORT
+ (pRxWI->RxWIPhyMode < MODE_HTMIX) &&
+#endif /* DOT11_N_SUPPORT */
+ (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE))
+ )
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
+ }
+ else
+#endif
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
+ /* skip HTC control field */
+ pRxBlk->pData += 4;
+ pRxBlk->DataSize -= 4;
+ }
+ }
+
+ /* 4. skip HW padding */
+ if (pRxInfo->L2PAD)
+ {
+ /* just move pData pointer */
+ /* because DataSize excluding HW padding */
+ RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
+ pRxBlk->pData += 2;
+ }
+
+ if (pRxInfo->BA)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
+
+ /* incremented by the number of MPDUs */
+ /* received in the A-MPDU when an A-MPDU is received. */
+ pCounter->MPDUInReceivedAMPDUCount.u.LowPart ++;
+ }
+
+#ifdef SOFT_ENCRYPT
+ /* 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) && (pRxInfo->Decrypted == 0))
+ {
+ if (RTMPSoftDecryptionAction(pAd,
+ (PUCHAR)pHeader,
+ UserPriority,
+ &pEntry->PairwiseKey,
+ pRxBlk->pData,
+ &(pRxBlk->DataSize)) != NDIS_STATUS_SUCCESS)
+ {
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ /* Record the Decrypted bit as 1 */
+ pRxInfo->Decrypted = 1;
+ }
+#endif /* SOFT_ENCRYPT */
+
+ if (!((pHeader->Frag == 0) && (pFmeCtrl->MoreFrag == 0)))
+ {
+ /* re-assemble the fragmented packets */
+ /* return complete frame (pRxPacket) or NULL */
+ bFragment = TRUE;
+ pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
+ }
+
+ if (pRxPacket)
+ {
+ /* process complete frame */
+ if (bFragment && (pFmeCtrl->Wep) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
+ {
+ /* Minus MIC length */
+ pRxBlk->DataSize -= 8;
+
+ /* For TKIP frame, calculate the MIC value */
+ if (APCheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
+ {
+ return;
+ }
+ }
+
+ if (pEntry)
+ {
+ pEntry->RxBytes+=pRxWI->RxWIMPDUByteCnt;
+ INC_COUNTER64(pEntry->RxPackets);
+ }
+#ifdef IKANOS_VX_1X0
+ RTMP_SET_PACKET_IF(pRxPacket, FromWhichBSSID);
+#endif /* IKANOS_VX_1X0 */
+ APRxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+ else
+ {
+ /* just return */
+ /* because RTMPDeFragmentDataFrame() will release rx packet, */
+ /* if packet is fragmented */
+ return;
+ }
+ return;
+
+err:
+ /* Increase received error packet counter per BSS */
+ if (pFmeCtrl->FrDs == 0 &&
+ pRxInfo->U2M &&
+ pRxWI->RxWIBSSID < pAd->ApCfg.BssidNum)
+ {
+ pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID].RxDropCount ++;
+ pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID].RxErrorCount ++;
+ }
+
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+VOID APHandleRxDataFrame_Hdr_Trns(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo;
+ RXWI_STRUC *pRxWI = pRxBlk->pRxWI;
+ HEADER_802_11 *pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ BOOLEAN bFragment = FALSE;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR FromWhichBSSID = BSS0;
+ UCHAR OldPwrMgmt = PWR_ACTIVE; /* UAPSD AP SUPPORT */
+ UCHAR UserPriority = 0;
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS)
+ BOOLEAN bWdsPacket = FALSE;
+#endif /* WDS_SUPPORT || CLIENT_WDS */
+ FRAME_CONTROL *pFmeCtrl = &pHeader->FC;
+ COUNTER_RALINK *pCounter = &pAd->RalinkCounters;
+ UCHAR *pData;
+
+//+++Add by shiang for debug
+if (0 /*!(pRxInfo->Mcast || pRxInfo->Bcast)*/){
+ DBGPRINT(RT_DEBUG_OFF, ("-->%s(%d): Dump Related Info!\n", __FUNCTION__, __LINE__));
+ hex_dump("DataFrameHeader", pHeader, 36);
+ hex_dump("DataFramePayload", pRxBlk->pTransData , pRxBlk->TransDataSize);
+}
+//---Add by shiangf for debug
+
+ if (APCheckVaildDataFrame(pAd, pRxBlk) != TRUE)
+ {
+ goto err;
+ }
+
+#ifdef IDS_SUPPORT
+ /*
+ Replay attack detection
+ Detect a spoofed data frame from a rogue AP, ignore it.
+ */
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ if (pFmeCtrl->FrDs == 1 &&
+ (RTMPReplayAttackDetection(pAd, pHeader->Addr2, pRxWI->RxWISNR2, 0, 0, pRxWI->RxWISNR1, pRxWI->RxWIBW) == TRUE))
+ {
+ goto err;
+ }
+ else
+#endif /* MT7601 */
+ if (pFmeCtrl->FrDs == 1 &&
+ (RTMPReplayAttackDetection(pAd, pHeader->Addr2, pRxWI->RxWIRSSI0, pRxWI->RxWIRSSI1, pRxWI->RxWIRSSI2, 0, 0) == TRUE))
+ {
+ goto err;
+ }
+#endif /* IDS_SUPPORT */
+
+ /* handle WDS */
+ if ((pFmeCtrl->FrDs == 1) && (pFmeCtrl->ToDs == 1))
+ {
+ do
+ {
+#ifdef CLIENT_WDS
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+ if (pEntry != NULL)
+ {
+ if (IS_ENTRY_CLIWDS(pEntry))
+ ;
+ else if (IS_ENTRY_CLIENT(pEntry)
+ && (pEntry->Sst == SST_ASSOC))
+ SET_ENTRY_CLIWDS(pEntry);
+ else
+ pEntry = NULL;
+ }
+
+ if (pEntry != NULL)
+ {
+ FromWhichBSSID = pEntry->apidx;
+
+ /* Increase received byte counter per BSS */
+ if (FromWhichBSSID < pAd->ApCfg.BssidNum)
+ {
+ MULTISSID_STRUCT *pMbss = pEntry->pMbss;
+ if (pMbss != NULL)
+ {
+ pMbss->ReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ pMbss->RxCount ++;
+ }
+ }
+ RX_BLK_SET_FLAG(pRxBlk, fRX_WDS);
+ bWdsPacket = TRUE;
+ CliWds_ProxyTabUpdate(pAd, pEntry->Aid, pHeader->Octet);
+ break;
+ }
+#endif /* CLIENT_WDS */
+
+
+#ifdef WDS_SUPPORT
+ /* handle WDS */
+ {
+ bWdsPacket = TRUE;
+ if (MAC_ADDR_EQUAL(pHeader->Addr1, pAd->CurrentAddress))
+ pEntry = FindWdsEntry(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2, pRxWI->RxWIPhyMode);
+ else
+ pEntry = NULL;
+
+
+ /* have no valid wds entry exist, then discard the incoming packet.*/
+ if (!(pEntry && WDS_IF_UP_CHECK(pAd, pEntry->MatchWDSTabIdx)))
+ {
+ /* drop the packet */
+ goto err;
+ }
+
+ /*receive corresponding WDS packet, disable TX lock state (fix WDS jam issue) */
+ if(pEntry && (pEntry->LockEntryTx == TRUE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive WDS packet, disable TX lock state!\n"));
+ pEntry->ContinueTxFailCnt = 0;
+ pEntry->LockEntryTx = FALSE;
+ }
+
+ RX_BLK_SET_FLAG(pRxBlk, fRX_WDS);
+ FromWhichBSSID = pEntry->MatchWDSTabIdx + MIN_NET_DEVICE_FOR_WDS;
+ break;
+ }
+#endif /* WDS_SUPPORT */
+ } while(FALSE);
+
+ if (pEntry == NULL)
+ {
+ /* have no WDS or MESH support */
+ /* drop the packet */
+ goto err;
+ }
+ }
+ /* handle APCLI. */
+ else if ((pFmeCtrl->FrDs == 1) && (pFmeCtrl->ToDs == 0))
+ {
+#ifdef APCLI_SUPPORT
+ if (VALID_WCID(pRxWI->RxWIWirelessCliID))
+ pEntry = ApCliTableLookUpByWcid(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2);
+ else
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ {
+ if (!(pEntry && APCLI_IF_UP_CHECK(pAd, pEntry->MatchAPCLITabIdx)))
+ {
+ goto err;
+ }
+ FromWhichBSSID = pEntry->MatchAPCLITabIdx + MIN_NET_DEVICE_FOR_APCLI;
+ RX_BLK_SET_FLAG(pRxBlk, fRX_APCLI);
+
+ /* Process broadcast packets */
+ if (pRxInfo->Mcast || pRxInfo->Bcast)
+ {
+ /* Process the received broadcast frame for AP-Client. */
+ if (!ApCliHandleRxBroadcastFrame(pAd, pRxBlk, pEntry, FromWhichBSSID))
+ {
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ return;
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ /* no APCLI support */
+ /* release packet */
+ goto err;
+ }
+ }
+ else
+ {
+ pEntry = PACInquiry(pAd, pRxWI->RxWIWirelessCliID);
+
+ /* can't find associated STA entry then filter invlid data frame */
+ if (!pEntry)
+ {
+ goto err;
+ }
+
+ FromWhichBSSID = pEntry->apidx;
+
+#ifdef STATS_COUNT_SUPPORT
+ /* Increase received byte counter per BSS */
+ if (pHeader->FC.FrDs == 0 &&
+ pRxInfo->U2M &&
+ FromWhichBSSID < pAd->ApCfg.BssidNum)
+ {
+ MULTISSID_STRUCT *pMbss = pEntry->pMbss;
+ if (pMbss != NULL)
+ {
+ pMbss->ReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ pMbss->RxCount ++;
+ }
+ }
+
+ /* update multicast counter */
+ if (IS_MULTICAST_MAC_ADDR(pHeader->Addr3))
+ INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
+#endif /* STATS_COUNT_SUPPORT */
+ }
+
+ ASSERT(pEntry->Aid == pRxWI->RxWIWirelessCliID);
+
+
+
+#ifdef DOT11_N_SUPPORT
+ /* check Atheros Client */
+ if (!pEntry->bIAmBadAtheros && (pFmeCtrl->Retry )
+ && (pRxInfo->AMPDU == 1) && (pAd->CommonCfg.bHTProtect == TRUE)
+ )
+ {
+ if (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == FALSE)
+ RTMP_UPDATE_PROTECT(pAd, 8 , ALLN_SETPROTECT, FALSE, FALSE);
+ pEntry->bIAmBadAtheros = TRUE;
+
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ /* update rssi sample */
+ Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
+
+ if (pRxInfo->U2M)
+ {
+ pEntry->LastRxRate = (ULONG)((pRxWI->RxWIMCS) + (pRxWI->RxWIBW <<7) +
+ (pRxWI->RxWISGI <<8) + (pRxWI->RxWISTBC <<9) +
+ (pRxWI->RxWIPhyMode <<14));
+
+#ifdef TXBF_SUPPORT
+ if (pRxWI->RxWISGI)
+ pEntry->OneSecRxSGICount++;
+ else
+ pEntry->OneSecRxLGICount++;
+#endif // TXBF_SUPPORT //
+ }
+
+ pAd->ApCfg.LastSNR0 = (UCHAR)(pRxWI->RxWISNR0);
+ pAd->ApCfg.LastSNR1 = (UCHAR)(pRxWI->RxWISNR1);
+#ifdef DOT11N_SS3_SUPPORT
+ pAd->ApCfg.LastSNR2 = (UCHAR)(pRxWI->RxWISNR2);
+#endif /* DOT11N_SS3_SUPPORT */
+ pEntry->freqOffset = (CHAR)(pRxWI->RxWIFOFFSET);
+ pEntry->freqOffsetValid = TRUE;
+
+
+ /* Gather PowerSave information from all valid DATA frames. IEEE 802.11/1999 p.461 */
+ /* must be here, before no DATA check */
+
+
+ pData = (UCHAR *)pHeader;
+
+
+ /* 1: PWR_SAVE, 0: PWR_ACTIVE */
+ OldPwrMgmt = APPsIndicate(pAd, pHeader->Addr2, pEntry->Aid, pFmeCtrl->PwrMgmt);
+#ifdef UAPSD_SUPPORT
+ if (pFmeCtrl->PwrMgmt)
+ {
+ if ((CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE)) &&
+ (pFmeCtrl->SubType & 0x08))
+ {
+ /*
+ In IEEE802.11e, 11.2.1.4 Power management with APSD,
+ If there is no unscheduled SP in progress, the unscheduled SP begins
+ when the QAP receives a trigger frame from a non-AP QSTA, which is a
+ QoS data or QoS Null frame associated with an AC the STA has
+ configured to be trigger-enabled.
+ */
+ /*
+ In WMM v1.1, A QoS Data or QoS Null frame that indicates transition
+ to/from Power Save Mode is not considered to be a Trigger Frame and
+ the AP shall not respond with a QoS Null frame.
+ */
+ /* Trigger frame must be QoS data or QoS Null frame */
+ UCHAR OldUP;
+
+ OldUP = (*(pData+LENGTH_802_11) & 0x07);
+ if (OldPwrMgmt == PWR_SAVE)
+ UAPSD_TriggerFrameHandle(pAd, pEntry, OldUP);
+ /* End of if */
+ }
+ } /* End of if */
+#endif /* UAPSD_SUPPORT */
+
+ /* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */
+ if ((pFmeCtrl->SubType & 0x04) && (pFmeCtrl->Order == 0)) /* bit 2 : no DATA */
+ {
+ /* Increase received drop packet counter per BSS */
+ if (pFmeCtrl->FrDs == 0 &&
+ pRxInfo->U2M &&
+ pRxWI->RxWIBSSID < pAd->ApCfg.BssidNum)
+ {
+ pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID].RxDropCount ++;
+ }
+
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ /*
+ update RxBlk->pData, DataSize
+ 802.11 Header, QOS, HTC, Hw Padding
+ */
+
+ /* 1. skip 802.11 HEADER */
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS) || defined(MESH_SUPPORT)
+ if (FALSE
+#if defined(WDS_SUPPORT) || defined(CLIENT_WDS)
+ || bWdsPacket
+#endif /* WDS_SUPPORT || CLIENT_WDS */
+ )
+ {
+ pData += LENGTH_802_11_WITH_ADDR4;
+ }
+ else
+#endif /* WDS_SUPPORT || CLIENT_WDS || MESH_SUPPORT */
+ {
+ pData += LENGTH_802_11;
+ }
+
+ /* 2. QOS */
+ if (pFmeCtrl->SubType & 0x08)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
+ UserPriority = *(pData) & 0x0f;
+
+
+ /* count packets priroity more than BE */
+ detect_wmm_traffic(pAd, UserPriority, 0);
+ /* bit 7 in QoS Control field signals the HT A-MSDU format */
+ if ((*pData) & 0x80)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
+
+ }
+
+ /* skip QOS contorl field */
+ pData += 2;
+ }
+ pRxBlk->UserPriority = UserPriority;
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap &&
+ (pHeader->FC.SubType & 0x08) && pHeader->FC.Order)
+ {
+ handleHtcField(pAd, pRxBlk);
+ }
+#endif /* TXBF_SUPPORT */
+
+ /* 3. Order bit: A-Ralink or HTC+ */
+ if (pFmeCtrl->Order)
+ {
+#ifdef AGGREGATION_SUPPORT
+ if (
+#ifdef DOT11_N_SUPPORT
+ (pRxWI->RxWIPhyMode < MODE_HTMIX) &&
+#endif /* DOT11_N_SUPPORT */
+ (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE))
+ )
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
+ }
+ else
+#endif
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
+ /* skip HTC control field */
+ pData += 4;
+ }
+ }
+
+ /* 4. skip HW padding */
+ if (pRxInfo->L2PAD)
+ {
+ /* just move pData pointer */
+ /* because DataSize excluding HW padding */
+ RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
+ pData += 2;
+ }
+
+ if (pRxInfo->BA)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
+
+ /* incremented by the number of MPDUs */
+ /* received in the A-MPDU when an A-MPDU is received. */
+ pCounter->MPDUInReceivedAMPDUCount.u.LowPart ++;
+ }
+
+#ifdef SOFT_ENCRYPT
+ /* 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) && (pRxInfo->Decrypted == 0))
+ {
+ if (RTMPSoftDecryptionAction(pAd,
+ (PUCHAR)pHeader,
+ UserPriority,
+ &pEntry->PairwiseKey,
+ pRxBlk->pTransData + 14,
+ &(pRxBlk->TransDataSize)) != NDIS_STATUS_SUCCESS)
+ {
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ /* Record the Decrypted bit as 1 */
+ pRxInfo->Decrypted = 1;
+ }
+#endif /* SOFT_ENCRYPT */
+
+ if (!((pHeader->Frag == 0) && (pFmeCtrl->MoreFrag == 0)))
+ {
+ /* re-assemble the fragmented packets */
+ /* return complete frame (pRxPacket) or NULL */
+ bFragment = TRUE;
+ pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
+ }
+
+ if (pRxPacket)
+ {
+ /* process complete frame */
+ if (bFragment && (pFmeCtrl->Wep) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
+ {
+ /* Minus MIC length */
+ pRxBlk->DataSize -= 8;
+
+ /* For TKIP frame, calculate the MIC value */
+ if (APCheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
+ {
+ return;
+ }
+ }
+
+ if (pEntry)
+ {
+ pEntry->RxBytes+=pRxWI->RxWIMPDUByteCnt;
+ INC_COUNTER64(pEntry->RxPackets);
+ }
+#ifdef IKANOS_VX_1X0
+ RTMP_SET_PACKET_IF(pRxPacket, FromWhichBSSID);
+#endif /* IKANOS_VX_1X0 */
+ APRxDataFrameAnnounce_Hdr_Trns(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+ else
+ {
+ /* just return */
+ /* because RTMPDeFragmentDataFrame() will release rx packet, */
+ /* if packet is fragmented */
+ return;
+ }
+ return;
+
+err:
+ /* Increase received error packet counter per BSS */
+ if (pFmeCtrl->FrDs == 0 &&
+ pRxInfo->U2M &&
+ pRxWI->RxWIBSSID < pAd->ApCfg.BssidNum)
+ {
+ pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID].RxDropCount ++;
+ pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID].RxErrorCount ++;
+ }
+
+ /* release packet */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Process RxDone interrupt, running in DPC level
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ This routine has to maintain Rx ring read pointer.
+ ========================================================================
+*/
+
+
+#undef MAX_RX_PROCESS_CNT
+#define MAX_RX_PROCESS_CNT (32)
+
+BOOLEAN APRxDoneInterruptHandle(RTMP_ADAPTER *pAd)
+{
+ UINT32 RxProcessed, RxPending;
+ BOOLEAN bReschedule = FALSE;
+ RXD_STRUC *pRxD;
+ RXINFO_STRUC *pRxInfo;
+ UCHAR *pData;
+ RXWI_STRUC *pRxWI;
+ PNDIS_PACKET pRxPacket;
+ PHEADER_802_11 pHeader;
+ RX_BLK rxblk, *pRxBlk;
+ MULTISSID_STRUCT *pMbss;
+ UINT8 RXWISize = pAd->chipCap.RXWISize;
+#ifdef WDS_SUPPORT
+ MAC_TABLE_ENTRY *pEntry = NULL;
+#endif
+#ifdef RLT_MAC
+ RXFCE_INFO *pFceInfo;
+#endif /* RLT_MAC */
+
+#ifdef LINUX
+#endif /* LINUX */
+
+ 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)) ||
+ !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP)) &&
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE))
+ {
+ break;
+ }
+
+#ifdef UAPSD_SUPPORT
+ UAPSD_TIMING_RECORD_INDEX(RxProcessed);
+#endif /* UAPSD_SUPPORT */
+
+
+ /*
+ 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
+ */
+
+ pRxBlk = &rxblk;
+ pRxPacket = GetPacketFromRxRing(pAd, pRxBlk, &bReschedule, &RxPending);
+ if (pRxPacket == NULL)
+ break;
+
+ /* get rx descriptor and data buffer */
+ pRxD = (RXD_STRUC *)&pRxBlk->hw_rx_info[0];
+#ifdef RLT_MAC
+ pFceInfo = rxblk.pRxFceInfo;
+#endif /* RLT_MAC */
+ pRxInfo = rxblk.pRxInfo;
+ pData = GET_OS_PKT_DATAPTR(pRxPacket);
+ pRxWI = (RXWI_STRUC *)pData;
+ pHeader = (PHEADER_802_11)(pData + RXWISize);
+
+#ifdef RLT_MAC
+ // TODO: shiang-6590, handle packet from other ports
+ if (pFceInfo->info_type != 0)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("==>%s(): GetFrameFromOtherPorts!\n", __FUNCTION__));
+ hex_dump("hw_rx_info", &rxblk.hw_rx_info[0], sizeof(rxblk.hw_rx_info));
+ DBGPRINT(RT_DEBUG_TRACE, ("Dump the RxD, RxFCEInfo and RxInfo:\n"));
+ hex_dump("RxD", (UCHAR *)pRxD, sizeof(RXD_STRUC));
+#ifdef RLT_MAC
+ dumpRxFCEInfo(pAd, pFceInfo);
+#endif /* RLT_MAC */
+ dump_rxinfo(pAd, pRxInfo);
+ hex_dump("RxFrame", (UCHAR *)pData, (pFceInfo->pkt_len));
+ DBGPRINT(RT_DEBUG_OFF, ("<==\n"));
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ continue;
+ }
+#endif /* RLT_MAC */
+
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
+ RTMPWIEndianChange(pAd , (PUCHAR)pRxWI, TYPE_RXWI);
+#endif
+
+//+++Add by shiang for debug
+if (0) {
+ DBGPRINT(RT_DEBUG_TRACE, ("==>%s():Dump the RxD, RxFCEInfo and RxInfo:\n", __FUNCTION__));
+ hex_dump("hw_rx_info", &rxblk.hw_rx_info[0], sizeof(rxblk.hw_rx_info));
+ hex_dump("RxD", (UCHAR *)pRxD, sizeof(RXD_STRUC));
+#ifdef RLT_MAC
+ dumpRxFCEInfo(pAd, pFceInfo);
+#endif /* RLT_MAC */
+ dump_rxinfo(pAd, pRxInfo);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Dump the RxWI and RxPacket:\n"));
+ dump_rxwi(pAd, pRxWI);
+ hex_dump("RxPacket", (UCHAR *)pHeader, pRxWI->RxWIMPDUByteCnt);
+ DBGPRINT(RT_DEBUG_TRACE, ("<==%s():Finish dump!\n", __FUNCTION__));
+}
+//---Add by shiang for debug
+
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_RXWI)
+ dbQueueEnqueueRxFrame(pData, (UCHAR *)pHeader, pAd->CommonCfg.DebugFlags);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ /* build RX_BLK */
+ rxblk.pRxWI = pRxWI;
+ rxblk.pHeader = pHeader;
+ rxblk.pRxPacket = pRxPacket;
+ rxblk.pData = (UCHAR *)pHeader;
+ rxblk.DataSize = pRxWI->RxWIMPDUByteCnt;
+ rxblk.Flags = 0;
+ SET_PKT_OPMODE_AP(&rxblk);
+
+#ifdef HDR_TRANS_SUPPORT
+ rxblk.bHdrRxTrans = pRxInfo->ip_sum_err; /* RXINFO bit 31 */
+ rxblk.bHdrVlanTaged = pRxInfo->tcp_sum_err; /* RXINFO bit 30 */
+ rxblk.pTransData = (UCHAR *) pHeader + 38; /* 36 byte - 802.11 MAC header (RX Wifi Info */
+ rxblk.TransDataSize = pRxWI->RxWIMPDUByteCnt;
+#endif /* HDR_TRANS_SUPPORT */
+
+ /* Increase Total receive byte counter after real data received no mater any error or not */
+ pAd->RalinkCounters.ReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ pAd->RalinkCounters.OneSecReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ pAd->RalinkCounters.RxCount++;
+ pAd->RalinkCounters.OneSecRxCount++;
+
+
+#ifdef STATS_COUNT_SUPPORT
+#ifdef RALINK_ATE
+#ifdef CONFIG_AP_SUPPORT
+ INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
+#endif /* CONFIG_AP_SUPPORT */
+#else /* RALINK_ATE */
+ INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
+#endif /* RALINK_ATE */
+#endif /* STATS_COUNT_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1))
+ {
+ if (MAC_ADDR_EQUAL(pHeader->Addr1, pAd->CurrentAddress))
+ pEntry = FindWdsEntry(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2, pRxWI->RxWIPhyMode);
+
+#ifdef STATS_COUNT_SUPPORT
+ if(pEntry)
+ {
+ pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.ReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.ReceivedFragmentCount);
+
+ if(IS_MULTICAST_MAC_ADDR(pHeader->Addr3))
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.MulticastReceivedFrameCount);
+
+ }
+#endif /* STATS_COUNT_SUPPORT */
+ }
+#endif
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ pAd->ate.RxCntPerSec++;
+ ATESampleRssi(pAd, pRxWI);
+#ifdef RALINK_QA
+ if (pAd->ate.bQARxStart == TRUE)
+ {
+ /* GetPacketFromRxRing() has copy the endian-changed RxD if it is necessary. */
+ ATE_QA_Statistics(pAd, pRxWI, pRxInfo, pHeader);
+ }
+
+#ifdef TXBF_SUPPORT
+ /* Check sounding frame */
+ if ((pAd->chipCap.FlgHwTxBfCap) && (pHeader->FC.Type == BTYPE_MGMT))
+ {
+ pRxBlk->pData += LENGTH_802_11;
+ pRxBlk->DataSize -= LENGTH_802_11;
+
+ if (pHeader->FC.Order) {
+ pRxBlk->pData += 4;
+ pRxBlk->DataSize -= 4;
+ }
+
+ if ((((pHeader->FC.SubType == SUBTYPE_ACTION) || (pHeader->FC.SubType == SUBTYPE_ACTION_NO_ACK))
+ && (pRxBlk ->pData)[ 0] == CATEGORY_HT
+ && ((pRxBlk ->pData)[ 1] == MIMO_N_BEACONFORM /*non-compressed beamforming report */
+ || (pRxBlk ->pData)[1] == MIMO_BEACONFORM) )) /*compressed beamforming report */
+ {
+ /* sounding frame */
+ /*printk("Receive sounding response\n"); */
+ if (pAd->ate.sounding == 1) {
+ int i, Nc = ((pRxBlk ->pData)[2] & 0x3) + 1;
+ pAd->ate.soundingSNR[0] = (CHAR)((pRxBlk ->pData)[8]);
+ pAd->ate.soundingSNR[1] = (Nc<2)? 0: (CHAR)((pRxBlk ->pData)[9]);
+ pAd->ate.soundingSNR[2] = (Nc<3)? 0: (CHAR)((pRxBlk ->pData)[10]);
+ pAd->ate.sounding = 2;
+ pAd->ate.soundingRespSize = pRxBlk->DataSize;
+ for (i=0; i<pRxBlk->DataSize && i<MAX_SOUNDING_RESPONSE_SIZE; i++)
+ pAd->ate.soundingResp[i] = pRxBlk->pData[i];
+ }
+ }
+ /* Roger Debug : Fix Me */
+ else
+ {
+ if (pHeader->FC.Order)
+ DBGPRINT( RT_DEBUG_WARN, ("fcsubtype=%x\ndata[0]=%x\ndata[1]=%x\n", pHeader->FC.SubType, (pRxBlk ->pData)[0], (pRxBlk ->pData)[1]));
+ }
+ }
+#endif /* TXBF_SUPPORT */
+#endif /* RALINK_QA */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ continue;
+ }
+#endif /* RALINK_ATE */
+
+ /* Check for all RxD errors */
+ if (APCheckRxError(pAd, pRxInfo, pRxWI->RxWIWirelessCliID) != NDIS_STATUS_SUCCESS)
+ {
+ APRxDErrorHandle(pAd, &rxblk);
+
+ /* Increase received error packet counter per BSS */
+ if (pHeader->FC.FrDs == 0 &&
+ pRxInfo->U2M &&
+ pRxWI->RxWIBSSID < pAd->ApCfg.BssidNum)
+ {
+ pMbss = &pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID];
+ pMbss->RxDropCount ++;
+ pMbss->RxErrorCount ++;
+ }
+
+#ifdef WDS_SUPPORT
+#ifdef STATS_COUNT_SUPPORT
+ if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1))
+ {
+ if (MAC_ADDR_EQUAL(pHeader->Addr1, pAd->CurrentAddress))
+ pEntry = FindWdsEntry(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2, pRxWI->RxWIPhyMode);
+ if(pEntry)
+ pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.RxErrors++;
+ }
+#endif /* STATS_COUNT_SUPPORT */
+#endif /* WDS_SUPPORT */
+ /* discard this frame */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ /*
+ All frames to AP are directed except probe_req. IEEE 802.11/1999 - p.463
+ Do this before checking "duplicate frame".
+ 2003-08-20 accept BEACON to decide if OLBC (Overlapping Legacy BSS Condition) happens
+ TODO: consider move this code to be inside "APCheckRxError()"
+ */
+ switch (pHeader->FC.Type)
+ {
+ case BTYPE_DATA:
+ if (pRxInfo->U2M)
+ {
+ Update_Rssi_Sample(pAd, &pAd->ApCfg.RssiSample, pRxWI);
+ pAd->ApCfg.NumOfAvgRssiSample ++;
+#ifdef DBG_DIAGNOSE
+ if (pRxWI->RxWIMCS < 24) /* 3*3 */
+ {
+ pAd->DiagStruct.RxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+ pAd->DiagStruct.RxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pRxWI->RxWIMCS]++;
+ }
+#endif /* DBG_DIAGNOSE */
+ }
+
+#ifdef HDR_TRANS_SUPPORT
+ rxblk.bHdrRxTrans = pRxInfo->ip_sum_err; /* RXINFO bit 31 */
+
+ if ( rxblk.bHdrRxTrans )
+ {
+ rxblk.bHdrVlanTaged = pRxInfo->tcp_sum_err; /* RXINFO bit 30 */
+ rxblk.pTransData = (UCHAR *) pHeader + 38; /* 36 byte - RX WIFI Size ( 802.11 Header ) */
+ rxblk.TransDataSize = pRxWI->RxWIMPDUByteCnt;
+ rxblk.DataSize += 36;
+
+
+ APHandleRxDataFrame_Hdr_Trns(pAd, &rxblk);
+ }
+ else
+#endif /* HDR_TRANS_SUPPORT */
+
+ APHandleRxDataFrame(pAd, &rxblk);
+ break;
+
+ case BTYPE_MGMT:
+ APHandleRxMgmtFrame(pAd, &rxblk);
+ break;
+
+ case BTYPE_CNTL:
+ APHandleRxControlFrame(pAd, &rxblk);
+ break;
+
+ default:
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ break;
+ }
+ }
+
+#ifdef UAPSD_SUPPORT
+ /* dont remove the function or UAPSD will fail */
+ UAPSD_MR_SP_RESUME(pAd);
+ UAPSD_SP_CloseInRVDone(pAd);
+#endif /* UAPSD_SUPPORT */
+
+ return bReschedule;
+}
+
+
+BOOLEAN APHandleRxDonePacket(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pRxPacket,
+ IN RX_BLK *pRxBlk)
+{
+ RXD_STRUC *pRxD;
+ RXINFO_STRUC *pRxInfo;
+ RXWI_STRUC *pRxWI;
+ PHEADER_802_11 pHeader;
+ MULTISSID_STRUCT *pMbss;
+ BOOLEAN bReschedule = FALSE;
+#ifdef WDS_SUPPORT
+ MAC_TABLE_ENTRY *pEntry = NULL;
+#endif /* WDS_SUPPORT */
+
+
+ SET_PKT_OPMODE_AP(pRxBlk);
+ /* get rx ring descriptor */
+ pRxD = (RXD_STRUC *)&pRxBlk->hw_rx_info[0];
+ pHeader = pRxBlk->pHeader;
+ pRxWI = pRxBlk->pRxWI;
+ pRxInfo = pRxBlk->pRxInfo;
+
+#ifdef WDS_SUPPORT
+ if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1))
+ {
+ if (MAC_ADDR_EQUAL(pHeader->Addr1, pAd->CurrentAddress))
+ pEntry = FindWdsEntry(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2, pRxWI->RxWIPhyMode);
+
+#ifdef STATS_COUNT_SUPPORT
+ if(pEntry)
+ {
+ pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.ReceivedByteCount += pRxWI->RxWIMPDUByteCnt;
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.ReceivedFragmentCount);
+
+ if(IS_MULTICAST_MAC_ADDR(pHeader->Addr3))
+ INC_COUNTER64(pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.MulticastReceivedFrameCount);
+ }
+#endif /* STATS_COUNT_SUPPORT */
+ }
+#endif /* WDS_SUPPORT */
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ pAd->ate.RxCntPerSec++;
+ ATESampleRssi(pAd, pRxWI);
+#ifdef RALINK_QA
+ if (pAd->ate.bQARxStart == TRUE)
+ {
+ /* GetPacketFromRxRing() has copy the endian-changed RxD if it is necessary. */
+ ATE_QA_Statistics(pAd, pRxWI, pRxInfo, pHeader);
+ }
+
+#ifdef TXBF_SUPPORT
+ /* Check sounding frame */
+ if ((pAd->chipCap.FlgHwTxBfCap) && (pHeader->FC.Type == BTYPE_MGMT))
+ {
+ pRxBlk->pData += LENGTH_802_11;
+ pRxBlk->DataSize -= LENGTH_802_11;
+
+ if (pHeader->FC.Order)
+ {
+ pRxBlk->pData += 4;
+ pRxBlk->DataSize -= 4;
+ }
+
+ if ((((pHeader->FC.SubType == SUBTYPE_ACTION) || (pHeader->FC.SubType == SUBTYPE_ACTION_NO_ACK))
+ && (pRxBlk ->pData)[ 0] == CATEGORY_HT
+ && ((pRxBlk ->pData)[ 1] == MIMO_N_BEACONFORM /* non-compressed beamforming report */
+ || (pRxBlk ->pData)[1] == MIMO_BEACONFORM) )) /* compressed beamforming report */
+ {
+ /* sounding frame */
+ /*printk("Receive sounding response\n"); */
+ if (pAd->ate.sounding == 1)
+ {
+ int i, Nc = ((pRxBlk ->pData)[2] & 0x3) + 1;
+
+ pAd->ate.soundingSNR[0] = (CHAR)((pRxBlk ->pData)[8]);
+ pAd->ate.soundingSNR[1] = (Nc<2)? 0: (CHAR)((pRxBlk ->pData)[9]);
+ pAd->ate.soundingSNR[2] = (Nc<3)? 0: (CHAR)((pRxBlk ->pData)[10]);
+ pAd->ate.sounding = 2;
+ pAd->ate.soundingRespSize = pRxBlk->DataSize;
+
+ for (i=0; i < pRxBlk->DataSize && i < MAX_SOUNDING_RESPONSE_SIZE; i++)
+ pAd->ate.soundingResp[i] = pRxBlk->pData[i];
+ }
+ }
+ else
+ {
+ if (pHeader->FC.Order)
+ DBGPRINT( RT_DEBUG_WARN, ("fcsubtype=%x\ndata[0]=%x\ndata[1]=%x\n", pHeader->FC.SubType, (pRxBlk ->pData)[0], (pRxBlk ->pData)[1]));
+ }
+ }
+#endif /* TXBF_SUPPORT */
+#endif /* RALINK_QA */
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ return bReschedule;
+ }
+#endif /* RALINK_ATE */
+
+ /* Check for all RxD errors */
+ if (APCheckRxError(pAd, pRxInfo, pRxWI->RxWIWirelessCliID) != NDIS_STATUS_SUCCESS)
+ {
+ APRxDErrorHandle(pAd, pRxBlk);
+
+ /* Increase received error packet counter per BSS */
+ if ((pHeader->FC.FrDs == 0) &&
+ pRxInfo->U2M &&
+ (pRxWI->RxWIBSSID < pAd->ApCfg.BssidNum))
+ {
+ pMbss = &pAd->ApCfg.MBSSID[pRxWI->RxWIBSSID];
+ pMbss->RxDropCount ++;
+ pMbss->RxErrorCount ++;
+ }
+
+#ifdef WDS_SUPPORT
+#ifdef STATS_COUNT_SUPPORT
+ if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1))
+ {
+ if (MAC_ADDR_EQUAL(pHeader->Addr1, pAd->CurrentAddress))
+ pEntry = FindWdsEntry(pAd, pRxWI->RxWIWirelessCliID, pHeader->Addr2, pRxWI->RxWIPhyMode);
+ if(pEntry)
+ pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsCounter.RxErrors++;
+ }
+#endif /* STATS_COUNT_SUPPORT */
+#endif /* WDS_SUPPORT */
+
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return bReschedule;
+ }
+
+ /*
+ All frames to AP are directed except probe_req. IEEE 802.11/1999 - p.463
+ Do this before checking "duplicate frame".
+ 2003-08-20 accept BEACON to decide if OLBC (Overlapping Legacy BSS Condition) happens
+ TODO: consider move this code to be inside "APCheckRxError()"
+ */
+ switch (pHeader->FC.Type)
+ {
+ case BTYPE_DATA:
+ if (pRxInfo->U2M)
+ {
+ Update_Rssi_Sample(pAd, &pAd->ApCfg.RssiSample, pRxWI);
+ pAd->ApCfg.NumOfAvgRssiSample++;
+#ifdef DBG_DIAGNOSE
+ if (pRxWI->RxWIMCS < 24)
+ {
+ pAd->DiagStruct.RxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+ pAd->DiagStruct.RxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pRxWI->RxWIMCS]++;
+ }
+#endif /* DBG_DIAGNOSE */
+ }
+ APHandleRxDataFrame(pAd, pRxBlk);
+ break;
+
+ case BTYPE_MGMT:
+ APHandleRxMgmtFrame(pAd, pRxBlk);
+ break;
+
+ case BTYPE_CNTL:
+ APHandleRxControlFrame(pAd, pRxBlk);
+ break;
+
+ default:
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ break;
+ }
+
+ return bReschedule;
+}
+
+
+BOOLEAN APFowardWirelessStaToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN ULONG FromWhichBSSID)
+{
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ BOOLEAN bAnnounce, bDirectForward;
+ UCHAR *pHeader802_3;
+ PNDIS_PACKET pForwardPacket;
+
+#ifdef INF_AMAZON_SE
+ /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+ RTMP_SET_PACKET_NOBULKOUT(pPacket, FALSE);
+#endif /* INF_AMAZON_SE */
+
+#ifdef APCLI_SUPPORT
+ /* have no need to forwad the packet to WM */
+ if (FromWhichBSSID >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ /* need annouce to upper layer */
+ return TRUE;
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ /* have no need to forwad the packet to WM */
+ if (FromWhichBSSID >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ /* need annouce to upper layer */
+ return TRUE;
+ }
+#endif /* WDS_SUPPORT */
+
+ pEntry = NULL;
+ bAnnounce = TRUE;
+ bDirectForward = FALSE;
+
+ pHeader802_3 = GET_OS_PKT_DATAPTR(pPacket);
+
+ if (pHeader802_3[0] & 0x01)
+ {
+ /*
+ ** In the case, the BSS have only one STA behind.
+ ** AP have no necessary to forward the M/Bcase packet back to STA again.
+ */
+ if (
+ ((FromWhichBSSID < MAX_MBSSID_NUM(pAd)) &&
+ (FromWhichBSSID < HW_BEACON_MAX_NUM) &&
+ (pAd->ApCfg.MBSSID[FromWhichBSSID].StaCount > 1)))
+ bDirectForward = TRUE;
+
+ /* tell caller to deliver the packet to upper layer */
+ bAnnounce = TRUE;
+ }
+ else
+ {
+ /* if destinated STA is a associated wireless STA */
+ pEntry = MacTableLookup(pAd, pHeader802_3);
+
+ if (pEntry && pEntry->Sst == SST_ASSOC)
+ {
+ bDirectForward = TRUE;
+ bAnnounce = FALSE;
+
+ if (FromWhichBSSID == pEntry->apidx)
+ {/* STAs in same SSID */
+ if ((pAd->ApCfg.MBSSID[pEntry->apidx].IsolateInterStaTraffic == 1))
+ {
+ /* release the packet */
+ bDirectForward = FALSE;
+ bAnnounce = FALSE;
+ }
+ }
+ else
+ {/* STAs in different SSID */
+ if (pAd->ApCfg.IsolateInterStaTrafficBTNBSSID == 1 ||
+ ((FromWhichBSSID < MAX_MBSSID_NUM(pAd)) &&
+ (FromWhichBSSID < HW_BEACON_MAX_NUM) &&
+ (pAd->ApCfg.MBSSID[pEntry->apidx].VLAN_VID != pAd->ApCfg.MBSSID[FromWhichBSSID].VLAN_VID)))
+ /* destination VLAN ID != source VLAN ID */
+ {
+ /*
+ Do not need to care WDS mode because packets from a
+ WDS interface will be passed to upper layer to do
+ bridge.
+ */
+ bDirectForward = FALSE;
+ bAnnounce = FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* announce this packet to upper layer (bridge) */
+ bDirectForward = FALSE;
+ bAnnounce = TRUE;
+ }
+ }
+
+ if (bDirectForward)
+ {
+ /* build an NDIS packet */
+ pForwardPacket = RTMP_DUPLICATE_PACKET(pAd, pPacket, FromWhichBSSID);
+
+ if (pForwardPacket == NULL)
+ {
+ return bAnnounce;
+ }
+
+ {
+ /* 1.1 apidx != 0, then we need set packet mbssid attribute. */
+ RTMP_SET_PACKET_NET_DEVICE_MBSSID(pForwardPacket, MAIN_MBSSID); /* set a default value */
+ if(pEntry && (pEntry->apidx != 0))
+ RTMP_SET_PACKET_NET_DEVICE_MBSSID(pForwardPacket, pEntry->apidx);
+
+ /* send bc/mc frame back to the same bss */
+ if (!pEntry)
+ RTMP_SET_PACKET_NET_DEVICE_MBSSID(pForwardPacket, FromWhichBSSID);
+
+ RTMP_SET_PACKET_WCID(pForwardPacket, pEntry ? pEntry->Aid : MCAST_WCID);
+ RTMP_SET_PACKET_SOURCE(pForwardPacket, PKTSRC_NDIS);
+ RTMP_SET_PACKET_MOREDATA(pForwardPacket, FALSE);
+
+#ifdef INF_AMAZON_SE
+ /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+ RTMP_SET_PACKET_NOBULKOUT(pForwardPacket, TRUE);
+#endif /* INF_AMAZON_SE */
+
+ APSendPacket(pAd, pForwardPacket);
+ }
+
+ /* Dequeue outgoing frames from TxSwQueue0..3 queue and process it */
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+
+ return bAnnounce;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ This routine is used to do insert packet into power-saveing queue.
+
+ Arguments:
+ pAd: Pointer to our adapter
+ pPacket: Pointer to send packet
+ pMacEntry: portint to entry of MacTab. the pMacEntry store attribute of client (STA).
+ QueIdx: Priority queue idex.
+
+ Return Value:
+ NDIS_STATUS_SUCCESS:If succes to queue the packet into TxSwQueue.
+ NDIS_STATUS_FAILURE: If failed to do en-queue.
+========================================================================
+*/
+NDIS_STATUS APInsertPsQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN MAC_TABLE_ENTRY *pMacEntry,
+ IN UCHAR QueIdx)
+{
+ ULONG IrqFlags;
+#ifdef UAPSD_SUPPORT
+ /* put the U-APSD packet to its U-APSD queue by AC ID */
+ UINT32 ac_id = QueIdx - QID_AC_BE; /* should be >= 0 */
+
+
+ if (UAPSD_MR_IS_UAPSD_AC(pMacEntry, ac_id))
+ UAPSD_PacketEnqueue(pAd, pMacEntry, pPacket, ac_id);
+ else
+#endif /* UAPSD_SUPPORT */
+ {
+ if (pMacEntry->PsQueue.Number >= MAX_PACKETS_IN_PS_QUEUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ InsertTailQueue(&pMacEntry->PsQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+ }
+ }
+
+ /* mark corresponding TIM bit in outgoing BEACON frame */
+#ifdef UAPSD_SUPPORT
+ if (UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(pMacEntry, QueIdx))
+ {
+ /* 1. the station is UAPSD station;
+ 2. one of AC is non-UAPSD (legacy) AC;
+ 3. the destinated AC of the packet is UAPSD AC. */
+ /* So we can not set TIM bit due to one of AC is legacy AC */
+ }
+ else
+#endif /* UAPSD_SUPPORT */
+ {
+ WLAN_MR_TIM_BIT_SET(pAd, pMacEntry->apidx, pMacEntry->Aid);
+ }
+ return NDIS_STATUS_SUCCESS;
+}
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+VOID ApCliRTMPSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull,
+ IN PMAC_TABLE_ENTRY pMacEntry)
+{
+ UCHAR NullFrame[48];
+ ULONG Length;
+ PHEADER_802_11 pHeader_802_11;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[pMacEntry->MatchAPCLITabIdx];
+
+ /* WPA 802.1x secured port control */
+ if (((pApCliEntry->AuthMode == Ndis802_11AuthModeWPA) ||
+ (pApCliEntry->AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pApCliEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+ || (pApCliEntry->IEEE8021X == TRUE)
+#ifdef WAPI_SUPPORT
+ || (pApCliEntry->AuthMode == Ndis802_11AuthModeWAICERT)
+ || (pApCliEntry->AuthMode == Ndis802_11AuthModeWAIPSK)
+#endif /* WAPI_SUPPORT */
+ ) &&
+ (pMacEntry->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, pMacEntry->Addr);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pApCliEntry->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pMacEntry->Addr);
+
+ if (pAd->CommonCfg.bAPSDForcePowerSave)
+ {
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ }
+ else
+ {
+ pHeader_802_11->FC.PwrMgmt = 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);
+
+}
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_dls.c b/cleopatre/devkit/mt7601udrv/ap/ap_dls.c
new file mode 100644
index 0000000000..d068e7f355
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_dls.c
@@ -0,0 +1,345 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ Handle WMM-DLS state machine.
+
+***************************************************************************/
+
+#include "rt_config.h"
+
+
+#ifdef QOS_DLS_SUPPORT
+
+/*
+========================================================================
+Routine Description:
+ DLS state machine init, including state transition and timer init.
+
+Arguments:
+ pAd points to our adapter
+ S pointer to the DLS state machine
+ Trans[]
+
+Return Value:
+ None
+
+ Note:
+ The state machine looks like the following
+
+ DLS_IDLE
+ MT2_PEER_DLS_REQ PeerDlsReqAction
+ MT2_PEER_DLS_RSP PeerDlsRspAction
+ MT2_PEER_DLS_TEAR_DOWN PeerDlsTearDownAction
+========================================================================
+ */
+VOID APDLSStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG,
+ (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
+
+ StateMachineSetAction(S, DLS_IDLE, MT2_PEER_DLS_REQ,
+ (STATE_MACHINE_FUNC)APPeerDlsReqAction);
+ StateMachineSetAction(S, DLS_IDLE, MT2_PEER_DLS_RSP,
+ (STATE_MACHINE_FUNC)APPeerDlsRspAction);
+ StateMachineSetAction(S, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN,
+ (STATE_MACHINE_FUNC)APPeerDlsTearDownAction);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Handle peer DLS Request action frame.
+
+Arguments:
+ pAd points to our adapter
+ *pElem action frame
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID APPeerDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *pElem)
+{
+ PMAC_TABLE_ENTRY pDAEntry, pSAEntry;
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ UINT16 CapabilityInfo;
+ UINT16 DLSTimeout;
+ PUCHAR pOutBuffer = NULL;
+ PFRAME_802_11 Fr;
+ UINT16 Status;
+ UINT32 FrameLen = 0;
+ HEADER_802_11 DlsRspHdr;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_RESPONSE;
+ UCHAR SupportedRatesLen = 0;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+ HT_CAPABILITY_IE HtCapability;
+ UCHAR HtCapabilityLen;
+
+
+ /* frame sanity check */
+ if (!PeerDlsReqSanity(pAd, pElem->Msg, pElem->MsgLen, DA, SA,
+ &CapabilityInfo, &DLSTimeout,
+ &SupportedRatesLen, &SupportedRates[0],
+ &HtCapabilityLen, &HtCapability))
+ {
+ return;
+ }
+
+ /* check whether the source station is legal */
+ pSAEntry = MacTableLookup(pAd, SA);
+ if (!pSAEntry)
+ return;
+
+ pSAEntry->bDlsInit = FALSE;
+
+ /* check whether the destination station exists in our associated table */
+ pDAEntry = MacTableLookup(pAd, DA);
+ if (!pDAEntry)
+ Status = MLME_DEST_STA_NOT_IN_QBSS;
+ else if (pDAEntry && (pDAEntry->apidx != pSAEntry->apidx))
+ Status = MLME_DEST_STA_NOT_IN_QBSS;
+ else if (pDAEntry && !CLIENT_STATUS_TEST_FLAG(pDAEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ Status = MLME_DEST_STA_IS_NOT_A_QSTA;
+ else if (pDAEntry->WepStatus != pSAEntry->WepStatus)
+ Status = MLME_QOS_UNSPECIFY; /* different security algorithm */
+ else if (!pAd->ApCfg.MBSSID[pSAEntry->apidx].bDLSCapable)
+ Status = MLME_DLS_NOT_ALLOW_IN_QBSS;
+ else
+ Status = MLME_SUCCESS;
+
+ if (pDAEntry)
+ pDAEntry->bDlsInit = FALSE;
+
+ /* forward DLS-Request to real destination */
+ Fr = (PFRAME_802_11)pElem->Msg;
+
+/* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
+ if(pOutBuffer == NULL)
+ return;
+
+ /*
+ If status is successful, forward DLS-Request frame to destination
+ otherwise send DLS-Response with reason code to originator.
+ */
+ if (Status == MLME_SUCCESS)
+ {
+ NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN);
+ NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].Bssid, MAC_ADDR_LEN);
+ NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN);
+ NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen);
+ FrameLen = pElem->MsgLen;
+ }
+ else
+ {
+ /* response error to source station */
+ MgtMacHeaderInit(pAd, &DlsRspHdr, SUBTYPE_ACTION, 0, SA,
+ pAd->ApCfg.MBSSID[pSAEntry->apidx].Bssid);
+
+ /*
+ Capability information and supported rate field are present
+ only when status code is zero.
+ */
+ MakeOutgoingFrame(pOutBuffer, (ULONG *) &FrameLen,
+ sizeof(HEADER_802_11), &DlsRspHdr,
+ 1, &Category,
+ 1, &Action,
+ 2, &Status,
+ 6, SA,
+ 6, DA,
+ END_OF_ARGS);
+ }
+
+ /* transmit the frame */
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+/* kfree(pOutBuffer); */
+ os_free_mem(NULL, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("DLS - APPeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x "
+ "with Status=%d\n",
+ SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], Status));
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Handle peer DLS Response action frame.
+
+Arguments:
+ pAd points to our adapter
+ *pElem action frame
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID APPeerDlsRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *pElem)
+{
+ PMAC_TABLE_ENTRY pDAEntry, pSAEntry;
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ UINT16 CapabilityInfo;
+ UINT16 StatusCode;
+ PUCHAR pOutBuffer = NULL;
+ PFRAME_802_11 Fr;
+ UINT32 FrameLen = 0;
+ UCHAR SupportedRatesLen = 0;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR HtCapabilityLen;
+ HT_CAPABILITY_IE HtCapability;
+
+
+ /* frame sanity check */
+ if (! PeerDlsRspSanity(pAd, pElem->Msg, pElem->MsgLen, DA, SA,
+ &CapabilityInfo, &StatusCode,
+ &SupportedRatesLen, &SupportedRates[0],
+ &HtCapabilityLen, &HtCapability))
+ {
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x "
+ "with StatusCode=%d\n",
+ SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode));
+
+ /* check whether the source station is legal */
+ pSAEntry = MacTableLookup(pAd, SA);
+ if (!pSAEntry)
+ return;
+
+ pDAEntry = MacTableLookup(pAd, DA);
+ if (!pDAEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Destination station does not exist!\n"));
+ return;
+ }
+
+ pSAEntry->bDlsInit = FALSE;
+
+ /* forward DLS-Request to real destination */
+ Fr = (PFRAME_802_11)pElem->Msg;
+
+/* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
+ if (pOutBuffer == NULL)
+ return; /* fatal error, no available memory */
+
+ NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN);
+ NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].Bssid, MAC_ADDR_LEN);
+ NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN);
+
+ NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen);
+ FrameLen = pElem->MsgLen;
+
+ /* transmit the response frame */
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+/* kfree(pOutBuffer); */
+ os_free_mem(NULL, pOutBuffer);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Handle peer DLS Tear down action frame.
+
+Arguments:
+ pAd points to our adapter
+ *pElem action frame
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID APPeerDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *pElem)
+{
+ PMAC_TABLE_ENTRY pDAEntry, pSAEntry;
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ UINT16 ReasonCode;
+ PUCHAR pOutBuffer = NULL;
+ PFRAME_802_11 Fr;
+ UINT32 FrameLen = 0;
+
+
+ /* frame sanity check */
+ if (! PeerDlsTearDownSanity(pAd, pElem->Msg, pElem->MsgLen,
+ DA, SA, &ReasonCode))
+ {
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+
+ pSAEntry = MacTableLookup(pAd, SA);
+ if (!pSAEntry)
+ return;
+
+ pDAEntry = MacTableLookup(pAd, DA);
+ if (!pDAEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Destination station does not exist!\n"));
+ return;
+ }
+
+ pSAEntry->bDlsInit = FALSE;
+
+ /* forward Tear-down to real destination */
+ Fr = (PFRAME_802_11)pElem->Msg;
+
+/* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */
+ os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
+ if (pOutBuffer == NULL)
+ return; /* fatal error, no available memory */
+
+ NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN);
+ NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].Bssid, MAC_ADDR_LEN);
+ NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN);
+
+ NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen);
+ FrameLen = pElem->MsgLen;
+
+ /* transmit the tear down frame */
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+/* kfree(pOutBuffer); */
+ os_free_mem(NULL, pOutBuffer);
+}
+
+#endif /* QOS_DLS_SUPPORT */
+
+/* End of ap_dls.c */
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_ftkd.c b/cleopatre/devkit/mt7601udrv/ap/ap_ftkd.c
new file mode 100644
index 0000000000..a4e28c7dc3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_ftkd.c
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related IEEE802.11r Key Distribution Protocol (FT KDP) body.
+
+ Overview:
+
+ 1. A station associates to us, send out a broadcast ADD-Notify packet.
+
+ ASSOC -->
+ FT_KDP_EVENT_INFORM(FT_KDP_SIG_FT_ASSOCIATION) -->
+ FT_KDP_EventInform(FT_KDP_SIG_FT_ASSOCIATION) -->
+ Notify IAPP daemon, IAPP_RcvHandlerRawDrv(), IAPP_SIG_Process() -->
+ Send ADD-Notify packet, IAPP_UDP_PacketSend(), IAPP_L2UpdateFrameSend()
+
+ 2. When receiving a ADD-Notify packet, send a unicast SSB packet to
+ request PMK-R1 key for the station with our R0KH.
+
+ IAPP daemon, IAPP_RcvHandlerUdp() -->
+ Notify driver, IAPP_MsgProcess() -->
+ IOCTL, RTMPAPSetInformation() -->
+ FT_KDP_StationInform() -->
+ Notify IAPP daemon, FT_KDP_EventInform(FT_KDP_SIG_KEY_REQ_AUTO) -->
+ Notify IAPP daemon, IAPP_RcvHandlerRawDrv(), IAPP_SIG_Process() -->
+ Send SSB packet with R0KHID = 0, by using TCP or UDP based on peerIP
+
+ 3. A station reassociates to us, send out a MOVE-Request packet.
+
+ REASSOC -->
+ FT_KDP_EVENT_INFORM(FT_KDP_SIG_FT_REASSOCIATION) -->
+ FT_KDP_EventInform(FT_KDP_SIG_FT_REASSOCIATION) -->
+ Notify IAPP daemon, IAPP_RcvHandlerRawDrv(), IAPP_SIG_Process() -->
+ Send MOVE-Request packet by using TCP or UDP, IAPP_L2UpdateFrameSend()
+
+ 4. When receiving a MOVE-Request packet, delete the STA MAC entry.
+
+ IAPP daemon, IAPP_RcvHandlerUdp()/ IAPP_RcvHandlerTcp() -->
+ Notify driver, IAPP_MsgProcess() -->
+ IOCTL, RTMPAPSetInformation() -->
+ RT_SET_DEL_MAC_ENTRY -->
+ Send MOVE-Response packet by using TCP, FT_KDP_MoveFrameSend()
+
+ 5. When receiving a MOVE-Response packet, nothing to do.
+
+ 6. When receiving a SSB packet (i.e. key request), send a unicast SAB
+ packet to response the key to the R1KH.
+
+ IAPP daemon -->
+ Notify driver, IAPP_MsgProcess() -->
+ IOCTL, RTMPAPSetInformation() -->
+ FT_KDP_IOCTL_KEY_REQ() -->
+ Notify IAPP daemon, FT_KDP_EventInform(FT_KDP_SIG_KEY_RSP_AUTO) -->
+ Send SAB packet with my R0KHID, FT_KDP_SecurityBlockSend() by using TCP
+
+ 7. When receiving a SAB packet (i.e. key response), set the PMK-R1 key.
+
+ IAPP daemon -->
+ Notify driver, IAPP_MsgProcess() -->
+ IOCTL, RTMPAPSetInformation() -->
+ FT_KDP_KeyResponseToUs()
+
+ 8. Send a information broadcast to the LAN periodically.
+
+***************************************************************************/
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_ids.c b/cleopatre/devkit/mt7601udrv/ap/ap_ids.c
new file mode 100644
index 0000000000..62b04d223c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_ids.c
@@ -0,0 +1,459 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ap_ids.c
+
+ Abstract:
+ monitor intrusion detection condition
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ */
+#ifdef IDS_SUPPORT
+
+#include "rt_config.h"
+
+#define IDS_EXEC_INTV 1000 /* 1 sec */
+
+
+VOID RTMPIdsStart(
+ IN PRTMP_ADAPTER pAd)
+{
+
+ if (pAd->ApCfg.IDSTimerRunning == FALSE)
+ {
+ RTMPSetTimer(&pAd->ApCfg.IDSTimer, IDS_EXEC_INTV);
+ pAd->ApCfg.IDSTimerRunning = TRUE;
+ }
+}
+
+VOID RTMPIdsStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN Cancelled;
+
+ if (pAd->ApCfg.IDSTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pAd->ApCfg.IDSTimer, &Cancelled);
+ pAd->ApCfg.IDSTimerRunning = FALSE;
+ }
+}
+
+#ifdef SYSTEM_LOG_SUPPORT
+VOID RTMPHandleIdsEvent(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+
+ UINT32 FloodFrameCount[IW_FLOOD_EVENT_TYPE_NUM];
+ UINT32 FloodFrameThreshold[IW_FLOOD_EVENT_TYPE_NUM];
+
+ FloodFrameCount[0] = pAd->ApCfg.RcvdAuthCount;
+ FloodFrameCount[1] = pAd->ApCfg.RcvdAssocReqCount;
+ FloodFrameCount[2] = pAd->ApCfg.RcvdReassocReqCount;
+ FloodFrameCount[3] = pAd->ApCfg.RcvdProbeReqCount;
+ FloodFrameCount[4] = pAd->ApCfg.RcvdDisassocCount;
+ FloodFrameCount[5] = pAd->ApCfg.RcvdDeauthCount;
+ FloodFrameCount[6] = pAd->ApCfg.RcvdEapReqCount;
+
+ FloodFrameThreshold[0] = pAd->ApCfg.AuthFloodThreshold;
+ FloodFrameThreshold[1] = pAd->ApCfg.AssocReqFloodThreshold;
+ FloodFrameThreshold[2] = pAd->ApCfg.ReassocReqFloodThreshold;
+ FloodFrameThreshold[3] = pAd->ApCfg.ProbeReqFloodThreshold;
+ FloodFrameThreshold[4] = pAd->ApCfg.DisassocFloodThreshold;
+ FloodFrameThreshold[5] = pAd->ApCfg.DeauthFloodThreshold;
+ FloodFrameThreshold[6] = pAd->ApCfg.EapReqFloodThreshold;
+
+ /* trigger flooding traffic event */
+ for (j = 0; j < IW_FLOOD_EVENT_TYPE_NUM; j++)
+ {
+ if ((FloodFrameThreshold[j] > 0) && (FloodFrameCount[j] > FloodFrameThreshold[j]))
+ {
+ RTMPSendWirelessEvent(pAd, IW_FLOOD_AUTH_EVENT_FLAG + j, NULL, MAX_MBSSID_NUM(pAd), 0);
+ /*DBGPRINT(RT_DEBUG_TRACE, ("flooding traffic event(%d) - %d\n", IW_FLOOD_AUTH_EVENT_FLAG + j, FloodFrameCount[j])); */
+ }
+ }
+
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ UINT32 SpoofedFrameCount[IW_SPOOF_EVENT_TYPE_NUM];
+ CHAR RssiOfSpoofedFrame[IW_SPOOF_EVENT_TYPE_NUM];
+ INT k;
+
+ SpoofedFrameCount[0] = pAd->ApCfg.MBSSID[i].RcvdConflictSsidCount;
+ SpoofedFrameCount[1] = pAd->ApCfg.MBSSID[i].RcvdSpoofedAssocRespCount;
+ SpoofedFrameCount[2] = pAd->ApCfg.MBSSID[i].RcvdSpoofedReassocRespCount;
+ SpoofedFrameCount[3] = pAd->ApCfg.MBSSID[i].RcvdSpoofedProbeRespCount;
+ SpoofedFrameCount[4] = pAd->ApCfg.MBSSID[i].RcvdSpoofedBeaconCount;
+ SpoofedFrameCount[5] = pAd->ApCfg.MBSSID[i].RcvdSpoofedDisassocCount;
+ SpoofedFrameCount[6] = pAd->ApCfg.MBSSID[i].RcvdSpoofedAuthCount;
+ SpoofedFrameCount[7] = pAd->ApCfg.MBSSID[i].RcvdSpoofedDeauthCount;
+ SpoofedFrameCount[8] = pAd->ApCfg.MBSSID[i].RcvdSpoofedUnknownMgmtCount;
+ SpoofedFrameCount[9] = pAd->ApCfg.MBSSID[i].RcvdReplayAttackCount;
+
+ RssiOfSpoofedFrame[0] = pAd->ApCfg.MBSSID[i].RssiOfRcvdConflictSsid;
+ RssiOfSpoofedFrame[1] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAssocResp;
+ RssiOfSpoofedFrame[2] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedReassocResp;
+ RssiOfSpoofedFrame[3] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedProbeResp;
+ RssiOfSpoofedFrame[4] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedBeacon;
+ RssiOfSpoofedFrame[5] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDisassoc;
+ RssiOfSpoofedFrame[6] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAuth;
+ RssiOfSpoofedFrame[7] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDeauth;
+ RssiOfSpoofedFrame[8] = pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedUnknownMgmt;
+ RssiOfSpoofedFrame[9] = pAd->ApCfg.MBSSID[i].RssiOfRcvdReplayAttack;
+
+ /* trigger spoofed attack event */
+ for (k = 0; k < IW_SPOOF_EVENT_TYPE_NUM; k++)
+ {
+ if (SpoofedFrameCount[k] > 0)
+ {
+ RTMPSendWirelessEvent(pAd, IW_CONFLICT_SSID_EVENT_FLAG + k, NULL, i, RssiOfSpoofedFrame[k]);
+ /*DBGPRINT(RT_DEBUG_TRACE, ("spoofed attack event(%d) - %d\n", IW_CONFLICT_SSID_EVENT_FLAG + k, SpoofedFrameCount[k])); */
+ }
+ }
+ }
+
+}
+#endif /* SYSTEM_LOG_SUPPORT */
+
+VOID RTMPClearAllIdsCounter(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+
+ pAd->ApCfg.RcvdAuthCount = 0;
+ pAd->ApCfg.RcvdAssocReqCount = 0;
+ pAd->ApCfg.RcvdReassocReqCount = 0;
+ pAd->ApCfg.RcvdProbeReqCount = 0;
+ pAd->ApCfg.RcvdDisassocCount = 0;
+ pAd->ApCfg.RcvdDeauthCount = 0;
+ pAd->ApCfg.RcvdEapReqCount = 0;
+
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ pAd->ApCfg.MBSSID[i].RcvdConflictSsidCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedAssocRespCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedReassocRespCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedProbeRespCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedBeaconCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedDisassocCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedAuthCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedDeauthCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedUnknownMgmtCount = 0;
+ pAd->ApCfg.MBSSID[i].RcvdReplayAttackCount = 0;
+
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdConflictSsid = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAssocResp = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedReassocResp = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedProbeResp = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedBeacon = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDisassoc = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAuth = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDeauth = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedUnknownMgmt = 0;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdReplayAttack = 0;
+
+ }
+}
+
+VOID RTMPIdsPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ pAd->ApCfg.IDSTimerRunning = FALSE;
+
+#ifdef SYSTEM_LOG_SUPPORT
+ /* when IDS occured, send out wireless event */
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPHandleIdsEvent(pAd);
+#endif /* SYSTEM_LOG_SUPPORT */
+
+ /* clear all IDS counter */
+ RTMPClearAllIdsCounter(pAd);
+
+ /* set timer */
+ if (pAd->ApCfg.IdsEnable)
+ {
+ RTMPSetTimer(&pAd->ApCfg.IDSTimer, IDS_EXEC_INTV);
+ pAd->ApCfg.IDSTimerRunning = TRUE;
+ }
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ This routine is used to check if a rogue AP sent an 802.11 management
+ frame to a client using our BSSID.
+
+ Arguments:
+ pAd - Pointer to our adapter
+ pHeader - Pointer to 802.11 header
+
+ Return Value:
+ TRUE - This is a spoofed frame
+ FALSE - This isn't a spoofed frame
+
+ ========================================================================
+*/
+BOOLEAN RTMPSpoofedMgmtDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2,
+ IN UCHAR AntSel)
+{
+ INT i;
+
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ /* Spoofed BSSID detection */
+ if (NdisEqualMemory(pHeader->Addr2, pAd->ApCfg.MBSSID[i].Bssid, MAC_ADDR_LEN))
+ {
+ CHAR RcvdRssi;
+
+ RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0, AntSel, BW_20), ConvertToRssi(pAd, Rssi1, RSSI_1, AntSel, BW_20), ConvertToRssi(pAd, Rssi2, RSSI_2, AntSel, BW_20));
+
+ switch (pHeader->FC.SubType)
+ {
+ case SUBTYPE_ASSOC_RSP:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedAssocRespCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAssocResp = RcvdRssi;
+ break;
+
+ case SUBTYPE_REASSOC_RSP:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedReassocRespCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedReassocResp = RcvdRssi;
+ break;
+
+ case SUBTYPE_PROBE_RSP:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedProbeRespCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedProbeResp = RcvdRssi;
+ break;
+
+ case SUBTYPE_BEACON:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedBeaconCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedBeacon = RcvdRssi;
+ break;
+
+ case SUBTYPE_DISASSOC:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedDisassocCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDisassoc = RcvdRssi;
+ break;
+
+ case SUBTYPE_AUTH:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedAuthCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAuth = RcvdRssi;
+ break;
+
+ case SUBTYPE_DEAUTH:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedDeauthCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDeauth = RcvdRssi;
+ break;
+
+ default:
+ pAd->ApCfg.MBSSID[i].RcvdSpoofedUnknownMgmtCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedUnknownMgmt = RcvdRssi;
+ break;
+
+ }
+
+ return TRUE;
+
+ }
+
+ }
+
+ return FALSE;
+}
+
+
+VOID RTMPConflictSsidDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2,
+ IN UCHAR AntSel)
+{
+ INT i;
+
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ /* Conflict SSID detection */
+ if (SSID_EQUAL(pSsid, SsidLen, pAd->ApCfg.MBSSID[i].Ssid, pAd->ApCfg.MBSSID[i].SsidLen))
+ {
+ CHAR RcvdRssi;
+
+ RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0, AntSel, BW_20), ConvertToRssi(pAd, Rssi1, RSSI_1, AntSel, BW_20), ConvertToRssi(pAd, Rssi2, RSSI_2, AntSel, BW_20));
+
+ pAd->ApCfg.MBSSID[i].RcvdConflictSsidCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdConflictSsid = RcvdRssi;
+ return;
+ }
+ }
+}
+
+BOOLEAN RTMPReplayAttackDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2,
+ IN UCHAR AntSel,
+ IN UCHAR BW)
+{
+ INT i;
+
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ /* Conflict SSID detection */
+ if (NdisEqualMemory(pAddr2, pAd->ApCfg.MBSSID[i].Bssid, MAC_ADDR_LEN))
+ {
+ CHAR RcvdRssi;
+
+ RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0, AntSel, BW), ConvertToRssi(pAd, Rssi1, RSSI_1, AntSel, BW), ConvertToRssi(pAd, Rssi2, RSSI_2, AntSel, BW));
+
+ pAd->ApCfg.MBSSID[i].RcvdReplayAttackCount ++;
+ pAd->ApCfg.MBSSID[i].RssiOfRcvdReplayAttack = RcvdRssi;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+VOID RTMPUpdateStaMgmtCounter(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT type)
+{
+
+ switch (type)
+ {
+ case SUBTYPE_ASSOC_REQ:
+ pAd->ApCfg.RcvdAssocReqCount ++;
+ /*DBGPRINT(RT_DEBUG_TRACE, ("RcvdAssocReqCount=%d\n", pAd->ApCfg.RcvdAssocReqCount)); */
+ break;
+
+ case SUBTYPE_REASSOC_REQ:
+ pAd->ApCfg.RcvdReassocReqCount ++;
+ /*DBGPRINT(RT_DEBUG_TRACE, ("RcvdReassocReqCount=%d\n", pAd->ApCfg.RcvdReassocReqCount)); */
+ break;
+
+ case SUBTYPE_PROBE_REQ:
+ pAd->ApCfg.RcvdProbeReqCount ++;
+ /*DBGPRINT(RT_DEBUG_TRACE, ("RcvdProbeReqCount=%d\n", pAd->ApCfg.RcvdProbeReqCount)); */
+ break;
+
+ case SUBTYPE_DISASSOC:
+ pAd->ApCfg.RcvdDisassocCount ++;
+ /*DBGPRINT(RT_DEBUG_TRACE, ("RcvdDisassocCount=%d\n", pAd->ApCfg.RcvdDisassocCount)); */
+ break;
+
+ case SUBTYPE_DEAUTH:
+ pAd->ApCfg.RcvdDeauthCount ++;
+ /*DBGPRINT(RT_DEBUG_TRACE, ("RcvdDeauthCount=%d\n", pAd->ApCfg.RcvdDeauthCount)); */
+ break;
+
+ case SUBTYPE_AUTH:
+ pAd->ApCfg.RcvdAuthCount ++;
+ /*DBGPRINT(RT_DEBUG_TRACE, ("RcvdAuthCount=%d\n", pAd->ApCfg.RcvdAuthCount)); */
+ break;
+
+ }
+
+}
+
+VOID rtmp_read_ids_from_file(
+ IN PRTMP_ADAPTER pAd,
+ PSTRING tmpbuf,
+ PSTRING buffer)
+{
+ /*IdsEnable */
+ if(RTMPGetKeyParameter("IdsEnable", tmpbuf, 10, buffer, TRUE))
+ {
+ if (simple_strtol(tmpbuf, 0, 10) == 1)
+ pAd->ApCfg.IdsEnable = TRUE;
+ else
+ pAd->ApCfg.IdsEnable = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IDS is %s\n", pAd->ApCfg.IdsEnable ? "enabled" : "disabled"));
+ }
+
+ /*AuthFloodThreshold */
+ if(RTMPGetKeyParameter("AuthFloodThreshold", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.AuthFloodThreshold = simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AuthFloodThreshold = %d\n", pAd->ApCfg.AuthFloodThreshold));
+ }
+
+ /*AssocReqFloodThreshold */
+ if(RTMPGetKeyParameter("AssocReqFloodThreshold", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.AssocReqFloodThreshold = simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocReqFloodThreshold = %d\n", pAd->ApCfg.AssocReqFloodThreshold));
+ }
+
+ /*ReassocReqFloodThreshold */
+ if(RTMPGetKeyParameter("ReassocReqFloodThreshold", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.ReassocReqFloodThreshold = simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ReassocReqFloodThreshold = %d\n", pAd->ApCfg.ReassocReqFloodThreshold));
+ }
+
+ /*ProbeReqFloodThreshold */
+ if(RTMPGetKeyParameter("ProbeReqFloodThreshold", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.ProbeReqFloodThreshold = simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ProbeReqFloodThreshold = %d\n", pAd->ApCfg.ProbeReqFloodThreshold));
+ }
+
+ /*DisassocFloodThreshold */
+ if(RTMPGetKeyParameter("DisassocFloodThreshold", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.DisassocFloodThreshold = simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DisassocFloodThreshold = %d\n", pAd->ApCfg.DisassocFloodThreshold));
+ }
+
+ /*DeauthFloodThreshold */
+ if(RTMPGetKeyParameter("DeauthFloodThreshold", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.DeauthFloodThreshold = simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DeauthFloodThreshold = %d\n", pAd->ApCfg.DeauthFloodThreshold));
+ }
+
+ /*EapReqFloodThreshold */
+ if(RTMPGetKeyParameter("EapReqFloodThreshold", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.EapReqFloodThreshold = simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("EapReqFloodThreshold = %d\n", pAd->ApCfg.EapReqFloodThreshold));
+ }
+}
+
+#endif /* IDS_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_mbss.c b/cleopatre/devkit/mt7601udrv/ap/ap_mbss.c
new file mode 100644
index 0000000000..0ec7ca5de0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_mbss.c
@@ -0,0 +1,378 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ Support multi-BSS function.
+
+ Note:
+ 1. Call RT28xx_MBSS_Init() in init function and
+ call RT28xx_MBSS_Remove() in close function
+
+ 2. MAC of different BSS is initialized in APStartUp()
+
+ 3. BSS Index (0 ~ 15) of different rx packet is got in
+ APHandleRxDoneInterrupt() by using FromWhichBSSID = pEntry->apidx;
+ Or FromWhichBSSID = BSS0;
+
+ 4. BSS Index (0 ~ 15) of different tx packet is assigned in
+ MBSS_VirtualIF_PacketSend() by using RTMP_SET_PACKET_NET_DEVICE_MBSSID()
+ 5. BSS Index (0 ~ 15) of different BSS is got in APHardTransmit() by using
+ RTMP_GET_PACKET_IF()
+
+ 6. BSS Index (0 ~ 15) of IOCTL command is put in pAd->OS_Cookie->ioctl_if
+
+ 7. Beacon of different BSS is enabled in APMakeAllBssBeacon() by writing 1
+ to the register MAC_BSSID_DW1
+
+ 8. The number of MBSS can be 1, 2, 4, or 8
+
+***************************************************************************/
+#ifdef MBSS_SUPPORT
+
+#define MODULE_MBSS
+#include "rt_config.h"
+
+
+/* --------------------------------- Public -------------------------------- */
+/*
+========================================================================
+Routine Description:
+ Initialize Multi-BSS function.
+
+Arguments:
+ pAd points to our adapter
+ pDevMain points to the main BSS network interface
+
+Return Value:
+ None
+
+Note:
+ 1. Only create and initialize virtual network interfaces.
+ 2. No main network interface here.
+ 3. If you down ra0 and modify the BssNum of RT2860AP.dat/RT2870AP.dat,
+ it will not work! You must rmmod rt2860ap.ko and lsmod rt2860ap.ko again.
+========================================================================
+*/
+
+extern void RtmpOSNetDevProtect(
+ IN BOOLEAN lock_it);
+
+VOID MBSS_Init(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_OS_NETDEV_OP_HOOK *pNetDevOps)
+{
+#define MBSS_MAX_DEV_NUM 32
+ PNET_DEV pDevNew;
+ INT32 IdBss, MaxNumBss;
+ INT status;
+ RTMP_OS_NETDEV_OP_HOOK netDevHook;
+
+ /* sanity check to avoid redundant virtual interfaces are created */
+ if (pAd->FlgMbssInit != FALSE)
+ return;
+
+
+ /* init */
+ MaxNumBss = pAd->ApCfg.BssidNum;
+ if (MaxNumBss > MAX_MBSSID_NUM(pAd))
+ MaxNumBss = MAX_MBSSID_NUM(pAd);
+
+
+ /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */
+ for(IdBss=FIRST_MBSSID; IdBss<MAX_MBSSID_NUM(pAd); IdBss++)
+ pAd->ApCfg.MBSSID[IdBss].MSSIDDev = NULL;
+
+ /* create virtual network interface */
+ for(IdBss=FIRST_MBSSID; IdBss<MaxNumBss; IdBss++)
+ {
+ UINT32 MC_RowID = 0, IoctlIF = 0;
+#ifdef MULTIPLE_CARD_SUPPORT
+ MC_RowID = pAd->MC_RowID;
+#endif /* MULTIPLE_CARD_SUPPORT */
+#ifdef HOSTAPD_SUPPORT
+ IoctlIF = pAd->IoctlIF;
+#endif /* HOSTAPD_SUPPORT */
+ pDevNew = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_MBSSID, IdBss, sizeof(PRTMP_ADAPTER), INF_MBSSID_DEV_NAME);
+#ifdef HOSTAPD_SUPPORT
+ pAd->IoctlIF = IoctlIF;
+#endif /* HOSTAPD_SUPPORT */
+ if (pDevNew == NULL)
+ {
+ /* allocation fail, exit */
+ pAd->ApCfg.BssidNum = IdBss; /* re-assign new MBSS number */
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("Allocate network device fail (MBSS)...\n"));
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Register MBSSID IF (%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pDevNew)));
+ }
+
+ RTMP_OS_NETDEV_SET_PRIV(pDevNew, pAd);
+
+ /* init operation functions and flags */
+ NdisCopyMemory(&netDevHook, pNetDevOps, sizeof(netDevHook));
+
+ netDevHook.priv_flags = INT_MBSSID; /* We are virtual interface */
+ netDevHook.needProtcted = TRUE;
+
+ /* Init MAC address of virtual network interface */
+ NdisMoveMemory(&netDevHook.devAddr[0], &pAd->ApCfg.MBSSID[IdBss].Bssid[0], MAC_ADDR_LEN);
+
+ /* backup our virtual network interface */
+ pAd->ApCfg.MBSSID[IdBss].MSSIDDev = pDevNew;
+
+ /* register this device to OS */
+ status = RtmpOSNetDevAttach(pAd->OpMode, pDevNew, &netDevHook);
+
+ }
+
+ pAd->FlgMbssInit = TRUE;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Remove Multi-BSS network interface.
+
+Arguments:
+ pAd points to our adapter
+
+Return Value:
+ None
+
+Note:
+ FIRST_MBSSID = 1
+ Main BSS is not removed here.
+========================================================================
+*/
+VOID MBSS_Remove(
+ IN PRTMP_ADAPTER pAd)
+{
+ MULTISSID_STRUCT *pMbss;
+ UINT IdBss;
+
+
+
+ for(IdBss=FIRST_MBSSID; IdBss<MAX_MBSSID_NUM(pAd); IdBss++)
+ {
+ pMbss = &pAd->ApCfg.MBSSID[IdBss];
+ RtmpOSNetDevProtect(1);
+ if (pMbss->MSSIDDev)
+ {
+ RtmpOSNetDevDetach(pMbss->MSSIDDev);
+ RtmpOSNetDevProtect(0);
+ RtmpOSNetDevFree(pMbss->MSSIDDev);
+
+ RtmpOSNetDevProtect(1);
+ /* clear it as NULL to prevent latter access error */
+ pMbss->MSSIDDev = NULL;
+ }
+ RtmpOSNetDevProtect(0);
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Get multiple bss idx.
+
+Arguments:
+ pAd points to our adapter
+ pDev which WLAN network interface
+
+Return Value:
+ 0: close successfully
+ otherwise: close fail
+
+Note:
+========================================================================
+*/
+INT32 RT28xx_MBSS_IdxGet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV pDev)
+{
+ INT32 BssId = -1;
+ INT32 IdBss;
+
+
+ for(IdBss=0; IdBss<pAd->ApCfg.BssidNum; IdBss++)
+ {
+ if (pAd->ApCfg.MBSSID[IdBss].MSSIDDev == pDev)
+ {
+ BssId = IdBss;
+ break;
+ }
+ }
+
+ return BssId;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Open a virtual network interface.
+
+Arguments:
+ pDev which WLAN network interface
+
+Return Value:
+ 0: open successfully
+ otherwise: open fail
+
+Note:
+========================================================================
+*/
+INT MBSS_Open(
+ IN PNET_DEV pDev)
+{
+ PRTMP_ADAPTER pAd;
+ INT BssId;
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
+ BssId = RT28xx_MBSS_IdxGet(pAd, pDev);
+ if (BssId < 0)
+ return -1;
+
+ pAd->ApCfg.MBSSID[BssId].bBcnSntReq = TRUE;
+ return 0;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Close a virtual network interface.
+
+Arguments:
+ pDev which WLAN network interface
+
+Return Value:
+ 0: close successfully
+ otherwise: close fail
+
+Note:
+========================================================================
+*/
+INT MBSS_Close(
+ IN PNET_DEV pDev)
+{
+ PRTMP_ADAPTER pAd;
+ INT BssId;
+
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
+ BssId = RT28xx_MBSS_IdxGet(pAd, pDev);
+ if (BssId < 0)
+ return -1;
+
+ RTMP_OS_NETDEV_STOP_QUEUE(pDev);
+
+ /* kick out all stas behind the Bss */
+ MbssKickOutStas(pAd, BssId, REASON_DISASSOC_INACTIVE);
+
+ pAd->ApCfg.MBSSID[BssId].bBcnSntReq = FALSE;
+
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+
+ return 0;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Send a packet to WLAN.
+
+Arguments:
+ pPktSrc points to our adapter
+ pDev which WLAN network interface
+
+Return Value:
+ 0: transmit successfully
+ otherwise: transmit fail
+
+Note:
+========================================================================
+*/
+int MBSS_PacketSend(
+ IN PNDIS_PACKET pPktSrc,
+ IN PNET_DEV pDev,
+ IN RTMP_NET_PACKET_TRANSMIT Func)
+{
+ RTMP_ADAPTER *pAd;
+ MULTISSID_STRUCT *pMbss;
+ PNDIS_PACKET pPkt = (PNDIS_PACKET)pPktSrc;
+ INT IdBss;
+
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
+ ASSERT(pAd);
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPkt, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+#endif /* RALINK_ATE */
+
+ if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
+ {
+ /* wlan is scanning/disabled/reset */
+ RELEASE_NDIS_PACKET(pAd, pPkt, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+
+ /* 0 is main BSS, dont handle it here */
+ /* FIRST_MBSSID = 1 */
+ pMbss = pAd->ApCfg.MBSSID;
+
+ for(IdBss=FIRST_MBSSID; IdBss<pAd->ApCfg.BssidNum; IdBss++)
+ {
+ /* find the device in our MBSS list */
+ if (pMbss[IdBss].MSSIDDev == pDev)
+ {
+/* NdisZeroMemory((PUCHAR)&(RTPKT_TO_OSPKT(pPktSrc))->cb[CB_OFF], 15); */
+ NdisZeroMemory((PUCHAR)(GET_OS_PKT_CB(pPktSrc) + CB_OFF), 15);
+ RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPktSrc, IdBss);
+/* SET_OS_PKT_NETDEV(pPktSrc, pDev); */
+
+
+ /* transmit the packet */
+ return Func(pPktSrc);
+ }
+ }
+
+ /* can not find the BSS so discard the packet */
+ RELEASE_NDIS_PACKET(pAd, pPkt, NDIS_STATUS_FAILURE);
+
+ return 0;
+}
+
+
+#endif /* MBSS_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_mbss_inf.c b/cleopatre/devkit/mt7601udrv/ap/ap_mbss_inf.c
new file mode 100644
index 0000000000..1d158dde15
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_mbss_inf.c
@@ -0,0 +1,273 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ Support multi-BSS function.
+
+ Note:
+ 1. Call RT28xx_MBSS_Init() in init function and
+ call RT28xx_MBSS_Remove() in close function
+
+ 2. MAC of different BSS is initialized in APStartUp()
+
+ 3. BSS Index (0 ~ 15) of different rx packet is got in
+ APHandleRxDoneInterrupt() by using FromWhichBSSID = pEntry->apidx;
+ Or FromWhichBSSID = BSS0;
+
+ 4. BSS Index (0 ~ 15) of different tx packet is assigned in
+ MBSS_VirtualIF_PacketSend() by using RTMP_SET_PACKET_NET_DEVICE_MBSSID()
+ 5. BSS Index (0 ~ 15) of different BSS is got in APHardTransmit() by using
+ RTMP_GET_PACKET_IF()
+
+ 6. BSS Index (0 ~ 15) of IOCTL command is put in pAd->OS_Cookie->ioctl_if
+
+ 7. Beacon of different BSS is enabled in APMakeAllBssBeacon() by writing 1
+ to the register MAC_BSSID_DW1
+
+ 8. The number of MBSS can be 1, 2, 4, or 8
+
+***************************************************************************/
+#define RTMP_MODULE_OS
+
+#ifdef MBSS_SUPPORT
+
+#define MODULE_MBSS
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rt_os_net.h"
+
+
+/* --------------------------------- Public -------------------------------- */
+NET_DEV_STATS *RT28xx_get_ether_stats(
+ IN PNET_DEV net_dev);
+
+/*
+========================================================================
+Routine Description:
+ Initialize Multi-BSS function.
+
+Arguments:
+ pAd points to our adapter
+ pDevMain points to the main BSS network interface
+
+Return Value:
+ None
+
+Note:
+ 1. Only create and initialize virtual network interfaces.
+ 2. No main network interface here.
+ 3. If you down ra0 and modify the BssNum of RT2860AP.dat/RT2870AP.dat,
+ it will not work! You must rmmod rt2860ap.ko and lsmod rt2860ap.ko again.
+========================================================================
+*/
+VOID RT28xx_MBSS_Init(
+ IN VOID *pAd,
+ IN PNET_DEV pDevMain)
+{
+ RTMP_OS_NETDEV_OP_HOOK netDevHook;
+
+ NdisZeroMemory(&netDevHook, sizeof(netDevHook));
+ netDevHook.open = MBSS_VirtualIF_Open; /* device opem hook point */
+ netDevHook.stop = MBSS_VirtualIF_Close; /* device close hook point */
+ netDevHook.xmit = MBSS_VirtualIF_PacketSend; /* hard transmit hook point */
+ netDevHook.ioctl = MBSS_VirtualIF_Ioctl; /* ioctl hook point */
+ netDevHook.get_stats = RT28xx_get_ether_stats;
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_MBSS_INIT,
+ 0, &netDevHook, 0);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Remove Multi-BSS network interface.
+
+Arguments:
+ pAd points to our adapter
+
+Return Value:
+ None
+
+Note:
+ FIRST_MBSSID = 1
+ Main BSS is not removed here.
+========================================================================
+*/
+VOID RT28xx_MBSS_Remove(
+ IN VOID *pAd)
+{
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_MBSS_REMOVE, 0, NULL, 0);
+
+}
+
+
+
+/* --------------------------------- Private -------------------------------- */
+/*
+========================================================================
+Routine Description:
+ Open a virtual network interface.
+
+Arguments:
+ pDev which WLAN network interface
+
+Return Value:
+ 0: open successfully
+ otherwise: open fail
+
+Note:
+========================================================================
+*/
+INT MBSS_VirtualIF_Open(
+ IN PNET_DEV pDev)
+{
+ VOID *pAd;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: ===> MBSSVirtualIF_open\n", RTMP_OS_NETDEV_GET_DEVNAME(pDev)));
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_MBSS_OPEN, 0, pDev, 0);
+
+ if (VIRTUAL_IF_UP(pAd) != 0)
+ return -1;
+
+ /* increase MODULE use count */
+ RT_MOD_INC_USE_COUNT();
+
+ RTMP_OS_NETDEV_START_QUEUE(pDev);
+
+ return 0;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Close a virtual network interface.
+
+Arguments:
+ pDev which WLAN network interface
+
+Return Value:
+ 0: close successfully
+ otherwise: close fail
+
+Note:
+========================================================================
+*/
+INT MBSS_VirtualIF_Close(
+ IN PNET_DEV pDev)
+{
+ VOID *pAd;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: ===> MBSSVirtualIF_close\n", RTMP_OS_NETDEV_GET_DEVNAME(pDev)));
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
+
+ RTMP_OS_NETDEV_STOP_QUEUE(pDev);
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_MBSS_CLOSE, 0, pDev, 0);
+
+ VIRTUAL_IF_DOWN(pAd);
+
+ RT_MOD_DEC_USE_COUNT();
+ return 0;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Send a packet to WLAN.
+
+Arguments:
+ pPktSrc points to our adapter
+ pDev which WLAN network interface
+
+Return Value:
+ 0: transmit successfully
+ otherwise: transmit fail
+
+Note:
+========================================================================
+*/
+INT MBSS_VirtualIF_PacketSend(
+ IN PNDIS_PACKET pPktSrc,
+ IN PNET_DEV pDev)
+{
+
+ MEM_DBG_PKT_ALLOC_INC(pPktSrc);
+
+ if(!(RTMP_OS_NETDEV_STATE_RUNNING(pDev)))
+ {
+ /* the interface is down */
+ RELEASE_NDIS_PACKET(NULL, pPktSrc, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+ return MBSS_PacketSend(pPktSrc, pDev, rt28xx_packet_xmit);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ IOCTL to WLAN.
+
+Arguments:
+ pDev which WLAN network interface
+ pIoCtrl command information
+ Command command ID
+
+Return Value:
+ 0: IOCTL successfully
+ otherwise: IOCTL fail
+
+Note:
+ SIOCETHTOOL 8946 New drivers use this ETHTOOL interface to
+ report link failure activity.
+========================================================================
+*/
+INT MBSS_VirtualIF_Ioctl(
+ IN PNET_DEV pDev,
+ IN OUT VOID *pIoCtrl,
+ IN INT Command)
+{
+ VOID *pAd;
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(pDev);
+ ASSERT(pAd);
+
+ if (!pAd)
+ return -EINVAL;
+
+/* if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */
+ if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) != NDIS_STATUS_SUCCESS)
+ return -ENETDOWN;
+
+ return rt28xx_ioctl(pDev, pIoCtrl, Command);
+}
+
+#endif /* MBSS_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_mlme.c b/cleopatre/devkit/mt7601udrv/ap/ap_mlme.c
new file mode 100644
index 0000000000..811ed3078b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_mlme.c
@@ -0,0 +1,592 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ mlme.c
+
+ Abstract:
+ Major MLME state machiones here
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 08-04-2003 created for 11g soft-AP
+ */
+
+#include "rt_config.h"
+#include <stdarg.h>
+
+
+#ifdef DOT11_N_SUPPORT
+
+int DetectOverlappingPeriodicRound;
+
+
+#ifdef DOT11N_DRAFT3
+VOID Bss2040CoexistTimeOut(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ int apidx;
+ PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Bss2040CoexistTimeOut(): Recovery to original setting!\n"));
+
+ /* Recovery to original setting when next DTIM Interval. */
+ pAd->CommonCfg.Bss2040CoexistFlag &= (~BSS_2040_COEXIST_TIMER_FIRED);
+ NdisZeroMemory(&pAd->CommonCfg.LastBSSCoexist2040, sizeof(BSS_2040_COEXIST_IE));
+ pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC;
+
+ if (pAd->CommonCfg.bBssCoexEnable == FALSE)
+ {
+ /* TODO: Find a better way to handle this when the timer is fired and we disable the bBssCoexEable support!! */
+ DBGPRINT(RT_DEBUG_TRACE, ("Bss2040CoexistTimeOut(): bBssCoexEnable is FALSE, return directly!\n"));
+ return;
+ }
+
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ SendBSS2040CoexistMgmtAction(pAd, MCAST_WCID, apidx, 0);
+
+}
+#endif /* DOT11N_DRAFT3 */
+
+#endif /* DOT11_N_SUPPORT */
+
+
+VOID APDetectOverlappingExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+#ifdef DOT11_N_SUPPORT
+ PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ if (DetectOverlappingPeriodicRound == 0)
+ {
+ /* switch back 20/40 */
+ if ((pAd->CommonCfg.Channel <=14) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+ }
+ }
+ else
+ {
+ if ((DetectOverlappingPeriodicRound == 25) || (DetectOverlappingPeriodicRound == 1))
+ {
+ if ((pAd->CommonCfg.Channel <=14) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth==BW_40))
+ {
+ SendBeaconRequest(pAd, 1);
+ SendBeaconRequest(pAd, 2);
+ SendBeaconRequest(pAd, 3);
+ }
+
+ }
+ DetectOverlappingPeriodicRound--;
+ }
+#endif /* DOT11_N_SUPPORT */
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ This routine is executed every second -
+ 1. Decide the overall channel quality
+ 2. Check if need to upgrade the TX rate to any client
+ 3. perform MAC table maintenance, including ageout no-traffic clients,
+ and release packet buffer in PSQ is fail to TX in time.
+ ==========================================================================
+ */
+VOID APMlmePeriodicExec(
+ PRTMP_ADAPTER pAd)
+{
+ /*
+ Reqeust by David 2005/05/12
+ It make sense to disable Adjust Tx Power on AP mode, since we can't
+ take care all of the client's situation
+ ToDo: need to verify compatibility issue with WiFi product.
+ */
+#ifdef CARRIER_DETECTION_SUPPORT
+ if (isCarrierDetectExist(pAd) == TRUE)
+ {
+ PCARRIER_DETECTION_STRUCT pCarrierDetect = &pAd->CommonCfg.CarrierDetect;
+ if (pCarrierDetect->OneSecIntCount < pCarrierDetect->CarrierGoneThreshold)
+ {
+ pCarrierDetect->CD_State = CD_NORMAL;
+ pCarrierDetect->recheck = pCarrierDetect->recheck1;
+ if (pCarrierDetect->Debug != RT_DEBUG_TRACE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Carrier gone\n"));
+ /* start all TX actions. */
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+ AsicEnableBssSync(pAd);
+ }
+ else
+ {
+ printk("Carrier gone\n");
+ }
+ }
+ pCarrierDetect->OneSecIntCount = 0;
+ }
+
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+ RTMP_CHIP_HIGH_POWER_TUNING(pAd, &pAd->ApCfg.RssiSample);
+
+
+ /* Disable Adjust Tx Power for WPA WiFi-test. */
+ /* Because high TX power results in the abnormal disconnection of Intel BG-STA. */
+/*#ifndef WIFI_TEST */
+/* if (pAd->CommonCfg.bWiFiTest == FALSE) */
+ /* for SmartBit 64-byte stream test */
+ /* removed based on the decision of Ralink congress at 2011/7/06 */
+/* if (pAd->MacTab.Size > 0) */
+ AsicAdjustTxPower(pAd);
+/*#endif // WIFI_TEST */
+
+ RTMP_CHIP_ASIC_TEMPERATURE_COMPENSATION(pAd);
+
+ /* BBP TUNING: dynamic tune BBP R66 to find a balance between sensibility
+ and noise isolation */
+/* AsicBbpTuning2(pAd); */
+
+ /* walk through MAC table, see if switching TX rate is required */
+
+ /* MAC table maintenance */
+ if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0)
+ {
+ /* one second timer */
+ MacTableMaintenance(pAd);
+ RTMPMaintainPMKIDCache(pAd);
+
+#ifdef WDS_SUPPORT
+ WdsTableMaintenance(pAd);
+#endif /* WDS_SUPPORT */
+
+
+#ifdef CLIENT_WDS
+ CliWds_ProxyTabMaintain(pAd);
+#endif /* CLIENT_WDS */
+ }
+
+ APUpdateCapabilityAndErpIe(pAd);
+
+#ifdef APCLI_SUPPORT
+ if (pAd->Mlme.OneSecPeriodicRound % 2 == 0)
+ ApCliIfMonitor(pAd);
+
+ if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
+ ApCliIfUp(pAd);
+
+ {
+ INT loop;
+ ULONG Now32;
+ NdisGetSystemUpTime(&Now32);
+ for (loop = 0; loop < MAX_APCLI_NUM; loop++)
+ {
+ PAPCLI_STRUCT pApCliEntry = &pAd->ApCfg.ApCliTab[loop];
+ if ((pApCliEntry->Valid == TRUE)
+ && (pApCliEntry->MacTabWCID < MAX_LEN_OF_MAC_TABLE))
+ {
+ /* update channel quality for Roaming and UI LinkQuality display */
+ MlmeCalculateChannelQuality(pAd,
+ &pAd->MacTab.Content[pApCliEntry->MacTabWCID], Now32);
+ }
+ }
+ }
+#endif /* APCLI_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.bHTProtect)
+ {
+ /*APUpdateCapabilityAndErpIe(pAd); */
+ APUpdateOperationMode(pAd);
+ if (pAd->CommonCfg.IOTestParm.bRTSLongProtOn == FALSE)
+ {
+ AsicUpdateProtect(pAd, (USHORT)pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, pAd->MacTab.fAnyStationNonGF);
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef A_BAND_SUPPORT
+ if ( (pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ )
+ {
+#ifdef DFS_SUPPORT
+ ApRadarDetectPeriodic(pAd);
+#else
+ pAd->Dot11_H.InServiceMonitorCount++;
+ if (pAd->Dot11_H.RDMode == RD_SILENCE_MODE)
+ {
+ if (pAd->Dot11_H.RDCount++ > pAd->Dot11_H.ChMovingTime)
+ {
+ AsicEnableBssSync(pAd);
+ pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
+ }
+ }
+#endif /* !DFS_SUPPORT */
+ }
+#endif /* A_BAND_SUPPORT */
+
+
+}
+
+
+/*! \brief To substitute the message type if the message is coming from external
+ * \param *Fr 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
+ */
+BOOLEAN APMsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType)
+{
+ USHORT Seq;
+ UCHAR EAPType;
+ BOOLEAN Return = FALSE;
+#ifdef WSC_AP_SUPPORT
+ UCHAR EAPCode;
+ PMAC_TABLE_ENTRY pEntry;
+#endif /* WSC_AP_SUPPORT */
+
+/*
+ TODO:
+ only PROBE_REQ can be broadcast, all others must be unicast-to-me && is_mybssid; otherwise,
+ ignore this frame
+*/
+
+ /* wpa EAPOL PACKET */
+ if (pFrame->Hdr.FC.Type == BTYPE_DATA)
+ {
+#ifdef WSC_AP_SUPPORT
+ /*WSC EAPOL PACKET */
+ pEntry = MacTableLookup(pAd, pFrame->Hdr.Addr2);
+ if (pEntry &&
+ ((pEntry->bWscCapable) ||
+ (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode < Ndis802_11AuthModeWPA)))
+ {
+ if ((MAC_ADDR_EQUAL(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, pEntry->Addr) ||
+ MAC_ADDR_EQUAL(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, ZERO_MAC_ADDR)) &&
+ IS_ENTRY_CLIENT(pEntry) &&
+ (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscConfMode != WSC_DISABLE))
+ {
+ *Machine = WSC_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ EAPCode = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 4);
+ Return = WscMsgTypeSubst(EAPType, EAPCode, MsgType);
+ }
+ }
+#endif /* WSC_AP_SUPPORT */
+ if (!Return)
+ {
+ *Machine = WPA_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ Return = WpaMsgTypeSubst(EAPType, (INT *) MsgType);
+ }
+ return Return;
+ }
+
+ if (pFrame->Hdr.FC.Type != BTYPE_MGMT)
+ return FALSE;
+
+ switch (pFrame->Hdr.FC.SubType)
+ {
+ case SUBTYPE_ASSOC_REQ:
+ *Machine = AP_ASSOC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_ASSOC_REQ;
+
+ break;
+/*
+ case SUBTYPE_ASSOC_RSP:
+ *Machine = AP_ASSOC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_ASSOC_RSP;
+ break;
+*/
+ case SUBTYPE_REASSOC_REQ:
+ *Machine = AP_ASSOC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_REASSOC_REQ;
+ break;
+/*
+ case SUBTYPE_REASSOC_RSP:
+ *Machine = AP_ASSOC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_REASSOC_RSP;
+ break;
+*/
+ case SUBTYPE_PROBE_REQ:
+ *Machine = AP_SYNC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_PROBE_REQ;
+ break;
+/* test for 40Mhz intolerant */
+ /*
+ For Active Scan
+ */
+ case SUBTYPE_PROBE_RSP:
+ *Machine = AP_SYNC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_PROBE_RSP;
+ break;
+ case SUBTYPE_BEACON:
+ *Machine = AP_SYNC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_BEACON;
+ break;
+/*
+ case SUBTYPE_ATIM:
+ *Machine = AP_SYNC_STATE_MACHINE;
+ *MsgType = APMT2_PEER_ATIM;
+ break;
+*/
+ case SUBTYPE_DISASSOC:
+ *Machine = AP_ASSOC_STATE_MACHINE;
+ *MsgType = APMT2_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));
+
+ *Machine = AP_AUTH_STATE_MACHINE;
+ if (Seq == 1)
+ *MsgType = APMT2_PEER_AUTH_REQ;
+ else if (Seq == 3)
+ *MsgType = APMT2_PEER_AUTH_CONFIRM;
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("wrong AUTH seq=%d Octet=%02x %02x %02x %02x %02x %02x %02x %02x\n", Seq,
+ pFrame->Octet[0], pFrame->Octet[1], pFrame->Octet[2], pFrame->Octet[3],
+ pFrame->Octet[4], pFrame->Octet[5], pFrame->Octet[6], pFrame->Octet[7]));
+ return FALSE;
+ }
+ break;
+
+ case SUBTYPE_DEAUTH:
+ *Machine = AP_AUTH_STATE_MACHINE; /*AP_AUTH_RSP_STATE_MACHINE;*/
+ *MsgType = APMT2_PEER_DEAUTH;
+ break;
+
+ case SUBTYPE_ACTION:
+ case SUBTYPE_ACTION_NO_ACK:
+ *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;
+}
+
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Periodic evaluate antenna link status
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID APAsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG TxTotalCnt;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+#ifdef CARRIER_DETECTION_SUPPORT
+ if(pAd->CommonCfg.CarrierDetect.CD_State == CD_SILENCE)
+ return;
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#ifdef RT8592
+ // TODO: shiang-6590, for 8592, this EvaaluateRxAnt still need??
+ if (IS_RT8592(pAd))
+ return;
+#endif /* RT8592 */
+
+#ifdef RT65xx //snowpin test
+ if (IS_RT6590(pAd))
+ return;
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ return;
+#endif /* MT7601 */
+
+#ifdef TXBF_SUPPORT
+ /* TODO: we didn't do RxAnt evaluate for 3x3 chips */
+ if (IS_RT3883(pAd) || IS_RT2883(pAd))
+ return;
+#endif /* TXBF_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+ if (pAd->ApCfg.bGreenAPActive == TRUE)
+ rtmp_bbp_set_rxpath(pAd, 1);
+ else
+#endif /* GREENAP_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+ rtmp_bbp_set_rxpath(pAd, pAd->Antenna.field.RxPath);
+
+ TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (TxTotalCnt > 50)
+ {
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
+ pAd->Mlme.bLowThroughput = FALSE;
+ }
+ else
+ {
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
+ pAd->Mlme.bLowThroughput = TRUE;
+ }
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ After evaluation, check antenna link status
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID APAsicRxAntEvalTimeout(
+ PRTMP_ADAPTER pAd)
+{
+ CHAR larger = -127, rssi0, rssi1, rssi2;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+ /* if the traffic is low, use average rssi as the criteria */
+ if (pAd->Mlme.bLowThroughput == TRUE)
+ {
+ rssi0 = pAd->ApCfg.RssiSample.LastRssi0;
+ rssi1 = pAd->ApCfg.RssiSample.LastRssi1;
+ rssi2 = pAd->ApCfg.RssiSample.LastRssi2;
+ }
+ else
+ {
+ rssi0 = pAd->ApCfg.RssiSample.AvgRssi0;
+ rssi1 = pAd->ApCfg.RssiSample.AvgRssi1;
+ rssi2 = pAd->ApCfg.RssiSample.AvgRssi2;
+ }
+
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ larger = max(rssi0, rssi1);
+#ifdef DOT11N_SS3_SUPPORT
+ if (pAd->CommonCfg.RxStream >= 3)
+ pAd->Mlme.RealRxPath = 3;
+ else
+#endif /* DOT11N_SS3_SUPPORT */
+ {
+ if (larger > (rssi2 + 20))
+ pAd->Mlme.RealRxPath = 2;
+ else
+ pAd->Mlme.RealRxPath = 3;
+ }
+ }
+ /* Disable the below to fix 1T/2R issue. It's suggested by Rory at 2007/7/11. */
+
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+ if (pAd->ApCfg.bGreenAPActive == TRUE)
+ rtmp_bbp_set_rxpath(pAd, 1);
+ else
+#endif /* GREENAP_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+ rtmp_bbp_set_rxpath(pAd, pAd->Mlme.RealRxPath);
+
+
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ After evaluation, check antenna link status
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID APAsicAntennaAvg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AntSelect,
+ IN SHORT* RssiAvg)
+{
+ SHORT realavgrssi;
+ LONG realavgrssi1;
+ ULONG recvPktNum = pAd->RxAnt.RcvPktNum[AntSelect];
+
+ realavgrssi1 = pAd->RxAnt.Pair1AvgRssiGroup1[AntSelect];
+
+ if(realavgrssi1 == 0)
+ {
+ *RssiAvg = 0;
+ return;
+ }
+
+ realavgrssi = (SHORT) (realavgrssi1 / recvPktNum);
+
+ pAd->RxAnt.Pair1AvgRssiGroup1[0] = 0;
+ pAd->RxAnt.Pair1AvgRssiGroup1[1] = 0;
+ pAd->RxAnt.Pair1AvgRssiGroup2[0] = 0;
+ pAd->RxAnt.Pair1AvgRssiGroup2[1] = 0;
+ pAd->RxAnt.RcvPktNum[0] = 0;
+ pAd->RxAnt.RcvPktNum[1] = 0;
+ *RssiAvg = realavgrssi - 256;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_qload.c b/cleopatre/devkit/mt7601udrv/ap/ap_qload.c
new file mode 100644
index 0000000000..7e3eaa3639
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_qload.c
@@ -0,0 +1,916 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ Provide information on the current STA population and traffic levels
+ in the QBSS.
+
+ This attribute is available only at a QAP. This attribute, when TRUE,
+ indicates that the QAP implementation is capable of generating and
+ transmitting the QBSS load element in the Beacon and Probe Response frames.
+
+***************************************************************************/
+
+#include "rt_config.h"
+
+#ifdef AP_QLOAD_SUPPORT
+
+typedef struct GNU_PACKED _ELM_QBSS_LOAD{
+
+ UINT8 ElementId;
+ UINT8 Length;
+
+ /* the total number of STAs currently associated with this QBSS */
+ UINT16 StationCount;
+
+ /* defined as the percentage of time, nomalized to 255, the QAP sensed the
+ medium busy, as indicated by either the physical or virtual carrier
+ sense mechanism.
+ This percentage is computed using the formula:
+ ((channel busy time / (dot11ChannelUtilizationBeaconIntervals *
+ dot11BeaconPeriod * 1024)) * 255) */
+ UINT8 ChanUtil;
+
+ /* specifies the remaining amount of medium time available via explicit
+ admission control, in units of 32 microsecond periods per 1 second.
+ The field is helpful for roaming non-AP QSTAs to select a QAP that is
+ likely to accept future admission control requests, but it does not
+ represent a guarantee that the HC will admit these requests. */
+ UINT16 AvalAdmCap;
+
+} ELM_QBSS_LOAD;
+
+#define ELM_QBSS_LOAD_ID 11
+#define ELM_QBSS_LOAD_LEN 5
+
+/*
+ We will send a alarm when channel busy time (primary or secondary) >=
+ Time Threshold and Num Threshold.
+
+ QBSS_LOAD_ALRAM_BUSY_TIME_THRESHOLD = 0 means alarm function is disabled.
+
+ If you want to enable it, use command
+ "iwpriv ra0 set qloadalarmtimethres=90"
+*/
+#define QBSS_LOAD_ALRAM_BUSY_TIME_THRESHOLD 0 /* unit: % */
+#define QBSS_LOAD_ALRAM_BUSY_NUM_THRESHOLD 10 /* unit: 1 */
+
+/* a alarm will not re-issued until QBSS_LOAD_ALARM_DURATION * TBTT */
+#define QBSS_LOAD_ALARM_DURATION 100 /* unit: TBTT */
+
+
+static VOID QBSS_LoadAlarmSuspend(
+ IN RTMP_ADAPTER *pAd);
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+/* handle a alarm */
+static VOID QBSS_LoadAlarm(
+ IN RTMP_ADAPTER *pAd);
+static VOID QBSS_LoadAlarmBusyTimeThresholdReset(
+ IN RTMP_ADAPTER *pAd,
+ IN UINT32 TimePeriod);
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+
+
+
+/* --------------------------------- Private -------------------------------- */
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+/*
+========================================================================
+Routine Description:
+ Handle a alarm.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+ You can use different methods to handle QBSS Load alarm here.
+
+ Current methods are:
+ 1. Change 20/40 to 20-only.
+ 2. Change channel to the clear channel.
+========================================================================
+*/
+static VOID QBSS_LoadAlarm(
+ IN RTMP_ADAPTER *pAd)
+{
+ /* suspend alarm until channel switch */
+ QBSS_LoadAlarmSuspend(pAd);
+
+ pAd->QloadAlarmNumber ++;
+
+ /* check if we have already been 20M bandwidth */
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if ((pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0))
+ {
+ MAC_TABLE *pMacTable;
+ UINT32 StaId;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Change to 20 bw...\n"));
+
+ /* disassociate stations without D3 2040Coexistence function */
+ pMacTable = &pAd->MacTab;
+
+ for(StaId=1; StaId<MAX_LEN_OF_MAC_TABLE; StaId++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[StaId];
+ BOOLEAN bDisconnectSta = FALSE;
+
+ if (!IS_ENTRY_CLIENT(pEntry))
+ continue;
+
+ if (pEntry->Sst != SST_ASSOC)
+ continue;
+
+ if (pEntry->BSS2040CoexistenceMgmtSupport)
+ bDisconnectSta = TRUE;
+
+ if (bDisconnectSta)
+ {
+ /* send wireless event - for ageout */
+ RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0);
+
+ {
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ HEADER_802_11 DeAuthHdr;
+ USHORT Reason;
+
+ /* send out a DISASSOC request frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n"));
+ /*NdisReleaseSpinLock(&pAd->MacTabLock); */
+ continue;
+ }
+
+ Reason = REASON_DEAUTH_STA_LEAVING;
+ MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0,
+ pEntry->Addr,
+ pAd->ApCfg.MBSSID[pEntry->apidx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DeAuthHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Deauth the station "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pEntry->Addr[0], pEntry->Addr[1],
+ pEntry->Addr[2], pEntry->Addr[3],
+ pEntry->Addr[4], pEntry->Addr[5]));
+
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ continue;
+ }
+ }
+
+ /* for 11n */
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
+
+ /* always 20M */
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+
+ /* mark alarm flag */
+ pAd->FlgQloadAlarm = TRUE;
+
+ QBSS_LoadAlarmResume(pAd);
+ }
+ else
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+ {
+ /* we are in 20MHz bandwidth so try to switch channel */
+ DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Switch channel...\n"));
+
+ /* send command to switch channel */
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_CHAN_RESCAN, NULL, 0);
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Re-calculate busy time threshold.
+
+Arguments:
+ pAd - WLAN control block pointer
+ TimePeriod - TBTT
+
+Return Value:
+ None
+
+Note:
+ EX: TBTT=100ms, 90%, pAd->QloadBusyTimeThreshold = 90ms
+========================================================================
+*/
+static VOID QBSS_LoadAlarmBusyTimeThresholdReset(
+ IN RTMP_ADAPTER *pAd,
+ IN UINT32 TimePeriod)
+{
+ pAd->QloadBusyTimeThreshold = TimePeriod;
+ pAd->QloadBusyTimeThreshold *= pAd->QloadAlarmBusyTimeThreshold;
+ pAd->QloadBusyTimeThreshold /= 100;
+ pAd->QloadBusyTimeThreshold <<= 10; /* translate mini-sec to micro-sec */
+}
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+
+
+
+/* --------------------------------- Public -------------------------------- */
+
+/*
+========================================================================
+Routine Description:
+ Initialize ASIC Channel Busy Calculation mechanism.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+ Init Condition: WMM must be enabled.
+========================================================================
+*/
+VOID QBSS_LoadInit(
+ IN RTMP_ADAPTER *pAd)
+{
+ UINT32 IdBss;
+
+
+ /* check whether any BSS enables WMM feature */
+ for(IdBss=0; IdBss<pAd->ApCfg.BssidNum; IdBss++)
+ {
+ if ((pAd->ApCfg.MBSSID[IdBss].bWmmCapable)
+ )
+ {
+ pAd->FlgQloadEnable = TRUE;
+ break;
+ }
+ }
+
+ if (pAd->FlgQloadEnable == TRUE)
+ {
+ /* Count EIFS, NAV, RX busy, TX busy as channel busy and
+ enable Channel statistic timer (bit 0) */
+
+ /* Note: if bit 0 == 0, the function will be disabled */
+ RTMP_IO_WRITE32(pAd, CH_TIME_CFG, 0x0000001F);
+
+ /* default value is 50, please reference to IEEE802.11e 2005 Annex D */
+ pAd->QloadChanUtilBeaconInt = 50;
+ }
+ else
+ {
+ /* no any WMM is enabled */
+ RTMP_IO_WRITE32(pAd, CH_TIME_CFG, 0x00000000);
+ }
+
+ pAd->QloadChanUtilTotal = 0;
+ pAd->QloadUpTimeLast = 0;
+
+#ifdef QLOAD_FUNC_BUSY_TIME_STATS
+ /* clear busy time statistics */
+ NdisZeroMemory(pAd->QloadBusyCountPri, sizeof(pAd->QloadBusyCountPri));
+ NdisZeroMemory(pAd->QloadBusyCountSec, sizeof(pAd->QloadBusyCountSec));
+#endif /* QLOAD_FUNC_BUSY_TIME_STATS */
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ /* init threshold before QBSS_LoadAlarmReset */
+ pAd->QloadAlarmBusyTimeThreshold = QBSS_LOAD_ALRAM_BUSY_TIME_THRESHOLD;
+ pAd->QloadAlarmBusyNumThreshold = QBSS_LOAD_ALRAM_BUSY_NUM_THRESHOLD;
+
+ QBSS_LoadAlarmReset(pAd);
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Reset alarm function.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID QBSS_LoadAlarmReset(
+ IN RTMP_ADAPTER *pAd)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ pAd->FlgQloadAlarm = FALSE;
+ pAd->QloadAlarmDuration = 0;
+ pAd->QloadAlarmNumber = 0;
+
+ pAd->FlgQloadAlarmIsSuspended = FALSE;
+
+ QBSS_LoadAlarmBusyTimeThresholdReset(pAd, pAd->CommonCfg.BeaconPeriod);
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Resume alarm function.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID QBSS_LoadAlarmResume(
+ IN RTMP_ADAPTER *pAd)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ pAd->FlgQloadAlarmIsSuspended = FALSE;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Suspend alarm function.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static VOID QBSS_LoadAlarmSuspend(
+ IN RTMP_ADAPTER *pAd)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ pAd->FlgQloadAlarmIsSuspended = TRUE;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Get average busy time in current channel.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ average busy time
+
+Note:
+========================================================================
+*/
+UINT32 QBSS_LoadBusyTimeGet(
+ IN RTMP_ADAPTER *pAd)
+{
+ if (pAd->QloadChanUtilBeaconCnt == 0)
+ return pAd->QloadChanUtilTotal;
+
+ return (pAd->QloadChanUtilTotal / pAd->QloadChanUtilBeaconCnt);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Check if a alarm is occurred and clear the alarm.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ TRUE - alarm occurs
+ FALSE - no alarm
+
+Note:
+ We will clear the alarm in the function.
+========================================================================
+*/
+BOOLEAN QBSS_LoadIsAlarmIssued(
+ IN RTMP_ADAPTER *pAd)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ BOOLEAN FlgQloadAlarm = pAd->FlgQloadAlarm;
+
+ pAd->FlgQloadAlarm = FALSE;
+ return FlgQloadAlarm;
+#else
+
+ return FALSE;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Check if the busy time is accepted.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ TURE - ok
+ FALSE - fail
+
+Note:
+========================================================================
+*/
+BOOLEAN QBSS_LoadIsBusyTimeAccepted(
+ IN RTMP_ADAPTER *pAd,
+ IN UINT32 BusyTime)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ if (pAd->QloadAlarmBusyTimeThreshold == 0)
+ return TRUE; /* always ok */
+
+ if (BusyTime >= pAd->QloadBusyTimeThreshold)
+ return FALSE;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Append the QBSS Load element to the beacon frame.
+
+Arguments:
+ pAd - WLAN control block pointer
+ *pBeaconBuf - the beacon or probe response frame
+
+Return Value:
+ the element total Length
+
+Note:
+ Append Condition: You must check whether WMM is enabled before the
+ function is using.
+========================================================================
+*/
+UINT32 QBSS_LoadElementAppend(
+ IN RTMP_ADAPTER *pAd,
+ OUT UINT8 *pBeaconBuf)
+{
+ ELM_QBSS_LOAD load, *pLoad = &load;
+ ULONG ElmLen;
+
+
+ /* check whether channel busy time calculation is enabled */
+ if (pAd->FlgQloadEnable == 0)
+ return 0;
+
+ /* init */
+ pLoad->ElementId = ELM_QBSS_LOAD_ID;
+ pLoad->Length = ELM_QBSS_LOAD_LEN;
+
+ pLoad->StationCount = le2cpu16(MacTableAssocStaNumGet(pAd));
+ pLoad->ChanUtil = pAd->QloadChanUtil;
+
+ /* because no ACM is supported, the available bandwidth is 1 sec */
+ pLoad->AvalAdmCap = le2cpu16(0x7a12); /* 0x7a12 * 32us = 1 second */
+
+
+ /* copy the element to the frame */
+ MakeOutgoingFrame(pBeaconBuf, &ElmLen,
+ sizeof(ELM_QBSS_LOAD), pLoad,
+ END_OF_ARGS);
+
+ return ElmLen;
+}
+
+
+
+
+/*
+========================================================================
+Routine Description:
+ Update Channel Utilization.
+
+Arguments:
+ pAd - WLAN control block pointer
+ UpTime - current up time
+
+Return Value:
+ None
+
+Note:
+ UpTime is used in QLOAD_FUNC_BUSY_TIME_STATS & QLOAD_FUNC_BUSY_TIME_ALARM
+
+ If UpTime != 0, it means that the time period calling the function
+ maybe not TBTT so we need to re-calculate the time period.
+
+ If you call the function in kernel thread, the time period sometimes
+ will not accurate due to kernel thread is not real-time, so we need to
+ recalculate the time period.
+========================================================================
+*/
+VOID QBSS_LoadUpdate(
+ IN RTMP_ADAPTER *pAd,
+ IN ULONG UpTime)
+{
+ UINT32 ChanUtilNu, ChanUtilDe;
+ UINT32 BusyTime = 0;
+ UINT32 BusyTimeId;
+ UINT32 TimePeriod = pAd->CommonCfg.BeaconPeriod;
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ BOOLEAN FlgIsBusyOverThreshold = FALSE;
+ BOOLEAN FlgIsAlarmNeeded = FALSE;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+
+ /* check whether channel busy time calculation is enabled */
+ if ((pAd->FlgQloadEnable == 0) ||
+ (pAd->FlgQloadAlarmIsSuspended == TRUE))
+ return;
+
+ /* calculate new time period if needed */
+ if ((UpTime > 0) &&
+ (pAd->QloadUpTimeLast > 0) &&
+ (UpTime > pAd->QloadUpTimeLast))
+ {
+ /* re-calculate time period */
+ TimePeriod = (UINT32)(UpTime - pAd->QloadUpTimeLast);
+
+ /* translate to mini-second */
+ TimePeriod = (TimePeriod*1000)/OS_HZ;
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ /* re-calculate QloadBusyTimeThreshold */
+ if (TimePeriod != pAd->QloadTimePeriodLast)
+ QBSS_LoadAlarmBusyTimeThresholdReset(pAd, TimePeriod);
+
+ pAd->QloadTimePeriodLast = TimePeriod;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+ }
+
+ /* update up time */
+ pAd->QloadUpTimeLast = UpTime;
+
+ /* do busy time statistics */
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0))
+ {
+ /* in 20MHz, no need to check busy time of secondary channel */
+ RTMP_IO_READ32(pAd, CH_BUSY_STA_SEC, &BusyTime);
+ pAd->QloadLatestChannelBusyTimeSec = BusyTime;
+
+#ifdef QLOAD_FUNC_BUSY_TIME_STATS
+ BusyTimeId = BusyTime >> 10; /* translate us to ms */
+
+ /* ex:95ms, 95*20/100 = 19 */
+ BusyTimeId = (BusyTimeId*QLOAD_BUSY_INTERVALS)/TimePeriod;
+
+ if (BusyTimeId >= QLOAD_BUSY_INTERVALS)
+ BusyTimeId = QLOAD_BUSY_INTERVALS - 1;
+
+ pAd->QloadBusyCountSec[BusyTimeId] ++;
+#endif /* QLOAD_FUNC_BUSY_TIME_STATS */
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ if ((pAd->FlgQloadAlarmIsSuspended == FALSE) &&
+ (pAd->QloadAlarmBusyTimeThreshold > 0))
+ {
+ /* Alarm is not suspended and is enabled */
+
+ if ((pAd->QloadBusyTimeThreshold != 0) &&
+ (BusyTime >= pAd->QloadBusyTimeThreshold))
+ {
+ FlgIsBusyOverThreshold = TRUE;
+ }
+ }
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ /* do busy time statistics for primary channel */
+ RTMP_IO_READ32(pAd, CH_BUSY_STA, &BusyTime);
+ pAd->QloadLatestChannelBusyTimePri = BusyTime;
+
+#ifdef QLOAD_FUNC_BUSY_TIME_STATS
+ BusyTimeId = BusyTime >> 10; /* translate us to ms */
+
+ /* ex:95ms, 95*20/100 = 19 */
+ BusyTimeId = (BusyTimeId*QLOAD_BUSY_INTERVALS)/TimePeriod;
+
+ if (BusyTimeId >= QLOAD_BUSY_INTERVALS)
+ BusyTimeId = QLOAD_BUSY_INTERVALS - 1;
+
+ pAd->QloadBusyCountPri[BusyTimeId] ++;
+#endif /* QLOAD_FUNC_BUSY_TIME_STATS */
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ if ((pAd->FlgQloadAlarmIsSuspended == FALSE) &&
+ (pAd->QloadAlarmBusyTimeThreshold > 0))
+ {
+ /* Alarm is not suspended and is enabled */
+
+ if ((pAd->QloadBusyTimeThreshold != 0) &&
+ (BusyTime >= pAd->QloadBusyTimeThreshold))
+ {
+ FlgIsBusyOverThreshold = TRUE;
+ }
+ }
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+ /* accumulate channel busy time for primary channel */
+ pAd->QloadChanUtilTotal += BusyTime;
+
+ /* update new channel utilization for primary channel */
+ if (++pAd->QloadChanUtilBeaconCnt >= pAd->QloadChanUtilBeaconInt)
+ {
+ ChanUtilNu = pAd->QloadChanUtilTotal;
+ ChanUtilNu *= 255;
+
+ ChanUtilDe = pAd->QloadChanUtilBeaconInt;
+
+ /*
+ Still use pAd->CommonCfg.BeaconPeriod.
+ Because we change QloadChanUtil not every TBTT.
+ */
+ ChanUtilDe *= pAd->CommonCfg.BeaconPeriod;
+
+ ChanUtilDe <<= 10; /* ms to us */
+
+ pAd->QloadChanUtil = (UINT8)(ChanUtilNu/ChanUtilDe);
+
+ /* re-accumulate channel busy time */
+ pAd->QloadChanUtilBeaconCnt = 0;
+ pAd->QloadChanUtilTotal = 0;
+ }
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ /* check if alarm function is enabled */
+ if ((pAd->FlgQloadAlarmIsSuspended == FALSE) &&
+ (pAd->QloadAlarmBusyTimeThreshold > 0))
+ {
+ /* Alarm is not suspended and is enabled */
+
+ /* check if we need to issue a alarm */
+ if (FlgIsBusyOverThreshold == TRUE)
+ {
+ if (pAd->QloadAlarmDuration == 0)
+ {
+ /* last alarm ended so we can check new alarm */
+
+ pAd->QloadAlarmBusyNum ++;
+
+ if (pAd->QloadAlarmBusyNum >= pAd->QloadAlarmBusyNumThreshold)
+ {
+ /*
+ The continued number of busy time >= threshold is larger
+ than number threshold so issuing a alarm.
+ */
+ FlgIsAlarmNeeded = TRUE;
+ pAd->QloadAlarmDuration ++;
+ }
+ }
+ }
+ else
+ pAd->QloadAlarmBusyNum = 0;
+
+ if (pAd->QloadAlarmDuration > 0)
+ {
+ /*
+ New alarm occurs so we can not re-issue new alarm during
+ QBSS_LOAD_ALARM_DURATION * TBTT.
+ */
+ if (++pAd->QloadAlarmDuration >= QBSS_LOAD_ALARM_DURATION)
+ {
+ /* can re-issue next alarm */
+ pAd->QloadAlarmDuration = 0;
+ pAd->QloadAlarmBusyNum = 0;
+ }
+ }
+
+ if (FlgIsAlarmNeeded == TRUE)
+ QBSS_LoadAlarm(pAd);
+ }
+ else
+ {
+ /* clear statistics counts */
+ pAd->QloadAlarmBusyNum = 0;
+ pAd->QloadAlarmDuration = 0;
+ pAd->FlgQloadAlarm = FALSE;
+ }
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Clear QoS Load information.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID QBSS_LoadStatusClear(
+ IN RTMP_ADAPTER *pAd)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_STATS
+ /* clear busy time statistics */
+ NdisZeroMemory(pAd->QloadBusyCountPri, sizeof(pAd->QloadBusyCountPri));
+ NdisZeroMemory(pAd->QloadBusyCountSec, sizeof(pAd->QloadBusyCountSec));
+#endif /* QLOAD_FUNC_BUSY_TIME_STATS */
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ /* clear alarm function variables */
+ pAd->QloadChanUtilTotal = 0;
+ pAd->FlgQloadAlarm = FALSE;
+ pAd->QloadAlarmBusyNum = 0;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Show QoS Load information.
+
+Arguments:
+ pAd - WLAN control block pointer
+ Arg - Input arguments
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+INT Show_QoSLoad_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_STATS
+ UINT32 BusyTimeId;
+ UINT32 Time;
+
+
+ Time = pAd->CommonCfg.BeaconPeriod / QLOAD_BUSY_INTERVALS;
+
+ printk("\n\tPrimary Busy Time\tTimes\n");
+
+ for(BusyTimeId=0; BusyTimeId<QLOAD_BUSY_INTERVALS; BusyTimeId++)
+ {
+ printk("\t%dms ~ %dms\t\t%d\n",
+ BusyTimeId*Time,
+ (BusyTimeId+1)*Time,
+ pAd->QloadBusyCountPri[BusyTimeId]);
+ }
+
+ printk("\n\tSecondary Busy Time\tTimes\n");
+
+ for(BusyTimeId=0; BusyTimeId<QLOAD_BUSY_INTERVALS; BusyTimeId++)
+ {
+ printk("\t%dms ~ %dms\t\t%d\n",
+ BusyTimeId*Time,
+ (BusyTimeId+1)*Time,
+ pAd->QloadBusyCountSec[BusyTimeId]);
+ }
+#else
+
+ printk("\tBusy time statistics is not included into the driver!\n");
+#endif /* QLOAD_FUNC_BUSY_TIME_STATS */
+
+ printk("\n");
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Command for QoS Load information clear.
+
+Arguments:
+ pAd - WLAN control block pointer
+ Arg - Input arguments
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+INT Set_QloadClr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING Arg)
+{
+ QBSS_LoadStatusClear(pAd);
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Command for QoS Alarm Time Threshold set.
+
+Arguments:
+ pAd - WLAN control block pointer
+ Arg - Input arguments
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+INT Set_QloadAlarmTimeThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING Arg)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ pAd->QloadAlarmBusyTimeThreshold = (UCHAR)simple_strtol(Arg, 0, 10);
+
+ QBSS_LoadAlarmReset(pAd);
+
+ pAd->QloadTimePeriodLast = pAd->CommonCfg.BeaconPeriod;
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Command for QoS Alarm Number Threshold set.
+
+Arguments:
+ pAd - WLAN control block pointer
+ Arg - Input arguments
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+INT Set_QloadAlarmNumThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING Arg)
+{
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+ pAd->QloadAlarmBusyNumThreshold = (UCHAR)simple_strtol(Arg, 0, 10);
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+ return TRUE;
+}
+
+#endif /* AP_QLOAD_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_sanity.c b/cleopatre/devkit/mt7601udrv/ap/ap_sanity.c
new file mode 100644
index 0000000000..ac35f97e1c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_sanity.c
@@ -0,0 +1,477 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ap_sanity.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 08-14-2003 created for 11g soft-AP
+ John Chang 12-30-2004 merge with STA driver for RT2600
+*/
+
+#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[];
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+
+BOOLEAN PeerAssocReqCmmSanity(
+ RTMP_ADAPTER *pAd,
+ BOOLEAN isReassoc,
+ VOID *Msg,
+ INT MsgLen,
+ IE_LISTS *ie_lists)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+ PEID_STRUCT eid_ptr;
+ UCHAR Sanity = 0;
+ UCHAR WPA1_OUI[4] = { 0x00, 0x50, 0xF2, 0x01 };
+ UCHAR WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
+ MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)NULL;
+ HT_CAPABILITY_IE *pHtCapability = &ie_lists->HTCapability;
+
+
+ pEntry = MacTableLookup(pAd, &Fr->Hdr.Addr2[0]);
+ if (pEntry == NULL)
+ return FALSE;
+
+ COPY_MAC_ADDR(&ie_lists->Addr2[0], &Fr->Hdr.Addr2[0]);
+
+ Ptr = (PCHAR)Fr->Octet;
+
+ NdisMoveMemory(&ie_lists->CapabilityInfo, &Fr->Octet[0], 2);
+ NdisMoveMemory(&ie_lists->ListenInterval, &Fr->Octet[2], 2);
+
+ if (isReassoc)
+ {
+ NdisMoveMemory(&ie_lists->ApAddr[0], &Fr->Octet[4], 6);
+ eid_ptr = (PEID_STRUCT) &Fr->Octet[10];
+ }
+ else
+ {
+ eid_ptr = (PEID_STRUCT) &Fr->Octet[4];
+ }
+
+
+ /* get variable fields from payload and advance the pointer */
+ while (((UCHAR *)eid_ptr + eid_ptr->Len + 1) < ((UCHAR *)Fr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_SSID:
+ if (((Sanity&0x1) == 1))
+ break;
+
+ if ((eid_ptr->Len <= MAX_LEN_OF_SSID))
+ {
+ Sanity |= 0x01;
+ NdisMoveMemory(&ie_lists->Ssid[0], eid_ptr->Octet, eid_ptr->Len);
+ ie_lists->SsidLen = eid_ptr->Len;
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - SsidLen = %d \n", ie_lists->SsidLen));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SSID\n"));
+ return FALSE;
+ }
+ break;
+
+ case IE_SUPP_RATES:
+ if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) &&
+ (eid_ptr->Len > 0))
+ {
+ Sanity |= 0x02;
+ NdisMoveMemory(&ie_lists->SupportedRates[0], eid_ptr->Octet, eid_ptr->Len);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("PeerAssocReqSanity - IE_SUPP_RATES., Len=%d. "
+ "Rates[0]=%x\n", eid_ptr->Len, ie_lists->SupportedRates[0]));
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("Rates[1]=%x %x %x %x %x %x %x\n",
+ ie_lists->SupportedRates[1], ie_lists->SupportedRates[2],
+ ie_lists->SupportedRates[3], ie_lists->SupportedRates[4],
+ ie_lists->SupportedRates[5], ie_lists->SupportedRates[6],
+ ie_lists->SupportedRates[7]));
+
+ ie_lists->SupportedRatesLen = eid_ptr->Len;
+ }
+ else
+ {
+ UCHAR RateDefault[8] = \
+ { 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c };
+
+ /* HT rate not ready yet. return true temporarily. rt2860c */
+ /*DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES\n")); */
+ Sanity |= 0x02;
+ ie_lists->SupportedRatesLen = 8;
+ NdisMoveMemory(&ie_lists->SupportedRates[0], RateDefault, 8);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("PeerAssocReqSanity - wrong IE_SUPP_RATES., Len=%d\n",
+ eid_ptr->Len));
+ }
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (eid_ptr->Len + ie_lists->SupportedRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(&ie_lists->SupportedRates[ie_lists->SupportedRatesLen], eid_ptr->Octet,
+ eid_ptr->Len);
+ ie_lists->SupportedRatesLen += eid_ptr->Len;
+ }
+ else
+ {
+ NdisMoveMemory(&ie_lists->SupportedRates[ie_lists->SupportedRatesLen], eid_ptr->Octet,
+ MAX_LEN_OF_SUPPORTED_RATES - (ie_lists->SupportedRatesLen));
+ ie_lists->SupportedRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
+ {
+ NdisMoveMemory(pHtCapability, eid_ptr->Octet, SIZE_HT_CAP_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 */
+
+ ie_lists->ht_cap_len = SIZE_HT_CAP_IE;
+ Sanity |= 0x10;
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_HT_CAP\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
+ }
+
+ break;
+ case IE_EXT_CAPABILITY:
+ if (eid_ptr->Len >= sizeof(EXT_CAP_INFO_ELEMENT))
+ {
+ NdisMoveMemory(&ie_lists->ExtCapInfo, eid_ptr->Octet, sizeof(EXT_CAP_INFO_ELEMENT));
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n"));
+ }
+
+ break;
+
+ case IE_WPA: /* same as IE_VENDOR_SPECIFIC */
+ case IE_WPA2:
+
+ if (NdisEqualMemory(eid_ptr->Octet, WPS_OUI, 4))
+ {
+#ifdef WSC_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bWpsEnable) ||
+ (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bEnableWpsV2 == FALSE))
+#endif /* WSC_V2_SUPPORT */
+ ie_lists->bWscCapable = TRUE;
+#endif /* WSC_AP_SUPPORT */
+ break;
+ }
+
+ /* Handle Atheros and Broadcom draft 11n STAs */
+ if (NdisEqualMemory(eid_ptr->Octet, BROADCOM_OUI, 3))
+ {
+ switch (eid_ptr->Octet[3])
+ {
+ case 0x33:
+ if ((eid_ptr->Len-4) == sizeof(HT_CAPABILITY_IE))
+ {
+ NdisMoveMemory(pHtCapability, &eid_ptr->Octet[4], SIZE_HT_CAP_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 */
+
+ ie_lists->ht_cap_len = SIZE_HT_CAP_IE;
+ }
+ break;
+
+ default:
+ /* ignore other cases */
+ break;
+ }
+ }
+
+ if (NdisEqualMemory(eid_ptr->Octet, RALINK_OUI, 3) && (eid_ptr->Len == 7))
+ {
+ if (eid_ptr->Octet[3] != 0)
+ ie_lists->RalinkIe = eid_ptr->Octet[3];
+ else
+ ie_lists->RalinkIe = 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. */
+ break;
+ }
+
+ /* WMM_IE */
+ if (NdisEqualMemory(eid_ptr->Octet, WME_INFO_ELEM, 6) && (eid_ptr->Len == 7))
+ {
+ ie_lists->bWmmCapable = TRUE;
+
+#ifdef UAPSD_SUPPORT
+ if (pEntry)
+ {
+ UAPSD_AssocParse(pAd,
+ pEntry, (UINT8 *)&eid_ptr->Octet[6],
+ pAd->ApCfg.MBSSID[\
+ pEntry->apidx].UapsdInfo.bAPSDCapable);
+ }
+#endif /* UAPSD_SUPPORT */
+
+ break;
+ }
+
+ if (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode < Ndis802_11AuthModeWPA)
+ break;
+
+ /* If this IE did not begins with 00:0x50:0xf2:0x01,
+ it would be proprietary. So we ignore it. */
+ if (!NdisEqualMemory(eid_ptr->Octet, WPA1_OUI, sizeof(WPA1_OUI))
+ && !NdisEqualMemory(&eid_ptr->Octet[2], WPA2_OUI, sizeof(WPA2_OUI)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Not RSN IE, maybe WMM IE!!!\n"));
+ break;
+ }
+
+ if (/*(eid_ptr->Len <= MAX_LEN_OF_RSNIE) &&*/ (eid_ptr->Len >= MIN_LEN_OF_RSNIE))
+ {
+ hex_dump("Received RSNIE in Assoc-Req", (UCHAR *)eid_ptr, eid_ptr->Len + 2);
+
+ /* Copy whole RSNIE context */
+ NdisMoveMemory(&ie_lists->RSN_IE[0], eid_ptr, eid_ptr->Len + 2);
+ ie_lists->RSNIE_Len =eid_ptr->Len + 2;
+
+ }
+ else
+ {
+ ie_lists->RSNIE_Len = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - missing IE_WPA(%d)\n",eid_ptr->Len));
+ return FALSE;
+ }
+ break;
+
+#ifdef WAPI_SUPPORT
+ case IE_WAPI:
+ if ((pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAICERT) &&
+ (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAIPSK))
+ break;
+
+ /* Sanity check the validity of WIE */
+ /* Todo - AlbertY */
+
+ /* Copy whole WAPI-IE context */
+ NdisMoveMemory(&ie_lists->RSN_IE[0], eid_ptr, eid_ptr->Len + 2);
+ ie_lists->RSNIE_Len =eid_ptr->Len + 2;
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_WAPI(%d)\n",eid_ptr->Len));
+ break;
+#endif /* WAPI_SUPPORT */
+
+
+
+#ifdef DOT11_VHT_AC
+ case IE_VHT_CAP:
+ if (eid_ptr->Len == sizeof(VHT_CAP_IE))
+ {
+ NdisMoveMemory(&ie_lists->vht_cap, eid_ptr->Octet, sizeof(VHT_CAP_IE));
+ ie_lists->vht_cap_len = eid_ptr->Len;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():IE_VHT_CAP\n", __FUNCTION__));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s():wrong IE_VHT_CAP, eid->Len = %d\n",
+ __FUNCTION__, eid_ptr->Len));
+ }
+#endif /* DOT11_VHT_AC */
+ default:
+ break;
+ }
+
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ if ((Sanity&0x3) != 0x03)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s(): - missing mandatory field\n", __FUNCTION__));
+ return FALSE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() - success\n", __FUNCTION__));
+ return TRUE;
+ }
+}
+
+
+
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN PeerDisassocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT UINT16 *SeqNum,
+ OUT USHORT *Reason)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2);
+ *SeqNum = Fr->Hdr.Sequence;
+ NdisMoveMemory(Reason, &Fr->Octet[0], 2);
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN PeerDeauthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT UINT16 *SeqNum,
+ OUT USHORT *Reason)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2);
+ *SeqNum = Fr->Hdr.Sequence;
+ NdisMoveMemory(Reason, &Fr->Octet[0], 2);
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+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,
+ CHAR *ChlgText
+ )
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr1, &Fr->Hdr.Addr1); /* BSSID */
+ COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2); /* SA */
+ NdisMoveMemory(Alg, &Fr->Octet[0], 2);
+ NdisMoveMemory(Seq, &Fr->Octet[2], 2);
+ NdisMoveMemory(Status, &Fr->Octet[4], 2);
+
+ if (*Alg == AUTH_MODE_OPEN)
+ {
+ if (*Seq == 1 || *Seq == 2)
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APPeerAuthSanity fail - wrong Seg# (=%d)\n", *Seq));
+ return FALSE;
+ }
+ }
+ else if (*Alg == AUTH_MODE_KEY)
+ {
+ if (*Seq == 1 || *Seq == 4)
+ {
+ return TRUE;
+ }
+ else if (*Seq == 2 || *Seq == 3)
+ {
+ NdisMoveMemory(ChlgText, &Fr->Octet[8], CIPHER_TEXT_LEN);
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APPeerAuthSanity fail - wrong Seg# (=%d)\n", *Seq));
+ return FALSE;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APPeerAuthSanity fail - wrong algorithm (=%d)\n", *Alg));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_sync.c b/cleopatre/devkit/mt7601udrv/ap/ap_sync.c
new file mode 100644
index 0000000000..cf5ef21f66
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_sync.c
@@ -0,0 +1,1422 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ sync.c
+
+ Abstract:
+ Synchronization state machine related services
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 08-04-2003 created for 11g soft-AP
+
+ */
+
+#include "rt_config.h"
+
+#define OBSS_BEACON_RSSI_THRESHOLD (-85)
+
+#ifdef DOT11_N_SUPPORT
+void build_ext_channel_switch_ie(
+ IN PRTMP_ADAPTER pAd,
+ IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
+#endif /* DOT11_N_SUPPORT */
+
+
+/*
+ ==========================================================================
+ Description:
+ The sync state machine,
+ Parameters:
+ Sm - pointer to the state machine
+ Note:
+ the state machine looks like the following
+
+ AP_SYNC_IDLE
+ APMT2_PEER_PROBE_REQ peer_probe_req_action
+ ==========================================================================
+ */
+VOID APSyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, (STATE_MACHINE_FUNC *)Trans, AP_MAX_SYNC_STATE, AP_MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, AP_SYNC_IDLE, AP_SYNC_MACHINE_BASE);
+
+ StateMachineSetAction(Sm, AP_SYNC_IDLE, APMT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)APPeerProbeReqAction);
+ StateMachineSetAction(Sm, AP_SYNC_IDLE, APMT2_PEER_BEACON, (STATE_MACHINE_FUNC)APPeerBeaconAction);
+#ifdef AP_SCAN_SUPPORT
+ StateMachineSetAction(Sm, AP_SYNC_IDLE, APMT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)APMlmeScanReqAction);
+
+ /* scan_listen state */
+ StateMachineSetAction(Sm, AP_SCAN_LISTEN, APMT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)APInvalidStateWhenScan);
+ StateMachineSetAction(Sm, AP_SCAN_LISTEN, APMT2_PEER_BEACON, (STATE_MACHINE_FUNC)APPeerBeaconAtScanAction);
+ StateMachineSetAction(Sm, AP_SCAN_LISTEN, APMT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)APPeerBeaconAtScanAction);
+ StateMachineSetAction(Sm, AP_SCAN_LISTEN, APMT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)APScanTimeoutAction);
+ StateMachineSetAction(Sm, AP_SCAN_LISTEN, APMT2_MLME_SCAN_CNCL, (STATE_MACHINE_FUNC)APScanCnclAction);
+
+ RTMPInitTimer(pAd, &pAd->MlmeAux.APScanTimer, GET_TIMER_FUNCTION(APScanTimeout), pAd, FALSE);
+#endif /* AP_SCAN_SUPPORT */
+}
+
+/*
+ ==========================================================================
+ Description:
+ Process the received ProbeRequest from clients
+ Parameters:
+ Elem - msg containing the ProbeReq frame
+ ==========================================================================
+ */
+VOID APPeerProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+ HEADER_802_11 ProbeRspHdr;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0, TmpLen;
+ LARGE_INTEGER FakeTimestamp;
+ UCHAR DsLen = 1;
+ UCHAR ErpIeLen = 1;
+ UCHAR apidx = 0, PhyMode, SupRateLen;
+ UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2;
+ BOOLEAN bRequestRssi=FALSE;
+
+#ifdef WSC_AP_SUPPORT
+ UCHAR Addr3[MAC_ADDR_LEN];
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Elem->Msg;
+
+ COPY_MAC_ADDR(Addr3, pFrame->Hdr.Addr3);
+#endif /* WSC_AP_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ /* if in bridge mode, no need to reply probe req. */
+ if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
+ return;
+#endif /* WDS_SUPPORT */
+
+ if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, &bRequestRssi))
+ return;
+
+ for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ RSNIe = IE_WPA;
+
+ if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) &&
+ !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev)))
+ {
+ /* the interface is down, so we can not send probe response */
+ continue;
+ }
+
+ PhyMode = pAd->ApCfg.MBSSID[apidx].PhyMode;
+
+ if (((SsidLen == 0) && (! pAd->ApCfg.MBSSID[apidx].bHideSsid)) ||
+#ifdef WSC_AP_SUPPORT
+ /* buffalo WPS testbed STA send ProbrRequest ssid length = 32 and ssid are not AP , but DA are AP. for WPS test send ProbeResponse */
+ ((SsidLen == 32) && MAC_ADDR_EQUAL(Addr3, pAd->ApCfg.MBSSID[apidx].Bssid) && (pAd->ApCfg.MBSSID[apidx].bHideSsid == 0)) ||
+#endif /* WSC_AP_SUPPORT */
+ ((SsidLen == pAd->ApCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, (ULONG) SsidLen)))
+ ;
+ else
+ continue; /* check next BSS */
+
+ /* allocate and send out ProbeRsp frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+ MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2,
+ pAd->ApCfg.MBSSID[apidx].Bssid);
+
+ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK))
+ RSNIe = IE_WPA;
+ else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK))
+ RSNIe = IE_WPA2;
+#ifdef WAPI_SUPPORT
+ else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAICERT) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAIPSK))
+ RSNIe = IE_WAPI;
+#endif /* WAPI_SUPPORT */
+
+ {
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+ if (PhyMode == WMODE_B)
+ SupRateLen = 4;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &ProbeRspHdr,
+ TIMESTAMP_LEN, &FakeTimestamp,
+ 2, &pAd->CommonCfg.BeaconPeriod,
+ 2, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo,
+ 1, &SsidIe,
+ 1, &pAd->ApCfg.MBSSID[apidx].SsidLen,
+ pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].Ssid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, pAd->CommonCfg.SupRate,
+ 1, &DsIe,
+ 1, &DsLen,
+ 1, &pAd->CommonCfg.Channel,
+ END_OF_ARGS);
+ }
+
+ if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B))
+ {
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &ErpIe,
+ 1, &ErpIeLen,
+ 1, &pAd->ApCfg.ErpIeContent,
+ 1, &ExtRateIe,
+ 1, &pAd->CommonCfg.ExtRateLen,
+ pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+#ifdef A_BAND_SUPPORT
+ /* add Channel switch announcement IE */
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE))
+ {
+ UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+ UCHAR CSALen=3;
+ UCHAR CSAMode=1;
+
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &CSAIe,
+ 1, &CSALen,
+ 1, &CSAMode,
+ 1, &pAd->CommonCfg.Channel,
+ 1, &pAd->Dot11_H.CSCount,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+#endif /* A_BAND_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ if (WMODE_CAP_N(PhyMode) &&
+ (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen, AddHtLen, NewExtLen;
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+ ADD_HT_INFO_IE addHTInfoTmp;
+#endif
+
+#ifdef A_BAND_SUPPORT
+ if (pAd->CommonCfg.bExtChannelSwitchAnnouncement && (pAd->CommonCfg.Channel > 14))
+ {
+ HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe;
+
+ build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe);
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+#endif /* A_BAND_SUPPORT */
+
+ 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 */
+#ifndef RT_BIG_ENDIAN
+ 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,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(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 */
+
+ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen);
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ 1, &AddHtInfoIe,
+ 1, &AddHtLen,
+ AddHtLen, &addHTInfoTmp,
+ END_OF_ARGS);
+
+#endif
+ FrameLen += TmpLen;
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ /* Append RSN_IE when WPA OR WPAPSK, */
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA)
+ ; /* enough information */
+ else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ {
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &RSNIe,
+ 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0],
+ pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0],
+ 1, &RSNIe2,
+ 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1],
+ pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSN_IE[1],
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &RSNIe,
+ 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0],
+ pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0],
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ /* add WMM IE here */
+ if (pAd->ApCfg.MBSSID[apidx].bWmmCapable)
+ {
+ UCHAR i;
+ UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0};
+ WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f;
+#ifdef UAPSD_SUPPORT
+ UAPSD_MR_IE_FILL(WmeParmIe[8], &pAd->ApCfg.MBSSID[apidx].UapsdInfo);
+#endif /* UAPSD_SUPPORT */
+ for (i=QID_AC_BE; i<=QID_AC_VO; i++)
+ {
+ WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */
+ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */
+ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */
+ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */
+ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */
+ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */
+ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */
+ }
+
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 26, WmeParmIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+#ifdef AP_QLOAD_SUPPORT
+ if (pAd->FlgQloadEnable != 0)
+ {
+ FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen);
+ }
+#endif /* AP_QLOAD_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */
+ if (WMODE_CAP_N(PhyMode) &&
+ (pAd->CommonCfg.Channel <= 14) &&
+ (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) &&
+ (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
+ {
+ OVERLAP_BSS_SCAN_IE OverlapScanParam;
+ ULONG TmpLen;
+ UCHAR OverlapScanIE, ScanIELen;
+
+ OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM;
+ ScanIELen = 14;
+ OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell);
+ OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell);
+ OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt);
+ OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel);
+ OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel);
+ OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
+ OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre);
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &OverlapScanIE,
+ 1, &ScanIELen,
+ ScanIELen, &OverlapScanParam,
+ END_OF_ARGS);
+
+ FrameLen += TmpLen;
+ }
+
+
+
+ /* 7.3.2.27 Extended Capabilities IE */
+ {
+ ULONG TmpLen;
+ EXT_CAP_INFO_ELEMENT extCapInfo;
+ UCHAR extInfoLen;
+
+
+ extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT);
+ NdisZeroMemory(&extCapInfo, extInfoLen);
+
+ /* P802.11n_D1.10, HT Information Exchange Support */
+ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) &&
+ (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) &&
+ (pAd->CommonCfg.bBssCoexEnable == TRUE))
+ {
+ extCapInfo.BssCoexistMgmtSupport = 1;
+
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &ExtCapIe,
+ 1, &extInfoLen,
+ extInfoLen, &extCapInfo,
+ END_OF_ARGS);
+
+ FrameLen += TmpLen;
+ }
+ }
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+ /*
+ add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back
+ Byte0.b3=1 for rssi-feedback
+ */
+{
+ ULONG TmpLen;
+ UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00};
+
+ if (pAd->CommonCfg.bAggregationCapable)
+ RalinkSpecificIe[5] |= 0x1;
+ if (pAd->CommonCfg.bPiggyBackCapable)
+ RalinkSpecificIe[5] |= 0x2;
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.bRdg)
+ RalinkSpecificIe[5] |= 0x4;
+#endif /* DOT11_N_SUPPORT */
+#ifdef RSSI_FEEDBACK
+ if (bRequestRssi == TRUE)
+ {
+ MAC_TABLE_ENTRY *pEntry=NULL;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n",
+ PRINT_MAC(Addr2)));
+
+ RalinkSpecificIe[5] |= 0x8;
+ pEntry = MacTableLookup(pAd, Addr2);
+
+ if (pEntry != NULL)
+ {
+ RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0;
+ RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1;
+ RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2;
+ }
+ }
+#endif /* RSSI_FEEDBACK */
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkSpecificIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+
+}
+
+#ifdef A_BAND_SUPPORT
+ /* add Channel switch announcement IE */
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE))
+ {
+ UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+ UCHAR CSALen=3;
+ UCHAR CSAMode=1;
+
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &CSAIe,
+ 1, &CSALen,
+ 1, &CSAMode,
+ 1, &pAd->CommonCfg.Channel,
+ 1, &pAd->Dot11_H.CSCount,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.bExtChannelSwitchAnnouncement)
+ {
+ HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe;
+
+ build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe);
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe,
+ END_OF_ARGS);
+ }
+#endif /* DOT11_N_SUPPORT */
+ FrameLen += TmpLen;
+ }
+#endif /* A_BAND_SUPPORT */
+
+ /* add country IE, power constraint IE */
+ if (pAd->CommonCfg.bCountryFlag)
+ {
+ ULONG TmpLen2=0;
+ UCHAR TmpFrame[256];
+ UCHAR CountryIe = IE_COUNTRY;
+ UCHAR MaxTxPower=16;
+
+#ifdef A_BAND_SUPPORT
+ /*
+ Only 802.11a APs that comply with 802.11h are required to include
+ a Power Constrint Element(IE=32) in beacons and probe response frames
+ */
+ if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE)
+ {
+ /* prepare power constraint IE */
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 3, PowerConstraintIE,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+#endif /* A_BAND_SUPPORT */
+
+ NdisZeroMemory(TmpFrame, sizeof(TmpFrame));
+
+ /* prepare channel information */
+ MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen,
+ 1, &pAd->ChannelList[0].Channel,
+ 1, &pAd->ChannelListNum,
+ 1, &MaxTxPower,
+ END_OF_ARGS);
+ TmpLen2 += TmpLen;
+
+ /* need to do the padding bit check, and concatenate it */
+ if ((TmpLen2%2) == 0)
+ {
+ UCHAR TmpLen3 = TmpLen2+4;
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &CountryIe,
+ 1, &TmpLen3,
+ 3, pAd->CommonCfg.CountryCode,
+ TmpLen2+1, TmpFrame,
+ END_OF_ARGS);
+ }
+ else
+ {
+ UCHAR TmpLen3 = TmpLen2+3;
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 1, &CountryIe,
+ 1, &TmpLen3,
+ 3, pAd->CommonCfg.CountryCode,
+ TmpLen2, TmpFrame,
+ END_OF_ARGS);
+ }
+ FrameLen += TmpLen;
+ }/* Country IE - */
+
+#ifdef DOT11_N_SUPPORT
+ if (WMODE_CAP_N(PhyMode) &&
+ (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen, AddHtLen;/*, NewExtLen; */
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+ ADD_HT_INFO_IE addHTInfoTmp;
+#endif
+ HtLen = sizeof(pAd->CommonCfg.HtCapability);
+ AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
+
+ if (pAd->bBroadComHT == TRUE)
+ {
+ UCHAR epigram_ie_len;
+ UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33};
+ UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34};
+
+
+ epigram_ie_len = HtLen + 4;
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_HTC[0],
+ HtLen, &pAd->CommonCfg.HtCapability,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(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, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_HTC[0],
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+
+ FrameLen += TmpLen;
+
+ epigram_ie_len = AddHtLen + 4;
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_AHTINFO[0],
+ AddHtLen, &pAd->CommonCfg.AddHTInfo,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen);
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &epigram_ie_len,
+ 4, &BROADCOM_AHTINFO[0],
+ AddHtLen, &addHTInfoTmp,
+ END_OF_ARGS);
+#endif
+
+ FrameLen += TmpLen;
+ }
+
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(PhyMode) &&
+ (pAd->CommonCfg.Channel > 14)) {
+ FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer+FrameLen), SUBTYPE_PROBE_RSP);
+ }
+#endif /* DOT11_VHT_AC */
+
+ }
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef WSC_AP_SUPPORT
+ /* for windows 7 logo test */
+ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) &&
+#ifdef DOT1X_SUPPORT
+ (pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) &&
+#endif /* DOT1X_SUPPORT */
+ (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled))
+ {
+ /*
+ Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based
+ or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP
+ network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't
+ receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and
+ prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">>
+ A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network.
+ The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero)
+ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp
+ */
+ ULONG TempLen1 = 0;
+ UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TempLen1,
+ 7, PROVISION_SERVICE_IE,
+ END_OF_ARGS);
+ FrameLen += TempLen1;
+ }
+
+ /* add Simple Config Information Element */
+ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode > WSC_DISABLE) && (pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen))
+ {
+ ULONG WscTmpLen = 0;
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &WscTmpLen,
+ pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen, pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.Value,
+ END_OF_ARGS);
+ FrameLen += WscTmpLen;
+ }
+#endif /* WSC_AP_SUPPORT */
+
+
+
+
+ /* 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is */
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ parse the received BEACON
+
+ NOTE:
+ The only thing AP cares about received BEACON frames is to decide
+ if there's any overlapped legacy BSS condition (OLBC).
+ If OLBC happened, this AP should set the ERP->Use_Protection bit in its
+ outgoing BEACON. The result is to tell all its clients to use RTS/CTS
+ or CTS-to-self protection to protect B/G mixed traffic
+ ==========================================================================
+ */
+
+
+typedef struct
+{
+ ULONG count;
+ UCHAR bssid[MAC_ADDR_LEN];
+} BSSIDENTRY;
+
+
+
+VOID APPeerBeaconAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Rates[MAX_LEN_OF_SUPPORTED_RATES], *pRates = NULL, RatesLen;
+ BOOLEAN LegacyBssExist;
+ CHAR RealRssi;
+ UCHAR *VarIE = NULL;
+ USHORT LenVIE;
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ UCHAR MaxSupportedRate = 0;
+
+
+ BCN_IE_LIST *ie_list = NULL;
+
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST));
+ if (ie_list == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+ NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST));
+
+ /* Init Variable IE structure */
+ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN);
+ if (VarIE == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate VarIE fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+
+
+
+ pRates = (PUCHAR)Rates;
+
+ ie_list->Channel = Elem->Channel;
+ RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20));
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ ie_list,
+ &LenVIE,
+ pVIE))
+ {
+
+ /* ignore BEACON not in this channel */
+ if (ie_list->Channel != pAd->CommonCfg.Channel
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ && (pAd->CommonCfg.bOverlapScanning == FALSE)
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+ )
+ {
+ goto __End_Of_APPeerBeaconAction;
+ }
+
+#ifdef IDS_SUPPORT
+ /* Conflict SSID detection */
+ RTMPConflictSsidDetection(pAd, (PUCHAR)ie_list->Ssid, ie_list->SsidLen, (CHAR)Elem->Rssi0, (CHAR)Elem->Rssi1, (CHAR)Elem->Rssi2, Elem->AntSel);
+#endif /* IDS_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ /* 40Mhz BSS Width Trigger events Intolerant devices */
+ if ((RealRssi > OBSS_BEACON_RSSI_THRESHOLD) && (ie_list->HtCapability.HtCapInfo.Forty_Mhz_Intolerant)) /* || (HtCapabilityLen == 0))) */
+ {
+ Handle_BSS_Width_Trigger_Events(pAd);
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+#ifdef DOT11N_DRAFT3
+ && (pAd->CommonCfg.bOverlapScanning == FALSE)
+#endif /* DOT11N_DRAFT3 */
+ )
+ {
+ if (pAd->CommonCfg.Channel<=14)
+ {
+ if (((pAd->CommonCfg.CentralChannel+2) != ie_list->Channel) &&
+ ((pAd->CommonCfg.CentralChannel-2) != ie_list->Channel))
+ {
+/*
+ DBGPRINT(RT_DEBUG_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x is a legacy BSS (%d) \n",
+ Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5], Channel));
+*/
+ goto __End_Of_APPeerBeaconAction;
+ }
+ }
+ else
+ {
+ if (ie_list->Channel != pAd->CommonCfg.Channel)
+ goto __End_Of_APPeerBeaconAction;
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ SupportRate(ie_list->SupRate, ie_list->SupRateLen, ie_list->ExtRate, ie_list->ExtRateLen, &pRates, &RatesLen, &MaxSupportedRate);
+
+ if ((ie_list->Erp & 0x01) || (RatesLen <= 4))
+ LegacyBssExist = TRUE;
+ else
+ LegacyBssExist = FALSE;
+
+ if (LegacyBssExist && pAd->CommonCfg.DisableOLBCDetect == 0)
+ {
+ pAd->ApCfg.LastOLBCDetectTime = pAd->Mlme.Now32;
+
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.bHTProtect)
+ && (ie_list->HtCapabilityLen == 0) && (RealRssi > OBSS_BEACON_RSSI_THRESHOLD))
+ {
+
+ pAd->ApCfg.LastNoneHTOLBCDetectTime = pAd->Mlme.Now32;
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+ if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ pEntry = &pAd->MacTab.Content[Elem->Wcid];
+
+ if (pEntry && IS_ENTRY_APCLI(pEntry) && (pEntry->MatchAPCLITabIdx < MAX_APCLI_NUM))
+ pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].ApCliRcvBeaconTime = pAd->Mlme.Now32;
+ }
+
+#endif /* APCLI_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ do
+ {
+ PMAC_TABLE_ENTRY pEntry;
+ BOOLEAN bWmmCapable;
+
+ /* check BEACON does in WDS TABLE. */
+ pEntry = WdsTableLookup(pAd, ie_list->Addr2, FALSE);
+ bWmmCapable = ie_list->EdcaParm.bValid ? TRUE : FALSE;
+
+ if (pEntry)
+ {
+ WdsPeerBeaconProc(pAd, pEntry, ie_list->CapabilityInfo,
+ MaxSupportedRate, RatesLen, bWmmCapable,
+ ie_list->RalinkIe, &ie_list->HtCapability,
+ ie_list->HtCapabilityLen);
+ }
+ } while(FALSE);
+#endif /* WDS_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pAd->CommonCfg.bOverlapScanning == TRUE)
+ {
+ INT index,secChIdx;
+ BOOLEAN found = FALSE;
+ ADD_HTINFO *pAdd_HtInfo;
+
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ {
+ /* found the effected channel, mark that. */
+ if(pAd->ChannelList[index].Channel == ie_list->Channel)
+ {
+ secChIdx = -1;
+ if (ie_list->HtCapabilityLen > 0 && ie_list->AddHtInfoLen > 0)
+ { /* This is a 11n AP. */
+ pAd->ChannelList[index].bEffectedChannel |= EFFECTED_CH_PRIMARY; /* 2; // 2 for 11N 20/40MHz AP with primary channel set as this channel. */
+ pAdd_HtInfo = &ie_list->AddHtInfo.AddHtInfo;
+ if (pAdd_HtInfo->ExtChanOffset == EXTCHA_BELOW)
+ {
+#ifdef A_BAND_SUPPORT
+ if (ie_list->Channel > 14)
+ secChIdx = ((index > 0) ? (index - 1) : -1);
+ else
+#endif /* A_BAND_SUPPORT */
+ secChIdx = ((index >= 4) ? (index - 4) : -1);
+ }
+ else if (pAdd_HtInfo->ExtChanOffset == EXTCHA_ABOVE)
+ {
+#ifdef A_BAND_SUPPORT
+ if (ie_list->Channel > 14)
+ secChIdx = (((index+1) < pAd->ChannelListNum) ? (index + 1) : -1);
+ else
+#endif /* A_BAND_SUPPORT */
+ secChIdx = (((index+4) < pAd->ChannelListNum) ? (index + 4) : -1);
+ }
+
+ if (secChIdx >=0)
+ pAd->ChannelList[secChIdx].bEffectedChannel |= EFFECTED_CH_SECONDARY; /* 1; */
+
+ if ((pAd->CommonCfg.Channel != ie_list->Channel) ||
+ (pAdd_HtInfo->ExtChanOffset != pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)
+ )
+ pAd->CommonCfg.BssCoexApCnt++;
+ }
+ else
+ {
+ /* This is a legacy AP. */
+ pAd->ChannelList[index].bEffectedChannel |= EFFECTED_CH_LEGACY; /* 4; 1 for legacy AP. */
+ pAd->CommonCfg.BssCoexApCnt++;
+ }
+
+ found = TRUE;
+ }
+ }
+ }
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+ }
+ /* sanity check fail, ignore this frame */
+
+__End_Of_APPeerBeaconAction:
+/*#ifdef AUTO_CH_SELECT_ENHANCE */
+#ifdef CONFIG_AP_SUPPORT
+IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+{
+ if (ie_list->Channel == pAd->ApCfg.AutoChannel_Channel)
+ {
+ if (AutoChBssSearchWithSSID(pAd, ie_list->Bssid, (PUCHAR)ie_list->Ssid, ie_list->SsidLen, ie_list->Channel) == BSS_NOT_FOUND)
+ pAd->pChannelInfo->ApCnt[pAd->ApCfg.current_channel_index]++;
+ AutoChBssInsertEntry(pAd, ie_list->Bssid, ie_list->Ssid, ie_list->SsidLen, ie_list->Channel, ie_list->NewExtChannelOffset, RealRssi);
+ }
+}
+#endif /* CONFIG_AP_SUPPORT */
+/*#endif // AUTO_CH_SELECT_ENHANCE */
+
+LabelErr:
+ if (VarIE != NULL)
+ os_free_mem(NULL, VarIE);
+ if (ie_list != NULL)
+ os_free_mem(NULL, ie_list);
+
+ return;
+}
+
+#ifdef AP_SCAN_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID APInvalidStateWhenScan(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.ApSyncMachine.CurrState));
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan timeout handler, executed in timer thread
+ ==========================================================================
+ */
+VOID APScanTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AP SYNC - Scan Timeout \n"));
+ MlmeEnqueue(pAd, AP_SYNC_STATE_MACHINE, APMT2_SCAN_TIMEOUT, 0, NULL, 0);
+ RTMP_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan timeout procedure. basically add channel index by 1 and rescan
+ ==========================================================================
+ */
+VOID APScanTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
+
+#ifdef CONFIG_MULTI_CHANNEL
+ if (pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE && (pAd->P2pCfg.bStartP2pConnect) && (pAd->Multi_Channel_Enable == TRUE))
+ {
+ pAd->MlmeAux.Channel = 0;
+ }
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /*
+ iwpriv set auto channel selection
+ update the current index of the channel
+ */
+ if (pAd->ApCfg.bAutoChannelAtBootup == TRUE)
+ {
+ /* update current channel info */
+ UpdateChannelInfo(pAd, pAd->ApCfg.current_channel_index, pAd->ApCfg.AutoChannelAlg);
+
+ /* move to next channel */
+ pAd->ApCfg.current_channel_index++;
+ if (pAd->ApCfg.current_channel_index < pAd->ChannelListNum)
+ {
+ pAd->ApCfg.AutoChannel_Channel = pAd->ChannelList[pAd->ApCfg.current_channel_index].Channel;
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ ScanNextChannel(pAd, OPMODE_AP);
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME SCAN req state machine procedure
+ ==========================================================================
+ */
+VOID APMlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ BOOLEAN Cancelled;
+ UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType;
+
+
+ /* Suspend MSDU transmission here */
+ RTMPSuspendMsduTransmission(pAd);
+
+ /* first check the parameter sanity */
+ if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, (PCHAR)Ssid, &SsidLen, &ScanType))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AP SYNC - MlmeScanReqAction\n"));
+ NdisGetSystemUpTime(&pAd->ApCfg.LastScanTime);
+
+ RTMPCancelTimer(&pAd->MlmeAux.APScanTimer, &Cancelled);
+
+ /* record desired BSS parameters */
+ pAd->MlmeAux.BssType = BssType;
+ pAd->MlmeAux.ScanType = ScanType;
+ pAd->MlmeAux.SsidLen = SsidLen;
+ NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+
+ /* start from the first channel */
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE) && (pAd->P2pCfg.bStartP2pConnect) && (pAd->Multi_Channel_Enable == TRUE))
+ {
+ PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
+ if (pP2PCtrl->GroupOpChannel != 0)
+ pAd->MlmeAux.Channel = pP2PCtrl->GroupOpChannel;
+ else
+ pAd->MlmeAux.Channel = FirstChannel(pAd);
+ }
+ else
+ pAd->MlmeAux.Channel = FirstChannel(pAd);
+
+ /* Let BBP register at 20MHz to do scan */
+// rtmp_bbp_set_bw(pAd, BW_20);
+// DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+
+#else
+ pAd->MlmeAux.Channel = FirstChannel(pAd);
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+ /* Let BBP register at 20MHz to do scan */
+ rtmp_bbp_set_bw(pAd, BW_20);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (pAd->ApCfg.bAutoChannelAtBootup == TRUE)/* iwpriv set auto channel selection */
+ {
+ APAutoChannelInit(pAd);
+ pAd->ApCfg.AutoChannel_Channel = pAd->ChannelList[0].Channel;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ ScanNextChannel(pAd, OPMODE_AP);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("AP SYNC - MlmeScanReqAction() sanity check fail. BUG!!!\n"));
+ pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ peer sends beacon back when scanning
+ ==========================================================================
+ */
+VOID APPeerBeaconAtScanAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PFRAME_802_11 pFrame;
+ UCHAR *VarIE = NULL;
+ USHORT LenVIE;
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ CHAR RealRssi = -127;
+
+ BCN_IE_LIST *ie_list = NULL;
+
+
+ os_alloc_mem(pAd, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST));
+ if (!ie_list) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Alloc memory for ie_list fail!!!\n", __FUNCTION__));
+ return;
+ }
+ NdisZeroMemory((UCHAR *)ie_list, sizeof(BCN_IE_LIST));
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN);
+ if (VarIE == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+
+ pFrame = (PFRAME_802_11) Elem->Msg;
+ /* Init Variable IE structure */
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg, Elem->MsgLen, Elem->Channel,
+ ie_list, &LenVIE, pVIE));
+ {
+ ULONG Idx;
+ CHAR Rssi = -127;
+
+ RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20));
+
+
+
+ /* ignore BEACON not in this channel */
+ if (ie_list->Channel != pAd->MlmeAux.Channel
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ && (pAd->CommonCfg.bOverlapScanning == FALSE)
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+ )
+ {
+ goto __End_Of_APPeerBeaconAtScanAction;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((RealRssi > OBSS_BEACON_RSSI_THRESHOLD) && (ie_list->HtCapability.HtCapInfo.Forty_Mhz_Intolerant)) /* || (HtCapabilityLen == 0))) */
+ {
+ Handle_BSS_Width_Trigger_Events(pAd);
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef IDS_SUPPORT
+ /* Conflict SSID detection */
+ if (ie_list->Channel == pAd->CommonCfg.Channel)
+ RTMPConflictSsidDetection(pAd, ie_list->Ssid, ie_list->SsidLen, Elem->Rssi0, Elem->Rssi1, Elem->Rssi2, Elem->AntSel);
+#endif /* IDS_SUPPORT */
+
+ /*
+ This correct im-proper RSSI indication during SITE SURVEY issue.
+ Always report bigger RSSI during SCANNING when receiving multiple BEACONs from the same AP.
+ This case happens because BEACONs come from adjacent channels, so RSSI become weaker as we
+ switch to more far away channels.
+ */
+ Idx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel);
+ if (Idx != BSS_NOT_FOUND)
+ Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
+
+
+
+ /* TODO: 2005-03-04 dirty patch. we should change all RSSI related variables to SIGNED SHORT for easy/efficient reading and calaulation */
+ RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20));
+ if ((RealRssi + pAd->BbpRssiToDbmDelta) > Rssi)
+ Rssi = RealRssi + pAd->BbpRssiToDbmDelta;
+
+ Idx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, Rssi, 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);
+ }
+ }
+
+ /* sanity check fail, ignored */
+__End_Of_APPeerBeaconAtScanAction:
+ /*scan beacon in pastive */
+#ifdef CONFIG_AP_SUPPORT
+IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+{
+ if (ie_list->Channel == pAd->ApCfg.AutoChannel_Channel)
+ {
+ if (AutoChBssSearchWithSSID(pAd, ie_list->Bssid, (PUCHAR)ie_list->Ssid, ie_list->SsidLen, ie_list->Channel) == BSS_NOT_FOUND)
+ pAd->pChannelInfo->ApCnt[pAd->ApCfg.current_channel_index]++;
+
+ AutoChBssInsertEntry(pAd, ie_list->Bssid, (CHAR *)ie_list->Ssid, ie_list->SsidLen, ie_list->Channel, ie_list->NewExtChannelOffset, RealRssi);
+ }
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+LabelErr:
+ if (VarIE != NULL)
+ os_free_mem(NULL, VarIE);
+ if (ie_list != NULL)
+ os_free_mem(NULL, ie_list);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME Cancel the SCAN req state machine procedure
+ ==========================================================================
+ */
+VOID APScanCnclAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ BOOLEAN Cancelled;
+
+ RTMPCancelTimer(&pAd->MlmeAux.APScanTimer, &Cancelled);
+ pAd->MlmeAux.Channel = 0;
+ ScanNextChannel(pAd, OPMODE_AP);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ if ChannelSel is false,
+ AP scans channels and lists the information of channels.
+ if ChannelSel is true,
+ AP scans channels and selects an optimal channel.
+
+ NOTE:
+ ==========================================================================
+*/
+VOID ApSiteSurvey(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_802_11_SSID pSsid,
+ IN UCHAR ScanType,
+ IN BOOLEAN ChannelSel)
+{
+ MLME_SCAN_REQ_STRUCT ScanReq;
+
+ AsicDisableSync(pAd);
+
+ BssTableInit(&pAd->ScanTab);
+ pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE;
+
+ RTMPZeroMemory(ScanReq.Ssid, MAX_LEN_OF_SSID);
+ ScanReq.SsidLen = 0;
+ if (pSsid)
+ {
+ ScanReq.SsidLen = pSsid->SsidLength;
+ NdisMoveMemory(ScanReq.Ssid, pSsid->Ssid, pSsid->SsidLength);
+ }
+ ScanReq.BssType = BSS_ANY;
+ ScanReq.ScanType = ScanType;
+ pAd->ApCfg.bAutoChannelAtBootup = ChannelSel;
+
+ MlmeEnqueue(pAd, AP_SYNC_STATE_MACHINE, APMT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0);
+ RTMP_MLME_HANDLER(pAd);
+}
+
+BOOLEAN ApScanRunning(
+ IN PRTMP_ADAPTER pAd)
+{
+ return (pAd->Mlme.ApSyncMachine.CurrState == AP_SCAN_LISTEN) ? TRUE : FALSE;
+}
+#endif /* AP_SCAN_SUPPORT */
+
+VOID SupportRate(
+ IN PUCHAR SupRate,
+ IN UCHAR SupRateLen,
+ IN PUCHAR ExtRate,
+ IN UCHAR ExtRateLen,
+ OUT PUCHAR *ppRates,
+ OUT PUCHAR RatesLen,
+ OUT PUCHAR pMaxSupportRate)
+{
+ INT i;
+
+ *pMaxSupportRate = 0;
+
+ if ((SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES) && (SupRateLen > 0))
+ {
+ NdisMoveMemory(*ppRates, SupRate, SupRateLen);
+ *RatesLen = SupRateLen;
+ }
+ else
+ {
+ /* HT rate not ready yet. return true temporarily. rt2860c */
+ /*DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES\n")); */
+ *RatesLen = 8;
+ *(*ppRates + 0) = 0x82;
+ *(*ppRates + 1) = 0x84;
+ *(*ppRates + 2) = 0x8b;
+ *(*ppRates + 3) = 0x96;
+ *(*ppRates + 4) = 0x12;
+ *(*ppRates + 5) = 0x24;
+ *(*ppRates + 6) = 0x48;
+ *(*ppRates + 7) = 0x6c;
+ DBGPRINT(RT_DEBUG_TRACE, ("SUPP_RATES., Len=%d\n", SupRateLen));
+ }
+
+ if (ExtRateLen + *RatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory((*ppRates + (ULONG)*RatesLen), ExtRate, ExtRateLen);
+ *RatesLen = (*RatesLen) + ExtRateLen;
+ }
+ else
+ {
+ NdisMoveMemory((*ppRates + (ULONG)*RatesLen), ExtRate, MAX_LEN_OF_SUPPORTED_RATES - (*RatesLen));
+ *RatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+ }
+
+
+
+ for (i = 0; i < *RatesLen; i++)
+ {
+ if(*pMaxSupportRate < (*(*ppRates + i) & 0x7f))
+ *pMaxSupportRate = (*(*ppRates + i) & 0x7f);
+ }
+
+ return;
+}
+
+#ifdef DOT11_N_SUPPORT
+/* Regulatory classes in the USA */
+
+typedef struct
+{
+ UCHAR regclass; /* regulatory class */
+ UCHAR spacing; /* 0: 20Mhz, 1: 40Mhz */
+ UCHAR channelset[16]; /* max 15 channels, use 0 as terminator */
+} REG_CLASS;
+
+REG_CLASS reg_class[] =
+{
+ { 1, 0, {36, 40, 44, 48, 0}},
+ { 2, 0, {52, 56, 60, 64, 0}},
+ { 3, 0, {149, 153, 157, 161, 0}},
+ { 4, 0, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0}},
+ { 5, 0, {165, 0}},
+ { 22, 1, {36, 44, 0}},
+ { 23, 1, {52, 60, 0}},
+ { 24, 1, {100, 108, 116, 124, 132, 0}},
+ { 25, 1, {149, 157, 0}},
+ { 26, 1, {149, 157, 0}},
+ { 27, 1, {40, 48, 0}},
+ { 28, 1, {56, 64, 0}},
+ { 29, 1, {104, 112, 120, 128, 136, 0}},
+ { 30, 1, {153, 161, 0}},
+ { 31, 1, {153, 161, 0}},
+ { 32, 1, {1, 2, 3, 4, 5, 6, 7, 0}},
+ { 33, 1, {5, 6, 7, 8, 9, 10, 11, 0}},
+ { 0, 0, {0}} /* end */
+};
+
+UCHAR get_regulatory_class(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i=0;
+ UCHAR regclass = 0;
+
+ do
+ {
+ if (reg_class[i].spacing == pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth)
+ {
+ int j=0;
+
+ do
+ {
+ if (reg_class[i].channelset[j] == pAd->CommonCfg.Channel)
+ {
+ regclass = reg_class[i].regclass;
+ break;
+ }
+ j++;
+ } while (reg_class[i].channelset[j] != 0);
+ }
+ i++;
+ } while (reg_class[i].regclass != 0);
+
+ ASSERT(regclass);
+
+ return regclass;
+}
+
+
+void build_ext_channel_switch_ie(
+ IN PRTMP_ADAPTER pAd,
+ IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE)
+{
+
+ pIE->ID = IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT;
+ pIE->Length = 4;
+ pIE->ChannelSwitchMode = 1; /*no further frames */
+ pIE->NewRegClass = get_regulatory_class(pAd);
+ pIE->NewChannelNum = pAd->CommonCfg.Channel;
+ pIE->ChannelSwitchCount = pAd->Dot11_H.CSCount;
+}
+#endif /* DOT11_N_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_wds.c b/cleopatre/devkit/mt7601udrv/ap/ap_wds.c
new file mode 100644
index 0000000000..10402b28cf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_wds.c
@@ -0,0 +1,1359 @@
+
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_wds.c
+
+ Abstract:
+ Support WDS function.
+
+ Revision History:
+ Who When What
+ ------ ---------- ----------------------------------------------
+ Fonchi 02-13-2007 created
+*/
+
+#ifdef WDS_SUPPORT
+
+#include "rt_config.h"
+
+
+#define VAILD_KEY_INDEX( _X ) ((((_X) >= 0) && ((_X) < 4)) ? (TRUE) : (FALSE))
+
+
+/*extern INT rt28xx_ioctl(PNET_DEV net_dev, struct ifreq *rq, int cmd); */
+
+
+BOOLEAN ApWdsAllowToSendPacket(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pPacket,
+ OUT UCHAR *pWcid)
+{
+ UCHAR wdsIndex;
+ BOOLEAN allowed;
+
+ /*DBGPRINT(RT_DEBUG_TRACE, ("ApCliAllowToSendPacket():Packet to ApCli interface!\n")); */
+ wdsIndex = RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS;
+ if (ValidWdsEntry(pAd, wdsIndex))
+ {
+ /* 3. send out the packet. b7 as WDS bit, b0-6 as WDS index when b7==1 */
+
+ *pWcid = (UCHAR)pAd->WdsTab.WdsEntry[wdsIndex].MacTabMatchWCID;
+ /*RTMP_SET_PACKET_WCID(pPacket, pAd->WdsTab.WdsEntry[wdsIndex].MacTabMatchWCID); // to all WDS links. */
+
+ allowed = TRUE;
+ }
+ else
+ {
+ allowed = FALSE;
+ }
+
+ return allowed;
+}
+
+
+LONG WdsEntryAlloc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr)
+{
+ INT i;
+ LONG WdsTabIdx = -1;
+
+ NdisAcquireSpinLock(&pAd->WdsTabLock);
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ if ((pAd->WdsTab.Mode >= WDS_LAZY_MODE) && !WDS_IF_UP_CHECK(pAd, i))
+ continue;
+
+ if (pAd->WdsTab.WdsEntry[i].Valid == FALSE)
+ {
+ pAd->WdsTab.WdsEntry[i].Valid = TRUE;
+ pAd->WdsTab.Size ++;
+ COPY_MAC_ADDR(pAd->WdsTab.WdsEntry[i].PeerWdsAddr, pAddr);
+ WdsTabIdx = i;
+ break;
+ }
+ else if (MAC_ADDR_EQUAL(pAd->WdsTab.WdsEntry[i].PeerWdsAddr, pAddr))
+ {
+ WdsTabIdx = i;
+ break;
+ }
+ }
+
+ if (i == MAX_WDS_ENTRY)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Unable to allocate WdsEntry.\n", __FUNCTION__));
+
+ NdisReleaseSpinLock(&pAd->WdsTabLock);
+
+ return WdsTabIdx;
+}
+
+VOID WdsEntryDel(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr)
+{
+ INT i;
+
+ /* delete one WDS entry */
+ NdisAcquireSpinLock(&pAd->WdsTabLock);
+
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ if (MAC_ADDR_EQUAL(pAddr, pAd->WdsTab.WdsEntry[i].PeerWdsAddr)
+ && (pAd->WdsTab.WdsEntry[i].Valid == TRUE))
+ {
+ pAd->WdsTab.WdsEntry[i].Valid = FALSE;
+ NdisZeroMemory(pAd->WdsTab.WdsEntry[i].PeerWdsAddr, MAC_ADDR_LEN);
+ pAd->WdsTab.Size--;
+ break;
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->WdsTabLock);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Delete all WDS Entry in pAd->MacTab
+ ==========================================================================
+ */
+BOOLEAN MacTableDeleteWDSEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr)
+{
+ if (wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+
+ MacTableDeleteEntry(pAd, wcid, pAddr);
+
+ return TRUE;
+}
+
+/*
+================================================================
+Description : because WDS and CLI share the same WCID table in ASIC.
+WDS 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 WDS
+from index MAX_AID_BA.
+================================================================
+*/
+MAC_TABLE_ENTRY *MacTableInsertWDSEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ UINT WdsTabIdx)
+{
+ PMAC_TABLE_ENTRY pEntry = NULL;
+ HTTRANSMIT_SETTING HTPhyMode;
+
+ /* if FULL, return */
+ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+ return NULL;
+
+ if((pEntry = WdsTableLookup(pAd, pAddr, TRUE)) != NULL)
+ return pEntry;
+
+ /* allocate one WDS entry */
+ do
+ {
+ /* allocate one MAC entry */
+ pEntry = MacTableInsertEntry(pAd, pAddr, (WdsTabIdx + MIN_NET_DEVICE_FOR_WDS), OPMODE_AP, TRUE);
+ if (pEntry)
+ {
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+ /* specific Max Tx Rate for Wds link. */
+ NdisZeroMemory(&HTPhyMode, sizeof(HTTRANSMIT_SETTING));
+ switch (pAd->WdsTab.WdsEntry[WdsTabIdx].PhyMode)
+ {
+ case 0xff: /* user doesn't specific a Mode for WDS link. */
+ case MODE_OFDM: /* specific OFDM mode. */
+ HTPhyMode.field.MODE = MODE_OFDM;
+ HTPhyMode.field.MCS = 7;
+ pEntry->RateLen = 8;
+ break;
+
+ case MODE_CCK:
+ HTPhyMode.field.MODE = MODE_CCK;
+ HTPhyMode.field.MCS = 3;
+ pEntry->RateLen = 4;
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case MODE_HTMIX:
+ HTPhyMode.field.MCS = 7;
+ HTPhyMode.field.ShortGI = pAd->WdsTab.WdsEntry[WdsTabIdx].HTPhyMode.field.ShortGI;
+ HTPhyMode.field.BW = pAd->WdsTab.WdsEntry[WdsTabIdx].HTPhyMode.field.BW;
+ HTPhyMode.field.STBC = pAd->WdsTab.WdsEntry[WdsTabIdx].HTPhyMode.field.STBC;
+ HTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->RateLen = 12;
+ break;
+
+ case MODE_HTGREENFIELD:
+ HTPhyMode.field.MCS = 7;
+ HTPhyMode.field.ShortGI = pAd->WdsTab.WdsEntry[WdsTabIdx].HTPhyMode.field.ShortGI;
+ HTPhyMode.field.BW = pAd->WdsTab.WdsEntry[WdsTabIdx].HTPhyMode.field.BW;
+ HTPhyMode.field.STBC = pAd->WdsTab.WdsEntry[WdsTabIdx].HTPhyMode.field.STBC;
+ HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ pEntry->RateLen = 12;
+ break;
+#endif /* DOT11_N_SUPPORT */
+
+ default:
+ break;
+ }
+
+ pEntry->MaxHTPhyMode.word = HTPhyMode.word;
+ pEntry->MinHTPhyMode.word = pAd->WdsTab.WdsEntry[WdsTabIdx].MinHTPhyMode.word;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->WdsTab.WdsEntry[WdsTabIdx].PhyMode >= MODE_HTMIX)
+ {
+ if (pAd->WdsTab.WdsEntry[WdsTabIdx].DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF-wds%d : Desired MCS = %d\n", WdsTabIdx,
+ pAd->WdsTab.WdsEntry[WdsTabIdx].DesiredTransmitSetting.field.MCS));
+
+ set_ht_fixed_mcs(pAd, pEntry, pAd->WdsTab.WdsEntry[WdsTabIdx].DesiredTransmitSetting.field.MCS, pAd->WdsTab.WdsEntry[WdsTabIdx].HTPhyMode.field.MCS);
+ }
+
+ pEntry->MmpsMode = MMPS_ENABLE;
+ NdisMoveMemory(&pEntry->HTCapability, &pAd->CommonCfg.HtCapability, sizeof(HT_CAPABILITY_IE));
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ if (pEntry->HTCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pEntry->HTCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pEntry->HTCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pEntry->HTCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pEntry->HTCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pEntry->HTCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (pEntry->HTCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+#endif /* DOT11_N_SUPPORT */
+ else
+ {
+ NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE));
+ }
+
+ /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
+ if (pAd->WdsTab.WdsEntry[WdsTabIdx].bAutoTxRateSwitch == FALSE)
+ {
+ pEntry->HTPhyMode.field.MCS = pAd->WdsTab.WdsEntry[WdsTabIdx].DesiredTransmitSetting.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+ /* If the legacy mode is set, overwrite the transmit setting of this entry. */
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->WdsTab.WdsEntry[WdsTabIdx].DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ else
+ {
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+
+ pAd->WdsTab.WdsEntry[WdsTabIdx].MacTabMatchWCID = (UCHAR)pEntry->Aid;
+ pEntry->MatchWDSTabIdx = WdsTabIdx;
+
+ AsicUpdateWdsEncryption(pAd, pEntry->Aid);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertWDSEntry - allocate entry #%d, Total= %d\n",WdsTabIdx, pAd->MacTab.Size));
+ break;
+ }
+ }while(FALSE);
+
+ return pEntry;
+}
+
+MAC_TABLE_ENTRY *WdsTableLookupByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount)
+{
+ /*USHORT HashIdx; */
+ ULONG WdsIndex;
+ PMAC_TABLE_ENTRY pCurEntry = NULL;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ if (wcid <=0 || wcid >= MAX_LEN_OF_MAC_TABLE )
+ return NULL;
+
+ NdisAcquireSpinLock(&pAd->WdsTabLock);
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ do
+ {
+ /*HashIdx = MAC_ADDR_HASH_INDEX(pAddr); */
+ /*pCurEntry = pAd->MacTab.Hash[wcid]; */
+ pCurEntry = &pAd->MacTab.Content[wcid];
+
+ WdsIndex = 0xff;
+ if ((pCurEntry) && IS_ENTRY_WDS(pCurEntry))
+ {
+ WdsIndex = pCurEntry->MatchWDSTabIdx;
+ }
+
+ if (WdsIndex == 0xff)
+ break;
+
+ if (pAd->WdsTab.WdsEntry[WdsIndex].Valid != TRUE)
+ break;
+
+ if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
+ {
+ if(bResetIdelCount)
+ pCurEntry->NoDataIdleCount = 0;
+ pEntry = pCurEntry;
+ break;
+ }
+ } while(FALSE);
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ NdisReleaseSpinLock(&pAd->WdsTabLock);
+
+ return pEntry;
+}
+
+MAC_TABLE_ENTRY *WdsTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount)
+{
+ USHORT HashIdx;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ NdisAcquireSpinLock(&pAd->WdsTabLock);
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ pEntry = pAd->MacTab.Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (IS_ENTRY_WDS(pEntry) && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+ if(bResetIdelCount)
+ pEntry->NoDataIdleCount = 0;
+ break;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ NdisReleaseSpinLock(&pAd->WdsTabLock);
+
+ return pEntry;
+}
+
+MAC_TABLE_ENTRY *FindWdsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN PUCHAR pAddr,
+ IN UINT32 PhyMode)
+{
+ MAC_TABLE_ENTRY *pEntry;
+
+ /* lookup the match wds entry for the incoming packet. */
+ pEntry = WdsTableLookupByWcid(pAd, Wcid, pAddr, TRUE);
+ if (pEntry == NULL)
+ pEntry = WdsTableLookup(pAd, pAddr, TRUE);
+
+ /* Only Lazy mode will auto learning, match with FrDs=1 and ToDs=1 */
+ if((pEntry == NULL) && (pAd->WdsTab.Mode >= WDS_LAZY_MODE))
+ {
+ LONG WdsIdx = WdsEntryAlloc(pAd, pAddr);
+ if (WdsIdx >= 0)
+ {
+ /* user doesn't specific a phy mode for WDS link. */
+ if (pAd->WdsTab.WdsEntry[WdsIdx].PhyMode == 0xff)
+ pAd->WdsTab.WdsEntry[WdsIdx].PhyMode = PhyMode;
+ pEntry = MacTableInsertWDSEntry(pAd, pAddr, (UCHAR)WdsIdx);
+
+ RTMPSetSupportMCS(pAd,
+ OPMODE_AP,
+ pEntry,
+ pAd->CommonCfg.SupRate,
+ pAd->CommonCfg.SupRateLen,
+ pAd->CommonCfg.ExtRate,
+ pAd->CommonCfg.ExtRateLen,
+#ifdef DOT11_VHT_AC
+ 0,
+ NULL,
+#endif /* DOT11_VHT_AC */
+ &pAd->CommonCfg.HtCapability,
+ sizeof(pAd->CommonCfg.HtCapability));
+ }
+ else
+ pEntry = NULL;
+ }
+
+ return pEntry;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is called by APMlmePeriodicExec() every second to check if
+ 1. any associated client in PSM. If yes, then TX MCAST/BCAST should be
+ out in DTIM only
+ 2. any client being idle for too long and should be aged-out from MAC table
+ 3. garbage collect PSQ
+ ==========================================================================
+*/
+VOID WdsTableMaintenance(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR idx;
+
+ if (pAd->WdsTab.Mode != WDS_LAZY_MODE)
+ return;
+
+ for (idx = 0; idx < pAd->WdsTab.Size; idx++)
+ {
+ UCHAR wcid = pAd->WdsTab.WdsEntry[idx].MacTabMatchWCID;
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[wcid];
+
+ if(!IS_ENTRY_WDS(pEntry))
+ continue;
+
+ NdisAcquireSpinLock(&pAd->WdsTabLock);
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pEntry->NoDataIdleCount ++;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ NdisReleaseSpinLock(&pAd->WdsTabLock);
+
+ /* delete those MAC entry that has been idle for a long time */
+ if (pEntry->NoDataIdleCount >= MAC_TABLE_AGEOUT_TIME)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ageout %02x:%02x:%02x:%02x:%02x:%02x from WDS #%d after %d-sec silence\n",
+ pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
+ pEntry->Addr[4],pEntry->Addr[5], idx, MAC_TABLE_AGEOUT_TIME));
+ WdsEntryDel(pAd, pEntry->Addr);
+ MacTableDeleteWDSEntry(pAd, pEntry->Aid, pEntry->Addr);
+ }
+ }
+
+}
+
+
+VOID RT28xx_WDS_Close(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT index;
+
+ for(index = 0; index < MAX_WDS_ENTRY; index++)
+ {
+ if (pAd->WdsTab.WdsEntry[index].dev)
+ RtmpOSNetDevClose(pAd->WdsTab.WdsEntry[index].dev);
+ }
+ return;
+}
+
+
+
+VOID WdsDown(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+
+ for (i=0; i<MAX_WDS_ENTRY; i++)
+ {
+ if(WdsTableLookup(pAd, pAd->WdsTab.WdsEntry[i].PeerWdsAddr, TRUE))
+ MacTableDeleteWDSEntry(pAd, pAd->WdsTab.WdsEntry[i].MacTabMatchWCID,
+ pAd->WdsTab.WdsEntry[i].PeerWdsAddr);
+ }
+}
+
+VOID AsicUpdateWdsRxWCIDTable(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT index;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ for(index = 0; index < MAX_WDS_ENTRY; index++)
+ {
+ if (pAd->WdsTab.WdsEntry[index].Valid != TRUE)
+ continue;
+
+ pEntry = MacTableInsertWDSEntry(pAd, pAd->WdsTab.WdsEntry[index].PeerWdsAddr, index);
+
+ RTMPSetSupportMCS(pAd,
+ OPMODE_AP,
+ pEntry,
+ pAd->CommonCfg.SupRate,
+ pAd->CommonCfg.SupRateLen,
+ pAd->CommonCfg.ExtRate,
+ pAd->CommonCfg.ExtRateLen,
+#ifdef DOT11_VHT_AC
+ 0,
+ NULL,
+#endif /* DOT11_VHT_AC */
+ &pAd->CommonCfg.HtCapability,
+ sizeof(pAd->CommonCfg.HtCapability));
+
+ switch (pAd->WdsTab.WdsEntry[index].PhyMode)
+ {
+ case 0xff: /* user doesn't specific a Mode for WDS link. */
+ case MODE_OFDM: /* specific OFDM mode. */
+ pEntry->SupportRateMode = SUPPORT_OFDM_MODE;
+ break;
+
+ case MODE_CCK:
+ pEntry->SupportRateMode = SUPPORT_CCK_MODE;
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case MODE_HTMIX:
+ case MODE_HTGREENFIELD:
+ pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE | SUPPORT_CCK_MODE);
+ break;
+#endif /* DOT11_N_SUPPORT */
+
+ default:
+ break;
+ }
+ }
+
+ return;
+}
+
+VOID AsicUpdateWdsEncryption(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid)
+{
+ UINT WdsIdex;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ do
+ {
+ if (wcid >= MAX_LEN_OF_MAC_TABLE)
+ break;
+
+ pEntry = &pAd->MacTab.Content[wcid];
+ if (pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].Valid != TRUE)
+ break;
+
+ if (!IS_ENTRY_WDS(pEntry))
+ break;
+
+ WdsIdex = pEntry->MatchWDSTabIdx;
+
+ if (((pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption3Enabled))
+ && (pAd->WdsTab.WdsEntry[WdsIdex].WdsKey.KeyLen > 0))
+ {
+
+ INT DefaultKeyId = 0;
+
+ if (pAd->WdsTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption1Enabled)
+ DefaultKeyId = pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].KeyIdx;
+
+ if (!VAILD_KEY_INDEX(DefaultKeyId))
+ break;
+
+ /* Update key into Asic Pairwise key table */
+ RTMP_ASIC_PAIRWISE_KEY_TABLE(
+ pAd,
+ pEntry->Aid,
+ &pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsKey);
+
+ /* update WCID attribute table and IVEIV table for this entry */
+ RTMP_SET_WCID_SEC_INFO(
+ pAd,
+ MAIN_MBSSID + MIN_NET_DEVICE_FOR_WDS,
+ DefaultKeyId,
+ pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsKey.CipherAlg,
+ pEntry->Aid,
+ PAIRWISEKEY);
+ }
+ } while (FALSE);
+
+ return;
+}
+
+VOID WdsPeerBeaconProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN USHORT CapabilityInfo,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN UCHAR MaxSupportedRateLen,
+ IN BOOLEAN bWmmCapable,
+ IN ULONG ClientRalinkIe,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen)
+{
+ UCHAR MaxSupportedRate = RATE_11;
+
+ MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps);
+
+ if (pEntry && IS_ENTRY_WDS(pEntry))
+ {
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+ pEntry->RateLen = MaxSupportedRateLen;
+
+ set_entry_phy_cfg(pAd, pEntry);
+
+ 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;
+#endif /* DOT11_N_SUPPORT */
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ pEntry->CapabilityInfo = CapabilityInfo;
+
+ if (ClientRalinkIe & 0x00000004)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET);
+ else
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET);
+
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000003) == 3)
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ /*RTMPSetPiggyBack(pAd, TRUE); */
+
+ }
+ else if (ClientRalinkIe & 0x00000001)
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ }
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000002) == 2)
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ /*RTMPSetPiggyBack(pAd, TRUE); */
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -PiggyBack2= 1\n"));
+ }
+ else
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ }
+
+#ifdef DOT11_N_SUPPORT
+ /* If this Entry supports 802.11n, upgrade to HT rate. */
+ if ((HtCapabilityLen != 0)
+ && WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ ht_mode_adjust(pAd, pEntry, pHtCapability, &pAd->CommonCfg.DesiredHtPhy);
+
+ /* find max fixed rate */
+ pEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].DesiredHtPhyInfo.MCSSet[0],
+ &pHtCapability->MCSSet[0]);
+
+ if ((pEntry->MaxHTPhyMode.field.MCS > pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS) && (pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS != MCS_AUTO))
+ pEntry->MaxHTPhyMode.field.MCS = pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].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;
+ 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, sizeof(HT_CAPABILITY_IE));
+ }
+ else
+ {
+ NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE));
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ if (bWmmCapable
+#ifdef DOT11_N_SUPPORT
+ || (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
+#endif /* DOT11_N_SUPPORT */
+ )
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ pEntry->HTPhyMode.field.MODE = pEntry->MaxHTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.STBC = pEntry->MaxHTPhyMode.field.STBC;
+ pEntry->HTPhyMode.field.ShortGI = pEntry->MaxHTPhyMode.field.ShortGI;
+ pEntry->HTPhyMode.field.BW = pEntry->MaxHTPhyMode.field.BW;
+
+ switch (pEntry->HTPhyMode.field.MODE)
+ {
+ case MODE_OFDM: /* specific OFDM mode. */
+ pEntry->SupportRateMode = SUPPORT_OFDM_MODE;
+ break;
+
+ case MODE_CCK:
+ pEntry->SupportRateMode = SUPPORT_CCK_MODE;
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case MODE_HTMIX:
+ case MODE_HTGREENFIELD:
+ pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE | SUPPORT_CCK_MODE);
+ break;
+#endif /* DOT11_N_SUPPORT */
+
+ default:
+ break;
+ }
+ }
+}
+
+VOID APWdsInitialize(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+
+ pAd->WdsTab.Mode = WDS_DISABLE_MODE;
+ pAd->WdsTab.Size = 0;
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ pAd->WdsTab.WdsEntry[i].PhyMode = 0xff;
+ pAd->WdsTab.WdsEntry[i].Valid = FALSE;
+ pAd->WdsTab.WdsEntry[i].MacTabMatchWCID = 0;
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ pAd->WdsTab.WdsEntry[i].KeyIdx = 0;
+ NdisZeroMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+
+ pAd->WdsTab.WdsEntry[i].bAutoTxRateSwitch = TRUE;
+ pAd->WdsTab.WdsEntry[i].DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ }
+ return;
+}
+
+INT Show_WdsTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+
+ for(i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("IF/WDS%d-%02x:%02x:%02x:%02x:%02x:%02x(%s) ,%s, KeyId=%d\n", i,
+ PRINT_MAC(pAd->WdsTab.WdsEntry[i].PeerWdsAddr),
+ pAd->WdsTab.WdsEntry[i].Valid == 1 ? "Valid" : "Invalid",
+ GetEncryptType(pAd->WdsTab.WdsEntry[i].WepStatus),
+ pAd->WdsTab.WdsEntry[i].KeyIdx));
+
+ if (pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen > 0)
+ hex_dump("Wds Key", pAd->WdsTab.WdsEntry[i].WdsKey.Key, pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen);
+ }
+
+
+ DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-4s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
+ "MAC", "IDX", "AID", "PSM", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC"));
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (IS_ENTRY_WDS(pEntry))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%02X:%02X:%02X:%02X:%02X:%02X ", PRINT_MAC(pEntry->Addr)));
+ DBGPRINT(RT_DEBUG_OFF,("%-4d", (int)pEntry->MatchWDSTabIdx));
+ DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid));
+ DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode));
+ DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi0));
+ DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi1));
+ DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi2));
+ DBGPRINT(RT_DEBUG_OFF, ("%-10s", get_phymode_str(pEntry->HTPhyMode.field.MODE)));
+ DBGPRINT(RT_DEBUG_OFF, ("%-6s", get_bw_str(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\n", pEntry->HTPhyMode.field.STBC));
+ }
+ }
+
+ return TRUE;
+}
+
+VOID rtmp_read_wds_from_file(
+ IN PRTMP_ADAPTER pAd,
+ PSTRING tmpbuf,
+ PSTRING buffer)
+{
+ PSTRING macptr;
+ INT i=0, j;
+ STRING tok_str[16];
+ BOOLEAN bUsePrevFormat = FALSE;
+ UCHAR macAddress[MAC_ADDR_LEN];
+ UCHAR keyMaterial[40];
+ UCHAR KeyLen, CipherAlg = CIPHER_NONE, KeyIdx;
+ PRT_802_11_WDS_ENTRY pWdsEntry;
+
+ /*WdsPhyMode */
+ if (RTMPGetKeyParameter("WdsPhyMode", tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ if ((strncmp(macptr, "CCK", 3) == 0) || (strncmp(macptr, "cck", 3) == 0))
+ pAd->WdsTab.WdsEntry[i].PhyMode = MODE_CCK;
+ else if ((strncmp(macptr, "OFDM", 4) == 0) || (strncmp(macptr, "ofdm", 4) == 0))
+ pAd->WdsTab.WdsEntry[i].PhyMode = MODE_OFDM;
+#ifdef DOT11_N_SUPPORT
+ else if ((strncmp(macptr, "HTMIX", 5) == 0) || (strncmp(macptr, "htmix", 5) == 0))
+ pAd->WdsTab.WdsEntry[i].PhyMode = MODE_HTMIX;
+ else if ((strncmp(macptr, "GREENFIELD", 10) == 0) || (strncmp(macptr, "greenfield", 10) == 0))
+ pAd->WdsTab.WdsEntry[i].PhyMode = MODE_HTGREENFIELD;
+#endif /* DOT11_N_SUPPORT */
+ else
+ pAd->WdsTab.WdsEntry[i].PhyMode = 0xff;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("If/wds%d - WdsPhyMode=%d\n", i, pAd->WdsTab.WdsEntry[i].PhyMode));
+ }
+ }
+
+ /*WdsList */
+ if (RTMPGetKeyParameter("WdsList", tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, TRUE))
+ {
+ if (pAd->WdsTab.Mode != WDS_LAZY_MODE)
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ if(strlen(macptr) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ continue;
+ if(strcmp(macptr,"00:00:00:00:00:00") == 0)
+ continue;
+ if(i >= MAX_WDS_ENTRY)
+ break;
+
+ for (j=0; j<ETH_LENGTH_OF_ADDRESS; j++)
+ {
+ AtoH(macptr, &macAddress[j], 1);
+ macptr=macptr+3;
+ }
+
+ WdsEntryAlloc(pAd, macAddress);
+ }
+ }
+ }
+ /*WdsEncrypType */
+ if (RTMPGetKeyParameter("WdsEncrypType", tmpbuf, 128, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ if ((strncmp(macptr, "NONE", 4) == 0) || (strncmp(macptr, "none", 4) == 0))
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11WEPDisabled;
+ else if ((strncmp(macptr, "WEP", 3) == 0) || (strncmp(macptr, "wep", 3) == 0))
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11WEPEnabled;
+ else if ((strncmp(macptr, "TKIP", 4) == 0) || (strncmp(macptr, "tkip", 4) == 0))
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11Encryption2Enabled;
+ else if ((strncmp(macptr, "AES", 3) == 0) || (strncmp(macptr, "aes", 3) == 0))
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11Encryption3Enabled;
+ else
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11WEPDisabled;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WdsEncrypType[%d]=%d(%s)\n", i, pAd->WdsTab.WdsEntry[i].WepStatus, GetEncryptType(pAd->WdsTab.WdsEntry[i].WepStatus)));
+ }
+
+ /* Previous WDS only supports single encryption type. */
+ /* For backward compatible, other wds link encryption type shall be the same with the first. */
+ if (i == 1)
+ {
+ for (j = 1; j < MAX_WDS_ENTRY; j++)
+ {
+ pAd->WdsTab.WdsEntry[j].WepStatus = pAd->WdsTab.WdsEntry[0].WepStatus;
+ DBGPRINT(RT_DEBUG_TRACE, ("@WdsEncrypType[%d]=%d(%s)\n", j, pAd->WdsTab.WdsEntry[i].WepStatus, GetEncryptType(pAd->WdsTab.WdsEntry[i].WepStatus)));
+ }
+ }
+
+ }
+ /* WdsKey */
+ /* This is a previous parameter and it only stores WPA key material, not WEP key */
+ if (RTMPGetKeyParameter("WdsKey", tmpbuf, 255, buffer, FALSE))
+ {
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ NdisZeroMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+
+ if (strlen(tmpbuf) > 0)
+ bUsePrevFormat = TRUE;
+
+ /* check if the wds-0 link key material is valid */
+ if (((pAd->WdsTab.WdsEntry[0].WepStatus == Ndis802_11Encryption2Enabled)
+ || (pAd->WdsTab.WdsEntry[0].WepStatus == Ndis802_11Encryption3Enabled))
+ && (strlen(tmpbuf) >= 8) && (strlen(tmpbuf) <= 64))
+ {
+ RT_CfgSetWPAPSKKey(pAd, tmpbuf, strlen(tmpbuf), (PUCHAR)RALINK_PASSPHRASE, sizeof(RALINK_PASSPHRASE), keyMaterial);
+ if (pAd->WdsTab.WdsEntry[0].WepStatus == Ndis802_11Encryption3Enabled)
+ pAd->WdsTab.WdsEntry[0].WdsKey.CipherAlg = CIPHER_AES;
+ else
+ pAd->WdsTab.WdsEntry[0].WdsKey.CipherAlg = CIPHER_TKIP;
+
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[0].WdsKey.Key, keyMaterial, 16);
+ pAd->WdsTab.WdsEntry[0].WdsKey.KeyLen = 16;
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[0].WdsKey.RxMic, keyMaterial+16, 8);
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[0].WdsKey.TxMic, keyMaterial+16, 8);
+ }
+
+ /* Previous WDS only supports single key-material. */
+ /* For backward compatible, other wds link key-material shall be the same with the first. */
+ if (pAd->WdsTab.WdsEntry[0].WdsKey.KeyLen == 16)
+ {
+ for (j = 1; j < MAX_WDS_ENTRY; j++)
+ {
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[j].WdsKey, &pAd->WdsTab.WdsEntry[0].WdsKey, sizeof(CIPHER_KEY));
+ }
+ }
+
+ }
+
+ /* The parameters can provide different key information for each WDS-Link */
+ /* no matter WEP or WPA */
+ if (!bUsePrevFormat)
+ {
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ AP_WDS_KeyNameMakeUp(tok_str, sizeof(tok_str), i);
+
+ /* WdsXKey (X=0~MAX_WDS_ENTRY-1) */
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
+ {
+ if (pAd->WdsTab.WdsEntry[i].WepStatus == Ndis802_11Encryption1Enabled)
+ {
+ /* Ascii type */
+ if (strlen(tmpbuf) == 5 || strlen(tmpbuf) == 13)
+ {
+ KeyLen = strlen(tmpbuf);
+ pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen = KeyLen;
+ NdisMoveMemory(pAd->WdsTab.WdsEntry[i].WdsKey.Key, tmpbuf, KeyLen);
+ if (KeyLen == 5)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+
+ pAd->WdsTab.WdsEntry[i].WdsKey.CipherAlg = CipherAlg;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d Key=%s ,type=Ascii, CipherAlg(%s)\n", i, tmpbuf, (CipherAlg == CIPHER_WEP64 ? "wep64" : "wep128")));
+ }
+ /* Hex type */
+ else if (strlen(tmpbuf) == 10 || strlen(tmpbuf) == 26)
+ {
+ KeyLen = strlen(tmpbuf);
+ pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen = KeyLen / 2;
+ AtoH(tmpbuf, pAd->WdsTab.WdsEntry[i].WdsKey.Key, KeyLen / 2);
+ if (KeyLen == 10)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+
+ pAd->WdsTab.WdsEntry[i].WdsKey.CipherAlg = CipherAlg;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d Key=%s ,type=Hex, CipherAlg(%s)\n", i, tmpbuf, (CipherAlg == CIPHER_WEP64 ? "wep64" : "wep128")));
+ }
+ /* Invalid type */
+ else
+ {
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ NdisZeroMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d has invalid key for WEP, reset encryption to OPEN\n", i));
+ }
+ }
+ else if ((pAd->WdsTab.WdsEntry[i].WepStatus == Ndis802_11Encryption2Enabled)
+ || (pAd->WdsTab.WdsEntry[i].WepStatus == Ndis802_11Encryption3Enabled))
+ {
+ if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) <= 64))
+ {
+ RT_CfgSetWPAPSKKey(pAd, tmpbuf, strlen(tmpbuf), (PUCHAR) RALINK_PASSPHRASE, sizeof(RALINK_PASSPHRASE), keyMaterial);
+ if (pAd->WdsTab.WdsEntry[i].WepStatus == Ndis802_11Encryption3Enabled)
+ pAd->WdsTab.WdsEntry[i].WdsKey.CipherAlg = CIPHER_AES;
+ else
+ pAd->WdsTab.WdsEntry[i].WdsKey.CipherAlg = CIPHER_TKIP;
+
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[i].WdsKey.Key, keyMaterial, 16);
+ pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen = 16;
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[i].WdsKey.RxMic, keyMaterial+16, 8);
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[i].WdsKey.TxMic, keyMaterial+16, 8);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d Key=%s, CipherAlg(%s)\n", i, tmpbuf, (CipherAlg == CIPHER_AES ? "AES" : "TKIP")));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d has invalid key for WPA, reset encryption to OPEN\n", i));
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ NdisZeroMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+ }
+
+ }
+ else
+ {
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ NdisZeroMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+ }
+ }
+ }
+ }
+
+ /* WdsDefaultKeyID */
+ if(RTMPGetKeyParameter("WdsDefaultKeyID", tmpbuf, 10, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ KeyIdx = (UCHAR) simple_strtol(macptr, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAd->WdsTab.WdsEntry[i].KeyIdx = (UCHAR) (KeyIdx - 1);
+ else
+ pAd->WdsTab.WdsEntry[i].KeyIdx = 0;
+
+ if ((pAd->WdsTab.WdsEntry[i].WepStatus == Ndis802_11Encryption2Enabled)
+ || (pAd->WdsTab.WdsEntry[i].WepStatus == Ndis802_11Encryption3Enabled))
+ pAd->WdsTab.WdsEntry[i].KeyIdx = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d - WdsDefaultKeyID(0~3)=%d\n", i, pAd->WdsTab.WdsEntry[i].KeyIdx));
+ }
+ }
+
+ /* WdsTxMode */
+ if (RTMPGetKeyParameter("WdsTxMode", tmpbuf, 25, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ pWdsEntry = &pAd->WdsTab.WdsEntry[i];
+
+ pWdsEntry->DesiredTransmitSetting.field.FixedTxMode =
+ RT_CfgSetFixedTxPhyMode(macptr);
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(wds%d) Tx Mode = %d\n", i,
+ pWdsEntry->DesiredTransmitSetting.field.FixedTxMode));
+ }
+ }
+
+ /* WdsTxMcs */
+ if (RTMPGetKeyParameter("WdsTxMcs", tmpbuf, 50, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ pWdsEntry = &pAd->WdsTab.WdsEntry[i];
+
+ pWdsEntry->DesiredTransmitSetting.field.MCS =
+ RT_CfgSetTxMCSProc(macptr, &pWdsEntry->bAutoTxRateSwitch);
+
+ if (pWdsEntry->DesiredTransmitSetting.field.MCS == MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(wds%d) Tx MCS = AUTO\n", i));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(wds%d) Tx MCS = %d\n", i,
+ pWdsEntry->DesiredTransmitSetting.field.MCS));
+ }
+ }
+ }
+
+ /*WdsEnable */
+ if(RTMPGetKeyParameter("WdsEnable", tmpbuf, 10, buffer, TRUE))
+ {
+ RT_802_11_WDS_ENTRY *pWdsEntry;
+ switch(simple_strtol(tmpbuf, 0, 10))
+ {
+ case 2: /* Bridge mode, DisAllow association(stop Beacon generation and Probe Req. */
+ pAd->WdsTab.Mode = WDS_BRIDGE_MODE;
+ break;
+ case 1:
+ case 3: /* Repeater mode */
+ pAd->WdsTab.Mode = WDS_REPEATER_MODE;
+ break;
+ case 4: /* Lazy mode, Auto learn wds entry by same SSID, channel, security policy */
+ for(i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ pWdsEntry = &pAd->WdsTab.WdsEntry[i];
+ if (pWdsEntry->Valid)
+ WdsEntryDel(pAd, pWdsEntry->PeerWdsAddr);
+
+ /* When Lazy mode is enabled, the all wds-link shall share the same encryption type and key material */
+ if (i > 0)
+ {
+ pAd->WdsTab.WdsEntry[i].WepStatus = pAd->WdsTab.WdsEntry[0].WepStatus;
+ pAd->WdsTab.WdsEntry[i].KeyIdx = pAd->WdsTab.WdsEntry[0].KeyIdx;
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, &pAd->WdsTab.WdsEntry[0].WdsKey, sizeof(CIPHER_KEY));
+ }
+ }
+ pAd->WdsTab.Mode = WDS_LAZY_MODE;
+ break;
+ case 0: /* Disable mode */
+ default:
+ APWdsInitialize(pAd);
+ pAd->WdsTab.Mode = WDS_DISABLE_MODE;
+ break;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WDS-Enable mode=%d\n", pAd->WdsTab.Mode));
+
+ }
+
+#ifdef WDS_VLAN_SUPPORT
+ /* WdsVlan */
+ if (RTMPGetKeyParameter("WDS_VLANID", tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->WdsTab.WdsEntry[i].VLAN_VID = simple_strtol(macptr, 0, 10);
+ pAd->WdsTab.WdsEntry[i].VLAN_Priority = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("If/wds%d - WdsVlanId=%d\n", i, pAd->WdsTab.WdsEntry[i].VLAN_VID));
+ }
+ }
+#endif /* WDS_VLAN_SUPPORT */
+}
+
+VOID WdsPrepareWepKeyFromMainBss(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+
+ /* Prepare WEP key for each wds-link if necessary */
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ /* For WDS backward compatible, refer to the WEP key of Main BSS in WEP mode */
+ if (pAd->WdsTab.WdsEntry[i].WepStatus == Ndis802_11Encryption1Enabled &&
+ pAd->WdsTab.WdsEntry[i].WdsKey.KeyLen == 0)
+ {
+ UCHAR main_bss_keyid = pAd->ApCfg.MBSSID[MAIN_MBSSID].DefaultKeyId;
+
+ if (pAd->ApCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11Encryption1Enabled &&
+ (pAd->SharedKey[MAIN_MBSSID][main_bss_keyid].KeyLen == 5 ||
+ pAd->SharedKey[MAIN_MBSSID][main_bss_keyid].KeyLen == 13))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Duplicate IF/WDS%d wep key from main_bssid \n", (UCHAR)i));
+ pAd->WdsTab.WdsEntry[i].KeyIdx = main_bss_keyid;
+ NdisMoveMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, &pAd->SharedKey[MAIN_MBSSID][main_bss_keyid], sizeof(CIPHER_KEY));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("No available wep key for IF/WDS%d, reset its encryption as OPEN \n", (UCHAR)i));
+ pAd->WdsTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ NdisZeroMemory(&pAd->WdsTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+ }
+ }
+ }
+
+}
+
+
+VOID WDS_Init(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_OS_NETDEV_OP_HOOK *pNetDevOps)
+{
+ INT index;
+ PNET_DEV pWdsNetDev;
+
+ /* sanity check to avoid redundant virtual interfaces are created */
+ if (pAd->flg_wds_init != FALSE)
+ return;
+
+ for(index = 0; index < MAX_WDS_ENTRY; index++)
+ {
+ UINT32 MC_RowID = 0, IoctlIF = 0;
+#ifdef MULTIPLE_CARD_SUPPORT
+ MC_RowID = pAd->MC_RowID;
+#endif /* MULTIPLE_CARD_SUPPORT */
+#ifdef HOSTAPD_SUPPORT
+ IoctlIF = pAd->IoctlIF;
+#endif /* HOSTAPD_SUPPORT */
+ pWdsNetDev = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_WDS, index, sizeof(PRTMP_ADAPTER), INF_WDS_DEV_NAME);
+#ifdef HOSTAPD_SUPPORT
+ pAd->IoctlIF = IoctlIF;
+#endif /* HOSTAPD_SUPPORT */
+ if (pWdsNetDev == NULL)
+ {
+ /* allocation fail, exit */
+ DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (WDS)...\n"));
+ break;
+ }
+ else
+ {
+ PMAC_TABLE_ENTRY pWdsEntry;
+ pWdsEntry = &pAd->MacTab.Content[pAd->WdsTab.WdsEntry[index].MacTabMatchWCID];
+ DBGPRINT(RT_DEBUG_TRACE, ("The new WDS interface MAC = %02X:%02X:%02X:%02X:%02X:%02X\n",
+ PRINT_MAC(pWdsEntry->Addr)));
+ }
+
+ NdisZeroMemory(&pAd->WdsTab.WdsEntry[index].WdsCounter, sizeof(WDS_COUNTER));
+ RTMP_OS_NETDEV_SET_PRIV(pWdsNetDev, pAd);
+ pAd->WdsTab.WdsEntry[index].PhyMode = 0xff;
+ pAd->WdsTab.WdsEntry[index].dev = pWdsNetDev;
+
+
+ pNetDevOps->priv_flags = INT_WDS; /* we are virtual interface */
+ pNetDevOps->needProtcted = TRUE;
+
+ /* Register this device */
+ RtmpOSNetDevAttach(pAd->OpMode, pWdsNetDev, pNetDevOps);
+
+ pAd->WdsTab.WdsEntry[index].PhyMode = 0xff;
+ pAd->WdsTab.WdsEntry[index].dev = pWdsNetDev;
+ }
+
+ pAd->flg_wds_init = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Total Allocate %d WDS interfaces!\n", index));
+
+}
+
+
+int WDS_PacketSend(
+ IN PNDIS_PACKET pSkb,
+ IN PNET_DEV dev,
+ IN RTMP_NET_PACKET_TRANSMIT Func)
+{
+ UCHAR i;
+ RTMP_ADAPTER *pAd;
+ PNDIS_PACKET pPacket = (PNDIS_PACKET) pSkb;
+
+ pAd = (PRTMP_ADAPTER) RTMP_OS_NETDEV_GET_PRIV(dev);
+
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+#endif /* RALINK_ATE */
+
+ if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+ if (!(RTMP_OS_NETDEV_STATE_RUNNING(dev)))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ if (ValidWdsEntry(pAd, i) && (pAd->WdsTab.WdsEntry[i].dev == dev))
+ {
+ RTMP_SET_PACKET_NET_DEVICE_WDS(pSkb, i);
+ SET_OS_PKT_NETDEV(pSkb, pAd->net_dev);
+
+ return Func(pSkb);
+ }
+ }
+
+
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+ return 0;
+}
+
+
+VOID WDS_Remove(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT index;
+
+ for(index = 0; index < MAX_WDS_ENTRY; index++)
+ {
+ if (pAd->WdsTab.WdsEntry[index].dev)
+ {
+ RtmpOSNetDevDetach(pAd->WdsTab.WdsEntry[index].dev);
+ RtmpOSNetDevFree(pAd->WdsTab.WdsEntry[index].dev);
+
+ /* Clear it as NULL to prevent latter access error. */
+ pAd->WdsTab.WdsEntry[index].dev = NULL;
+ }
+ }
+}
+
+
+BOOLEAN WDS_StatsGet(
+ IN PRTMP_ADAPTER pAd,
+ IN RT_CMD_STATS *pStats)
+{
+ INT WDS_apidx = 0,index;
+
+
+ /*struct net_device_stats stats; */
+ for(index = 0; index < MAX_WDS_ENTRY; index++)
+ {
+ if (pAd->WdsTab.WdsEntry[index].dev == pStats->pNetDev)
+ {
+ WDS_apidx = index;
+
+ break;
+ }
+ }
+
+ if(index >= MAX_WDS_ENTRY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("rt28xx_ioctl can not find wds I/F\n"));
+ return FALSE;
+ }
+
+ pStats->pStats = pAd->stats;
+
+ pStats->rx_packets = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.ReceivedFragmentCount.QuadPart;
+ pStats->tx_packets = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TransmittedFragmentCount.QuadPart;
+
+ pStats->rx_bytes = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.ReceivedByteCount;
+ pStats->tx_bytes = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TransmittedByteCount;
+
+ pStats->rx_errors = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxErrors;
+ pStats->tx_errors = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TxErrors;
+
+ pStats->multicast = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.MulticastReceivedFrameCount.QuadPart; /* multicast packets received */
+ pStats->collisions = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.OneCollision + pAd->WdsTab.WdsEntry[index].WdsCounter.MoreCollisions; /* Collision packets */
+
+ pStats->rx_over_errors = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxNoBuffer; /* receiver ring buff overflow */
+ pStats->rx_crc_errors = 0;/*pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error */
+ pStats->rx_frame_errors = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RcvAlignmentErrors; /* recv'd frame alignment error */
+ pStats->rx_fifo_errors = pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxNoBuffer; /* recv'r fifo overrun */
+
+ return TRUE;
+}
+
+#endif /* WDS_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_wds_inf.c b/cleopatre/devkit/mt7601udrv/ap/ap_wds_inf.c
new file mode 100644
index 0000000000..cecfe7a724
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_wds_inf.c
@@ -0,0 +1,156 @@
+
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_wds.c
+
+ Abstract:
+ Support WDS function.
+
+ Revision History:
+ Who When What
+ ------ ---------- ----------------------------------------------
+ Fonchi 02-13-2007 created
+*/
+#define RTMP_MODULE_OS
+
+#ifdef WDS_SUPPORT
+
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rt_os_net.h"
+
+NET_DEV_STATS *RT28xx_get_wds_ether_stats(
+ IN PNET_DEV net_dev);
+
+
+/* Register WDS interface */
+VOID RT28xx_WDS_Init(
+ IN VOID *pAd,
+ IN PNET_DEV net_dev)
+{
+
+ RTMP_OS_NETDEV_OP_HOOK netDevOpHook;
+
+ NdisZeroMemory((PUCHAR)&netDevOpHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
+ netDevOpHook.open = WdsVirtualIF_open;
+ netDevOpHook.stop = WdsVirtualIF_close;
+ netDevOpHook.xmit = WdsVirtualIFSendPackets;
+ netDevOpHook.ioctl = WdsVirtualIF_ioctl;
+ netDevOpHook.get_stats = RT28xx_get_wds_ether_stats;
+ NdisMoveMemory(&netDevOpHook.devAddr[0], RTMP_OS_NETDEV_GET_PHYADDR(net_dev), MAC_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("The new WDS interface MAC = %02X:%02X:%02X:%02X:%02X:%02X\n",
+ PRINT_MAC(netDevOpHook.devAddr)));
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_WDS_INIT,
+ 0, &netDevOpHook, 0);
+
+}
+
+
+INT WdsVirtualIFSendPackets(
+ IN PNDIS_PACKET pPktSrc,
+ IN PNET_DEV pDev)
+{
+
+
+ MEM_DBG_PKT_ALLOC_INC(pPktSrc);
+
+ if(!(RTMP_OS_NETDEV_STATE_RUNNING(pDev)))
+ {
+ /* the interface is down */
+ RELEASE_NDIS_PACKET(NULL, pPktSrc, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+ return WDS_PacketSend(pPktSrc, pDev, rt28xx_packet_xmit);
+}
+
+
+INT WdsVirtualIF_open(
+ IN PNET_DEV dev)
+{
+ VOID *pAd;
+#ifdef RTL865X_SOC
+ INT index;
+ unsigned int linkid;
+#endif
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: ===> VirtualIF_open\n", RTMP_OS_NETDEV_GET_DEVNAME(dev)));
+
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
+ if (VIRTUAL_IF_UP(pAd) != 0)
+ return -1;
+
+ /* increase MODULE use count */
+ RT_MOD_INC_USE_COUNT();
+
+ RTMP_OS_NETDEV_START_QUEUE(dev);
+ return 0;
+}
+
+
+INT WdsVirtualIF_close(
+ IN PNET_DEV dev)
+{
+ VOID *pAd;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: ===> VirtualIF_close\n", RTMP_OS_NETDEV_GET_DEVNAME(dev)));
+
+
+ pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+ //RTMP_OS_NETDEV_CARRIER_OFF(dev);
+ RTMP_OS_NETDEV_STOP_QUEUE(dev);
+
+ VIRTUAL_IF_DOWN(pAd);
+
+ RT_MOD_DEC_USE_COUNT();
+
+ return 0;
+}
+
+
+INT WdsVirtualIF_ioctl(
+ IN PNET_DEV net_dev,
+ IN OUT VOID *rq,
+ IN INT cmd)
+{
+ VOID *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev); /*RTMP_OS_NETDEV_GET_PRIV(pVirtualAd->RtmpDev); */
+
+/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) */
+ if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("VirtualIF_ioctl(%s)::Network is down!\n", RTMP_OS_NETDEV_GET_DEVNAME(net_dev)));
+ return -ENETDOWN;
+ }
+
+ return rt28xx_ioctl(net_dev, rq, cmd);
+}
+
+
+VOID RT28xx_WDS_Remove(
+ IN VOID *pAd)
+{
+
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_WDS_REMOVE, 0, NULL, 0);
+}
+
+#endif /* WDS_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/ap/ap_wpa.c b/cleopatre/devkit/mt7601udrv/ap/ap_wpa.c
new file mode 100644
index 0000000000..fd90e914c2
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/ap_wpa.c
@@ -0,0 +1,1614 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wpa.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 03-07-22 Initial
+ Rory Chen 04-11-29 Add WPA2PSK
+*/
+#include "rt_config.h"
+
+extern UCHAR EAPOL[];
+
+/*
+ ==========================================================================
+ Description:
+ Port Access Control Inquiry function. Return entry's Privacy and Wpastate.
+ Return:
+ pEntry
+ ==========================================================================
+*/
+MAC_TABLE_ENTRY *PACInquiry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid)
+{
+
+ MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY*)NULL;
+
+/* *Privacy = Ndis802_11PrivFilterAcceptAll; */
+/* *WpaState = AS_NOTUSE; */
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ pEntry = &(pAd->MacTab.Content[Wcid]);
+
+ /*if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[Wcid])) */
+
+ /*ASSERT(IS_ENTRY_CLIENT(&pAd->MacTab.Content[Wcid])); */
+ /*ASSERT(pEntry->Sst == SST_ASSOC); */
+
+/* *Privacy = pEntry->PrivacyFilter; */
+/* *WpaState = pEntry->WpaState; */
+ }
+
+ return pEntry;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check sanity of multicast cipher selector in RSN IE.
+ Return:
+ TRUE if match
+ FALSE otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPCheckMcast(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ UCHAR apidx;
+
+
+ ASSERT(pEntry);
+ ASSERT(pEntry->apidx < pAd->ApCfg.BssidNum);
+
+ apidx = pEntry->apidx;
+
+ pEntry->AuthMode = pAd->ApCfg.MBSSID[apidx].AuthMode;
+
+ if (eid_ptr->Len >= 6)
+ {
+ /* WPA and WPA2 format not the same in RSN_IE */
+ if (eid_ptr->Eid == IE_WPA)
+ {
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2)
+ pEntry->AuthMode = Ndis802_11AuthModeWPA;
+ else if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ pEntry->AuthMode = Ndis802_11AuthModeWPAPSK;
+
+ if (NdisEqualMemory(&eid_ptr->Octet[6], &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][6], 4))
+ return TRUE;
+ }
+ else if (eid_ptr->Eid == IE_WPA2)
+ {
+ UCHAR IE_Idx = 0;
+
+ /* When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure */
+ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ IE_Idx = 1;
+
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2)
+ pEntry->AuthMode = Ndis802_11AuthModeWPA2;
+ else if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ pEntry->AuthMode = Ndis802_11AuthModeWPA2PSK;
+
+ if (NdisEqualMemory(&eid_ptr->Octet[2], &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][2], 4))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check sanity of unicast cipher selector in RSN IE.
+ Return:
+ TRUE if match
+ FALSE otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPCheckUcast(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ PUCHAR pStaTmp;
+ USHORT Count;
+ UCHAR apidx;
+
+ ASSERT(pEntry);
+ ASSERT(pEntry->apidx < pAd->ApCfg.BssidNum);
+
+ apidx = pEntry->apidx;
+
+ pEntry->WepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus;
+
+ if (eid_ptr->Len < 16)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : the length is too short(%d) \n", eid_ptr->Len));
+ return FALSE;
+ }
+
+ /* Store STA RSN_IE capability */
+ pStaTmp = (PUCHAR)&eid_ptr->Octet[0];
+ if(eid_ptr->Eid == IE_WPA2)
+ {
+ /* skip Version(2),Multicast cipter(4) 2+4==6 */
+ /* point to number of unicast */
+ pStaTmp +=6;
+ }
+ else if (eid_ptr->Eid == IE_WPA)
+ {
+ /* skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */
+ /* point to number of unicast */
+ pStaTmp += 10;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : invalid IE=%d\n", eid_ptr->Eid));
+ return FALSE;
+ }
+
+ /* Store unicast cipher count */
+ NdisMoveMemory(&Count, pStaTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+
+ /* pointer to unicast cipher */
+ pStaTmp += sizeof(USHORT);
+
+ if (eid_ptr->Len >= 16)
+ {
+ if (eid_ptr->Eid == IE_WPA)
+ {
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ {/* multiple cipher (TKIP/CCMP) */
+
+ while (Count > 0)
+ {
+ /* TKIP */
+ if (MIX_CIPHER_WPA_TKIP_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher))
+ {
+ /* Compare if peer STA uses the TKIP as its unicast cipher */
+ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4))
+ {
+ pEntry->WepStatus = Ndis802_11Encryption2Enabled;
+ return TRUE;
+ }
+
+ /* Our AP uses the AES as the secondary cipher */
+ /* Compare if the peer STA use AES as its unicast cipher */
+ if (MIX_CIPHER_WPA_AES_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher))
+ {
+ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][16], 4))
+ {
+ pEntry->WepStatus = Ndis802_11Encryption3Enabled;
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ /* AES */
+ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4))
+ {
+ pEntry->WepStatus = Ndis802_11Encryption3Enabled;
+ return TRUE;
+ }
+ }
+
+ pStaTmp += 4;
+ Count--;
+ }
+ }
+ else
+ {/* single cipher */
+ while (Count > 0)
+ {
+ if (RTMPEqualMemory(pStaTmp , &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4))
+ return TRUE;
+
+ pStaTmp += 4;
+ Count--;
+ }
+ }
+ }
+ else if (eid_ptr->Eid == IE_WPA2)
+ {
+ UCHAR IE_Idx = 0;
+
+ /* When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure */
+ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ IE_Idx = 1;
+
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ {/* multiple cipher (TKIP/CCMP) */
+
+ while (Count > 0)
+ {
+ /* WPA2 TKIP */
+ if (MIX_CIPHER_WPA2_TKIP_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher))
+ {
+ /* Compare if peer STA uses the TKIP as its unicast cipher */
+ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4))
+ {
+ pEntry->WepStatus = Ndis802_11Encryption2Enabled;
+ return TRUE;
+ }
+
+ /* Our AP uses the AES as the secondary cipher */
+ /* Compare if the peer STA use AES as its unicast cipher */
+ if (MIX_CIPHER_WPA2_AES_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher))
+ {
+ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][12], 4))
+ {
+ pEntry->WepStatus = Ndis802_11Encryption3Enabled;
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ /* AES */
+ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4))
+ {
+ pEntry->WepStatus = Ndis802_11Encryption3Enabled;
+ return TRUE;
+ }
+ }
+
+ pStaTmp += 4;
+ Count--;
+ }
+ }
+ else
+ {/* single cipher */
+ while (Count > 0)
+ {
+ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4))
+ return TRUE;
+
+ pStaTmp += 4;
+ Count--;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Check invalidity of authentication method selection in RSN IE.
+ Return:
+ TRUE if match
+ FALSE otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPCheckAKM(PUCHAR sta_akm, PUCHAR ap_rsn_ie, INT iswpa2)
+{
+ PUCHAR pTmp;
+ USHORT Count;
+
+ pTmp = ap_rsn_ie;
+
+ if(iswpa2)
+ /* skip Version(2),Multicast cipter(4) 2+4==6 */
+ pTmp +=6;
+ else
+ /*skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */
+ pTmp += 10;/*point to number of unicast */
+
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ pTmp += sizeof(USHORT);/*pointer to unicast cipher */
+
+ /* Skip all unicast cipher suite */
+ while (Count > 0)
+ {
+ /* Skip OUI */
+ pTmp += 4;
+ Count--;
+ }
+
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ pTmp += sizeof(USHORT);/*pointer to AKM cipher */
+ while (Count > 0)
+ {
+ /*rtmp_hexdump(RT_DEBUG_TRACE,"MBSS WPA_IE AKM ",pTmp,4); */
+ if(RTMPEqualMemory(sta_akm,pTmp,4))
+ return TRUE;
+ else
+ {
+ pTmp += 4;
+ Count--;
+ }
+ }
+ return FALSE;/* do not match the AKM */
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Check sanity of authentication method selector in RSN IE.
+ Return:
+ TRUE if match
+ FALSE otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPCheckAUTH(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ PUCHAR pStaTmp;
+ USHORT Count;
+ UCHAR apidx;
+
+ ASSERT(pEntry);
+ ASSERT(pEntry->apidx < pAd->ApCfg.BssidNum);
+
+ apidx = pEntry->apidx;
+
+ if (eid_ptr->Len < 16)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPCheckAUTH ==> WPAIE len is too short(%d) \n", eid_ptr->Len));
+ return FALSE;
+ }
+
+ /* Store STA RSN_IE capability */
+ pStaTmp = (PUCHAR)&eid_ptr->Octet[0];
+ if(eid_ptr->Eid == IE_WPA2)
+ {
+ /* skip Version(2),Multicast cipter(4) 2+4==6 */
+ /* point to number of unicast */
+ pStaTmp +=6;
+ }
+ else if (eid_ptr->Eid == IE_WPA)
+ {
+ /* skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */
+ /* point to number of unicast */
+ pStaTmp += 10;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPCheckAUTH ==> Unknown WPAIE, WPAIE=%d\n", eid_ptr->Eid));
+ return FALSE;
+ }
+
+ /* Store unicast cipher count */
+ NdisMoveMemory(&Count, pStaTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ /* pointer to unicast cipher */
+ pStaTmp += sizeof(USHORT);
+
+ /* Skip all unicast cipher suite */
+ while (Count > 0)
+ {
+ /* Skip OUI */
+ pStaTmp += 4;
+ Count--;
+ }
+
+ /* Store AKM count */
+ NdisMoveMemory(&Count, pStaTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+
+ /*pointer to AKM cipher */
+ pStaTmp += sizeof(USHORT);
+
+ if (eid_ptr->Len >= 16)
+ {
+ if (eid_ptr->Eid == IE_WPA)
+ {
+ while (Count > 0)
+ {
+ if (RTMPCheckAKM(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][0],0))
+ return TRUE;
+
+ pStaTmp += 4;
+ Count--;
+ }
+ }
+ else if (eid_ptr->Eid == IE_WPA2)
+ {
+ UCHAR IE_Idx = 0;
+
+ /* When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure */
+ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ IE_Idx = 1;
+
+ while (Count > 0)
+ {
+ if (RTMPCheckAKM(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][0],1))
+ return TRUE;
+
+ pStaTmp += 4;
+ Count--;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check validity of the received RSNIE.
+
+ Return:
+ status code
+ ==========================================================================
+*/
+UINT APValidateRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR pRsnIe,
+ IN UCHAR rsnie_len)
+{
+ UINT StatusCode = MLME_SUCCESS;
+ PEID_STRUCT eid_ptr;
+ INT apidx;
+ PMULTISSID_STRUCT pMbss;
+
+ if (rsnie_len == 0)
+ return MLME_SUCCESS;
+
+ eid_ptr = (PEID_STRUCT)pRsnIe;
+ if ((eid_ptr->Len + 2) != rsnie_len)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : the len is invalid !!!\n"));
+ return MLME_UNSPECIFY_FAIL;
+ }
+
+ apidx = pEntry->apidx;
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+#ifdef WAPI_SUPPORT
+ if (eid_ptr->Eid == IE_WAPI)
+ return MLME_SUCCESS;
+#endif /* WAPI_SUPPORT */
+
+ /* check group cipher */
+ if (!RTMPCheckMcast(pAd, eid_ptr, pEntry))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : invalid group cipher !!!\n"));
+ StatusCode = MLME_INVALID_GROUP_CIPHER;
+ }
+ /* Check pairwise cipher */
+ else if (!RTMPCheckUcast(pAd, eid_ptr, pEntry))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : invalid pairwise cipher !!!\n"));
+ StatusCode = MLME_INVALID_PAIRWISE_CIPHER;
+ }
+ /* Check AKM */
+ else if (!RTMPCheckAUTH(pAd, eid_ptr, pEntry))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : invalid AKM !!!\n"));
+ StatusCode = MLME_INVALID_AKMP;
+ }
+
+ if (StatusCode != MLME_SUCCESS)
+ {
+ /* send wireless event - for RSN IE sanity check fail */
+ RTMPSendWirelessEvent(pAd, IW_RSNIE_SANITY_FAIL_EVENT_FLAG, pEntry->Addr, 0, 0);
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : invalid status code(%d) !!!\n", __FUNCTION__, StatusCode));
+ }
+ else
+ {
+ UCHAR CipherAlg = CIPHER_NONE;
+
+ if (pEntry->WepStatus == Ndis802_11Encryption1Enabled)
+ CipherAlg = CIPHER_WEP64;
+ else if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+ CipherAlg = CIPHER_TKIP;
+ else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ CipherAlg = CIPHER_AES;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : (AID#%d WepStatus=%s)\n", __FUNCTION__, pEntry->Aid, CipherName[CipherAlg]));
+ }
+
+
+
+ return StatusCode;
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Function to handle countermeasures active attack. Init 60-sec timer if necessary.
+ Return:
+ ==========================================================================
+*/
+VOID HandleCounterMeasure(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ INT i;
+ BOOLEAN Cancelled;
+
+ if (!pEntry)
+ return;
+
+ /* Todo by AlbertY - Not support currently in ApClient-link */
+ if (IS_ENTRY_APCLI(pEntry))
+ return;
+
+ /* if entry not set key done, ignore this RX MIC ERROR */
+ if ((pEntry->WpaState < AS_PTKINITDONE) || (pEntry->GTKState != REKEY_ESTABLISHED))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HandleCounterMeasure ===> \n"));
+
+ /* record which entry causes this MIC error, if this entry sends disauth/disassoc, AP doesn't need to log the CM */
+ pEntry->CMTimerRunning = TRUE;
+ pAd->ApCfg.MICFailureCounter++;
+
+ /* send wireless event - for MIC error */
+ RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pEntry->Addr, 0, 0);
+
+ if (pAd->ApCfg.CMTimerRunning == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>> \n"));
+
+ /* send wireless event - for counter measures */
+ RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pEntry->Addr, 0, 0);
+ ApLogEvent(pAd, pEntry->Addr, EVENT_COUNTER_M);
+
+ /* renew GTK */
+ GenRandom(pAd, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, pAd->ApCfg.MBSSID[pEntry->apidx].GNonce);
+
+ /* Cancel CounterMeasure Timer */
+ RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled);
+ pAd->ApCfg.CMTimerRunning = FALSE;
+
+ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ /* happened twice within 60 sec, AP SENDS disaccociate all associated STAs. All STA's transition to State 2 */
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]))
+ {
+ MlmeDeAuthAction(pAd, &pAd->MacTab.Content[i], REASON_MIC_FAILURE, FALSE);
+ }
+ }
+
+ /* Further, ban all Class 3 DATA transportation for a period 0f 60 sec */
+ /* disallow new association , too */
+ pAd->ApCfg.BANClass3Data = TRUE;
+
+ /* check how many entry left... should be zero */
+ /*pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations = pAd->MacTab.Size; */
+ /*DBGPRINT(RT_DEBUG_TRACE, ("GKeyDoneStations=%d \n", pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations)); */
+ }
+
+ RTMPSetTimer(&pAd->ApCfg.CounterMeasureTimer, 60 * MLME_TASK_EXEC_INTV * MLME_TASK_EXEC_MULTIPLE);
+ pAd->ApCfg.CMTimerRunning = TRUE;
+ pAd->ApCfg.PrevaMICFailTime = pAd->ApCfg.aMICFailTime;
+ RTMP_GetCurrentSystemTime(&pAd->ApCfg.aMICFailTime);
+}
+
+/*
+ ==========================================================================
+ Description:
+ countermeasures active attack timer execution
+ Return:
+ ==========================================================================
+*/
+VOID CMTimerExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ UINT i,j=0;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+
+ pAd->ApCfg.BANClass3Data = FALSE;
+ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])
+ && (pAd->MacTab.Content[i].CMTimerRunning == TRUE))
+ {
+ pAd->MacTab.Content[i].CMTimerRunning =FALSE;
+ j++;
+ }
+ }
+ if (j > 1)
+ DBGPRINT(RT_DEBUG_ERROR, ("Find more than one entry which generated MIC Fail .. \n"));
+
+ pAd->ApCfg.CMTimerRunning = FALSE;
+}
+
+VOID WPARetryExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)FunctionContext;
+
+ if ((pEntry) && IS_ENTRY_CLIENT(pEntry))
+ {
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pEntry->pAd;
+
+ pEntry->ReTryCounter++;
+ DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec---> ReTryCounter=%d, WpaState=%d \n", pEntry->ReTryCounter, pEntry->WpaState));
+
+ switch (pEntry->AuthMode)
+ {
+ case Ndis802_11AuthModeWPA:
+ case Ndis802_11AuthModeWPAPSK:
+ case Ndis802_11AuthModeWPA2:
+ case Ndis802_11AuthModeWPA2PSK:
+ /* 1. GTK already retried, give up and disconnect client. */
+ if (pEntry->ReTryCounter > (GROUP_MSG1_RETRY_TIMER_CTR + 1))
+ {
+ /* send wireless event - for group key handshaking timeout */
+ RTMPSendWirelessEvent(pAd, IW_GROUP_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Group Key HS exceed retry count, Disassociate client, pEntry->ReTryCounter %d\n", pEntry->ReTryCounter));
+ MlmeDeAuthAction(pAd, pEntry, REASON_GROUP_KEY_HS_TIMEOUT, FALSE);
+ }
+ /* 2. Retry GTK. */
+ else if (pEntry->ReTryCounter > GROUP_MSG1_RETRY_TIMER_CTR)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry 2-way group-key Handshake \n"));
+ if (pEntry->GTKState == REKEY_NEGOTIATING)
+ {
+ WPAStart2WayGroupHS(pAd, pEntry);
+ RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
+ }
+ }
+ /* 3. 4-way message 1 retried more than three times. Disconnect client */
+ else if (pEntry->ReTryCounter > (PEER_MSG1_RETRY_TIMER_CTR + 3))
+ {
+ /* send wireless event - for pairwise key handshaking timeout */
+ RTMPSendWirelessEvent(pAd, IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::MSG1 timeout, pEntry->ReTryCounter = %d\n", pEntry->ReTryCounter));
+ MlmeDeAuthAction(pAd, pEntry, REASON_4_WAY_TIMEOUT, FALSE);
+ }
+ /* 4. Retry 4 way message 1, the last try, the timeout is 3 sec for EAPOL-Start */
+ else if (pEntry->ReTryCounter == (PEER_MSG1_RETRY_TIMER_CTR + 3))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Retry MSG1, the last try\n"));
+ WPAStart4WayHS(pAd , pEntry, PEER_MSG3_RETRY_EXEC_INTV);
+ }
+ /* 4. Retry 4 way message 1 */
+ else if (pEntry->ReTryCounter < (PEER_MSG1_RETRY_TIMER_CTR + 3))
+ {
+ if ((pEntry->WpaState == AS_PTKSTART) || (pEntry->WpaState == AS_INITPSK) || (pEntry->WpaState == AS_INITPMK))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry MSG1 of 4-way Handshake\n"));
+ WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+#ifdef APCLI_SUPPORT
+ else if ((pEntry) && IS_ENTRY_APCLI(pEntry))
+ {
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
+ {
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pEntry->pAd;
+
+ if (pEntry->MatchAPCLITabIdx < MAX_APCLI_NUM)
+ {
+ UCHAR ifIndex = pEntry->MatchAPCLITabIdx;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] startdown.\n", __FUNCTION__, ifIndex));
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex);
+ }
+ }
+ }
+#endif /* APCLI_SUPPORT */
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Timer execution function for periodically updating group key.
+ Return:
+ ==========================================================================
+*/
+VOID GREKEYPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ UINT i, apidx;
+ ULONG temp_counter = 0;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+ PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) SystemSpecific3;
+ PMULTISSID_STRUCT pMbss = NULL;
+
+
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ if (&pAd->ApCfg.MBSSID[apidx].REKEYTimer == pTimer)
+ break;
+ }
+
+ if (apidx == pAd->ApCfg.BssidNum)
+ return;
+ else
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+ if (pMbss->AuthMode < Ndis802_11AuthModeWPA ||
+ pMbss->AuthMode > Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ return;
+
+ if ((pMbss->WPAREKEY.ReKeyMethod == TIME_REKEY) && (pMbss->REKEYCOUNTER < 0xffffffff))
+ temp_counter = (++pMbss->REKEYCOUNTER);
+ /* REKEYCOUNTER is incremented every MCAST packets transmitted, */
+ /* But the unit of Rekeyinterval is 1K packets */
+ else if (pMbss->WPAREKEY.ReKeyMethod == PKT_REKEY)
+ temp_counter = pMbss->REKEYCOUNTER/1000;
+ else
+ {
+ return;
+ }
+
+ if (temp_counter > (pMbss->WPAREKEY.ReKeyInterval))
+ {
+ pMbss->REKEYCOUNTER = 0;
+ pMbss->RekeyCountDown = 3;
+ DBGPRINT(RT_DEBUG_TRACE, ("Rekey Interval Excess, GKeyDoneStations=%d\n", pMbss->StaCount));
+
+ /* take turn updating different groupkey index, */
+ if ((pMbss->StaCount) > 0)
+ {
+ /* change key index */
+ pMbss->DefaultKeyId = (pMbss->DefaultKeyId == 1) ? 2 : 1;
+
+ /* Generate GNonce randomly */
+ GenRandom(pAd, pMbss->Bssid, pMbss->GNonce);
+
+ /* Update GTK */
+ WpaDeriveGTK(pMbss->GMK,
+ (UCHAR*)pMbss->GNonce,
+ pMbss->Bssid, pMbss->GTK, LEN_TKIP_GTK);
+
+ /* Process 2-way handshaking */
+ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+
+ pEntry = &pAd->MacTab.Content[i];
+ if (IS_ENTRY_CLIENT(pEntry) &&
+ (pEntry->WpaState == AS_PTKINITDONE) &&
+ (pEntry->apidx == apidx))
+ {
+ pEntry->GTKState = REKEY_NEGOTIATING;
+
+ WPAStart2WayGroupHS(pAd, pEntry);
+ DBGPRINT(RT_DEBUG_TRACE, ("Rekey interval excess, Update Group Key for %x %x %x %x %x %x , DefaultKeyId= %x \n",\
+ pEntry->Addr[0],pEntry->Addr[1],\
+ pEntry->Addr[2],pEntry->Addr[3],\
+ pEntry->Addr[4],pEntry->Addr[5],\
+ pMbss->DefaultKeyId));
+ }
+ }
+ }
+ }
+
+ /* Use countdown to ensure the 2-way handshaking had completed */
+ if (pMbss->RekeyCountDown > 0)
+ {
+ pMbss->RekeyCountDown--;
+ if (pMbss->RekeyCountDown == 0)
+ {
+ USHORT Wcid;
+
+ /* Get a specific WCID to record this MBSS key attribute */
+ GET_GroupKey_WCID(pAd, Wcid, apidx);
+
+ /* Install shared key table */
+ WPAInstallSharedKey(pAd,
+ pMbss->GroupKeyWepStatus,
+ apidx,
+ pMbss->DefaultKeyId,
+ Wcid,
+ TRUE,
+ pMbss->GTK,
+ LEN_TKIP_GTK);
+ }
+ }
+
+}
+
+
+#ifdef DOT1X_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ Sending EAP Req. frame to station in authenticating state.
+ These frames come from Authenticator deamon.
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ pPacket Pointer to outgoing EAP frame body + 8023 Header
+ Len length of pPacket
+
+ Return Value:
+ None
+ ========================================================================
+*/
+VOID WpaSend(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pPacket,
+ IN ULONG Len)
+{
+ PEAP_HDR pEapHdr;
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR Header802_3[LENGTH_802_3];
+ MAC_TABLE_ENTRY *pEntry;
+ PUCHAR pData;
+
+
+ NdisMoveMemory(Addr, pPacket, 6);
+ NdisMoveMemory(Header802_3, pPacket, LENGTH_802_3);
+ pEapHdr = (EAP_HDR*)(pPacket + LENGTH_802_3);
+ pData = (pPacket + LENGTH_802_3);
+
+ if ((pEntry = MacTableLookup(pAdapter, Addr)) == NULL)
+ {
+
+ return;
+ }
+
+ /* Send EAP frame to STA */
+ if (((pEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pEapHdr->ProType != EAPOLKey)) ||
+ (pAdapter->ApCfg.MBSSID[pEntry->apidx].IEEE8021X == TRUE))
+ RTMPToWirelessSta(pAdapter,
+ pEntry,
+ Header802_3,
+ LENGTH_802_3,
+ pData,
+ Len - LENGTH_802_3,
+ (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
+
+
+ if (RTMPEqualMemory((pPacket+12), EAPOL, 2))
+ {
+ switch (pEapHdr->code)
+ {
+ case EAP_CODE_REQUEST:
+ if ((pEntry->WpaState >= AS_PTKINITDONE) && (pEapHdr->ProType == EAPPacket))
+ {
+ pEntry->WpaState = AS_AUTHENTICATION;
+ DBGPRINT(RT_DEBUG_TRACE, ("Start to re-authentication by 802.1x daemon\n"));
+ }
+ break;
+
+ /* After receiving EAP_SUCCESS, trigger state machine */
+ case EAP_CODE_SUCCESS:
+ if ((pEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pEapHdr->ProType != EAPOLKey))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Send EAP_CODE_SUCCESS\n\n"));
+ if (pEntry->Sst == SST_ASSOC)
+ {
+ pEntry->WpaState = AS_INITPMK;
+ /* Only set the expire and counters */
+ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+ WPAStart4WayHS(pAdapter, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
+ }
+ }
+ else
+ {
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ pEntry->WpaState = AS_PTKINITDONE;
+ pAdapter->ApCfg.MBSSID[pEntry->apidx].PortSecured = WPA_802_1X_PORT_SECURED;
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+#ifdef WSC_AP_SUPPORT
+ if (pAdapter->ApCfg.MBSSID[pEntry->apidx].WscControl.WscConfMode != WSC_DISABLE)
+ WscInformFromWPA(pEntry);
+#endif /* WSC_AP_SUPPORT */
+ DBGPRINT(RT_DEBUG_TRACE,("IEEE8021X-WEP : Send EAP_CODE_SUCCESS\n\n"));
+ }
+ break;
+
+ case EAP_CODE_FAILURE:
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Send Deauth, Reason : REASON_NO_LONGER_VALID\n"));
+ MlmeDeAuthAction(pAdapter, pEntry, REASON_NO_LONGER_VALID, FALSE);
+ }
+}
+
+VOID RTMPAddPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PUCHAR pAddr,
+ IN UCHAR *PMKID,
+ IN UCHAR *PMK)
+{
+ INT i, CacheIdx;
+
+ /* Update PMKID status */
+ if ((CacheIdx = RTMPSearchPMKIDCache(pAd, apidx, pAddr)) != -1)
+ {
+ NdisGetSystemUpTime(&(pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[CacheIdx].RefreshTime));
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[CacheIdx].PMKID, PMKID, LEN_PMKID);
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[CacheIdx].PMK, PMK, PMK_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddPMKIDCache update %02x:%02x:%02x:%02x:%02x:%02x cache(%d) from IF(ra%d)\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], CacheIdx, apidx));
+
+ return;
+ }
+
+ /* Add a new PMKID */
+ for (i = 0; i < MAX_PMKID_COUNT; i++)
+ {
+ if (!pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].Valid)
+ {
+ pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].Valid = TRUE;
+ NdisGetSystemUpTime(&(pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].RefreshTime));
+ COPY_MAC_ADDR(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].MAC, pAddr);
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].PMKID, PMKID, LEN_PMKID);
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].PMK, PMK, PMK_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddPMKIDCache add %02x:%02x:%02x:%02x:%02x:%02x cache(%d) from IF(ra%d)\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], i, apidx));
+ break;
+ }
+ }
+
+ if (i == MAX_PMKID_COUNT)
+ {
+ ULONG timestamp = 0, idx = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddPMKIDCache(IF(%d) Cache full\n", apidx));
+ for (i = 0; i < MAX_PMKID_COUNT; i++)
+ {
+ if (pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].Valid)
+ {
+ if (((timestamp == 0) && (idx == 0)) || ((timestamp != 0) && timestamp < pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].RefreshTime))
+ {
+ timestamp = pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].RefreshTime;
+ idx = i;
+ }
+ }
+ }
+ pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[idx].Valid = TRUE;
+ NdisGetSystemUpTime(&(pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[idx].RefreshTime));
+ COPY_MAC_ADDR(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[idx].MAC, pAddr);
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[idx].PMKID, PMKID, LEN_PMKID);
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[idx].PMK, PMK, PMK_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddPMKIDCache add %02x:%02x:%02x:%02x:%02x:%02x cache(%ld) from IF(ra%d)\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], idx, apidx));
+ }
+}
+
+INT RTMPSearchPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PUCHAR pAddr)
+{
+ INT i = 0;
+
+ for (i = 0; i < MAX_PMKID_COUNT; i++)
+ {
+ if ((pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].Valid)
+ && MAC_ADDR_EQUAL(&pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[i].MAC, pAddr))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSearchPMKIDCache %02x:%02x:%02x:%02x:%02x:%02x cache(%d) from IF(ra%d)\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], i, apidx));
+ break;
+ }
+ }
+
+ if (i == MAX_PMKID_COUNT)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSearchPMKIDCache - IF(%d) not found\n", apidx));
+ return -1;
+ }
+
+ return i;
+}
+
+VOID RTMPDeletePMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN INT idx)
+{
+ PAP_BSSID_INFO pInfo = &pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[idx];
+
+ if (pInfo->Valid)
+ {
+ pInfo->Valid = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPDeletePMKIDCache(IF(%d), del PMKID CacheIdx=%d\n", apidx, idx));
+ }
+}
+
+VOID RTMPMaintainPMKIDCache(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ ULONG Now;
+ for (i = 0; i < MAX_MBSSID_NUM(pAd); i++)
+ {
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[i];
+
+ for (j = 0; j < MAX_PMKID_COUNT; j++)
+ {
+ PAP_BSSID_INFO pBssInfo = &pMbss->PMKIDCache.BSSIDInfo[j];
+
+ NdisGetSystemUpTime(&Now);
+
+ if ((pBssInfo->Valid)
+ && /*((Now - pBssInfo->RefreshTime) >= pMbss->PMKCachePeriod)*/
+ (RTMP_TIME_AFTER(Now, (pBssInfo->RefreshTime + pMbss->PMKCachePeriod))))
+ {
+ RTMPDeletePMKIDCache(pAd, i, j);
+ }
+ }
+ }
+}
+#endif /* DOT1X_SUPPORT */
+
+VOID RTMPGetTxTscFromAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx,
+ OUT PUCHAR pTxTsc)
+{
+ USHORT Wcid;
+ USHORT offset;
+ UCHAR IvEiv[8];
+ int i;
+
+ /* Sanity check of apidx */
+ if (apidx >= MAX_MBSSID_NUM(pAd))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPGetTxTscFromAsic : invalid apidx(%d)\n", apidx));
+ return;
+ }
+
+ /* Initial value */
+ NdisZeroMemory(IvEiv, 8);
+ NdisZeroMemory(pTxTsc, 6);
+
+ /* Get apidx for this BSSID */
+ GET_GroupKey_WCID(pAd, Wcid, apidx);
+
+ /* When the group rekey action is triggered, a count-down(3 seconds) is started.
+ During the count-down, use the initial PN as TSC.
+ Otherwise, get the IVEIV from ASIC. */
+ if (pAd->ApCfg.MBSSID[apidx].RekeyCountDown > 0)
+ {
+ /*
+ 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. */
+ IvEiv[0] = 1;
+ }
+ else
+ {
+ UINT32 temp1, temp2;
+ /* Read IVEIV from Asic */
+ offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
+
+ /* Use Read32 to avoid endian problem */
+ RTMP_IO_READ32(pAd, offset, &temp1);
+ RTMP_IO_READ32(pAd, offset+4, &temp2);
+ for ( i=0; i<4; i++)
+ {
+ IvEiv[i] = (UCHAR)(temp1 >> (i*8));
+ IvEiv[i+4] = (UCHAR)(temp2 >> (i*8));
+ }
+ }
+
+ /* Record current TxTsc */
+ if (pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ { /* AES */
+ *pTxTsc = IvEiv[0];
+ *(pTxTsc+1) = IvEiv[1];
+ *(pTxTsc+2) = IvEiv[4];
+ *(pTxTsc+3) = IvEiv[5];
+ *(pTxTsc+4) = IvEiv[6];
+ *(pTxTsc+5) = IvEiv[7];
+ }
+ else
+ { /* TKIP */
+ *pTxTsc = IvEiv[2];
+ *(pTxTsc+1) = IvEiv[0];
+ *(pTxTsc+2) = IvEiv[4];
+ *(pTxTsc+3) = IvEiv[5];
+ *(pTxTsc+4) = IvEiv[6];
+ *(pTxTsc+5) = IvEiv[7];
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPGetTxTscFromAsic : WCID(%d) TxTsc 0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x \n",
+ Wcid, *pTxTsc, *(pTxTsc+1), *(pTxTsc+2), *(pTxTsc+3), *(pTxTsc+4), *(pTxTsc+5)));
+
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set group re-key timer
+
+ Return:
+
+ ==========================================================================
+*/
+VOID WPA_APSetGroupRekeyAction(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT8 apidx = 0;
+
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+ if ((pMbss->WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pMbss->WepStatus == Ndis802_11Encryption3Enabled) ||
+ (pMbss->WepStatus == Ndis802_11Encryption4Enabled))
+ {
+ /* Group rekey related */
+ if ((pMbss->WPAREKEY.ReKeyInterval != 0)
+ && ((pMbss->WPAREKEY.ReKeyMethod == TIME_REKEY) || (
+ pMbss->WPAREKEY.ReKeyMethod == PKT_REKEY)))
+ {
+ /* Regularly check the timer */
+ if (pMbss->REKEYTimerRunning == FALSE)
+ {
+ RTMPSetTimer(&pMbss->REKEYTimer, GROUP_KEY_UPDATE_EXEC_INTV);
+
+ pMbss->REKEYTimerRunning = TRUE;
+ pMbss->REKEYCOUNTER = 0;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, (" %s : Group rekey method= %ld , interval = 0x%lx\n",
+ __FUNCTION__, pMbss->WPAREKEY.ReKeyMethod,
+ pMbss->WPAREKEY.ReKeyInterval));
+ }
+ else
+ pMbss->REKEYTimerRunning = FALSE;
+ }
+ }
+}
+
+#ifdef QOS_DLS_SUPPORT
+VOID RTMPHandleSTAKey(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ extern UCHAR OUI_WPA2_WEP40[];
+ ULONG FrameLen = 0;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ UCHAR *mpool;
+ PEAPOL_PACKET pOutPacket;
+ PEAPOL_PACKET pSTAKey;
+ PHEADER_802_11 pHeader;
+ UCHAR Offset = 0;
+ ULONG MICMsgLen;
+ UCHAR DA[MAC_ADDR_LEN];
+ UCHAR Key_Data[512];
+ UCHAR key_length;
+ UCHAR mic[LEN_KEY_DESC_MIC];
+ UCHAR rcv_mic[LEN_KEY_DESC_MIC];
+ UCHAR digest[80];
+ UCHAR temp[64];
+ PMAC_TABLE_ENTRY pDaEntry;
+
+ /*Benson add for big-endian 20081016--> */
+ KEY_INFO peerKeyInfo;
+ /*Benson add 20081016 <-- */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleSTAKey\n"));
+
+ if (!pEntry)
+ return;
+
+ if ((pEntry->WpaState != AS_PTKINITDONE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here"));
+ return;
+ }
+
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ /* QoS control field (2B) is took off */
+/* if (pHeader->FC.SubType & 0x08) */
+/* Offset += 2; */
+
+ pSTAKey = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset];
+ /*Benson add for big-endian 20081016--> */
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pSTAKey->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+ *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
+ /*Benson add 20081016 <-- */
+
+ /* Check Replay Counter */
+ if (!RTMPEqualMemory(pSTAKey->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in STAKey handshake!! \n"));
+ DBGPRINT(RT_DEBUG_ERROR, ("Receive : %d %d %d %d \n",
+ pSTAKey->KeyDesc.ReplayCounter[0],
+ pSTAKey->KeyDesc.ReplayCounter[1],
+ pSTAKey->KeyDesc.ReplayCounter[2],
+ pSTAKey->KeyDesc.ReplayCounter[3]));
+ DBGPRINT(RT_DEBUG_ERROR, ("Current : %d %d %d %d \n",
+ pEntry->R_Counter[4],pEntry->R_Counter[5],
+ pEntry->R_Counter[6],pEntry->R_Counter[7]));
+ return;
+ }
+
+ /* Check MIC, if not valid, discard silently */
+ NdisMoveMemory(DA, &pSTAKey->KeyDesc.KeyData[6], MAC_ADDR_LEN);
+
+ if (peerKeyInfo.KeyMic && peerKeyInfo.Secure && peerKeyInfo.Request)/*Benson add for big-endian 20081016 --> */
+ {
+ pEntry->bDlsInit = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("STAKey Initiator: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]));
+ }
+
+
+ MICMsgLen = pSTAKey->Body_Len[1] | ((pSTAKey->Body_Len[0]<<8) && 0xff00);
+ MICMsgLen += LENGTH_EAPOL_H;
+ if (MICMsgLen > (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Receive wrong format EAPOL packets \n"));
+ return;
+ }
+
+ /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */
+ NdisZeroMemory(temp, 64);
+ NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, sizeof(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK));
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+
+ WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, temp,
+ pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK);
+ DBGPRINT(RT_DEBUG_TRACE, ("PTK-%x %x %x %x %x %x %x %x \n",
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7]));
+
+
+ /* Record the received MIC for check later */
+ NdisMoveMemory(rcv_mic, pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+ {
+ RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, mic, MD5_DIGEST_SIZE);
+ }
+ else
+ {
+ RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, digest, SHA1_DIGEST_SIZE);
+ NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+ }
+
+ if (!RTMPEqualMemory(rcv_mic, mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in STAKey handshake!! \n"));
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in STAKey handshake!! \n"));
+
+ /* Receive init STA's STAKey Message-2, and terminate the handshake */
+ /*if (pEntry->bDlsInit && !pSTAKey->KeyDesc.KeyInfo.Request) */
+ if (pEntry->bDlsInit && !peerKeyInfo.Request) /*Benson add for big-endian 20081016 --> */
+ {
+ pEntry->bDlsInit = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive init STA's STAKey Message-2, STAKey handshake finished \n"));
+ return;
+ }
+
+ /* Receive init STA's STAKey Message-2, and terminate the handshake */
+ if (RTMPEqualMemory(&pSTAKey->KeyDesc.KeyData[2], OUI_WPA2_WEP40, 3))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("Receive a STAKey message which not support currently, just drop it \n"));
+ return;
+ }
+
+ do
+ {
+ pDaEntry = MacTableLookup(pAd, DA);
+ if (!pDaEntry)
+ break;
+
+ if ((pDaEntry->WpaState != AS_PTKINITDONE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here \n"));
+ break;
+ }
+
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); /* allocate memory */
+ if(pOutBuffer == NULL)
+ break;
+
+ MAKE_802_3_HEADER(Header802_3, pDaEntry->Addr, pAd->ApCfg.MBSSID[pDaEntry->apidx].Bssid, EAPOL);
+
+ /* Increment replay counter by 1 */
+ ADD_ONE_To_64BIT_VAR(pDaEntry->R_Counter);
+
+ /* Allocate memory for output */
+ os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER);
+ if (mpool == NULL)
+ {
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__));
+ return;
+ }
+
+ pOutPacket = (PEAPOL_PACKET)mpool;
+ NdisZeroMemory(pOutPacket, TX_EAPOL_BUFFER);
+
+ /* 0. init Packet and Fill header */
+ pOutPacket->ProVer = EAPOL_VER;
+ pOutPacket->ProType = EAPOLKey;
+ pOutPacket->Body_Len[1] = 0x5f;
+
+ /* 1. Fill replay counter */
+/* NdisMoveMemory(pDaEntry->R_Counter, pAd->ApCfg.R_Counter, sizeof(pDaEntry->R_Counter)); */
+ NdisMoveMemory(pOutPacket->KeyDesc.ReplayCounter, pDaEntry->R_Counter, LEN_KEY_DESC_REPLAY);
+
+ /* 2. Fill key version, keyinfo, key len */
+ pOutPacket->KeyDesc.KeyInfo.KeyDescVer= GROUP_KEY;
+ pOutPacket->KeyDesc.KeyInfo.KeyType = GROUPKEY;
+ pOutPacket->KeyDesc.KeyInfo.Install = 1;
+ pOutPacket->KeyDesc.KeyInfo.KeyAck = 1;
+ pOutPacket->KeyDesc.KeyInfo.KeyMic = 1;
+ pOutPacket->KeyDesc.KeyInfo.Secure = 1;
+ pOutPacket->KeyDesc.KeyInfo.EKD_DL = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("STAKey handshake for peer STA %02x:%02x:%02x:%02x:%02x:%02x\n",
+ DA[0], DA[1], DA[2], DA[3], DA[4], DA[5]));
+
+ if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ pOutPacket->KeyDesc.Type = WPA1_KEY_DESC;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n"));
+ }
+ else if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pOutPacket->KeyDesc.Type = WPA2_KEY_DESC;
+ pOutPacket->KeyDesc.KeyDataLen[1] = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n"));
+ }
+
+ pOutPacket->KeyDesc.KeyLength[1] = LEN_TKIP_TK;
+ pOutPacket->KeyDesc.KeyDataLen[1] = LEN_TKIP_TK;
+ pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_TKIP;
+ if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ pOutPacket->KeyDesc.KeyLength[1] = LEN_AES_TK;
+ pOutPacket->KeyDesc.KeyDataLen[1] = LEN_AES_TK;
+ pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_AES;
+ }
+
+ /* Key Data Encapsulation format, use Ralink OUI to distinguish proprietary and standard. */
+ Key_Data[0] = 0xDD;
+ Key_Data[1] = 0x00; /* Length (This field will be filled later) */
+ Key_Data[2] = 0x00; /* OUI */
+ Key_Data[3] = 0x0C; /* OUI */
+ Key_Data[4] = 0x43; /* OUI */
+ Key_Data[5] = 0x02; /* Data Type (STAKey Key Data Encryption) */
+
+ /* STAKey Data Encapsulation format */
+ Key_Data[6] = 0x00; /*Reserved */
+ Key_Data[7] = 0x00; /*Reserved */
+
+ /* STAKey MAC address */
+ NdisMoveMemory(&Key_Data[8], pEntry->Addr, MAC_ADDR_LEN); /* initiator MAC address */
+
+ /* STAKey (Handle the difference between TKIP and AES-CCMP) */
+ if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Key_Data[1] = 0x1E; /* 4+2+6+16(OUI+Reserved+STAKey_MAC_Addr+STAKey) */
+ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_AES_TK);
+ }
+ else
+ {
+ Key_Data[1] = 0x2E; /* 4+2+6+32(OUI+Reserved+STAKey_MAC_Addr+STAKey) */
+ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_TK);
+ NdisMoveMemory(&Key_Data[14+LEN_TK], pEntry->PairwiseKey.TxMic, LEN_TKIP_MIC);
+ NdisMoveMemory(&Key_Data[14+LEN_TK+LEN_TKIP_MIC], pEntry->PairwiseKey.RxMic, LEN_TKIP_MIC);
+ }
+
+ key_length = Key_Data[1];
+ pOutPacket->Body_Len[1] = key_length + 0x5f;
+
+ /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */
+ NdisZeroMemory(temp, 64);
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+ WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, temp, DA, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PTK-0-%x %x %x %x %x %x %x %x \n",
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6],
+ pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7]));
+
+ NdisMoveMemory(pOutPacket->KeyDesc.KeyData, Key_Data, key_length);
+ NdisZeroMemory(mic, sizeof(mic));
+
+ *(USHORT *)(&pOutPacket->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pOutPacket->KeyDesc.KeyInfo));
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ pOutPacket->Body_Len[1] + 4, pOutPacket,
+ END_OF_ARGS);
+
+ /* Calculate MIC */
+ if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
+ NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, mic, MD5_DIGEST_SIZE);
+ NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
+ }
+
+ RTMPToWirelessSta(pAd, pDaEntry, Header802_3, LENGTH_802_3, (PUCHAR)pOutPacket, pOutPacket->Body_Len[1] + 4, FALSE);
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ os_free_mem(NULL, mpool);
+ }while(FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleSTAKey: FrameLen=%ld\n", FrameLen));
+}
+#endif /* QOS_DLS_SUPPORT */
+
+#ifdef HOSTAPD_SUPPORT
+/*for sending an event to notify hostapd about michael failure. */
+VOID ieee80211_notify_michael_failure(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN UINT keyix,
+ IN INT report)
+{
+ static const char *tag = "MLME-MICHAELMICFAILURE.indication";
+/* struct net_device *dev = pAd->net_dev; */
+/* union iwreq_data wrqu; */
+ char buf[128]; /* XXX */
+
+
+ /* TODO: needed parameters: count, keyid, key type, src address, TSC */
+ if(report)/*station reports a mic error to this ap. */
+ {
+ snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=%s)", tag,
+ keyix, "uni",
+ ether_sprintf(pHeader->Addr2));
+ }
+ else/*ap itself receives a mic error. */
+ {
+ snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=%s)", tag,
+ keyix, IEEE80211_IS_MULTICAST(pHeader->Addr1) ? "broad" : "uni",
+ ether_sprintf(pHeader->Addr2));
+ }
+ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, -1, NULL, NULL, 0);
+/* NdisZeroMemory(&wrqu, sizeof(wrqu)); */
+/* wrqu.data.length = strlen(buf); */
+/* wireless_send_event(dev, RT_WLAN_EVENT_CUSTOM, &wrqu, buf); */
+}
+
+
+const CHAR* ether_sprintf(const UINT8 *mac)
+{
+ static char etherbuf[18];
+ snprintf(etherbuf,sizeof(etherbuf),"%02x:%02x:%02x:%02x:%02x:%02x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
+ return etherbuf;
+}
+#endif /* HOSTAPD_SUPPORT */
+
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+VOID ApcliWpaSendEapolStart(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid,
+ IN PMAC_TABLE_ENTRY pMacEntry,
+ IN PAPCLI_STRUCT pApCliEntry)
+{
+ IEEE8021X_FRAME Packet;
+ UCHAR Header802_3[14];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> ApCliWpaSendEapolStart\n"));
+
+ NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);
+
+ MAKE_802_3_HEADER(Header802_3, pBssid, &pApCliEntry->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, pMacEntry,
+ Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n"));
+}
+
+#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 ApcliWpaCheckEapCode(
+ 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 /* APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif/*APCLI_SUPPORT*/
diff --git a/cleopatre/devkit/mt7601udrv/ap/apcli_assoc.c b/cleopatre/devkit/mt7601udrv/ap/apcli_assoc.c
new file mode 100644
index 0000000000..4d317fd047
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/apcli_assoc.c
@@ -0,0 +1,806 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+
+ Module Name:
+ apcli_assoc.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 2006-6-23 modified for rt61-APClinent
+*/
+
+#ifdef APCLI_SUPPORT
+
+#include "rt_config.h"
+
+static VOID ApCliAssocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+static VOID ApCliMlmeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliMlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliPeerAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliPeerDisassocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliAssocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliInvalidStateWhenAssoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliInvalidStateWhenDisassociate(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliAssocPostProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN USHORT CapabilityInfo,
+ IN USHORT IfIndex,
+ 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);
+
+DECLARE_TIMER_FUNCTION(ApCliAssocTimeout);
+BUILD_TIMER_FUNCTION(ApCliAssocTimeout);
+
+/*
+ ==========================================================================
+ 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
+ ==========================================================================
+ */
+VOID ApCliAssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ UCHAR i;
+
+ StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans,
+ APCLI_MAX_ASSOC_STATE, APCLI_MAX_ASSOC_MSG,
+ (STATE_MACHINE_FUNC)Drop, APCLI_ASSOC_IDLE,
+ APCLI_ASSOC_MACHINE_BASE);
+
+ /* first column */
+ StateMachineSetAction(S, APCLI_ASSOC_IDLE, APCLI_MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)ApCliMlmeAssocReqAction);
+ StateMachineSetAction(S, APCLI_ASSOC_IDLE, APCLI_MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliMlmeDisassocReqAction);
+ StateMachineSetAction(S, APCLI_ASSOC_IDLE, APCLI_MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliPeerDisassocAction);
+
+ /* second column */
+ StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenAssoc);
+ StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenDisassociate);
+ StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliPeerDisassocAction);
+ StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)ApCliPeerAssocRspAction);
+ StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ApCliAssocTimeoutAction);
+
+ /* timer init */
+ RTMPInitTimer(pAd, &pAd->ApCliMlmeAux.ApCliAssocTimer, GET_TIMER_FUNCTION(ApCliAssocTimeout), pAd, FALSE);
+
+ for (i=0; i < MAX_APCLI_NUM; i++)
+ pAd->ApCfg.ApCliTab[i].AssocCurrState = APCLI_ASSOC_IDLE;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ 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
+ ==========================================================================
+ */
+static VOID ApCliAssocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - enqueue APCLI_MT2_ASSOC_TIMEOUT \n"));
+
+ MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_ASSOC_TIMEOUT, 0, NULL, 0);
+ RTMP_MLME_HANDLER(pAd);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ 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
+ Post :
+ -# An association request frame is generated and sent to the air
+ -# Association timer starts
+ -# Association state -> ASSOC_WAIT_RSP
+
+ ==========================================================================
+ */
+static VOID ApCliMlmeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ NDIS_STATUS NStatus;
+ BOOLEAN Cancelled;
+ 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;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ ULONG tmp;
+ UCHAR SsidIe = IE_SSID;
+ UCHAR SupRateIe = IE_SUPP_RATES;
+ UCHAR ExtRateIe = IE_EXT_SUPP_RATES;
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState;
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ USHORT VarIesOffset = 0;
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+ UCHAR RSNIe = IE_WPA;
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ /* Block all authentication request durning WPA block period */
+ if (pAd->ApCfg.ApCliTab[ifIndex].bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Block Auth request durning WPA block period!\n"));
+ *pCurrState = APCLI_ASSOC_IDLE;
+ ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+ else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
+ {
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAssocTimer, &Cancelled);
+
+ /* allocate and send out AssocRsp frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() allocate memory failed \n"));
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+
+ return;
+ }
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ pAd->ApCfg.ApCliTab[ifIndex].AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+ pAd->ApCfg.ApCliTab[ifIndex].AssocInfo.AvailableRequestFixedIEs =
+ NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
+ pAd->ApCfg.ApCliTab[ifIndex].AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
+ pAd->ApCfg.ApCliTab[ifIndex].AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
+ pAd->ApCfg.ApCliTab[ifIndex].AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+
+ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs, MAX_VIE_LEN);
+ /*First add SSID*/
+ VarIesOffset = 0;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, &SsidIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ VarIesOffset += pAd->MlmeAux.SsidLen;
+
+ /*Second add Supported rates*/
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, &SupRateIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
+ VarIesOffset += pAd->MlmeAux.SupRateLen;
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Send ASSOC request...\n"));
+ ApCliMgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr, ifIndex);
+
+ /* Build basic frame first */
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AssocHdr,
+ 2, &CapabilityInfo,
+ 2, &ListenIntv,
+ 1, &SsidIe,
+ 1, &pAd->ApCliMlmeAux.SsidLen,
+ pAd->ApCliMlmeAux.SsidLen, pAd->ApCliMlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->ApCliMlmeAux.SupRateLen,
+ pAd->ApCliMlmeAux.SupRateLen, pAd->ApCliMlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if(pAd->ApCliMlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->ApCliMlmeAux.ExtRateLen,
+ pAd->ApCliMlmeAux.ExtRateLen, pAd->ApCliMlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ /* HT */
+ if ((pAd->ApCliMlmeAux.HtCapabilityLen > 0) &&
+ WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ ULONG TmpLen;
+ HT_CAPABILITY_IE HtCapabilityTmp;
+
+ NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE));
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->ApCliMlmeAux.HtCapability, pAd->ApCliMlmeAux.HtCapabilityLen);
+#ifdef DOT11N_SS3_SUPPORT
+ HtCapabilityTmp.MCSSet[2] = (pAd->ApCliMlmeAux.HtCapability.MCSSet[2] & pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet[2]);
+#endif /* DOT11N_SS3_SUPPORT */
+
+#ifdef RT_BIG_ENDIAN
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+#endif /* RT_BIG_ENDINA */
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &pAd->ApCliMlmeAux.HtCapabilityLen,
+ pAd->ApCliMlmeAux.HtCapabilityLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef AGGREGATION_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)
+ {
+#ifdef PIGGYBACK_SUPPORT
+ if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->ApCliMlmeAux.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
+#endif /* PIGGYBACK_SUPPORT */
+ if (pAd->ApCliMlmeAux.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;
+ }
+#endif /* AGGREGATION_SUPPORT */
+
+ if (pAd->ApCliMlmeAux.APEdcaParm.bValid)
+ {
+ if (pAd->ApCfg.ApCliTab[ifIndex].UapsdInfo.bAPSDCapable &&
+ pAd->ApCliMlmeAux.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;
+ }
+ /* Append RSN_IE when WPAPSK OR WPA2PSK, */
+ if (((pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPA2PSK))
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ || (pAd->ApCfg.ApCliTab[ifIndex].AuthMode >= Ndis802_11AuthModeWPA)
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+#ifdef WSC_AP_SUPPORT
+ && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE)
+#endif /* WSC_AP_SUPPORT */
+ )
+ {
+ RSNIe = IE_WPA;
+
+ if ((pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ ||(pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPA2)
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+ )
+ RSNIe = IE_WPA2;
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pAd->ApCfg.ApCliTab[ifIndex].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->ApCfg.ApCliTab[ifIndex].SavedPMK[idx].BSSID, 6))
+ {
+ FoundPMK = TRUE;
+ break;
+ }
+ }
+
+ /*
+ 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->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPA2) &&
+ (NdisEqualMemory(pAd->MlmeAux.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN)))
+ {
+ FoundPMK = FALSE;
+ }
+
+ if (FoundPMK)
+ {
+ // Set PMK number
+ *(PUSHORT) &pAd->ApCfg.ApCliTab[ifIndex].RSN_IE[pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len] = 1;
+ NdisMoveMemory(&pAd->ApCfg.ApCliTab[ifIndex].RSN_IE[pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len + 2], &pAd->ApCfg.ApCliTab[ifIndex].SavedPMK[idx].PMKID, 16);
+ pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len += 18;
+ }
+ }
+
+#ifdef SIOCSIWGENIE
+ if ((pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP & WPA_SUPPLICANT_ENABLE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].bRSN_IE_FromWpaSupplicant == TRUE))
+ {
+ ;
+ }
+ else
+#endif
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &RSNIe,
+ 1, &pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len,
+ pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len, pAd->ApCfg.ApCliTab[ifIndex].RSN_IE,
+ END_OF_ARGS);
+
+ FrameLen += tmp;
+ }
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (((pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP & 0x7F) != WPA_SUPPLICANT_ENABLE) ||
+ (pAd->ApCfg.ApCliTab[ifIndex].bRSN_IE_FromWpaSupplicant == FALSE))
+#endif
+ {
+ // Append Variable IE
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, &RSNIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, &pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len, 1);
+ VarIesOffset += 1;
+
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, pAd->ApCfg.ApCliTab[ifIndex].RSN_IE, pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len);
+ VarIesOffset += pAd->ApCfg.ApCliTab[ifIndex].RSNIE_Len;
+
+ // Set Variable IEs Length
+ pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen = VarIesOffset;
+ }
+
+#ifdef SIOCSIWGENIE
+ if ((pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP & WPA_SUPPLICANT_ENABLE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].bRSN_IE_FromWpaSupplicant == TRUE))
+ {
+ ULONG TmpWpaAssocIeLen = 0;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpWpaAssocIeLen,
+ pAd->ApCfg.ApCliTab[ifIndex].WpaAssocIeLen, pAd->ApCfg.ApCliTab[ifIndex].pWpaAssocIe,
+ END_OF_ARGS);
+
+ FrameLen += TmpWpaAssocIeLen;
+
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs + VarIesOffset, pAd->ApCfg.ApCliTab[ifIndex].pWpaAssocIe, pAd->ApCfg.ApCliTab[ifIndex].WpaAssocIeLen);
+ VarIesOffset += pAd->ApCfg.ApCliTab[ifIndex].WpaAssocIeLen;
+
+ // Set Variable IEs Length
+ pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen = VarIesOffset;
+ }
+#endif
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->ApCliMlmeAux.ApCliAssocTimer, Timeout);
+ *pCurrState = APCLI_ASSOC_WAIT_RSP;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Upper layer issues disassoc request
+ Parameters:
+ Elem -
+ ==========================================================================
+ */
+static VOID ApCliMlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
+ HEADER_802_11 DisassocHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState;
+
+
+ /* skip sanity check */
+ pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
+
+ /* allocate and send out DeassocReq frame */
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeDisassocReqAction() allocate memory failed\n"));
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DEASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Send DISASSOC request [BSSID::%02x:%02x:%02x:%02x:%02x:%02x] \n",
+ pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
+ pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5]));
+ ApCliMgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr, ifIndex);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DisassocHdr,
+ 2, &pDisassocReq->Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DEASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pAd->ApCfg.ApCliTab[ifIndex].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);
+ }
+ RtmpOSWrielessEventSend(pAd->net_dev, SIOCGIWAP, -1, NULL, NULL, 0);
+ RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, NULL, BSS0, 0);
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ peer sends assoc rsp back
+ Parameters:
+ Elme - MLME message containing the received frame
+ ==========================================================================
+ */
+static VOID ApCliPeerAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ BOOLEAN Cancelled;
+ 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];
+ EDCA_PARM EdcaParm;
+ UCHAR CkipFlag;
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; /* AP might use this additional ht info IE */
+ UCHAR HtCapabilityLen;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState;
+
+
+ if (ApCliPeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
+ &HtCapability, &AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
+ {
+ /* The frame is for me ? */
+ if(MAC_ADDR_EQUAL(Addr2, pAd->ApCliMlmeAux.Bssid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAssocTimer, &Cancelled);
+ if(Status == MLME_SUCCESS)
+ {
+ /* go to procedure listed on page 376 */
+ ApCliAssocPostProc(pAd, Addr2, CapabilityInfo, ifIndex, SupRate, SupRateLen,
+ ExtRate, ExtRateLen, &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+
+ ApCliCtrlMsg.Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+ else
+ {
+ ApCliCtrlMsg.Status = Status;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+
+ *pCurrState = APCLI_ASSOC_IDLE;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliPeerAssocRspAction() sanity check fail\n"));
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ left part of IEEE 802.11/1999 p.374
+ Parameters:
+ Elem - MLME message containing the received frame
+ ==========================================================================
+ */
+static VOID ApCliPeerDisassocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Reason;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState;
+
+ if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
+ {
+ if (MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, Addr2))
+ {
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PEER_DISCONNECT_REQ, 0, NULL, ifIndex);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliPeerDisassocAction() sanity check fail\n"));
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ what the state machine will do after assoc timeout
+ ==========================================================================
+ */
+static VOID ApCliAssocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliAssocTimeoutAction\n"));
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_REQ_TIMEOUT, 0, NULL, ifIndex);
+
+ return;
+}
+
+static VOID ApCliInvalidStateWhenAssoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliInvalidStateWhenAssoc(state=%ld), reset APCLI_ASSOC state machine\n", *pCurrState));
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+
+ return;
+}
+
+static VOID ApCliInvalidStateWhenDisassociate(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - InvalidStateWhenApCliDisassoc(state=%ld), reset APCLI_ASSOC state machine\n", *pCurrState));
+ *pCurrState = APCLI_ASSOC_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DEASSOC_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ procedures on IEEE 802.11/1999 p.376
+ Parametrs:
+ ==========================================================================
+ */
+static VOID ApCliAssocPostProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN USHORT CapabilityInfo,
+ IN USHORT IfIndex,
+ 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)
+{
+
+ pAd->ApCliMlmeAux.BssType = BSS_INFRA;
+ pAd->ApCliMlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+ NdisMoveMemory(&pAd->ApCliMlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+
+ /* filter out un-supported rates */
+ pAd->ApCliMlmeAux.SupRateLen = SupRateLen;
+ NdisMoveMemory(pAd->ApCliMlmeAux.SupRate, SupRate, SupRateLen);
+ RTMPCheckRates(pAd, pAd->ApCliMlmeAux.SupRate, &pAd->ApCliMlmeAux.SupRateLen);
+
+ /* filter out un-supported rates */
+ pAd->ApCliMlmeAux.ExtRateLen = ExtRateLen;
+ NdisMoveMemory(pAd->ApCliMlmeAux.ExtRate, ExtRate, ExtRateLen);
+ RTMPCheckRates(pAd, pAd->ApCliMlmeAux.ExtRate, &pAd->ApCliMlmeAux.ExtRateLen);
+
+ DBGPRINT(RT_DEBUG_TRACE, (HtCapabilityLen ? "%s===> 11n HT STA\n" : "%s===> legacy STA\n", __FUNCTION__));
+
+#ifdef DOT11_N_SUPPORT
+ if (HtCapabilityLen > 0 && WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ ApCliCheckHt(pAd, IfIndex, pHtCapability, pAddHtInfo);
+ }
+#endif /* DOT11_N_SUPPORT */
+
+}
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+VOID ApcliSendAssocIEsToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT ifIndex)
+{
+ STRING custom[IW_CUSTOM_MAX] = {0};
+
+ if ((pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen + 17) <= IW_CUSTOM_MAX)
+ {
+ sprintf(custom, "ASSOCINFO_ReqIEs=");
+ NdisMoveMemory(custom+17, pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs, pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen);
+ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_REQIE_EVENT_FLAG, NULL, (PUCHAR)custom, pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen + 17);
+
+ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_ASSOCINFO_EVENT_FLAG, NULL, NULL, 0);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->ApCfg.ApCliTab[%d].ReqVarIELen + 17 > MAX_CUSTOM_LEN\n",ifIndex));
+
+ return;
+}
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif /* APCLI_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/apcli_auth.c b/cleopatre/devkit/mt7601udrv/ap/apcli_auth.c
new file mode 100644
index 0000000000..0f82e68dce
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/apcli_auth.c
@@ -0,0 +1,570 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+
+ Module Name:
+ apcli_auth.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 2006-6-23 modified for rt61-APClinent
+*/
+
+#ifdef APCLI_SUPPORT
+
+#include "rt_config.h"
+
+static VOID ApCliAuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+static VOID ApCliMlmeAuthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliPeerAuthRspAtSeq2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliPeerAuthRspAtSeq4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliPeerDeauthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliAuthTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliInvalidStateWhenAuth(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliMlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+DECLARE_TIMER_FUNCTION(ApCliAuthTimeout);
+BUILD_TIMER_FUNCTION(ApCliAuthTimeout);
+
+/*
+ ==========================================================================
+ 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
+ ==========================================================================
+ */
+
+VOID ApCliAuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ UCHAR i;
+
+ StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans,
+ APCLI_MAX_AUTH_STATE, APCLI_MAX_AUTH_MSG,
+ (STATE_MACHINE_FUNC)Drop, APCLI_AUTH_REQ_IDLE,
+ APCLI_AUTH_MACHINE_BASE);
+
+ /* the first column */
+ StateMachineSetAction(Sm, APCLI_AUTH_REQ_IDLE, APCLI_MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)ApCliMlmeAuthReqAction);
+ StateMachineSetAction(Sm, APCLI_AUTH_REQ_IDLE, APCLI_MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)ApCliPeerDeauthAction);
+ StateMachineSetAction(Sm, APCLI_AUTH_REQ_IDLE, APCLI_MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)ApCliMlmeDeauthReqAction);
+
+ /* the second column */
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ2, APCLI_MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenAuth);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ2, APCLI_MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)ApCliPeerAuthRspAtSeq2Action);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ2, APCLI_MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)ApCliPeerDeauthAction);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ2, APCLI_MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)ApCliAuthTimeoutAction);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ2, APCLI_MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)ApCliMlmeDeauthReqAction);
+
+ /* the third column */
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ4, APCLI_MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenAuth);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ4, APCLI_MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)ApCliPeerAuthRspAtSeq4Action);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ4, APCLI_MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)ApCliPeerDeauthAction);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ4, APCLI_MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)ApCliAuthTimeoutAction);
+ StateMachineSetAction(Sm, APCLI_AUTH_WAIT_SEQ4, APCLI_MT2_MLME_DEAUTH_REQ, (STATE_MACHINE_FUNC)ApCliMlmeDeauthReqAction);
+
+ /* timer init */
+ RTMPInitTimer(pAd, &pAd->ApCliMlmeAux.ApCliAuthTimer, GET_TIMER_FUNCTION(ApCliAuthTimeout), pAd, FALSE);
+
+ for (i=0; i < MAX_APCLI_NUM; i++)
+ pAd->ApCfg.ApCliTab[i].AuthCurrState = APCLI_AUTH_REQ_IDLE;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ function to be executed at timer thread when auth timer expires
+ ==========================================================================
+ */
+static VOID ApCliAuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - AuthTimeout\n"));
+
+ MlmeEnqueue(pAd, APCLI_AUTH_STATE_MACHINE, APCLI_MT2_AUTH_TIMEOUT, 0, NULL, 0);
+ RTMP_MLME_HANDLER(pAd);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliMlmeAuthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ BOOLEAN Cancelled;
+ NDIS_STATUS NState;
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Alg, Seq, Status;
+ ULONG Timeout;
+ HEADER_802_11 AuthHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState;
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ /* Block all authentication request durning WPA block period */
+ if (pAd->ApCfg.ApCliTab[ifIndex].bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - Block Auth request durning WPA block period!\n"));
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+ ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+ else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg))
+ {
+ /* reset timer */
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAuthTimer, &Cancelled);
+
+ pAd->ApCliMlmeAux.Alg = Alg;
+
+ Seq = 1;
+ Status = MLME_SUCCESS;
+
+ /* allocate and send out AuthReq frame */
+ NState = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
+ if(NState != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - MlmeAuthReqAction() allocate memory failed\n"));
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg));
+ ApCliMgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->ApCliMlmeAux.Bssid, ifIndex);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&AuthHdr,
+ 2, &Alg,
+ 2, &Seq,
+ 2, &Status,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->ApCliMlmeAux.ApCliAuthTimer, AUTH_TIMEOUT);
+
+ *pCurrState = APCLI_AUTH_WAIT_SEQ2;
+ } else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("APCLI AUTH - MlmeAuthReqAction() sanity check failed. BUG!!!!!\n"));
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliPeerAuthRspAtSeq2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ BOOLEAN Cancelled;
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Seq, Status, Alg;
+ USHORT RemoteStatus;
+ UCHAR iv_hdr[LEN_WEP_IV_HDR];
+/* UCHAR ChlgText[CIPHER_TEXT_LEN]; */
+ UCHAR *ChlgText = NULL;
+ UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
+ ULONG c_len = 0;
+ HEADER_802_11 AuthHdr;
+ NDIS_STATUS NState;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ UCHAR ChallengeIe = IE_CHALLENGE_TEXT;
+ UCHAR len_challengeText = CIPHER_TEXT_LEN;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState;
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&ChlgText, CIPHER_TEXT_LEN);
+ if (ChlgText == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return;
+ }
+
+ if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, (CHAR *) ChlgText))
+ {
+ if(MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, Addr2) && Seq == 2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status));
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAuthTimer, &Cancelled);
+
+ if(Status == MLME_SUCCESS)
+ {
+ if(pAd->ApCliMlmeAux.Alg == Ndis802_11AuthModeOpen)
+ {
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+
+ ApCliCtrlMsg.Status= MLME_SUCCESS;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+ else
+ {
+ PCIPHER_KEY pKey;
+ UINT default_key = pAd->ApCfg.ApCliTab[ifIndex].DefaultKeyId;
+
+ pKey = &pAd->ApCfg.ApCliTab[ifIndex].SharedKey[default_key];
+
+ /* 2. shared key, need to be challenged */
+ Seq++;
+ RemoteStatus = MLME_SUCCESS;
+ /* allocate and send out AuthRsp frame */
+ NState = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if(NState != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - ApCliPeerAuthRspAtSeq2Action allocate memory fail\n"));
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+
+ ApCliCtrlMsg.Status= MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ goto LabelOK;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n"));
+ ApCliMgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->ApCliMlmeAux.Bssid, ifIndex);
+ AuthHdr.FC.Wep = 1;
+
+ /* Encrypt challenge text & auth information */
+ /* TSC increment */
+ INC_TX_TSC(pKey->TxTsc, LEN_WEP_TSC);
+
+ /* Construct the 4-bytes WEP IV header */
+ RTMPConstructWEPIVHdr(default_key, pKey->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,
+ pKey,
+ CyperChlgText,
+ c_len) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - ApCliPeerAuthRspAtSeq2Action allocate memory fail\n"));
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+
+ ApCliCtrlMsg.Status= MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ 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, QID_AC_BE, pOutBuffer, FrameLen);
+
+ RTMPSetTimer(&pAd->ApCliMlmeAux.ApCliAuthTimer, AUTH_TIMEOUT);
+ *pCurrState = APCLI_AUTH_WAIT_SEQ4;
+ }
+ }
+ else
+ {
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+
+ ApCliCtrlMsg.Status= Status;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+ }
+ } else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - PeerAuthSanity() sanity check fail\n"));
+ }
+
+LabelOK:
+ if (pOutBuffer != NULL)
+ MlmeFreeMemory(pAd, pOutBuffer);
+ if (ChlgText != NULL)
+ os_free_mem(NULL, ChlgText);
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliPeerAuthRspAtSeq4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ BOOLEAN Cancelled;
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Alg, Seq, Status;
+ CHAR ChlgText[CIPHER_TEXT_LEN];
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState;
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+ {
+ if(MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, Addr2) && Seq == 4)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - Receive AUTH_RSP seq#4 to me\n"));
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAuthTimer, &Cancelled);
+
+ ApCliCtrlMsg.Status = MLME_SUCCESS;
+
+ if(Status != MLME_SUCCESS)
+ {
+ ApCliCtrlMsg.Status = Status;
+ }
+
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+ } else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI - PeerAuthRspAtSeq4Action() sanity check fail\n"));
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+*/
+static VOID ApCliPeerDeauthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR Addr3[MAC_ADDR_LEN];
+ USHORT Reason;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState;
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ pMacEntry = &pAd->MacTab.Content[pAd->ApCfg.ApCliTab[ifIndex].MacTabWCID];
+ if (!pMacEntry || !IS_ENTRY_APCLI(pMacEntry))
+ {
+ return;
+ }
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+ if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, Addr3, &Reason))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH_RSP - receive DE-AUTH from our AP\n"));
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if ((pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeWPA2)
+ &&(pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED))
+ {
+ pAd->ApCfg.ApCliTab[ifIndex].bLostAp = TRUE;
+ }
+#endif /*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PEER_DISCONNECT_REQ, 0, NULL, ifIndex);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH_RSP - ApCliPeerDeauthAction() sanity check fail\n"));
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliAuthTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - AuthTimeoutAction\n"));
+
+ *pCurrState = APCLI_AUTH_REQ_IDLE;
+
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_REQ_TIMEOUT, 0, NULL, ifIndex);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliInvalidStateWhenAuth(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n",
+ pAd->Mlme.ApCliAuthMachine.CurrState));
+
+ *pCurrState= APCLI_AUTH_REQ_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliMlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PMLME_DEAUTH_REQ_STRUCT pDeauthReq;
+ HEADER_802_11 DeauthHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - ApCliMlmeAuthReqAction (state=%ld), reset AUTH state machine\n",
+ pAd->Mlme.ApCliAuthMachine.CurrState));
+
+ pDeauthReq = (PMLME_DEAUTH_REQ_STRUCT)(Elem->Msg);
+
+ *pCurrState= APCLI_AUTH_REQ_IDLE;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pDeauthReq->Reason));
+
+ ApCliMgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pDeauthReq->Addr, pDeauthReq->Addr, ifIndex);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DeauthHdr,
+ 2, &pDeauthReq->Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+#endif /* APCLI_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/apcli_ctrl.c b/cleopatre/devkit/mt7601udrv/ap/apcli_ctrl.c
new file mode 100644
index 0000000000..74b4e219e6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/apcli_ctrl.c
@@ -0,0 +1,875 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ apcli_ctrl.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 2006-06-23 modified for rt61-APClinent
+*/
+#ifdef APCLI_SUPPORT
+
+#include "rt_config.h"
+
+
+static VOID ApCliCtrlJoinReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlJoinReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlProbeRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlAuthRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlAuth2RspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlAuthReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlAuth2ReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlDeAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlAssocReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlDisconnectReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlPeerDeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlDeAssocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliCtrlDeAuthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+/*
+ ==========================================================================
+ Description:
+ The apcli ctrl state machine,
+ Parameters:
+ Sm - pointer to the state machine
+ Note:
+ the state machine looks like the following
+ ==========================================================================
+ */
+VOID ApCliCtrlStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ UCHAR i;
+
+ StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans,
+ APCLI_MAX_CTRL_STATE, APCLI_MAX_CTRL_MSG,
+ (STATE_MACHINE_FUNC)Drop, APCLI_CTRL_DISCONNECTED,
+ APCLI_CTRL_MACHINE_BASE);
+
+ /* disconnected state */
+ StateMachineSetAction(Sm, APCLI_CTRL_DISCONNECTED, APCLI_CTRL_JOIN_REQ, (STATE_MACHINE_FUNC)ApCliCtrlJoinReqAction);
+
+ /* probe state */
+ StateMachineSetAction(Sm, APCLI_CTRL_PROBE, APCLI_CTRL_PROBE_RSP, (STATE_MACHINE_FUNC)ApCliCtrlProbeRspAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_PROBE, APCLI_CTRL_JOIN_REQ_TIMEOUT, (STATE_MACHINE_FUNC)ApCliCtrlJoinReqTimeoutAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_PROBE, APCLI_CTRL_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlDisconnectReqAction);
+
+ /* auth state */
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH, APCLI_CTRL_AUTH_RSP, (STATE_MACHINE_FUNC)ApCliCtrlAuthRspAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH, APCLI_CTRL_AUTH_REQ_TIMEOUT, (STATE_MACHINE_FUNC)ApCliCtrlAuthReqTimeoutAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH, APCLI_CTRL_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlDisconnectReqAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH, APCLI_CTRL_PEER_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlPeerDeAssocReqAction);
+
+ /* auth2 state */
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH_2, APCLI_CTRL_AUTH_RSP, (STATE_MACHINE_FUNC)ApCliCtrlAuth2RspAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH_2, APCLI_CTRL_AUTH_REQ_TIMEOUT, (STATE_MACHINE_FUNC)ApCliCtrlAuth2ReqTimeoutAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH_2, APCLI_CTRL_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlDisconnectReqAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_AUTH_2, APCLI_CTRL_PEER_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlPeerDeAssocReqAction);
+
+ /* assoc state */
+ StateMachineSetAction(Sm, APCLI_CTRL_ASSOC, APCLI_CTRL_ASSOC_RSP, (STATE_MACHINE_FUNC)ApCliCtrlAssocRspAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_ASSOC, APCLI_CTRL_ASSOC_REQ_TIMEOUT, (STATE_MACHINE_FUNC)ApCliCtrlAssocReqTimeoutAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_ASSOC, APCLI_CTRL_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlDeAssocAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_ASSOC, APCLI_CTRL_PEER_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlPeerDeAssocReqAction);
+
+ /* deassoc state */
+ StateMachineSetAction(Sm, APCLI_CTRL_DEASSOC, APCLI_CTRL_DEASSOC_RSP, (STATE_MACHINE_FUNC)ApCliCtrlDeAssocRspAction);
+
+ /* connected state */
+ StateMachineSetAction(Sm, APCLI_CTRL_CONNECTED, APCLI_CTRL_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlDeAuthAction);
+ StateMachineSetAction(Sm, APCLI_CTRL_CONNECTED, APCLI_CTRL_PEER_DISCONNECT_REQ, (STATE_MACHINE_FUNC)ApCliCtrlPeerDeAssocReqAction);
+
+ for (i = 0; i < MAX_APCLI_NUM; i++)
+ pAd->ApCfg.ApCliTab[i].CtrlCurrState = APCLI_CTRL_DISCONNECTED;
+
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME JOIN req state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlJoinReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_MLME_JOIN_REQ_STRUCT JoinReq;
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+#ifdef WSC_AP_SUPPORT
+ PWSC_CTRL pWpsCtrl = &pAd->ApCfg.ApCliTab[ifIndex].WscControl;
+#endif /* WSC_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Start Probe Req.\n", __FUNCTION__));
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ if (ApScanRunning(pAd) == TRUE)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ NdisZeroMemory(&JoinReq, sizeof(APCLI_MLME_JOIN_REQ_STRUCT));
+
+ if (!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR))
+ {
+ COPY_MAC_ADDR(JoinReq.Bssid, pApCliEntry->CfgApCliBssid);
+ }
+
+#ifdef WSC_AP_SUPPORT
+ if ((pWpsCtrl->WscConfMode != WSC_DISABLE) &&
+ (pWpsCtrl->bWscTrigger == TRUE))
+ {
+ ULONG bss_idx = 0;
+ NdisZeroMemory(JoinReq.Ssid, MAX_LEN_OF_SSID);
+ JoinReq.SsidLen = pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.SsidLength;
+ NdisMoveMemory(JoinReq.Ssid, pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.Ssid, JoinReq.SsidLen);
+ if (pWpsCtrl->WscMode == 1) /* PIN */
+ {
+ bss_idx = BssSsidTableSearchBySSID(&pAd->ScanTab, (PUCHAR)(JoinReq.Ssid), JoinReq.SsidLen);
+ if (bss_idx == BSS_NOT_FOUND)
+ {
+ ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE);
+ return;
+ }
+ else
+ {
+ INT old_conf_mode = pWpsCtrl->WscConfMode;
+ ADD_HTINFO RootApHtInfo, ApHtInfo;
+ UCHAR channel = pAd->CommonCfg.Channel, RootApChannel = pAd->ScanTab.BssEntry[bss_idx].Channel;
+ UCHAR RootApCentralChannel = pAd->ScanTab.BssEntry[bss_idx].CentralChannel;
+ ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo;
+ RootApHtInfo = pAd->ScanTab.BssEntry[bss_idx].AddHtInfo.AddHtInfo;
+
+ if ((RootApChannel != channel) ||
+ ((RootApCentralChannel != RootApChannel) &&
+ (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (ApHtInfo.ExtChanOffset != RootApHtInfo.ExtChanOffset)))
+ {
+ STRING ChStr[5] = {0};
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ {
+ if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE)
+ Set_HtExtcha_Proc(pAd, "1");
+ else
+ Set_HtExtcha_Proc(pAd, "0");
+ }
+ snprintf(ChStr, sizeof(ChStr), "%d", pAd->ScanTab.BssEntry[bss_idx].Channel);
+ Set_Channel_Proc(pAd, ChStr);
+ /*
+ ApStop will call WscStop, we need to reset WscConfMode, WscMode & bWscTrigger here.
+ */
+
+ pWpsCtrl->WscState = WSC_STATE_START;
+ pWpsCtrl->WscStatus = STATUS_WSC_START_ASSOC;
+ pWpsCtrl->WscMode = 1;
+ pWpsCtrl->WscConfMode = old_conf_mode;
+ pWpsCtrl->bWscTrigger = TRUE;
+ return;
+ }
+ }
+ }
+ }
+ else
+#endif /* WSC_AP_SUPPORT */
+ if (pApCliEntry->CfgSsidLen != 0)
+ {
+ JoinReq.SsidLen = pApCliEntry->CfgSsidLen;
+ NdisMoveMemory(&(JoinReq.Ssid), pApCliEntry->CfgSsid, JoinReq.SsidLen);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe Ssid=%s, Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ __FUNCTION__, JoinReq.Ssid, JoinReq.Bssid[0], JoinReq.Bssid[1], JoinReq.Bssid[2],
+ JoinReq.Bssid[3], JoinReq.Bssid[4], JoinReq.Bssid[5]));
+
+ *pCurrState = APCLI_CTRL_PROBE;
+
+ MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_MLME_PROBE_REQ,
+ sizeof(APCLI_MLME_JOIN_REQ_STRUCT), &JoinReq, ifIndex);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME JOIN req timeout state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlJoinReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_MLME_JOIN_REQ_STRUCT JoinReq;
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe Req Timeout.\n", __FUNCTION__));
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ if (ApScanRunning(pAd) == TRUE)
+ {
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ return;
+ }
+
+ /* stay in same state. */
+ *pCurrState = APCLI_CTRL_PROBE;
+
+ /* retry Probe Req. */
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Retry Probe Req.\n", __FUNCTION__));
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ NdisZeroMemory(&JoinReq, sizeof(APCLI_MLME_JOIN_REQ_STRUCT));
+
+ if (!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR))
+ {
+ COPY_MAC_ADDR(JoinReq.Bssid, pApCliEntry->CfgApCliBssid);
+ }
+
+#ifdef WSC_AP_SUPPORT
+ if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE))
+ {
+ NdisZeroMemory(JoinReq.Ssid, MAX_LEN_OF_SSID);
+ JoinReq.SsidLen = pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.SsidLength;
+ NdisMoveMemory(JoinReq.Ssid, pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.Ssid, JoinReq.SsidLen);
+ }
+ else
+#endif /* WSC_AP_SUPPORT */
+ if (pApCliEntry->CfgSsidLen != 0)
+ {
+ JoinReq.SsidLen = pApCliEntry->CfgSsidLen;
+ NdisMoveMemory(&(JoinReq.Ssid), pApCliEntry->CfgSsid, JoinReq.SsidLen);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe Ssid=%s, Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ __FUNCTION__, JoinReq.Ssid, JoinReq.Bssid[0], JoinReq.Bssid[1], JoinReq.Bssid[2],
+ JoinReq.Bssid[3], JoinReq.Bssid[4], JoinReq.Bssid[5]));
+ MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_MLME_PROBE_REQ,
+ sizeof(APCLI_MLME_JOIN_REQ_STRUCT), &JoinReq, ifIndex);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Probe Rsp state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlProbeRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT *Info = (APCLI_CTRL_MSG_STRUCT *)(Elem->Msg);
+ USHORT Status = Info->Status;
+ PAPCLI_STRUCT pApCliEntry;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if (Status == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe respond success.\n", __FUNCTION__));
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Apcli-Interface Ssid=%s.\n", __FUNCTION__, pApCliEntry->Ssid));
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Apcli-Interface Bssid=%02x:%02x:%02x:%02x:%02x:%02x.\n", __FUNCTION__,
+ pAd->ApCliMlmeAux.Bssid[0],
+ pAd->ApCliMlmeAux.Bssid[1],
+ pAd->ApCliMlmeAux.Bssid[2],
+ pAd->ApCliMlmeAux.Bssid[3],
+ pAd->ApCliMlmeAux.Bssid[4],
+ pAd->ApCliMlmeAux.Bssid[5]));
+
+ *pCurrState = APCLI_CTRL_AUTH;
+
+ pApCliEntry->AuthReqCnt = 0;
+
+ COPY_MAC_ADDR(AuthReq.Addr, pAd->ApCliMlmeAux.Bssid);
+
+ /* start Authentication Req. */
+ /* If AuthMode is Auto, try shared key first */
+ if ((pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeShared) ||
+ (pAd->ApCfg.ApCliTab[ifIndex].AuthMode == Ndis802_11AuthModeAutoSwitch))
+ {
+ AuthReq.Alg = Ndis802_11AuthModeShared;
+ }
+ else
+ {
+ AuthReq.Alg = Ndis802_11AuthModeOpen;
+ }
+
+ AuthReq.Timeout = AUTH_TIMEOUT;
+ MlmeEnqueue(pAd, APCLI_AUTH_STATE_MACHINE, APCLI_MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq, ifIndex);
+ } else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe respond fail.\n", __FUNCTION__));
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME AUTH Rsp state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlAuthRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT *Info = (APCLI_CTRL_MSG_STRUCT *)(Elem->Msg);
+ USHORT Status = Info->Status;
+ MLME_ASSOC_REQ_STRUCT AssocReq;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if(Status == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Auth Rsp Success.\n", __FUNCTION__));
+ *pCurrState = APCLI_CTRL_ASSOC;
+
+ pApCliEntry->AssocReqCnt = 0;
+
+ AssocParmFill(pAd, &AssocReq, pAd->ApCliMlmeAux.Bssid, pAd->ApCliMlmeAux.CapabilityInfo,
+ ASSOC_TIMEOUT, 5);
+ MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_MLME_ASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq, ifIndex);
+ }
+ else
+ {
+ if (pApCliEntry->AuthMode == Ndis802_11AuthModeAutoSwitch)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Auth Rsp Failure.\n", __FUNCTION__));
+
+ *pCurrState = APCLI_CTRL_AUTH_2;
+
+ /* start Second Authentication Req. */
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Start Second Auth Rep.\n", __FUNCTION__));
+ COPY_MAC_ADDR(AuthReq.Addr, pAd->ApCliMlmeAux.Bssid);
+ AuthReq.Alg = Ndis802_11AuthModeOpen;
+ AuthReq.Timeout = AUTH_TIMEOUT;
+ MlmeEnqueue(pAd, APCLI_AUTH_STATE_MACHINE, APCLI_MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq, ifIndex);
+ } else
+ {
+ NdisZeroMemory(pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ NdisZeroMemory(pAd->ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pApCliEntry->AuthReqCnt = 0;
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ }
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME AUTH2 Rsp state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlAuth2RspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT *Info = (APCLI_CTRL_MSG_STRUCT *)(Elem->Msg);
+ USHORT Status = Info->Status;
+ MLME_ASSOC_REQ_STRUCT AssocReq;
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if(Status == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Auth2 Rsp Success.\n", __FUNCTION__));
+ *pCurrState = APCLI_CTRL_ASSOC;
+
+ pApCliEntry->AssocReqCnt = 0;
+
+ AssocParmFill(pAd, &AssocReq, pAd->ApCliMlmeAux.Bssid, pAd->ApCliMlmeAux.CapabilityInfo,
+ ASSOC_TIMEOUT, 5);
+ MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_MLME_ASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq, ifIndex);
+ } else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Sta Auth Rsp Failure.\n", __FUNCTION__));
+
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Auth Req timeout state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlAuthReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_AUTH_REQ_STRUCT AuthReq;
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Auth Req Timeout.\n", __FUNCTION__));
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ pApCliEntry->AuthReqCnt++;
+
+ if (pApCliEntry->AuthReqCnt > 5)
+ {
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ NdisZeroMemory(pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ NdisZeroMemory(pAd->ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pApCliEntry->AuthReqCnt = 0;
+ return;
+ }
+
+ /* stay in same state. */
+ *pCurrState = APCLI_CTRL_AUTH;
+
+ /* retry Authentication. */
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Retry Auth Req.\n", __FUNCTION__));
+ COPY_MAC_ADDR(AuthReq.Addr, pAd->ApCliMlmeAux.Bssid);
+ AuthReq.Alg = pAd->ApCliMlmeAux.Alg; /*Ndis802_11AuthModeOpen; */
+ AuthReq.Timeout = AUTH_TIMEOUT;
+ MlmeEnqueue(pAd, APCLI_AUTH_STATE_MACHINE, APCLI_MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq, ifIndex);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Auth2 Req timeout state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlAuth2ReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME ASSOC RSP state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PAPCLI_STRUCT pApCliEntry;
+ APCLI_CTRL_MSG_STRUCT *Info = (APCLI_CTRL_MSG_STRUCT *)(Elem->Msg);
+ USHORT Status = Info->Status;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if(Status == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) apCliIf = %d, Receive Assoc Rsp Success.\n", __FUNCTION__, ifIndex));
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pAd->ApCfg.ApCliTab[ifIndex].WpaSupplicantUP)
+ {
+ ApcliSendAssocIEsToWpaSupplicant(pAd,ifIndex);
+ RtmpOSWrielessEventSend(pAd->net_dev,
+ RT_WLAN_EVENT_CUSTOM,
+ RT_ASSOC_EVENT_FLAG,
+ NULL, NULL, 0);
+ }
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+
+ if (ApCliLinkUp(pAd, ifIndex))
+ {
+ *pCurrState = APCLI_CTRL_CONNECTED;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) apCliIf = %d, Insert Remote AP to MacTable failed.\n", __FUNCTION__, ifIndex));
+ /* Reset the apcli interface as disconnected and Invalid. */
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ pApCliEntry->Valid = FALSE;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) apCliIf = %d, Receive Assoc Rsp Failure.\n", __FUNCTION__, ifIndex));
+
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+
+ /* set the apcli interface be valid. */
+ pApCliEntry->Valid = FALSE;
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME DeASSOC RSP state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlDeAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PAPCLI_STRUCT pApCliEntry;
+ APCLI_CTRL_MSG_STRUCT *Info = (APCLI_CTRL_MSG_STRUCT *)(Elem->Msg);
+ USHORT Status = Info->Status;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if (Status == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Receive DeAssoc Rsp Success.\n", __FUNCTION__));
+ } else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Receive DeAssoc Rsp Failure.\n", __FUNCTION__));
+ }
+
+ if (pApCliEntry->Valid)
+ ApCliLinkDown(pAd, ifIndex);
+
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Assoc Req timeout state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlAssocReqTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_ASSOC_REQ_STRUCT AssocReq;
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Assoc Req Timeout.\n", __FUNCTION__));
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ /* give up to retry authentication req after retry it 5 times. */
+ pApCliEntry->AssocReqCnt++;
+ if (pApCliEntry->AssocReqCnt > 5)
+ {
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+ NdisZeroMemory(pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ NdisZeroMemory(pAd->ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pApCliEntry->AuthReqCnt = 0;
+ return;
+ }
+
+ /* stay in same state. */
+ *pCurrState = APCLI_CTRL_ASSOC;
+
+ /* retry Association Req. */
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Retry Association Req.\n", __FUNCTION__));
+ AssocParmFill(pAd, &AssocReq, pAd->ApCliMlmeAux.Bssid, pAd->ApCliMlmeAux.CapabilityInfo,
+ ASSOC_TIMEOUT, 5);
+ MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_MLME_ASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq, ifIndex);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Disconnect Rsp state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlDisconnectReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) MLME Request disconnect.\n", __FUNCTION__));
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if (pApCliEntry->Valid)
+ ApCliLinkDown(pAd, ifIndex);
+
+ /* set the apcli interface be invalid. */
+ pApCliEntry->Valid = FALSE;
+
+ /* clear ApCliMlmeAux.Ssid and Bssid. */
+ NdisZeroMemory(pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->ApCliMlmeAux.SsidLen = 0;
+ NdisZeroMemory(pAd->ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pAd->ApCliMlmeAux.Rssi = 0;
+
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Peer DeAssoc Req state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlPeerDeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PAPCLI_STRUCT pApCliEntry;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Peer DeAssoc Req.\n", __FUNCTION__));
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+ if (pApCliEntry->Valid)
+ ApCliLinkDown(pAd, ifIndex);
+
+ /* set the apcli interface be invalid. */
+ pApCliEntry->Valid = FALSE;
+
+ /* clear ApCliMlmeAux.Ssid and Bssid. */
+ NdisZeroMemory(pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->ApCliMlmeAux.SsidLen = 0;
+ NdisZeroMemory(pAd->ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pAd->ApCliMlmeAux.Rssi = 0;
+
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Disconnect Req state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlDeAssocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PAPCLI_STRUCT pApCliEntry;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) MLME Request Disconnect.\n", __FUNCTION__));
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ DisassocParmFill(pAd, &DisassocReq, pAd->ApCliMlmeAux.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq, ifIndex);
+
+ if (pApCliEntry->Valid)
+ ApCliLinkDown(pAd, ifIndex);
+
+ /* set the apcli interface be invalid. */
+ pApCliEntry->Valid = FALSE;
+
+ /* clear ApCliMlmeAux.Ssid and Bssid. */
+ NdisZeroMemory(pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->ApCliMlmeAux.SsidLen = 0;
+ NdisZeroMemory(pAd->ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pAd->ApCliMlmeAux.Rssi = 0;
+
+ *pCurrState = APCLI_CTRL_DEASSOC;
+
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ APCLI MLME Disconnect Req state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliCtrlDeAuthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PAPCLI_STRUCT pApCliEntry;
+ MLME_DEAUTH_REQ_STRUCT DeAuthFrame;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("(%s) MLME Request Disconnect.\n", __FUNCTION__));
+
+ if (ifIndex >= MAX_APCLI_NUM)
+ return;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ /* Fill in the related information */
+ DeAuthFrame.Reason = (USHORT)REASON_DEAUTH_STA_LEAVING;
+ COPY_MAC_ADDR(DeAuthFrame.Addr, pAd->ApCliMlmeAux.Bssid);
+
+ MlmeEnqueue(pAd,
+ APCLI_AUTH_STATE_MACHINE,
+ APCLI_MT2_MLME_DEAUTH_REQ,
+ sizeof(MLME_DEAUTH_REQ_STRUCT),
+ &DeAuthFrame,
+ ifIndex);
+
+ if (pApCliEntry->Valid)
+ ApCliLinkDown(pAd, ifIndex);
+
+ /* set the apcli interface be invalid. */
+ pApCliEntry->Valid = FALSE;
+
+ /* clear ApCliMlmeAux.Ssid and Bssid. */
+ NdisZeroMemory(pAd->ApCliMlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->ApCliMlmeAux.SsidLen = 0;
+ NdisZeroMemory(pAd->ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID);
+ pAd->ApCliMlmeAux.Rssi = 0;
+
+ *pCurrState = APCLI_CTRL_DISCONNECTED;
+
+ return;
+}
+
+#endif /* APCLI_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ap/apcli_sync.c b/cleopatre/devkit/mt7601udrv/ap/apcli_sync.c
new file mode 100644
index 0000000000..fc8a8a53af
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ap/apcli_sync.c
@@ -0,0 +1,576 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ sta_sync.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 2006-06-23 modified for rt61-APClinent
+*/
+
+#ifdef APCLI_SUPPORT
+
+#include "rt_config.h"
+
+static VOID ApCliProbeTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+static VOID ApCliMlmeProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliPeerProbeRspAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliProbeTimeoutAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliInvalidStateWhenJoin(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+static VOID ApCliEnqueueProbeRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR SsidLen,
+ OUT PCHAR Ssid,
+ IN USHORT ifIndex);
+
+DECLARE_TIMER_FUNCTION(ApCliProbeTimeout);
+BUILD_TIMER_FUNCTION(ApCliProbeTimeout);
+
+/*
+ ==========================================================================
+ Description:
+ The sync state machine,
+ Parameters:
+ Sm - pointer to the state machine
+ Note:
+ the state machine looks like the following
+ ==========================================================================
+ */
+VOID ApCliSyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ UCHAR i;
+
+ StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans,
+ APCLI_MAX_SYNC_STATE, APCLI_MAX_SYNC_MSG,
+ (STATE_MACHINE_FUNC)Drop, APCLI_SYNC_IDLE,
+ APCLI_SYNC_MACHINE_BASE);
+
+ /* column 1 */
+ StateMachineSetAction(Sm, APCLI_SYNC_IDLE, APCLI_MT2_MLME_PROBE_REQ, (STATE_MACHINE_FUNC)ApCliMlmeProbeReqAction);
+
+ /*column 2 */
+ StateMachineSetAction(Sm, APCLI_JOIN_WAIT_PROBE_RSP, APCLI_MT2_MLME_PROBE_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenJoin);
+ StateMachineSetAction(Sm, APCLI_JOIN_WAIT_PROBE_RSP, APCLI_MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)ApCliPeerProbeRspAtJoinAction);
+ StateMachineSetAction(Sm, APCLI_JOIN_WAIT_PROBE_RSP, APCLI_MT2_PROBE_TIMEOUT, (STATE_MACHINE_FUNC)ApCliProbeTimeoutAtJoinAction);
+
+ /* timer init */
+ RTMPInitTimer(pAd, &pAd->ApCliMlmeAux.ProbeTimer, GET_TIMER_FUNCTION(ApCliProbeTimeout), pAd, FALSE);
+
+ for (i = 0; i < MAX_APCLI_NUM; i++)
+ pAd->ApCfg.ApCliTab[i].SyncCurrState = APCLI_SYNC_IDLE;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Becaon timeout handler, executed in timer thread
+ ==========================================================================
+ */
+static VOID ApCliProbeTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCli_SYNC - ProbeReqTimeout\n"));
+
+ MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_PROBE_TIMEOUT, 0, NULL, 0);
+ RTMP_MLME_HANDLER(pAd);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME PROBE req state machine procedure
+ ==========================================================================
+ */
+static VOID ApCliMlmeProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ BOOLEAN Cancelled;
+ APCLI_MLME_JOIN_REQ_STRUCT *Info = (APCLI_MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCli SYNC - ApCliMlmeProbeReqAction(Ssid %s)\n", Info->Ssid));
+
+ /* reset all the timers */
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ProbeTimer, &Cancelled);
+
+ pAd->ApCliMlmeAux.Rssi = -9999;
+ pAd->ApCliMlmeAux.Channel = pAd->CommonCfg.Channel;
+ pAd->ApCliMlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen;
+ NdisMoveMemory(pAd->ApCliMlmeAux.SupRate, pAd->CommonCfg.SupRate, pAd->CommonCfg.SupRateLen);
+
+ /* Prepare the default value for extended rate */
+ pAd->ApCliMlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
+ NdisMoveMemory(pAd->ApCliMlmeAux.ExtRate, pAd->CommonCfg.ExtRate, pAd->CommonCfg.ExtRateLen);
+
+ RTMPSetTimer(&pAd->ApCliMlmeAux.ProbeTimer, PROBE_TIMEOUT);
+
+ ApCliEnqueueProbeRequest(pAd, Info->SsidLen, (PCHAR) Info->Ssid, ifIndex);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCli SYNC - Start Probe the SSID %s on channel =%d\n", pAd->ApCliMlmeAux.Ssid, pAd->ApCliMlmeAux.Channel));
+
+ *pCurrState = APCLI_JOIN_WAIT_PROBE_RSP;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ When waiting joining the (I)BSS, beacon received from external
+ ==========================================================================
+ */
+static VOID ApCliPeerProbeRspAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT LenVIE;
+ UCHAR *VarIE = NULL;
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+#ifdef DOT11_N_SUPPORT
+ UCHAR CentralChannel;
+#endif /* DOT11_N_SUPPORT */
+
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
+
+ BCN_IE_LIST *ie_list = NULL;
+
+
+ /* Init Variable IE structure */
+ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN);
+ if (VarIE == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+
+ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST));
+ if (ie_list == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+ NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST));
+
+
+
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ ie_list,
+ &LenVIE,
+ pVIE))
+ {
+ /*
+ 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.
+ */
+ INT ssidEqualFlag = FALSE;
+ INT ssidEmptyFlag = FALSE;
+ INT bssidEqualFlag = FALSE;
+ INT bssidEmptyFlag = FALSE;
+ INT matchFlag = FALSE;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
+
+ /* Check the Probe-Rsp's Bssid. */
+ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR))
+ bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid);
+ else
+ bssidEmptyFlag = TRUE;
+
+ /* Check the Probe-Rsp's Ssid. */
+ if(pApCliEntry->CfgSsidLen != 0)
+ ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen);
+ else
+ ssidEmptyFlag = TRUE;
+
+
+ /* bssid and ssid, Both match. */
+ if (bssidEqualFlag && ssidEqualFlag)
+ matchFlag = TRUE;
+
+ /* ssid match but bssid doesn't be indicate. */
+ else if(ssidEqualFlag && bssidEmptyFlag)
+ matchFlag = TRUE;
+
+ /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */
+ else if (bssidEmptyFlag && ssidEmptyFlag)
+ matchFlag = TRUE;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag));
+ if (matchFlag)
+ {
+ /* Validate RSN IE if necessary, then copy store this information */
+ if ((LenVIE > 0)
+#ifdef WSC_AP_SUPPORT
+ && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) ||
+ (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE))
+#endif /* WSC_AP_SUPPORT */
+ )
+ {
+ if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex))
+ {
+ pAd->ApCliMlmeAux.VarIELen = LenVIE;
+ NdisMoveMemory(pAd->ApCliMlmeAux.VarIEs, pVIE, pAd->ApCliMlmeAux.VarIELen);
+ }
+ else
+ {
+ /* ignore this response */
+ pAd->ApCliMlmeAux.VarIELen = 0;
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n"));
+ goto LabelErr;
+ }
+ }
+ else
+ {
+ if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA
+#ifdef WSC_AP_SUPPORT
+ && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) ||
+ (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE))
+#endif /* WSC_AP_SUPPORT */
+ )
+ {
+ /* ignore this response */
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n"));
+ goto LabelErr;
+ }
+
+ pAd->ApCliMlmeAux.VarIELen = 0;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel));
+
+ /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */
+ if (bssidEqualFlag == FALSE)
+ {
+ /* caculate real rssi value. */
+ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20);
+ CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20);
+ CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20);
+ LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pAd->ApCliMlmeAux.Rssi, (LONG)RealRssi));
+ if (pAd->ApCliMlmeAux.Rssi > (LONG)RealRssi)
+ goto LabelErr;
+ else
+ pAd->ApCliMlmeAux.Rssi = RealRssi;
+ } else
+ {
+ BOOLEAN Cancelled;
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ProbeTimer, &Cancelled);
+ }
+
+ NdisMoveMemory(pAd->ApCliMlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen);
+ pAd->ApCliMlmeAux.SsidLen = ie_list->SsidLen;
+
+ NdisMoveMemory(pAd->ApCliMlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN);
+ pAd->ApCliMlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+ pAd->ApCliMlmeAux.BssType = ie_list->BssType;
+ pAd->ApCliMlmeAux.BeaconPeriod = ie_list->BeaconPeriod;
+ pAd->ApCliMlmeAux.Channel = ie_list->Channel;
+ pAd->ApCliMlmeAux.AtimWin = ie_list->AtimWin;
+ pAd->ApCliMlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod;
+ pAd->ApCliMlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration;
+ pAd->ApCliMlmeAux.APRalinkIe = ie_list->RalinkIe;
+
+ /* Copy AP's supported rate to ApCliMlmeAux for creating assoication request */
+ /* Also filter out not supported rate */
+ pAd->ApCliMlmeAux.SupRateLen = ie_list->SupRateLen;
+ NdisMoveMemory(pAd->ApCliMlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen);
+ RTMPCheckRates(pAd, pAd->ApCliMlmeAux.SupRate, &pAd->ApCliMlmeAux.SupRateLen);
+ pAd->ApCliMlmeAux.ExtRateLen = ie_list->ExtRateLen;
+ NdisMoveMemory(pAd->ApCliMlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen);
+ RTMPCheckRates(pAd, pAd->ApCliMlmeAux.ExtRate, &pAd->ApCliMlmeAux.ExtRateLen);
+
+#ifdef DOT11_N_SUPPORT
+ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet,sizeof(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet));
+ /* filter out un-supported ht rates */
+ if ((ie_list->HtCapabilityLen > 0) &&
+ (pApCliEntry->DesiredHtPhyInfo.bHtEnable) &&
+ WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ RTMPZeroMemory(&pAd->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ pAd->ApCliMlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset;
+ pAd->ApCliMlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen;
+ ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo);
+
+ if (ie_list->AddHtInfoLen > 0)
+ {
+ CentralChannel = ie_list->AddHtInfo.ControlChan;
+ /* Check again the Bandwidth capability of this AP. */
+ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo,
+ &ie_list->HtCapability);
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, ie_list->AddHtInfo.ControlChan));
+
+ }
+
+ }
+ else
+#endif /* DOT11_N_SUPPORT */
+ {
+ RTMPZeroMemory(&pAd->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ RTMPZeroMemory(&pAd->ApCliMlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
+ pAd->ApCliMlmeAux.HtCapabilityLen = 0;
+ }
+ ApCliUpdateMlmeRate(pAd);
+
+#ifdef DOT11_N_SUPPORT
+ /* copy QOS related information */
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ NdisMoveMemory(&pAd->ApCliMlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM));
+ NdisMoveMemory(&pAd->ApCliMlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisMoveMemory(&pAd->ApCliMlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+ else
+#endif /* DOT11_N_SUPPORT */
+ {
+ NdisZeroMemory(&pAd->ApCliMlmeAux.APEdcaParm, sizeof(EDCA_PARM));
+ NdisZeroMemory(&pAd->ApCliMlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisZeroMemory(&pAd->ApCliMlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
+ pAd->ApCliMlmeAux.SupRateLen, pAd->ApCliMlmeAux.ExtRateLen));
+
+ if (ie_list->AironetCellPowerLimit != 0xFF)
+ {
+ /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */
+ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit);
+ }
+ else /*Used the default TX Power Percentage. */
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+
+#ifdef WSC_AP_SUPPORT
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) &&
+ (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE))
+ {
+ ADD_HTINFO RootApHtInfo, ApHtInfo;
+ ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo;
+ RootApHtInfo = ie_list->AddHtInfo.AddHtInfo;
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (RootApHtInfo.RecomWidth) &&
+ (RootApHtInfo.ExtChanOffset != ApHtInfo.ExtChanOffset))
+ {
+ /*STRING ChStr[5] = {0}; */
+
+ if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE)
+ Set_HtExtcha_Proc(pAd, "1");
+ else
+ Set_HtExtcha_Proc(pAd, "0");
+
+ goto LabelErr;
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+#endif /* WSC_AP_SUPPORT */
+ if(bssidEqualFlag == TRUE)
+ {
+ *pCurrState = APCLI_SYNC_IDLE;
+
+ ApCliCtrlMsg.Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ }
+ }
+ /* not to me BEACON, ignored */
+ }
+ /* sanity check fail, ignore this frame */
+
+LabelErr:
+ if (VarIE != NULL)
+ os_free_mem(NULL, VarIE);
+ if (ie_list != NULL)
+ os_free_mem(NULL, ie_list);
+
+ return;
+}
+
+static VOID ApCliProbeTimeoutAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_SYNC - ProbeTimeoutAtJoinAction\n"));
+ *pCurrState = SYNC_IDLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_SYNC - ApCliMlmeAux.Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->ApCliMlmeAux.Bssid[0], pAd->ApCliMlmeAux.Bssid[1], pAd->ApCliMlmeAux.Bssid[2], pAd->ApCliMlmeAux.Bssid[3], pAd->ApCliMlmeAux.Bssid[4], pAd->ApCliMlmeAux.Bssid[5]));
+
+ if(!MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, ZERO_MAC_ADDR))
+ {
+ ApCliCtrlMsg.Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+ } else
+ {
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_JOIN_REQ_TIMEOUT, 0, NULL, ifIndex);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliInvalidStateWhenJoin(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
+ USHORT ifIndex = (USHORT)(Elem->Priv);
+ PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
+
+ *pCurrState = APCLI_SYNC_IDLE;
+ ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP,
+ sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_AYNC - ApCliInvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", *pCurrState));
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+static VOID ApCliEnqueueProbeRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR SsidLen,
+ OUT PCHAR Ssid,
+ IN USHORT ifIndex)
+{
+ NDIS_STATUS NState;
+ PUCHAR pOutBuffer;
+ ULONG FrameLen = 0;
+ HEADER_802_11 Hdr80211;
+ UCHAR SsidIe = IE_SSID;
+ UCHAR SupRateIe = IE_SUPP_RATES;
+ UCHAR ssidLen;
+ CHAR ssid[MAX_LEN_OF_SSID];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
+
+
+ NState = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
+ if(NState != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("EnqueueProbeRequest() allocate memory fail\n"));
+ return;
+ } else
+ {
+ if(MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, ZERO_MAC_ADDR))
+ ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
+ BROADCAST_ADDR, BROADCAST_ADDR, ifIndex);
+ else
+ ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
+ pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, ifIndex);
+
+ ssidLen = SsidLen;
+ NdisZeroMemory(ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(ssid, Ssid, ssidLen);
+
+ /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr80211,
+ 1, &SsidIe,
+ 1, &ssidLen,
+ ssidLen, ssid,
+ 1, &SupRateIe,
+ 1, &pAd->ApCliMlmeAux.SupRateLen,
+ pAd->ApCliMlmeAux.SupRateLen, pAd->ApCliMlmeAux.SupRate,
+ END_OF_ARGS);
+
+ /* Add the extended rate IE */
+ if (pAd->ApCliMlmeAux.ExtRateLen != 0)
+ {
+ ULONG tmp;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->ApCliMlmeAux.ExtRateLen,
+ pAd->ApCliMlmeAux.ExtRateLen, pAd->ApCliMlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ return;
+}
+
+#endif /* APCLI_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/ate/chips/mt7601_ate.c b/cleopatre/devkit/mt7601udrv/ate/chips/mt7601_ate.c
new file mode 100644
index 0000000000..208d3968b1
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ate/chips/mt7601_ate.c
@@ -0,0 +1,921 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2011, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt5592_ate.c
+
+ Abstract:
+ Specific ATE funcitons and variables for RT5572/RT5592
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
+#ifdef MT7601
+
+#include "rt_config.h"
+
+extern MT7601_FREQ_ITEM MT7601_Frequency_Plan[];
+extern UINT32 NUM_OF_MT7601_CHNL;
+extern RTMP_REG_PAIR MT7601_BBP_BW20RegTb[];
+extern UCHAR MT7601_BBP_BW20RegTb_Size;
+extern RTMP_REG_PAIR MT7601_BBP_BW40RegTb[];
+extern UCHAR MT7601_BBP_BW40RegTb_Size;
+extern RTMP_REG_PAIR MT7601_BBP_HighTempBW20RegTb[];
+extern UCHAR MT7601_BBP_HighTempBW20RegTb_Size;
+extern RTMP_REG_PAIR MT7601_BBP_HighTempBW40RegTb[];
+extern UCHAR MT7601_BBP_HighTempBW40RegTb_Size;
+extern RTMP_REG_PAIR MT7601_BBP_LowTempBW20RegTb[];
+extern UCHAR MT7601_BBP_LowTempBW20RegTb_Size;
+extern RTMP_REG_PAIR MT7601_BBP_LowTempBW40RegTb[];
+extern UCHAR MT7601_BBP_LowTempBW40RegTb_Size;
+
+VOID MT7601ATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 Value = 0;
+ CHAR TxPwer = 0;
+ UCHAR index = 0, Channel = 0;
+ /* added to prevent RF register reading error */
+ UCHAR RFValue = 0;
+ INT IdReg;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ SYNC_CHANNEL_WITH_QA(pATEInfo, &Channel);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> %s: SwitchChannel#%d BW = %x\n",
+ __FUNCTION__, Channel, pAd->ate.TxWI.TxWIBW));
+
+ /* fill Tx power value */
+ TxPwer = pATEInfo->TxPower0;
+
+ if (Channel > 14)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Can't find the Channel#%d \n", __FUNCTION__, Channel));
+ return;
+ }
+
+ for (index = 0; index < NUM_OF_MT7601_CHNL; index++)
+ {
+ if (Channel == MT7601_Frequency_Plan[index].Channel)
+ {
+ /* Frequeny plan setting */
+ AndesRFRandomWrite(pAd, 4,
+ RF_BANK0, RF_R17, MT7601_Frequency_Plan[index].K_R17,
+ RF_BANK0, RF_R18, MT7601_Frequency_Plan[index].K_R18,
+ RF_BANK0, RF_R19, MT7601_Frequency_Plan[index].K_R19,
+ RF_BANK0, RF_R20, MT7601_Frequency_Plan[index].N_R20);
+ }
+ }
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_0, &Value);
+ Value = Value & (~0x3F3F);
+ Value |= (TxPwer & 0x3F);
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_0, Value);
+
+ /* BBP setting */
+ 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)));
+
+ //RtmpUpdateFilterCoefficientControl(pAd, Channel);
+
+ /*
+ vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration.
+ */
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, 0x0A);
+ rlt_rf_write(pAd, RF_BANK0, RF_R05, 0x20);
+ rlt_rf_read(pAd, RF_BANK0, RF_R04, &RFValue);
+ RFValue = RFValue | 0x80;
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, RFValue);
+ RTMPusecDelay(2000);
+
+ rtmp_bbp_set_bw(pAd, pAd->ate.TxWI.TxWIBW);
+
+ switch (pAd->ate.TxWI.TxWIBW)
+ {
+ case BW_20:
+ if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_HIGH )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_HighTempBW20RegTb, MT7601_BBP_HighTempBW20RegTb_Size);
+ }
+ else if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_LOW )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_LowTempBW20RegTb, MT7601_BBP_LowTempBW20RegTb_Size);
+ }
+ else
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_BW20RegTb, MT7601_BBP_BW20RegTb_Size);
+ }
+
+
+ /* Tx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10001);
+ /* Rx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10000);
+ break;
+ case BW_40:
+ if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_HIGH )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_HighTempBW40RegTb, MT7601_BBP_HighTempBW40RegTb_Size);
+ }
+ else if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_LOW )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_LowTempBW40RegTb, MT7601_BBP_LowTempBW40RegTb_Size);
+ }
+ else
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_BW40RegTb, MT7601_BBP_BW40RegTb_Size);
+ }
+
+ /* Tx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10101);
+ /* Rx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10100);
+
+ break;
+ default:
+ break;
+ }
+
+ ATEAsicSetTxRxPath(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== %s: SwitchChannel#%d\n",
+ __FUNCTION__, Channel));
+
+}
+
+
+INT MT7601ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR TxPower = 0;
+ UCHAR MaxPower;
+ UINT32 RegValue = 0;
+ UCHAR Channel = pATEInfo->Channel;
+
+#ifdef RALINK_QA
+ if ((pATEInfo->bQATxStart == TRUE) || (pATEInfo->bQARxStart == TRUE))
+ {
+ return 0;
+ }
+ else
+#endif /* RALINK_QA */
+ if (index == 0)
+ {
+ TxPower = pATEInfo->TxPower0;
+ }
+ else
+ {
+ DBGPRINT_ERR(("%s : Only TxPower0 and TxPower1 are adjustable !\n", __FUNCTION__));
+ DBGPRINT_ERR(("%s : TxPower%d is out of range !\n", __FUNCTION__, index));
+ return -1;
+ }
+
+ if (Channel <= 14) /* G band */
+ {
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ if ( pATEInfo->bAutoTxAlc == FALSE )
+ {
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_1, &RegValue);
+ RegValue &= ~(0xFFFF);
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_1, RegValue);
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_1, pAd->chipCap.TxALCData.InitTxAlcCfg1);
+ }
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_0, &RegValue);
+ MaxPower = RegValue >> 24;
+ RegValue = RegValue & (~0x3F3F);
+ if ( TxPower > MaxPower )
+ TxPower = MaxPower;
+ RegValue |= (TxPower & 0x3F);
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_0, RegValue);
+
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : (TxPower%d=%d)\n", __FUNCTION__, index, TxPower));
+
+ return 0;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set RT5370 and RT5372 and RT5390 and RT5392 ATE RF BW
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT MT7601_Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT powerIndex;
+ UCHAR value = 0;
+ UCHAR BBPCurrentBW;
+ INT IdReg;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+
+ BBPCurrentBW = simple_strtol(arg, 0, 10);
+
+ if ((BBPCurrentBW == 0))
+ {
+ pAd->ate.TxWI.TxWIBW = BW_20;
+ }
+ else
+ {
+ pAd->ate.TxWI.TxWIBW = BW_40;
+ }
+
+ if ((pAd->ate.TxWI.TxWIPHYMODE == MODE_CCK) && (pAd->ate.TxWI.TxWIBW == BW_40))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_BW_Proc!! Warning!! CCK only supports 20MHZ!!\nBandwidth switch to 20\n"));
+ pAd->ate.TxWI.TxWIBW = BW_20;
+ }
+
+ if (pAd->ate.TxWI.TxWIBW == BW_20)
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ /* BW=20;G band */
+ for (powerIndex=0; powerIndex<MAX_TXPOWER_ARRAY_SIZE; powerIndex++)
+ {
+ if (pAd->Tx20MPwrCfgGBand[powerIndex] == 0xffffffff)
+ continue;
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgGBand[powerIndex]);
+ RtmpOsMsDelay(5);
+ }
+ }
+
+ /* BW=20 */
+ {
+ /* Set BBP R4 bit[4:3]=0:0 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, &value);
+ value &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+ }
+
+ if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_HIGH )
+ {
+ for(IdReg=0; IdReg < MT7601_BBP_HighTempBW20RegTb_Size; IdReg++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, MT7601_BBP_HighTempBW20RegTb[IdReg].Register,
+ MT7601_BBP_HighTempBW20RegTb[IdReg].Value);
+ }
+ }
+ else if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_LOW )
+ {
+ for(IdReg=0; IdReg < MT7601_BBP_LowTempBW20RegTb_Size; IdReg++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, MT7601_BBP_LowTempBW20RegTb[IdReg].Register,
+ MT7601_BBP_LowTempBW20RegTb[IdReg].Value);
+ }
+ }
+ else
+ {
+ for(IdReg=0; IdReg < MT7601_BBP_BW20RegTb_Size; IdReg++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, MT7601_BBP_BW20RegTb[IdReg].Register,
+ MT7601_BBP_BW20RegTb[IdReg].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.TxWIPHYMODE;
+
+ if (TxMode == MODE_CCK)
+ {
+ /* when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, &value);
+ value |= 0x20; /* set bit5=1 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+ }
+ }
+ }
+ /* If bandwidth = 40M, set RF Reg4 bit 21 = 0. */
+ else if (pAd->ate.TxWI.TxWIBW == BW_40)
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ /* BW=40;G band */
+ for (powerIndex=0; powerIndex<MAX_TXPOWER_ARRAY_SIZE; powerIndex++)
+ {
+ if (pAd->Tx40MPwrCfgGBand[powerIndex] == 0xffffffff)
+ continue;
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgGBand[powerIndex]);
+ RtmpOsMsDelay(5);
+ }
+ }
+
+ {
+ /* 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 ( pChipCap->TemperatureMode == TEMPERATURE_MODE_HIGH )
+ {
+ for(IdReg=0; IdReg < MT7601_BBP_HighTempBW40RegTb_Size; IdReg++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, MT7601_BBP_HighTempBW40RegTb[IdReg].Register,
+ MT7601_BBP_HighTempBW40RegTb[IdReg].Value);
+ }
+ }
+ else if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_LOW )
+ {
+ for(IdReg=0; IdReg < MT7601_BBP_LowTempBW40RegTb_Size; IdReg++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, MT7601_BBP_LowTempBW40RegTb[IdReg].Register,
+ MT7601_BBP_LowTempBW40RegTb[IdReg].Value);
+ }
+ }
+ else
+ {
+ for(IdReg=0; IdReg < MT7601_BBP_BW40RegTb_Size; IdReg++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, MT7601_BBP_BW40RegTb[IdReg].Register,
+ MT7601_BBP_BW40RegTb[IdReg].Value);
+ }
+ }
+
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.TxWIBW));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+
+
+
+
+#ifdef RTMP_INTERNAL_TX_ALC
+
+
+BOOLEAN MT7601ATEGetTssiCompensationParam(
+ IN PRTMP_ADAPTER pAd,
+ OUT PCHAR TssiLinear0,
+ OUT PCHAR TssiLinear1,
+ OUT PINT32 TargetPower)
+{
+#define MAX_TSSI_WAITING_COUNT 40
+ UCHAR RFReg, BBPReg;
+ UCHAR PacketType;
+ UCHAR BbpR47;
+ UCHAR TxRate;
+ INT32 Power;
+ UINT count;
+ UCHAR ch = 0;
+ MT7601_TX_ALC_DATA *pTxALCData = &pAd->chipCap.TxALCData;
+
+ if ((pAd->ate.Channel >= 1) && (pAd->ate.Channel <= 14))
+ {
+ ch = pAd->ate.Channel;
+ }
+ else
+ {
+ ch = 1;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::Incorrect channel #%d\n", __FUNCTION__, pAd->ate.Channel));
+ }
+
+ if ( pTxALCData->TssiTriggered == 0 )
+ {
+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD) )
+ {
+ MT7601_EnableTSSI(pAd);
+ pTxALCData->TssiTriggered = 1;
+ }
+
+ return FALSE;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPReg);
+ if(BBPReg & 0x10)
+ {
+ printk("#\n");
+
+ return FALSE;
+ }
+
+ /* 4. Read TSSI */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47);
+ BbpR47 = (BbpR47 & ~0x07);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, TssiLinear0);
+
+
+ /* 5. Read Temperature */
+ BbpR47 = (BbpR47 & ~0x07) | 0x04;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &(pAd->chipCap.CurrentTemperBbpR49));
+
+ BbpR47 = (BbpR47 & ~0x07) | 0x01;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &PacketType);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI = 0x%X\n", *TssiLinear0));
+ DBGPRINT(RT_DEBUG_TRACE, ("temperature = 0x%X\n", pAd->chipCap.CurrentTemperBbpR49));
+ //DBGPRINT(RT_DEBUG_TRACE, ("PacketType = 0x%X\n", PacketType));
+
+ Power = pAd->ate.TxPower0;
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("Channel Desire Power = %d\n", Power));
+
+ switch ( PacketType & 0x03)
+ {
+ case 0:
+ TxRate = (PacketType >> 2) & 0x03;
+ DBGPRINT(RT_DEBUG_TRACE, ("tx_11b_rate: %x\n", TxRate));
+ switch (TxRate)
+ {
+ case 0: // 1 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_CCK_1M : BW20_MCS_POWER_CCK_1M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_1M;
+ break;
+ case 1: // 2 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_CCK_2M : BW20_MCS_POWER_CCK_2M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_2M;
+ break;
+ case 2: // 5.5 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_CCK_5M : BW20_MCS_POWER_CCK_5M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_5M;
+ break;
+ case 3: // 11Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_CCK_11M : BW20_MCS_POWER_CCK_11M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_11M;
+ break;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R178, &BBPReg);
+ if ( BBPReg == 0 )
+ {
+ Power += 24576; // 3 * 8192
+ }
+ else
+ {
+ Power += 819; //0.1 x 8192;
+ }
+ break;
+ case 1:
+ TxRate = (PacketType >> 4) & 0x0F;
+ DBGPRINT(RT_DEBUG_TRACE, ("tx_11g_rate: %x\n", TxRate));
+ switch ( TxRate )
+ {
+ case 0xB: // 6 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_6M : BW20_MCS_POWER_OFDM_6M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_6M;
+ break;
+ case 0xF: // 9 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_9M : BW20_MCS_POWER_OFDM_9M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_9M;
+ break;
+ case 0xA: // 12 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_12M : BW20_MCS_POWER_OFDM_12M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_12M;
+ break;
+ case 0xE: // 18 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_18M : BW20_MCS_POWER_OFDM_18M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_18M;
+ break;
+ case 0x9: // 24 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_24M : BW20_MCS_POWER_OFDM_24M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_24M;
+ break;
+ case 0xD: // 36 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_36M : BW20_MCS_POWER_OFDM_36M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_36M;
+ break;
+ case 0x8: // 48 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_48M : BW20_MCS_POWER_OFDM_48M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_48M;
+ break;
+ case 0xC: // 54 Mbps
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_OFDM_54M : BW20_MCS_POWER_OFDM_54M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_54M;
+ break;
+ }
+ break;
+ default:
+ BbpR47 = (BbpR47 & ~0x07) | 0x02;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &TxRate);
+ DBGPRINT(RT_DEBUG_TRACE, ("tx_11n_rate: %x\n", TxRate));
+ TxRate &= 0x7F; // TxRate[7] is bandwidth
+ switch ( TxRate )
+ {
+ case 0x0:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS0: BW20_MCS_POWER_HT_MCS0;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS0;
+ break;
+ case 0x1:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS1: BW20_MCS_POWER_HT_MCS1;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS1;
+ break;
+ case 0x2:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS2: BW20_MCS_POWER_HT_MCS2;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS2;
+ break;
+ case 0x3:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS3: BW20_MCS_POWER_HT_MCS3;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS3;
+ break;
+ case 0x4:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS4: BW20_MCS_POWER_HT_MCS4;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS4;
+ break;
+ case 0x5:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS5: BW20_MCS_POWER_HT_MCS5;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS5;
+ break;
+ case 0x6:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS6: BW20_MCS_POWER_HT_MCS6;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS6;
+ break;
+ case 0x7:
+ Power += (pAd->ate.TxWI.TxWIBW == BW_40)? BW40_MCS_POWER_HT_MCS7: BW20_MCS_POWER_HT_MCS7;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS7;
+ break;
+
+ }
+ break;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPReg);
+ switch ( BBPReg & 0x3 )
+ {
+ case 1:
+ Power -= 49152; // -6 dB*8192
+ break;
+ case 2:
+ Power -= 98304; //-12 dB*8192
+ break;
+ case 3:
+ Power += 49152; // 6 dB*8192
+ break;
+ case 0:
+ default:
+ break;
+ }
+
+ Power += pTxALCData->MT7601_TSSI_T0_Delta_Offset;
+
+ *TargetPower = Power;
+ DBGPRINT(RT_DEBUG_TRACE, ("TargetPower: 0x%x(%d)\n", *TargetPower, *TargetPower));
+
+ return TRUE;
+
+}
+
+
+VOID MT7601ATEAsicTxAlcGetAutoAgcOffset(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT32 TargetPower, CurrentPower, PowerDiff;
+ UCHAR TssiLinear0, TssiLinear1;
+ CHAR tssi_offset;
+ INT16 tssi_db, tssi_m_dc;
+ UINT32 value;
+ UCHAR ch = 0;
+ MT7601_TX_ALC_DATA *pTxALCData = &pAd->chipCap.TxALCData;
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ //if (pATEInfo->OneSecPeriodicRound % 4 == 0)
+ {
+
+ if ((pAd->ate.Channel >= 1) && (pAd->ate.Channel <= 14))
+ {
+ ch = pAd->ate.Channel;
+ }
+ else
+ {
+ ch = 1;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::Incorrect channel #%d\n", __FUNCTION__, pAd->ate.Channel));
+ }
+
+ // if base power is lower than 10 dBm use High VGA
+ if(pAd->TxPower[ch - 1].Power <= 20)
+ pTxALCData->TSSI_USE_HVGA = 1;
+ else
+ pTxALCData->TSSI_USE_HVGA = 0;
+
+ if (MT7601ATEGetTssiCompensationParam(pAd, &TssiLinear0 , &TssiLinear1, &TargetPower) == FALSE )
+ return;
+
+ tssi_m_dc = TssiLinear0 - ((pTxALCData->TSSI_USE_HVGA == 1) ? pTxALCData->TssiDC0_HVGA : pTxALCData->TssiDC0);
+
+
+ tssi_db = lin2dBd(tssi_m_dc);
+
+ if ( ch <= 4 )
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[0];
+ else if ( ch >= 9 )
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[2];
+ else
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[1];
+
+ if(pTxALCData->TSSI_USE_HVGA == 1)
+ tssi_db -= pTxALCData->TSSI_DBOFFSET_HVGA;
+
+ CurrentPower = (pTxALCData->TssiSlope*tssi_db) + (tssi_offset << 9);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CurrentPower: %d\n", CurrentPower));
+
+ PowerDiff = TargetPower - CurrentPower;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PowerDiff: %d\n", PowerDiff));
+
+ if((TssiLinear0 > 126) && ( PowerDiff > 0)) // upper saturation
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s :: upper saturation.\n", __FUNCTION__));
+ PowerDiff = 0;
+ }
+ else
+ {
+ //if(((TssiLinear0 -TssiDC0) < 1) && (PowerDiff < 0)) // lower saturation
+ if(((TssiLinear0 -((pTxALCData->TSSI_USE_HVGA == 1) ? pTxALCData->TssiDC0_HVGA : pTxALCData->TssiDC0)) < 1) && (PowerDiff < 0)) // lower saturation
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s :: lower saturation.\n", __FUNCTION__));
+ PowerDiff = 0;
+ }
+ }
+
+ if( ((pTxALCData->PowerDiffPre ^ PowerDiff) < 0 )
+ && ( (PowerDiff < 4096) && (PowerDiff > -4096)) // +- 0.5
+ && ( (pTxALCData->PowerDiffPre < 4096) && (pTxALCData->PowerDiffPre > -4096))) // +- 0.5
+ {
+ if((PowerDiff > 0) && ((PowerDiff + pTxALCData->PowerDiffPre) >= 0))
+ PowerDiff = 0;
+ else if((PowerDiff < 0) && ((PowerDiff + pTxALCData->PowerDiffPre) < 0))
+ PowerDiff = 0;
+ else
+ pTxALCData->PowerDiffPre = PowerDiff;
+ }
+ else
+ {
+ pTxALCData->PowerDiffPre = PowerDiff;
+ }
+
+ PowerDiff = PowerDiff + ((PowerDiff>0)?2048:-2048);
+ PowerDiff = PowerDiff / 4096;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("final PowerDiff: %d(0x%x)\n", PowerDiff, PowerDiff));
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_1, &value);
+ CurrentPower = (value & 0x3F);
+ CurrentPower = CurrentPower > 0x1F ? CurrentPower - 0x40 : CurrentPower;
+ PowerDiff += CurrentPower;
+ if ( PowerDiff > 31 )
+ PowerDiff = 31;
+ if ( PowerDiff < -32 )
+ PowerDiff = -32;
+ //PowerDiff = PowerDiff + (value & 0x3F);
+ value = (value & ~0x3F) | (PowerDiff & 0x3F);
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_1, value);
+ DBGPRINT(RT_DEBUG_TRACE, ("MAC 13b4: 0x%x\n", value));
+
+ //MT7601AsicTemperatureCompensation(pAd);
+
+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD) )
+ {
+ MT7601_EnableTSSI(pAd);
+ pTxALCData->TssiTriggered = 1;
+ }
+
+ }
+
+
+}
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+
+VOID MT7601ATEAsicTemperatureCompensation(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->OneSecPeriodicRound % 4 == 0)
+ {
+#ifdef RTMP_INTERNAL_TX_ALC
+ if ( pAd->TxPowerCtrl.bInternalTxALC == FALSE )
+#endif /* RTMP_INTERNAL_TX_ALC */
+ {
+ MT7601_Read_Temperature(pAd, &pChipCap->CurrentTemperBbpR49);
+ }
+
+ MT7601AsicTemperatureCompensation(pAd, FALSE);
+ }
+}
+
+/*
+ ==========================================================================
+ 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 MT7601ATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ CHAR DeltaPwr = 0;
+ CHAR TxAgcCompensate = 0;
+ CHAR DeltaPowerByBbpR1 = 0;
+ 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 RTMP_INTERNAL_TX_ALC
+ /* Get temperature compensation delta power value */
+ MT7601ATEAsicTxAlcGetAutoAgcOffset(pAd);
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set MT7601 ATE RF central frequency offset
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT MT7601_Set_ATE_TX_FREQ_OFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR RFFreqOffset = 0;
+ ULONG R4 = 0;
+ UCHAR RFValue = 0;
+ UCHAR PreRFValue = 0;
+ RFFreqOffset = simple_strtol(arg, 0, 10);
+
+ pAd->ate.RFFreqOffset = RFFreqOffset;
+
+ if ( IS_MT7601(pAd))
+ {
+ rlt_rf_write(pAd, RF_BANK0, RF_R12, pAd->ate.RFFreqOffset);
+
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, 0x0A);
+ rlt_rf_write(pAd, RF_BANK0, RF_R05, 0x20);
+ rlt_rf_read(pAd, RF_BANK0, RF_R04, &RFValue);
+ RFValue = RFValue | 0x80; /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration. */
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, RFValue);
+ RTMPusecDelay(2000);
+ }
+
+ 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"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+VOID MT7601ATERxVGAInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR R66 = 0x14;
+ CHAR LNAGain = GET_LNA_GAIN(pAd);
+
+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, 0x14);
+
+ ATEBBPWriteWithRxChain(pAd, BBP_R66, R66, RX_CHAIN_ALL);
+
+
+ return;
+}
+
+
+VOID MT7601ATEAsicSetTxRxPath(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BbpValue = 0;
+
+ AsicSetRxAnt(pAd, pAd->ate.RxAntennaSel);
+}
+
+
+struct _ATE_CHIP_STRUCT MT7601ATE =
+{
+ /* functions */
+ .ChannelSwitch = MT7601ATEAsicSwitchChannel,
+ .TxPwrHandler = MT7601ATETxPwrHandler,
+ .TssiCalibration = NULL,
+ .ExtendedTssiCalibration = NULL /* RT5572_ATETssiCalibrationExtend */,
+ .RxVGAInit = MT7601ATERxVGAInit,
+ .AsicSetTxRxPath = MT7601ATEAsicSetTxRxPath,
+ .AdjustTxPower = MT7601ATEAsicAdjustTxPower,
+ //.AsicExtraPowerOverMAC = DefaultATEAsicExtraPowerOverMAC,
+ .Set_BW_Proc = MT7601_Set_ATE_TX_BW_Proc,
+ .Set_FREQ_OFFSET_Proc = MT7601_Set_ATE_TX_FREQ_OFFSET_Proc,
+ .TemperCompensation = MT7601ATEAsicTemperatureCompensation,
+
+ /* variables */
+ .maxTxPwrCnt = 5,
+ .bBBPStoreTXCARR = FALSE,
+ .bBBPStoreTXCARRSUPP = FALSE,
+ .bBBPStoreTXCONT = FALSE,
+ .bBBPLoadATESTOP = FALSE,/* ralink debug */
+};
+
+
+#endif /* MT7601 */
+
diff --git a/cleopatre/devkit/mt7601udrv/ate/common/ate_usb.c b/cleopatre/devkit/mt7601udrv/ate/common/ate_usb.c
new file mode 100644
index 0000000000..a7cd163ed1
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ate/common/ate_usb.c
@@ -0,0 +1,627 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ate_usb.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifdef RTMP_MAC_USB
+
+#include "rt_config.h"
+
+extern UCHAR EpToQueue[];
+/* 802.11 MAC Header, Type:Data, Length:24bytes + 6 bytes QOS/HTC + 2 bytes padding */
+extern UCHAR TemplateFrame[32];
+
+INT TxDmaBusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT result;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); /* disable DMA */
+ result = (UsbCfg.field.TxBusy) ? TRUE : FALSE;
+
+ return result;
+}
+
+
+INT RxDmaBusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT result;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); /* disable DMA */
+ result = (UsbCfg.field.RxBusy) ? TRUE : FALSE;
+
+ return result;
+}
+
+
+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;
+ }
+ 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;
+}
+
+
+static VOID ATEWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN TXWI_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)
+{
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ pTxWI->TxWIFRAG= FRAG;
+ pTxWI->TxWITS= InsTimestamp;
+ pTxWI->TxWIAMPDU = AMPDU;
+
+ pTxWI->TxWIMIMOps = PWR_ACTIVE;
+ pTxWI->TxWIMpduDensity = 4;
+ pTxWI->TxWIACK = Ack;
+ pTxWI->TxWITXOP = Txopmode;
+ pTxWI->TxWINSEQ = NSeq;
+ //pTxWI->TxWIBAWinSize = BASize;
+ pTxWI->TxWIBAWinSize = 21;
+
+ pTxWI->TxWIWirelessCliID = WCID;
+ pTxWI->TxWIMPDUByteCnt = Length;
+ //pTxWI->TxWIPacketId = PID;
+ pTxWI->TxWIPacketId = 7;
+
+ pTxWI->TxWIBW = Transmit.field.BW;
+ pTxWI->TxWIShortGI = Transmit.field.ShortGI;
+ pTxWI->TxWISTBC= Transmit.field.STBC;
+
+ pTxWI->TxWIMCS = Transmit.field.MCS;
+ pTxWI->TxWIPHYMODE= Transmit.field.MODE;
+ pTxWI->TxWICFACK = CfAck;
+
+ return;
+}
+
+
+/*
+========================================================================
+ Routine Description:
+ Write TxInfo for ATE mode.
+
+ Return Value:
+ None
+========================================================================
+*/
+static VOID ATEWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN TXINFO_STRUC *pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst)
+{
+#ifdef RLT_MAC
+ struct _TXINFO_NMAC_PKT *nmac_info;
+
+ nmac_info = (struct _TXINFO_NMAC_PKT *)pTxInfo;
+ nmac_info->pkt_80211 = 1;
+ nmac_info->info_type = 0;
+ nmac_info->d_port = 0;
+ nmac_info->cso = 0;
+ nmac_info->tso = 0;
+#endif /* RLT_MAC */
+
+#ifdef RTMP_MAC
+ /* ATE doesn't support checksum offload. */
+ pTxInfo->TxInfoCSO = 1;
+ pTxInfo->TxInfoUSO = 0;
+ pTxInfo->TxInfoTCPOffset = 0;
+ pTxInfo->TxInfoIPOffset = 0;
+#endif /* RTMP_MAC */
+
+ pTxInfo->TxInfoPktLen = USBDMApktLen;
+ pTxInfo->TxInfoQSEL = QueueSel;
+
+ if (QueueSel != FIFO_EDCA)
+ DBGPRINT(RT_DEBUG_TRACE, ("======= QueueSel != FIFO_EDCA =======\n"));
+
+ pTxInfo->TxInfoUDMANextVld = NextValid;
+ pTxInfo->TxInfoUDMATxburst = TxBurst;
+ pTxInfo->TxInfoWIV = bWiv;
+#ifndef USB_BULK_BUF_ALIGMENT
+ pTxInfo->TxInfoSwLstRnd = 0;
+#else
+ pTxInfo->bFragLasAlignmentsectiontRound = 0;
+#endif /* USB_BULK_BUF_ALIGMENT */
+
+ return;
+}
+
+
+INT ATESetUpFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TxIdx)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT pos = 0;
+ PTX_CONTEXT pNullContext;
+ PUCHAR pDest;
+ HTTRANSMIT_SETTING TxHTPhyMode;
+ TXWI_STRUC *pTxWI;
+ TXINFO_STRUC *pTxInfo;
+ UINT32 TransferBufferLength, OrgBufferLength = 0;
+ UCHAR padLen = 0;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+#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[0]);
+ 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 (pATEInfo->bQATxStart == TRUE)
+ {
+ pHeader80211 = NdisMoveMemory(&(pAd->NullFrame),
+ pATEInfo->Header, pATEInfo->HLen);
+ }
+ else
+#endif /* RALINK_QA */
+ {
+ 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 (pATEInfo->bQATxStart == TRUE)
+ {
+ /* modify sequence number... */
+ if (pATEInfo->TxDoneCount == 0)
+ {
+ pATEInfo->seq = pHeader80211->Sequence;
+ }
+ else
+ {
+ pHeader80211->Sequence = ++pATEInfo->seq;
+ }
+ /* We already got all the address fields from QA GUI. */
+ }
+ else
+#endif /* RALINK_QA */
+ {
+ COPY_MAC_ADDR(pAd->NullFrame.Addr1, pATEInfo->Addr1);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr2, pATEInfo->Addr2);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr3, pATEInfo->Addr3);
+ }
+
+ RTMPZeroMemory(&pAd->NullContext[0].TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE);
+ pTxInfo = (TXINFO_STRUC *)&pAd->NullContext[0].TransferBuffer->field.WirelessPacket[0];
+
+#ifdef RALINK_QA
+ if (pATEInfo->bQATxStart == TRUE)
+ {
+ /* Avoid to exceed the range of WirelessPacket[]. */
+ ASSERT(pATEInfo->TxInfo.TxInfoPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+ NdisMoveMemory(pTxInfo, &(pATEInfo->TxInfo), sizeof(pATEInfo->TxInfo));
+ }
+ else
+#endif /* RALINK_QA */
+ {
+ /* Avoid to exceed the range of WirelessPacket[]. */
+ ASSERT(pATEInfo->TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+
+ /* pTxInfo->TxInfoPktLen will be updated to include padding later */
+ ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWISize + pATEInfo->TxLength)
+ , TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxInfo->TxInfoQSEL = FIFO_EDCA;
+ }
+
+ pTxWI = (TXWI_STRUC *)&pAd->NullContext[0].TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+
+ /* fill TxWI */
+ if (pATEInfo->bQATxStart == TRUE)
+ {
+ TxHTPhyMode.field.BW = pATEInfo->TxWI.TxWIBW;
+ TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.TxWIShortGI;
+ TxHTPhyMode.field.STBC = pATEInfo->TxWI.TxWISTBC;
+ TxHTPhyMode.field.MCS = pATEInfo->TxWI.TxWIMCS;
+ TxHTPhyMode.field.MODE = pATEInfo->TxWI.TxWIPHYMODE;
+ ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.TxWIFRAG, pATEInfo->TxWI.TxWITS,
+ pATEInfo->TxWI.TxWIAMPDU, pATEInfo->TxWI.TxWIACK, pATEInfo->TxWI.TxWINSEQ,
+ pATEInfo->TxWI.TxWIBAWinSize, BSSID_WCID,
+ pATEInfo->TxWI.TxWIMPDUByteCnt/* include 802.11 header */,
+ pATEInfo->TxWI.TxWIPacketId,
+ 0, pATEInfo->TxWI.TxWITXOP/*IFS_HTTXOP*/, pATEInfo->TxWI.TxWICFACK
+ /*FALSE*/, TxHTPhyMode);
+ }
+ else
+ {
+ TxHTPhyMode.field.BW = pATEInfo->TxWI.TxWIBW;
+ TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.TxWIShortGI;
+ TxHTPhyMode.field.STBC = 0;
+ TxHTPhyMode.field.MCS = pATEInfo->TxWI.TxWIMCS;
+ TxHTPhyMode.field.MODE = pATEInfo->TxWI.TxWIPHYMODE;
+
+ ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE
+ /* No ack required. */, FALSE, 0, BSSID_WCID, pATEInfo->TxLength,
+ 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);
+ }
+
+ hex_dump("ATE", pAd->NullContext[0].TransferBuffer->field.WirelessPacket, 24);
+ dump_txinfo(pAd, pTxInfo);
+ dumpTxWI(pAd, pTxWI);
+
+
+ RTMPMoveMemory(&pAd->NullContext[0].TransferBuffer->field.WirelessPacket[TXINFO_SIZE + TXWISize],
+ &pAd->NullFrame, sizeof(HEADER_802_11));
+
+ pDest = &(pAd->NullContext[0].TransferBuffer->field.WirelessPacket[TXINFO_SIZE + TXWISize + sizeof(HEADER_802_11)]);
+
+ /* prepare frame payload */
+#ifdef RALINK_QA
+ if (pATEInfo->bQATxStart == TRUE)
+ {
+ /* copy the pattern one by one to the frame payload */
+ if ((pATEInfo->PLen != 0) && (pATEInfo->DLen != 0))
+ {
+ for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen)
+ {
+ RTMPMoveMemory(pDest, pATEInfo->Pattern, pATEInfo->PLen);
+ pDest += pATEInfo->PLen;
+ }
+ }
+ TransferBufferLength = TXINFO_SIZE + TXWISize + pATEInfo->TxWI.TxWIMPDUByteCnt;
+ }
+ else
+#endif /* RALINK_QA */
+ {
+ for (pos = 0; pos < (pATEInfo->TxLength - sizeof(HEADER_802_11)); pos++)
+ {
+ /* default payload is 0xA5 */
+ *pDest = pATEInfo->Payload;
+ pDest += 1;
+ }
+ TransferBufferLength = TXINFO_SIZE + TXWISize + pATEInfo->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->TxInfoPktLen to include padding. */
+ pTxInfo->TxInfoPktLen = 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[0].BulkOutSize = TransferBufferLength;
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
+ RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo) + TXWISize + TXINFO_SIZE), DIR_WRITE, FALSE);
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+#endif /* RT_BIG_ENDIAN */
+
+ hex_dump("ATE TX", &pAd->NullContext[0].TransferBuffer->field.WirelessPacket[0], TXWISize + TXINFO_SIZE);
+
+ return 0;
+}
+
+
+/*
+========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+========================================================================
+*/
+VOID ATE_RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId)
+{
+ PTX_CONTEXT pNullContext = &(pAd->NullContext[0]);
+ 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_ERR(("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+ return;
+ }
+
+ pAd->BulkOutReq++;
+
+ return;
+}
+
+
+/*
+========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ 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:
+ None
+
+ Note:
+
+========================================================================
+*/
+VOID ATEResetBulkIn(
+ IN PRTMP_ADAPTER pAd)
+{
+ if ((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_ERR(("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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ 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, ("pATEInfo->Mode == %d\npAd->ContinBulkOut == %d\npAd->BulkOutRemained == %d\n",
+ pATEInfo->Mode, pAd->ContinBulkOut, atomic_read(&pAd->BulkOutRemained)));
+
+ if ((pATEInfo->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_ERR(("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+ }
+
+ pAd->BulkOutReq++;
+ }
+
+ return ret;
+}
+
+
+/*
+========================================================================
+
+ 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 /* RTMP_MAC_USB */
+
diff --git a/cleopatre/devkit/mt7601udrv/ate/common/rt_ate.c b/cleopatre/devkit/mt7601udrv/ate/common/rt_ate.c
new file mode 100644
index 0000000000..fb4af7843b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ate/common/rt_ate.c
@@ -0,0 +1,6298 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_ate.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#include "rt_config.h"
+
+#define ATE_BBP_REG_NUM 168
+UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
+
+/* 802.11 MAC Header, Type:Data, Length:24bytes + 6 bytes QOS/HTC + 2 bytes padding */
+UCHAR TemplateFrame[32] = {0x08,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+extern FREQUENCY_ITEM *FreqItems3020;
+extern UCHAR NUM_OF_3020_CHNL;
+
+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
+
+#define ATE_TASK_EXEC_INTV 100 // 1000 -> 100
+
+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. */
+#endif /* DOT11N_SS3_SUPPORT */
+static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
+
+#ifdef RTMP_INTERNAL_TX_ALC
+
+/* The desired TSSI over CCK */
+extern CHAR desiredTSSIOverCCK[4];
+
+/* The desired TSSI over OFDM */
+extern CHAR desiredTSSIOverOFDM[8];
+
+/* The desired TSSI over HT */
+extern CHAR desiredTSSIOverHT[8];
+
+/* The desired TSSI over HT using STBC */
+extern CHAR desiredTSSIOverHTUsingSTBC[8];
+
+/* The Tx power tuning entry*/
+extern TX_POWER_TUNING_ENTRY_STRUCT TxPowerTuningTable[];
+
+/*
+==========================================================================
+ Description:
+ Get the desired TSSI based on ATE setting.
+
+ Arguments:
+ pAd
+
+ Return Value:
+ The desired TSSI
+==========================================================================
+ */
+ #ifdef MT7601
+CHAR ATEGetDesiredTSSI(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::Currently not support singledriver.\n", __FUNCTION__));
+ return 0;
+
+ }
+ #else
+CHAR ATEGetDesiredTSSI(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR desiredTSSI = 0;
+ UCHAR MCS = 0;
+ UCHAR MaxMCS = 7;
+
+ MCS = (UCHAR)(pATEInfo->TxWI.TxWIMCS);
+
+ if (pATEInfo->TxWI.TxWIPHYMODE == MODE_CCK)
+ {
+ if (MCS > 3) /* boundary verification */
+ {
+ DBGPRINT_ERR(("%s: incorrect MCS: MCS = %d\n",
+ __FUNCTION__,
+ MCS));
+
+ MCS = 0;
+ }
+
+ desiredTSSI = desiredTSSIOverCCK[MCS];
+ }
+ else if (pATEInfo->TxWI.TxWIPHYMODE == MODE_OFDM)
+ {
+ if (MCS > 7) /* boundary verification */
+ {
+ DBGPRINT_ERR(("%s: incorrect MCS: MCS = %d\n",
+ __FUNCTION__,
+ MCS));
+
+ MCS = 0;
+ }
+
+ desiredTSSI = desiredTSSIOverOFDM[MCS];
+ }
+ else if ((pATEInfo->TxWI.TxWIPHYMODE == MODE_HTMIX) || (pATEInfo->TxWI.TxWIPHYMODE == MODE_HTGREENFIELD))
+ {
+ if (pATEInfo->TxWI.TxWISTBC == STBC_NONE)
+ {
+ if (MCS > MaxMCS) /* boundary verification */
+ {
+ DBGPRINT_ERR(("%s: incorrect MCS: MCS = %d\n",
+ __FUNCTION__,
+ MCS));
+
+ MCS = 0;
+ }
+
+ desiredTSSI = desiredTSSIOverHT[MCS];
+ }
+ else
+ {
+ if (MCS > MaxMCS) /* boundary verification */
+ {
+ DBGPRINT_ERR(("%s: incorrect MCS: MCS = %d\n",
+ __FUNCTION__,
+ MCS));
+
+ MCS = 0;
+ }
+
+ desiredTSSI = desiredTSSIOverHTUsingSTBC[MCS];
+ }
+
+
+ /*
+ For HT BW40 MCS 7 with/without STBC configuration,
+ the desired TSSI value should subtract one from the formula.
+ */
+ if ((pATEInfo->TxWI.TxWIBW == BW_40) && (MCS == MCS_7))
+ {
+ desiredTSSI -= 1;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSI = %d, Latest Tx setting: MODE = %d, MCS = %d, STBC = %d\n",
+ __FUNCTION__,
+ desiredTSSI,
+ pATEInfo->TxWI.TxWIPHYMODE,
+ pATEInfo->TxWI.TxWIMCS,
+ pATEInfo->TxWI.TxWISTBC));
+
+
+ return desiredTSSI;
+}
+#endif /* MT7601 */
+
+#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. TxPowerPercentage
+ 1. auto calibration based on TSSI feedback
+ 2. extra 2 db for CCK
+ 3. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+==========================================================================
+*/
+VOID DefaultATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ PATE_CHIP_STRUCT pChipStruct = pATEInfo->pChipStruct;
+ INT index = 0, inner_index = 0, 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;
+ const TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable = pAd->chipCap.TxPowerTuningTable_2G;
+ PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL;
+ UCHAR RFValue = 0, TmpValue = 0;
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ maxTxPwrCnt = pChipStruct->maxTxPwrCnt;
+
+ if (pATEInfo->TxWI.TxWIBW == BW_40)
+ {
+ if (pATEInfo->Channel > 14)
+ {
+ for (index =0 ; index < maxTxPwrCnt; index ++)
+ {
+ TxPwr[index] = pAd->Tx40MPwrCfgABand[index];
+ }
+ }
+ else
+ {
+ for (index =0 ; index < maxTxPwrCnt; index ++)
+ {
+ TxPwr[index] = pAd->Tx40MPwrCfgGBand[index];
+ }
+ }
+ }
+ else
+ {
+ if (pATEInfo->Channel > 14)
+ {
+ for (index =0 ; index < maxTxPwrCnt; index ++)
+ {
+ TxPwr[index] = pAd->Tx20MPwrCfgABand[index];
+ }
+ }
+ else
+ {
+ for (index =0 ; index < maxTxPwrCnt; index ++)
+ {
+ TxPwr[index] = pAd->Tx20MPwrCfgGBand[index];
+ }
+ }
+ }
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ /* Locate the internal Tx ALC tuning entry */
+ if (pAd->TxPowerCtrl.bInternalTxALC == TRUE)
+ {
+ {
+ desiredTSSI = ATEGetDesiredTSSI(pAd);
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+ currentTSSI = BbpR49 & 0x1F;
+
+ if (pAd->TxPowerCtrl.bExtendedTssiMode == TRUE) /* Per-channel TSSI */
+ {
+ if ((pATEInfo->Channel >= 1) && (pATEInfo->Channel <= 14))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: bExtendedTssiMode = %d, original desiredTSSI = %d, CentralChannel = %d, PerChTxPwrOffset = %d\n",
+ __FUNCTION__,
+ pAd->TxPowerCtrl.bExtendedTssiMode,
+ desiredTSSI,
+ pATEInfo->Channel,
+ pAd->TxPowerCtrl.PerChTxPwrOffset[pATEInfo->Channel]));
+
+ desiredTSSI += pAd->TxPowerCtrl.PerChTxPwrOffset[pATEInfo->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_TX_ALC = pTxPowerTuningEntry->RF_TX_ALC;
+ pAd->TxPowerCtrl.MAC_PowerDelta = pTxPowerTuningEntry->MAC_PowerDelta;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->TxPowerCtrl.idxTxPowerTable = %d, pAd->TxPowerCtrl.RF_TX_ALC = %d, pAd->TxPowerCtrl.MAC_PowerDelta = %d\n",
+ pAd->TxPowerCtrl.idxTxPowerTable, pAd->TxPowerCtrl.RF_TX_ALC, pAd->TxPowerCtrl.MAC_PowerDelta ));
+
+ /* Tx power adjustment over RF */
+ /* In ATE mode, only adjust TX0_ALC by default. */
+ if (IS_RT5350(pAd))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MT7601 Bata driver not support RT30xxReadRFRegister() and RT30xxWriteRFRegister().\n"));
+ }
+ else if (IS_RT3352(pAd))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MT7601 Bata driver not support RT30xxReadRFRegister() and RT30xxWriteRFRegister().\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MT7601 Bata driver not support RT30xxReadRFRegister() and RT30xxWriteRFRegister().\n"));
+ }
+
+ /* Tx power adjustment over MAC */
+ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSI = %d, currentTSSI = %d, idxTxPowerTable = %d, {RF_TX_ALC = %d, MAC_PowerDelta = %d}\n",
+ __FUNCTION__,
+ desiredTSSI,
+ currentTSSI,
+ pAd->TxPowerCtrl.idxTxPowerTable,
+ pTxPowerTuningEntry->RF_TX_ALC,
+ pTxPowerTuningEntry->MAC_PowerDelta));
+ }
+ }
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ /* TX power compensation for temperature variation based on TSSI. */
+ /* Do it per 4 seconds. */
+ if (pATEInfo->OneSecPeriodicRound % 4 == 0)
+ {
+ if (pATEInfo->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 (pATEInfo->Channel <= 14)
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ DeltaPwr += (*pTxAgcCompensate);
+ }
+
+ /* Reset different new tx power for different TX rate. */
+ for (index=0; index<maxTxPwrCnt; index++)
+ {
+ if (TxPwr[index] != 0xffffffff)
+ {
+ for (inner_index=0; inner_index<8; inner_index++)
+ {
+ Value = (CHAR)((TxPwr[index] >> inner_index*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 + (index * 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 ((inner_index >= 0) && (inner_index <= 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 ((inner_index == 0) || (inner_index == 2) || (inner_index == 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 ((inner_index == 0) || (inner_index == 2) || (inner_index == 3) ||
+ ((inner_index >= 4) && (inner_index <= 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_ERR(("%s : unknown register = 0x%X\n",
+ __FUNCTION__,
+ (TX_PWR_CFG_0 + (index << 2))));
+ }
+ 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[index] = (TxPwr[index] & ~(0x0000000F << inner_index*4)) | (Value << inner_index*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 (index == 5)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_5, TxPwr[index]);
+ }
+ else if (index == 6)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_6, TxPwr[index]);
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + (index << 2), TxPwr[index]);
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0_EXT + (index << 2), (TxPwr[index] & 0xf0f0f0f0) >> 4);
+ }
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + (index << 2), TxPwr[index]);
+ }
+#else
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + (index << 2), TxPwr[index]);
+#endif /* DOT11N_SS3_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATEAsicAdjustTxPower - DeltaPwr=%d, offset=0x%x, TxPwr=%lx, BbpR1=%x, round=%ld, pTxAgcCompensate=%d \n",
+ DeltaPwr, TX_PWR_CFG_0 + (index << 2), TxPwr[index], BbpR49, pATEInfo->OneSecPeriodicRound, *pTxAgcCompensate));
+
+ }
+ }
+
+}
+
+
+/*
+==========================================================================
+ 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. TxPowerPercentage
+ 1. auto calibration based on TSSI feedback
+ 2. extra 2 db for CCK
+ 3. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+==========================================================================
+*/
+VOID ATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->AdjustTxPower != NULL)
+ pATEInfo->pChipStruct->AdjustTxPower(pAd);
+ else
+ DBGPRINT_ERR(("%s: AdjustTxPower() for this chipset does not exist !\n", __FUNCTION__));
+
+ return;
+}
+
+
+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 || (RssiNumber >= 3))
+ return -99;
+
+ LNAGain = GET_LNA_GAIN(pAd);
+ if (pAd->LatchRfRegs.Channel > 14)
+ RssiOffset = pAd->ARssiOffset[RssiNumber];
+ else
+ RssiOffset = pAd->BGRssiOffset[RssiNumber];
+
+ return (-12 - RssiOffset - LNAGain - Rssi);
+}
+
+
+VOID ATESampleRssi(
+ IN RTMP_ADAPTER *pAd,
+ IN RXWI_STRUC *pRxWI)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pRxWI->RxWIRSSI0 != 0)
+ {
+ pATEInfo->LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RxWIRSSI0, RSSI_0);
+ pATEInfo->AvgRssi0X8 = (pATEInfo->AvgRssi0X8 - pATEInfo->AvgRssi0) + pATEInfo->LastRssi0;
+ pATEInfo->AvgRssi0 = pATEInfo->AvgRssi0X8 >> 3;
+ }
+
+ if (pRxWI->RxWIRSSI1 != 0)
+ {
+ pATEInfo->LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RxWIRSSI1, RSSI_1);
+ pATEInfo->AvgRssi1X8 = (pATEInfo->AvgRssi1X8 - pATEInfo->AvgRssi1) + pATEInfo->LastRssi1;
+ pATEInfo->AvgRssi1 = pATEInfo->AvgRssi1X8 >> 3;
+ }
+
+ if (pRxWI->RxWIRSSI2 != 0)
+ {
+ pATEInfo->LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RxWIRSSI2, RSSI_2);
+ pATEInfo->AvgRssi2X8 = (pATEInfo->AvgRssi2X8 - pATEInfo->AvgRssi2) + pATEInfo->LastRssi2;
+ pATEInfo->AvgRssi2 = pATEInfo->AvgRssi2X8 >> 3;
+ }
+
+ pATEInfo->LastSNR0 = (CHAR)(pRxWI->RxWIRSSI0);
+ pATEInfo->LastSNR1 = (CHAR)(pRxWI->RxWIRSSI1);
+#ifdef DOT11N_SS3_SUPPORT
+ pATEInfo->LastSNR2 = (CHAR)(pRxWI->RxWIRSSI2);
+#endif /* DOT11N_SS3_SUPPORT */
+
+ pATEInfo->NumOfAvgRssiSample ++;
+
+ return;
+}
+
+
+VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+ USHORT offset = 0;
+ USHORT value;
+
+
+ for (offset = 0; offset < (EEPROM_SIZE >> 1);)
+ {
+ RT28xx_EEPROM_READ16(pAd, (offset << 1), value);
+ Data[offset] = value;
+ offset++;
+ }
+
+ return;
+}
+
+
+VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+ USHORT offset = 0;
+ 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)
+ {
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ USHORT length = 0x100;
+ UCHAR *ptr = (UCHAR *)Data;
+ UCHAR index;
+ UCHAR AllFF[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ for ( offset = 0 ; offset < length ; offset += 16 )
+ {
+ if ( memcmp( ptr, AllFF, 16 ) )
+ {
+ for ( index = 0 ; index < 16 ; index += 2 )
+ {
+ value = *(USHORT *)(ptr + index);
+ eFuseWrite(pAd, offset + index ,&value, 2);
+ }
+ }
+
+ ptr += 16;
+ }
+ pAd->bCalFreeIC = FALSE;
+ return;
+ }
+ else
+#endif /* MT7601 */
+ {
+ USHORT offset = 0;
+ USHORT length = EEPROM_SIZE;
+
+ RTUSBWriteEEPROM(pAd, offset, (UCHAR *)Data, length);
+ return;
+ }
+ }
+#endif /* RTMP_USB_SUPPORT */
+
+ for (offset = 0; offset < (EEPROM_SIZE >> 1);)
+ {
+ value = Data[offset];
+ RT28xx_EEPROM_WRITE16(pAd, (offset << 1), value);
+ offset++;
+ }
+
+ return;
+}
+
+
+VOID rt_ee_write_bulk(PRTMP_ADAPTER pAd, USHORT *Data, USHORT offset, USHORT length)
+{
+ USHORT pos;
+ USHORT value;
+ USHORT len = length;
+
+
+ for (pos = 0; pos < (len >> 1);)
+ {
+ value = Data[pos];
+ RT28xx_EEPROM_WRITE16(pAd, offset+(pos*2), value);
+ pos++;
+ }
+
+ return;
+}
+
+
+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;
+}
+
+
+VOID DefaultATEAsicSetTxRxPath(
+ IN PRTMP_ADAPTER pAd)
+{
+
+}
+
+
+VOID ATEAsicSetTxRxPath(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->AsicSetTxRxPath != NULL)
+ pATEInfo->pChipStruct->AsicSetTxRxPath(pAd);
+
+ return;
+}
+
+
+/*
+==========================================================================
+ Description:
+
+ Default AsicSwitchChannel() dedicated for ATE.
+
+==========================================================================
+*/
+VOID DefaultATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 Value = 0;
+ CHAR TxPwer = 0, TxPwer2 = 0;
+ UCHAR BbpValue = 0, R66 = 0x30, Channel = 0;
+
+ SYNC_CHANNEL_WITH_QA(pATEInfo, &Channel);
+
+ /* fill Tx power value */
+ TxPwer = pATEInfo->TxPower0;
+ TxPwer2 = pATEInfo->TxPower1;
+
+ /* 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)));
+
+ /* 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 (pATEInfo->TxAntennaSel == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF7;
+ }
+ else if (pATEInfo->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 (pATEInfo->TxWI.TxWIBW == 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);
+
+}
+
+
+/*
+==========================================================================
+ Description:
+
+ AsicSwitchChannel() dedicated for ATE.
+
+==========================================================================
+*/
+VOID ATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->ChannelSwitch != NULL)
+ pATEInfo->pChipStruct->ChannelSwitch(pAd);
+
+ return;
+}
+
+
+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;
+}
+
+
+static VOID BbpHardReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 MacData = 0;
+
+
+ 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);
+
+ return;
+}
+
+
+static int CheckMCSValid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Mode,
+ IN UCHAR Mcs)
+{
+ int index;
+ 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_ERR(("unrecognizable Tx Mode %d\n", Mode));
+ return -1;
+ break;
+ }
+
+ index = 0;
+ while (pRateTab[index] != -1)
+ {
+ if (pRateTab[index] == Mcs)
+ return 0;
+ index++;
+ }
+
+ return -1;
+}
+
+
+INT DefaultATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR TxPower = 0;
+
+#ifdef RALINK_QA
+ if ((pATEInfo->bQATxStart == TRUE) || (pATEInfo->bQARxStart == TRUE))
+ {
+ /*
+ When QA is used for Tx, pATEInfo->TxPower0/1 and real tx power
+ are not synchronized.
+ */
+ return 0;
+ }
+ else
+#endif /* RALINK_QA */
+
+ if (index == 0)
+ {
+ TxPower = pATEInfo->TxPower0;
+ }
+ else if (index == 1)
+ {
+ TxPower = pATEInfo->TxPower1;
+ }
+ else
+ {
+ DBGPRINT_ERR(("%s : Only TxPower0 and TxPower1 are adjustable !\n", __FUNCTION__));
+ DBGPRINT_ERR(("TxPower%d is out of range !\n", index));
+ return -1;
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- %s\n", __FUNCTION__));
+
+ return 0;
+}
+
+
+INT ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->TxPwrHandler != NULL)
+ pATEInfo->pChipStruct->TxPwrHandler(pAd, index);
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ 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 ((pATEInfo->TxWI.TxWIPHYMODE == MODE_CCK) && (pATEInfo->Channel == 14) && (pATEInfo->TxWI.TxWIBW == 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 step;
+ 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 (step = 0;step < 6;step++)
+ RTMP_IO_WRITE32(pAd, offset + step*4, Protect[step]);
+
+ return;
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+==========================================================================
+ Description:
+ Used only by ATE to disassociate all STAs and stop AP service.
+ Note:
+==========================================================================
+*/
+VOID ATEAPStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN Cancelled;
+ UINT32 Value = 0;
+ INT apidx = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! ATEAPStop !!!\n"));
+
+ /* To prevent MCU to modify BBP registers w/o indications from driver. */
+#ifdef DFS_SUPPORT
+ NewRadarDetectionStop(pAd);
+#endif /* DFS_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ CarrierDetectionStop(pAd);
+ }
+#endif /* CARRIER_DETECTION_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef WDS_SUPPORT
+ WdsDown(pAd);
+#endif /* WDS_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+ ApCliIfDown(pAd);
+#endif /* APCLI_SUPPORT */
+
+ MacTableReset(pAd);
+
+ /* Disable pre-tbtt interrupt */
+ RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
+ Value &=0xe;
+ RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
+ /* Disable piggyback */
+ RTMPSetPiggyBack(pAd, FALSE);
+
+ ATEDisableAsicProtect(pAd);
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ AsicDisableSync(pAd);
+
+#ifdef LED_CONTROL_SUPPORT
+ /* Set LED */
+ RTMPSetLED(pAd, LED_LINK_DOWN);
+#endif /* LED_CONTROL_SUPPORT */
+ }
+
+#ifdef RTMP_MAC_USB
+ /* For USB, we need to clear the beacon sync buffer. */
+ RTUSBBssBeaconExit(pAd);
+#endif /* RTMP_MAC_USB */
+
+ for (apidx = 0; apidx < MAX_MBSSID_NUM(pAd); apidx++)
+ {
+ if (pAd->ApCfg.MBSSID[apidx].REKEYTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pAd->ApCfg.MBSSID[apidx].REKEYTimer, &Cancelled);
+ pAd->ApCfg.MBSSID[apidx].REKEYTimerRunning = FALSE;
+ }
+ }
+
+ if (pAd->ApCfg.CMTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled);
+ pAd->ApCfg.CMTimerRunning = FALSE;
+ }
+
+#ifdef WAPI_SUPPORT
+ RTMPCancelWapiRekeyTimerAction(pAd, NULL);
+#endif /* WAPI_SUPPORT */
+
+ /* Cancel the Timer, to make sure the timer was not queued. */
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
+ RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected);
+
+ if (pAd->ApCfg.ApQuickResponeForRateUpTimerRunning == TRUE)
+ RTMPCancelTimer(&pAd->ApCfg.ApQuickResponeForRateUpTimer, &Cancelled);
+
+#ifdef IDS_SUPPORT
+ /* if necessary, cancel IDS timer */
+ RTMPIdsStop(pAd);
+#endif /* IDS_SUPPORT */
+
+
+#ifdef GREENAP_SUPPORT
+ if (pAd->ApCfg.bGreenAPEnable == TRUE)
+ {
+ RTMP_CHIP_DISABLE_AP_MIMOPS(pAd);
+ pAd->ApCfg.GreenAPLevel=GREENAP_WITHOUT_ANY_STAS_CONNECT;
+ pAd->ApCfg.bGreenAPEnable = FALSE;
+ }
+#endif /* GREENAP_SUPPORT */
+
+
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+
+
+static NDIS_STATUS ATESTART(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 MacData=0, atemode=0, temp=0;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR BbpData = 0;
+#ifdef RTMP_MAC_USB
+ UCHAR LoopCount=0;
+#endif /* RTMP_MAC_USB */
+ PATE_CHIP_STRUCT pChipStruct = pATEInfo->pChipStruct;
+ BOOLEAN Cancelled;
+
+ 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 = pATEInfo->Mode;
+ pATEInfo->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
+
+#ifdef MT7601
+ MT7601DisableTxRx(pAd, GUIRADIO_OFF);
+#endif /* MT7601 */
+
+
+ /* 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 */
+ ATE_MAC_RX_DISABLE(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);
+
+ ATE_MAC_TX_CTS_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ if (atemode == ATE_TXCARR)
+ {
+ if (pChipStruct->bBBPStoreTXCARR == TRUE)
+ {
+ UINT32 bbp_index=0;
+ UCHAR RestoreRfICType=pAd->RfIcType;
+
+ BbpHardReset(pAd);
+
+ /* Restore All BBP Value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,bbp_index,restore_BBP[bbp_index]);
+
+ pAd->RfIcType=RestoreRfICType;
+ }
+
+ if (pATEInfo->TxMethod == TX_METHOD_1)
+ {
+ /* 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_RESET_TX_MODE(pAd, BBP_R22, &BbpData);
+ }
+ }
+ else if (atemode == ATE_TXCARRSUPP)
+ {
+ if (pChipStruct->bBBPStoreTXCARRSUPP == TRUE)
+ {
+ UINT32 bbp_index=0;
+ UCHAR RestoreRfICType=pAd->RfIcType;
+
+ BbpHardReset(pAd);
+
+ /* Restore All BBP Value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,bbp_index,restore_BBP[bbp_index]);
+
+ pAd->RfIcType=RestoreRfICType;
+ }
+
+ /* No Cont. TX set BBP R22 bit7=0 */
+ ATE_BBP_STOP_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ /* No Carrier Suppression set BBP R24 bit0=0 */
+ ATE_BBP_CTS_TX_SIN_WAVE_DISABLE(pAd, BBP_R24, &BbpData);
+
+ if (pATEInfo->TxMethod == TX_METHOD_1)
+ {
+ BbpSoftReset(pAd);
+ RTMP_IO_WRITE32(pAd, RA_TX_PIN_CFG, Default_TX_PIN_CFG);
+ }
+ }
+
+ /*
+ 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 (pChipStruct->bBBPStoreTXCONT == TRUE)
+ {
+ UINT32 bbp_index=0;
+ UCHAR RestoreRfICType=pAd->RfIcType;
+
+ BbpHardReset(pAd);
+
+ /* Restore All BBP Value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,bbp_index,restore_BBP[bbp_index]);
+
+ pAd->RfIcType=RestoreRfICType;
+ }
+
+ /* Not Cont. TX anymore, so set BBP R22 bit7=0 */
+ ATE_BBP_STOP_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ if (pATEInfo->TxMethod == TX_METHOD_1)
+ {
+ BbpSoftReset(pAd);
+ RTMP_IO_WRITE32(pAd, RA_TX_PIN_CFG, Default_TX_PIN_CFG);
+ }
+ }
+
+ /* Abort Tx, Rx DMA. */
+ RtmpDmaEnable(pAd, 0);
+
+ /* Start Tx, RX DMA */
+ RtmpDmaEnable(pAd, 1);
+ }
+
+#ifdef RTMP_MAC_USB
+/* pAd->ContinBulkIn = FALSE; */
+ RTUSBRejectPendingPackets(pAd);
+ RTUSBCleanUpDataBulkOutQueue(pAd);
+
+
+ RTUSBCleanUpMLMEBulkOutQueue(pAd);
+
+
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Abort Tx, RX DMA. */
+ /* If disable DMA TX and RX, in-band command not word */
+ //RtmpDmaEnable(pAd, 0);
+
+ /* Disable Tx */
+ ATE_MAC_TX_DISABLE(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. */
+ pATEInfo->LastSNR0 = 0;
+ pATEInfo->LastSNR1 = 0;
+#ifdef DOT11N_SS3_SUPPORT
+ pATEInfo->LastSNR2 = 0;
+#endif /* DOT11N_SS3_SUPPORT */
+ pATEInfo->LastRssi0 = 0;
+ pATEInfo->LastRssi1 = 0;
+ pATEInfo->LastRssi2 = 0;
+ pATEInfo->AvgRssi0 = 0;
+ pATEInfo->AvgRssi1 = 0;
+ pATEInfo->AvgRssi2 = 0;
+ pATEInfo->AvgRssi0X8 = 0;
+ pATEInfo->AvgRssi1X8 = 0;
+ pATEInfo->AvgRssi2X8 = 0;
+ pATEInfo->NumOfAvgRssiSample = 0;
+
+#ifdef RALINK_QA
+ /* Tx frame */
+ pATEInfo->bQATxStart = FALSE;
+ pATEInfo->bQARxStart = FALSE;
+ pATEInfo->seq = 0;
+
+ /* counters */
+ pATEInfo->U2M = 0;
+ pATEInfo->OtherData = 0;
+ pATEInfo->Beacon = 0;
+ pATEInfo->OtherCount = 0;
+ pATEInfo->TxAc0 = 0;
+ pATEInfo->TxAc1 = 0;
+ pATEInfo->TxAc2 = 0;
+ pATEInfo->TxAc3 = 0;
+ pATEInfo->TxHCCA = 0;
+ pATEInfo->TxMgmt = 0;
+ pATEInfo->RSSI0 = 0;
+ pATEInfo->RSSI1 = 0;
+ pATEInfo->RSSI2 = 0;
+ pATEInfo->SNR0 = 0;
+ pATEInfo->SNR1 = 0;
+#ifdef DOT11N_SS3_SUPPORT
+ pATEInfo->SNR2 = 0;
+#endif /* DOT11N_SS3_SUPPORT */
+ pATEInfo->IPG = 200;
+
+ /* control */
+ pATEInfo->TxDoneCount = 0;
+ /* TxStatus : 0 --> task is idle, 1 --> task is running */
+ pATEInfo->TxStatus = 0;
+#endif /* RALINK_QA */
+
+ /* Soft reset BBP. */
+ BbpSoftReset(pAd);
+
+#ifdef CONFIG_AP_SUPPORT
+
+ /* Set IPG 200 by default. */
+ Set_ATE_IPG_Proc(pAd, "200");
+ if (atemode == ATE_STOP)
+ ATEAPStop(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if ((atemode == ATE_STOP) && (pATEInfo->PeriodicTimer.State == FALSE))
+ {
+ /* Do it for the first time entering ATE mode */
+ pATEInfo->PeriodicTimer.State = TRUE;
+ }
+
+ if (pATEInfo->PeriodicTimer.State == TRUE)
+ {
+ /*
+ For rx statistics, we cancel pAd->Mlme.PeriodicTimer
+ and set pAd->ate.PeriodicTimer.
+ */
+ RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+ /* Init ATE periodic timer */
+ RTMPInitTimer(pAd, &pAd->ate.PeriodicTimer, GET_TIMER_FUNCTION(ATEPeriodicExec), pAd, TRUE);
+ /* Set ATE periodic timer */
+ RTMPSetTimer(&pAd->ate.PeriodicTimer, ATE_TASK_EXEC_INTV);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("We are still in ATE mode, "));
+ DBGPRINT(RT_DEBUG_TRACE, ("so we keep ATE periodic timer running.\n"));
+ }
+
+#ifdef LED_CONTROL_SUPPORT
+ RTMPExitLEDMode(pAd);
+#endif /* LED_CONTROL_SUPPORT */
+
+
+#ifdef RTMP_MAC_USB
+ /* Default value in BBP R22 is 0x0. */
+ ATE_BBP_RESET_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ /* Clear bit4 to stop continuous Tx production test. */
+ ATE_MAC_TX_CTS_DISABLE(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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 MacData=0, ring_index=0;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR BbpData = 0;
+ PATE_CHIP_STRUCT pChipStruct = pATEInfo->pChipStruct;
+ BOOLEAN Cancelled;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__));
+
+ if (pChipStruct->bBBPLoadATESTOP == TRUE)
+ {
+ UINT32 bbp_index=0;
+ UCHAR RestoreRfICType=pAd->RfIcType;
+
+ BbpHardReset(pAd);
+
+ /* Supposed that we have had a record in restore_BBP[] */
+ /* restore all BBP value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,bbp_index,restore_BBP[bbp_index]);
+
+ ASSERT(RestoreRfICType != 0);
+ pAd->RfIcType=RestoreRfICType;
+ }
+
+
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = FALSE;
+ //pAd->ContinBulkIn = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ /* Default value in BBP R22 is 0x0. */
+ ATE_BBP_RESET_TX_MODE(pAd, BBP_R22, &BbpData);
+
+#ifdef MT7601
+ MT7601DisableTxRx(pAd, GUIRADIO_OFF);
+#else
+ /* Clear bit4 to stop continuous Tx production test. */
+ ATE_MAC_TX_CTS_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Abort Tx, RX DMA */
+ RtmpDmaEnable(pAd, 0);
+
+ /* Disable Tx */
+ ATE_MAC_TX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+#endif /* MT7601 */
+
+ pAd->ContinBulkIn = FALSE;
+
+
+ if (pATEInfo->PeriodicTimer.State == FALSE)
+ {
+ /*
+ For rx statistics, we cancel pAd->Mlme.PeriodicTimer
+ and set pATEInfo->PeriodicTimer in stead of.
+ Now we recover it before we leave ATE mode.
+ */
+ RTMPCancelTimer(&pATEInfo->PeriodicTimer, &Cancelled);
+ /* 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);
+ }
+ else
+ {
+ /* ATE periodic timer has been cancelled. */
+ Status = NDIS_STATUS_FAILURE;
+ DBGPRINT_ERR(("Initialization of MLME periodic timer failed, Status[=0x%08x]\n", Status));
+
+ return Status;
+ }
+
+
+#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
+ */
+/* pAd->ContinBulkIn = FALSE; */
+
+ if (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);
+ BbpSoftReset(pAd);
+ {
+
+ /*
+ ===> 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_AP_SUPPORT
+ APStartUp(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+
+ /* Clear ATE Bulk in/out counter and continue setup. */
+
+ /* Wait 50ms to prevent next URB to bulkout during HW reset. */
+ /* todo : remove this if not necessary */
+ RtmpOsMsDelay(50);
+
+ pATEInfo->Mode = ATE_STOP;
+#endif /* RTMP_MAC_USB */
+
+#ifdef CONFIG_AP_SUPPORT
+ /* restore RX_FILTR_CFG */
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, APNORMAL);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* Enable Tx */
+ ATE_MAC_TX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Enable Tx, Rx DMA. */
+ RtmpDmaEnable(pAd, 1);
+
+ /* Enable Rx */
+ ATE_MAC_RX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+
+#ifdef RTMP_MAC_USB
+ /* Wait 10ms for all of the bulk-in URBs to complete. */
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 MacData=0;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR BbpData = 0;
+ PATE_CHIP_STRUCT pChipStruct = pATEInfo->pChipStruct;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__));
+
+ pATEInfo->Mode = ATE_TXCARR;
+
+ if (pChipStruct->bBBPStoreTXCARR == TRUE)
+ {
+ UINT32 bbp_index=0;
+
+ /* Zero All BBP Value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ restore_BBP[bbp_index]=0;
+
+ /* Record All BBP Value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd,bbp_index,&restore_BBP[bbp_index]);
+ }
+
+#ifdef RTMP_MAC_USB
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+#endif /* RTMP_MAC_USB */
+
+ /* QA has done the following steps if it is used. */
+ if (pATEInfo->bQATxStart == FALSE)
+ {
+ if ((!IS_RT3883(pAd)) && (!IS_RT3352(pAd)) && (!IS_RT5350(pAd)) && (!IS_RT3593(pAd)))
+ BbpSoftReset(pAd);/* Soft reset BBP. */
+
+ if (pATEInfo->TxMethod == TX_METHOD_1)
+ {
+ /* 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 (pATEInfo->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 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
+ {
+ /* 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. */
+ ATE_MAC_TX_CTS_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__));
+ return Status;
+}
+
+
+static NDIS_STATUS TXCONT(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 MacData=0;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR BbpData = 0;
+ PATE_CHIP_STRUCT pChipStruct = pATEInfo->pChipStruct;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__));
+
+ if (pATEInfo->bQATxStart == TRUE)
+ {
+ /*
+ set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
+ and bit2(MAC TX enable) back to zero.
+ */
+ ATE_MAC_TX_CTS_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+ ATE_MAC_TX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* set BBP R22 bit7=0 */
+ ATE_BBP_STOP_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+ }
+ else
+ {
+ if (pATEInfo->TxMethod == TX_METHOD_1)
+ {
+ /* store the original value of RA_TX_PIN_CFG */
+ RTMP_IO_READ32(pAd, RA_TX_PIN_CFG, &Default_TX_PIN_CFG);
+ }
+ }
+
+ if (pChipStruct->bBBPStoreTXCONT == TRUE)
+ {
+ UINT32 bbp_index=0;
+
+ /* Zero All BBP Value */
+ for(bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ restore_BBP[bbp_index]=0;
+
+ /* Record All BBP Value */
+ for(bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd,bbp_index,&restore_BBP[bbp_index]);
+ }
+
+ /* Step 1: send 50 packets first. */
+ pATEInfo->Mode = ATE_TXCONT;
+ pATEInfo->TxCount = 50;
+
+ if ((!IS_RT3883(pAd)) && (!IS_RT3352(pAd)) && (!IS_RT5350(pAd)) && (!IS_RT3593(pAd)))
+ BbpSoftReset(pAd);/* Soft reset BBP. */
+
+ /* Abort Tx, RX DMA. */
+ RtmpDmaEnable(pAd, 0);
+
+
+ /* Do it after Tx/Rx DMA is aborted. */
+ pATEInfo->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 */
+ ATE_MAC_TX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Start Tx, Rx DMA. */
+ RtmpDmaEnable(pAd, 1);
+
+#ifdef RTMP_MAC_USB
+ InterlockedExchange(&pAd->BulkOutRemained, pATEInfo->TxCount);
+#endif /* RTMP_MAC_USB */
+
+#ifdef RALINK_QA
+ if (pATEInfo->bQATxStart == TRUE)
+ {
+ pATEInfo->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 */
+
+ if (pATEInfo->TxMethod == TX_METHOD_1)
+ {
+ /* give RA_TX_PIN_CFG(0x1328) a proper value. */
+ if (pATEInfo->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_START_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+ }
+ else
+ {
+ /* Step 2: send more 50 packets then start Continuous Tx Mode. */
+ /* Abort Tx, RX DMA. */
+ RtmpDmaEnable(pAd, 0);
+
+ /* Cont. TX set BBP R22 bit7=1 */
+ ATE_BBP_START_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ pATEInfo->TxCount = 50;
+
+ pATEInfo->TxDoneCount = 0;
+ SetJapanFilter(pAd);
+
+
+#ifdef RTMP_MAC_USB
+ /* Build up Tx frame. */
+ ATESetUpFrame(pAd, 0);
+#endif /* RTMP_MAC_USB */
+
+ /* Enable Tx */
+ ATE_MAC_TX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Start Tx, Rx DMA. */
+ RtmpDmaEnable(pAd, 1);
+
+#ifdef RTMP_MAC_USB
+ InterlockedExchange(&pAd->BulkOutRemained, pATEInfo->TxCount);
+#endif /* RTMP_MAC_USB */
+#ifdef RALINK_QA
+ if (pATEInfo->bQATxStart == TRUE)
+ {
+ pATEInfo->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 */
+ ATE_MAC_TX_CTS_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__));
+ return Status;
+}
+
+
+static NDIS_STATUS TXCARS(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 MacData=0;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR BbpData = 0;
+ PATE_CHIP_STRUCT pChipStruct = pATEInfo->pChipStruct;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__));
+
+ pATEInfo->Mode = ATE_TXCARRSUPP;
+
+ if (pChipStruct->bBBPStoreTXCARRSUPP == TRUE)
+ {
+ UINT32 bbp_index=0;
+
+ /* Zero All BBP Value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ restore_BBP[bbp_index]=0;
+
+ /* Record All BBP Value */
+ for (bbp_index=0;bbp_index<ATE_BBP_REG_NUM;bbp_index++)
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd,bbp_index,&restore_BBP[bbp_index]);
+ }
+#ifdef RTMP_MAC_USB
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+#endif /* RTMP_MAC_USB */
+
+ /* QA has done the following steps if it is used. */
+ if (pATEInfo->bQATxStart == FALSE)
+ {
+ if (!IS_RT3883(pAd) && !IS_RT3593(pAd))
+ {
+ /* RT3883 and RT3593 do not need BbpSoftReset() */
+ /* Soft reset BBP. */
+ BbpSoftReset(pAd);
+ }
+
+ if (pATEInfo->TxMethod == TX_METHOD_1)
+ {
+ /* 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 (pATEInfo->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 Continuous Tx Mode) */
+ ATE_BBP_START_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ /* Carrier Suppression set BBP R24 bit0=1 (TX continuously send out 5.5MHZ sin save) */
+ ATE_BBP_CTS_TX_SIN_WAVE_ENABLE(pAd, BBP_R24, &BbpData);
+ }
+ else
+ {
+ /* Carrier Suppression set BBP R22 bit7=1 (Enable Continuous Tx Mode) */
+ ATE_BBP_START_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ /* Carrier Suppression set BBP R24 bit0=1 (TX continuously send out 5.5MHZ sin save) */
+ ATE_BBP_CTS_TX_SIN_WAVE_ENABLE(pAd, BBP_R24, &BbpData);
+
+ /* Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1. */
+ ATE_MAC_TX_CTS_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__));
+ return Status;
+}
+
+
+static NDIS_STATUS TXFRAME(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ 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};
+#ifdef RTMP_INTERNAL_TX_ALC
+#if defined(RT3350) || defined(RT3352)
+ UCHAR RFValue, BBP49Value;
+ CHAR ChannelPower = pATEInfo->TxPower0;
+ CHAR *TssiRefPerChannel = pATEInfo->TssiRefPerChannel;
+ UCHAR CurrentChannel = pATEInfo->Channel;
+#endif /* defined(RT3350) || defined(RT3352) */
+#endif /* RTMP_INTERNAL_TX_ALC */
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+#ifdef RTMP_INTERNAL_TX_ALC
+#if defined(RT3350) || defined(RT3352)
+ if (pATEInfo->bTSSICalbrEnableG == TRUE)
+ {
+ if ((!IS_RT3350(pAd)) && (!IS_RT3352(pAd)))
+ {
+ DBGPRINT_ERR(("Not support TSSI calibration since not 3350/3352 chip!!!\n"));
+ Status = NDIS_STATUS_FAILURE;
+
+ return Status;
+ }
+
+ /* Internal TSSI 0 */
+ RFValue = (0x3 | 0x0 << 2 | 0x3 << 4);
+ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R27, RFValue);
+
+ RFValue = (0x3 | 0x0 << 2);
+ ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R28, RFValue);
+
+ /* set BBP R49[7] = 1 */
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpData);
+ BBP49Value = BbpData;
+ BbpData |= 0x80;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R49, BbpData);
+ }
+#endif /* defined(RT3350) || defined(RT3352) */
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s(Count=%u)\n", __FUNCTION__, pATEInfo->TxCount));
+ pATEInfo->Mode |= ATE_TXFRAME;
+
+ if (pATEInfo->bQATxStart == FALSE)
+ {
+ /* set IPG to sync tx power with QA tools */
+ /* default value of IPG is 200 */
+ snprintf(IPGStr, sizeof(IPGStr), "%u", pATEInfo->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. */
+ ATE_BBP_RESET_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ /* Clear bit4 to stop continuous Tx production test. */
+ ATE_MAC_TX_CTS_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+#endif /* RTMP_MAC_USB */
+
+#ifdef RALINK_QA
+ /* add this for LoopBack mode */
+ if (pATEInfo->bQARxStart == FALSE)
+ {
+#ifdef TXBF_SUPPORT
+ /* Enable Rx if Sending Sounding. Otherwise Disable */
+ if (pATEInfo->txSoundingMode != 0)
+ {
+ ATE_MAC_RX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+ }
+ else
+#endif /* TXBF_SUPPORT */
+ {
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+ }
+ }
+
+ if (pATEInfo->bQATxStart == TRUE)
+ {
+ pATEInfo->TxStatus = 1;
+ }
+#else
+#ifdef TXBF_SUPPORT
+ /* Enable Rx if Sending Sounding. Otherwise Disable */
+ if (pATEInfo->txSoundingMode != 0)
+ {
+ ATE_MAC_RX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+ }
+ else
+#endif /* TXBF_SUPPORT */
+ {
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+ }
+#endif /* RALINK_QA */
+
+
+#ifdef RTMP_MAC_USB
+ /* Enable Tx */
+ ATE_MAC_TX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ SetJapanFilter(pAd);
+
+ /* Abort Tx, RX DMA. */
+ RtmpDmaEnable(pAd, 0);
+
+ pATEInfo->TxDoneCount = 0;
+
+ /* Setup frame format. */
+ ATESetUpFrame(pAd, 0);
+
+ /* Start Tx, RX DMA. */
+ RtmpDmaEnable(pAd, 1);
+
+ /* Check count is continuous or not yet. */
+ if (pATEInfo->TxCount == 0)
+ {
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+ }
+ else
+ {
+ InterlockedExchange(&pAd->BulkOutRemained, pATEInfo->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 */
+
+#ifdef RTMP_INTERNAL_TX_ALC
+#if defined(RT3350) || defined(RT3352)
+ if (pATEInfo->bTSSICalbrEnableG == TRUE)
+ {
+ if ((IS_RT3350(pAd)) || (IS_RT3352(pAd)))
+ {
+ if ((pATEInfo->TxWI.MCS == 7)
+ && (pATEInfo->TxWI.BW == BW_20) && (pATEInfo->TxAntennaSel == 1))
+ {
+ if (pATEInfo->Channel == 7)
+ {
+ /* step 1: get calibrated channel 7 TSSI reading as reference */
+ RtmpOsMsDelay(500);
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel %d, Calibrated Tx.Power0= 0x%04x\n", CurrentChannel, ChannelPower));
+
+ /* read BBP R49[4:0] and write to EEPROM 0x6E */
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpData);
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP R49 = 0x%02x\n", BbpData));
+ BbpData &= 0x1f;
+ TssiRefPerChannel[CurrentChannel-1] = BbpData;
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI = 0x%02x\n", TssiRefPerChannel[CurrentChannel-1]));
+ }
+
+ /* step 2: calibrate channel 1 and 13 TSSI delta values */
+ else if (pATEInfo->Channel == 1)
+ {
+ /* Channel 1 */
+ RtmpOsMsDelay(500);
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel %d, Calibrated Tx.Power0= 0x%04x\n", CurrentChannel, ChannelPower));
+
+ /* read BBP R49[4:0] */
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpData);
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP R49 = 0x%02x\n", BbpData));
+ BbpData &= 0x1f;
+ TssiRefPerChannel[CurrentChannel-1] = BbpData;
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI = 0x%02x\n", TssiRefPerChannel[CurrentChannel-1]));
+ }
+ else if (pATEInfo->Channel == 13)
+ {
+ /* Channel 13 */
+ RtmpOsMsDelay(500);
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel %d, Calibrated Tx.Power0= 0x%04x\n", CurrentChannel, ChannelPower));
+
+ /* read BBP R49[4:0] */
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpData);
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP R49 = 0x%02x\n", BbpData));
+ BbpData &= 0x1f;
+ TssiRefPerChannel[CurrentChannel-1] = BbpData;
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI = 0x%02x\n", TssiRefPerChannel[CurrentChannel-1]));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Channel %d, Calibrated Tx.Power0= 0x%04x\n", CurrentChannel, ChannelPower));
+ }
+ }
+ }
+ }
+#endif /* defined(RT3350) || defined(RT3352) */
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__));
+ return Status;
+}
+
+
+static NDIS_STATUS RXFRAME(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ 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 */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ /* Default value in BBP R22 is 0x0. */
+ ATE_BBP_RESET_TX_MODE(pAd, BBP_R22, &BbpData);
+
+
+ /* Clear bit4 to stop continuous Tx production test. */
+ ATE_MAC_TX_CTS_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ pATEInfo->Mode |= ATE_RXFRAME;
+
+#ifdef RTMP_MAC_USB
+ /* Abort Tx, RX DMA. */
+ RtmpDmaEnable(pAd, 0);
+#endif /* RTMP_MAC_USB */
+
+ /* Disable Tx of MAC block. */
+ ATE_MAC_TX_DISABLE(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. */
+ ATE_MAC_RX_ENABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+
+#ifdef RTMP_MAC_USB
+ /* Kick bulk in. */
+ RTUSBBulkReceive(pAd);
+#endif /* RTMP_MAC_USB */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : <=== %s\n", __FUNCTION__));
+ return Status;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set ATE operation mode to
+ 0. ATESTART = Start/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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ 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, pATEInfo->Channel);
+ RtmpOsMsDelay(5);
+
+ Status = TXCARR(pAd);
+ }
+ else if (!strcmp(arg, "TXCARS"))
+ {
+ ATEAsicSwitchChannel(pAd);
+ /* AsicLockChannel() is empty function so far in fact */
+ AsicLockChannel(pAd, pATEInfo->Channel);
+ RtmpOsMsDelay(5);
+
+ Status = TXCARS(pAd);
+ }
+ else if (!strcmp(arg, "TXCONT"))
+ {
+ ATEAsicSwitchChannel(pAd);
+ /* AsicLockChannel() is empty function so far in fact */
+ AsicLockChannel(pAd, pATEInfo->Channel);
+ RtmpOsMsDelay(5);
+
+ Status = TXCONT(pAd);
+ }
+ else if (!strcmp(arg, "TXFRAME"))
+ {
+
+ ATEAsicSwitchChannel(pAd);
+ /* AsicLockChannel() is empty function so far in fact */
+ AsicLockChannel(pAd, pATEInfo->Channel);
+ RtmpOsMsDelay(5);
+
+ Status = TXFRAME(pAd);
+ }
+ else if (!strcmp(arg, "RXFRAME"))
+ {
+ ATEAsicSwitchChannel(pAd);
+ /* AsicLockChannel() is empty function so far in fact */
+ AsicLockChannel(pAd, pATEInfo->Channel);
+ RTMPusecDelay(5);
+
+ Status = RXFRAME(pAd);
+ }
+#ifdef RALINK_QA
+ /* Enter ATE mode and set Tx/Rx Idle */
+ else if (!strcmp(arg, "TXSTOP"))
+ {
+ Status = TXSTOP(pAd);
+ }
+ else if (!strcmp(arg, "RXSTOP"))
+ {
+ Status = RXSTOP(pAd);
+ }
+#endif /* RALINK_QA */
+ else
+ {
+ DBGPRINT_ERR(("ATE : Invalid arg in %s!\n", __FUNCTION__));
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ /* Handle ATEACTIVE and ATEPASSIVE commands as a special case */
+ if (!strcmp(arg, "ATEACTIVE"))
+ {
+ pATEInfo->PassiveMode = FALSE;
+ return TRUE;
+ }
+
+ if (!strcmp(arg, "ATEPASSIVE"))
+ {
+ pATEInfo->PassiveMode = TRUE;
+ return TRUE;
+ }
+
+ /* Disallow all other ATE commands in passive mode */
+ if (pATEInfo->PassiveMode)
+ return TRUE;
+
+ if (ATECmdHandler(pAd, arg) == NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT_ERR(("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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ PSTRING value;
+ INT octet;
+
+ /* Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ if (strlen(arg) != 17)
+ return FALSE;
+
+ for (octet = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ /* sanity check */
+ if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
+ {
+ return FALSE;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ AtoH(value, &pATEInfo->Addr1[octet++], 1);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+
+ /* sanity check */
+ if (octet != MAC_ADDR_LEN)
+ {
+ return FALSE;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %02x:%02x:%02x:%02x:%02x:%02x)\n",
+ pATEInfo->Addr1[0], pATEInfo->Addr1[1], pATEInfo->Addr1[2], pATEInfo->Addr1[3],
+ pATEInfo->Addr1[4], pATEInfo->Addr1[5]));
+
+#endif /* CONFIG_AP_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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ PSTRING value;
+ INT octet;
+
+ /* Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ if (strlen(arg) != 17)
+ return FALSE;
+
+ for (octet=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ /* sanity check */
+ if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
+ {
+ return FALSE;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ AtoH(value, &pATEInfo->Addr3[octet++], 1);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+
+ /* sanity check */
+ if (octet != MAC_ADDR_LEN)
+ {
+ return FALSE;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %02x:%02x:%02x:%02x:%02x:%02x)\n",
+ pATEInfo->Addr3[0], pATEInfo->Addr3[1], pATEInfo->Addr3[2], pATEInfo->Addr3[3],
+ pATEInfo->Addr3[4], pATEInfo->Addr3[5]));
+#endif /* CONFIG_AP_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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ PSTRING value;
+ INT octet;
+
+ /* Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ if (strlen(arg) != 17)
+ return FALSE;
+
+ for (octet=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ /* sanity check */
+ if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
+ {
+ return FALSE;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ AtoH(value, &pATEInfo->Addr2[octet++], 1);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+
+ /* sanity check */
+ if (octet != MAC_ADDR_LEN)
+ {
+ return FALSE;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %02x:%02x:%02x:%02x:%02x:%02x)\n",
+ pATEInfo->Addr2[0], pATEInfo->Addr2[1], pATEInfo->Addr2[2], pATEInfo->Addr2[3],
+ pATEInfo->Addr2[4], pATEInfo->Addr2[5]));
+
+#endif /* CONFIG_AP_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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR channel;
+
+
+ channel = simple_strtol(arg, 0, 10);
+
+ /* to allow A band channel : ((channel < 1) || (channel > 14)) */
+ if ((channel < 1) || (channel > 216))
+ {
+ DBGPRINT_ERR(("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
+ return FALSE;
+ }
+
+ pATEInfo->Channel = channel;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pATEInfo->Channel));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Initialize the channel - set the power and switch to selected channel
+ 0 => use current value
+ else set channel to specified channel
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Set_ATE_INIT_CHAN_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ int index;
+ int value;
+
+ /* Get channel parameter */
+ value = simple_strtol(arg, 0, 10);
+
+ if (value<0 || value>216)
+ {
+ DBGPRINT_ERR(("Set_ATE_INIT_CHAN_Proc::Channel out of range\n"));
+ return FALSE;
+ }
+
+ if (value != 0)
+ pATEInfo->Channel = value;
+
+ for (index=0; index<MAX_NUM_OF_CHANNELS; index++)
+ {
+ if (pATEInfo->Channel == pAd->TxPower[index].Channel)
+ {
+ pATEInfo->TxPower0 = pAd->TxPower[index].Power;
+ pATEInfo->TxPower1 = pAd->TxPower[index].Power2;
+#ifdef DOT11N_SS3_SUPPORT
+ if (IS_RT2883(pAd) || IS_RT3593(pAd) || IS_RT3883(pAd))
+ pATEInfo->TxPower2 = pAd->TxPower[index].Power3;
+#endif /* DOT11N_SS3_SUPPORT */
+ break;
+ }
+ }
+
+ if (index == MAX_NUM_OF_CHANNELS)
+ {
+ DBGPRINT_ERR(("Set_ATE_INIT_CHAN_Proc::Channel not found\n"));
+ return FALSE;
+ }
+
+ /* Force non-QATool mode */
+ pATEInfo->bQATxStart = pATEInfo->bQARxStart = FALSE;
+
+ ATETxPwrHandler(pAd, 0);
+ ATETxPwrHandler(pAd, 1);
+#ifdef DOT11N_SS3_SUPPORT
+ ATETxPwrHandler(pAd, 2);
+#endif /* DOT11N_SS3_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_INIT_CHAN_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set ATE Tx Power
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+static INT ATESetAntennaTxPower(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg,
+ IN INT Antenna)
+
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR TxPower;
+ INT index, maximun_index;
+
+ pATEInfo = &(pAd->ate);
+ TxPower = simple_strtol(arg, 0, 10);
+ index = Antenna;
+ maximun_index = pAd->Antenna.field.TxPath - 1;
+
+ if ((index < 0) || (index > maximun_index))
+ {
+ DBGPRINT_ERR(("No such antenna! The range is 0~%d.\n", maximun_index));
+ return FALSE;
+ }
+
+ if (pATEInfo->Channel <= 14) /* 2.4 GHz */
+ {
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ CHAR MaxPower;
+ UINT32 RegValue = 0;
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_0, &RegValue);
+ MaxPower = (RegValue & 0x003F0000) >> 16;
+ if (TxPower > MaxPower )
+ {
+ DBGPRINT_ERR(("Set_ATE_TX_POWER%d_Proc::Out of range! (Value=%d)\n", index, TxPower));
+ DBGPRINT_ERR(("TxPower range is 0~39 in G band.\n"));
+ return FALSE;
+ }
+ }
+ else
+#endif /* MT7601 */
+ if (!IS_RT3390(pAd))
+ {
+ if ((TxPower > 31) || (TxPower < 0))
+ {
+ DBGPRINT_ERR(("Set_ATE_TX_POWER%d_Proc::Out of range! (Value=%d)\n", index, TxPower));
+ DBGPRINT_ERR(("TxPower range is 0~31 in G band.\n"));
+ return FALSE;
+ }
+ }
+ }
+ else /* 5.5 GHz */
+ {
+ if ((TxPower > (pATEInfo->MaxTxPowerBandA)) || (TxPower < (pATEInfo->MinTxPowerBandA)))
+ {
+ DBGPRINT_ERR(("Set_ATE_TX_POWER%d_Proc::Out of range! (Value=%d)\n", index, TxPower));
+ DBGPRINT_ERR(("TxPower range is %d~%d in A band.\n", pATEInfo->MinTxPowerBandA, pATEInfo->MaxTxPowerBandA));
+ return FALSE;
+ }
+ }
+
+ switch (index)
+ {
+ case 0:
+ pATEInfo->TxPower0 = TxPower;
+ break;
+ case 1:
+ pATEInfo->TxPower1 = TxPower;
+ break;
+#ifdef DOT11N_SS3_SUPPORT
+ case 2:
+ pATEInfo->TxPower2 = TxPower;
+ break;
+#endif /* DOT11N_SS3_SUPPORT */
+ default:
+ return FALSE;
+ }
+
+ ATETxPwrHandler(pAd, index);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER%d_Proc Success\n", index));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ INT ret;
+
+ ret = ATESetAntennaTxPower(pAd, arg, 0);
+ return ret;
+}
+
+
+/*
+==========================================================================
+ 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)
+{
+ INT ret;
+
+ ret = ATESetAntennaTxPower(pAd, arg, 1);
+ return ret;
+}
+
+
+#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)
+{
+ INT ret;
+
+ ret = ATESetAntennaTxPower(pAd, arg, 2);
+ return ret;
+}
+#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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR value;
+ INT maximun_index = pAd->Antenna.field.TxPath;
+
+ value = simple_strtol(arg, 0, 10);
+
+ if ((value > maximun_index) || (value < 0))
+ {
+ DBGPRINT_ERR(("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
+ DBGPRINT_ERR(("Set_ATE_TX_Antenna_Proc::The range is 0~%d\n", maximun_index));
+
+ return FALSE;
+ }
+
+ pATEInfo->TxAntennaSel = value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pATEInfo->TxAntennaSel));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
+
+ /* calibration power unbalance issues */
+ ATEAsicSwitchChannel(pAd);
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR value;
+ INT maximun_index = pAd->Antenna.field.RxPath;
+
+ value = simple_strtol(arg, 0, 10);
+
+ if ((value > maximun_index) || (value < 0))
+ {
+ DBGPRINT_ERR(("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
+ DBGPRINT_ERR(("Set_ATE_RX_Antenna_Proc::The range is 0~%d\n", maximun_index));
+
+ return FALSE;
+ }
+
+ pATEInfo->RxAntennaSel = value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pATEInfo->RxAntennaSel));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
+
+ /* calibration power unbalance issues */
+ ATEAsicSwitchChannel(pAd);
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+VOID DefaultATEAsicExtraPowerOverMAC(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG ExtraPwrOverMAC = 0;
+ ULONG ExtraPwrOverTxPwrCfg7 = 0, ExtraPwrOverTxPwrCfg8 = 0, ExtraPwrOverTxPwrCfg9 = 0;
+
+ /* For OFDM_54 and HT_MCS_7, extra fill the corresponding register value into MAC 0x13D4 */
+ RTMP_IO_READ32(pAd, 0x1318, &ExtraPwrOverMAC);
+ ExtraPwrOverTxPwrCfg7 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for OFDM 54 */
+ RTMP_IO_READ32(pAd, 0x131C, &ExtraPwrOverMAC);
+ ExtraPwrOverTxPwrCfg7 |= (ExtraPwrOverMAC & 0x0000FF00) << 8; /* Get Tx power for HT MCS 7 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_7, ExtraPwrOverTxPwrCfg7);
+
+ /* For STBC_MCS_7, extra fill the corresponding register value into MAC 0x13DC */
+ RTMP_IO_READ32(pAd, 0x1324, &ExtraPwrOverMAC);
+ ExtraPwrOverTxPwrCfg9 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for STBC MCS 7 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_9, ExtraPwrOverTxPwrCfg9);
+
+ if (IS_RT5392(pAd))
+ {
+ /* For HT_MCS_15, extra fill the corresponding register value into MAC 0x13DC */
+ RTMP_IO_READ32(pAd, 0x1320, &ExtraPwrOverMAC);
+ ExtraPwrOverTxPwrCfg8 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for HT MCS 15 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_8, ExtraPwrOverTxPwrCfg8);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Offset =0x13D8, TxPwr = 0x%08X, ", (UINT)ExtraPwrOverTxPwrCfg8));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Offset = 0x13D4, TxPwr = 0x%08X, Offset = 0x13DC, TxPwr = 0x%08X\n",
+ (UINT)ExtraPwrOverTxPwrCfg7,
+ (UINT)ExtraPwrOverTxPwrCfg9));
+}
+
+
+VOID ATEAsicExtraPowerOverMAC(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->AsicExtraPowerOverMAC!= NULL)
+ pATEInfo->pChipStruct->AsicExtraPowerOverMAC(pAd);
+
+ return;
+}
+
+
+VOID ATEAsicTemperCompensation(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->TemperCompensation!= NULL)
+ pATEInfo->pChipStruct->TemperCompensation(pAd);
+
+ return;
+}
+
+
+#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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR PABias = 0;
+ UCHAR RFValue;
+
+ PABias = simple_strtol(arg, 0, 10);
+
+ if (PABias >= 16)
+ {
+ DBGPRINT_ERR(("Set_ATE_PA_Bias_Proc::Out of range, it should be in range of 0~15.\n"));
+ return FALSE;
+ }
+
+ pATEInfo->PABias = PABias;
+
+ ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R19, (PUCHAR)&RFValue);
+ RFValue = (((RFValue & 0x0F) | (pATEInfo->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", pATEInfo->PABias));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_PA_Bias_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+#endif /* RT3350 */
+
+
+/*
+==========================================================================
+ Description:
+ Set ATE RF BW(default)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Default_Set_ATE_TX_FREQ_OFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR RFFreqOffset = 0;
+
+
+ RFFreqOffset = simple_strtol(arg, 0, 10);
+
+ if (RFFreqOffset >= 64)
+ {
+ DBGPRINT_ERR(("Set_ATE_TX_FREQ_OFFSET_Proc::Out of range(0 ~ 63).\n"));
+ return FALSE;
+ }
+
+ pATEInfo->RFFreqOffset = RFFreqOffset;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pATEInfo->RFFreqOffset));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set ATE RF frequence offset
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Set_ATE_TX_FREQ_OFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ INT ret = FALSE;
+
+ if (pATEInfo->pChipStruct->Set_FREQ_OFFSET_Proc != NULL)
+ {
+ ret = pATEInfo->pChipStruct->Set_FREQ_OFFSET_Proc(pAd, arg);
+ }
+
+ if (ret == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQ_OFFSET_Proc (RFFreqOffset = %d)\n", pATEInfo->RFFreqOffset));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQ_OFFSET_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ return ret;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set ATE RF BW(default)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Default_Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ INT powerIndex;
+ UCHAR value = 0;
+ UCHAR BBPCurrentBW;
+
+ BBPCurrentBW = simple_strtol(arg, 0, 10);
+
+ if ((BBPCurrentBW == 0)
+ )
+ {
+ pATEInfo->TxWI.TxWIBW = BW_20;
+ }
+ else
+ {
+ pATEInfo->TxWI.TxWIBW = BW_40;
+ }
+
+ if ((pATEInfo->TxWI.TxWIPHYMODE == MODE_CCK) && (pATEInfo->TxWI.TxWIBW == BW_40))
+ {
+ DBGPRINT_ERR(("Set_ATE_TX_BW_Proc!! Warning!! CCK only supports 20MHZ!!\n"));
+ DBGPRINT_ERR(("Bandwidth switch to 20!!\n"));
+ pATEInfo->TxWI.TxWIBW = BW_20;
+ }
+
+ if (pATEInfo->TxWI.TxWIBW == BW_20)
+ {
+ if (pATEInfo->Channel <= 14)
+ {
+ /* BW=20;G band */
+ for (powerIndex=0; powerIndex<MAX_TXPOWER_ARRAY_SIZE; powerIndex++)
+ {
+ if (pAd->Tx20MPwrCfgGBand[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; powerIndex<MAX_TXPOWER_ARRAY_SIZE; powerIndex++)
+ {
+ if (pAd->Tx20MPwrCfgABand[powerIndex] == 0xffffffff)
+ continue;
+
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgABand[powerIndex]);
+ RtmpOsMsDelay(5);
+ }
+ }
+
+ /* set BW = 20 MHz */
+ /* 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);
+
+ /* set BW = 20 MHz */
+ {
+ pAd->LatchRfRegs.R4 &= ~0x00200000;
+ RtmpRfIoWrite(pAd);
+ }
+
+ /* BW = 20 MHz */
+ /* Set BBP R68=0x0B to improve Rx sensitivity. */
+ value = 0x0B;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+ /* Set BBP R69=0x16 */
+ value = 0x16;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+ /* Set BBP R70=0x08 */
+ value = 0x08;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+ /* Set BBP R73=0x11 */
+ if ( IS_RT5390(pAd) || IS_RT5392(pAd))
+ value = 0x13;
+ else
+ value = 0x11;
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+
+ if (pATEInfo->Channel == 14)
+ {
+ INT TxMode = pATEInfo->TxWI.TxWIPHYMODE;
+
+ 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 (pATEInfo->TxWI.TxWIBW == BW_40)
+ {
+ if (pATEInfo->Channel <= 14)
+ {
+ /* BW=40;G band */
+ for (powerIndex=0; powerIndex<MAX_TXPOWER_ARRAY_SIZE; powerIndex++)
+ {
+ if (pAd->Tx40MPwrCfgGBand[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; powerIndex<MAX_TXPOWER_ARRAY_SIZE; powerIndex++)
+ {
+ if (pAd->Tx40MPwrCfgABand[powerIndex] == 0xffffffff)
+ continue;
+
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgABand[powerIndex]);
+ RtmpOsMsDelay(5);
+ }
+
+ if ((pATEInfo->TxWI.TxWIPHYMODE >= 2) && (pATEInfo->TxWI.TxWIMCS == 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);
+
+ /* Set BBP R66=0x3C */
+ value = 0x3C;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+
+
+ /* 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) || IS_RT5392(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", pATEInfo->TxWI.TxWIBW));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->Set_BW_Proc != NULL)
+ pATEInfo->pChipStruct->Set_BW_Proc(pAd, arg);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pATEInfo->TxWI.TxWIBW));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ pATEInfo->TxLength = simple_strtol(arg, 0, 10);
+
+ if ((pATEInfo->TxLength < 24) || (pATEInfo->TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
+ {
+ pATEInfo->TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
+ DBGPRINT_ERR(("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", pATEInfo->TxLength));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ pATEInfo->TxCount = simple_strtol(arg, 0, 10);
+
+ if (pATEInfo->TxCount == 0)
+ {
+ pATEInfo->TxCount = 0xFFFFFFFF;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pATEInfo->TxCount));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR MCS;
+ INT result;
+
+ MCS = simple_strtol(arg, 0, 10);
+ result = CheckMCSValid(pAd, pATEInfo->TxWI.TxWIPHYMODE, MCS);
+
+ if (result != -1)
+ {
+ pATEInfo->TxWI.TxWIMCS = (UCHAR)MCS;
+ }
+ else
+ {
+ DBGPRINT_ERR(("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", pATEInfo->TxWI.TxWIMCS));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR BbpData = 0;
+
+ pATEInfo->TxWI.TxWIPHYMODE = simple_strtol(arg, 0, 10);
+
+ if (pATEInfo->TxWI.TxWIPHYMODE > 3)
+ {
+ pATEInfo->TxWI.TxWIPHYMODE = 0;
+ DBGPRINT_ERR(("Set_ATE_TX_MODE_Proc::Out of range.\nIt should be in range of 0~3\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
+ return FALSE;
+ }
+
+#if defined(RT5592) || defined(MT7601)
+ /* Turn on BBP 20MHz mode by request here. */
+ if (IS_RT5592(pAd) || IS_MT7601(pAd))
+ {
+ if (pATEInfo->TxWI.TxWIBW == BW_20)
+ {
+ BbpData = 0x40;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
+ }
+ else /* BW == 40MHz */
+ {
+ BbpData = 0x50;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
+ }
+ }
+ //else
+#endif /* defined(RT5592) || defined(MT7601) */
+ /* Turn on BBP 20MHz mode by request here. */
+ if (pATEInfo->TxWI.TxWIPHYMODE == 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);
+ pATEInfo->TxWI.TxWIBW = BW_20;
+ DBGPRINT(RT_DEBUG_OFF, ("Set_ATE_TX_MODE_Proc::CCK Only support 20MHZ. Switch to 20MHZ.\n"));
+ }
+
+#ifdef RT3350
+ if (IS_RT3350(pAd))
+ {
+ if (pATEInfo->TxWI.TxWIPHYMODE == 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 (pATEInfo->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 (pATEInfo->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", pATEInfo->TxWI.TxWIPHYMODE));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ pATEInfo->TxWI.TxWIShortGI = simple_strtol(arg, 0, 10);
+
+ if (pATEInfo->TxWI.TxWIShortGI > 1)
+ {
+ pATEInfo->TxWI.TxWIShortGI = 0;
+ DBGPRINT_ERR(("Set_ATE_TX_GI_Proc::Out of range\n"));
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pATEInfo->TxWI.TxWIShortGI));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+INT Set_ATE_RX_FER_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ pATEInfo->bRxFER = simple_strtol(arg, 0, 10);
+
+ if (pATEInfo->bRxFER == 1)
+ {
+ pATEInfo->RxCntPerSec = 0;
+ pATEInfo->RxTotalCnt = 0;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFER = %d)\n", pATEInfo->bRxFER));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+INT Set_ATE_Read_RF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ {
+ 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;
+}
+
+
+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;
+}
+
+
+/*
+==========================================================================
+ 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_OFF, ("===> %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_ERR(("%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_ERR(("%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_ERR(("--> Error %d closing %s\n", -retval, src));
+
+ }
+ }
+
+ /* restore */
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
+
+ return ret;
+}
+
+
+#ifdef RTMP_EFUSE_SUPPORT
+/*
+==========================================================================
+ Description:
+ Load and Write E-Fuse from pAd->EEPROMImage.
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Set_ATE_Load_E2P_From_Buf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ BOOLEAN ret = FALSE;
+ UINT32 value = (UINT32) simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_OFF, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
+
+ if (value > 0)
+ {
+
+ rt_ee_write_all(pAd, pAd->EEPROMImage);
+ ret = TRUE;
+
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
+
+ return ret;
+}
+
+
+INT Set_ATE_Cal_Free_Info_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ BOOLEAN ret = FALSE;
+
+ if ( pAd->bCalFreeIC )
+ DBGPRINT(RT_DEBUG_OFF, ("%s (bCalFreeIC=TRUE)\n\n", __FUNCTION__));
+ else
+ DBGPRINT(RT_DEBUG_OFF, ("%s (bCalFreeIC=FALSE)\n\n", __FUNCTION__));
+
+ return TRUE;
+}
+
+#endif /* RTMP_EFUSE_SUPPORT */
+
+
+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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 value = simple_strtol(arg, 0, 10);
+
+ if (value > 0)
+ {
+ pATEInfo->bAutoTxAlc = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("ATEAUTOALC = TRUE , auto alc enabled!\n"));
+ }
+ else
+ {
+ pATEInfo->bAutoTxAlc = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("ATEAUTOALC = FALSE , auto alc disabled!\n"));
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+#ifdef TXBF_SUPPORT
+/*
+==========================================================================
+ Description:
+ Set ATE Tx Beamforming mode
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Set_ATE_TXBF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR value;
+
+ value = simple_strtol(arg, 0, 10);
+
+ switch (value)
+ {
+ case 0:
+ /* no BF */
+ pATEInfo->TxWI.iTxBF = pATEInfo->TxWI.eTxBF = 0;
+ break;
+ case 1:
+ /* ETxBF */
+ pATEInfo->TxWI.eTxBF = 1;
+ break;
+ case 2:
+ /* ITxBF */
+ pATEInfo->TxWI.iTxBF = 1;
+ break;
+ case 3:
+ /* Enable TXBF support */
+ pATEInfo->bTxBF = TRUE;
+ break;
+ case 4:
+ /* Disable TXBF support */
+ pATEInfo->bTxBF = FALSE;
+ break;
+ default:
+ DBGPRINT_ERR(("Set_ATE_TXBF_Proc: Invalid parameter %d\n", value));
+ break;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+ }
+
+
+/*
+==========================================================================
+ Description:
+ Set ATE Sounding type
+ 0 => no sounding
+ 1 => Data sounding
+ 2 => 2 stream NDP sounding
+ 3 => 3 stream NDP Sounding
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Set_ATE_TXSOUNDING_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ CHAR value;
+
+ value = simple_strtol(arg, 0, 10);
+
+ if (value<0 || value>3)
+ {
+ DBGPRINT_ERR(("Set_ATE_TXSOUNDING_Proc: Invalid parameter %d\n", value));
+ return FALSE;
+ }
+
+ pATEInfo->txSoundingMode = value;
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Do a Divider Calibration on calibration channels and save in EEPROM
+ 0 => do G and A band
+ 1 => G band only
+ 2 => A band only
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Set_ATE_TXBF_DIVCAL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ int value;
+ ITXBF_DIV_PARAMS divParams;
+ CHAR initChanArg[] = "0";
+
+ value = simple_strtol(arg, 0, 10);
+
+ if (value<0 || value>2)
+ return FALSE;
+
+ /* G band */
+ if (value==0 || value==1)
+ {
+ pATEInfo->Channel = 1;
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFDividerCalibration(pAd, 1, 0, NULL);
+
+ pATEInfo->Channel = 14;
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFDividerCalibration(pAd, 1, 0, NULL);
+
+ /* Display delta phase information */
+ ITxBFGetEEPROM(pAd, NULL, NULL, &divParams);
+
+ DBGPRINT(RT_DEBUG_WARN, ("Divider Cal Done:\n"
+ "ch1-ch14 = [%2d, %2d] degrees\n"
+ "ant0-ant2 = [%2d, %2d] degrees\n",
+ (UCHAR)(divParams.gBeg[0]-divParams.gEnd[0])*360/256,
+ (UCHAR)(divParams.gBeg[1]-divParams.gEnd[1])*360/256,
+ (UCHAR)(divParams.gBeg[0]-divParams.gBeg[1])*360/256,
+ (UCHAR)(divParams.gEnd[0]-divParams.gEnd[1])*360/256) );
+ }
+
+ /* A Band */
+ if (value==0 || value==2)
+ {
+ pATEInfo->Channel = 36;
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFDividerCalibration(pAd, 1, 0, NULL);
+
+ pATEInfo->Channel = 120;
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFDividerCalibration(pAd, 1, 0, NULL);
+
+ pATEInfo->Channel = 165;
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFDividerCalibration(pAd, 1, 0, NULL);
+ }
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Do a LNA Calibration on calibration channels and save in EEPROM
+ 0 => do G and A band
+ 1 => G band only
+ 2 => A band only
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+INT Set_ATE_TXBF_LNACAL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ int value;
+ int i;
+ CHAR initChanArg[] = "0";
+
+ value = simple_strtol(arg, 0, 10);
+
+ if (value<0 || value>2)
+ return FALSE;
+
+ /* G Band */
+ if (value==0 || value==1)
+ {
+ pATEInfo->Channel = 1;
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFLNACalibration(pAd, 1, 0, TRUE);
+
+ pATEInfo->Channel = 14;
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFLNACalibration(pAd, 1, 0, TRUE);
+ }
+
+ /* A Band */
+ if (value==0 || value==2)
+ {
+ static UCHAR channels[6] = {36, 64, 100, 128, 132, 165};
+ for (i=0; i<6; i++)
+ {
+ pATEInfo->Channel = channels[i];
+ Set_ATE_INIT_CHAN_Proc(pAd, initChanArg);
+ ITxBFLNACalibration(pAd, 1, 0, FALSE);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Sanity check for the channel of Implicit TxBF calibration.
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ Note:
+ 1. This sanity check function only work for Implicit TxBF calibration.
+ 2. Currently supported channels are:
+ 1, 14, 36, 64, 128, 132, 165
+==========================================================================
+*/
+static BOOLEAN rtmp_ate_txbf_cal_valid_ch(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR channel)
+{
+ BOOLEAN bValidCh;
+
+ /* TODO: shall we check the capability of the chipset here ?? */
+ switch (channel)
+ {
+ case 1:
+ case 14:
+#ifdef A_BAND_SUPPORT
+ case 36:
+ case 64:
+ case 100:
+ case 128:
+ case 132:
+ case 165:
+#endif /* A_BAND_SUPPORT */
+ bValidCh = TRUE;
+ break;
+ default:
+ bValidCh = FALSE;
+ break;
+ }
+
+ return bValidCh;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set to start the initialization procedures of iTxBf calibration in DUT side
+ 0 => do nothing
+ 1 => do following initializations
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ Note:
+ This cmd shall only used in DUT side for calibration
+==========================================================================
+*/
+INT Set_ATE_TXBF_INIT_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ int val;
+ USHORT eepromVal;
+ UCHAR cmdStr[32];
+
+ val = simple_strtol(arg, 0, 10);
+ if (val != 1)
+ return FALSE;
+
+ /* Do ATESTART */
+#ifdef CONFIG_RT2880_ATE_CMD_NEW
+ Set_ATE_Proc(pAd, "ATESTART");
+#else
+ Set_ATE_Proc(pAd, "APSTOP");
+#endif /* CONFIG_RT2880_ATE_CMD_NEW */
+
+ /* set ATETXBF=3 */
+ Set_ATE_TXBF_Proc(pAd, "3");
+
+
+ /* Set self mac address as 22:22:22:22:22:22 */
+ RTMP_IO_WRITE32(pAd, 0x1008, 0x22222222);
+ RTMP_IO_WRITE32(pAd, 0x100c, 0x00002222);
+
+ /* set ATEDA=11:11:11:11:11:11 */
+ /* set ATESA=22:22:22:22:22:22 */
+ /* set ATEBSSID=22:22:22:22:22:22 */
+ for (val = 0; val < MAC_ADDR_LEN; val++)
+ {
+ pATEInfo->Addr1[val] = 0x11; /* the RA */
+ pATEInfo->Addr2[val] = 0x22; /* the TA */
+ pATEInfo->Addr3[val] = 0x22; /* the BSSID */
+ }
+
+ /* set ATETXMODE=2 */
+ Set_ATE_TX_MODE_Proc(pAd, "2");
+
+ /* set ATETXMCS=16 */
+ Set_ATE_TX_MCS_Proc(pAd, "16");
+
+ /* set ATETXBW=0 */
+ Set_ATE_TX_BW_Proc(pAd, "0");
+
+ /* set ATETXGI=0 */
+ Set_ATE_TX_GI_Proc(pAd, "0");
+
+ /* set ATETXANT=0 */
+ Set_ATE_TX_Antenna_Proc(pAd, "0");
+
+ /* set ATERXANT=0 */
+ Set_ATE_RX_Antenna_Proc(pAd, "0");
+
+ /* set ATETXFREQOFFSET=eeprom */
+ /* read EEPROM Frequency offset from EEPROM and set it to BBP */
+ RT28xx_EEPROM_READ16(pAd, 0x44, eepromVal);
+ snprintf(cmdStr, sizeof(cmdStr), "%d\n", (eepromVal & 0xff));
+ Set_ATE_TX_FREQ_OFFSET_Proc(pAd, cmdStr);
+
+ /* bbp 65=29 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, 0x29);
+
+ /* bbp 163=bd */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R163, 0xbd);
+
+ /* bbp 173=28 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R173, 0x28);
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set to do iTxBF calibration procedures for specific channel, following show us the supported channels.
+ 1, 14, 36, 64, 128, 132, 165
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ Note:
+ This cmd shall only used in DUT side for calibration
+==========================================================================
+*/
+INT Set_ATE_TXBF_CAL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR ch;
+ UCHAR cmdStr[32];
+
+ ch = simple_strtol(arg, 0, 10);
+ if (rtmp_ate_txbf_cal_valid_ch(pAd, ch) == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATECHANNEL=Channel */
+ snprintf(cmdStr, sizeof(cmdStr), "%d\n", ch);
+ if (Set_ATE_CHANNEL_Proc(pAd, cmdStr) == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATEINITCHAN =0 */
+ if (Set_ATE_INIT_CHAN_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXSOUNDING=3 */
+ if (Set_ATE_TXSOUNDING_Proc(pAd, "3") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ETxBfNoncompress=0 */
+ if (Set_ETxBfNoncompress_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXMCS=0 */
+ if (Set_ATE_TX_MCS_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXCNT=1 */
+ if (Set_ATE_TX_COUNT_Proc(pAd, "1") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXLEN=258 */
+ if (Set_ATE_TX_LENGTH_Proc(pAd, "258") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set InvTxBfTag=0 */
+ if (Set_InvTxBfTag_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATE=TXFRAME */
+ if (Set_ATE_Proc(pAd, "TXFRAME") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ITxBfCal=1 */
+ return Set_ITxBfCal_Proc(pAd, "1");
+
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set to start the initialization procedures of iTxBf calibration in Golden side at specified channel
+ arg => valid values are "1, 14, 36, 64, 128, 132, 165"
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ Note:
+ This cmd shall only used in GOLDEN side for calibration feedback
+==========================================================================
+*/
+INT Set_ATE_TXBF_GOLDEN_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR ch;
+ UCHAR cmdStr[32];
+ USHORT eepromVal;
+
+ ch = simple_strtol(arg, 0, 10);
+ if (rtmp_ate_txbf_cal_valid_ch(pAd, ch) == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATE=ATESTART */
+#ifdef CONFIG_RT2880_ATE_CMD_NEW
+ Set_ATE_Proc(pAd, "ATESTART");
+#else
+ Set_ATE_Proc(pAd, "APSTOP");
+#endif // CONFIG_RT2880_ATE_CMD_NEW //
+
+ /* set the ate channel and read txpower from EEPROM and set to bbp */
+ /* iwpriv ra0 set ATECHANNEL=Channel */
+ /* iwpriv ra0 set ATETXPOWER=0 */
+ snprintf(cmdStr, sizeof(cmdStr), "%d\n", ch);
+ Set_ATE_INIT_CHAN_Proc(pAd, cmdStr);
+
+
+ /* Set self mac address as 11:11:11:11:11:11 */
+ /* iwpriv ra0 set ATESA=11:11:11:11:11:11 */
+ RTMP_IO_WRITE32(pAd, 0x1008, 0x11111111);
+ RTMP_IO_WRITE32(pAd, 0x100c, 0x00001111);
+
+ /* iwpriv ra0 set ATETXMODE=2 */
+ Set_ATE_TX_MODE_Proc(pAd, "2");
+
+ /* iwpriv ra0 set ATETXBW=0 */
+ Set_ATE_TX_BW_Proc(pAd, "0");
+
+ /* iwpriv ra0 set ATETXGI=0 */
+ Set_ATE_TX_GI_Proc(pAd, "0");
+
+ /* iwpriv ra0 set ATETXANT=1 */
+ Set_ATE_TX_Antenna_Proc(pAd, "1");
+
+ /* iwpriv ra0 set ATERXANT=1 */
+ Set_ATE_RX_Antenna_Proc(pAd, "1");
+
+ /* iwpriv ra0 set ATETXFREQOFFSET=ValueOfEEPROM */
+ RT28xx_EEPROM_READ16(pAd, 0x44, eepromVal);
+ snprintf(cmdStr, sizeof(cmdStr), "%d\n", (eepromVal & 0xff));
+ Set_ATE_TX_FREQ_OFFSET_Proc(pAd, cmdStr);
+
+ /* iwpriv ra0 bbp 65=29 */
+ /* iwpriv ra0 bbp 163=9d */
+ /* iwpriv ra0 bbp 173=00 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, 0x29);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R163, 0x9d);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R173, 0x00);
+
+ /* iwpriv ra0 set ATE=RXFRAME */
+ Set_ATE_Proc(pAd, "RXFRAME");
+
+ /* reset the BBP_R173 as 0 to eliminate the compensation */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R173, 0x00);
+
+ return TRUE;
+
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set to do iTxBF calibration verification procedures at sepcified channel, following show us the supported channels.
+ args=> valid values are "1, 14, 36, 64, 128, 132, 165"
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ Note:
+ This cmd shall only used in GOLDEN side for calibration verification
+==========================================================================
+*/
+INT Set_ATE_TXBF_VERIFY_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR ch;
+ UCHAR cmdStr[32];
+
+ ch = simple_strtol(arg, 0, 10);
+ if (rtmp_ate_txbf_cal_valid_ch(pAd, ch) == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATECHANNEL=Channel */
+ snprintf(cmdStr, sizeof(cmdStr), "%d\n", ch);
+ if (Set_ATE_CHANNEL_Proc(pAd, cmdStr) == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXSOUNDING=3 */
+ if (Set_ATE_TXSOUNDING_Proc(pAd, "3") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ETxBfNoncompress=0 */
+ if (Set_ETxBfNoncompress_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXMCS=0 */
+ if (Set_ATE_TX_MCS_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXCNT=1 */
+ if (Set_ATE_TX_COUNT_Proc(pAd, "1") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXLEN=258 */
+ if (Set_ATE_TX_LENGTH_Proc(pAd, "258") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set InvTxBfTag=0 */
+ if (Set_InvTxBfTag_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATE=TXFRAME */
+ if (Set_ATE_Proc(pAd, "TXFRAME") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ITxBfCal=0 */
+ return Set_ITxBfCal_Proc(pAd, "0");
+}
+
+
+INT Set_ATE_ForceBBP_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR bbpReg;
+
+ bbpReg = simple_strtol(arg, 0, 10);
+
+ /*
+ 0: no any restriction for BBP writing
+ 1~255: force to not allow to change this specific BBP register.
+
+ Note:
+ BBP_R0 is not write-able, so use 0 as the rest operation shall be safe enough
+ */
+ pATEInfo->forceBBPReg = bbpReg;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_ForceBBP_Proc:(forceBBPReg value=%d)\n", pATEInfo->forceBBPReg));
+
+ return TRUE;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Set to do iTxBF calibration verification without R173 compensation procedures at sepcified channel, following show us the supported channels.
+ args=> valid values are "1, 14, 36, 64, 128, 132, 165"
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ Note:
+ This cmd shall only used in GOLDEN side for calibration verification
+==========================================================================
+*/
+INT Set_ATE_TXBF_VERIFY_NoComp_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR ch;
+ UCHAR cmdStr[32];
+ UCHAR bbpR173 = 0;
+ int retval;
+
+ ch = simple_strtol(arg, 0, 10);
+ if (rtmp_ate_txbf_cal_valid_ch(pAd, ch) == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATECHANNEL=Channel */
+ snprintf(cmdStr, sizeof(cmdStr), "%d\n", ch);
+ if (Set_ATE_CHANNEL_Proc(pAd, cmdStr) == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXSOUNDING=3 */
+ if (Set_ATE_TXSOUNDING_Proc(pAd, "3") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ETxBfNoncompress=0 */
+ if (Set_ETxBfNoncompress_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXMCS=0 */
+ if (Set_ATE_TX_MCS_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXCNT=1 */
+ if (Set_ATE_TX_COUNT_Proc(pAd, "1") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set ATETXLEN=258 */
+ if (Set_ATE_TX_LENGTH_Proc(pAd, "258") == FALSE)
+ return FALSE;
+
+ /* iwpriv ra0 set InvTxBfTag=0 */
+ if (Set_InvTxBfTag_Proc(pAd, "0") == FALSE)
+ return FALSE;
+
+ /* save current BBP_R173 value and reset it as 0 */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R173, &bbpR173);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R173, 0);
+
+ /* force BBP_R173 value when do following procedures. */
+ Set_ATE_ForceBBP_Proc(pAd, "173");
+
+ /* iwpriv ra0 set ATE=TXFRAME */
+ if (Set_ATE_Proc(pAd, "TXFRAME") == FALSE)
+ {
+ Set_ATE_ForceBBP_Proc(pAd, "0");
+ return FALSE;
+ }
+
+ /* enable the update of BBP_R173 */
+ Set_ATE_ForceBBP_Proc(pAd, "0");
+
+ /* iwpriv ra0 set ITxBfCal=0 */
+ retval = Set_ITxBfCal_Proc(pAd, "0");
+
+ /* recovery the BBP_173 to original value */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R173, bbpR173);
+
+ /* done and return */
+ return retval;
+
+}
+#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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 data, value;
+
+ pATEInfo->IPG = simple_strtol(arg, 0, 10);
+ value = pATEInfo->IPG;
+
+ RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &data);
+
+ if (value <= 0)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("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", pATEInfo->IPG));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_IPG_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ PSTRING value;
+
+ value = arg;
+
+ /* only one octet acceptable */
+ if (strlen(value) != 2)
+ return FALSE;
+
+ AtoH(value, &(pATEInfo->Payload), 1);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_Payload_Proc (repeated pattern = 0x%2x)\n", pATEInfo->Payload));
+ DBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Payload_Proc Success\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+
+
+INT Set_ATE_Show_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ PSTRING Mode_String = NULL;
+ PSTRING TxMode_String = NULL;
+
+ switch (pATEInfo->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", pATEInfo->PABias));
+#endif /* RT3350 */
+ DBGPRINT(RT_DEBUG_OFF, ("TxPower0=%d\n", pATEInfo->TxPower0));
+ DBGPRINT(RT_DEBUG_OFF, ("TxPower1=%d\n", pATEInfo->TxPower1));
+#ifdef DOT11N_SS3_SUPPORT
+ DBGPRINT(RT_DEBUG_OFF, ("TxPower2=%d\n", pATEInfo->TxPower2));
+#endif /* DOT11N_SS3_SUPPORT */
+ DBGPRINT(RT_DEBUG_OFF, ("TxAntennaSel=%d\n", pATEInfo->TxAntennaSel));
+ DBGPRINT(RT_DEBUG_OFF, ("RxAntennaSel=%d\n", pATEInfo->RxAntennaSel));
+ DBGPRINT(RT_DEBUG_OFF, ("BBPCurrentBW=%u\n", pATEInfo->TxWI.TxWIBW));
+ DBGPRINT(RT_DEBUG_OFF, ("GI=%u\n", pATEInfo->TxWI.TxWIShortGI));
+ DBGPRINT(RT_DEBUG_OFF, ("MCS=%u\n", pATEInfo->TxWI.TxWIMCS));
+
+ switch (pATEInfo->TxWI.TxWIPHYMODE)
+ {
+ 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",
+ pATEInfo->Addr1[0], pATEInfo->Addr1[1], pATEInfo->Addr1[2], pATEInfo->Addr1[3], pATEInfo->Addr1[4], pATEInfo->Addr1[5]));
+ DBGPRINT(RT_DEBUG_OFF, ("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pATEInfo->Addr2[0], pATEInfo->Addr2[1], pATEInfo->Addr2[2], pATEInfo->Addr2[3], pATEInfo->Addr2[4], pATEInfo->Addr2[5]));
+ DBGPRINT(RT_DEBUG_OFF, ("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pATEInfo->Addr3[0], pATEInfo->Addr3[1], pATEInfo->Addr3[2], pATEInfo->Addr3[3], pATEInfo->Addr3[4], pATEInfo->Addr3[5]));
+ DBGPRINT(RT_DEBUG_OFF, ("Channel=%u\n", pATEInfo->Channel));
+ DBGPRINT(RT_DEBUG_OFF, ("TxLength=%u\n", pATEInfo->TxLength));
+ DBGPRINT(RT_DEBUG_OFF, ("TxCount=%u\n", pATEInfo->TxCount));
+ DBGPRINT(RT_DEBUG_OFF, ("RFFreqOffset=%u\n", pATEInfo->RFFreqOffset));
+ DBGPRINT(RT_DEBUG_OFF, ("bAutoTxAlc=%d\n", pATEInfo->bAutoTxAlc));
+ DBGPRINT(RT_DEBUG_OFF, ("IPG=%u\n", pATEInfo->IPG));
+ DBGPRINT(RT_DEBUG_OFF, ("Payload=0x%02x\n", pATEInfo->Payload));
+#ifdef TXBF_SUPPORT
+ DBGPRINT(RT_DEBUG_OFF, ("bTxBF=%d\n", pATEInfo->bTxBF));
+ DBGPRINT(RT_DEBUG_OFF, ("txSoundingMode=%d\n", pATEInfo->txSoundingMode));
+#endif /* TXBF_SUPPORT */
+ DBGPRINT(RT_DEBUG_OFF, ("Set_ATE_Show_Proc Success\n"));
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+ 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 */
+ 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 */
+ DBGPRINT(RT_DEBUG_OFF, ("ATETXFREQOFFSET, set frequency offset, range 0~63\n"));
+ 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"));
+ 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"));
+ DBGPRINT(RT_DEBUG_OFF, ("ATELDE2P, load EEPROM from .bin file.\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("ATERE2P, display all EEPROM content.\n"));
+#ifdef LED_CONTROL_SUPPORT
+#endif /* LED_CONTROL_SUPPORT */
+ 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 beam forming.\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("ATETXSOUNDING, Sounding mode 0:none, 1:Data sounding, 2:2 stream NDP, 3:3 stream NDP.\n"));
+#endif /* TXBF_SUPPORT */
+#ifdef RTMP_INTERNAL_TX_ALC
+ DBGPRINT(RT_DEBUG_OFF, ("ATETSSICBA, start internal TSSI calibration.\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("ATETSSICBAEX, start extended internal TSSI calibration.\n"));
+#endif /* RTMP_INTERNAL_TX_ALC */
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+ DBGPRINT(RT_DEBUG_OFF, ("ATEREADEXTSSI, start advanced temperature TSSI calibration.\n"));
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+ DBGPRINT(RT_DEBUG_OFF, ("ATESHOW, display all parameters of ATE.\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("ATEHELP, online help.\n"));
+
+ return TRUE;
+}
+
+
+#ifdef RTMP_INTERNAL_TX_ALC
+
+
+INT Set_ATE_TSSI_CALIBRATION_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->TssiCalibration != NULL)
+{
+ pATEInfo->pChipStruct->TssiCalibration(pAd, arg);
+ }
+ else
+ {
+ RTMP_CHIP_ATE_TSSI_CALIBRATION(pAd, arg);
+ }
+
+ return TRUE;
+}
+
+
+INT Set_ATE_TSSI_CALIBRATION_EX_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (pATEInfo->pChipStruct->ExtendedTssiCalibration != NULL)
+ {
+ pATEInfo->pChipStruct->ExtendedTssiCalibration(pAd, arg);
+ }
+ else
+ {
+ RTMP_CHIP_ATE_TSSI_CALIBRATION_EXTEND(pAd, arg);
+ }
+
+ return TRUE;
+}
+
+
+#if defined(RT3350) || defined(RT3352)
+INT RT335x2_Set_ATE_TSSI_CALIBRATION_ENABLE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+ {
+ BOOLEAN bTSSICalbrEnableG = FALSE;
+
+ if (pAd->TxPowerCtrl.bInternalTxALC == FALSE)
+ {
+ DBGPRINT_ERR(("Please set e2p 0x36 as 0x2024!!!\n"));
+ return FALSE;
+ }
+
+ if ((!IS_RT3350(pAd)) && (!IS_RT3352(pAd)))
+ {
+ DBGPRINT_ERR(("Not support TSSI calibration since not 3350/3352 chip!!!\n"));
+ return FALSE;
+ }
+
+ if (strcmp(arg, "0") == 0)
+ {
+ bTSSICalbrEnableG = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI calibration disabled!\n"));
+ }
+ else if (strcmp(arg, "1") == 0)
+ {
+ bTSSICalbrEnableG = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI calibration enabled!\n"));
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ pAd->ate.bTSSICalbrEnableG = bTSSICalbrEnableG;
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+ }
+
+
+CHAR InsertTssi(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;
+}
+
+
+INT RT335xATETssiCalibrationExtend(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ CHAR TssiRefPerChannel[CFG80211_NUM_OF_CHAN_2GHZ], TssiDeltaPerChannel[CFG80211_NUM_OF_CHAN_2GHZ];
+ UCHAR CurrentChannel;
+ UCHAR BbpData = 0;
+ USHORT EEPData;
+
+ if (pAd->ate.bTSSICalbrEnableG == FALSE)
+ {
+ DBGPRINT_ERR(("No TSSI readings obtained !!!\n"));
+ DBGPRINT_ERR(("TSSI calibration failed !!!\n"));
+
+ return FALSE;
+ }
+ else
+ {
+ pAd->ate.bTSSICalbrEnableG = FALSE;
+ }
+
+ NdisCopyMemory(TssiRefPerChannel, pAd->ate.TssiRefPerChannel, CFG80211_NUM_OF_CHAN_2GHZ);
+ NdisCopyMemory(TssiDeltaPerChannel, pAd->ate.TssiDeltaPerChannel, CFG80211_NUM_OF_CHAN_2GHZ);
+
+ /* step 1: write TSSI_ref to EEPROM 0x6E */
+ CurrentChannel = 7;
+ BbpData = TssiRefPerChannel[CurrentChannel-1];
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI_ref = 0x%02x\n", TssiRefPerChannel[CurrentChannel-1]));
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_OVER_OFDM_54, EEPData);
+ EEPData &= 0xff00;
+ EEPData |= BbpData;
+ DBGPRINT(RT_DEBUG_TRACE, ("Write E2P 0x6e: 0x%04x\n", EEPData));
+#ifdef RTMP_EFUSE_SUPPORT
+ if(pAd->bUseEfuse)
+ {
+ if(pAd->bFroceEEPROMBuffer)
+ NdisMoveMemory(&(pAd->EEPROMImage[EEPROM_TSSI_OVER_OFDM_54]), (PUCHAR) (&EEPData) ,2);
+ else
+ eFuseWrite(pAd, EEPROM_TSSI_OVER_OFDM_54, (PUCHAR) (&EEPData), 2);
+ }
+ else
+#endif /* RTMP_EFUSE_SUPPORT */
+ {
+ RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_OVER_OFDM_54, EEPData);
+ RTMPusecDelay(10);
+ }
+
+ /* step 2: insert the TSSI table */
+ /* insert channel 2 to 6 TSSI values */
+ for (CurrentChannel = 2; CurrentChannel < 7; CurrentChannel++)
+ TssiRefPerChannel[CurrentChannel-1] = InsertTssi(CurrentChannel, 1, 7, TssiRefPerChannel[0], TssiRefPerChannel[6]);
+
+ /* insert channel 8 to 12 TSSI values */
+ for (CurrentChannel = 8; CurrentChannel < 13; CurrentChannel++)
+ TssiRefPerChannel[CurrentChannel-1] = InsertTssi(CurrentChannel, 7, 13, TssiRefPerChannel[6], TssiRefPerChannel[12]);
+
+ /* channel 14 TSSI equals channel 13 TSSI */
+ TssiRefPerChannel[13] = TssiRefPerChannel[12];
+
+ for (CurrentChannel = 1; CurrentChannel <= 14; CurrentChannel++)
+ {
+ TssiDeltaPerChannel[CurrentChannel-1] = TssiRefPerChannel[CurrentChannel-1] - TssiRefPerChannel[6];
+
+ /* boundary check */
+ if(TssiDeltaPerChannel[CurrentChannel-1] > 7 )
+ TssiDeltaPerChannel[CurrentChannel-1] = 7;
+ if(TssiDeltaPerChannel[CurrentChannel-1] < -8 )
+ TssiDeltaPerChannel[CurrentChannel-1] = -8;
+
+ /* eeprom only use 4 bit for TSSI delta */
+ TssiDeltaPerChannel[CurrentChannel-1] &= 0x0f;
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel %d, TSSI= 0x%x, TssiDelta=0x%x\n",
+ CurrentChannel, TssiRefPerChannel[CurrentChannel-1], TssiDeltaPerChannel[CurrentChannel-1]));
+ }
+
+ /* step 3: store TSSI delta values to EEPROM */
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_1-1, EEPData);
+ EEPData &= 0x00ff;
+ EEPData |= (TssiDeltaPerChannel[0] << 8) | (TssiDeltaPerChannel[1] << 12);
+
+#ifdef RTMP_EFUSE_SUPPORT
+ if (pAd->bUseEfuse)
+ {
+ if (pAd->bFroceEEPROMBuffer)
+ NdisMoveMemory(&(pAd->EEPROMImage[EEPROM_TX_POWER_OFFSET_OVER_CH_1-1]), (PUCHAR)(&EEPData), 2);
+ else
+ eFuseWrite(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_1-1, (PUCHAR) (&EEPData), 2);
+ }
+ else
+#endif /* RTMP_EFUSE_SUPPORT */
+ {
+ RT28xx_EEPROM_WRITE16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_1-1, EEPData);
+ RTMPusecDelay(10);
+ }
+
+ for (CurrentChannel = 3; CurrentChannel <= 14; CurrentChannel += 4)
+ {
+ EEPData = (TssiDeltaPerChannel[CurrentChannel+2] << 12) |(TssiDeltaPerChannel[CurrentChannel+1] << 8)
+ | (TssiDeltaPerChannel[CurrentChannel] << 4) | TssiDeltaPerChannel[CurrentChannel-1];
+#ifdef RTMP_EFUSE_SUPPORT
+ if (pAd->bUseEfuse)
+ {
+ if (pAd->bFroceEEPROMBuffer)
+ NdisMoveMemory(&(pAd->EEPROMImage[(EEPROM_TX_POWER_OFFSET_OVER_CH_3 +((CurrentChannel-3)/2))]), (PUCHAR)(&EEPData), 2);
+ else
+ eFuseWrite(pAd, (EEPROM_TX_POWER_OFFSET_OVER_CH_3 +((CurrentChannel-3)/2)), (PUCHAR) (&EEPData), 2);
+ }
+ else
+#endif /* RTMP_EFUSE_SUPPORT */
+ {
+ RT28xx_EEPROM_WRITE16(pAd, (EEPROM_TX_POWER_OFFSET_OVER_CH_3 +((CurrentChannel-3)/2)), EEPData);
+ RTMPusecDelay(10);
+ }
+ }
+
+ /* step 4: disable legacy ALC and set TSSI enabled and TSSI extend mode to EEPROM */
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_ENABLE, EEPData);
+ /* disable legacy ALC */
+ EEPData &= ~(1 << 1);
+ /* enable TSSI */
+ EEPData |= (1 << 13);
+#ifdef RTMP_EFUSE_SUPPORT
+ if (pAd->bUseEfuse)
+ {
+ if (pAd->bFroceEEPROMBuffer)
+ NdisMoveMemory(&(pAd->EEPROMImage[EEPROM_TSSI_ENABLE]), (PUCHAR)(&EEPData), 2);
+ else
+ eFuseWrite(pAd, EEPROM_TSSI_ENABLE, (PUCHAR)(&EEPData), 2);
+ }
+ else
+#endif /* RTMP_EFUSE_SUPPORT */
+ {
+ RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_ENABLE, EEPData);
+ RTMPusecDelay(10);
+ }
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_MODE_EXTEND, EEPData);
+ /* set extended TSSI mode */
+ EEPData |= (1 << 15);
+#ifdef RTMP_EFUSE_SUPPORT
+ if (pAd->bUseEfuse)
+ {
+ if (pAd->bFroceEEPROMBuffer)
+ NdisMoveMemory(&(pAd->EEPROMImage[EEPROM_TSSI_MODE_EXTEND]), (PUCHAR)(&EEPData), 2);
+ else
+ eFuseWrite(pAd, EEPROM_TSSI_MODE_EXTEND, (PUCHAR)(&EEPData), 2);
+ }
+ else
+#endif /* RTMP_EFUSE_SUPPORT */
+ {
+ RT28xx_EEPROM_WRITE16(pAd, EEPROM_TSSI_MODE_EXTEND, EEPData);
+ RTMPusecDelay(10);
+ }
+
+ /* step 5: synchronize ATE private data structure with the values written to EEPROM */
+ NdisCopyMemory(pAd->ate.TssiRefPerChannel, TssiRefPerChannel, CFG80211_NUM_OF_CHAN_2GHZ);
+ NdisCopyMemory(pAd->ate.TssiDeltaPerChannel, TssiDeltaPerChannel, CFG80211_NUM_OF_CHAN_2GHZ);
+
+ return TRUE;
+}
+
+#endif /* defined(RT3350) || defined(RT3352) */
+#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);
+ return TRUE;
+}
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+
+
+
+#ifdef MT7601
+INT Set_ATE_Read_Temperature_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ CHAR Temperature;
+
+ DBGPRINT(RT_DEBUG_TRACE,("Set_MT7601ATE_Read_Temperature_Proc\n"));
+
+ MT7601_Read_Temperature(pAd, &Temperature);
+
+ DBGPRINT(RT_DEBUG_TRACE,("Temperature = %d (0x%X)\n", Temperature, Temperature));
+
+ return TRUE;
+}
+
+
+INT Set_ATE_Read_TSSI_DC_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR BbpReg;
+
+ DBGPRINT(RT_DEBUG_TRACE,("Set_ATE_Read_TSSI_DC_Proc\n"));
+
+ RTMP_IO_WRITE32(pAd, 0x50C, 0x30);
+ RTMP_IO_WRITE32(pAd, 0x504, 0xC0030);
+ /* Set VGA gain */
+ rlt_rf_write(pAd, RF_BANK5, RF_R03, 0x8);
+ /* Mixer disable */
+ rlt_rf_write(pAd, RF_BANK4, RF_R39, 0x0);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4 , 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R58 , 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21 , 0x1);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21 , 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47 , 0x50);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22 , 0x40);
+ RtmpOsMsDelay(10);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpReg);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, 0x40);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpReg);
+ DBGPRINT(RT_DEBUG_TRACE,("TSSI DC = %d (0x%X)\n", BbpReg, BbpReg));
+ RtmpOsMsDelay(1);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22 , 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21 , 0x1);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21 , 0x0);
+ RTMP_IO_WRITE32(pAd, 0x504, 0x0);
+ RTMP_IO_WRITE32(pAd, 0x50C, 0x0);
+ rlt_rf_write(pAd, RF_BANK4, RF_R39, 0xB3);
+
+ return TRUE;
+}
+#endif /* MT7601 */
+
+
+struct _ATE_CHIP_STRUCT RALINKDefault =
+{
+ /* functions */
+ .ChannelSwitch = DefaultATEAsicSwitchChannel,
+ .TxPwrHandler = DefaultATETxPwrHandler,
+ .TssiCalibration = NULL,
+ .ExtendedTssiCalibration = NULL,
+ .RxVGAInit = NULL,
+ .AsicSetTxRxPath = DefaultATEAsicSetTxRxPath,
+ .AdjustTxPower = DefaultATEAsicAdjustTxPower,
+ .AsicExtraPowerOverMAC = NULL,
+
+ /* command handlers */
+ .Set_BW_Proc = Default_Set_ATE_TX_BW_Proc,
+ .Set_FREQ_OFFSET_Proc = Default_Set_ATE_TX_FREQ_OFFSET_Proc,
+
+ /* variables */
+ .maxTxPwrCnt = 5,
+ .bBBPStoreTXCARR = TRUE,
+ .bBBPStoreTXCARRSUPP = TRUE,
+ .bBBPStoreTXCONT = FALSE,
+ .bBBPLoadATESTOP = TRUE,
+};
+
+#ifdef RT28xx
+#ifdef RTMP_MAC_USB
+extern ATE_CHIP_STRUCT RALINK2870;
+#endif /* RTMP_MAC_USB */
+#endif /* RT28xx */
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef MT7601
+extern ATE_CHIP_STRUCT MT7601ATE;
+#endif
+
+/*
+==========================================================================
+ Description:
+ Assign chip structure when initialization.
+ This routine is specific for ATE.
+
+==========================================================================
+*/
+NDIS_STATUS ChipStructAssign(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ pATEInfo->pChipStruct = &RALINKDefault;
+
+#ifdef RT28xx
+#ifdef A_BAND_SUPPORT
+ if (IS_PCI_ONLY_INF(pAd) || IS_USB_INF(pAd) || IS_RBUS_INF(pAd))
+
+ {
+
+
+
+ if (pATEInfo->pChipStruct == &RALINKDefault)
+ {
+ /* Not RT2860/RT2870/RT2880 ! */
+ DBGPRINT_ERR(("Error - Unknown chipset !!!\n"));
+ DBGPRINT_ERR(("The interface type is %d\n", pAd->infType));
+
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+#endif /* A_BAND_SUPPORT */
+#endif /* RT28xx */
+
+
+
+
+
+
+
+
+
+
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ pATEInfo->pChipStruct = &MT7601ATE;
+ }
+#endif /* MT7601 */
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+==========================================================================
+ Description:
+ Initialize ATE_INFO structure.
+ This routine is specific for ATE.
+
+==========================================================================
+*/
+NDIS_STATUS ATEInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ NdisZeroMemory(pATEInfo, sizeof(ATE_INFO));
+
+ if (ChipStructAssign(pAd) != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("%s failed !\n", __FUNCTION__));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ pATEInfo->Mode = ATE_STOP;
+#ifdef RT3350
+ pATEInfo->PABias = 0;
+#endif /* RT3350 */
+ pATEInfo->TxCount = 1000;/* to sync with QA and to exceed TX_RING_SIZE ... */
+ pATEInfo->TxDoneCount = 0;
+ pATEInfo->RFFreqOffset = 0;
+ pATEInfo->Payload = 0xA5;/* to be backward compatible */
+ pATEInfo->IPG = 200;/* 200 : sync with QA */
+ pATEInfo->TxLength = 1024;
+ pATEInfo->TxWI.TxWIShortGI = 0;/* LONG GI : 800 ns*/
+ pATEInfo->TxWI.TxWIPHYMODE = MODE_CCK;
+ pATEInfo->TxWI.TxWIMCS = 3;
+ pATEInfo->TxWI.TxWIBW = BW_20;
+ /* please do not change this default channel value */
+ pATEInfo->Channel = 1;
+
+
+ pATEInfo->QID = QID_AC_BE;
+
+#ifdef DOT11N_SS3_SUPPORT
+ /* For 3T/3R ++ */
+ /* use broadcast address as default value */
+ pATEInfo->Addr1[0] = 0xFF;
+ pATEInfo->Addr1[1] = 0xFF;
+ pATEInfo->Addr1[2] = 0xFF;
+ pATEInfo->Addr1[3] = 0xFF;
+ pATEInfo->Addr1[4] = 0xFF;
+ pATEInfo->Addr1[5] = 0xFF;
+
+ pATEInfo->Addr2[0] = 0x00;
+ pATEInfo->Addr2[1] = 0x11;
+ pATEInfo->Addr2[2] = 0x22;
+ pATEInfo->Addr2[3] = 0xAA;
+ pATEInfo->Addr2[4] = 0xBB;
+ pATEInfo->Addr2[5] = 0xCC;
+
+ NdisMoveMemory(pATEInfo->Addr3, pATEInfo->Addr2, ETH_LENGTH_OF_ADDRESS);
+
+ {
+ UINT32 data;
+
+ data = 0xFFFFFFFF;
+ RTMP_IO_WRITE32(pAd, 0x1044, data);
+ RTMP_IO_READ32(pAd, 0x1048, &data);
+
+ data = data | 0x0000FFFF;
+ RTMP_IO_WRITE32(pAd, 0x1048, data);
+ }
+ /* For stream mode in 3T/3R -- */
+#else
+ pATEInfo->Addr1[0] = 0x00;
+ pATEInfo->Addr1[1] = 0x11;
+ pATEInfo->Addr1[2] = 0x22;
+ pATEInfo->Addr1[3] = 0xAA;
+ pATEInfo->Addr1[4] = 0xBB;
+ pATEInfo->Addr1[5] = 0xCC;
+
+ NdisMoveMemory(pATEInfo->Addr2, pATEInfo->Addr1, ETH_LENGTH_OF_ADDRESS);
+ NdisMoveMemory(pATEInfo->Addr3, pATEInfo->Addr1, ETH_LENGTH_OF_ADDRESS);
+#endif /* DOT11N_SS3_SUPPORT */
+
+ pATEInfo->bRxFER = 0;
+ pATEInfo->bQAEnabled = FALSE;
+ pATEInfo->bQATxStart = FALSE;
+ pATEInfo->bQARxStart = FALSE;
+ pATEInfo->bAutoTxAlc = FALSE;
+#ifdef RTMP_INTERNAL_TX_ALC
+#if defined(RT3350) || defined(RT3352)
+ pATEInfo->bTSSICalbrEnableG = FALSE;
+ NdisZeroMemory((PUCHAR)&(pATEInfo->TssiRefPerChannel), CFG80211_NUM_OF_CHAN_2GHZ);
+ NdisZeroMemory((PUCHAR)&(pATEInfo->TssiDeltaPerChannel), CFG80211_NUM_OF_CHAN_2GHZ);
+#endif /* defined(RT3350) || defined(RT3352) */
+#endif /* RTMP_INTERNAL_TX_ALC */
+ /* Default TXCONT/TXCARR/TXCARS mechanism is TX_METHOD_1 */
+ pATEInfo->TxMethod = TX_METHOD_1;
+ if ((IS_RT2070(pAd) || IS_RT2860(pAd) || IS_RT2872(pAd) || IS_RT2883(pAd)))
+ {
+ /* Early chipsets must be applied original TXCONT/TXCARR/TXCARS mechanism. */
+ pATEInfo->TxMethod = TX_METHOD_0;
+ }
+
+ /* Power range is 0~31 in A band. */
+ pATEInfo->MinTxPowerBandA = 0;
+ pATEInfo->MaxTxPowerBandA = 31;
+ if ((IS_RT2860(pAd)) || (IS_RT2872(pAd)) || (IS_RT2883(pAd)))
+ {
+ /* Power range of early chipsets is -7~15 in A band. */
+ pATEInfo->MinTxPowerBandA = -7;
+ pATEInfo->MaxTxPowerBandA = 15;
+ }
+
+#ifdef TXBF_SUPPORT
+ pATEInfo->bTxBF = FALSE;
+#endif /* TXBF_SUPPORT */
+
+
+#ifdef RTMP_MAC_USB
+#endif /* RTMP_MAC_USB */
+
+#ifdef RALINK_QA
+ pATEInfo->TxStatus = 0;
+ RtmpOsTaskPidInit(&(pATEInfo->AtePid));
+/* pATEInfo->AtePid = THREAD_PID_INIT_VALUE; */
+#endif /* RALINK_QA */
+ pATEInfo->OneSecPeriodicRound = 0;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef RALINK_QA
+/*
+==========================================================================
+ Description:
+ This routine is specific for ATE.
+ When we start tx from QA GUI, it will modify BBP registers without
+ notify ATE driver what the tx subtype is.
+
+ Return:
+ VOID
+==========================================================================
+*/
+VOID ReadQATxTypeFromBBP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR Bbp22Value = 0, Bbp24Value = 0;
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &Bbp22Value);
+
+ switch (Bbp22Value)
+ {
+ case BBP22_TXFRAME:
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
+ pATEInfo->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"));
+ pATEInfo->bQATxStart = TRUE;
+
+ if (pATEInfo->TxMethod == TX_METHOD_0)
+ {
+ Set_ATE_Proc(pAd, "TXCONT");
+ }
+ }
+ break;
+
+ case BBP24_CARRSUPP:
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
+ pATEInfo->bQATxStart = TRUE;
+
+ if (pATEInfo->TxMethod == TX_METHOD_0)
+ {
+ Set_ATE_Proc(pAd, "TXCARS");
+ }
+ }
+ break;
+
+ default:
+ {
+ DBGPRINT_ERR(("Unknown TX subtype !\n"));
+ }
+ break;
+ }
+ }
+ break;
+
+ case BBP22_TXCARR:
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
+ pATEInfo->bQATxStart = TRUE;
+
+ if (pATEInfo->TxMethod == TX_METHOD_0)
+ {
+ Set_ATE_Proc(pAd, "TXCARR");
+ }
+ }
+ break;
+
+ default:
+ {
+ DBGPRINT_ERR(("Unknown Start TX subtype !\n"));
+ }
+ break;
+ }
+
+ return;
+}
+#endif /* RALINK_QA */
+
+
+NDIS_STATUS ATEBBPWriteWithRxChain(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR bbpId,
+ IN CHAR bbpVal,
+ IN RX_CHAIN_IDX rx_ch_idx)
+{
+ UCHAR idx = 0, val = 0;
+
+ if (((pAd->MACVersion & 0xffff0000) < 0x28830000) ||
+ (pAd->Antenna.field.RxPath == 1))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, bbpId, bbpVal);
+ return NDIS_STATUS_SUCCESS;
+ }
+
+ while (rx_ch_idx != 0)
+ {
+ if (idx >= pAd->Antenna.field.RxPath)
+ break;
+
+ if (rx_ch_idx & 0x01)
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &val);
+ val = (val & (~0x60)/* clear bit5 and bit6 */) | (idx << 5);
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, val);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, bbpId, bbpVal);
+ }
+#endif /* RTMP_MAC_USB */
+
+
+ DBGPRINT(RT_DEBUG_INFO,
+ ("%s(Idx):Write(R%d,val:0x%x) to Chain(0x%x, idx:%d)\n",
+ __FUNCTION__, bbpId, bbpVal, rx_ch_idx, idx));
+ }
+ rx_ch_idx >>= 1;
+ idx++;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#define SMM_BASEADDR 0x4000
+#define PKT_BASEADDR 0x8000
+
+
+#ifdef RLT_MAC
+INT Set_ADCDump_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+
+ DBGPRINT_ERR(("%s::Not supported!!!\n", __FUNCTION__));
+ return TRUE;
+}
+
+#else
+INT Set_ADCDump_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR BBP_R21_Ori=0,BBP_R60_Ori=0,BBP_R142_ORI=0,BBP_R143_ORI=0;
+ UINT32 MACValue=0,PBF_SYS_CTRL_ORI=0,PBF_CAP_CTRL_ORI=0;
+ UINT32 CaptureModeOffset=0,CaptureStartAddr=0;
+ UINT32 SMM_Addr;
+ UINT32 PKT_Addr;
+ int i = 0;
+ PSTRING src = "ADCDump.txt";
+ RTMP_OS_FD srcf;
+ RTMP_OS_FS_INFO osFSInfo;
+ UCHAR msg[128];
+ UCHAR msg1[128];
+ CAPTURE_MODE_SHARE_MEMORY SMMValued;
+ CAPTURE_MODE_PACKET_BUFFER PKTValue1d;
+ CAPTURE_MODE_PACKET_BUFFER PKTValue2d;
+ UCHAR retval=0;
+ UCHAR DataSourceADC6=simple_strtol(arg, 0, 10);
+
+ pAd->ate.Mode = ATE_START;
+
+ /* Disable Tx/Rx */
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BBP_R21_Ori);
+
+ /* Disable BBP power saving */
+
+ /* disable all Tx/Rx Queue */
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0x00000000);
+
+ /* capture mode */
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MACValue);
+ PBF_SYS_CTRL_ORI=MACValue;
+ MACValue |= 0x00004000; /* bit[14]=1 */
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MACValue);
+
+ /* capture setting */
+ if (DataSourceADC6 == 1)
+ {
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R60, &BBP_R60_Ori);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R60, 0x80);
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R142, &BBP_R142_ORI);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R142, 0x10);
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R143, &BBP_R143_ORI);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R143, 0x05);
+
+ RTMP_IO_READ32(pAd, PBF_CAP_CTRL, &MACValue);
+ PBF_CAP_CTRL_ORI=MACValue;
+ MACValue |= 0x00008000; /* set bit[15]=1 for ADC 6 */
+ MACValue &= ~0x80000000; /* set bit[31]=0 */
+ RTMP_IO_WRITE32(pAd, PBF_CAP_CTRL, MACValue);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, PBF_CAP_CTRL, &MACValue);
+ PBF_CAP_CTRL_ORI=MACValue;
+ MACValue &= ~0x80008000; /* set bit[31]=0, bit[15]=0 for ADC 8 */
+ RTMP_IO_WRITE32(pAd, PBF_CAP_CTRL, MACValue);
+ }
+
+ /* trigger offset */
+ RTMP_IO_READ32(pAd, PBF_CAP_CTRL, &MACValue);
+ MACValue &= ~(0x1FFF0000);
+ RTMP_IO_WRITE32(pAd, PBF_CAP_CTRL, MACValue);
+
+ if ((CaptureModeOffset > 0) && (CaptureModeOffset <= 0x1FFF))
+ {
+ RTMP_IO_READ32(pAd, PBF_CAP_CTRL, &MACValue);
+ MACValue |= CaptureModeOffset << 16;
+ RTMP_IO_WRITE32(pAd, PBF_CAP_CTRL, MACValue);
+ }
+
+ /* start capture */
+ RTMP_IO_READ32(pAd, PBF_CAP_CTRL, &MACValue);
+ MACValue = MACValue | 0x40000000; /* set bit[30]=1 */
+ RTMP_IO_WRITE32(pAd, PBF_CAP_CTRL, MACValue);
+
+ if (0)
+ {
+ /* start TX */
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+ }
+ else
+ {
+ /* start RX */
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x8);
+ }
+
+ /* Wait until [0x440] bit30=0 */
+ do
+ {
+ i++;
+ RTMPusecDelay(10);
+ RTMP_IO_READ32(pAd, PBF_CAP_CTRL, &MACValue);
+ MACValue = MACValue & 0x40000000; /* bit[30] */
+
+ if (MACValue == 0)
+ {
+ break;
+ }
+
+ if (i == 1000) /* 3 sec */
+ {
+ printk("Error, over 3s\n");
+ break;
+ }
+ } while (MACValue != 0);
+
+ if (DataSourceADC6 == 1)
+ {
+ /* restore BBP R60 */
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R60, BBP_R60_Ori);
+ }
+
+ /* Stop TX/RX */
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+ /* Read [0x440] bit[12:0] */
+ RTMP_IO_READ32(pAd, PBF_CAP_CTRL, &CaptureStartAddr);
+ CaptureStartAddr = CaptureStartAddr & 0x00001FFF;
+
+ /* Dump data from MAC memory */
+ RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+ SMM_Addr=SMM_BASEADDR+CaptureStartAddr*2;
+ PKT_Addr=PKT_BASEADDR+CaptureStartAddr*4;
+
+ /* SMM Address must be four byte alignment*/
+ SMM_Addr=(SMM_Addr/4)*4;
+
+ /* open file */
+ 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
+ {
+ memset(msg, 0x00, 128);
+ memset(msg1, 0x00, 128);
+
+ for (i=0;i<0x1000;i++)
+ {
+ RTMP_IO_READ32(pAd,SMM_Addr, &SMMValued.Value);
+ SMM_Addr += 4;
+
+ if(SMM_Addr >= 0x8000)
+ SMM_Addr = SMM_Addr - SMM_BASEADDR;
+
+ RTMP_IO_READ32(pAd,PKT_Addr, &PKTValue1d.Value);
+ PKT_Addr += 4;
+
+ if(PKT_Addr >= 0x10000)
+ PKT_Addr = PKT_Addr - PKT_BASEADDR;
+
+ RTMP_IO_READ32(pAd,PKT_Addr, &PKTValue2d.Value);
+ PKT_Addr += 4;
+
+ if(PKT_Addr >= 0x10000)
+ PKT_Addr = PKT_Addr - PKT_BASEADDR;
+
+ sprintf(msg, "%d %d %d %d %d %d\n",SMMValued.field.LOW_BYTE1,SMMValued.field.LOW_BYTE0
+ ,PKTValue1d.field.BYTE3,PKTValue1d.field.BYTE2
+ ,PKTValue1d.field.BYTE1,PKTValue1d.field.BYTE0);
+ sprintf(msg1, "%d %d %d %d %d %d\n",SMMValued.field.LOW_BYTE1,SMMValued.field.LOW_BYTE0
+ ,PKTValue2d.field.BYTE3,PKTValue2d.field.BYTE2
+ ,PKTValue2d.field.BYTE1,PKTValue2d.field.BYTE0);
+
+ retval=RtmpOSFileWrite(srcf, (PSTRING)msg, strlen(msg));
+ retval=RtmpOSFileWrite(srcf, (PSTRING)msg1, strlen(msg1));
+ }
+ }
+ }
+ 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);
+
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BBP_R21_Ori);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R60, BBP_R60_Ori);
+
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R142, BBP_R142_ORI);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R142, BBP_R142_ORI);
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, PBF_SYS_CTRL_ORI);
+ RTMP_IO_WRITE32(pAd, PBF_CAP_CTRL, PBF_CAP_CTRL_ORI);
+
+ /* Finish */
+ /* normal mode */
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MACValue);
+ MACValue &= ~0x00004000;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MACValue);
+
+ /* reset packet buffer */
+ RTMP_IO_WRITE32(pAd, PBF_CTRL,0x00000020 );
+
+ /* enable Tx/Rx Queue */
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0x00F40016);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0C);
+ pAd->ate.Mode = ATE_STOP;
+
+ return TRUE;
+}
+#endif /* RLT_MAC */
+
+
+/* one-second periodic execution */
+VOID ATEPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ if (ATE_ON(pAd))
+ {
+ pATEInfo->OneSecPeriodicRound++;
+
+ /* for performace enchanement */
+ NdisZeroMemory(&pAd->RalinkCounters,
+ (UINT32)&pAd->RalinkCounters.OneSecEnd -
+ (UINT32)&pAd->RalinkCounters.OneSecStart);
+ NICUpdateRawCounters(pAd);
+
+ if (pATEInfo->bRxFER == 1)
+ {
+ pATEInfo->RxTotalCnt += pATEInfo->RxCntPerSec;
+ ate_print(KERN_EMERG "ATEPeriodicExec: Rx packet cnt = %d/%d\n",
+ pATEInfo->RxCntPerSec, pATEInfo->RxTotalCnt);
+ pATEInfo->RxCntPerSec = 0;
+
+ if (pATEInfo->RxAntennaSel == 0)
+ ate_print(KERN_EMERG "ATEPeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
+ pATEInfo->AvgRssi0, pATEInfo->AvgRssi1, pATEInfo->AvgRssi2);
+ else
+ ate_print(KERN_EMERG "ATEPeriodicExec: Rx AvgRssi=%d\n\n", pATEInfo->AvgRssi0);
+ }
+
+ MlmeResetRalinkCounters(pAd);
+
+ /* In QA Mode, QA will handle all registers. */
+ if (pATEInfo->bQAEnabled == TRUE)
+ {
+ return;
+ }
+
+ if ((pATEInfo->bAutoTxAlc == TRUE)
+ && ((pATEInfo->Mode == ATE_TXFRAME) || (pATEInfo->Mode == ATE_TXCONT)))
+ {
+ ATEAsicAdjustTxPower(pAd);
+ }
+
+ ATEAsicExtraPowerOverMAC(pAd);
+
+ //ATEAsicTemperCompensation(pAd);
+
+ }
+ else
+ {
+ DBGPRINT_ERR(("%s is NOT called in ATE mode.\n", __FUNCTION__));
+ }
+
+ return;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/ate/common/rt_qa.c b/cleopatre/devkit/mt7601udrv/ate/common/rt_qa.c
new file mode 100644
index 0000000000..0f5dde5e9c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ate/common/rt_qa.c
@@ -0,0 +1,2497 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_qa.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#include "rt_config.h"
+
+#ifdef RALINK_QA
+NDIS_STATUS TXSTOP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 MacData=0, atemode=0;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR BbpData = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__));
+
+ atemode = pATEInfo->Mode;
+ pATEInfo->Mode &= ATE_TXSTOP;
+ pATEInfo->bQATxStart = FALSE;
+
+ if (atemode == ATE_TXCARR)
+ {
+ if (pATEInfo->TxMethod == TX_METHOD_0)
+ {
+ /* No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0 */
+ ATE_BBP_RESET_TX_MODE(pAd, BBP_R22, &BbpData);
+ }
+ }
+ else if (atemode == ATE_TXCARRSUPP)
+ {
+ if (pATEInfo->TxMethod == TX_METHOD_0)
+ {
+ /* No Cont. TX set BBP R22 bit7=0 */
+ /* QA will do this in new TXCARRSUPP proposal */
+ ATE_BBP_STOP_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+
+ /* No Carrier Suppression set BBP R24 bit0=0 */
+ ATE_BBP_CTS_TX_SIN_WAVE_DISABLE(pAd, BBP_R24, &BbpData);
+ }
+ }
+
+ /*
+ We should free some resource which was allocated
+ when ATE_TXFRAME, ATE_STOP, and ATE_TXCONT.
+ */
+ else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+ {
+ if (atemode == ATE_TXCONT)
+ {
+ if (pATEInfo->TxMethod == TX_METHOD_0)
+ {
+ /* No Cont. TX set BBP R22 bit7=0 */
+ /* QA will do this in new TXCONT proposal */
+ ATE_BBP_STOP_CTS_TX_MODE(pAd, BBP_R22, &BbpData);
+ }
+ }
+
+
+#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);
+
+ /* Enable Tx, Rx DMA. */
+ RtmpDmaEnable(pAd, 1);
+#endif /* RTMP_MAC_USB */
+ }
+
+ /* task Tx status : 0 --> task is idle, 1 --> task is running */
+ pATEInfo->TxStatus = 0;
+
+ if (pATEInfo->TxMethod == TX_METHOD_0)
+ {
+ BbpSoftReset(pAd);/* Soft reset BBP. */
+ }
+
+ /* Disable Tx */
+ ATE_MAC_TX_DISABLE(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;
+}
+
+
+NDIS_STATUS RXSTOP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 MacData=0;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ATE : ===> %s\n", __FUNCTION__));
+
+ /* Disable Rx */
+ ATE_MAC_RX_DISABLE(pAd, MAC_SYS_CTRL, &MacData);
+
+ pATEInfo->Mode &= ATE_RXSTOP;
+ pATEInfo->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 */
+
+ if ((!IS_RT3883(pAd)) && (!IS_RT3352(pAd)) && (!IS_RT5350(pAd)))
+ BbpSoftReset(pAd);/* Soft reset BBP. */
+
+ 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 >> 2); 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 >> 2); i++)
+ {
+ pDst = (dst + (i << 2));
+ RTMP_IO_READ32(pAd, offset, &Value);
+ Value = OS_HTONL(Value);
+ memmove(pDst, &Value, 4);
+ offset += 4;
+ }
+ return;
+}
+
+
+VOID BubbleSort(INT32 size, INT32 array[])
+{
+ INT32 outer, inner, temp;
+
+ for (outer = size-1; outer>0; outer--)
+ {
+ for (inner = 0; inner<outer; inner++)
+ {
+ if (array[inner] > array[inner+1])
+ {
+ temp = array[inner];
+ array[inner]=array[inner+1];
+ array[inner+1]=temp;
+ }
+ }
+ }
+ return;
+}
+
+
+VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ INT32 RSSI0, RSSI1, RSSI2;
+ CHAR Rssi0Offset, Rssi1Offset, Rssi2Offset;
+ UCHAR BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
+ UCHAR Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
+ USHORT LNA_Gain = 0;
+ INT32 column = 0;
+ UCHAR Org_Channel = pATEInfo->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;
+ }
+ /***********************************************************************/
+ {
+ pATEInfo->Channel = channel;
+ ATEAsicSwitchChannel(pAd);
+ RtmpOsMsDelay(5);
+
+ data = 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
+ data = 0x40;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
+ data = 0x40;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
+ RtmpOsMsDelay(5);
+
+ /* start Rx */
+ pATEInfo->bQARxStart = TRUE;
+ Set_ATE_Proc(pAd, "RXFRAME");
+
+ RtmpOsMsDelay(5);
+
+ for (column = 0; column < 10; column++)
+ {
+ 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][column] = 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][column] = 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][column] = 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]);
+ }
+ }
+
+ pATEInfo->Channel = Org_Channel;
+ ATEAsicSwitchChannel(pAd);
+
+ /* restore original value */
+
+ 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;
+}
+
+
+static VOID ATE_BBPRead(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR offset,
+ IN UCHAR *pValue)
+{
+ if (ATE_ON(pAd))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, pValue);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, pValue);
+ }
+}
+
+
+static VOID ATE_BBPWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR offset,
+ IN UCHAR value)
+{
+ 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);
+ }
+}
+
+
+BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UCHAR tmp = 0, bbp_data = 0;
+
+ ATE_BBPRead(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 */
+ pATEInfo->TxAntennaSel = 0;
+ break;
+ /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
+ case 0:
+ /* Antenna one */
+ pATEInfo->TxAntennaSel = 1;
+ break;
+ /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
+ case 1:
+ /* Antenna two */
+ pATEInfo->TxAntennaSel = 2;
+ break;
+ default:
+ DBGPRINT_ERR(("%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 */
+ pATEInfo->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 */
+ pATEInfo->RxAntennaSel = 1;
+ tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
+ if (tmp == 2) /* 3R */
+ {
+ /* Default : All ADCs will be used by QA */
+ pATEInfo->RxAntennaSel = 0;
+ }
+ break;
+ /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
+ case 1:
+ /* Antenna two */
+ pATEInfo->RxAntennaSel = 2;
+ break;
+ /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
+ case 2:
+ /* Antenna three */
+ pATEInfo->RxAntennaSel = 3;
+ break;
+ default:
+ DBGPRINT_ERR(("%s -- Impossible! : return FALSE; \n", __FUNCTION__));
+ return FALSE;
+ }
+ break;/* case BBP_R3 */
+
+ default:
+ DBGPRINT_ERR(("%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_ERR(("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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
+
+ pATEInfo->bQAEnabled = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE,("pATEInfo->bQAEnabled = %s\n", (pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ INT32 ret;
+
+ DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
+
+ pATEInfo->bQAEnabled = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE,("pATEInfo->bQAEnabled = %s\n", (pATEInfo->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(pATEInfo->AtePid))
+ {
+ /*
+ This command came from QA.
+ Get the pid of ATE agent.
+ */
+ memcpy((UCHAR *)&pATEInfo->AtePid,
+ (&pRaCfg->data[0]) - 2/* == sizeof(pRaCfg->status) */,
+ sizeof(pATEInfo->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. */
+#ifdef LINUX
+ ret = RTMP_THREAD_PID_KILL(pATEInfo->AtePid);
+ if (ret)
+ DBGPRINT_ERR(("%s : unable to kill ate thread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)));
+#endif /* LINUX */
+ }
+
+
+ /* AP/STA may be already 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);
+ 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);
+
+ offset &= 0x0000FFFF;
+ memcpy(&len, pRaCfg->data+2, 2);
+ len = OS_NTOHS(len);
+
+ if (len > 371)
+ {
+ DBGPRINT_ERR(("%s : length requested is too large, make it smaller\n", __FUNCTION__));
+ pRaCfg->length = OS_HTONS(2);
+ pRaCfg->status = OS_HTONS(1);
+
+ return -EFAULT;
+ }
+
+ RTMP_IO_READ_BULK(pAd, pRaCfg->data, offset, (len << 2));/* unit in four bytes*/
+
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status)+(len << 2), 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);
+
+ ATE_BBPRead(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);
+ ATE_BBPWrite(pAd, offset, value);
+
+ if ((offset == BBP_R1) || (offset == BBP_R3))
+ {
+ SyncTxRxConfig(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;
+ ATE_BBPRead(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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ memcpy_exl(pAd, &pRaCfg->data[0], (UCHAR *)&pATEInfo->U2M, 4);
+ memcpy_exl(pAd, &pRaCfg->data[4], (UCHAR *)&pATEInfo->OtherData, 4);
+ memcpy_exl(pAd, &pRaCfg->data[8], (UCHAR *)&pATEInfo->Beacon, 4);
+ memcpy_exl(pAd, &pRaCfg->data[12], (UCHAR *)&pATEInfo->OtherCount, 4);
+ memcpy_exl(pAd, &pRaCfg->data[16], (UCHAR *)&pATEInfo->TxAc0, 4);
+ memcpy_exl(pAd, &pRaCfg->data[20], (UCHAR *)&pATEInfo->TxAc1, 4);
+ memcpy_exl(pAd, &pRaCfg->data[24], (UCHAR *)&pATEInfo->TxAc2, 4);
+ memcpy_exl(pAd, &pRaCfg->data[28], (UCHAR *)&pATEInfo->TxAc3, 4);
+ memcpy_exl(pAd, &pRaCfg->data[32], (UCHAR *)&pATEInfo->TxHCCA, 4);
+ memcpy_exl(pAd, &pRaCfg->data[36], (UCHAR *)&pATEInfo->TxMgmt, 4);
+ memcpy_exl(pAd, &pRaCfg->data[40], (UCHAR *)&pATEInfo->RSSI0, 4);
+ memcpy_exl(pAd, &pRaCfg->data[44], (UCHAR *)&pATEInfo->RSSI1, 4);
+ memcpy_exl(pAd, &pRaCfg->data[48], (UCHAR *)&pATEInfo->RSSI2, 4);
+ memcpy_exl(pAd, &pRaCfg->data[52], (UCHAR *)&pATEInfo->SNR0, 4);
+ memcpy_exl(pAd, &pRaCfg->data[56], (UCHAR *)&pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ pATEInfo->U2M = 0;
+ pATEInfo->OtherData = 0;
+ pATEInfo->Beacon = 0;
+ pATEInfo->OtherCount = 0;
+ pATEInfo->TxAc0 = 0;
+ pATEInfo->TxAc1 = 0;
+ pATEInfo->TxAc2 = 0;
+ pATEInfo->TxAc3 = 0;
+ pATEInfo->TxHCCA = 0;
+ pATEInfo->TxMgmt = 0;
+ pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ USHORT *p;
+ USHORT err = 1;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ UINT8 TxInfoSize = 4;
+
+ if ((pATEInfo->TxStatus != 0) && (pATEInfo->Mode & ATE_TXFRAME))
+ {
+ DBGPRINT_ERR(("%s : Ate Tx is already running,"
+ "to run next Tx, you must stop it first\n", __FUNCTION__));
+ err = 2;
+ goto tx_start_error;
+ }
+ else if ((pATEInfo->TxStatus != 0) && !(pATEInfo->Mode & ATE_TXFRAME))
+ {
+ int slot = 0;
+
+ while ((slot++ < 10) && (pATEInfo->TxStatus != 0))
+ {
+ RtmpOsMsDelay(5);
+ }
+
+ /* force it to stop */
+ pATEInfo->TxStatus = 0;
+ pATEInfo->TxDoneCount = 0;
+ pATEInfo->bQATxStart = FALSE;
+ }
+
+ /*
+ Reset ATE mode and set Tx/Rx idle
+ for new proposed TXCONT/TXCARR/TXCARRSUPP solution.
+ */
+ if ((pATEInfo->Mode & ATE_TXFRAME) && (pATEInfo->TxMethod == TX_METHOD_1))
+ {
+ TXSTOP(pAd);
+ }
+
+ /*
+ If pRaCfg->length == 0, this "RACFG_CMD_TX_START"
+ is for Carrier test or Carrier Suppression test.
+ */
+ if (OS_NTOHS(pRaCfg->length) != 0)
+ {
+ /* get frame info */
+#ifdef RTMP_MAC_USB
+ NdisMoveMemory(&pATEInfo->TxInfo, pRaCfg->data - 2, TxInfoSize);
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR) &pATEInfo->TxInfo, TYPE_TXINFO);
+#endif /* RT_BIG_ENDIAN */
+#endif /* RTMP_MAC_USB */
+
+ NdisMoveMemory(&pATEInfo->TxWI, pRaCfg->data + 2, TXWISize);
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pAd, (PUCHAR)&pATEInfo->TxWI, TYPE_TXWI);
+#endif /* RT_BIG_ENDIAN */
+
+ NdisMoveMemory(&pATEInfo->TxCount, pRaCfg->data + TXWISize + 2, 4);
+ pATEInfo->TxCount = OS_NTOHL(pATEInfo->TxCount);
+
+/* p = (USHORT *)(&pRaCfg->data[TXWISize + TxInfoSize + 2]); */
+
+ /* always use QID_AC_BE */
+ pATEInfo->QID = 0;
+
+ p = (USHORT *)(&pRaCfg->data[TXWISize + TxInfoSize + 2*2]);
+ pATEInfo->HLen = OS_NTOHS(*p);
+
+ if (pATEInfo->HLen > 32)
+ {
+ DBGPRINT_ERR(("%s : pATEInfo->HLen > 32\n", __FUNCTION__));
+ DBGPRINT_ERR(("pATEInfo->HLen = %d\n", pATEInfo->HLen));
+ err = 3;
+ goto tx_start_error;
+ }
+
+ NdisMoveMemory(&pATEInfo->Header, pRaCfg->data + (TXWISize + TxInfoSize + 2*3), pATEInfo->HLen);
+
+ pATEInfo->PLen = OS_NTOHS(pRaCfg->length) - (pATEInfo->HLen + (TXWISize + TxInfoSize + 2*4));
+
+ if (pATEInfo->PLen > 32)
+ {
+ DBGPRINT_ERR(("%s : pATEInfo->PLen > 32\n", __FUNCTION__));
+ err = 4;
+ goto tx_start_error;
+ }
+
+ NdisMoveMemory(&pATEInfo->Pattern, pRaCfg->data + (TXWISize + TxInfoSize + 2*3) + pATEInfo->HLen, pATEInfo->PLen);
+ pATEInfo->DLen = pATEInfo->TxWI.TxWIMPDUByteCnt - pATEInfo->HLen;
+
+
+ }
+
+ ReadQATxTypeFromBBP(pAd);
+
+ if (pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ UINT32 count=0;
+
+ count = OS_HTONL(pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+ pATEInfo->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;
+}
+
+
+#ifdef 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_FREQ_OFFSET_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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
+
+ memcpy_exl(pAd, &pRaCfg->data[0], (UCHAR *)&pATEInfo->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 (pATEInfo->RxAntennaSel == 0)
+ {
+ INT32 RSSI0 = 0;
+ INT32 RSSI1 = 0;
+ INT32 RSSI2 = 0;
+
+ RSSI0 = (INT32)(pATEInfo->LastRssi0 - pAd->BbpRssiToDbmDelta);
+ RSSI1 = (INT32)(pATEInfo->LastRssi1 - pAd->BbpRssiToDbmDelta);
+ RSSI2 = (INT32)(pATEInfo->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)(pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ 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);
+
+ pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
+ memcpy(pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
+ memcpy(pATEInfo->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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ DBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
+ memcpy(pATEInfo->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_ERR(("%s : exceed EEPROM size\n", __FUNCTION__));
+
+ 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_ERR(("%s : exceed EEPROM size(%d)\n", __FUNCTION__, EEPROM_SIZE));
+ DBGPRINT_ERR(("offset=%d\n", offset));
+ DBGPRINT_ERR(("length=%d\n", len));
+ DBGPRINT_ERR(("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, pos, value;
+ USHORT len;
+
+ memcpy(&offset, &pRaCfg->status, 4);
+ offset = OS_NTOHL(offset);
+ memcpy(&len, pRaCfg->data+2, 2);
+ len = OS_NTOHS(len);
+
+ for (pos = 0; pos < len; pos += 4)
+ {
+ memcpy_exl(pAd, (UCHAR *)&value, pRaCfg->data+4+pos, 4);
+ DBGPRINT(RT_DEBUG_TRACE,("Write %x %x\n", offset + pos, value));
+ RTMP_IO_WRITE32(pAd, ((offset+pos) & (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 pos;
+
+ offset = OS_NTOHS(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = OS_NTOHS(len);
+
+ for (pos = offset; pos < (offset+len); pos++)
+ {
+ pRaCfg->data[pos - offset] = 0;
+
+ ATE_BBPRead(pAd, pos, &pRaCfg->data[pos - 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 pos;
+ UCHAR *value;
+
+ offset = OS_NTOHS(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = OS_NTOHS(len);
+
+ for (pos = offset; pos < (offset+len); pos++)
+ {
+ value = pRaCfg->data + 2 + (pos - offset);
+ ATE_BBPWrite(pAd, pos, *value);
+ }
+
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+
+
+
+
+
+
+#ifdef TXBF_SUPPORT
+static INT DO_RACFG_CMD_ATE_TXBF_DUT_INIT(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN struct ate_racfghdr *pRaCfg)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("DO_RACFG_CMD_ATE_TXBF_DUT_INIT\n"));
+
+ Set_ATE_TXBF_INIT_Proc(pAd, "1");
+
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static INT DO_RACFG_CMD_ATE_TXBF_LNA_CAL(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN struct ate_racfghdr *pRaCfg)
+{
+ USHORT band;
+ CHAR bandStr[32] = {0};
+
+ DBGPRINT(RT_DEBUG_TRACE,("DO_RACFG_CMD_ATE_TXBF_LNA_CAL\n"));
+
+ band = OS_NTOHS(pRaCfg->status);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : band=0x%x(0x%x)\n",
+ __FUNCTION__, band, pRaCfg->status));
+ snprintf(bandStr, sizeof(bandStr), "%d\n", band);
+ Set_ATE_TXBF_LNACAL_Proc(pAd, &bandStr[0]);
+
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static INT DO_RACFG_CMD_ATE_TXBF_DIV_CAL(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN struct ate_racfghdr *pRaCfg)
+{
+ USHORT band;
+ CHAR bandStr[32] = {0};
+
+ DBGPRINT(RT_DEBUG_TRACE,("DO_RACFG_CMD_ATE_TXBF_DIV_CAL\n"));
+
+ band = OS_NTOHS(pRaCfg->status);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : band=0x%x(0x%x)\n",
+ __FUNCTION__, band, pRaCfg->status));
+ snprintf(bandStr, sizeof(bandStr), "%d\n", band);
+ Set_ATE_TXBF_DIVCAL_Proc(pAd, &bandStr[0]);
+
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static INT DO_RACFG_CMD_ATE_TXBF_PHASE_CAL(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN struct ate_racfghdr *pRaCfg)
+{
+ SHORT value = 0;
+ STRING str[LEN_OF_ARG];
+ BOOLEAN result = FALSE;
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ DBGPRINT(RT_DEBUG_TRACE,("DO_RACFG_CMD_ATE_TXBF_PHASE_CAL\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = OS_NTOHS(value);
+ snprintf((char *)str, sizeof(str), "%d", value);
+
+ result = (BOOLEAN)Set_ATE_TXBF_CAL_Proc(pAd, str);
+ pRaCfg->data[0] = result;
+
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status) + 1, NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static INT DO_RACFG_CMD_ATE_TXBF_GOLDEN_INIT(
+ 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,("DO_RACFG_CMD_ATE_TXBF_GOLDEN_INIT\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = OS_NTOHS(value);
+ snprintf((char *)str, sizeof(str), "%d", value);
+
+ Set_ATE_TXBF_GOLDEN_Proc(pAd, str);
+
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static INT DO_RACFG_CMD_ATE_TXBF_VERIFY(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN struct ate_racfghdr *pRaCfg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ SHORT value = 0;
+ STRING str[LEN_OF_ARG];
+ BOOLEAN result;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DO_RACFG_CMD_ATE_TXBF_VERIFY\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = OS_NTOHS(value);
+ snprintf((char *)str, sizeof(str), "%d", value);
+
+ result = (BOOLEAN)Set_ATE_TXBF_VERIFY_Proc(pAd, str);
+
+ pRaCfg->data[0] = result;
+ pRaCfg->data[1] = pATEInfo->calParams[0];
+ pRaCfg->data[2] = pATEInfo->calParams[1];
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status) + 3, NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static INT DO_RACFG_CMD_ATE_TXBF_VERIFY_NOCOMP(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN struct ate_racfghdr *pRaCfg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ SHORT value = 0;
+ STRING str[LEN_OF_ARG];
+ BOOLEAN result;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DO_RACFG_CMD_ATE_TXBF_VERIFY_NOCOMP\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = OS_NTOHS(value);
+ snprintf((char *)str, sizeof(str), "%d", value);
+
+ result = (BOOLEAN)Set_ATE_TXBF_VERIFY_NoComp_Proc(pAd, str);
+
+ pRaCfg->data[0] = result;
+ pRaCfg->data[1] = pATEInfo->calParams[0];
+ pRaCfg->data[2] = pATEInfo->calParams[1];
+ ResponseToGUI(pRaCfg, wrq, sizeof(pRaCfg->status) + 3, NDIS_STATUS_SUCCESS);
+
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* TXBF_SUPPORT */
+
+
+static INT32 DO_RACFG_CMD_ATE_SHOW_PARAM(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN struct ate_racfghdr *pRaCfg)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ INT32 Status = NDIS_STATUS_SUCCESS;
+ UINT32 Len;
+ ATE_EX_PARAM ATEExParam;
+
+ 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_AP_SUPPORT
+ NdisMoveMemory(ATEExParam.DA, pATEInfo->Addr1, MAC_ADDR_LEN);
+ NdisMoveMemory(ATEExParam.SA, pATEInfo->Addr3, MAC_ADDR_LEN);
+ NdisMoveMemory(ATEExParam.BSSID, pATEInfo->Addr2, MAC_ADDR_LEN);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ ATEExParam.MCS = pATEInfo->TxWI.TxWIMCS;
+ ATEExParam.PhyMode = pATEInfo->TxWI.TxWIPHYMODE;
+ ATEExParam.ShortGI = pATEInfo->TxWI.TxWIShortGI;
+ ATEExParam.BW = pATEInfo->TxWI.TxWIBW;
+ 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,/* 0x0080 */
+ DO_RACFG_CMD_ATE_STOP/* 0x0081 */
+ /* cmd id end with 0x81 */
+};
+
+
+static RACFG_CMD_HANDLER RACFG_CMD_SET3[] =
+{
+ /* cmd id start from 0x100 */
+ DO_RACFG_CMD_ATE_START_TX_CARRIER,/* 0x0100 */
+ DO_RACFG_CMD_ATE_START_TX_CONT,/* 0x0101 */
+ DO_RACFG_CMD_ATE_START_TX_FRAME,/* 0x0102 */
+ DO_RACFG_CMD_ATE_SET_BW,/* 0x0103 */
+ DO_RACFG_CMD_ATE_SET_TX_POWER0,/* 0x0104 */
+ DO_RACFG_CMD_ATE_SET_TX_POWER1,/* 0x0105 */
+ DO_RACFG_CMD_ATE_SET_FREQ_OFFSET,/* 0x0106 */
+ DO_RACFG_CMD_ATE_GET_STATISTICS,/* 0x0107 */
+ DO_RACFG_CMD_ATE_RESET_COUNTER,/* 0x0108 */
+ DO_RACFG_CMD_ATE_SEL_TX_ANTENNA,/* 0x0109 */
+ DO_RACFG_CMD_ATE_SEL_RX_ANTENNA,/* 0x010a */
+ DO_RACFG_CMD_ATE_SET_PREAMBLE,/* 0x010b */
+ DO_RACFG_CMD_ATE_SET_CHANNEL,/* 0x010c */
+ DO_RACFG_CMD_ATE_SET_ADDR1,/* 0x010d */
+ DO_RACFG_CMD_ATE_SET_ADDR2,/* 0x010e */
+ DO_RACFG_CMD_ATE_SET_ADDR3,/* 0x010f */
+ DO_RACFG_CMD_ATE_SET_RATE,/* 0x0110 */
+ DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN,/* 0x0111 */
+ DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT,/* 0x0112 */
+ DO_RACFG_CMD_ATE_START_RX_FRAME,/* 0x0113 */
+ DO_RACFG_CMD_ATE_E2PROM_READ_BULK,/* 0x0114 */
+ DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK,/* 0x0115 */
+ DO_RACFG_CMD_ATE_IO_WRITE_BULK,/* 0x0116 */
+ DO_RACFG_CMD_ATE_BBP_READ_BULK,/* 0x0117 */
+ DO_RACFG_CMD_ATE_BBP_WRITE_BULK,/* 0x0118 */
+ NULL,/* 0x0119 */
+ NULL,/* 0x011a */
+#ifdef DOT11N_SS3_SUPPORT
+ DO_RACFG_CMD_ATE_SET_TX_POWER2,/* 0x011b */
+#else
+ NULL,/* 0x011b */
+#endif /* DOT11N_SS3_SUPPORT */
+#ifdef TXBF_SUPPORT
+ DO_RACFG_CMD_ATE_TXBF_DUT_INIT,/* 0x011c */
+ DO_RACFG_CMD_ATE_TXBF_LNA_CAL,/* 0x011d */
+ DO_RACFG_CMD_ATE_TXBF_DIV_CAL,/* 0x011e */
+ DO_RACFG_CMD_ATE_TXBF_PHASE_CAL,/* 0x011f */
+ DO_RACFG_CMD_ATE_TXBF_GOLDEN_INIT,/* 0x0120 */
+ DO_RACFG_CMD_ATE_TXBF_VERIFY,/* 0x0121 */
+ DO_RACFG_CMD_ATE_TXBF_VERIFY_NOCOMP/* 0x0122 */
+#else
+ NULL,/* 0x011c */
+ NULL,/* 0x011d */
+ NULL,/* 0x011e */
+ NULL,/* 0x011f */
+ NULL,/* 0x0120 */
+ NULL,/* 0x0121 */
+ NULL/* 0x0122 */
+#endif /* TXBF_SUPPORT */
+ /* cmd id end with 0x122 */
+};
+
+
+static RACFG_CMD_HANDLER RACFG_CMD_SET4[] =
+{
+ /* cmd id start from 0x200 */
+ NULL,/* 0x0200 */
+ NULL,/* 0x0201 */
+ NULL/* 0x0202 */
+ /* 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)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+ 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 (pATEInfo->PassiveMode)
+ {
+ int entry, 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 (entry=0; entry<sizeof(allowedCmds)/sizeof(allowedCmds[0]); entry++)
+ {
+ if (Command_Id==allowedCmds[entry])
+ {
+ allowCmd = TRUE;
+ break;
+ }
+ }
+
+ /* Also allow writes to BF profile registers */
+ if (Command_Id==RACFG_CMD_BBP_WRITE8)
+ {
+ int offset = OS_NTOHS(pRaCfg->status);
+ 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_ERR(("Unknown magic number of RACFG command = %x\n", ATEMagicNum));
+ break;
+ }
+
+ ERROR1:
+ os_free_mem(NULL, pRaCfg);
+ ERROR0:
+ return Status;
+}
+
+
+VOID ATE_QA_Statistics(
+ IN RTMP_ADAPTER *pAd,
+ IN RXWI_STRUC *pRxWI,
+ IN RXINFO_STRUC *pRxInfo,
+ IN PHEADER_802_11 pHeader)
+{
+ PATE_INFO pATEInfo = &(pAd->ate);
+
+ /* update counter first */
+ if (pHeader != NULL)
+ {
+ if (pHeader->FC.Type == BTYPE_DATA)
+ {
+ if (pRxInfo->U2M)
+ {
+ pATEInfo->U2M++;
+ }
+ else
+ pATEInfo->OtherData++;
+ }
+ else if (pHeader->FC.Type == BTYPE_MGMT)
+ {
+ if (pHeader->FC.SubType == SUBTYPE_BEACON)
+ pATEInfo->Beacon++;
+ else
+ pATEInfo->OtherCount++;
+ }
+ else if (pHeader->FC.Type == BTYPE_CNTL)
+ {
+ pATEInfo->OtherCount++;
+ }
+ }
+ pATEInfo->RSSI0 = pRxWI->RxWIRSSI0;
+ pATEInfo->RSSI1 = pRxWI->RxWIRSSI1;
+ pATEInfo->RSSI2 = pRxWI->RxWIRSSI2;
+ pATEInfo->SNR0 = pRxWI->RxWISNR0;
+ pATEInfo->SNR1 = pRxWI->RxWISNR1;
+
+
+}
+
+
+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 offset;
+
+ rt_ee_read_all(pAd, (USHORT *)buffer);
+ p = buffer;
+
+ for (offset = 0; offset < (EEPROM_SIZE >> 1); offset++)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%4.4x ", *p));
+ if (((offset+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_ERR(("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);
+
+ ATE_BBPRead(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);
+ }
+
+ ATE_BBPWrite(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 */
+
diff --git a/cleopatre/devkit/mt7601udrv/ate/include/rt_ate.h b/cleopatre/devkit/mt7601udrv/ate/include/rt_ate.h
new file mode 100644
index 0000000000..06e87392bf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ate/include/rt_ate.h
@@ -0,0 +1,808 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_ate.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifndef __RT_ATE_H__
+#define __RT_ATE_H__
+
+typedef struct _ATE_CHIP_STRUCT {
+ /* functions */
+ VOID (*ChannelSwitch)(PRTMP_ADAPTER pAd);
+ INT (*TxPwrHandler)(PRTMP_ADAPTER pAd, char index);
+ INT (*TssiCalibration)(PRTMP_ADAPTER pAd, PSTRING arg);
+ INT (*ExtendedTssiCalibration)(PRTMP_ADAPTER pAd, PSTRING arg);
+ VOID (*RxVGAInit)(PRTMP_ADAPTER pAd);
+ VOID (*AsicSetTxRxPath)(PRTMP_ADAPTER pAd);
+ VOID (*AdjustTxPower)(PRTMP_ADAPTER pAd);
+ VOID (*AsicExtraPowerOverMAC)(PRTMP_ADAPTER pAd);
+ VOID (*TemperCompensation)(PRTMP_ADAPTER *pAd);
+
+ /* command handlers */
+ INT (*Set_BW_Proc)(PRTMP_ADAPTER pAd, PSTRING arg);
+ INT (*Set_FREQ_OFFSET_Proc)(PRTMP_ADAPTER pAd, PSTRING arg);
+
+ /* variables */
+ INT maxTxPwrCnt;
+ BOOLEAN bBBPStoreTXCARR;
+ BOOLEAN bBBPStoreTXCARRSUPP;
+ BOOLEAN bBBPStoreTXCONT;
+ BOOLEAN bBBPLoadATESTOP;
+
+}ATE_CHIP_STRUCT, *PATE_CHIP_STRUCT;
+
+typedef union _CAPTURE_MODE_SHARE_MEMORY {
+ struct
+ {
+ UINT32 LOW_BYTE0:8;
+ UINT32 LOW_BYTE1:8;
+ UINT32 HIGH_BYTE0:8;
+ UINT32 HIGH_BYTE1:8;
+ } field;
+ UINT32 Value;
+}CAPTURE_MODE_SHARE_MEMORY, *PCAPTURE_MODE_SHARE_MEMORY;
+
+typedef struct _ATE_INFO {
+ PATE_CHIP_STRUCT pChipStruct;
+ UCHAR Mode;
+ BOOLEAN PassiveMode;
+#ifdef RT3350
+ UCHAR PABias;
+#endif /* RT3350 */
+ CHAR TxPower0;
+ CHAR TxPower1;
+#ifdef DOT11N_SS3_SUPPORT
+ CHAR TxPower2;
+#endif /* DOT11N_SS3_SUPPORT */
+ CHAR MinTxPowerBandA; /* Power range of early chipsets is -7~15 in A band */
+ CHAR MaxTxPowerBandA; /* Power range of early chipsets is -7~15 in A band */
+ 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 */
+ UCHAR TxMethod; /* Early chipsets must be applied old TXCONT/TXCARR/TXCARS mechanism. */
+ 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 RTMP_INTERNAL_TX_ALC
+#if defined(RT3350) || defined(RT3352)
+ BOOLEAN bTSSICalbrEnableG; /* Enable TSSI calibration */
+ CHAR TssiRefPerChannel[CFG80211_NUM_OF_CHAN_2GHZ];
+ CHAR TssiDeltaPerChannel[CFG80211_NUM_OF_CHAN_2GHZ];
+#endif /* defined(RT3350) || defined(RT3352) */
+#endif /* RTMP_INTERNAL_TX_ALC */
+#ifdef TXBF_SUPPORT
+ BOOLEAN bTxBF; /* Enable Tx Bean Forming */
+ SHORT txSoundingMode; /* Sounding mode for non-QA ATE. 0=none, 1=Data Sounding, 2=NDP */
+ UCHAR calParams[2];
+#endif /* TXBF_SUPPORT */
+ UINT32 RxTotalCnt;
+ UINT32 RxCntPerSec;
+ UCHAR forceBBPReg; /* force to not update the specific BBP register, now used for ATE TxBF */
+
+ 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;
+ USHORT HLen; /* Header Length */
+
+#ifdef RALINK_QA
+ /* Tx frame */
+#ifdef RTMP_MAC_USB
+ TXINFO_STRUC TxInfo; /* TxInfo */
+#endif /* RTMP_MAC_USB */
+ 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;
+#endif /* DOT11N_SS3_SUPPORT */
+ INT32 BF_SNR[3]; /* Last RXWI BF SNR. Units=0.25 dB */
+ /* TxStatus : 0 --> task is idle, 1 --> task is running */
+ UCHAR TxStatus;
+#endif /* RALINK_QA */
+#ifdef TXBF_SUPPORT
+#define MAX_SOUNDING_RESPONSE_SIZE (57*2*2*9+3+2+6) /* Assume 114 carriers (40MHz), 3x3, 8bits/coeff, + SNR + HT HEADER + MIMO CONTROL FIELD */
+ UCHAR sounding;
+ UINT32 sounding_jiffies;
+ CHAR soundingSNR[3];
+ UINT32 LastRxRate;
+ UINT32 LastTxRate;
+ UINT32 soundingRespSize; /* Size of Sounding response */
+ UCHAR soundingResp[MAX_SOUNDING_RESPONSE_SIZE]; /* Entire Sounding response */
+#endif /* TXBF_SUPPORT */
+ RALINK_TIMER_STRUCT PeriodicTimer;
+ ULONG OneSecPeriodicRound;
+} ATE_INFO, *PATE_INFO;
+
+/*
+ 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 Frames (without time gap) */
+#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 RTMP_INTERNAL_TX_ALC
+#define EEPROM_TSSI_ENABLE 0x36
+#define EEPROM_TSSI_MODE_EXTEND 0x76
+
+#define ATE_MDSM_NORMAL_TX_POWER 0x00
+#define ATE_MDSM_DROP_TX_POWER_BY_6dBm 0x01
+#define ATE_MDSM_DROP_TX_POWER_BY_12dBm 0x02
+#define ATE_MDSM_ADD_TX_POWER_BY_6dBm 0x03
+#define ATE_MDSM_BBP_R1_STATIC_TX_POWER_CONTROL_MASK 0x03
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+#define LEN_OF_ARG 16
+#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP)
+#define TX_METHOD_0 0 /* Early chipsets must be applied this original TXCONT/TXCARR/TXCARS mechanism. */
+#define TX_METHOD_1 1 /* Default TXCONT/TXCARR/TXCARS mechanism is TX_METHOD_1 */
+
+#define ATE_MAC_TX_ENABLE(_A, _I, _pV) \
+{ \
+ RTMP_IO_READ32(_A, _I, _pV); \
+ (*(_pV)) |= (1 << 2); \
+ RTMP_IO_WRITE32(_A, _I, (*(_pV))); \
+}
+
+#define ATE_MAC_TX_DISABLE(_A, _I, _pV) \
+{ \
+ RTMP_IO_READ32(_A, _I, _pV); \
+ (*(_pV)) &= ~(1 << 2); \
+ RTMP_IO_WRITE32(_A, _I, (*(_pV))); \
+}
+
+#define ATE_MAC_RX_ENABLE(_A, _I, _pV) \
+{ \
+ RTMP_IO_READ32(_A, _I, _pV); \
+ (*(_pV)) |= (1 << 3); \
+ RTMP_IO_WRITE32(_A, _I, (*(_pV))); \
+}
+
+#define ATE_MAC_RX_DISABLE(_A, _I, _pV) \
+{ \
+ RTMP_IO_READ32(_A, _I, _pV); \
+ (*(_pV)) &= ~(1 << 3); \
+ RTMP_IO_WRITE32(_A, _I, (*(_pV))); \
+}
+
+/* Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1. */
+#define ATE_MAC_TX_CTS_ENABLE(_A, _I, _pV) \
+{ \
+ RTMP_IO_READ32(_A, _I, _pV); \
+ (*(_pV)) |= (1 << 4); \
+ RTMP_IO_WRITE32(_A, _I, (*(_pV))); \
+}
+
+/* Clear MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 0. */
+#define ATE_MAC_TX_CTS_DISABLE(_A, _I, _pV) \
+{ \
+ RTMP_IO_READ32(_A, _I, _pV); \
+ (*(_pV)) &= ~(1 << 4); \
+ RTMP_IO_WRITE32(_A, _I, (*(_pV))); \
+}
+
+/* Clear BBP R22 to reset Tx Mode (bit7~bit0) = 0. */
+#define ATE_BBP_RESET_TX_MODE(_A, _I, _pV) \
+{ \
+ ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV); \
+ (*(_pV)) &= (0x00); \
+ ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, (*(_pV))); \
+}
+
+/* Set BBP R22 to start Continuous Tx Mode (bit7) = 1. */
+#define ATE_BBP_START_CTS_TX_MODE(_A, _I, _pV) \
+{ \
+ ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV); \
+ (*(_pV)) |= (1 << 7); \
+ ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, (*(_pV))); \
+}
+
+/* Clear BBP R22 to stop Continuous Tx Mode (bit7) = 0. */
+#define ATE_BBP_STOP_CTS_TX_MODE(_A, _I, _pV) \
+{ \
+ ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV); \
+ (*(_pV)) &= ~(1 << 7); \
+ ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, (*(_pV))); \
+}
+
+/* Set BBP R24 to send out Continuous Tx sin wave (bit0) = 1. */
+#define ATE_BBP_CTS_TX_SIN_WAVE_ENABLE(_A, _I, _pV) \
+{ \
+ ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV); \
+ (*(_pV)) |= (1 << 0); \
+ ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, (*(_pV))); \
+}
+
+/* Clear BBP R24 to stop Continuous Tx sin wave (bit0) = 0. */
+#define ATE_BBP_CTS_TX_SIN_WAVE_DISABLE(_A, _I, _pV) \
+{ \
+ ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV); \
+ (*(_pV)) &= ~(1 << 0); \
+ ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, (*(_pV))); \
+}
+
+/*
+==========================================================================
+ Description:
+ This routine sets initial value of VGA in the RX chain.
+ AGC is the abbreviation of "Automatic Gain Controller",
+ while VGA (Variable Gain Amplifier) is a part of AGC loop.
+ (i.e., VGA + level detector + feedback loop = AGC)
+
+ Return:
+ VOID
+==========================================================================
+*/
+#define ATE_CHIP_RX_VGA_GAIN_INIT(__pAd) \
+ if (__pAd->ate.pChipStruct->RxVGAInit != NULL) \
+ __pAd->ate.pChipStruct->RxVGAInit(__pAd)
+
+#define ATE_CHIP_SET_TX_RX_PATH(__pAd) \
+ if (__pAd->ate.pChipStruct->AsicSetTxRxPath != NULL) \
+ __pAd->ate.pChipStruct->AsicSetTxRxPath(__pAd)
+
+
+
+#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 */
+
+INT DefaultATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index);
+
+
+
+
+
+#if defined(RT28xx) || defined(RT2880)
+VOID RT28xxATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd);
+
+INT RT28xxATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index);
+#endif /* defined(RT28xx) || defined(RT2880) */
+
+
+#ifdef RALINK_QA
+VOID ATE_QA_Statistics(
+ IN RTMP_ADAPTER *pAd,
+ IN RXWI_STRUC *pRxWI,
+ IN RXINFO_STRUC *pRxInfo,
+ IN PHEADER_802_11 pHeader);
+
+INT RtmpDoAte(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN PSTRING wrq_name);
+
+INT Set_TxStop_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_RxStop_Proc(
+ IN RTMP_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 RALINK_QA
+#define SYNC_CHANNEL_WITH_QA(_A, _pV)\
+ if ((_A->bQATxStart == TRUE) || (_A->bQARxStart == TRUE))\
+ {\
+ return;\
+ }\
+ else\
+ *_pV = _A->Channel
+#else
+#define SYNC_CHANNEL_WITH_QA(_A, _pV)\
+ *_pV = _A->Channel
+#endif /* RALINK_QA */
+
+VOID rt_ee_read_all(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Data);
+
+VOID rt_ee_write_all(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT *Data);
+
+VOID rt_ee_write_bulk(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT *Data,
+ IN USHORT offset,
+ IN USHORT length);
+
+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);
+
+INT Set_ATE_INIT_CHAN_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ADCDump_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);
+
+
+#if defined(RT3350) || defined(RT3352)
+INT RT335x_Set_ATE_TSSI_CALIBRATION_ENABLE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+CHAR InsertTssi(
+ IN UCHAR InChannel,
+ IN UCHAR Channel0,
+ IN UCHAR Channel1,
+ IN CHAR Tssi0,
+ IN CHAR Tssi1);
+
+INT RT335xATETssiCalibrationExtend(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+#endif /* defined(RT3350) || defined(RT3352) */
+
+CHAR ATEGetDesiredTSSI(
+ IN PRTMP_ADAPTER pAd);
+
+#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 */
+
+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);
+
+VOID DefaultATEAsicExtraPowerOverMAC(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ATEAsicExtraPowerOverMAC(
+ IN PRTMP_ADAPTER pAd);
+#ifdef RT3350
+INT Set_ATE_PA_Bias_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* RT3350 */
+
+INT Default_Set_ATE_TX_FREQ_OFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+
+
+
+#if defined(RT28xx) || defined(RT2880)
+INT RT28xx_Set_ATE_TX_FREQ_OFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* defined(RT28xx) || defined(RT2880) */
+
+
+INT Set_ATE_TX_FREQ_OFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Default_Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+
+
+
+#if defined(RT28xx) || defined(RT2880)
+INT RT28xx_Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* defined(RT28xx) || defined(RT2880) */
+
+
+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);
+
+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);
+
+INT Set_ATE_Load_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef RTMP_EFUSE_SUPPORT
+INT Set_ATE_Load_E2P_From_Buf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_Cal_Free_Info_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* RTMP_EFUSE_SUPPORT */
+
+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_TXBF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXSOUNDING_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXBF_DIVCAL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXBF_LNACAL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXBF_INIT_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXBF_CAL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXBF_GOLDEN_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXBF_VERIFY_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_TXBF_VERIFY_NoComp_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_ForceBBP_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 DefaultATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd);
+
+
+#ifdef MT7601
+INT Set_ATE_Read_Temperature_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ATE_Read_TSSI_DC_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* MT7601 */
+
+VOID ATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ATESampleRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN RXWI_STRUC *pRxWI);
+
+
+#ifdef RTMP_MAC_USB
+INT TxDmaBusy(
+ IN PRTMP_ADAPTER pAd);
+
+INT RxDmaBusy(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RtmpDmaEnable(
+ IN PRTMP_ADAPTER pAd,
+ IN INT Enable);
+
+INT ATESetUpFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TxIdx);
+
+VOID RTUSBRejectPendingPackets(
+ IN PRTMP_ADAPTER pAd);
+#endif /* RTMP_MAC_USB */
+
+
+NDIS_STATUS ChipStructAssign(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS ATEInit(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef RALINK_QA
+VOID ReadQATxTypeFromBBP(
+ IN PRTMP_ADAPTER pAd);
+#endif /* RALINK_QA */
+
+NDIS_STATUS ATEBBPWriteWithRxChain(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR bbpId,
+ IN CHAR bbpVal,
+ IN RX_CHAIN_IDX rx_ch_idx);
+
+
+
+
+
+
+#if defined(RT28xx) || defined(RT2880)
+VOID RT28xxATERxVGAInit(
+ IN PRTMP_ADAPTER pAd);
+#endif /* defined(RT28xx) || defined(RT2880) */
+
+
+VOID ATEPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID ATEAsicSetTxRxPath(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RtmpRfIoWrite(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd);
+
+VOID BbpSoftReset(
+ IN PRTMP_ADAPTER pAd);
+
+#endif /* __RT_ATE_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/ate/include/rt_qa.h b/cleopatre/devkit/mt7601udrv/ate/include/rt_qa.h
new file mode 100644
index 0000000000..801bcbae7f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/ate/include/rt_qa.h
@@ -0,0 +1,181 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_qa.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifndef __RT_QA_H__
+#define __RT_QA_H__
+
+#ifdef RALINK_QA
+#ifndef RALINK_ATE
+#error "For supporting QA GUI, please set HAS_ATE=y and HAS_QA_SUPPORT=y."
+#endif /* RALINK_ATE */
+
+#include "rt_ate.h"
+
+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;
+
+/* Stop Transmission */
+#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 -- */
+
+/* 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
+#ifdef TXBF_SUPPORT
+#define RACFG_CMD_ATE_TXBF_DUT_INIT 0x011c
+#define RACFG_CMD_ATE_TXBF_LNA_CAL 0x011d
+#define RACFG_CMD_ATE_TXBF_DIV_CAL 0x011e
+#define RACFG_CMD_ATE_TXBF_PHASE_CAL 0x011f
+#define RACFG_CMD_ATE_TXBF_GOLDEN_INIT 0x0120
+#define RACFG_CMD_ATE_TXBF_VERIFY 0x0121
+#endif /* TXBF_SUPPORT */
+
+
+/* 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;
+
+NDIS_STATUS TXSTOP(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS RXSTOP(
+ IN PRTMP_ADAPTER pAd);
+
+#endif /* RALINK_QA */
+
+#endif /* __RT_QA_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/chips/mt7601.c b/cleopatre/devkit/mt7601udrv/chips/mt7601.c
new file mode 100644
index 0000000000..259ef2ef03
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/chips/mt7601.c
@@ -0,0 +1,3382 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ mt7601.c
+
+ Abstract:
+ Specific funcitons and configurations for MT7601 (RT63xx)
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifdef MT7601
+
+#include "rt_config.h"
+
+#include "mcu/MT7601_firmware.h"
+
+//#define MT7601FPGA
+
+#ifdef RTMP_EFUSE_SUPPORT
+/* MT7601_USB_V0_C-20130107 */
+UCHAR MT7601_EFUSE_DEFAULT_BIN[] = {
+ 0x01, 0x76, 0x00, 0x0c, 0x00, 0x0c, 0x43, 0x26, 0x60, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x01, 0x02, 0x8f, 0x14, 0x01, 0x76, 0x00, 0x00, 0x4a, 0x00, 0x01, 0x00, 0x80, 0x50, 0x08, 0x00,
+ 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x20, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x11, 0xff, 0x04, 0x28, 0xff, 0xff, 0x2c, 0x01, 0xff, 0xff, 0x99, 0x99,
+ 0x8c, 0x88, 0xff, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
+ 0x20, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05,
+ 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+#endif /* RTMP_EFUSE_SUPPORT */
+
+static RTMP_REG_PAIR MT7601_MACRegTable[] = {
+ //{TSO_CTRL, 0x16058}, // must set when enable HDR_TRANS_SUPPORT
+ {TSO_CTRL, 0x06050}, // must set when enable HDR_TRANS_SUPPORT
+ {BCN_OFFSET0, 0x18100800},
+ {BCN_OFFSET1, 0x38302820},
+ {PBF_SYS_CTRL, 0x80c00},
+ {PBF_CFG, 0x7F723c1f},
+ {FCE_CTRL, 0x1},
+ {0xA38, 0x0}, // For bi-direction RX fifo overflow issue.
+ {TX0_RF_GAIN_CORR, 0x003B0005}, // 20120806 Jason Huang
+ {TX0_RF_GAIN_ATTEN, 0x00006900}, // 20120806 Jason Huang
+ {TX0_BB_GAIN_ATTEN, 0x00000400}, // 20120806 Jason Huang
+ {TX_ALC_VGA3, 0x00060006}, // 20120806 Jason Huang
+ //{TX_SW_CFG0, 0x400}, // 20120822 Gary
+ {TX_SW_CFG0, 0x402}, // 20121017 Jason Huang
+ {TX_SW_CFG1, 0x0}, // 20120822 Gary
+ {TX_SW_CFG2, 0x0}, // 20120822 Gary
+
+#ifdef HDR_TRANS_SUPPORT
+ {HEADER_TRANS_CTRL_REG, 0x2},
+#else
+ {HEADER_TRANS_CTRL_REG, 0x0},
+#endif /* HDR_TRANS_SUPPORT */
+
+#ifdef CONFIG_RX_CSO_SUPPORT
+ {CHECKSUM_OFFLOAD, 0x30f},
+ {FCE_PARAM, 0x00256f0f},
+#else
+ {CHECKSUM_OFFLOAD, 0x200},
+ {FCE_PARAM, 0x00254f0f},
+#endif /* CONFIG_RX_CSO_SUPPORT */
+};
+static UCHAR MT7601_NUM_MAC_REG_PARMS = (sizeof(MT7601_MACRegTable) / sizeof(RTMP_REG_PAIR));
+
+
+//1019 BBP CR
+static RTMP_REG_PAIR MT7601_BBP_InitRegTb[] = {
+ /* TX/RX Controls */
+ {BBP_R1, 0x04},
+ {BBP_R4, 0x40},
+ {BBP_R20, 0x06},
+ {BBP_R31, 0x08},
+ /* CCK Tx Control */
+ {BBP_R178, 0xFF},
+ /* AGC/Sync controls */
+ //{BBP_R65, 0x2C},
+ {BBP_R66, 0x14},
+ {BBP_R68, 0x8B},
+ {BBP_R69, 0x12},
+ {BBP_R70, 0x09},
+ {BBP_R73, 0x11},
+ {BBP_R75, 0x60},
+ {BBP_R76, 0x44},
+ {BBP_R84, 0x9A},
+ {BBP_R86, 0x38},
+ {BBP_R91, 0x07},
+ {BBP_R92, 0x02},
+ /* Rx Path Controls */
+ {BBP_R99, 0x50},
+ {BBP_R101, 0x00},
+ {BBP_R103, 0xC0},
+ {BBP_R104, 0x92},
+ {BBP_R105, 0x3C},
+ {BBP_R106, 0x03},
+ {BBP_R128, 0x12},
+ /* Change RXWI content: Gain Report */
+ {BBP_R142, 0x04},
+ {BBP_R143, 0x37},
+ /* Change RXWI content: Antenna Report */
+ {BBP_R142, 0x03},
+ {BBP_R143, 0x99},
+ /* Calibration Index Register */
+ /* CCK Receiver Control */
+ {BBP_R160, 0xEB},
+ {BBP_R161, 0xC4},
+ {BBP_R162, 0x77},
+ {BBP_R163, 0xF9},
+ {BBP_R164, 0x88},
+ {BBP_R165, 0x80},
+ {BBP_R166, 0xFF},
+ {BBP_R167, 0xE4},
+ /* Added AGC controls */
+ /* These AGC/GLRT registers are accessed through R195 and R196. */
+ /* 0x00 */
+ {BBP_R195, 0x00},
+ {BBP_R196, 0x00},
+ /* 0x01 */
+ {BBP_R195, 0x01},
+ {BBP_R196, 0x04},
+ /* 0x02 */
+ {BBP_R195, 0x02},
+ {BBP_R196, 0x20},
+ /* 0x03 */
+ {BBP_R195, 0x03},
+ {BBP_R196, 0x0A},
+ /* 0x06 */
+ {BBP_R195, 0x06},
+ {BBP_R196, 0x16},
+ /* 0x07 */
+ {BBP_R195, 0x07},
+ {BBP_R196, 0x05},
+ /* 0x08 */
+ {BBP_R195, 0x08},
+ {BBP_R196, 0x37},
+ /* 0x0A */
+ {BBP_R195, 0x0A},
+ {BBP_R196, 0x15},
+ /* 0x0B */
+ {BBP_R195, 0x0B},
+ {BBP_R196, 0x17},
+ /* 0x0C */
+ {BBP_R195, 0x0C},
+ {BBP_R196, 0x06},
+ /* 0x0D */
+ {BBP_R195, 0x0D},
+ {BBP_R196, 0x09},
+ /* 0x0E */
+ {BBP_R195, 0x0E},
+ {BBP_R196, 0x05},
+ /* 0x0F */
+ {BBP_R195, 0x0F},
+ {BBP_R196, 0x09},
+ /* 0x10 */
+ {BBP_R195, 0x10},
+ {BBP_R196, 0x20},
+ /* 0x20 */
+ {BBP_R195, 0x20},
+ {BBP_R196, 0x17},
+ /* 0x21 */
+ {BBP_R195, 0x21},
+ {BBP_R196, 0x06},
+ /* 0x22 */
+ {BBP_R195, 0x22},
+ {BBP_R196, 0x09},
+ /* 0x23 */
+ {BBP_R195, 0x23},
+ {BBP_R196, 0x17},
+ /* 0x24 */
+ {BBP_R195, 0x24},
+ {BBP_R196, 0x06},
+ /* 0x25 */
+ {BBP_R195, 0x25},
+ {BBP_R196, 0x09},
+ /* 0x26 */
+ {BBP_R195, 0x26},
+ {BBP_R196, 0x17},
+ /* 0x27 */
+ {BBP_R195, 0x27},
+ {BBP_R196, 0x06},
+ /* 0x28 */
+ {BBP_R195, 0x28},
+ {BBP_R196, 0x09},
+ /* 0x29 */
+ {BBP_R195, 0x29},
+ {BBP_R196, 0x05},
+ /* 0x2A */
+ {BBP_R195, 0x2A},
+ {BBP_R196, 0x09},
+ /* 0x80 */
+ {BBP_R195, 0x80},
+ {BBP_R196, 0x8B},
+ /* 0x81 */
+ {BBP_R195, 0x81},
+ {BBP_R196, 0x12},
+ /* 0x82 */
+ {BBP_R195, 0x82},
+ {BBP_R196, 0x09},
+ /* 0x83 */
+ {BBP_R195, 0x83},
+ {BBP_R196, 0x17},
+ /* 0x84 */
+ {BBP_R195, 0x84},
+ {BBP_R196, 0x11},
+ /* 0x85 */
+ {BBP_R195, 0x85},
+ {BBP_R196, 0x00},
+ /* 0x86 */
+ {BBP_R195, 0x86},
+ {BBP_R196, 0x00},
+ /* 0x87 */
+ {BBP_R195, 0x87},
+ {BBP_R196, 0x18},
+ /* 0x88 */
+ {BBP_R195, 0x88},
+ {BBP_R196, 0x60},
+ /* 0x89 */
+ {BBP_R195, 0x89},
+ {BBP_R196, 0x44},
+ /* */
+ {BBP_R195, 0x8A},
+ {BBP_R196, 0x8B},
+ {BBP_R195, 0x8B},
+ {BBP_R196, 0x8B},
+ {BBP_R195, 0x8C},
+ {BBP_R196, 0x8B},
+ {BBP_R195, 0x8D},
+ {BBP_R196, 0x8B},
+ /* */
+ {BBP_R195, 0x8E},
+ {BBP_R196, 0x09},
+ {BBP_R195, 0x8F},
+ {BBP_R196, 0x09},
+ {BBP_R195, 0x90},
+ {BBP_R196, 0x09},
+ {BBP_R195, 0x91},
+ {BBP_R196, 0x09},
+ /* */
+ {BBP_R195, 0x92},
+ {BBP_R196, 0x11},
+ {BBP_R195, 0x93},
+ {BBP_R196, 0x11},
+ {BBP_R195, 0x94},
+ {BBP_R196, 0x11},
+ {BBP_R195, 0x95},
+ {BBP_R196, 0x11},
+ // PPAD
+ {BBP_R47, 0x80},
+ {BBP_R60, 0x80},
+ {BBP_R150, 0xD2},
+ {BBP_R151, 0x32},
+ {BBP_R152, 0x23},
+ {BBP_R153, 0x41},
+ {BBP_R154, 0x00},
+ {BBP_R155, 0x4F},
+ {BBP_R253, 0x7E},
+ {BBP_R195, 0x30},
+ {BBP_R196, 0x32},
+ {BBP_R195, 0x31},
+ {BBP_R196, 0x23},
+ {BBP_R195, 0x32},
+ {BBP_R196, 0x45},
+ {BBP_R195, 0x35},
+ {BBP_R196, 0x4A},
+ {BBP_R195, 0x36},
+ {BBP_R196, 0x5A},
+ {BBP_R195, 0x37},
+ {BBP_R196, 0x5A},
+};
+static UCHAR MT7601_BBP_InitRegTb_Size = (sizeof(MT7601_BBP_InitRegTb) / sizeof(RTMP_REG_PAIR));
+
+RTMP_REG_PAIR MT7601_BBP_BW20RegTb[] = {
+ {BBP_R69, 0x12},
+ {BBP_R91, 0x07},
+ /* 0x23 */
+ {BBP_R195, 0x23},
+ {BBP_R196, 0x17},
+ /* 0x24 */
+ {BBP_R195, 0x24},
+ {BBP_R196, 0x06},
+ /* 0x81 */
+ {BBP_R195, 0x81},
+ {BBP_R196, 0x12},
+ /* 0x83 */
+ {BBP_R195, 0x83},
+ {BBP_R196, 0x17},
+};
+const UCHAR MT7601_BBP_BW20RegTb_Size = (sizeof(MT7601_BBP_BW20RegTb) / sizeof(RTMP_REG_PAIR));
+
+RTMP_REG_PAIR MT7601_BBP_BW40RegTb[] = {
+ {BBP_R69, 0x15},
+ {BBP_R91, 0x04},
+ /* 0x23 */
+ {BBP_R195, 0x23},
+ {BBP_R196, 0x12},
+ /* 0x24 */
+ {BBP_R195, 0x24},
+ {BBP_R196, 0x08},
+ /* 0x81 */
+ {BBP_R195, 0x81},
+ {BBP_R196, 0x15},
+ /* 0x83 */
+ {BBP_R195, 0x83},
+ {BBP_R196, 0x16},
+};
+const UCHAR MT7601_BBP_BW40RegTb_Size = (sizeof(MT7601_BBP_BW40RegTb) / sizeof(RTMP_REG_PAIR));
+
+static RTMP_REG_PAIR MT7601_BBP_CommonRegTb[] = {
+ {BBP_R75, 0x60},
+ {BBP_R92, 0x02},
+ {BBP_R178, 0xFF}, // For CCK CH14 OBW
+ /* 0x88 */
+ {BBP_R195, 0x88},
+ {BBP_R196, 0x60},
+
+};
+const static UCHAR MT7601_BBP_CommonRegTb_Size = (sizeof(MT7601_BBP_CommonRegTb) / sizeof(RTMP_REG_PAIR));
+
+
+RTMP_REG_PAIR MT7601_BBP_HighTempBW20RegTb[] = {
+ {BBP_R69, 0x12},
+ {BBP_R91, 0x07},
+ /* 0x23 */
+ {BBP_R195, 0x23},
+ {BBP_R196, 0x17},
+ /* 0x24 */
+ {BBP_R195, 0x24},
+ {BBP_R196, 0x06},
+ /* 0x81 */
+ {BBP_R195, 0x81},
+ {BBP_R196, 0x12},
+ /* 0x83 */
+ {BBP_R195, 0x83},
+ {BBP_R196, 0x17},
+};
+const UCHAR MT7601_BBP_HighTempBW20RegTb_Size = (sizeof(MT7601_BBP_HighTempBW20RegTb) / sizeof(RTMP_REG_PAIR));
+
+RTMP_REG_PAIR MT7601_BBP_HighTempBW40RegTb[] = {
+ {BBP_R69, 0x15},
+ {BBP_R91, 0x04},
+ /* 0x23 */
+ {BBP_R195, 0x23},
+ {BBP_R196, 0x12},
+ /* 0x24 */
+ {BBP_R195, 0x24},
+ {BBP_R196, 0x08},
+ /* 0x81 */
+ {BBP_R195, 0x81},
+ {BBP_R196, 0x15},
+ /* 0x83 */
+ {BBP_R195, 0x83},
+ {BBP_R196, 0x16},
+};
+const UCHAR MT7601_BBP_HighTempBW40RegTb_Size = (sizeof(MT7601_BBP_HighTempBW40RegTb) / sizeof(RTMP_REG_PAIR));
+
+static RTMP_REG_PAIR MT7601_BBP_HighTempCommonRegTb[] = {
+ {BBP_R75, 0x60},
+ {BBP_R92, 0x02},
+ {BBP_R178, 0xFF}, // For CCK CH14 OBW
+ /* 0x88 */
+ {BBP_R195, 0x88},
+ {BBP_R196, 0x60},
+};
+const static UCHAR MT7601_BBP_HighTempCommonRegTb_Size = (sizeof(MT7601_BBP_HighTempCommonRegTb) / sizeof(RTMP_REG_PAIR));
+
+RTMP_REG_PAIR MT7601_BBP_LowTempBW20RegTb[] = {
+ {BBP_R69, 0x12},
+ {BBP_R75, 0x5E},
+ {BBP_R91, 0x07},
+ {BBP_R92, 0x02},
+ /* 0x23 */
+ {BBP_R195, 0x23},
+ {BBP_R196, 0x17},
+ /* 0x24 */
+ {BBP_R195, 0x24},
+ {BBP_R196, 0x06},
+ /* 0x81 */
+ {BBP_R195, 0x81},
+ {BBP_R196, 0x12},
+ /* 0x83 */
+ {BBP_R195, 0x83},
+ {BBP_R196, 0x17},
+ /* 0x88 */
+ {BBP_R195, 0x88},
+ {BBP_R196, 0x5E},
+};
+const UCHAR MT7601_BBP_LowTempBW20RegTb_Size = (sizeof(MT7601_BBP_LowTempBW20RegTb) / sizeof(RTMP_REG_PAIR));
+
+RTMP_REG_PAIR MT7601_BBP_LowTempBW40RegTb[] = {
+ {BBP_R69, 0x15},
+ {BBP_R75, 0x5C},
+ {BBP_R91, 0x04},
+ {BBP_R92, 0x03},
+ /* 0x23 */
+ {BBP_R195, 0x23},
+ {BBP_R196, 0x10},
+ /* 0x24 */
+ {BBP_R195, 0x24},
+ {BBP_R196, 0x08},
+ /* 0x81 */
+ {BBP_R195, 0x81},
+ {BBP_R196, 0x15},
+ /* 0x83 */
+ {BBP_R195, 0x83},
+ {BBP_R196, 0x16},
+ /* 0x88 */
+ {BBP_R195, 0x88},
+ {BBP_R196, 0x5B},
+};
+UCHAR MT7601_BBP_LowTempBW40RegTb_Size = (sizeof(MT7601_BBP_LowTempBW40RegTb) / sizeof(RTMP_REG_PAIR));
+
+static RTMP_REG_PAIR MT7601_BBP_LowTempCommonRegTb[] = {
+ {BBP_R178, 0xFF}, // For CCK CH14 OBW
+};
+const static UCHAR MT7601_BBP_LowTempCommonRegTb_Size = (sizeof(MT7601_BBP_LowTempCommonRegTb) / sizeof(RTMP_REG_PAIR));
+
+// 20121122 RF CR
+/* Bank Register Value(Hex) */
+static BANK_RF_REG_PAIR MT7601_RF_Central_RegTb[] = {
+/*
+ Bank 0 - For central blocks: BG, PLL, XTAL, LO, ADC/DAC
+*/
+ {RF_BANK0, RF_R00, 0x02},
+ {RF_BANK0, RF_R01, 0x01},
+ {RF_BANK0, RF_R02, 0x11},
+ {RF_BANK0, RF_R03, 0xFF},
+ {RF_BANK0, RF_R04, 0x0A},
+ {RF_BANK0, RF_R05, 0x20},
+ {RF_BANK0, RF_R06, 0x00},
+
+ /*
+ BG
+ */
+ {RF_BANK0, RF_R07, 0x00},
+ {RF_BANK0, RF_R08, 0x00},
+ {RF_BANK0, RF_R09, 0x00},
+ {RF_BANK0, RF_R10, 0x00},
+ {RF_BANK0, RF_R11, 0x21},
+
+ /*
+ XO
+ */
+ //{RF_BANK0, RF_R12, 0x00}, // By EEPROM
+ {RF_BANK0, RF_R13, 0x00}, // 40MHZ xtal
+ //{RF_BANK0, RF_R13, 0x13}, // 20MHZ xtal
+ {RF_BANK0, RF_R14, 0x7C},
+ {RF_BANK0, RF_R15, 0x22},
+ {RF_BANK0, RF_R16, 0x80},
+
+
+ /*
+ PLL
+ */
+ {RF_BANK0, RF_R17, 0x99},
+ {RF_BANK0, RF_R18, 0x99},
+ {RF_BANK0, RF_R19, 0x09},
+ {RF_BANK0, RF_R20, 0x50},
+ {RF_BANK0, RF_R21, 0xB0},
+ {RF_BANK0, RF_R22, 0x00},
+ {RF_BANK0, RF_R23, 0xC5},
+ {RF_BANK0, RF_R24, 0xFC},
+ {RF_BANK0, RF_R25, 0x40},
+ {RF_BANK0, RF_R26, 0x4D},
+ {RF_BANK0, RF_R27, 0x02},
+ {RF_BANK0, RF_R28, 0x72},
+ {RF_BANK0, RF_R29, 0x01},
+ {RF_BANK0, RF_R30, 0x00},
+ {RF_BANK0, RF_R31, 0x00},
+
+ /*
+ Test Ports
+ */
+ {RF_BANK0, RF_R32, 0x00},
+ {RF_BANK0, RF_R33, 0x00},
+ {RF_BANK0, RF_R34, 0x23},
+ {RF_BANK0, RF_R35, 0x01}, /* Change setting to reduce spurs */
+ {RF_BANK0, RF_R36, 0x00},
+ {RF_BANK0, RF_R37, 0x00},
+
+ /*
+ ADC/DAC
+ */
+ {RF_BANK0, RF_R38, 0x00},
+ {RF_BANK0, RF_R39, 0x20},
+ {RF_BANK0, RF_R40, 0x00},
+ {RF_BANK0, RF_R41, 0xD0},
+ {RF_BANK0, RF_R42, 0x1B},
+ {RF_BANK0, RF_R43, 0x02},
+ {RF_BANK0, RF_R44, 0x00},
+};
+static UINT32 MT7601_RF_Central_RegTb_Size = (sizeof(MT7601_RF_Central_RegTb) / sizeof(BANK_RF_REG_PAIR));
+
+static BANK_RF_REG_PAIR MT7601_RF_Channel_RegTb[] = {
+ {RF_BANK4, RF_R00, 0x01},
+ {RF_BANK4, RF_R01, 0x00},
+ {RF_BANK4, RF_R02, 0x00},
+ {RF_BANK4, RF_R03, 0x00},
+
+ /*
+ LDO
+ */
+ {RF_BANK4, RF_R04, 0x00},
+ {RF_BANK4, RF_R05, 0x08},
+ {RF_BANK4, RF_R06, 0x00},
+
+ /*
+ RX
+ */
+ {RF_BANK4, RF_R07, 0x5B},
+ {RF_BANK4, RF_R08, 0x52},
+ {RF_BANK4, RF_R09, 0xB6},
+ {RF_BANK4, RF_R10, 0x57},
+ {RF_BANK4, RF_R11, 0x33},
+ {RF_BANK4, RF_R12, 0x22},
+ {RF_BANK4, RF_R13, 0x3D},
+ {RF_BANK4, RF_R14, 0x3E},
+ {RF_BANK4, RF_R15, 0x13},
+ {RF_BANK4, RF_R16, 0x22},
+ {RF_BANK4, RF_R17, 0x23},
+ {RF_BANK4, RF_R18, 0x02},
+ {RF_BANK4, RF_R19, 0xA4},
+ {RF_BANK4, RF_R20, 0x01},
+ {RF_BANK4, RF_R21, 0x12},
+ {RF_BANK4, RF_R22, 0x80},
+ {RF_BANK4, RF_R23, 0xB3},
+ {RF_BANK4, RF_R24, 0x00}, /* Reserved */
+ {RF_BANK4, RF_R25, 0x00}, /* Reserved */
+ {RF_BANK4, RF_R26, 0x00}, /* Reserved */
+ {RF_BANK4, RF_R27, 0x00}, /* Reserved */
+
+ /*
+ LOGEN
+ */
+ {RF_BANK4, RF_R28, 0x18},
+ {RF_BANK4, RF_R29, 0xEE},
+ {RF_BANK4, RF_R30, 0x6B},
+ {RF_BANK4, RF_R31, 0x31},
+ {RF_BANK4, RF_R32, 0x5D},
+ {RF_BANK4, RF_R33, 0x00}, /* Reserved */
+
+ /*
+ TX
+ */
+ {RF_BANK4, RF_R34, 0x96},
+ {RF_BANK4, RF_R35, 0x55},
+ {RF_BANK4, RF_R36, 0x08},
+ {RF_BANK4, RF_R37, 0xBB},
+ {RF_BANK4, RF_R38, 0xB3},
+ {RF_BANK4, RF_R39, 0xB3},
+ {RF_BANK4, RF_R40, 0x03},
+ {RF_BANK4, RF_R41, 0x00}, /* Reserved */
+ {RF_BANK4, RF_R42, 0x00}, /* Reserved */
+ {RF_BANK4, RF_R43, 0xC5},
+ {RF_BANK4, RF_R44, 0xC5},
+ {RF_BANK4, RF_R45, 0xC5},
+ {RF_BANK4, RF_R46, 0x07},
+ {RF_BANK4, RF_R47, 0xA8},
+ {RF_BANK4, RF_R48, 0xEF},
+ {RF_BANK4, RF_R49, 0x1A},
+
+ /*
+ PA
+ */
+ {RF_BANK4, RF_R54, 0x07},
+ {RF_BANK4, RF_R55, 0xA7},
+ {RF_BANK4, RF_R56, 0xCC},
+ {RF_BANK4, RF_R57, 0x14},
+ {RF_BANK4, RF_R58, 0x07},
+ {RF_BANK4, RF_R59, 0xA8},
+ {RF_BANK4, RF_R60, 0xD7},
+ {RF_BANK4, RF_R61, 0x10},
+ {RF_BANK4, RF_R62, 0x1C},
+ {RF_BANK4, RF_R63, 0x00}, /* Reserved */
+};
+static UINT32 MT7601_RF_Channel_RegTb_Size = (sizeof(MT7601_RF_Channel_RegTb) / sizeof(BANK_RF_REG_PAIR));
+
+static BANK_RF_REG_PAIR MT7601_RF_VGA_RegTb[] = {
+ {RF_BANK5, RF_R00, 0x47},
+ {RF_BANK5, RF_R01, 0x00},
+ {RF_BANK5, RF_R02, 0x00},
+ {RF_BANK5, RF_R03, 0x08},
+ {RF_BANK5, RF_R04, 0x04},
+ {RF_BANK5, RF_R05, 0x20},
+ {RF_BANK5, RF_R06, 0x3A},
+ {RF_BANK5, RF_R07, 0x3A},
+ {RF_BANK5, RF_R08, 0x00},
+ {RF_BANK5, RF_R09, 0x00},
+ {RF_BANK5, RF_R10, 0x10},
+ {RF_BANK5, RF_R11, 0x10},
+ {RF_BANK5, RF_R12, 0x10},
+ {RF_BANK5, RF_R13, 0x10},
+ {RF_BANK5, RF_R14, 0x10},
+ {RF_BANK5, RF_R15, 0x20},
+ {RF_BANK5, RF_R16, 0x22},
+ {RF_BANK5, RF_R17, 0x7C},
+ {RF_BANK5, RF_R18, 0x00},
+ {RF_BANK5, RF_R19, 0x00},
+ {RF_BANK5, RF_R20, 0x00},
+ {RF_BANK5, RF_R21, 0xF1},
+ {RF_BANK5, RF_R22, 0x11},
+ {RF_BANK5, RF_R23, 0x02},
+ {RF_BANK5, RF_R24, 0x41},
+ {RF_BANK5, RF_R25, 0x20},
+ {RF_BANK5, RF_R26, 0x00},
+ {RF_BANK5, RF_R27, 0xD7},
+ {RF_BANK5, RF_R28, 0xA2},
+ {RF_BANK5, RF_R29, 0x20},
+ {RF_BANK5, RF_R30, 0x49},
+ {RF_BANK5, RF_R31, 0x20},
+ {RF_BANK5, RF_R32, 0x04},
+ {RF_BANK5, RF_R33, 0xF1},
+ {RF_BANK5, RF_R34, 0xA1},
+ {RF_BANK5, RF_R35, 0x01},
+ {RF_BANK5, RF_R41, 0x00},
+ {RF_BANK5, RF_R42, 0x00},
+ {RF_BANK5, RF_R43, 0x00},
+ {RF_BANK5, RF_R44, 0x00},
+ {RF_BANK5, RF_R45, 0x00},
+ {RF_BANK5, RF_R46, 0x00},
+ {RF_BANK5, RF_R47, 0x00},
+ {RF_BANK5, RF_R48, 0x00},
+ {RF_BANK5, RF_R49, 0x00},
+ {RF_BANK5, RF_R50, 0x00},
+ {RF_BANK5, RF_R51, 0x00},
+ {RF_BANK5, RF_R52, 0x00},
+ {RF_BANK5, RF_R53, 0x00},
+ {RF_BANK5, RF_R54, 0x00},
+ {RF_BANK5, RF_R55, 0x00},
+ {RF_BANK5, RF_R56, 0x00},
+ {RF_BANK5, RF_R57, 0x00},
+ {RF_BANK5, RF_R58, 0x31},
+ {RF_BANK5, RF_R59, 0x31},
+ {RF_BANK5, RF_R60, 0x0A},
+ {RF_BANK5, RF_R61, 0x02},
+ {RF_BANK5, RF_R62, 0x00},
+ {RF_BANK5, RF_R63, 0x00},
+};
+static UINT32 MT7601_RF_VGA_RegTb_Size = (sizeof(MT7601_RF_VGA_RegTb) / sizeof(BANK_RF_REG_PAIR));
+
+const MT7601_FREQ_ITEM MT7601_Frequency_Plan[] =
+{
+ /* CH, K_R17, K_R18, K_R19, N_R20 */
+ { 1, 0x99, 0x99, 0x09, 0x50},
+ { 2, 0x46, 0x44, 0x0A, 0x50},
+ { 3, 0xEC, 0xEE, 0x0A, 0x50},
+ { 4, 0x99, 0x99, 0x0B, 0x50},
+ { 5, 0x46, 0x44, 0x08, 0x51},
+ { 6, 0xEC, 0xEE, 0x08, 0x51},
+ { 7, 0x99, 0x99, 0x09, 0x51},
+ { 8, 0x46, 0x44, 0x0A, 0x51},
+ { 9, 0xEC, 0xEE, 0x0A, 0x51},
+ { 10, 0x99, 0x99, 0x0B, 0x51},
+ { 11, 0x46, 0x44, 0x08, 0x52},
+ { 12, 0xEC, 0xEE, 0x08, 0x52},
+ { 13, 0x99, 0x99, 0x09, 0x52},
+ { 14, 0x33, 0x33, 0x0B, 0x52},
+};
+UINT32 NUM_OF_MT7601_CHNL = (sizeof(MT7601_Frequency_Plan) / sizeof(MT7601_FREQ_ITEM));
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Enable Wlan function. this action will enable wlan clock so that chip can accept command. So MUST put in the
+ very beginning of Initialization. And put in the very LAST in the Halt function.
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL <= DISPATCH_LEVEL
+
+ Note:
+ Before Enable RX, make sure you have enabled Interrupt.
+ ========================================================================
+*/
+VOID MT7601_WLAN_ChipOnOff(
+ IN RTMP_ADAPTER *pAd,
+ IN BOOLEAN bOn,
+ IN BOOLEAN bResetWLAN)
+{
+ WLAN_FUN_CTRL_STRUC WlanFunCtrl = {.word=0};
+ int RET;
+
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_WAIT(&pAd->hw_atomic, RET);
+ if (RET != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", RET));
+ return;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &WlanFunCtrl.word);
+ DBGPRINT(RT_DEBUG_INFO, ("==>%s(): OnOff:%d, pAd->WlanFunCtrl:0x%x, Reg-WlanFunCtrl=0x%x\n",
+ __FUNCTION__, bOn, pAd->WlanFunCtrl.word, WlanFunCtrl.word));
+
+ if (bResetWLAN == TRUE)
+ {
+ WlanFunCtrl.field.GPIO0_OUT_OE_N = 0xFF;
+ WlanFunCtrl.field.FRC_WL_ANT_SET = 0;
+
+ if (pAd->WlanFunCtrl.field.WLAN_EN)
+ {
+ /*
+ Restore all HW default value and reset RF.
+ */
+ WlanFunCtrl.field.WLAN_RESET = 1;
+ WlanFunCtrl.field.WLAN_RESET_RF = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Reset(1) WlanFunCtrl.word = 0x%x\n", WlanFunCtrl.word));
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word);
+ RTMPusecDelay(20);
+ WlanFunCtrl.field.WLAN_RESET = 0;
+ WlanFunCtrl.field.WLAN_RESET_RF = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("Reset(2) WlanFunCtrl.word = 0x%x\n", WlanFunCtrl.word));
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word);
+ RTMPusecDelay(20);
+ }
+ }
+
+ if (bOn == TRUE)
+ {
+ /*
+ Enable WLAN function and clock
+ WLAN_FUN_CTRL[1:0] = 0x3
+ */
+ ENABLE_WLAN_FUN(WlanFunCtrl);
+ }
+ else
+ {
+ /*
+ Diable WLAN function and clock
+ WLAN_FUN_CTRL[1:0] = 0x0
+ */
+ DISABLE_WLAN_FUN(WlanFunCtrl);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WlanFunCtrl.word = 0x%x\n", WlanFunCtrl.word));
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word);
+ RTMPusecDelay(20);
+
+ if (bOn)
+ {
+ RTMP_IO_READ32(pAd, MAC_CSR0, &pAd->MACVersion);
+ DBGPRINT(RT_DEBUG_TRACE, ("MACVersion = 0x%08x\n", pAd->MACVersion));
+ }
+
+ if (bOn == TRUE)
+ {
+ UINT index = 0;
+ CMB_CTRL_STRUC CmbCtrl;
+
+ CmbCtrl.word = 0;
+
+ do
+ {
+ do
+ {
+ RTMP_IO_READ32(pAd, CMB_CTRL, &CmbCtrl.word);
+
+ /*
+ Check status of PLL_LD & XTAL_RDY.
+ HW issue: Must check PLL_LD&XTAL_RDY when setting EEP to disable PLL power down
+ */
+ if ((CmbCtrl.field.PLL_LD == 1) && (CmbCtrl.field.XTAL_RDY == 1))
+ break;
+
+ RTMPusecDelay(20);
+ } while (index++ < MAX_CHECK_COUNT);
+
+ if (index >= MAX_CHECK_COUNT)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("Lenny:[boundary]Check PLL_LD ..CMB_CTRL 0x%08x, index=%d!\n",
+ CmbCtrl.word, index));
+ /*
+ Disable WLAN then enable WLAN again
+ */
+ DISABLE_WLAN_FUN(WlanFunCtrl);
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word);
+ RTMPusecDelay(20);
+
+ ENABLE_WLAN_FUN(WlanFunCtrl);
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word);
+ RTMPusecDelay(20);
+ }
+ else
+ {
+ break;
+ }
+ }
+ while (TRUE);
+ }
+
+ pAd->WlanFunCtrl.word = WlanFunCtrl.word;
+ RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &WlanFunCtrl.word);
+ DBGPRINT(RT_DEBUG_INFO,
+ ("<== %s(): pAd->WlanFunCtrl.word = 0x%x, Reg->WlanFunCtrl=0x%x!\n",
+ __FUNCTION__, pAd->WlanFunCtrl.word, WlanFunCtrl.word));
+
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_UP(&pAd->hw_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+}
+
+
+VOID MT7601_RXDC_CAL(RTMP_ADAPTER *pAd)
+{
+#define MAX_RXDCOC_RETRY_CNT 20
+ UINT count;
+ UCHAR RValue;
+ UINT32 Mac_R1004;
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Mac_R1004);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x08);
+
+//1012 BBP CR
+ AndesBBPRandomWrite(pAd, 4,
+ BBP_R158, 0x8D,
+ BBP_R159, 0xFC,
+ BBP_R158, 0x8C,
+ BBP_R159, 0x4C);
+
+ for ( count = 0; count < MAX_RXDCOC_RETRY_CNT; count++ )
+ {
+ RTMPusecDelay(300);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R158, 0x8C);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R159, &RValue);
+
+ if ( RValue == 0x0c )
+ break;
+ }
+
+ if (count == MAX_RXDCOC_RETRY_CNT )
+ DBGPRINT_ERR(("MT7601_RXDC_CAL Fail!\n"));
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
+
+ //0725 BBP CR change DCOC sequence.
+ AndesBBPRandomWrite(pAd, 2,
+ BBP_R158, 0x8D,
+ BBP_R159, 0xE0);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Mac_R1004);
+}
+
+
+VOID MT7601_INIT_CAL(RTMP_ADAPTER *pAd)
+{
+ UCHAR RfValue;
+ UINT32 Mac_R1004;
+ UCHAR Temperature;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==>%s\n", __FUNCTION__));
+
+#ifdef MT7601FPGA
+ return;
+#endif /*MT7601FPGA */
+
+ MT7601_Bootup_Read_Temperature(pAd, &pAd->chipCap.CurrentTemperBbpR49);
+ pAd->chipCap.CurrentTemperature = (pAd->chipCap.CurrentTemperBbpR49 - pAd->chipCap.TemperatureRef25C) * MT7601_E2_TEMPERATURE_SLOPE;
+ pAd->chipCap.TemperatureDPD = pAd->chipCap.CurrentTemperature;
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Mac_R1004);
+
+ // R Calibration
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_R, 0);
+
+ // VCO Cal
+ rlt_rf_read(pAd, RF_BANK0, RF_R04, &RfValue);
+ RfValue = RfValue | 0x80;
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, RfValue);
+ RTMPusecDelay(2000);
+
+ /* TXDC */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_TXDCOC, 0);
+
+ // MT7601_RXDC_CAL
+ MT7601_RXDC_CAL(pAd);
+
+ /* Tx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x00001);
+
+ /* Rx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x00000);
+
+ /* TXLOFT */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_LOFT, 0);
+
+ /* TXIQ */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_TXIQ, 0);
+
+ /* RXIQ */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_RXIQ, 0);
+
+#ifdef DPD_CALIBRATION_SUPPORT
+ /* DPD-Calibration */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_DPD, pAd->chipCap.CurrentTemperature);
+#endif /* DPD_CALIBRATION_SUPPORT */
+
+ // MT7601_RXDC_CAL
+ MT7601_RXDC_CAL(pAd);
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ MT7601_TssiDcGainCalibration(pAd);
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Mac_R1004);
+
+ MT7601AsicTemperatureCompensation(pAd, TRUE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==%s\n", __FUNCTION__));
+
+}
+
+
+VOID dump_bw_info(RTMP_ADAPTER *pAd)
+{
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize FCE.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID InitFce(
+ PRTMP_ADAPTER pAd)
+{
+ L2_STUFFING_STRUC L2Stuffing = { {0} };
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: -->\n", __FUNCTION__));
+
+ RTMP_IO_READ32(pAd, FCE_L2_STUFF, &L2Stuffing.word);
+ L2Stuffing.field.FS_WR_MPDU_LEN_EN = 0;
+ RTMP_IO_WRITE32(pAd, FCE_L2_STUFF, L2Stuffing.word);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: <--\n", __FUNCTION__));
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize specific RF registers.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static VOID NICInitMT7601RFRegisters(RTMP_ADAPTER *pAd)
+{
+
+ UINT32 IdReg;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
+
+#ifdef MT7601FPGA
+ return;
+#endif /*MT7601FPGA */
+
+ rlt_rf_write(pAd, RF_BANK0, RF_R12, pAd->RfFreqOffset);
+
+ AndesRFRandomWritePair(pAd, MT7601_RF_Central_RegTb, MT7601_RF_Central_RegTb_Size);
+
+ AndesRFRandomWritePair(pAd, MT7601_RF_Channel_RegTb, MT7601_RF_Channel_RegTb_Size);
+
+ AndesRFRandomWritePair(pAd, MT7601_RF_VGA_RegTb, MT7601_RF_VGA_RegTb_Size);
+
+ MT7601_INIT_CAL(pAd);
+
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize specific MAC registers.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static VOID NICInitMT7601MacRegisters(RTMP_ADAPTER *pAd)
+{
+ UINT32 IdReg;
+ UINT32 MacReg = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
+
+ /*
+ Enable PBF and MAC clock
+ SYS_CTRL[11:10] = 0x3
+ */
+ AndesRandomWritePair(pAd, MT7601_MACRegTable, MT7601_NUM_MAC_REG_PARMS);
+
+ /*
+ Release BBP and MAC reset
+ MAC_SYS_CTRL[1:0] = 0x0
+ */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacReg);
+ MacReg &= ~(0x3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacReg);
+
+ //InitFce(pAd);
+
+ RTMP_IO_WRITE32(pAd, AUX_CLK_CFG, 0);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize specific BBP registers.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static VOID NICInitMT7601BbpRegisters(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT IdReg;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
+
+#ifdef MT7601FPGA
+ return;
+#endif /*MT7601FPGA */
+
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_InitRegTb, MT7601_BBP_InitRegTb_Size);
+
+ return;
+}
+
+
+static VOID MT7601_AsicAntennaDefaultReset(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN EEPROM_ANTENNA_STRUC *pAntenna)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
+ pAntenna->word = 0;
+ pAntenna->field.RfIcType = 0xf;
+ pAntenna->field.TxPath = 1;
+ pAntenna->field.RxPath = 1;
+}
+
+
+static VOID MT7601_ChipBBPAdjust(RTMP_ADAPTER *pAd)
+{
+ static char *ext_str[]={"extNone", "extAbove", "", "extBelow"};
+ UCHAR rf_bw, ext_ch;
+
+#ifdef DOT11_N_SUPPORT
+ if (get_ht_cent_ch(pAd, &rf_bw, &ext_ch) == FALSE)
+#endif /* DOT11_N_SUPPORT */
+ {
+ rf_bw = BW_20;
+ ext_ch = EXTCHA_NONE;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ }
+
+ rtmp_bbp_set_bw(pAd, rf_bw);
+
+ /* TX/Rx : control channel setting */
+ rtmp_mac_set_ctrlch(pAd, ext_ch);
+ rtmp_bbp_set_ctrlch(pAd, ext_ch);
+
+#ifdef DOT11_N_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() : %s, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n",
+ __FUNCTION__, ext_str[ext_ch],
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth,
+ pAd->CommonCfg.Channel,
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA,
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset));
+#endif /* DOT11_N_SUPPORT */
+}
+
+
+
+
+VOID MT7601_ChipAGCInit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BandWidth)
+{
+ UCHAR R66 = 0x14;
+ CHAR lan_gain = GET_LNA_GAIN(pAd);
+
+ if (pAd->LatchRfRegs.Channel <= 14) /* BG band */
+ {
+ /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
+
+ R66 += 2 * (lan_gain - 8 ) + 0x20;
+
+ rtmp_bbp_set_agc(pAd, R66, RX_CHAIN_ALL);
+
+ }
+
+}
+
+
+static VOID MT7601_ChipSwitchChannel(
+ struct _RTMP_ADAPTER *pAd,
+ UCHAR Channel,
+ BOOLEAN bScan)
+{
+
+ CHAR TxPwer = 0;
+ UCHAR index;
+ UCHAR RFValue = 0;
+ UINT32 Value = 0;
+ INT IdReg;
+ UINT32 ret;
+#ifdef SINGLE_SKU_V2
+ CHAR SkuBasePwr;
+ CHAR ChannelPwrAdj;
+#endif /* SINGLE_SKU_V2 */
+
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: SwitchChannel#%d(RF=%d, %dT)\n",
+ __FUNCTION__, Channel, pAd->RfIcType, pAd->Antenna.field.TxPath));
+
+#ifdef MT7601FPGA
+ return;
+#endif /*MT7601FPGA */
+
+ if (Channel > 14)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
+ return;
+ }
+
+#ifdef SINGLE_SKU_V2
+ SkuBasePwr = GetSkuChannelBasePwr(pAd, Channel);
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ if (pAd->TxPowerCtrl.bInternalTxALC != TRUE)
+#endif /* RTMP_INTERNAL_TX_ALC */
+ {
+ UINT32 value;
+ if ( pAd->DefaultTargetPwr > SkuBasePwr )
+ ChannelPwrAdj = SkuBasePwr - pAd->DefaultTargetPwr;
+ else
+ ChannelPwrAdj = 0;
+
+ if ( ChannelPwrAdj > 31 )
+ ChannelPwrAdj = 31;
+ if ( ChannelPwrAdj < -32 )
+ ChannelPwrAdj = -32;
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_1, &value);
+ value = (value & ~0x3F) | (ChannelPwrAdj & 0x3F);
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_1, value);
+ DBGPRINT(RT_DEBUG_TRACE, ("SkuBasePwr = 0x%x, DefaultTargetPwr = 0x%x, ChannelPwrAdj 0x13b4: 0x%x\n", SkuBasePwr, pAd->DefaultTargetPwr, value));
+ }
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ if (pAd->TxPowerCtrl.bInternalTxALC)
+ {
+ TxPwer = SkuBasePwr;
+ pAd->TxPower[Channel - 1].Power = TxPwer;
+ }
+ else
+#endif /* RTMP_INTERNAL_TX_ALC */
+#endif /* SINGLE_SKU_V2 */
+ TxPwer = pAd->TxPower[Channel - 1].Power;
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_WAIT(&pAd->hw_atomic, ret);
+ if (ret != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ return;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ for (index = 0; index < NUM_OF_MT7601_CHNL; index++)
+ {
+ if (Channel == MT7601_Frequency_Plan[index].Channel)
+ {
+ /* Frequeny plan setting */
+ AndesRFRandomWrite(pAd, 4,
+ RF_BANK0, RF_R17, MT7601_Frequency_Plan[index].K_R17,
+ RF_BANK0, RF_R18, MT7601_Frequency_Plan[index].K_R18,
+ RF_BANK0, RF_R19, MT7601_Frequency_Plan[index].K_R19,
+ RF_BANK0, RF_R20, MT7601_Frequency_Plan[index].N_R20);
+ }
+ }
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_0, &Value);
+ Value = Value & (~0x3F3F);
+ Value |= (TxPwer & 0x3F);
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_0, Value);
+
+ pAd->LatchRfRegs.Channel = Channel; /* Channel latch */
+
+ /* BBP setting */
+ if (Channel <= 14)
+ {
+ AndesBBPRandomWrite(pAd, 3,
+ BBP_R62, (0x37 - GET_LNA_GAIN(pAd)),
+ BBP_R63, (0x37 - GET_LNA_GAIN(pAd)),
+ BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+ //RtmpUpdateFilterCoefficientControl(pAd, Channel);
+ }
+
+ /*
+ vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration.
+ */
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, 0x0A);
+ rlt_rf_write(pAd, RF_BANK0, RF_R05, 0x20);
+ rlt_rf_read(pAd, RF_BANK0, RF_R04, &RFValue);
+ RFValue = RFValue | 0x80;
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, RFValue);
+ RTMPusecDelay(2000);
+
+ rtmp_bbp_set_bw(pAd, pAd->CommonCfg.BBPCurrentBW);
+
+ switch (pAd->CommonCfg.BBPCurrentBW)
+ {
+ case BW_20:
+ if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_HIGH )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_HighTempBW20RegTb, MT7601_BBP_HighTempBW20RegTb_Size);
+ }
+ else if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_LOW )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_LowTempBW20RegTb, MT7601_BBP_LowTempBW20RegTb_Size);
+ }
+ else
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_BW20RegTb, MT7601_BBP_BW20RegTb_Size);
+ }
+
+
+ /* Tx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10001);
+ /* Rx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10000);
+ break;
+ case BW_40:
+ if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_HIGH )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_HighTempBW40RegTb, MT7601_BBP_HighTempBW40RegTb_Size);
+ }
+ else if ( pChipCap->TemperatureMode == TEMPERATURE_MODE_LOW )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_LowTempBW40RegTb, MT7601_BBP_LowTempBW40RegTb_Size);
+ }
+ else
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_BW40RegTb, MT7601_BBP_BW40RegTb_Size);
+
+ }
+
+ /* Tx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10101);
+ /* Rx Filter BW */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_BW, 0x10100);
+
+ break;
+ default:
+ break;
+ }
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ /* B5.R6 and B5.R7 */
+ rlt_rf_read(pAd, RF_BANK5, RF_R06, &RFValue);
+ pAd->CommonCfg.MO_Cfg.Stored_RF_B5_R6 = RFValue;
+ rlt_rf_read(pAd, RF_BANK5, RF_R07, &RFValue);
+ pAd->CommonCfg.MO_Cfg.Stored_RF_B5_R7 = RFValue;
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ /* CCK CH14 OBW */
+ if ( (pAd->CommonCfg.BBPCurrentBW == BW_20) && ( Channel == 14 ) )
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, 0x60);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R178, 0x0);
+
+ UINT32 value;
+ CHAR CCK1MPwr, CCK11MPwr;
+ value = pAd->TxCCKPwrCfg;
+ CCK1MPwr = value & 0x3F;
+ CCK1MPwr -= 2;
+ if ( CCK1MPwr < -32 )
+ CCK1MPwr = -32;
+ CCK11MPwr = (value & 0x3F00) >> 8;
+ CCK11MPwr -= 2;
+ if ( CCK11MPwr < -32 )
+ CCK11MPwr = -32;
+
+ value = (value & ~0xFFFF) | (CCK11MPwr << 8 ) | CCK1MPwr;
+
+ pAd->Tx20MPwrCfgGBand[0] = value;
+ }
+ else
+ {
+ UCHAR BBPValue;
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= ~(0x20);
+ AndesBBPRandomWrite(pAd, 2,
+ BBP_R4, BBPValue,
+ BBP_R178, 0xFF);
+ pAd->Tx20MPwrCfgGBand[0] = pAd->TxCCKPwrCfg;
+ }
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0, pAd->Tx20MPwrCfgGBand[0]);
+
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_UP(&pAd->hw_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+#ifdef SINGLE_SKU_V2
+ UpdateSkuRatePwr(pAd, Channel, pAd->CommonCfg.BBPCurrentBW, SkuBasePwr);
+#endif /* SINGLE_SKU_V2 */
+
+
+}
+
+
+NTSTATUS MT7601DisableTxRx(
+ RTMP_ADAPTER *pAd,
+ UCHAR Level)
+{
+ UINT32 MacReg = 0;
+ UINT32 MTxCycle;
+ BOOLEAN bResetWLAN = FALSE;
+ BOOLEAN bFree = TRUE;
+ UINT8 CheckFreeTimes = 0;
+ UINT32 MaxRetry;
+
+ if (!IS_MT7601(pAd))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("----> %s\n", __FUNCTION__));
+
+ if ( Level == DOT11POWERSAVE )
+ MaxRetry = 20;
+ else
+ MaxRetry = 2000;
+
+ if (Level == RTMP_HALT)
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
+ }
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s Tx success = %ld\n",
+ __FUNCTION__, (ULONG)pAd->WlanCounters.TransmittedFragmentCount.u.LowPart));
+ DBGPRINT(RT_DEBUG_INFO, ("%s Tx success = %ld\n",
+ __FUNCTION__, (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart));
+
+ if ( StopDmaTx(pAd, Level) == STATUS_UNSUCCESSFUL )
+ return STATUS_UNSUCCESSFUL;
+
+ /*
+ Check page count in TxQ,
+ */
+ for (MTxCycle = 0; MTxCycle < MaxRetry; MTxCycle++)
+ {
+ BOOLEAN bFree = TRUE;
+ RTMP_IO_READ32(pAd, 0x438, &MacReg);
+ if (MacReg != 0)
+ bFree = FALSE;
+ RTMP_IO_READ32(pAd, 0xa30, &MacReg);
+ if (MacReg & 0x000000FF)
+ bFree = FALSE;
+ RTMP_IO_READ32(pAd, 0xa34, &MacReg);
+ if (MacReg & 0xFF00FF00)
+ bFree = FALSE;
+ if (bFree)
+ break;
+ RtmpOsMsDelay(10);
+ if (MacReg == 0xFFFFFFFF)
+ {
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if (MTxCycle >= MaxRetry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Check TxQ page count max\n"));
+ RTMP_IO_READ32(pAd, 0x0a30, &MacReg);
+ DBGPRINT(RT_DEBUG_TRACE, ("0x0a30 = 0x%08x\n", MacReg));
+
+ RTMP_IO_READ32(pAd, 0x0a34, &MacReg);
+ DBGPRINT(RT_DEBUG_TRACE, ("0x0a34 = 0x%08x\n", MacReg));
+
+ RTMP_IO_READ32(pAd, 0x438, &MacReg);
+ DBGPRINT(RT_DEBUG_TRACE, ("0x438 = 0x%08x\n", MacReg));
+ bResetWLAN = TRUE;
+
+ if ( Level == DOT11POWERSAVE )
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ Check MAC Tx idle
+ */
+ for (MTxCycle = 0; MTxCycle < MaxRetry; MTxCycle++)
+ {
+ RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacReg);
+ if (MacReg & 0x1)
+ RTMPusecDelay(50);
+ else
+ break;
+
+ if (MacReg == 0xFFFFFFFF)
+ {
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if (MTxCycle >= MaxRetry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Check MAC Tx idle max(0x%08x)\n", MacReg));
+ bResetWLAN = TRUE;
+
+ if ( Level == DOT11POWERSAVE )
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) == FALSE)
+ {
+ if (Level == RTMP_HALT)
+ {
+ /*
+ Disable MAC TX/RX
+ */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacReg);
+ MacReg &= ~(0x0000000c);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacReg);
+ }
+ else
+ {
+ /*
+ Disable MAC RX
+ */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacReg);
+ MacReg &= ~(0x00000008);
+ //MacReg &= ~(0x0000000c);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacReg);
+ }
+ }
+
+ /*
+ Check page count in RxQ,
+ */
+ for (MTxCycle = 0; MTxCycle < MaxRetry; MTxCycle++)
+ {
+ bFree = TRUE;
+ RTMP_IO_READ32(pAd, 0x430, &MacReg);
+
+ if (MacReg & (0x00FF0000))
+ bFree = FALSE;
+
+ RTMP_IO_READ32(pAd, 0xa30, &MacReg);
+
+ if (MacReg != 0)
+ bFree = FALSE;
+
+ RTMP_IO_READ32(pAd, 0xa34, &MacReg);
+
+ if (MacReg != 0)
+ bFree = FALSE;
+
+ if (bFree && (CheckFreeTimes > 5)) //&& (!IsInBandCmdProcessing(pAd)))
+ break;
+
+ if (bFree)
+ CheckFreeTimes++;
+
+ if (MacReg == 0xFFFFFFFF)
+ {
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ return STATUS_UNSUCCESSFUL;
+ }
+#ifdef RTMP_MAC_USB
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE);
+ RTUSBBulkCmdRspEventReceive(pAd);
+ RTUSBBulkReceive(pAd);
+#endif
+ }
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE);
+
+ if (MTxCycle >= MaxRetry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Check RxQ page count max\n"));
+
+ RTMP_IO_READ32(pAd, 0x0a30, &MacReg);
+ DBGPRINT(RT_DEBUG_TRACE, ("0x0a30 = 0x%08x\n", MacReg));
+
+ RTMP_IO_READ32(pAd, 0x0a34, &MacReg);
+ DBGPRINT(RT_DEBUG_TRACE, ("0x0a34 = 0x%08x\n", MacReg));
+
+ RTMP_IO_READ32(pAd, 0x0430, &MacReg);
+ DBGPRINT(RT_DEBUG_TRACE, ("0x0430 = 0x%08x\n", MacReg));
+ bResetWLAN = TRUE;
+
+ if ( Level == DOT11POWERSAVE )
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ Check MAC Rx idle
+ */
+ for (MTxCycle = 0; MTxCycle < MaxRetry; MTxCycle++)
+ {
+ RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacReg);
+ if (MacReg & 0x2)
+ RTMPusecDelay(50);
+ else
+ break;
+ if (MacReg == 0xFFFFFFFF)
+ {
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if (MTxCycle >= MaxRetry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Check MAC Rx idle max(0x%08x)\n", MacReg));
+ bResetWLAN = TRUE;
+
+ if ( Level == DOT11POWERSAVE )
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if ( StopDmaRx(pAd, Level) == STATUS_UNSUCCESSFUL )
+ return STATUS_UNSUCCESSFUL;
+
+ if ((Level == RTMP_HALT) &&
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) == FALSE))
+ {
+ if (!pAd->chipCap.IsComboChip)
+ NICEraseFirmware(pAd);
+
+ /*
+ Disable RF/MAC
+ */
+
+ if ((pAd->chipCap.IsComboChip) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_SUSPEND)
+ || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_CMD_RADIO_OFF))
+ bResetWLAN = 0;
+
+ MT7601_WLAN_ChipOnOff(pAd, FALSE, bResetWLAN);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<---- %s\n", __FUNCTION__));
+
+ return STATUS_SUCCESS;
+}
+
+
+#ifdef RTMP_USB_SUPPORT
+VOID MT7601UsbAsicRadioOff(RTMP_ADAPTER *pAd, UCHAR Stage)
+{
+ UINT32 Value, ret;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s\n", __FUNCTION__));
+
+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) )
+ return;
+
+ if (Stage == SUSPEND_RADIO_OFF)
+ {
+ MT7601DisableTxRx(pAd, RTMP_HALT);
+ }
+ else
+ {
+ if ( MT7601DisableTxRx(pAd, DOT11POWERSAVE) == STATUS_UNSUCCESSFUL )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Give up radio off!\n"));
+ return;
+ }
+ }
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_WAIT(&pAd->hw_atomic, ret);
+ if (ret != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+ return;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP);
+
+ if (Stage != SUSPEND_RADIO_OFF )
+ {
+ PWR_SAVING_OP(pAd, RADIO_OFF, 1, 0, 0, 0, 0);
+ }
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+
+ /* Stop bulkin pipe*/
+ if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ RTUSBCancelPendingBulkInIRP(pAd);
+ //pAd->PendingRx = 0;
+ }
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_UP(&pAd->hw_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- %s\n", __FUNCTION__));
+}
+
+
+VOID MT7601UsbAsicRadioOn(RTMP_ADAPTER *pAd, UCHAR Stage)
+{
+ UINT32 MACValue = 0;
+ UINT32 rx_filter_flag;
+ WPDMA_GLO_CFG_STRUC GloCfg;
+ RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+ UCHAR RFValue = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> %s\n", __FUNCTION__));
+
+ if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) )
+ return;
+
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP);
+
+#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_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == 1)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: autopm_resume success\n", __FUNCTION__));
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND);
+ }
+ else if ((RTMP_Usb_AutoPM_Get_Interface(pObj->pUsb_Dev,pObj->intf)) == (-1))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: autopm_resume fail ------\n", __FUNCTION__));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SUSPEND);
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: autopm_resume do nothing\n", __FUNCTION__));
+
+#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */
+#endif /* CONFIG_PM */
+
+ if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
+ {
+ MT7601_WLAN_ChipOnOff(pAd, TRUE, FALSE);
+ }
+
+ /* 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));
+
+ /* 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);
+
+ /* 4. Clear idle flag*/
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND);
+
+ /* Send Bulkin IRPs after flag fRTMP_ADAPTER_IDLE_RADIO_OFF is cleared.*/
+ RTUSBBulkCmdRspEventReceive(pAd);
+ RTUSBBulkReceive(pAd);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
+
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, 0x0A);
+ rlt_rf_write(pAd, RF_BANK0, RF_R05, 0x20);
+
+ rlt_rf_read(pAd, RF_BANK0, RF_R04, &RFValue);
+ RFValue = RFValue | 0x80;
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, RFValue);
+ RTMPusecDelay(2000);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== %s\n", __FUNCTION__));
+}
+#endif /* RTMP_USB_SUPPORT */
+
+
+
+
+VOID MT7601_NICInitAsicFromEEPROM(
+ IN PRTMP_ADAPTER pAd)
+{
+ // TODO: wait TC6008 EEPROM format
+}
+
+
+INT MT7601_ReadChannelPwr(RTMP_ADAPTER *pAd)
+{
+ UINT32 i, idx, ss_offset_g, MacReg;
+ EEPROM_TX_PWR_STRUC Power;
+ CHAR tx_pwr1, tx_pwr2;
+ CHAR max_tx1_pwr;
+ UINT16 TargetPwr = 0;
+ BOOLEAN bUseDefault = TRUE;
+#ifdef RTMP_INTERNAL_TX_ALC
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s()--->\n", __FUNCTION__));
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_0, &MacReg);
+ max_tx1_pwr = (MacReg >> 16) & 0x3F;
+
+#if defined (RTMP_INTERNAL_TX_ALC) || defined (SINGLE_SKU_V2)
+ RT28xx_EEPROM_READ16(pAd, EEPROM_G_TARGET_POWER, TargetPwr);
+ tx_pwr1 = TargetPwr & 0xFF;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: EEPROM 0xD0 = 0x%x\n", __FUNCTION__, tx_pwr1));
+
+ if ( (tx_pwr1 == 0x0) || (tx_pwr1 > max_tx1_pwr) )
+ {
+ tx_pwr1 = 0x20;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: EEPROM 0xD0 Error! Use Default Target Power = 0x%x\n", __FUNCTION__, tx_pwr1));
+ }
+#endif /* defined (RTMP_INTERNAL_TX_ALC) || defined (SINGLE_SKU_V2) */
+
+#ifdef SINGLE_SKU_V2
+ pAd->DefaultTargetPwr = tx_pwr1;
+#endif /* SINGLE_SKU_V2 */
+
+ /* 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)*/
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ NicConfig2.word = pAd->EEPROMDefaultValue[EEPROM_NIC_CFG2_OFFSET];
+ if ( NicConfig2.field.bInternalTxALC )
+ {
+
+ for ( i = 0; i < 7; i++ )
+ {
+ idx = i * 2;
+
+ pAd->TxPower[idx].Power = tx_pwr1;
+ pAd->TxPower[idx + 1].Power = tx_pwr1;
+
+ pAd->TxPower[idx].Channel = i * 2 +1;
+ pAd->TxPower[idx + 1].Channel = i * 2 + 2;
+
+ 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));
+ }
+
+ return TRUE;
+ }
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ /* 0. 11b/g, ch1 - ch 14, 1SS */
+ ss_offset_g = EEPROM_G_TX_PWR_OFFSET;
+
+ for (i = 0; i < 7; i++)
+ {
+ idx = i * 2;
+ RT28xx_EEPROM_READ16(pAd, ss_offset_g + idx, Power.word);
+
+ tx_pwr1 = tx_pwr2 = DEFAULT_TX_POWER;
+
+ if ((Power.field.Byte0 <= max_tx1_pwr) && (Power.field.Byte0 >= 0))
+ tx_pwr1 = Power.field.Byte0;
+
+ if ((Power.field.Byte1 <= max_tx1_pwr) || (Power.field.Byte1 >= 0))
+ tx_pwr2 = Power.field.Byte1;
+
+ pAd->TxPower[idx].Power = tx_pwr1;
+ pAd->TxPower[idx + 1].Power = tx_pwr2;
+
+ pAd->TxPower[idx].Channel = i * 2 +1;
+ pAd->TxPower[idx + 1].Channel = i * 2 + 2;
+
+ 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));
+
+ }
+
+ return TRUE;
+}
+
+
+VOID MT7601_ReadTxPwrPerRate(RTMP_ADAPTER *pAd)
+{
+ UINT32 data, Adata, Gdata;
+ USHORT i, value, value2;
+ CHAR value_1, value_2;
+ CHAR Apwrdelta, Gpwrdelta;
+ CHAR t1,t2;
+
+ /* 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))
+ {
+ /* Unit = 0.5 dBm, Max is 4 dBm */
+ Gpwrdelta = (value2&0x1f);
+ if ( Gpwrdelta > 8 )
+ Gpwrdelta = 8;
+
+ if ((value2 & 0x40) == 0 )
+ Gpwrdelta = -Gpwrdelta;
+ }
+
+ }
+ if ((value2 & 0xff00) != 0xff00)
+ {
+ if ((value2 & 0x8000))
+ {
+ Apwrdelta = ((value2&0x1f00)>>8);
+ if ( Apwrdelta > 8 )
+ Apwrdelta = 8;
+
+ if ((value2 & 0x4000) == 0)
+ Apwrdelta = - Apwrdelta;
+ }
+ }
+
+#ifdef SINGLE_SKU_V2
+ pAd->chipCap.Apwrdelta = Apwrdelta;
+ pAd->chipCap.Gpwrdelta = Gpwrdelta;
+#endif /* SINGLE_SKU_V2 */
+ DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %d, Apwrdelta = %d .\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;
+
+ /* signed 6-bit */
+ value_1 = (value&0x3f);
+ value_2 = (value&0x3f00)>>8;
+
+ /* signed extension */
+ value_1 = (value_1 > 0x1F) ? value_1 - 0x40 : value_1;
+ value_2 = (value_2 > 0x1F) ? value_2 - 0x40 : value_2;
+
+ t1 = value_1 + Gpwrdelta;
+ t2 = value_2 + Gpwrdelta;
+
+ /* boundary check */
+ if ( t1 > 31 )
+ t1 = 31;
+ if ( t1 < -32 )
+ t1 = -32;
+
+ if ( t2 > 31 )
+ t2 = 31;
+ if ( t2 < -32 )
+ t2 = -32;
+
+ Gdata = (t1 & 0x3f) + ((t2 & 0x3f)<<8);
+
+ t1 = value_1 + Apwrdelta;
+ t2 = value_2 + Apwrdelta;
+
+ /* boundary check */
+ if ( t1 > 31 )
+ t1 = 31;
+ if ( t1 < -32 )
+ t1 = -32;
+
+ if ( t2 > 31 )
+ t2 = 31;
+ if ( t2 < -32 )
+ t2 = -32;
+
+ Adata = (t1 & 0x3f) + (( t2 & 0x3f ) <<8);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
+
+ if ( i != 4 )
+ {
+ /* signed 6-bit */
+ value_1 = (value&0x3f);
+ value_2 = (value&0x3f00)>>8;
+
+ /* signed extension */
+ value_1 = (value_1 > 0x1F) ? value_1 - 0x40 : value_1;
+ value_2 = (value_2 > 0x1F) ? value_2 - 0x40 : value_2;
+
+ t1 = value_1 + Gpwrdelta;
+ t2 = value_2 + Gpwrdelta;
+
+ /* boundary check */
+ if ( t1 > 31 )
+ t1 = 31;
+ if ( t1 < -32 )
+ t1 = -32;
+
+ if ( t2 > 31 )
+ t2 = 31;
+ if ( t2 < -32 )
+ t2 = -32;
+
+ Gdata |= (( (t1 & 0x3f )<<16) + ( (t2 & 0x3f )<<24));
+
+ t1 = value_1 + Apwrdelta;
+ t2 = value_2 + Apwrdelta;
+
+ /* boundary check */
+ if ( t1 > 31 )
+ t1 = 31;
+ if ( t1 < -32 )
+ t1 = -32;
+
+ if ( t2 > 31 )
+ t2 = 31;
+ if ( t2 < -32 )
+ t2 = -32;
+
+ Adata |= (( (t1 & 0x3f ) <<16) + ( (t2 & 0x3f ) <<24));
+ }
+ else
+ {
+ Gdata |= 0xFFFF0000;
+ Adata |= 0xFFFF0000;
+ }
+ 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-%08x, Adata = %08x, Gdata = %08x \n", data, Adata, Gdata));
+ }
+
+ /* Extra set MAC registers to compensate Tx power if any */
+ RTMP_CHIP_ASIC_EXTRA_POWER_OVER_MAC(pAd);
+
+ pAd->TxCCKPwrCfg = pAd->Tx20MPwrCfgGBand[0];
+
+}
+
+
+VOID MT7601_AsicExtraPowerOverMAC(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG ExtraPwrOverMAC = 0;
+ ULONG ExtraPwrOverTxPwrCfg7 = 0, ExtraPwrOverTxPwrCfg9 = 0;
+
+ /* For OFDM_54 and HT_MCS_7, extra fill the corresponding register value into MAC 0x13D4 */
+ RTMP_IO_READ32(pAd, 0x1318, &ExtraPwrOverMAC);
+ ExtraPwrOverTxPwrCfg7 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for OFDM 54 */
+ RTMP_IO_READ32(pAd, 0x131C, &ExtraPwrOverMAC);
+ ExtraPwrOverTxPwrCfg7 |= (ExtraPwrOverMAC & 0x0000FF00) << 8; /* Get Tx power for HT MCS 7 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_7, ExtraPwrOverTxPwrCfg7);
+
+ /* For STBC_MCS_7, extra fill the corresponding register value into MAC 0x13DC */
+ RTMP_IO_READ32(pAd, 0x1324, &ExtraPwrOverMAC);
+ ExtraPwrOverTxPwrCfg9 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for STBC MCS 7 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_9, ExtraPwrOverTxPwrCfg9);
+
+ DBGPRINT(RT_DEBUG_INFO, ("Offset = 0x13D4, TxPwr = 0x%08X, Offset = 0x13DC, TxPwr = 0x%08X\n",
+ (UINT)ExtraPwrOverTxPwrCfg7,
+ (UINT)ExtraPwrOverTxPwrCfg9));
+}
+
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(SINGLE_SKU_V2)
+VOID MT7601_InitPAModeTable(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT32 PAMode;
+ UINT32 Value = 0;
+ UINT16 index, offset;
+
+ RTMP_IO_READ32(pAd, RF_PA_MODE_CFG0, &Value);
+ for ( index = 0, offset = 0; index < 4 ; index++, offset+= 2 )
+ {
+ PAMode = (Value >> offset ) & 0x3;
+ if ( PAMode == 3 )
+ pAd->chipCap.PAModeCCK[index] = RF_PA_MODE3_DECODE;
+ else if ( PAMode == 1 )
+ pAd->chipCap.PAModeCCK[index] = RF_PA_MODE1_DECODE;
+ else if ( PAMode == 0 )
+ pAd->chipCap.PAModeCCK[index] = RF_PA_MODE0_DECODE;
+ else if ( PAMode == 2 )
+ pAd->chipCap.PAModeCCK[index] = RF_PA_MODE2_DECODE;
+ DBGPRINT(RT_DEBUG_TRACE, ("PAModeCCK[%d] = %d\n", index, pAd->chipCap.PAModeCCK[index]));
+ }
+
+ for ( index = 0, offset = 8; index < 8 ; index++, offset+= 2 )
+ {
+ PAMode = (Value >> offset ) & 0x3;
+ if ( PAMode == 3 )
+ pAd->chipCap.PAModeOFDM[index] = RF_PA_MODE3_DECODE;
+ else if ( PAMode == 1 )
+ pAd->chipCap.PAModeOFDM[index] = RF_PA_MODE1_DECODE;
+ else if ( PAMode == 0 )
+ pAd->chipCap.PAModeOFDM[index] = RF_PA_MODE0_DECODE;
+ else if ( PAMode == 2 )
+ pAd->chipCap.PAModeOFDM[index] = RF_PA_MODE2_DECODE;
+ DBGPRINT(RT_DEBUG_TRACE, ("PAModeOFDM[%d] = %d\n", index, pAd->chipCap.PAModeOFDM[index]));
+ }
+
+ RTMP_IO_READ32(pAd, RF_PA_MODE_CFG1, &Value);
+
+ for ( index = 0, offset = 0; index < 16 ; index++, offset+= 2 )
+ {
+ PAMode = (Value >> offset ) & 0x3;
+ if ( PAMode == 3 )
+ pAd->chipCap.PAModeHT[index] = RF_PA_MODE3_DECODE;
+ else if ( PAMode == 1 )
+ pAd->chipCap.PAModeHT[index] = RF_PA_MODE1_DECODE;
+ else if ( PAMode == 0 )
+ pAd->chipCap.PAModeHT[index] = RF_PA_MODE0_DECODE;
+ else if ( PAMode == 2 )
+ pAd->chipCap.PAModeHT[index] = RF_PA_MODE2_DECODE;
+ DBGPRINT(RT_DEBUG_TRACE, ("PAModeHT[%d] = %d\n", index, pAd->chipCap.PAModeHT[index]));
+ }
+
+}
+#endif /* defined(RTMP_INTERNAL_TX_ALC) || defined(SINGLE_SKU_V2) */
+
+
+VOID MT7601_InitTemperatureCompensation(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Value = 0;
+
+ pAd->chipCap.TemperatureMode = TEMPERATURE_MODE_NORMAL;
+ pAd->chipCap.CurrentTemperature = 0;
+ pAd->chipCap.bPllLockProtect = FALSE;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_G_TARGET_POWER, Value);
+ pAd->chipCap.TemperatureRef25C = (Value >> 8) & 0xFF;
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->TemperatureRef25C = 0x%x\n", pAd->chipCap.TemperatureRef25C));
+
+}
+
+
+VOID MT7601_TemperatureCompensation(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+#ifdef RTMP_INTERNAL_TX_ALC
+ if ( pAd->TxPowerCtrl.bInternalTxALC == FALSE )
+#endif /* RTMP_INTERNAL_TX_ALC */
+ {
+ MT7601_Read_Temperature(pAd, &pChipCap->CurrentTemperBbpR49);
+ }
+
+ MT7601AsicTemperatureCompensation(pAd, FALSE);
+ }
+}
+
+
+VOID MT7601AsicTemperatureCompensation(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bPowerOn)
+{
+ INT32 CurrentTemper;
+ INT IdReg;
+ UCHAR RfReg;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 high_temp_cr_threshold, low_temp_cr_threshold;
+
+ CurrentTemper = (pChipCap->CurrentTemperBbpR49 - pChipCap->TemperatureRef25C) * MT7601_E2_TEMPERATURE_SLOPE; // 3.9 * 10
+ pChipCap->CurrentTemperature = CurrentTemper;
+
+ /* DPD Calibration */
+ if ( ((CurrentTemper - pChipCap->TemperatureDPD) > 450) || ((CurrentTemper - pChipCap->TemperatureDPD) < -450 ))
+ {
+ pChipCap->TemperatureDPD = CurrentTemper;
+
+#ifdef DPD_CALIBRATION_SUPPORT
+ /* DPD-Calibration */
+ AndesCalibrationOP(pAd, ANDES_CALIBRATION_DPD, pChipCap->TemperatureDPD);
+#endif /* DPD_CALIBRATION_SUPPORT */
+
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, 0x0A);
+ rlt_rf_write(pAd, RF_BANK0, RF_R05, 0x20);
+ rlt_rf_read(pAd, RF_BANK0, RF_R04, &RfReg);
+ RfReg = RfReg | 0x80;
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, RfReg);
+ RTMPusecDelay(2000);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::ReCalibration DPD.\n", __FUNCTION__));
+ }
+
+ /* PLL Lock Protect */
+ if ( CurrentTemper < -50 ) // ( 20 - 25 ) * 10 = -50
+ {
+ if ( pAd->chipCap.bPllLockProtect == FALSE )
+ {
+ pAd->chipCap.bPllLockProtect = TRUE;
+ rlt_rf_write(pAd, RF_BANK4, RF_R04, 0x06);
+
+ rlt_rf_read(pAd, RF_BANK4, RF_R10, &RfReg);
+ RfReg = RfReg & ~0x30;
+ rlt_rf_write(pAd, RF_BANK4, RF_R10, RfReg);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Enable PLL Lock Protect.\n", __FUNCTION__));
+ }
+ }
+ else if ( CurrentTemper > 50 ) // ( 30 - 25 ) * 10 = 50
+ {
+ if ( pAd->chipCap.bPllLockProtect == TRUE )
+ {
+ pAd->chipCap.bPllLockProtect = FALSE;
+ rlt_rf_write(pAd, RF_BANK4, RF_R04, 0x0);
+
+ rlt_rf_read(pAd, RF_BANK4, RF_R10, &RfReg);
+ RfReg = (RfReg & ~0x30) | 0x10;
+ rlt_rf_write(pAd, RF_BANK4, RF_R10, RfReg);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Disable PLL Lock Protect.\n", __FUNCTION__));
+ }
+ }
+
+ if ( bPowerOn )
+ {
+ high_temp_cr_threshold = 350;
+ low_temp_cr_threshold = -250;
+ }
+ else
+ {
+ high_temp_cr_threshold = 400;
+ low_temp_cr_threshold = -200;
+ }
+
+
+ /* BBP CR for H, L, N temperature */
+ if ( CurrentTemper > high_temp_cr_threshold ) // (60 - 25) * 10 = 350
+ {
+ if ( pChipCap->TemperatureMode != TEMPERATURE_MODE_HIGH )
+ {
+ pChipCap->TemperatureMode = TEMPERATURE_MODE_HIGH;
+
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_HighTempCommonRegTb, MT7601_BBP_HighTempCommonRegTb_Size);
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_20 )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_HighTempBW20RegTb, MT7601_BBP_HighTempBW20RegTb_Size);
+ }
+ else if (pAd->CommonCfg.BBPCurrentBW == BW_40 )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_HighTempBW40RegTb, MT7601_BBP_HighTempBW40RegTb_Size);
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::Unsupported BW(%x)\n", __FUNCTION__, pAd->CommonCfg.BBPCurrentBW));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Change to TEMPERATURE_MODE_HIGH\n", __FUNCTION__));
+ }
+ }
+ else if ( CurrentTemper > low_temp_cr_threshold ) // ( 0 - 25 ) * 10
+ {
+ if ( pChipCap->TemperatureMode != TEMPERATURE_MODE_NORMAL )
+ {
+ pChipCap->TemperatureMode = TEMPERATURE_MODE_NORMAL;
+
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_CommonRegTb, MT7601_BBP_CommonRegTb_Size);
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_20 )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_BW20RegTb, MT7601_BBP_BW20RegTb_Size);
+ }
+ else if (pAd->CommonCfg.BBPCurrentBW == BW_40 )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_BW40RegTb, MT7601_BBP_BW40RegTb_Size);
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::Unsupported BW(%x)\n", __FUNCTION__, pAd->CommonCfg.BBPCurrentBW));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Change to TEMPERATURE_MODE_NORMAL\n", __FUNCTION__));
+ }
+ }
+ else
+ {
+ if ( pChipCap->TemperatureMode != TEMPERATURE_MODE_LOW )
+ {
+ pChipCap->TemperatureMode = TEMPERATURE_MODE_LOW;
+
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_LowTempCommonRegTb, MT7601_BBP_LowTempCommonRegTb_Size);
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_20 )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_LowTempBW20RegTb, MT7601_BBP_LowTempBW20RegTb_Size);
+ }
+ else if (pAd->CommonCfg.BBPCurrentBW == BW_40 )
+ {
+ AndesBBPRandomWritePair(pAd, MT7601_BBP_LowTempBW40RegTb, MT7601_BBP_LowTempBW40RegTb_Size);
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::Unsupported BW(%x)\n", __FUNCTION__, pAd->CommonCfg.BBPCurrentBW));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Change to TEMPERATURE_MODE_LOW\n", __FUNCTION__));
+ }
+ }
+
+}
+
+
+#ifdef RTMP_INTERNAL_TX_ALC
+INT16 lin2dBd(UINT16 linearValue)
+{
+ short exp;
+ unsigned int mantisa;
+ int app,dBd;
+ // Default backoff ; to enhance leading bit searching time
+ mantisa = linearValue << DEFAULT_BO;
+ exp = -(DEFAULT_BO);
+ // Leading bit searching
+ if (mantisa < (0x8000)) {
+ while (mantisa < (0x8000)) {
+ mantisa = mantisa << 1; // no need saturation
+ exp--;
+ if (exp < -20) {
+ //printf("error, input too small");
+ //printf("exponent = %d\n",exp);
+ return LIN2DB_ERROR_CODE;
+ }
+ }
+ }
+ else {
+ while (mantisa > (0xFFFF)) {
+ mantisa = mantisa >> 1; // no need saturation
+ exp ++;
+ if (exp > 20) {
+ //printf("error, input too large");
+ //printf("exponent = %d\n",exp);
+ return LIN2DB_ERROR_CODE;
+ }
+ }
+ }
+ //printf("exp=0d%d,mantisa=0x%x\n",exp,mantisa);
+
+ if (mantisa <= 47104) {
+ app= (mantisa+(mantisa>>3)+(mantisa>>4)-38400); //S(15,0)
+ if(app<0) {app=0;}
+ }
+ else {
+ app=(mantisa-(mantisa>>3)-(mantisa>>6)-23040); //S(15,0)
+ if(app<0) {app=0;}
+ }
+
+ dBd=((15+exp)<<15)+app;//since 2^15=1 here
+ //printf("dBd1=%d\n",dBd);
+ dBd=(dBd<<2)+(dBd<<1)+(dBd>>6)+(dBd>>7);
+ dBd=(dBd>>10);//S10.5
+ //printf("app=%d,dBd=%d,dBdF=%f\n",app,dBd,(double)dBd/32);
+ return(dBd);
+}
+
+
+VOID MT7601_EnableTSSI(IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFReg, BBPReg;
+ UINT32 ret;
+ MT7601_TX_ALC_DATA *pTxALCData = &pAd->chipCap.TxALCData;
+
+ AndesFunSetOP(pAd, 5, pTxALCData->TSSI_USE_HVGA);
+
+
+
+}
+
+
+VOID MT7601_TssiDcGainCalibration(RTMP_ADAPTER *pAd)
+{
+ UCHAR Rf_B5_R03, Rf_B4_R39, bbp_r47;
+ INT i, count;
+ UCHAR RValue;
+ INT16 tssi_linear;
+ INT16 tssi0_db = 0, tssi0_db_hvga = 0;
+ MT7601_TX_ALC_DATA *pTxALCData = &pAd->chipCap.TxALCData;
+
+ /* Mac Bypass */
+ RTMP_IO_WRITE32(pAd, 0x50C, 0x30);
+ RTMP_IO_WRITE32(pAd, 0x504, 0xC0030);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R58, 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R241, 0x2);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R23, 0x8);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &bbp_r47);
+
+
+ /* Set VGA gain */
+ rlt_rf_read(pAd, RF_BANK5, RF_R03, &Rf_B5_R03);
+ rlt_rf_write(pAd, RF_BANK5, RF_R03, 0x8);
+
+ /* Mixer disable */
+ rlt_rf_read(pAd, RF_BANK4, RF_R39, &Rf_B4_R39);
+ rlt_rf_write(pAd, RF_BANK4, RF_R39, 0x0);
+
+ for( i = 0; i < 4; i++)
+ {
+ if ( ( i == 0 ) || ( i == 2 ) )
+ rlt_rf_write(pAd, RF_BANK4, RF_R39, 0x0); //disable PA
+ else
+ rlt_rf_write(pAd, RF_BANK4, RF_R39, Rf_B4_R39); // enable PA
+
+ if( i < 2)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R23, 0x8);
+ rlt_rf_write(pAd, RF_BANK5, RF_R03, 0x8);
+ }
+ else
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R23, 0x2);
+ rlt_rf_write(pAd, RF_BANK5, RF_R03, 0x11);
+ }
+
+ /* BBP TSSI initial and soft reset */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22 , 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R244, 0x0);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, 0x1);
+ RTMPusecDelay(1);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, 0x0);
+
+ /* TSSI measurement */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, 0x50);
+ if ( ( i == 0 ) || ( i == 2 ) )
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, 0x40); // enable dc
+ else
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R244, 0x31); // enable ton gen
+
+ for ( count = 0; count < 20; count++ )
+ {
+ //RTMPusecDelay(100);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &RValue);
+
+ if ( (RValue & 0x10) == 0x00 )
+ break;
+ }
+ if ( count == 20 )
+ DBGPRINT(RT_DEBUG_ERROR, ("TssiDC0 Read Fail!\n"));
+
+ /* TSSI read */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, 0x40);
+ if(i == 0)
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &pTxALCData->TssiDC0);
+ else if(i == 2)
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &pTxALCData->TssiDC0_HVGA);
+ else
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, (PUCHAR)&tssi_linear);
+
+ tssi_linear = tssi_linear & 0xff;
+ tssi_linear = (tssi_linear & 0x80) ? tssi_linear - 0x100 : tssi_linear;
+
+ if(i==1)
+ tssi0_db = lin2dBd(tssi_linear - pTxALCData->TssiDC0);
+ else if(i == 3)
+ {
+ tssi_linear = tssi_linear - pTxALCData->TssiDC0_HVGA;
+ tssi_linear = tssi_linear * 4;
+ tssi0_db_hvga = lin2dBd(tssi_linear);
+ }
+
+ }
+
+ pTxALCData->TSSI0_DB = tssi0_db;
+ DBGPRINT(RT_DEBUG_TRACE, ("tssi0_db_hvga = %x\n", tssi0_db_hvga));
+ DBGPRINT(RT_DEBUG_TRACE, ("tssi0_db = %x\n", tssi0_db));
+
+
+ pTxALCData->TSSI_DBOFFSET_HVGA = tssi0_db_hvga - tssi0_db;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R244, 0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, 0x1);
+ RTMPusecDelay(1);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, 0x0);
+ RTMP_IO_WRITE32(pAd, 0x504, 0x0);
+ RTMP_IO_WRITE32(pAd, 0x50C, 0x0);
+ rlt_rf_write(pAd, RF_BANK5, RF_R03, Rf_B5_R03);
+ rlt_rf_write(pAd, RF_BANK4, RF_R39, Rf_B4_R39);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, bbp_r47);
+ // -(tssi0_db*slope +tssi0_db) / 4096
+ DBGPRINT(RT_DEBUG_TRACE, ("TssiDC0 = %d (0x%x)\n", pTxALCData->TssiDC0, pTxALCData->TssiDC0));
+ DBGPRINT(RT_DEBUG_TRACE, ("TssiDC0_HVGA = %d (0x%x)\n", pTxALCData->TssiDC0_HVGA, pTxALCData->TssiDC0));
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI_DBOFFSET_HVGA = %x\n", pTxALCData->TSSI_DBOFFSET_HVGA));
+
+}
+
+
+VOID MT7601_InitDesiredTSSITable(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Value = 0;
+ UINT16 index, offset;
+ INT32 init_offset;
+ MT7601_TX_ALC_DATA *pTxALCData = &pAd->chipCap.TxALCData;
+
+
+ if (pAd->TxPowerCtrl.bInternalTxALC == FALSE)
+ {
+ return;
+ }
+
+ /* TSSI Slope in EEPROM 0x6E u.2.6 */
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TX0_TSSI_SLOPE, Value);
+ pTxALCData->TssiSlope = Value & 0xFF;
+
+ /* TSSI Offset Channel 1 ~ 4 in EEPROF 0x6F s.3.4 */
+ pTxALCData->MT7601_TSSI_OFFSET[0] = (Value & 0xFF00) >> 8;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TX0_TSSI_OFFSET_GROUP1, Value);
+ pTxALCData->MT7601_TSSI_OFFSET[1] = Value & 0xFF;
+ pTxALCData->MT7601_TSSI_OFFSET[2] = (Value & 0xFF00) >> 8;
+
+#ifdef DOT11_N_SUPPORT
+ if(pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power <= 20)
+ pTxALCData->TSSI_USE_HVGA = 1;
+ else
+ pTxALCData->TSSI_USE_HVGA = 0;
+#else
+ if(pAd->TxPower[pAd->CommonCfg.Channel-1].Power <= 20)
+ pTxALCData->TSSI_USE_HVGA = 1;
+ else
+ pTxALCData->TSSI_USE_HVGA = 0;
+#endif /* DOT11_N_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI slope = 0x%x, offset[0] = 0x%x, offset[1] = 0x%x, offset[2] = 0x%x, TSSI_USE_HVGA = %x\n",
+ pTxALCData->TssiSlope, pTxALCData->MT7601_TSSI_OFFSET[0], pTxALCData->MT7601_TSSI_OFFSET[1],
+ pTxALCData->MT7601_TSSI_OFFSET[2], pTxALCData->TSSI_USE_HVGA));
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TX0_TSSI_OFFSET, Value);
+ pTxALCData->MT7601_TSSI_T0_Delta_Offset = ((CHAR)(Value & 0xFF)) * 1024;
+ DBGPRINT(RT_DEBUG_TRACE, ("TSSI T0 Delta offset = %d\n", pTxALCData->MT7601_TSSI_T0_Delta_Offset));
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_1, &Value);
+ init_offset = ( (pTxALCData->TSSI0_DB * pTxALCData->TssiSlope) + pTxALCData->MT7601_TSSI_OFFSET[1]) / 4096;
+ init_offset = -(init_offset-10);
+
+ if(init_offset < -0x20)
+ init_offset = 0x20;
+ else if(init_offset > 0x1f)
+ init_offset = 0x1f;
+
+ Value = (Value & ~0x3F) | (init_offset & 0x3F);
+ pTxALCData->InitTxAlcCfg1 = Value;
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_1, Value);
+ DBGPRINT(RT_DEBUG_TRACE, ("Init MAC 13b4: 0x%x\n", Value));
+
+ MT7601_InitPAModeTable(pAd);
+}
+
+
+BOOLEAN MT7601_GetTssiCompensationParam(
+ IN PRTMP_ADAPTER pAd,
+ OUT PCHAR TssiLinear0,
+ OUT PCHAR TssiLinear1,
+ OUT PINT32 TargetPower)
+{
+ UCHAR RFReg, BBPReg;
+ UCHAR PacketType;
+ UCHAR BbpR47;
+ UCHAR BBPR4, BBPR178;
+ UCHAR TxRate;
+ INT32 Power;
+ UINT count;
+ UINT32 ret;
+ MT7601_TX_ALC_DATA *pTxALCData = &pAd->chipCap.TxALCData;
+
+ if ( pTxALCData->TssiTriggered == 0 )
+ {
+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD) )
+ {
+ MT7601_EnableTSSI(pAd);
+ pTxALCData->TssiTriggered = 1;
+ }
+
+ return FALSE;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPReg);
+ if(BBPReg & 0x10)
+ {
+ //printk("#\n");
+
+ return FALSE;
+ }
+
+ /* 4. Read TSSI */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47);
+ BbpR47 = (BbpR47 & ~0x07);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, TssiLinear0);
+
+
+ /* 5. Read Temperature */
+ BbpR47 = (BbpR47 & ~0x07) | 0x04;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &(pAd->chipCap.CurrentTemperBbpR49));
+
+ BbpR47 = (BbpR47 & ~0x07) | 0x01;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &PacketType);
+
+ DBGPRINT(RT_DEBUG_INFO, ("TSSI = 0x%X\n", *TssiLinear0));
+ DBGPRINT(RT_DEBUG_INFO, ("temperature = 0x%X\n", pAd->chipCap.CurrentTemperBbpR49));
+ DBGPRINT(RT_DEBUG_INFO, ("PacketType = 0x%X\n", PacketType));
+
+ pTxALCData->TssiTriggered = 0;
+
+#ifdef DOT11_N_SUPPORT
+ Power = pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power;
+#else
+ Power = pAd->TxPower[pAd->CommonCfg.Channel-1].Power ;
+#endif /* DOT11_N_SUPPORT */
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("Channel Desire Power = %d\n", Power));
+
+ switch ( PacketType & 0x03)
+ {
+ case 0:
+ TxRate = (PacketType >> 4) & 0x03;
+ DBGPRINT(RT_DEBUG_INFO, ("tx_11b_rate: %x\n", TxRate));
+ switch (TxRate)
+ {
+ case 0: // 1 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_CCK_1M : BW20_MCS_POWER_CCK_1M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_1M;
+ break;
+ case 1: // 2 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_CCK_2M : BW20_MCS_POWER_CCK_2M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_2M;
+ break;
+ case 2: // 5.5 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_CCK_5M : BW20_MCS_POWER_CCK_5M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_5M;
+ break;
+ case 3: // 11Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_CCK_11M : BW20_MCS_POWER_CCK_11M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_CCK_11M;
+ break;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPR4);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R178, &BBPR178);
+ if ( BBPR4 & 0x20 )
+ {
+ if ( BBPR178 == 0 )
+ {
+ Power += 9830; // 8192 * 1.2
+ }
+ else
+ {
+ Power += 18022; // 8192 * 2.2
+ }
+ }
+ else
+ {
+ if ( BBPR178 == 0 )
+ {
+ Power += 24576; // 8192 * 3
+ }
+ else
+ {
+ Power += 819; /// 8192 * 0.1
+ }
+ }
+ break;
+ case 1:
+ TxRate = (PacketType >> 4) & 0x0F;
+ DBGPRINT(RT_DEBUG_INFO, ("tx_11g_rate: %x\n", TxRate));
+ switch ( TxRate )
+ {
+ case 0xB: // 6 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_6M : BW20_MCS_POWER_OFDM_6M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_6M;
+ break;
+ case 0xF: // 9 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_9M : BW20_MCS_POWER_OFDM_9M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_9M;
+ break;
+ case 0xA: // 12 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_12M : BW20_MCS_POWER_OFDM_12M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_12M;
+ break;
+ case 0xE: // 18 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_18M : BW20_MCS_POWER_OFDM_18M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_18M;
+ break;
+ case 0x9: // 24 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_24M : BW20_MCS_POWER_OFDM_24M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_24M;
+ break;
+ case 0xD: // 36 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_36M : BW20_MCS_POWER_OFDM_36M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_36M;
+ break;
+ case 0x8: // 48 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_48M : BW20_MCS_POWER_OFDM_48M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_48M;
+ break;
+ case 0xC: // 54 Mbps
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_OFDM_54M : BW20_MCS_POWER_OFDM_54M;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_OFDM_54M;
+ break;
+ }
+ break;
+ default:
+ BbpR47 = (BbpR47 & ~0x07) | 0x02;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &TxRate);
+ DBGPRINT(RT_DEBUG_INFO, ("tx_11n_rate: %x\n", TxRate));
+ TxRate &= 0x7F; // TxRate[7] is bandwidth
+ switch ( TxRate )
+ {
+ case 0x0:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS0: BW20_MCS_POWER_HT_MCS0;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS0;
+ break;
+ case 0x1:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS1: BW20_MCS_POWER_HT_MCS1;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS1;
+ break;
+ case 0x2:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS2: BW20_MCS_POWER_HT_MCS2;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS2;
+ break;
+ case 0x3:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS3: BW20_MCS_POWER_HT_MCS3;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS3;
+ break;
+ case 0x4:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS4: BW20_MCS_POWER_HT_MCS4;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS4;
+ break;
+ case 0x5:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS5: BW20_MCS_POWER_HT_MCS5;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS5;
+ break;
+ case 0x6:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS6: BW20_MCS_POWER_HT_MCS6;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS6;
+ break;
+ case 0x7:
+ Power += (pAd->CommonCfg.BBPCurrentBW == BW_40)? BW40_MCS_POWER_HT_MCS7: BW20_MCS_POWER_HT_MCS7;
+ Power = Power << 12;
+ DBGPRINT(RT_DEBUG_INFO, ("Channel PWR + MCS PWR = %x\n", Power));
+ Power += RF_PA_MODE_HT_MCS7;
+ break;
+
+ }
+ break;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPReg);
+ switch ( BBPReg & 0x3 )
+ {
+ case 1:
+ Power -= 49152; // -6 dB*8192
+ break;
+ case 2:
+ Power -= 98304; //-12 dB*8192
+ break;
+ case 3:
+ Power += 49152; // 6 dB*8192
+ break;
+ case 0:
+ default:
+ break;
+ }
+
+ Power += pTxALCData->MT7601_TSSI_T0_Delta_Offset;
+
+ *TargetPower = Power;
+ DBGPRINT(RT_DEBUG_INFO, ("TargetPower: 0x%x(%d)\n", *TargetPower, *TargetPower));
+
+ return TRUE;
+
+}
+
+VOID MT7601_AsicTxAlcGetAutoAgcOffset(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1)
+{
+ INT32 TargetPower, CurrentPower, PowerDiff;
+ UCHAR TssiLinear0, TssiLinear1;
+ CHAR tssi_offset;
+ INT16 tssi_db, tssi_m_dc;
+ UINT32 value;
+ UCHAR BBPReg;
+ MT7601_TX_ALC_DATA *pTxALCData = &pAd->chipCap.TxALCData;
+
+#ifdef MT7601FPGA
+ return;
+#endif /*MT7601FPGA */
+
+ if ( pAd->TxPowerCtrl.bInternalTxALC == FALSE )
+ return;
+
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+ // if base power is lower than 10 dBm use High VGA
+#ifdef DOT11_N_SUPPORT
+ if(pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power <= 20)
+ pTxALCData->TSSI_USE_HVGA = 1;
+ else
+ pTxALCData->TSSI_USE_HVGA = 0;
+#else
+ if(pAd->TxPower[pAd->CommonCfg.Channel-1].Power <= 20)
+ pTxALCData->TSSI_USE_HVGA = 1;
+ else
+ pTxALCData->TSSI_USE_HVGA = 0;
+#endif /* DOT11_N_SUPPORT */
+
+ if (MT7601_GetTssiCompensationParam(pAd, &TssiLinear0 , &TssiLinear1, &TargetPower) == FALSE )
+ return;
+
+ tssi_m_dc = TssiLinear0 - ((pTxALCData->TSSI_USE_HVGA == 1) ? pTxALCData->TssiDC0_HVGA : pTxALCData->TssiDC0);
+
+ DBGPRINT(RT_DEBUG_INFO, ("tssi_m_dc: %d\n", tssi_m_dc));
+ DBGPRINT(RT_DEBUG_INFO, ("TssiLinear0: %d\n", TssiLinear0));
+ if ( pTxALCData->TSSI_USE_HVGA == 1 )
+ DBGPRINT(RT_DEBUG_INFO, ("TssiDC0_HVGA: %d\n", pTxALCData->TssiDC0_HVGA));
+ else
+ DBGPRINT(RT_DEBUG_INFO, ("TssiDC0: %d\n", pTxALCData->TssiDC0));
+
+ tssi_db = lin2dBd(tssi_m_dc);
+
+#ifdef DOT11_N_SUPPORT
+ if ( pAd->CommonCfg.CentralChannel <= 4 )
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[0];
+ else if ( pAd->CommonCfg.CentralChannel >= 9 )
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[2];
+ else
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[1];
+#else
+ if ( pAd->CommonCfg.Channel <= 4 )
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[0];
+ else if ( pAd->CommonCfg.Channel >= 9 )
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[2];
+ else
+ tssi_offset = pTxALCData->MT7601_TSSI_OFFSET[1];
+#endif /* DOT11_N_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_INFO, ("tssi_offset: %d\n", tssi_offset));
+ DBGPRINT(RT_DEBUG_INFO, ("tssi_offset<<9: %d\n", tssi_offset<<9));
+ DBGPRINT(RT_DEBUG_INFO, ("TssiSlope: %d\n", pTxALCData->TssiSlope));
+ DBGPRINT(RT_DEBUG_INFO, ("tssi_db: %d\n", tssi_db));
+ if(pTxALCData->TSSI_USE_HVGA == 1)
+ tssi_db -= pTxALCData->TSSI_DBOFFSET_HVGA;
+
+ CurrentPower = (pTxALCData->TssiSlope*tssi_db) + (tssi_offset << 9);
+
+ DBGPRINT(RT_DEBUG_INFO, ("CurrentPower: %d\n", CurrentPower));
+
+ PowerDiff = TargetPower - CurrentPower;
+
+ DBGPRINT(RT_DEBUG_INFO, ("PowerDiff: %d\n", PowerDiff));
+
+ if((TssiLinear0 > 126) && ( PowerDiff > 0)) // upper saturation
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s :: upper saturation.\n", __FUNCTION__));
+ PowerDiff = 0;
+ }
+ else
+ {
+ //if(((TssiLinear0 -TssiDC0) < 1) && (PowerDiff < 0)) // lower saturation
+ if(((TssiLinear0 -((pTxALCData->TSSI_USE_HVGA == 1) ? pTxALCData->TssiDC0_HVGA : pTxALCData->TssiDC0)) < 1) && (PowerDiff < 0)) // lower saturation
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s :: lower saturation.\n", __FUNCTION__));
+ PowerDiff = 0;
+ }
+ }
+
+ if( ((pTxALCData->PowerDiffPre ^ PowerDiff) < 0 )
+ && ( (PowerDiff < 4096) && (PowerDiff > -4096)) // +- 0.5
+ && ( (pTxALCData->PowerDiffPre < 4096) && (pTxALCData->PowerDiffPre > -4096))) // +- 0.5
+ {
+ if((PowerDiff > 0) && ((PowerDiff + pTxALCData->PowerDiffPre) >= 0))
+ PowerDiff = 0;
+ else if((PowerDiff < 0) && ((PowerDiff + pTxALCData->PowerDiffPre) < 0))
+ PowerDiff = 0;
+ else
+ pTxALCData->PowerDiffPre = PowerDiff;
+ }
+ else
+ {
+ pTxALCData->PowerDiffPre = PowerDiff;
+ }
+
+ PowerDiff = PowerDiff + ((PowerDiff>0)?2048:-2048);
+ PowerDiff = PowerDiff / 4096;
+
+ DBGPRINT(RT_DEBUG_INFO, ("final PowerDiff: %d(0x%x)\n", PowerDiff, PowerDiff));
+
+ RTMP_IO_READ32(pAd, TX_ALC_CFG_1, &value);
+ CurrentPower = (value & 0x3F);
+ CurrentPower = CurrentPower > 0x1F ? CurrentPower - 0x40 : CurrentPower;
+ PowerDiff += CurrentPower;
+ if ( PowerDiff > 31 )
+ PowerDiff = 31;
+ if ( PowerDiff < -32 )
+ PowerDiff = -32;
+ //PowerDiff = PowerDiff + (value & 0x3F);
+ value = (value & ~0x3F) | (PowerDiff & 0x3F);
+ RTMP_IO_WRITE32(pAd, TX_ALC_CFG_1, value);
+ DBGPRINT(RT_DEBUG_INFO, ("MAC 13b4: 0x%x\n", value));
+
+ //MT7601AsicTemperatureCompensation(pAd);
+
+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD) )
+ {
+ MT7601_EnableTSSI(pAd);
+ pTxALCData->TssiTriggered = 1;
+ }
+
+ }
+
+
+}
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+
+INT MT7601_Bootup_Read_Temperature(
+ IN PRTMP_ADAPTER pAd,
+ OUT CHAR* Temperature)
+{
+ UINT32 MAC0504, MAC050C;
+ UCHAR BBPReg;
+ int i;
+
+ RTMP_IO_READ32(pAd, 0x50C, &MAC050C);
+ RTMP_IO_READ32(pAd, 0x504, &MAC0504);
+
+ RTMP_IO_WRITE32(pAd, 0x504, 0x0);
+ RTMP_IO_WRITE32(pAd, 0x50C, 0x10);
+ RTMP_IO_WRITE32(pAd, 0x504, 0x10);
+
+ /* BBP R47[4] = 1 */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPReg);
+ BBPReg &= (~0x7f);
+ BBPReg |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPReg);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, 0x40);
+
+ i = 100;
+ while ( i > 0 )
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPReg);
+ if( (BBPReg & 0x10) == 0)
+ {
+ break;
+ }
+ i--;
+ }
+
+ BBPReg = (BBPReg & ~0x07) | 0x04;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPReg);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, Temperature);
+ DBGPRINT(RT_DEBUG_TRACE, ("Boot up temperature = 0x%X\n", *Temperature));
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, 0x0);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BBPReg);
+ BBPReg |= 0x2;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BBPReg);
+ BBPReg &= ~0x2;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BBPReg);
+
+ RTMP_IO_WRITE32(pAd, 0x504, 0);
+ RTMP_IO_WRITE32(pAd, 0x50C, MAC050C);
+ RTMP_IO_WRITE32(pAd, 0x504, MAC0504);
+
+ return TRUE;
+}
+
+
+INT MT7601_Read_Temperature(
+ IN PRTMP_ADAPTER pAd,
+ OUT CHAR* Temperature)
+{
+ UCHAR BBPReg;
+ int i;
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ if ( (pAd->chipCap.TxALCData.TssiTriggered == 1) && ( pAd->TxPowerCtrl.bInternalTxALC == TRUE ) )
+ {
+ *Temperature = pAd->chipCap.CurrentTemperBbpR49;
+ }
+ else
+#endif /* RTMP_INTERNAL_TX_ALC */
+ {
+ /* BBP R47[4] = 1 */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPReg);
+ BBPReg &= (~0x7f);
+ BBPReg |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPReg);
+
+ i = 100;
+ while ( i > 0 )
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPReg);
+ if( (BBPReg & 0x10) == 0)
+ {
+ break;
+ }
+ i--;
+ }
+
+ BBPReg = (BBPReg & ~0x07) | 0x04;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPReg);
+ RTMPusecDelay(500);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, Temperature);
+ //DBGPRINT(RT_DEBUG_TRACE, ("temperature = 0x%X\n", *Temperature));
+ }
+
+ return TRUE;
+}
+
+
+VOID MT7601SetRxAnt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ant)
+{
+ UCHAR Val;
+
+ 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)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ return;
+ }
+
+ /* For PPAD Debug, BBP R153[7] = 1 --> Main Ant, R153[7] = 0 --> Aux Ant */
+ 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_R154, 0x00); /* Clear R154[4], Rx Ant is not bound to the previous rx packet selected Ant */
+
+ if (Ant == 0)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &Val);
+ Val &= ~0x80;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, Val); /* Main Ant */
+ DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: MT7601 --> switch to main\x1b[m\n", __FUNCTION__));
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &Val);
+ Val |= 0x80;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, Val); /* Aux Ant */
+ DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: MT7601 --> switch to aux\x1b[m\n", __FUNCTION__));
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize MT7601.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID MT7601_Init(RTMP_ADAPTER *pAd)
+{
+ RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ UINT32 Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-->%s():\n", __FUNCTION__));
+
+ pAd->RfIcType = RFIC_UNKNOWN;
+ /*
+ Init chip capabilities
+ */
+ RTMP_IO_READ32(pAd, 0x00, &Value);
+ pChipCap->ChipID = Value;
+
+ pChipCap->MaxNss = 1;
+ pChipCap->TXWISize = 20;
+ pChipCap->RXWISize = 24;
+ // TODO: check WPDMABurstSIZE???
+ pChipCap->WPDMABurstSIZE = 3;
+
+ pChipCap->SnrFormula = SNR_FORMULA2;
+ pChipCap->FlgIsHwWapiSup = TRUE;
+ pChipCap->VcoPeriod = 10;
+ pChipCap->FlgIsVcoReCalMode = VCO_CAL_DISABLE;
+ pChipCap->FlgIsHwAntennaDiversitySup = TRUE;
+ pChipCap->FlgSwBasedPPAD = TRUE;
+#ifdef STREAM_MODE_SUPPORT
+ pChipCap->FlgHwStreamMode = FALSE;
+#endif /* STREAM_MODE_SUPPORT */
+#ifdef TXBF_SUPPORT
+ pChipCap->FlgHwTxBfCap = FALSE;
+#endif /* TXBF_SUPPORT */
+#ifdef FIFO_EXT_SUPPORT
+ pChipCap->FlgHwFifoExtCap = TRUE;
+#endif /* FIFO_EXT_SUPPORT */
+
+#ifdef CONFIG_RX_CSO_SUPPORT
+ pChipCap->asic_caps |= fASIC_CAP_CSO;
+#endif /* CONFIG_RX_CSO_SUPPORT */
+
+ pChipCap->asic_caps |= (fASIC_CAP_PMF_ENC);
+
+ pChipCap->phy_caps = fPHY_CAP_24G;
+ pChipCap->phy_caps |= fPHY_CAP_HT;
+
+ // TODO: check RfReg17WtMethod???
+ //pChipCap->RfReg17WtMethod = RF_REG_WT_METHOD_STEP_ON;
+
+ pChipCap->MaxNumOfRfId = 63;
+ pChipCap->pRFRegTable = NULL;
+
+ pChipCap->MaxNumOfBbpId = 255;
+ pChipCap->pBBPRegTable = NULL;
+ pChipCap->bbpRegTbSize = 0;
+
+#ifdef NEW_MBSSID_MODE
+ pChipCap->MBSSIDMode = MBSSID_MODE1;
+#else
+ pChipCap->MBSSIDMode = MBSSID_MODE0;
+#endif /* NEW_MBSSID_MODE */
+
+
+
+#ifdef RTMP_EFUSE_SUPPORT
+ pChipCap->EFUSE_USAGE_MAP_START = 0x1E0;
+ pChipCap->EFUSE_USAGE_MAP_END = 0x1FC;
+ pChipCap->EFUSE_USAGE_MAP_SIZE = 29;
+ pChipCap->EFUSE_DEFAULT_BIN = MT7601_EFUSE_DEFAULT_BIN;
+ pChipCap->EFUSE_DEFAULT_BIN_SIZE = 0x100;
+#endif /* RTMP_EFUSE_SUPPORT */
+
+ pChipCap->WlanMemmapOffset = 0x410000;
+ pChipCap->InbandPacketMaxLen = 192;
+
+ RTMP_DRS_ALG_INIT(pAd, RATE_ALG_GRP);
+
+ /*
+ Following function configure beacon related parameters
+ in pChipCap
+ FlgIsSupSpecBcnBuf / BcnMaxHwNum /
+ WcidHwRsvNum / BcnMaxHwSize / BcnBase[]
+ */
+ rlt_bcn_buf_init(pAd);
+
+ /*
+ init operator
+ */
+
+ /* BBP adjust */
+ pChipOps->ChipBBPAdjust = MT7601_ChipBBPAdjust;
+
+
+ /* Channel */
+ pChipOps->ChipSwitchChannel = MT7601_ChipSwitchChannel;
+ pChipOps->ChipAGCInit = MT7601_ChipAGCInit;
+
+ pChipOps->AsicMacInit = NICInitMT7601MacRegisters;
+ pChipOps->AsicBbpInit = NICInitMT7601BbpRegisters;
+ pChipOps->AsicRfInit = NICInitMT7601RFRegisters;
+ pChipOps->AsicRfTurnOn = NULL;
+
+ pChipOps->AsicHaltAction = NULL;
+ pChipOps->AsicRfTurnOff = NULL;
+ pChipOps->AsicReverseRfFromSleepMode = NULL;
+ pChipOps->AsicResetBbpAgent = NULL;
+
+ /* MAC */
+
+ /* EEPROM */
+ pChipOps->NICInitAsicFromEEPROM = MT7601_NICInitAsicFromEEPROM;
+
+ /* Temperature Compensation */
+ pChipOps->InitTemperCompensation = MT7601_InitTemperatureCompensation;
+ pChipOps->TemperCompensation = MT7601_TemperatureCompensation;
+
+ /* Antenna */
+ pChipOps->AsicAntennaDefaultReset = MT7601_AsicAntennaDefaultReset;
+
+ /* TX ALC */
+ pChipOps->ATETssiCalibration = NULL;
+ pChipOps->ATETssiCalibrationExtend = NULL;
+ pChipOps->AsicTxAlcGetAutoAgcOffset = NULL;
+ pChipOps->ATEReadExternalTSSI = NULL;
+ pChipOps->TSSIRatio = NULL;
+
+ /* Others */
+#ifdef CARRIER_DETECTION_SUPPORT
+ pAd->chipCap.carrier_func = TONE_RADAR_V2;
+ pChipOps->ToneRadarProgram = ToneRadarProgram_v2;
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+ /* Chip tuning */
+ pChipOps->RxSensitivityTuning = NULL;
+#ifdef RTMP_INTERNAL_TX_ALC
+ pChipOps->InitDesiredTSSITable = MT7601_InitDesiredTSSITable;
+ pChipOps->AsicTxAlcGetAutoAgcOffset = MT7601_AsicTxAlcGetAutoAgcOffset;
+ pChipCap->TxALCData.TssiSlope = 0;
+ pChipCap->TxALCData.TssiDC0 = 0;
+ pChipCap->TxALCData.TssiDC0_HVGA = 0;
+ pChipCap->TxALCData.TSSI_USE_HVGA = 0;
+ pChipCap->TxALCData.PowerDiffPre = 100;
+#endif /* RTMP_INTERNAL_TX_ALC */
+ pChipOps->AsicGetTxPowerOffset = AsicGetTxPowerOffset;
+
+ pChipOps->AsicExtraPowerOverMAC = MT7601_AsicExtraPowerOverMAC;
+
+ pChipOps->SetRxAnt = MT7601SetRxAnt;
+
+
+ pChipOps->DisableTxRx = MT7601DisableTxRx;
+
+#ifdef RTMP_USB_SUPPORT
+ pChipOps->AsicRadioOn = MT7601UsbAsicRadioOn;
+ pChipOps->AsicRadioOff = MT7601UsbAsicRadioOff;
+#endif
+
+
+#ifdef RTMP_USB_SUPPORT
+ pChipOps->loadFirmware = USBLoadFirmwareToAndes;
+#endif
+
+ //pChipOps->sendCommandToMcu = AsicSendCmdToAndes;
+ //pChipOps->loadFirmware = NULL;
+#ifdef CONFIG_ANDES_SUPPORT
+ pChipCap->WlanMemmapOffset = 0x410000;
+ pChipCap->InbandPacketMaxLen = 192;
+ pChipCap->CmdRspRxRing = RX_RING1;
+#endif
+ pChipCap->MCUType = ANDES;
+ pChipCap->FWImageName = MT7601_FirmwareImage;
+
+/* Following callback functions already initiailized in RtmpChipOpsEepromHook( ) */
+ /* 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);
+*/
+
+/*
+ Following callback functions already initiailized in RtmpChipOpsHook()
+ 1. Power save related
+*/
+#ifdef GREENAP_SUPPORT
+ pChipOps->EnableAPMIMOPS = NULL;
+ pChipOps->DisableAPMIMOPS = NULL;
+#endif /* GREENAP_SUPPORT */
+ // TODO: ------Upper parameters are not finialized yet!!
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ pChipOps->AsicMeasureFalseCCA = MT7601_AsicMeasureFalseCCA;
+ pChipOps->AsicMitigateMicrowave = MT7601_AsicMitigateMicrowave;
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+#ifdef HDR_TRANS_SUPPORT
+ if (1) {
+ UINT8 cnt = HT_RX_WCID_SIZE/HT_RX_WCID_OFFSET;
+ UINT32 RegVal;
+
+ /* enable TX/RX Header Translation */
+ RTMP_IO_WRITE32(pAd, HT_RX_WCID_EN_BASE , 0xFF); /* all RX WCID enable */
+
+ /* black list - skip EAP-888e/DLS-890d */
+ RTMP_IO_WRITE32(pAd, HT_RX_BL_BASE, 0x888e890d);
+ //RTMP_IO_WRITE32(pAd, HT_RX_BL_BASE, 0x08000806);
+
+ /* tsc conrotl */
+/*
+ RTMP_IO_READ32(pAd, 0x250, &RegVal);
+ RegVal |= 0x6000;
+ RTMP_IO_WRITE32(pAd, 0x250, RegVal);
+*/
+ }
+#endif /* HDR_TRANS_SUPPORT */
+
+#ifdef NEW_WOW_SUPPORT
+ pChipOps->AsicWOWEnable = RT28xxAndesWOWEnable;
+ pChipOps->AsicWOWDisable = RT28xxAndesWOWDisable;
+#endif /* NEW_WOW_SUPPORT */
+
+}
+
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+VOID MT7601_AsicMeasureFalseCCA(
+ IN PRTMP_ADAPTER pAd
+)
+{
+ UINT32 reg;
+ /* restore LAN gain*/
+ //printk("Stored_BBP_R65=%x @%s \n", pAd->CommonCfg.MO_Cfg.Stored_BBP_R65, __FUNCTION__);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, pAd->CommonCfg.MO_Cfg.Stored_BBP_R65);
+ /* restore RF LPF threshold */
+ rlt_rf_write(pAd, RF_BANK5, RF_R06, pAd->CommonCfg.MO_Cfg.Stored_RF_B5_R6);
+ rlt_rf_write(pAd, RF_BANK5, RF_R07, pAd->CommonCfg.MO_Cfg.Stored_RF_B5_R7);
+
+ /* clear false cca counter */
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &reg);
+
+ /* reset false CCA counter */
+ pAd->CommonCfg.MO_Cfg.nFalseCCACnt = 0;
+}
+
+
+VOID MT7601_AsicMitigateMicrowave(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT8 RegValue;
+ //printk("Detect Microwave...\n");
+ /* set middle gain */
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R65, &RegValue);
+ RegValue |= 0x08;
+ RegValue &= 0xFB; /*BBP_R65[3:2] from 3 into 2 */
+ /* narrow down RF LPF */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R65, RegValue);
+ rlt_rf_write(pAd, RF_BANK5, RF_R06, 0x3F);
+ rlt_rf_write(pAd, RF_BANK5, RF_R07, 0x3F);
+
+}
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+#endif /* MT7601 */
+
diff --git a/cleopatre/devkit/mt7601udrv/chips/rtmp_chip.c b/cleopatre/devkit/mt7601udrv/chips/rtmp_chip.c
new file mode 100644
index 0000000000..7c31d1be0c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/chips/rtmp_chip.c
@@ -0,0 +1,1041 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_chip.c
+
+ Abstract:
+ Ralink Wireless driver CHIP related functions
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
+#include "rt_config.h"
+
+
+
+FREQUENCY_ITEM RtmpFreqItems3020[] =
+{
+ /* ISM : 2.4 to 2.483 GHz, 11g */
+ /*-CH---N-------R---K-----------*/
+ {1, 241, 2, 2},
+ {2, 241, 2, 7},
+ {3, 242, 2, 2},
+ {4, 242, 2, 7},
+ {5, 243, 2, 2},
+ {6, 243, 2, 7},
+ {7, 244, 2, 2},
+ {8, 244, 2, 7},
+ {9, 245, 2, 2},
+ {10, 245, 2, 7},
+ {11, 246, 2, 2},
+ {12, 246, 2, 7},
+ {13, 247, 2, 2},
+ {14, 248, 2, 4},
+};
+
+FREQUENCY_ITEM FreqItems3020_Xtal20M[] =
+{
+ /*
+ * RF_R08:
+ * <7:0>: pll_N<7:0>
+ *
+ * RF_R09:
+ * <3:0>: pll_K<3:0>
+ * <4>: pll_N<8>
+ * <7:5>pll_N<11:9>
+ *
+ */
+ /*-CH---N--------R---N[7:4]K[3:0]------*/
+ {1, 0xE2, 2, 0x14},
+ {2, 0xE3, 2, 0x14},
+ {3, 0xE4, 2, 0x14},
+ {4, 0xE5, 2, 0x14},
+ {5, 0xE6, 2, 0x14},
+ {6, 0xE7, 2, 0x14},
+ {7, 0xE8, 2, 0x14},
+ {8, 0xE9, 2, 0x14},
+ {9, 0xEA, 2, 0x14},
+ {10, 0xEB, 2, 0x14},
+ {11, 0xEC, 2, 0x14},
+ {12, 0xED, 2, 0x14},
+ {13, 0xEE, 2, 0x14},
+ {14, 0xF0, 2, 0x18},
+};
+
+UCHAR NUM_OF_3020_CHNL = (sizeof(RtmpFreqItems3020) / sizeof(FREQUENCY_ITEM));
+
+FREQUENCY_ITEM *FreqItems3020 = RtmpFreqItems3020;
+
+#if defined(RT28xx) || defined(RT2883)
+/* Reset the RFIC setting to new series */
+RTMP_RF_REGS RF2850RegTable[] = {
+ /* ch R1 R2 R3(TX0~4=0) R4*/
+ {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
+ {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
+ {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
+ {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
+ {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
+ {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
+ {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
+ {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
+ {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
+ {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
+ {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
+ {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
+ {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
+ {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
+
+ /* 802.11 UNI / HyperLan 2*/
+ {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
+ {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
+ {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
+ {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
+ {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
+ {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
+ {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
+ {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
+ {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
+ {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
+ {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
+ {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, /* Plugfest#4, Day4, change RFR3 left4th 9->5.*/
+
+ /* 802.11 HyperLan 2*/
+ {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
+
+ /* 2008.04.30 modified */
+ /* The system team has AN to improve the EVM value */
+ /* for channel 102 to 108 for the RT2850/RT2750 dual band solution.*/
+ {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
+ {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
+ {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
+
+ {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
+ {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
+ {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
+ {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
+ {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
+ {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
+ {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, /* 0x980ed1bb->0x980ed15b required by Rory 20070927*/
+ {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
+ {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
+ {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
+ {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
+ {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
+
+ /* 802.11 UNII*/
+ {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
+ {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
+ {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
+ {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
+ {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
+ {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
+ {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
+ {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f},
+ {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327},
+ {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307},
+ {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f},
+
+ /* Japan*/
+ {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
+ {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
+ {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
+ {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
+ {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
+ {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
+ {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
+
+ /* still lack of MMAC(Japan) ch 34,38,42,46*/
+};
+UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
+#endif /* defined(RT28xx) || defined(RT2883) */
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+
+/* The Tx power tuning entry*/
+const 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},
+};
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize specific beacon frame architecture.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpChipBcnSpecInit(RTMP_ADAPTER *pAd)
+{
+}
+
+
+/*
+========================================================================
+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;
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd))
+ {
+ pChipCap->BcnBase[0] = 0xC000;
+ pChipCap->BcnBase[1] = 0xC200;
+ pChipCap->BcnBase[2] = 0xC400;
+ pChipCap->BcnBase[3] = 0xC600;
+ pChipCap->BcnBase[4] = 0xC800;
+ pChipCap->BcnBase[5] = 0xCA00;
+ pChipCap->BcnBase[6] = 0xCC00;
+ pChipCap->BcnBase[7] = 0xCE00;
+ } else
+#endif /* MT7601 */
+ {
+ 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).
+ */
+#ifdef MT7601
+ if ( IS_MT7601(pAd))
+ pChipCap->WcidHwRsvNum = 127;
+ else
+#endif
+ if (pChipCap->BcnMaxNum == 8)
+ pChipCap->WcidHwRsvNum = 222;
+ else if (pChipCap->BcnMaxNum == 7)
+ pChipCap->WcidHwRsvNum = 238;
+ else
+ pChipCap->WcidHwRsvNum = 255;
+
+ pAd->chipOps.BeaconUpdate = RtmpChipWriteMemory;
+}
+
+
+#ifdef RLT_MAC
+/*
+========================================================================
+Routine Description:
+ Initialize specific beacon frame architecture.
+
+Arguments:
+ pAd - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID rlt_bcn_buf_init(RTMP_ADAPTER *pAd)
+{
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ pChipCap->FlgIsSupSpecBcnBuf = FALSE;
+ pChipCap->BcnMaxHwNum = 16;
+#ifdef MT7601
+ if ( IS_MT7601(pAd))
+ pChipCap->WcidHwRsvNum = 127;
+ else
+#endif
+ 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 = (pChipCap->BcnMaxHwNum - MAX_MESH_NUM);
+#endif /* APCLI_SUPPORT */
+
+ pChipCap->BcnMaxHwSize = 0x2000;
+
+ pChipCap->BcnBase[0] = 0xc000;
+ pChipCap->BcnBase[1] = 0xc200;
+ pChipCap->BcnBase[2] = 0xc400;
+ pChipCap->BcnBase[3] = 0xc600;
+ pChipCap->BcnBase[4] = 0xc800;
+ pChipCap->BcnBase[5] = 0xca00;
+ pChipCap->BcnBase[6] = 0xcc00;
+ pChipCap->BcnBase[7] = 0xce00;
+ pChipCap->BcnBase[8] = 0xd000;
+ pChipCap->BcnBase[9] = 0xd200;
+ pChipCap->BcnBase[10] = 0xd400;
+ pChipCap->BcnBase[11] = 0xd600;
+ pChipCap->BcnBase[12] = 0xd800;
+ pChipCap->BcnBase[13] = 0xda00;
+ pChipCap->BcnBase[14] = 0xdc00;
+ pChipCap->BcnBase[15] = 0xde00;
+
+#ifdef CONFIG_MULTI_CHANNEL
+ /* Record HW Null Frame offset */
+ //pAd->NullBufOffset[0] = 0xd000;
+ pAd->NullBufOffset[0] = 0xd000;
+ pAd->NullBufOffset[1] = 0xd200;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ pAd->chipOps.BeaconUpdate = RtmpChipWriteMemory;
+}
+#endif /* RLT_MAC */
+
+
+/*
+========================================================================
+Routine Description:
+ write high memory.
+ if firmware do not support auto high/low memory switching, we should switch to high memory by ourself.
+
+Arguments:
+ pAd - WLAN control block pointer
+ Offset - Memory offsets
+ Value - Written value
+ Unit - Unit in "Byte"
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpChipWriteHighMemory(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN UINT32 Value,
+ IN UINT8 Unit)
+{
+#ifdef RTMP_MAC_USB
+ switch(Unit)
+ {
+ case 1:
+ RTUSBSingleWrite(pAd, Offset, Value, TRUE);
+ break;
+ case 2:
+ {
+ UINT16 ShortVal = (UINT16)Value;
+ RTUSBMultiWrite(pAd, Offset, (UCHAR *) &ShortVal, 2, TRUE);
+ break;
+ }
+ case 4:
+ RTUSBWriteMACRegister(pAd, Offset, Value, TRUE);
+ default:
+ break;
+ }
+#endif /* RTMP_MAC_USB */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ write memory
+
+Arguments:
+ pAd - WLAN control block pointer
+ Offset - Memory offsets
+ Value - Written value
+ Unit - Unit in "Byte"
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpChipWriteMemory(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN UINT32 Value,
+ IN UINT8 Unit)
+{
+ switch(Unit)
+ {
+ case 1:
+ RTMP_IO_WRITE8(pAd, Offset, Value);
+ break;
+ case 2:
+ RTMP_IO_WRITE16(pAd, Offset, Value);
+ break;
+ case 4:
+ RTMP_IO_WRITE32(pAd, Offset, Value);
+ default:
+ break;
+ }
+}
+
+
+#ifdef GREENAP_SUPPORT
+static VOID EnableAPMIMOPSv2(RTMP_ADAPTER *pAd, BOOLEAN ReduceCorePower)
+ {
+ rtmp_bbp_set_mmps(pAd, ReduceCorePower);
+ rtmp_mac_set_mmps(pAd, ReduceCorePower);
+
+ DBGPRINT(RT_DEBUG_INFO, ("EnableAPMIMOPSNew, 30xx changes the # of antenna to 1\n"));
+ }
+
+
+static VOID DisableAPMIMOPSv2(RTMP_ADAPTER *pAd)
+ {
+ rtmp_bbp_set_mmps(pAd, FALSE);
+ rtmp_mac_set_mmps(pAd, FALSE);
+
+ DBGPRINT(RT_DEBUG_INFO, ("DisableAPMIMOPSNew, 30xx reserve only one antenna\n"));
+}
+
+
+static VOID EnableAPMIMOPSv1(
+ IN RTMP_ADAPTER *pAd,
+ IN BOOLEAN ReduceCorePower)
+{
+ UCHAR BBPR3 = 0,BBPR1 = 0;
+ ULONG TxPinCfg = 0x00050F0A;/*Gary 2007/08/09 0x050A0A*/
+ UCHAR BBPR4=0;
+ UCHAR CentralChannel;
+
+
+
+ if(pAd->CommonCfg.Channel>14)
+ TxPinCfg=0x00050F05;
+
+ TxPinCfg &= 0xFFFFFFF3;
+ TxPinCfg &= 0xFFFFF3FF;
+ pAd->ApCfg.bGreenAPActive=TRUE;
+
+ CentralChannel = pAd->CommonCfg.CentralChannel;
+ DBGPRINT(RT_DEBUG_INFO, ("Run with BW_20\n"));
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ CentralChannel = pAd->CommonCfg.Channel;
+
+ /* Set BBP registers to BW20 */
+ rtmp_bbp_set_bw(pAd, BW_20);
+
+ /* RF Bandwidth related registers would be set in AsicSwitchChannel() */
+ if (pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)
+ {
+ /*Tx/Rx Stream*/
+ rtmp_bbp_set_txdac(pAd, 0);
+ rtmp_bbp_set_rxpath(pAd, 1);
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+ }
+ AsicSwitchChannel(pAd, CentralChannel, FALSE);
+
+ DBGPRINT(RT_DEBUG_INFO, ("EnableAPMIMOPS, 305x/28xx changes the # of antenna to 1\n"));
+}
+
+
+static VOID DisableAPMIMOPSv1(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BBPR3=0,BBPR1=0;
+ ULONG TxPinCfg = 0x00050F0A; /* Gary 2007/08/09 0x050A0A */
+ UCHAR CentralChannel;
+ UINT32 Value=0;
+
+
+
+ if(pAd->CommonCfg.Channel>14)
+ TxPinCfg=0x00050F05;
+ /* 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;
+
+ pAd->ApCfg.bGreenAPActive=FALSE;
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (pAd->CommonCfg.Channel != 14))
+ {
+ INT ext_ch = EXTCHA_NONE;
+
+ DBGPRINT(RT_DEBUG_INFO, ("Run with BW_40\n"));
+ /* Set CentralChannel to work for BW40 */
+ if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ ext_ch = EXTCHA_ABOVE;
+ }
+ else if ((pAd->CommonCfg.Channel > 2) && (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW))
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ ext_ch = EXTCHA_BELOW;
+ }
+ CentralChannel = pAd->CommonCfg.CentralChannel;
+ AsicSetChannel(pAd, CentralChannel, BW_40, ext_ch, FALSE);
+ }
+
+ /*Tx Stream*/
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) && (pAd->Antenna.field.TxPath == 2))
+ rtmp_bbp_set_txdac(pAd, 2);
+ else
+ rtmp_bbp_set_txdac(pAd, 0);
+
+ /*Rx Stream*/
+ rtmp_bbp_set_rxpath(pAd, pAd->Antenna.field.RxPath);
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+
+ DBGPRINT(RT_DEBUG_INFO, ("DisableAPMIMOPS, 305x/28xx reserve only one antenna\n"));
+}
+#endif /* GREENAP_SUPPORT */
+
+
+static VOID RxSensitivityTuning(RTMP_ADAPTER *pAd)
+{
+ UCHAR R66 = 0x26 + GET_LNA_GAIN(pAd);
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+#endif /* RALINK_ATE */
+ {
+ rtmp_bbp_set_agc(pAd, R66, RX_CHAIN_ALL);
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
+}
+
+
+
+
+static VOID ChipBBPAdjust(RTMP_ADAPTER *pAd)
+{
+ UCHAR rf_bw, ext_ch;
+ UCHAR bbp_val;
+
+#ifdef DOT11_N_SUPPORT
+ if (get_ht_cent_ch(pAd, &rf_bw, &ext_ch) == FALSE)
+#endif /* DOT11_N_SUPPORT */
+ {
+ rf_bw = BW_20;
+ ext_ch = EXTCHA_NONE;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ }
+
+ rtmp_bbp_set_bw(pAd, rf_bw);
+
+ /* TX/RX : control channel setting */
+ rtmp_mac_set_ctrlch(pAd, ext_ch);
+ rtmp_bbp_set_ctrlch(pAd, ext_ch);
+
+ /* request by Gary 20070208 for middle and long range G Band*/
+#ifdef DOT11_N_SUPPORT
+ if (rf_bw == BW_40)
+ bbp_val = (pAd->CommonCfg.Channel > 14) ? 0x48 : 0x38;
+ else
+#endif /* DOT11_N_SUPPORT */
+ bbp_val = (pAd->CommonCfg.Channel > 14) ? 0x40 : 0x38;
+ rtmp_bbp_set_agc(pAd, bbp_val, RX_CHAIN_ALL);
+
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+#ifdef RT28xx
+ RT28xx_ch_tunning(pAd, BW_40);
+#endif /* RT28xx */
+ }
+ 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, ("%s(): BW_%s, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n",
+ __FUNCTION__, (rf_bw == BW_40 ? "40" : "20"),
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth,
+ pAd->CommonCfg.Channel,
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA,
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset));
+
+ /* request by Gary 20070208 for middle and long range A Band*/
+ if (pAd->CommonCfg.Channel > 14)
+ bbp_val = 0x1D;
+ else
+ bbp_val = 0x2D;
+ 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 Default_ChipSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan)
+{
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): dummy channel switch function!\n", __FUNCTION__));
+}
+
+
+static VOID Default_ChipAGCInit(RTMP_ADAPTER *pAd, UCHAR BandWidth)
+{
+ UCHAR R66 = 0x30, lan_gain;
+
+ lan_gain = GET_LNA_GAIN(pAd);
+ if (pAd->LatchRfRegs.Channel <= 14)
+ { // BG band
+ {
+ R66 = 0x2E + lan_gain;
+ }
+ }
+ else
+ { //A band
+ {
+ if (BandWidth == BW_20)
+ R66 = (UCHAR)(0x32 + (lan_gain * 5) / 3);
+#ifdef DOT11_N_SUPPORT
+ else
+ R66 = (UCHAR)(0x3A + (lan_gain * 5) / 3);
+#endif // DOT11_N_SUPPORT //
+ }
+ }
+ rtmp_bbp_set_agc(pAd, R66, RX_CHAIN_ALL);
+
+}
+
+
+static VOID AsicAntennaDefaultReset(
+ IN PRTMP_ADAPTER pAd,
+ IN EEPROM_ANTENNA_STRUC *pAntenna)
+{
+ {
+
+ 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));
+}
+
+
+VOID NetDevNickNameInit(
+ IN PRTMP_ADAPTER pAd)
+{
+}
+
+
+
+
+#ifdef HW_ANTENNA_DIVERSITY_SUPPORT
+UINT32 SetHWAntennaDivsersity(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN Enable)
+{
+ if (Enable == TRUE)
+ {
+ UINT8 BBPValue = 0, RFValue = 0;
+ USHORT value;
+
+ // RF_R29 bit7:6
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_GAIN, value);
+
+ RT30xxReadRFRegister(pAd, RF_R29, &RFValue);
+ RFValue &= 0x3f; // clear bit7:6
+ RFValue |= (value << 6);
+ RT30xxWriteRFRegister(pAd, RF_R29, RFValue);
+
+ // BBP_R47 bit7=1
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BBPValue);
+ BBPValue |= 0x80;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BBPValue);
+
+ BBPValue = 0xbe;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, BBPValue);
+ BBPValue = 0xb0;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, BBPValue);
+ BBPValue = 0x23;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue);
+ BBPValue = 0x3a;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R153, BBPValue);
+ BBPValue = 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, BBPValue);
+ BBPValue = 0x3b;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R155, BBPValue);
+ BBPValue = 0x04;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R253, BBPValue);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HwAnDi> Enable!\n"));
+ }
+ else
+ {
+ UINT8 BBPValue = 0;
+
+ /*
+ main antenna: BBP_R152 bit7=1
+ aux antenna: BBP_R152 bit7=0
+ */
+ if (pAd->FixDefaultAntenna == 0)
+ {
+ /* fix to main antenna */
+ /* do not care BBP R153, R155, R253 */
+ BBPValue = 0x3e;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, BBPValue);
+ BBPValue = 0x30;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, BBPValue);
+ BBPValue = 0x23;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue);
+ BBPValue = 0x00;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, BBPValue);
+ }
+ else
+ {
+ /* fix to aux antenna */
+ /* do not care BBP R153, R155, R253 */
+ BBPValue = 0x3e;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, BBPValue);
+ BBPValue = 0x30;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, BBPValue);
+ BBPValue = 0xa3;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BBPValue);
+ BBPValue = 0x00;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, BBPValue);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HwAnDi> Disable!\n"));
+ }
+
+ return 0;
+}
+#endif // HW_ANTENNA_DIVERSITY_SUPPORT //
+
+
+
+
+INT WaitForAsicReady(
+ IN RTMP_ADAPTER *pAd)
+{
+ UINT32 mac_val = 0, reg = MAC_CSR0;
+ int idx = 0;
+
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ reg = ASIC_VERSION;
+#endif /* RT3290 */
+ do
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+
+ RTMP_IO_READ32(pAd, reg, &mac_val);
+ if ((mac_val != 0x00) && (mac_val != 0xFFFFFFFF))
+ return TRUE;
+
+ RTMPusecDelay(10);
+ } while (idx++ < 100);
+
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("%s(0x%x):AsicNotReady!\n",
+ __FUNCTION__, mac_val));
+
+ return TRUE;
+}
+
+
+INT AsicGetMacVersion(
+ IN RTMP_ADAPTER *pAd)
+{
+ UINT32 reg = MAC_CSR0;
+
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ reg = 0x0;
+#endif /* RT3290 */
+
+ if (WaitForAsicReady(pAd) == TRUE)
+ {
+ RTMP_IO_READ32(pAd, reg, &pAd->MACVersion);
+ DBGPRINT(RT_DEBUG_OFF, ("MACVersion[Ver:Rev]=0x%08x\n",
+ pAd->MACVersion));
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s() failed!\n", __FUNCTION__));
+ return FALSE;
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize chip related information.
+
+Arguments:
+ pCB - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpChipOpsHook(VOID *pCB)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pCB;
+ RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ UINT32 MacValue;
+
+
+ /* sanity check */
+ WaitForAsicReady(pAd);
+ RTMP_IO_READ32(pAd, MAC_CSR0, &MacValue);
+ pAd->MACVersion = MacValue;
+
+ /* default init */
+ RTMP_DRS_ALG_INIT(pAd, RATE_ALG_LEGACY);
+
+
+
+
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ {
+ RT3290_Init(pAd);
+ goto done;
+ }
+#endif /* RT290 */
+
+#ifdef RT8592
+ if (IS_RT8592(pAd)) {
+ RT85592_Init(pAd);
+ goto done;
+ }
+#endif /* RT8592 */
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd)) {
+ RT6590_Init(pAd);
+ goto done;
+ }
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd)) {
+ MT7601_Init(pAd);
+ goto done;
+ }
+#endif /* MT7601 */
+
+#ifdef GREENAP_SUPPORT
+ pChipOps->EnableAPMIMOPS = EnableAPMIMOPSv1;
+ pChipOps->DisableAPMIMOPS = DisableAPMIMOPSv1;
+#endif /* GREENAP_SUPPORT */
+
+ /* 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;
+ pChipCap->TXWISize = 16;
+ pChipCap->RXWISize = 16;
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+ pChipCap->TxPowerTuningTable_2G = TxPowerTuningTableOrg;
+#ifdef A_BAND_SUPPORT
+ pChipCap->TxPowerTuningTable_5G = TxPowerTuningTableOrg;
+#endif /* A_BAND_SUPPORT */
+#endif /* defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION) */
+ pChipOps->AsicMacInit = NULL;
+ pChipOps->AsicBbpInit = NULL;
+ pChipOps->AsicRfInit = NULL;
+
+#ifdef RTMP_EFUSE_SUPPORT
+ pChipCap->EFUSE_USAGE_MAP_START = 0x2d0;
+ pChipCap->EFUSE_USAGE_MAP_END = 0x2fc;
+ pChipCap->EFUSE_USAGE_MAP_SIZE = 45;
+#endif /* RTMP_EFUSE_SUPPORT */
+
+ pChipCap->VcoPeriod = 10;
+ pChipCap->FlgIsVcoReCalMode = VCO_CAL_DISABLE;
+ pChipCap->WPDMABurstSIZE = 2; /* default 64B */
+ pChipCap->MBSSIDMode = MBSSID_MODE0;
+
+
+ RtmpChipBcnInit(pAd);
+
+ pChipOps->RxSensitivityTuning = RxSensitivityTuning;
+ pChipOps->ChipBBPAdjust = ChipBBPAdjust;
+ pChipOps->ChipSwitchChannel = Default_ChipSwitchChannel;
+
+ /* TX ALC */
+ pChipCap->bTempCompTxALC = FALSE;
+ pChipOps->AsicGetTxPowerOffset = NULL;
+ pChipOps->InitDesiredTSSITable = NULL;
+ pChipOps->AsicTxAlcGetAutoAgcOffset = NULL;
+ pChipOps->AsicExtraPowerOverMAC = NULL;
+
+ pChipOps->ChipAGCInit = Default_ChipAGCInit;
+ 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;
+
+ pChipOps->InitTemperCompensation = NULL;
+ pChipOps->TemperCompensation = NULL;
+
+#ifdef RT28xx
+ pChipOps->ChipSwitchChannel = RT28xx_ChipSwitchChannel;
+#endif /* RT28xx */
+#ifdef CARRIER_DETECTION_SUPPORT
+ pChipCap->carrier_func = DISABLE_TONE_RADAR;
+ pChipOps->ToneRadarProgram = NULL;
+#endif /* CARRIER_DETECTOIN_SUPPORT */
+#ifdef DFS_SUPPORT
+ pChipCap->DfsEngineNum = 4;
+#endif /* DFS_SUPPORT */
+ pChipOps->CckMrcStatusCtrl = NULL;
+ pChipOps->RadarGLRTCompensate = NULL;
+
+
+ /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
+
+
+
+#if defined(RT3883) || defined(RT3290) || defined(RT65xx) || defined(MT7601)
+done:
+#endif /* defined(RT3883) || defined(RT3290) || defined(RT65xx) || define(MT7601) */
+ DBGPRINT(RT_DEBUG_TRACE, ("Chip specific bbpRegTbSize=%d!\n", pChipCap->bbpRegTbSize));
+ DBGPRINT(RT_DEBUG_TRACE, ("Chip VCO calibration mode = %d!\n", pChipCap->FlgIsVcoReCalMode));
+}
diff --git a/cleopatre/devkit/mt7601udrv/common/action.c b/cleopatre/devkit/mt7601udrv/common/action.c
new file mode 100644
index 0000000000..945b902ad5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/action.c
@@ -0,0 +1,1126 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ action.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 2006 created for rt2860
+ */
+
+#include "rt_config.h"
+#include "action.h"
+
+extern UCHAR ZeroSsid[32];
+
+
+static VOID ReservedAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ Note:
+ The state machine looks like the following
+
+ ASSOC_IDLE
+ MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
+ MT2_PEER_DISASSOC_REQ peer_disassoc_action
+ MT2_PEER_ASSOC_REQ drop
+ MT2_PEER_REASSOC_REQ drop
+ MT2_CLS3ERR cls3err_action
+ ==========================================================================
+ */
+VOID ActionStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
+#ifdef QOS_DLS_SUPPORT
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction);
+#endif /* QOS_DLS_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+#endif /* DOT11_N_SUPPORT */
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
+
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+}
+
+#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;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[pInfo->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[pInfo->Wcid].MatchAPCLITabIdx;
+ ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, pInfo->pAddr);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ apidx = pAd->MacTab.Content[pInfo->Wcid].apidx;
+ ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+ }
+ }
+#endif /* CONFIG_AP_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];
+
+#ifdef UNALIGNMENT_SUPPORT
+ {
+ BA_PARM tmpBaParm;
+
+ NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&Frame.BaParm), sizeof(BA_PARM));
+ *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm));
+ NdisMoveMemory((PUCHAR)(&Frame.BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM));
+ }
+#else
+ *(USHORT *)(&(Frame.BaParm)) = cpu2le16((*(USHORT *)(&(Frame.BaParm))));
+#endif /* UNALIGNMENT_SUPPORT */
+
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[pInfo->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[pInfo->Wcid].MatchAPCLITabIdx;
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ apidx = pAd->MacTab.Content[pInfo->Wcid].apidx;
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->ApCfg.MBSSID[apidx].Bssid);
+ }
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[pInfo->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[pInfo->Wcid].MatchAPCLITabIdx;
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ apidx = pAd->MacTab.Content[pInfo->Wcid].apidx;
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+ }
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APPeerDlsReqAction(pAd, Elem);
+#endif /* CONFIG_AP_SUPPORT */
+ break;
+
+ case ACTION_DLS_RESPONSE:
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APPeerDlsRspAction(pAd, Elem);
+#endif /* CONFIG_AP_SUPPORT */
+ break;
+
+ case ACTION_DLS_TEARDOWN:
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APPeerDlsTearDownAction(pAd, Elem);
+#endif /* CONFIG_AP_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_AP_SUPPORT
+extern UCHAR get_regulatory_class(IN PRTMP_ADAPTER pAd);
+
+VOID ApPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+ BSS_2040_COEXIST_IE BssCoexist;
+
+ /* Format as in IEEE 7.4.7.2*/
+ if (Action == ACTION_BSS_2040_COEXIST)
+ {
+ BssCoexist.word = Elem->Msg[LENGTH_802_11+2];
+ }
+}
+
+
+VOID SendBSS2040CoexistMgmtAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx,
+ IN UCHAR InfoReq)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ FRAME_ACTION_HDR Frame;
+ ULONG FrameLen;
+ BSS_2040_COEXIST_ELEMENT BssCoexistInfo;
+ BSS_2040_INTOLERANT_CH_REPORT BssIntolerantInfo;
+ PUCHAR pAddr1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SendBSS2040CoexistMgmtAction(): Wcid=%d, apidx=%d, InfoReq=%d!\n", Wcid, apidx, InfoReq));
+
+ NdisZeroMemory((PUCHAR)&BssCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
+ NdisZeroMemory((PUCHAR)&BssIntolerantInfo, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
+
+ BssCoexistInfo.ElementID = IE_2040_BSS_COEXIST;
+ BssCoexistInfo.Len = 1;
+ BssCoexistInfo.BssCoexistIe.word = pAd->CommonCfg.LastBSSCoexist2040.word;
+ BssCoexistInfo.BssCoexistIe.field.InfoReq = InfoReq;
+ BssIntolerantInfo.ElementID = IE_2040_BSS_INTOLERANT_REPORT;
+ BssIntolerantInfo.Len = 1;
+ BssIntolerantInfo.RegulatoryClass = get_regulatory_class(pAd);
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - SendBSS2040CoexistMgmtAction() allocate memory failed \n"));
+ return;
+ }
+
+ if (Wcid == MCAST_WCID)
+ pAddr1 = &BROADCAST_ADDR[0];
+ else
+ pAddr1 = pAd->MacTab.Content[Wcid].Addr;
+ ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+
+ Frame.Category = CATEGORY_PUBLIC;
+ Frame.Action = ACTION_BSS_2040_COEXIST;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ACTION_HDR), &Frame,
+ sizeof(BSS_2040_COEXIST_ELEMENT), &BssCoexistInfo,
+ sizeof(BSS_2040_INTOLERANT_CH_REPORT), &BssIntolerantInfo,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - SendBSS2040CoexistMgmtAction( BSSCoexist2040 = 0x%x ) \n", BssCoexistInfo.BssCoexistIe.word));
+
+}
+
+#endif /* CONFIG_AP_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 rf_channel = 0, rf_bw;
+
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s(): NewChannel=%d, Secondary=%d\n",
+ __FUNCTION__, NewChannel, Secondary));
+
+ if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
+ return;
+
+ pAd->CommonCfg.Channel = NewChannel;
+ if (Secondary == EXTCHA_NONE)
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
+
+ rf_bw = BW_20;
+ rf_channel = pAd->CommonCfg.Channel;
+ }
+ /* 1. Switches to BW = 40 And Station supports BW = 40.*/
+ else if (((Secondary == EXTCHA_ABOVE) || (Secondary == EXTCHA_BELOW)) &&
+ (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)
+ )
+ {
+ rf_bw = BW_40;
+#ifdef GREENAP_SUPPORT
+ if (pAd->ApCfg.bGreenAPActive == 1)
+ {
+ rf_bw = BW_20;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ }
+ else
+#endif /* GREENAP_SUPPORT */
+ if (Secondary == EXTCHA_ABOVE)
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ else
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+
+ rf_channel = pAd->CommonCfg.CentralChannel;
+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
+ }
+
+ if (rf_channel != 0) {
+ AsicSetChannel(pAd, rf_channel, rf_bw, Secondary, FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): %dMHz LINK UP, CtrlChannel=%d, CentralChannel= %d \n",
+ __FUNCTION__, (rf_bw == BW_40 ? 40 : 20),
+ pAd->CommonCfg.Channel,
+ pAd->CommonCfg.CentralChannel));
+ }
+}
+#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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ BOOLEAN bNeedFallBack = FALSE;
+
+ /*ApPublicAction(pAd, Elem);*/
+ if ((pBssCoexistIe->field.BSS20WidthReq ==1) || (pBssCoexistIe->field.Intolerant40 == 1))
+ {
+ bNeedFallBack = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSS_2040_COEXIST: BSS20WidthReq=%d, Intolerant40=%d!\n", pBssCoexistIe->field.BSS20WidthReq, pBssCoexistIe->field.Intolerant40));
+ }
+ else if ((pIntolerantReport) && (pIntolerantReport->Len > 1)
+ /*&& (pIntolerantReport->RegulatoryClass == get_regulatory_class(pAd))*/)
+ {
+ int i;
+ UCHAR *ptr;
+ INT retVal;
+ BSS_COEX_CH_RANGE coexChRange;
+
+ ptr = pIntolerantReport->ChList;
+ bNeedFallBack = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("The pIntolerantReport len = %d, chlist=", pIntolerantReport->Len));
+ for(i =0 ; i < (pIntolerantReport->Len -1); i++, ptr++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%d,", *ptr));
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+
+ retVal = GetBssCoexEffectedChRange(pAd, &coexChRange);
+ if (retVal == TRUE)
+ {
+ ptr = pIntolerantReport->ChList;
+ bNeedFallBack = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Check IntolerantReport Channel List in our effectedChList(%d~%d)\n",
+ pAd->ChannelList[coexChRange.effectChStart].Channel,
+ pAd->ChannelList[coexChRange.effectChEnd].Channel));
+ for(i =0 ; i < (pIntolerantReport->Len -1); i++, ptr++)
+ {
+ UCHAR chEntry;
+
+ chEntry = *ptr;
+ if (chEntry >= pAd->ChannelList[coexChRange.effectChStart].Channel &&
+ chEntry <= pAd->ChannelList[coexChRange.effectChEnd].Channel)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Found Intolerant channel in effect range=%d!\n", *ptr));
+ bNeedFallBack = TRUE;
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("After CoexChRange Check, bNeedFallBack=%d!\n", bNeedFallBack));
+ }
+
+ if (bNeedFallBack)
+ {
+ pBssCoexistIe->field.Intolerant40 = 1;
+ pBssCoexistIe->field.BSS20WidthReq = 1;
+ }
+ }
+
+ if (bNeedFallBack)
+ {
+ int apidx;
+
+ NdisMoveMemory((PUCHAR)&pAd->CommonCfg.LastBSSCoexist2040, (PUCHAR)pBssCoexistIe, sizeof(BSS_2040_COEXIST_IE));
+ pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC;
+
+ if (!(pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_TIMER_FIRED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Fire the Bss2040CoexistTimer with timeout=%ld!\n",
+ pAd->CommonCfg.Dot11BssWidthChanTranDelay));
+
+ pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_TIMER_FIRED;
+ /* More 5 sec for the scan report of STAs.*/
+ RTMPSetTimer(&pAd->CommonCfg.Bss2040CoexistTimer, (pAd->CommonCfg.Dot11BssWidthChanTranDelay + 5) * 1000);
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Already fallback to 20MHz, Extend the timeout of Bss2040CoexistTimer!\n"));
+ /* More 5 sec for the scan report of STAs.*/
+ RTMPModTimer(&pAd->CommonCfg.Bss2040CoexistTimer, (pAd->CommonCfg.Dot11BssWidthChanTranDelay + 5) * 1000);
+ }
+
+ apidx = pAd->MacTab.Content[Elem->Wcid].apidx;
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ SendBSS2040CoexistMgmtAction(pAd, MCAST_WCID, apidx, 0);
+ }
+
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ break;
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+ case ACTION_WIFI_DIRECT:
+
+ break;
+
+
+ default:
+ break;
+ }
+
+}
+
+
+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)
+
+{
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+ INT apidx;
+#endif /* CONFIG_AP_SUPPORT */
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[Elem->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[Elem->Wcid].MatchAPCLITabIdx;
+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, pAddr);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ apidx = pAd->MacTab.Content[Elem->Wcid].apidx;
+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+ }
+ }
+#endif /* CONFIG_AP_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);
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID SendNotifyBWActionFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ FRAME_ACTION_HDR Frame;
+ ULONG FrameLen;
+ PUCHAR pAddr1;
+
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
+ return;
+ }
+
+ if (Wcid == MCAST_WCID)
+ pAddr1 = &BROADCAST_ADDR[0];
+ else
+ pAddr1 = pAd->MacTab.Content[Wcid].Addr;
+
+ ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+
+ Frame.Category = CATEGORY_HT;
+ Frame.Action = NOTIFY_BW_ACTION;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ACTION_HDR), &Frame,
+ END_OF_ARGS);
+
+ *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+ FrameLen++;
+
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
+
+}
+#endif /* DOT11N_DRAFT3 */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+VOID PeerHTAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+ MAC_TABLE_ENTRY *pEntry;
+
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ pEntry = &pAd->MacTab.Content[Elem->Wcid];
+
+ switch(Action)
+ {
+ case NOTIFY_BW_ACTION:
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
+
+ if (Elem->Msg[LENGTH_802_11+2] == 0) /* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */
+ pEntry->HTPhyMode.field.BW = 0;
+ else
+ {
+ pEntry->HTPhyMode.field.BW = pEntry->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))
+ pEntry->MmpsMode = MMPS_ENABLE;
+ else if (((Elem->Msg[LENGTH_802_11+2] & 0x2) == 0))
+ pEntry->MmpsMode = MMPS_STATIC;
+ else
+ pEntry->MmpsMode = MMPS_DYNAMIC;
+
+ DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pEntry->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);
+ }
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (pHT_info->Forty_MHz_Intolerant)
+ {
+ Handle_BSS_Width_Trigger_Events(pAd);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ 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 <MAX_LEN_OF_BA_ORI_TABLE) && (total > 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 <NUM_OF_TID; i++)
+ {
+ idx = pEntry->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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].CurrentAddress);
+ else
+#endif /* APCLI_SUPPORT */
+ BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function.*/
+ FrameBar.StartingSeq.field.StartSeq = Sequence; /* make sure sequence not clear in DEL funciton.*/
+ FrameBar.BarControl.TID = TID; /* make sure sequence not clear in DEL funciton.*/
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_BAR), &FrameBar,
+ END_OF_ARGS);
+ /*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))*/
+ if (1) /* Now we always send BAR.*/
+ {
+ /*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);*/
+ MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[TID]), pOutBuffer, FrameLen);
+
+ }
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ }
+}
+#endif /* DOT11_N_SUPPORT */
+
+VOID ActHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN PUCHAR Addr1,
+ IN PUCHAR Addr2,
+ IN PUCHAR Addr3)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SUBTYPE_ACTION;
+
+ COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
+ COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
+ COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
+}
+
+VOID BarHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PFRAME_BAR pCntlBar,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA)
+{
+/* USHORT Duration;*/
+
+ NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
+ pCntlBar->FC.Type = BTYPE_CNTL;
+ pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
+ pCntlBar->BarControl.MTID = 0;
+ pCntlBar->BarControl.Compressed = 1;
+ pCntlBar->BarControl.ACKPolicy = 0;
+
+
+ pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
+
+ COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
+ COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Insert Category and action code into the action frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. category code of the frame.
+ 4. action code of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID InsertActField(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 Category,
+ IN UINT8 ActCode)
+{
+ ULONG TempLen;
+
+ MakeOutgoingFrame( pFrameBuf, &TempLen,
+ 1, &Category,
+ 1, &ActCode,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
diff --git a/cleopatre/devkit/mt7601udrv/common/ba_action.c b/cleopatre/devkit/mt7601udrv/common/ba_action.c
new file mode 100644
index 0000000000..cc7211f013
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/ba_action.c
@@ -0,0 +1,2190 @@
+#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;
+
+
+ if (CLIENT_STATUS_TEST_FLAG(pEntryPeer, fCLIENT_STATUS_RALINK_CHIPSET))
+ MaxPeerRxSize = (1 << (pEntryPeer->MaxRAmpduFactor + 3)); /* (2^(13 + exp)) / 2048 bytes */
+ else
+ MaxPeerRxSize = (((1 << (pEntryPeer->MaxRAmpduFactor + 3)) * 10) / 16) -1;
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ MaxSize = 31;
+ else
+#endif /* RT65xx */
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ MaxSize = 21;
+ else
+#endif /* MT7601 */
+ 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) /* 2880e */
+ {
+ if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
+ MaxSize = 7; /* for non-open mode */
+ else
+ MaxSize = 13;
+ }
+ else
+ MaxSize = 7;
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AP_ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
+#endif /* CONFIG_AP_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; i<num; i++)
+ {
+ /* get mpdu_blk */
+ mpdu_blk = (struct reordering_mpdu *) mem;
+ /* initial mpdu_blk */
+ NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
+ /* next mpdu_blk */
+ mem += sizeof(struct reordering_mpdu);
+ /* insert mpdu_blk into freelist */
+ ba_enqueue(freelist, mpdu_blk);
+ }
+
+ return(TRUE);
+}
+
+/* static int blk_count=0; sample take off, no use */
+
+static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
+{
+ struct reordering_mpdu *mpdu_blk;
+
+ NdisAcquireSpinLock(&pAd->mpdu_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_OFF, ("%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<<TID)) && (isForced == FALSE))
+ {
+ /* try again after 3 secs*/
+ DelayTime = 3000;
+/* DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n"));*/
+/* return;*/
+ }
+
+
+ Idx = pEntry->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<<TID)))
+ {
+ RTMPInitTimer(pAd, &pBAEntry->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;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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<<TID);
+ RTMPCancelTimer(&pBAEntry->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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[pBAEntry->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[pBAEntry->Wcid].MatchAPCLITabIdx;
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(&pAd->MacTab.Content[pBAEntry->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[pBAEntry->Wcid].MatchWDSTabIdx;
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid);
+ }
+ else
+#endif /* WDS_SUPPORT */
+ {
+ apidx = pAd->MacTab.Content[pBAEntry->Wcid].apidx;
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->ApCfg.MBSSID[apidx].Bssid);
+ }
+ }
+#endif /* CONFIG_AP_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<<TID))
+ {
+ RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+ }
+ else
+ {
+ RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
+ }
+
+
+ /* Set Bitmap flag.*/
+ pEntry->RXBAbitmap |= (1<<TID);
+ pEntry->BARecWcidArray[TID] = Idx;
+
+ pEntry->BADeclineBitmap &= ~(1<<TID);
+
+ /* Set BA session mask in WCID table.*/
+ RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->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; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
+ {
+ pBAEntry =&pAd->BATable.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; i<NUM_OF_TID; i++)
+ {
+ BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
+ BARecSessionTearDown(pAd, Wcid, i, FALSE);
+ }
+}
+
+
+/*
+ ==========================================================================
+ 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 BAOriSessionSetupTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
+ MAC_TABLE_ENTRY *pEntry;
+ PRTMP_ADAPTER pAd;
+
+ if (pBAEntry == NULL)
+ return;
+
+ pAd = pBAEntry->pAdapter;
+
+
+#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;
+
+
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+ INT apidx;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[Elem->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[Elem->Wcid].MatchAPCLITabIdx;
+ ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, pAddr);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(&pAd->MacTab.Content[Elem->Wcid]))
+ {
+ apidx = pAd->MacTab.Content[Elem->Wcid].MatchWDSTabIdx;
+ ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid, pAddr);
+ }
+ else
+#endif /* WDS_SUPPORT */
+ {
+ apidx = pAd->MacTab.Content[Elem->Wcid].apidx;
+ ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+ }
+ }
+#endif /* CONFIG_AP_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; */
+
+#ifdef UNALIGNMENT_SUPPORT
+ {
+ BA_PARM tmpBaParm;
+
+ NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&ADDframe.BaParm), sizeof(BA_PARM));
+ *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm));
+ NdisMoveMemory((PUCHAR)(&ADDframe.BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM));
+ }
+#else
+ *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
+#endif /* UNALIGNMENT_SUPPORT */
+
+ 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)
+ )
+ {
+ pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->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;
+ FRAME_PSMP_ACTION Frame;
+ ULONG FrameLen;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[Wcid]))
+ {
+ apidx = pAd->MacTab.Content[Wcid].MatchAPCLITabIdx;
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(&pAd->MacTab.Content[Wcid]))
+ {
+ apidx = pAd->MacTab.Content[Wcid].MatchWDSTabIdx;
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid, pAd->MacTab.Content[Wcid].Addr);
+ }
+ else
+#endif /* WDS_SUPPORT */
+ {
+ apidx = pAd->MacTab.Content[Wcid].apidx;
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ Frame.Category = CATEGORY_HT;
+ Frame.Action = SMPS_ACTION;
+ switch (Psmp)
+ {
+ case MMPS_ENABLE:
+ Frame.Psmp = 0;
+ break;
+ case MMPS_DYNAMIC:
+ Frame.Psmp = 3;
+ break;
+ case MMPS_STATIC:
+ 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 _BEACON_REQUEST {
+ 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 _MEASUREMENT_REQ
+{
+ UCHAR ID;
+ UCHAR Length;
+ UCHAR Token;
+ UCHAR RequestMode;
+ UCHAR Type;
+} MEASUREMENT_REQ;
+
+#ifdef CONFIG_AP_SUPPORT
+VOID SendBeaconRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ FRAME_RM_REQ_ACTION Frame;
+ ULONG FrameLen;
+ BEACON_REQUEST BeaconReq;
+ MEASUREMENT_REQ MeasureReg;
+ UCHAR apidx;
+
+ if (IS_ENTRY_APCLI(&pAd->MacTab.Content[Wcid]))
+ return;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Radio - SendBeaconRequest() allocate memory failed \n"));
+ return;
+ }
+ apidx = pAd->MacTab.Content[Wcid].apidx;
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+
+ Frame.Category = CATEGORY_RM;
+ Frame.Action = RADIO_MEASUREMENT_REQUEST_ACTION;
+ Frame.Token = 1;
+ Frame.Repetition = 0; /* executed once*/
+
+ BeaconReq.RegulatoryClass = 32; /* ?????*/
+ BeaconReq.ChannelNumber = 255; /* all channels*/
+ BeaconReq.RandomInterval = 0;
+ BeaconReq.MeasurementDuration = 10; /* 10 TU*/
+ BeaconReq.MeasurementMode = 1; /* Active mode */
+ COPY_MAC_ADDR(BeaconReq.BSSID, BROADCAST_ADDR);
+ BeaconReq.ReportingCondition = 254; /* report not necesssary*/
+ BeaconReq.Threshold = 0; /* minimum RCPI*/
+ BeaconReq.SSIDIE[0] = 0;
+ BeaconReq.SSIDIE[1] = 0; /* wildcard SSID zero length */
+
+
+ MeasureReg.ID = IE_MEASUREMENT_REQUEST;
+ MeasureReg.Token = 0;
+ MeasureReg.RequestMode = 0;
+ MeasureReg.Type = 5; /* Beacon Request*/
+ MeasureReg.Length = sizeof(MEASUREMENT_REQ)+sizeof(BEACON_REQUEST)-2;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_RM_REQ_ACTION), &Frame,
+ sizeof(MEASUREMENT_REQ), &MeasureReg,
+ sizeof(BEACON_REQUEST), &BeaconReq,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE,("Radio - SendBeaconRequest\n"));
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ RTMP_AP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* maybe insert VLAN tag to the received packet */
+ UCHAR VLAN_Size = 0;
+ UCHAR *data_p;
+ USHORT VLAN_VID = 0, VLAN_Priority = 0;
+
+ /* VLAN related */
+ MBSS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+
+#ifdef WDS_VLAN_SUPPORT
+ if (VLAN_VID == 0) /* maybe WDS packet */
+ WDS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+#endif /* WDS_VLAN_SUPPORT */
+
+ if (VLAN_VID != 0)
+ VLAN_Size = LENGTH_802_1Q;
+
+ data_p = OS_PKT_HEAD_BUF_EXTEND(pRxPkt, LENGTH_802_3+VLAN_Size);
+ RT_VLAN_8023_HEADER_COPY(pAd, VLAN_VID, VLAN_Priority,
+ Header802_3, LENGTH_802_3,
+ data_p, FromWhichBSSID, TPID);
+ }
+#endif /* CONFIG_AP_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);
+
+#define INDICATE_LEGACY_OR_AMSDU_HDR_TRNS(_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_Hdr_Trns(_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);
+ }
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+static VOID ba_enqueue_reordering_packet_hdr_trns(
+ 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);
+
+
+ RTMP_OS_PKT_INIT(pRxBlk->pRxPacket,
+ get_netdev_from_bssid(pAd, FromWhichBSSID),
+ pRxBlk->pTransData, pRxBlk->TransDataSize);
+
+
+ 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_HDR_TRNS(pAd, pRxBlk, FromWhichBSSID);
+ }
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+/*
+ ==========================================================================
+ 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->RxWIWirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->RxWITID;
+
+
+ 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;
+ }
+ }
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+VOID Indicate_AMPDU_Packet_Hdr_Trns(
+ 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->RxWIWirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->RxWITID;
+
+
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->TransDataSize > 1514))
+ {
+ 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_HDR_TRNS(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_HDR_TRNS(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_HDR_TRNS(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_hdr_trns(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+ }
+
+ /* V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer*/
+ else
+ {
+ LONG WinStartSeq, TmpSeq;
+
+
+ printk("999999999\n");
+
+ 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_hdr_trns(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+
+ TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
+ if (TmpSeq != RESET_RCV_SEQ)
+ {
+ pBAEntry->LastIndSeq = TmpSeq;
+ }
+ }
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+VOID BaReOrderingBufferMaintain(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Now32;
+ UCHAR Wcid;
+ USHORT Idx;
+ UCHAR TID;
+ PBA_REC_ENTRY pBAEntry = NULL;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ /* update last rx time*/
+ NdisGetSystemUpTime(&Now32);
+
+ for (Wcid = 1; Wcid < MAX_LEN_OF_MAC_TABLE; Wcid++)
+ {
+ pEntry = &pAd->MacTab.Content[Wcid];
+ if (IS_ENTRY_NONE(pEntry))
+ continue;
+
+ for (TID= 0; TID < NUM_OF_TID; TID++)
+ {
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+ }
+ }
+}
+#endif /* DOT11_N_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/client_wds.c b/cleopatre/devkit/mt7601udrv/common/client_wds.c
new file mode 100644
index 0000000000..b5edbfc31a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/client_wds.c
@@ -0,0 +1,197 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ client_wds.c
+
+ Abstract:
+*/
+
+
+#ifdef CLIENT_WDS
+
+#include "rt_config.h"
+
+VOID CliWds_ProxyTabInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT idx;
+ ULONG i;
+
+ NdisAllocateSpinLock(pAd, &pAd->ApCfg.CliWdsTabLock);
+
+/* pAd->ApCfg.pCliWdsEntryPool = kmalloc(sizeof(CLIWDS_PROXY_ENTRY) * CLIWDS_POOL_SIZE, GFP_ATOMIC);*/
+ os_alloc_mem(pAd, (UCHAR **)&(pAd->ApCfg.pCliWdsEntryPool), sizeof(CLIWDS_PROXY_ENTRY) * CLIWDS_POOL_SIZE);
+ if (pAd->ApCfg.pCliWdsEntryPool)
+ {
+ NdisZeroMemory(pAd->ApCfg.pCliWdsEntryPool, sizeof(CLIWDS_PROXY_ENTRY) * CLIWDS_POOL_SIZE);
+ initList(&pAd->ApCfg.CliWdsEntryFreeList);
+ for (i = 0; i < CLIWDS_POOL_SIZE; i++)
+ insertTailList(&pAd->ApCfg.CliWdsEntryFreeList, (PLIST_ENTRY)(pAd->ApCfg.pCliWdsEntryPool + (ULONG)i));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pCliWdsEntryPool", __FUNCTION__));
+ }
+
+ for (idx = 0; idx < CLIWDS_HASH_TAB_SIZE; idx++)
+ initList(&pAd->ApCfg.CliWdsProxyTab[idx]);
+
+ return;
+}
+
+
+VOID CliWds_ProxyTabDestory(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT idx;
+ PCLIWDS_PROXY_ENTRY pCliWdsEntry;
+
+ NdisFreeSpinLock(&pAd->ApCfg.CliWdsTabLock);
+
+ for (idx = 0; idx < CLIWDS_HASH_TAB_SIZE; idx++)
+ {
+ pCliWdsEntry =
+ (PCLIWDS_PROXY_ENTRY)pAd->ApCfg.CliWdsProxyTab[idx].pHead;
+ while(pCliWdsEntry)
+ {
+ PCLIWDS_PROXY_ENTRY pCliWdsEntryNext = pCliWdsEntry->pNext;
+ CliWdsEntyFree(pAd, pCliWdsEntry);
+ pCliWdsEntry = pCliWdsEntryNext;
+ }
+ }
+
+ if (pAd->ApCfg.pCliWdsEntryPool)
+/* kfree(pAd->ApCfg.pCliWdsEntryPool);*/
+ os_free_mem(NULL, pAd->ApCfg.pCliWdsEntryPool);
+ pAd->ApCfg.pCliWdsEntryPool = NULL;
+
+ return;
+}
+
+
+PCLIWDS_PROXY_ENTRY CliWdsEntyAlloc(
+ IN PRTMP_ADAPTER pAd)
+{
+ PCLIWDS_PROXY_ENTRY pCliWdsEntry;
+
+ RTMP_SEM_LOCK(&pAd->ApCfg.CliWdsTabLock);
+
+ pCliWdsEntry = (PCLIWDS_PROXY_ENTRY)removeHeadList(&pAd->ApCfg.CliWdsEntryFreeList);
+
+ RTMP_SEM_UNLOCK(&pAd->ApCfg.CliWdsTabLock);
+
+ return pCliWdsEntry;
+}
+
+
+VOID CliWdsEntyFree(
+ IN PRTMP_ADAPTER pAd,
+ IN PCLIWDS_PROXY_ENTRY pCliWdsEntry)
+{
+ RTMP_SEM_LOCK(&pAd->ApCfg.CliWdsTabLock);
+
+ insertTailList(&pAd->ApCfg.CliWdsEntryFreeList, (PLIST_ENTRY)pCliWdsEntry);
+
+ RTMP_SEM_UNLOCK(&pAd->ApCfg.CliWdsTabLock);
+
+ return;
+}
+
+
+PUCHAR CliWds_ProxyLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pMac)
+{
+ UINT8 HashId = (*(pMac + 5) & (CLIWDS_HASH_TAB_SIZE - 1));
+ PCLIWDS_PROXY_ENTRY pCliWdsEntry;
+
+ pCliWdsEntry =
+ (PCLIWDS_PROXY_ENTRY)pAd->ApCfg.CliWdsProxyTab[HashId].pHead;
+ while (pCliWdsEntry)
+ {
+ if (MAC_ADDR_EQUAL(pMac, pCliWdsEntry->Addr))
+ {
+ ULONG Now;
+ NdisGetSystemUpTime(&Now);
+
+ pCliWdsEntry->LastRefTime = Now;
+ if (VALID_WCID(pCliWdsEntry->Aid))
+ return pAd->MacTab.Content[pCliWdsEntry->Aid].Addr;
+ else
+ return NULL;
+ }
+ pCliWdsEntry = pCliWdsEntry->pNext;
+ }
+ return NULL;
+}
+
+
+VOID CliWds_ProxyTabUpdate(
+ IN PRTMP_ADAPTER pAd,
+ IN SHORT Aid,
+ IN PUCHAR pMac)
+{
+ UINT8 HashId = (*(pMac + 5) & (CLIWDS_HASH_TAB_SIZE - 1));
+ PCLIWDS_PROXY_ENTRY pCliWdsEntry;
+
+ if (CliWds_ProxyLookup(pAd, pMac) != NULL)
+ return;
+
+ pCliWdsEntry = CliWdsEntyAlloc(pAd);
+ if (pCliWdsEntry)
+ {
+ ULONG Now;
+ NdisGetSystemUpTime(&Now);
+
+ pCliWdsEntry->Aid = Aid;
+ COPY_MAC_ADDR(&pCliWdsEntry->Addr, pMac);
+ pCliWdsEntry->LastRefTime = Now;
+ pCliWdsEntry->pNext = NULL;
+ insertTailList(&pAd->ApCfg.CliWdsProxyTab[HashId], (PLIST_ENTRY)pCliWdsEntry);
+ }
+ return;
+}
+
+
+VOID CliWds_ProxyTabMaintain(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG idx;
+ PCLIWDS_PROXY_ENTRY pCliWdsEntry;
+ ULONG Now;
+
+ NdisGetSystemUpTime(&Now);
+ for (idx = 0; idx < CLIWDS_HASH_TAB_SIZE; idx++)
+ {
+ pCliWdsEntry = (PCLIWDS_PROXY_ENTRY)(pAd->ApCfg.CliWdsProxyTab[idx].pHead);
+ while(pCliWdsEntry)
+ {
+ PCLIWDS_PROXY_ENTRY pCliWdsEntryNext = pCliWdsEntry->pNext;
+ if (RTMP_TIME_AFTER(Now, pCliWdsEntry->LastRefTime + (CLI_WDS_ENTRY_AGEOUT * OS_HZ / 1000)))
+ {
+ delEntryList(&pAd->ApCfg.CliWdsProxyTab[idx], (PLIST_ENTRY)pCliWdsEntry);
+ CliWdsEntyFree(pAd, pCliWdsEntry);
+ }
+ pCliWdsEntry = pCliWdsEntryNext;
+ }
+ }
+ return;
+}
+
+#endif /* CLIENT_WDS */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_aes.c b/cleopatre/devkit/mt7601udrv/common/cmm_aes.c
new file mode 100644
index 0000000000..b254c63ce6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_aes.c
@@ -0,0 +1,1142 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_aes.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Wu 02-25-02 Initial
+*/
+
+#include "rt_config.h"
+
+
+
+/*****************************/
+/******** SBOX Table *********/
+/*****************************/
+
+UCHAR SboxTable[256] =
+{
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+VOID xor_32(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0;i<4; i++)
+ {
+ out[i] = a[i] ^ b[i];
+ }
+}
+
+VOID xor_128(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0;i<16; i++)
+ {
+ out[i] = a[i] ^ b[i];
+ }
+}
+
+UCHAR RTMPCkipSbox(
+ IN UCHAR a)
+{
+ return SboxTable[(int)a];
+}
+
+VOID next_key(
+ IN PUCHAR key,
+ IN INT round)
+{
+ UCHAR rcon;
+ UCHAR sbox_key[4];
+ UCHAR rcon_table[12] =
+ {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+ 0x1b, 0x36, 0x36, 0x36
+ };
+
+ sbox_key[0] = RTMPCkipSbox(key[13]);
+ sbox_key[1] = RTMPCkipSbox(key[14]);
+ sbox_key[2] = RTMPCkipSbox(key[15]);
+ sbox_key[3] = RTMPCkipSbox(key[12]);
+
+ rcon = rcon_table[round];
+
+ xor_32(&key[0], sbox_key, &key[0]);
+ key[0] = key[0] ^ rcon;
+
+ xor_32(&key[4], &key[0], &key[4]);
+ xor_32(&key[8], &key[4], &key[8]);
+ xor_32(&key[12], &key[8], &key[12]);
+}
+
+VOID byte_sub(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0; i< 16; i++)
+ {
+ out[i] = RTMPCkipSbox(in[i]);
+ }
+}
+
+/************************************/
+/* bitwise_xor() */
+/* A 128 bit, bitwise exclusive or */
+/************************************/
+
+void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
+{
+ int i;
+ for (i=0; i<16; i++)
+ {
+ out[i] = ina[i] ^ inb[i];
+ }
+}
+
+VOID shift_row(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ out[0] = in[0];
+ out[1] = in[5];
+ out[2] = in[10];
+ out[3] = in[15];
+ out[4] = in[4];
+ out[5] = in[9];
+ out[6] = in[14];
+ out[7] = in[3];
+ out[8] = in[8];
+ out[9] = in[13];
+ out[10] = in[2];
+ out[11] = in[7];
+ out[12] = in[12];
+ out[13] = in[1];
+ out[14] = in[6];
+ out[15] = in[11];
+}
+
+VOID mix_column(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ INT i;
+ UCHAR add1b[4];
+ UCHAR add1bf7[4];
+ UCHAR rotl[4];
+ UCHAR swap_halfs[4];
+ UCHAR andf7[4];
+ UCHAR rotr[4];
+ UCHAR temp[4];
+ UCHAR tempb[4];
+
+ for (i=0 ; i<4; i++)
+ {
+ if ((in[i] & 0x80)== 0x80)
+ add1b[i] = 0x1b;
+ else
+ add1b[i] = 0x00;
+ }
+
+ swap_halfs[0] = in[2]; /* Swap halfs */
+ swap_halfs[1] = in[3];
+ swap_halfs[2] = in[0];
+ swap_halfs[3] = in[1];
+
+ rotl[0] = in[3]; /* Rotate left 8 bits */
+ rotl[1] = in[0];
+ rotl[2] = in[1];
+ rotl[3] = in[2];
+
+ andf7[0] = in[0] & 0x7f;
+ andf7[1] = in[1] & 0x7f;
+ andf7[2] = in[2] & 0x7f;
+ andf7[3] = in[3] & 0x7f;
+
+ for (i = 3; i>0; i--) /* logical shift left 1 bit */
+ {
+ andf7[i] = andf7[i] << 1;
+ if ((andf7[i-1] & 0x80) == 0x80)
+ {
+ andf7[i] = (andf7[i] | 0x01);
+ }
+ }
+ andf7[0] = andf7[0] << 1;
+ andf7[0] = andf7[0] & 0xfe;
+
+ xor_32(add1b, andf7, add1bf7);
+
+ xor_32(in, add1bf7, rotr);
+
+ temp[0] = rotr[0]; /* Rotate right 8 bits */
+ rotr[0] = rotr[1];
+ rotr[1] = rotr[2];
+ rotr[2] = rotr[3];
+ rotr[3] = temp[0];
+
+ xor_32(add1bf7, rotr, temp);
+ xor_32(swap_halfs, rotl,tempb);
+ xor_32(temp, tempb, out);
+}
+
+
+/************************************************/
+/* construct_mic_header1() */
+/* Builds the first MIC header block from */
+/* header fields. */
+/************************************************/
+
+void construct_mic_header1(
+ unsigned char *mic_header1,
+ int header_length,
+ unsigned char *mpdu)
+{
+ mic_header1[0] = (unsigned char)((header_length - 2) / 256);
+ mic_header1[1] = (unsigned char)((header_length - 2) % 256);
+ mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
+ mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
+ mic_header1[4] = mpdu[4]; /* A1 */
+ mic_header1[5] = mpdu[5];
+ mic_header1[6] = mpdu[6];
+ mic_header1[7] = mpdu[7];
+ mic_header1[8] = mpdu[8];
+ mic_header1[9] = mpdu[9];
+ mic_header1[10] = mpdu[10]; /* A2 */
+ mic_header1[11] = mpdu[11];
+ mic_header1[12] = mpdu[12];
+ mic_header1[13] = mpdu[13];
+ mic_header1[14] = mpdu[14];
+ mic_header1[15] = mpdu[15];
+}
+
+/************************************************/
+/* construct_mic_header2() */
+/* Builds the last MIC header block from */
+/* header fields. */
+/************************************************/
+
+void construct_mic_header2(
+ unsigned char *mic_header2,
+ unsigned char *mpdu,
+ int a4_exists,
+ int qc_exists)
+{
+ int i;
+
+ for (i = 0; i<16; i++) mic_header2[i]=0x00;
+
+ mic_header2[0] = mpdu[16]; /* A3 */
+ mic_header2[1] = mpdu[17];
+ mic_header2[2] = mpdu[18];
+ mic_header2[3] = mpdu[19];
+ mic_header2[4] = mpdu[20];
+ mic_header2[5] = mpdu[21];
+
+ /* In Sequence Control field, mute sequence numer bits (12-bit) */
+ mic_header2[6] = mpdu[22] & 0x0f; /* SC */
+ mic_header2[7] = 0x00; /* mpdu[23]; */
+
+ if ((!qc_exists) & a4_exists)
+ {
+ for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
+
+ }
+
+ if (qc_exists && (!a4_exists))
+ {
+ mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
+ mic_header2[9] = mpdu[25] & 0x00;
+ }
+
+ if (qc_exists && a4_exists)
+ {
+ for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
+
+ mic_header2[14] = mpdu[30] & 0x0f;
+ mic_header2[15] = mpdu[31] & 0x00;
+ }
+}
+
+
+/************************************************/
+/* construct_mic_iv() */
+/* Builds the MIC IV from header fields and PN */
+/************************************************/
+
+void construct_mic_iv(
+ unsigned char *mic_iv,
+ int qc_exists,
+ int a4_exists,
+ unsigned char *mpdu,
+ unsigned int payload_length,
+ unsigned char *pn_vector)
+{
+ int i;
+
+ mic_iv[0] = 0x59;
+ if (qc_exists && a4_exists)
+ mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
+ if (qc_exists && !a4_exists)
+ mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
+ if (!qc_exists)
+ mic_iv[1] = 0x00;
+ for (i = 2; i < 8; i++)
+ mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+ for (i = 8; i < 14; i++)
+ mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
+#else
+ for (i = 8; i < 14; i++)
+ mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
+#endif
+ i = (payload_length / 256);
+ i = (payload_length % 256);
+ mic_iv[14] = (unsigned char) (payload_length / 256);
+ mic_iv[15] = (unsigned char) (payload_length % 256);
+
+}
+
+/****************************************/
+/* aes128k128d() */
+/* Performs a 128 bit AES encrypt with */
+/* 128 bit data. */
+/****************************************/
+void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
+{
+ int round;
+ int i;
+ unsigned char intermediatea[16];
+ unsigned char intermediateb[16];
+ unsigned char round_key[16];
+
+ for(i=0; i<16; i++) round_key[i] = key[i];
+
+ for (round = 0; round < 11; round++)
+ {
+ if (round == 0)
+ {
+ xor_128(round_key, data, ciphertext);
+ next_key(round_key, round);
+ }
+ else if (round == 10)
+ {
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ xor_128(intermediateb, round_key, ciphertext);
+ }
+ else /* 1 - 9 */
+ {
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ mix_column(&intermediateb[0], &intermediatea[0]);
+ mix_column(&intermediateb[4], &intermediatea[4]);
+ mix_column(&intermediateb[8], &intermediatea[8]);
+ mix_column(&intermediateb[12], &intermediatea[12]);
+ xor_128(intermediatea, round_key, ciphertext);
+ next_key(round_key, round);
+ }
+ }
+
+}
+
+void construct_ctr_preload(
+ unsigned char *ctr_preload,
+ int a4_exists,
+ int qc_exists,
+ unsigned char *mpdu,
+ unsigned char *pn_vector,
+ int c)
+{
+
+ int i = 0;
+ for (i=0; i<16; i++) ctr_preload[i] = 0x00;
+ i = 0;
+
+ ctr_preload[0] = 0x01; /* flag */
+ if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
+ if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
+
+ for (i = 2; i < 8; i++)
+ ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+ for (i = 8; i < 14; i++)
+ ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
+#else
+ for (i = 8; i < 14; i++)
+ ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
+#endif
+ ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
+ ctr_preload[15] = (unsigned char) (c % 256);
+
+}
+
+BOOLEAN RTMPSoftDecryptAES(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pWpaKey)
+{
+ UINT HeaderLen;
+ UCHAR PN[6];
+ UINT payload_len;
+ UINT num_blocks;
+ UINT payload_remainder;
+ USHORT fc;
+ UCHAR fc0;
+ UCHAR fc1;
+ UINT frame_type;
+ UINT frame_subtype;
+ UINT from_ds;
+ UINT to_ds;
+ INT a4_exists;
+ INT qc_exists;
+ UCHAR aes_out[16];
+ int payload_index;
+ UINT i;
+ UCHAR ctr_preload[16];
+ UCHAR chain_buffer[16];
+ UCHAR padded_buffer[16];
+ UCHAR mic_iv[16];
+ UCHAR mic_header1[16];
+ UCHAR mic_header2[16];
+ UCHAR MIC[8];
+ UCHAR TrailMIC[8];
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ fc0 = *pData;
+ fc1 = *(pData + 1);
+
+ fc = *((PUSHORT)pData);
+
+ frame_type = ((fc0 >> 2) & 0x03);
+ frame_subtype = ((fc0 >> 4) & 0x0f);
+
+ from_ds = (fc1 & 0x2) >> 1;
+ to_ds = (fc1 & 0x1);
+
+ a4_exists = (from_ds & to_ds);
+ qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
+ (frame_subtype == 0x09) || /* Likely to change. */
+ (frame_subtype == 0x0a) ||
+ (frame_subtype == 0x0b)
+ );
+
+ HeaderLen = 24;
+
+ if (a4_exists)
+ HeaderLen += 6;
+
+ if (qc_exists)
+ HeaderLen += 2;
+
+ if (pWpaKey->KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(the Length can not be 0)\n"));
+ return FALSE;
+ }
+
+ PN[0] = *(pData+ HeaderLen);
+ PN[1] = *(pData+ HeaderLen + 1);
+ PN[2] = *(pData+ HeaderLen + 4);
+ PN[3] = *(pData+ HeaderLen + 5);
+ PN[4] = *(pData+ HeaderLen + 6);
+ PN[5] = *(pData+ HeaderLen + 7);
+
+ payload_len = DataByteCnt - HeaderLen - 8 - 8; /* 8 bytes for CCMP header , 8 bytes for MIC*/
+ payload_remainder = (payload_len) % 16;
+ num_blocks = (payload_len) / 16;
+
+
+
+ /* Find start of payload*/
+ payload_index = HeaderLen + 8; /*IV+EIV*/
+
+ for (i=0; i< num_blocks; i++)
+ {
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ i+1 );
+
+ aes128k128d(pWpaKey->Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+ NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
+ payload_index += 16;
+ }
+
+
+ /* If there is a short final block, then pad it*/
+ /* encrypt it and copy the unpadded part back */
+
+ if (payload_remainder > 0)
+ {
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ num_blocks + 1);
+
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+ aes128k128d(pWpaKey->Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
+ payload_index += payload_remainder;
+ }
+
+
+ /* Descrypt the MIC*/
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ 0);
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, 8);
+
+ aes128k128d(pWpaKey->Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+
+ NdisMoveMemory(TrailMIC, chain_buffer, 8);
+
+
+
+ /* Calculate MIC*/
+
+
+ /*Force the protected frame bit on*/
+ *(pData + 1) = *(pData + 1) | 0x40;
+
+ /* Find start of payload*/
+ /* Because the CCMP header has been removed*/
+ payload_index = HeaderLen;
+
+ construct_mic_iv(
+ mic_iv,
+ qc_exists,
+ a4_exists,
+ pData,
+ payload_len,
+ PN);
+
+ construct_mic_header1(
+ mic_header1,
+ HeaderLen,
+ pData);
+
+ construct_mic_header2(
+ mic_header2,
+ pData,
+ a4_exists,
+ qc_exists);
+
+ aes128k128d(pWpaKey->Key, mic_iv, aes_out);
+ bitwise_xor(aes_out, mic_header1, chain_buffer);
+ aes128k128d(pWpaKey->Key, chain_buffer, aes_out);
+ bitwise_xor(aes_out, mic_header2, chain_buffer);
+ aes128k128d(pWpaKey->Key, chain_buffer, aes_out);
+
+ /* iterate through each 16 byte payload block */
+ for (i = 0; i < num_blocks; i++)
+ {
+ bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+ payload_index += 16;
+ aes128k128d(pWpaKey->Key, chain_buffer, aes_out);
+ }
+
+ /* Add on the final payload block if it needs padding */
+ if (payload_remainder > 0)
+ {
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ aes128k128d(pWpaKey->Key, chain_buffer, aes_out);
+ }
+
+ /* aes_out contains padded mic, discard most significant*/
+ /* 8 bytes to generate 64 bit MIC*/
+ for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
+
+ if (!NdisEqualMemory(MIC, TrailMIC, 8))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); /* MIC error. */
+ return FALSE;
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct AAD of CCMP.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ It's described in IEEE Std 802.11-2007.
+ The AAD is constructed from the MPDU header.
+
+ ========================================================================
+*/
+VOID RTMPConstructCCMPAAD(
+ IN PUCHAR pHdr,
+ IN BOOLEAN isDataFrame,
+ IN UINT8 a4_exists,
+ IN UINT8 qc_exists,
+ OUT UCHAR *aad_hdr,
+ OUT UINT *aad_len)
+{
+ UINT len = 0;
+
+ /* Frame control -
+ Subtype bits (bits 4 5 6) in a Data MPDU masked to 0
+ Retry bit (bit 11) masked to 0
+ PwrMgt bit (bit 12) masked to 0
+ MoreData bit (bit 13) masked to 0
+ Protected Frame bit (bit 14) always set to 1 */
+ if (isDataFrame)
+ aad_hdr[0] = (*pHdr) & 0x8f;
+ else
+ aad_hdr[0] = (*pHdr);
+ aad_hdr[1] = (*(pHdr + 1)) & 0xc7;
+ aad_hdr[1] = aad_hdr[1] | 0x40;
+ len = 2;
+
+ /* Append Addr 1, 2 & 3 */
+ NdisMoveMemory(&aad_hdr[len], pHdr + 4, 3 * MAC_ADDR_LEN);
+ len += (3 * MAC_ADDR_LEN);
+
+ /* SC -
+ MPDU Sequence Control field, with the Sequence Number
+ subfield (bits 4-15 of the Sequence Control field)
+ masked to 0. The Fragment Number subfield is not modified. */
+ aad_hdr[len] = (*(pHdr + 22)) & 0x0f;
+ aad_hdr[len + 1] = 0x00;
+ len += 2;
+
+
+ /* Append the Addr4 field if present. */
+ if (a4_exists)
+ {
+ NdisMoveMemory(&aad_hdr[len], pHdr + 24, MAC_ADDR_LEN);
+ len += MAC_ADDR_LEN;
+ }
+
+ /* QC -
+ QoS Control field, if present, a 2-octet field that includes
+ the MSDU priority. The QC TID field is used in the
+ construction of the AAD and the remaining QC fields are
+ set to 0 for the AAD calculation (bits 4 to 15 are set to 0). */
+ if (qc_exists & a4_exists)
+ {
+ aad_hdr[len] = (*(pHdr + 30)) & 0x0f; /* Qos_TC */
+ aad_hdr[len + 1] = 0x00;
+ len += 2;
+ }
+ else if (qc_exists & !a4_exists)
+ {
+ aad_hdr[len] = (*(pHdr + 24)) & 0x0f; /* Qos_TC */
+ aad_hdr[len + 1] = 0x00;
+ len += 2;
+ }
+
+ *aad_len = len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct NONCE header of CCMP.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPConstructCCMPNonce(
+ IN PUCHAR pHdr,
+ IN UINT8 a4_exists,
+ IN UINT8 qc_exists,
+ IN BOOLEAN isMgmtFrame,
+ IN UCHAR *pn,
+ OUT UCHAR *nonce_hdr,
+ OUT UINT *nonce_hdr_len)
+{
+ UINT n_offset = 0;
+ INT i;
+
+ /* Decide the Priority Octet
+ The Priority sub-field of the Nonce Flags field shall
+ be set to the fixed value 0 when there is no QC field
+ present in the MPDU header. When the QC field is present,
+ bits 0 to 3 of the Priority field shall be set to the
+ value of the QC TID (bits 0 to 3 of the QC field).*/
+ if (qc_exists && a4_exists)
+ nonce_hdr[0] = (*(pHdr + 30)) & 0x0f;
+ if (qc_exists && !a4_exists)
+ nonce_hdr[0] = (*(pHdr + 24)) & 0x0f;
+
+ n_offset += 1;
+
+ /* Fill in MPDU Address A2 field */
+ NdisMoveMemory(&nonce_hdr[n_offset], pHdr + 10, MAC_ADDR_LEN);
+ n_offset += MAC_ADDR_LEN;
+
+ /* Fill in the PN. The PN field occupies octets 7¡V12.
+ The octets of PN shall be ordered so that PN0 is at octet index 12
+ and PN5 is at octet index 7. */
+ for (i = 0; i < 6; i++)
+ nonce_hdr[n_offset + i] = pn[5 - i];
+ n_offset += LEN_PN;
+
+ *nonce_hdr_len = n_offset;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct CCMP header.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ It's a 8-octets header.
+
+ ========================================================================
+*/
+VOID RTMPConstructCCMPHdr(
+ IN UINT8 key_idx,
+ IN UCHAR *pn,
+ OUT UCHAR *ccmp_hdr)
+{
+ NdisZeroMemory(ccmp_hdr, LEN_CCMP_HDR);
+
+ ccmp_hdr[0] = pn[0];
+ ccmp_hdr[1] = pn[1];
+ ccmp_hdr[3] = (key_idx <<6) | 0x20;
+ ccmp_hdr[4] = pn[2];
+ ccmp_hdr[5] = pn[3];
+ ccmp_hdr[6] = pn[4];
+ ccmp_hdr[7] = pn[5];
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPSoftEncryptCCMP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHdr,
+ IN PUCHAR pIV,
+ IN PUCHAR pKey,
+ INOUT PUCHAR pData,
+ IN UINT32 DataLen)
+{
+ UINT8 frame_type, frame_subtype;
+ UINT8 from_ds, to_ds;
+ UINT8 a4_exists, qc_exists;
+ UINT8 aad_hdr[30];
+ UINT aad_len = 0;
+ UINT8 nonce_hdr[13];
+ UINT32 nonce_hdr_len = 0;
+ UINT32 out_len = DataLen + 8;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pHdr, DIR_READ, FALSE);
+#endif
+
+ /* Initial variable */
+ NdisZeroMemory(aad_hdr, 30);
+ NdisZeroMemory(nonce_hdr, 13);
+
+ /* Indicate type and subtype of Frame Control field */
+ frame_type = (((*pHdr) >> 2) & 0x03);
+ frame_subtype = (((*pHdr) >> 4) & 0x0f);
+
+ /* Indicate the fromDS and ToDS */
+ from_ds = ((*(pHdr + 1)) & 0x2) >> 1;
+ to_ds = ((*(pHdr + 1)) & 0x1);
+
+ /* decide if the Address 4 exist or QoS exist */
+ a4_exists = (from_ds & to_ds);
+ qc_exists = 0;
+ if (frame_type == BTYPE_DATA)
+ {
+ 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 = 0;
+ if (frame_type == BTYPE_DATA)
+ {
+ qc_exists = ((frame_subtype == SUBTYPE_QDATA) ||
+ (frame_subtype == SUBTYPE_QDATA_CFACK) ||
+ (frame_subtype == SUBTYPE_QDATA_CFPOLL) ||
+ (frame_subtype == SUBTYPE_QDATA_CFACK_CFPOLL));
+ }
+
+ /* Extract PN and from CCMP header */
+ pn[0] = pData[0];
+ pn[1] = pData[1];
+ pn[2] = pData[4];
+ pn[3] = pData[5];
+ pn[4] = pData[6];
+ pn[5] = pData[7];
+
+ /* skip ccmp header */
+ cipherData_ptr = pData + LEN_CCMP_HDR;
+ cipherData_len = *DataLen - LEN_CCMP_HDR;
+
+ /* Construct AAD header */
+ RTMPConstructCCMPAAD(pHdr,
+ (frame_type == BTYPE_DATA),
+ a4_exists,
+ qc_exists,
+ aad_hdr,
+ &aad_len);
+
+ /* Construct NONCE header */
+ RTMPConstructCCMPNonce(pHdr,
+ a4_exists,
+ qc_exists,
+ (frame_type == BTYPE_MGMT),
+ pn,
+ nonce_hdr,
+ &nonce_hdr_len);
+
+ /* CCM recipient processing -
+ uses the temporal key, AAD, nonce, MIC,
+ and MPDU cipher text data */
+ if (AES_CCM_Decrypt(cipherData_ptr, cipherData_len,
+ pKey->Key, 16,
+ nonce_hdr, nonce_hdr_len,
+ aad_hdr, aad_len, LEN_CCMP_MIC,
+ pData, &out_len))
+ return FALSE;
+
+ *DataLen = out_len;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pHdr, DIR_READ, FALSE);
+#endif
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ CCMP test vector
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID CCMP_test_vector(
+ IN PRTMP_ADAPTER pAd,
+ IN INT input)
+{
+ UINT8 Key_ID = 0;
+ /*UINT8 A1[6] = {0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c};*/
+ /*UINT8 A2[6] = {0x50, 0x30, 0xf1, 0x84, 0x44, 0x08};*/
+ /*UINT8 A3[6] = {0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba};*/
+ UINT8 TK[16] = {0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
+ 0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f};
+ UINT8 PN[6] = {0x0C, 0xE7, 0x76, 0x97, 0x03, 0xB5};
+ UINT8 HDR[24]= {0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
+ 0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
+ 0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33};
+ UINT8 AAD[22] = {0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c,
+ 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae,
+ 0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00};
+ UINT8 CCMP_HDR[8] = {0x0c, 0xe7, 0x00, 0x20, 0x76, 0x97, 0x03, 0xb5};
+ UINT8 CCM_NONCE[13] = {0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5,
+ 0x03, 0x97, 0x76, 0xe7, 0x0c};
+ UINT8 P_TEXT_DATA[20] = {0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
+ 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
+ 0x7e, 0x78, 0xa0, 0x50};
+ UINT8 C_TEXT_DATA[28] = {0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23,
+ 0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c,
+ 0x3c, 0x04, 0xd0, 0x19, 0x78, 0x45, 0xce, 0x0b,
+ 0x16, 0xf9, 0x76, 0x23};
+ UINT8 res_buf[100];
+ UINT res_len = 0;
+
+ printk("== CCMP test vector == \n");
+
+ /* Check AAD */
+ NdisZeroMemory(res_buf, 100);
+ res_len = 0;
+ RTMPConstructCCMPAAD(HDR, TRUE, 0, 0, res_buf, &res_len);
+ if (res_len == 22 && NdisEqualMemory(res_buf, AAD, res_len))
+ printk("Construct AAD is OK!!!\n");
+ else
+ {
+ printk("\n!!!Construct AAD is FAILURE!!!\n\n");
+ hex_dump("Calculate AAD", res_buf, res_len);
+ }
+ /* Check NONCE */
+ NdisZeroMemory(res_buf, 100);
+ res_len = 0;
+ RTMPConstructCCMPNonce(HDR, 0, 0, FALSE, PN, res_buf, &res_len);
+ if (res_len == 13 && NdisEqualMemory(res_buf, CCM_NONCE, res_len))
+ printk("Construct NONCE is OK!!!\n");
+ else
+ {
+ printk("\n!!!Construct NONCE is FAILURE!!!\n\n");
+ hex_dump("Calculate NONCE", res_buf, res_len);
+ }
+ /* Check CCMP-Header */
+ NdisZeroMemory(res_buf, 100);
+ res_len = 0;
+ RTMPConstructCCMPHdr(Key_ID, PN, res_buf);
+ if (NdisEqualMemory(res_buf, CCMP_HDR, 8))
+ printk("Construct CCMP_HDR is OK!!!\n");
+ else
+ {
+ printk("\n!!!Construct CCMP_HDR is FAILURE!!!\n\n");
+ hex_dump("Calculate CCMP_HDR", res_buf, 8);
+ }
+
+ /* Encrypt action */
+ NdisZeroMemory(res_buf, 100);
+ NdisMoveMemory(res_buf, P_TEXT_DATA, sizeof(P_TEXT_DATA));
+ res_len = sizeof(C_TEXT_DATA);
+ if (AES_CCM_Encrypt(res_buf, sizeof(P_TEXT_DATA),
+ TK, sizeof(TK),
+ CCM_NONCE, sizeof(CCM_NONCE),
+ AAD, sizeof(AAD), 8,
+ res_buf, &res_len) == 0)
+ {
+ if (res_len == sizeof(C_TEXT_DATA) &&
+ NdisEqualMemory(res_buf, C_TEXT_DATA, res_len))
+ printk("CCM_Encrypt is OK!!!\n");
+ else
+ {
+ printk("\n!!!CCM_Encrypt is FAILURE!!!\n\n");
+ hex_dump("CCM_Encrypt", res_buf, res_len);
+ }
+ }
+
+ /* Decrypt action */
+ NdisZeroMemory(res_buf, 100);
+ NdisMoveMemory(res_buf, C_TEXT_DATA, sizeof(C_TEXT_DATA));
+ res_len = sizeof(P_TEXT_DATA);
+ if (AES_CCM_Decrypt(res_buf, sizeof(C_TEXT_DATA), TK, 16,
+ CCM_NONCE, sizeof(CCM_NONCE),
+ AAD, sizeof(AAD), 8,
+ res_buf, &res_len) == 0)
+ {
+ if (res_len == sizeof(P_TEXT_DATA) &&
+ NdisEqualMemory(res_buf, P_TEXT_DATA, res_len))
+ printk("CCM_Decrypt is OK!!!\n");
+ else
+ {
+ printk("\n!!!CCM_Decrypt is FAILURE!!!\n\n");
+ hex_dump("CCM_Decrypt", res_buf, res_len);
+ }
+ }
+
+ printk("== CCMP test vector == \n");
+
+ }
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_asic.c b/cleopatre/devkit/mt7601udrv/common/cmm_asic.c
new file mode 100644
index 0000000000..03ff71a9ad
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_asic.c
@@ -0,0 +1,2699 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_asic.c
+
+ Abstract:
+ Functions used to communicate with ASIC
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#include "rt_config.h"
+
+
+
+
+/*
+ ========================================================================
+
+ 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;
+
+#ifdef DOT11_VHT_AC
+#ifdef RT65xx
+ // TODO: shiang-6590, fix me for this protection mechanism
+ if (IS_RT65XX(pAd))
+ {
+ // Temporary tuen on RTS in VHT, MAC: TX_PROT_CFG6, TX_PROT_CFG7, TX_PROT_CFG8
+ PROT_CFG_STRUC vht_port_cfg;
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG6, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = 0;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG6, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG7, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = 0;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG7, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG8, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = 0;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG8, vht_port_cfg.word);
+ }
+#endif /* RT65xx */
+#endif /* DOT11_VHT_AC */
+
+
+ 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;
+
+#ifdef DOT11_VHT_AC
+#ifdef RT65xx
+ // TODO: shiang-6590, fix me for this protection mechanism
+ if (IS_RT65XX(pAd))
+ {
+ // Temporary tuen on RTS in VHT, MAC: TX_PROT_CFG6, TX_PROT_CFG7, TX_PROT_CFG8
+ PROT_CFG_STRUC vht_port_cfg;
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG6, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG6, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG7, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG7, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG8, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG8, vht_port_cfg.word);
+ }
+#endif /* RT65xx */
+#endif /* DOT11_VHT_AC */
+
+ 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;
+
+#ifdef DOT11_VHT_AC
+#ifdef RT65xx
+ // TODO: shiang-6590, fix me for this protection mechanism
+ if (IS_RT65XX(pAd))
+ {
+ // Temporary tuen on RTS in VHT, MAC: TX_PROT_CFG6, TX_PROT_CFG7, TX_PROT_CFG8
+ PROT_CFG_STRUC vht_port_cfg;
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG6, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = 0;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG6, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG7, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG7, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG8, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG8, vht_port_cfg.word);
+ }
+#endif /* RT65xx */
+#endif /* DOT11_VHT_AC */
+ 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;
+
+#ifdef DOT11_VHT_AC
+#ifdef RT65xx
+ // TODO: shiang-6590, fix me for this protection mechanism
+ if (IS_RT65XX(pAd))
+ {
+ // Temporary tuen on RTS in VHT, MAC: TX_PROT_CFG6, TX_PROT_CFG7, TX_PROT_CFG8
+ PROT_CFG_STRUC vht_port_cfg;
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG6, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG6, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG7, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG7, vht_port_cfg.word);
+
+ RTMP_IO_READ32(pAd, TX_PROT_CFG8, &vht_port_cfg.word);
+ vht_port_cfg.field.ProtectCtrl = ASIC_RTS;
+ RTMP_IO_WRITE32(pAd, TX_PROT_CFG8, vht_port_cfg.word);
+ }
+#endif /* RT65xx */
+#endif /* DOT11_VHT_AC */
+ 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)
+{
+ // TODO: shiang-6590, now this function only used for AP mode, why we need this differentation?
+ if (pAd->chipOps.ChipBBPAdjust != NULL)
+ pAd->chipOps.ChipBBPAdjust(pAd);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSwitchChannel(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan)
+{
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SUSPEND);
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef AP_QLOAD_SUPPORT
+ /* clear all statistics count for QBSS Load */
+ QBSS_LoadStatusClear(pAd);
+#endif /* AP_QLOAD_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (pAd->chipOps.ChipSwitchChannel)
+ pAd->chipOps.ChipSwitchChannel(pAd, Channel, bScan);
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("For this chip, no specified channel switch function!\n"));
+
+ /* R66 should be set according to Channel and use 20MHz when scanning*/
+ if (bScan)
+ RTMPSetAGCInitValue(pAd, BW_20);
+ else
+ RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ This function is required for 2421 only, and should not be used during
+ site survey. It's only required after NIC decided to stay at a channel
+ for a longer period.
+ When this function is called, it's always after AsicSwitchChannel().
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicLockChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+
+
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+VOID InitLookupTable(
+ IN PRTMP_ADAPTER pAd)
+{
+ int Idx, IdxTmp;
+ int i;
+ enum IEEE80211_BAND band;
+ int band_nums = 1;
+ const int Offset = 7;
+ EEPROM_WORD_STRUC WordStruct = {{0}};
+ UCHAR PlusStepNum[IEEE80211_BAND_NUMS][8] = {{0, 1, 3, 2, 3, 3, 3, 2}, {0, 1, 3, 2, 3, 3, 3, 2}};
+ UCHAR MinusStepNum[IEEE80211_BAND_NUMS][8] = {{1, 1, 1, 1, 1, 1, 0, 1}, {1, 1, 1, 1, 1, 1, 0, 1}};
+ UCHAR Step[IEEE80211_BAND_NUMS] = {10, 10};
+ UCHAR RFValue = 0, BbpValue = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> InitLookupTable\n"));
+
+ /* Read from EEPROM, as parameters for lookup table for G band */
+ RT28xx_EEPROM_READ16(pAd, 0x6e, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 6e = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_2G][0] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][2] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x70, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 70 = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_2G][4] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][6] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x72, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 72 = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_2G][0] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][2] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x74, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4] EEPROM 74 = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_2G][4] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][6] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x76, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 76 = %x\n", WordStruct.word));
+ pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_2G] = (WordStruct.field.Byte0 & 0x0F);
+ Step[IEEE80211_BAND_2G] = (WordStruct.field.Byte0 >> 4);
+ pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_2G] = (CHAR)WordStruct.field.Byte1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] Plus = %u %u %u %u %u %u %u %u\n",
+ PlusStepNum[IEEE80211_BAND_2G][0],
+ PlusStepNum[IEEE80211_BAND_2G][1],
+ PlusStepNum[IEEE80211_BAND_2G][2],
+ PlusStepNum[IEEE80211_BAND_2G][3],
+ PlusStepNum[IEEE80211_BAND_2G][4],
+ PlusStepNum[IEEE80211_BAND_2G][5],
+ PlusStepNum[IEEE80211_BAND_2G][6],
+ PlusStepNum[IEEE80211_BAND_2G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] Minus = %u %u %u %u %u %u %u %u\n",
+ MinusStepNum[IEEE80211_BAND_2G][0],
+ MinusStepNum[IEEE80211_BAND_2G][1],
+ MinusStepNum[IEEE80211_BAND_2G][2],
+ MinusStepNum[IEEE80211_BAND_2G][3],
+ MinusStepNum[IEEE80211_BAND_2G][4],
+ MinusStepNum[IEEE80211_BAND_2G][5],
+ MinusStepNum[IEEE80211_BAND_2G][6],
+ MinusStepNum[IEEE80211_BAND_2G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] tssi gain/step = %u\n", pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_2G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4] Step = %u\n", Step[IEEE80211_BAND_2G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4] RefTemp_2G = %d\n", pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_2G]));
+
+#ifdef A_BAND_SUPPORT
+ if (RFIC_IS_5G_BAND(pAd))
+ {
+ /* Read from EEPROM, as parameters for lookup table for A band */
+ RT28xx_EEPROM_READ16(pAd, 0xd4, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM d4 = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_5G][0] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][2] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xd6, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM d6 = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_5G][4] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][6] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xd8, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM d8 = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_5G][0] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][2] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xda, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM da = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_5G][4] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][6] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xdc, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM dc = %x\n", WordStruct.word));
+ pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_5G] = (WordStruct.field.Byte0 & 0x0F);
+ Step[IEEE80211_BAND_5G] = (WordStruct.field.Byte0 >> 4);
+ pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_5G] = (CHAR)WordStruct.field.Byte1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] Plus = %u %u %u %u %u %u %u %u\n",
+ PlusStepNum[IEEE80211_BAND_5G][0],
+ PlusStepNum[IEEE80211_BAND_5G][1],
+ PlusStepNum[IEEE80211_BAND_5G][2],
+ PlusStepNum[IEEE80211_BAND_5G][3],
+ PlusStepNum[IEEE80211_BAND_5G][4],
+ PlusStepNum[IEEE80211_BAND_5G][5],
+ PlusStepNum[IEEE80211_BAND_5G][6],
+ PlusStepNum[IEEE80211_BAND_5G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] Minus = %u %u %u %u %u %u %u %u\n",
+ MinusStepNum[IEEE80211_BAND_5G][0],
+ MinusStepNum[IEEE80211_BAND_5G][1],
+ MinusStepNum[IEEE80211_BAND_5G][2],
+ MinusStepNum[IEEE80211_BAND_5G][3],
+ MinusStepNum[IEEE80211_BAND_5G][4],
+ MinusStepNum[IEEE80211_BAND_5G][5],
+ MinusStepNum[IEEE80211_BAND_5G][6],
+ MinusStepNum[IEEE80211_BAND_5G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] tssi gain/step = %u\n", pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_5G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] Step = %u\n", Step[IEEE80211_BAND_5G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] RefTemp_2G = %d\n", pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_5G]));
+
+ band_nums = IEEE80211_BAND_NUMS;
+ }
+#endif /* A_BAND_SUPPORT */
+
+
+ for (band = IEEE80211_BAND_2G; band < band_nums; band++)
+ {
+ /* positive */
+ i = 0;
+ IdxTmp = 1;
+
+ pAd->TxPowerCtrl.LookupTable[band][1 + Offset] = Step[band] / 2;
+ pAd->TxPowerCtrl.LookupTable[band][0 + Offset] = pAd->TxPowerCtrl.LookupTable[band][1 + Offset] - Step[band];
+ for (Idx = 2; Idx < 26;)/* Idx++ )*/
+ {
+ if (PlusStepNum[band][i] != 0 || i >= 8)
+ {
+ if (Idx >= IdxTmp + PlusStepNum[band][i] && i < 8)
+ {
+ pAd->TxPowerCtrl.LookupTable[band][Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][Idx - 1 + Offset] + (Step[band] - (i+1) + 1);
+ IdxTmp = IdxTmp + PlusStepNum[band][i];
+ i += 1;
+ }
+ else
+ {
+ pAd->TxPowerCtrl.LookupTable[band][Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][Idx - 1 + Offset] + (Step[band] - (i+1) + 1);
+ }
+ Idx++;
+ }
+ else
+ {
+ i += 1;
+ }
+ }
+
+ /* negative */
+ i = 0;
+ IdxTmp = 1;
+ for (Idx = 1; Idx < 8;)/* Idx++ )*/
+ {
+ if (MinusStepNum[band][i] != 0 || i >= 8)
+ {
+ if ((Idx + 1) >= IdxTmp + MinusStepNum[band][i] && i < 8)
+ {
+ pAd->TxPowerCtrl.LookupTable[band][-Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][-Idx + 1 + Offset] - (Step[band] + (i+1) - 1);
+ IdxTmp = IdxTmp + MinusStepNum[band][i];
+ i += 1;
+ }
+ else
+ {
+ pAd->TxPowerCtrl.LookupTable[band][-Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][-Idx + 1 + Offset] - (Step[band] + (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 band(%d)] %d, %d\n", band, Idx - Offset, pAd->TxPowerCtrl.LookupTable[band][Idx]));
+ }
+ }
+
+ /* Set BBP_R47 */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpValue);
+ BbpValue = (BbpValue & 0xf7); /* bit3 = 0 */
+ BbpValue = (BbpValue | 0x80); /* bit7 = 1, bit4 = 0 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpValue);
+
+ /* Set RF_R27 */
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+ /* Set [7:6] to 01. For method 2, it is set at initialization. */
+ RFValue = ((RFValue & 0x7f) | 0x40);
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Set RF_R27 to 0x%x\n", RFValue));
+}
+
+
+VOID AsicGetAutoAgcOffsetForTemperatureSensor(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1)
+{
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ const TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable;
+ TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTableEntry0 = NULL; /* Ant0 */
+ TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTableEntry1 = NULL; /* Ant1 */
+ BBP_R49_STRUC BbpR49;
+ BOOLEAN bAutoTxAgc = FALSE;
+ PCHAR pTxAgcCompensate = NULL;
+ UCHAR RFValue = 0;
+ CHAR TuningTableUpperBound = 0, TuningTableIndex0 = 0, TuningTableIndex1 = 0;
+ INT CurrentTemp = 0;
+ INT RefTemp;
+ INT *LookupTable;
+ INT LookupTableIndex = pAd->TxPowerCtrl.LookupTableIndex + TEMPERATURE_COMPENSATION_LOOKUP_TABLE_OFFSET;
+
+ DBGPRINT(RT_DEBUG_INFO, ("-->%s\n", __FUNCTION__));
+
+ BbpR49.byte = 0;
+ *pTotalDeltaPwr = 0;
+
+#ifdef A_BAND_SUPPORT
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ /* a band channel */
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ TxPowerTuningTable = pChipCap->TxPowerTuningTable_5G;
+ RefTemp = pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_5G];
+ LookupTable = &pAd->TxPowerCtrl.LookupTable[IEEE80211_BAND_5G][0];
+ TuningTableUpperBound = pChipCap->TxAlcTxPowerUpperBound_5G;
+ }
+ else
+#endif /* A_BAND_SUPPORT */
+ {
+ /* bg band channel */
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ TxPowerTuningTable = pChipCap->TxPowerTuningTable_2G;
+ RefTemp = pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_2G];
+ LookupTable = &pAd->TxPowerCtrl.LookupTable[IEEE80211_BAND_2G][0];
+ TuningTableUpperBound = pChipCap->TxAlcTxPowerUpperBound_2G;
+ }
+
+ /* AutoTxAgc in EEPROM means temperature compensation enabled/diablded. */
+ if (bAutoTxAgc)
+ {
+ /* Current temperature */
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ {
+ UINT32 bbp_val;
+ RTMP_BBP_IO_READ32(pAd, CORE_R35, &bbp_val);
+ CurrentTemp = (UCHAR)(bbp_val & 0xff);
+ }
+ else
+#endif /* RT65xx */
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte);
+ CurrentTemp = (CHAR)BbpR49.byte;
+ }
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] BBP_R49 = %02x, current temp = %d\n", BbpR49.byte, CurrentTemp));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] RefTemp = %d\n", RefTemp));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] index = %d\n", pAd->TxPowerCtrl.LookupTableIndex));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex - 1, LookupTable[LookupTableIndex - 1]));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex, LookupTable[LookupTableIndex]));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex + 1, LookupTable[LookupTableIndex + 1]));
+ if (CurrentTemp > RefTemp + LookupTable[LookupTableIndex + 1] + ((LookupTable[LookupTableIndex + 1] - LookupTable[LookupTableIndex]) >> 2) &&
+ LookupTableIndex < 32)
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] ++\n"));
+ LookupTableIndex++;
+ pAd->TxPowerCtrl.LookupTableIndex++;
+ }
+ else if (CurrentTemp < RefTemp + LookupTable[LookupTableIndex] - ((LookupTable[LookupTableIndex] - LookupTable[LookupTableIndex - 1]) >> 2) &&
+ LookupTableIndex > 0)
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] --\n"));
+ LookupTableIndex--;
+ pAd->TxPowerCtrl.LookupTableIndex--;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] ==\n"));
+ }
+
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] idxTxPowerTable=%d, idxTxPowerTable2=%d, TuningTableUpperBound=%d\n",
+ pAd->TxPowerCtrl.idxTxPowerTable + pAd->TxPowerCtrl.LookupTableIndex,
+ pAd->TxPowerCtrl.idxTxPowerTable2 + pAd->TxPowerCtrl.LookupTableIndex,
+ TuningTableUpperBound));
+
+ TuningTableIndex0 = pAd->TxPowerCtrl.idxTxPowerTable
+ + pAd->TxPowerCtrl.LookupTableIndex
+#ifdef DOT11_N_SUPPORT
+ + pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power;
+#else
+ + pAd->TxPower[pAd->CommonCfg.Channel-1].Power;
+#endif /* DOT11_N_SUPPORT */
+ /* The boundary verification */
+ TuningTableIndex0 = (TuningTableIndex0 > TuningTableUpperBound) ? TuningTableUpperBound : TuningTableIndex0;
+ TuningTableIndex0 = (TuningTableIndex0 < LOWERBOUND_TX_POWER_TUNING_ENTRY) ?
+ LOWERBOUND_TX_POWER_TUNING_ENTRY : TuningTableIndex0;
+ TxPowerTuningTableEntry0 = &TxPowerTuningTable[TuningTableIndex0 + TX_POWER_TUNING_ENTRY_OFFSET];
+
+ TuningTableIndex1 = pAd->TxPowerCtrl.idxTxPowerTable2
+ + pAd->TxPowerCtrl.LookupTableIndex
+#ifdef DOT11_N_SUPPORT
+ + pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power2;
+#else
+ + pAd->TxPower[pAd->CommonCfg.Channel-1].Power2;
+#endif /* DOT11_N_SUPPORT */
+ /* The boundary verification */
+ TuningTableIndex1 = (TuningTableIndex1 > TuningTableUpperBound) ? TuningTableUpperBound : TuningTableIndex1;
+ TuningTableIndex1 = (TuningTableIndex1 < LOWERBOUND_TX_POWER_TUNING_ENTRY) ?
+ LOWERBOUND_TX_POWER_TUNING_ENTRY : TuningTableIndex1;
+ TxPowerTuningTableEntry1 = &TxPowerTuningTable[TuningTableIndex1 + TX_POWER_TUNING_ENTRY_OFFSET];
+
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] (tx0)RF_TX_ALC = %x, MAC_PowerDelta = %d, TuningTableIndex = %d\n",
+ TxPowerTuningTableEntry0->RF_TX_ALC, TxPowerTuningTableEntry0->MAC_PowerDelta, TuningTableIndex0));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] (tx1)RF_TX_ALC = %x, MAC_PowerDelta = %d, TuningTableIndex = %d\n",
+ TxPowerTuningTableEntry1->RF_TX_ALC, TxPowerTuningTableEntry1->MAC_PowerDelta, TuningTableIndex1));
+
+ /* Update RF_R49 [0:5] */
+ RT30xxReadRFRegister(pAd, RF_R49, &RFValue);
+ RFValue = ((RFValue & ~0x3F) | TxPowerTuningTableEntry0->RF_TX_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);
+ }
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] Update RF_R49[0:5] to 0x%x\n", TxPowerTuningTableEntry0->RF_TX_ALC));
+ RT30xxWriteRFRegister(pAd, RF_R49, RFValue);
+
+ /* Update RF_R50 [0:5] */
+ RT30xxReadRFRegister(pAd, RF_R50, &RFValue);
+ RFValue = ((RFValue & ~0x3F) | TxPowerTuningTableEntry1->RF_TX_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);
+ }
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] Update RF_R50[0:5] to 0x%x\n", TxPowerTuningTableEntry1->RF_TX_ALC));
+ RT30xxWriteRFRegister(pAd, RF_R50, RFValue);
+
+ *pTotalDeltaPwr = TxPowerTuningTableEntry0->MAC_PowerDelta;
+
+ }
+
+ *pAgcCompensate = *pTxAgcCompensate;
+ DBGPRINT(RT_DEBUG_INFO, ("<--%s\n", __FUNCTION__));
+}
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+
+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);
+}
+
+}
+
+
+/*
+ ==========================================================================
+ 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",
+ PRINT_MAC(pBssid)));
+
+ Addr4 = (ULONG)(pBssid[0]) |
+ (ULONG)(pBssid[1] << 8) |
+ (ULONG)(pBssid[2] << 16) |
+ (ULONG)(pBssid[3] << 24);
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+#ifdef HDR_TRANS_SUPPORT
+ RTMP_IO_WRITE32(pAd, HT_MAC_BSSID_DW0, Addr4);
+#endif /* HDR_TRANS_SUPPORT */
+
+ Addr4 = 0;
+ /* always one BSSID in STA mode*/
+ Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
+
+
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+
+#ifdef HDR_TRANS_SUPPORT
+ /*
+ point WCID MAC table to 0x1800
+ This is for debug.
+ But HDR_TRANS doesn't work if you remove it.
+ Check after IC formal release.
+ */
+ Addr4 |= 0x18000000;
+ RTMP_IO_WRITE32(pAd, HT_MAC_BSSID_DW1, Addr4);
+#endif /* HDR_TRANS_SUPPORT */
+
+}
+
+
+VOID AsicSetMcastWC(RTMP_ADAPTER *pAd)
+{
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
+
+ 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(RTMP_ADAPTER *pAd, UCHAR Wcid)
+{
+ UINT32 offset;
+
+ DBGPRINT(RT_DEBUG_INFO, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
+
+ offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
+ RTMP_IO_WRITE32(pAd, offset, 0x0);
+ offset += 4;
+ RTMP_IO_WRITE32(pAd, offset, 0x0);
+}
+
+#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);
+}
+
+/*
+ ==========================================================================
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU*/
+ csr.field.bTsfTicking = 1;
+ csr.field.TsfSyncMode = 3; /* sync TSF similar as in ADHOC mode?*/
+ csr.field.bBeaconGen = 1; /* AP should generate BEACON*/
+ csr.field.bTBTTEnable = 1;
+ }
+#endif /* CONFIG_AP_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 = (USHORT) pAd->BeaconTxWI.TxWIMPDUByteCnt;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ UINT32 longptr;
+
+#ifdef RT_BIG_ENDIAN
+ {
+ TXWI_STRUC localTxWI;
+
+ NdisMoveMemory((PUCHAR)&localTxWI, (PUCHAR)&pAd->BeaconTxWI, TXWISize);
+ RTMPWIEndianChange(pAd, (PUCHAR)&localTxWI, TYPE_TXWI);
+ beaconLen = (USHORT) localTxWI.TxWIMPDUByteCnt;
+ }
+#endif /* RT_BIG_ENDIAN */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(TxWIMPDUByteCnt=%d, beaconLen=%d)\n", pAd->BeaconTxWI.TxWIMPDUByteCnt, beaconLen));
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. TxWIMPDUByteCnt = %d)\n", pAd->BeaconTxWI.TxWIMPDUByteCnt));
+
+ 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 RTMP_MAC_USB
+ /* move BEACON TXD and frame content to on-chip memory*/
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+ for (i=0; i < TXWISize; i+=2)
+ {
+ longptr = *ptr + (*(ptr+1)<<8);
+ RTMP_CHIP_UPDATE_BEACON(pAd, HW_BEACON_BASE0(pAd) + i, longptr, 2);
+ ptr += 2;
+ }
+
+ /* start right after the 16-byte TXWI field*/
+ ptr = pAd->BeaconBuf;
+ /*for (i=0; i< pAd->BeaconTxWI.TxWIMPDUByteCnt; i+=2)*/
+ for (i=0; i< beaconLen; i+=2)
+ {
+ longptr = *ptr + (*(ptr+1)<<8);
+ RTMP_CHIP_UPDATE_BEACON(pAd, HW_BEACON_BASE0(pAd) + TXWISize + i, longptr, 2);
+ ptr +=2;
+ }
+#endif /* RTMP_MAC_USB */
+
+
+
+ /* 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;
+ /*
+ (STA ad-hoc mode) Upon the reception of BEACON frame from associated BSS,
+ local TSF is updated with remote TSF only if the remote TSF is greater than local TSF
+ */
+ 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; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.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 (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+ {
+ 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 (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+ {
+ 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];
+ }
+ /*sync with window 20110524*/
+ 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*/
+
+#ifdef INF_AMAZON_SE
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ Ac2Cfg.field.Aifsn = 0x3; /*for WiFi WMM A1-T07.*/
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* INF_AMAZON_SE */
+
+
+ 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];
+/* For WMM Test PASS */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef RTMP_MAC_USB
+#ifdef MT7601
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if ( IS_MT7601(pAd) && Ac3Cfg.field.Aifsn > 0)
+ Ac3Cfg.field.Aifsn --;
+ }
+#endif /* MT7601 */
+#endif /* RTMP_MAC_USB */
+#endif /* CONFIG_AP_SUPPORT */
+
+/*#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];
+ }
+ }
+/*#endif WIFI_TEST */
+
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+ /*========================================================*/
+ /* DMA Register has a copy too.*/
+ /*========================================================*/
+ csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
+ csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+
+ csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
+ csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+ CwminCsr.word = 0;
+ CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
+ CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
+ CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO];
+#endif /* CONFIG_AP_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];*/
+ AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VI];*/
+#ifdef INF_AMAZON_SE
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VO]*/
+ AifsnCsr.field.Aifsn2 = 0x2; /*pEdcaParm->Aifsn[QID_AC_VI]; for WiFi WMM A1-T07.*/
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* INF_AMAZON_SE */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VO]*/
+#endif /* CONFIG_AP_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]));
+ }
+
+ }
+
+ pAd->CommonCfg.RestoreBurstMode = Ac0Cfg.word;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetSlotTime(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUseShortSlotTime)
+{
+ ULONG SlotTime;
+ UINT32 RegValue = 0;
+
+
+ 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;
+
+
+
+ /* For some reasons, always set it to short slot time.*/
+ /* ToDo: Should consider capability with 11B*/
+
+ 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, FALSE);
+
+ offset += MAX_LEN_OF_SHARE_KEY;
+ if (pTxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pTxMic, 8, FALSE);
+ }
+
+ offset += 8;
+ if (pRxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pRxMic, 8, FALSE);
+ }
+}
+#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);
+
+#ifdef WAPI_SUPPORT
+ /* Update WAPI related information */
+ if (CipherAlg == CIPHER_SMS4)
+ {
+ if (KeyTabFlag == SHAREDKEYTABLE)
+ WCIDAttri.field.WAPI_MCBC = 1;
+ WCIDAttri.field.WAPIKeyIdx = ((KeyIdx == 0) ? 0 : 1);
+ }
+#endif /* WAPI_SUPPORT */
+
+ /* 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;
+
+ /* 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, FALSE);
+#endif /* RTMP_MAC_USB */
+ for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
+ {
+ UINT32 Value;
+ RTMP_IO_READ32(pAd, offset + i, &Value);
+ }
+
+ offset += MAX_LEN_OF_PEER_KEY;
+
+ /* MIC KEY*/
+ if (pTxMic)
+ {
+#ifdef RTMP_MAC_USB
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8, FALSE);
+#endif /* RTMP_MAC_USB */
+ }
+ offset += 8;
+ if (pRxMic)
+ {
+#ifdef RTMP_MAC_USB
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8, FALSE);
+#endif /* RTMP_MAC_USB */
+ }
+ 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 RTMP_ADAPTER *pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1,
+ IN BOOLEAN in_atomic)
+{
+#ifdef RT65xx
+ // TODO: shiang-6590, fix me, currently firmware is not ready yet, so ignore it!
+ if (IS_RT65XX(pAd))
+ return TRUE;
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ return TRUE;
+#endif /* MT7601 */
+
+ if (pAd->chipOps.sendCommandToMcu)
+ return pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1, in_atomic);
+ else
+ return FALSE;
+}
+
+
+BOOLEAN AsicSendCommandToMcuBBP(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1,
+ IN BOOLEAN FlgIsNeedLocked)
+{
+#ifdef RT65xx
+ // TODO: shiang-6590, fix me, currently firmware is not ready yet, so ignore it!
+ if (IS_RT65XX(pAd)) {
+ return TRUE;
+ }
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ return TRUE;
+#endif /* MT7601 */
+
+ 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 WAPI_SUPPORT
+VOID AsicUpdateWAPIPN(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG pn_low,
+ IN ULONG pn_high)
+{
+ if (IS_HW_WAPI_SUPPORT(pAd))
+ {
+ ULONG offset;
+
+ offset = WAPI_PN_TABLE_BASE + (WCID * WAPI_PN_ENTRY_SIZE);
+
+ RTMP_IO_WRITE32(pAd, offset, pn_low);
+ RTMP_IO_WRITE32(pAd, offset + 4, pn_high);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s : Not support HW_WAPI_PN_TABLE\n",
+ __FUNCTION__));
+ }
+
+}
+#endif /* WAPI_SUPPORT */
+
+
+
+#ifdef VCORECAL_SUPPORT
+VOID AsicVCORecalibration(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue = 0;
+ UINT32 TxPinCfg = 0;
+ UINT8 mode = pAd->chipCap.FlgIsVcoReCalMode;
+
+ if (mode == VCO_CAL_DISABLE)
+ return;
+
+#ifdef RTMP_INTERNAL_TX_ALC
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ RTMP_IO_READ32(pAd, TX_PIN_CFG, &TxPinCfg);
+ TxPinCfg &= 0xFCFFFFF0;
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+ switch (mode)
+ {
+
+#ifdef RLT_RF
+ case VCO_CAL_MODE_3:
+
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, 0x0A);
+ rlt_rf_write(pAd, RF_BANK0, RF_R05, 0x20);
+ rlt_rf_read(pAd, RF_BANK0, RF_R04, &RFValue);
+ RFValue = RFValue | 0x80; /* bit 7=vcocal_en*/
+ rlt_rf_write(pAd, RF_BANK0, RF_R04, RFValue);
+ break;
+#endif /* RLT_RF */
+
+ default:
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+ RTMP_IO_READ32(pAd, TX_PIN_CFG, &TxPinCfg);
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ if (pAd->Antenna.field.TxPath == 1)
+ TxPinCfg |= 0x2;
+ else if (pAd->Antenna.field.TxPath == 2)
+ TxPinCfg |= 0xA;
+ else if (pAd->Antenna.field.TxPath == 3)
+ TxPinCfg |= 0x0200000A;
+ }
+ else
+ {
+ if (pAd->Antenna.field.TxPath == 1)
+ TxPinCfg |= 0x1;
+ else if (pAd->Antenna.field.TxPath == 2)
+ TxPinCfg |= 0x5;
+ else if (pAd->Antenna.field.TxPath == 3)
+ TxPinCfg |= 0x01000005;
+ }
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+#ifdef TXBF_SUPPORT
+ // Do a Divider Calibration and update BBP registers
+ if (pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_DISABLE_CAL)==0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ ITxBFDividerCalibration(pAd, 2, 0, NULL);
+ }
+
+ if (pAd->CommonCfg.ETxBfEnCond)
+ {
+ INT idx;
+
+ for (idx = 1; idx < MAX_LEN_OF_MAC_TABLE; idx++)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+
+ pEntry = &pAd->MacTab.Content[idx];
+ if ((IS_ENTRY_CLIENT(pEntry)) && (pEntry->eTxBfEnCond))
+ {
+ BOOLEAN Cancelled;
+
+ RTMPCancelTimer(&pEntry->eTxBfProbeTimer, &Cancelled);
+
+ pEntry->bfState = READY_FOR_SNDG0;
+ eTxBFProbing(pAd, pEntry);
+ }
+ }
+ }
+#endif // TXBF_SUPPORT //
+}
+#endif /* VCORECAL_SUPPORT */
+
+
+#ifdef STREAM_MODE_SUPPORT
+// StreamModeRegVal - return MAC reg value for StreamMode setting
+UINT32 StreamModeRegVal(
+ IN RTMP_ADAPTER *pAd)
+{
+ UINT32 streamWord;
+
+ switch (pAd->CommonCfg.StreamMode)
+ {
+ case 1:
+ streamWord = 0x030000;
+ break;
+ case 2:
+ streamWord = 0x0c0000;
+ break;
+ case 3:
+ streamWord = 0x0f0000;
+ break;
+ default:
+ streamWord = 0x0;
+ break;
+ }
+
+ return streamWord;
+}
+
+
+/*
+ ========================================================================
+ Description:
+ configure the stream mode of specific MAC or all MAC and set to ASIC.
+
+ Prameters:
+ pAd ---
+ pMacAddr ---
+ bClear --- disable the stream mode for specific macAddr when
+ (pMacAddr!=NULL)
+
+ Return:
+ ========================================================================
+*/
+VOID AsicSetStreamMode(
+ IN RTMP_ADAPTER *pAd,
+ IN PUCHAR pMacAddr,
+ IN INT chainIdx,
+ IN BOOLEAN bEnabled)
+{
+ UINT32 streamWord;
+ UINT32 regAddr, regVal;
+
+
+ if (!pAd->chipCap.FlgHwStreamMode)
+ return;
+
+ streamWord = StreamModeRegVal(pAd);
+ if (!bEnabled)
+ streamWord = 0;
+
+ regAddr = TX_CHAIN_ADDR0_L + chainIdx * 4;
+ RTMP_IO_WRITE32(pAd, regAddr,
+ (UINT32)(pMacAddr[0]) |
+ (UINT32)(pMacAddr[1] << 8) |
+ (UINT32)(pMacAddr[2] << 16) |
+ (UINT32)(pMacAddr[3] << 24));
+
+ RTMP_IO_READ32(pAd, regAddr + 4, &regVal);
+ regVal &= (~0x000f0000);
+ RTMP_IO_WRITE32(pAd, regAddr + 4,
+ (regVal | streamWord) |
+ (UINT32)(pMacAddr[4]) |
+ (UINT32)(pMacAddr[5] << 8));
+
+}
+
+
+VOID RtmpStreamModeInit(
+ IN RTMP_ADAPTER *pAd)
+{
+ int chainIdx;
+ UCHAR *pMacAddr;
+
+ if (pAd->chipCap.FlgHwStreamMode == FALSE)
+ return;
+
+ for (chainIdx = 0; chainIdx < STREAM_MODE_STA_NUM; chainIdx++)
+ {
+ pMacAddr = &pAd->CommonCfg.StreamModeMac[chainIdx][0];
+ AsicSetStreamMode(pAd, pMacAddr, chainIdx, TRUE);
+ }
+}
+#endif // STREAM_MODE_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableRalinkBurstMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Data = 0;
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ pAd->CommonCfg.RestoreBurstMode = Data;
+ Data &= 0xFFF00000;
+ Data |= 0x86380;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableRalinkBurstMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Data = 0;
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+ Data = pAd->CommonCfg.RestoreBurstMode;
+ Data &= 0xFFFFFF00;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE))
+ Data |= 0x80;
+ else if (pAd->CommonCfg.bEnableTxBurst)
+ Data |= 0x20;
+ }
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef WOW_SUPPORT
+#ifdef RTMP_MAC_USB
+
+/* switch firmware
+ a) before into WOW mode, switch firmware to WOW-enable firmware
+ b) exit from WOW mode, switch firmware to normal firmware
+*/
+VOID AsicLoadWOWFirmware(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN WOW)
+{
+ if (WOW)
+ pAd->WOW_Cfg.bWOWFirmware = TRUE;
+ else
+ pAd->WOW_Cfg.bWOWFirmware = FALSE;
+
+ RtmpAsicLoadFirmware(pAd);
+}
+
+/* In WOW mode, 8051 mcu will send null frame, and pick data from 0x7780
+ * the null frame includes TxWI and 802.11 header */
+VOID AsicWOWSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull)
+{
+
+ TXWI_STRUC *TxWI;
+ PUCHAR NullFrame;
+ UINT8 packet_len;
+ PUCHAR ptr;
+ USHORT offset;
+ UINT32 cipher = pAd->StaCfg.GroupCipher;
+ UINT32 Value;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ ComposeNullFrame(pAd);
+ TxWI = (TXWI_STRUC *)&pAd->NullContext[0].TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+ NullFrame = (PUCHAR)&pAd->NullFrame;
+ packet_len = TxWI->TxWIMPDUByteCnt;
+
+ DBGPRINT(RT_DEBUG_OFF, ("TxWI:\n"));
+ /* copy TxWI to MCU memory */
+ ptr = (PUCHAR)TxWI;
+ for (offset = 0; offset < TXWISize; offset += 4)
+ {
+ RTMPMoveMemory(&Value, ptr+offset, 4);
+ DBGPRINT(RT_DEBUG_OFF, ("offset: %02d %08x\n", offset, Value));
+ RTMP_IO_WRITE32(pAd, HW_NULL2_BASE + offset, Value);
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("802.11 header:\n"));
+ /* copy 802.11 header to memory */
+ ptr = (PUCHAR)NullFrame;
+ for (offset = 0; offset < packet_len; offset += 4)
+ {
+ RTMPMoveMemory(&Value, ptr+offset, 4);
+ DBGPRINT(RT_DEBUG_OFF, ("offset: %02d %08x\n", offset, Value));
+ RTMP_IO_WRITE32(pAd, HW_NULL2_BASE + TXWISize + offset, Value);
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("Write GroupCipher Mode: %d\n", pAd->StaCfg.GroupCipher));
+
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &Value);
+
+ switch (cipher) /* don't care WEP, because it dosen't have re-key issue */
+ {
+ case Ndis802_11Encryption2Enabled: /* TKIP */
+ Value |= 0x0330;
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, Value);
+ break;
+ case Ndis802_11Encryption3Enabled: /* AES */
+ Value |= 0x0440;
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, Value);
+ break;
+ }
+}
+
+#endif /* RTMP_MAC_USB */
+#endif /* WOW_SUPPORT */
+
+
+INT AsicSetPreTbttInt(RTMP_ADAPTER *pAd, BOOLEAN enable)
+{
+ UINT32 val;
+
+ RTMP_IO_READ32(pAd, INT_TIMER_CFG, &val);
+ val &= 0xffff0000;
+ val |= 6 << 4; /* Pre-TBTT is 6ms before TBTT interrupt. 1~10 ms is reasonable. */
+ RTMP_IO_WRITE32(pAd, INT_TIMER_CFG, val);
+ /* Enable pre-tbtt interrupt */
+ RTMP_IO_READ32(pAd, INT_TIMER_EN, &val);
+ val |=0x1;
+ RTMP_IO_WRITE32(pAd, INT_TIMER_EN, val);
+
+ return TRUE;
+}
+
+
+BOOLEAN AsicWaitPDMAIdle(struct _RTMP_ADAPTER *pAd, INT round, INT wait_us)
+{
+ INT i = 0;
+ WPDMA_GLO_CFG_STRUC GloCfg;
+
+
+ do {
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) {
+ DBGPRINT(RT_DEBUG_TRACE, ("==> DMAIdle, GloCfg=0x%x\n", GloCfg.word));
+ return TRUE;
+ }
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+ RTMPusecDelay(wait_us);
+ }while ((i++) < round);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy, GloCfg=0x%x\n", GloCfg.word));
+
+ return FALSE;
+}
+
+
+#ifdef DOT11_N_SUPPORT
+#if defined(RT65xx) || defined(MT7601)
+#define MAX_AGG_CNT 32
+#elif defined(RT2883) || defined(RT3883)
+#define MAX_AGG_CNT 16
+#else
+#define MAX_AGG_CNT 8
+#endif
+INT AsicReadAggCnt(RTMP_ADAPTER *pAd, ULONG *aggCnt, int cnt_len)
+{
+ UINT32 reg_addr;
+ TX_AGG_CNT_STRUC reg_val;
+ int i, cnt, seg;
+ static USHORT aggReg[] = {
+ TX_AGG_CNT, TX_AGG_CNT3,
+#if MAX_AGG_CNT > 8
+ TX_AGG_CNT4, TX_AGG_CNT7,
+#endif
+#if MAX_AGG_CNT > 16
+ TX_AGG_CNT8, TX_AGG_CNT15,
+#endif
+ };
+
+
+ NdisZeroMemory(aggCnt, cnt_len * sizeof(ULONG));
+ seg = (sizeof(aggReg) /sizeof(USHORT));
+
+ cnt = 0;
+ for (i = 0; i < seg; i += 2)
+ {
+ for (reg_addr = aggReg[i] ; reg_addr <= aggReg[i+1] ; reg_addr += 4)
+ {
+ RTMP_IO_READ32(pAd, reg_addr, &reg_val.word);
+ if (cnt < (cnt_len -1)) {
+ aggCnt[cnt] = reg_val.field.AggCnt_x;
+ aggCnt[cnt+1] = reg_val.field.AggCnt_y;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():Get AggSize at Reg(0x%x) with val(0x%08x) [AGG_%d=>%ld, AGG_%d=>%ld]\n",
+ __FUNCTION__, reg_addr, reg_val.word, cnt, aggCnt[cnt], cnt+1, aggCnt[cnt+1]));
+ cnt += 2;
+ } else {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():Get AggSize at Reg(0x%x) failed, no enough buffer(cnt_len=%d, cnt=%d)\n",
+ __FUNCTION__, reg_addr, cnt_len, cnt));
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+#endif /* DOT11_N_SUPPORT */
+
+
+INT AsicSetChannel(RTMP_ADAPTER *pAd, UCHAR ch, UCHAR bw, UCHAR ext_ch, BOOLEAN bScan)
+{
+ rtmp_bbp_set_bw(pAd, bw);
+
+ /* Tx/RX : control channel setting */
+ rtmp_bbp_set_ctrlch(pAd, ext_ch);
+ rtmp_mac_set_ctrlch(pAd, ext_ch);
+
+ /* Let BBP register at 20MHz to do scan */
+ AsicSwitchChannel(pAd, ch, bScan);
+ AsicLockChannel(pAd, ch);
+
+#ifdef RT28xx
+ RT28xx_ch_tunning(pAd, bw);
+#endif /* RT28xx */
+
+ return 0;
+}
+
+
+#ifdef NEW_WOW_SUPPORT
+VOID RT28xxAndesWOWEnable(
+ IN PRTMP_ADAPTER pAd)
+{
+ NEW_WOW_MASK_CFG_STRUCT mask_cfg;
+ NEW_WOW_SEC_CFG_STRUCT sec_cfg;
+ NEW_WOW_INFRA_CFG_STRUCT infra_cfg;
+ NEW_WOW_P2P_CFG_STRUCT p2p_cfg;
+ NEW_WOW_PARAM_STRUCT wow_param;
+ struct CMD_UNIT CmdUnit;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ /* WOW enable */
+ NdisZeroMemory(&wow_param, sizeof(wow_param));
+
+ wow_param.Parameter = WOW_ENABLE; /* WOW enable */
+ wow_param.Value = TRUE;
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_FEATURE; /* feature enable */
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_PARAM_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&wow_param;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed(%d/%d)!!\x1b[m\n", __FUNCTION__,
+ CmdUnit.u.ANDES.Type, wow_param.Parameter);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+ /* mask configuration */
+ NdisZeroMemory(&mask_cfg, sizeof(mask_cfg));
+
+ mask_cfg.Config_Type = WOW_MASK_CFG; /* detect mask config */
+ mask_cfg.Function_Enable = TRUE;
+ mask_cfg.Detect_Mask = 1UL << WOW_MAGIC_PKT; /* magic packet */
+ mask_cfg.Event_Mask = 0;
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_CONFIG; /* WOW config */
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_MASK_CFG_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&mask_cfg;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed!!(%d/%d)\x1b[m\n", __FUNCTION__,
+ CmdUnit.u.ANDES.Type, mask_cfg.Config_Type);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+ /* security configuration */
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPAPSK)
+ {
+ NdisZeroMemory(&sec_cfg, sizeof(sec_cfg));
+
+ sec_cfg.Config_Type = WOW_SEC_CFG; /* security config */
+
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+ sec_cfg.WPA_Ver = 0;
+ else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+ sec_cfg.WPA_Ver = 1;
+
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+
+ NdisCopyMemory(sec_cfg.PTK, pEntry->PTK, 64);
+ NdisCopyMemory(sec_cfg.R_COUNTER, pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
+
+ sec_cfg.Key_Id = pAd->StaCfg.DefaultKeyId;
+ sec_cfg.Cipher_Alg = pEntry->WepStatus;
+ printk("\x1b[31m%s: wep status %d\x1b[m\n", __FUNCTION__, pEntry->WepStatus);
+ sec_cfg.Group_Cipher = pAd->StaCfg.GroupCipher;
+ printk("\x1b[31m%s: group status %d\x1b[m\n", __FUNCTION__, sec_cfg.Group_Cipher);
+ printk("\x1b[31m%s: aid %d\x1b[m\n", __FUNCTION__, pEntry->Aid);
+ sec_cfg.WCID = BSSID_WCID;
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_CONFIG; /* WOW config */
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_SEC_CFG_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&sec_cfg;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed(%d/%d)!!\x1b[m\n", __FUNCTION__,
+ CmdUnit.u.ANDES.Type, sec_cfg.Config_Type);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+ }
+
+ /* Infra configuration */
+
+ NdisZeroMemory(&infra_cfg, sizeof(infra_cfg));
+
+ infra_cfg.Config_Type = WOW_INFRA_CFG; /* infra config */
+
+ COPY_MAC_ADDR(infra_cfg.STA_MAC, pAd->CurrentAddress);
+ COPY_MAC_ADDR(infra_cfg.AP_MAC, pAd->CommonCfg.Bssid);
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_CONFIG; /* WOW config */
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_INFRA_CFG_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&infra_cfg;
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ infra_cfg.AP_Status = TRUE;
+ else
+ infra_cfg.AP_Status = FALSE;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed(%d/%d)!!\x1b[m\n", __FUNCTION__,
+ CmdUnit.u.ANDES.Type, infra_cfg.Config_Type);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+
+ /* P2P configuration */
+
+ /* Wakeup Option */
+ NdisZeroMemory(&wow_param, sizeof(wow_param));
+
+ wow_param.Parameter = WOW_WAKEUP; /* Wakeup Option */
+ if (pAd->WOW_Cfg.bInBand)
+ {
+ wow_param.Value = WOW_WAKEUP_BY_USB;
+ }
+ else
+ {
+ INT32 Value;
+
+ wow_param.Value = WOW_WAKEUP_BY_GPIO;
+
+ RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &Value);
+ printk("\x1b[31m%s: 0x80 = %x\x1b[m\n", __FUNCTION__, Value);
+ Value &= ~0x01010000; /* GPIO0(ouput) --> 0(data) */
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, Value);
+ }
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_FEATURE; /* feature enable */
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_PARAM_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&wow_param;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed(%d/%d)!!\x1b[m\n", __FUNCTION__,
+ CmdUnit.u.ANDES.Type, wow_param.Parameter);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+
+ /* traffic to Andes */
+ NdisZeroMemory(&wow_param, sizeof(wow_param));
+ wow_param.Parameter = WOW_TRAFFIC; /* Traffic switch */
+ wow_param.Value = WOW_PKT_TO_ANDES; /* incoming packet to FW */
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_FEATURE; /* feature enable */
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_PARAM_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&wow_param.Parameter;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed(%d/%d)!!\x1b[m\n", __FUNCTION__,
+ CmdUnit.u.ANDES.Type, wow_param.Parameter);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+}
+
+VOID RT28xxAndesWOWDisable(
+ IN PRTMP_ADAPTER pAd)
+{
+ NEW_WOW_PARAM_STRUCT param;
+ struct CMD_UNIT CmdUnit;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ UINT32 Value;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ printk("\x1b[31m%s: ...\x1b[m", __FUNCTION__);
+
+ /* clean BulkIn Reset flag */
+ //pAd->Flags &= ~0x80000;
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ /* WOW disable */
+ NdisZeroMemory(&param, sizeof(param));
+ param.Parameter = WOW_ENABLE;
+ param.Value = FALSE;
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_FEATURE; /* WOW enable */
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_PARAM_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&param;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed!!\x1b[m\n", __FUNCTION__);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+
+ /* traffic to Host */
+ NdisZeroMemory(&param, sizeof(param));
+ param.Parameter = WOW_TRAFFIC;
+ param.Value = WOW_PKT_TO_HOST;
+
+ CmdUnit.u.ANDES.Type = CMD_WOW_FEATURE;
+ CmdUnit.u.ANDES.CmdPayloadLen = sizeof(NEW_WOW_PARAM_STRUCT);
+ CmdUnit.u.ANDES.CmdPayload = (PUCHAR)&param;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ {
+ printk("\x1b[31m%s: send WOW config command failed!!\x1b[m\n", __FUNCTION__);
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+
+ /* Restore MAC TX/RX */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= 0xC;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+
+ RTUSBBulkReceive(pAd);
+ RTUSBBulkCmdRspEventReceive(pAd);
+
+ //printk("\x1b[31m%s: pendingRx %d\x1b[m\n", __FUNCTION__, pAd->PendingRx);
+ //printk("\x1b[31m%s: BulkInReq %d\x1b[m\n", __FUNCTION__, pAd->BulkInReq);
+
+ /* restore hardware remote wakeup flag */
+ RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &Value);
+ printk("\x1b[31m%s: 0x80 %08x\x1b[m\n", __FUNCTION__, Value);
+ Value &= ~0x80;
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, Value);
+
+ if (pAd->WOW_Cfg.bInBand == FALSE)
+ {
+ INT32 Value;
+
+ RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &Value);
+ printk("\x1b[31m%s: 0x80 = %x\x1b[m\n", __FUNCTION__, Value);
+ Value &= ~0x01010000; /* GPIO0(ouput) --> 0(data) */
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, Value);
+ }
+}
+
+#endif /* NEW_WOW_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_cfg.c b/cleopatre/devkit/mt7601udrv/common/cmm_cfg.c
new file mode 100644
index 0000000000..5bd9773cdf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_cfg.c
@@ -0,0 +1,1494 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ cmm_cfg.c
+
+ Abstract:
+ Ralink WiFi Driver configuration related subroutines
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+*/
+
+
+
+#include "rt_config.h"
+#ifdef DOT11_N_SUPPORT
+#if defined(RT65xx) || defined(MT7601)
+#define MAX_AGG_CNT 32
+#elif defined(RT2883) || defined(RT3883)
+#define MAX_AGG_CNT 16
+#else
+#define MAX_AGG_CNT 8
+#endif
+/* DisplayTxAgg - display Aggregation statistics from MAC */
+void DisplayTxAgg (RTMP_ADAPTER *pAd)
+{
+ ULONG totalCount;
+ ULONG aggCnt[MAX_AGG_CNT + 2];
+ int i;
+
+ AsicReadAggCnt(pAd, aggCnt, sizeof(aggCnt) / sizeof(ULONG));
+ totalCount = aggCnt[0] + aggCnt[1];
+ if (totalCount > 0)
+ for (i=0; i<MAX_AGG_CNT; i++) {
+ DBGPRINT(RT_DEBUG_OFF, ("\t%d MPDU=%ld (%ld%%)\n", i+1, aggCnt[i+2], aggCnt[i+2]*100/totalCount));
+ }
+ printk("====================\n");
+
+}
+#endif /* DOT11_N_SUPPORT */
+
+static BOOLEAN RT_isLegalCmdBeforeInfUp(
+ IN PSTRING SetCmd);
+
+
+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;
+
+ NdisZeroMemory(macAddr, MAC_ADDR_LEN);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (bFromApcli)
+ NdisMoveMemory(&macAddr[0], pAd->ApCfg.ApCliTab[apidx].CurrentAddress, MAC_ADDR_LEN);
+ else
+#endif /* APCLI_SUPPORT */
+ NdisMoveMemory(&macAddr[0], pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ iPin = macAddr[3] * 256 * 256 + macAddr[4] * 256 + macAddr[5];
+
+ iPin = iPin % 10000000;
+
+
+ checksum = ComputeChecksum( iPin );
+ iPin = iPin*10 + checksum;
+
+ return iPin;
+}
+
+
+static char *phy_mode_str[]={"CCK", "OFDM", "HTMIX", "GF", "VHT"};
+char* get_phymode_str(int Mode)
+{
+ if (Mode >= MODE_CCK && Mode <= MODE_VHT)
+ return phy_mode_str[Mode];
+ else
+ return "N/A";
+}
+
+
+static UCHAR *phy_bw_str[] = {"20M", "40M", "80M", "10M"};
+char* get_bw_str(int bandwidth)
+{
+ if (bandwidth >= BW_20 && bandwidth <= BW_10)
+ return phy_bw_str[bandwidth];
+ else
+ 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;
+
+ /*
+ 1. If this value is set before interface up, do not reject this value.
+ 2. Country can be set only when EEPROM not programmed
+ */
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE) && (*pCountryRegion & EEPROM_IS_PROGRAMMED))
+ {
+ 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;
+
+}
+
+
+static UCHAR CFG_WMODE_MAP[]={
+ PHY_11BG_MIXED, (WMODE_B | WMODE_G), /* 0 => B/G mixed */
+ PHY_11B, (WMODE_B), /* 1 => B only */
+ PHY_11A, (WMODE_A), /* 2 => A only */
+ PHY_11ABG_MIXED, (WMODE_A | WMODE_B | WMODE_G), /* 3 => A/B/G mixed */
+ PHY_11G, WMODE_G, /* 4 => G only */
+ PHY_11ABGN_MIXED, (WMODE_B | WMODE_G | WMODE_GN | WMODE_A | WMODE_AN), /* 5 => A/B/G/GN/AN mixed */
+ PHY_11N_2_4G, (WMODE_GN), /* 6 => N in 2.4G band only */
+ PHY_11GN_MIXED, (WMODE_G | WMODE_GN), /* 7 => G/GN, i.e., no CCK mode */
+ PHY_11AN_MIXED, (WMODE_A | WMODE_AN), /* 8 => A/N in 5 band */
+ PHY_11BGN_MIXED, (WMODE_B | WMODE_G | WMODE_GN), /* 9 => B/G/GN mode*/
+ PHY_11AGN_MIXED, (WMODE_G | WMODE_GN | WMODE_A | WMODE_AN), /* 10 => A/AN/G/GN mode, not support B mode */
+ PHY_11N_5G, (WMODE_AN), /* 11 => only N in 5G band */
+#ifdef DOT11_VHT_AC
+ PHY_11VHT_N_ABG_MIXED, (WMODE_B | WMODE_G | WMODE_GN |WMODE_A | WMODE_AN | WMODE_AC), /* 12 => B/G/GN/A/AN/AC mixed*/
+ PHY_11VHT_N_AG_MIXED, (WMODE_G | WMODE_GN |WMODE_A | WMODE_AN | WMODE_AC), /* 13 => G/GN/A/AN/AC mixed , no B mode */
+ PHY_11VHT_N_A_MIXED, (WMODE_A | WMODE_AN | WMODE_AC), /* 14 => A/AC/AN mixed */
+ PHY_11VHT_N_MIXED, (WMODE_AN | WMODE_AC), /* 15 => AC/AN mixed, but no A mode */
+#endif /* DOT11_VHT_AC */
+ PHY_MODE_MAX, WMODE_INVALID /* default phy mode if not match */
+};
+
+
+static PSTRING BAND_STR[] = {"Invalid", "2.4G", "5G", "2.4G/5G"};
+static PSTRING WMODE_STR[]= {"", "A", "B", "G", "gN", "aN", "AC"};
+
+UCHAR *wmode_2_str(UCHAR wmode)
+{
+ UCHAR *str;
+ INT idx, pos, max_len;
+
+ max_len = WMODE_COMP * 3;
+ if (os_alloc_mem(NULL, &str, max_len) == NDIS_STATUS_SUCCESS)
+ {
+ NdisZeroMemory(str, max_len);
+ pos = 0;
+ for (idx = 0; idx < WMODE_COMP; idx++)
+ {
+ if (wmode & (1 << idx)) {
+ if ((strlen(str) + strlen(WMODE_STR[idx + 1])) >= (max_len - 1))
+ break;
+ if (strlen(str)) {
+ NdisMoveMemory(&str[pos], "/", 1);
+ pos++;
+ }
+ NdisMoveMemory(&str[pos], WMODE_STR[idx + 1], strlen(WMODE_STR[idx + 1]));
+ pos += strlen(WMODE_STR[idx + 1]);
+ }
+ if (strlen(str) >= max_len)
+ break;
+ }
+
+ return str;
+ }
+ else
+ return NULL;
+}
+
+
+UCHAR cfgmode_2_wmode(UCHAR cfg_mode)
+{
+ DBGPRINT(RT_DEBUG_OFF, ("cfg_mode=%d\n", cfg_mode));
+ if (cfg_mode >= PHY_MODE_MAX)
+ cfg_mode = PHY_MODE_MAX;
+
+ return CFG_WMODE_MAP[cfg_mode * 2 + 1];
+}
+
+
+UCHAR wmode_2_cfgmode(UCHAR wmode)
+{
+ INT index;
+ DBGPRINT(RT_DEBUG_OFF, ("wmode=%d\n", wmode));
+
+ for (index = 0; index < PHY_MODE_MAX; index++ )
+ {
+ if ( wmode == CFG_WMODE_MAP[index*2 + 1])
+ return CFG_WMODE_MAP[index*2];
+ }
+
+ return PHY_11ABGN_MIXED;
+}
+
+
+static BOOLEAN wmode_valid(RTMP_ADAPTER *pAd, enum WIFI_MODE wmode)
+{
+ if ((WMODE_CAP_5G(wmode) && (!PHY_CAP_5G(pAd->chipCap.phy_caps))) ||
+ (WMODE_CAP_2G(wmode) && (!PHY_CAP_2G(pAd->chipCap.phy_caps))) ||
+ (WMODE_CAP_N(wmode) && RTMP_TEST_MORE_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DOT_11N))
+ )
+ return FALSE;
+ else
+ return TRUE;
+}
+
+
+static BOOLEAN wmode_valid_and_correct(RTMP_ADAPTER *pAd, UCHAR* wmode)
+{
+ BOOLEAN ret = TRUE;
+ UCHAR mode = *wmode;
+
+ if (WMODE_CAP_5G(*wmode) && (!PHY_CAP_5G(pAd->chipCap.phy_caps)))
+ {
+ *wmode = *wmode & ~(WMODE_A | WMODE_AN | WMODE_AC);
+ }
+ else if (WMODE_CAP_2G(*wmode) && (!PHY_CAP_2G(pAd->chipCap.phy_caps)))
+ {
+ *wmode = *wmode & ~(WMODE_B | WMODE_G | WMODE_GN);
+ }
+ else if (WMODE_CAP_N(*wmode) && RTMP_TEST_MORE_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DOT_11N))
+ {
+ *wmode = *wmode & ~(WMODE_GN | WMODE_AN);
+ }
+
+ if ( *wmode == 0 )
+ ret = FALSE;
+
+ return ret;
+}
+
+
+BOOLEAN wmode_band_equal(UCHAR smode, UCHAR tmode)
+{
+ BOOLEAN eq = FALSE;
+ UCHAR *str1, *str2;
+
+ if ((WMODE_CAP_5G(smode) == WMODE_CAP_5G(tmode)) &&
+ (WMODE_CAP_2G(smode) == WMODE_CAP_2G(tmode)))
+ eq = TRUE;
+
+ str1 = wmode_2_str(smode);
+ str2 = wmode_2_str(tmode);
+ if (str1 && str2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("Old WirelessMode:%s(0x%x), "
+ "New WirelessMode:%s(0x%x)!\n",
+ str1, smode, str2, tmode));
+ }
+ if (str1)
+ os_free_mem(NULL, str1);
+ if (str2)
+ os_free_mem(NULL, str2);
+
+ return eq;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Wireless Mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT RT_CfgSetWirelessMode(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ LONG cfg_mode;
+ UCHAR wmode, *mode_str;
+
+
+ cfg_mode = simple_strtol(arg, 0, 10);
+
+ /* check if chip support 5G band when WirelessMode is 5G band */
+ wmode = cfgmode_2_wmode((UCHAR)cfg_mode);
+ if ((wmode == WMODE_INVALID) || (!wmode_valid_and_correct(pAd, &wmode))) {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("%s(): Invalid wireless mode(%ld), ChipCap(%s)\n",
+ __FUNCTION__, cfg_mode,
+ BAND_STR[pAd->chipCap.phy_caps & 0x3]));
+ return FALSE;
+ }
+
+ if (wmode_band_equal(pAd->CommonCfg.PhyMode, wmode) == TRUE)
+ DBGPRINT(RT_DEBUG_OFF, ("wmode_band_equal(): Band Equal!\n"));
+ else
+ DBGPRINT(RT_DEBUG_OFF, ("wmode_band_equal(): Band Not Equal!\n"));
+
+ pAd->CommonCfg.PhyMode = wmode;
+ pAd->CommonCfg.cfg_wmode = wmode;
+
+ mode_str = wmode_2_str(wmode);
+ if (mode_str)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): Set WMODE=%s(0x%x)\n",
+ __FUNCTION__, mode_str, wmode));
+ os_free_mem(NULL, mode_str);
+ }
+
+ return TRUE;
+}
+
+
+/* maybe can be moved to GPL code, ap_mbss.c, but the code will be open */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+static UCHAR RT_CfgMbssWirelessModeMaxGet(RTMP_ADAPTER *pAd)
+{
+ UCHAR wmode = 0, *mode_str;
+ INT idx;
+ MULTISSID_STRUCT *wdev;
+
+ for(idx = 0; idx < pAd->ApCfg.BssidNum; idx++) {
+ wdev = &pAd->ApCfg.MBSSID[idx];
+ mode_str = wmode_2_str(wdev->PhyMode);
+ if (mode_str)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(BSS%d): wmode=%s(0x%x)\n",
+ __FUNCTION__, idx, mode_str, wdev->PhyMode));
+ os_free_mem(pAd, mode_str);
+ }
+ wmode |= wdev->PhyMode;
+ }
+
+ mode_str = wmode_2_str(wmode);
+ if (mode_str)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): Combined WirelessMode = %s(0x%x)\n",
+ __FUNCTION__, mode_str, wmode));
+ os_free_mem(pAd, mode_str);
+ }
+ return wmode;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set Wireless Mode for MBSS
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT RT_CfgSetMbssWirelessMode(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ LONG cfg_mode;
+ UCHAR wmode;
+
+
+ cfg_mode = simple_strtol(arg, 0, 10);
+
+ wmode = cfgmode_2_wmode((UCHAR)cfg_mode);
+ if ((wmode == WMODE_INVALID) || (!wmode_valid(pAd, wmode))) {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("%s(): Invalid wireless mode(%d, wmode=0x%x), ChipCap(%s)\n",
+ __FUNCTION__, cfg_mode, wmode,
+ BAND_STR[pAd->chipCap.phy_caps & 0x3]));
+ return FALSE;
+ }
+
+ if (WMODE_CAP_5G(wmode) && WMODE_CAP_2G(wmode))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("AP cannot support 2.4G/5G band mxied mode!\n"));
+ return FALSE;
+ }
+
+ if (pAd->ApCfg.BssidNum > 1)
+ {
+ /* pAd->CommonCfg.PhyMode = maximum capability of all MBSS */
+ if (wmode_band_equal(pAd->CommonCfg.PhyMode, wmode) == TRUE)
+ {
+ wmode = RT_CfgMbssWirelessModeMaxGet(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("mbss> Maximum phy mode = %d!\n", wmode));
+ }
+ else
+ {
+ UINT32 IdBss;
+
+ /* replace all phy mode with the one with different band */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("mbss> Different band with the current one!\n"));
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("mbss> Reset band of all BSS to the new one!\n"));
+
+ for(IdBss=0; IdBss<pAd->ApCfg.BssidNum; IdBss++)
+ pAd->ApCfg.MBSSID[IdBss].PhyMode = wmode;
+ }
+ }
+
+ pAd->CommonCfg.PhyMode = wmode;
+ pAd->CommonCfg.cfg_wmode = wmode;
+ return TRUE;
+}
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+static BOOLEAN RT_isLegalCmdBeforeInfUp(
+ IN PSTRING SetCmd)
+{
+ BOOLEAN TestFlag;
+ TestFlag = !strcmp(SetCmd, "Debug") ||
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ !strcmp(SetCmd, "OpMode") ||
+#endif /* CONFIG_APSTA_MIXED_SUPPORT */
+#ifdef EXT_BUILD_CHANNEL_LIST
+ !strcmp(SetCmd, "CountryCode") ||
+ !strcmp(SetCmd, "DfsType") ||
+ !strcmp(SetCmd, "ChannelListAdd") ||
+ !strcmp(SetCmd, "ChannelListShow") ||
+ !strcmp(SetCmd, "ChannelListDel") ||
+#endif /* EXT_BUILD_CHANNEL_LIST */
+#ifdef SINGLE_SKU
+ !strcmp(SetCmd, "ModuleTxpower") ||
+#endif /* SINGLE_SKU */
+ FALSE; /* default */
+ return TestFlag;
+}
+
+
+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 INT keyStringLen,
+ IN UCHAR *pHashStr,
+ IN INT hashStrLen,
+ OUT PUCHAR pPMKBuf)
+{
+ UCHAR keyMaterial[40];
+
+ if ((keyStringLen < 8) || (keyStringLen > 64))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
+ keyStringLen, keyString));
+ return FALSE;
+ }
+
+ NdisZeroMemory(pPMKBuf, 32);
+ if (keyStringLen == 64)
+ {
+ AtoH(keyString, pPMKBuf, 32);
+ }
+ else
+ {
+ RtmpPasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
+ NdisMoveMemory(pPMKBuf, keyMaterial, 32);
+ }
+
+ return TRUE;
+}
+
+INT RT_CfgSetFixedTxPhyMode(PSTRING arg)
+{
+ INT fix_tx_mode = FIXED_TXMODE_HT;
+ ULONG value;
+
+
+ if (rtstrcasecmp(arg, "OFDM") == TRUE)
+ fix_tx_mode = FIXED_TXMODE_OFDM;
+ else if (rtstrcasecmp(arg, "CCK") == TRUE)
+ fix_tx_mode = FIXED_TXMODE_CCK;
+ else if (rtstrcasecmp(arg, "HT") == TRUE)
+ fix_tx_mode = FIXED_TXMODE_HT;
+ else if (rtstrcasecmp(arg, "VHT") == TRUE)
+ fix_tx_mode = FIXED_TXMODE_VHT;
+ else
+ {
+ value = simple_strtol(arg, 0, 10);
+ switch (value)
+ {
+ case FIXED_TXMODE_CCK:
+ case FIXED_TXMODE_OFDM:
+ case FIXED_TXMODE_HT:
+ case FIXED_TXMODE_VHT:
+ fix_tx_mode = value;
+ default:
+ 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(PSTRING arg, 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;
+}
+
+#ifdef WSC_INCLUDED
+INT RT_CfgSetWscPinCode(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING pPinCodeStr,
+ OUT PWSC_CTRL pWscControl)
+{
+ UINT pinCode;
+
+ pinCode = (UINT) simple_strtol(pPinCodeStr, 0, 10); /* When PinCode is 03571361, return value is 3571361.*/
+ if (strlen(pPinCodeStr) == 4)
+ {
+ pWscControl->WscEnrolleePinCode = pinCode;
+ pWscControl->WscEnrolleePinCodeLen = 4;
+ }
+ else if ( ValidateChecksum(pinCode) )
+ {
+ pWscControl->WscEnrolleePinCode = pinCode;
+ pWscControl->WscEnrolleePinCodeLen = 8;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RT_CfgSetWscPinCode(): invalid Wsc PinCode (%d)\n", pinCode));
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWscPinCode():Wsc PinCode=%d\n", pinCode));
+
+ return TRUE;
+
+}
+#endif /* WSC_INCLUDED */
+
+/*
+========================================================================
+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;
+
+#ifdef CONFIG_AP_SUPPORT
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].MSSIDDev = pData;
+#endif /* CONFIG_AP_SUPPORT */
+ 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;
+#ifdef WSC_INCLUDED
+ pList->pWscTask = &pAd->wscTask;
+#endif /* WSC_INCLUDED */
+ }
+ 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;
+
+ case CMD_RTPRIV_IOCTL_MCU_SLEEP_CLEAR:
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP);
+ 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 */
+
+ 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_RT28XX_USB_ASICRADIO_OFF:
+ /* RT28xxUsbAsicRadioOff */
+ //RT28xxUsbAsicRadioOff(pAd);
+ ASIC_RADIO_OFF(pAd, SUSPEND_RADIO_OFF);
+ break;
+
+ case CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_ON:
+ /* RT28xxUsbAsicRadioOn */
+ //RT28xxUsbAsicRadioOn(pAd);
+ ASIC_RADIO_ON(pAd, RESUME_RADIO_ON);
+ break;
+
+ case CMD_RTPRIV_IOCTL_SANITY_CHECK:
+ /* sanity check before IOCTL */
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+#ifdef IFUP_IN_PROBE
+ || (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))
+#endif /* IFUP_IN_PROBE */
+ )
+ {
+ if(pData == NULL || RT_isLegalCmdBeforeInfUp((PSTRING) pData) == FALSE)
+ 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 */
+#ifdef CONFIG_AP_SUPPORT
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+ 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 EXT_BUILD_CHANNEL_LIST
+ case CMD_RTPRIV_SET_PRECONFIG_VALUE:
+ /* Set some preconfigured value before interface up*/
+ pAd->CommonCfg.DfsType = MAX_RD_REGION;
+ break;
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+
+#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->BulkInMaxPacketSize = pConfig->BulkInMaxPacketSize;
+ pAd->BulkOutMaxPacketSize = pConfig->BulkOutMaxPacketSize;
+
+ for (i = 0; i < 6; i++)
+ pAd->BulkOutEpAddr[i] = pConfig->BulkOutEpAddr[i];
+
+ for (i = 0; i < 6; i++) {
+ DBGPRINT(RT_DEBUG_OFF, ("%s():pAd->BulkOutEpAddr=0x%x\n", __FUNCTION__, pAd->BulkOutEpAddr[i]));
+ }
+
+
+ for (i = 0; i < 2; i++)
+ pAd->BulkInEpAddr[i] = pConfig->BulkInEpAddr[i];
+
+ 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
+ {
+#ifdef CONFIG_AP_SUPPORT
+ extern VOID APMakeAllBssBeacon(IN PRTMP_ADAPTER pAd);
+ extern VOID APUpdateAllBeaconFrame(IN PRTMP_ADAPTER pAd);
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ 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;
+ if(pAd->OpMode == OPMODE_STA)
+ {
+ 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*/
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else if(pAd->OpMode == OPMODE_AP)
+ {
+ INT index;
+ for(index = 0; index < MAX_MBSSID_NUM(pAd); index++)
+ {
+ if (pAd->ApCfg.MBSSID[index].MSSIDDev == (PNET_DEV)(pStats->pNetDev))
+ {
+ break;
+ }
+ }
+
+ if(index >= MAX_MBSSID_NUM(pAd))
+ {
+ //reset counters
+ pStats->rx_packets = 0;
+ pStats->tx_packets = 0;
+ pStats->rx_bytes = 0;
+ pStats->tx_bytes = 0;
+ pStats->rx_errors = 0;
+ pStats->tx_errors = 0;
+ pStats->multicast = 0; /* multicast packets received*/
+ pStats->collisions = 0; /* Collision packets*/
+ pStats->rx_over_errors = 0; /* receiver ring buff overflow*/
+ pStats->rx_crc_errors = 0; /* recved pkt with crc error*/
+ pStats->rx_frame_errors = 0; /* recv'd frame alignment error*/
+ pStats->rx_fifo_errors = 0; /* recv'r fifo overrun*/
+
+ DBGPRINT(RT_DEBUG_ERROR, ("CMD_RTPRIV_IOCTL_INF_STATS_GET: can not find mbss I/F\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ pStats->rx_packets = pAd->ApCfg.MBSSID[index].RxCount;
+ pStats->tx_packets = pAd->ApCfg.MBSSID[index].TxCount;
+ pStats->rx_bytes = pAd->ApCfg.MBSSID[index].ReceivedByteCount;
+ pStats->tx_bytes = pAd->ApCfg.MBSSID[index].TransmittedByteCount;
+ pStats->rx_errors = pAd->ApCfg.MBSSID[index].RxErrorCount;
+ pStats->tx_errors = pAd->ApCfg.MBSSID[index].TxErrorCount;
+ pStats->multicast = pAd->ApCfg.MBSSID[index].mcPktsRx; /* multicast packets received */
+ pStats->collisions = 0; /* Collision packets*/
+ pStats->rx_over_errors = 0; /* receiver ring buff overflow*/
+ pStats->rx_crc_errors = 0;/* recved pkt with crc error*/
+ pStats->rx_frame_errors = 0; /* recv'd frame alignment error*/
+ pStats->rx_fifo_errors = 0; /* recv'r fifo overrun*/
+ }
+#endif
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_INF_IW_STATUS_GET:
+ /* get wireless statistics */
+ {
+ UCHAR CurOpMode = OPMODE_AP;
+#ifdef CONFIG_AP_SUPPORT
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+#endif /* CONFIG_AP_SUPPORT */
+ RT_CMD_IW_STATS *pStats = (RT_CMD_IW_STATS *)pData;
+
+ pStats->qual = 0;
+ pStats->level = 0;
+ pStats->noise = 0;
+ pStats->pStats = pAd->iw_stats;
+
+
+ /*check if the interface is down*/
+ if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ return NDIS_STATUS_FAILURE;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == OPMODE_AP)
+ {
+#ifdef APCLI_SUPPORT
+ if ((pStats->priv_flags == INT_APCLI)
+ )
+ {
+ INT ApCliIdx = ApCliIfLookUp(pAd, (PUCHAR)pStats->dev_addr);
+ if ((ApCliIdx >= 0) && VALID_WCID(pAd->ApCfg.ApCliTab[ApCliIdx].MacTabWCID))
+ pMacEntry = &pAd->MacTab.Content[pAd->ApCfg.ApCliTab[ApCliIdx].MacTabWCID];
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ /*
+ only AP client support wireless stats function.
+ return NULL pointer for all other cases.
+ */
+ pMacEntry = NULL;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == OPMODE_AP)
+ {
+ if (pMacEntry != NULL)
+ pStats->qual = ((pMacEntry->ChannelQuality * 12)/10 + 10);
+ else
+ pStats->qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (pStats->qual > 100)
+ pStats->qual = 100;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == OPMODE_AP)
+ {
+ if (pMacEntry != NULL)
+ pStats->level =
+ RTMPMaxRssi(pAd, pMacEntry->RssiSample.AvgRssi0,
+ pMacEntry->RssiSample.AvgRssi1,
+ pMacEntry->RssiSample.AvgRssi2);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ pStats->noise = RTMPMaxRssi(pAd, pAd->ApCfg.RssiSample.AvgRssi0,
+ pAd->ApCfg.RssiSample.AvgRssi1,
+ pAd->ApCfg.RssiSample.AvgRssi2) -
+ RTMPMinSnr(pAd, pAd->ApCfg.RssiSample.AvgSnr0,
+ pAd->ApCfg.RssiSample.AvgSnr1);
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_INF_MAIN_CREATE:
+ *(VOID **)pData = RtmpPhyNetDevMainCreate(pAd);
+ break;
+
+ case CMD_RTPRIV_IOCTL_INF_MAIN_ID_GET:
+ *(ULONG *)pData = INT_MAIN;
+ break;
+
+ case CMD_RTPRIV_IOCTL_INF_MAIN_CHECK:
+ if (Data != INT_MAIN)
+ return NDIS_STATUS_FAILURE;
+ break;
+
+ case CMD_RTPRIV_IOCTL_INF_P2P_CHECK:
+ if (Data != INT_P2P)
+ return NDIS_STATUS_FAILURE;
+ break;
+
+#ifdef WDS_SUPPORT
+ case CMD_RTPRIV_IOCTL_WDS_INIT:
+ WDS_Init(pAd, pData);
+ break;
+
+ case CMD_RTPRIV_IOCTL_WDS_REMOVE:
+ WDS_Remove(pAd);
+ break;
+
+ case CMD_RTPRIV_IOCTL_WDS_STATS_GET:
+ if (Data == INT_WDS)
+ {
+ if (WDS_StatsGet(pAd, pData) != TRUE)
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ return NDIS_STATUS_FAILURE;
+ break;
+#endif /* WDS_SUPPORT */
+
+#ifdef RALINK_ATE
+#ifdef RALINK_QA
+ case CMD_RTPRIV_IOCTL_ATE:
+ RtmpDoAte(pAd, wrq, pData);
+ break;
+#endif /* RALINK_QA */
+#endif /* RALINK_ATE */
+
+ case CMD_RTPRIV_IOCTL_MAC_ADDR_GET:
+
+ RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
+ RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
+ RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
+
+ PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
+ PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
+ PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
+ PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
+ PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
+ PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
+
+ for(i=0; i<6; i++)
+ *(UCHAR *)(pData+i) = PermanentAddress[i];
+ break;
+#ifdef CONFIG_AP_SUPPORT
+ case CMD_RTPRIV_IOCTL_AP_SIOCGIWRATEQ:
+ /* handle for SIOCGIWRATEQ */
+ {
+ RT_CMD_IOCTL_RATE *pRate = (RT_CMD_IOCTL_RATE *)pData;
+ HTTRANSMIT_SETTING HtPhyMode;
+
+#ifdef APCLI_SUPPORT
+ if (pRate->priv_flags == INT_APCLI)
+ HtPhyMode = pAd->ApCfg.ApCliTab[pObj->ioctl_if].HTPhyMode;
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (pRate->priv_flags == INT_WDS)
+ HtPhyMode = pAd->WdsTab.WdsEntry[pObj->ioctl_if].HTPhyMode;
+ else
+#endif /* WDS_SUPPORT */
+ {
+ HtPhyMode = pAd->ApCfg.MBSSID[pObj->ioctl_if].HTPhyMode;
+#ifdef MBSS_SUPPORT
+ /* reset phy mode for MBSS */
+ MBSS_PHY_MODE_RESET(pObj->ioctl_if, HtPhyMode);
+#endif /* MBSS_SUPPORT */
+ }
+ RtmpDrvMaxRateGet(pAd, HtPhyMode.field.MODE, HtPhyMode.field.ShortGI,
+ HtPhyMode.field.BW, HtPhyMode.field.MCS,
+ (UINT32 *)&pRate->BitRate);
+ }
+ break;
+#endif /* CONFIG_AP_SUPPORT */
+
+ case CMD_RTPRIV_IOCTL_SIOCGIWNAME:
+ RtmpIoctl_rt_ioctl_giwname(pAd, pData, 0);
+ break;
+
+#if defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_SUPPORT)
+ case CMD_RTPRIV_IOCTL_ADAPTER_CSO_SUPPORT_TEST:
+ *(UCHAR *)pData = (pAd->MoreFlags & fASIC_CAP_CSO) ? 1:0;
+ break;
+#endif /* defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_SUPPORT) */
+
+ }
+
+#ifdef RT_CFG80211_SUPPORT
+ if ((CMD_RTPRIV_IOCTL_80211_START <= cmd) &&
+ (cmd <= CMD_RTPRIV_IOCTL_80211_END))
+ {
+ CFG80211DRV_IoctlHandle(pAd, wrq, cmd, subcmd, pData, Data);
+ }
+#endif /* RT_CFG80211_SUPPORT */
+
+ if (cmd >= CMD_RTPRIV_IOCTL_80211_COM_LATEST_ONE)
+ 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;
+ }
+
+
+ NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef AP_SCAN_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if ((strlen(arg) != 0) && (strlen(arg) <= MAX_LEN_OF_SSID))
+ {
+ NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
+ Ssid.SsidLength = strlen(arg);
+ }
+
+ if (Ssid.SsidLength == 0)
+ ApSiteSurvey(pAd, &Ssid, SCAN_PASSIVE, FALSE);
+ else
+ ApSiteSurvey(pAd, &Ssid, SCAN_ACTIVE, FALSE);
+
+ return TRUE;
+ }
+#endif /* AP_SCAN_SUPPORT */
+#endif // CONFIG_AP_SUPPORT //
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_SiteSurvey_Proc\n"));
+
+ return TRUE;
+}
+
+INT Set_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ANT_DIVERSITY_TYPE UsedAnt;
+ int i;
+ DBGPRINT(RT_DEBUG_OFF, ("==> Set_Antenna_Proc *******************\n"));
+
+ for (i = 0; i < strlen(arg); i++)
+ if (!isdigit(arg[i]))
+ return -EINVAL;
+
+ UsedAnt = simple_strtol(arg, 0, 10);
+
+ switch (UsedAnt)
+ {
+ /* 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;
+ /* 3: Fix in the PHY Antenna CON2*/
+ case ANT_FIX_ANT1:
+ AsicSetRxAnt(pAd, 1);
+ DBGPRINT(RT_DEBUG_OFF, ("<== %s(Fix in Ant CON2), (%d,%d)\n",
+ __FUNCTION__, pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("<== %s(N/A cmd: %d), (%d,%d)\n", __FUNCTION__, UsedAnt,
+ pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+ break;
+ }
+
+ return TRUE;
+}
+
+
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+INT Set_MO_FalseCCATh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG th;
+
+ th = simple_strtol(arg, 0, 10);
+
+ if (th > 65535)
+ th = 65535;
+
+ pAd->CommonCfg.MO_Cfg.nFalseCCATh = th;
+
+ DBGPRINT(RT_DEBUG_OFF, ("%s: set falseCCA threshold %lu for microwave oven application!!\n", __FUNCTION__, th));
+
+ return TRUE;
+}
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_cmd.c b/cleopatre/devkit/mt7601udrv/common/cmm_cmd.c
new file mode 100644
index 0000000000..6fddedee5c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_cmd.c
@@ -0,0 +1,169 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_cmd.c
+
+ Abstract:
+ All command related API.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-25-2004 created
+*/
+
+#include "rt_config.h"
+
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTInitializeCmdQ(
+ IN PCmdQ cmdq)
+{
+ cmdq->head = NULL;
+ cmdq->tail = NULL;
+ cmdq->size = 0;
+ cmdq->CmdQState = RTMP_TASK_STAT_INITED;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTThreadDequeueCmd(
+ IN PCmdQ cmdq,
+ OUT PCmdQElmt *pcmdqelmt)
+{
+ *pcmdqelmt = cmdq->head;
+
+ if (*pcmdqelmt != NULL)
+ {
+ cmdq->head = cmdq->head->next;
+ cmdq->size--;
+ if (cmdq->size == 0)
+ cmdq->tail = NULL;
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTEnqueueInternalCmd(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength)
+{
+ NDIS_STATUS status;
+ PCmdQElmt cmdqelmt = NULL;
+
+
+ status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt, sizeof(CmdQElmt));
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
+ return (NDIS_STATUS_RESOURCES);
+ NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
+
+ if(InformationBufferLength > 0)
+ {
+ status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength);
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
+ {
+ os_free_mem(pAd, cmdqelmt);
+ return (NDIS_STATUS_RESOURCES);
+ }
+ else
+ {
+ NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+ cmdqelmt->bufferlength = InformationBufferLength;
+ }
+ }
+ else
+ {
+ cmdqelmt->buffer = NULL;
+ cmdqelmt->bufferlength = 0;
+ }
+
+ cmdqelmt->command = Oid;
+ cmdqelmt->CmdFromNdis = FALSE;
+
+ if (cmdqelmt != NULL)
+ {
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT)
+ {
+ EnqueueCmd((&pAd->CmdQ), cmdqelmt);
+ status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = NDIS_STATUS_FAILURE;
+ }
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ if (cmdqelmt->buffer)
+ os_free_mem(pAd, cmdqelmt->buffer);
+ os_free_mem(pAd, cmdqelmt);
+ }
+ else
+ RTCMDUp(&pAd->cmdQTask);
+ }
+ return(NDIS_STATUS_SUCCESS);
+}
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_cs.c b/cleopatre/devkit/mt7601udrv/common/cmm_cs.c
new file mode 100644
index 0000000000..d736385fee
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_cs.c
@@ -0,0 +1,763 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_cs.c
+
+ Abstract:
+ Carrier Sensing related functions
+
+ Revision History:
+ Who When What
+ ---------------------------------------------------------------------
+*/
+#include "rt_config.h"
+
+#ifdef CARRIER_DETECTION_SUPPORT
+static ULONG time[20];
+static ULONG idle[20];
+static ULONG busy[20];
+static ULONG cd_idx=0;
+
+static void ToneRadarProgram(PRTMP_ADAPTER pAd);
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Check current CS state, indicating Silient state (carrier exist) or not
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ TRUE if the current state is SILENT state, FALSE other wise
+ Note:
+ ==========================================================================
+*/
+INT isCarrierDetectExist(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->CommonCfg.CarrierDetect.CD_State == CD_SILENCE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Enable or Disable Carrier Detection feature (AP ioctl).
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 set CarrierDetect=[1/0]
+ ==========================================================================
+*/
+INT Set_CarrierDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+ UINT Enable;
+
+ if (apidx != MAIN_MBSSID)
+ return FALSE;
+
+ Enable = (UINT) simple_strtol(arg, 0, 10);
+
+ pAd->CommonCfg.CarrierDetect.Enable = (BOOLEAN)(Enable == 0 ? FALSE : TRUE);
+
+ RTMP_CHIP_RADAR_GLRT_COMPENSATE(pAd);
+ RTMP_CHIP_CCK_MRC_STATUS_CTRL(pAd);
+
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ CarrierDetectionStart(pAd);
+ else
+ CarrierDetectionStop(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %s\n", __FUNCTION__,
+ pAd->CommonCfg.CarrierDetect.Enable == TRUE ? "Enable Carrier Detection":"Disable Carrier Detection"));
+
+ return TRUE;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ When h/w interrupt is not available for CS, f/w take care of the operation, this function monitor necessary
+ parameters that determine the CS state periodically. (every 100ms)
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+VOID CarrierDetectionPeriodicStateCtrl(
+ IN PRTMP_ADAPTER pAd)
+{
+ CD_STATE *pCD_State = &pAd->CommonCfg.CarrierDetect.CD_State;
+ ULONG *pOneSecIntCount = &pAd->CommonCfg.CarrierDetect.OneSecIntCount;
+ CARRIER_DETECT_PARAM CarrDetectParam;
+
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode */
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+ /* tell firmware to prepare Recheck and RadarToneCount */
+ AsicSendCommandToMcu(pAd, CD_CHECKOUT_MCU_CMD, 0xff, 0x00, 0x00, FALSE);
+ /* Debug */
+ if (pAd->CommonCfg.CarrierDetect.Debug == RT_DEBUG_TRACE)
+ {
+ CARRIER_DETECT_DEBUG CarrDetectDebug;
+ RTUSBMultiRead(pAd, 0x4CB0, (PUCHAR) &CarrDetectDebug, sizeof(CarrDetectDebug));
+ printk("delta_div = 0x%02X, rRadarToneCount = %u, Recheck = %u, Criteria = %u, Threshold = 0x%08X, VGA_Mask = 0x%04X\n",
+ CarrDetectDebug.delta_div,
+ CarrDetectDebug.RadarToneCount,
+ CarrDetectDebug.ReCheck,
+ CarrDetectDebug.Criteria << 6, /* ms -> 16us*/
+ CarrDetectDebug.Threshold,
+ CarrDetectDebug.VGA_Mask);
+ }
+
+ RTUSBMultiRead(pAd, RADAR_TONE_COUNT, (PUCHAR) &CarrDetectParam, sizeof(CarrDetectParam));
+ switch(*pCD_State)
+ {
+ case CD_NORMAL:
+ if (CarrDetectParam.ReCheck == 0)
+ {
+ *pCD_State = CD_SILENCE;
+ if (pAd->CommonCfg.CarrierDetect.Debug != RT_DEBUG_TRACE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Carrier Detected\n"));
+
+ /* stop all TX actions including Beacon sending.*/
+ AsicDisableSync(pAd);
+ }
+ else
+ printk("Carrier Detected\n");
+ }
+ break;
+
+ case CD_SILENCE:
+ *pOneSecIntCount += CarrDetectParam.RadarToneCount;
+ break;
+
+ default:
+ break;
+ }
+}
+#endif /* CARRIER_DETECTION_FIRMWARE_SUPPORT */
+
+/*
+ ==========================================================================
+ Description:
+ When there is no f/w taking care of CS operation, this function depends on h/w interrupts for every possible carrier
+ tone to judge the CS state
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+VOID RTMPHandleRadarInterrupt(PRTMP_ADAPTER pAd)
+{
+ UINT32 value, delta;
+ UCHAR bbp=0;
+ PCARRIER_DETECTION_STRUCT pCarrierDetect = &pAd->CommonCfg.CarrierDetect;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandleRadarInterrupt()\n"));
+ RTMP_IO_READ32(pAd, PBF_LIFE_TIMER, &value);
+ RTMP_IO_READ32(pAd, CH_IDLE_STA, &pCarrierDetect->idle_time);
+ RTMP_IO_READ32(pAd, CH_BUSY_STA, &pCarrierDetect->busy_time);
+ delta = (value >> 4) - pCarrierDetect->TimeStamp;
+ pCarrierDetect->TimeStamp = value >> 4;
+ pCarrierDetect->OneSecIntCount++;
+
+ if(pAd->chipCap.carrier_func==TONE_RADAR_V2)
+ {
+ RTMP_CARRIER_IO_READ8(pAd, 1, &bbp);
+ if (!(bbp & 0x1))
+ return;
+ else
+ {
+ /* Disable carrier detection and clear the status bit*/
+ RTMP_CARRIER_IO_WRITE8(pAd, 0, 0);
+ RTMP_CARRIER_IO_WRITE8(pAd, 1, 1);
+ /* Clear interrupt */
+ RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR ,(1<<20));
+ }
+ }
+
+ if (pCarrierDetect->Debug)
+ {
+ if (cd_idx < 20)
+ {
+ time[cd_idx] = delta;
+ idle[cd_idx] = pCarrierDetect->idle_time;
+ busy[cd_idx] = pCarrierDetect->busy_time;
+ cd_idx++;
+ }
+ else
+ {
+ int i;
+ pCarrierDetect->Debug = 0;
+ for (i = 0; i < 20; i++)
+ {
+ printk("%3d %4ld %ld %ld\n", i, time[i], idle[i], busy[i]);
+ }
+ cd_idx = 0;
+
+ }
+ }
+
+ if (pCarrierDetect->CD_State == CD_NORMAL)
+ {
+ if ((delta < pCarrierDetect->criteria) && (pCarrierDetect->recheck))
+ pCarrierDetect->recheck --;
+ else
+ pCarrierDetect->recheck = pCarrierDetect->recheck1;
+
+ if (pCarrierDetect->recheck == 0)
+ {
+ /* declare carrier sense*/
+ pCarrierDetect->CD_State = CD_SILENCE;
+
+ if (pCarrierDetect->Debug != RT_DEBUG_TRACE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Carrier Detected\n"));
+
+ /* stop all TX actions including Beacon sending.*/
+ AsicDisableSync(pAd);
+ }
+ else
+ {
+ printk("Carrier Detected\n");
+ }
+ }
+ }
+
+ if(pAd->chipCap.carrier_func == TONE_RADAR_V2)
+ {
+ /* Clear Status bit */
+ //RTMP_CARRIER_IO_WRITE8(pAd, 1, bbp);
+ RTMP_CARRIER_IO_READ8(pAd, 1, &bbp);
+ if (bbp & 0x1)
+ DBGPRINT(RT_DEBUG_ERROR, ("CS bit not cleared!!!\n"));
+ /* re-enable carrier detection */
+ RTMP_CARRIER_IO_WRITE8(pAd, 0, 1);
+ }
+ else if(pAd->chipCap.carrier_func == TONE_RADAR_V1 &&
+ pCarrierDetect->Enable)
+ {
+ ToneRadarProgram(pAd);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Reset CS state to NORMAL state.
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT CarrierDetectReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
+ return 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Criteria in CS is a timing difference threshold for a pair of carrier tones. This function is a ioctl uesed to adjust the
+ Criteria. (unit: 16us)
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierCriteria_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT32 Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ pAd->CommonCfg.CarrierDetect.criteria = Value;
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+ {
+ USHORT sVal = (USHORT) (Value >> 6); /* convert unit from 16us to ms:(2^4 /2^10) */
+ RTUSBMultiWrite(pAd, CD_CRITERIA, (PUCHAR) &sVal, 2, FALSE);
+ /* send enable cmd to mcu to take effect */
+ AsicSendCommandToMcu(pAd, CD_ONOFF_MCU_CMD, 0xff, 0x01, 0x00, FALSE);
+ }
+#endif /* CARRIER_DETECTION_FIRMWARE_SUPPORT */
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ReCheck in CS is a value indicating how many continuous incoming carrier tones is enough us to announce that there
+ is carrier tone (and hence enter SILENT state). This function is a ioctl uesed to adjust the ReCheck value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierReCheck_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.recheck1 = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set Recheck = %u\n", pAd->CommonCfg.CarrierDetect.recheck1));
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+ RTMP_IO_WRITE8(pAd, CD_CHECK_COUNT, pAd->CommonCfg.CarrierDetect.recheck1);
+ /* send enable cmd to mcu to take effect */
+ AsicSendCommandToMcu(pAd, CD_ONOFF_MCU_CMD, 0xff, 0x01, 0x00, FALSE);
+#endif /* CARRIER_DETECTION_FIRMWARE_SUPPORT */
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ CarrierGoneThreshold is used to determine whether we should leave SILENT state. When the number of carrier
+ tones in a certain period of time is less than CarrierGoneThreshold, we should return to NORMAL state. This function
+ is a ioctl uesed to adjust the CarrierGoneThreshold.
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierGoneThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.CarrierGoneThreshold = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set CarrierGoneThreshold = %u\n", pAd->CommonCfg.CarrierDetect.CarrierGoneThreshold));
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Setting up the carrier debug level. set 0 means to turning off the carrier debug
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.Debug = simple_strtol(arg, 0, 10);
+ printk("pAd->CommonCfg.CarrierDetect.Debug = %ld\n", pAd->CommonCfg.CarrierDetect.Debug);
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Delta control the delay line characteristic of the cross correlation energy calculation.
+ This function is a ioctl uesed to adjust the Delta value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierDelta_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.delta = simple_strtol(arg, 0, 10);
+ printk("Delta = %d\n", pAd->CommonCfg.CarrierDetect.delta);
+ CarrierDetectionStart(pAd);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ To set ON/OFF of the "Not Divide Flag"
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierDivFlag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.div_flag = simple_strtol(arg, 0, 10);
+ printk("DivFlag = %d\n", pAd->CommonCfg.CarrierDetect.div_flag);
+ CarrierDetectionStart(pAd);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Carrier Threshold is the energy threshold for h/w to determine a carrier tone or not.
+ This function is a ioctl uesed to adjust the Threshold value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.threshold = simple_strtol(arg, 0, 10);
+ printk("CarrThrd = %d(0x%x)\n", pAd->CommonCfg.CarrierDetect.threshold, pAd->CommonCfg.CarrierDetect.threshold);
+ CarrierDetectionStart(pAd);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Carrier SymRund is the number of round bits in Radar Symmetric Round Bits Option.
+ This function is a ioctl uesed to adjust the SymRund. (unit: bit)
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierSymRund_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.SymRund= simple_strtol(arg, 0, 10);
+ printk("SymRund = %d\n", pAd->CommonCfg.CarrierDetect.SymRund);
+ CarrierDetectionStart(pAd);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Carrier Masks are used to prevent false trigger while doing Rx_PE, Packet_End, and AGC tuning.
+ This function is a ioctl uesed to adjust these three mask. (unit: 100ns)
+
+ Arguments:
+ pAd Pointer to our adapter
+ arg Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+INT Set_CarrierMask_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CarrierDetect.VGA_Mask = simple_strtol(arg, 0, 10);
+ pAd->CommonCfg.CarrierDetect.Packet_End_Mask = simple_strtol(arg, 0, 10);
+ pAd->CommonCfg.CarrierDetect.Rx_PE_Mask = simple_strtol(arg, 0, 10);
+ printk("CarrMask = %u(%x)\n", pAd->CommonCfg.CarrierDetect.VGA_Mask, pAd->CommonCfg.CarrierDetect.VGA_Mask);
+ CarrierDetectionStart(pAd);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Initialize CS parameters.
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+VOID CSInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ PCARRIER_DETECTION_STRUCT pCarrierDetect = &pAd->CommonCfg.CarrierDetect;
+
+ pCarrierDetect->TimeStamp = 0;
+ pCarrierDetect->recheck = pCarrierDetect->recheck1;
+ pCarrierDetect->OneSecIntCount = 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ To trigger CS start
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+VOID CarrierDetectionStart(PRTMP_ADAPTER pAd)
+{
+ /*ULONG Value;*/
+ /* Enable Bandwidth usage monitor*/
+ DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetectionStart\n"));
+ /*RTMP_IO_READ32(pAd, CH_TIME_CFG, &Value);*/
+ /*RTMP_IO_WRITE32(pAd, CH_TIME_CFG, Value | 0x1f); */
+
+ /* Init Carrier Detect*/
+ if (pAd->CommonCfg.CarrierDetect.Enable)
+ {
+ CSInit(pAd);
+ ToneRadarProgram(pAd);
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+ {
+ USHORT criteria = (USHORT) (pAd->CommonCfg.CarrierDetect.criteria >> 6); /* convert unit from 16us to 1ms:(2^4 /2^10) */
+ RTUSBMultiWrite(pAd, CD_CRITERIA, (PUCHAR) &criteria, 2, FALSE);
+ RTMP_IO_WRITE8(pAd, CD_CHECK_COUNT, pAd->CommonCfg.CarrierDetect.recheck1);
+ AsicSendCommandToMcu(pAd, CD_ONOFF_MCU_CMD, 0xff, 0x01, 0x00, FALSE);
+ }
+#else
+ /* trun on interrupt polling for pcie device */
+ if (pAd->infType == RTMP_DEV_INF_PCIE)
+ AsicSendCommandToMcu(pAd, CD_INT_POLLING_CMD, 0xff, 0x01, 0x00, FALSE);
+#endif /* CARRIER_DETECTION_FIRMWARE_SUPPORT */
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ To stop CS
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+VOID CarrierDetectionStop(IN PRTMP_ADAPTER pAd)
+{
+ CarrierDetectReset(pAd);
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+ /* Stop firmware CS action */
+ AsicSendCommandToMcu(pAd, CD_ONOFF_MCU_CMD, 0xff, 0x00, 0x00, FALSE);
+#endif /* CARRIER_DETECTION_FIRMWARE_SUPPORT */
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ To program CS related BBP registers (CS initialization)
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+static VOID ToneRadarProgram(PRTMP_ADAPTER pAd)
+{
+ ULONG threshold;
+ /* if wireless mode is 20Mhz mode, then the threshold should div by 2 */
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_20)
+ threshold = pAd->CommonCfg.CarrierDetect.threshold >> 1;
+ else
+ threshold = pAd->CommonCfg.CarrierDetect.threshold;
+ /* Call ToneRadarProgram_v1/ToneRadarProgram_v2*/
+ RTMP_CHIP_CARRIER_PROGRAM(pAd, threshold);
+}
+
+/*
+ ==========================================================================
+ Description:
+ To program CS v1 related BBP registers (CS initialization)
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+VOID ToneRadarProgram_v1(PRTMP_ADAPTER pAd, ULONG threshold)
+{
+ UCHAR bbp;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ToneRadarProgram v1\n"));
+ /* programe delta delay & division bit*/
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R184, 0xf0);
+ bbp = pAd->CommonCfg.CarrierDetect.delta << 4;
+ bbp |= (pAd->CommonCfg.CarrierDetect.div_flag & 0x1) << 3;
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R185, bbp);
+
+ /* program threshold*/
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R184, 0x34);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R185, (threshold & 0xff000000) >> 24);
+
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R184, 0x24);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R185, (threshold & 0xff0000) >> 16);
+
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R184, 0x14);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R185, (threshold & 0xff00) >> 8);
+
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R184, 0x04);
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R185, threshold & 0xff);
+
+ /* ToneRadarEnable v1 */
+ BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R184, 0x05);
+}
+
+/*
+ ==========================================================================
+ Description:
+ To program CS v2 related BBP registers (CS initialization)
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+VOID ToneRadarProgram_v2(PRTMP_ADAPTER pAd, ULONG threshold)
+{
+ UCHAR bbp;
+
+ /* programe delta delay & division bit*/
+ DBGPRINT(RT_DEBUG_TRACE, ("ToneRadarProgram v2\n"));
+ bbp = pAd->CommonCfg.CarrierDetect.delta | \
+ ((pAd->CommonCfg.CarrierDetect.SymRund & 0x3) << 4) | \
+ ((pAd->CommonCfg.CarrierDetect.div_flag & 0x1) << 6) | \
+ 0x80; /* Full 40MHz Detection Mode */
+ RTMP_CARRIER_IO_WRITE8(pAd, 5, bbp);
+
+ /* program *_mask*/
+ RTMP_CARRIER_IO_WRITE8(pAd, 2, pAd->CommonCfg.CarrierDetect.VGA_Mask);
+ RTMP_CARRIER_IO_WRITE8(pAd, 3, pAd->CommonCfg.CarrierDetect.Packet_End_Mask);
+ RTMP_CARRIER_IO_WRITE8(pAd, 4, pAd->CommonCfg.CarrierDetect.Rx_PE_Mask);
+
+ /* program threshold*/
+ RTMP_CARRIER_IO_WRITE8(pAd, 6, threshold & 0xff);
+ RTMP_CARRIER_IO_WRITE8(pAd, 7, (threshold & 0xff00) >> 8);
+ RTMP_CARRIER_IO_WRITE8(pAd, 8, (threshold & 0xff0000) >> 16);
+ RTMP_CARRIER_IO_WRITE8(pAd, 9, (threshold & 0xff000000) >> 24);
+
+ /* ToneRadarEnable v2 */
+ RTMP_CARRIER_IO_WRITE8(pAd, 0, 1);
+}
+
+#endif /* CARRIER_DETECTION_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_data.c b/cleopatre/devkit/mt7601udrv/common/cmm_data.c
new file mode 100644
index 0000000000..ce6b48947b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_data.c
@@ -0,0 +1,3569 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ cmm_data.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+
+#include "rt_config.h"
+
+
+UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
+UCHAR EAPOL[] = {0x88, 0x8e};
+UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */
+
+UCHAR IPX[] = {0x81, 0x37};
+UCHAR APPLE_TALK[] = {0x80, 0xf3};
+
+
+UCHAR 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};
+
+
+
+VOID dump_rxinfo(RTMP_ADAPTER *pAd, RXINFO_STRUC *pRxInfo)
+{
+ hex_dump("RxInfo Raw Data", (UCHAR *)pRxInfo, sizeof(RXINFO_STRUC));
+
+ DBGPRINT(RT_DEBUG_OFF, ("RxInfo Fields:\n"));
+
+#ifdef RLT_MAC
+ DBGPRINT(RT_DEBUG_OFF, ("\tBA=%d\n", pRxInfo->BA));
+ DBGPRINT(RT_DEBUG_OFF, ("\tDATA=%d\n", pRxInfo->DATA));
+ DBGPRINT(RT_DEBUG_OFF, ("\tNULLDATA=%d\n", pRxInfo->NULLDATA));
+ DBGPRINT(RT_DEBUG_OFF, ("\tFRAG=%d\n", pRxInfo->FRAG));
+ DBGPRINT(RT_DEBUG_OFF, ("\tU2M=%d\n", pRxInfo->U2M));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMcast=%d\n", pRxInfo->Mcast));
+ DBGPRINT(RT_DEBUG_OFF, ("\tBcast=%d\n", pRxInfo->Bcast));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMyBss=%d\n", pRxInfo->MyBss));
+ DBGPRINT(RT_DEBUG_OFF, ("\tCrc=%d\n", pRxInfo->Crc));
+ DBGPRINT(RT_DEBUG_OFF, ("\tCipherErr=%d\n", pRxInfo->CipherErr));
+ DBGPRINT(RT_DEBUG_OFF, ("\tAMSDU=%d\n", pRxInfo->AMSDU));
+ DBGPRINT(RT_DEBUG_OFF, ("\tHTC=%d\n", pRxInfo->HTC));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRSSI=%d\n", pRxInfo->RSSI));
+ DBGPRINT(RT_DEBUG_OFF, ("\tL2PAD=%d\n", pRxInfo->L2PAD));
+ DBGPRINT(RT_DEBUG_OFF, ("\tAMPDU=%d\n", pRxInfo->AMPDU));
+ DBGPRINT(RT_DEBUG_OFF, ("\tDecrypted=%d\n", pRxInfo->Decrypted));
+ DBGPRINT(RT_DEBUG_OFF, ("\tBssIdx3=%d\n", pRxInfo->BssIdx3));
+ DBGPRINT(RT_DEBUG_OFF, ("\twapi_kidx=%d\n", pRxInfo->wapi_kidx));
+ DBGPRINT(RT_DEBUG_OFF, ("\tpn_len=%d\n", pRxInfo->pn_len));
+ DBGPRINT(RT_DEBUG_OFF, ("\ttcp_sum_bypass=%d\n", pRxInfo->tcp_sum_bypass));
+ DBGPRINT(RT_DEBUG_OFF, ("\tip_sum_bypass=%d\n", pRxInfo->ip_sum_bypass));
+#endif /* RLT_MAC */
+
+#ifdef RTMP_MAC
+ DBGPRINT(RT_DEBUG_OFF, ("\t" ));
+#endif /* RTMP_MAC */
+}
+
+
+#ifdef RLT_MAC
+VOID dumpRxFCEInfo(RTMP_ADAPTER *pAd, RXFCE_INFO *pRxFceInfo)
+{
+ hex_dump("RxFCEInfo Raw Data", (UCHAR *)pRxFceInfo, sizeof(RXFCE_INFO));
+
+ DBGPRINT(RT_DEBUG_OFF, ("RxFCEInfo Fields:\n"));
+
+ DBGPRINT(RT_DEBUG_OFF, ("\tinfo_type=%d\n", pRxFceInfo->info_type));
+ DBGPRINT(RT_DEBUG_OFF, ("\ts_port=%d\n", pRxFceInfo->s_port));
+ DBGPRINT(RT_DEBUG_OFF, ("\tqsel=%d\n", pRxFceInfo->qsel));
+ DBGPRINT(RT_DEBUG_OFF, ("\tpcie_intr=%d\n", pRxFceInfo->pcie_intr));
+ DBGPRINT(RT_DEBUG_OFF, ("\tmac_len=%d\n", pRxFceInfo->mac_len));
+ DBGPRINT(RT_DEBUG_OFF, ("\tl3l4_done=%d\n", pRxFceInfo->l3l4_done));
+ DBGPRINT(RT_DEBUG_OFF, ("\tpkt_80211=%d\n", pRxFceInfo->pkt_80211));
+ DBGPRINT(RT_DEBUG_OFF, ("\tip_err=%d\n", pRxFceInfo->ip_err));
+ DBGPRINT(RT_DEBUG_OFF, ("\ttcp_err=%d\n", pRxFceInfo->tcp_err));
+ DBGPRINT(RT_DEBUG_OFF, ("\tudp_err=%d\n", pRxFceInfo->udp_err));
+ DBGPRINT(RT_DEBUG_OFF, ("\tpkt_len=%d\n", pRxFceInfo->pkt_len));
+}
+#endif /* RLT_MAC */
+
+
+static UCHAR *txwi_txop_str[]={"HT_TXOP", "PIFS", "SIFS", "BACKOFF", "Invalid"};
+#define TXWI_TXOP_STR(_x) ((_x) <= 3 ? txwi_txop_str[(_x)]: txwi_txop_str[4])
+
+VOID dumpTxWI(RTMP_ADAPTER *pAd, TXWI_STRUC *pTxWI)
+{
+ hex_dump("TxWI Raw Data: ", (UCHAR *)pTxWI, sizeof(TXWI_STRUC));
+
+ DBGPRINT(RT_DEBUG_OFF, ("TxWI Fields:\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("\tPHYMODE=%d(%s)\n", pTxWI->TxWIPHYMODE, get_phymode_str(pTxWI->TxWIPHYMODE)));
+ DBGPRINT(RT_DEBUG_OFF, ("\tSTBC=%d\n", pTxWI->TxWISTBC));
+ DBGPRINT(RT_DEBUG_OFF, ("\tShortGI=%d\n", pTxWI->TxWIShortGI));
+ DBGPRINT(RT_DEBUG_OFF, ("\tBW=%d(%sMHz)\n", pTxWI->TxWIBW, get_bw_str(pTxWI->TxWIBW)));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMCS=%d\n", pTxWI->TxWIMCS));
+ DBGPRINT(RT_DEBUG_OFF, ("\tTxOP=%d(%s)\n", pTxWI->TxWITXOP, TXWI_TXOP_STR(pTxWI->TxWITXOP)));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMpduDensity=%d\n", pTxWI->TxWIMpduDensity));
+ DBGPRINT(RT_DEBUG_OFF, ("\tAMPDU=%d\n", pTxWI->TxWIAMPDU));
+ DBGPRINT(RT_DEBUG_OFF, ("\tTS=%d\n", pTxWI->TxWITS));
+ DBGPRINT(RT_DEBUG_OFF, ("\tCF-ACK=%d\n", pTxWI->TxWICFACK));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMIMO-PS=%d\n", pTxWI->TxWIMIMOps));
+ DBGPRINT(RT_DEBUG_OFF, ("\tNSEQ=%d\n", pTxWI->TxWINSEQ));
+ DBGPRINT(RT_DEBUG_OFF, ("\tACK=%d\n", pTxWI->TxWIACK));
+ DBGPRINT(RT_DEBUG_OFF, ("\tFRAG=%d\n", pTxWI->TxWIFRAG));
+ DBGPRINT(RT_DEBUG_OFF, ("\tWCID=%d\n", pTxWI->TxWIWirelessCliID));
+ DBGPRINT(RT_DEBUG_OFF, ("\tBAWinSize=%d\n", pTxWI->TxWIBAWinSize));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMPDUtotalByteCnt=%d\n", pTxWI->TxWIMPDUByteCnt));
+#ifdef RLT_MAC
+ DBGPRINT(RT_DEBUG_OFF, ("\tPID=%d\n", pTxWI->TxWIPacketId));
+#endif /* RLT_MAC */
+}
+
+
+VOID dump_rxwi(RTMP_ADAPTER *pAd, RXWI_STRUC *pRxWI)
+{
+ hex_dump("RxWI Raw Data", (UCHAR *)pRxWI, sizeof(RXWI_STRUC));
+
+ DBGPRINT(RT_DEBUG_OFF, ("RxWI Fields:\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("\tWCID=%d\n", pRxWI->RxWIWirelessCliID));
+ DBGPRINT(RT_DEBUG_OFF, ("\tPhyMode=%d(%s)\n", pRxWI->RxWIPhyMode, get_phymode_str(pRxWI->RxWIPhyMode)));
+#ifdef RT65xx
+ if (IS_RT65XX(pAd) && (pRxWI->RxWIPhyMode == MODE_VHT))
+ DBGPRINT(RT_DEBUG_OFF, ("\tMCS=%d(Nss:%d, MCS:%d)\n", pRxWI->RxWIMCS, (pRxWI->RxWIMCS >> 4), (pRxWI->RxWIMCS & 0xf)));
+ else
+#endif /* RT65xx */
+ DBGPRINT(RT_DEBUG_OFF, ("\tMCS=%d\n", pRxWI->RxWIMCS));
+ DBGPRINT(RT_DEBUG_OFF, ("\tBW=%d\n", pRxWI->RxWIBW));
+ DBGPRINT(RT_DEBUG_OFF, ("\tSGI=%d\n", pRxWI->RxWISGI));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMPDUtotalByteCnt=%d\n", pRxWI->RxWIMPDUByteCnt));
+ DBGPRINT(RT_DEBUG_OFF, ("\tTID=%d\n", pRxWI->RxWITID));
+ DBGPRINT(RT_DEBUG_OFF, ("\tSTBC=%d\n", pRxWI->RxWISTBC));
+ DBGPRINT(RT_DEBUG_OFF, ("\tkey_idx=%d\n", pRxWI->RxWIKeyIndex));
+ DBGPRINT(RT_DEBUG_OFF, ("\tBSS_IDX=%d\n", pRxWI->RxWIBSSID));
+}
+
+
+static UCHAR *txinfo_type_str[]={"PKT", "", "CMD", "RSV", "Invalid"};
+static UCHAR *txinfo_d_port_str[]={"WLAN", "CPU_RX", "CPU_TX", "HOST", "VIRT_RX", "VIRT_TX", "DROP", "Invalid"};
+static UCHAR *txinfo_que_str[]={"MGMT", "HCCA", "EDCA_1", "EDCA_2", "Invalid"};
+
+#define TXINFO_TYPE_STR(_x) ((_x)<=3 ? txinfo_type_str[_x] : txinfo_type_str[4])
+#define TXINFO_DPORT_STR(_x) ((_x) <= 6 ? txinfo_d_port_str[_x]: txinfo_d_port_str[7])
+#define TXINFO_QUE_STR(_x) ((_x) <= 3 ? txinfo_que_str[_x]: txinfo_que_str[4])
+
+VOID dump_txinfo(RTMP_ADAPTER *pAd, TXINFO_STRUC *pTxInfo)
+{
+ hex_dump("TxInfo Raw Data: ", (UCHAR *)pTxInfo, sizeof(TXINFO_STRUC));
+
+ DBGPRINT(RT_DEBUG_OFF, ("TxInfo Fields:\n"));
+
+#ifdef RLT_MAC
+{
+ struct _TXINFO_NMAC_PKT *pkt_txinfo = (struct _TXINFO_NMAC_PKT *)pTxInfo;
+
+ DBGPRINT(RT_DEBUG_OFF, ("\tInfo_Type=%d(%s)\n", pkt_txinfo->info_type, TXINFO_TYPE_STR(pkt_txinfo->info_type)));
+ DBGPRINT(RT_DEBUG_OFF, ("\td_port=%d(%s)\n", pkt_txinfo->d_port, TXINFO_DPORT_STR(pkt_txinfo->d_port)));
+ DBGPRINT(RT_DEBUG_OFF, ("\tQSEL=%d(%s)\n", pkt_txinfo->QSEL, TXINFO_QUE_STR(pkt_txinfo->QSEL)));
+ DBGPRINT(RT_DEBUG_OFF, ("\tWIV=%d\n", pkt_txinfo->wiv));
+ DBGPRINT(RT_DEBUG_OFF, ("\t802.11=%d\n", pkt_txinfo->pkt_80211));
+ DBGPRINT(RT_DEBUG_OFF, ("\tcso=%d\n", pkt_txinfo->cso));
+ DBGPRINT(RT_DEBUG_OFF, ("\ttso=%d\n", pkt_txinfo->tso));
+ DBGPRINT(RT_DEBUG_OFF, ("\tpkt_len=0x%x\n", pkt_txinfo->pkt_len));
+}
+#endif /* RLT_MAC */
+
+#ifdef RTMP_MAC
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+#endif /* RTMP_MAC */
+}
+
+
+#ifdef DBG_DIAGNOSE
+static VOID dumpTxBlk(TX_BLK *pTxBlk)
+{
+ NDIS_PACKET *pPacket;
+ int i, frameNum;
+ PQUEUE_ENTRY pQEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE,("Dump TX_BLK Structure:\n"));
+ DBGPRINT(RT_DEBUG_TRACE,("\tTxFrameType=%d!\n", pTxBlk->TxFrameType));
+ DBGPRINT(RT_DEBUG_TRACE,("\tTotalFrameLen=%d\n", pTxBlk->TotalFrameLen));
+ DBGPRINT(RT_DEBUG_TRACE,("\tTotalFrameNum=%ld!\n", pTxBlk->TxPacketList.Number));
+ DBGPRINT(RT_DEBUG_TRACE,("\tTotalFragNum=%d!\n", pTxBlk->TotalFragNum));
+ DBGPRINT(RT_DEBUG_TRACE,("\tpPacketList=\n"));
+
+ frameNum = pTxBlk->TxPacketList.Number;
+
+ for(i=0; i < frameNum; i++)
+ { int j;
+ UCHAR *pBuf;
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (pPacket)
+ {
+ pBuf = GET_OS_PKT_DATAPTR(pPacket);
+ DBGPRINT(RT_DEBUG_TRACE,("\t\t[%d]:ptr=0x%x, Len=%d!\n", i, (UINT32)(GET_OS_PKT_DATAPTR(pPacket)), GET_OS_PKT_LEN(pPacket)));
+ DBGPRINT(RT_DEBUG_TRACE,("\t\t"));
+ for (j =0 ; j < GET_OS_PKT_LEN(pPacket); j++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("%02x ", (pBuf[j] & 0xff)));
+ if (j == 16)
+ break;
+ }
+ InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("\tWcid=%d!\n", pTxBlk->Wcid));
+ DBGPRINT(RT_DEBUG_TRACE,("\tapidx=%d!\n", pTxBlk->apidx));
+ DBGPRINT(RT_DEBUG_TRACE,("----EndOfDump\n"));
+
+}
+#endif
+
+
+/*
+ ========================================================================
+
+ 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 RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR *pData,
+ IN UINT Length)
+{
+ PNDIS_PACKET pPacket;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ ULONG FreeNum;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ UCHAR rtmpHwHdr[40];
+ BOOLEAN bUseDataQ = FALSE, FlgDataQForce = FALSE, FlgIsLocked = FALSE;
+ int retryCnt = 0, hw_len = TXINFO_SIZE + TXWISize + TSO_SIZE;
+
+
+ ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+ if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG)
+ {
+ bUseDataQ = TRUE;
+ QueIdx &= (~MGMT_USE_QUEUE_FLAG);
+ }
+
+#ifdef FPGA_MODE
+ if (pAd->fpga_on & 0x1) {
+ if (pAd->tx_kick_cnt > 0) {
+ if (pAd->tx_kick_cnt < 0xffff)
+ pAd->tx_kick_cnt--;
+ }
+ else
+ return NDIS_STATUS_FAILURE;
+
+ QueIdx = 0;
+ bUseDataQ = TRUE;
+ }
+#endif /* FPGA_MODE */
+
+
+ do
+ {
+ /* Reset is in progress, stop immediately*/
+ if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST)) ||
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
+ )
+ {
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+
+ /* 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, hw_len);
+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, hw_len, pData, Length);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+ break;
+ }
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef UAPSD_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UAPSD_MR_QOS_NULL_HANDLE(pAd, pData, pPacket);
+ }
+#endif /* UAPSD_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ Status = MlmeHardTransmit(pAd, QueIdx, pPacket, FlgDataQForce, FlgIsLocked);
+ if (Status == NDIS_STATUS_SUCCESS)
+ retryCnt = 0;
+ else
+ RELEASE_NDIS_PACKET(pAd, pPacket, Status);
+ }
+ 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;
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ ========================================================================
+
+ 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
+ FlgIsDeltsFrame 1: the frame is a DELTS frame
+
+ Return Value:
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_SUCCESS
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+void AP_QueuePsActionPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pMacEntry,
+ IN PNDIS_PACKET pPacket,
+ IN BOOLEAN FlgIsDeltsFrame,
+ IN BOOLEAN FlgIsLocked,
+ IN UCHAR MgmtQid)
+{
+
+#ifdef UAPSD_SUPPORT
+#ifdef UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY
+ PNDIS_PACKET DuplicatePkt = NULL;
+#endif /* UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY */
+#endif /* UAPSD_SUPPORT */
+
+ /* Note: for original mode of 4 AC are UAPSD, if station want to change
+ the mode of a AC to legacy PS, we dont know where to put the
+ response;
+ 1. send the response;
+ 2. but the station is in ps mode, so queue the response;
+ 3. we should queue the reponse to UAPSD queue because the station
+ is not yet change its mode to legacy ps AC;
+ 4. so AP should change its mode to legacy ps AC only when the station
+ sends a trigger frame and we send out the reponse;
+ 5. the mechanism is too complicate; */
+
+#ifdef UAPSD_SUPPORT
+ /*
+ If the frame is action frame and the VO is UAPSD, we can not send the
+ frame to VO queue, we need to send to legacy PS queue; or the frame
+ maybe not got from QSTA.
+ */
+/* if ((pMacEntry->bAPSDDeliverEnabledPerAC[MgmtQid]) &&*/
+/* (FlgIsDeltsFrame == 0))*/
+ if (pMacEntry->bAPSDDeliverEnabledPerAC[MgmtQid])
+ {
+ /* queue the management frame to VO queue if VO is deliver-enabled */
+ DBGPRINT(RT_DEBUG_TRACE, ("ps> mgmt to UAPSD queue %d ... (IsDelts: %d)\n",
+ MgmtQid, FlgIsDeltsFrame));
+
+#ifdef UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY
+ if (!pMacEntry->bAPSDAllAC)
+ {
+ /* duplicate one packet to legacy PS queue */
+ RTMP_SET_PACKET_UAPSD(pPacket, 0, MgmtQid);
+ DuplicatePkt = RTMP_DUPLICATE_PACKET(pAd, pPacket, pMacEntry->apidx);
+ }
+ else
+#endif /* UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY */
+ {
+ RTMP_SET_PACKET_UAPSD(pPacket, 1, MgmtQid);
+ }
+
+ UAPSD_PacketEnqueue(pAd, pMacEntry, pPacket, MgmtQid);
+
+ if (pMacEntry->bAPSDAllAC)
+ {
+ /* mark corresponding TIM bit in outgoing BEACON frame*/
+ WLAN_MR_TIM_BIT_SET(pAd, pMacEntry->apidx, pMacEntry->Aid);
+ }
+ else
+ {
+#ifdef UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY
+ /* duplicate one packet to legacy PS queue */
+
+ /*
+ Sometimes AP will send DELTS frame to STA but STA will not
+ send any trigger frame to get the DELTS frame.
+ We must force to send it so put another one in legacy PS
+ queue.
+ */
+ if (DuplicatePkt != NULL)
+ {
+ pPacket = DuplicatePkt;
+ goto Label_Legacy_PS;
+ }
+#endif /* UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY */
+ }
+ }
+ else
+#endif /* UAPSD_SUPPORT */
+ {
+/* DuplicatePkt = DuplicatePacket(get_netdev_from_bssid(pAd, pMacEntry->apidx), pPacket, pMacEntry->apidx);*/
+
+#ifdef UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY
+Label_Legacy_PS:
+#endif /* UAPSD_CC_FUNC_PS_MGMT_TO_LEGACY */
+ if (pMacEntry->PsQueue.Number >= MAX_PACKETS_IN_PS_QUEUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
+ return;
+ }
+ else
+ {
+ ULONG IrqFlags=0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ps> mgmt to legacy ps queue... (%d)\n", FlgIsDeltsFrame));
+
+ if (FlgIsLocked == FALSE)
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ InsertTailQueue(&pMacEntry->PsQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
+ if (FlgIsLocked == FALSE)
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+ }
+
+ /* mark corresponding TIM bit in outgoing BEACON frame*/
+ WLAN_MR_TIM_BIT_SET(pAd, pMacEntry->apidx, pMacEntry->Aid);
+ }
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+/*
+ ========================================================================
+
+ 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 RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket,
+ IN BOOLEAN FlgDataQForce,
+ IN BOOLEAN FlgIsLocked)
+{
+#ifdef CONFIG_AP_SUPPORT
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ PHEADER_802_11 pHeader_802_11;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+#endif /* CONFIG_AP_SUPPORT */
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+
+ if ((pAd->Dot11_H.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+ ||(isCarrierDetectExist(pAd) == TRUE)
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* CARRIER_DETECTION_SUPPORT */
+ )
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+ if (pSrcBufVA == NULL)
+ return NDIS_STATUS_FAILURE;
+
+#ifdef CONFIG_AP_SUPPORT
+ pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWISize + TSO_SIZE);
+
+ /*
+ Section 11.2.1.1 STA Power Management modes of IEEE802.11-2007:
+ The Power Managment bit shall not be set in any management frame,
+ except an Action frame.
+
+ So in the 'baseline' test plan
+ (Wi-Fi 802.11 WPA2, WPA, WEP Interoperability Test Plan),
+ Section 2.2.6, the following Requirement:
+ APs shall ignore the power save bit in any received Authenticate and
+ (Re) Associate, and shall assume that the station is awake for the
+ response.
+ */
+
+ /*
+ IEEE802.11, 11.2.1.4 AP operation during the contention period f)
+ A single buffered MSDU or management frame for a STA in the PS mode shall
+ be forwarded to the STA after a PS-Poll has been received from that STA.
+ The More Data field shall be set to indicate the presence of further
+ buffered MSDUs or "management frames" for the polling STA.
+ */
+
+ /*
+ IEEE802.11e, 11.2.1.4 Power management with APSD,
+ An unscheduled SP ends after the QAP has attempted to transmit at least
+ one MSDU or MMPDU associated with a delivery-enabled AC and destined for
+ the non-AP QSTA, but no more than the number indicated in the Max SP
+ Length field if the field has a nonzero value.
+ */
+
+ if ((pHeader_802_11->FC.Type == BTYPE_DATA) ||
+ (pHeader_802_11->FC.Type == BTYPE_MGMT))
+ {
+ if (pHeader_802_11->FC.SubType != SUBTYPE_QOS_NULL)
+ pEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
+ }
+
+
+
+ if ((pEntry != NULL) &&
+ (pEntry->PsMode == PWR_SAVE) &&
+ (((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+ (pHeader_802_11->FC.SubType != SUBTYPE_NULL_FUNC) &&
+ (pHeader_802_11->FC.SubType != SUBTYPE_QOS_NULL)) ||
+ ((pHeader_802_11->FC.Type == BTYPE_MGMT) &&
+ (pHeader_802_11->FC.SubType == SUBTYPE_ACTION)) ||
+ ((pHeader_802_11->FC.Type == BTYPE_MGMT) &&
+ (pHeader_802_11->FC.SubType == SUBTYPE_ACTION_NO_ACK))))
+ {
+ /* the peer is in PS mode, we need to queue the management frame */
+ UINT8 FlgIsDeltsFrame = 0, MgmtQid = QID_AC_VO;
+
+ /*
+ 1. Data & Not QoS Null, or
+ 2. Management & Action, or
+ 3. Management & Action No ACK;
+ */
+ DBGPRINT(RT_DEBUG_TRACE, ("STA in ps mode, queue the mgmt frame\n"));
+ RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
+ RTMP_SET_PACKET_MGMT_PKT(pPacket, 1); /* is management frame */
+ RTMP_SET_PACKET_MGMT_PKT_DATA_QUE(pPacket, 0); /* default to management queue */
+
+
+ if (FlgDataQForce == TRUE)
+ RTMP_SET_PACKET_MGMT_PKT_DATA_QUE(pPacket, 1); /* force to data queue */
+
+ if ((pHeader_802_11->FC.Type == BTYPE_MGMT) &&
+ (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
+ {
+ FRAME_ADDBA_REQ *pFrameBa = (FRAME_ADDBA_REQ *)pHeader_802_11;
+ if (pFrameBa->Category == CATEGORY_BA)
+ MgmtQid = QueIdx;
+ }
+
+
+ AP_QueuePsActionPacket(pAd, pEntry, pPacket, FlgIsDeltsFrame,
+ FlgIsLocked, MgmtQid);
+ return NDIS_STATUS_SUCCESS;
+ }
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ {
+ return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+ }
+}
+
+
+NDIS_STATUS MlmeHardTransmitMgmtRing(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ UCHAR *pSrcBufVA;
+ UINT SrcBufLen;
+ HEADER_802_11 *pHeader_802_11;
+ BOOLEAN bAckRequired, bInsertTimestamp;
+ UCHAR MlmeRate;
+ TXWI_STRUC *pFirstTxWI;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+ UCHAR PID;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ 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;
+ }
+
+
+ pFirstTxWI = (TXWI_STRUC *)(pSrcBufVA + TXINFO_SIZE);
+ pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TSO_SIZE + TXWISize);
+
+ 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);
+ }
+
+
+ /* 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.*/
+
+ pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; /* (pAd->StaCfg.Psm == PWR_SAVE);*/
+
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+ pHeader_802_11->FC.MoreData = RTMP_GET_PACKET_MOREDATA(pPacket);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ bInsertTimestamp = FALSE;
+ if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL*/
+ {
+ 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->Dot11_H.RDMode != RD_NORMAL_MODE))
+ {
+ 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 - TXWISize - TSO_SIZE), PID, 0,
+ (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE,
+ &pAd->CommonCfg.MlmeTransmit);
+ }
+ else
+ {
+ /* dont use low rate to send QoS Null data frame */
+ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
+ bInsertTimestamp, FALSE, bAckRequired, FALSE,
+ 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWISize - TSO_SIZE),
+ pMacEntry->MaxHTPhyMode.field.MCS, 0,
+ (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
+ IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pAd, (PUCHAR)pFirstTxWI, TYPE_TXWI);
+#endif
+
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("TxMgmtPkt", (UCHAR *)pHeader_802_11, ((SrcBufLen - TXINFO_SIZE - TXWISize - TSO_SIZE) > 7000 ? 7000 : (SrcBufLen - TXINFO_SIZE - TXWISize - TSO_SIZE)));
+}
+//---Add by shiang for debug
+
+ /* 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_SUPPORT
+ else if (RTMP_GET_PACKET_EOSP(pPacket))
+ TxFrameType = TX_LEGACY_FRAME;
+#endif /* UAPSD_SUPPORT */
+ else if(((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
+#ifdef WFA_VHT_PF
+ && (pAd->force_amsdu == FALSE)
+#endif /* WFA_VHT_PF */
+ )
+ return TX_AMPDU_FRAME;
+ else if((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED)
+#ifdef WFA_VHT_PF
+ || (pAd->force_amsdu == TRUE)
+#endif /* WFA_VHT_PF */
+ )
+ )
+ 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(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk)
+{
+ PACKET_INFO PacketInfo;
+ PNDIS_PACKET pPacket;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+
+ pPacket = pTxBlk->pPacket;
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+#ifdef TX_PKT_SG
+ NdisMoveMemory( &pTxBlk->pkt_info, &PacketInfo, sizeof(PacketInfo));
+#endif /* TX_PKT_SG */
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+ pTxBlk->pMbss = NULL;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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);
+
+#ifdef WAPI_SUPPORT
+ /* Check if this is an WPI data frame*/
+ if ((RTMPIsWapiCipher(pAd, pTxBlk->apidx) == TRUE) &&
+ (RTMP_GET_PACKET_WAI(pTxBlk->pPacket) == FALSE))
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWPIDataFrame);
+ else
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWPIDataFrame);
+#endif /* WAPI_SUPPORT */
+
+ 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_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;
+#ifdef CONFIG_AP_SUPPORT
+ pTxBlk->pMbss = pMacEntry->pMbss;
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef WDS_SUPPORT
+ if(IS_ENTRY_WDS(pMacEntry))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWDSEntry);
+ }
+ else
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ if(IS_ENTRY_APCLI(pMacEntry))
+ {
+ PNDIS_PACKET apCliPkt = NULL;
+
+ /* For each tx packet, update our MAT convert engine databases.*/
+ apCliPkt = (PNDIS_PACKET)MATEngineTxHandle(pAd, pPacket, pMacEntry->MatchAPCLITabIdx, pTxBlk->OpMode);
+ if(apCliPkt)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+ pPacket = apCliPkt;
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+ pTxBlk->pPacket = apCliPkt;
+ }
+ pTxBlk->pApCliEntry = &pAd->ApCfg.ApCliTab[pMacEntry->MatchAPCLITabIdx];
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bApCliPacket);
+
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef CLIENT_WDS
+ if (IS_ENTRY_CLIWDS(pMacEntry))
+ {
+ PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
+ PUCHAR pSA = GET_OS_PKT_DATAPTR(pPacket) + MAC_ADDR_LEN;
+ if (((pMacEntry->apidx < MAX_MBSSID_NUM(pAd))
+ && !MAC_ADDR_EQUAL(pSA, pAd->ApCfg.MBSSID[pMacEntry->apidx].Bssid))
+ || !MAC_ADDR_EQUAL(pDA, pMacEntry->Addr)
+ )
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bClientWDSFrame);
+ }
+ }
+ else
+#endif /* CLIENT_WDS */
+ if (IS_ENTRY_CLIENT(pMacEntry))
+ { }
+ else
+ return FALSE;
+
+ /* If both of peer and us 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);
+ }
+#endif /* CONFIG_AP_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 WAPI_SUPPORT
+ /* According to WAPIA certification description, WAI packets can not
+ include QoS header */
+ if (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))
+ {
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
+ }
+#endif /* WAPI_SUPPORT */
+#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_SUPPORT
+ if (RTMP_GET_PACKET_EOSP(pPacket))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
+ }
+#endif /* UAPSD_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)
+{
+ int minLen = LENGTH_802_3;
+
+ /*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;
+
+ /* Make sure the first packet has non-zero-length data payload */
+ if (RTMP_GET_PACKET_VLAN(pPacket))
+ minLen += LENGTH_802_1Q; /* VLAN tag */
+ else if (RTMP_GET_PACKET_LLCSNAP(pPacket))
+ minLen += 8; /* SNAP hdr Len*/
+ if (minLen >= GET_OS_PKT_LEN(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_AP_SUPPORT
+ if ((MAC_ADDR_EQUAL(GET_OS_PKT_DATAPTR(pTxBlk->pPacket), GET_OS_PKT_DATAPTR(pPacket))) && (pAd->OpMode == OPMODE_AP)) /* unicast to same STA*/
+ return TRUE;
+ else
+#endif /* CONFIG_AP_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 RTMP_ADAPTER *pAd,
+ IN BOOLEAN bIntContext,
+ IN UCHAR QIdx,
+ IN INT 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, *pTxBlk;
+
+#ifdef DBG_DIAGNOSE
+ BOOLEAN firstRound;
+ RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
+#endif
+
+
+ if (QIdx == NUM_OF_TX_RING)
+ {
+ sQIdx = 0;
+#ifdef CONFIG_MULTI_CHANNEL
+ eQIdx = QID_HCCA; /* 5 ACs, start from 0.*/
+#else
+ eQIdx = QID_AC_VO; /* 4 ACs, start from 0.*/
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ }
+ 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 |
+#ifdef CONFIG_MULTI_CHANNEL
+ fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET |
+#endif /* CONFIG_MULTI_CHANNEL */
+ fRTMP_ADAPTER_NIC_NOT_EXIST
+ )))
+
+ )
+ {
+ RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+ return;
+ }
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MultiChannelFlowCtl & (1 << QueIdx)) == (1 << QueIdx))
+ {
+ break;
+ }
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+ 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));
+
+ pTxBlk->QueIdx = QueIdx;
+
+#ifdef VENDOR_FEATURE1_SUPPORT
+ pTxBlk->HeaderBuf = (UCHAR *)pTxBlk->HeaderBuffer;
+#endif /* VENDOR_FEATURE1_SUPPORT */
+
+ pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (RTMP_GET_PACKET_MGMT_PKT(pPacket) == 1)
+ {
+ /* this is a management frame */
+ NDIS_STATUS status;
+
+ pEntry = RemoveHeadQueue(pQueue);
+
+ status = MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+
+ if (status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("Transmit queued management frame error!\n"));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ Count++;
+ continue;
+ }
+ else
+ {
+ /*when WDS Jam happen, drop following 1min to HW TxRing Pkts*/
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+ UCHAR RAWcid;
+ RAWcid = RTMP_GET_PACKET_WCID(pPacket);
+ pMacEntry = &pAd->MacTab.Content[RAWcid];
+
+#ifdef WDS_SUPPORT
+ /*
+ It WDS life checking.
+ WDS need to check the peer is come back or not
+ by sending few (2 ~3) WDS Packet out to peer.
+ It must be checked first.
+ */
+ if(IS_ENTRY_WDS(pMacEntry))
+ {
+ ULONG Now32;
+ NdisGetSystemUpTime(&Now32);
+ if(pMacEntry->LockEntryTx && RTMP_TIME_BEFORE(Now32, pMacEntry->TimeStamp_toTxRing + WDS_ENTRY_RETRY_INTERVAL))
+ {
+ pEntry = RemoveHeadQueue(pQueue);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ continue;
+ }
+ else
+ NdisGetSystemUpTime(&pMacEntry->TimeStamp_toTxRing);
+ }
+ else
+#endif /* WDS_SUPPORT */
+ if (!IS_ENTRY_NONE(pMacEntry)
+ && (pMacEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck))
+ {
+ /*
+ Sample Lin, 20100412
+
+ For non-WDS interface, we need to send packet to detect
+ the link periodically; Or when
+ pMacEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck,
+ no any chance to clear pMacEntry->ContinueTxFailCnt.
+
+ EX: When pMacEntry->ContinueTxFailCnt >=
+ pAd->ApCfg.EntryLifeCheck, the condition will not be
+ removed and we will drop all packets for the pEntry.
+ But maybe the signal becomes better.
+ So we try to send a packet periodically and we will
+ get the tx status in tx done interrupt.
+ If the tx status is success, pMacEntry->ContinueTxFailCnt
+ will be cleared to 0.
+ */
+#define ENTRY_RETRY_INTERVAL (100 * OS_HZ / 1000)
+ ULONG Now32;
+ NdisGetSystemUpTime(&Now32);
+ if(RTMP_TIME_BEFORE(Now32, pMacEntry->TimeStamp_toTxRing + ENTRY_RETRY_INTERVAL))
+ {
+ pEntry = RemoveHeadQueue(pQueue);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ continue;
+ }
+ else
+ NdisGetSystemUpTime(&pMacEntry->TimeStamp_toTxRing);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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 | 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)
+ {
+ // 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;
+ }
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ Status = APHardTransmit(pAd, pTxBlk, QueIdx);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ }
+
+ RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+#ifdef RTMP_MAC_USB
+ if (!hasTxDesc)
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MultiChannelFlowCtl & (1 << QueIdx)) != (1 << QueIdx))
+#endif /* CONFIG_MULTI_CHANNEL */
+ 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:
+ 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"));
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier */
+ /* no carrier detection when scanning */
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ CarrierDetectionStop(pAd);
+ }
+#endif
+#endif /* CONFIG_AP_SUPPORT */
+
+ /*
+ Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
+ use Lowbound as R66 value on ScanNextChannel(...)
+ */
+ rtmp_bbp_get_agc(pAd, &pAd->BbpTuning.R66CurrentValue, RX_CHAIN_0);
+
+ pAd->hw_cfg.bbp_bw = pAd->CommonCfg.BBPCurrentBW;
+
+ RTMPSetAGCInitValue(pAd, BW_20);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ /* abort all TX rings */
+ /*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); */
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Resume MSDU transmission
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPResumeMsduTransmission(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT
+ /* no carrier detection when scanning*/
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ CarrierDetectionStart(pAd);
+#endif /* CARRIER_DETECTION_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ /*
+ 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_bbp_set_agc(pAd, pAd->BbpTuning.R66CurrentValue, RX_CHAIN_ALL);
+
+ pAd->CommonCfg.BBPCurrentBW = pAd->hw_cfg.bbp_bw;
+
+ 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;
+
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR FromWhichBSSID = RTMP_GET_PACKET_IF(pPacket);
+ UCHAR VLAN_Size;
+ USHORT VLAN_VID = 0, VLAN_Priority = 0;
+
+
+ if ((FromWhichBSSID < pAd->ApCfg.BssidNum)
+ )
+ VLAN_Size = (pAd->ApCfg.MBSSID[FromWhichBSSID].VLAN_VID != 0) ? LENGTH_802_1Q : 0;
+#ifdef WDS_VLAN_SUPPORT
+ else if ((FromWhichBSSID >= MIN_NET_DEVICE_FOR_WDS) &&
+ (FromWhichBSSID < (MIN_NET_DEVICE_FOR_WDS + MAX_WDS_ENTRY)))
+ {
+ VLAN_Size = (pAd->WdsTab.\
+ WdsEntry[FromWhichBSSID - MIN_NET_DEVICE_FOR_WDS].\
+ VLAN_VID != 0) ? LENGTH_802_1Q : 0;
+ }
+#endif /* WDS_VLAN_SUPPORT */
+ else /* only MBssid support VLAN.*/
+ VLAN_Size = 0;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UCHAR WhichBSSID = FromWhichBSSID;
+ if (pRemovedLLCSNAP)
+ {
+ pPayload -= (LENGTH_802_3 + VLAN_Size);
+ PayloadSize += (LENGTH_802_3 + VLAN_Size);
+ /*NdisMoveMemory(pPayload, &Header802_3, LENGTH_802_3);*/
+ }
+ else
+ {
+ pPayload -= VLAN_Size;
+ PayloadSize += VLAN_Size;
+ }
+
+ MBSS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, WhichBSSID);
+
+#ifdef WDS_VLAN_SUPPORT
+ if (VLAN_VID == 0) /* maybe WDS packet */
+ WDS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+#endif /* WDS_VLAN_SUPPORT */
+
+ RT_VLAN_8023_HEADER_COPY(pAd, VLAN_VID, VLAN_Priority,
+ Header802_3, LENGTH_802_3, pPayload,
+ FromWhichBSSID, TPID);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
+ if (pClonePacket)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AP_ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
+#endif /* CONFIG_AP_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:
+
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+ MULTISSID_STRUCT *pMbss;
+#endif /* CONFIG_AP_SUPPORT */
+ BOOLEAN bWmmReq;
+
+#ifdef CONFIG_AP_SUPPORT
+/* if (IS_ENTRY_CLIENT(pMacEntry))*/
+/* pMbss = pMacEntry->pMbss;*/
+/* else*/
+/* pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];*/
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* for APClient, WDS, Mesh, they use MAIN BSS */
+ UCHAR apidx;
+ apidx = RTMP_GET_PACKET_NET_DEVICE(pPacket);
+ if (apidx >= MAX_MBSSID_NUM(pAd))
+ apidx = MAIN_MBSSID;
+ pMbss = &pAd->ApCfg.MBSSID[apidx];
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /*
+ for bc/mc packets, if it has VLAN tag or DSCP field, we also need
+ to get UP for IGMP use.
+ */
+ bWmmReq = (
+#ifdef CONFIG_AP_SUPPORT
+ (
+ (pMbss->bWmmCapable)) ||
+#endif /* CONFIG_AP_SUPPORT */
+ 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)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ USHORT VLAN_VID = 0;
+
+ /* 0x8100 means VLAN packets */
+
+ /* Dest. MAC Address (6-bytes) +
+ Source MAC Address (6-bytes) +
+ Length/Type = 802.1Q Tag Type (2-byte) +
+ Tag Control Information (2-bytes) +
+ Length / Type (2-bytes) +
+ data payload (0-n bytes) +
+ Pad (0-p bytes) +
+ Frame Check Sequence (4-bytes) */
+
+ /* No matter unicast or multicast */
+ /*if (IS_ENTRY_CLIENT(pMacEntry))*/
+#ifdef WDS_VLAN_SUPPORT
+ if (IS_ENTRY_WDS(pMacEntry))
+ {
+ UINT32 WdsId;
+
+ WdsId = RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS;
+ if (WdsId < MAX_WDS_ENTRY)
+ VLAN_VID = pAd->WdsTab.WdsEntry[WdsId].VLAN_VID;
+ }
+ else
+#endif /* WDS_VLAN_SUPPORT */
+ {
+ VLAN_VID = pMbss->VLAN_VID;
+ }
+
+ if (VLAN_VID != 0)
+ {
+ /* check if the packet is my VLAN */
+ /* VLAN tag: 3-bit UP + 1-bit CFI + 12-bit VLAN ID */
+ USHORT vlan_id = *(USHORT *)pSrcBuf;
+
+ vlan_id = cpu2be16(vlan_id);
+ vlan_id = vlan_id & 0x0FFF; /* 12 bit */
+ if (vlan_id != VLAN_VID)
+ {
+ /* not my VLAN packet, discard it */
+ return FALSE;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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;
+#ifdef WAPI_SUPPORT
+ case 0x88b4:
+ {
+ /* WAI Packet.*/
+ /*hex_dump("WAI Packet", pSrcBuf, pktLen);*/
+ RTMP_SET_PACKET_WAI(pPacket, 1);
+ }
+ break;
+#endif /* WAPI_SUPPORT */
+
+
+ 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 RTMP_ADAPTER *pAd,
+ IN RSSI_SAMPLE *pRssi,
+ IN RXWI_STRUC *pRxWI)
+{
+ CHAR rssi[3];
+ UCHAR snr[3];
+ BOOLEAN bInitial = FALSE;
+ CHAR Phymode = get_pkt_phymode_by_rxwi(pRxWI);
+
+
+ if (!(pRssi->AvgRssi0 | pRssi->AvgRssi0X8 | pRssi->LastRssi0))
+ {
+ bInitial = TRUE;
+ }
+
+ get_pkt_rssi_by_rxwi(pAd, pRxWI, 3, &rssi[0]);
+ get_pkt_snr_by_rxwi(pAd, pRxWI, 3, &snr[0]);
+ if (rssi[0] != 0)
+ {
+ pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi[0], RSSI_0, pRxWI->RxWISNR1, pRxWI->RxWIBW);
+ 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 (snr[0] != 0 && Phymode != MODE_CCK)
+ {
+ pRssi->LastSnr0 = ConvertToSnr(pAd, (UCHAR)snr[0]);
+ 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;
+ }
+
+ if (rssi[1] != 0)
+ {
+ pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi[1], RSSI_1, pRxWI->RxWISNR1, pRxWI->RxWIBW);
+ 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 (snr[1] != 0 && Phymode != MODE_CCK)
+ {
+ pRssi->LastSnr1 = ConvertToSnr(pAd, (UCHAR)snr[1]);
+ 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;
+ }
+
+ if (rssi[2] != 0)
+ {
+ pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi[2], RSSI_2, pRxWI->RxWISNR1, pRxWI->RxWIBW);
+
+ 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 RTMP_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;
+
+
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("Indicate_Legacy_Packet", pRxBlk->pData, pRxBlk->DataSize);
+ hex_dump("802_11_hdr", (UCHAR *)pRxBlk->pHeader, LENGTH_802_11);
+}
+//---Add by shiang for debug
+
+ /*
+ 1. get 802.3 Header
+ 2. remove LLC
+ a. pointer pRxBlk->pData to payload
+ b. modify pRxBlk->DataSize
+ */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ RTMP_AP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif /* CONFIG_AP_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->RxWIWirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->RxWITID;
+ 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->RxWITID, pRxBlk->pRxInfo->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 */
+
+#ifdef CONFIG_AP_SUPPORT
+ MBSS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+
+#ifdef WDS_VLAN_SUPPORT
+ if (VLAN_VID == 0) /* maybe WDS packet */
+ WDS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+#endif /* WDS_VLAN_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("Before80211_2_8023", pRxBlk->pData, pRxBlk->DataSize);
+ hex_dump("header802_3", &Header802_3[0], LENGTH_802_3);
+}
+//---Add by shiang for debug
+ RT_80211_TO_8023_PACKET(pAd, VLAN_VID, VLAN_Priority,
+ pRxBlk, Header802_3, FromWhichBSSID, TPID);
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("After80211_2_8023", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), GET_OS_PKT_LEN(pRxBlk->pRxPacket));
+}
+//---Add by shiang for debug
+
+
+ /* pass this 802.3 packet to upper layer or forward this packet to WM directly*/
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AP_ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
+#endif /* CONFIG_AP_SUPPORT */
+
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+/* Normal legacy Rx packet indication*/
+VOID Indicate_Legacy_Packet_Hdr_Trns(
+ IN RTMP_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;
+
+ struct sk_buff *pOSPkt;
+
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("Indicate_Legacy_Packet", pRxBlk->pTransData, pRxBlk->TransDataSize);
+ hex_dump("802_11_hdr", pRxBlk->pHeader, LENGTH_802_11);
+}
+//---Add by shiang for debug
+
+ /*
+ 1. get 802.3 Header
+ 2. remove LLC
+ a. pointer pRxBlk->pData to payload
+ b. modify pRxBlk->DataSize
+ */
+
+ if (pRxBlk->TransDataSize > 1514 )
+ {
+
+ /* 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->RxWIWirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->RxWITID;
+ 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->RxWITID, pRxBlk->pRxInfo->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 */
+
+#ifdef CONFIG_AP_SUPPORT
+ MBSS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+
+#ifdef WDS_VLAN_SUPPORT
+ if (VLAN_VID == 0) /* maybe WDS packet */
+ WDS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+#endif /* WDS_VLAN_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("Before80211_2_8023", pRxBlk->pData, pRxBlk->TransDataSize);
+ hex_dump("header802_3", &Header802_3[0], LENGTH_802_3);
+}
+//---Add by shiang for debug
+
+
+
+
+
+ RtmpOsSetPacket(get_netdev_from_bssid(pAd, FromWhichBSSID), pRxPacket, pRxBlk->pTransData, pRxBlk->TransDataSize);
+
+
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("After80211_2_8023", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), GET_OS_PKT_LEN(pRxBlk->pRxPacket));
+}
+//---Add by shiang for debug
+
+
+ /* pass this 802.3 packet to upper layer or forward this packet to WM directly*/
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AP_ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
+#endif /* CONFIG_AP_SUPPORT */
+
+}
+#endif /* HDR_TRANS_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);
+ }
+ }
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+VOID CmmRxnonRalinkFrameIndicate_Hdr_Trns(
+ 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_Hdr_Trns(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_Hdr_Trns(pAd, pRxBlk, FromWhichBSSID);
+ }
+ }
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ RTMP_AP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ USHORT VLAN_VID = 0, VLAN_Priority = 0;
+
+ MBSS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+#ifdef WDS_VLAN_SUPPORT
+ if (VLAN_VID == 0) /* maybe WDS packet */
+ WDS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+#endif /* WDS_VLAN_SUPPORT */
+
+ RT_VLAN_PKT_DUPLICATE(pPacket2, pAd, VLAN_VID, VLAN_Priority,
+ (pData2-LENGTH_802_3), LENGTH_802_3, pData2,
+ Payload2Size, FromWhichBSSID, TPID);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (!pPacket2)
+ {
+ /* release packet*/
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ /* update payload size of 1st packet*/
+ pRxBlk->DataSize = Payload1Size;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ MBSS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+
+#ifdef WDS_VLAN_SUPPORT
+ if (VLAN_VID == 0) /* maybe WDS packet */
+ WDS_VLAN_INFO_GET(pAd, VLAN_VID, VLAN_Priority, FromWhichBSSID);
+#endif /* WDS_VLAN_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ RT_80211_TO_8023_PACKET(pAd, VLAN_VID, VLAN_Priority,
+ pRxBlk, Header802_3, FromWhichBSSID, TPID);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AP_ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (pPacket2)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AP_ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
+#endif /* CONFIG_AP_SUPPORT */
+ }
+}
+
+
+#define RESET_FRAGFRAME(_fragFrame) \
+ { \
+ _fragFrame.RxSize = 0; \
+ _fragFrame.Sequence = 0; \
+ _fragFrame.LastFrag = 0; \
+ _fragFrame.Flags = 0; \
+ }
+
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+ IN RTMP_ADAPTER *pAd,
+ IN RX_BLK *pRxBlk)
+{
+ HEADER_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 RTMP_ADAPTER *pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ if (pRxBlk->pRxWI->RxWIWirelessCliID >= MAX_LEN_OF_MAC_TABLE)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: invalid wcid.\n"));
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ pEntry = &pAd->MacTab.Content[pRxBlk->pRxWI->RxWIWirelessCliID];
+ if (pEntry == NULL)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ APRxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ return;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+}
+
+
+#define BCN_TBTT_OFFSET 64 /*defer 64 us*/
+VOID ReSyncBeaconTime(
+ IN RTMP_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);
+
+#ifdef WAPI_SUPPORT
+ if (pTxBlk->CipherAlg == CIPHER_SMS4)
+ ex_tail = LEN_WPI_MIC;
+ else
+#endif /* WAPI_SUPPORT */
+ 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;
+#ifdef WAPI_SUPPORT
+ pTxBlk->KeyIdx = pMacEntry->usk_id;
+
+ /* TSC increment pre encryption transmittion */
+ if (pKey->CipherAlg == CIPHER_SMS4)
+ inc_iv_byte(pKey->TxTsc, LEN_WAPI_TSC, 2);
+ else
+#endif /* WAPI_SUPPORT */
+ 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 */
+
+/*
+ ==========================================================================
+ Description:
+ Send out a NULL frame to a specified STA at a higher TX rate. The
+ purpose is to ensure the designated client is okay to received at this
+ rate.
+ ==========================================================================
+ */
+VOID RtmpEnqueueNullFrame(
+ 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)
+{
+ NDIS_STATUS NState;
+ PHEADER_802_11 pNullFr;
+ PUCHAR pFrame;
+ ULONG Length;
+
+ /* since TxRate may change, we have to change Duration each time */
+ NState = MlmeAllocateMemory(pAd, (PUCHAR *)&pFrame);
+ pNullFr = (PHEADER_802_11) pFrame;
+ Length = sizeof(HEADER_802_11);
+
+ if (NState == NDIS_STATUS_SUCCESS)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ MgtMacHeaderInit(pAd, pNullFr, SUBTYPE_NULL_FUNC, 0, pAddr,
+ pAd->ApCfg.MBSSID[apidx].Bssid);
+#endif /* CONFIG_AP_SUPPORT */
+
+ pNullFr->FC.Type = BTYPE_DATA;
+ pNullFr->FC.FrDs = 1;
+ pNullFr->Duration = RTMPCalcDuration(pAd, TxRate, 14);
+
+
+#ifdef UAPSD_SUPPORT
+ if (bQosNull)
+ {
+ UCHAR *qos_p = ((UCHAR *)pNullFr) + Length;
+
+ pNullFr->FC.SubType = SUBTYPE_QOS_NULL;
+
+ /* copy QOS control bytes */
+ qos_p[0] = ((bEOSP) ? (1 << 4) : 0) | OldUP;
+ qos_p[1] = 0;
+ Length += 2;
+ } /* End of if */
+#endif /* UAPSD_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_INFO, ("send NULL Frame @%d Mbps to AID#%d...\n", RateIdToMbps[TxRate], PID & 0x3f));
+ MiniportMMRequest(pAd, MapUserPriorityToAccessCategory[7], (PUCHAR)pNullFr, Length);
+ MlmeFreeMemory(pAd, pFrame);
+ }
+}
+
+
+
+#ifdef RLT_MAC
+BOOLEAN CmdRspEventCallbackHandle(PRTMP_ADAPTER pAd, PUCHAR pRspBuffer)
+{
+
+ INT32 Ret;
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+ struct CMD_RSP_EVENT *CmdRspEvent, *CmdRspEventTmp;
+ RXFCE_INFO_CMD *pFceInfo = (RXFCE_INFO_CMD *)pRspBuffer;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pFceInfo, TYPE_RXINFO);
+#endif
+
+
+ if ((pFceInfo->info_type != CMD_PACKET))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Packet is not command response/event\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ if (pFceInfo->self_gen)
+ {
+ /* if have callback function */
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_RESPONSE_EVENT_CALLBACK,
+ pRspBuffer,
+ sizeof(*pFceInfo) + pFceInfo->pkt_len);
+ }
+ else
+ {
+ unsigned long IrqFlags;
+ RTMP_IRQ_LOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+ DlListForEachSafe(CmdRspEvent, CmdRspEventTmp, &MCtrl->CmdRspEventList, struct CMD_RSP_EVENT, List)
+ {
+ if (CmdRspEvent->CmdSeq == pFceInfo->cmd_seq)
+ {
+
+ if ((*CmdRspEvent->RspPayloadLen == pFceInfo->pkt_len) && (*CmdRspEvent->RspPayloadLen != 0))
+ {
+ NdisMoveMemory(*CmdRspEvent->RspPayload, pRspBuffer + sizeof(*pFceInfo),
+ pFceInfo->pkt_len);
+ }
+ else if ((*CmdRspEvent->RspPayloadLen == 0) && (pFceInfo->pkt_len == 8))
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("Command response(ack) success\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Expect response len(%d), Command response len(%d) invalid\n", *CmdRspEvent->RspPayloadLen, pFceInfo->pkt_len));
+ *CmdRspEvent->RspPayloadLen = pFceInfo->pkt_len;
+ }
+
+ if (CmdRspEvent->NeedWait)
+ {
+ RtmpComplete(CmdRspEvent->AckDone);
+ }
+ else
+ {
+ DlListDel(&CmdRspEvent->List);
+ os_free_mem(NULL, CmdRspEvent);
+ }
+
+ break;
+ }
+ }
+ RTMP_IRQ_UNLOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef RTMP_USB_SUPPORT
+BOOLEAN CmdRspEventHandle(RTMP_ADAPTER *pAd)
+{
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+
+ CmdRspEventCallbackHandle(pAd, pCmdRspEventContext->CmdRspBuffer);
+
+ return TRUE;
+
+}
+#endif /* RTMP_USB_SUPPORT */
+#endif /* RLT_MAC */
+
+
+#ifdef CONFIG_AP_SUPPORT
+MAC_TABLE_ENTRY *MulTestTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount)
+{
+ USHORT HashIdx;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ pEntry = pAd->MacTab.Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+ if(bResetIdelCount)
+ pEntry->NoDataIdleCount = 0;
+ break;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ return pEntry;
+}
+
+
+MAC_TABLE_ENTRY *MacTableInsertMulTestEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ UINT WdsTabIdx)
+{
+ PMAC_TABLE_ENTRY pEntry = NULL;
+ HTTRANSMIT_SETTING HTPhyMode;
+
+ /* if FULL, return */
+ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+ return NULL;
+
+ if((pEntry = MulTestTableLookup(pAd, pAddr, TRUE)) != NULL)
+ return pEntry;
+
+ /* allocate one WDS entry */
+ do
+ {
+ /* allocate one MAC entry */
+ pEntry = MacTableInsertEntry(pAd, pAddr, BSS0, OPMODE_AP, TRUE);
+ if (pEntry)
+ {
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+ /* specific Max Tx Rate for Wds link. */
+ NdisZeroMemory(&HTPhyMode, sizeof(HTTRANSMIT_SETTING));
+ switch (pAd->MulTestTab.WdsEntry[WdsTabIdx].PhyMode)
+ {
+ case 0xff: /* user doesn't specific a Mode for WDS link. */
+ case MODE_OFDM: /* specific OFDM mode. */
+ HTPhyMode.field.MODE = MODE_OFDM;
+ HTPhyMode.field.MCS = 7;
+ pEntry->RateLen = 8;
+ break;
+
+ case MODE_CCK:
+ HTPhyMode.field.MODE = MODE_CCK;
+ HTPhyMode.field.MCS = 3;
+ pEntry->RateLen = 4;
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case MODE_HTMIX:
+ HTPhyMode.field.MCS = 7;
+ HTPhyMode.field.ShortGI = pAd->MulTestTab.WdsEntry[WdsTabIdx].HTPhyMode.field.ShortGI;
+ HTPhyMode.field.BW = pAd->MulTestTab.WdsEntry[WdsTabIdx].HTPhyMode.field.BW;
+ HTPhyMode.field.STBC = pAd->MulTestTab.WdsEntry[WdsTabIdx].HTPhyMode.field.STBC;
+ HTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->RateLen = 12;
+ break;
+
+ case MODE_HTGREENFIELD:
+ HTPhyMode.field.MCS = 7;
+ HTPhyMode.field.ShortGI = pAd->MulTestTab.WdsEntry[WdsTabIdx].HTPhyMode.field.ShortGI;
+ HTPhyMode.field.BW = pAd->MulTestTab.WdsEntry[WdsTabIdx].HTPhyMode.field.BW;
+ HTPhyMode.field.STBC = pAd->MulTestTab.WdsEntry[WdsTabIdx].HTPhyMode.field.STBC;
+ HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ pEntry->RateLen = 12;
+ break;
+#endif /* DOT11_N_SUPPORT */
+
+ default:
+ break;
+ }
+
+ {
+ pEntry->Sst = SST_ASSOC;
+
+ pEntry->MaxSupportedRate = RATE_54;
+
+ 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];
+ }
+
+ // Set WMM capability
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) || (pAd->CommonCfg.bWmmCapable))
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ UCHAR j, bitmask; /*k,bitmask; */
+ CHAR i;
+
+ if ((pAd->CommonCfg.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 ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pAd->CommonCfg.HtCapability.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->ApCfg.MBSSID[pEntry->apidx].DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pAd->CommonCfg.HtCapability.MCSSet[j] & bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = i;
+ break;
+ }
+ if (i==0)
+ break;
+ }
+
+
+ if (pAd->ApCfg.MBSSID[pEntry->apidx].DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("@@@ IF-ra%d DesiredTransmitSetting.field.MCS = %d\n", pEntry->apidx,
+ pAd->ApCfg.MBSSID[pEntry->apidx].DesiredTransmitSetting.field.MCS));
+
+ if (pAd->ApCfg.MBSSID[pEntry->apidx].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->ApCfg.MBSSID[pEntry->apidx].HTPhyMode.field.MCS)
+ {
+ /* STA supports fixed MCS */
+ pEntry->MaxHTPhyMode.field.MCS = pAd->ApCfg.MBSSID[pEntry->apidx].HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ if (pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity < 5)
+ pEntry->MpduDensity = 5;
+ else
+ pEntry->MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)pAd->CommonCfg.HtCapability.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 (pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ /* Record the received capability from association request */
+ NdisMoveMemory(&pEntry->HTCapability, &pAd->CommonCfg.HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+ else
+ {
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE));
+ }
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+ }
+
+ //pEntry->MaxHTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ //pEntry->MinHTPhyMode.word = pAd->MulTestTab.WdsEntry[WdsTabIdx].MinHTPhyMode.word;
+ //pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+
+ /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
+ if (pAd->MulTestTab.WdsEntry[WdsTabIdx].bAutoTxRateSwitch == FALSE)
+ {
+ pEntry->HTPhyMode.field.MCS = pAd->MulTestTab.WdsEntry[WdsTabIdx].DesiredTransmitSetting.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+ /* If the legacy mode is set, overwrite the transmit setting of this entry. */
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->MulTestTab.WdsEntry[WdsTabIdx].DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ else
+ {
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+
+ pAd->MulTestTab.WdsEntry[WdsTabIdx].MacTabMatchWCID = (UCHAR)pEntry->Aid;
+ pEntry->MatchWDSTabIdx = WdsTabIdx;
+
+ AsicUpdateMulTestEncryption(pAd, pEntry->Aid);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertWDSEntry - allocate entry #%d, Total= %d\n",WdsTabIdx, pAd->MacTab.Size));
+ break;
+ }
+ }while(FALSE);
+
+ return pEntry;
+}
+
+
+VOID AsicUpdateMulTestRxWCIDTable(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT index;
+
+ for(index = 0; index < MAX_WDS_ENTRY; index++)
+ {
+ if (pAd->MulTestTab.WdsEntry[index].Valid != TRUE)
+ continue;
+
+ MacTableInsertMulTestEntry(pAd, pAd->MulTestTab.WdsEntry[index].PeerWdsAddr, index);
+ }
+
+ return;
+}
+
+VOID AsicUpdateMulTestEncryption(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid)
+{
+ UINT WdsIdex;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ do
+ {
+ if (wcid >= MAX_LEN_OF_MAC_TABLE)
+ break;
+
+ pEntry = &pAd->MacTab.Content[wcid];
+ if (pAd->MulTestTab.WdsEntry[pEntry->MatchWDSTabIdx].Valid != TRUE)
+ break;
+
+ WdsIdex = pEntry->MatchWDSTabIdx;
+
+ if (((pAd->MulTestTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->MulTestTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->MulTestTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption3Enabled)
+#ifdef WAPI_SUPPORT
+ || (pAd->MulTestTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11EncryptionSMS4Enabled)
+#endif /* WAPI_SUPPORT */
+ ) && (pAd->MulTestTab.WdsEntry[WdsIdex].WdsKey.KeyLen > 0))
+ {
+
+ INT DefaultKeyId = 0;
+
+ if (pAd->MulTestTab.WdsEntry[WdsIdex].WepStatus == Ndis802_11Encryption1Enabled)
+ DefaultKeyId = pAd->MulTestTab.WdsEntry[pEntry->MatchWDSTabIdx].KeyIdx;
+
+ NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
+
+ /* Assign key material and its length */
+ NdisMoveMemory((PUCHAR)(&pEntry->PairwiseKey), (PUCHAR)(&pAd->MulTestTab.WdsEntry[WdsIdex].WdsKey), sizeof(CIPHER_KEY));
+
+ DBGPRINT(RT_DEBUG_ERROR, ("pEntry->PairwiseKey.CipherAlg = (%d)\n", pEntry->PairwiseKey.CipherAlg));
+
+ pEntry->WepStatus = pAd->MulTestTab.WdsEntry[WdsIdex].WepStatus;
+
+ /* Assign the pairwise cipher algorithm */
+ if (pEntry->WepStatus == Ndis802_11Encryption1Enabled)
+ {
+ if (pAd->MulTestTab.WdsEntry[WdsIdex].WdsKey.CipherAlg == CIPHER_WEP64)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
+ else if (pAd->MulTestTab.WdsEntry[WdsIdex].WdsKey.CipherAlg == CIPHER_WEP128)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (wcid-%d)\n",
+ __FUNCTION__, pEntry->Aid));
+ return;
+
+ }
+ }
+ else if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
+ else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
+#ifdef WAPI_SUPPORT
+ else if (pEntry->WepStatus == Ndis802_11EncryptionSMS4Enabled)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_SMS4;
+#endif /* WAPI_SUPPORT */
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (wcid-%d)\n",
+ __FUNCTION__, pEntry->Aid));
+ return;
+ }
+
+#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 */
+ {
+ /* Update key into Asic Pairwise key table */
+ RTMP_ASIC_PAIRWISE_KEY_TABLE(
+ pAd,
+ pEntry->Aid,
+ &pAd->MulTestTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsKey);
+
+ /* update WCID attribute table and IVEIV table for this entry */
+ RTMP_SET_WCID_SEC_INFO(
+ pAd,
+ BSS0,
+ DefaultKeyId,
+ pAd->MulTestTab.WdsEntry[pEntry->MatchWDSTabIdx].WdsKey.CipherAlg,
+ pEntry->Aid,
+ PAIRWISEKEY);
+ }
+
+
+
+
+ }
+ } while (FALSE);
+
+ return;
+}
+#endif
+
+
+NTSTATUS StopDmaRx(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Level)
+{
+ PNDIS_PACKET pRxPacket;
+ RX_BLK RxBlk, *pRxBlk;
+ UINT32 RxPending = 0, MacReg = 0, MTxCycle = 0;
+ BOOLEAN bReschedule = FALSE;
+ UINT32 MaxRetry;
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
+
+ if ( Level == DOT11POWERSAVE )
+ MaxRetry = 20;
+ else
+ MaxRetry = 2000;
+
+ /*
+ process whole rx ring
+ */
+ while (1)
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return STATUS_UNSUCCESSFUL;
+ pRxBlk = &RxBlk;
+ pRxPacket = GetPacketFromRxRing(pAd, pRxBlk, &bReschedule, &RxPending);
+ if ((RxPending == 0) && (bReschedule == FALSE))
+ break;
+ else
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ }
+
+ /*
+ Check DMA Rx idle
+ */
+ for (MTxCycle = 0; MTxCycle < MaxRetry ; MTxCycle++)
+ {
+
+#ifdef RTMP_MAC_USB
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &MacReg);
+
+ if (MacReg & 0x40000000)
+ {
+ RTMPusecDelay(50);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("==> DMA Rx Idle, MacReg=0x%x\n", MacReg));
+ break;
+ }
+#endif /* RTMP_MAC_USB */
+
+ if (MacReg == 0xFFFFFFFF)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if (MTxCycle >= MaxRetry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:RX DMA busy!! DMA_CFG = 0x%08x\n", __FUNCTION__, MacReg));
+
+ if ( Level == GUIRADIO_OFF )
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (Level == RTMP_HALT)
+ {
+ /*
+ Disable DMA RX
+ */
+
+ }
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("<==== %s\n", __FUNCTION__));
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS StopDmaTx(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Level)
+{
+ UINT32 MacReg = 0, MTxCycle = 0;
+#ifdef RTMP_MAC_USB
+ USB_DMA_CFG_STRUC UsbCfg;
+#endif /* RTMP_MAC_USB */
+ UINT8 IdleNums = 0;
+ UINT32 MaxRetry;
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
+
+ if ( Level == DOT11POWERSAVE )
+ MaxRetry = 20;
+ else
+ MaxRetry = 2000;
+
+ for (MTxCycle = 0; MTxCycle < MaxRetry; MTxCycle++)
+ {
+
+#ifdef RTMP_MAC_USB
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &MacReg);
+
+ if (MacReg & 0x80000000 )
+ {
+ RTMPusecDelay(50);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("==> DMA Tx Idle, MacReg=0x%x\n", MacReg));
+ break;
+ }
+#endif /* RTMP_MAC_USB */
+
+ if (MacReg == 0xFFFFFFFF)
+ {
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if (MTxCycle >= MaxRetry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("TX DMA busy!! DMA_CFG(%x)\n", MacReg));
+
+ if ( Level == GUIRADIO_OFF )
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (Level == RTMP_HALT)
+ {
+ }
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("<==== %s\n", __FUNCTION__));
+ return STATUS_SUCCESS;
+}
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_data_usb.c b/cleopatre/devkit/mt7601udrv/common/cmm_data_usb.c
new file mode 100644
index 0000000000..46865c2b6c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_data_usb.c
@@ -0,0 +1,1312 @@
+/*
+ All functions in this file must be USB-depended, or you should out your function
+ in other files.
+
+*/
+
+#ifdef RTMP_MAC_USB
+
+#include "rt_config.h"
+
+
+NDIS_STATUS RTUSBFreeDescriptorRelease(RTMP_ADAPTER *pAd, UCHAR BulkOutPipeId)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ unsigned long IrqFlags;
+
+
+ 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;
+}
+
+
+/*
+ ========================================================================
+
+ 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 RTUSBFreeDescRequest(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UINT32 req_cnt)
+{
+ 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 + req_cnt + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
+ {
+
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (req_cnt + 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(RTMP_ADAPTER *pAd, UCHAR BulkOutPipeId)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ BOOLEAN needQueBack = FALSE;
+ unsigned long IrqFlags;
+
+
+ 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
+
+ ========================================================================
+*/
+static VOID rlt_usb_write_txinfo(
+ IN RTMP_ADAPTER *pAd,
+ IN TXINFO_STRUC *pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst,
+ IN UCHAR pkt_80211 )
+{
+#ifdef RLT_MAC
+ struct _TXINFO_NMAC_PKT *nmac_info;
+
+ nmac_info = (struct _TXINFO_NMAC_PKT *)pTxInfo;
+#ifdef HDR_TRANS_SUPPORT
+ nmac_info->pkt_80211 = pkt_80211;
+#else
+ nmac_info->pkt_80211 = 1;
+#endif /* HDR_TRANS_SUPPORT */
+ nmac_info->info_type = 0;
+ nmac_info->d_port = 0;
+ nmac_info->cso = 0;
+ nmac_info->tso = 0;
+#endif /* RLT_MAC */
+
+#ifdef RTMP_MAC
+
+#endif /* RTMP_MAC */
+
+ pTxInfo->TxInfoPktLen = USBDMApktLen;
+ pTxInfo->TxInfoQSEL = QueueSel;
+#ifndef CONFIG_MULTI_CHANNEL
+ if (QueueSel != FIFO_EDCA)
+ DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA <====\n"));
+#endif /* !CONFIG_MULTI_CHANNEL */
+ pTxInfo->TxInfoUDMANextVld = FALSE; /*NextValid; Need to check with Jan about this.*/
+ pTxInfo->TxInfoUDMATxburst = TxBurst;
+ pTxInfo->TxInfoWIV = bWiv;
+#ifndef USB_BULK_BUF_ALIGMENT
+ pTxInfo->TxInfoSwLstRnd = 0;
+#else
+ pTxInfo->bFragLasAlignmentsectiontRound = 0;
+#endif /* USB_BULK_BUF_ALIGMENT */
+}
+
+
+static VOID rlt_usb_update_txinfo(
+ IN RTMP_ADAPTER *pAd,
+ IN TXINFO_STRUC *pTxInfo,
+ IN TX_BLK *pTxBlk)
+{
+#ifdef RLT_MAC
+#endif /* RLT_MAC */
+}
+
+
+
+
+/* IRQL = DISPATCH_LEVEL */
+VOID ComposeNullFrame(RTMP_ADAPTER *pAd)
+{
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ UCHAR *buf;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ USHORT data_len = sizeof(pAd->NullFrame);;
+
+ PTX_CONTEXT pNullContext = &pAd->NullContext[0];
+
+ NdisZeroMemory(&pAd->NullFrame, data_len);
+ 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);
+ buf = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
+
+ RTMPZeroMemory(buf, 100);
+ pTxInfo = (TXINFO_STRUC *)buf;
+ pTxWI = (TXWI_STRUC *)&buf[TXINFO_SIZE];
+ rlt_usb_write_txinfo(pAd, pTxInfo,
+ (USHORT)(data_len + TXWISize + TSO_SIZE), TRUE,
+ EpToQueue[MGMTPIPEIDX], FALSE, FALSE, 1);
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
+ BSSID_WCID, data_len, 0, 0,
+ (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS,
+ IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ RTMPMoveMemory((VOID *)&buf[TXWISize + TXINFO_SIZE], (VOID *)&pAd->NullFrame, data_len);
+ pNullContext->BulkOutSize = TXINFO_SIZE + TXWISize + TSO_SIZE + data_len + 4;
+
+}
+
+
+/*
+ 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"));
+ }
+ else if ((pHTTXContext->ENextBulkOutPosition == 8) && ((pHTTXContext->CurWritePosition + 7912 ) > MAX_TXBULK_LIMIT) )
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c4!\n"));
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+ }
+
+#endif /* USB_BULK_BUF_ALIGMENT */
+ else
+ {
+ canWrite = NDIS_STATUS_SUCCESS;
+ }
+
+
+ return canWrite;
+}
+
+
+USHORT RtmpUSB_WriteSubTxResource(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *freeCnt)
+{
+
+ /* Dummy function. Should be removed in the future.*/
+ return 0;
+
+}
+
+USHORT RtmpUSB_WriteFragTxResource(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR fragNum,
+ OUT USHORT *freeCnt)
+{
+ 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 */
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ /* 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 = (TXINFO_STRUC *)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (TXWI_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 = TXWISize + 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*/
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((QueIdx == QID_HCCA) && (pAd->Multi_Channel_Enable == TRUE))
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(USBDMApktLen),
+ FALSE, FIFO_EDCA2, FALSE, FALSE, 1);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE, 1);
+
+ if (fragNum == pTxBlk->TotalFragNum)
+ {
+ pTxInfo->TxInfoUDMATxburst = 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->TxInfoSwLstRnd = 1;
+ TxQLastRound = TRUE;
+ }
+#endif /* USB_BULK_BUF_ALIGMENT */
+ }
+ else
+ {
+ pTxInfo->TxInfoUDMATxburst = 1;
+ }
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWISize + hwHdrLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWISize), DIR_WRITE, FALSE);
+#endif /* RT_BIG_ENDIAN */
+ pWirelessPacket += (TXINFO_SIZE + TXWISize + hwHdrLen);
+ pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWISize + 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;
+
+#ifdef UAPSD_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UAPSD_TagFrame(pAd, pTxBlk->pPacket, pTxBlk->Wcid, pHTTXContext->CurWritePosition);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+ /* 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 RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *freeCnt)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ UCHAR *pWirelessPacket, *buf;
+ UCHAR QueIdx;
+ unsigned long IrqFlags;
+ NDIS_STATUS Status;
+ UINT32 hdr_copy_len, hdr_len, dma_len = 0, padding;
+#ifndef USB_BULK_BUF_ALIGMENT
+ BOOLEAN bTxQLastRound = FALSE;
+#endif /* USB_BULK_BUF_ALIGMENT */
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ /* 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;
+ buf = &pTxBlk->HeaderBuf[0];
+ pTxInfo = (TXINFO_STRUC *)buf;
+ pTxWI= (TXWI_STRUC *)&buf[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];
+
+ /* Build our URB for USBD */
+ hdr_len = TXWISize + TSO_SIZE + pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+ hdr_copy_len = TXINFO_SIZE + hdr_len;
+ dma_len = hdr_len + pTxBlk->SrcBufLen;
+ padding = (4 - (dma_len % 4)) & 0x03; /* round up to 4 byte alignment*/
+ dma_len += padding;
+
+ pTxBlk->Priv = (TXINFO_SIZE + dma_len);
+
+ /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + TSO_SIZE + 802.11 header + payload */
+#ifdef HDR_TRANS_SUPPORT
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((QueIdx == QID_HCCA) && (pAd->Multi_Channel_Enable == TRUE))
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(dma_len), FALSE, FIFO_EDCA2, FALSE /*NextValid*/, FALSE, pTxBlk->NeedTrans?0:1);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(dma_len), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE, pTxBlk->NeedTrans?0:1);
+#else
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((QueIdx == QID_HCCA) && (pAd->Multi_Channel_Enable == TRUE))
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(dma_len), FALSE, FIFO_EDCA2, FALSE /*NextValid*/, FALSE, 1);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(dma_len), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE, 1);
+#endif /* HDR_TRANS_SUPPORT */
+
+
+#ifndef USB_BULK_BUF_ALIGMENT
+ if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
+ {
+ pTxInfo->TxInfoSwLstRnd = 1;
+ bTxQLastRound = TRUE;
+ }
+#endif /* USB_BULK_BUF_ALIGMENT */
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, hdr_copy_len);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWISize + TSO_SIZE), DIR_WRITE, FALSE);
+#endif /* RT_BIG_ENDIAN */
+ pWirelessPacket += (hdr_copy_len);
+
+ /* 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 += hdr_copy_len;
+#ifndef USB_BULK_BUF_ALIGMENT
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+#endif /* USB_BULK_BUF_ALIGMENT */
+
+#ifdef TX_PKT_SG
+ if (pTxBlk->pkt_info.BufferCount > 1) {
+ INT i, len;
+ void *data;
+ PKT_SG_T *sg = &pTxBlk->pkt_info.sg_list[0];
+
+ for (i = 0 ; i < pTxBlk->pkt_info.BufferCount; i++) {
+ data = sg[i].data;
+ len = sg[i].len;
+ if (i == 0) {
+ len -= ((ULONG)pTxBlk->pSrcBufData - (ULONG)sg[i].data);
+ data = pTxBlk->pSrcBufData;
+ }
+ //DBGPRINT(RT_DEBUG_TRACE, ("%s:sg[%d]=0x%x, len=%d\n", __FUNCTION__, i, data, len));
+ if (len <= 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():sg[%d] info error, sg.data=0x%x, sg.len=%d, pTxBlk->pSrcBufData=0x%x, pTxBlk->SrcBufLen=%d, data=0x%x, len=%d\n",
+ __FUNCTION__, i, sg[i].data, sg[i].len, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, data, len));
+ break;
+ }
+ NdisMoveMemory(pWirelessPacket, data, len);
+ pWirelessPacket += len;
+ }
+ }
+ else
+#endif /* TX_PKT_SG */
+ {
+ 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 UAPSD_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UAPSD_TagFrame(pAd, pTxBlk->pPacket, pTxBlk->Wcid, pHTTXContext->CurWritePosition);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+#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 (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 RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR frmNum,
+ OUT USHORT *freeCnt)
+{
+ 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;
+ UCHAR *pWirelessPacket = NULL;
+ UCHAR QueIdx;
+ NDIS_STATUS Status;
+ unsigned long IrqFlags;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ /* get Tx Ring Resource & Dma Buffer address*/
+ QueIdx = pTxBlk->QueIdx;
+ pHTTXContext = &pAd->TxContext[QueIdx];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ if(frmNum == 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 = (TXINFO_STRUC *)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (TXWI_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 + TXWISize + hwHdrLen;
+
+ /* pTxInfo->USBDMApktLen now just a temp value and will to correct latter.*/
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((QueIdx == QID_HCCA) && (pAd->Multi_Channel_Enable == TRUE))
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA2, FALSE /*NextValid*/, FALSE, 1);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE, 1);
+
+ /* Copy it.*/
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWISize), 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 RTMP_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 = (TXINFO_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->TxInfoPktLen = USBDMApktLen;
+
+
+ /*
+ Update TXWI->TxWIMPDUByteCnt,
+ the length = 802.11 header + payload_of_all_batch_frames
+ */
+ pTxWI= (TXWI_STRUC *)(pWirelessPacket + TXINFO_SIZE);
+ pTxWI->TxWIMPDUByteCnt = 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->TxInfoSwLstRnd = 1;
+ }
+#endif /* USB_BULK_BUF_ALIGMENT */
+
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+#ifdef UAPSD_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UAPSD_TagFrame(pAd, pTxBlk->pPacket, pTxBlk->Wcid, pHTTXContext->CurWritePosition);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+
+ /* 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 RTMP_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 RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx)
+{
+
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MultiChannelFlowCtl & (1 << QueIdx)) == (1 << QueIdx))
+ {
+ return;
+ }
+#endif /* CONFIG_MULTI_CHANNEL */
+ 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 UCHAR *pSrcBufVA,
+ IN UINT SrcBufLen)
+{
+ TXINFO_STRUC *pTxInfo;
+ ULONG BulkOutSize;
+ UCHAR padLen;
+ PUCHAR pDest;
+ ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
+ TX_CONTEXT *pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
+ ULONG IrqFlags;
+
+
+ pTxInfo = (TXINFO_STRUC *)(pSrcBufVA);
+
+ /* Build our URB for USBD*/
+ BulkOutSize = (SrcBufLen + 3) & (~3);
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE, 1);
+
+ BulkOutSize += 4; /* Always add 4 extra bytes at every packet.*/
+
+//+++Add by shiang for debug
+if (0) {
+ DBGPRINT(RT_DEBUG_OFF, ("-->%s():shiang-6590, QueIdx=%d, SrcBufLen=%d\n", __FUNCTION__, QueIdx, SrcBufLen));
+ dump_txinfo(pAd, pTxInfo);
+ dumpTxWI(pAd, (TXWI_STRUC *)(pSrcBufVA + TXINFO_SIZE));
+}
+//---Add by shiang for debug
+
+/* 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);
+ 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;
+
+#ifdef UAPSD_SUPPORT
+ /*
+ If the packet is QoS Null frame, we mark the packet with its WCID;
+ If not, we mark the packet with bc/mc WCID = 0.
+
+ We will handle it in rtusb_mgmt_dma_done_tasklet().
+
+ Even AP send a QoS Null frame but not EOSP frame in USB mode,
+ then we will call UAPSD_SP_Close() and we will check
+ pEntry->bAPSDFlagSPStart() so do not worry about it.
+ */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (RTMP_GET_PACKET_QOS_NULL(pPacket) != 0x00)
+ pMLMEContext->Wcid = RTMP_GET_PACKET_WCID(pPacket);
+ else
+ pMLMEContext->Wcid = MCAST_WCID;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+ /*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)
+{
+
+ PTX_CONTEXT pNullContext = &pAd->NullContext[0];
+
+#ifdef CONFIG_MULTI_CHANNEL
+
+
+ if (QueIdx == EDCA_AC0_PIPE)
+ {
+ pNullContext = &pAd->NullContext[0];
+ }
+ else if (QueIdx == HCCA_PIPE)
+ {
+ pNullContext = &pAd->NullContext[1];
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow pipe!!\n", __FUNCTION__));
+
+#endif /* CONFIG_MULTI_CHANNEL */
+ if (pNullContext->InUse == FALSE)
+ {
+ PTX_CONTEXT pNullContext;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ UCHAR *pWirelessPkt;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ pNullContext = &(pAd->NullContext[0]);
+
+ /* Set the in use bit*/
+ pNullContext->InUse = TRUE;
+ pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
+
+ RTMPZeroMemory(&pWirelessPkt[0], 100);
+ pTxInfo = (TXINFO_STRUC *)&pWirelessPkt[0];
+ rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(frameLen + TXWISize + TSO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE, 1);
+ pTxInfo->TxInfoQSEL = FIFO_EDCA;
+ pTxWI = (TXWI_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(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
+#endif /* RT_BIG_ENDIAN */
+ RTMPMoveMemory(&pWirelessPkt[TXWISize + TXINFO_SIZE + TSO_SIZE], pNullFrame, frameLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWISize + TSO_SIZE], DIR_WRITE, FALSE);
+#endif /* RT_BIG_ENDIAN */
+ pNullContext->BulkOutSize = TXINFO_SIZE + TXWISize + TSO_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]));
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((QueIdx == HCCA_PIPE) && (pAd->Multi_Channel_Enable == TRUE))
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL_HCCA);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+ 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 RTMP_ADAPTER *pAd,
+ OUT RX_BLK *pRxBlk,
+ OUT BOOLEAN *pbReschedule,
+ INOUT UINT32 *pRxPending)
+{
+ RX_CONTEXT *pRxContext;
+ PNDIS_PACKET pNetPkt;
+ UCHAR *pData;
+ ULONG ThisFrameLen, RxBufferLength, valid_len;
+ RXWI_STRUC *pRxWI;
+ UINT8 RXWISize = pAd->chipCap.RXWISize;
+ RXINFO_STRUC *pRxInfo;
+#ifdef RLT_MAC
+ RXFCE_INFO *pRxFceInfo;
+#endif /* RLT_MAC */
+
+
+ pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
+ if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
+ return NULL;
+
+ RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
+ valid_len = RXDMA_FIELD_SIZE + RXWISize + sizeof(RXINFO_STRUC);
+#ifdef RLT_MAC
+ valid_len += sizeof(RXFCE_INFO);
+#endif /* RLT_MAC */
+ if (RxBufferLength < valid_len)
+ {
+ goto label_null;
+ }
+
+ pData = &pRxContext->TransferBuffer[pAd->ReadPosition];
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("GetPacketFromRxRing", pData, (RxBufferLength > 7000 ? 7000 : RxBufferLength));
+}
+//---Add by shiang for debug
+
+ /* 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 (RXDMA_FIELD_SIZE + sizeof(RXINFO_STRUC))*/
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("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 += RXDMA_FIELD_SIZE;
+#ifdef RLT_MAC
+ pRxInfo = (RXINFO_STRUC *)pData;
+ pRxFceInfo = (RXFCE_INFO *)(pData + ThisFrameLen);
+
+ pData += RXINFO_SIZE;
+#endif /* RLT_MAC */
+#ifdef RTMP_MAC
+ pRxInfo = (RXINFO_STRUC *)(pData + ThisFrameLen);
+#endif /* RTMP_MAC */
+
+ pRxWI = (RXWI_STRUC *)pData;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pAd, pData, TYPE_RXWI);
+#endif /* RT_BIG_ENDIAN */
+ if (pRxWI->RxWIMPDUByteCnt > ThisFrameLen)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
+ __FUNCTION__, pRxWI->RxWIMPDUByteCnt, ThisFrameLen));
+ goto label_null;
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pAd, 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);
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pRxInfo, TYPE_RXINFO);
+#endif /* RT_BIG_ENDIAN */
+
+#ifdef RLT_MAC
+ NdisMoveMemory((VOID *)&pRxBlk->hw_rx_info[0], (VOID *)pRxFceInfo, sizeof(RXFCE_INFO));
+ pRxBlk->pRxFceInfo = (RXFCE_INFO *)&pRxBlk->hw_rx_info[0];
+#endif /* RLT_MAC */
+
+ NdisMoveMemory(&pRxBlk->hw_rx_info[RXINFO_OFFSET], pRxInfo, RXINFO_SIZE);
+ pRxBlk->pRxInfo = (RXINFO_STRUC *)&pRxBlk->hw_rx_info[RXINFO_OFFSET];
+
+
+ /* update next packet read position.*/
+ pAd->ReadPosition += (ThisFrameLen + RXDMA_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RXDMA_FIELD_SIZE + sizeof(RXINFO_STRUC))*/
+
+ return pNetPkt;
+
+label_null:
+
+ return NULL;
+}
+
+
+
+#endif /* RTMP_MAC_USB */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_dfs.c b/cleopatre/devkit/mt7601udrv/common/cmm_dfs.c
new file mode 100644
index 0000000000..46c5bcae3a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_dfs.c
@@ -0,0 +1,3136 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_dfs.c
+
+ Abstract:
+ Support DFS function.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#include "rt_config.h"
+
+#ifdef DFS_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+
+#ifdef DFS_DEBUG
+NewDFSDebugResult TestResult[1000];
+#endif
+
+NewDFSValidRadar NewDFSValidTable[] =
+{
+ /* FCC-1 && (Japan W53 Radar 1 / W56 Radar 2)*/
+ {
+ (NEW_DFS_FCC | NEW_DFS_JAP | NEW_DFS_JAP_W53),
+ 7,
+ 10, 1000,
+ 0,
+ 4,
+ 0, 0,
+ 28570 - 70,
+ 150
+ },
+ /* FCC-2*/
+ {
+ (NEW_DFS_FCC | NEW_DFS_JAP),
+ 7,
+ 13, 1000,
+ 0,
+ 1,
+ 3000, 4600 - 20,
+ 0,
+ 25
+ },
+ /* FCC-3 & FCC-4*/
+ {
+ (NEW_DFS_FCC | NEW_DFS_JAP),
+ 7,
+ /*120, 200, FCC-3 */
+ /*220, 400, FCC-4*/
+ 100, 1500,
+ 0,
+ 1,
+ 4000, 10000 - 40,
+ 0,
+ 60
+ },
+ /* FCC-6*/
+ {
+ (NEW_DFS_FCC | NEW_DFS_JAP),
+ 7,
+ 12, 1000,
+ 0,
+ 1,
+ 0, 0,
+ 6660-10,
+ 35
+ },
+ /* Japan W53 Radar 2*/
+ {
+ NEW_DFS_JAP_W53,
+ 7,
+ 40, 1000,
+ 0,
+ 1,
+ 0, 0,
+ 76923 - 30,
+ 180
+ },
+ /* Japan W56 Radar 1*/
+ {
+ NEW_DFS_JAP,
+ 7,
+ 5, 500,
+ 0,
+ 2,
+ 0, 0,
+ 27777 - 30,
+ 70
+ },
+ /* Japan W56 Radar 3*/
+ {
+ NEW_DFS_JAP,
+ 7,
+ 30, 1000,
+ 0,
+ 1,
+ 0, 0,
+ 80000 - 50,
+ 200
+ },
+
+/* CE Staggered radar*/
+
+ {
+ /* EN-1*/
+ /* width 0.8 - 5 us*/
+ /* PRF 200 - 1000 Hz*/
+ /* PRI 5000 - 1000 us (T: 20000 - 100000)*/
+ /* */
+ NEW_DFS_EU,
+ 0xf,
+ 10, 1000,
+ 0,
+ 1,
+ 20000-15, 100000-70,
+ 0,
+ 120
+ },
+ /* EN-2*/
+ /* width 0.8 - 15 us*/
+ /* PRF 200 - 1600 Hz*/
+ /* PRI 5000 - 625 us (T: 12500 - 100000)*/
+ {
+ NEW_DFS_EU,
+ 0xf,
+ 10, 2000,
+ 0,
+ 1,
+ 12500 - 10, 100000 - 70,
+ 0,
+ 120
+ },
+
+ /* EN-3*/
+ /* width 0.8 - 15 us*/
+ /* PRF 2300 - 4000 Hz*/
+ /* PRI 434 - 250 us (T: 5000 - 8695)*/
+ {
+ NEW_DFS_EU,
+ 0xf,
+ 21, 2000,
+ 0,
+ 1,
+ 5000 - 4, 8695 - 7,
+ 0,
+ 50
+ },
+ /* EN-4*/
+ /* width 20 - 30 us*/
+ /* PRF 2000 - 4000 Hz*/
+ /* PRI 500 - 250 us (T: 5000 - 10000)*/
+ /* Note : with Chirp Modulation +- 2,5Mhz*/
+ {
+ NEW_DFS_EU,
+ 0xf,
+ 380, 3000,
+ 0,
+ 4,
+ 5000 - 4, 10000 - 8,
+ 0,
+ 60
+ },
+ /* EN-5*/
+ /* width 0.8 - 2 us*/
+ /* PRF 300 - 400 Hz*/
+ /* PRI 3333 - 2500 us (T: 50000 - 66666)*/
+ /* Staggered PRF, 20 - 50 pps*/
+ {
+ NEW_DFS_EU,
+ 0xf,
+ 10, 800,
+ 0,
+ 1,
+ 50000 - 35, 66666 + 50,
+ 0,
+ 30
+ },
+ /* EN-6*/
+ /* width 0.8 - 2 us*/
+ /* PRF 400 - 1200 Hz*/
+ /* PRI 2500 - 833 us (T: 16666 - 50000)*/
+ /* Staggered PRF, 80 - 400 pps*/
+ {
+ NEW_DFS_EU,
+ 0xf,
+ 10, 800,
+ 0,
+ 1,
+ 16666 - 13, 50000 + 35,
+ 0,
+ 30
+ },
+
+ {
+ NEW_DFS_END,
+ 0,
+ 0, 0,
+ 0,
+ 0,
+ 0, 0,
+ 0,
+ 0,
+ },
+};
+
+static NewDFSTable NewDFSTable1[] =
+{
+ {
+ /* ch, mode(0~7), M(~511), el, eh(~4095), wl, wh(~4095), err_w, tl, th, err_t, bl, bh*/
+ NEW_DFS_FCC,
+ {
+ {0, 0, 10, 8, 16, 6, 2000, 5, 2900, 29000, 5, 0, 0},
+ {1, 0, 70, 42, 126, 20, 5000, 5, 2900, 29000, 10, 0, 0},
+ {2, 0, 100, 42, 160, 20, 5000, 25, 2900, 10100, 20, 0, 0},
+ {3, 2, 200, 20, 150, 900, 2200, 50, 1000, 999999999, 200, 0, 999999999},
+ }
+ },
+
+ {
+ NEW_DFS_EU,
+ {
+ {0, 0, 10, 10, 18, 4, 4095, 5, 7800, 101000, 5, 0, 0},
+ {1, 0, 70, 42, 90, 20, 4095, 3, 4900, 101000, 10, 0, 0},
+ {2, 0, 100, 42, 160, 20, 4095, 5, 4900, 101000, 20, 0, 0},
+ {3, 3, 200, 20, 150, 200, 4095, 100, 4900, 11000, 200, 0, 0},
+ {4, 8, 0, 8, 17, 7, 70, 2, 32500, 200500, 10, 0, 0},
+ /*{5, 1, 0, 12, 16, 8, 700, 5, 33000, 135000, 100, 0, 0},*/
+ }
+ },
+
+ {
+ NEW_DFS_JAP,
+ {
+ {0, 0, 10, 8, 16, 4, 2000, 5, 2900, 85000, 5, 0, 0},
+ {1, 0, 70, 48, 126, 20, 5000, 5, 2900, 85000, 10, 0, 0},
+ {2, 0, 100, 48, 160, 20, 5000, 25, 2900, 85000, 20, 0, 0},
+ {3, 2, 200, 20, 150, 900, 2200, 50, 1000, 999999999, 200, 0, 999999999},
+ }
+ },
+
+ {
+ NEW_DFS_JAP_W53,
+ {
+ {0, 0, 10, 8, 16, 8, 2000, 5, 28000, 85000, 10},
+ {1, 0, 32, 24, 64, 20, 2000, 5, 28000, 85000, 10},
+ {2, 0, 100, 42, 160, 20, 2000, 25, 28000, 85000, 10},
+ /*{3, 2, 200, 20, 150, 300, 2000, 50, 15000, 45000, 200},*/
+ }
+ },
+};
+
+static void dfs_sw_init(
+ IN PRTMP_ADAPTER pAd);
+
+static BOOLEAN StagerRadarCheck(
+ IN PRTMP_ADAPTER pAd,
+ UINT8 dfs_channel);
+
+static BOOLEAN ChirpRadarCheck(
+ IN PRTMP_ADAPTER pAd);
+
+static BOOLEAN DfsEventDataFetch(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ OUT PDFS_EVENT pDfsEvent);
+
+static VOID DfsCheckBusyIdle(
+ IN PRTMP_ADAPTER pAd);
+
+static BOOLEAN DfsChannelCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DfsChannel);
+
+static VOID ChannelSelectOnRadarDetection(
+ IN PRTMP_ADAPTER pAd);
+
+static BOOLEAN DfsEventDrop(
+ IN PRTMP_ADAPTER pAd,
+ IN PDFS_EVENT pDfsEvent);
+
+static inline BOOLEAN NewRadarDetectionMcuStart(PRTMP_ADAPTER pAd)
+{
+ /*
+ 8051 firmware don't care parameter Token, Arg0 and Arg1
+ */
+ return AsicSendCommandToMcu(pAd, DFS_ONOFF_MCU_CMD, 0xff, 0x01, 0x01, FALSE);
+}
+
+static inline BOOLEAN NewRadarDetectionMcuStop(PRTMP_ADAPTER pAd)
+{
+ /*
+ 8051 firmware don't care parameter Token, Arg0 and Arg1
+ */
+ return AsicSendCommandToMcu(pAd, DFS_ONOFF_MCU_CMD, 0xff, 0x01, 0x00, FALSE);
+}
+
+
+#ifdef RTMP_MAC_USB
+static VOID SwCheckDfsEventWithFw(
+ IN PRTMP_ADAPTER pAd);
+#endif /*RTMP_MAC_USB */
+
+/*
+ ========================================================================
+ Routine Description:
+ Radar wave detection. The API should be invoke each second.
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID ApRadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+
+ pAd->Dot11_H.InServiceMonitorCount++;
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].RemainingTimeForUse > 0)
+ {
+ pAd->ChannelList[i].RemainingTimeForUse --;
+ if ((pAd->Mlme.PeriodicRound%5) == 0)
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n",
+ pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
+ }
+ }
+ }
+ /*radar detect*/
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ RadarDetectPeriodic(pAd);
+ }
+ return;
+}
+
+
+/* 0 = Switch Channel when Radar Hit (Normal mode)
+ 1 = Don't Switch Channel when Radar Hit */
+INT Set_RadarDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ pRadarDetect->McuRadarDebug = simple_strtol(arg, 0, 16);
+
+ if (pRadarDetect->McuRadarDebug & RADAR_DONT_SWITCH)
+ printk("Dont Switch Channel\n");
+
+ if (pRadarDetect->McuRadarDebug & RADAR_DEBUG_SILENCE)
+ printk("Silence\n");
+
+ if (pRadarDetect->McuRadarDebug & RADAR_DEBUG_EVENT)
+ {
+ if (pRadarDetect->bDfsSwDisable == 1)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): Warning!! DfsSwDisable is 1\n", __FUNCTION__));
+ printk("Show effective event\n");
+ }
+
+ if (pRadarDetect->McuRadarDebug & RADAR_DEBUG_SW_SILENCE)
+ printk("SW detection Silence\n");
+ return TRUE;
+}
+
+INT Set_ResetRadarHwDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR channel = 0;
+#ifdef RT65xx
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ /* Reset status */
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R1, pRadarDetect->EnabledChMask);
+#else
+ /*Set BBP_R140=0x02 and Read BBP_R141 to store at channel */
+ RTMP_DFS_IO_READ8(pAd, 0x2, &channel);
+ /* reset the radar channel for new counting */
+ RTMP_DFS_IO_WRITE8(pAd, 0x2, channel);
+#endif
+ printk("==>reset the radar channel for new counting channel =0x%x\n",channel);
+ return TRUE;
+}
+
+
+INT Set_DfsLowerLimit_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ pRadarDetect->DfsLowerLimit = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_DfsUpperLimit_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ pRadarDetect->DfsUpperLimit = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+
+INT Set_DfsSwDisable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ pRadarDetect->bDfsSwDisable = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("pRadarDetect->bDfsSwDisable = %u\n", pRadarDetect->bDfsSwDisable));
+ return TRUE;
+}
+
+INT Set_DfsEnvtDropAdjTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->EvtDropAdjTime = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("EventDropAdjTime = %u\n", pDfsSwParam->EvtDropAdjTime));
+ return TRUE;
+}
+
+INT Set_RadarStart_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pAd->CommonCfg.RadarDetect.DfsProgramParam;
+
+ if (simple_strtol(arg, 0, 10) == 0)
+ {
+ NewRadarDetectionStart(pAd);
+ }
+ else if ((simple_strtol(arg, 0, 10) >= 1) && (simple_strtol(arg, 0, 10) <= pAd->CommonCfg.RadarDetect.EnabledChMask))
+ {
+ pDfsProgramParam->ChEnable = simple_strtol(arg, 0, 10);
+ printk("Ch Enable == 0x%x\n", pDfsProgramParam->ChEnable);
+ NewRadarDetectionStart(pAd);
+ }
+
+ return TRUE;
+}
+
+INT Set_RadarStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ NewRadarDetectionStop(pAd);
+ return TRUE;
+}
+
+
+INT Set_RadarSetTbl1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PUCHAR p2 = arg;
+ ULONG idx, value;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pAd->CommonCfg.RadarDetect.DfsProgramParam;
+
+ while((*p2 != ':') && (*p2 != '\0'))
+ {
+ p2++;
+ }
+
+ if (*p2 == ':')
+ {
+ A2Dec(idx, arg);
+ A2Dec(value, p2+ 1);
+ if (idx == 0)
+ {
+ pDfsProgramParam->DeltaDelay = value;
+ printk("Delta_Delay = %d\n", pDfsProgramParam->DeltaDelay);
+ }
+ else
+ modify_table1(pAd, idx, value);
+ NewRadarDetectionStart(pAd);
+ }
+ else
+ printk("please enter iwpriv ra0 set RadarT1=xxx:yyy\n");
+
+ return TRUE;
+}
+
+INT Set_RadarSetTbl2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PUCHAR p2 = arg;
+ ULONG idx, value;
+
+ while((*p2 != ':') && (*p2 != '\0'))
+ {
+ p2++;
+ }
+
+ if (*p2 == ':')
+ {
+ A2Dec(idx, arg);
+ A2Dec(value, p2+ 1);
+ modify_table2(pAd, idx, value);
+ }
+ else
+ printk("please enter iwpriv ra0 set RadarT2=xxx:yyy\n");
+
+ return TRUE;
+}
+
+
+INT Set_Fcc5Thrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->fcc_5_threshold = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_ChBusyThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int i;
+ PUCHAR p1 = arg, p2;
+ ULONG value;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ pRadarDetect->fdf_num = 0;
+ for (i = 0; i < MAX_FDF_NUMBER; i++)
+ {
+ p2 = p1;
+ while((*p2 != ':') && (*p2 != '\0'))
+ {
+ p2++;
+ }
+
+ if (*p2 == ':')
+ {
+ if (*p1 == '-')
+ {
+ p1++;
+ A2Dec(value, p1);
+ value *= -1;
+ }
+ else
+ A2Dec(value, p1);
+
+ pRadarDetect->ch_busy_threshold[i] = value;
+ printk("pRadarDetect->ch_busy_threshold[%d] = %d\n", i, pRadarDetect->ch_busy_threshold[i]);
+ pRadarDetect->fdf_num++;
+ p1 = p2 + 1;
+ }
+ else
+ {
+ pRadarDetect->ch_busy_threshold[i] = simple_strtol(p1, 0, 10);
+ printk("pRadarDetect->ch_busy_threshold[%d] = %d\n", i, pRadarDetect->ch_busy_threshold[i]);
+ pRadarDetect->fdf_num++;
+ break;
+ }
+ }
+ printk("pRadarDetect->fdf_num = %d\n", pRadarDetect->fdf_num);
+
+ return TRUE;
+}
+
+
+INT Set_RssiThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int i;
+ PUCHAR p1 = arg, p2;
+ ULONG value;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ pRadarDetect->fdf_num = 0;
+ for (i = 0; i < MAX_FDF_NUMBER; i++)
+ {
+ p2 = p1;
+ while((*p2 != ':') && (*p2 != '\0'))
+ {
+ p2++;
+ }
+
+ if (*p2 == ':')
+ {
+ if (*p1 == '-')
+ {
+ p1++;
+ A2Dec(value, p1);
+ value *= -1;
+ }
+ else
+ A2Dec(value, p1);
+
+ pRadarDetect->rssi_threshold[i] = value;
+ printk("pRadarDetect->rssi_threshold[%d] = %d\n", i, pRadarDetect->rssi_threshold[i]);
+ pRadarDetect->fdf_num++;
+ p1 = p2 + 1;
+ }
+ else
+ {
+ pRadarDetect->rssi_threshold[i] = simple_strtol(p1, 0, 10);
+ printk("pRadarDetect->rssi_threshold[%d] = %d\n", i, pRadarDetect->rssi_threshold[i]);
+ pRadarDetect->fdf_num++;
+ break;
+ }
+ }
+ printk("pRadarDetect->fdf_num = %d\n", pRadarDetect->fdf_num);
+
+ return TRUE;
+ pRadarDetect->rssi_threshold[0] = simple_strtol(arg, 0, 10);
+
+ return TRUE;
+}
+
+INT Set_PollTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ pRadarDetect->PollTime = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_Ch0LErr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_width_ch0_err_L = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_DeclareThres_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_declare_thres = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_CheckLoop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_check_loop = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_MaxPeriod_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_max_period = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_PeriodErr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_period_err = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_Ch0HErr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_width_ch0_err_H = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_Ch1Shift_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_width_diff_ch1_Shift = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_Ch2Shift_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ pDfsSwParam->dfs_width_diff_ch2_Shift = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+
+#ifdef DFS_DEBUG
+INT Set_CEPrintDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int i;
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+
+ if (simple_strtol(arg, 0, 10) == 0)
+ {
+ pDfsSwParam->DebugPortPrint = 1;
+ }
+
+ if (simple_strtol(arg, 0, 10) == 1)
+ {
+ if (pDfsSwParam->DebugPortPrint == 3)
+ {
+ for (i = 0; i < 384; i++)
+ {
+ printk("%02x ", pDfsSwParam->DebugPort[i]);
+ if (((i+1) % 18) == 0)
+ printk("\n");
+ }
+ pDfsSwParam->DebugPortPrint = 0;
+ }
+ }
+ return TRUE;
+}
+#endif /* DFS_DEBUG */
+
+
+INT Set_RadarSim_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+int i=0, id=0;
+int dfs_data[] = { 208, 142172,
+ 160, 260514,
+ 208, 363873,
+ 160, 482216,
+ 208, 585575,
+ 164, 703918,
+ 208, 807277,
+ 160, 925620,
+ 208, 1028979,
+ 164, 1147321};
+
+ pDfsSwParam->dfs_w_counter++;
+ for (i = 0; i < 10; i++)
+ {
+ pDfsSwParam->DFS_W[id][pDfsSwParam->dfs_w_idx[id]].counter = pDfsSwParam->dfs_w_counter;
+ pDfsSwParam->DFS_W[id][pDfsSwParam->dfs_w_idx[id]].timestamp = dfs_data[2*i+1];
+ pDfsSwParam->DFS_W[id][pDfsSwParam->dfs_w_idx[id]].width = dfs_data[2*i];
+ pDfsSwParam->dfs_w_last_idx[id] = pDfsSwParam->dfs_w_idx[id];
+ pDfsSwParam->dfs_w_idx[id]++;
+ if (pDfsSwParam->dfs_w_idx[id] >= NEW_DFS_DBG_PORT_ENT_NUM)
+ pDfsSwParam->dfs_w_idx[id] = 0;
+ }
+ pDfsSwParam->hw_idx[0] = pDfsSwParam->dfs_w_idx[0];
+ SWRadarCheck(pAd, 0);
+ return TRUE;
+}
+
+INT Set_PrintBusyIdle_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ pRadarDetect->print_ch_busy_sta = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_BusyIdleRatio_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ pRadarDetect->ch_busy_idle_ratio = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_DfsRssiHigh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ pRadarDetect->DfsRssiHigh = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+
+INT Set_DfsRssiLow_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ pRadarDetect->DfsRssiLow = simple_strtol(arg, 0, 10);
+ return TRUE;
+}
+INT Set_EventExpire_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pAd->CommonCfg.RadarDetect.DfsProgramParam;
+ UINT8 dfs_channel, bbp_val;
+ UINT32 EventExpiration = 0;
+ STRING StrBuf[64];
+ PSTRING SubStr = NULL;
+
+ strncpy(StrBuf, arg, 64);
+ if ((SubStr = strchr(StrBuf, '_')) != NULL)
+ {
+ *SubStr = '\0';
+ SubStr++;
+ EventExpiration = (UINT32) simple_strtol(SubStr, 0, 16);
+ dfs_channel = (UINT8) simple_strtol(StrBuf, 0, 16);
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("%s(): dfs_channel = %u, EventExpiration = 0x%08x\n",
+ __FUNCTION__, dfs_channel, EventExpiration));
+
+ pDfsProgramParam->RadarEventExpire[dfs_channel] = EventExpiration;
+
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, dfs_channel); /* disable DFS and select channel */
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R17, EventExpiration); /* set value */
+ /* Enable detection*/
+ bbp_val = (pDfsProgramParam->ChEnable << 16);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, bbp_val);
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("%s(): Input format Error. (should be <Channel>_<value>)\n", __FUNCTION__));
+ return 0;
+ }
+
+ return TRUE;
+}
+INT Set_CEPrint_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ int i, j, id = simple_strtol(arg, 0, 10);
+ int n = pDfsSwParam->dfs_w_last_idx[id];
+
+ if ((id >= 0) && (id <= 3))
+ {
+ printk("Last Idx = %d\n", n);
+ for (i = 0; i < NEW_DFS_DBG_PORT_ENT_NUM; i++)
+ {
+ printk("Cnt=%u, w= %u Time=%u\n", (unsigned int)(pDfsSwParam->DFS_W[id][i].counter),
+ pDfsSwParam->DFS_W[id][i].width,
+ (unsigned int)pDfsSwParam->DFS_W[id][i].timestamp);
+ if (pDfsSwParam->DFS_W[id][i].counter == 0)
+ break;
+ }
+ }
+
+ if ((id >= 10) && (id < 13))
+ {
+ id -= 10;
+ for (i = 0; i < NEW_DFS_MPERIOD_ENT_NUM; i++)
+ {
+ printk("T=%u, w1= %u(%u), w2= %u(%u)\n", (unsigned int)(pDfsSwParam->DFS_T[id][i].period),
+ pDfsSwParam->DFS_T[id][i].width, pDfsSwParam->DFS_T[id][i].idx,
+ pDfsSwParam->DFS_T[id][i].width2, pDfsSwParam->DFS_T[id][i].idx2);
+ if (pDfsSwParam->DFS_T[id][i].period == 0)
+ break;
+ }
+
+ }
+ if (id == 77)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < NEW_DFS_DBG_PORT_ENT_NUM; j++)
+ {
+ pDfsSwParam->DFS_W[i][j].counter = 0;
+ pDfsSwParam->DFS_W[i][j].width = 0;
+ pDfsSwParam->DFS_W[i][j].timestamp = 0;
+ }
+ for (j = 0; j < NEW_DFS_MPERIOD_ENT_NUM; j++)
+ {
+ pDfsSwParam->DFS_T[i][j].period = 0;
+ pDfsSwParam->DFS_T[i][j].width = 0;
+ pDfsSwParam->DFS_T[i][j].width2 = 0;
+ pDfsSwParam->DFS_T[i][j].idx = 0;
+ pDfsSwParam->DFS_T[i][j].idx2 = 0;
+ }
+ }
+ }
+#ifdef DFS_DEBUG
+ if (id > 20)
+ {
+ pDfsSwParam->BBP127Repeat = id - 20;
+ }
+
+ if (id == 5)
+ {
+
+ for (i = 0; i < NEW_DFS_DBG_PORT_ENT_NUM; i++)
+ {
+ printk("Cnt=%u, w= %u Time=%lu, start_idx = %u end_idx = %u\n", (unsigned int)(pDfsSwParam->CE_DebugCh0[i].counter),
+ (unsigned int)pDfsSwParam->CE_DebugCh0[i].width, pDfsSwParam->CE_DebugCh0[i].timestamp,
+ pDfsSwParam->CE_DebugCh0[i].start_idx, pDfsSwParam->CE_DebugCh0[i].end_idx);
+ }
+
+ for (i = 0; i < NEW_DFS_MPERIOD_ENT_NUM; i++)
+ {
+ printk("T=%lu, w1= %u(%u), w2= %u(%u)\n", (pDfsSwParam->CE_TCh0[i].period),
+ pDfsSwParam->CE_TCh0[i].width, pDfsSwParam->CE_TCh0[i].idx,
+ pDfsSwParam->CE_TCh0[i].width2, pDfsSwParam->CE_TCh0[i].idx2);
+ }
+
+ }
+#endif /* DFS_DEBUG */
+
+ return TRUE;
+}
+
+
+INT Set_RfReg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+
+ printk("1 %x\n", pAd->LatchRfRegs.R1);
+ printk("2 %x\n", pAd->LatchRfRegs.R2);
+ printk("3 %x\n", pAd->LatchRfRegs.R3);
+ printk("4 %x\n", pAd->LatchRfRegs.R4);
+ return TRUE;
+}
+
+INT Show_BlockCh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int i;
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].RemainingTimeForUse != 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Ch%d: RemainingTimeForUse:%d sec;\n",
+ pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
+ }
+ }
+ return TRUE;
+}
+
+
+VOID DFSInit(PRTMP_ADAPTER pAd)
+{
+ INT i;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pRadarDetect->DfsProgramParam;
+
+ pRadarDetect->ch_busy_countdown = -1;
+ pRadarDetect->EnabledChMask = ((1 << pAd->chipCap.DfsEngineNum) -1);
+ pRadarDetect->PollTime = 3;
+ pRadarDetect->DfsRssiHigh = -30;
+ pRadarDetect->DfsRssiLow = -90;
+ pRadarDetect->DFSWatchDogIsRunning=FALSE;
+ pRadarDetect->use_tasklet = 1;
+ pRadarDetect->McuRadarDebug = RADAR_DONT_SWITCH; //snowpin test 0;
+ pRadarDetect->radarDeclared = 0;
+ pRadarDetect->dfs_func = HARDWARE_DFS_V2;
+ pDfsProgramParam->DeltaDelay = 0x3;
+ pDfsProgramParam->ChEnable = pRadarDetect->EnabledChMask;
+ for (i=0; i < pAd->chipCap.DfsEngineNum; i++)
+ {
+ if ((i == 3) &&
+ (pAd->CommonCfg.RDDurRegion == FCC || pAd->CommonCfg.RDDurRegion == JAP))
+ pDfsProgramParam->RadarEventExpire[i] = 0x10000000; /* for Chirp Radar */
+ else
+ pDfsProgramParam->RadarEventExpire[i] = 0x1000000;
+ }
+ /*pDfsProgramParam->RadarEventExpire[0] = 0x1000000;*/
+ /*pDfsProgramParam->RadarEventExpire[3] = 0x99999999;*/
+ pDfsProgramParam->Symmetric_Round = 1;
+ pDfsProgramParam->VGA_Mask = 45;
+ pDfsProgramParam->Packet_End_Mask = 45;
+ pDfsProgramParam->Rx_PE_Mask = 45;
+
+ /*pAd->CommonCfg.ce_sw_check = CE_SW_CHECK;*/
+ /*pDfsSwParam->ce_sw_id_check = 0;*/
+ /*pDfsSwParam->ce_sw_t_diff = 14;*/
+
+ /* from dfs_mcu.c, one time init */
+ dfs_sw_init(pAd);
+
+}
+
+void NewRadarDetectionStart(PRTMP_ADAPTER pAd)
+{
+ pNewDFSTable pDFS2Table;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ /*PDFS_PROGRAM_PARAM pDfsProgramParam = &pRadarDetect->DfsProgramParam;*/
+
+ pRadarDetect->bDfsInit = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->NewRadarDetectionStart()\n"));
+
+ DFSInit(pAd);
+
+#ifdef RTMP_MAC_USB
+ INIT_DFS_EVENT_BUFF_SHARED_MEMORY(pAd, BBPR127TABLE_OFFSET, 8, 0xfe);
+#endif /* RTMP_MAC_USB */
+
+ RTMP_CHIP_RADAR_GLRT_COMPENSATE(pAd);
+
+ if ((pAd->CommonCfg.RDDurRegion == CE) && RESTRICTION_BAND_1(pAd))
+ pAd->Dot11_H.ChMovingTime = 605;
+ else
+ pAd->Dot11_H.ChMovingTime = 65;
+
+ if (pAd->CommonCfg.RDDurRegion == FCC)
+ {
+ if (pRadarDetect->ch_busy_idle_ratio == 0)
+ pRadarDetect->ch_busy_idle_ratio = 2;
+
+ pDFS2Table = &NewDFSTable1[0];
+ DBGPRINT(RT_DEBUG_TRACE,("DFS start, use FCC table\n"));
+ }
+ else if (pAd->CommonCfg.RDDurRegion == CE)
+ {
+ if (pRadarDetect->ch_busy_idle_ratio == 0)
+ pRadarDetect->ch_busy_idle_ratio = 3;
+
+ pDFS2Table = &NewDFSTable1[1];
+ DBGPRINT(RT_DEBUG_TRACE,("DFS start, use CE table\n"));
+ }
+ else /* JAP*/
+ {
+
+ if ((pAd->CommonCfg.Channel >= 52) && (pAd->CommonCfg.Channel <= 64))
+ {
+ pDFS2Table = &NewDFSTable1[3];
+
+ if (pRadarDetect->ch_busy_idle_ratio == 0)
+ pRadarDetect->ch_busy_idle_ratio = 3;
+ }
+ else
+ {
+ pDFS2Table = &NewDFSTable1[2];
+ /*pDfsProgramParam->Symmetric_Round = 1;*/
+
+ if (pRadarDetect->ch_busy_idle_ratio == 0)
+ pRadarDetect->ch_busy_idle_ratio = 2;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("DFS start, use JAP table\n"));
+ }
+
+ NewRadarDetectionProgram(pAd, pDFS2Table);
+
+ /*the usage of dfs_sw_init*/
+ /*dfs_sw_init(pAd);*/
+
+#ifdef RTMP_MAC_USB
+ if (NewRadarDetectionMcuStart(pAd) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("NewRadarDetectionMcuStart failed.\n"));
+ }
+#endif /* RTMP_MAC_USB */
+ pRadarDetect->bDfsInit = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE,("Poll Time=%d\n", pRadarDetect->PollTime));
+}
+
+VOID NewRadarDetectionStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NewRadarDetectionStop\n"));
+
+ /* set init bit = false to prevent dfs rotines */
+ pRadarDetect->bDfsInit = FALSE;
+ pRadarDetect->radarDeclared = 0;
+
+#ifdef RT65xx
+ /* Disable detection*/
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, 0);
+
+ /* Clear status */
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R1, pRadarDetect->EnabledChMask);
+#else
+ /* Disable detection*/
+ RTMP_DFS_IO_WRITE8(pAd, 0x1, 0);
+
+ /* Clear Status */
+ RTMP_DFS_IO_WRITE8(pAd, 0x2, pRadarDetect->EnabledChMask);
+#endif
+
+#ifdef RTMP_MAC_USB
+ if (NewRadarDetectionMcuStop(pAd) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("NewRadarDetectionMcuStop failed.\n"));
+ }
+#endif /* RTMP_MAC_USB */
+
+}
+
+
+/* the debug port have timestamp 22 digit, the max number is 0x3fffff, each unit is 25ns for 40Mhz mode and 50ns for 20Mhz mode*/
+/* so a round of timestamp is about 25 * 0x3fffff / 1000 = 104857us (about 100ms) or*/
+/* 50 * 0x3fffff / 1000 = 209715us (about 200ms) in 20Mhz mode*/
+/* 3ms = 3000,000 ns / 25ns = 120000 -- a unit */
+/* 0x3fffff/120000 = 34.9 ~= 35*/
+/* CE Staggered radar check*/
+/* At beginning, the goal is to detect staggered radar, now, we also detect regular radar with this function.*/
+
+
+int SWRadarCheck(
+ IN PRTMP_ADAPTER pAd, USHORT id)
+{
+ int i, j, start_idx, end_idx;
+ pNewDFSDebugPort pCurrent, p1, pEnd;
+ ULONG period;
+ int radar_detected = 0;
+ USHORT widthsum;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pRadarDetect->DfsSwParam;
+ /*ENTRY_PLUS could be replace by (pDfsSwParam->sw_idx[id]+1)%128*/
+ USHORT Total, SwIdxPlus = ENTRY_PLUS(pDfsSwParam->sw_idx[id], 1, NEW_DFS_DBG_PORT_ENT_NUM);
+ UCHAR CounterToCheck;
+
+ if (!DFS_CHECK_FLAGS(pAd, pRadarDetect) ||
+ (SwIdxPlus == pDfsSwParam->hw_idx[id])) /* no entry to process*/
+ return 0;
+
+ /* process how many entries?? total NEW_DFS_DBG_PORT_ENT_NUM*/
+ if (pDfsSwParam->hw_idx[id] > SwIdxPlus)
+ Total = pDfsSwParam->hw_idx[id] - SwIdxPlus;
+ else
+ Total = pDfsSwParam->hw_idx[id] + NEW_DFS_DBG_PORT_ENT_NUM - SwIdxPlus;
+
+ if (Total > NEW_DFS_DBG_PORT_ENT_NUM)
+ pDfsSwParam->pr_idx[id] = ENTRY_PLUS(pDfsSwParam->sw_idx[id], MAX_PROCESS_ENTRY, NEW_DFS_DBG_PORT_ENT_NUM);
+ else
+ pDfsSwParam->pr_idx[id] = ENTRY_PLUS(pDfsSwParam->sw_idx[id], Total, NEW_DFS_DBG_PORT_ENT_NUM);
+
+
+ start_idx = ENTRY_PLUS(pDfsSwParam->pr_idx[id], 1, NEW_DFS_DBG_PORT_ENT_NUM);
+ end_idx = pDfsSwParam->pr_idx[id];
+
+ pEnd = &pDfsSwParam->DFS_W[id][end_idx];
+ /*printk("start_idx = %d, end_idx=%d, counter=%d\n", start_idx, end_idx, pEnd->counter);*/
+
+ /*if (pDfsSwParam->dfs_w_counter != pEnd->counter)*/
+ /* return 0;*/
+
+ if (start_idx > end_idx)
+ end_idx += NEW_DFS_DBG_PORT_ENT_NUM;
+
+
+ pDfsSwParam->sw_idx[id] = pDfsSwParam->pr_idx[id];
+
+ /* FCC && Japan*/
+
+ if (pAd->CommonCfg.RDDurRegion != CE)
+ {
+ ULONG minPeriod = (3000 << 1);
+ /* Calculate how many counters to check*/
+ /* if pRadarDetect->PollTime is 1ms, a round of timestamp is 107 for 20Mhz, 53 for 40Mhz*/
+ /* if pRadarDetect->PollTime is 2ms, a round of timestamp is 71 for 20Mhz, 35 for 40Mhz*/
+ /* if pRadarDetect->PollTime is 3ms, a round of timestamp is 53 for 20Mhz, 27 for 40Mhz*/
+ /* if pRadarDetect->PollTime is 4ms, a round of timestamp is 43 for 20Mhz, 21 for 40Mhz*/
+ /* the max period to check for 40Mhz for FCC is 28650 * 2*/
+ /* the max period to check for 40Mhz for Japan is 80000 * 2*/
+ /* 0x40000 = 4194304 / 57129 = 73.xxx*/
+ /* 0x40000 = 4194304 / 160000 = 26.2144*/
+ /* 53/73 < 1 (1+1)*/
+ /* 53/26.2144 = 2.02... (2+1)*/
+ /* 27/26.2144 = 1.02... (1+1)*/
+ /* 20M should use the same value as 40Mhz mode*/
+
+
+ if (pRadarDetect->MCURadarRegion == NEW_DFS_JAP_W53)
+ {
+ minPeriod = 28500 << 1;
+ }
+
+
+ if (pAd->CommonCfg.RDDurRegion == FCC)
+ {
+ CounterToCheck = 1+1;
+ }
+ else /* if (pAd->CommonCfg.RDDurRegion == JAP)*/
+ {
+ if (pRadarDetect->PollTime <= 2)
+ CounterToCheck = 2+1;
+ else
+ CounterToCheck = 1+1;
+ }
+
+
+
+ /* First Loop for FCC/JAP*/
+ for (i = end_idx; i > start_idx; i--)
+ {
+ pCurrent = &pDfsSwParam->DFS_W[id][i & NEW_DFS_DBG_PORT_MASK];
+
+ /* we only handle entries has same counter with the last one*/
+ if (pCurrent->counter != pEnd->counter)
+ break;
+
+ pCurrent->start_idx = 0xffff;
+
+ /* calculate if any two pulse become a valid period, add it in period table,*/
+ for (j = i - 1; j > start_idx; j--)
+ {
+ p1 = &pDfsSwParam->DFS_W[id][j & NEW_DFS_DBG_PORT_MASK];
+
+ /* check period, must within max period*/
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ {
+ if (p1->counter + CounterToCheck < pCurrent->counter)
+ break;
+
+ widthsum = p1->width + pCurrent->width;
+ if (id == 0)
+ {
+ if (widthsum < 600)
+ pDfsSwParam->dfs_width_diff = pDfsSwParam->dfs_width_ch0_err_L;
+ else
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch2_Shift;
+ }
+ else if (id == 1)
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch1_Shift;
+ else if (id == 2)
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch2_Shift;
+
+ if ( (pAd->Dot11_H.RDMode == RD_SILENCE_MODE) ||
+ (PERIOD_MATCH(p1->width, pCurrent->width, pDfsSwParam->dfs_width_diff)) )
+ {
+ if (p1->timestamp >= pCurrent->timestamp)
+ period = 0x400000 + pCurrent->timestamp - p1->timestamp;
+ else
+ period = pCurrent->timestamp - p1->timestamp;
+
+ if ((period >= (minPeriod - 2)) && (period <= pDfsSwParam->dfs_max_period))
+ {
+
+ /* add in period table*/
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx = (i & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width = pCurrent->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx2 = (j & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width2 = p1->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].period = period;
+
+
+ if (pCurrent->start_idx == 0xffff)
+ pCurrent->start_idx = pDfsSwParam->dfs_t_idx[id];
+ pCurrent->end_idx = pDfsSwParam->dfs_t_idx[id];
+
+ pDfsSwParam->dfs_t_idx[id]++;
+ if (pDfsSwParam->dfs_t_idx[id] >= NEW_DFS_MPERIOD_ENT_NUM)
+ pDfsSwParam->dfs_t_idx[id] = 0;
+ }
+ else if (period > pDfsSwParam->dfs_max_period)
+ break;
+ }
+
+ }
+ else
+ {
+ if (p1->counter + CounterToCheck < pCurrent->counter)
+ break;
+
+ widthsum = p1->width + pCurrent->width;
+ if (id == 0)
+ {
+ if (widthsum < 600)
+ pDfsSwParam->dfs_width_diff = pDfsSwParam->dfs_width_ch0_err_L;
+ else
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch2_Shift;
+ }
+ else if (id == 1)
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch1_Shift;
+ else if (id == 2)
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch2_Shift;
+
+
+ if ( (pAd->Dot11_H.RDMode == RD_SILENCE_MODE) ||
+ (PERIOD_MATCH(p1->width, pCurrent->width, pDfsSwParam->dfs_width_diff)) )
+
+ {
+ if (p1->timestamp >= pCurrent->timestamp)
+ period = 0x400000 + pCurrent->timestamp - p1->timestamp;
+ else
+ period = pCurrent->timestamp - p1->timestamp;
+
+ if ((period >= ((minPeriod >> 1) - 2)) && (period <= (pDfsSwParam->dfs_max_period >> 1)))
+ {
+ /* add in period table*/
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx = (i & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width = pCurrent->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx2 = (j & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width2 = p1->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].period = period;
+
+ if (pCurrent->start_idx == 0xffff)
+ pCurrent->start_idx = pDfsSwParam->dfs_t_idx[id];
+ pCurrent->end_idx = pDfsSwParam->dfs_t_idx[id];
+
+ pDfsSwParam->dfs_t_idx[id]++;
+ if (pDfsSwParam->dfs_t_idx[id] >= NEW_DFS_MPERIOD_ENT_NUM)
+ pDfsSwParam->dfs_t_idx[id] = 0;
+ }
+ else if (period > (pDfsSwParam->dfs_max_period >> 1))
+ break;
+ }
+ }
+
+ } /* for (j = i - 1; j > start_idx; j--)*/
+
+ } /* for (i = end_idx; i > start_idx; i--)*/
+
+
+ /* Second Loop for FCC/JAP*/
+ for (i = end_idx; i > start_idx; i--)
+ {
+
+ pCurrent = &pDfsSwParam->DFS_W[id][i & NEW_DFS_DBG_PORT_MASK];
+
+ /* we only handle entries has same counter with the last one*/
+ if (pCurrent->counter != pEnd->counter)
+ break;
+ if (pCurrent->start_idx != 0xffff)
+ {
+ /*pNewDFSDebugPort p2, p3, p4, p5, p6;*/
+ pNewDFSDebugPort p2, p3;
+ pNewDFSMPeriod pCE_T;
+ ULONG idx[10], T[10];
+
+ for (idx[0] = pCurrent->start_idx; idx[0] <= pCurrent->end_idx; idx[0]++)
+ {
+
+ pCE_T = &pDfsSwParam->DFS_T[id][idx[0]];
+
+ p2 = &pDfsSwParam->DFS_W[id][pCE_T->idx2];
+
+ if (p2->start_idx == 0xffff)
+ continue;
+
+ T[0] = pCE_T->period;
+
+
+ for (idx[1] = p2->start_idx; idx[1] <= p2->end_idx; idx[1]++)
+ {
+
+ pCE_T = &pDfsSwParam->DFS_T[id][idx[1]];
+
+ p3 = &pDfsSwParam->DFS_W[id][pCE_T->idx2];
+
+ if (idx[0] == idx[1])
+ continue;
+
+ if (p3->start_idx == 0xffff)
+ continue;
+
+
+
+ T[1] = pCE_T->period;
+
+
+ if ( PERIOD_MATCH(T[0], T[1], pDfsSwParam->dfs_period_err))
+ {
+ if (id <= 2) /* && (id >= 0)*/
+ {
+
+ /*if (((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (T[1] > minPeriod)) ||*/
+ /* ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_20) && (T[1] > (minPeriod >> 1))) )*/
+ {
+ unsigned int loop, PeriodMatched = 0, idx1;
+ for (loop = 1; loop < pDfsSwParam->dfs_check_loop; loop++)
+ {
+ idx1 = (idx[1] >= loop)? (idx[1] - loop): (NEW_DFS_MPERIOD_ENT_NUM + idx[1] - loop);
+ if (PERIOD_MATCH(pDfsSwParam->DFS_T[id][idx1].period, T[1], pDfsSwParam->dfs_period_err))
+ {
+#ifdef DFS_DEBUG
+ if (PeriodMatched < 5)
+ {
+ pDfsSwParam->CounterStored[PeriodMatched] = pDfsSwParam->DFS_W[id][pDfsSwParam->DFS_T[id][idx1].idx].counter;
+ pDfsSwParam->CounterStored2[PeriodMatched] = loop;
+ pDfsSwParam->CounterStored3 = idx[1];
+ }
+#endif
+ /*printk("%d %d\n", loop, pDfsSwParam->DFS_T[id][idx[1]-loop].period);*/
+ PeriodMatched++;
+ }
+
+ }
+
+
+ if (PeriodMatched > pDfsSwParam->dfs_declare_thres)
+ {
+#ifdef DFS_DEBUG
+ if (PeriodMatched == 3)
+ {
+ pDfsSwParam->T_Matched_3++;
+ /*printk("counter=%d %d %d\n", pDfsSwParam->CounterStored[0], pDfsSwParam->CounterStored[1], pDfsSwParam->CounterStored[2]);*/
+ /*printk("idx[1]=%d, loop =%d %d %d\n", pDfsSwParam->CounterStored3, pDfsSwParam->CounterStored2[0], pDfsSwParam->CounterStored2[1], pDfsSwParam->CounterStored2[2]);*/
+ }
+ else if (PeriodMatched == 4)
+ {
+ pDfsSwParam->T_Matched_4++;
+ /*printk("counter=%d %d %d %d\n", pDfsSwParam->CounterStored[0], pDfsSwParam->CounterStored[1], pDfsSwParam->CounterStored[2], pDfsSwParam->CounterStored[3]);*/
+ /*printk("idx[1]=%d, loop =%d %d %d %d\n", pDfsSwParam->CounterStored3, pDfsSwParam->CounterStored2[0], pDfsSwParam->CounterStored2[1], pDfsSwParam->CounterStored2[2], pDfsSwParam->CounterStored2[3]);*/
+ }
+ else
+ {
+ pDfsSwParam->T_Matched_5++;
+ /*printk("counter=%d %d %d %d %d\n", pDfsSwParam->CounterStored[0], pDfsSwParam->CounterStored[1], pDfsSwParam->CounterStored[2], pDfsSwParam->CounterStored[3], pDfsSwParam->CounterStored[4]);*/
+ /*printk("idx[1]=%d, loop =%d %d %d %d %d\n", pDfsSwParam->CounterStored3, pDfsSwParam->CounterStored2[0], pDfsSwParam->CounterStored2[1], pDfsSwParam->CounterStored2[2], pDfsSwParam->CounterStored2[3], pDfsSwParam->CounterStored2[4]);*/
+ }
+
+ pDfsSwParam->DebugPortPrint = 1;
+
+#endif
+
+ {
+ pNewDFSValidRadar pDFSValidRadar;
+ ULONG T1 = (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)? (T[1]>>1) : T[1];
+
+ pDFSValidRadar = &NewDFSValidTable[0];
+
+
+ while (pDFSValidRadar->type != NEW_DFS_END)
+ {
+ if ((pDFSValidRadar->type & pRadarDetect->MCURadarRegion) == 0)
+ {
+ pDFSValidRadar++;
+ continue;
+ }
+
+ if (pDFSValidRadar->TLow)
+ {
+ if ( (T1 > (pDFSValidRadar->TLow - pDFSValidRadar->TMargin)) &&
+ (T1 < (pDFSValidRadar->THigh + pDFSValidRadar->TMargin)) )
+ {
+ radar_detected = 1;
+ }
+ }
+ else
+ {
+ if ( (T1 > (pDFSValidRadar->T - pDFSValidRadar->TMargin)) &&
+ (T1 < (pDFSValidRadar->T + pDFSValidRadar->TMargin)) )
+ {
+ radar_detected = 1;
+ break;
+ }
+ }
+
+ pDFSValidRadar++;
+ }
+ if (radar_detected == 1)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("W=%d, T=%d (%d), period matched=%d\n", (unsigned int)pCE_T->width, (unsigned int)T1, (unsigned int)id, PeriodMatched));
+ printk("SWRadarCheck: Radar Detected\n");
+ return radar_detected;
+ }
+ else if (pRadarDetect->MCURadarRegion != NEW_DFS_JAP_W53)
+ DBGPRINT(RT_DEBUG_TRACE, ("W=%d, T=%d (%d), period matched=%d\n", (unsigned int)pCE_T->width, (unsigned int)T1, (unsigned int)id, PeriodMatched));
+
+ }
+
+
+ }
+#ifdef DFS_DEBUG
+ else if (PeriodMatched == 2)
+ {
+ pDfsSwParam->T_Matched_2++;
+ }
+#endif
+
+
+ }
+
+ } /* if (id <= 2) && (id >= 0)*/
+
+ }
+
+ } /* for (idx[1] = p2->start_idx; idx[1] <= p2->end_idx; idx[1]++)*/
+
+
+ /* increase FCC-1 detection*/
+ if (id <= 2)
+ {
+ if (IS_FCC_RADAR_1((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40), T[0]))
+ {
+ int loop, idx1, PeriodMatched_fcc1 = 0;
+ for (loop = 1; loop < pDfsSwParam->dfs_check_loop; loop++)
+ {
+ idx1 = (idx[0] >= loop)? (idx[0] - loop): (NEW_DFS_MPERIOD_ENT_NUM + idx[0] - loop);
+ if ( IS_FCC_RADAR_1((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40), pDfsSwParam->DFS_T[id][idx1].period) )
+ {
+ /*printk("%d %d %d\n", PeriodMatched_fcc1, pDfsSwParam->DFS_T[id][idx1].period, loop);*/
+ PeriodMatched_fcc1++;
+ }
+ }
+
+ if (PeriodMatched_fcc1 > 3)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeriodMatched_fcc1 = %d (%d)\n", PeriodMatched_fcc1, id));
+ radar_detected = 1;
+ return radar_detected;
+ }
+
+ }
+
+ }
+
+
+ /* increase W56-3 detection*/
+ if ((pRadarDetect->MCURadarRegion == NEW_DFS_JAP) && (id <= 2))
+ {
+ if (IS_W56_RADAR_3((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40), T[0]))
+ {
+ int loop, idx1, PeriodMatched_w56_3 = 0;
+ for (loop = 1; loop < pDfsSwParam->dfs_check_loop; loop++)
+ {
+ idx1 = (idx[0] >= loop)? (idx[0] - loop): (NEW_DFS_MPERIOD_ENT_NUM + idx[0] - loop);
+ if ( IS_W56_RADAR_3((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40), pDfsSwParam->DFS_T[id][idx1].period) )
+ {
+ /*printk("%d %d %d\n", PeriodMatched_w56_3, pDfsSwParam->DFS_T[id][idx1].period, loop);*/
+ PeriodMatched_w56_3++;
+ }
+ }
+
+ if (PeriodMatched_w56_3 > 3)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeriodMatched_w56_3 = %d (%d)\n", PeriodMatched_w56_3, id));
+ radar_detected = 1;
+ return radar_detected;
+ }
+
+ }
+
+ }
+
+
+ if ((pRadarDetect->MCURadarRegion == NEW_DFS_JAP_W53) && (id <= 2) && IS_W53_RADAR_2((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40), T[0]))
+ {
+ int loop, idx1, PeriodMatched_W56_2 = 0;
+
+ for (loop = 1; loop < pDfsSwParam->dfs_check_loop; loop++)
+ {
+ idx1 = (idx[0] >= loop)? (idx[0] - loop): (NEW_DFS_MPERIOD_ENT_NUM + idx[0] - loop);
+ if ( IS_W53_RADAR_2((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40), pDfsSwParam->DFS_T[id][idx1].period) )
+ {
+ /*printk("%d %d %d\n", PeriodMatched_W56_2, pDfsSwParam->DFS_T[id][idx1].period, loop);*/
+ PeriodMatched_W56_2++;
+ }
+ }
+
+ if (PeriodMatched_W56_2 >= 3)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeriodMatched_W56_2 = %d(%d)\n", PeriodMatched_W56_2, id));
+ radar_detected = 1;
+ return radar_detected;
+ }
+ }
+
+
+
+ } /* for (idx[0] = pCurrent->start_idx; idx[0] <= pCurrent->end_idx; idx[0]++)*/
+ } /* if (pCurrent->start_idx != 0xffff)*/
+ } /* for (i = end_idx; i > start_idx; i--)*/
+
+ return radar_detected;
+ }
+
+ /* CE have staggered radar */
+
+ /* Calculate how many counters to check*/
+ /* if pRadarDetect->PollTime is 1ms, a round of timestamp is 107 for 20Mhz, 53 for 40Mhz*/
+ /* if pRadarDetect->PollTime is 2ms, a round of timestamp is 71 for 20Mhz, 35 for 40Mhz*/
+ /* if pRadarDetect->PollTime is 3ms, a round of timestamp is 53 for 20Mhz, 27 for 40Mhz*/
+ /* if pRadarDetect->PollTime is 4ms, a round of timestamp is 43 for 20Mhz, 21 for 40Mhz*/
+ /* if pRadarDetect->PollTime is 8ms, a round of timestamp is ?? for 20Mhz, 12 for 40Mhz*/
+ /* the max period to check for 40Mhz is 133333 + 125000 + 117647 = 375980*/
+ /* 0x40000 = 4194304 / 375980 = 11.1556*/
+ /* 53/11.1556 = 4.75...*/
+ /* 35/11.1556 = 3.1374, (4+1) is safe, (3+1) to save CPU power, but may lost some data*/
+ /* 27/11.1556 = 2.42, (3+1) is OK*/
+ /* 21/11.1556 = 1.88, (2+1) is OK*/
+ /* 20M should use the same value as 40Mhz mode*/
+ if (pRadarDetect->PollTime == 1)
+ CounterToCheck = 5+1;
+ else if (pRadarDetect->PollTime == 2)
+ CounterToCheck = 4+1;
+ else if (pRadarDetect->PollTime == 3)
+ CounterToCheck = 3+1;
+ else if (pRadarDetect->PollTime <= 8)
+ CounterToCheck = 2+1;
+ else
+ CounterToCheck = 1+1;
+
+ /* First Loop for CE*/
+ for (i = end_idx; i > start_idx; i--)
+ {
+ pCurrent = &pDfsSwParam->DFS_W[id][i & NEW_DFS_DBG_PORT_MASK];
+
+ /* we only handle entries has same counter with the last one*/
+ if (pCurrent->counter != pEnd->counter)
+ break;
+
+ pCurrent->start_idx = 0xffff;
+
+ /* calculate if any two pulse become a valid period, add it in period table,*/
+ for (j = i - 1; j > start_idx; j--)
+ {
+ p1 = &pDfsSwParam->DFS_W[id][j & NEW_DFS_DBG_PORT_MASK];
+
+
+ /* check period, must within 16666 ~ 66666*/
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ {
+ if (p1->counter + CounterToCheck < pCurrent->counter)
+ break;
+
+ widthsum = p1->width + pCurrent->width;
+ if (id == 0)
+ {
+ if (((p1->width > 310) && (pCurrent->width < 300)) || ((pCurrent->width > 310) && ((p1->width < 300))) )
+ continue;
+ if (widthsum < 620)
+ pDfsSwParam->dfs_width_diff = pDfsSwParam->dfs_width_ch0_err_H;
+ else
+ pDfsSwParam->dfs_width_diff = pDfsSwParam->dfs_width_ch0_err_L;
+
+ }
+ else if (id == 1)
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch1_Shift;
+ else if (id == 2)
+ pDfsSwParam->dfs_width_diff = widthsum >> pDfsSwParam->dfs_width_diff_ch2_Shift;
+
+ if ( (pAd->Dot11_H.RDMode == RD_SILENCE_MODE) ||
+ (PERIOD_MATCH(p1->width, pCurrent->width, pDfsSwParam->dfs_width_diff)) )
+ {
+ if (p1->timestamp >= pCurrent->timestamp)
+ period = 0x400000 + pCurrent->timestamp - p1->timestamp;
+ else
+ period = pCurrent->timestamp - p1->timestamp;
+
+ /*if ((period >= (33333 - 20)) && (period <= (133333 + 20)))*/
+ if ((period >= (33333 - 20)) && (period <= pDfsSwParam->dfs_max_period))
+ //if ((period >= (10000 - 2)) && (period <= pDfsSwParam->dfs_max_period))
+ {
+
+ /* add in period table*/
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx = (i & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width = pCurrent->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx2 = (j & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width2 = p1->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].period = period;
+
+
+ if (pCurrent->start_idx == 0xffff)
+ pCurrent->start_idx = pDfsSwParam->dfs_t_idx[id];
+ pCurrent->end_idx = pDfsSwParam->dfs_t_idx[id];
+
+ pDfsSwParam->dfs_t_idx[id]++;
+ if (pDfsSwParam->dfs_t_idx[id] >= NEW_DFS_MPERIOD_ENT_NUM)
+ pDfsSwParam->dfs_t_idx[id] = 0;
+ }
+ else if (period > pDfsSwParam->dfs_max_period) /* to allow miss a pulse*/
+ break;
+ }
+
+ }
+ else
+ {
+ if (p1->counter + CounterToCheck < pCurrent->counter)
+ break;
+
+ widthsum = p1->width + pCurrent->width;
+ if (id == 0)
+ {
+ if (((p1->width > 300) && (pCurrent->width < 300)) || ((pCurrent->width > 300) && ((p1->width < 300))) )
+ continue;
+ if (widthsum < 620)
+ pDfsSwParam->dfs_width_diff = pDfsSwParam->dfs_width_ch0_err_H;
+ else
+ pDfsSwParam->dfs_width_diff = pDfsSwParam->dfs_width_ch0_err_L;
+ }
+ else if (id == 1)
+ {
+ pDfsSwParam->dfs_width_diff = widthsum >> 3; /* for 20M verified */
+ //printk("dfs_width_diff = %u\n",pDfsSwParam->dfs_width_diff);
+ }
+ else if (id == 2)
+ pDfsSwParam->dfs_width_diff = widthsum >> 6;
+
+ if ( (pAd->Dot11_H.RDMode == RD_SILENCE_MODE) ||
+ (PERIOD_MATCH(p1->width, pCurrent->width, pDfsSwParam->dfs_width_diff)) )
+
+ {
+ if (p1->timestamp >= pCurrent->timestamp)
+ period = 0x400000 + pCurrent->timestamp - p1->timestamp;
+ else
+ period = pCurrent->timestamp - p1->timestamp;
+
+ //if ((period >= (5000 - 2)) && (period <= (pDfsSwParam->dfs_max_period >> 1)))
+ if ((period >= (16666 - 20)) && (period <= (pDfsSwParam->dfs_max_period >> 1)))//neil modify for ce 5-1
+ {
+ /* add in period table*/
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx = (i & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width = pCurrent->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].idx2 = (j & NEW_DFS_DBG_PORT_MASK);
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].width2 = p1->width;
+ pDfsSwParam->DFS_T[id][pDfsSwParam->dfs_t_idx[id]].period = period;
+
+ if (pCurrent->start_idx == 0xffff)
+ pCurrent->start_idx = pDfsSwParam->dfs_t_idx[id];
+ pCurrent->end_idx = pDfsSwParam->dfs_t_idx[id];
+
+ pDfsSwParam->dfs_t_idx[id]++;
+ if (pDfsSwParam->dfs_t_idx[id] >= NEW_DFS_MPERIOD_ENT_NUM)
+ pDfsSwParam->dfs_t_idx[id] = 0;
+ }
+ else if (period > (pDfsSwParam->dfs_max_period >> 1))
+ break;
+ }
+ }
+ } /* for (j = i - 1; j > start_idx; j--)*/
+ }
+
+ /* Second Loop for CE*/
+ for (i = end_idx; i > start_idx; i--)
+ {
+ pCurrent = &pDfsSwParam->DFS_W[id][i & NEW_DFS_DBG_PORT_MASK];
+
+ /* we only handle entries has same counter with the last one*/
+ if (pCurrent->counter != pEnd->counter)
+ break;
+
+ /* Check Staggered radar*/
+ if (pCurrent->start_idx != 0xffff)
+ {
+ pNewDFSDebugPort p2, p3;
+ pNewDFSMPeriod pCE_T;
+ ULONG idx[10], T[10];
+
+ /*printk("pCurrent=%d, idx=%d~%d\n", pCurrent->timestamp, pCurrent->start_idx, pCurrent->end_idx);*/
+
+ for (idx[0] = pCurrent->start_idx; idx[0] <= pCurrent->end_idx; idx[0]++)
+ {
+ pCE_T = &pDfsSwParam->DFS_T[id][idx[0]];
+
+ p2 = &pDfsSwParam->DFS_W[id][pCE_T->idx2];
+
+ /*printk("idx[0]= %d, idx=%d p2=%d, idx=%d~%d\n", idx[0], pCE_T->idx2, p2->timestamp, p2->start_idx, p2->end_idx);*/
+
+ if (p2->start_idx == 0xffff)
+ continue;
+
+ T[0] = pCE_T->period;
+
+
+ for (idx[1] = p2->start_idx; idx[1] <= p2->end_idx; idx[1]++)
+ {
+
+ pCE_T = &pDfsSwParam->DFS_T[id][idx[1]];
+
+ p3 = &pDfsSwParam->DFS_W[id][pCE_T->idx2];
+
+ /*printk("p3=%d, idx=%d~%d\n", p3->timestamp, p3->start_idx, p3->end_idx);*/
+
+ if (idx[0] == idx[1])
+ continue;
+
+ if (p3->start_idx == 0xffff)
+ continue;
+
+
+
+ T[1] = pCE_T->period;
+
+
+ if (PERIOD_MATCH(T[0], T[1], pDfsSwParam->dfs_period_err))
+ {
+ if (id <= 2) /* && (id >= 0)*/
+ {
+
+
+ if (((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (T[1] > 66666)) ||
+ ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_20) && (T[1] > 33333)) )
+ {
+ unsigned int loop, PeriodMatched = 0, idx1;
+
+ for (loop = 1; loop < pDfsSwParam->dfs_check_loop; loop++)
+ {
+ idx1 = (idx[1] >= loop)? (idx[1] - loop): (NEW_DFS_MPERIOD_ENT_NUM + idx[1] - loop);
+ if (PERIOD_MATCH(pDfsSwParam->DFS_T[id][idx1].period, T[1], pDfsSwParam->dfs_period_err))
+ {
+#ifdef DFS_DEBUG
+ if (PeriodMatched < 5)
+ {
+ pDfsSwParam->CounterStored[PeriodMatched] = pDfsSwParam->DFS_W[id][pDfsSwParam->DFS_T[id][idx1].idx].counter;
+ pDfsSwParam->CounterStored2[PeriodMatched] = loop;
+ pDfsSwParam->CounterStored3 = idx[1];
+ }
+#endif
+ /*printk("%d %d\n", loop, pDfsSwParam->DFS_T[id][idx[1]-loop].period);*/
+ PeriodMatched++;
+ }
+
+ }
+
+
+ if (PeriodMatched > pDfsSwParam->dfs_declare_thres)
+ {
+#ifdef DFS_DEBUG
+ if (PeriodMatched == 3)
+ {
+ pDfsSwParam->T_Matched_3++;
+ /*printk("counter=%d %d %d\n", pDfsSwParam->CounterStored[0], pDfsSwParam->CounterStored[1], pDfsSwParam->CounterStored[2]);*/
+ /*printk("idx[1]=%d, loop =%d %d %d\n", pDfsSwParam->CounterStored3, pDfsSwParam->CounterStored2[0], pDfsSwParam->CounterStored2[1], pDfsSwParam->CounterStored2[2]);*/
+ }
+ else if (PeriodMatched == 4)
+ {
+ pDfsSwParam->T_Matched_4++;
+ /*printk("counter=%d %d %d %d\n", pDfsSwParam->CounterStored[0], pDfsSwParam->CounterStored[1], pDfsSwParam->CounterStored[2], pDfsSwParam->CounterStored[3]);*/
+ /*printk("idx[1]=%d, loop =%d %d %d %d\n", pDfsSwParam->CounterStored3, pDfsSwParam->CounterStored2[0], pDfsSwParam->CounterStored2[1], pDfsSwParam->CounterStored2[2], pDfsSwParam->CounterStored2[3]);*/
+ }
+ else
+ {
+ pDfsSwParam->T_Matched_5++;
+ /*printk("counter=%d %d %d %d %d\n", pDfsSwParam->CounterStored[0], pDfsSwParam->CounterStored[1], pDfsSwParam->CounterStored[2], pDfsSwParam->CounterStored[3], pDfsSwParam->CounterStored[4]);*/
+ /*printk("idx[1]=%d, loop =%d %d %d %d %d\n", pDfsSwParam->CounterStored3, pDfsSwParam->CounterStored2[0], pDfsSwParam->CounterStored2[1], pDfsSwParam->CounterStored2[2], pDfsSwParam->CounterStored2[3], pDfsSwParam->CounterStored2[4]);*/
+ }
+
+ pDfsSwParam->DebugPortPrint = 1;
+#endif
+ printk("Radar Detected(CE), W=%d, T=%d (%d), period matched=%d\n", (unsigned int)pCE_T->width, (unsigned int)T[1], (unsigned int)id, PeriodMatched);
+
+
+ if (PeriodMatched > (pDfsSwParam->dfs_declare_thres + 1))
+ radar_detected = 1;
+ return radar_detected;
+ }
+#ifdef DFS_DEBUG
+ else if (PeriodMatched == 2)
+ {
+ pDfsSwParam->T_Matched_2++;
+ /*printk("counter=%d %d\n", pDfsSwParam->CounterStored[0], pDfsSwParam->CounterStored[1]);*/
+ /*printk("idx[1]=%d, loop =%d %d\n", pDfsSwParam->CounterStored3, pDfsSwParam->CounterStored2[0], pDfsSwParam->CounterStored2[1]);*/
+ }
+#endif
+
+
+ }
+ }
+
+ }
+
+ } /* for (idx[1] = p2->start_idx; idx[1] <= p2->end_idx; idx[1]++)*/
+
+ } /* for (idx[0] = pCurrent->start_idx; idx[0] <= pCurrent->end_idx; idx[0]++)*/
+
+ }
+
+ } /* for (i = end_idx; i < start_idx; i--)*/
+
+
+ return radar_detected;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Recheck DFS radar of stager type.
+ Arguments:
+ pAdapter Pointer to our adapter
+ dfs_channel DFS detect channel
+ Return Value:
+ "TRUE" if check pass, "FALSE" otherwise.
+ Note:
+ ==========================================================================
+ */
+static BOOLEAN StagerRadarCheck(IN PRTMP_ADAPTER pAd, UINT8 dfs_channel)
+{
+ UINT T1=0, T2=0, T3=0, T_all=0, F1, F2, F3 = 0, Fmax = 0, freq_diff_min, freq_diff_max;
+ UINT8 dfs_stg2=0, dfs_typ5=0; /*, bbp141=0;*/
+ UINT F_MAX, F_MID, F_MIN;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->StagerRadarCheck()\n"));
+ {
+ UINT32 bbp_val = 0;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pAd->CommonCfg.RadarDetect.DfsProgramParam;
+
+ /* select channel */
+ bbp_val = (pDfsProgramParam->ChEnable << 16) | dfs_channel;
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, bbp_val);
+
+ RTMP_BBP_IO_READ32(pAd, DFS_R19, &T_all);
+ RTMP_BBP_IO_READ32(pAd, DFS_R22, &T1);
+ RTMP_BBP_IO_READ32(pAd, DFS_R25, &T2);
+ }
+
+ T3 = T_all - T1 -T2;
+
+ if (T3 < 5)
+ T3 = 0;
+
+ /*1. Check radar stagger2 or stagger3*/
+ if (T3 == 0 || ((T3 > (T1 + T2) ? (T3 - T1 - T2) : (T1 + T2 - T3)) < 25))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("stg2 confirmed\n"));
+ dfs_stg2 =1;
+ F1 = 20000000/T1; /*hz*/
+ F2 = 20000000/T2;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("stg3 confirmed\n"));
+ F1 = 20000000/T1; /*hz*/
+ F2 = 20000000/T2;
+ F3 = 20000000/T3;
+ }
+
+ F_MAX = (F1 > F2) ? ( (F1 > F3) ? F1 : F3 ) : ( (F2 > F3) ? F2 : F3 );
+ F_MIN = (F1 < F2) ? ( (F1 < F3) ? F1 : F3 ) : ( (F2 < F3) ? F2 : F3 );
+ F_MID = (F1 > F2) ? ((F1 < F3) ? F1 : ( (F2 > F3) ? F2 : F3 )) : ( F2 < F3 ? F2 : ((F1 > F3) ? F1 :F3) );
+
+ DBGPRINT(RT_DEBUG_TRACE, ("F_MAX=%d F_MID=%d F_MIN=%d\n", F_MAX, F_MID, F_MIN));
+
+ F1 = F_MAX;
+ F2 = F_MID;
+ F3 = F_MIN;
+
+ Fmax = F1;
+
+ /*2. Check radar type 5 or type6*/
+ if (Fmax>295 && Fmax<=405)
+ {
+ dfs_typ5 = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("type5 confirmed\n"));
+ freq_diff_min = 20;
+ freq_diff_max = 50;
+ }
+ else if (Fmax>405 && Fmax<=1205) /* tolerate more range for looser type6 */
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("type6 confirmed\n"));
+ freq_diff_min = 80;
+ freq_diff_max = 400;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("StagerRadarCheck failed, T1=%d, T2=%d, T3=%d\n", T1, T2, T3));
+ return FALSE;
+ }
+
+ /*3. According to decision of stagger and type do period check */
+ if (dfs_stg2 == 1)
+ {
+ UINT freq_diff = (F1 - F2);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("StagerRadarCheck freq_diff_min=%d freq_diff_max=%d \n", freq_diff_min, freq_diff_max));
+ DBGPRINT(RT_DEBUG_TRACE, ("StagerRadarCheck dfs_stg2, dff=%d \n", freq_diff));
+
+ if ((freq_diff >= freq_diff_min) && (freq_diff <= freq_diff_max))
+ return TRUE; /* S/W check success */
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("StagerRadarCheck failed, F1=%d, F2=%d\n", F1, F2));
+ DBGPRINT(RT_DEBUG_TRACE, ("stg2 fail on S/W Freq confirmed\n"));
+ return FALSE; /* S/W check fail */
+ }
+ }
+ else /* dfs_stg3 */
+ {
+ UINT freq_diff_1 = (F1 - F2);
+ UINT freq_diff_2 = (F2 - F3);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("StagerRadarCheck freq_diff_min=%d freq_diff_max=%d \n", freq_diff_min, freq_diff_max));
+ DBGPRINT(RT_DEBUG_TRACE, ("StagerRadarCheck dfs_stg3, dff_1=%d, dff_2=%d \n", freq_diff_1, freq_diff_2));
+
+
+ if( (freq_diff_1 >= freq_diff_min) && (freq_diff_1 <= freq_diff_max) && (freq_diff_2 >= freq_diff_min) && (freq_diff_2 <= freq_diff_max) )
+ return TRUE; /* S/W check success */
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("StagerRadarCheck failed, F1=%d, F2=%d, F3=%d\n", F1, F2, F3));
+ DBGPRINT(RT_DEBUG_TRACE, ("stg3 fail on S/W Freq confirmed\n"));
+ return FALSE; /* S/W check fail */
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<---StagerRadarCheck()\n"));
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Recheck DFS radar of chrp type.
+ Arguments:
+ pAdapter Pointer to our adapter
+ dfs_channel DFS detect channel
+ Return Value:
+ "TRUE" if check pass, "FALSE" otherwise.
+ Note:
+ ==========================================================================
+ */
+static BOOLEAN ChirpRadarCheck(IN PRTMP_ADAPTER pAd)
+{
+ UINT32 CurrentTime, delta;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+
+ RTMP_IO_READ32(pAd, PBF_LIFE_TIMER, &CurrentTime);
+ delta = CurrentTime - pRadarDetect->TimeStamp;
+ pRadarDetect->TimeStamp = CurrentTime;
+
+ /* ChirpCheck = 0 means the very first detection since start up*/
+ if (pRadarDetect->ChirpCheck++ == 0)
+ return FALSE;
+
+ if (delta <= (12*(1<<20))) /* 12 sec */
+ {
+ if (pRadarDetect->ChirpCheck >= 2)
+ {
+ /* Anouce the radar on any mutiple detection within 12 sec*/
+ DBGPRINT(RT_DEBUG_TRACE, ("ChirpRadarCheck OK.\n"));
+ return TRUE;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ChirpRadarCheck failed, discard previous detection.\n"));
+ pRadarDetect->ChirpCheck = 1;
+ return FALSE;
+ }
+ /* default */
+ return FALSE;
+}
+
+static VOID DfsCheckBusyIdle(
+ IN PRTMP_ADAPTER pAd)
+{
+ int busy_delta, idle_delta;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ RTMP_IO_READ32(pAd, CH_IDLE_STA, &pRadarDetect->idle_time);
+ RTMP_IO_READ32(pAd, CH_BUSY_STA, &pRadarDetect->busy_time);
+
+ /*ch_busy_sta_index begining at 0.*/
+ busy_delta = pRadarDetect->busy_time - pRadarDetect->ch_busy_sta[pRadarDetect->ch_busy_sta_index];
+ idle_delta = pRadarDetect->idle_time - pRadarDetect->ch_idle_sta[pRadarDetect->ch_busy_sta_index];
+
+ if (busy_delta < 0)
+ {
+ busy_delta = ~busy_delta;
+ busy_delta = (busy_delta >> CH_BUSY_SAMPLE_POWER);
+ busy_delta = ~busy_delta;
+ }
+ else
+ busy_delta = busy_delta >> CH_BUSY_SAMPLE_POWER;
+
+ if (idle_delta < 0)
+ {
+ idle_delta = ~idle_delta;
+ idle_delta = idle_delta >> CH_BUSY_SAMPLE_POWER;
+ idle_delta = ~idle_delta;
+ }
+ else
+ idle_delta = idle_delta >> CH_BUSY_SAMPLE_POWER;
+
+ pRadarDetect->ch_busy_sum += busy_delta;
+ pRadarDetect->ch_idle_sum += idle_delta;
+
+ /* not sure if this is necessary??*/
+ if (pRadarDetect->ch_busy_sum < 0)
+ pRadarDetect->ch_busy_sum = 0;
+ if (pRadarDetect->ch_idle_sum < 0)
+ pRadarDetect->ch_idle_sum = 0;
+
+ pRadarDetect->ch_busy_sta[pRadarDetect->ch_busy_sta_index] = pRadarDetect->busy_time;
+ pRadarDetect->ch_idle_sta[pRadarDetect->ch_busy_sta_index] = pRadarDetect->idle_time;
+
+ pRadarDetect->ch_busy_sta_index++;
+ pRadarDetect->ch_busy_sta_index &= CH_BUSY_MASK;
+
+ if ((pRadarDetect->ch_idle_sum >> pRadarDetect->ch_busy_idle_ratio) < pRadarDetect->ch_busy_sum )
+ {
+
+ if (!(pRadarDetect->McuRadarDebug & RADAR_DEBUG_DONT_CHECK_BUSY))
+ pRadarDetect->ch_busy = 1;
+ }
+ else
+ {
+ if (!(pRadarDetect->McuRadarDebug & RADAR_DEBUG_DONT_CHECK_RSSI))
+ {
+ if ((pAd->ApCfg.RssiSample.AvgRssi0) && (pAd->ApCfg.RssiSample.AvgRssi0 > pRadarDetect->DfsRssiHigh))
+ pRadarDetect->ch_busy = 2;
+ else if ((pAd->ApCfg.RssiSample.AvgRssi0) && (pAd->ApCfg.RssiSample.AvgRssi0 < pRadarDetect->DfsRssiLow))
+ pRadarDetect->ch_busy = 3;
+ else
+ pRadarDetect->ch_busy = 0;
+ }
+ }
+
+ if (pRadarDetect->print_ch_busy_sta)
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("%d %d %d %d\n", pRadarDetect->ch_idle_sum, pRadarDetect->ch_busy_sum, pAd->ApCfg.RssiSample.AvgRssi0, pRadarDetect->ch_busy));
+
+}
+
+static BOOLEAN DfsChannelCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DfsChannel)
+{
+ pNewDFSTable pDFS2Table;
+ UINT8 i;
+ UINT32 W, T;
+ BOOLEAN radarDeclared = 0;
+ /*UCHAR BBP_1 = 0, BBP_2 = 0, BBP_3 = 0, BBP_4 = 0;*/
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DFS HW check channel = 0x%x\n", DfsChannel));
+ /*Select the DFS table based on radar country region*/
+ if (pAd->CommonCfg.RDDurRegion == FCC)
+ pDFS2Table = &NewDFSTable1[0];
+ else if (pAd->CommonCfg.RDDurRegion == CE)
+ {
+ pDFS2Table = &NewDFSTable1[1];
+ }
+ else /* Japan*/
+ {
+ if ((pAd->CommonCfg.Channel >= 52) && (pAd->CommonCfg.Channel <= 64))
+ {
+ pDFS2Table = &NewDFSTable1[3];
+ }
+ else
+ {
+ pDFS2Table = &NewDFSTable1[2];
+ }
+ }
+ /*check which channe(0~3) is detecting radar signals*/
+ for (i = 0; i < pAd->chipCap.DfsEngineNum; i++)
+ {
+
+ if (DfsChannel & (0x1 << i))
+ {
+ UINT32 bbp_val = 0;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pAd->CommonCfg.RadarDetect.DfsProgramParam;
+
+ /* select channel */
+ bbp_val = (pDfsProgramParam->ChEnable << 16) | i;
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, bbp_val);
+
+ RTMP_BBP_IO_READ32(pAd, DFS_R19, &T);
+ RTMP_BBP_IO_READ32(pAd, DFS_R20, &W);
+ if (DfsSwCheckOnHwDetection(pAd, pDFS2Table, i, T, W) == FALSE)
+ continue;
+
+ printk("T = %u, W= %u detected by ch %d\n", T, W, i);
+ RTMP_BBP_IO_READ32(pAd, 0x2a70, &bbp_val);
+ printk("bbp 0x2a70 = 0x%08x\n", bbp_val);
+
+ /*set this variable to 1 for announcing that we find the radar signals.*/
+ radarDeclared = 1;
+
+ if ( ((i == 3) || (i == 2)) && (pDFS2Table->entry[i].mode != 0) )
+ {
+ ULONG B, W2;
+ RTMP_BBP_IO_READ32(pAd, DFS_R22, &B);
+ DBGPRINT(RT_DEBUG_TRACE, ("Burst = %lu(0x%lx)\n", B, B));
+
+ RTMP_BBP_IO_READ32(pAd, DFS_R23, &W2);
+ DBGPRINT(RT_DEBUG_TRACE, ("The second Width = %lu(0x%lx)\n", W2, W2));
+ }
+
+ }
+ }
+ return radarDeclared;
+}
+
+static BOOLEAN DfsEventDataFetch(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ OUT PDFS_EVENT pDfsEvent)
+{
+ pDfsEvent->EngineId = pData[0];
+ if (pDfsEvent->EngineId == 0xff) /* end of event */
+ return FALSE;
+
+ pDfsEvent->TimeStamp = pData[1];
+ pDfsEvent->TimeStamp |= (pData[2] << 8);
+ pDfsEvent->TimeStamp |= (pData[3] << 16);
+
+ pDfsEvent->Width = pData[4];
+ pDfsEvent->Width |= (pData[5] << 8);
+
+ /* Check if event is valid */
+ if (!DFS_EVENT_SANITY_CHECK(pAd, *pDfsEvent))
+ return FALSE;
+
+ return TRUE;
+}
+
+VOID NewRadarDetectionProgram(PRTMP_ADAPTER pAd, pNewDFSTable pDFS2Table)
+{
+ UINT8 idx, TalbeIdx, DFSR3;
+ UINT8 DfsEngineNum = pAd->chipCap.DfsEngineNum;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pRadarDetect->DfsProgramParam;
+
+
+ pRadarDetect->bDfsInit = FALSE;
+
+ /* Get Table index*/
+ for (TalbeIdx = 0; !((1<<TalbeIdx) & pDFS2Table->type); TalbeIdx++)
+ {
+ if (TalbeIdx > MAX_RD_REGION)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Table index out of range.\n"));
+ return;
+ }
+ }
+
+ for(idx = 0; idx<DfsEngineNum; idx++)
+ {
+ if ((pRadarDetect->DFSParamFromConfig & (0x1<<idx)) && pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].valid)
+ {
+ pDFS2Table->entry[idx].mode = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].mode;
+ pDFS2Table->entry[idx].avgLen = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].avgLen;
+ pDFS2Table->entry[idx].ELow = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].ELow;
+ pDFS2Table->entry[idx].EHigh = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].EHigh;
+ pDFS2Table->entry[idx].WLow = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].WLow;
+ pDFS2Table->entry[idx].WHigh = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].WHigh;
+ pDFS2Table->entry[idx].EpsilonW = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].EpsilonW;
+ pDFS2Table->entry[idx].TLow = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].TLow;
+ pDFS2Table->entry[idx].THigh = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].THigh;
+ pDFS2Table->entry[idx].EpsilonT = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].EpsilonT;
+ pDFS2Table->entry[idx].BLow = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].BLow;
+ pDFS2Table->entry[idx].BHigh = pDfsProgramParam->NewDFSTableEntry[(TalbeIdx*DfsEngineNum)+idx].BHigh;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("TalbeIdx = %d; idx = %d; DFSParam = %2d; %3d; %3d; %3d; %3d; %4d; %3d; %6lu; %7lu; %4d; %2lu; %2lu\n", TalbeIdx, idx,
+ pDFS2Table->entry[idx].mode, pDFS2Table->entry[idx].avgLen, pDFS2Table->entry[idx].ELow,
+ pDFS2Table->entry[idx].EHigh, pDFS2Table->entry[idx].WLow, pDFS2Table->entry[idx].WHigh,
+ pDFS2Table->entry[idx].EpsilonW, pDFS2Table->entry[idx].TLow, pDFS2Table->entry[idx].THigh,
+ pDFS2Table->entry[idx].EpsilonT, pDFS2Table->entry[idx].BLow, pDFS2Table->entry[idx].BHigh));
+ }
+ }
+
+ /* Symmetric round*/
+ if(pRadarDetect->SymRoundFromCfg != 0)
+ {
+ pDfsProgramParam->Symmetric_Round = pRadarDetect->SymRoundFromCfg;
+ DBGPRINT(RT_DEBUG_TRACE, ("Symmetric_Round = %d\n", pDfsProgramParam->Symmetric_Round));
+ }
+
+ /* BusyIdleRatio*/
+ if(pRadarDetect->BusyIdleFromCfg != 0)
+ {
+ pRadarDetect->ch_busy_idle_ratio = pRadarDetect->BusyIdleFromCfg;
+ DBGPRINT(RT_DEBUG_TRACE, ("ch_busy_idle_ratio = %d\n", pRadarDetect->ch_busy_idle_ratio));
+ }
+ /* DfsRssiHigh*/
+ if(pRadarDetect->DfsRssiHighFromCfg != 0)
+ {
+ pRadarDetect->DfsRssiHigh = pRadarDetect->DfsRssiHighFromCfg;
+ DBGPRINT(RT_DEBUG_TRACE, ("DfsRssiHigh = %d\n", pRadarDetect->DfsRssiHigh));
+ }
+ /* DfsRssiLow*/
+ if(pRadarDetect->DfsRssiLowFromCfg != 0)
+ {
+ pRadarDetect->DfsRssiLow = pRadarDetect->DfsRssiLowFromCfg;
+ DBGPRINT(RT_DEBUG_TRACE, ("DfsRssiLow = %d\n", pRadarDetect->DfsRssiLow));
+ }
+
+ /*pRadarDetect->MCURadarRegion = pAd->CommonCfg.RDDurRegion;*/
+ pRadarDetect->MCURadarRegion = pDFS2Table->type;
+
+ {
+ UINT32 bbp_val = 0;
+
+ DFSR3 = pDfsProgramParam->Symmetric_Round << 4;
+
+ /* Full 40Mhz*/
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ DFSR3 |= 0x80; /* BW 40*/
+
+ /* Delta Delay*/
+ DFSR3 |= (pDfsProgramParam->DeltaDelay & 0xf);
+ DBGPRINT(RT_DEBUG_TRACE,("R3 = 0x%x\n", DFSR3));
+
+ /* VGA Mask*/
+ DBGPRINT(RT_DEBUG_TRACE,("VGA_Mask = 0x%x\n", pDfsProgramParam->VGA_Mask));
+
+ /* Input Control 0 */
+ bbp_val = (pDfsProgramParam->VGA_Mask << 16) | (DFSR3);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R2, bbp_val);
+
+
+ /* packet end Mask*/
+ DBGPRINT(RT_DEBUG_TRACE,("Packet_End_Mask = 0x%x\n", pDfsProgramParam->Packet_End_Mask));
+
+ /* Rx PE Mask*/
+ DBGPRINT(RT_DEBUG_TRACE,("Rx_PE_Mask = 0x%x\n", pDfsProgramParam->Rx_PE_Mask));
+
+ /* Input Control 1 */
+ bbp_val = (pDfsProgramParam->Rx_PE_Mask << 16) | (pDfsProgramParam->Packet_End_Mask);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R3, bbp_val);
+
+ /* program each channel*/
+ for (idx = 0; idx < DfsEngineNum; idx++)
+ {
+ /* select channel*/
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, idx);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("write DFS Channle[%d] configuration \n", idx));
+
+ /* Detection Mode */
+ bbp_val = (pDFS2Table->entry[idx].mode & 0xf);
+
+ if (pAd->chipCap.DfsEngineNum > 4 && (idx==4 || idx==5))
+ bbp_val |= ((pDFS2Table->entry[idx].avgLen & 0x3) << 28);
+ else
+ bbp_val |= ((pDFS2Table->entry[idx].avgLen & 0x1ff) << 16);
+
+ /* DFS Mode */
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R4, bbp_val);
+
+ /* DFS Energy */
+ bbp_val = ((pDFS2Table->entry[idx].EHigh & 0x0fff) << 16) | (pDFS2Table->entry[idx].ELow & 0x0fff);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R5, bbp_val);
+
+ /* DFS Period Low */
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R7, pDFS2Table->entry[idx].TLow);
+
+ /* DFS Period High */
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R9, pDFS2Table->entry[idx].THigh);
+
+ /* DFS Burst Low */
+ /* DFS Burst High */
+
+ /* DFS Width */
+ bbp_val = ((pDFS2Table->entry[idx].WHigh & 0x0fff) << 16) | (pDFS2Table->entry[idx].WLow & 0x0fff);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R14, bbp_val);
+
+
+ /* DFS Measurement Uncertainty */
+ bbp_val = (pDFS2Table->entry[idx].EpsilonW << 16) | (pDFS2Table->entry[idx].EpsilonT);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R15, bbp_val);
+
+ /* DFS Event Expiration */
+ if (pDfsProgramParam->RadarEventExpire[idx] != 0)
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R17, pDfsProgramParam->RadarEventExpire[idx]);
+
+ }
+
+ /* Reset status */
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R1, pRadarDetect->EnabledChMask);
+
+ /* Enable detection*/
+ bbp_val = (pDfsProgramParam->ChEnable << 16);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, bbp_val);
+ }
+ pRadarDetect->bDfsInit = TRUE;
+
+}
+
+BOOLEAN DfsSwCheckOnHwDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN pNewDFSTable pDFS2Table,
+ IN UINT8 DfsChannel,
+ IN ULONG RadarPeriod,
+ IN ULONG RadarWidth)
+{
+ BOOLEAN bRadarCheck = TRUE;
+ if (!RadarPeriod || !RadarWidth)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Block eception on zero RadarPeriod or RadarWidth\n"));
+ return FALSE;
+ }
+
+ if (pDFS2Table->type == NEW_DFS_JAP)
+ {
+ /* Double check on pusle Width and Period*/
+ if (DfsChannel < 3)
+ {
+ /*check short pulse*/
+ if (RadarWidth < 375)
+ {
+ /* block the illegal period */
+ if ((RadarPeriod < 2800) ||
+ (RadarPeriod > 5000 && RadarPeriod < 6400) ||
+ (RadarPeriod > 6800 && RadarPeriod < 27560)||
+ (RadarPeriod > 27960 && RadarPeriod < 28360) ||
+ (RadarPeriod > 28700 && RadarPeriod < 79900) ||
+ (RadarPeriod > 80100))
+ {
+ /*(0~140), (250~320us), (340~1378us), (1398~1418), (1435~3995us) and (4005us~) according to the spec*/
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("Radar check: ch=%u, T=%lu, W=%lu, blocked\n", DfsChannel, RadarPeriod, RadarWidth));
+ bRadarCheck = FALSE;
+ }
+ }
+ else if (RadarWidth > 375)
+ {
+ if ((RadarPeriod<3500) || (RadarPeriod>10400))
+ {
+ /* block the illegal period */
+ /*(0~175) and (520us~) according to the spec*/
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("Radar check: ch=%u, T=%lu, W=%lu, blocked\n", DfsChannel, RadarPeriod, RadarWidth));
+ bRadarCheck = FALSE;
+ }
+ }
+ }
+ else if (DfsChannel == 3)
+ {
+ bRadarCheck = ChirpRadarCheck(pAd);
+ }
+ }
+ else if (pDFS2Table->type == NEW_DFS_EU)
+ {
+ if (DfsChannel == 4) /* to do: check dfs mode 8or9*/
+ {
+ if (StagerRadarCheck(pAd, DfsChannel) == FALSE)
+ bRadarCheck = FALSE;
+ }
+ }
+ return bRadarCheck;
+}
+
+static VOID ChannelSelectOnRadarDetection(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ UINT i;
+
+ if (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)
+ return;
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
+ {
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ {
+ if ((pAd->ChannelList[i].Channel >> 2) & 1)
+ {
+ if ((pAd->ChannelList[i+1].Channel - pAd->ChannelList[i].Channel) == 4 )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Find extend channel = %u\n", pAd->ChannelList[i+1].Channel));
+ pAd->ChannelList[i+1].RemainingTimeForUse = 1800;
+ }
+ }
+ else
+ {
+ if ((pAd->ChannelList[i].Channel - pAd->ChannelList[i-1].Channel) == 4 )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Find extend channel = %u\n", pAd->ChannelList[i-1].Channel));
+ pAd->ChannelList[i-1].RemainingTimeForUse = 1800;
+ }
+ }
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("BW is not 40.\n"));
+
+ pAd->ChannelList[i].RemainingTimeForUse = 1800;/*30 min = 1800 sec*/
+ break;
+ }
+ }
+
+ /*when find an radar, the ChMovingTime will be set to announce how many seconds to sending software radar detection time.*/
+ if ((pAd->CommonCfg.RDDurRegion == CE) && RESTRICTION_BAND_1(pAd))
+ pAd->Dot11_H.ChMovingTime = 605;
+ else
+ pAd->Dot11_H.ChMovingTime = 65;
+
+ /*if the Radar country region is JAP, we need find a new clear channel */
+ if (pAd->CommonCfg.RDDurRegion == JAP_W56)
+ {
+ for (i = 0; i < pAd->ChannelListNum ; i++)
+ {
+ pAd->CommonCfg.Channel = APAutoSelectChannel(pAd, FALSE);
+ if ((pAd->CommonCfg.Channel >= 100) && (pAd->CommonCfg.Channel <= 140))
+ break;
+ }
+ }
+ else if (pAd->CommonCfg.RDDurRegion == JAP_W53)
+ {
+ for (i = 0; i < pAd->ChannelListNum ; i++)
+ {
+ pAd->CommonCfg.Channel = APAutoSelectChannel(pAd, FALSE);
+ if ((pAd->CommonCfg.Channel >= 36) && (pAd->CommonCfg.Channel <= 60))
+ break;
+ }
+ }
+ else
+ pAd->CommonCfg.Channel = APAutoSelectChannel(pAd, FALSE);
+
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ /*ApSelectChannelCheck(pAd);*/
+ if (pAd->Dot11_H.RDMode == RD_NORMAL_MODE)
+ {
+ pAd->Dot11_H.RDMode = RD_SWITCHING_MODE;
+ /* Prepare a count-down for channel switching */
+ pAd->Dot11_H.CSCount = 0;
+ }
+ else if (pAd->Dot11_H.RDMode == RD_SILENCE_MODE)
+ {
+ pAd->Dot11_H.RDMode = RD_SWITCHING_MODE;
+ /*set this flag to 1 and the AP will restart to switch into new channel */
+ pRadarDetect->DFSAPRestart = 1;
+ schedule_dfs_task(pAd);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): Error! Unexpected radar state.\n", __FUNCTION__));
+ }
+ pRadarDetect->radarDeclared = 0;
+}
+
+static BOOLEAN DfsEventDrop(
+ IN PRTMP_ADAPTER pAd,
+ IN PDFS_EVENT pDfsEvent)
+{
+ UINT32 TimeDiff = 0; /* unit: 50ns */
+ UINT16 PreEnvtWidth = 0;
+ BOOLEAN RetVal = FALSE;
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pAd->CommonCfg.RadarDetect.DfsSwParam;
+ PDFS_EVENT pPreDfsEvent = &pDfsSwParam->PreDfsEvent;
+
+ if (pDfsEvent->EngineId != pPreDfsEvent->EngineId)
+ {
+ /* update prevoius event record then leave */
+ NdisCopyMemory(pPreDfsEvent, pDfsEvent, DFS_EVENT_SIZE);
+ return FALSE;
+ }
+
+ if (pDfsEvent->EngineId == 0x01 || pDfsEvent->EngineId == 0x02)
+ {
+ if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ {
+ TimeDiff = ((pDfsEvent->TimeStamp - pPreDfsEvent->TimeStamp) >> 1); /* 25ns to 50ns*/
+ PreEnvtWidth = pPreDfsEvent->Width >> 1;
+ }
+ else
+ {
+ TimeDiff = (pDfsEvent->TimeStamp - pPreDfsEvent->TimeStamp);
+ PreEnvtWidth = pPreDfsEvent->Width;
+ }
+
+ if (TimeDiff < pDfsSwParam->EvtDropAdjTime &&
+ PreEnvtWidth >= 200)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("%s(): EngineId = %x, Width = %u, TimeStamp = %u\n",
+ __FUNCTION__,
+ pDfsEvent->EngineId,
+ pDfsEvent->Width,
+ pDfsEvent->TimeStamp));
+ RetVal = TRUE;
+ }
+ }
+
+ /* update prevoius event record */
+ NdisCopyMemory(pPreDfsEvent, pDfsEvent, DFS_EVENT_SIZE);
+
+ return RetVal;
+}
+
+static void dfs_sw_init(PRTMP_ADAPTER pAd)
+{
+ int j, k;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pRadarDetect->DfsSwParam;
+
+ pDfsSwParam->fcc_5_threshold = 1000;
+ pDfsSwParam->fcc_5_idx = 0;
+ pDfsSwParam->fcc_5_last_idx = 0;
+ pDfsSwParam->dfs_check_loop = DFS_SW_RADAR_CHECK_LOOP;
+ pDfsSwParam->dfs_width_diff_ch1_Shift = DFS_SW_RADAR_CH1_SHIFT;
+ pDfsSwParam->dfs_width_diff_ch2_Shift = DFS_SW_RADAR_CH2_SHIFT;
+ pDfsSwParam->PreDfsEvent.EngineId = 0xff;
+ pDfsSwParam->EvtDropAdjTime = 2000;
+
+ /* clear long pulse table */
+ pDfsSwParam->FCC_5[pDfsSwParam->fcc_5_idx].counter = 0;
+ pDfsSwParam->fcc_5_idx = 0;
+ pDfsSwParam->fcc_5_last_idx = 0;
+
+ /*pDfsSwParam->dfs_width_diff_Shift = DFS_SW_RADAR_SHIFT;*/
+ pDfsSwParam->dfs_width_ch0_err_L = DFS_SW_RADAR_CH0_ERR;
+ if (pAd->CommonCfg.RDDurRegion == CE)
+ pDfsSwParam->dfs_period_err = (DFS_SW_RADAR_PERIOD_ERR << 2);
+ else
+ pDfsSwParam->dfs_period_err = DFS_SW_RADAR_PERIOD_ERR;
+ if (pAd->CommonCfg.RDDurRegion == CE)
+ {
+ pDfsSwParam->dfs_width_ch0_err_H = CE_STAGGERED_RADAR_CH0_H_ERR;
+ pDfsSwParam->dfs_declare_thres = CE_STAGGERED_RADAR_DECLARE_THRES;
+ pDfsSwParam->dfs_max_period = CE_STAGGERED_RADAR_PERIOD_MAX;
+ }
+ else
+ {
+ /*pDfsSwParam->dfs_declare_thres = DFS_SW_RADAR_DECLARE_THRES;*/
+ if (pAd->CommonCfg.RDDurRegion == FCC)
+ pDfsSwParam->dfs_max_period = FCC_RADAR_PERIOD_MAX;
+ else if (pAd->CommonCfg.RDDurRegion == JAP)
+ pDfsSwParam->dfs_max_period = JAP_RADAR_PERIOD_MAX;
+ }
+
+ pDfsSwParam->dfs_check_loop = DFS_SW_RADAR_CHECK_LOOP;
+ pDfsSwParam->dfs_width_diff_ch1_Shift = DFS_SW_RADAR_CH1_SHIFT;
+ pDfsSwParam->dfs_width_diff_ch2_Shift = DFS_SW_RADAR_CH2_SHIFT;
+ pDfsSwParam->dfs_width_ch0_err_L = DFS_SW_RADAR_CH0_ERR;
+ if (pAd->CommonCfg.RDDurRegion == CE)
+ pDfsSwParam->dfs_period_err = (DFS_SW_RADAR_PERIOD_ERR << 2);
+ else
+ pDfsSwParam->dfs_period_err = DFS_SW_RADAR_PERIOD_ERR;
+
+ if (pAd->CommonCfg.RDDurRegion == CE)
+ {
+ pDfsSwParam->dfs_width_ch0_err_H = CE_STAGGERED_RADAR_CH0_H_ERR;
+ pDfsSwParam->dfs_declare_thres = CE_STAGGERED_RADAR_DECLARE_THRES;
+ pDfsSwParam->dfs_max_period = CE_STAGGERED_RADAR_PERIOD_MAX;
+ }
+ else
+ {
+ /*pDfsSwParam->dfs_declare_thres = DFS_SW_RADAR_DECLARE_THRES;*/
+ if (pAd->CommonCfg.RDDurRegion == FCC)
+ pDfsSwParam->dfs_max_period = FCC_RADAR_PERIOD_MAX;
+ else if (pAd->CommonCfg.RDDurRegion == JAP)
+ pDfsSwParam->dfs_max_period = JAP_RADAR_PERIOD_MAX;
+ }
+
+ if (pRadarDetect->use_tasklet)
+ pRadarDetect->PollTime = NEW_DFS_CHECK_TIME_TASKLET;
+ else
+ pRadarDetect->PollTime = NEW_DFS_CHECK_TIME;
+
+ for (k = 0; k < pAd->chipCap.DfsEngineNum; k++)
+ {
+ for (j = 0; j < NEW_DFS_DBG_PORT_ENT_NUM; j++)
+ {
+ pDfsSwParam->DFS_W[k][j].start_idx = 0xffff;
+ }
+ }
+
+ for (k = 0; k < pAd->chipCap.DfsEngineNum; k++)
+ {
+ pDfsSwParam->sw_idx[k] = NEW_DFS_DBG_PORT_ENT_NUM - 1;
+ pDfsSwParam->hw_idx[k] = 0;
+ }
+
+ NdisZeroMemory(pDfsSwParam->DFS_T, sizeof(pDfsSwParam->DFS_T));
+ NdisZeroMemory(pDfsSwParam->DFS_W, sizeof(pDfsSwParam->DFS_W));
+}
+
+void modify_table1(PRTMP_ADAPTER pAd, ULONG idx, ULONG value)
+{
+ pNewDFSTable pDFS2Table;
+ ULONG x, y;
+ UINT8 DfsEngineNum = pAd->chipCap.DfsEngineNum;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pRadarDetect->DfsProgramParam;
+
+ if (pAd->CommonCfg.RDDurRegion == FCC)
+ pDFS2Table = &NewDFSTable1[0];
+ else if (pAd->CommonCfg.RDDurRegion == CE)
+ {
+ pDFS2Table = &NewDFSTable1[1];
+ }
+ else /* Japan*/
+ {
+ if ((pAd->CommonCfg.Channel >= 52) && (pAd->CommonCfg.Channel <= 64))
+ {
+ pDFS2Table = &NewDFSTable1[3];
+ }
+ else
+ {
+ pDFS2Table = &NewDFSTable1[2];
+ }
+ }
+
+ if (idx == 0)
+ {
+ pDfsProgramParam->DeltaDelay = value;
+ }
+ else if (idx <= (DfsEngineNum*16))
+ {
+ x = idx / 16;
+ y = idx % 16;
+ pRadarDetect->DFSParamFromConfig = 0; /* to prevent table be loaded from config file again */
+ switch (y)
+ {
+ case 1:
+ pDFS2Table->entry[x].mode = (USHORT)value;
+ break;
+ case 2:
+ pDFS2Table->entry[x].avgLen = (USHORT)value;
+ break;
+ case 3:
+ pDFS2Table->entry[x].ELow = (USHORT)value;
+ break;
+
+ case 4:
+ pDFS2Table->entry[x].EHigh = (USHORT)value;
+ break;
+
+ case 5:
+ pDFS2Table->entry[x].WLow = (USHORT)value;
+ break;
+
+ case 6:
+ pDFS2Table->entry[x].WHigh = (USHORT)value;
+ break;
+
+ case 7:
+ pDFS2Table->entry[x].EpsilonW = (USHORT)value;
+ break;
+
+ case 8:
+ pDFS2Table->entry[x].TLow = (ULONG)value;
+ break;
+
+ case 9:
+ pDFS2Table->entry[x].THigh = (ULONG)value;
+ break;
+
+ case 0xa:
+ pDFS2Table->entry[x].EpsilonT = (USHORT)value;
+ break;
+
+ case 0xb:
+ pDFS2Table->entry[x].BLow= (USHORT)value;
+ break;
+ case 0xc:
+ pDFS2Table->entry[x].BHigh = (USHORT)value;
+ break;
+
+ default:
+ break;
+ }
+
+ }
+ else if (idx == (DfsEngineNum*16 +1))
+ {
+ pDfsProgramParam->Symmetric_Round = (ULONG)value;
+ }
+ else if (idx == (DfsEngineNum*16 +2))
+ {
+ pDfsProgramParam->VGA_Mask = (ULONG)value;
+ }
+ else if (idx == (DfsEngineNum*16 +3))
+ {
+ pDfsProgramParam->Packet_End_Mask = (ULONG)value;
+ }
+ else if (idx == (DfsEngineNum*16 +4))
+ {
+ pDfsProgramParam->Rx_PE_Mask = (ULONG)value;
+ }
+
+ printk("Delta_Delay(0) = %d\n", pDfsProgramParam->DeltaDelay);
+
+ for (x = 0; x < DfsEngineNum; x++)
+ {
+ printk("Channel %lu\n", x);
+ printk("\t\tmode(%02lu)=%d, M(%02lu)=%03d, EL(%02lu)=%03d EH(%02lu)=%03d, WL(%02lu)=%03d WH(%02lu)=%04d, eW(%02lu)=%02d\n\t\tTL(%02lu)=%05u TH(%02lu)=%06u, eT(%02lu)=%03d, BL(%02lu)=%u, BH(%02lu)=%u\n",
+ (x*16+1), (unsigned int)pDFS2Table->entry[x].mode,
+ (x*16+2), (unsigned int)pDFS2Table->entry[x].avgLen,
+ (x*16+3), (unsigned int)pDFS2Table->entry[x].ELow,
+ (x*16+4), (unsigned int)pDFS2Table->entry[x].EHigh,
+ (x*16+5), (unsigned int)pDFS2Table->entry[x].WLow,
+ (x*16+6), (unsigned int)pDFS2Table->entry[x].WHigh,
+ (x*16+7), (unsigned int)pDFS2Table->entry[x].EpsilonW,
+ (x*16+8), (unsigned int)pDFS2Table->entry[x].TLow,
+ (x*16+9), (unsigned int)pDFS2Table->entry[x].THigh,
+ (x*16+0xa), (unsigned int)pDFS2Table->entry[x].EpsilonT,
+ (x*16+0xb), (unsigned int)pDFS2Table->entry[x].BLow,
+ (x*16+0xc), (unsigned int)pDFS2Table->entry[x].BHigh);
+ }
+
+ printk("Symmetric_Round(%02d) = %d\n", (DfsEngineNum*16 +1), pDfsProgramParam->Symmetric_Round);
+ printk("VGA_Mask(%02d) = %d\n", (DfsEngineNum*16 +2), pDfsProgramParam->VGA_Mask);
+ printk("Packet_End_Mask(%02d) = %d\n", (DfsEngineNum*16 +3), pDfsProgramParam->Packet_End_Mask);
+ printk("Rx_PE_Mask(%02d) = %d\n", (DfsEngineNum*16 +4), pDfsProgramParam->Rx_PE_Mask);
+
+}
+
+
+void modify_table2(PRTMP_ADAPTER pAd, ULONG idx, ULONG value)
+{
+ pNewDFSValidRadar pDFSValidRadar;
+ ULONG x, y;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+ idx--;
+
+ x = idx / 17;
+ y = idx % 17;
+
+ pDFSValidRadar = &NewDFSValidTable[0];
+
+ while (pDFSValidRadar->type != NEW_DFS_END)
+ {
+ if (pDFSValidRadar->type & pRadarDetect->MCURadarRegion)
+ {
+ if (x == 0)
+ break;
+ else
+ {
+ x--;
+ pDFSValidRadar++;
+ }
+ }
+ else
+ pDFSValidRadar++;
+ }
+
+ if (pDFSValidRadar->type == NEW_DFS_END)
+ {
+ printk("idx=%d exceed max number\n", (unsigned int)idx);
+ return;
+ }
+ switch(y)
+ {
+ case 0:
+ pDFSValidRadar->channel = value;
+ break;
+ case 1:
+ pDFSValidRadar->WLow = value;
+ break;
+ case 2:
+ pDFSValidRadar->WHigh = value;
+ break;
+ case 3:
+ pDFSValidRadar->W = value;
+ break;
+ case 8:
+ pDFSValidRadar->WMargin = value;
+ break;
+ case 9:
+ pDFSValidRadar->TLow = value;
+ break;
+ case 10:
+ pDFSValidRadar->THigh = value;
+ break;
+ case 11:
+ pDFSValidRadar->T = value;
+ break;
+ case 16:
+ pDFSValidRadar->TMargin = value;
+ break;
+ }
+
+ pDFSValidRadar = &NewDFSValidTable[0];
+ while (pDFSValidRadar->type != NEW_DFS_END)
+ {
+ if (pDFSValidRadar->type & pRadarDetect->MCURadarRegion)
+ {
+ printk("ch = %x --- ", pDFSValidRadar->channel);
+ printk("wl:wh = %d:%d ", pDFSValidRadar->WLow, pDFSValidRadar->WHigh);
+ printk("W = %u --- ", pDFSValidRadar->W);
+ printk("W Margin = %d\n", pDFSValidRadar->WMargin);
+ printk("Tl:Th = %d:%d ", (unsigned int)pDFSValidRadar->TLow, (unsigned int)pDFSValidRadar->THigh);
+ printk("T = %lu --- ", pDFSValidRadar->T);
+ printk("T Margin = %d\n", pDFSValidRadar->TMargin);
+ }
+ pDFSValidRadar++;
+ }
+
+}
+
+
+#ifdef RTMP_MAC_USB
+VOID NewUsbTimerCB_Radar(
+ IN PRTMP_ADAPTER pAd)
+
+{
+ UCHAR channel=0;
+ UCHAR radarDeclared = 0;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode */
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+ if (!DFS_CHECK_FLAGS(pAd, pRadarDetect) ||
+ (pRadarDetect->PollTime == 0))
+ return;
+
+ if (pRadarDetect->RadarTimeStampLow++ > 5)
+ pRadarDetect->RadarTimeStampLow = 0;
+
+ /*500ms*/
+ if ((pRadarDetect->RadarTimeStampLow % 5) == 0)
+ DfsCheckBusyIdle(pAd);
+
+ if (!pRadarDetect->bDfsSwDisable &&
+ (pRadarDetect->RadarTimeStampLow & 0x1) && /* 200ms */
+ !pRadarDetect->ch_busy)
+ SwCheckDfsEventWithFw(pAd);
+
+ /*
+ The following codes is used to check if the hardware find the Radar Signal
+ Read the 0~3 channel which had detected radar signals
+ Poll Status register
+ Set BBP_R140=0x02 and Read BBP_R141 to store at channel
+ */
+ //RTMP_DFS_IO_READ8(pAd, 0x2, &channel);
+ RTMP_BBP_IO_READ32(pAd, DFS_R1, &channel);
+
+ if (channel & pRadarDetect->EnabledChMask)
+ {
+ radarDeclared = DfsChannelCheck(pAd, channel & pRadarDetect->EnabledChMask);
+ }
+
+ /* reset the radar channel for new counting */
+ //RTMP_DFS_IO_WRITE8(pAd, 0x2, channel);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R1, channel);
+
+
+ if (pRadarDetect->McuRadarDebug & RADAR_SIMULATE)
+ {
+ radarDeclared = 1;
+ pRadarDetect->McuRadarDebug &= ~RADAR_SIMULATE;
+ }
+
+ /* Now, find an Radar signal */
+ if (radarDeclared || pRadarDetect->radarDeclared)
+ {
+ /*
+ Radar found!!!
+ Announce that this channel could not use in 30 minutes if we need find a clear channel
+ */
+ if (!(pRadarDetect->McuRadarDebug & RADAR_DONT_SWITCH))
+ {
+ ChannelSelectOnRadarDetection(pAd);
+ }
+ else
+ pRadarDetect->radarDeclared = 0;
+
+ }
+}
+
+static VOID SwCheckDfsEventWithFw(
+ IN PRTMP_ADAPTER pAd)
+{
+ int k, NumEvent = 64; /* event number per event buffer */
+ UCHAR id = 0;
+ UCHAR BBPR127_Table[DFS_EVENT_BUFFER_SIZE];
+ UCHAR BBPR127_OWERID;
+ UCHAR OwenerIDValue = 0;
+ UCHAR BBP127TableIdx = 0;
+ DFS_EVENT DfsEvent;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pRadarDetect->DfsSwParam;
+
+ /*pRadarDetect->McuRadarTick = 0;*/
+
+ for (BBP127TableIdx = 0; BBP127TableIdx < 6; BBP127TableIdx++)
+ {
+ RTUSBMultiRead(pAd, BBPR127TABLE_OWNERID + BBP127TableIdx, &BBPR127_OWERID, 1);
+
+ if (BBPR127_OWERID == 1)
+ continue;
+
+ NdisZeroMemory(BBPR127_Table, DFS_EVENT_BUFFER_SIZE);
+ RTUSBMultiRead(pAd, BBPR127TABLE_OFFSET + (BBP127TableIdx * 512), BBPR127_Table, DFS_EVENT_BUFFER_SIZE);
+
+ OwenerIDValue = 0x01;
+ RTUSBMultiWrite_OneByte(pAd, BBPR127TABLE_OWNERID + BBP127TableIdx, &OwenerIDValue);
+
+ pDfsSwParam->dfs_w_counter++;
+
+ if (pRadarDetect->McuRadarDebug & RADAR_DEBUG_SHOW_RAW_EVENT)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("\n=============0x%02x==============\n", BBP127TableIdx));
+ if (IS_RT3572(pAd))
+ {
+ DFS_EVENT_BUFF_PRINT(1, BBPR127_Table, DFS_EVENT_BUFFER_SIZE);
+ }
+ else
+ {
+ DFS_EVENT_BUFF_PRINT(0, BBPR127_Table, DFS_EVENT_BUFFER_SIZE);
+ }
+ }
+
+ for (k = 0; k < NumEvent; k++)
+ {
+ PUCHAR pTableOffset = NULL;
+ if (IS_RT3572(pAd))
+ {
+ pTableOffset = (BBPR127_Table+1) + (DFS_EVENT_SIZE*k);
+ }
+ else
+ {
+ pTableOffset = BBPR127_Table + (DFS_EVENT_SIZE*k);
+ }
+
+ if (DfsEventDataFetch(pAd, pTableOffset, &DfsEvent) == FALSE)
+ break;
+
+ if (DfsEventDrop(pAd, &DfsEvent) == TRUE)
+ continue;
+
+ if (pRadarDetect->use_tasklet)
+ {
+ id = DfsEvent.EngineId;
+
+ if (id < pAd->chipCap.DfsEngineNum)
+ {
+ /*if (DfsEvent.TimeStamp != pDfsSwParam->DFS_W[id][((pDfsSwParam->dfs_w_idx[id] == 0)? (NEW_DFS_DBG_PORT_ENT_NUM-1):(pDfsSwParam->dfs_w_idx[id] - 1))].timestamp)*/
+ {
+ pDfsSwParam->DFS_W[id][pDfsSwParam->dfs_w_idx[id]].counter = pDfsSwParam->dfs_w_counter;
+ pDfsSwParam->DFS_W[id][pDfsSwParam->dfs_w_idx[id]].timestamp = DfsEvent.TimeStamp;
+ pDfsSwParam->DFS_W[id][pDfsSwParam->dfs_w_idx[id]].width = DfsEvent.Width;
+
+ if (pRadarDetect->McuRadarDebug & RADAR_DEBUG_EVENT)
+ {
+ printk("counter = %lu ", pDfsSwParam->dfs_w_counter);
+ DFS_EVENT_PRINT(DfsEvent);
+ }
+
+ pDfsSwParam->dfs_w_last_idx[id] = pDfsSwParam->dfs_w_idx[id];
+ pDfsSwParam->dfs_w_idx[id]++;
+
+ if (pDfsSwParam->dfs_w_idx[id] >= NEW_DFS_DBG_PORT_ENT_NUM)
+ pDfsSwParam->dfs_w_idx[id] = 0;
+ }
+ }
+ }
+ }
+
+ if (pRadarDetect->use_tasklet)
+ {
+ /* set hw_idx*/
+ pDfsSwParam->hw_idx[0] = pDfsSwParam->dfs_w_idx[0];
+ pDfsSwParam->hw_idx[1] = pDfsSwParam->dfs_w_idx[1];
+ pDfsSwParam->hw_idx[2] = pDfsSwParam->dfs_w_idx[2];
+ pDfsSwParam->hw_idx[3] = pDfsSwParam->dfs_w_idx[3];
+
+ /*dfs tasklet will call SWRadarCheck*/
+ schedule_dfs_task(pAd);
+ }
+ }
+}
+
+void schedule_dfs_task(PRTMP_ADAPTER pAd)
+{
+ POS_COOKIE pObj;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pRadarDetect->DfsSwParam;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (pRadarDetect->DFSAPRestart == 1)
+ {
+ int i, j;
+
+ pDfsSwParam->dfs_w_counter += 10;
+ /* reset period table */
+ for (i = 0; i < pAd->chipCap.DfsEngineNum; i++)
+ {
+ for (j = 0; j < NEW_DFS_MPERIOD_ENT_NUM; j++)
+ {
+ pDfsSwParam->DFS_T[i][j].period = 0;
+ pDfsSwParam->DFS_T[i][j].idx = 0;
+ pDfsSwParam->DFS_T[i][j].idx2 = 0;
+ }
+ }
+
+ APStop(pAd);
+ APStartUp(pAd);
+ RTMP_BBP_IO_WRITE32(pAd, DFS_R0, (pRadarDetect->EnabledChMask << 16)); /* re-enable DFS engine */
+ //RTMP_DFS_IO_WRITE8(pAd, pRadarDetect->EnabledChMask, 1); /* re-enable DFS engine */
+ pRadarDetect->DFSAPRestart = 0;
+ }
+ else
+ {
+ /*s/w check radar event buffer*/
+ int idx;
+ if (pRadarDetect->radarDeclared == 0)
+ {
+ for (idx = 0; idx < 4; idx++)
+ {
+ if (SWRadarCheck(pAd, idx) == 1)
+ {
+ //radar signals found
+ pRadarDetect->radarDeclared = 1;
+ break;
+ }
+ }
+ }
+ }
+}
+#endif /* RTMP_MAC_USB */
+#endif /*CONFIG_AP_SUPPORT*/
+#endif /* DFS_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_info.c b/cleopatre/devkit/mt7601udrv/common/cmm_info.c
new file mode 100644
index 0000000000..4d69674a66
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_info.c
@@ -0,0 +1,6151 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ cmm_info.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#include "rt_config.h"
+
+
+
+/*
+ ==========================================================================
+ Description:
+ Get Driver version.
+
+ Return:
+ ==========================================================================
+*/
+INT Set_DriverVersion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", AP_DRIVER_VERSION));
+#endif /* CONFIG_AP_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;
+#ifdef CONFIG_AP_SUPPORT
+ UINT32 i = 0;
+#ifdef MBSS_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (FlgIsDiffMbssModeUsed) {
+ LONG cfg_mode = simple_strtol(arg, 0, 10);
+
+ /* assign wireless mode for the BSS */
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].PhyMode =
+ cfgmode_2_wmode((UCHAR)cfg_mode);
+
+ /*
+ If the band is different with other BSS, we will correct it in
+ RT_CfgSetMbssWirelessMode()
+ */
+ success = RT_CfgSetMbssWirelessMode(pAd, arg);
+ }
+ else
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ success = RT_CfgSetWirelessMode(pAd, arg);
+
+ if (success)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* recover Wmm Capable for "each" BSS */
+ /* all phy mode of MBSS are the same */
+ for(i=0; i<pAd->ApCfg.BssidNum; i++)
+ {
+ pAd->ApCfg.MBSSID[i].bWmmCapable = \
+ pAd->ApCfg.MBSSID[i].bWmmCapableOrg;
+
+#ifdef MBSS_SUPPORT
+ /* In Same-MBSS Mode, all phy modes are the same */
+ if (FlgIsDiffMbssModeUsed == 0)
+ pAd->ApCfg.MBSSID[i].PhyMode = pAd->CommonCfg.PhyMode;
+#endif /* MBSS_SUPPORT */
+ }
+
+ RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Cmm_WirelessMode_Proc::(=%d)\n", pAd->CommonCfg.PhyMode));
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Cmm_WirelessMode_Proc::(BSS%d=%d)\n",
+ pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].PhyMode));
+
+ for(i=0; i<pAd->ApCfg.BssidNum; i++)
+ {
+ /*
+ When last mode is not 11B-only, new mode is 11B, we need to re-make
+ beacon frame content.
+
+ Because we put support rate/extend support rate element in
+ APMakeBssBeacon(), not APUpdateBeaconFrame().
+ */
+ APMakeBssBeacon(pAd, i);
+ }
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
+ }
+
+ return success;
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set Wireless Mode for MBSS
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_MBSS_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ return Set_Cmm_WirelessMode_Proc(pAd, arg, 1);
+}
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+/*
+ ==========================================================================
+ Description:
+ Set Wireless Mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_WirelessMode_Proc(RTMP_ADAPTER *pAd, 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)
+{
+#ifdef CONFIG_AP_SUPPORT
+ INT i;
+#endif /* CONFIG_AP_SUPPORT */
+ INT success = TRUE;
+ UCHAR Channel;
+
+ Channel = (UCHAR) simple_strtol(arg, 0, 10);
+
+ /* check if this channel is valid*/
+ if (ChannelSanity(pAd, Channel) == TRUE)
+ {
+ success = TRUE;
+ }
+ else
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ Channel = FirstChannel(pAd);
+ DBGPRINT(RT_DEBUG_WARN,("This channel is out of channel list, set as the first channel(%d) \n ", Channel));
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if ((WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ && (pAd->CommonCfg.bIEEE80211H == TRUE))
+ {
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].Channel == Channel)
+ {
+ if (pAd->ChannelList[i].RemainingTimeForUse > 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: previous detection of a radar on this channel(Channel=%d)\n", Channel));
+ success = FALSE;
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("RemainingTimeForUse %d ,Channel %d\n",
+ pAd->ChannelList[i].RemainingTimeForUse, Channel));
+ }
+ }
+ }
+ }
+
+ if (success == TRUE)
+ {
+ pAd->CommonCfg.Channel = Channel;
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ if ((pAd->CommonCfg.Channel > 14 )
+ && (pAd->CommonCfg.bIEEE80211H == TRUE))
+ {
+ if (pAd->Dot11_H.RDMode == RD_SILENCE_MODE)
+ {
+ APStop(pAd);
+ APStartUp(pAd);
+ }
+ else
+ {
+ NotifyChSwAnnToPeerAPs(pAd, ZERO_MAC_ADDR, pAd->CurrentAddress, 1, pAd->CommonCfg.Channel);
+ pAd->Dot11_H.RDMode = RD_SWITCHING_MODE;
+ pAd->Dot11_H.CSCount = 0;
+ }
+ }
+ else
+ {
+ APStop(pAd);
+ APStartUp(pAd);
+ }
+ }
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ pAd->CommonCfg.TxPowerPercentage = TxPower;
+#endif /* CONFIG_AP_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;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APUpdateCapabilityAndErpIe(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ if (Preamble == Rt802_11PreambleAuto)
+ return FALSE;
+#endif /* CONFIG_AP_SUPPORT */
+
+ switch (Preamble)
+ {
+ case Rt802_11PreambleShort:
+ pAd->CommonCfg.TxPreamble = Preamble;
+ break;
+ case Rt802_11PreambleLong:
+ pAd->CommonCfg.TxPreamble = Preamble;
+ 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;
+ 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;
+ }
+
+
+ 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 */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef PIGGYBACK_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
+ RTMPSetPiggyBack(pAd, pAd->CommonCfg.bPiggyBackCapable);
+ }
+#endif /* PIGGYBACK_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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 EXT_BUILD_CHANNEL_LIST
+/*
+ ==========================================================================
+ Description:
+ Set Country Code.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ExtCountryCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+
+ if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) == NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s can only be used when interface is down.\n", __FUNCTION__));
+ return TRUE;
+ }
+
+ if(strlen(arg) == 2)
+ {
+ NdisMoveMemory(pAd->CommonCfg.CountryCode, arg, 2);
+ pAd->CommonCfg.bCountryFlag = TRUE;
+ }
+ else
+ {
+ NdisZeroMemory(pAd->CommonCfg.CountryCode, 3);
+ pAd->CommonCfg.bCountryFlag = FALSE;
+ }
+
+ {
+ UCHAR CountryCode[3] = {0};
+ NdisMoveMemory(CountryCode, pAd->CommonCfg.CountryCode, 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryCode_Proc::(bCountryFlag=%d, CountryCode=%s)\n",
+ pAd->CommonCfg.bCountryFlag,
+ CountryCode));
+ }
+ return TRUE;
+}
+/*
+ ==========================================================================
+ Description:
+ Set Ext DFS Type
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ExtDfsType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR *pDfsType = &pAd->CommonCfg.DfsType;
+ if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) == NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s can only be used when interface is down.\n", __FUNCTION__));
+ return TRUE;
+ }
+
+ if (!strcmp(arg, "CE"))
+ *pDfsType = CE;
+ else if (!strcmp(arg, "FCC"))
+ *pDfsType = FCC;
+ else if (!strcmp(arg, "JAP"))
+ *pDfsType = JAP;
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Unsupported DFS type:%s (Legal types are: CE, FCC, JAP)\n", arg));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Add new channel list
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ChannelListAdd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ CH_DESP inChDesp;
+ PCH_REGION pChRegion = NULL;
+
+ if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) == NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s can only be used when interface is down.\n", __FUNCTION__));
+ return TRUE;
+ }
+
+ /* Get Channel Region (CountryCode)*/
+ {
+ INT loop = 0;
+
+ while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0)
+ {
+ if (strncmp((PSTRING) ChRegion[loop].CountReg, pAd->CommonCfg.CountryCode, 2) == 0)
+ {
+ pChRegion = &ChRegion[loop];
+ break;
+ }
+ loop++;
+ }
+ if (pChRegion == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryCode is not configured or not valid\n"));
+ return TRUE;
+ }
+ }
+
+ /* Parsing the arg, IN:arg; OUT:inChRegion */
+ {
+ UCHAR strBuff[64], count = 0;
+ PUCHAR pStart, pEnd, tempIdx, tempBuff[5];
+
+ if (strlen(arg) <64)
+ NdisCopyMemory(strBuff, arg, strlen(arg));
+
+ if ((pStart = rtstrchr(strBuff, '[')) != NULL)
+ {
+ if ((pEnd = rtstrchr(pStart++, ']')) != NULL)
+ {
+ tempBuff[count++] = pStart;
+ for(tempIdx = pStart ;tempIdx != pEnd; tempIdx++)
+ {
+ if(*tempIdx == ',')
+ {
+ *tempIdx = '\0';
+ tempBuff[count++] = ++tempIdx;
+ }
+ }
+ *(pEnd) = '\0';
+
+ if (count != 5)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Input Error. Too more or too less parameters.\n"));
+ return TRUE;
+ }
+ else
+ {
+ inChDesp.FirstChannel = (UCHAR) simple_strtol(tempBuff[0], 0, 10);
+ inChDesp.NumOfCh = (UCHAR) simple_strtol(tempBuff[1], 0, 10);
+ inChDesp.MaxTxPwr = (UCHAR) simple_strtol(tempBuff[2], 0, 10);
+ inChDesp.Geography = (!strcmp(tempBuff[3], "BOTH") ? BOTH: (!strcmp(tempBuff[3], "IDOR") ? IDOR : ODOR));
+ inChDesp.DfsReq= (!strcmp(tempBuff[4], "TRUE") ? TRUE : FALSE);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Missing End \"]\"\n"));
+ return TRUE;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Invalid input format.\n", __FUNCTION__));
+ return TRUE;
+ }
+ }
+
+ /* Add entry to Channel List*/
+ {
+ UCHAR EntryIdx;
+ PCH_DESP pChDesp = NULL;
+ UCHAR CountryCode[3] = {0};
+ if (pAd->CommonCfg.pChDesp == NULL)
+ {
+ os_alloc_mem(pAd, &pAd->CommonCfg.pChDesp, MAX_PRECONFIG_DESP_ENTRY_SIZE*sizeof(CH_DESP));
+ pChDesp = (PCH_DESP) pAd->CommonCfg.pChDesp;
+ if (pChDesp)
+ {
+ for (EntryIdx= 0; pChRegion->pChDesp[EntryIdx].FirstChannel != 0; EntryIdx++)
+ {
+ if (EntryIdx == (MAX_PRECONFIG_DESP_ENTRY_SIZE-2)) /* Keep an NULL entry in the end of table*/
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Table is full.\n"));
+ return TRUE;
+ }
+ NdisCopyMemory(&pChDesp[EntryIdx], &pChRegion->pChDesp[EntryIdx], sizeof(CH_DESP));
+ }
+ /* Copy the NULL entry*/
+ NdisCopyMemory(&pChDesp[EntryIdx], &pChRegion->pChDesp[EntryIdx], sizeof(CH_DESP));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("os_alloc_mem failded.\n"));
+ return FALSE;
+ }
+ }
+ else
+ {
+ pChDesp = (PCH_DESP) pAd->CommonCfg.pChDesp;
+ for (EntryIdx= 0; pChDesp[EntryIdx].FirstChannel != 0; EntryIdx++)
+ {
+ if(EntryIdx == (MAX_PRECONFIG_DESP_ENTRY_SIZE-2)) /* Keep an NULL entry in the end of table*/
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Table is full.\n"));
+ return TRUE;
+ }
+ }
+ }
+ NdisMoveMemory(CountryCode, pAd->CommonCfg.CountryCode, 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("Add channel lists {%u, %u, %u, %s, %s} to %s.\n",
+ inChDesp.FirstChannel,
+ inChDesp.NumOfCh,
+ inChDesp.MaxTxPwr,
+ (inChDesp.Geography == BOTH) ? "BOTH" : (inChDesp.Geography == IDOR) ? "IDOR" : "ODOR",
+ (inChDesp.DfsReq == TRUE) ? "TRUE" : "FALSE",
+ CountryCode));
+ NdisCopyMemory(&pChDesp[EntryIdx], &inChDesp, sizeof(CH_DESP));
+ pChDesp[++EntryIdx].FirstChannel = 0;
+ }
+ return TRUE;
+}
+
+INT Set_ChannelListShow_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PCH_REGION pChRegion = NULL;
+ UCHAR EntryIdx, CountryCode[3]={0};
+
+ /* Get Channel Region (CountryCode)*/
+ {
+ INT loop = 0;
+
+ while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0)
+ {
+ if (strncmp((PSTRING) ChRegion[loop].CountReg, pAd->CommonCfg.CountryCode, 2) == 0)
+ {
+ pChRegion = &ChRegion[loop];
+ break;
+ }
+ loop++;
+ }
+ if (pChRegion == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryCode is not configured or not valid\n"));
+ return TRUE;
+ }
+ }
+
+ NdisMoveMemory(CountryCode, pAd->CommonCfg.CountryCode, 2);
+ if (pAd->CommonCfg.DfsType == MAX_RD_REGION)
+ pAd->CommonCfg.DfsType = pChRegion->DfsType;
+ DBGPRINT(RT_DEBUG_ERROR, ("=========================================\n"));
+ DBGPRINT(RT_DEBUG_ERROR, ("CountryCode:%s\n", CountryCode));
+ DBGPRINT(RT_DEBUG_ERROR, ("DfsType:%s\n",
+ (pAd->CommonCfg.DfsType == JAP) ? "JAP" :
+ ((pAd->CommonCfg.DfsType == FCC) ? "FCC" : "CE" )));
+
+ if (pAd->CommonCfg.pChDesp != NULL)
+ {
+ PCH_DESP pChDesp = (PCH_DESP) pAd->CommonCfg.pChDesp;
+ for (EntryIdx = 0; pChDesp[EntryIdx].FirstChannel != 0; EntryIdx++)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%u. {%3u, %2u, %2u, %s, %5s}.\n",
+ EntryIdx,
+ pChDesp[EntryIdx].FirstChannel,
+ pChDesp[EntryIdx].NumOfCh,
+ pChDesp[EntryIdx].MaxTxPwr,
+ (pChDesp[EntryIdx].Geography == BOTH) ? "BOTH" : (pChDesp[EntryIdx].Geography == IDOR) ? "IDOR" : "ODOR",
+ (pChDesp[EntryIdx].DfsReq == TRUE) ? "TRUE" : "FALSE"));
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Default channel list table:\n"));
+ for (EntryIdx = 0; pChRegion->pChDesp[EntryIdx].FirstChannel != 0; EntryIdx++)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%u. {%3u, %2u, %2u, %s, %5s}.\n",
+ EntryIdx,
+ pChRegion->pChDesp[EntryIdx].FirstChannel,
+ pChRegion->pChDesp[EntryIdx].NumOfCh,
+ pChRegion->pChDesp[EntryIdx].MaxTxPwr,
+ (pChRegion->pChDesp[EntryIdx].Geography == BOTH) ? "BOTH" : (pChRegion->pChDesp[EntryIdx].Geography == IDOR) ? "IDOR" : "ODOR",
+ (pChRegion->pChDesp[EntryIdx].DfsReq == TRUE) ? "TRUE" : "FALSE"));
+ }
+ }
+ DBGPRINT(RT_DEBUG_ERROR, ("=========================================\n"));
+ return TRUE;
+}
+
+INT Set_ChannelListDel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR EntryIdx, TargetIdx, NumOfEntry;
+ PCH_REGION pChRegion = NULL;
+ PCH_DESP pChDesp = NULL;
+ TargetIdx = simple_strtol(arg, 0, 10);
+ if (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) == NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s can only be used when interface is down.\n", __FUNCTION__));
+ return TRUE;
+ }
+
+ /* Get Channel Region (CountryCode)*/
+ {
+ INT loop = 0;
+ while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0)
+ {
+ if (strncmp((PSTRING) ChRegion[loop].CountReg, pAd->CommonCfg.CountryCode, 2) == 0)
+ {
+ pChRegion = &ChRegion[loop];
+ break;
+ }
+ loop++;
+ }
+ if (pChRegion == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryCode is not configured or not valid\n"));
+ return TRUE;
+ }
+ }
+
+ if (pAd->CommonCfg.pChDesp == NULL)
+ {
+ os_alloc_mem(pAd, &pAd->CommonCfg.pChDesp, MAX_PRECONFIG_DESP_ENTRY_SIZE*sizeof(CH_DESP));
+ if (pAd->CommonCfg.pChDesp)
+ {
+ pChDesp = (PCH_DESP) pAd->CommonCfg.pChDesp;
+ for (EntryIdx= 0; pChRegion->pChDesp[EntryIdx].FirstChannel != 0; EntryIdx++)
+ {
+ if (EntryIdx == (MAX_PRECONFIG_DESP_ENTRY_SIZE-2)) /* Keep an NULL entry in the end of table*/
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Table is full.\n"));
+ return TRUE;
+ }
+ NdisCopyMemory(&pChDesp[EntryIdx], &pChRegion->pChDesp[EntryIdx], sizeof(CH_DESP));
+ }
+ /* Copy the NULL entry*/
+ NdisCopyMemory(&pChDesp[EntryIdx], &pChRegion->pChDesp[EntryIdx], sizeof(CH_DESP));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("os_alloc_mem failded.\n"));
+ return FALSE;
+ }
+ }
+ else
+ pChDesp = (PCH_DESP) pAd->CommonCfg.pChDesp;
+
+ if (!strcmp(arg, "default"))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Default table used.\n" ));
+ if (pAd->CommonCfg.pChDesp != NULL)
+ os_free_mem(NULL, pAd->CommonCfg.pChDesp);
+ pAd->CommonCfg.pChDesp = NULL;
+ pAd->CommonCfg.DfsType = MAX_RD_REGION;
+ }
+ else if (!strcmp(arg, "all"))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Remove all entries.\n" ));
+ for (EntryIdx = 0; EntryIdx < MAX_PRECONFIG_DESP_ENTRY_SIZE; EntryIdx++)
+ NdisZeroMemory(&pChDesp[EntryIdx], sizeof(CH_DESP));
+ }
+ else if (TargetIdx < (MAX_PRECONFIG_DESP_ENTRY_SIZE-1))
+ {
+ for (EntryIdx= 0; pChDesp[EntryIdx].FirstChannel != 0; EntryIdx++)
+ {
+ if(EntryIdx == (MAX_PRECONFIG_DESP_ENTRY_SIZE-2)) /* Keep an NULL entry in the end of table */
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Last entry should be NULL.\n"));
+ pChDesp[EntryIdx].FirstChannel = 0;
+ return TRUE;
+ }
+ }
+ NumOfEntry = EntryIdx;
+ if (TargetIdx >= NumOfEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Out of table range.\n"));
+ return TRUE;
+ }
+ for (EntryIdx = TargetIdx; EntryIdx < NumOfEntry; EntryIdx++)
+ NdisCopyMemory(&pChDesp[EntryIdx], &pChDesp[EntryIdx+1], sizeof(CH_DESP));
+ NdisZeroMemory(&pChDesp[EntryIdx], sizeof(CH_DESP)); /*NULL entry*/
+ DBGPRINT(RT_DEBUG_TRACE, ("Entry %u deleted.\n", TargetIdx));
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Entry not found.\n"));
+
+ return TRUE;
+}
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+#ifdef WSC_INCLUDED
+INT Set_WscGenPinCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PWSC_CTRL pWscControl = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ pWscControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(apcli%d) Set_WscGenPinCode_Proc:: This command is from apcli interface now.\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) Set_WscGenPinCode_Proc:: This command is from ra interface now.\n", apidx));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+ if (pWscControl == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pWscControl == NULL!\n", __FUNCTION__));
+ return TRUE;
+ }
+
+ if (pWscControl->WscEnrollee4digitPinCode)
+ {
+ pWscControl->WscEnrolleePinCodeLen = 4;
+ pWscControl->WscEnrolleePinCode = WscRandomGen4digitPinCode(pAd);
+ }
+ else
+ {
+ pWscControl->WscEnrolleePinCodeLen = 8;
+ pWscControl->WscEnrolleePinCode = WscRandomGeneratePinCode(pAd, apidx);
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscGenPinCode_Proc:: Enrollee PinCode\t\t%08u\n", pWscControl->WscEnrolleePinCode));
+
+ return TRUE;
+}
+
+INT Set_WscVendorPinCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PWSC_CTRL pWscControl = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ UCHAR apidx = pObj->ioctl_if;
+
+#ifdef CONFIG_AP_SUPPORT
+/* POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;*/
+/* UCHAR apidx = pObj->ioctl_if;*/
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ pWscControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscVendorPinCode_Proc() for apcli(%d)\n", apidx));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WscVendorPinCode_Proc() for ra%d!\n", apidx));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+ if (!pWscControl)
+ return FALSE;
+ else
+ return RT_CfgSetWscPinCode(pAd, arg, pWscControl);
+}
+#endif /* WSC_INCLUDED */
+
+#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, ("==>%s()\n", __FUNCTION__));
+
+ if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
+ RTDebugLevel = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==%s(RTDebugLevel = %ld)\n",
+ __FUNCTION__, RTDebugLevel));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ For DebugFunc information
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_DebugFunc_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+ DBGPRINT_S(RT_DEBUG_TRACE, ("==>%s()\n", __FUNCTION__));
+ RTDebugFunc = simple_strtol(arg, 0, 10);
+ DBGPRINT_S(RT_DEBUG_TRACE, ("Set RTDebugFunc = 0x%x\n",__FUNCTION__, RTDebugFunc));
+
+ return TRUE;
+}
+#endif
+
+
+INT Show_DescInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Reset statistics counter
+
+ Arguments:
+ pAd 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));
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ {
+ int i;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ NdisZeroMemory(&pAd->MacTab.Content[i].TxBFCounters, sizeof(pAd->MacTab.Content[i].TxBFCounters));
+ }
+#endif /* TXBF_SUPPORT */
+
+ return TRUE;
+}
+
+
+BOOLEAN RTMPCheckStrPrintAble(
+ IN CHAR *pInPutStr,
+ IN UCHAR strLen)
+{
+ UCHAR i=0;
+
+ for (i=0; i<strLen; i++)
+ {
+ if ((pInPutStr[i] < 0x20) ||
+ (pInPutStr[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:
+
+ ========================================================================
+*/
+
+#if defined(CONFIG_STA_SUPPORT) || defined(APCLI_WPA_SUPPLICANT_SUPPORT)
+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;
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ UCHAR ifIndex;
+ BOOLEAN apcliEn=FALSE;
+ INT idx, BssIdx;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+ 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++)
+ {
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pObj->ioctl_if_type == INT_APCLI)
+ {
+ /*if (MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[ifIndex].SharedKey[i].BssId, pKey->BSSID)) */
+ {
+ ifIndex = pObj->ioctl_if;
+ BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + ifIndex;
+ DBGPRINT(RT_DEBUG_TRACE,("APCLI RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
+ pAd->ApCfg.ApCliTab[ifIndex].SharedKey[i].KeyLen = 0;
+ pAd->ApCfg.ApCliTab[ifIndex].SharedKey[i].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAd, BssIdx, (UCHAR)i);
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+ }
+ else
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+ {
+ }
+ }
+ }
+ /* 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 /* defined(CONFIG_STA_SUPPORT) || defined(APCLI_WPA_SUPPLICANT_SUPPORT) */
+
+
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Change NIC PHY mode. Re-association may be necessary
+
+ Arguments:
+ pAd - Pointer to our adapter
+ phymode -
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPSetPhyMode(
+ IN RTMP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ if (pAd->CommonCfg.Channel != 0)
+ pAd->CommonCfg.Channel = FirstChannel(pAd);
+#endif /* CONFIG_AP_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 (WMODE_B):
+ 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;
+
+ /*
+ In current design, we will put supported/extended rate element in
+ beacon even we are 11n-only mode.
+ Or some 11n stations will not connect to us if we do not put
+ supported/extended rate element in beacon.
+ */
+ case (WMODE_G):
+ case (WMODE_B | WMODE_G):
+ case (WMODE_A | WMODE_B | WMODE_G):
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_GN):
+ case (WMODE_A | WMODE_B | WMODE_G | WMODE_GN | WMODE_AN):
+ case (WMODE_B | WMODE_G | WMODE_GN):
+ case (WMODE_G | WMODE_GN):
+#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 (WMODE_A):
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_A | WMODE_AN):
+ case (WMODE_A | WMODE_G | WMODE_GN | WMODE_AN):
+ case (WMODE_AN):
+#endif /* DOT11_N_SUPPORT */
+#ifdef DOT11_VHT_AC
+ case (WMODE_A | WMODE_AN | WMODE_AC):
+ case (WMODE_AN | WMODE_AC):
+#endif /* DOT11_VHT_AC */
+ 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;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UINT apidx;
+
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ MlmeUpdateTxRates(pAd, FALSE, apidx);
+ }
+#ifdef WDS_SUPPORT
+ for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++)
+ {
+ MlmeUpdateTxRates(pAd, FALSE, apidx + MIN_NET_DEVICE_FOR_WDS);
+ }
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++)
+ {
+ MlmeUpdateTxRates(pAd, FALSE, apidx + MIN_NET_DEVICE_FOR_APCLI);
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_VHT_AC
+ SetCommonVHT(pAd);
+#endif /* DOT11_VHT_AC */
+}
+
+
+/*
+ ========================================================================
+ 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_AP_SUPPORT
+ BOOLEAN IEEE8021X = FALSE;
+#endif /* CONFIG_AP_SUPPORT */
+
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (BssIdx >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ if (pEntry)
+ BssIdx -= MIN_NET_DEVICE_FOR_APCLI;
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPAddWcidAttributeEntry: AP-Client link doesn't need to set Group WCID Attribute. \n"));
+ return;
+ }
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (BssIdx >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ if (pEntry)
+ BssIdx = BSS0;
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPAddWcidAttributeEntry: WDS link doesn't need to set Group WCID Attribute. \n"));
+ return;
+ }
+ }
+ else
+#endif /* WDS_SUPPORT */
+ {
+ if (BssIdx >= pAd->ApCfg.BssidNum)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for MBSSID link. \n", BssIdx));
+ return;
+ }
+ }
+
+ /* choose wcid number*/
+ if (pEntry)
+ Wcid = pEntry->Aid;
+ else
+ GET_GroupKey_WCID(pAd, Wcid, BssIdx);
+
+#ifdef DOT1X_SUPPORT
+ if ((BssIdx < pAd->ApCfg.BssidNum) && (BssIdx < MAX_MBSSID_NUM(pAd)) && (BssIdx < HW_BEACON_MAX_NUM))
+ IEEE8021X = pAd->ApCfg.MBSSID[BssIdx].IEEE8021X;
+#endif /* DOT1X_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ /* Update WCID attribute table*/
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /*
+ 1. Wds-links and Mesh-links always use Pair-wise key table.
+ 2. When the CipherAlg is TKIP, AES 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.
+ */
+ if (pEntry && (IS_ENTRY_WDS(pEntry) || IS_ENTRY_MESH(pEntry)))
+ WCIDAttri = (BssIdx<<4) | (CipherAlg<<1) | PAIRWISEKEYTABLE;
+ else if ((pEntry) &&
+ ((CipherAlg == CIPHER_TKIP) ||
+ (CipherAlg == CIPHER_AES) ||
+ (CipherAlg == CIPHER_NONE) ||
+ (IEEE8021X == TRUE)))
+ WCIDAttri = (BssIdx<<4) | (CipherAlg<<1) | PAIRWISEKEYTABLE;
+ else
+ WCIDAttri = (BssIdx<<4) | (CipherAlg<<1) | SHAREDKEYTABLE;
+ }
+#endif /* CONFIG_AP_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";
+#ifdef WAPI_SUPPORT
+ if(enc == Ndis802_11EncryptionSMS4Enabled)
+ return "SMS4";
+#endif /* WAPI_SUPPORT */
+ 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";
+#ifdef WAPI_SUPPORT
+ if(auth == Ndis802_11AuthModeWAICERT)
+ return "WAI-CERT";
+ if(auth == Ndis802_11AuthModeWAIPSK)
+ return "WAI-PSK";
+#endif /* WAPI_SUPPORT */
+
+ 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*/
+
+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*/
+ RTMPZeroMemory(SecurityStr, 32);
+ 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;
+
+
+ TotalLen = sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len) + 100;
+
+ if (wrq->u.data.length == 0)
+ BufLen = IW_SCAN_MAX_DATA;
+ else
+ BufLen = wrq->u.data.length;
+
+ 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 WSC_INCLUDED
+ sprintf(msg+strlen(msg)-1,"%-4s%-5s\n", " WPS", " DPID");
+#endif /* WSC_INCLUDED */
+
+
+ WaitCnt = 0;
+
+ while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
+ OS_WAIT(500);
+
+ for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
+ {
+ pBss = &pAdapter->ScanTab.BssEntry[i];
+
+ if( pBss->Channel==0)
+ break;
+
+ if((strlen(msg)+100 ) >= BufLen)
+ break;
+
+
+ RTMPCommSiteSurveyData(msg, pBss, TotalLen);
+
+#ifdef WSC_INCLUDED
+ /*WPS*/
+ if (pBss->WpsAP & 0x01)
+ sprintf(msg+strlen(msg)-1,"%-4s", " YES");
+ else
+ sprintf(msg+strlen(msg)-1,"%-4s", " NO");
+
+ if (pBss->WscDPIDFromWpsAP == DEV_PASS_ID_PIN)
+ sprintf(msg+strlen(msg),"%-5s\n", " PIN");
+ else if (pBss->WscDPIDFromWpsAP == DEV_PASS_ID_PBC)
+ sprintf(msg+strlen(msg),"%-5s\n", " PBC");
+ else
+ sprintf(msg+strlen(msg),"%-5s\n", " ");
+#endif /* WSC_INCLUDED */
+
+ }
+
+ 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) /* "\n"+Addr+aid+psm+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;
+ RT_802_11_MAC_ENTRY *pDst;
+ MAC_TABLE_ENTRY *pEntry;
+ 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;
+ }
+
+ NdisZeroMemory(pMacTab, sizeof(RT_802_11_MAC_TABLE));
+ pMacTab->Num = 0;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &(pAd->MacTab.Content[i]);
+
+ if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC))
+ {
+ pDst = &pMacTab->Entry[pMacTab->Num];
+
+
+ pDst->ApIdx = (UCHAR)pEntry->apidx;
+ COPY_MAC_ADDR(pDst->Addr, &pEntry->Addr);
+ pDst->Aid = (UCHAR)pEntry->Aid;
+ pDst->Psm = pEntry->PsMode;
+#ifdef DOT11_N_SUPPORT
+ pDst->MimoPs = pEntry->MmpsMode;
+#endif /* DOT11_N_SUPPORT */
+
+ /* Fill in RSSI per entry*/
+ pDst->AvgRssi0 = pEntry->RssiSample.AvgRssi0;
+ pDst->AvgRssi1 = pEntry->RssiSample.AvgRssi1;
+ pDst->AvgRssi2 = pEntry->RssiSample.AvgRssi2;
+
+ /* the connected time per entry*/
+ pDst->ConnectedTime = pEntry->StaConnectTime;
+ pDst->TxRate.word = pEntry->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; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.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
+#ifdef CONFIG_AP_SUPPORT
+VOID RTMPAR9IoctlGetMacTable(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ INT i;
+ char *msg;
+
+/* 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__));
+ return;
+ }
+ 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; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.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*/
+ wrq->u.data.length = strlen(msg);
+ if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s", msg));
+ }
+
+/* kfree(msg);*/
+ os_free_mem(NULL, msg);
+}
+
+VOID RTMPIoctlGetSTAT2(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ char *msg;
+ PMULTISSID_STRUCT pMbss;
+ INT apidx;
+
+
+/* msg = kmalloc(sizeof(CHAR)*(pAd->ApCfg.BssidNum*(14*128)), MEM_ALLOC_FLAG);*/
+ os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR)*(pAd->ApCfg.BssidNum*(14*128)));
+ if (msg == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
+ return;
+ }
+ memset(msg, 0 ,pAd->ApCfg.BssidNum*(14*128));
+ sprintf(msg,"%s","\n");
+
+ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
+ {
+ pMbss=&pAd->ApCfg.MBSSID[apidx];
+
+ sprintf(msg+strlen(msg),"ra%d\n",apidx);
+ sprintf(msg+strlen(msg),"bytesTx = %ld\n",(pMbss->TransmittedByteCount));
+ sprintf(msg+strlen(msg),"bytesRx = %ld\n",(pMbss->ReceivedByteCount));
+ sprintf(msg+strlen(msg),"pktsTx = %ld\n",pMbss->TxCount);
+ sprintf(msg+strlen(msg),"pktsRx = %ld\n",pMbss->RxCount);
+ sprintf(msg+strlen(msg),"errorsTx = %ld\n",pMbss->TxErrorCount);
+ sprintf(msg+strlen(msg),"errorsRx = %ld\n",pMbss->RxErrorCount);
+ sprintf(msg+strlen(msg),"discardPktsTx = %ld\n",pMbss->TxDropCount);
+ sprintf(msg+strlen(msg),"discardPktsRx = %ld\n",pMbss->RxDropCount);
+ sprintf(msg+strlen(msg),"ucPktsTx = %ld\n",pMbss->ucPktsTx);
+ sprintf(msg+strlen(msg),"ucPktsRx = %ld\n",pMbss->ucPktsRx);
+ sprintf(msg+strlen(msg),"mcPktsTx = %ld\n",pMbss->mcPktsTx);
+ sprintf(msg+strlen(msg),"mcPktsRx = %ld\n",pMbss->mcPktsRx);
+ sprintf(msg+strlen(msg),"bcPktsTx = %ld\n",pMbss->bcPktsTx);
+ sprintf(msg+strlen(msg),"bcPktsRx = %ld\n",pMbss->bcPktsRx);
+
+ }
+
+ wrq->u.data.length = strlen(msg);
+ if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s", msg));
+ }
+
+/* kfree(msg);*/
+ os_free_mem(NULL, msg);
+}
+
+
+VOID RTMPIoctlGetRadioDynInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ char *msg;
+ PMULTISSID_STRUCT pMbss;
+ INT status,bandwidth,ShortGI;
+
+
+/* msg = kmalloc(sizeof(CHAR)*(4096), MEM_ALLOC_FLAG);*/
+ os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR)*(4096));
+ if (msg == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
+ return;
+ }
+ memset(msg, 0 ,4096);
+ sprintf(msg,"%s","\n");
+
+
+ pMbss=&pAd->ApCfg.MBSSID[0];
+ if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ status = 0;
+ else
+ status = 1;
+
+ if(pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40)
+ bandwidth = 1;
+ else
+ bandwidth = 0;
+
+ if(pAd->CommonCfg.RegTransmitSetting.field.ShortGI == GI_800)
+ ShortGI = 1;
+ else
+ ShortGI = 0;
+
+
+ sprintf(msg+strlen(msg),"status = %d\n",status);
+ sprintf(msg+strlen(msg),"channelsInUse = %d\n",pAd->ChannelListNum);
+ sprintf(msg+strlen(msg),"channel = %d\n",pAd->CommonCfg.Channel);
+ sprintf(msg+strlen(msg),"chanWidth = %d\n",bandwidth);
+ sprintf(msg+strlen(msg),"guardIntvl = %d\n",ShortGI);
+ sprintf(msg+strlen(msg),"MCS = %d\n",pMbss->DesiredTransmitSetting.field.MCS);
+
+ wrq->u.data.length = strlen(msg);
+
+ if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s", msg));
+ }
+
+/* kfree(msg);*/
+ os_free_mem(NULL, msg);
+}
+#endif/*CONFIG_AP_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_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef DOT11N_SS3_SUPPORT
+ if (pAd->CommonCfg.TxStream >= 3)
+ ValidMcs = 23;
+#endif /* DOT11N_SS3_SUPPORT */
+
+ Mcs_tmp = simple_strtol(arg, 0, 10);
+
+ if (Mcs_tmp <= ValidMcs || Mcs_tmp == 32)
+ HtMcs = Mcs_tmp;
+ else
+ HtMcs = MCS_AUTO;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].DesiredTransmitSetting.field.MCS = HtMcs;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d) for ra%d\n",
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].DesiredTransmitSetting.field.MCS, pObj->ioctl_if));
+ }
+#endif /* CONFIG_AP_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);
+
+#ifdef CONFIG_AP_SUPPORT
+ /* Intel IOT*/
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ Value = 64;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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;
+}
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set Tx Stream number
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_HtTxStream_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if ((Value <= 3) && (Value >= 1) && (Value <= pAd->Antenna.field.TxPath)) /* 3*3*/
+ pAd->CommonCfg.TxStream = Value;
+ else
+ pAd->CommonCfg.TxStream = pAd->Antenna.field.TxPath;
+
+ if ((pAd->MACVersion < RALINK_2883_VERSION) &&
+ (pAd->CommonCfg.TxStream > 2))
+ {
+ pAd->CommonCfg.TxStream = 2; /* only 2 TX streams for RT2860 series*/
+ }
+
+ SetCommonHT(pAd);
+
+ APStop(pAd);
+ APStartUp(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtTxStream_Proc::(Tx Stream=%d)\n",pAd->CommonCfg.TxStream));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Rx Stream number
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_HtRxStream_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if ((Value <= 3) && (Value >= 1) && (Value <= pAd->Antenna.field.RxPath))
+ pAd->CommonCfg.RxStream = Value;
+ else
+ pAd->CommonCfg.RxStream = pAd->Antenna.field.RxPath;
+
+ if ((pAd->MACVersion < RALINK_2883_VERSION) &&
+ (pAd->CommonCfg.RxStream > 2)) /* 3*3*/
+ {
+ pAd->CommonCfg.RxStream = 2; /* only 2 RX streams for RT2860 series*/
+ }
+
+ SetCommonHT(pAd);
+
+ APStop(pAd);
+ APStartUp(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRxStream_Proc::(Rx Stream=%d)\n",pAd->CommonCfg.RxStream));
+
+ return TRUE;
+}
+
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+INT Set_GreenAP_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ {
+ pAd->ApCfg.bGreenAPActive=FALSE;
+ pAd->ApCfg.bGreenAPEnable = FALSE;
+ }
+ else if (Value == 1)
+ pAd->ApCfg.bGreenAPEnable = TRUE;
+ else
+ return FALSE; /*Invalid argument*/
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_GreenAP_Proc::(bGreenAPEnable=%d)\n",pAd->ApCfg.bGreenAPEnable));
+
+ return TRUE;
+}
+#endif /* GREENAP_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+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 */
+
+
+#ifdef DOT11_VHT_AC
+INT Set_VhtBw_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+ ULONG vht_cw;
+ UCHAR cent_ch;
+ vht_cw = simple_strtol(arg, 0, 10);
+
+
+ if (vht_cw == VHT_BW_80)
+ pAd->CommonCfg.vht_bw = VHT_BW_80;
+ else
+ pAd->CommonCfg.vht_bw = VHT_BW_2040;
+
+#ifdef DOT11_VHT_AC
+ if (!WMODE_CAP_AC(pAd->CommonCfg.PhyMode))
+ goto direct_done;
+
+ SetCommonHT(pAd);
+ if(pAd->CommonCfg.BBPCurrentBW == BW_80)
+ cent_ch = pAd->CommonCfg.vht_cent_ch;
+ else
+ cent_ch = pAd->CommonCfg.CentralChannel;
+
+ AsicSwitchChannel(pAd, cent_ch, FALSE);
+ AsicLockChannel(pAd, cent_ch);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_%s, PrimaryChannel(%d), %s CentralChannel = %d, apply it immediately\n",
+ (pAd->CommonCfg.BBPCurrentBW == BW_80 ? "80":
+ (pAd->CommonCfg.BBPCurrentBW == BW_40 ? "40" :
+ "20")),
+ pAd->CommonCfg.Channel,
+ (pAd->CommonCfg.BBPCurrentBW == BW_80 ? "VHT" : "HT"), cent_ch));
+
+direct_done:
+#endif /* DOT11_VHT_AC */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_VhtBw_Proc::(VHT_BW=%d)\n", pAd->CommonCfg.vht_bw));
+
+ return TRUE;
+}
+
+
+INT Set_VhtStbc_Proc(
+ IN RTMP_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;
+}
+#endif /* DOT11_VHT_AC */
+
+
+
+INT Set_FixedTxMode_Proc(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+#ifdef CONFIG_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+#endif /* CONFIG_AP_SUPPORT */
+ INT fix_tx_mode = RT_CfgSetFixedTxPhyMode(arg);
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+#endif /* CONFIG_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():(FixedTxMode=%d)\n",
+ __FUNCTION__, 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 */
+
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+/* ---------------------- DEBUG QUEUE ------------------------*/
+
+#define DBQ_LENGTH 512
+#define DBQ_DATA_LENGTH 8
+
+/* Define to include TX and RX HT Control field in log */
+/* #define DBQ_INCLUDE_HTC */
+
+typedef
+struct {
+ UCHAR type; /* type of data*/
+ ULONG timestamp; /* sec/usec timestamp from gettimeofday*/
+ UCHAR data[DBQ_DATA_LENGTH]; /* data*/
+} DBQUEUE_ENTRY;
+
+/* Type field definitions */
+#define DBQ_TYPE_EMPTY 0
+#define DBQ_TYPE_TXWI 0x70 /* TXWI*/
+#define DBQ_TYPE_TXHDR 0x72 /* TX Header*/
+#define DBQ_TYPE_TXFIFO 0x73 /* TX Stat FIFO*/
+#define DBQ_TYPE_RXWI 0x78 /* RXWI uses 0x78 to 0x7A for 5 longs*/
+#define DBQ_TYPE_RXHDR 0x7B /* RX Header*/
+#define DBQ_TYPE_TXQHTC 0x7c /* RX Qos+HT Control field*/
+#define DBQ_TYPE_RXQHTC 0x7d /* RX Qos+HT Control field */
+#define DBQ_TYPE_RALOG 0x7e /* RA Log */
+
+#define DBQ_INIT_SIG 0x4442484E /* 'DBIN' - dbqInit initialized flag*/
+#define DBQ_ENA_SIG 0x4442454E /* 'DBEN' - dbqEnable enabled flag*/
+
+static DBQUEUE_ENTRY dbQueue[DBQ_LENGTH];
+static ULONG dbqTail=0;
+static ULONG dbqEnable=0;
+static ULONG dbqInit=0;
+
+/* dbQueueInit - initialize Debug Queue variables and clear the queue*/
+void dbQueueInit(void)
+{
+ int i;
+
+ for (i=0; i<DBQ_LENGTH; i++)
+ dbQueue[i].type = DBQ_TYPE_EMPTY;
+ dbqTail = 0;
+ dbqInit = DBQ_INIT_SIG;
+}
+
+/* dbQueueEnqueue - enqueue data*/
+void dbQueueEnqueue(UCHAR type, UCHAR *data)
+{
+ DBQUEUE_ENTRY *oldTail;
+ struct timeval tval;
+
+ if (dbqEnable!=DBQ_ENA_SIG || data==NULL)
+ return;
+
+ if (dbqInit!=DBQ_INIT_SIG || dbqTail>=DBQ_LENGTH)
+ dbQueueInit();
+
+ oldTail = &dbQueue[dbqTail];
+
+ /* Advance tail and mark as empty*/
+ if (dbqTail >= DBQ_LENGTH-1)
+ dbqTail = 0;
+ else
+ dbqTail++;
+ dbQueue[dbqTail].type = DBQ_TYPE_EMPTY;
+
+ /* Enqueue data*/
+ oldTail->type = type;
+ do_gettimeofday(&tval);
+ oldTail->timestamp = tval.tv_sec*1000000L + tval.tv_usec;
+ memcpy(oldTail->data, data, DBQ_DATA_LENGTH);
+}
+
+void dbQueueEnqueueTxFrame(UCHAR *pTxWI, UCHAR *pHeader_802_11)
+{
+ dbQueueEnqueue(DBQ_TYPE_TXWI, pTxWI);
+
+ /* 802.11 Header */
+ if (pHeader_802_11 != NULL) {
+ dbQueueEnqueue(DBQ_TYPE_TXHDR, pHeader_802_11);
+#ifdef DBQ_INCLUDE_HTC
+ /* Qos+HT Control field */
+ if ((pHeader_802_11[0] & 0x08) && (pHeader_802_11[1] & 0x80))
+ dbQueueEnqueue(DBQ_TYPE_TXQHTC, pHeader_802_11+24);
+#endif /* DBQ_INCLUDE_HTC */
+ }
+}
+
+void dbQueueEnqueueRxFrame(UCHAR *pRxWI, UCHAR *pHeader_802_11, ULONG flags)
+{
+ /* Ignore Beacons if disabled */
+ if ((flags & DBF_DBQ_NO_BCN) && (pHeader_802_11[0] & 0xfc)==0x80)
+ return;
+
+ /* RXWI */
+ dbQueueEnqueue(DBQ_TYPE_RXWI, pRxWI);
+ if (flags & DBF_DBQ_RXWI_FULL) {
+ dbQueueEnqueue(DBQ_TYPE_RXWI+1, pRxWI+8);
+ dbQueueEnqueue(DBQ_TYPE_RXWI+2, pRxWI+16);
+ }
+
+ /* 802.11 Header */
+ dbQueueEnqueue(DBQ_TYPE_RXHDR, (UCHAR *)pHeader_802_11);
+
+#ifdef DBQ_INCLUDE_HTC
+ /* Qos+HT Control field */
+ if ((pHeader_802_11[0] & 0x08) &&
+ (pHeader_802_11[1] & 0x80))
+ dbQueueEnqueue(DBQ_TYPE_RXQHTC, pHeader_802_11+24);
+#endif /* DBQ_INCLUDE_HTC */
+}
+
+
+/* dbQueueDisplayPhy - Display PHY rate */
+static void dbQueueDisplayPHY(USHORT phyRate)
+{
+ static CHAR *mode[4] = {" C", "oM","mM", "gM"};
+
+ DBGPRINT(RT_DEBUG_OFF, ("%2s%02d %c%c%c%c",
+ //(phyRate>>8) & 0xFF, phyRate & 0xFF,
+ mode[(phyRate>>14) & 0x3], // Mode: c, o, m, g
+ phyRate & 0x7F, // MCS
+ (phyRate & 0x0100)? 'S': 'L', // Guard Int: S or L
+ (phyRate & 0x0080)? '4': '2', // BW: 4 or 2
+ (phyRate & 0x0200)? 'S': 's', // STBC: S or s
+ (phyRate & 0x2000)? 'I': ((phyRate & 0x800)? 'E': '_') // Beamforming: E or I or _
+ ) );
+}
+
+/* dbQueueDump - dump contents of debug queue*/
+static void dbQueueDump(
+ IN PRTMP_ADAPTER pAd,
+ BOOLEAN decode)
+{
+ DBQUEUE_ENTRY *oldTail;
+ int i, origMCS, succMCS;
+ ULONG lastTimestamp=0;
+ BOOLEAN showTimestamp;
+ USHORT phyRate;
+
+ if (dbqInit!=DBQ_INIT_SIG || dbqTail>=DBQ_LENGTH)
+ return;
+
+ oldTail = &dbQueue[dbqTail];
+
+ for (i=0; i<DBQ_LENGTH; i++) {
+ if (++oldTail >= &dbQueue[DBQ_LENGTH])
+ oldTail = dbQueue;
+
+ /* Skip empty entries*/
+ if (oldTail->type == DBQ_TYPE_EMPTY)
+ continue;
+
+ showTimestamp = FALSE;
+
+ switch (oldTail->type) {
+ case 0x70: /* TXWI - 2 longs, MSB to LSB */
+ case 0x78: /* RXWI - 2 longs, MSB to LSB */
+ showTimestamp = TRUE;
+
+ if (decode && oldTail->type==0x70) {
+ DBGPRINT(RT_DEBUG_OFF, ("\nTxWI ") );
+ dbQueueDisplayPHY(oldTail->data[3]*256 + oldTail->data[2]);
+ DBGPRINT(RT_DEBUG_OFF, ("%c s=%03X %02X %s-",
+ (oldTail->data[0] & 0x10)? 'A': '_', // AMPDU
+ (oldTail->data[7]*256 + oldTail->data[6]) & 0xFFF, // Size
+ oldTail->data[5], // WCID
+ (oldTail->data[4] & 0x01)? "AK": "NA" )); // ACK/NACK
+ }
+ else if (decode && oldTail->type==0x78) {
+ DBGPRINT(RT_DEBUG_OFF, ("\nRxWI ") );
+ dbQueueDisplayPHY(oldTail->data[7]*256 + oldTail->data[6]);
+ DBGPRINT(RT_DEBUG_OFF, (" s=%03X %02X %02X%01X-",
+ (oldTail->data[3]*256 + oldTail->data[2]) & 0xFFF, // Size
+ oldTail->data[0], // WCID
+ oldTail->data[5], oldTail->data[4]>>4 )); // Seq Number
+ }
+ else
+ DBGPRINT(RT_DEBUG_OFF, ("\n%cxWI %02X%02X %02X%02X-%02X%02X %02X%02X----",
+ oldTail->type==0x70? 'T': 'R',
+ oldTail->data[3], oldTail->data[2], oldTail->data[1], oldTail->data[0],
+ oldTail->data[7], oldTail->data[6], oldTail->data[5], oldTail->data[4]) );
+ break;
+
+ case 0x79: /* RXWI - next 2 longs, MSB to LSB */
+ if (decode) {
+ DBGPRINT(RT_DEBUG_OFF, ("Rx2 %2d %2d %2d S:%d %d %d ",
+ ConvertToRssi(pAd, (CHAR)oldTail->data[0], RSSI_0),
+ ConvertToRssi(pAd, (CHAR)oldTail->data[1], RSSI_1),
+ ConvertToRssi(pAd, (CHAR)oldTail->data[2], RSSI_2),
+ (oldTail->data[4]*3 + 8)/16,
+ (oldTail->data[5]*3 + 8)/16,
+ (oldTail->data[6]*3 + 8)/16) );
+ }
+ else
+ DBGPRINT(RT_DEBUG_OFF, ("Rx2 %02X%02X %02X%02X-%02X%02X %02X%02X ",
+ oldTail->data[3], oldTail->data[2], oldTail->data[1], oldTail->data[0],
+ oldTail->data[7], oldTail->data[6], oldTail->data[5], oldTail->data[4]) );
+ break;
+
+
+ case 0x7c: /* TX HTC+QoS, 6 bytes, MSB to LSB */
+ case 0x7d: /* RX HTC+QoS, 6 bytes, MSB to LSB */
+ DBGPRINT(RT_DEBUG_OFF, ("%cxHTC H:%02X%02X%02X%02X Q:%02X%02X ",
+ oldTail->type==0x7c? 'T': 'R',
+ oldTail->data[5], oldTail->data[4], oldTail->data[3], oldTail->data[2],
+ oldTail->data[1], oldTail->data[0]) );
+ break;
+
+ case 0x72: /* Tx 802.11 header, MSB to LSB, translate type/subtype*/
+ case 0x7b: /* Rx*/
+ {
+ UCHAR tCode;
+ struct _typeTableEntry {
+ UCHAR code; /* Type/subtype*/
+ CHAR str[4];
+ } *pTab;
+ static struct _typeTableEntry typeTable[] = {
+ {0x00, "mARq"}, {0x01, "mARp"}, {0x02, "mRRq"}, {0x03, "mRRp"},
+ {0x04, "mPRq"}, {0x05, "mPRp"}, {0x08, "mBcn"}, {0x09, "mATI"},
+ {0x0a, "mDis"}, {0x0b, "mAut"}, {0x0c, "mDAu"}, {0x0d, "mAct"},
+ {0x0e, "mANA"},
+ {0x17, "cCWr"}, {0x18, "cBAR"}, {0x19, "cBAc"}, {0x1a, "cPSP"},
+ {0x1b, "cRTS"}, {0x1c, "cCTS"}, {0x1d, "cACK"}, {0x1e, "cCFE"},
+ {0x1f, "cCEA"},
+ {0x20, "dDat"}, {0x21, "dDCA"}, {0x22, "dDCP"}, {0x23, "dDAP"},
+ {0x24, "dNul"}, {0x25, "dCFA"}, {0x26, "dCFP"}, {0x27, "dCAP"},
+ {0x28, "dQDa"}, {0x29, "dQCA"}, {0x2a, "dQCP"}, {0x2b, "dQAP"},
+ {0x2c, "dQNu"}, {0x2e, "dQNP"}, {0x2f, "dQNA"},
+ {0xFF, "RESV"}};
+
+ tCode = ((oldTail->data[0]<<2) & 0x30) | ((oldTail->data[0]>>4) & 0xF);
+ for (pTab=typeTable; pTab->code!=0xFF; pTab++) {
+ if (pTab->code == tCode)
+ break;
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("%cxH %c%c%c%c [%02X%02X %02X%02X] \n",
+ oldTail->type==0x72? 'T': 'R',
+ pTab->str[0], pTab->str[1], pTab->str[2], pTab->str[3],
+ oldTail->data[3], oldTail->data[2], oldTail->data[1], oldTail->data[0]) );
+ }
+ break;
+
+ case 0x73: /* TX STAT FIFO*/
+ showTimestamp = TRUE;
+
+ /* origMCS is limited to 4 bits. Check for case of MCS16 to 23*/
+ origMCS = (oldTail->data[0]>>1) & 0xF;
+ succMCS = (oldTail->data[2] & 0x7F);
+ if (succMCS>origMCS && origMCS<8)
+ origMCS += 16;
+ phyRate = (oldTail->data[3]<<8) + oldTail->data[2];
+
+ DBGPRINT(RT_DEBUG_OFF, ("TxFI %02X%02X%02X%02X=%c%c%c%c%c M%02d/%02d%c%c",
+ oldTail->data[3], oldTail->data[2],
+ oldTail->data[1], oldTail->data[0],
+ (phyRate & 0x0100)? 'S': 'L', /* Guard Int: S or L */
+ (phyRate & 0x0080)? '4': '2', /* BW: 4 or 2 */
+ (phyRate & 0x0200)? 'S': 's', /* STBC: S or s */
+ (phyRate & 0x2000)? 'I': ((phyRate & 0x0800)? 'E': '_'), /* Beamforming: E or I or _ */
+ (oldTail->data[0] & 0x40)? 'A': '_', /* Aggregated: A or _ */
+ succMCS, origMCS, /* MCS: <Final>/<orig> */
+ succMCS==origMCS? ' ': '*', /* Retry: '*' if MCS doesn't match */
+ (oldTail->data[0] & 0x20)? ' ': 'F') ); /* Success/Fail _ or F */
+ break;
+ case 0x7E: /* RA Log info */
+ {
+ struct {USHORT phy; USHORT per; USHORT tp; USHORT bfPer;} *p = (void*)(oldTail->data);
+ DBGPRINT(RT_DEBUG_OFF, ("RALog %02X%02X %d %d %d ",
+ (p->phy>>8) & 0xFF, p->phy & 0xFF, p->per, p->tp, p->bfPer) );
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_OFF, ("%02X %02X%02X %02X%02X %02X%02X %02X%02X ", oldTail->type,
+ oldTail->data[0], oldTail->data[1], oldTail->data[2], oldTail->data[3],
+ oldTail->data[4], oldTail->data[5], oldTail->data[6], oldTail->data[7]) );
+ break;
+ }
+
+ if (showTimestamp)
+ {
+ ULONG t = oldTail->timestamp;
+ ULONG dt = oldTail->timestamp-lastTimestamp;
+
+ DBGPRINT(RT_DEBUG_OFF, ("%lu.%06lu ", t/1000000L, t % 1000000L) );
+
+ if (dt>999999L)
+ DBGPRINT(RT_DEBUG_OFF, ("+%lu.%06lu s\n", dt/1000000L, dt % 1000000L) );
+ else
+ DBGPRINT(RT_DEBUG_OFF, ("+%lu us\n", dt) );
+ lastTimestamp = oldTail->timestamp;
+ }
+ }
+}
+
+/*
+ Set_DebugQueue_Proc - Control DBQueue
+ iwpriv ra0 set DBQueue=dd.
+ dd: 0=>disable, 1=>enable, 2=>dump, 3=>clear, 4=>dump & decode
+*/
+INT Set_DebugQueue_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG argValue = simple_strtol(arg, 0, 10);
+
+ switch (argValue) {
+ case 0:
+ dbqEnable = 0;
+ break;
+ case 1:
+ dbqEnable = DBQ_ENA_SIG;
+ break;
+ case 2:
+ dbQueueDump(pAd, FALSE);
+ break;
+ case 3:
+ dbQueueInit();
+ break;
+ case 4:
+ dbQueueDump(pAd, TRUE);
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+#ifdef STREAM_MODE_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ Set the enable/disable the stream mode
+
+ Arguments:
+ 1: enable for 1SS
+ 2: enable for 2SS
+ 3: enable for 1SS and 2SS
+ 0: disable
+
+ Notes:
+ Currently only support 1SS
+ ========================================================================
+*/
+INT Set_StreamMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT32 streamWord, reg, regAddr;
+
+ if (pAd->chipCap.FlgHwStreamMode == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("chip not supported feature\n"));
+ return FALSE;
+ }
+
+ pAd->CommonCfg.StreamMode = (simple_strtol(arg, 0, 10) & 0x3);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():StreamMode=%d\n", __FUNCTION__, pAd->CommonCfg.StreamMode));
+
+ streamWord = StreamModeRegVal(pAd);
+ for (regAddr = TX_CHAIN_ADDR0_H; regAddr <= TX_CHAIN_ADDR3_H; regAddr += 8)
+ {
+ RTMP_IO_READ32(pAd, regAddr, &reg);
+ reg &= (~0x000F0000);
+ RTMP_IO_WRITE32(pAd, regAddr, streamWord | reg);
+ }
+
+ return TRUE;
+}
+
+
+INT Set_StreamModeMac_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ return FALSE;
+}
+
+
+INT Set_StreamModeMCS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.StreamModeMCS = simple_strtol(arg, 0, 16);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():StreamModeMCS=%02X\n",
+ __FUNCTION__, pAd->CommonCfg.StreamModeMCS));
+
+ return TRUE;
+}
+#endif /* STREAM_MODE_SUPPORT */
+
+
+#ifdef PRE_ANT_SWITCH
+/*
+ Set_PreAntSwitch_Proc - enable/disable Preamble Antenna Switch
+ usage: iwpriv ra0 set PreAntSwitch=[0 | 1]
+*/
+INT Set_PreAntSwitch_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.PreAntSwitch = simple_strtol(arg, 0, 10)!=0;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():(PreAntSwitch=%d)\n",
+ __FUNCTION__, pAd->CommonCfg.PreAntSwitch));
+ return TRUE;
+}
+
+
+/*
+ Set_PreAntSwitchRSSI_Proc - set Preamble Antenna Switch RSSI threshold
+ usage: iwpriv ra0 set PreAntSwitchRSSI=<RSSI threshold in dBm>
+*/
+INT Set_PreAntSwitchRSSI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.PreAntSwitchRSSI = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():(PreAntSwitchRSSI=%d)\n",
+ __FUNCTION__, pAd->CommonCfg.PreAntSwitchRSSI));
+ return TRUE;
+}
+
+/*
+ Set_PreAntSwitchTimeout_Proc - set Preamble Antenna Switch Timeout threshold
+ usage: iwpriv ra0 set PreAntSwitchTimeout=<timeout in seconds, 0=>disabled>
+*/
+INT Set_PreAntSwitchTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.PreAntSwitchTimeout = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():(PreAntSwitchTimeout=%d)\n",
+ __FUNCTION__, pAd->CommonCfg.PreAntSwitchTimeout));
+ return TRUE;
+}
+#endif /* PRE_ANT_SWITCH */
+
+
+
+
+#ifdef CFO_TRACK
+/*
+ Set_CFOTrack_Proc - enable/disable CFOTrack
+ usage: iwpriv ra0 set CFOTrack=[0..8]
+*/
+INT Set_CFOTrack_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.CFOTrack = simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():(CFOTrack=%d)\n",
+ __FUNCTION__, pAd->CommonCfg.CFOTrack));
+ return TRUE;
+}
+#endif /* CFO_TRACK */
+
+
+#ifdef DBG_CTRL_SUPPORT
+INT Set_DebugFlags_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.DebugFlags = simple_strtol(arg, 0, 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_DebugFlags_Proc::(DebugFlags=%02lX)\n", pAd->CommonCfg.DebugFlags));
+ return TRUE;
+}
+#endif /* DBG_CTRL_SUPPORT */
+
+
+
+
+
+
+INT Set_LongRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg)
+{
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+ return TRUE;
+}
+
+INT Set_ShortRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg)
+{
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+ return TRUE;
+}
+
+INT Set_AutoFallBack_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg)
+{
+ return RT_CfgSetAutoFallBack(pAdapter, arg);
+}
+
+
+
+PSTRING RTMPGetRalinkAuthModeStr(
+ IN NDIS_802_11_AUTHENTICATION_MODE authMode)
+{
+ switch(authMode)
+ {
+ case Ndis802_11AuthModeOpen:
+ return "OPEN";
+ case Ndis802_11AuthModeWPAPSK:
+ return "WPAPSK";
+ case Ndis802_11AuthModeShared:
+ return "SHARED";
+ case Ndis802_11AuthModeAutoSwitch:
+ return "WEPAUTO";
+ case Ndis802_11AuthModeWPA:
+ return "WPA";
+ case Ndis802_11AuthModeWPA2:
+ return "WPA2";
+ case Ndis802_11AuthModeWPA2PSK:
+ return "WPA2PSK";
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ return "WPAPSKWPA2PSK";
+ case Ndis802_11AuthModeWPA1WPA2:
+ return "WPA1WPA2";
+ case Ndis802_11AuthModeWPANone:
+ return "WPANONE";
+ default:
+ return "UNKNOW";
+ }
+}
+
+PSTRING RTMPGetRalinkEncryModeStr(
+ IN USHORT encryMode)
+{
+ switch(encryMode)
+ {
+ case Ndis802_11WEPDisabled:
+ return "NONE";
+ case Ndis802_11WEPEnabled:
+ return "WEP";
+ case Ndis802_11Encryption2Enabled:
+ return "TKIP";
+ case Ndis802_11Encryption3Enabled:
+ return "AES";
+ case Ndis802_11Encryption4Enabled:
+ return "TKIPAES";
+ default:
+ return "UNKNOW";
+ }
+}
+
+
+INT Show_SSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ UCHAR ssid_str[33];
+
+
+ NdisZeroMemory(&ssid_str[0], 33);
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ NdisMoveMemory(&ssid_str[0],
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid,
+ pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen);
+ }
+#endif /* CONFIG_AP_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 (WMODE_B | WMODE_G):
+ snprintf(pBuf, BufLen, "\t11B/G");
+ break;
+ case (WMODE_B):
+ snprintf(pBuf, BufLen, "\t11B");
+ break;
+ case (WMODE_A):
+ snprintf(pBuf, BufLen, "\t11A");
+ break;
+ case (WMODE_A | WMODE_B | WMODE_G):
+ snprintf(pBuf, BufLen, "\t11A/B/G");
+ break;
+ case (WMODE_G):
+ snprintf(pBuf, BufLen, "\t11G");
+ break;
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_A | WMODE_B | WMODE_G | WMODE_GN | WMODE_AN):
+ snprintf(pBuf, BufLen, "\t11A/B/G/N");
+ break;
+ case (WMODE_GN):
+ snprintf(pBuf, BufLen, "\t11N only with 2.4G");
+ break;
+ case (WMODE_G | WMODE_GN):
+ snprintf(pBuf, BufLen, "\t11G/N");
+ break;
+ case (WMODE_A | WMODE_AN):
+ snprintf(pBuf, BufLen, "\t11A/N");
+ break;
+ case (WMODE_B | WMODE_G | WMODE_GN):
+ snprintf(pBuf, BufLen, "\t11B/G/N");
+ break;
+ case (WMODE_A | WMODE_G | WMODE_GN | WMODE_AN):
+ snprintf(pBuf, BufLen, "\t11A/G/N");
+ break;
+ case (WMODE_AN):
+ 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_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ snprintf(pBuf, BufLen, "\t%u", pAd->ApCfg.MBSSID[pObj->ioctl_if].DesiredTransmitSetting.field.MCS);
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ snprintf(pBuf, BufLen, "\t%s", pAd->ApCfg.MBSSID[pObj->ioctl_if].bWmmCapable ? "TRUE":"FALSE");
+#endif /* CONFIG_AP_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;
+}
+
+
+INT Show_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
+#ifdef CONFIG_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AuthMode = pAd->ApCfg.MBSSID[pObj->ioctl_if].AuthMode;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if ((AuthMode >= Ndis802_11AuthModeOpen) &&
+ (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ snprintf(pBuf, BufLen, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
+#ifdef WAPI_SUPPORT
+ else if (AuthMode == Ndis802_11AuthModeWAICERT)
+ snprintf(pBuf, BufLen, "\t%s", "WAI_CERT");
+ else if (AuthMode == Ndis802_11AuthModeWAIPSK)
+ snprintf(pBuf, BufLen, "\t%s", "WAI_PSK");
+#endif /* WAPI_SUPPORT */
+ 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_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ WepStatus = pAd->ApCfg.MBSSID[pObj->ioctl_if].WepStatus;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if ((WepStatus >= Ndis802_11WEPEnabled) &&
+ (WepStatus <= Ndis802_11Encryption4KeyAbsent))
+ snprintf(pBuf, BufLen, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
+#ifdef WAPI_SUPPORT
+ else if (WepStatus == Ndis802_11EncryptionSMS4Enabled)
+ snprintf(pBuf, BufLen, "\t%s", "WPI_SMS4");
+#endif /* WAPI_SUPPORT */
+ 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_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ DefaultKeyId = pAd->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId;
+#endif /* CONFIG_AP_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;
+#ifdef CONFIG_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ index = pObj->ioctl_if;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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_AP_SUPPORT
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ NdisMoveMemory(PMK, pAd->ApCfg.MBSSID[pObj->ioctl_if].PMK, 32);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ sprintf(pBuf, "\tPMK = ");
+ for (idx = 0; idx < 32; idx++)
+ sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
+
+ return 0;
+}
+
+
+INT Show_STA_RAInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ sprintf(pBuf, "\n");
+#ifdef PRE_ANT_SWITCH
+ sprintf(pBuf+strlen(pBuf), "PreAntSwitch: %d\n", pAd->CommonCfg.PreAntSwitch);
+ sprintf(pBuf+strlen(pBuf), "PreAntSwitchRSSI: %d\n", pAd->CommonCfg.PreAntSwitchRSSI);
+#endif /* PRE_ANT_SWITCH */
+
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ sprintf(pBuf+strlen(pBuf), "LowTrafficThrd: %d\n", pAd->CommonCfg.lowTrafficThrd);
+ sprintf(pBuf+strlen(pBuf), "TrainUpRule: %d\n", pAd->CommonCfg.TrainUpRule);
+ sprintf(pBuf+strlen(pBuf), "TrainUpRuleRSSI: %d\n", pAd->CommonCfg.TrainUpRuleRSSI);
+ sprintf(pBuf+strlen(pBuf), "TrainUpLowThrd: %d\n", pAd->CommonCfg.TrainUpLowThrd);
+ sprintf(pBuf+strlen(pBuf), "TrainUpHighThrd: %d\n", pAd->CommonCfg.TrainUpHighThrd);
+#endif // NEW_RATE_ADAPT_SUPPORT //
+
+#ifdef STREAM_MODE_SUPPORT
+ sprintf(pBuf+strlen(pBuf), "StreamMode: %d\n", pAd->CommonCfg.StreamMode);
+ sprintf(pBuf+strlen(pBuf), "StreamModeMCS: 0x%04x\n", pAd->CommonCfg.StreamModeMCS);
+#endif // STREAM_MODE_SUPPORT //
+#ifdef TXBF_SUPPORT
+ sprintf(pBuf+strlen(pBuf), "ITxBfEn: %d\n", pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn);
+ sprintf(pBuf+strlen(pBuf), "ITxBfTimeout: %ld\n", pAd->CommonCfg.ITxBfTimeout);
+ sprintf(pBuf+strlen(pBuf), "ETxBfTimeout: %ld\n", pAd->CommonCfg.ETxBfTimeout);
+ sprintf(pBuf+strlen(pBuf), "ETxBfEnCond: %ld\n", pAd->CommonCfg.ETxBfEnCond);
+ sprintf(pBuf+strlen(pBuf), "ETxBfNoncompress: %d\n", pAd->CommonCfg.ETxBfNoncompress);
+ sprintf(pBuf+strlen(pBuf), "ETxBfIncapable: %d\n", pAd->CommonCfg.ETxBfIncapable);
+#endif // TXBF_SUPPORT //
+
+#ifdef DBG_CTRL_SUPPORT
+ sprintf(pBuf+strlen(pBuf), "DebugFlags: 0x%lx\n", pAd->CommonCfg.DebugFlags);
+#endif /* DBG_CTRL_SUPPORT */
+ return 0;
+}
+
+
+INT Show_MacTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+ UINT32 RegValue;
+ ULONG DataRate=0;
+
+ printk("\n");
+ RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+ printk("BackOff Slot : %s slot time, BKOFF_SLOT_CFG(0x1104) = 0x%08x\n",
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED) ? "short" : "long",
+ RegValue);
+
+#ifdef DOT11_N_SUPPORT
+ printk("HT Operating Mode : %d\n", pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
+ printk("\n");
+#endif /* DOT11_N_SUPPORT */
+
+ printk("\n%-19s%-4s%-4s%-4s%-4s%-8s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s%-7s%-7s\n",
+ "MAC", "AID", "BSS", "PSM", "WMM", "MIMOPS", "RSSI0", "RSSI1",
+ "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC", "Idle", "Rate");
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+
+ if ((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry))
+ && (pEntry->Sst == SST_ASSOC))
+ {
+ DataRate=0;
+ getRate(pEntry->HTPhyMode, &DataRate);
+
+
+ printk("%02X:%02X:%02X:%02X:%02X:%02X ", PRINT_MAC(pEntry->Addr));
+ printk("%-4d", (int)pEntry->Aid);
+ printk("%-4d", (int)pEntry->apidx);
+ printk("%-4d", (int)pEntry->PsMode);
+ printk("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE));
+#ifdef DOT11_N_SUPPORT
+ printk("%-8d", (int)pEntry->MmpsMode);
+#endif /* DOT11_N_SUPPORT */
+ printk("%-7d", pEntry->RssiSample.AvgRssi0);
+ printk("%-7d", pEntry->RssiSample.AvgRssi1);
+ printk("%-7d", pEntry->RssiSample.AvgRssi2);
+ printk("%-10s", get_phymode_str(pEntry->HTPhyMode.field.MODE));
+ printk("%-6s", get_bw_str(pEntry->HTPhyMode.field.BW));
+#ifdef DOT11_VHT_AC
+ if (pEntry->HTPhyMode.field.MODE == MODE_VHT)
+ printk("%dS-M%d", ((pEntry->HTPhyMode.field.MCS>>4) + 1), (pEntry->HTPhyMode.field.MCS & 0xf));
+ else
+#endif /* DOT11_VHT_AC */
+ printk("%-6d", pEntry->HTPhyMode.field.MCS);
+ printk("%-6d", pEntry->HTPhyMode.field.ShortGI);
+ printk("%-6d", pEntry->HTPhyMode.field.STBC);
+ printk("%-7d", (int)(pEntry->StaIdleTimeout - pEntry->NoDataIdleCount));
+ printk("%-7d", (int)DataRate);
+ printk("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
+ (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
+
+ printk("\t\t\t\t%-10s", get_phymode_str(pEntry->MaxHTPhyMode.field.MODE));
+ printk("%-6s", get_bw_str(pEntry->MaxHTPhyMode.field.BW));
+#ifdef DOT11_VHT_AC
+ if (pEntry->MaxHTPhyMode.field.MODE == MODE_VHT)
+ printk("%dS-M%d", ((pEntry->MaxHTPhyMode.field.MCS>>4) + 1), (pEntry->MaxHTPhyMode.field.MCS & 0xf));
+ else
+#endif /* DOT11_VHT_AC */
+ printk("%-6d", pEntry->MaxHTPhyMode.field.MCS);
+ printk("%-6d", pEntry->MaxHTPhyMode.field.ShortGI);
+ printk("%-6d\n", pEntry->MaxHTPhyMode.field.STBC);
+
+ printk("\n");
+ }
+ }
+
+ return TRUE;
+}
+
+
+INT show_devinfo_proc(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ UCHAR *pstr;
+
+
+ DBGPRINT(RT_DEBUG_OFF, ("Device MAC\n"));
+ if (pAd->OpMode == OPMODE_AP)
+ pstr = "AP";
+ else if (pAd->OpMode == OPMODE_STA)
+ pstr = "STA";
+ else
+ pstr = "Unknown";
+ DBGPRINT(RT_DEBUG_OFF, ("Operation Mode: %s\n", pstr));
+
+ pstr = wmode_2_str(pAd->CommonCfg.PhyMode);
+ if (pstr) {
+ DBGPRINT(RT_DEBUG_OFF, ("WirelessMode: %s(%d)\n", pstr, pAd->CommonCfg.PhyMode));
+ os_free_mem(pAd, pstr);
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("Channel: %d\n", pAd->CommonCfg.Channel));
+ DBGPRINT(RT_DEBUG_OFF, ("\tCentralChannel: %d\n", pAd->CommonCfg.CentralChannel));
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode))
+ DBGPRINT(RT_DEBUG_OFF, ("\tVHT CentralChannel: %d\n", pAd->CommonCfg.vht_cent_ch));
+#endif /* DOT11_VHT_AC */
+ DBGPRINT(RT_DEBUG_OFF, ("\tRF Channel: %d\n", pAd->LatchRfRegs.Channel));
+
+ DBGPRINT(RT_DEBUG_OFF, ("Bandwidth\n"));
+ pstr = (pAd->CommonCfg.RegTransmitSetting.field.BW) ? "20/40" : "20";
+ DBGPRINT(RT_DEBUG_OFF, ("\tHT-BW: %s\n", pstr));
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode))
+ {
+ if (pAd->CommonCfg.vht_bw)
+ pstr = "80";
+ DBGPRINT(RT_DEBUG_OFF, ("\tVHT-BW: %s\n", pstr));
+ }
+#endif /* DOT11_VHT_AC */
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ {
+ dump_bw_info(pAd);
+ }
+#endif /* RT65xx */
+
+ DBGPRINT(RT_DEBUG_OFF, ("Security\n"));
+
+ DBGPRINT(RT_DEBUG_OFF, ("MAC Ver: %s\n", MAC_VERSION));
+ DBGPRINT(RT_DEBUG_OFF, ("BBP Ver: %s\n", BBP_VERSION));
+ DBGPRINT(RT_DEBUG_OFF, ("RF Ver: %s\n", RF_VERSION));
+
+ return TRUE;
+}
+
+
+#ifdef WSC_STA_SUPPORT
+INT Show_WpsManufacturer_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ sprintf(pBuf, "\tManufacturer = %s", pAd->StaCfg.WscControl.RegData.SelfInfo.Manufacturer);
+ return 0;
+}
+
+INT Show_WpsModelName_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ sprintf(pBuf, "\tModelName = %s", pAd->StaCfg.WscControl.RegData.SelfInfo.ModelName);
+ return 0;
+}
+
+INT Show_WpsDeviceName_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ sprintf(pBuf, "\tDeviceName = %s", pAd->StaCfg.WscControl.RegData.SelfInfo.DeviceName);
+ return 0;
+}
+
+INT Show_WpsModelNumber_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ sprintf(pBuf, "\tModelNumber = %s", pAd->StaCfg.WscControl.RegData.SelfInfo.ModelNumber);
+ return 0;
+}
+
+INT Show_WpsSerialNumber_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ sprintf(pBuf, "\tSerialNumber = %s", pAd->StaCfg.WscControl.RegData.SelfInfo.SerialNumber);
+ return 0;
+}
+
+INT Show_WpsUuid_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ UCHAR *bin = pAd->StaCfg.WscControl.RegData.SelfInfo.Uuid;
+
+ sprintf(pBuf, "\tUuid = %02x%02x%02x%02x-%02x%02x-%02x%02x-"
+ "%02x%02x-%02x%02x%02x%02x%02x%02x",
+ bin[0], bin[1], bin[2], bin[3],
+ bin[4], bin[5], bin[6], bin[7],
+ bin[8], bin[9], bin[10], bin[11],
+ bin[12], bin[13], bin[14], bin[15]);
+
+ return 0;
+}
+#endif /* WSC_STA_SUPPORT */
+
+
+#ifdef SINGLE_SKU
+INT Show_ModuleTxpower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PSTRING pBuf,
+ IN ULONG BufLen)
+{
+ snprintf(pBuf, BufLen, "\tModuleTxpower = %d", pAd->CommonCfg.ModuleTxpower);
+ return 0;
+}
+#endif /* SINGLE_SKU */
+
+#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;
+
+
+ DBGPRINT(RT_DEBUG_OFF, ("=============================================================\n"));
+ if((pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState == APCLI_CTRL_CONNECTED)
+ && (pAd->ApCfg.ApCliTab[ifIndex].SsidLen != 0))
+ {
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+
+ if ( IS_ENTRY_APCLI(pEntry)
+ && (pEntry->Sst == SST_ASSOC)
+ && (pEntry->PortSecured == WPA_802_1X_PORT_SECURED))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("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)
+ DBGPRINT(RT_DEBUG_OFF, ("ApCli%d Connected AP : Disconnect\n",ifIndex));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("ApCli%d Connected AP : Disconnect\n",ifIndex));
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("=============================================================\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;
+}
+
+
+#ifdef TXBF_SUPPORT
+
+/*
+ Set_ReadITxBf_Proc - Read Implicit BF profile and display it
+ iwpriv ra0 set ReadITxBf=<profile number>
+*/
+INT Set_ReadITxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int profileNum = simple_strtol(arg, 0, 10);
+ int scIndex, i, maxCarriers;
+
+ Read_TxBfProfile(pAd, &profData, profileNum, TRUE);
+
+ /* Display profile. Note: each column is displayed as a row. This shortens the display */
+ DBGPRINT(RT_DEBUG_OFF, ("---ITxBF Profile: %d - %dx%d, %dMHz\n",
+ profileNum, profData.rows, profData.columns, profData.fortyMHz? 40: 20));
+
+ maxCarriers = profData.fortyMHz? PROFILE_MAX_CARRIERS_40: PROFILE_MAX_CARRIERS_20;
+
+ for (scIndex=0; scIndex<maxCarriers; scIndex++) {
+ for (i=0; i<profData.rows; i++) {
+ DBGPRINT(RT_DEBUG_OFF, ("%d %d ", Unpack_IBFValue(profData.data[scIndex], 2*i+1), Unpack_IBFValue(profData.data[scIndex], 2*i)));
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+
+ if (profData.columns>1) {
+ for (i=0; i<profData.rows; i++) {
+ DBGPRINT(RT_DEBUG_OFF, ("%d %d ", Unpack_IBFValue(profData.data[scIndex], 2*i+7), Unpack_IBFValue(profData.data[scIndex], 2*i+6)));
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ Set_ReadETxBf_Proc - Read Explicit BF profile and display it
+ usage: iwpriv ra0 set ReadETxBf=<profile number>
+*/
+INT Set_ReadETxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int profileNum = simple_strtol(arg, 0, 10);
+ int scIndex, i, maxCarriers;
+
+ Read_TxBfProfile(pAd, &profData, profileNum, FALSE);
+
+ /* Dump ETxBF profile values. Note: each column is displayed as a row. This shortens the display */
+ DBGPRINT(RT_DEBUG_OFF, ("---ETxBF Profile: %d - %dx%d, %dMHz, grp=%d\n",
+ profileNum, profData.rows, profData.columns, profData.fortyMHz? 40: 20, profData.grouping));
+
+ maxCarriers = profData.fortyMHz? PROFILE_MAX_CARRIERS_40: PROFILE_MAX_CARRIERS_20;
+
+ for (scIndex=0; scIndex<maxCarriers; scIndex++) {
+ for (i=0; i<profData.rows; i++) {
+ DBGPRINT(RT_DEBUG_OFF, ("%d %d\t", (CHAR)(profData.data[scIndex][6*i]), (CHAR)(profData.data[scIndex][6*i+1]) ));
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+
+ if (profData.columns>1) {
+ for (i=0; i<profData.rows; i++) {
+ DBGPRINT(RT_DEBUG_OFF, ("%d %d ", (CHAR)(profData.data[scIndex][6*i+2]), (CHAR)(profData.data[scIndex][6*i+3]) ));
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+ }
+
+ if (profData.columns>2) {
+ for (i=0; i<profData.rows; i++) {
+ DBGPRINT(RT_DEBUG_OFF, ("%d %d ", (CHAR)(profData.data[scIndex][6*i+4]), (CHAR)(profData.data[scIndex][6*i+5]) ));
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ Set_WriteITxBf_Proc - Write Implicit BF matrix
+ usage: iwpriv ra0 set WriteITxBf=<profile number>
+ Assumes profData contains a valid Implicit Profile
+*/
+INT Set_WriteITxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int profileNum = simple_strtol(arg, 0, 10);
+
+ if (!profData.impProfile)
+ return FALSE;
+
+ Write_TxBfProfile(pAd, &profData, profileNum);
+
+ return TRUE;
+}
+
+
+/*
+ Set_WriteETxBf_Proc - Write Explicit BF matrix
+ usage: iwpriv ra0 set WriteETxBf=<profile number>
+ Assumes profData contains a valid Explicit Profile
+*/
+INT Set_WriteETxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int profileNum = simple_strtol(arg, 0, 10);
+
+ if (profData.impProfile)
+ return FALSE;
+
+ Write_TxBfProfile(pAd, &profData, profileNum);
+
+ return TRUE;
+}
+
+
+/*
+ Set_StatITxBf_Proc - Compute power of each chain in Implicit BF matrix
+ usage: iwpriv ra0 set StatITxBf=<profile number>
+*/
+INT Set_StatITxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int scIndex, maxCarriers, i;
+ unsigned long col1Power[3] = {0,0,0}, col2Power[3] = {0,0,0};
+ int profileNum = simple_strtol(arg, 0, 10);
+ PROFILE_DATA *pProfData;
+
+ pProfData = (PROFILE_DATA *)kmalloc(sizeof(PROFILE_DATA), MEM_ALLOC_FLAG);
+ if (pProfData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Set_StatITxBf_Proc: kmalloc failed\n"));
+ return FALSE;
+ }
+
+ Read_TxBfProfile(pAd, pProfData, profileNum, TRUE);
+
+ maxCarriers = pProfData->fortyMHz? PROFILE_MAX_CARRIERS_40: PROFILE_MAX_CARRIERS_20;
+
+ for (scIndex=0; scIndex<maxCarriers; scIndex++) {
+ for (i=0; i<pProfData->rows; i++) {
+ int ival = Unpack_IBFValue(pProfData->data[scIndex], 2*i+1);
+ int qval = Unpack_IBFValue(pProfData->data[scIndex], 2*i);
+ col1Power[i] += ival*ival+qval*qval;
+
+ if (pProfData->columns==2) {
+ ival = Unpack_IBFValue(pProfData->data[scIndex], 2*i+7);
+ qval = Unpack_IBFValue(pProfData->data[scIndex], 2*i+6);
+ col2Power[i] += ival*ival+qval*qval;
+ }
+ }
+ }
+
+ /* Remove implied scale factor of 2^-16. Convert to thousandths */
+ for (i=0; i<pProfData->rows; i++) {
+ col1Power[i] >>= 12;
+ col1Power[i] = ((col1Power[i]*1000)/maxCarriers)>>4;
+ col2Power[i] >>= 12;
+ col2Power[i] = ((col2Power[i]*1000)/maxCarriers)>>4;
+ }
+
+ /* Display stats */
+ DBGPRINT(RT_DEBUG_OFF, ("ITxBF Stats:\n %dx1=[0.%03lu 0.%03lu, 0.%03lu]\n",
+ pProfData->rows, col1Power[0], col1Power[1], col1Power[2]));
+ if (pProfData->columns==2) {
+ DBGPRINT(RT_DEBUG_OFF, (" %dx2=[0.%03lu 0.%03lu, 0.%03lu]\n",
+ pProfData->rows, (col1Power[0]+col2Power[0])/2, (col1Power[1]+col2Power[1])/2,
+ (col1Power[2]+col2Power[2])/2) );
+ }
+
+ kfree(pProfData);
+
+ return TRUE;
+}
+
+/*
+ Set_StatETxBf_Proc - Compute power of each chain in Explicit BF matrix
+ usage: iwpriv ra0 set StatETxBf=<profile number>
+*/
+INT Set_StatETxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int scIndex, maxCarriers, i;
+ unsigned long col1Power[3] = {0,0,0}, col2Power[3] = {0,0,0}, col3Power[3] = {0,0,0};
+ int profileNum = simple_strtol(arg, 0, 10);
+ PROFILE_DATA *pProfData;
+
+ pProfData = (PROFILE_DATA *)kmalloc(sizeof(PROFILE_DATA), MEM_ALLOC_FLAG);
+ if (pProfData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Set_StatETxBf_Proc: kmalloc failed\n"));
+ return FALSE;
+ }
+
+ Read_TxBfProfile(pAd, pProfData, profileNum, FALSE);
+
+ maxCarriers = pProfData->fortyMHz? PROFILE_MAX_CARRIERS_40: PROFILE_MAX_CARRIERS_20;
+
+ for (scIndex=0; scIndex<maxCarriers; scIndex++) {
+ for (i=0; i<pProfData->rows; i++) {
+ int ival = (CHAR)(pProfData->data[scIndex][6*i]);
+ int qval = (CHAR)(pProfData->data[scIndex][6*i+1]);
+ col1Power[i] += ival*ival+qval*qval;
+
+ if (pProfData->columns>1) {
+ ival = (CHAR)(pProfData->data[scIndex][6*i+2]);
+ qval = (CHAR)(pProfData->data[scIndex][6*i+3]);
+ col2Power[i] += ival*ival+qval*qval;
+ }
+
+ if (pProfData->columns>2) {
+ ival = (CHAR)(pProfData->data[scIndex][6*i+4]);
+ qval = (CHAR)(pProfData->data[scIndex][6*i+5]);
+ col3Power[i] += ival*ival+qval*qval;
+ }
+ }
+ }
+
+ /* Remove implied scale factor of 2^-14. Convert to thousandths */
+ for (i=0; i<pProfData->rows; i++) {
+ col1Power[i] >>= 10;
+ col1Power[i] = ((col1Power[i]*1000)/maxCarriers)>>4;
+ col2Power[i] >>= 10;
+ col2Power[i] = ((col2Power[i]*1000)/maxCarriers)>>4;
+ col3Power[i] >>= 10;
+ col3Power[i] = ((col3Power[i]*1000)/maxCarriers)>>4;
+ }
+
+ /* Display stats */
+ DBGPRINT(RT_DEBUG_OFF, ("ETxBF Stats:\n %dx1=[0.%03lu 0.%03lu, 0.%03lu]\n",
+ pProfData->rows, col1Power[0], col1Power[1], col1Power[2]));
+ if (pProfData->columns==2) {
+ DBGPRINT(RT_DEBUG_OFF, (" %dx2=[0.%03lu 0.%03lu, 0.%03lu]\n",
+ pProfData->rows, (col1Power[0]+col2Power[0])/2,
+ (col1Power[1]+col2Power[1])/2, (col1Power[2]+col2Power[2])/2) );
+ }
+ if (pProfData->columns==3) {
+ DBGPRINT(RT_DEBUG_OFF, (" %dx3=[0.%03lu 0.%03lu, 0.%03lu]\n",
+ pProfData->rows, (col1Power[0]+col2Power[0]+col3Power[0])/3,
+ (col1Power[1]+col2Power[1]+col3Power[1])/3,
+ (col1Power[2]+col2Power[2]+col3Power[2])/3) );
+ }
+
+ kfree(pProfData);
+
+ return TRUE;
+}
+
+
+/*
+ Set_TxBfTag_Proc - Display BF Profile Tags
+ usage: "iwpriv ra0 set TxBfTag=n"
+ n: 0=>all,
+ 1=>Explicit,
+ 2=>Implicit,
+ 3=>dump Power table
+*/
+INT Set_TxBfTag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int argVal = simple_strtol(arg, 0, 10);
+ int profileNum;
+
+ if (argVal==0 || argVal==1) {
+ /* Display Explicit tagfield */
+ DBGPRINT(RT_DEBUG_OFF, ("---Explicit TxBfTag:\n"));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 4);
+ for (profileNum=0; profileNum<4; profileNum++)
+ displayTagfield(pAd, profileNum, FALSE);
+ }
+
+ if (argVal==0 || argVal==2) {
+ /* Display Implicit tagfield */
+ DBGPRINT(RT_DEBUG_OFF, ("---Implicit TxBfTag:\n"));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 0);
+ for (profileNum=0; profileNum<4; profileNum++)
+ displayTagfield(pAd, profileNum, TRUE);
+ }
+
+ if (argVal==3) {
+ int i;
+ /* 4. Dump power table */
+ for (i = 0; i < (14 + 12 + 16 + 7); i++)
+ DBGPRINT(RT_DEBUG_OFF, ("%d: Ch%2d=[%d, %d %d]\n", i,
+ pAd->TxPower[i].Channel, pAd->TxPower[i].Power,
+ pAd->TxPower[i].Power2, pAd->TxPower[i].Power3));
+ }
+
+ return TRUE;
+}
+
+
+/*
+ Set_InvTxBfTag_Proc - Invalidate BF Profile Tags
+ usage: "iwpriv ra0 set InvTxBfTag=n"
+ Reset Valid bit and zero out MAC address of each profile. The next profile will be stored in profile 0
+*/
+INT Set_InvTxBfTag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int profileNum;
+ UCHAR row[EXP_MAX_BYTES];
+ UCHAR r163Value = 0;
+
+ /* Disable Profile Updates during access */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R163, &r163Value);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R163, r163Value & ~0x88);
+
+ /* Invalidate Implicit tags */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 0);
+ for (profileNum=0; profileNum<4; profileNum++) {
+ Read_TagField(pAd, row, profileNum);
+ row[0] &= 0x7F;
+ row[1] = row[2] = row[3] = row[4] = row[5] = row[6] = 0xAA;
+ Write_TagField(pAd, row, profileNum);
+ }
+
+ /* Invalidate Explicit tags */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 4);
+ for (profileNum=0; profileNum<4; profileNum++) {
+ Read_TagField(pAd, row, profileNum);
+ row[0] &= 0x7F;
+ row[1] = row[2] = row[3] = row[4] = row[5] = row[6] = 0x55;
+ Write_TagField(pAd, row, profileNum);
+ }
+
+ /* Restore Profile Updates */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R163, r163Value);
+
+ return TRUE;
+}
+
+
+/*
+ Set_ITxBfTimeout_Proc - Set ITxBF timeout value
+ usage: iwpriv ra0 set ITxBfTimeout=<decimal timeout in units of 25 microsecs>
+*/
+INT Set_ITxBfTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG t = simple_strtol(arg, 0, 10);
+
+ if (t > 65535) {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ITxBfTimeout_Proc: value > 65535!\n"));
+ return FALSE;
+ }
+
+ pAd->CommonCfg.ITxBfTimeout = t;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 0x02);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, pAd->CommonCfg.ITxBfTimeout & 0xFF);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 1);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, (pAd->CommonCfg.ITxBfTimeout>>8) & 0xFF);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ITxBfTimeout_Proc::(ITxBfTimeout=%d)\n", (int)pAd->CommonCfg.ITxBfTimeout));
+ return TRUE;
+}
+
+
+/*
+ Set_ETxBfTimeout_Proc - Set ITxBF timeout value
+ usage: iwpriv ra0 set ETxBfTimeout=<decimal timeout in units of 25 microsecs>
+*/
+INT Set_ETxBfTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG t = simple_strtol(arg, 0, 10);
+
+ if (t > 65535) {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ETxBfTimeout_Proc: value > 65535!\n"));
+ return FALSE;
+ }
+
+ pAd->CommonCfg.ETxBfTimeout = t;
+ RTMP_IO_WRITE32(pAd, TX_TXBF_CFG_3, pAd->CommonCfg.ETxBfTimeout);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ETxBfTimeout_Proc::(ETxBfTimeout=%d)\n", (int)pAd->CommonCfg.ETxBfTimeout));
+ return TRUE;
+}
+
+
+/*
+ Set_ETxBfCodebook_Proc - Set ETxBf Codebook
+ usage: iwpriv ra0 set ETxBfCodebook=0 to 3
+*/
+INT Set_ETxBfCodebook_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ TX_TXBF_CFG_0_STRUC regValue;
+ ULONG t = simple_strtol(arg, 0, 10);
+
+ if (t > 3) {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ETxBfCodebook_Proc: value > 3!\n"));
+ return FALSE;
+ }
+
+ RTMP_IO_READ32(pAd, TX_TXBF_CFG_0, &regValue.word);
+ regValue.field.EtxbfFbkCode = t;
+ RTMP_IO_WRITE32(pAd, TX_TXBF_CFG_0, regValue.word);
+ return TRUE;
+}
+
+
+/*
+ Set_ETxBfCoefficient_Proc - Set ETxBf Coefficient
+ usage: iwpriv ra0 set ETxBfCoefficient=0 to 3
+*/
+INT Set_ETxBfCoefficient_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ TX_TXBF_CFG_0_STRUC regValue;
+ ULONG t = simple_strtol(arg, 0, 10);
+
+ if (t > 3) {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ETxBfCoefficient_Proc: value > 3!\n"));
+ return FALSE;
+ }
+
+ RTMP_IO_READ32(pAd, TX_TXBF_CFG_0, &regValue.word);
+ regValue.field.EtxbfFbkCoef = t;
+ RTMP_IO_WRITE32(pAd, TX_TXBF_CFG_0, regValue.word);
+ return TRUE;
+}
+
+
+/*
+ Set_ETxBfGrouping_Proc - Set ETxBf Grouping
+ usage: iwpriv ra0 set ETxBfGrouping=0 to 2
+*/
+INT Set_ETxBfGrouping_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ TX_TXBF_CFG_0_STRUC regValue;
+ ULONG t = simple_strtol(arg, 0, 10);
+
+ if (t > 2) {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ETxBfGrouping_Proc: value > 2!\n"));
+ return FALSE;
+ }
+
+ RTMP_IO_READ32(pAd, TX_TXBF_CFG_0, &regValue.word);
+ regValue.field.EtxbfFbkNg = t;
+ RTMP_IO_WRITE32(pAd, TX_TXBF_CFG_0, regValue.word);
+ return TRUE;
+}
+
+
+/*
+ Set_ETxBfNoncompress_Proc - Set ETxBf Noncompress option
+ usage: iwpriv ra0 set ETxBfNoncompress=0 or 1
+*/
+INT Set_ETxBfNoncompress_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG t = simple_strtol(arg, 0, 10);
+
+ if (t > 1) {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_ETxBfNoncompress_Proc: value > 1!\n"));
+ return FALSE;
+ }
+
+ pAd->CommonCfg.ETxBfNoncompress = t;
+ return TRUE;
+}
+
+
+/*
+ Set_ETxBfIncapable_Proc - Set ETxBf Incapable option
+ usage: iwpriv ra0 set ETxBfIncapable=0 or 1
+*/
+INT Set_ETxBfIncapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG t = simple_strtol(arg, 0, 10);
+
+ if (t > 1)
+ return FALSE;
+
+ pAd->CommonCfg.ETxBfIncapable = t;
+ setETxBFCap(pAd, &pAd->CommonCfg.HtCapability.TxBFCap);
+
+ return TRUE;
+}
+
+
+/*
+ Set_ITxBfDivCal_Proc - Calculate ITxBf Divider Calibration parameters
+ usage: iwpriv ra0 set ITxBfDivCal=dd
+ 0=>display calibration parameters
+ 1=>update EEPROM values
+ 2=>update BBP R176
+ 10=>display calibration parameters and dump capture data
+ 11=>Skip divider calibration, just capture and dump capture data
+*/
+INT Set_ITxBfDivCal_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int calFunction;
+
+ calFunction = simple_strtol(arg, 0, 10);
+
+ return ITxBFDividerCalibration(pAd, calFunction, 0, NULL);
+}
+
+
+/*
+ Set_ITxBfLNACal_Proc - Calculate ITxBf LNA Calibration parameters
+ usage: iwpriv ra0 set ITxBfLnaCal=dd
+ 0=>display calibration parameters
+ 1=>update EEPROM values
+ 2=>update BBP R174
+ 10=>display calibration parameters and dump capture data
+*/
+INT Set_ITxBfLnaCal_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR channel = pAd->CommonCfg.Channel;
+ int calFunction;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ channel = pAd->ate.Channel;
+#endif /* RALINK_ATE */
+
+ calFunction = simple_strtol(arg, 0, 10);
+
+ return ITxBFLNACalibration(pAd, calFunction, 0, channel<=14);
+}
+
+
+/*
+ Set_ITxBfCal_Proc - Calculate ITxBf Calibration parameters
+ usage: "iwpriv ra0 set ITxBfCal=[0 | 1]"
+ 0=>calculate values, 1=>update BBP and EEPROM
+*/
+INT Set_ITxBfCal_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ int calFunction = simple_strtol(arg, 0, 10);
+ int calParams[2];
+ int ret;
+ UCHAR channel = pAd->CommonCfg.Channel;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ channel = pAd->ate.Channel;
+#endif /* RALINK_ATE */
+
+ ret = iCalcCalibration(pAd, calParams, 0);
+ if (ret < 0) {
+ if (ret == -3)
+ DBGPRINT(RT_DEBUG_OFF, ("Set_ITxBfCal_Proc: kmalloc failed\n"));
+ else if (ret == -2)
+ DBGPRINT(RT_DEBUG_OFF, ("Set_ITxBfCal_Proc: MAC Address mismatch\n"));
+ else
+ DBGPRINT(RT_DEBUG_OFF, ("Set_ITxBfCal_Proc: Invalid profiles\n"));
+ return FALSE;
+ }
+
+ /* Display result */
+ DBGPRINT((calFunction==0? RT_DEBUG_OFF: RT_DEBUG_WARN),
+ ("ITxBfCal Result = [0x%02x 0x%02x]\n", calParams[0], calParams[1]));
+
+#ifdef RALINK_ATE
+ pAd->ate.calParams[0] = (UCHAR)calParams[0];
+ pAd->ate.calParams[1] = (UCHAR)calParams[1];
+
+ /* Double check */
+ DBGPRINT((calFunction==0? RT_DEBUG_OFF: RT_DEBUG_WARN),
+ ("ITxBfCal Result in ATE = [0x%02x 0x%02x]\n", pAd->ate.calParams[0], pAd->ate.calParams[1]));
+#endif /* RALINK_ATE */
+
+ /* Update BBP R176 and EEPROM for Ant 0 and 2 */
+ if (calFunction == 1) {
+ UCHAR r27Value = 0, r173Value = 0;
+ ITXBF_PHASE_PARAMS phaseParams;
+ UCHAR divPhase[2] = {0}, phaseValues[2] = {0};
+
+ /* Read R173 to see if Phase compensation is already enabled */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R173, &r173Value);
+
+ /* Select Ant 0 */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &r27Value);
+ r27Value &= ~0x60;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, r27Value);
+
+ /* Update R176 */
+ if (r173Value & 0x08) {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R176, &phaseValues[0]);
+ phaseValues[0] += calParams[0];
+ }
+ else
+ phaseValues[0] = calParams[0];
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R176, phaseValues[0]);
+
+ /* Select Ant 2 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, r27Value | 0x40);
+
+ /* Update R176 */
+ if (r173Value & 0x08) {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R176, &phaseValues[1]);
+ phaseValues[1] += calParams[1];
+ }
+ else
+ phaseValues[1] = calParams[1];
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R176, phaseValues[1]);
+
+ /* Enable TX Phase Compensation */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R173, r173Value | 0x08);
+
+ /* Remove Divider phase */
+ ITxBFDividerCalibration(pAd, 3, 0, divPhase);
+ phaseValues[0] -= divPhase[0];
+ phaseValues[1] -= divPhase[1];
+
+ /* Update EEPROM */
+
+ ITxBFGetEEPROM(pAd, &phaseParams, 0, 0);
+
+ /* Only allow calibration on specific channels */
+ if (channel == 1) {
+ phaseParams.gBeg[0] = phaseValues[0];
+ phaseParams.gBeg[1] = phaseValues[1];
+ }
+ else if (channel == 14) {
+ phaseParams.gEnd[0] = phaseValues[0];
+ phaseParams.gEnd[1] = phaseValues[1];
+ }
+ else if (channel == 36) {
+ phaseParams.aLowBeg[0] = phaseValues[0];
+ phaseParams.aLowBeg[1] = phaseValues[1];
+ }
+ else if (channel == 64) {
+ phaseParams.aLowEnd[0] = phaseValues[0];
+ phaseParams.aLowEnd[1] = phaseValues[1];
+ }
+ else if (channel == 100) {
+ phaseParams.aMidBeg[0] = phaseValues[0];
+ phaseParams.aMidBeg[1] = phaseValues[1];
+ }
+ else if (channel == 128) {
+ phaseParams.aMidEnd[0] = phaseValues[0];
+ phaseParams.aMidEnd[1] = phaseValues[1];
+ }
+ else if (channel == 132) {
+ phaseParams.aHighBeg[0] = phaseValues[0];
+ phaseParams.aHighBeg[1] = phaseValues[1];
+ }
+ else if (channel == 165) {
+ phaseParams.aHighEnd[0] = phaseValues[0];
+ phaseParams.aHighEnd[1] = phaseValues[1];
+ }
+ else {
+ DBGPRINT(RT_DEBUG_OFF,
+ ("Invalid channel: %d\nMust calibrate channel 1, 14, 36, 64, 100, 128, 132 or 165", channel) );
+ return FALSE;
+ }
+ ITxBFSetEEPROM(pAd, &phaseParams, 0, 0);
+
+ DBGPRINT(RT_DEBUG_WARN, ("Set_ITxBfCal_Proc: Calibration Parameters updated\n"));
+ }
+
+ return TRUE;
+}
+
+
+/*
+ Set_ETxBfEnCond_Proc - enable/disable ETxBF
+ usage: iwpriv ra0 set ETxBfEnCond=dd
+ 0=>disable, 1=>enable
+ Note: After use this command, need to re-run apStartup()/LinkUp() operations to sync all status.
+ If ETxBfIncapable!=0 then we don't need to reassociate.
+*/
+INT Set_ETxBfEnCond_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR i, enableETxBf;
+ MAC_TABLE_ENTRY *pEntry;
+ UINT8 byteValue;
+
+ enableETxBf = simple_strtol(arg, 0, 10);
+
+ if (enableETxBf > 1)
+ return FALSE;
+
+ pAd->CommonCfg.ETxBfEnCond = enableETxBf && (pAd->Antenna.field.TxPath > 1);
+ pAd->CommonCfg.RegTransmitSetting.field.TxBF = enableETxBf==0? 0: 1;
+
+ setETxBFCap(pAd, &pAd->CommonCfg.HtCapability.TxBFCap);
+ rtmp_asic_set_bf(pAd);
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (!IS_ENTRY_NONE(pEntry))
+ {
+ pEntry->eTxBfEnCond = clientSupportsETxBF(pAd, &pEntry->HTCapability.TxBFCap)? enableETxBf: 0;
+ pEntry->bfState = READY_FOR_SNDG0;
+ }
+ }
+
+
+ if (pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn || enableETxBf)
+ {
+ RT30xxReadRFRegister(pAd, RF_R39, (PUCHAR)&byteValue);
+ byteValue |= 0x40;
+ RT30xxWriteRFRegister(pAd, RF_R39, (UCHAR)byteValue);
+
+ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)&byteValue);
+ byteValue |= 0x20;
+ RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)byteValue);
+ }
+ else
+ {
+ /* depends on Gary Tsao's comments. we shall disable it */
+ if (pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn == 0)
+ {
+ RT30xxReadRFRegister(pAd, RF_R39, (PUCHAR)&byteValue);
+ byteValue &= (~0x40);
+ RT30xxWriteRFRegister(pAd, RF_R39, (UCHAR)byteValue);
+
+ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)&byteValue);
+ byteValue &= (~0x20);
+ RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)byteValue);
+ }
+ }
+
+
+ return TRUE;
+}
+
+INT Set_NoSndgCntThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR i;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++){
+ pAd->MacTab.Content[i].noSndgCntThrd = simple_strtol(arg, 0, 10);
+ }
+ return TRUE;
+}
+
+INT Set_NdpSndgStreams_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR i;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++){
+ pAd->MacTab.Content[i].ndpSndgStreams = simple_strtol(arg, 0, 10);
+ }
+ return TRUE;
+}
+
+
+INT Set_Trigger_Sounding_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR macAddr[MAC_ADDR_LEN];
+ CHAR *value;
+ INT i;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ /* 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,":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; /*Invalid*/
+
+ AtoH(value, &macAddr[i++], 1);
+ }
+
+ /*DBGPRINT(RT_DEBUG_TRACE, ("TriggerSounding=%02x:%02x:%02x:%02x:%02x:%02x\n",*/
+ /* macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5], macAddr[6]) );*/
+ pEntry = MacTableLookup(pAd, macAddr);
+ if (pEntry==NULL)
+ return FALSE;
+
+ Trigger_Sounding_Packet(pAd, SNDG_TYPE_SOUNDING, 0, pEntry->sndgMcs, pEntry);
+
+ return TRUE;
+}
+
+/*
+ Set_ITxBfEn_Proc - enable/disable ITxBF
+ usage: iwpriv ra0 set ITxBfEn=dd
+ 0=>disable, 1=>enable
+*/
+INT Set_ITxBfEn_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR i;
+ UCHAR enableITxBF;
+ BOOLEAN bCalibrated;
+ UINT8 byteValue;
+
+ enableITxBF = simple_strtol(arg, 0, 10);
+
+ if (enableITxBF > 1)
+ return FALSE;
+
+ bCalibrated = rtmp_chk_itxbf_calibration(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set ITxBfEn=%d, calibration of ITxBF=%d, so enableITxBF=%d!\n",
+ enableITxBF , bCalibrated, (enableITxBF & bCalibrated)));
+
+ enableITxBF &= bCalibrated;
+
+ pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn = enableITxBF && (pAd->Antenna.field.TxPath > 1);
+
+ rtmp_asic_set_bf(pAd);
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pMacEntry = &pAd->MacTab.Content[i];
+ if ((!IS_ENTRY_NONE(pMacEntry)) && (pAd->Antenna.field.TxPath> 1))
+ pMacEntry->iTxBfEn = enableITxBF;
+ }
+
+ if (enableITxBF || pAd->CommonCfg.ETxBfEnCond)
+ {
+ RT30xxReadRFRegister(pAd, RF_R39, (PUCHAR)&byteValue);
+ byteValue |= 0x40;
+ RT30xxWriteRFRegister(pAd, RF_R39, (UCHAR)byteValue);
+
+ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)&byteValue);
+ byteValue |= 0x20;
+ RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)byteValue);
+ }
+
+ /* If enabling ITxBF then set LNA compensation, do a Divider Calibration and update BBP registers */
+ if (enableITxBF) {
+ ITxBFLoadLNAComp(pAd);
+ ITxBFDividerCalibration(pAd, 2, 0, NULL);
+ }
+ else
+ {
+ /* depends on Gary Tsao's comments. */
+ if (pAd->CommonCfg.ETxBfEnCond == 0)
+ {
+ RT30xxReadRFRegister(pAd, RF_R39, (PUCHAR)&byteValue);
+ byteValue &= (~0x40);
+ RT30xxWriteRFRegister(pAd, RF_R39, (UCHAR)byteValue);
+
+ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)&byteValue);
+ byteValue &= (~0x20);
+ RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)byteValue);
+ }
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R173, 0);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &byteValue);
+ byteValue &= ~0x60;
+ for ( i = 0; i < 3; i++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, (byteValue & (i << 5)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R174, 0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R176, 0);
+ }
+ }
+ return TRUE;
+}
+#endif /* TXBF_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+void assoc_ht_info_debugshow(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR ht_cap_len,
+ IN HT_CAPABILITY_IE *pHTCapability)
+{
+ HT_CAP_INFO *pHTCap;
+ HT_CAP_PARM *pHTCapParm;
+ EXT_HT_CAP_INFO *pExtHT;
+#ifdef TXBF_SUPPORT
+ HT_BF_CAP *pBFCap;
+#endif /* TXBF_SUPPORT */
+
+
+ if (pHTCapability && (ht_cap_len > 0))
+ {
+ pHTCap = &pHTCapability->HtCapInfo;
+ pHTCapParm = &pHTCapability->HtCapParm;
+ pExtHT = &pHTCapability->ExtHtCapInfo;
+#ifdef TXBF_SUPPORT
+ pBFCap = &pHTCapability->TxBFCap;
+#endif /* TXBF_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Peer - 11n HT Info\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\tHT Cap Info: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t AdvCode(%d), BW(%d), MIMOPS(%d), GF(%d), ShortGI_20(%d), ShortGI_40(%d)\n",
+ pHTCap->AdvCoding, pHTCap->ChannelWidth, pHTCap->MimoPs, pHTCap->GF,
+ pHTCap->ShortGIfor20, pHTCap->ShortGIfor40));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t TxSTBC(%d), RxSTBC(%d), DelayedBA(%d), A-MSDU(%d), CCK_40(%d)\n",
+ pHTCap->TxSTBC, pHTCap->RxSTBC, pHTCap->DelayedBA, pHTCap->AMsduSize, pHTCap->CCKmodein40));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t PSMP(%d), Forty_Mhz_Intolerant(%d), L-SIG(%d)\n",
+ pHTCap->PSMP, pHTCap->Forty_Mhz_Intolerant, pHTCap->LSIGTxopProSup));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\tHT Parm Info: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t MaxRx A-MPDU Factor(%d), MPDU Density(%d)\n",
+ pHTCapParm->MaxRAmpduFactor, pHTCapParm->MpduDensity));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\tHT MCS set: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t RxMCS(%02x %02x %02x %02x %02x) MaxRxMbps(%d) TxMCSSetDef(%02x)\n",
+ pHTCapability->MCSSet[0], pHTCapability->MCSSet[1], pHTCapability->MCSSet[2],
+ pHTCapability->MCSSet[3], pHTCapability->MCSSet[4],
+ (pHTCapability->MCSSet[11]<<8) + pHTCapability->MCSSet[10],
+ pHTCapability->MCSSet[12]));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\tExt HT Cap Info: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t PCO(%d), TransTime(%d), MCSFeedback(%d), +HTC(%d), RDG(%d)\n",
+ pExtHT->Pco, pExtHT->TranTime, pExtHT->MCSFeedback, pExtHT->PlusHTC, pExtHT->RDGSupport));
+
+#ifdef TXBF_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("\tTX BF Cap: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t ImpRxCap(%d), RXStagSnd(%d), TXStagSnd(%d), RxNDP(%d), TxNDP(%d) ImpTxCap(%d)\n",
+ pBFCap->TxBFRecCapable, pBFCap->RxSoundCapable, pBFCap->TxSoundCapable,
+ pBFCap->RxNDPCapable, pBFCap->TxNDPCapable, pBFCap->ImpTxBFCapable));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t Calibration(%d), ExpCSICapable(%d), ExpComSteerCapable(%d), ExpCSIFbk(%d), ExpNoComBF(%d) ExpComBF(%d)\n",
+ pBFCap->Calibration, pBFCap->ExpCSICapable, pBFCap->ExpComSteerCapable,
+ pBFCap->ExpCSIFbk, pBFCap->ExpNoComBF, pBFCap->ExpComBF));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t MinGrouping(%d), CSIBFAntSup(%d), NoComSteerBFAntSup(%d), ComSteerBFAntSup(%d), CSIRowBFSup(%d) ChanEstimation(%d)\n",
+ pBFCap->MinGrouping, pBFCap->CSIBFAntSup, pBFCap->NoComSteerBFAntSup,
+ pBFCap->ComSteerBFAntSup, pBFCap->CSIRowBFSup, pBFCap->ChanEstimation));
+#endif /* TXBF_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\nPeer - MODE=%d, BW=%d, MCS=%d, ShortGI=%d, MaxRxFactor=%d, MpduDensity=%d, MIMOPS=%d, AMSDU=%d\n",
+ pEntry->HTPhyMode.field.MODE, pEntry->HTPhyMode.field.BW,
+ pEntry->HTPhyMode.field.MCS, pEntry->HTPhyMode.field.ShortGI,
+ pEntry->MaxRAmpduFactor, pEntry->MpduDensity,
+ pEntry->MmpsMode, pEntry->AMsduSize));
+
+#ifdef DOT11N_DRAFT3
+ DBGPRINT(RT_DEBUG_TRACE, ("\tExt Cap Info: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tBss2040CoexistMgmt=%d\n", pEntry->BSS2040CoexistenceMgmtSupport));
+#endif /* DOT11N_DRAFT3 */
+ }
+}
+
+
+INT Set_BurstMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == 1)
+ {
+ pAd->CommonCfg.bRalinkBurstMode= TRUE;
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE);
+ AsicEnableRalinkBurstMode(pAd);
+ }
+ else
+ {
+ pAd->CommonCfg.bRalinkBurstMode = FALSE;
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE);
+ AsicDisableRalinkBurstMode(pAd);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BurstMode_Proc ::%s\n",
+ (pAd->CommonCfg.bRalinkBurstMode == TRUE) ? "enabled" : "disabled"));
+
+ return TRUE;
+}
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef DOT11_VHT_AC
+VOID assoc_vht_info_debugshow(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN VHT_CAP_IE *vht_cap,
+ IN VHT_OP_IE *vht_op)
+{
+ VHT_CAP_INFO *cap_info;
+ VHT_MCS_SET *mcs_set;
+ VHT_OP_INFO *op_info;
+ VHT_MCS_MAP *mcs_map;
+
+
+ if (!WMODE_CAP_AC(pAd->CommonCfg.PhyMode))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Peer - 11AC VHT Info\n"));
+ if (vht_cap)
+ {
+ cap_info = &vht_cap->vht_cap;
+ mcs_set = &vht_cap->mcs_set;
+
+ hex_dump("peer vht_cap raw data", (UCHAR *)cap_info, sizeof(VHT_CAP_INFO));
+ hex_dump("peer vht_mcs raw data", (UCHAR *)mcs_set, sizeof(VHT_MCS_SET));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\tVHT Cap Info: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tMaxMpduLen(%d), BW(%d), SGI_80M(%d), TxSTBC(%d), RxSTBC(%d), +HTC-VHT(%d)\n",
+ cap_info->max_mpdu_len, cap_info->ch_width, cap_info->sgi_80M, cap_info->tx_stbc,
+ cap_info->rx_stbc, cap_info->htc_vht_cap));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tMaxAmpduExp(%d), VhtLinkAdapt(%d), RxAntConsist(%d), TxAntConsist(%d)\n",
+ cap_info->max_ampdu_exp, cap_info->vht_link_adapt, cap_info->rx_ant_consistency, cap_info->tx_ant_consistency));
+ mcs_map = &mcs_set->rx_mcs_map;
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tRxMcsSet: HighRate(%d), RxMCSMap(%d,%d,%d,%d,%d,%d,%d)\n",
+ mcs_set->rx_high_rate, mcs_map->mcs_ss1, mcs_map->mcs_ss2, mcs_map->mcs_ss3,
+ mcs_map->mcs_ss4, mcs_map->mcs_ss5, mcs_map->mcs_ss6, mcs_map->mcs_ss7));
+ mcs_map = &mcs_set->tx_mcs_map;
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tTxMcsSet: HighRate(%d), TxMcsMap(%d,%d,%d,%d,%d,%d,%d)\n",
+ mcs_set->tx_high_rate, mcs_map->mcs_ss1, mcs_map->mcs_ss2, mcs_map->mcs_ss3,
+ mcs_map->mcs_ss4, mcs_map->mcs_ss5, mcs_map->mcs_ss6, mcs_map->mcs_ss7));
+ }
+
+ if (vht_op)
+ {
+ op_info = &vht_op->vht_op_info;
+ mcs_map = &vht_op->basic_mcs_set;
+ DBGPRINT(RT_DEBUG_TRACE, ("\tHT OP Info: \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tChannel Width(%d), CenteralFreq1(%d), CenteralFreq2(%d)\n",
+ op_info->ch_width, op_info->center_freq_1, op_info->center_freq_2));
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tBasicMCSSet(SS1:%d, SS2:%d, SS3:%d, SS4:%d, SS5:%d, SS6:%d, SS7:%d)\n",
+ mcs_map->mcs_ss1, mcs_map->mcs_ss2, mcs_map->mcs_ss3,
+ mcs_map->mcs_ss4, mcs_map->mcs_ss5, mcs_map->mcs_ss6,
+ mcs_map->mcs_ss7));
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+
+}
+#endif /* DOT11_VHT_AC */
+
+
+INT Set_RateAdaptInterval(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+ UINT32 ra_time, ra_qtime;
+ PSTRING token;
+ char sep = ':';
+ ULONG irqFlags;
+
+/*
+ The ra_interval inupt string format should be d:d, in units of ms.
+ =>The first decimal number indicates the rate adaptation checking period,
+ =>The second decimal number indicates the rate adaptation quick response checking period.
+*/
+ DBGPRINT(RT_DEBUG_TRACE,("%s():%s\n", __FUNCTION__, arg));
+
+ token = strchr(arg, sep);
+ if (token != NULL)
+ {
+ *token = '\0';
+
+ if (strlen(arg) && strlen(token+1))
+ {
+ ra_time = simple_strtol(arg, 0, 10);
+ ra_qtime = simple_strtol(token+1, 0, 10);
+ DBGPRINT(RT_DEBUG_OFF, ("%s():Set RateAdaptation TimeInterval as(%d:%d) ms\n",
+ __FUNCTION__, ra_time, ra_qtime));
+
+ RTMP_IRQ_LOCK(&pAd->irq_lock, irqFlags);
+ pAd->ra_interval = ra_time;
+ pAd->ra_fast_interval = ra_qtime;
+#ifdef CONFIG_AP_SUPPORT
+ if (pAd->ApCfg.ApQuickResponeForRateUpTimerRunning == TRUE)
+ {
+ BOOLEAN Cancelled;
+
+ RTMPCancelTimer(&pAd->ApCfg.ApQuickResponeForRateUpTimer, &Cancelled);
+ pAd->ApCfg.ApQuickResponeForRateUpTimerRunning = FALSE;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, irqFlags);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+
+}
+
+
+INT Set_VcoPeriod_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg)
+{
+ pAd->chipCap.VcoPeriod = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("VCO Period = %d seconds\n", pAd->chipCap.VcoPeriod));
+ return TRUE;
+}
+
+#ifdef SINGLE_SKU
+INT Set_ModuleTxpower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT16 Value;
+
+ if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Do NOT accept this command after interface is up.\n"));
+ return FALSE;
+ }
+
+ Value = (UINT16)simple_strtol(arg, 0, 10);
+ pAd->CommonCfg.ModuleTxpower = Value;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ModuleTxpower_Proc::(ModuleTxpower=%d)\n", pAd->CommonCfg.ModuleTxpower));
+ return TRUE;
+}
+#endif /* SINGLE_SKU */
+
+
+#ifdef FPGA_MODE
+INT set_tx_kickcnt(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ pAd->tx_kick_cnt = (INT)simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():tx_kick_cnt=%d\n", __FUNCTION__, pAd->tx_kick_cnt));
+
+ return TRUE;
+}
+
+
+INT set_data_phy_mode(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ pAd->data_phy = (INT)simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_phy=%d\n", __FUNCTION__, pAd->data_phy));
+
+ return TRUE;
+}
+
+
+INT set_data_bw(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ pAd->data_bw = (UCHAR)simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_bw=%d\n", __FUNCTION__, pAd->data_bw));
+
+ return TRUE;
+}
+
+
+INT set_data_mcs(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ UCHAR mcs = (UCHAR)simple_strtol(arg, 0, 10);
+
+ pAd->data_mcs = ((mcs / 10) <<4) | (mcs % 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_mcs=%d\n", __FUNCTION__, pAd->data_mcs));
+
+ return TRUE;
+}
+
+
+INT set_data_gi(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ pAd->data_gi = (UCHAR)simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_gi=%d\n", __FUNCTION__, pAd->data_gi));
+
+ return TRUE;
+}
+
+
+INT set_data_basize(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ pAd->data_basize = (UCHAR)simple_strtol(arg, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_basize=%d\n", __FUNCTION__, pAd->data_basize));
+
+ return TRUE;
+}
+
+
+INT set_fpga_mode(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ ULONG fpga_on;
+
+ fpga_on = simple_strtol(arg, 0, 10);
+
+ if (fpga_on & 2)
+ {
+ pAd->data_phy = MODE_VHT;
+ pAd->data_bw = BW_80;
+ pAd->data_gi = 1;
+ pAd->data_mcs = 7;
+ pAd->data_basize = 31;
+#ifdef CONFIG_AP_SUPPORT
+ pAd->ApCfg.MBSSID[0].bAutoTxRateSwitch = FALSE;
+#endif /* CONFIG_AP_SUPPORT */
+ } else {
+#ifdef CONFIG_AP_SUPPORT
+ pAd->ApCfg.MBSSID[0].bAutoTxRateSwitch = TRUE;
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ if (fpga_on & 4)
+ pAd->data_mcs = (1 <<4) | 7;
+
+ pAd->fpga_on = fpga_on;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): fpga_on=%d\n", __FUNCTION__, pAd->fpga_on));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_phy=%d\n", __FUNCTION__, pAd->data_phy));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_bw=%d\n", __FUNCTION__, pAd->data_bw));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_mcs=%d\n", __FUNCTION__, pAd->data_mcs));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_gi=%d\n", __FUNCTION__, pAd->data_gi));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): data_basize=%d\n", __FUNCTION__, pAd->data_basize));
+
+#ifdef CONFIG_AP_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): bAutoTxRateSwitch=%d\n",
+ __FUNCTION__,
+ pAd->ApCfg.MBSSID[0].bAutoTxRateSwitch));
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+#endif /* FPGA_MODE */
+
+#ifdef WFA_VHT_PF
+INT set_force_amsdu(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ pAd->force_amsdu = (simple_strtol(arg, 0, 10) > 0 ? TRUE : FALSE);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): force_amsdu=%d\n",
+ __FUNCTION__, pAd->force_amsdu));
+ return TRUE;
+}
+#endif /* WFA_VHT_PF */
+
+#ifdef RLT_RF
+INT set_rf(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ INT bank_id = 0, rf_id = 0, rv = 0;
+ UCHAR rf_val = 0;
+
+ if (arg)
+ {
+ rv = sscanf(arg, "%d-%d-%x", &(bank_id), &(rf_id), &(rf_val));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():rv = %d, bank_id = %d, rf_id = %d, rf_val = 0x%02x\n", __FUNCTION__, rv, bank_id, rf_id, rf_val));
+ if (rv == 3)
+ {
+ rlt_rf_write(pAd, (UCHAR)bank_id, (UCHAR)rf_id, (UCHAR)rf_val);
+
+ rlt_rf_read(pAd, bank_id, rf_id, &rf_val);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():%d %03d 0x%02X\n", __FUNCTION__, bank_id, rf_id, rf_val));
+ }
+ else if (rv == 2)
+ {
+ rlt_rf_read(pAd, bank_id, rf_id, &rf_val);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():%d %03d 0x%02X\n", __FUNCTION__, bank_id, rf_id, rf_val));
+ }
+ }
+
+ return TRUE;
+}
+#endif /* RLT_RF */
+
+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},
+ {"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},
+#ifdef SINGLE_SKU
+ {"ModuleTxpower", Show_ModuleTxpower_Proc},
+#endif /* SINGLE_SKU */
+#endif /* DBG */
+ {"rainfo", Show_STA_RAInfo_Proc},
+ {NULL, NULL}
+};
+
+
+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;
+}
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_mac_usb.c b/cleopatre/devkit/mt7601udrv/common/cmm_mac_usb.c
new file mode 100644
index 0000000000..0ffd51a2bd
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_mac_usb.c
@@ -0,0 +1,2159 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+
+#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[0];
+ PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+ 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);
+ }
+
+ if (pCmdRspEventContext->pUrb)
+ RTUSB_UNLINK_URB(pCmdRspEventContext->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)
+ {
+ RELEASE_NDIS_PACKET(pAd, pAd->MgmtRing.Cell[i].pNdisPacket, NDIS_STATUS_FAILURE);
+ pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+ if (pMLMEContext)
+ pMLMEContext->TransferBuffer = NULL;
+ }
+
+ }
+
+
+ /* Free Tx frame resource*/
+ for (acidx = 0; acidx < NUM_OF_TX_RING; 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->CmdRspLock);
+ 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; i<MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ NdisFreeSpinLock(&pAd->BATable.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[0];
+ PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+
+ 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,
+ (PUCHAR *)&pRxContext->TransferBuffer,
+ MAX_RXBULK_SIZE,
+ pRxContext->data_dma);
+ }
+
+ /* Command Response */
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pCmdRspEventContext->pUrb,
+ (PUCHAR *)&pCmdRspEventContext->CmdRspBuffer,
+ CMD_RSP_BULK_SIZE,
+ pCmdRspEventContext->data_dma);
+
+
+
+ /* Free PsPoll frame resource*/
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pPsPollContext->pUrb,
+ (PUCHAR *)&pPsPollContext->TransferBuffer,
+ sizeof(TX_BUFFER),
+ pPsPollContext->data_dma);
+
+ /* Free NULL frame resource*/
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pNullContext->pUrb,
+ (PUCHAR *)&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)
+ {
+ RELEASE_NDIS_PACKET(pAd, pAd->MgmtRing.Cell[i].pNdisPacket, NDIS_STATUS_FAILURE);
+ 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 < NUM_OF_TX_RING; acidx++)
+ {
+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+ if (pHTTXContext)
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pHTTXContext->pUrb,
+ (PUCHAR *)&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;
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+
+ 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;
+ }
+
+ pCmdRspEventContext->pAd = pAd;
+ pCmdRspEventContext->InUse = FALSE;
+ pCmdRspEventContext->Readable = FALSE;
+ NdisZeroMemory(pCmdRspEventContext->CmdRspBuffer, CMD_RSP_BULK_SIZE);
+
+ 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[0]);
+ 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<NUM_OF_TX_RING; 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,
+ (PUCHAR *)&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);
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &(pAd->CmdRspEventContext);
+ 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<NUM_OF_TX_RING; acidx++)
+ {
+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+
+ NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
+ /*Allocate URB and bulk buffer*/
+ Status = RTMPAllocUsbBulkBufStruct(pAd,
+ &pHTTXContext->pUrb,
+ (PVOID *)&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,
+ (PVOID *)&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,
+ (PVOID *)&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,
+ (PVOID *)&pRxContext->TransferBuffer,
+ MAX_RXBULK_SIZE,
+ &pRxContext->data_dma,
+ "RxContext");
+ if (Status != NDIS_STATUS_SUCCESS)
+ goto err;
+
+ }
+
+ /* Init command response event related parameters */
+ Status = RTMPAllocUsbBulkBufStruct(pAd,
+ &pCmdRspEventContext->pUrb,
+ (PVOID *)&pCmdRspEventContext->CmdRspBuffer,
+ CMD_RSP_BULK_SIZE,
+ &pCmdRspEventContext->data_dma,
+ "CmdRspEventContext");
+
+ 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);
+ NdisAllocateSpinLock(pAd, &pAd->CmdRspLock);
+ 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;
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+
+ 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;
+ }
+
+ pCmdRspEventContext->pAd = pAd;
+ pCmdRspEventContext->InUse = FALSE;
+ pCmdRspEventContext->Readable = FALSE;
+ NdisZeroMemory(pCmdRspEventContext->TransferBuffer, CMD_RSP_BULK_SIZE);
+
+ 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[0]);
+ 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<NUM_OF_TX_RING; acidx++)
+ {
+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+
+ NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
+ /*Allocate URB*/
+ Status = RTMPAllocUsbBulkBufStruct(pAd,
+ &pHTTXContext->pUrb,
+ (PVOID *)&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,
+ (PVOID *)&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,
+ (PVOID *)&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,
+ (PUCHAR *)&pPsPollContext->TransferBuffer,
+ sizeof(TX_BUFFER),
+ pPsPollContext->data_dma);
+
+ /* Free NULL frame resource*/
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pNullContext->pUrb,
+ (PUCHAR *)&pNullContext->TransferBuffer,
+ sizeof(TX_BUFFER),
+ pNullContext->data_dma);
+
+ /* MGMT Ring*/
+ 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,
+ (PUCHAR *)&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,
+ (PUCHAR *)&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);
+ NdisAllocateSpinLock(pAd, &pAd->CmdRspLock);
+ 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;
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &(pAd->CmdRspEventContext);
+
+
+ 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,
+ (PUCHAR *)&pRxContext->TransferBuffer,
+ MAX_RXBULK_SIZE,
+ pRxContext->data_dma);
+ }
+
+ if (pCmdRspEventContext)
+ {
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pCmdRspEventContext->pUrb,
+ (PUCHAR *)&pCmdRspEventContext->TransferBuffer,
+ CMD_RSP_BULK_SIZE,
+ pCmdRspEventContext->data_dma);
+ }
+
+ /* Free PsPoll frame resource*/
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pPsPollContext->pUrb,
+ (PUCHAR *)&pPsPollContext->TransferBuffer,
+ sizeof(TX_BUFFER),
+ pPsPollContext->data_dma);
+
+ /* Free NULL frame resource*/
+ RTMPFreeUsbBulkBufStruct(pAd,
+ &pNullContext->pUrb,
+ (PUCHAR *)&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)
+ {
+ RELEASE_NDIS_PACKET(pAd, pAd->MgmtRing.Cell[i].pNdisPacket, NDIS_STATUS_FAILURE);
+ 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,
+ (PUCHAR *)&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->CmdRspLock);
+ 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, FALSE);
+ RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word, FALSE);
+#ifdef HDR_TRANS_SUPPORT
+ RTUSBWriteMACRegister(pAd, HT_MAC_ADDR_DW0, StaMacReg0.word, FALSE);
+ StaMacReg1.word &= 0xff00ffff;
+ StaMacReg1.word |= 0x00410000;
+ RTUSBWriteMACRegister(pAd, HT_MAC_ADDR_DW1, StaMacReg1.word, FALSE);
+#endif /* HDR_TRANS_SUPPORT */
+ 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;
+
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+
+ if (AsicWaitPDMAIdle(pAd, 200, 1000) == FALSE) {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+ }
+
+/*
+ // USB not support WPDMA
+ RTMPusecDelay(50);
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ GloCfg.field.EnTXWriteBackDDONE = 1;
+ GloCfg.field.EnableRxDMA = 1;
+ GloCfg.field.EnableTxDMA = 1;
+ RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.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;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+#ifdef CONFIG_AP_SUPPORT
+ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)))
+ {
+ bcn_idx = pAd->ApCfg.MBSSID[apidx].BcnBufIdx;
+ pBeaconFrame = (PUCHAR) pAd->ApCfg.MBSSID[apidx].BeaconBuf;
+ bBcnReq = BeaconTransmitRequired(pAd, apidx, &pAd->ApCfg.MBSSID[apidx]);
+ }
+#endif /* CONFIG_AP_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)
+ {
+ /* when the ra interface is down, do not send its beacon frame */
+ /* clear all zero */
+ for(i=0; i < TXWISize; i+=4) {
+ RTMP_CHIP_UPDATE_BEACON(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00, 4);
+ }
+
+ pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWISize);
+ }
+ else
+ {
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pAd, ptr, TYPE_TXWI);
+#endif
+ if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWISize) == 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, TXWISize);
+ }
+
+ if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
+ {
+ for (i=0; i < TXWISize; i+=4)
+ {
+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ RTMP_CHIP_UPDATE_BEACON(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue, 4);
+ 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);
+ longValue = *ptr + (*(ptr+1)<<8);
+ RTMP_CHIP_UPDATE_BEACON(pAd, pAd->BeaconOffset[bcn_idx] + TXWISize + i, longValue, 2);
+ }
+ ptr +=2;
+ pBeaconFrame += 2;
+ }
+
+
+ pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
+
+ /* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.*/
+#ifdef CONFIG_AP_SUPPORT
+ {
+ ptr = (PUCHAR) (pAd->ApCfg.MBSSID[apidx].BeaconBuf + pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon);
+ if ((*(ptr + 4)) & 0x01)
+ pBeaconSync->DtimBitOn |= (1 << apidx);
+ else
+ pBeaconSync->DtimBitOn &= ~(1 << apidx);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+}
+
+}
+
+
+VOID RTUSBBssBeaconStop(
+ IN RTMP_ADAPTER *pAd)
+{
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ int i, offset;
+ BOOLEAN Cancelled = TRUE;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ if (pBeaconSync && pBeaconSync->EnableBeacon)
+ {
+ INT NumOfBcn = 0;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ NumOfBcn = pAd->ApCfg.BssidNum + MAX_MESH_NUM;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+
+ for(i=0; i<NumOfBcn; i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWISize);
+
+ for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
+ RTMP_CHIP_UPDATE_BEACON(pAd, pAd->BeaconOffset[i] + offset, 0x00, 4);
+
+ 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;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+/* LARGE_INTEGER tsfTime, deltaTime;*/
+
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ if (pBeaconSync && pBeaconSync->EnableBeacon)
+ {
+ INT NumOfBcn = 0;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ NumOfBcn = pAd->ApCfg.BssidNum + MAX_MESH_NUM;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ for(apidx=0; apidx<NumOfBcn; apidx++)
+ {
+ UCHAR CapabilityInfoLocationInBeacon = 0;
+ UCHAR TimIELocationInBeacon = 0;
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ {
+ CapabilityInfoLocationInBeacon = pAd->ApCfg.MBSSID[apidx].CapabilityInfoLocationInBeacon;
+ TimIELocationInBeacon = pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
+ pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWISize);
+ }
+ 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, j;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ os_alloc_mem(pAd, (PUCHAR *)(&pAd->CommonCfg.pBeaconSync), sizeof(BEACON_SYNC_STRUCT));
+
+ 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;
+ os_alloc_mem(pAd, &pBeaconSync->BeaconTxWI[i], TXWISize);
+ if (pBeaconSync->BeaconTxWI[i])
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWISize);
+ else
+ goto error2;
+ }
+ pBeaconSync->BeaconBitMap = 0;
+
+ /*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);*/
+ pBeaconSync->EnableBeacon = TRUE;
+ }else
+ goto error1;
+
+ return;
+
+error2:
+ for (j = 0; j < i; j++)
+ os_free_mem(pAd, pBeaconSync->BeaconTxWI[j]);
+
+ os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
+
+error1:
+ DBGPRINT(RT_DEBUG_ERROR, ("memory are not available\n"));
+}
+
+
+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; i<HW_BEACON_MAX_COUNT(pAd); i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+ pBeaconSync->TimIELocationInBeacon[i] = 0;
+ os_free_mem(pAd, pBeaconSync->BeaconTxWI[i]);
+ }
+
+ 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);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ ULONG UpTime;
+
+ /* update channel utilization */
+ NdisGetSystemUpTime(&UpTime);
+
+#ifdef AP_QLOAD_SUPPORT
+ QBSS_LoadUpdate(pAd, UpTime);
+#endif /* AP_QLOAD_SUPPORT */
+
+
+ if (pAd->ApCfg.DtimCount == 0 && pBeaconSync->DtimBitOn)
+ {
+ POS_COOKIE pObj;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ RTMP_OS_TASKLET_SCHE(&pObj->tbtt_task);
+ }
+
+
+ APUpdateAllBeaconFrame(pAd);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+
+ 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;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE))
+ {
+ ChannelSwitchingCountDownProc(pAd);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+}
+
+
+/********************************************************************
+ *
+ * 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;
+
+ ASIC_RADIO_ON(pAd, MLME_RADIO_ON);
+
+ /* Clear Radio off flag*/
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APStartUp(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef LED_CONTROL_SUPPORT
+ /* Set LED*/
+#ifdef CONFIG_AP_SUPPORT
+ RTMPSetLED(pAd, LED_LINK_UP);
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* LED_CONTROL_SUPPORT */
+
+}
+
+
+VOID RT28xxUsbMlmeRadioOFF(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef WSC_INCLUDED
+#ifdef WSC_LED_SUPPORT
+ UINT WPSLedMode10;
+#endif /* WSC_LED_SUPPORT */
+#endif /* WSC_INCLUDED */
+
+ DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ return;
+
+#ifdef WSC_INCLUDED
+#ifdef WSC_LED_SUPPORT
+ if(LED_MODE(pAd) == WPS_LED_MODE_10)
+ {
+ //WPSLedMode10 = LINK_STATUS_WPS_MODE10_TURN_OFF;
+ //RTEnqueueInternalCmd(pAd, CMDTHREAD_LED_WPS_MODE10, &WPSLedMode10, sizeof(WPSLedMode10));
+ }
+#endif /* WSC_LED_SUPPORT */
+#endif /* WSC_INCLUDED */
+
+
+ /* Set Radio off flag*/
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APStop(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef LED_CONTROL_SUPPORT
+ /* Set LED*/
+ RTMPSetLED(pAd, LED_RADIO_OFF);
+#endif /* LED_CONTROL_SUPPORT */
+
+ ASIC_RADIO_OFF(pAd, MLME_RADIO_OFF);
+}
+
+
+VOID RT28xxUsbAsicRadioOff(RTMP_ADAPTER *pAd)
+{
+ WPDMA_GLO_CFG_STRUC GloCfg;
+ UINT32 Value;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s\n", __FUNCTION__));
+
+ if (pAd->CommonCfg.CentralChannel)
+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+ else
+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ //MT7601DisableTxRx(pAd, GUIRADIO_OFF);
+ MT7601DisableTxRx(pAd, GUIRADIO_OFF);
+
+ AndesPwrSavingOP(pAd, RADIO_OFF, 0x01, 0, 0, 0, 0);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
+ }
+ else
+#endif /* MT7601 */
+ {
+ /* 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, FALSE); /* abort all TX rings*/
+
+ /* Waiting for DMA idle*/
+ AsicWaitPDMAIdle(pAd, 100, 1000);
+
+ /* Disable MAC Tx/Rx*/
+ RTUSBReadMACRegister(pAd, MAC_SYS_CTRL, &Value);
+ Value &= (0xfffffff3);
+ RTUSBWriteMACRegister(pAd, MAC_SYS_CTRL, Value, FALSE);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== %s\n", __FUNCTION__));
+
+}
+
+
+VOID RT28xxUsbAsicRadioOn(RTMP_ADAPTER *pAd)
+{
+ UINT32 MACValue = 0;
+ BOOLEAN brc;
+ UINT RetryRound = 0;
+ UINT32 rx_filter_flag;
+ WPDMA_GLO_CFG_STRUC GloCfg;
+ 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_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"));
+
+#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.*/
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
+ AndesPwrSavingOP(pAd, RADIO_ON, 0, 0, 0, 0, 0);
+
+ //pAd->hw_cfg.cent_ch = pAd->CommonCfg.CentralChannel;
+
+ //AsicSwitchChannel(pAd, pAd->hw_cfg.cent_ch, FALSE);
+ //AsicLockChannel(pAd, pAd->hw_cfg.cent_ch);
+
+ }
+ else
+#endif /* MT7601 */
+ {
+ RetryRound = 0;
+
+ do
+ {
+ brc = AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02, FALSE);
+ 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/Rx DMA.*/
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+
+
+ /* 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);
+
+
+ /* 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.*/
+ /* */
+ DBGPRINT(RT_DEBUG_TRACE, ("<== %s\n", __FUNCTION__));
+
+
+}
+
+
+BOOLEAN AsicCheckCommandOk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command)
+{
+ UINT32 CmdStatus, CID, i;
+ UINT32 ThisCIDMask = 0;
+ INT ret;
+
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd))
+ {
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
+ if (ret != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ return FALSE;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ 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);
+
+ ret = FALSE;
+ RTUSBReadMACRegister(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
+ if (i < 200)
+ {
+ if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
+ || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
+ ret = TRUE;
+ }
+ RTUSBWriteMACRegister(pAd, H2M_MAILBOX_STATUS, 0xffffffff, FALSE);
+ RTUSBWriteMACRegister(pAd, H2M_MAILBOX_CID, 0xffffffff, FALSE);
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd))
+ {
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+
+ return ret;
+
+}
+
+
+#ifdef WOW_SUPPORT
+VOID RT28xxUsbAsicWOWEnable(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Value;
+
+ /* load WOW-enable firmware */
+ AsicLoadWOWFirmware(pAd, TRUE);
+ /* put null frame data to MCU memory from 0x7780 */
+ AsicWOWSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE));
+ /* send WOW enable command to MCU. */
+ AsicSendCommandToMcu(pAd, 0x33, 0xff, pAd->WOW_Cfg.nSelectedGPIO, pAd->WOW_Cfg.nDelay, FALSE);
+ /* set GPIO pulse hold time at MSB (Byte) */
+ RTMP_IO_READ32(pAd, GPIO_HOLDTIME_OFFSET, &Value);
+ Value &= 0x00FFFFFF;
+ Value |= (pAd->WOW_Cfg.nHoldTime << 24);
+ RTMP_IO_WRITE32(pAd, GPIO_HOLDTIME_OFFSET, Value);
+ DBGPRINT(RT_DEBUG_OFF, ("Send WOW enable cmd (%d/%d/%d)\n", pAd->WOW_Cfg.nDelay, pAd->WOW_Cfg.nSelectedGPIO, pAd->WOW_Cfg.nHoldTime));
+ RTMP_IO_READ32(pAd, GPIO_HOLDTIME_OFFSET, &Value);
+ DBGPRINT(RT_DEBUG_OFF, ("Hold time: 0x7020 ==> %x\n", Value));
+}
+
+VOID RT28xxUsbAsicWOWDisable(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Value;
+ /* load normal firmware */
+ AsicLoadWOWFirmware(pAd, FALSE);
+ /* for suspend/resume, needs to restore RX Queue operation mode to auto mode */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Value);
+ Value &= ~0x2200;
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Value);
+ //AsicSendCommandToMcu(pAd, 0x34, 0xff, 0x00, 0x00, FALSE); /* send WOW disable command to MCU*/
+ DBGPRINT(RT_DEBUG_OFF, ("MCU back to normal mode (%d/%d)\n", pAd->WOW_Cfg.nDelay, pAd->WOW_Cfg.nSelectedGPIO));
+}
+#endif /* WOW_SUPPORT */
+#endif /* RTMP_MAC_USB */
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_mat.c b/cleopatre/devkit/mt7601udrv/common/cmm_mat.c
new file mode 100644
index 0000000000..307c9b0255
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_mat.c
@@ -0,0 +1,443 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_mat.c
+
+ Abstract:
+ Support Mac Address Translation function.
+
+ Note:
+ MAC Address Translation(MAT) engine subroutines, we should just take care
+ packet to bridge.
+
+ Revision History:
+ Who When What
+ -------------- ---------- ----------------------------------------------
+ Shiang 02-26-2007 Init version
+*/
+
+#ifdef MAT_SUPPORT
+
+#include "rt_config.h"
+
+
+extern MATProtoOps MATProtoIPHandle;
+extern MATProtoOps MATProtoARPHandle;
+extern MATProtoOps MATProtoPPPoEDisHandle;
+extern MATProtoOps MATProtoPPPoESesHandle;
+extern MATProtoOps MATProtoIPv6Handle;
+
+extern UCHAR SNAP_802_1H[];
+extern UCHAR SNAP_BRIDGE_TUNNEL[];
+
+#define MAX_MAT_NODE_ENTRY_NUM 128 /* We support maximum 128 node entry for our system */
+#define MAT_NODE_ENTRY_SIZE 40 /*28 // bytes //change to 40 for IPv6Mac Table */
+
+typedef struct _MATNodeEntry
+{
+ UCHAR data[MAT_NODE_ENTRY_SIZE];
+ struct _MATNodeEntry *next;
+}MATNodeEntry, *PMATNodeEntry;
+
+
+#ifdef KMALLOC_BATCH
+/*static MATNodeEntry *MATNodeEntryPoll = NULL; */
+#endif
+
+static MATProtoTable MATProtoTb[]=
+{
+ {ETH_P_IP, &MATProtoIPHandle}, /* IP handler */
+ {ETH_P_ARP, &MATProtoARPHandle}, /* ARP handler */
+ {ETH_P_PPP_DISC, &MATProtoPPPoEDisHandle}, /* PPPoE discovery stage handler */
+ {ETH_P_PPP_SES, &MATProtoPPPoESesHandle}, /* PPPoE session stage handler */
+ {ETH_P_IPV6, &MATProtoIPv6Handle}, /* IPv6 handler */
+};
+
+#define MAX_MAT_SUPPORT_PROTO_NUM (sizeof(MATProtoTb)/sizeof(MATProtoTable))
+
+
+/* --------------------------------- Public Function-------------------------------- */
+NDIS_STATUS MATDBEntryFree(
+ IN MAT_STRUCT *pMatStruct,
+ IN PUCHAR NodeEntry)
+{
+#ifdef KMALLOC_BATCH
+ MATNodeEntry *pPtr, *pMATNodeEntryPoll;
+
+ pMATNodeEntryPoll = (MATNodeEntry *)pAd->MatCfg.MATNodeEntryPoll;
+ pPtr = (MATNodeEntry *)NodeEntry;
+ NdisZeroMemory(pPtr, sizeof(MATNodeEntry));
+ if (pMATNodeEntryPoll->next)
+ {
+ pPtr->next = pMATNodeEntryPoll->next;
+ pMATNodeEntryPoll->next = pPtr;
+ } else {
+ pMATNodeEntryPoll->next = pPtr;
+ }
+#else
+ os_free_mem(NULL, NodeEntry);
+#endif
+
+ return TRUE;
+
+}
+
+PUCHAR MATDBEntryAlloc(IN MAT_STRUCT *pMatStruct, IN UINT32 size)
+{
+#ifdef KMALLOC_BATCH
+ MATNodeEntry *pPtr = NULL, *pMATNodeEntryPoll;
+ pMATNodeEntryPoll = (MATNodeEntry *)pMatStruct->pMATNodeEntryPoll;
+
+ if (pMATNodeEntryPoll->next)
+ {
+ pPtr = pMATNodeEntryPoll->next;
+ pMATNodeEntryPoll->next = pPtr->next;
+ }
+
+#else
+ UCHAR *pPtr = NULL;
+
+ os_alloc_mem(NULL, (PUCHAR *)&pPtr, size);
+ /*pPtr = kmalloc(size, MEM_ALLOC_FLAG); */
+
+#endif
+
+ return (PUCHAR)pPtr;
+}
+
+
+VOID dumpPkt(PUCHAR pHeader, int len)
+{
+ int i;
+ PSTRING tmp;
+
+ tmp = (PSTRING)pHeader;
+
+ DBGPRINT(RT_DEBUG_OFF, ("--StartDump\n"));
+ for(i=0;i<len; i++)
+ {
+ if ( (i%16==0) && (i!=0))
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("%02x ", tmp[i]& 0xff));
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\n--EndDump\n"));
+
+ return;
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ For each out-going packet, check the upper layer protocol type if need
+ to handled by our APCLI convert engine. If yes, call corresponding handler
+ to handle it.
+
+ Arguments:
+ pAd =>Pointer to our adapter
+ pPkt =>pointer to the 802.11 header of outgoing packet
+ ifIdx =>Interface Index want to dispatch to.
+
+ Return Value:
+ Success =>
+ TRUE
+ Mapped mac address if found, else return specific default mac address
+ depends on the upper layer protocol type.
+ Error =>
+ FALSE.
+
+ Note:
+ 1.the pPktHdr must be a 802.3 packet.
+ 2.Maybe we need a TxD arguments?
+ 3.We check every packet here including group mac address becasue we need to
+ handle DHCP packet.
+ ========================================================================
+ */
+PUCHAR MATEngineTxHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPkt,
+ IN UINT ifIdx,
+ IN UCHAR OpMode)
+{
+ PUCHAR pLayerHdr = NULL, pPktHdr = NULL, pMacAddr = NULL;
+ UINT16 protoType, protoType_ori;
+ INT i;
+ struct _MATProtoOps *pHandle = NULL;
+ PUCHAR retSkb = NULL;
+ BOOLEAN bVLANPkt = FALSE;
+
+
+ if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED)
+ return NULL;
+
+ pPktHdr = GET_OS_PKT_DATAPTR(pPkt);
+ if (!pPktHdr)
+ return NULL;
+
+ protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12));
+
+ /* Get the upper layer protocol type of this 802.3 pkt. */
+ protoType = OS_NTOHS(protoType_ori);
+
+ /* handle 802.1q enabled packet. Skip the VLAN tag field to get the protocol type. */
+ if (protoType == 0x8100)
+ {
+ protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12 + 4));
+ protoType = OS_NTOHS(protoType_ori);
+ bVLANPkt = TRUE;
+ }
+
+
+ /* For differnet protocol, dispatch to specific handler */
+ for (i=0; i < MAX_MAT_SUPPORT_PROTO_NUM; i++)
+ {
+ if (protoType == MATProtoTb[i].protocol)
+ {
+ pHandle = MATProtoTb[i].pHandle; /* the pHandle must not be null! */
+ pLayerHdr = bVLANPkt ? (pPktHdr + MAT_VLAN_ETH_HDR_LEN) : (pPktHdr + MAT_ETHER_HDR_LEN);
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ pMacAddr = &pAd->ApCfg.ApCliTab[ifIdx].CurrentAddress[0];
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (pHandle->tx!=NULL)
+ retSkb = pHandle->tx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, pMacAddr);
+
+ return retSkb;
+ }
+ }
+ return retSkb;
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Depends on the Received packet, check the upper layer protocol type
+ and search for specific mapping table to find out the real destination
+ MAC address.
+
+ Arguments:
+ pAd =>Pointer to our adapter
+ pPkt =>pointer to the 802.11 header of receviced packet
+ infIdx =>Interface Index want to dispatch to.
+
+ Return Value:
+ Success =>
+ Mapped mac address if found, else return specific default mac address
+ depends on the upper layer protocol type.
+ Error =>
+ NULL
+
+ Note:
+ ========================================================================
+ */
+PUCHAR MATEngineRxHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPkt,
+ IN UINT infIdx)
+{
+ PUCHAR pMacAddr = NULL;
+ PUCHAR pLayerHdr = NULL, pPktHdr = NULL;
+ UINT16 protoType;
+ INT i =0;
+ struct _MATProtoOps *pHandle = NULL;
+
+
+ if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED)
+ return NULL;
+
+ pPktHdr = GET_OS_PKT_DATAPTR(pPkt);
+ if (!pPktHdr)
+ return NULL;
+
+ /* If it's a multicast/broadcast packet, we do nothing. */
+ if (IS_GROUP_MAC(pPktHdr))
+ return NULL;
+
+ /* Get the upper layer protocol type of this 802.3 pkt and dispatch to specific handler */
+ protoType = OS_NTOHS(get_unaligned((PUINT16)(pPktHdr + 12)));
+
+ for (i=0; i<MAX_MAT_SUPPORT_PROTO_NUM; i++)
+ {
+ if (protoType == MATProtoTb[i].protocol)
+ {
+ pHandle = MATProtoTb[i].pHandle; /* the pHandle must not be null! */
+ pLayerHdr = (pPktHdr + MAT_ETHER_HDR_LEN);
+/* RTMP_SEM_LOCK(&MATDBLock); */
+ if(pHandle->rx!=NULL)
+ pMacAddr = pHandle->rx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, NULL);
+/* RTMP_SEM_UNLOCK(&MATDBLock); */
+ break;
+ }
+ }
+
+ if (pMacAddr)
+ NdisMoveMemory(pPktHdr, pMacAddr, MAC_ADDR_LEN);
+
+ return NULL;
+
+}
+
+
+BOOLEAN MATPktRxNeedConvert(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV net_dev)
+{
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ int i = 0;
+
+ /* Check if the packet will be send to apcli interface. */
+ while(i<MAX_APCLI_NUM)
+ {
+ /*BSSID match the ApCliBssid ?(from a valid AP) */
+ if ((pAd->ApCfg.ApCliTab[i].Valid == TRUE)
+ && (net_dev == pAd->ApCfg.ApCliTab[i].dev))
+ return TRUE;
+ i++;
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ return FALSE;
+
+}
+
+
+NDIS_STATUS MATEngineExit(
+ IN RTMP_ADAPTER *pAd)
+{
+ struct _MATProtoOps *pHandle = NULL;
+ int i;
+
+ if(pAd->MatCfg.status == MAT_ENGINE_STAT_EXITED)
+ return TRUE;
+
+ /* For each registered protocol, we call it's exit handler. */
+ for (i=0; i<MAX_MAT_SUPPORT_PROTO_NUM; i++)
+ {
+ pHandle = MATProtoTb[i].pHandle;
+ if (pHandle->exit!=NULL)
+ pHandle->exit(&pAd->MatCfg);
+ }
+
+#ifdef KMALLOC_BATCH
+ /* Free the memory used to store node entries. */
+ if (pAd->MatCfg.pMATNodeEntryPoll)
+ {
+ os_free_mem(pAd, pAd->MatCfg.pMATNodeEntryPoll);
+ pAd->MatCfg.pMATNodeEntryPoll = NULL;
+ }
+#endif
+
+ pAd->MatCfg.status = MAT_ENGINE_STAT_EXITED;
+
+ return TRUE;
+
+}
+
+
+NDIS_STATUS MATEngineInit(
+ IN RTMP_ADAPTER *pAd)
+{
+ MATProtoOps *pHandle = NULL;
+ int i, status;
+
+ if(pAd->MatCfg.status == MAT_ENGINE_STAT_INITED)
+ return TRUE;
+
+#ifdef KMALLOC_BATCH
+ /* Allocate memory for node entry, we totally allocate 128 entries and link them together. */
+/* pAd->MatCfg.pMATNodeEntryPoll = kmalloc(sizeof(MATNodeEntry) * MAX_MAT_NODE_ENTRY_NUM, GFP_KERNEL); */
+ os_alloc_mem_suspend(NULL, (UCHAR **)&(pAd->MatCfg.pMATNodeEntryPoll), sizeof(MATNodeEntry) * MAX_MAT_NODE_ENTRY_NUM);
+ if (pAd->MatCfg.pMATNodeEntryPoll != NULL)
+ {
+ MATNodeEntry *pPtr=NULL;
+
+ NdisZeroMemory(pAd->MatCfg.pMATNodeEntryPoll, sizeof(MATNodeEntry) * MAX_MAT_NODE_ENTRY_NUM);
+ pPtr = pAd->MatCfg.pMATNodeEntryPoll;
+ for (i = 0; i < (MAX_MAT_NODE_ENTRY_NUM -1); i++)
+ {
+ pPtr->next = (MATNodeEntry *)(pPtr+1);
+ pPtr = pPtr->next;
+ }
+ pPtr->next = NULL;
+ } else {
+ return FALSE;
+ }
+#endif
+
+ /* For each specific protocol, call it's init function. */
+ for (i = 0; i < MAX_MAT_SUPPORT_PROTO_NUM; i++)
+ {
+ pHandle = MATProtoTb[i].pHandle;
+ ASSERT(pHandle);
+ if (pHandle->init != NULL)
+ {
+ status = pHandle->init(&pAd->MatCfg);
+ if (status == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MATEngine Init Protocol (0x%x) failed, Stop the MAT Funciton initialization failed!\n", MATProtoTb[i].protocol));
+ goto init_failed;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("MATEngine Init Protocol (0x%04x) success!\n", MATProtoTb[i].protocol));
+ }
+ }
+
+ NdisAllocateSpinLock(pAd, &pAd->MatCfg.MATDBLock);
+ pAd->MatCfg.pPriv = (VOID *)pAd;
+ pAd->MatCfg.status = MAT_ENGINE_STAT_INITED;
+
+ return TRUE;
+
+init_failed:
+ /* For each specific protocol, call it's exit function. */
+ for (i = 0; i < MAX_MAT_SUPPORT_PROTO_NUM; i++)
+ {
+ if ((pHandle = MATProtoTb[i].pHandle) != NULL)
+ {
+ if (pHandle->exit != NULL)
+ {
+ status = pHandle->exit(&pAd->MatCfg);
+ if (status == FALSE)
+ goto init_failed;
+ }
+ }
+ }
+
+#ifdef KMALLOC_BATCH
+ if (pAd->MatCfg.pMATNodeEntryPoll)
+ os_free_mem(pAd, pAd->MatCfg.pMATNodeEntryPoll);
+ pAd->MatCfg.status = MAT_ENGINE_STAT_EXITED;
+#endif /* KMALLOC_BATCH */
+
+ return FALSE;
+
+}
+
+#endif /* MAT_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_mat_iparp.c b/cleopatre/devkit/mt7601udrv/common/cmm_mat_iparp.c
new file mode 100644
index 0000000000..5f799962e3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_mat_iparp.c
@@ -0,0 +1,694 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_mat_iparp.c
+
+ Abstract:
+ MAT convert engine subroutine for ip base protocols, currently now we
+ just handle IP/ARP protocols.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Shiang 02/26/07 Init version
+*/
+#ifdef MAT_SUPPORT
+
+#include "rt_config.h"
+
+static NDIS_STATUS MATProto_IP_Init(MAT_STRUCT *pMatCfg);
+static NDIS_STATUS MATProto_IP_Exit(MAT_STRUCT *pMatCfg);
+static PUCHAR MATProto_IP_Rx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
+static PUCHAR MATProto_IP_Tx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
+
+static NDIS_STATUS MATProto_ARP_Init(MAT_STRUCT *pMatCfg);
+static NDIS_STATUS MATProto_ARP_Exit(MAT_STRUCT *pMatCfg);
+static PUCHAR MATProto_ARP_Rx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
+static PUCHAR MATProto_ARP_Tx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb,PUCHAR pLayerHdr, PUCHAR pMacAddr);
+
+#define IPV4_ADDR_LEN 4
+
+#define NEED_UPDATE_IPMAC_TB(Mac, IP) (IS_UCAST_MAC(Mac) && IS_GOOD_IP(IP))
+
+
+typedef struct _IPMacMappingEntry
+{
+ UINT ipAddr; /* In network order */
+ UCHAR macAddr[MAC_ADDR_LEN];
+ ULONG lastTime;
+ struct _IPMacMappingEntry *pNext;
+}IPMacMappingEntry, *PIPMacMappingEntry;
+
+
+typedef struct _IPMacMappingTable
+{
+ BOOLEAN valid;
+ IPMacMappingEntry *hash[MAT_MAX_HASH_ENTRY_SUPPORT+1]; /*0~63 for specific station, 64 for broadcast MacAddress */
+ UCHAR curMcastAddr[MAC_ADDR_LEN]; /* The multicast mac addr for currecnt received packet destined to ipv4 multicast addr */
+}IPMacMappingTable;
+
+
+struct _MATProtoOps MATProtoIPHandle =
+{
+ .init = MATProto_IP_Init,
+ .tx = MATProto_IP_Tx,
+ .rx = MATProto_IP_Rx,
+ .exit = MATProto_IP_Exit,
+};
+
+struct _MATProtoOps MATProtoARPHandle =
+{
+ .init = MATProto_ARP_Init,
+ .tx = MATProto_ARP_Tx,
+ .rx = MATProto_ARP_Rx,
+ .exit =MATProto_ARP_Exit,
+};
+
+
+VOID dumpIPMacTb(
+ IN MAT_STRUCT *pMatCfg,
+ IN int index)
+{
+ IPMacMappingTable *pIPMacTable;
+ IPMacMappingEntry *pHead;
+ int startIdx, endIdx;
+
+ pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
+ if (!pIPMacTable)
+ return;
+
+ if (!pIPMacTable->valid)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s():IPMacTable not init yet, so cannot do dump!\n", __FUNCTION__));
+ return;
+ }
+
+
+ if(index < 0)
+ { /* dump all. */
+ startIdx = 0;
+ endIdx = MAT_MAX_HASH_ENTRY_SUPPORT;
+ }
+ else
+ { /* dump specific hash index. */
+ startIdx = endIdx = index;
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("%s():\n", __FUNCTION__));
+ for(; startIdx<= endIdx; startIdx++)
+ {
+ pHead = pIPMacTable->hash[startIdx];
+ while(pHead)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("IPMac[%d]:\n", startIdx));
+ DBGPRINT(RT_DEBUG_OFF, ("\t:IP=0x%x,Mac=%02x:%02x:%02x:%02x:%02x:%02x, lastTime=0x%lx, next=%p\n",
+ pHead->ipAddr, pHead->macAddr[0],pHead->macAddr[1],pHead->macAddr[2],
+ pHead->macAddr[3],pHead->macAddr[4],pHead->macAddr[5], pHead->lastTime,
+ pHead->pNext));
+ pHead = pHead->pNext;
+ }
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\t----EndOfDump!\n"));
+
+}
+
+
+static inline NDIS_STATUS getDstIPFromIpPkt(
+ IN PUCHAR pIpHdr,
+ IN UINT *dstIP)
+{
+
+ if (!pIpHdr)
+ return FALSE;
+
+ NdisMoveMemory(dstIP, (pIpHdr + 16), 4); /*shift 16 for IP header len before DstIP. */
+/* DBGPRINT(RT_DEBUG_TRACE, ("%s(): Get the dstIP=0x%x\n", __FUNCTION__, *dstIP)); */
+
+ return TRUE;
+}
+
+static inline NDIS_STATUS getSrcIPFromIpPkt(
+ IN PUCHAR pIpHdr,
+ IN UINT *pSrcIP)
+{
+
+ if (!pIpHdr)
+ return FALSE;
+
+ NdisMoveMemory(pSrcIP, (pIpHdr + 12), 4); /*shift 12 for IP header len before DstIP. */
+/* DBGPRINT(RT_DEBUG_TRACE, ("%s(): Get the srcIP=0x%x\n", __FUNCTION__, *pSrcIP)); */
+
+ return TRUE;
+
+}
+
+static NDIS_STATUS IPMacTableUpdate(
+ IN MAT_STRUCT *pMatCfg,
+ IN PUCHAR pMacAddr,
+ IN UINT ipAddr)
+{
+ UINT hashIdx;
+ IPMacMappingTable *pIPMacTable;
+ IPMacMappingEntry *pEntry = NULL, *pPrev = NULL, *pNewEntry =NULL;
+ ULONG now;
+
+ pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
+
+ if (!pIPMacTable)
+ return FALSE;
+
+ if (!pIPMacTable->valid)
+ return FALSE;
+
+ hashIdx = MAT_IP_ADDR_HASH_INDEX(ipAddr);
+
+ pEntry = pPrev = pIPMacTable->hash[hashIdx];
+ while(pEntry)
+ {
+ NdisGetSystemUpTime(&now);
+
+ /* Find a existed IP-MAC Mapping entry */
+ if (ipAddr == pEntry->ipAddr)
+ {
+ /* DBGPRINT(RT_DEBUG_TRACE, ("%s(): Got the Mac(%02x:%02x:%02x:%02x:%02x:%02x) of mapped IP(%d.%d.%d.%d)\n",
+ __FUNCTION__, pEntry->macAddr[0],pEntry->macAddr[1],pEntry->macAddr[2], pEntry->macAddr[3],pEntry->macAddr[4],
+ pEntry->macAddr[5], (ipAddr>>24) & 0xff, (ipAddr>>16) & 0xff, (ipAddr>>8) & 0xff, ipAddr & 0xff));
+ */
+ /* compare is useless. So we directly copy it into the entry. */
+ NdisMoveMemory(pEntry->macAddr, pMacAddr, 6);
+ pEntry->lastTime = now;
+ return TRUE;
+ }
+ else
+ { /* handle the age-out situation */
+ /*if ((Now - pEntry->lastTime) > MAT_TB_ENTRY_AGEOUT_TIME) */
+ if (RTMP_TIME_AFTER(now, pEntry->lastTime + MAT_TB_ENTRY_AGEOUT_TIME))
+ {
+ /* Remove the aged entry */
+ if (pEntry == pIPMacTable->hash[hashIdx])
+ {
+ pIPMacTable->hash[hashIdx]= pEntry->pNext;
+ pPrev = pIPMacTable->hash[hashIdx];
+ }
+ else
+ {
+ pPrev->pNext = pEntry->pNext;
+ }
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+
+ pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
+ pMatCfg->nodeCount--;
+ }
+ else
+ {
+ pPrev = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+ }
+
+
+ /* Allocate a new IPMacMapping entry and insert into the hash */
+ pNewEntry = (IPMacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(IPMacMappingEntry));
+ if (pNewEntry != NULL)
+ {
+ pNewEntry->ipAddr = ipAddr;
+ NdisMoveMemory(pNewEntry->macAddr, pMacAddr, 6);
+ pNewEntry->pNext = NULL;
+ NdisGetSystemUpTime(&pNewEntry->lastTime);
+
+ if (pIPMacTable->hash[hashIdx] == NULL)
+ { /* Hash list is empty, directly assign it. */
+ pIPMacTable->hash[hashIdx] = pNewEntry;
+ }
+ else
+ {
+ /* Ok, we insert the new entry into the root of hash[hashIdx] */
+ pNewEntry->pNext = pIPMacTable->hash[hashIdx];
+ pIPMacTable->hash[hashIdx] = pNewEntry;
+ }
+ /*dumpIPMacTb(pMatCfg, hashIdx); //for debug */
+
+ pMatCfg->nodeCount++;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static PUCHAR IPMacTableLookUp(
+ IN MAT_STRUCT *pMatCfg,
+ IN UINT ipAddr)
+{
+ IPMacMappingTable *pIPMacTable;
+ UINT hashIdx, ip;
+ IPMacMappingEntry *pEntry = NULL;
+ PUCHAR pGroupMacAddr;
+
+ pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
+
+ if (!pIPMacTable)
+ return NULL;
+
+ if (!pIPMacTable->valid)
+ return NULL;
+
+ /*if multicast ip, need converting multicast group address to ethernet address. */
+ ip = ntohl(ipAddr);
+ if (IS_MULTICAST_IP(ip))
+ {
+ pGroupMacAddr = (PUCHAR)(&pIPMacTable->curMcastAddr);
+ ConvertMulticastIP2MAC((PUCHAR) &ipAddr, (UCHAR **)(&pGroupMacAddr), ETH_P_IP);
+ return pIPMacTable->curMcastAddr;
+ }
+
+ /* Use hash to find out the location of that entry and get the Mac address. */
+ hashIdx = MAT_IP_ADDR_HASH_INDEX(ipAddr);
+
+/* spin_lock_irqsave(&IPMacTabLock, irqFlag); */
+ pEntry = pIPMacTable->hash[hashIdx];
+ while(pEntry)
+ {
+ if (pEntry->ipAddr == ipAddr)
+ {
+/* DBGPRINT(RT_DEBUG_TRACE, ("%s(): dstMac=%02x:%02x:%02x:%02x:%02x:%02x for mapped dstIP(%d.%d.%d.%d)\n",
+ __FUNCTION__, pEntry->macAddr[0],pEntry->macAddr[1],pEntry->macAddr[2],
+ pEntry->macAddr[3],pEntry->macAddr[4],pEntry->macAddr[5],
+ (ipAddr>>24) & 0xff, (ipAddr>>16) & 0xff, (ipAddr>>8) & 0xff, ipAddr & 0xff));
+*/
+
+ /*Update the lastTime to prevent the aging before pDA processed! */
+ NdisGetSystemUpTime(&pEntry->lastTime);
+
+ return pEntry->macAddr;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ /*
+ We didn't find any matched Mac address, our policy is treat it as
+ broadcast packet and send to all.
+ */
+ return pIPMacTable->hash[IPMAC_TB_HASH_INDEX_OF_BCAST]->macAddr;
+
+}
+
+
+static NDIS_STATUS IPMacTable_RemoveAll(
+ IN MAT_STRUCT *pMatCfg)
+{
+ IPMacMappingEntry *pEntry;
+ IPMacMappingTable *pIPMacTable;
+ INT i;
+
+
+ pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
+
+ if (!pIPMacTable)
+ return TRUE;
+
+ if (pIPMacTable->valid)
+ {
+ pIPMacTable->valid = FALSE;
+ for (i=0; i<IPMAC_TB_HASH_ENTRY_NUM; i++)
+ {
+ while((pEntry = pIPMacTable->hash[i]) != NULL)
+ {
+ pIPMacTable->hash[i] = pEntry->pNext;
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+ }
+ }
+ }
+
+/* kfree(pIPMacTable); */
+ os_free_mem(NULL, pIPMacTable);
+ pMatCfg->MatTableSet.IPMacTable = NULL;
+
+ return TRUE;
+
+}
+
+
+static NDIS_STATUS IPMacTable_init(
+ IN MAT_STRUCT *pMatCfg)
+{
+ IPMacMappingTable *pIPMacTable;
+ IPMacMappingEntry *pEntry = NULL;
+
+
+ if (pMatCfg->MatTableSet.IPMacTable != NULL)
+ {
+ pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
+ }
+ else
+ {
+/* pMatCfg->MatTableSet.IPMacTable = kmalloc(sizeof(IPMacMappingTable), GFP_KERNEL); */
+ os_alloc_mem_suspend(NULL, (UCHAR **)&(pMatCfg->MatTableSet.IPMacTable), sizeof(IPMacMappingTable));
+ if (pMatCfg->MatTableSet.IPMacTable)
+ {
+ pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
+ NdisZeroMemory(pIPMacTable, sizeof(IPMacMappingTable));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("IPMacTable_init(): Allocate memory for IPMacTable failed!\n"));
+ return FALSE;
+ }
+ }
+
+ if (pIPMacTable->valid == FALSE)
+ {
+ /*Set the last hash entry (hash[64]) as our default broadcast Mac address */
+ pEntry = (IPMacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(IPMacMappingEntry));
+ if (!pEntry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("IPMacTable_init(): Allocate memory for IPMacTable broadcast entry failed!\n"));
+ return FALSE;
+ }
+
+ /*pEntry->ipAddr = 0; */
+ NdisZeroMemory(pEntry, sizeof(IPMacMappingEntry));
+ NdisMoveMemory(&pEntry->macAddr[0], &BROADCAST_ADDR[0], 6);
+ pEntry->pNext = NULL;
+ pIPMacTable->hash[IPMAC_TB_HASH_INDEX_OF_BCAST] = pEntry;
+
+ pIPMacTable->valid = TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): IPMacTable already inited!\n", __FUNCTION__));
+ }
+
+ return TRUE;
+
+}
+
+
+static NDIS_STATUS MATProto_ARP_Exit(
+ IN MAT_STRUCT *pMatCfg)
+{
+ INT status;
+
+ status = IPMacTable_RemoveAll(pMatCfg);
+
+ return status;
+}
+
+static PUCHAR MATProto_ARP_Rx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pMacAddr)
+{
+ PUCHAR pArpHdr = NULL, pRealMac = NULL;
+ PUCHAR tgtMac, tgtIP;
+ BOOLEAN isUcastMac, isGoodIP;
+
+
+ pArpHdr = pLayerHdr;
+
+/*dumpPkt(RTPKT_TO_OSPKT(pSkb)->data, RTPKT_TO_OSPKT(pSkb)->len); */
+ /* We just take care about the target(Mac/IP address) fields. */
+ tgtMac = pArpHdr + 18;
+ tgtIP = tgtMac + 6;
+
+ /* isUcastMac = !(00:00:00:00:00:00|| mcastMac); */
+ isUcastMac = ((tgtMac[0]|tgtMac[1]|tgtMac[2]|tgtMac[3]|tgtMac[4]|tgtMac[5])!=0);
+ isUcastMac &= ((tgtMac[0] & 0x1)==0);
+
+ /* isGoodIP = ip address is not 0.0.0.0 */
+ isGoodIP = (*(UINT *)tgtIP != 0);
+
+
+ if (isUcastMac && isGoodIP)
+ pRealMac = IPMacTableLookUp(pMatCfg, *(UINT *)tgtIP);
+
+ /*
+ For need replaced mac, we need to replace the targetMAC as correct one to make
+ the real receiver can receive that.
+ */
+ if (isUcastMac && pRealMac)
+ NdisMoveMemory(tgtMac, pRealMac, MAC_ADDR_LEN);
+
+ if (pRealMac == NULL)
+ pRealMac = &BROADCAST_ADDR[0];
+/* pRealMac = pIPMacTable->hash[IPMAC_TB_HASH_INDEX_OF_BCAST]->macAddr; */
+
+ return pRealMac;
+}
+
+static PUCHAR MATProto_ARP_Tx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pMacAddr)
+{
+ PUCHAR pSMac, pSIP;
+ BOOLEAN isUcastMac, isGoodIP;
+ NET_PRO_ARP_HDR *arpHdr;
+ PUCHAR pPktHdr;
+ PNDIS_PACKET newSkb = NULL;
+
+ pPktHdr = GET_OS_PKT_DATAPTR(pSkb);
+
+ arpHdr = (NET_PRO_ARP_HDR *)pLayerHdr;
+
+ /*
+ Check the arp header.
+ We just handle ether type hardware address and IPv4 internet
+ address type and opcode is ARP reuqest/response.
+ */
+ if ((arpHdr->ar_hrd != OS_HTONS(ARPHRD_ETHER)) || (arpHdr->ar_pro != OS_HTONS(ETH_P_IP)) ||
+ (arpHdr->ar_op != OS_HTONS(ARPOP_REPLY) && arpHdr->ar_op != OS_HTONS(ARPOP_REQUEST)))
+ return NULL;
+
+ /* We just take care about the sender(Mac/IP address) fields. */
+ pSMac =(PUCHAR)(pLayerHdr + 8);
+ pSIP = (PUCHAR)(pSMac + MAC_ADDR_LEN);
+
+ isUcastMac = IS_UCAST_MAC(pSMac);
+ isGoodIP = IS_GOOD_IP(get_unaligned32((PUINT) pSIP));
+
+/*
+ DBGPRINT(RT_DEBUG_TRACE,("%s(): ARP Pkt=>senderIP=%d.%d.%d.%d, senderMac=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ __FUNCTION__, pSIP[0], pSIP[1], pSIP[2], pSIP[3],
+ pSMac[0],pSMac[1],pSMac[2],pSMac[3],pSMac[4],pSMac[5]));
+*/
+ if (isUcastMac && isGoodIP)
+ IPMacTableUpdate(pMatCfg, pSMac, get_unaligned32((PUINT) pSIP));
+
+ /*
+ For outgoing unicast mac, we need to replace the senderMAC as ourself to make
+ the receiver can send to us.
+ */
+ if (isUcastMac)
+ {
+ if(OS_PKT_CLONED(pSkb))
+ {
+ newSkb = (PNDIS_PACKET)OS_PKT_COPY(pSkb);
+ if(newSkb)
+ {
+ if (IS_VLAN_PACKET(GET_OS_PKT_DATAPTR(newSkb)))
+ pSMac = (PUCHAR)(GET_OS_PKT_DATAPTR(newSkb) + MAT_VLAN_ETH_HDR_LEN + 8);
+ else
+ pSMac = (PUCHAR)(GET_OS_PKT_DATAPTR(newSkb) + MAT_ETHER_HDR_LEN + 8);
+ }
+ }
+
+ ASSERT(pMacAddr);
+ NdisMoveMemory(pSMac, pMacAddr, MAC_ADDR_LEN);
+ }
+
+ return (PUCHAR)newSkb;
+}
+
+
+static NDIS_STATUS MATProto_ARP_Init(
+ IN MAT_STRUCT *pMatCfg)
+{
+ BOOLEAN status = FALSE;
+
+ status = IPMacTable_init(pMatCfg);
+
+ return status;
+}
+
+
+static NDIS_STATUS MATProto_IP_Exit(
+ IN MAT_STRUCT *pMatCfg)
+{
+ INT status;
+
+ status = IPMacTable_RemoveAll(pMatCfg);
+
+ return status;
+}
+
+
+static PUCHAR MATProto_IP_Rx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+ PUCHAR pMacAddr;
+ UINT dstIP;
+
+ /* Fetch the IP addres from the packet header. */
+ getDstIPFromIpPkt(pLayerHdr, &dstIP);
+ pMacAddr = IPMacTableLookUp(pMatCfg, dstIP);
+
+ return pMacAddr;
+}
+
+static UCHAR DHCP_MAGIC[]= {0x63, 0x82, 0x53, 0x63};
+static PUCHAR MATProto_IP_Tx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+ PUCHAR pSrcMac;
+ PUCHAR pSrcIP;
+ BOOLEAN needUpdate;
+ PUCHAR pPktHdr;
+
+ pPktHdr = GET_OS_PKT_DATAPTR(pSkb);
+
+ pSrcMac = pPktHdr + 6;
+ pSrcIP = pLayerHdr + 12;
+
+
+ needUpdate = NEED_UPDATE_IPMAC_TB(pSrcMac, get_unaligned32((PUINT)(pSrcIP)));
+ if (needUpdate)
+ IPMacTableUpdate(pMatCfg, pSrcMac, get_unaligned32((PUINT)(pSrcIP)));
+
+ /*For UDP packet, we need to check about the DHCP packet, to modify the flag of DHCP discovey/request as broadcast. */
+ if (*(pLayerHdr + 9) == 0x11)
+ {
+ PUCHAR udpHdr;
+ UINT16 srcPort, dstPort;
+
+ udpHdr = pLayerHdr + 20;
+ srcPort = OS_NTOHS(get_unaligned((PUINT16)(udpHdr)));
+ dstPort = OS_NTOHS(get_unaligned((PUINT16)(udpHdr+2)));
+
+ if (srcPort==68 && dstPort==67) /*It's a DHCP packet */
+ {
+ PUCHAR bootpHdr;
+ UINT16 bootpFlag;
+
+ bootpHdr = udpHdr + 8;
+ bootpFlag = OS_NTOHS(get_unaligned((PUINT16)(bootpHdr+10)));
+ DBGPRINT(RT_DEBUG_TRACE, ("is bootp packet! bootpFlag=0x%x\n", bootpFlag));
+ if (bootpFlag != 0x8000) /*check if it's a broadcast request. */
+ {
+ PUCHAR dhcpHdr;
+
+ dhcpHdr = bootpHdr + 236;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("the DHCP flag is a unicast, dhcp_magic=%02x:%02x:%02x:%02x\n",
+ dhcpHdr[0], dhcpHdr[1], dhcpHdr[2], dhcpHdr[3]));
+ if (NdisEqualMemory(dhcpHdr, DHCP_MAGIC, 4))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("dhcp magic macthed!\n"));
+ bootpFlag = OS_HTONS(0x8000);
+ NdisMoveMemory((bootpHdr+10), &bootpFlag, 2); /*Set the bootp flag as broadcast */
+ NdisZeroMemory((udpHdr+6), 2); /*modify the UDP chksum as zero */
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+static NDIS_STATUS MATProto_IP_Init(
+ IN MAT_STRUCT *pMatCfg)
+{
+ BOOLEAN status;
+
+ status = IPMacTable_init(pMatCfg);
+
+ return status;
+}
+
+
+static inline void IPintToIPstr(int ipint, char Ipstr[20], ULONG BufLen)
+{
+ int temp = 0;
+
+ temp = ipint & 0x000FF;
+ snprintf(Ipstr, BufLen, "%d.", temp);
+ temp = (ipint>>8) & 0x000FF;
+ snprintf(Ipstr, BufLen, "%s%d.", Ipstr, temp);
+ temp = (ipint>>16) & 0x000FF;
+ snprintf(Ipstr, BufLen, "%s%d.", Ipstr, temp);
+ temp = (ipint>>24) & 0x000FF;
+ snprintf(Ipstr, BufLen, "%s%d", Ipstr, temp);
+}
+
+
+VOID getIPMacTbInfo(
+ IN MAT_STRUCT *pMatCfg,
+ IN char *pOutBuf,
+ IN ULONG BufLen)
+{
+ IPMacMappingTable *pIPMacTable;
+ IPMacMappingEntry *pHead;
+ int startIdx, endIdx;
+ char Ipstr[20] = {0};
+
+
+ pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
+ if ((!pIPMacTable) || (!pIPMacTable->valid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():IPMacTable not init yet!\n", __FUNCTION__));
+ return;
+ }
+
+ /* dump all. */
+ startIdx = 0;
+ endIdx = MAT_MAX_HASH_ENTRY_SUPPORT;
+
+ sprintf(pOutBuf, "\n");
+ sprintf(pOutBuf+strlen(pOutBuf), "%-18s%-20s\n", "IP", "MAC");
+ for(; startIdx< endIdx; startIdx++)
+ {
+ pHead = pIPMacTable->hash[startIdx];
+ while(pHead)
+ {
+/* if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30)) */
+ if (RtmpOsCmdDisplayLenCheck(strlen(pOutBuf), 30) == FALSE)
+ break;
+ NdisZeroMemory(Ipstr, 20);
+ IPintToIPstr(pHead->ipAddr, Ipstr, sizeof(Ipstr));
+ sprintf(pOutBuf+strlen(pOutBuf), "%-18s%02x:%02x:%02x:%02x:%02x:%02x\n",
+ Ipstr, pHead->macAddr[0],pHead->macAddr[1],pHead->macAddr[2],
+ pHead->macAddr[3],pHead->macAddr[4],pHead->macAddr[5]);
+ pHead = pHead->pNext;
+ }
+ }
+}
+
+#endif /* MAT_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_mat_ipv6.c b/cleopatre/devkit/mt7601udrv/common/cmm_mat_ipv6.c
new file mode 100644
index 0000000000..814d001f26
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_mat_ipv6.c
@@ -0,0 +1,824 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_mat_ipv6.c
+
+ Abstract:
+ MAT convert engine subroutine for ipv6 base protocols, currently now we
+ just handle IPv6/ICMPv6 packets without Authentication/Encryption headers.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Shiang 06/03/07 Init version
+*/
+#ifdef MAT_SUPPORT
+
+#include "rt_config.h"
+#include "ipv6.h"
+
+/*#include <asm/checksum.h> */
+/*#include <net/ip6_checksum.h> */
+
+const UCHAR IPV6_LOOPBACKADDR[] ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+
+static NDIS_STATUS MATProto_IPv6_Init(MAT_STRUCT *pMatCfg);
+static NDIS_STATUS MATProto_IPv6_Exit(MAT_STRUCT *pMatCfg);
+static PUCHAR MATProto_IPv6_Rx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pDevMacAdr);
+static PUCHAR MATProto_IPv6_Tx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pDevMacAdr);
+
+#define RT_UDP_HDR_LEN 8
+
+typedef struct _IPv6MacMappingEntry
+{
+ UCHAR ipv6Addr[16]; /* In network order */
+ UCHAR macAddr[MAC_ADDR_LEN];
+ ULONG lastTime;
+ struct _IPv6MacMappingEntry *pNext;
+}IPv6MacMappingEntry, *PIPv6MacMappingEntry;
+
+
+typedef struct _IPv6MacMappingTable
+{
+ BOOLEAN valid;
+ IPv6MacMappingEntry *hash[MAT_MAX_HASH_ENTRY_SUPPORT+1]; /*0~63 for specific station, 64 for broadcast MacAddress */
+ UCHAR curMcastAddr[MAC_ADDR_LEN]; /* The multicast mac addr for currecnt received packet destined to ipv6 multicast addr */
+}IPv6MacMappingTable;
+
+
+struct _MATProtoOps MATProtoIPv6Handle =
+{
+ .init = MATProto_IPv6_Init,
+ .tx = MATProto_IPv6_Tx,
+ .rx = MATProto_IPv6_Rx,
+ .exit = MATProto_IPv6_Exit,
+};
+
+static inline BOOLEAN needUpdateIPv6MacTB(
+ UCHAR *pMac,
+ RT_IPV6_ADDR *pIPv6Addr)
+{
+ ASSERT(pIPv6Addr);
+
+ if (isMcastEtherAddr(pMac) || isZeroEtherAddr(pMac))
+ return FALSE;
+
+ /* IPv6 multicast address */
+ if (IS_MULTICAST_IPV6_ADDR(*pIPv6Addr))
+ return FALSE;
+
+ /* unspecified address */
+ if(IS_UNSPECIFIED_IPV6_ADDR(*pIPv6Addr))
+ return FALSE;
+
+ /* loopback address */
+ if (IS_LOOPBACK_IPV6_ADDR(*pIPv6Addr))
+ return FALSE;
+
+/*
+ DBGPRINT(RT_DEBUG_INFO, ("%s(): Good IPv6 unicast addr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+ __FUNCTION__, PRINT_IPV6_ADDR(*pIPv6Addr)));
+*/
+ return TRUE;
+}
+
+
+/*
+ IPv6 Header Format
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |Version| Traffic Class | Flow Label |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Payload Length | Next Header | Hop Limit |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ + +
+ | Source Address |
+ + +
+ | |
+ + +
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ + +
+ | Destination Address |
+ + +
+ | |
+ + +
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+ICMPv6 Format:
+ |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Code | Checksum |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Message Body |
+ + +
+ | |
+ ......
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+NDIS_STATUS dumpIPv6MacTb(
+ IN MAT_STRUCT *pMatCfg,
+ IN int index)
+{
+ IPv6MacMappingTable *pIPv6MacTable;
+ IPv6MacMappingEntry *pHead;
+ int startIdx, endIdx;
+
+
+ pIPv6MacTable = (IPv6MacMappingTable *)pMatCfg->MatTableSet.IPv6MacTable;
+ if ((!pIPv6MacTable) || (!pIPv6MacTable->valid))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s():IPv6MacTable not init yet, so cannot do dump!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+
+ if(index < 0)
+ { /* dump all. */
+ startIdx = 0;
+ endIdx = MAT_MAX_HASH_ENTRY_SUPPORT;
+ }
+ else
+ { /* dump specific hash index. */
+ startIdx = endIdx = index;
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("%s():\n", __FUNCTION__));
+ for(; startIdx<= endIdx; startIdx++)
+ {
+ pHead = pIPv6MacTable->hash[startIdx];
+ while(pHead)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("IPv6Mac[%d]:\n", startIdx));
+ DBGPRINT(RT_DEBUG_OFF, ("\t:IPv6=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x,Mac=%02x:%02x:%02x:%02x:%02x:%02x, lastTime=0x%lx, next=%p\n",
+ PRINT_IPV6_ADDR(*((RT_IPV6_ADDR *)(&pHead->ipv6Addr[0]))), pHead->macAddr[0],pHead->macAddr[1],pHead->macAddr[2],
+ pHead->macAddr[3],pHead->macAddr[4],pHead->macAddr[5], pHead->lastTime, pHead->pNext));
+ pHead = pHead->pNext;
+ }
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\t----EndOfDump!\n"));
+
+ return TRUE;
+}
+
+
+
+static NDIS_STATUS IPv6MacTableUpdate(
+ IN MAT_STRUCT *pMatCfg,
+ IN PUCHAR pMacAddr,
+ IN PCHAR pIPv6Addr)
+{
+ UINT hashIdx;
+ IPv6MacMappingTable *pIPv6MacTable;
+ IPv6MacMappingEntry *pEntry = NULL, *pPrev = NULL, *pNewEntry =NULL;
+ ULONG now;
+
+
+ pIPv6MacTable = (IPv6MacMappingTable *)pMatCfg->MatTableSet.IPv6MacTable;
+ if ((!pIPv6MacTable) || (!pIPv6MacTable->valid))
+ return FALSE;
+
+ hashIdx = MAT_IPV6_ADDR_HASH_INDEX(pIPv6Addr);
+ pEntry = pPrev = pIPv6MacTable->hash[hashIdx];
+ while(pEntry)
+ {
+ NdisGetSystemUpTime(&now);
+
+ /* Find a existed IP-MAC Mapping entry */
+ if (NdisEqualMemory(pIPv6Addr, pEntry->ipv6Addr, IPV6_ADDR_LEN))
+ {
+
+ /* comparison is useless. So we directly copy it into the entry. */
+ NdisMoveMemory(pEntry->macAddr, pMacAddr, 6);
+ NdisGetSystemUpTime(&pEntry->lastTime);
+
+ return TRUE;
+ }
+ else
+ { /* handle the aging-out situation */
+ if (RTMP_TIME_AFTER(now, (pEntry->lastTime + MAT_TB_ENTRY_AGEOUT_TIME)))
+ {
+ /* Remove the aged entry */
+ if (pEntry == pIPv6MacTable->hash[hashIdx])
+ {
+ pIPv6MacTable->hash[hashIdx]= pEntry->pNext;
+ pPrev = pIPv6MacTable->hash[hashIdx];
+ }
+ else
+ {
+ pPrev->pNext = pEntry->pNext;
+ }
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+
+ pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
+ pMatCfg->nodeCount--;
+ }
+ else
+ {
+ pPrev = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+ }
+
+
+ /* Allocate a new IPv6MacMapping entry and insert into the hash */
+ pNewEntry = (IPv6MacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(IPv6MacMappingEntry));
+ if (pNewEntry != NULL)
+ {
+ NdisMoveMemory(pNewEntry->ipv6Addr, pIPv6Addr, IPV6_ADDR_LEN);
+ NdisMoveMemory(pNewEntry->macAddr, pMacAddr, 6);
+ pNewEntry->pNext = NULL;
+ NdisGetSystemUpTime(&pNewEntry->lastTime);
+
+ if (pIPv6MacTable->hash[hashIdx] == NULL)
+ { /* Hash list is empty, directly assign it. */
+ pIPv6MacTable->hash[hashIdx] = pNewEntry;
+ }
+ else
+ {
+ /* Ok, we insert the new entry into the root of hash[hashIdx] */
+ pNewEntry->pNext = pIPv6MacTable->hash[hashIdx];
+ pIPv6MacTable->hash[hashIdx] = pNewEntry;
+ }
+ /*dumpIPv6MacTb(pMatCfg, hashIdx); //for debug */
+
+ pMatCfg->nodeCount++;
+
+ return TRUE;
+ }
+
+ DBGPRINT(RT_DEBUG_ERROR, ("IPv6MacTableUpdate():Insertion failed!\n"));
+
+ return FALSE;
+}
+
+
+static PUCHAR IPv6MacTableLookUp(
+ IN MAT_STRUCT *pMatCfg,
+ IN PUCHAR pIPv6Addr)
+{
+ UINT hashIdx;
+ IPv6MacMappingTable *pIPv6MacTable;
+ IPv6MacMappingEntry *pEntry = NULL;
+ PUCHAR pGroupMacAddr;
+
+
+ pIPv6MacTable = (IPv6MacMappingTable *)pMatCfg->MatTableSet.IPv6MacTable;
+ if ((!pIPv6MacTable) ||(!pIPv6MacTable->valid))
+ return NULL;
+
+ /*if IPV6 multicast address, need converting multicast group address to ethernet address. */
+ if (IS_MULTICAST_IPV6_ADDR(*(RT_IPV6_ADDR *)pIPv6Addr))
+ {
+ pGroupMacAddr = (PUCHAR)&pIPv6MacTable->curMcastAddr;
+ ConvertMulticastIP2MAC(pIPv6Addr, (UCHAR **)(&pGroupMacAddr), ETH_P_IPV6);
+ return pIPv6MacTable->curMcastAddr;
+ }
+
+ /* Use hash to find out the location of that entry and get the Mac address. */
+ hashIdx = MAT_IPV6_ADDR_HASH_INDEX(pIPv6Addr);
+
+/* spin_lock_irqsave(&IPMacTabLock, irqFlag); */
+ pEntry = pIPv6MacTable->hash[hashIdx];
+ while(pEntry)
+ {
+ if (NdisEqualMemory(pEntry->ipv6Addr, pIPv6Addr, IPV6_ADDR_LEN))
+ {
+
+ /*Update the lastTime to prevent the aging before pDA processed! */
+ NdisGetSystemUpTime(&pEntry->lastTime);
+
+ return pEntry->macAddr;
+ }
+ else
+ {
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ /*
+ We didn't find any matched Mac address, our policy is treat it as
+ broadcast packet and send to all.
+ */
+ return pIPv6MacTable->hash[IPV6MAC_TB_HASH_INDEX_OF_BCAST]->macAddr;
+
+}
+
+
+static inline unsigned short int icmpv6_csum(
+ RT_IPV6_ADDR *saddr,
+ RT_IPV6_ADDR *daddr,
+ USHORT len,
+ UCHAR proto,
+ UCHAR *pICMPMsg)
+{
+ int carry;
+ UINT32 ulen;
+ UINT32 uproto;
+ int i;
+ unsigned int csum = 0;
+ unsigned short int chksum;
+
+ if (len % 4)
+ return 0;
+
+ for( i = 0; i < 4; i++)
+ {
+ csum += saddr->ipv6_addr32[i];
+ carry = (csum < saddr->ipv6_addr32[i]);
+ csum += carry;
+ }
+
+ for( i = 0; i < 4; i++)
+ {
+ csum += daddr->ipv6_addr32[i];
+ carry = (csum < daddr->ipv6_addr32[i]);
+ csum += carry;
+ }
+
+ ulen = OS_HTONL((UINT32)len);
+ csum += ulen;
+ carry = (csum < ulen);
+ csum += carry;
+
+ uproto = OS_HTONL((UINT32)proto);
+ csum += uproto;
+ carry = (csum < uproto);
+ csum += carry;
+
+ for (i = 0; i < len; i += 4)
+ {
+ csum += get_unaligned32(((UINT32 *)&pICMPMsg[i]));
+ carry = (csum < get_unaligned32(((UINT32 *)&pICMPMsg[i])));
+ csum += carry;
+ }
+
+ while (csum>>16)
+ csum = (csum & 0xffff) + (csum >> 16);
+
+ chksum = ~csum;
+
+ return chksum;
+}
+
+
+
+static PUCHAR MATProto_IPv6_Rx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+
+ PUCHAR pMacAddr;
+ PUCHAR pDstIPv6Addr;
+
+ /* Fetch the IPv6 addres from the packet header. */
+ pDstIPv6Addr = (UCHAR *)(&((RT_IPV6_HDR *)pLayerHdr)->dstAddr);
+
+ pMacAddr = IPv6MacTableLookUp(pMatCfg, pDstIPv6Addr);
+
+ return pMacAddr;
+
+}
+
+static PNDIS_PACKET ICMPv6_Handle_Tx(
+ IN MAT_STRUCT *pMatSrtuct,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr,
+ IN UINT32 offset)
+{
+ RT_IPV6_HDR *pIPv6Hdr;
+ RT_ICMPV6_HDR *pICMPv6Hdr;
+ RT_ICMPV6_OPTION_HDR *pOptHdr;
+
+ USHORT payloadLen;
+ UINT32 ICMPOffset = 0, ICMPMsgLen = 0, leftLen;
+
+ PNDIS_PACKET newSkb = NULL;
+ BOOLEAN needModify = FALSE;
+ PUCHAR pSrcMac;
+
+ pIPv6Hdr = (RT_IPV6_HDR *)pLayerHdr;
+ payloadLen = OS_NTOHS(pIPv6Hdr->payload_len);
+
+ pICMPv6Hdr = (RT_ICMPV6_HDR *)(pLayerHdr + offset);
+ ICMPOffset = offset;
+ ICMPMsgLen = payloadLen + IPV6_HDR_LEN - ICMPOffset;
+
+
+
+ leftLen = ICMPMsgLen;
+ switch (pICMPv6Hdr->type)
+ {
+ case ICMPV6_MSG_TYPE_ROUTER_SOLICITATION:
+ offset += ROUTER_SOLICITATION_FIXED_LEN;
+ /* for unspecified source address, it should not include the option about link-layer address. */
+ if (!(IS_UNSPECIFIED_IPV6_ADDR(pIPv6Hdr->srcAddr)))
+ {
+ while(leftLen > sizeof(RT_ICMPV6_OPTION_HDR))
+ {
+ pOptHdr = (RT_ICMPV6_OPTION_HDR *)(pLayerHdr + offset);
+ if (pOptHdr->len == 0)
+ break; /* discard it, because it's invalid. */
+
+ if (pOptHdr->type == TYPE_SRC_LL_ADDR)
+ {
+ /*replace the src link-layer address as ours. */
+ needModify = TRUE;
+ offset += 2; /* 2 = "type, len" fields. Here indicate to the place of src mac. */
+
+ break;
+ } else {
+ offset += (pOptHdr->len * 8); /* in unit of 8 octets. */
+ leftLen -= (pOptHdr->len * 8);
+ }
+ }
+ }
+ break;
+
+ case ICMPV6_MSG_TYPE_ROUTER_ADVERTISEMENT:
+ offset += ROUTER_ADVERTISEMENT_FIXED_LEN;
+ /* for unspecified source address, it should not include the option about link-layer address. */
+ if (!(IS_UNSPECIFIED_IPV6_ADDR(pIPv6Hdr->srcAddr)))
+ {
+ while(leftLen > sizeof(RT_ICMPV6_OPTION_HDR))
+ {
+ pOptHdr = (RT_ICMPV6_OPTION_HDR *)(pLayerHdr + offset);
+ if (pOptHdr->len == 0)
+ break; /* discard it, because it's invalid. */
+
+ if (pOptHdr->type == TYPE_SRC_LL_ADDR)
+ {
+ /*replace the src link-layer address as ours. */
+ needModify = TRUE;
+ offset += 2; /* 2 = "type, len" fields. Here indicate to the place of src mac. */
+
+ break;
+ } else {
+ offset += (pOptHdr->len * 8); /* in unit of 8 octets. */
+ leftLen -= (pOptHdr->len * 8);
+ }
+ }
+ }
+ break;
+
+ case ICMPV6_MSG_TYPE_NEIGHBOR_SOLICITATION:
+ offset += NEIGHBOR_SOLICITATION_FIXED_LEN;
+ /* for unspecified source address, it should not include the option about link-layer address. */
+ if (!(IS_UNSPECIFIED_IPV6_ADDR(pIPv6Hdr->srcAddr)))
+ {
+ while(leftLen > sizeof(RT_ICMPV6_OPTION_HDR))
+ {
+ pOptHdr = (RT_ICMPV6_OPTION_HDR *)(pLayerHdr + offset);
+ if (pOptHdr->len == 0)
+ break; /* discard it, because it's invalid. */
+
+ if (pOptHdr->type == TYPE_SRC_LL_ADDR)
+ {
+ /*replace the src link-layer address as ours. */
+ needModify = TRUE;
+ offset += 2; /* 2 = "type, len" fields. Here indicate to the place of src mac. */
+
+ break;
+ } else {
+ offset += (pOptHdr->len * 8); /* in unit of 8 octets. */
+ leftLen -= (pOptHdr->len * 8);
+ }
+ }
+ }
+ break;
+
+ case ICMPV6_MSG_TYPE_NEIGHBOR_ADVERTISEMENT:
+ offset += NEIGHBOR_ADVERTISEMENT_FIXED_LEN;
+ /* for unspecified source address, it should not include the option about link-layer address. */
+ if (!(IS_UNSPECIFIED_IPV6_ADDR(pIPv6Hdr->srcAddr)))
+ {
+ while(leftLen > sizeof(RT_ICMPV6_OPTION_HDR))
+ {
+ pOptHdr = (RT_ICMPV6_OPTION_HDR *)(pLayerHdr + offset);
+ if (pOptHdr->len == 0)
+ break; /* discard it, because it's invalid. */
+
+ if (pOptHdr->type == TYPE_TGT_LL_ADDR)
+ {
+ /*replace the src link-layer address as ours. */
+ needModify = TRUE;
+ offset += 2; /* 2 = "type, len" fields. */
+
+ break;
+ }else {
+ offset += (pOptHdr->len * 8); /* in unit of 8 octets. */
+ leftLen -= (pOptHdr->len * 8);
+ }
+ }
+ }
+ break;
+ case ICMPV6_MSG_TYPE_REDIRECT:
+ offset += REDIRECT_FIXED_LEN;
+ /* for unspecified source address, it should not include the options about link-layer address. */
+ if (!(IS_UNSPECIFIED_IPV6_ADDR(pIPv6Hdr->srcAddr)))
+ {
+ while(leftLen > sizeof(RT_ICMPV6_OPTION_HDR))
+ {
+ pOptHdr = (RT_ICMPV6_OPTION_HDR *)(pLayerHdr + offset);
+ if (pOptHdr->len == 0)
+ break; /* discard it, because it's invalid. */
+
+ if (pOptHdr->type == TYPE_TGT_LL_ADDR)
+ {
+ /* TODO: Need to check if the TGT_LL_ADDR is the inner MAC. */
+ /*replace the src link-layer address as ours. */
+ needModify = TRUE;
+ offset += 2; /* 2 = "type, len" fields. */
+
+ break;
+ }else {
+ offset += (pOptHdr->len * 8); /* in unit of 8 octets. */
+ leftLen -= (pOptHdr->len * 8);
+ }
+ }
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Un-supported ICMPv6 msg type(0x%x)! Ignore it\n", pICMPv6Hdr->type));
+ break;
+ }
+
+ /* We need to handle about the solicitation/Advertisement packets. */
+ if (needModify)
+ {
+ if(OS_PKT_CLONED(pSkb))
+ {
+ newSkb = (PNDIS_PACKET)OS_PKT_COPY(RTPKT_TO_OSPKT(pSkb));
+ if(newSkb) {
+ if (IS_VLAN_PACKET(GET_OS_PKT_DATAPTR(newSkb)))
+ pIPv6Hdr = (RT_IPV6_HDR *)(GET_OS_PKT_DATAPTR(newSkb) + MAT_VLAN_ETH_HDR_LEN);
+ else
+ pIPv6Hdr = (RT_IPV6_HDR *)(GET_OS_PKT_DATAPTR(newSkb) + MAT_ETHER_HDR_LEN);
+ }
+ }
+
+ pICMPv6Hdr = (RT_ICMPV6_HDR *)((PUCHAR)pIPv6Hdr + ICMPOffset);
+ pSrcMac = (PUCHAR)((PUCHAR)pIPv6Hdr + offset);
+ NdisMoveMemory(pSrcMac, pDevMacAdr, MAC_ADDR_LEN);
+
+ /* Now re-calculate the Checksum. */
+ pICMPv6Hdr->chksum = 0;
+ pICMPv6Hdr->chksum = icmpv6_csum(&pIPv6Hdr->srcAddr, &pIPv6Hdr->dstAddr, ICMPMsgLen ,
+ IPV6_NEXT_HEADER_ICMPV6, (PUCHAR)pICMPv6Hdr);
+ }
+
+ return newSkb;
+
+}
+
+
+static PUCHAR MATProto_IPv6_Tx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+ PUCHAR pSrcMac, pSrcIP;
+ BOOLEAN needUpdate;
+ UCHAR nextProtocol;
+ UINT32 offset;
+ HEADER_802_3 *pEthHdr;
+ RT_IPV6_HDR *pIPv6Hdr;
+ PNDIS_PACKET newSkb = NULL;
+
+ pIPv6Hdr = (RT_IPV6_HDR *)pLayerHdr;
+ pEthHdr = (HEADER_802_3 *)(GET_OS_PKT_DATAPTR(pSkb));
+
+ pSrcMac = (UCHAR *)&pEthHdr->SAAddr2;
+ pSrcIP = (UCHAR *)&pIPv6Hdr->srcAddr;
+
+
+
+ needUpdate = needUpdateIPv6MacTB(pSrcMac, (RT_IPV6_ADDR *)(&pIPv6Hdr->srcAddr));
+ if (needUpdate)
+ IPv6MacTableUpdate(pMatCfg, pSrcMac, (CHAR *)(&pIPv6Hdr->srcAddr));
+
+
+ /* We need to traverse the whole IPv6 Header and extend headers to check about the ICMPv6 pacekt. */
+
+ nextProtocol = pIPv6Hdr->nextHdr;
+ offset = IPV6_HDR_LEN;
+ /*DBGPRINT(RT_DEBUG_INFO, ("NextProtocol=0x%x! payloadLen=%d! offset=%d!\n", nextProtocol, payloadLen, offset)); */
+ while(nextProtocol != IPV6_NEXT_HEADER_ICMPV6 &&
+ nextProtocol != IPV6_NEXT_HEADER_UDP &&
+ nextProtocol != IPV6_NEXT_HEADER_TCP &&
+ nextProtocol != IPV6_NEXT_HEADER_NONE)
+ {
+ if(IPv6ExtHdrHandle((RT_IPV6_EXT_HDR *)(pLayerHdr + offset), &nextProtocol, &offset) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("IPv6ExtHdrHandle failed!\n"));
+ break;
+ }
+ }
+
+ switch (nextProtocol)
+ {
+ case IPV6_NEXT_HEADER_ICMPV6:
+ newSkb = ICMPv6_Handle_Tx(pMatCfg, pSkb, pLayerHdr, pDevMacAdr, offset);
+ break;
+
+ case IPV6_NEXT_HEADER_UDP:
+ /*newSkb = DHCPv6_Handle_Tx(pMatStrcut, pSkb, pLayerHdr, pMacAddr, offset); */
+ break;
+
+ case IPV6_NEXT_HEADER_TCP:
+ case IPV6_NEXT_HEADER_NONE:
+ default:
+ break;
+ }
+
+ return (PUCHAR)newSkb;
+
+}
+
+
+
+static NDIS_STATUS IPv6MacTable_RemoveAll(
+ IN MAT_STRUCT *pMatCfg)
+{
+ IPv6MacMappingTable *pIPv6MacTable;
+ IPv6MacMappingEntry *pEntry;
+ UINT32 i;
+
+
+ pIPv6MacTable = (IPv6MacMappingTable *)pMatCfg->MatTableSet.IPv6MacTable;
+ if (!pIPv6MacTable)
+ return TRUE;
+
+ if (pIPv6MacTable->valid)
+ {
+ pIPv6MacTable->valid = FALSE;
+ for (i=0; i<IPV6MAC_TB_HASH_ENTRY_NUM; i++)
+ {
+ while((pEntry = pIPv6MacTable->hash[i]) != NULL)
+ {
+ pIPv6MacTable->hash[i] = pEntry->pNext;
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+ }
+ }
+ }
+
+/* kfree(pIPv6MacTable); */
+ os_free_mem(NULL, pIPv6MacTable);
+ pMatCfg->MatTableSet.IPv6MacTable = NULL;
+
+ return TRUE;
+
+}
+
+
+static NDIS_STATUS IPv6MacTable_init(
+ IN MAT_STRUCT *pMatCfg)
+{
+ IPv6MacMappingEntry *pEntry = NULL;
+ IPv6MacMappingTable *pIPv6MacTable;
+
+
+ if (pMatCfg->MatTableSet.IPv6MacTable != NULL)
+ {
+ pIPv6MacTable = (IPv6MacMappingTable *)pMatCfg->MatTableSet.IPv6MacTable;
+ }
+ else
+ {
+/* pMatCfg->MatTableSet.IPv6MacTable = kmalloc(sizeof(IPv6MacMappingTable), GFP_KERNEL); */
+ os_alloc_mem_suspend(NULL, (UCHAR **)&(pMatCfg->MatTableSet.IPv6MacTable), sizeof(IPv6MacMappingTable));
+ if (pMatCfg->MatTableSet.IPv6MacTable)
+ {
+ pIPv6MacTable = (IPv6MacMappingTable *)pMatCfg->MatTableSet.IPv6MacTable;
+ NdisZeroMemory(pIPv6MacTable, sizeof(IPv6MacMappingTable));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("IPMacTable_init(): Allocate memory for IPv6MacTable failed!\n"));
+ return FALSE;
+ }
+ }
+
+ if (pIPv6MacTable->valid == FALSE)
+ {
+ /*Set the last hash entry (hash[64]) as our default broadcast Mac address */
+ pEntry = (IPv6MacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(IPv6MacMappingEntry));
+ if (!pEntry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("IPMacTable_init(): Allocate memory for IPMacTable broadcast entry failed!\n"));
+ return FALSE;
+ }
+ NdisZeroMemory(pEntry, sizeof(IPv6MacMappingEntry));
+ NdisMoveMemory(pEntry->macAddr, BROADCAST_ADDR, MAC_ADDR_LEN);
+ pEntry->pNext = NULL;
+ pIPv6MacTable->hash[IPV6MAC_TB_HASH_INDEX_OF_BCAST] = pEntry;
+
+ pIPv6MacTable->valid = TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): IPv6MacTable already inited!\n", __FUNCTION__));
+ }
+
+ return TRUE;
+
+}
+
+
+static NDIS_STATUS MATProto_IPv6_Exit(
+ IN MAT_STRUCT *pMatCfg)
+{
+ INT status;
+
+ status = IPv6MacTable_RemoveAll(pMatCfg);
+
+ return status;
+}
+
+
+static NDIS_STATUS MATProto_IPv6_Init(
+ IN MAT_STRUCT *pMatCfg)
+{
+
+ BOOLEAN status = FALSE;
+
+ status = IPv6MacTable_init(pMatCfg);
+
+ return status;
+}
+
+
+
+VOID getIPv6MacTbInfo(
+ IN MAT_STRUCT *pMatCfg,
+ IN char *pOutBuf,
+ IN ULONG BufLen)
+{
+ IPv6MacMappingTable *pIPv6MacTable;
+ IPv6MacMappingEntry *pHead;
+ int startIdx, endIdx;
+ char Ipv6str[40] = {0};
+
+
+ pIPv6MacTable = (IPv6MacMappingTable *)pMatCfg->MatTableSet.IPv6MacTable;
+ if ((!pIPv6MacTable) || (!pIPv6MacTable->valid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():IPv6MacTable not init yet!\n", __FUNCTION__));
+ return;
+ }
+
+
+ /* dump all. */
+ startIdx = 0;
+ endIdx = MAT_MAX_HASH_ENTRY_SUPPORT;
+
+ sprintf(pOutBuf, "\n");
+ sprintf(pOutBuf+strlen(pOutBuf), "%-40s%-20s\n", "IP", "MAC");
+ for(; startIdx< endIdx; startIdx++)
+ {
+ pHead = pIPv6MacTable->hash[startIdx];
+
+ while(pHead)
+ {
+/* if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30)) */
+ if (RtmpOsCmdDisplayLenCheck(strlen(pOutBuf), 30) == FALSE)
+ break;
+ NdisZeroMemory(Ipv6str, 40);
+ sprintf(Ipv6str, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", PRINT_IPV6_ADDR(*((RT_IPV6_ADDR *)(&pHead->ipv6Addr[0]))));
+ sprintf(pOutBuf+strlen(pOutBuf), "%-40s%02x:%02x:%02x:%02x:%02x:%02x\n",
+ Ipv6str, pHead->macAddr[0],pHead->macAddr[1],pHead->macAddr[2],
+ pHead->macAddr[3],pHead->macAddr[4],pHead->macAddr[5]);
+ pHead = pHead->pNext;
+ }
+ }
+}
+
+#endif /* MAT_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_mat_pppoe.c b/cleopatre/devkit/mt7601udrv/common/cmm_mat_pppoe.c
new file mode 100644
index 0000000000..8988a7dcb6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_mat_pppoe.c
@@ -0,0 +1,1062 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_mat_pppoe.c
+
+ Abstract:
+ MAT convert engine subroutine for PPPoE protocol.Due to the difference
+ of characteristic of PPPoE discovery stage and session stage, we seperate
+ that as two parts and used different stretegy to handle it.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Shiang 02/26/07 Init version
+*/
+
+#ifdef MAT_SUPPORT
+
+#include "rt_config.h"
+
+static NDIS_STATUS MATProto_PPPoEDis_Init(MAT_STRUCT *pMatStruct);
+static NDIS_STATUS MATProto_PPPoEDis_Exit(MAT_STRUCT *pMatStruct);
+static PUCHAR MATProto_PPPoEDis_Rx(MAT_STRUCT *pMatStruct, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pDevMacAdr);
+static PUCHAR MATProto_PPPoEDis_Tx(MAT_STRUCT *pMatStruct, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pDevMacAdr);
+
+static NDIS_STATUS MATProto_PPPoESes_Init(MAT_STRUCT *pMatStruct);
+static NDIS_STATUS MATProto_PPPoESes_Exit(MAT_STRUCT *pMatStruct);
+static PUCHAR MATProto_PPPoESes_Rx(MAT_STRUCT *pMatStruct, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pDevMacAdr);
+static PUCHAR MATProto_PPPoESes_Tx(MAT_STRUCT *pMatStruct, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pDevMacAdr);
+
+
+/*
+ 1 2 3 4
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | VER | TYPE | CODE | SESSION_ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | LENGTH | payload ~
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ VER = 0x1, TYPE =0x1
+
+PPPoE Discovery Stage(Ethernet protocol type = 0x8863):
+ PADI:
+ DESTINATION_ADDR = 0xffffffff
+ CODE = 0x09, SESSION_ID = 0x0000
+ LENGTH = payload length
+
+ PADO:
+ DESTINATION_ADDR = Unicast Ethernet address of sender
+ CODE = 0x07, SESSION_ID = 0x0000
+ LENGTH = payload length
+ NEcessary TAGS: AC-NAME(0x0102), Sevice-Name(0x0101), and other service names.
+
+ Note: if the PPPoE server cannot serve the PADI it MUST NOT respond with a PADO
+
+
+ PADR:
+ DESTINATION_ADDR = unicast Ethernet address
+ CODE = 0x19, SESSION_ID = 0x0000
+ LENGTH = payload length
+ Necessary TAGS: Service-Name(0x0101)
+ Optional TAGS: ....
+
+ PADS:
+ If success:
+ DESTINATION_ADDR = unicast Ethernet address
+ CODE = 0x65, SESSION_ID = unique value for this pppoe session.(16 bits)
+ LENGHT - payload length
+ Necessary TAGS: Service-Name(0x0101)
+
+ if failed:
+ SESSION_ID = 0x0000
+ Necessary TAGS: Service-Name-Error(0x0201).
+
+ PADT:
+ DESTINATION_ADDR = unicast Ethernet address
+ CODE = 0xa7, SESSION_ID = previous assigned 16 bits session ID.
+ Necessary TAGS: NO.
+
+PPPoE Session Stage(Ethernet protocol type = 0x8864):
+ PPP data:
+ DESTINATION_ADDR = unicast Ethernet address
+ CODE = 0x00,
+ LCP:
+ DESTINATION_ADDR = unicast Ethernet address
+ CODE = 0x00,
+
+*/
+
+#define PPPOE_CODE_PADI 0x09
+#define PPPOE_CODE_PADO 0x07
+#define PPPOE_CODE_PADR 0x19
+#define PPPOE_CODE_PADS 0x65
+#define PPPOE_CODE_PADT 0xa7
+#define PPPOE_TAG_ID_HOST_UNIQ 0x0103
+#define PPPOE_TAG_ID_AC_COOKIE 0x0104
+
+#define PPPoE_SES_ENTRY_AGEOUT_TIME 3000
+
+/* Data structure used for PPPoE discovery stage */
+#define PPPOE_DIS_UID_LEN 6
+typedef struct _UidMacMappingEntry
+{
+ UCHAR isServer;
+ UCHAR uIDAddByUs; /* If the host-uniq or AC-cookie is add by our driver, set it as 1, else set as 0. */
+ UCHAR uIDStr[PPPOE_DIS_UID_LEN]; /* String used for identify who sent this pppoe packet in discovery stage. */
+ UCHAR macAddr[MAC_ADDR_LEN]; /* Mac address associated to this uid string. */
+ ULONG lastTime;
+ struct _UidMacMappingEntry *pNext; /*Pointer to next entry in link-list of Uid hash table. */
+}UidMacMappingEntry, *PUidMacMappingEntry;
+
+typedef struct _UidMacMappingTable
+{
+ BOOLEAN valid;
+ UidMacMappingEntry *uidHash[MAT_MAX_HASH_ENTRY_SUPPORT];
+}UidMacMappingTable;
+
+/* "Host-Uniq <-> Mac Address" Mapping table used for PPPoE Discovery stage */
+
+/* Data struct used for PPPoE session stage */
+typedef struct _SesMacMappingEntry
+{
+ UINT16 sessionID; /* In network order */
+ UCHAR outMacAddr[MAC_ADDR_LEN];
+ UCHAR inMacAddr[MAC_ADDR_LEN];
+ ULONG lastTime;
+ struct _SesMacMappingEntry *pNext;
+}SesMacMappingEntry, *PSesMacMappingEntry;
+
+typedef struct _SesMacMappingTable
+{
+ BOOLEAN valid;
+ SesMacMappingEntry *sesHash[MAT_MAX_HASH_ENTRY_SUPPORT];
+}SesMacMappingTable;
+
+/* Declaration of protocol handler for PPPoE Discovery stage */
+struct _MATProtoOps MATProtoPPPoEDisHandle =
+{
+ .init = MATProto_PPPoEDis_Init,
+ .tx = MATProto_PPPoEDis_Tx,
+ .rx = MATProto_PPPoEDis_Rx,
+ .exit = MATProto_PPPoEDis_Exit,
+};
+
+/* Declaration of protocol handler for PPPoE Session stage */
+struct _MATProtoOps MATProtoPPPoESesHandle =
+{
+ .init = MATProto_PPPoESes_Init,
+ .tx = MATProto_PPPoESes_Tx,
+ .rx = MATProto_PPPoESes_Rx,
+ .exit =MATProto_PPPoESes_Exit,
+};
+
+
+NDIS_STATUS dumpSesMacTb(
+ IN MAT_STRUCT *pMatCfg,
+ IN int hashIdx)
+{
+ SesMacMappingTable *pSesMacTable;
+ SesMacMappingEntry *pHead;
+ int startIdx, endIdx;
+
+
+ pSesMacTable = (SesMacMappingTable *)pMatCfg->MatTableSet.SesMacTable;
+ if ((!pSesMacTable) || (!pSesMacTable->valid))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("SesMacTable not init yet, so cannot do dump!\n"));
+ return FALSE;
+ }
+
+ if(hashIdx < 0)
+ { /* dump all. */
+ startIdx = 0;
+ endIdx = MAT_MAX_HASH_ENTRY_SUPPORT - 1;
+ }
+ else
+ { /* dump specific hash index. */
+ startIdx = endIdx = hashIdx;
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("%s():\n", __FUNCTION__));
+ for (; startIdx<= endIdx; startIdx++)
+ {
+ pHead = pSesMacTable->sesHash[startIdx];
+ while(pHead)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("SesMac[%d]:\n", startIdx));
+ DBGPRINT(RT_DEBUG_OFF, ("\tsesID=%d,inMac=%02x:%02x:%02x:%02x:%02x:%02x,outMac=%02x:%02x:%02x:%02x:%02x:%02x,lastTime=0x%lx, pNext=%p\n",
+ pHead->sessionID, PRINT_MAC(pHead->inMacAddr), PRINT_MAC(pHead->outMacAddr), pHead->lastTime, pHead->pNext));
+ pHead = pHead->pNext;
+ }
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\t----EndOfDump!\n"));
+
+ return TRUE;
+
+}
+
+
+NDIS_STATUS dumpUidMacTb(MAT_STRUCT *pMatCfg, int hashIdx)
+{
+ UidMacMappingTable *pUidMacTable;
+ UidMacMappingEntry *pHead;
+ int i;
+ int startIdx, endIdx;
+
+
+ pUidMacTable = (UidMacMappingTable *)pMatCfg->MatTableSet.UidMacTable;
+ if ((!pUidMacTable) || (!pUidMacTable->valid))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("UidMacTable not init yet, so cannot do dump!\n"));
+ return FALSE;
+ }
+
+ if(hashIdx < 0)
+ { /* dump all. */
+ startIdx = 0;
+ endIdx = MAT_MAX_HASH_ENTRY_SUPPORT-1;
+ }
+ else
+ { /* dump specific hash index. */
+ startIdx = endIdx = hashIdx;
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("%s():\n", __FUNCTION__));
+ for (; startIdx<= endIdx; startIdx++)
+ {
+ pHead = pUidMacTable->uidHash[startIdx];
+ while(pHead)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("UidMac[%d]:\n", startIdx));
+ DBGPRINT(RT_DEBUG_OFF, ("\tisSrv=%d, uIDAddbyUs=%d, Mac=%02x:%02x:%02x:%02x:%02x:%02x, lastTime=0x%lx, pNext=%p\n",
+ pHead->isServer, pHead->uIDAddByUs, PRINT_MAC(pHead->macAddr), pHead->lastTime, pHead->pNext));
+ DBGPRINT(RT_DEBUG_OFF, ("\tuIDStr="));
+ for(i=0; i< PPPOE_DIS_UID_LEN; i++)
+ DBGPRINT(RT_DEBUG_OFF, ("%02x", pHead->uIDStr[i]));
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+ pHead = pHead->pNext;
+ }
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("\t----EndOfDump!\n"));
+
+ return TRUE;
+}
+
+
+static NDIS_STATUS UidMacTable_RemoveAll(
+ IN MAT_STRUCT *pMatCfg)
+{
+ UidMacMappingTable *pUidMacTable;
+ UidMacMappingEntry *pEntry;
+ INT i;
+
+ pUidMacTable = (UidMacMappingTable *)pMatCfg->MatTableSet.UidMacTable;
+
+ if(!pUidMacTable)
+ return TRUE;
+
+ if (pUidMacTable->valid)
+ {
+ pUidMacTable->valid = FALSE;
+ for (i=0; i<MAT_MAX_HASH_ENTRY_SUPPORT; i++)
+ {
+ while((pEntry = pUidMacTable->uidHash[i]) != NULL)
+ {
+ pUidMacTable->uidHash[i] = pEntry->pNext;
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+ }
+ }
+ }
+
+/* kfree(pMatCfg->MatTableSet.UidMacTable); */
+ os_free_mem(NULL, pMatCfg->MatTableSet.UidMacTable);
+ pMatCfg->MatTableSet.UidMacTable = NULL;
+
+ return TRUE;
+}
+
+
+static NDIS_STATUS SesMacTable_RemoveAll(
+ IN MAT_STRUCT *pMatCfg)
+{
+ SesMacMappingTable *pSesMacTable;
+ SesMacMappingEntry *pEntry;
+ INT i;
+
+ pSesMacTable = (SesMacMappingTable *)pMatCfg->MatTableSet.SesMacTable;
+ if (!pSesMacTable)
+ return TRUE;
+
+ if (pSesMacTable->valid)
+ {
+ pSesMacTable->valid = FALSE;
+ for (i=0; i<MAT_MAX_HASH_ENTRY_SUPPORT; i++)
+ {
+ while((pEntry = pSesMacTable->sesHash[i]) != NULL)
+ {
+ pSesMacTable->sesHash[i] = pEntry->pNext;
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+ }
+ }
+ }
+
+/* kfree(pMatCfg->MatTableSet.SesMacTable); */
+ os_free_mem(NULL, pMatCfg->MatTableSet.SesMacTable);
+ pMatCfg->MatTableSet.SesMacTable = NULL;
+
+ return TRUE;
+
+}
+
+
+static PUidMacMappingEntry UidMacTableUpdate(
+ IN MAT_STRUCT *pMatCfg,
+ IN PUCHAR pInMac,
+ IN PUCHAR pOutMac,
+ IN PUCHAR pTagInfo,
+ IN UINT16 tagLen,
+ IN UINT16 isServer)
+{
+ UINT hashIdx, i=0, uIDAddByUs = 0;
+ UidMacMappingTable *pUidMacTable;
+ UidMacMappingEntry *pEntry = NULL, *pPrev = NULL, *pNewEntry =NULL;
+ UCHAR hashVal = 0;
+ PUCHAR pUIDStr= NULL;
+ ULONG now;
+
+
+ pUidMacTable = (UidMacMappingTable *)pMatCfg->MatTableSet.UidMacTable;
+ if ((!pUidMacTable) || (!pUidMacTable->valid))
+ return NULL;
+
+ if (pTagInfo && tagLen >0)
+ {
+ pUIDStr = pTagInfo;
+ uIDAddByUs = 0;
+ tagLen = (tagLen > PPPOE_DIS_UID_LEN ? PPPOE_DIS_UID_LEN : tagLen);
+ }
+ else
+ {
+ /*
+ We assume the station just have one role,i.e., just a PPPoE server or just a PPPoE client.
+ For a packet send by server, we use the destination MAC as our uIDStr
+ For a packet send by client, we use the source MAC as our uIDStr.
+ */
+ pUIDStr = isServer ? pOutMac: pInMac;
+ tagLen = MAC_ADDR_LEN;
+ uIDAddByUs = 1;
+ }
+
+ for (i=0; i<tagLen; i++)
+ hashVal ^= (pUIDStr[i] & 0xff);
+ hashIdx = hashVal % MAT_MAX_HASH_ENTRY_SUPPORT;
+
+ /*First, check if the hashIdx exists */
+ if (hashIdx < MAT_MAX_HASH_ENTRY_SUPPORT)
+ {
+ pEntry = pPrev = pUidMacTable->uidHash[hashIdx];
+ while(pEntry)
+ {
+ NdisGetSystemUpTime(&now);
+
+ /* Find the existed UidMac Mapping entry */
+ if (NdisEqualMemory(pUIDStr, pEntry->uIDStr, tagLen) && IS_EQUAL_MAC(pEntry->macAddr, pInMac))
+ {
+ /* Update info of this entry */
+ pEntry->isServer = isServer;
+ pEntry->uIDAddByUs = uIDAddByUs;
+ pEntry->lastTime = now;
+
+ return pEntry;
+ }
+ else
+ { /* handle the age-out situation */
+ if (RTMP_TIME_AFTER(now, (pEntry->lastTime + MAT_TB_ENTRY_AGEOUT_TIME)))
+ {
+ /* Remove the aged entry from the uidHash */
+ if (pEntry == pUidMacTable->uidHash[hashIdx])
+ {
+ pUidMacTable->uidHash[hashIdx]= pEntry->pNext;
+ pPrev = pUidMacTable->uidHash[hashIdx];
+ }
+ else
+ {
+ pPrev->pNext = pEntry->pNext;
+ }
+
+ /*After remove this entry from macHash list and uidHash list, now free it! */
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+ pMatCfg->nodeCount--;
+ pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
+ }
+ else
+ {
+ pPrev = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+ }
+ }
+
+
+ /* Allocate a new UidMacMapping entry and insert into the double-hash */
+ pNewEntry = (UidMacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(UidMacMappingEntry));
+ if (pNewEntry)
+ {
+ NdisZeroMemory(pNewEntry, sizeof(UidMacMappingEntry));
+
+ pNewEntry->isServer = isServer;
+ pNewEntry->uIDAddByUs = uIDAddByUs;
+ NdisMoveMemory(pNewEntry->macAddr, pInMac, MAC_ADDR_LEN);
+ NdisMoveMemory(pNewEntry->uIDStr, pUIDStr, tagLen);
+ pNewEntry->pNext = NULL;
+ NdisGetSystemUpTime(&pNewEntry->lastTime);
+
+ /* Update mac-side hash link list */
+ if (pUidMacTable->uidHash[hashIdx] == NULL)
+ { /* Hash list is empty, directly assign it. */
+ pUidMacTable->uidHash[hashIdx] = pNewEntry;
+ }
+ else
+ {
+ /* Ok, we insert the new entry into the root of uidHash[hashIdx] */
+ pNewEntry->pNext = pUidMacTable->uidHash[hashIdx];
+ pUidMacTable->uidHash[hashIdx] = pNewEntry;
+ }
+ /*dumpUidMacTb(pMatCfg, hashIdx); //for debug */
+
+ pMatCfg->nodeCount++;
+
+ return pNewEntry;
+ }
+
+ return NULL;
+}
+
+
+static PUidMacMappingEntry UidMacTableLookUp(
+ IN MAT_STRUCT *pMatCfg,
+ IN PUCHAR pTagInfo,
+ IN UINT16 tagLen)
+{
+ UINT hashIdx;
+ UINT16 len;
+ UCHAR hashValue = 0;
+ UidMacMappingEntry *pEntry = NULL;
+ UidMacMappingTable *pUidMacTable;
+
+ pUidMacTable = (UidMacMappingTable *)pMatCfg->MatTableSet.UidMacTable;
+ if ((!pUidMacTable) || (!pUidMacTable->valid))
+ return NULL;
+
+ /* Use hash to find out the location of that entry and get the Mac address. */
+ len = tagLen;
+ while(len)
+ hashValue ^= pTagInfo[--len];
+ hashIdx = hashValue % MAT_MAX_HASH_ENTRY_SUPPORT;
+
+ pEntry = pUidMacTable->uidHash[hashIdx];
+ while(pEntry)
+ {
+ if (NdisEqualMemory(pEntry->uIDStr, pTagInfo, tagLen))
+ {
+/* DBGPRINT(RT_DEBUG_TRACE,("%s(): dstMac=%02x:%02x:%02x:%02x:%02x:%02x for mapped dstIP(%d.%d.%d.%d)\n",
+ __FUNCTION__, pEntry->macAddr[0],pEntry->macAddr[1],pEntry->macAddr[2],
+ pEntry->macAddr[3],pEntry->macAddr[4],pEntry->macAddr[5],
+ (ipAddr>>24) & 0xff, (ipAddr>>16) & 0xff, (ipAddr>>8) & 0xff, ipAddr & 0xff));
+*/
+ /*Update the lastTime to prevent the aging before pDA processed! */
+ NdisGetSystemUpTime(&pEntry->lastTime);
+
+ return pEntry;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ /* We didn't find any matched Mac address. */
+ return NULL;
+
+}
+
+
+static PUCHAR getInMacByOutMacFromSesMacTb(
+ IN MAT_STRUCT *pMatCfg,
+ IN PUCHAR outMac,
+ IN UINT16 sesID)
+{
+ UINT16 hashIdx;
+ SesMacMappingEntry *pEntry = NULL;
+ SesMacMappingTable *pSesMacTable;
+
+ pSesMacTable = (SesMacMappingTable *)pMatCfg->MatTableSet.SesMacTable;
+
+ if (!pSesMacTable->valid)
+ return NULL;
+
+ /* Use hash to find out the location of that entry and get the Mac address. */
+ hashIdx = sesID % MAT_MAX_HASH_ENTRY_SUPPORT;
+
+ pEntry = pSesMacTable->sesHash[hashIdx];
+ while(pEntry)
+ {
+ if ((pEntry->sessionID == sesID) && IS_EQUAL_MAC(pEntry->outMacAddr, outMac))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): find it! dstMac=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ __FUNCTION__, pEntry->inMacAddr[0],pEntry->inMacAddr[1],pEntry->inMacAddr[2],
+ pEntry->inMacAddr[3],pEntry->inMacAddr[4],pEntry->inMacAddr[5]));
+
+ /*Update the lastTime to prevent the aging before pDA processed! */
+ NdisGetSystemUpTime(&pEntry->lastTime);
+
+ return pEntry->inMacAddr;
+ }
+ else
+ {
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ /* We didn't find any matched Mac address, just return and didn't do any modification */
+ return NULL;
+}
+
+
+/* This function used to maintain the pppoe convert table which incoming node
+ is a pppoe client and want to connect to use inner pppoe server.
+*/
+static NDIS_STATUS SesMacTableUpdate(
+ IN MAT_STRUCT *pMatCfg,
+ IN PUCHAR inMacAddr,
+ IN UINT16 sesID,
+ IN PUCHAR outMacAddr)
+{
+ UINT16 hashIdx;
+ SesMacMappingEntry *pEntry, *pPrev, *pNewEntry;
+ SesMacMappingTable *pSesMacTable;
+ ULONG now;
+
+ pSesMacTable = (SesMacMappingTable *)pMatCfg->MatTableSet.SesMacTable;
+ if ((!pSesMacTable) || (!pSesMacTable->valid))
+ return FALSE;
+
+ hashIdx = sesID % MAT_MAX_HASH_ENTRY_SUPPORT;
+
+/*
+ DBGPRINT(RT_DEBUG_TRACE,("%s():sesID=0x%04x,inMac=%02x%02x:%02x:%02x:%02x:%02x,
+ outMac=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, sesID,
+ inMacAddr[0],inMacAddr[1],inMacAddr[2],inMacAddr[3],inMacAddr[4],inMacAddr[5],
+ outMacAddr[0],outMacAddr[1],outMacAddr[2],outMacAddr[3],outMacAddr[4],outMacAddr[5]));
+*/
+
+ pEntry = pPrev = pSesMacTable->sesHash[hashIdx];
+ while(pEntry)
+ {
+ NdisGetSystemUpTime(&now);
+
+ /* Find a existed IP-MAC Mapping entry */
+ if ((sesID == pEntry->sessionID) &&
+ IS_EQUAL_MAC(pEntry->inMacAddr, inMacAddr) &&
+ IS_EQUAL_MAC(pEntry->outMacAddr, outMacAddr))
+ {
+ /* compare is useless. So we directly copy it into the entry. */
+ pEntry->lastTime = now;
+
+ return TRUE;
+ }
+ else
+ { /* handle the age-out situation */
+ if (RTMP_TIME_AFTER(now, (pEntry->lastTime + PPPoE_SES_ENTRY_AGEOUT_TIME)))
+ {
+ /* Remove the aged entry */
+ if (pEntry == pSesMacTable->sesHash[hashIdx])
+ {
+ pSesMacTable->sesHash[hashIdx]= pEntry->pNext;
+ pPrev = pSesMacTable->sesHash[hashIdx];
+ }
+ else
+ {
+ pPrev->pNext = pEntry->pNext;
+ }
+ MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
+ pMatCfg->nodeCount--;
+ pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
+ }
+ else
+ {
+ pPrev = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+ }
+
+
+ /* Allocate a new IPMacMapping entry and insert into the hash */
+ pNewEntry = (SesMacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(SesMacMappingEntry));
+ if (pNewEntry != NULL)
+ {
+ pNewEntry->sessionID= sesID;
+ NdisMoveMemory(pNewEntry->inMacAddr, inMacAddr, MAC_ADDR_LEN);
+ NdisMoveMemory(pNewEntry->outMacAddr, outMacAddr, MAC_ADDR_LEN);
+ pNewEntry->pNext = NULL;
+ NdisGetSystemUpTime(&pNewEntry->lastTime);
+
+ if (pSesMacTable->sesHash[hashIdx] == NULL)
+ { /* Hash list is empty, directly assign it. */
+ pSesMacTable->sesHash[hashIdx] = pNewEntry;
+ }
+ else
+ {
+ /* Ok, we insert the new entry into the root of hash[hashIdx] */
+ pNewEntry->pNext = pSesMacTable->sesHash[hashIdx];
+ pSesMacTable->sesHash[hashIdx] = pNewEntry;
+ }
+
+ /*dumpSesMacTb(pMatCfg, hashIdx); */
+ pMatCfg->nodeCount++;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* PPPoE discovery stage Rx handler.
+ When Rx, check if the PPPoE tag "Host-uniq" exists or not.
+ If exists, we check our database and convert the dstMac to correct one.
+ */
+static PUCHAR MATProto_PPPoEDis_Rx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+ PUCHAR pData, pSrvMac = NULL, pCliMac= NULL, pOutMac=NULL, pInMac = NULL, pTagContent = NULL, pPayloadLen;
+ UINT16 payloadLen, leftLen;
+ UINT16 tagID, tagLen =0;
+ UINT16 needUpdateSesTb= 0, sesID=0, isPADT = 0;
+ UINT16 findTag=0;
+ PUidMacMappingEntry pEntry = NULL;
+
+ pData = pLayerHdr;
+ if (*(pData) != 0x11)
+ return NULL;
+
+ /* Check the Code type. */
+ pData++;
+ switch(*pData)
+ {
+ case PPPOE_CODE_PADO:
+ /*It's a packet send by a PPPoE server which behind of our device. */
+ findTag = PPPOE_TAG_ID_HOST_UNIQ;
+ break;
+ case PPPOE_CODE_PADS:
+ needUpdateSesTb = 1;
+ findTag = PPPOE_TAG_ID_HOST_UNIQ;
+ pCliMac = (PUCHAR)(GET_OS_PKT_DATAPTR(pSkb));
+ pSrvMac = (PUCHAR)(GET_OS_PKT_DATAPTR(pSkb) + 6);
+ break;
+ case PPPOE_CODE_PADR:
+ /*It's a packet send by a PPPoE client which in front of our device. */
+ findTag = PPPOE_TAG_ID_AC_COOKIE;
+ break;
+ case PPPOE_CODE_PADI:
+ /*Do nothing! Just forward this packet to upper layer directly. */
+ return NULL;
+ case PPPOE_CODE_PADT:
+ isPADT = 1;
+ pOutMac= (PUCHAR)(GET_OS_PKT_DATAPTR(pSkb) + 6);
+ break;
+ default:
+ return NULL;
+ }
+
+ /* Ignore the Code field(length=1) */
+ pData ++;
+ if (needUpdateSesTb || isPADT)
+ sesID = OS_NTOHS(get_unaligned((PUINT16)(pData)));
+
+ if (isPADT)
+ {
+ pInMac = getInMacByOutMacFromSesMacTb(pMatCfg, pOutMac, sesID);
+ return pInMac;
+ }
+ /* Ignore the session ID field.(length = 2) */
+ pData += 2;
+
+ /* Get the payload length, ignore the payload length field.(length = 2) */
+ payloadLen = OS_NTOHS(get_unaligned((PUINT16)(pData)));
+ pPayloadLen = pData;
+ pData += 2;
+
+
+ /* First parsing the PPPoE paylod to find out the required tag(e.g., x0103 or 0x0104) */
+ leftLen = payloadLen;
+ while (leftLen)
+ {
+ tagID = OS_NTOHS(get_unaligned((PUINT16)(pData)));
+ tagLen = OS_NTOHS(get_unaligned((PUINT16)(pData+2)));
+
+ if (tagID== findTag && tagLen>0)
+ {
+
+ /*shift to the tag value field. */
+ pTagContent = pData + 4;
+ tagLen = tagLen > PPPOE_DIS_UID_LEN ? PPPOE_DIS_UID_LEN : tagLen;
+ break;
+ }
+ else
+ {
+ pData += (tagLen + 4);
+ leftLen -= (tagLen + 4);
+ }
+ }
+
+
+ /* Now update our pppoe discovery table "UidMacTable" */
+ if (pTagContent)
+ {
+ pEntry = UidMacTableLookUp(pMatCfg, pTagContent, tagLen);
+
+ /* Remove the AC-Cookie or host-uniq if we ever add the field for this session. */
+ if (pEntry)
+ {
+ if (pEntry->uIDAddByUs)
+ {
+ PUCHAR tagHead, nextTagHead;
+ UINT removedTagLen, tailLen;
+
+ removedTagLen = 4 + tagLen; /*The total length tag ID/info we want to remove. */
+ tagHead = pTagContent - 4; /*The start address of the tag we want to remove in sk bufffer */
+ tailLen = GET_OS_PKT_LEN(pSkb) - (pTagContent - (PUCHAR)(GET_OS_PKT_DATAPTR(pSkb))) - removedTagLen; /*Total left bytes we want to move. */
+ if (tailLen)
+ {
+ nextTagHead = pTagContent + tagLen; /*The start address of next tag ID/info in sk buffer. */
+ memmove(tagHead, nextTagHead, tailLen);
+ }
+/* SET_OS_PKT_DATATAIL(pSkb, GET_OS_PKT_DATATAIL(pSkb), (-removedTagLen)); */
+/* GET_OS_PKT_LEN(pSkb) -= removedTagLen; */
+ OS_PKT_TAIL_ADJUST(pSkb, removedTagLen);
+
+ *((UINT16 *)pPayloadLen) = OS_HTONS(payloadLen - removedTagLen);
+ }
+
+ if (needUpdateSesTb) {
+
+ SesMacTableUpdate(pMatCfg, pEntry->macAddr,sesID, pSrvMac);
+ }
+
+ return pEntry->macAddr;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+/* PPPoE discovery stage Tx handler.
+ If the pakcet is PADI/PADR, check if the PPPoE tag "Host-uniq" exists or not.
+ If exists, we just record it in our table, else we insert the Mac address
+ of Sender as well as the host-uniq, then forward to the destination. It's
+ a one(MAC)-to-one(Host-uniq) mapping in our table.
+ If the packet is PADO/PADS, check if the PPPoE tag "AC-Cookie" exists or not.
+ If exists, we just record it in our table, else we insert the Mac address
+ of Sender as well as the AC-Cookie, then forward to the destination. It may
+ one(MAC)-to-many(AC-Cookie) mapping in our table.
+
+ Host-uniq TAG ID= 0x0103
+ AC-Cookie TAG ID= 0x0104
+ */
+static PUCHAR MATProto_PPPoEDis_Tx(
+ IN MAT_STRUCT *pMatStruct,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+ PUCHAR pData, pTagContent = NULL, pPayloadLen, pPPPPoETail;
+ PUCHAR pSrcMac, pDstMac;
+ UINT16 payloadLen, leftLen, offset;
+ UINT16 tagID, tagLen =0;
+ UINT16 isServer = 0, needUpdateSesTb= 0, sesID = 0;
+ UINT16 findTag=0;
+ PUidMacMappingEntry pEntry = NULL;
+ PUCHAR pPktHdr;
+ PNDIS_PACKET pModSkb = NULL;
+
+ pPktHdr = GET_OS_PKT_DATAPTR(pSkb);
+ pDstMac = pPktHdr;
+ pSrcMac = (pPktHdr + 6);
+ pData = pLayerHdr;
+
+
+ /* Check the pppoe version and Type. It should be 0x11 */
+ if (*(pData) != 0x11)
+ return NULL;
+
+ /* Check the Code type. */
+ pData++;
+ switch(*pData)
+ {
+ /* Send by pppoe client */
+ case PPPOE_CODE_PADI:
+ case PPPOE_CODE_PADR:
+ findTag = PPPOE_TAG_ID_HOST_UNIQ;
+ break;
+ /* Send by pppoe server */
+ case PPPOE_CODE_PADO:
+ case PPPOE_CODE_PADS:
+ isServer = 1;
+ findTag = PPPOE_TAG_ID_AC_COOKIE;
+ if (*pData == PPPOE_CODE_PADS) /* For PADS, we need record the session ID. */
+ needUpdateSesTb = 1;
+ break;
+ /* Both server and client can send this packet */
+ case PPPOE_CODE_PADT:
+ /* TODO:
+ currently we didn't handle PADT packet. We just leave the
+ session entry and make it age-out automatically. Maybe we
+ can remove the entry when we receive this packet.
+ */
+ return NULL;
+ default:
+ return NULL;
+ }
+
+ /*
+ Ignore the Code field(length=1) and if it's a PADS packet, we
+ should hold the session ID and for latter to update our table.
+ */
+ pData ++;
+ if (needUpdateSesTb)
+ sesID = OS_NTOHS(get_unaligned((PUINT16)(pData)));
+
+ /* Ignore the session ID field.(length = 2) */
+ pData += 2;
+
+ /* Get the payload length, and shift the payload length field(length = 2) to next field. */
+ payloadLen = OS_NTOHS(get_unaligned((PUINT16)(pData)));
+ pPayloadLen = pData;
+ offset = pPayloadLen - (PUCHAR)(GET_OS_PKT_DATAPTR(pSkb));
+ pData += 2;
+
+
+ /* First parsing the PPPoE paylod to find out the required tag(e.g., x0103 or 0x0104) */
+ leftLen = payloadLen;
+ while (leftLen)
+ {
+ tagID = OS_NTOHS(get_unaligned((PUINT16)(pData)));
+ tagLen = OS_NTOHS(get_unaligned((PUINT16)(pData+2)));
+
+ if (tagID== findTag && tagLen>0)
+ {
+
+ /* Move the pointer to the tag value field. 4 = 2(TAG ID) + 2(TAG_LEN) */
+ pTagContent = pData + 4;
+/* tagLen = tagLen > PPPOE_DIS_UID_LEN ? PPPOE_DIS_UID_LEN : tagLen; */
+ break;
+ }
+ else
+ {
+ pData += (tagLen + 4);
+ leftLen -= (tagLen + 4);
+ }
+ }
+
+
+ /* Now update our pppoe discovery table "UidMacTable" */
+ pEntry = UidMacTableUpdate(pMatStruct, pSrcMac, pDstMac, pTagContent, tagLen, isServer);
+
+ if (pEntry && (pTagContent == NULL))
+ {
+ PUCHAR tailHead;
+
+ if(OS_PKT_CLONED(pSkb))
+ {
+/* pModSkb = (PNDIS_PACKET)skb_copy(RTPKT_TO_OSPKT(pSkb), MEM_ALLOC_FLAG); */
+ pModSkb = (PNDIS_PACKET)OS_PKT_COPY(RTPKT_TO_OSPKT(pSkb));
+ }
+ else
+ pModSkb = (PNDIS_PACKET)RTPKT_TO_OSPKT(pSkb);
+
+ if(!pModSkb)
+ return NULL;
+
+/* tailHead = skb_put(RTPKT_TO_OSPKT(pModSkb), (PPPOE_DIS_UID_LEN + 4)); */
+ tailHead = OS_PKT_TAIL_BUF_EXTEND(pModSkb, (PPPOE_DIS_UID_LEN + 4));
+ if (tailHead)
+ {
+ pPayloadLen = GET_OS_PKT_DATAPTR(pModSkb) + offset;
+ pPPPPoETail = pPayloadLen + payloadLen;
+ if(tailHead > pPPPPoETail)
+ tailHead = pPPPPoETail;
+
+ if (pEntry->isServer)
+ { /*Append the AC-Cookie tag info in the tail of the pppoe packet. */
+ tailHead[0] = 0x01;
+ tailHead[1] = 0x04;
+ tailHead[2] = 0x00;
+ tailHead[3] = PPPOE_DIS_UID_LEN;
+ tailHead += 4;
+ NdisMoveMemory(tailHead, pEntry->uIDStr, PPPOE_DIS_UID_LEN);
+ }
+ else
+ { /*Append the host-uniq tag info in the tail of the pppoe packet. */
+ tailHead[0] = 0x01;
+ tailHead[1] = 0x03;
+ tailHead[2] = 0x00;
+ tailHead[3] = PPPOE_DIS_UID_LEN;
+ tailHead += 4;
+ NdisMoveMemory(tailHead, pEntry->uIDStr, PPPOE_DIS_UID_LEN);
+ }
+ *(UINT16 *)pPayloadLen = OS_HTONS(payloadLen + 4 + PPPOE_DIS_UID_LEN);
+ }
+ }
+
+ if (needUpdateSesTb)
+ SesMacTableUpdate(pMatStruct, pSrcMac, sesID, pDstMac);
+
+ return (PUCHAR)pModSkb;
+}
+
+
+/* PPPoE discovery stage init function */
+static NDIS_STATUS MATProto_PPPoEDis_Init(
+ IN MAT_STRUCT *pMatCfg)
+{
+ UidMacMappingTable *pUidMacTable;
+ SesMacMappingTable *pSesMacTable;
+
+ pUidMacTable = (UidMacMappingTable *)pMatCfg->MatTableSet.UidMacTable;
+ if (!pUidMacTable)
+ {
+/* pMatCfg->MatTableSet.UidMacTable = (VOID *)kmalloc(sizeof(UidMacMappingTable), GFP_KERNEL); */
+ os_alloc_mem_suspend(NULL, (UCHAR **)&(pMatCfg->MatTableSet.UidMacTable), sizeof(UidMacMappingTable));
+ if (pMatCfg->MatTableSet.UidMacTable)
+ {
+ pUidMacTable = (UidMacMappingTable *)pMatCfg->MatTableSet.UidMacTable;
+ NdisZeroMemory(pUidMacTable, sizeof(UidMacMappingTable));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MATProto_PPPoEDis_Init(): Allocate memory for UidMacTable failed!\n"));
+ return FALSE;
+ }
+ }
+ pUidMacTable->valid = TRUE;
+
+ pSesMacTable = (SesMacMappingTable *)pMatCfg->MatTableSet.SesMacTable;
+ if (!pSesMacTable)
+ {
+/* pMatCfg->MatTableSet.SesMacTable = (VOID *)kmalloc(sizeof(SesMacMappingTable), GFP_KERNEL); */
+ os_alloc_mem_suspend(NULL, (UCHAR **)&(pMatCfg->MatTableSet.SesMacTable), sizeof(SesMacMappingTable));
+ if (pMatCfg->MatTableSet.SesMacTable)
+ {
+ pSesMacTable = (SesMacMappingTable *)pMatCfg->MatTableSet.SesMacTable;
+ NdisZeroMemory(pSesMacTable, sizeof(SesMacMappingTable));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MATProto_PPPoEDis_Init(): Allocate memory for SesMacTable failed!\n"));
+ return FALSE;
+ }
+
+ }
+ pSesMacTable->valid = TRUE;
+
+ return TRUE;
+}
+
+
+/* PPPoE discovery stage exit function */
+static NDIS_STATUS MATProto_PPPoEDis_Exit(
+ IN MAT_STRUCT *pMatCfg)
+{
+ UidMacTable_RemoveAll(pMatCfg);
+ SesMacTable_RemoveAll(pMatCfg);
+
+ return TRUE;
+}
+
+
+/* PPPoE Session stage Rx handler
+ When we receive a ppp pakcet, first check if the srcMac is a PPPoE server or not.
+ if it's a server, check the session ID of specific PPPoEServeryEntry and find out the
+ correct dstMac Address.
+ if it's not a server, check the session ID and find out the cor
+
+ */
+static PUCHAR MATProto_PPPoESes_Rx(
+ IN MAT_STRUCT *pMatCfg,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+ PUCHAR srcMac, dstMac = NULL, pData;
+ UINT16 sesID;
+
+ srcMac = (GET_OS_PKT_DATAPTR(pSkb) + 6);
+ pData = pLayerHdr;
+
+ /*skip the first two bytes.(version/Type/Code) */
+ pData += 2;
+
+ /*get the session ID */
+ sesID = OS_NTOHS(get_unaligned((PUINT16)(pData)));
+
+ /* Try to find the dstMac from SesMacHash table. */
+ dstMac = getInMacByOutMacFromSesMacTb(pMatCfg, srcMac, sesID);
+
+ return dstMac;
+}
+
+/* PPPoE Session stage Tx handler */
+static PUCHAR MATProto_PPPoESes_Tx(
+ IN MAT_STRUCT *pMatStruct,
+ IN PNDIS_PACKET pSkb,
+ IN PUCHAR pLayerHdr,
+ IN PUCHAR pDevMacAdr)
+{
+
+ /*
+ For transmit packet, we do nothing.
+ */
+ return NULL;
+}
+
+
+/* PPPoE session stage init function */
+static NDIS_STATUS MATProto_PPPoESes_Init(
+ IN MAT_STRUCT *pMatStruct)
+{
+ return TRUE;
+}
+
+/* PPPoE session stage exit function */
+static NDIS_STATUS MATProto_PPPoESes_Exit(
+ IN MAT_STRUCT *pMatStruct)
+{
+
+ return TRUE;
+}
+
+#endif /* MAT_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_profile.c b/cleopatre/devkit/mt7601udrv/common/cmm_profile.c
new file mode 100644
index 0000000000..fe324ff12a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_profile.c
@@ -0,0 +1,5059 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ cmm_profile.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#include "rt_config.h"
+
+
+#define ETH_MAC_ADDR_STR_LEN 17 /* in format of xx:xx:xx:xx:xx:xx*/
+
+/* We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.*/
+BOOLEAN rtstrmactohex(PSTRING s1, PSTRING s2)
+{
+ int i = 0;
+ PSTRING ptokS = s1, ptokE = s1;
+
+ if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
+ return FALSE;
+
+ while((*ptokS) != '\0')
+ {
+ if((ptokE = strchr(ptokS, ':')) != NULL)
+ *ptokE++ = '\0';
+ if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
+ break; /* fail*/
+ AtoH(ptokS, (PUCHAR)&s2[i++], 1);
+ ptokS = ptokE;
+ if (ptokS == NULL)
+ break;
+ if (i == 6)
+ break; /* parsing finished*/
+ }
+
+ return ( i == 6 ? TRUE : FALSE);
+
+}
+
+
+#define ASC_LOWER(_x) ((((_x) >= 0x41) && ((_x) <= 0x5a)) ? (_x) + 0x20 : (_x))
+/* we assume the s1 and s2 both are strings.*/
+BOOLEAN rtstrcasecmp(PSTRING s1, PSTRING s2)
+{
+ PSTRING p1 = s1, p2 = s2;
+ CHAR c1, c2;
+
+ if (strlen(s1) != strlen(s2))
+ return FALSE;
+
+ while(*p1 != '\0')
+ {
+ c1 = ASC_LOWER(*p1);
+ c2 = ASC_LOWER(*p2);
+ if(c1 != c2)
+ 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; i++)
+ {
+ temp1 = *(s1+i);
+ temp2 = *(s2+i);
+
+ if (('a' <= temp1) && (temp1 <= 'z'))
+ temp1 = 'A'+(temp1-'a');
+ if (('a' <= temp2) && (temp2 <= 'z'))
+ temp2 = 'A'+(temp2-'a');
+
+ if (temp1 != temp2)
+ break;
+ }
+
+ if (i == l2)
+ return (char *) s1;
+
+ s1++;
+ }
+
+ return NULL; /* not found*/
+}
+
+
+ /**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+PSTRING rtstrstr(PSTRING s1,const PSTRING s2)
+{
+ INT l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return s1;
+
+ l1 = strlen(s1);
+
+ while (l1 >= 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_ptr<start_ptr)
+ {
+ os_free_mem(NULL, (PUCHAR)pMemBuf);
+ return (FALSE);
+ }
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+
+ if((start_ptr=rtstrstr(temp_buf2, "=")) == NULL)
+ {
+ os_free_mem(NULL, (PUCHAR)pMemBuf);
+ return (FALSE);
+ }
+ ptr = (start_ptr +1);
+ /*trim special characters, i.e., TAB or space*/
+ while(*start_ptr != 0x00)
+ {
+ if( ((*ptr == ' ') && bTrimSpace) || (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+ len = strlen(start_ptr);
+
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, ((len >= destsize) ? destsize: len));
+
+ os_free_mem(NULL, (PUCHAR)pMemBuf);
+
+ return TRUE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get multiple 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
+
+ Return Value:
+ TRUE Success
+ FALSE Fail
+
+ Note:
+ This routine get the value with the matched key (case case-sensitive)
+ ========================================================================
+*/
+INT RTMPGetKeyParameterWithOffset(
+ IN PSTRING key,
+ OUT PSTRING dest,
+ OUT USHORT *end_offset,
+ IN INT destsize,
+ IN PSTRING buffer,
+ IN BOOLEAN bTrimSpace)
+{
+ PSTRING temp_buf1 = NULL;
+ PSTRING temp_buf2 = NULL;
+ PSTRING start_ptr;
+ PSTRING end_ptr;
+ PSTRING ptr;
+ PSTRING offset = 0;
+ INT len;
+
+ if (*end_offset >= MAX_INI_BUFFER_SIZE)
+ return (FALSE);
+
+ os_alloc_mem(NULL, (PUCHAR *)&temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+ if(temp_buf1 == NULL)
+ return (FALSE);
+
+ os_alloc_mem(NULL, (PUCHAR *)&temp_buf2, MAX_PARAM_BUFFER_SIZE);
+ if(temp_buf2 == NULL)
+ {
+ os_free_mem(NULL, (PUCHAR)temp_buf1);
+ return (FALSE);
+ }
+
+ /*find section */
+ if(*end_offset == 0)
+ {
+ if ((offset = RTMPFindSection(buffer)) == NULL)
+ {
+ os_free_mem(NULL, (PUCHAR)temp_buf1);
+ os_free_mem(NULL, (PUCHAR)temp_buf2);
+ return (FALSE);
+ }
+ }
+ else
+ offset = buffer + (*end_offset);
+
+ 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)temp_buf1);
+ os_free_mem(NULL, (PUCHAR)temp_buf2);
+ return (FALSE);
+ }
+
+ start_ptr+=strlen("\n");
+ if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+ end_ptr=start_ptr+strlen(start_ptr);
+
+ if (end_ptr<start_ptr)
+ {
+ os_free_mem(NULL, (PUCHAR)temp_buf1);
+ os_free_mem(NULL, (PUCHAR)temp_buf2);
+ return (FALSE);
+ }
+
+ *end_offset = end_ptr - buffer;
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+ len = strlen(temp_buf2);
+ strcpy(temp_buf1, temp_buf2);
+ if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+ {
+ os_free_mem(NULL, (PUCHAR)temp_buf1);
+ os_free_mem(NULL, (PUCHAR)temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf2, start_ptr+1);
+ ptr = temp_buf2;
+ /*trim space or tab*/
+ while(*ptr != 0x00)
+ {
+ if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+
+ len = strlen(ptr);
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, len >= destsize ? destsize: len);
+
+ os_free_mem(NULL, (PUCHAR)temp_buf1);
+ os_free_mem(NULL, (PUCHAR)temp_buf2);
+ return TRUE;
+}
+
+
+
+
+static int rtmp_parse_key_buffer_from_file(IN PRTMP_ADAPTER pAd,IN PSTRING buffer,IN ULONG KeyType,IN INT BSSIdx,IN INT KeyIdx)
+{
+ PSTRING keybuff;
+ /*INT i = BSSIdx, idx = KeyIdx, retVal;*/
+ ULONG KeyLen;
+ /*UCHAR CipherAlg = CIPHER_WEP64;*/
+ CIPHER_KEY *pSharedKey;
+
+ keybuff = buffer;
+ KeyLen = strlen(keybuff);
+ pSharedKey = &pAd->SharedKey[BSSIdx][KeyIdx];
+
+ if(((KeyType != 0) && (KeyType != 1)) ||
+ ((KeyType == 0) && (KeyLen != 10) && (KeyLen != 26)) ||
+ ((KeyType== 1) && (KeyLen != 5) && (KeyLen != 13)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length(%ld) or Type(%ld)\n",
+ KeyIdx+1, KeyLen, KeyType));
+ return FALSE;
+ }
+ else
+ {
+ return RT_CfgSetWepKey(pAd, buffer, pSharedKey, KeyIdx);
+ }
+
+}
+
+
+static void rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
+{
+ STRING tok_str[16];
+ PSTRING macptr;
+ INT i = 0, idx;
+ ULONG KeyType[HW_BEACON_MAX_NUM];
+ ULONG KeyIdx;
+
+ NdisZeroMemory(KeyType, sizeof(KeyType));
+
+ /*DefaultKeyID*/
+ if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer, TRUE))
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ {
+ break;
+ }
+
+ KeyIdx = simple_strtol(macptr, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAd->ApCfg.MBSSID[i].DefaultKeyId = (UCHAR) (KeyIdx - 1 );
+ else
+ pAd->ApCfg.MBSSID[i].DefaultKeyId = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) DefaultKeyID(0~3)=%d\n", i, pAd->ApCfg.MBSSID[i].DefaultKeyId));
+ }
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (TRUE)
+ {
+ BOOLEAN bKeyxStryIsUsed = FALSE;
+
+ //GPRINT(RT_DEBUG_TRACE, ("pAd->ApCfg.BssidNum=%d\n", pAd->ApCfg.BssidNum));
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ snprintf(tok_str, sizeof(tok_str), "Key%dStr%d", idx + 1, i + 1);
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
+ {
+ rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[i], i, idx);
+
+ if (bKeyxStryIsUsed == FALSE)
+ {
+ bKeyxStryIsUsed = TRUE;
+ }
+ }
+ }
+
+ if (bKeyxStryIsUsed == FALSE)
+ {
+ snprintf(tok_str, sizeof(tok_str), "Key%dStr", idx + 1);
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
+ {
+ if (pAd->ApCfg.BssidNum == 1)
+ {
+ rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
+ }
+ else
+ {
+ /* Anyway, we still do the legacy dissection of the whole KeyxStr string.*/
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ rtmp_parse_key_buffer_from_file(pAd, macptr, KeyType[i], i, idx);
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+}
+
+#ifdef CONFIG_AP_SUPPORT
+
+#ifdef APCLI_SUPPORT
+static void rtmp_read_ap_client_from_file(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING tmpbuf,
+ IN PSTRING buffer)
+{
+ PSTRING macptr = NULL;
+ INT i=0, j=0, idx;
+ UCHAR macAddress[MAC_ADDR_LEN];
+ /*UCHAR keyMaterial[40];*/
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ ULONG KeyIdx;
+ STRING tok_str[16];
+ ULONG KeyType[MAX_APCLI_NUM];
+ ULONG KeyLen;
+ /*UCHAR CipherAlg = CIPHER_WEP64;*/
+
+
+ NdisZeroMemory(KeyType, sizeof(KeyType));
+
+ /*ApCliEnable*/
+ if(RTMPGetKeyParameter("ApCliEnable", tmpbuf, 128, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+ if ((strncmp(macptr, "0", 1) == 0))
+ pApCliEntry->Enable = FALSE;
+ else if ((strncmp(macptr, "1", 1) == 0))
+ pApCliEntry->Enable = TRUE;
+ else
+ pApCliEntry->Enable = FALSE;
+
+ if (pApCliEntry->Enable)
+ {
+ /*pApCliEntry->WpaState = SS_NOTUSE;*/
+ /*pApCliEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;*/
+ /*NdisZeroMemory(pApCliEntry->ReplayCounter, LEN_KEY_DESC_REPLAY); */
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliEntry[%d].Enable=%d\n", i, pApCliEntry->Enable));
+ }
+ }
+
+ /*ApCliSsid*/
+ if(RTMPGetKeyParameter("ApCliSsid", tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, FALSE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ /*Ssid acceptable strlen must be less than 32 and bigger than 0.*/
+ pApCliEntry->CfgSsidLen = (UCHAR)strlen(macptr);
+ if (pApCliEntry->CfgSsidLen > 32)
+ {
+ pApCliEntry->CfgSsidLen = 0;
+ continue;
+ }
+ if(pApCliEntry->CfgSsidLen > 0)
+ {
+ memcpy(&pApCliEntry->CfgSsid, macptr, pApCliEntry->CfgSsidLen);
+ pApCliEntry->Valid = FALSE;/* it should be set when successfuley association*/
+ } else
+ {
+ NdisZeroMemory(&(pApCliEntry->CfgSsid), MAX_LEN_OF_SSID);
+ continue;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("ApCliEntry[%d].CfgSsidLen=%d, CfgSsid=%s\n", i, pApCliEntry->CfgSsidLen, pApCliEntry->CfgSsid));
+ }
+ }
+
+ /*ApCliBssid*/
+ if(RTMPGetKeyParameter("ApCliBssid", tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ if(strlen(macptr) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17*/
+ continue;
+ if(strcmp(macptr,"00:00:00:00:00:00") == 0)
+ continue;
+ for (j=0; j<ETH_LENGTH_OF_ADDRESS; j++)
+ {
+ AtoH(macptr, &macAddress[j], 1);
+ macptr=macptr+3;
+ }
+ memcpy(pApCliEntry->CfgApCliBssid, &macAddress, ETH_LENGTH_OF_ADDRESS);
+ pApCliEntry->Valid = FALSE;/* it should be set when successfuley association*/
+ }
+ }
+
+ /*ApCliAuthMode*/
+ if (RTMPGetKeyParameter("ApCliAuthMode", tmpbuf, 255, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ if ((strncmp(macptr, "WEPAUTO", 7) == 0) || (strncmp(macptr, "wepauto", 7) == 0))
+ pApCliEntry->AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strncmp(macptr, "SHARED", 6) == 0) || (strncmp(macptr, "shared", 6) == 0))
+ pApCliEntry->AuthMode = Ndis802_11AuthModeShared;
+ else if ((strncmp(macptr, "WPAPSK", 6) == 0) || (strncmp(macptr, "wpapsk", 6) == 0))
+ pApCliEntry->AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strncmp(macptr, "WPA2PSK", 7) == 0) || (strncmp(macptr, "wpa2psk", 7) == 0))
+ pApCliEntry->AuthMode = Ndis802_11AuthModeWPA2PSK;
+ else
+ pApCliEntry->AuthMode = Ndis802_11AuthModeOpen;
+
+ /*pApCliEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;*/
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) ApCli_AuthMode=%d \n", i, pApCliEntry->AuthMode));
+ RTMPMakeRSNIE(pAd, pApCliEntry->AuthMode, pApCliEntry->WepStatus, (i + MIN_NET_DEVICE_FOR_APCLI));
+ }
+
+ }
+
+ /*ApCliEncrypType*/
+ if (RTMPGetKeyParameter("ApCliEncrypType", tmpbuf, 255, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ pApCliEntry->WepStatus = Ndis802_11WEPDisabled;
+ if ((strncmp(macptr, "WEP", 3) == 0) || (strncmp(macptr, "wep", 3) == 0))
+ {
+ if (pApCliEntry->AuthMode < Ndis802_11AuthModeWPA)
+ pApCliEntry->WepStatus = Ndis802_11WEPEnabled;
+ }
+ else if ((strncmp(macptr, "TKIP", 4) == 0) || (strncmp(macptr, "tkip", 4) == 0))
+ {
+ if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ pApCliEntry->WepStatus = Ndis802_11Encryption2Enabled;
+ }
+ else if ((strncmp(macptr, "AES", 3) == 0) || (strncmp(macptr, "aes", 3) == 0))
+ {
+ if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA)
+ pApCliEntry->WepStatus = Ndis802_11Encryption3Enabled;
+ }
+ else
+ {
+ pApCliEntry->WepStatus = Ndis802_11WEPDisabled;
+ }
+
+ pApCliEntry->PairCipher = pApCliEntry->WepStatus;
+ pApCliEntry->GroupCipher = pApCliEntry->WepStatus;
+ pApCliEntry->bMixCipher = FALSE;
+
+ /*pApCliEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;*/
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) APCli_EncrypType = %d \n", i, pApCliEntry->WepStatus));
+ RTMPMakeRSNIE(pAd, pApCliEntry->AuthMode, pApCliEntry->WepStatus, (i + MIN_NET_DEVICE_FOR_APCLI));
+ }
+
+ }
+
+ /*ApCliWPAPSK*/
+ if (RTMPGetKeyParameter("ApCliWPAPSK", tmpbuf, 255, buffer, FALSE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ int retval = TRUE;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ if((strlen(macptr) < 8) || (strlen(macptr) > 64))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("APCli_WPAPSK_KEY, key string required 8 ~ 64 characters!!!\n"));
+ continue;
+ }
+
+ NdisMoveMemory(pApCliEntry->PSK, macptr, strlen(macptr));
+ pApCliEntry->PSKLen = strlen(macptr);
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) APCli_WPAPSK_KEY=%s, Len=%d\n", i, pApCliEntry->PSK, pApCliEntry->PSKLen));
+
+ if ((pApCliEntry->AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (pApCliEntry->AuthMode != Ndis802_11AuthModeWPA2PSK))
+ {
+ retval = FALSE;
+ }
+
+ {
+ retval = RT_CfgSetWPAPSKKey(pAd, macptr, strlen(macptr), (PUCHAR)pApCliEntry->CfgSsid, (INT)pApCliEntry->CfgSsidLen, pApCliEntry->PMK);
+ }
+ if (retval == TRUE)
+ {
+ /* Start STA supplicant WPA state machine*/
+ DBGPRINT(RT_DEBUG_TRACE, ("Start AP-client WPAPSK state machine \n"));
+ /*pApCliEntry->WpaState = SS_START; */
+ }
+
+ /*RTMPMakeRSNIE(pAd, pApCliEntry->AuthMode, pApCliEntry->WepStatus, (i + MIN_NET_DEVICE_FOR_APCLI)); */
+#ifdef DBG
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) PMK Material => \n", i));
+
+ for (j = 0; j < 32; j++)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%02x:", pApCliEntry->PMK[j]));
+ if ((j%16) == 15)
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+ }
+ DBGPRINT(RT_DEBUG_OFF,("\n"));
+#endif
+ }
+ }
+
+ /*ApCliDefaultKeyID*/
+ if (RTMPGetKeyParameter("ApCliDefaultKeyID", tmpbuf, 255, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ KeyIdx = simple_strtol(macptr, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pApCliEntry->DefaultKeyId = (UCHAR) (KeyIdx - 1);
+ else
+ pApCliEntry->DefaultKeyId = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) DefaultKeyID(0~3)=%d\n", i, pApCliEntry->DefaultKeyId));
+ }
+ }
+
+ /*ApCliKeyXType, ApCliKeyXStr*/
+ for (idx=0; idx<4; idx++)
+ {
+ snprintf(tok_str, sizeof(tok_str), "ApCliKey%dType", idx+1);
+ /*ApCliKey1Type*/
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ KeyType[i] = simple_strtol(macptr, 0, 10);
+ }
+
+ snprintf(tok_str, sizeof(tok_str), "ApCliKey%dStr", idx+1);
+ /*ApCliKey1Str*/
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 512, buffer, FALSE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+ KeyLen = strlen(macptr);
+ if(((KeyType[i] == 0) && (KeyLen != 10) && (KeyLen != 26)) ||
+ ((KeyType[i] != 0) && (KeyLen != 5) && (KeyLen != 13)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("I/F(apcli%d) Key%dStr is Invalid key length!\n", i, idx+1));
+ }
+ else
+ {
+ if (RT_CfgSetWepKey(pAd, macptr, &pApCliEntry->SharedKey[idx], idx) != TRUE)
+ DBGPRINT(RT_DEBUG_ERROR, ("RT_CfgSetWepKey fail!\n"));
+ }
+ }
+ }
+ }
+ }
+
+ /* ApCliTxMode*/
+ if (RTMPGetKeyParameter("ApCliTxMode", tmpbuf, 25, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ pApCliEntry->DesiredTransmitSetting.field.FixedTxMode =
+ RT_CfgSetFixedTxPhyMode(macptr);
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) Tx Mode = %d\n", i,
+ pApCliEntry->DesiredTransmitSetting.field.FixedTxMode));
+ }
+ }
+
+ /* ApCliTxMcs*/
+ if (RTMPGetKeyParameter("ApCliTxMcs", tmpbuf, 50, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_APCLI_NUM); macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ pApCliEntry->DesiredTransmitSetting.field.MCS =
+ RT_CfgSetTxMCSProc(macptr, &pApCliEntry->bAutoTxRateSwitch);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) Tx MCS = %s(%d)\n", i,
+ (pApCliEntry->DesiredTransmitSetting.field.MCS == MCS_AUTO ? "AUTO" : ""),
+ pApCliEntry->DesiredTransmitSetting.field.MCS));
+ }
+ }
+
+
+#ifdef WSC_AP_SUPPORT
+
+ /* Wsc4digitPinCode = TRUE use 4-digit Pin code, otherwise 8-digit Pin code */
+ if (RTMPGetKeyParameter("ApCli_Wsc4digitPinCode", tmpbuf, 32, buffer, TRUE))
+ {
+ if (simple_strtol(macptr, 0, 10) != 0) //Enable
+ pAd->ApCfg.ApCliTab[0].WscControl.WscEnrollee4digitPinCode = TRUE;
+ else //Disable
+ pAd->ApCfg.ApCliTab[0].WscControl.WscEnrollee4digitPinCode = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(apcli%d) ApCli_Wsc4digitPinCode=%d\n", i, pAd->ApCfg.ApCliTab[0].WscControl.WscEnrollee4digitPinCode));
+ }
+#endif /* WSC_AP_SUPPORT */
+
+
+#ifdef UAPSD_SUPPORT
+ /*APSDCapable*/
+ if(RTMPGetKeyParameter("ApCliAPSDCapable", tmpbuf, 10, buffer, TRUE))
+ {
+ pAd->ApCfg.FlgApCliIsUapsdInfoUpdated = TRUE;
+
+ for (i = 0, macptr = rstrtok(tmpbuf,";");
+ (macptr && i < MAX_APCLI_NUM);
+ macptr = rstrtok(NULL,";"), i++)
+ {
+ pApCliEntry = &pAd->ApCfg.ApCliTab[i];
+
+ pApCliEntry->UapsdInfo.bAPSDCapable = \
+ (UCHAR) simple_strtol(macptr, 0, 10);
+ DBGPRINT(RT_DEBUG_ERROR, ("ApCliAPSDCapable[%d]=%d\n", i,
+ pApCliEntry->UapsdInfo.bAPSDCapable));
+ }
+ }
+#endif /* UAPSD_SUPPORT */
+}
+#endif /* APCLI_SUPPORT */
+
+
+static void rtmp_read_acl_parms_from_file(IN PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
+{
+ STRING tok_str[32];
+ PSTRING macptr;
+ INT i=0, j=0, idx;
+ UCHAR macAddress[MAC_ADDR_LEN];
+
+
+ memset(macAddress, 0, MAC_ADDR_LEN);
+ for (idx=0; idx<MAX_MBSSID_NUM(pAd); idx++)
+ {
+ memset(&pAd->ApCfg.MBSSID[idx].AccessControlList, 0, sizeof(RT_802_11_ACL));
+ /* AccessPolicyX*/
+ snprintf(tok_str, sizeof(tok_str), "AccessPolicy%d", idx);
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 10, buffer, TRUE))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: /* Allow All, and the AccessControlList is positive now.*/
+ pAd->ApCfg.MBSSID[idx].AccessControlList.Policy = 1;
+ break;
+ case 2: /* Reject All, and the AccessControlList is negative now.*/
+ pAd->ApCfg.MBSSID[idx].AccessControlList.Policy = 2;
+ break;
+ case 0: /* Disable, don't care the AccessControlList.*/
+ default:
+ pAd->ApCfg.MBSSID[idx].AccessControlList.Policy = 0;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s=%ld\n", tok_str, pAd->ApCfg.MBSSID[idx].AccessControlList.Policy));
+ }
+ /* AccessControlListX*/
+ snprintf(tok_str, sizeof(tok_str), "AccessControlList%d", idx);
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (strlen(macptr) != 17) /* Mac address acceptable format 01:02:03:04:05:06 length 17*/
+ continue;
+
+ ASSERT(pAd->ApCfg.MBSSID[idx].AccessControlList.Num <= MAX_NUM_OF_ACL_LIST);
+
+ for (j=0; j<ETH_LENGTH_OF_ADDRESS; j++)
+ {
+ AtoH(macptr, &macAddress[j], 1);
+ macptr=macptr+3;
+ }
+
+ if (pAd->ApCfg.MBSSID[idx].AccessControlList.Num == MAX_NUM_OF_ACL_LIST)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("The AccessControlList is full, and no more entry can join the list!\n"));
+ DBGPRINT(RT_DEBUG_WARN, ("The last entry of ACL is %02x:%02x:%02x:%02x:%02x:%02x\n",
+ macAddress[0],macAddress[1],macAddress[2],macAddress[3],macAddress[4],macAddress[5]));
+
+ break;
+ }
+
+ pAd->ApCfg.MBSSID[idx].AccessControlList.Num++;
+ NdisMoveMemory(pAd->ApCfg.MBSSID[idx].AccessControlList.Entry[(pAd->ApCfg.MBSSID[idx].AccessControlList.Num - 1)].Addr, macAddress, ETH_LENGTH_OF_ADDRESS);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s=Get %ld Mac Address\n", tok_str, pAd->ApCfg.MBSSID[idx].AccessControlList.Num));
+ }
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ In kernel mode read parameters from file
+
+ Arguments:
+ src the location of the file.
+ dest put the parameters to the destination.
+ Length size to read.
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+static void rtmp_read_ap_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
+{
+ PSTRING macptr;
+ INT i=0;
+
+ /*WmmCapable*/
+ if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE))
+ {
+ BOOLEAN bEnableWmm = FALSE;
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ {
+ break;
+ }
+
+ if(simple_strtol(macptr, 0, 10) != 0)
+ {
+ pAd->ApCfg.MBSSID[i].bWmmCapable = TRUE;
+ bEnableWmm = TRUE;
+ }
+ else
+ {
+ pAd->ApCfg.MBSSID[i].bWmmCapable = FALSE;
+ }
+
+ if (bEnableWmm)
+ {
+ pAd->CommonCfg.APEdcaParm.bValid = TRUE;
+ pAd->ApCfg.BssEdcaParm.bValid = TRUE;
+ }
+ else
+ {
+ pAd->CommonCfg.APEdcaParm.bValid = FALSE;
+ pAd->ApCfg.BssEdcaParm.bValid = FALSE;
+ }
+
+ pAd->ApCfg.MBSSID[i].bWmmCapableOrg = \
+ pAd->ApCfg.MBSSID[i].bWmmCapable;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WmmCapable=%d\n", i, pAd->ApCfg.MBSSID[i].bWmmCapable));
+ }
+ }
+ /*DLSCapable*/
+ if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ {
+ break;
+ }
+
+ if(simple_strtol(macptr, 0, 10) != 0) /*Enable*/
+ {
+ pAd->ApCfg.MBSSID[i].bDLSCapable = TRUE;
+ }
+ else /*Disable*/
+ {
+ pAd->ApCfg.MBSSID[i].bDLSCapable = FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) DLSCapable=%d\n", i, pAd->ApCfg.MBSSID[i].bDLSCapable));
+ }
+ }
+ /*APAifsn*/
+ if(RTMPGetKeyParameter("APAifsn", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->CommonCfg.APEdcaParm.Aifsn[i] = (UCHAR) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APAifsn[%d]=%d\n", i, pAd->CommonCfg.APEdcaParm.Aifsn[i]));
+ }
+ }
+ /*APCwmin*/
+ if(RTMPGetKeyParameter("APCwmin", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->CommonCfg.APEdcaParm.Cwmin[i] = (UCHAR) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCwmin[%d]=%d\n", i, pAd->CommonCfg.APEdcaParm.Cwmin[i]));
+ }
+ }
+ /*APCwmax*/
+ if(RTMPGetKeyParameter("APCwmax", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->CommonCfg.APEdcaParm.Cwmax[i] = (UCHAR) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APCwmax[%d]=%d\n", i, pAd->CommonCfg.APEdcaParm.Cwmax[i]));
+ }
+ }
+ /*APTxop*/
+ if(RTMPGetKeyParameter("APTxop", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->CommonCfg.APEdcaParm.Txop[i] = (USHORT) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APTxop[%d]=%d\n", i, pAd->CommonCfg.APEdcaParm.Txop[i]));
+ }
+ }
+ /*APACM*/
+ if(RTMPGetKeyParameter("APACM", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->CommonCfg.APEdcaParm.bACM[i] = (BOOLEAN) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APACM[%d]=%d\n", i, pAd->CommonCfg.APEdcaParm.bACM[i]));
+ }
+ }
+ /*BSSAifsn*/
+ if(RTMPGetKeyParameter("BSSAifsn", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->ApCfg.BssEdcaParm.Aifsn[i] = (UCHAR) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSSAifsn[%d]=%d\n", i, pAd->ApCfg.BssEdcaParm.Aifsn[i]));
+ }
+ }
+ /*BSSCwmin*/
+ if(RTMPGetKeyParameter("BSSCwmin", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->ApCfg.BssEdcaParm.Cwmin[i] = (UCHAR) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSSCwmin[%d]=%d\n", i, pAd->ApCfg.BssEdcaParm.Cwmin[i]));
+ }
+ }
+ /*BSSCwmax*/
+ if(RTMPGetKeyParameter("BSSCwmax", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->ApCfg.BssEdcaParm.Cwmax[i] = (UCHAR) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSSCwmax[%d]=%d\n", i, pAd->ApCfg.BssEdcaParm.Cwmax[i]));
+ }
+ }
+ /*BSSTxop*/
+ if(RTMPGetKeyParameter("BSSTxop", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->ApCfg.BssEdcaParm.Txop[i] = (USHORT) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSSTxop[%d]=%d\n", i, pAd->ApCfg.BssEdcaParm.Txop[i]));
+ }
+ }
+ /*BSSACM*/
+ if(RTMPGetKeyParameter("BSSACM", tmpbuf, 32, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->ApCfg.BssEdcaParm.bACM[i] = (BOOLEAN) simple_strtol(macptr, 0, 10);;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSSACM[%d]=%d\n", i, pAd->ApCfg.BssEdcaParm.bACM[i]));
+ }
+ }
+ /*AckPolicy*/
+ 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]));
+ }
+ }
+#ifdef UAPSD_SUPPORT
+ /*APSDCapable*/
+ if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer, TRUE))
+ {
+
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i < HW_BEACON_MAX_NUM)
+ {
+ pAd->ApCfg.MBSSID[i].UapsdInfo.bAPSDCapable = \
+ (UCHAR) simple_strtol(macptr, 0, 10);
+ DBGPRINT(RT_DEBUG_ERROR, ("APSDCapable[%d]=%d\n", i,
+ pAd->ApCfg.MBSSID[i].UapsdInfo.bAPSDCapable));
+ }
+ }
+
+ if (i == 1)
+ {
+ /*
+ Old format in UAPSD settings: only 1 parameter
+ i.e. UAPSD for all BSS is enabled or disabled.
+ */
+ for(i=1; i<HW_BEACON_MAX_NUM; i++)
+ {
+ pAd->ApCfg.MBSSID[i].UapsdInfo.bAPSDCapable =
+ pAd->ApCfg.MBSSID[0].UapsdInfo.bAPSDCapable;
+ DBGPRINT(RT_DEBUG_ERROR, ("APSDCapable[%d]=%d\n", i,
+ pAd->ApCfg.MBSSID[i].UapsdInfo.bAPSDCapable));
+ }
+ }
+
+#ifdef APCLI_SUPPORT
+ if (pAd->ApCfg.FlgApCliIsUapsdInfoUpdated == FALSE)
+ {
+ /*
+ Backward:
+ All UAPSD for AP Client interface is same as MBSS0
+ when we can not find "ApCliAPSDCapable".
+ When we find "ApCliAPSDCapable" hereafter, we will over-write.
+ */
+ for(i=0; i<MAX_APCLI_NUM; i++)
+ {
+ pAd->ApCfg.ApCliTab[i].UapsdInfo.bAPSDCapable = \
+ pAd->ApCfg.MBSSID[0].UapsdInfo.bAPSDCapable;
+ DBGPRINT(RT_DEBUG_ERROR, ("default ApCliAPSDCapable[%d]=%d\n",
+ i, pAd->ApCfg.ApCliTab[i].UapsdInfo.bAPSDCapable));
+ }
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* UAPSD_SUPPORT */
+}
+
+#ifdef DOT1X_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ In kernel mode read parameters from file
+
+ Arguments:
+ src the location of the file.
+ dest put the parameters to the destination.
+ Length size to read.
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+static void rtmp_read_radius_parms_from_file(IN PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
+{
+ STRING tok_str[16];
+ PSTRING macptr;
+ UINT32 ip_addr;
+ INT i=0;
+ BOOLEAN bUsePrevFormat = FALSE;
+ USHORT offset;
+ INT count[HW_BEACON_MAX_NUM];
+
+ /* own_ip_addr*/
+ if (RTMPGetKeyParameter("own_ip_addr", tmpbuf, 32, buffer, TRUE))
+ {
+ Set_OwnIPAddr_Proc(pAd, tmpbuf);
+ }
+
+
+ /* session_timeout_interval*/
+ if (RTMPGetKeyParameter("session_timeout_interval", tmpbuf, 32, buffer, TRUE))
+ {
+ pAd->ApCfg.session_timeout_interval = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("session_timeout_interval=%d\n", pAd->ApCfg.session_timeout_interval));
+ }
+
+ /* quiet_interval*/
+ if (RTMPGetKeyParameter("quiet_interval", tmpbuf, 32, buffer, TRUE))
+ {
+ pAd->ApCfg.quiet_interval = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("quiet_interval=%d\n", pAd->ApCfg.quiet_interval));
+ }
+
+ /* EAPifname*/
+ if (RTMPGetKeyParameter("EAPifname", tmpbuf, 256, buffer, TRUE))
+ {
+ Set_EAPIfName_Proc(pAd, tmpbuf);
+ }
+
+ /* PreAuthifname*/
+ if (RTMPGetKeyParameter("PreAuthifname", tmpbuf, 256, buffer, TRUE))
+ {
+ Set_PreAuthIfName_Proc(pAd, tmpbuf);
+ }
+
+ /*PreAuth*/
+ if(RTMPGetKeyParameter("PreAuth", tmpbuf, 10, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ if(simple_strtol(macptr, 0, 10) != 0) /*Enable*/
+ pAd->ApCfg.MBSSID[i].PreAuth = TRUE;
+ else /*Disable*/
+ pAd->ApCfg.MBSSID[i].PreAuth = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) PreAuth=%d\n", i, pAd->ApCfg.MBSSID[i].PreAuth));
+ }
+ }
+
+ /*IEEE8021X*/
+ if(RTMPGetKeyParameter("IEEE8021X", tmpbuf, 10, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ if(simple_strtol(macptr, 0, 10) != 0) /*Enable*/
+ pAd->ApCfg.MBSSID[i].IEEE8021X = TRUE;
+ else /*Disable*/
+ pAd->ApCfg.MBSSID[i].IEEE8021X = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), IEEE8021X=%d\n", i, pAd->ApCfg.MBSSID[i].IEEE8021X));
+ }
+ }
+
+ /* RADIUS_Server*/
+ offset = 0;
+ /*if (RTMPGetKeyParameter("RADIUS_Server", tmpbuf, 256, buffer, TRUE))*/
+ while (RTMPGetKeyParameterWithOffset("RADIUS_Server", tmpbuf, &offset, 256, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_MBSSID_NUM(pAd)); macptr = rstrtok(NULL,";"), i++)
+ {
+ if (rtinet_aton(macptr, &ip_addr) && pAd->ApCfg.MBSSID[i].radius_srv_num < MAX_RADIUS_SRV_NUM)
+ {
+ INT srv_idx = pAd->ApCfg.MBSSID[i].radius_srv_num;
+
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_ip = ip_addr;
+ pAd->ApCfg.MBSSID[i].radius_srv_num++;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), radius_ip(seq-%d)=%s(%x)\n", i, pAd->ApCfg.MBSSID[i].radius_srv_num, macptr, pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_ip));
+ }
+ }
+ }
+ /* RADIUS_Port*/
+ /*if (RTMPGetKeyParameter("RADIUS_Port", tmpbuf, 128, buffer, TRUE))*/
+ offset = 0;
+ memset(&count[0], 0, sizeof(count));
+ while (RTMPGetKeyParameterWithOffset("RADIUS_Port", tmpbuf, &offset, 128, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_MBSSID_NUM(pAd)); macptr = rstrtok(NULL,";"), i++)
+ {
+ if (count[i] < pAd->ApCfg.MBSSID[i].radius_srv_num)
+ {
+ INT srv_idx = count[i];
+
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_port = (UINT32) simple_strtol(macptr, 0, 10);
+ count[i] ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), radius_port(seq-%d)=%d\n", i, count[i], pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_port));
+ }
+ }
+ }
+ /* RADIUS_Key*/
+ /*if (RTMPGetKeyParameter("RADIUS_Key", tmpbuf, 640, buffer, FALSE))*/
+ offset = 0;
+ memset(&count[0], 0, sizeof(count));
+ while (RTMPGetKeyParameterWithOffset("RADIUS_Key", tmpbuf, &offset, 640, buffer, FALSE))
+ {
+ if (strlen(tmpbuf) > 0)
+ bUsePrevFormat = TRUE;
+
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_MBSSID_NUM(pAd)); macptr = rstrtok(NULL,";"), i++)
+ {
+ if (strlen(macptr) > 0 && (count[i] < pAd->ApCfg.MBSSID[i].radius_srv_num))
+ {
+ INT srv_idx = count[i];
+
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key_len = strlen(macptr);
+ NdisMoveMemory(pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key, macptr, strlen(macptr));
+ count[i] ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), radius_key(seq-%d)=%s, len=%d\n", i,
+ count[i],
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key,
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key_len));
+ }
+ }
+ }
+
+ /* NasIdX, X indicate the interface index(1~8) */
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ snprintf(tok_str, sizeof(tok_str), "NasId%d", i + 1);
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 33, buffer, FALSE))
+ {
+ if (strlen(tmpbuf) > 0)
+ {
+ pAd->ApCfg.MBSSID[i].NasIdLen = strlen(tmpbuf);
+ NdisMoveMemory(pAd->ApCfg.MBSSID[i].NasId, tmpbuf, strlen(tmpbuf));
+ DBGPRINT(RT_DEBUG_TRACE, ("IF-ra%d NAS-ID=%s, len=%d\n", i,
+ pAd->ApCfg.MBSSID[i].NasId,
+ pAd->ApCfg.MBSSID[i].NasIdLen));
+ }
+ }
+ }
+
+ if (!bUsePrevFormat)
+ {
+ for (i = 0; i < MAX_MBSSID_NUM(pAd); i++)
+ {
+ INT srv_idx = 0;
+
+ snprintf(tok_str, sizeof(tok_str), "RADIUS_Key%d", i + 1);
+
+ /* RADIUS_KeyX (X=1~MAX_MBSSID_NUM)*/
+ /*if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE)) */
+ offset = 0;
+ while (RTMPGetKeyParameterWithOffset(tok_str, tmpbuf, &offset, 128, buffer, FALSE))
+ {
+ if (strlen(tmpbuf) > 0 && (srv_idx < pAd->ApCfg.MBSSID[i].radius_srv_num))
+ {
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key_len = strlen(tmpbuf);
+ NdisMoveMemory(pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key, tmpbuf, strlen(tmpbuf));
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d), update radius_key(seq-%d)=%s, len=%d\n", i, srv_idx+1,
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key,
+ pAd->ApCfg.MBSSID[i].radius_srv_info[srv_idx].radius_key_len));
+ srv_idx ++;
+ }
+ }
+ }
+ }
+}
+#endif /* DOT1X_SUPPORT */
+
+static int rtmp_parse_wpapsk_buffer_from_file(IN PRTMP_ADAPTER pAd,IN PSTRING buffer,IN INT BSSIdx)
+{
+ PSTRING tmpbuf = buffer;
+ INT i = BSSIdx;
+ /*UCHAR keyMaterial[40];*/
+ ULONG len = strlen(tmpbuf);
+ int ret = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WPAPSK_KEY=%s\n", i, tmpbuf));
+
+ ret = RT_CfgSetWPAPSKKey(pAd, tmpbuf, len, (PUCHAR)pAd->ApCfg.MBSSID[i].Ssid, pAd->ApCfg.MBSSID[i].SsidLen, pAd->ApCfg.MBSSID[i].PMK);
+ if (ret == FALSE)
+ return FALSE;
+
+#ifdef WSC_AP_SUPPORT
+ NdisZeroMemory(pAd->ApCfg.MBSSID[i].WscControl.WpaPsk, 64);
+ pAd->ApCfg.MBSSID[i].WscControl.WpaPskLen = 0;
+ if ((len >= 8) && (len <= 64))
+ {
+ NdisMoveMemory(pAd->ApCfg.MBSSID[i].WscControl.WpaPsk, tmpbuf, len);
+ pAd->ApCfg.MBSSID[i].WscControl.WpaPskLen = len;
+ }
+#endif /* WSC_AP_SUPPORT */
+ return ret;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+#ifdef DOT11_VHT_AC
+static void VHTParametersHook(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING pValueStr,
+ IN PSTRING pInput)
+{
+ long Value;
+
+ /* Channel Width */
+ if (RTMPGetKeyParameter("VHT_BW", pValueStr, 25, pInput, TRUE))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == VHT_BW_80)
+ pAd->CommonCfg.vht_bw = VHT_BW_80;
+ else
+ pAd->CommonCfg.vht_bw = VHT_BW_2040;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("VHT: Channel Width = %s\n", (Value==VHT_BW_80) ? "80 MHz" : "20/40 MHz" ));
+ }
+}
+
+#endif /* DOT11_VHT_AC */
+
+#ifdef CUSTOMER_DEMO
+void demo_mode_cfg(RTMP_ADAPTER *pAd)
+{
+ int IdBss, i;
+ UCHAR cfg_mode;
+
+ pAd->CommonCfg.Channel = 40;
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ cfg_mode = 14;
+ pAd->ApCfg.MBSSID[i].PhyMode = cfgmode_2_wmode(cfg_mode);
+ DBGPRINT(RT_DEBUG_TRACE, ("BSS%d PhyMode=%d\n", i, pAd->ApCfg.MBSSID[i].PhyMode));
+
+ if (i == 0)
+ {
+ /* for first time, update all phy mode is same as ra0 */
+ for(IdBss=1; IdBss<pAd->ApCfg.BssidNum; IdBss++)
+ pAd->ApCfg.MBSSID[IdBss].PhyMode = pAd->ApCfg.MBSSID[0].PhyMode;
+ /* set mode for 1st time */
+ RT_CfgSetWirelessMode(pAd, "14");
+ }
+ else
+ RT_CfgSetMbssWirelessMode(pAd, "14");
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
+
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+ pAd->CommonCfg.vht_bw = VHT_BW_80;
+}
+#endif /* CUSTOMER_DEMO */
+
+
+#ifdef DOT11_N_SUPPORT
+static void HTParametersHook(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING pValueStr,
+ IN PSTRING pInput)
+{
+ long Value;
+#ifdef CONFIG_AP_SUPPORT
+ INT i=0;
+ PSTRING Bufptr;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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);
+
+#ifdef CONFIG_AP_SUPPORT
+ /* Intel IOT*/
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ Value = 64;
+#endif /* CONFIG_AP_SUPPORT */
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (i = 0, Bufptr = rstrtok(pValueStr,";"); (Bufptr && i < MAX_MBSSID_NUM(pAd)); Bufptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->ApCfg.MBSSID[i].DesiredTransmitSetting.field.FixedTxMode =
+ RT_CfgSetFixedTxPhyMode(Bufptr);
+ DBGPRINT(RT_DEBUG_TRACE, ("(IF-ra%d) Fixed Tx Mode = %d\n", i,
+ pAd->ApCfg.MBSSID[i].DesiredTransmitSetting.field.FixedTxMode));
+ }
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (i = 0, Bufptr = rstrtok(pValueStr,";"); (Bufptr && i < MAX_MBSSID_NUM(pAd)); Bufptr = rstrtok(NULL,";"), i++)
+ {
+ Value = simple_strtol(Bufptr, 0, 10);
+ if ((Value >= 0 && Value <= 23) || (Value == 32))
+ {
+ pAd->ApCfg.MBSSID[i].DesiredTransmitSetting.field.MCS = Value;
+ }
+ else
+ {
+ pAd->ApCfg.MBSSID[i].DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("(IF-ra%d) HT: MCS = %s(%d)\n", i,
+ (pAd->ApCfg.MBSSID[i].DesiredTransmitSetting.field.MCS == MCS_AUTO ? "AUTO" : "Fixed"),
+ pAd->ApCfg.MBSSID[i].DesiredTransmitSetting.field.MCS));
+ }
+ }
+#endif /* CONFIG_AP_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));
+ }
+#ifdef GREENAP_SUPPORT
+ /*Green AP*/
+ if(RTMPGetKeyParameter("GreenAP", pValueStr, 10, pInput, TRUE))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->ApCfg.bGreenAPEnable = FALSE;
+ }
+ else
+ {
+ pAd->ApCfg.bGreenAPEnable = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Green AP= %d\n", pAd->ApCfg.bGreenAPEnable));
+ }
+#endif /* GREENAP_SUPPORT */
+ /* 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 */
+
+ if (RTMPGetKeyParameter("BurstMode", pValueStr, 25, pInput, TRUE))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ pAd->CommonCfg.bRalinkBurstMode = ((Value == 1) ? 1 : 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: RaBurstMode= %d\n", pAd->CommonCfg.bRalinkBurstMode));
+ }
+#endif /* DOT11_N_SUPPORT */
+
+}
+#endif /* DOT11_N_SUPPORT */
+
+
+
+
+void RTMPSetCountryCode(RTMP_ADAPTER *pAd, PSTRING CountryCode)
+{
+ NdisMoveMemory(pAd->CommonCfg.CountryCode, CountryCode , 2);
+ pAd->CommonCfg.CountryCode[2] = ' ';
+ 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;
+
+/* 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
+ /*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 /* RTMP_EFUSE_SUPPORT */
+ /*CountryCode*/
+
+ if (pAd->CommonCfg.bCountryFlag == 0)
+ {
+ 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');
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.Geography = BOTH;
+ pAd->CommonCfg.CountryCode[2] = ' ';
+ }
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef MBSS_SUPPORT
+ /*BSSIDNum; This must read first of other multiSSID field, so list this field first in configuration file*/
+ if(RTMPGetKeyParameter("BssidNum", tmpbuf, 25, pBuffer, TRUE))
+ {
+ pAd->ApCfg.BssidNum = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ if(pAd->ApCfg.BssidNum > MAX_MBSSID_NUM(pAd))
+ {
+ pAd->ApCfg.BssidNum = MAX_MBSSID_NUM(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("BssidNum=%d(MAX_MBSSID_NUM is %d)\n", pAd->ApCfg.BssidNum,MAX_MBSSID_NUM(pAd)));
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("BssidNum=%d\n", pAd->ApCfg.BssidNum));
+ }
+
+ if (HW_BEACON_OFFSET > (HW_BEACON_MAX_SIZE(pAd) / pAd->ApCfg.BssidNum))
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("mbss> fatal error! beacon offset is error in driver! "
+ "Please re-assign HW_BEACON_OFFSET!\n"));
+ }
+#else
+ pAd->ApCfg.BssidNum = 1;
+#endif /* MBSS_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* SSID*/
+ if (TRUE)
+ {
+ STRING tok_str[16];
+ UCHAR BssidCountSupposed = 0;
+ BOOLEAN bSSIDxIsUsed = FALSE;
+
+ //PRINT(RT_DEBUG_TRACE, ("pAd->ApCfg.BssidNum=%d\n", pAd->ApCfg.BssidNum));
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ snprintf(tok_str, sizeof(tok_str), "SSID%d", i + 1);
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 33, pBuffer, FALSE))
+ {
+ NdisMoveMemory(pAd->ApCfg.MBSSID[i].Ssid, tmpbuf , strlen(tmpbuf));
+ pAd->ApCfg.MBSSID[i].Ssid[strlen(tmpbuf)] = '\0';
+ pAd->ApCfg.MBSSID[i].SsidLen = strlen((PSTRING) pAd->ApCfg.MBSSID[i].Ssid);
+ if (bSSIDxIsUsed == FALSE)
+ {
+ bSSIDxIsUsed = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("SSID[%d]=%s\n", i, pAd->ApCfg.MBSSID[i].Ssid));
+ }
+ }
+ if (bSSIDxIsUsed == FALSE)
+ {
+ if(RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE))
+ {
+ BssidCountSupposed = delimitcnt(tmpbuf, ";") + 1;
+ if (pAd->ApCfg.BssidNum != BssidCountSupposed)
+ {
+ DBGPRINT_ERR(("Your no. of SSIDs( = %d) does not match your BssidNum( = %d)!\n", BssidCountSupposed, pAd->ApCfg.BssidNum));
+ }
+ if (pAd->ApCfg.BssidNum > 1)
+ {
+ /* Anyway, we still do the legacy dissection of the whole SSID string.*/
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ int apidx = 0;
+
+ if (i < pAd->ApCfg.BssidNum)
+ {
+ apidx = i;
+ }
+ else
+ {
+ break;
+ }
+
+ NdisMoveMemory(pAd->ApCfg.MBSSID[apidx].Ssid, macptr , strlen(macptr));
+ pAd->ApCfg.MBSSID[apidx].Ssid[strlen(macptr)] = '\0';
+ pAd->ApCfg.MBSSID[apidx].SsidLen = strlen((PSTRING) pAd->ApCfg.MBSSID[apidx].Ssid);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SSID[%d]=%s\n", i, pAd->ApCfg.MBSSID[apidx].Ssid));
+ }
+ }
+ else
+ {
+ if ((strlen(tmpbuf) > 0) && (strlen(tmpbuf) <= 32))
+ {
+ NdisMoveMemory(pAd->ApCfg.MBSSID[BSS0].Ssid, tmpbuf , strlen(tmpbuf));
+ pAd->ApCfg.MBSSID[BSS0].Ssid[strlen(tmpbuf)] = '\0';
+ pAd->ApCfg.MBSSID[BSS0].SsidLen = strlen((PSTRING) pAd->ApCfg.MBSSID[BSS0].Ssid);
+ DBGPRINT(RT_DEBUG_TRACE, ("SSID=%s\n", pAd->ApCfg.MBSSID[BSS0].Ssid));
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* CONFIG_AP_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))
+ {
+ UCHAR cfg_mode;
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ cfg_mode = simple_strtol(macptr, 0, 10);
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ pAd->ApCfg.MBSSID[i].PhyMode = cfgmode_2_wmode(cfg_mode);
+ DBGPRINT(RT_DEBUG_TRACE, ("BSS%d PhyMode=%d\n", i, pAd->ApCfg.MBSSID[i].PhyMode));
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (i == 0)
+ {
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+ /* for first time, update all phy mode is same as ra0 */
+ {
+ UINT32 IdBss;
+ for(IdBss=1; IdBss<pAd->ApCfg.BssidNum; IdBss++)
+ pAd->ApCfg.MBSSID[IdBss].PhyMode = pAd->ApCfg.MBSSID[0].PhyMode;
+ }
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ /* set mode for 1st time */
+ RT_CfgSetWirelessMode(pAd, macptr);
+ }
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+ else
+ RT_CfgSetMbssWirelessMode(pAd, macptr);
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ 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));
+ }
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DFS_SUPPORT
+ /*DFSIndoor*/
+ {
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pRadarDetect->DfsProgramParam;
+
+ if (RTMPGetKeyParameter("DfsIndoor", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pAd->Dot11_H.bDFSIndoor = (USHORT) (simple_strtol(tmpbuf, 0, 10) != 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("DfsIndoor=%d\n", pAd->Dot11_H.bDFSIndoor));
+ }
+ {
+ INT k=0;
+ /*SymRoundFromCfg*/
+ if (RTMPGetKeyParameter("SymRoundFromCfg", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pRadarDetect->SymRoundFromCfg = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ pRadarDetect->SymRoundCfgValid = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("SymRoundFromCfg=%d\n", pRadarDetect->SymRoundFromCfg));
+ }
+
+ /*BusyIdleFromCfg*/
+ if (RTMPGetKeyParameter("BusyIdleFromCfg", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pRadarDetect->BusyIdleFromCfg = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ pRadarDetect->BusyIdleCfgValid = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("BusyIdleFromCfg=%d\n", pRadarDetect->BusyIdleFromCfg));
+ }
+ /*DfsRssiHighFromCfg*/
+ if (RTMPGetKeyParameter("DfsRssiHighFromCfg", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pRadarDetect->DfsRssiHighFromCfg = simple_strtol(tmpbuf, 0, 10);
+ pRadarDetect->DfsRssiHighCfgValid = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("DfsRssiHighFromCfg=%d\n", pRadarDetect->DfsRssiHighFromCfg));
+ }
+
+ /*DfsRssiLowFromCfg*/
+ if (RTMPGetKeyParameter("DfsRssiLowFromCfg", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pRadarDetect->DfsRssiLowFromCfg = simple_strtol(tmpbuf, 0, 10);
+ pRadarDetect->DfsRssiLowCfgValid = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("DfsRssiLowFromCfg=%d\n", pRadarDetect->DfsRssiLowFromCfg));
+ }
+
+ /*DFSParamFromConfig*/
+ if (RTMPGetKeyParameter("DFSParamFromConfig", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pRadarDetect->DFSParamFromConfig = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DFSParamFromConfig=%d\n", pRadarDetect->DFSParamFromConfig));
+ }
+
+ /* DFSParam*/
+ for(k = 0; k < 4*pAd->chipCap.DfsEngineNum; k++)
+ {
+ STRING tok_str[32];
+ INT index ;
+ UINT8 DfsEngineNum = pAd->chipCap.DfsEngineNum;
+ index = (k%DfsEngineNum);
+ if (((k-k%DfsEngineNum)/DfsEngineNum) == 0)
+ snprintf(tok_str, sizeof(tok_str), "FCCParamCh%d", index);
+ else if (((k-k%DfsEngineNum)/DfsEngineNum) == 1)
+ snprintf(tok_str, sizeof(tok_str), "CEParamCh%d", index);
+ else if (((k-k%DfsEngineNum)/DfsEngineNum) == 2)
+ snprintf(tok_str, sizeof(tok_str), "JAPParamCh%d", index);
+ else if (((k-k%DfsEngineNum)/DfsEngineNum) == 3)
+ snprintf(tok_str, sizeof(tok_str), "JAPW53ParamCh%d", index);
+
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, pBuffer, TRUE))
+ {
+ ULONG DfsParam;
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ DfsParam = simple_strtol(macptr, 0, 10);
+ switch (i)
+ {
+ case 0:
+ pDfsProgramParam->NewDFSTableEntry[k].mode = DfsParam;
+ break;
+ case 1:
+ pDfsProgramParam->NewDFSTableEntry[k].avgLen = DfsParam;
+ pDfsProgramParam->NewDFSTableEntry[k].valid = 1;
+ break;
+ case 2:
+ pDfsProgramParam->NewDFSTableEntry[k].ELow = DfsParam;
+ break;
+ case 3:
+ pDfsProgramParam->NewDFSTableEntry[k].EHigh = DfsParam;
+ break;
+ case 4:
+ pDfsProgramParam->NewDFSTableEntry[k].WLow = DfsParam;
+ break;
+ case 5:
+ pDfsProgramParam->NewDFSTableEntry[k].WHigh = DfsParam;
+ break;
+ case 6:
+ pDfsProgramParam->NewDFSTableEntry[k].EpsilonW = DfsParam;
+ break;
+ case 7:
+ pDfsProgramParam->NewDFSTableEntry[k].TLow = DfsParam;
+ break;
+ case 8:
+ pDfsProgramParam->NewDFSTableEntry[k].THigh = DfsParam;
+ break;
+ case 9:
+ pDfsProgramParam->NewDFSTableEntry[k].EpsilonT = DfsParam;
+ break;
+
+ case 10:
+ pDfsProgramParam->NewDFSTableEntry[k].BLow = DfsParam;
+ break;
+ case 11:
+ pDfsProgramParam->NewDFSTableEntry[k].BHigh = DfsParam;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* DFS_SUPPORT */
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /*DtimPeriod*/
+ if(RTMPGetKeyParameter("DtimPeriod", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pAd->ApCfg.DtimPeriod = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("DtimPeriod=%d\n", pAd->ApCfg.DtimPeriod));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ /*TxPower*/
+ if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
+ 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));
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ /*OLBCDetection*/
+ if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, pBuffer, TRUE))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: /*disable OLBC Detection*/
+ pAd->CommonCfg.DisableOLBCDetect = 1;
+ break;
+ case 0: /*enable OLBC Detection*/
+ pAd->CommonCfg.DisableOLBCDetect = 0;
+ break;
+ default:
+ pAd->CommonCfg.DisableOLBCDetect= 0;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ /*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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ rtmp_read_ap_wmm_parms_from_file(pAd, tmpbuf, pBuffer);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#if defined(P2P_SUPPORT) || defined(CONFIG_AP_SUPPORT)
+ /* IdleTimeout & StationKeepAlive shall be supported in P2P mode,
+ so moved out from CONFIG_AP_SUPPORT block
+ */
+ /* IdleTimeout*/
+ if(RTMPGetKeyParameter("IdleTimeout", tmpbuf, 10, pBuffer, TRUE))
+ {
+ ApCfg_Set_IdleTimeout_Proc(pAd, tmpbuf);
+ }
+
+ /*StationKeepAlive*/
+ if(RTMPGetKeyParameter("StationKeepAlive", tmpbuf, 32, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ int apidx = i;
+
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ pAd->ApCfg.MBSSID[apidx].StationKeepAliveTime = simple_strtol(macptr, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) StationKeepAliveTime=%d\n", i, pAd->ApCfg.MBSSID[apidx].StationKeepAliveTime));
+ }
+ }
+#endif /* defined(P2P_SUPPORT) || defined(CONFIG_AP_SUPPORT) */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* MaxStaNum*/
+ if (RTMPGetKeyParameter("MaxStaNum", tmpbuf, 32, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ ApCfg_Set_MaxStaNum_Proc(pAd, i, macptr);
+ }
+ }
+
+ /*NoForwarding*/
+ if(RTMPGetKeyParameter("NoForwarding", tmpbuf, 32, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ if(simple_strtol(macptr, 0, 10) != 0) /*Enable*/
+ pAd->ApCfg.MBSSID[i].IsolateInterStaTraffic = TRUE;
+ else /*Disable*/
+ pAd->ApCfg.MBSSID[i].IsolateInterStaTraffic = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) NoForwarding=%ld\n", i, pAd->ApCfg.MBSSID[i].IsolateInterStaTraffic));
+ }
+ }
+ /*NoForwardingBTNBSSID*/
+ if(RTMPGetKeyParameter("NoForwardingBTNBSSID", tmpbuf, 10, pBuffer, TRUE))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/
+ pAd->ApCfg.IsolateInterStaTrafficBTNBSSID = TRUE;
+ else /*Disable*/
+ pAd->ApCfg.IsolateInterStaTrafficBTNBSSID = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoForwardingBTNBSSID=%ld\n", pAd->ApCfg.IsolateInterStaTrafficBTNBSSID));
+ }
+ /*HideSSID*/
+ if(RTMPGetKeyParameter("HideSSID", tmpbuf, 32, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ int apidx = i;
+
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ if(simple_strtol(macptr, 0, 10) != 0) /*Enable*/
+ {
+ pAd->ApCfg.MBSSID[apidx].bHideSsid = TRUE;
+#ifdef WSC_V2_SUPPORT
+ pAd->ApCfg.MBSSID[apidx].WscControl.WscV2Info.bWpsEnable = FALSE;
+#endif /* WSC_V2_SUPPORT */
+ }
+ else /*Disable*/
+ pAd->ApCfg.MBSSID[apidx].bHideSsid = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) HideSSID=%d\n", i, pAd->ApCfg.MBSSID[apidx].bHideSsid));
+ }
+ }
+
+ /*AutoChannelSelect*/
+ if(RTMPGetKeyParameter("AutoChannelSelect", tmpbuf, 10, pBuffer, TRUE))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/
+ {
+ ChannelSel_Alg SelAlg=(ChannelSel_Alg)simple_strtol(tmpbuf, 0, 10);
+ if (SelAlg > 2 || SelAlg < 0)
+ {
+ pAd->ApCfg.bAutoChannelAtBootup = FALSE;
+ }
+ else /*Enable*/
+ {
+ pAd->ApCfg.bAutoChannelAtBootup = TRUE;
+ pAd->ApCfg.AutoChannelAlg = SelAlg;
+ }
+ }
+ else /*Disable*/
+ pAd->ApCfg.bAutoChannelAtBootup = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("AutoChannelAtBootup=%d\n", pAd->ApCfg.bAutoChannelAtBootup));
+ }
+ /*AutoChannelSkipList*/
+ if (RTMPGetKeyParameter("AutoChannelSkipList", tmpbuf, 50, pBuffer, FALSE))
+ {
+ pAd->ApCfg.AutoChannelSkipListNum = delimitcnt(tmpbuf, ";") + 1;
+ if ( pAd->ApCfg.AutoChannelSkipListNum > 10 )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Your no. of AutoChannelSkipList( %d ) is larger than 10 (boundary)\n",pAd->ApCfg.AutoChannelSkipListNum));
+ pAd->ApCfg.AutoChannelSkipListNum = 10;
+ }
+
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr ; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i < pAd->ApCfg.AutoChannelSkipListNum )
+ {
+ pAd->ApCfg.AutoChannelSkipList[i] = simple_strtol(macptr, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, (" AutoChannelSkipList[%d]= %d \n", i, pAd->ApCfg.AutoChannelSkipList[i]));
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /*ShortSlot*/
+ if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE))
+ {
+ RT_CfgSetShortSlot(pAd, tmpbuf);
+ DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
+ }
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ {
+#if defined(CONFIG_AP_SUPPORT) || defined(STA_ITXBF_SUPPORT)
+ /*ITxBfEn*/
+ if(RTMPGetKeyParameter("ITxBfEn", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn = (simple_strtol(tmpbuf, 0, 10) != 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("ITxBfEn = %d\n", pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn));
+
+ rtmp_asic_set_bf(pAd);
+ }
+
+ /* ITxBfTimeout */
+ if(RTMPGetKeyParameter("ITxBfTimeout", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.ITxBfTimeout = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("ITxBfTimeout = %ld\n", pAd->CommonCfg.ITxBfTimeout));
+ }
+#endif /* defined(CONFIG_AP_SUPPORT) || defined(STA_ITXBF_SUPPORT) */
+
+ /* ETxBfEnCond*/
+ if(RTMPGetKeyParameter("ETxBfEnCond", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.ETxBfEnCond = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("ETxBfEnCond = %ld\n", pAd->CommonCfg.ETxBfEnCond));
+
+ if (pAd->CommonCfg.ETxBfEnCond)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.TxBF = TRUE;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.TxBF = FALSE;
+ }
+ rtmp_asic_set_bf(pAd);
+ }
+
+ /* ETxBfTimeout*/
+ if(RTMPGetKeyParameter("ETxBfTimeout", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.ETxBfTimeout = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("ETxBfTimeout = %ld\n", pAd->CommonCfg.ETxBfTimeout));
+ }
+
+ /* ETxBfNoncompress*/
+ if(RTMPGetKeyParameter("ETxBfNoncompress", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.ETxBfNoncompress = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("ETxBfNoncompress = %d\n", pAd->CommonCfg.ETxBfNoncompress));
+ }
+
+ /* ETxBfIncapable */
+ if(RTMPGetKeyParameter("ETxBfIncapable", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.ETxBfIncapable = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("ETxBfIncapable = %d\n", pAd->CommonCfg.ETxBfIncapable));
+ }
+ }
+#endif /* TXBF_SUPPORT */
+
+
+#ifdef PRE_ANT_SWITCH
+ /*PreAntSwitch*/
+ if(RTMPGetKeyParameter("PreAntSwitch", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.PreAntSwitch = (simple_strtol(tmpbuf, 0, 10) != 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("PreAntSwitch = %d\n", pAd->CommonCfg.PreAntSwitch));
+ }
+#endif /* PRE_ANT_SWITCH */
+
+
+
+#ifdef STREAM_MODE_SUPPORT
+ /* StreamMode*/
+ if (pAd->chipCap.FlgHwStreamMode)
+ {
+ if(RTMPGetKeyParameter("StreamMode", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.StreamMode = (simple_strtol(tmpbuf, 0, 10) & 0x03);
+ DBGPRINT(RT_DEBUG_TRACE, ("StreamMode= %d\n", pAd->CommonCfg.StreamMode));
+ }
+
+ /* StreamModeMac*/
+ for (i = 0; i < STREAM_MODE_STA_NUM; i++)
+ {
+ STRING tok_str[32];
+
+ sprintf(tok_str, "StreamModeMac%d", i);
+
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, MAX_PARAM_BUFFER_SIZE, pBuffer, TRUE))
+ {
+ int j;
+ if(strlen(tmpbuf) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17*/
+ continue;
+
+ for (j=0; j<ETH_LENGTH_OF_ADDRESS; j++)
+ {
+ AtoH(tmpbuf, &pAd->CommonCfg.StreamModeMac[i][j], 1);
+ tmpbuf=tmpbuf+3;
+ }
+ }
+ }
+
+ if (NdisEqualMemory(ZERO_MAC_ADDR, &pAd->CommonCfg.StreamModeMac[0][0], MAC_ADDR_LEN))
+ {
+ /* set default broadcast mac to entry 0 if user not set it */
+ NdisMoveMemory(&pAd->CommonCfg.StreamModeMac[0][0], BROADCAST_ADDR, MAC_ADDR_LEN);
+ }
+ }
+#endif /* STREAM_MODE_SUPPORT */
+
+#ifdef DBG_CTRL_SUPPORT
+ /*DebugFlags*/
+ if(RTMPGetKeyParameter("DebugFlags", tmpbuf, 32, pBuffer, TRUE))
+ {
+ pAd->CommonCfg.DebugFlags = simple_strtol(tmpbuf, 0, 16);
+ DBGPRINT(RT_DEBUG_TRACE, ("DebugFlags = 0x%02lx\n", pAd->CommonCfg.DebugFlags));
+ }
+#endif /* DBG_CTRL_SUPPORT */
+
+ /*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));
+ }
+ }
+
+#ifdef DFS_SUPPORT
+ {
+ /*CSPeriod*/
+ if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, pBuffer, TRUE))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0)
+ pAd->Dot11_H.CSPeriod = simple_strtol(tmpbuf, 0, 10);
+ else
+ pAd->Dot11_H.CSPeriod = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->Dot11_H.CSPeriod));
+ }
+
+ }
+#endif /* DFS_SUPPORT */
+
+ /*RDRegion*/
+ if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE))
+ {
+ if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
+ {
+ pAd->CommonCfg.RDDurRegion = JAP_W53;
+ /*pRadarDetect->DfsSessionTime = 15;*/
+ }
+ else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
+ {
+ pAd->CommonCfg.RDDurRegion = JAP_W56;
+ /*pRadarDetect->DfsSessionTime = 13;*/
+ }
+ else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
+ {
+ pAd->CommonCfg.RDDurRegion = JAP;
+ /*pRadarDetect->DfsSessionTime = 5;*/
+ }
+ else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
+ {
+ pAd->CommonCfg.RDDurRegion = FCC;
+ /*pRadarDetect->DfsSessionTime = 5;*/
+ }
+ else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
+ {
+ pAd->CommonCfg.RDDurRegion = CE;
+ /*pRadarDetect->DfsSessionTime = 13;*/
+ }
+ else
+ {
+ pAd->CommonCfg.RDDurRegion = CE;
+ /*pRadarDetect->DfsSessionTime = 13;*/
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RDDurRegion));
+ }
+ else
+ {
+ pAd->CommonCfg.RDDurRegion = CE;
+ /*pRadarDetect->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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < pAd->ApCfg.BssidNum); macptr = rstrtok(NULL,";"), i++)
+ {
+ ApCfg_Set_AuthMode_Proc(pAd, i, macptr);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ /*EncrypType*/
+ if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, pBuffer, TRUE))
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /*
+ We need to reset the WepStatus of all interfaces as 1 (Ndis802_11WEPDisabled) first.
+ Or it may have problem when some interface enabled but didn't configure it.
+ */
+ for ( i= 0; i<pAd->ApCfg.BssidNum; i++)
+ pAd->ApCfg.MBSSID[i].WepStatus = Ndis802_11WEPDisabled;
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ int apidx;
+
+ if (i<pAd->ApCfg.BssidNum)
+ {
+ apidx = i;
+ }
+ else
+ {
+ break;
+ }
+
+ if ((strncmp(macptr, "NONE", 4) == 0) || (strncmp(macptr, "none", 4) == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPDisabled;
+ else if ((strncmp(macptr, "WEP", 3) == 0) || (strncmp(macptr, "wep", 3) == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPEnabled;
+ else if ((strncmp(macptr, "TKIPAES", 7) == 0) || (strncmp(macptr, "tkipaes", 7) == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption4Enabled;
+ else if ((strncmp(macptr, "TKIP", 4) == 0) || (strncmp(macptr, "tkip", 4) == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption2Enabled;
+ else if ((strncmp(macptr, "AES", 3) == 0) || (strncmp(macptr, "aes", 3) == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption3Enabled;
+#ifdef WAPI_SUPPORT
+ else if ((strncmp(macptr, "SMS4", 4) == 0) || (strncmp(macptr, "sms4", 4) == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11EncryptionSMS4Enabled;
+#endif /* WAPI_SUPPORT */
+ else
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPDisabled;
+
+ /* decide the group key encryption type*/
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled)
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus = Ndis802_11Encryption2Enabled;
+ else
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus;
+
+ /* move to ap.c::APStartUp to process*/
+ /*RTMPMakeRSNIE(pAd, pAd->ApCfg.MBSSID[apidx].AuthMode, pAd->ApCfg.MBSSID[apidx].WepStatus, apidx);*/
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) EncrypType=%d\n", i, pAd->ApCfg.MBSSID[apidx].WepStatus));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* WpaMixPairCipher*/
+ if(RTMPGetKeyParameter("WpaMixPairCipher", tmpbuf, 256, pBuffer, TRUE))
+ {
+ /*
+ In WPA-WPA2 mix mode, it provides a more flexible cipher combination.
+ - WPA-AES and WPA2-TKIP
+ - WPA-AES and WPA2-TKIPAES
+ - WPA-TKIP and WPA2-AES
+ - WPA-TKIP and WPA2-TKIPAES
+ - WPA-TKIPAES and WPA2-AES
+ - WPA-TKIPAES and WPA2-TKIP
+ - WPA-TKIPAES and WPA2-TKIPAES (default)
+ */
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (pAd->ApCfg.MBSSID[i].AuthMode != Ndis802_11AuthModeWPA1WPA2 &&
+ pAd->ApCfg.MBSSID[i].AuthMode != Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ continue;
+
+ if (pAd->ApCfg.MBSSID[i].WepStatus != Ndis802_11Encryption4Enabled)
+ continue;
+
+ if ((strncmp(macptr, "WPA_AES_WPA2_TKIPAES", 20) == 0) || (strncmp(macptr, "wpa_aes_wpa2_tkipaes", 20) == 0))
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_AES_WPA2_TKIPAES;
+ else if ((strncmp(macptr, "WPA_AES_WPA2_TKIP", 17) == 0) || (strncmp(macptr, "wpa_aes_wpa2_tkip", 17) == 0))
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_AES_WPA2_TKIP;
+ else if ((strncmp(macptr, "WPA_TKIP_WPA2_AES", 17) == 0) || (strncmp(macptr, "wpa_tkip_wpa2_aes", 17) == 0))
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_TKIP_WPA2_AES;
+ else if ((strncmp(macptr, "WPA_TKIP_WPA2_TKIPAES", 21) == 0) || (strncmp(macptr, "wpa_tkip_wpa2_tkipaes", 21) == 0))
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_TKIP_WPA2_TKIPAES;
+ else if ((strncmp(macptr, "WPA_TKIPAES_WPA2_AES", 20) == 0) || (strncmp(macptr, "wpa_tkipaes_wpa2_aes", 20) == 0))
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_TKIPAES_WPA2_AES;
+ else if ((strncmp(macptr, "WPA_TKIPAES_WPA2_TKIPAES", 24) == 0) || (strncmp(macptr, "wpa_tkipaes_wpa2_tkipaes", 24) == 0))
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIPAES;
+ else if ((strncmp(macptr, "WPA_TKIPAES_WPA2_TKIP", 21) == 0) || (strncmp(macptr, "wpa_tkipaes_wpa2_tkip", 21) == 0))
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIP;
+ else /*Default*/
+ pAd->ApCfg.MBSSID[i].WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIPAES;
+
+ DBGPRINT(RT_DEBUG_OFF, ("I/F(ra%d) MixWPACipher=0x%02x\n", i, pAd->ApCfg.MBSSID[i].WpaMixPairCipher));
+ }
+ }
+
+ /*RekeyMethod*/
+ if(RTMPGetKeyParameter("RekeyMethod", tmpbuf, 128, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ PRT_WPA_REKEY pRekeyInfo = &pAd->ApCfg.MBSSID[i].WPAREKEY;
+
+ if ((strcmp(macptr, "TIME") == 0) || (strcmp(macptr, "time") == 0))
+ pRekeyInfo->ReKeyMethod = TIME_REKEY;
+ else if ((strcmp(macptr, "PKT") == 0) || (strcmp(macptr, "pkt") == 0))
+ pRekeyInfo->ReKeyMethod = PKT_REKEY;
+ else if ((strcmp(macptr, "DISABLE") == 0) || (strcmp(macptr, "disable") == 0))
+ pRekeyInfo->ReKeyMethod = DISABLE_REKEY;
+ else
+ pRekeyInfo->ReKeyMethod = DISABLE_REKEY;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) ReKeyMethod=%ld\n", i, pRekeyInfo->ReKeyMethod));
+ }
+
+ /* Apply to remaining MBSS*/
+ if (i == 1)
+ {
+ for (i = 1; i < pAd->ApCfg.BssidNum; i++)
+ {
+ pAd->ApCfg.MBSSID[i].WPAREKEY.ReKeyMethod =
+ pAd->ApCfg.MBSSID[0].WPAREKEY.ReKeyMethod;
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) ReKeyMethod=%ld\n",
+ i, pAd->ApCfg.MBSSID[i].WPAREKEY.ReKeyMethod));
+ }
+ }
+ }
+ /*RekeyInterval*/
+ if(RTMPGetKeyParameter("RekeyInterval", tmpbuf, 255, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ ULONG value_interval;
+ PRT_WPA_REKEY pRekeyInfo = &pAd->ApCfg.MBSSID[i].WPAREKEY;
+
+ value_interval = simple_strtol(macptr, 0, 10);
+
+ if((value_interval >= 10) && (value_interval < MAX_REKEY_INTER))
+ pRekeyInfo->ReKeyInterval = value_interval;
+ else /*Default*/
+ pRekeyInfo->ReKeyInterval = 3600;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) ReKeyInterval=%ld\n",
+ i, pRekeyInfo->ReKeyInterval));
+ }
+
+ /* Apply to remaining MBSS*/
+ if (i == 1)
+ {
+ for (i = 1; i < pAd->ApCfg.BssidNum; i++)
+ {
+ pAd->ApCfg.MBSSID[i].WPAREKEY.ReKeyInterval =
+ pAd->ApCfg.MBSSID[0].WPAREKEY.ReKeyInterval;
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) ReKeyInterval=%ld\n",
+ i, pAd->ApCfg.MBSSID[i].WPAREKEY.ReKeyInterval));
+ }
+ }
+
+ }
+ /*PMKCachePeriod*/
+ if(RTMPGetKeyParameter("PMKCachePeriod", tmpbuf, 255, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->ApCfg.MBSSID[i].PMKCachePeriod =
+ simple_strtol(macptr, 0, 10) * 60 * OS_HZ;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) PMKCachePeriod=%ld\n",
+ i, pAd->ApCfg.MBSSID[i].PMKCachePeriod));
+ }
+
+ /* Apply to remaining MBSS*/
+ if (i == 1)
+ {
+ for (i = 1; i < pAd->ApCfg.BssidNum; i++)
+ {
+ pAd->ApCfg.MBSSID[i].PMKCachePeriod =
+ pAd->ApCfg.MBSSID[0].PMKCachePeriod;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) PMKCachePeriod=%ld\n",
+ i, pAd->ApCfg.MBSSID[i].PMKCachePeriod));
+ }
+ }
+ }
+
+ /*WPAPSK_KEY*/
+ if(TRUE)
+ {
+ STRING tok_str[16];
+ BOOLEAN bWPAPSKxIsUsed = FALSE;
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("pAd->ApCfg.BssidNum=%d\n", pAd->ApCfg.BssidNum));
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ snprintf(tok_str, sizeof(tok_str), "WPAPSK%d", i + 1);
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 65, pBuffer, FALSE))
+ {
+ rtmp_parse_wpapsk_buffer_from_file(pAd, tmpbuf, i);
+
+ if (bWPAPSKxIsUsed == FALSE)
+ {
+ bWPAPSKxIsUsed = TRUE;
+ }
+ }
+ }
+ if (bWPAPSKxIsUsed == FALSE)
+ {
+ if (RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE))
+ {
+ if (pAd->ApCfg.BssidNum == 1)
+ {
+ rtmp_parse_wpapsk_buffer_from_file(pAd, tmpbuf, BSS0);
+ }
+ else
+ {
+ /* Anyway, we still do the legacy dissection of the whole WPAPSK passphrase.*/
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ rtmp_parse_wpapsk_buffer_from_file(pAd, macptr, i);
+ }
+
+ }
+ }
+ }
+
+#ifdef DBG
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ int j;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WPAPSK Key => \n", i));
+ for (j = 0; j < 32; j++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02x:", pAd->ApCfg.MBSSID[i].PMK[j]));
+ if ((j%16) == 15)
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+ }
+#endif
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /*DefaultKeyID, KeyType, KeyStr*/
+ rtmp_read_key_parms_from_file(pAd, tmpbuf, pBuffer);
+
+#ifdef WAPI_SUPPORT
+ rtmp_read_wapi_parms_from_file(pAd, tmpbuf, pBuffer);
+#endif /* WAPI_SUPPORT */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /*Access Control List*/
+ rtmp_read_acl_parms_from_file(pAd, tmpbuf, pBuffer);
+
+#ifdef APCLI_SUPPORT
+ rtmp_read_ap_client_from_file(pAd, tmpbuf, pBuffer);
+#endif /* APCLI_SUPPORT */
+
+#ifdef IGMP_SNOOP_SUPPORT
+ /* Igmp Snooping information*/
+ rtmp_read_igmp_snoop_from_file(pAd, tmpbuf, pBuffer);
+#endif /* IGMP_SNOOP_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ rtmp_read_wds_from_file(pAd, tmpbuf, pBuffer);
+#endif /* WDS_SUPPORT */
+
+#ifdef DOT1X_SUPPORT
+ rtmp_read_radius_parms_from_file(pAd, tmpbuf, pBuffer);
+#endif /* DOT1X_SUPPORT */
+
+#ifdef IDS_SUPPORT
+ rtmp_read_ids_from_file(pAd, tmpbuf, pBuffer);
+#endif /* IDS_SUPPORT */
+ rtmp_read_multest_from_file(pAd, tmpbuf, pBuffer);
+ }
+
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ HTParametersHook(pAd, tmpbuf, pBuffer);
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_VHT_AC
+ VHTParametersHook(pAd, tmpbuf, pBuffer);
+#endif /* DOT11_VHT_AC */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef WSC_AP_SUPPORT
+ STRING tok_str[16] = {0};
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ snprintf(tok_str, sizeof(tok_str), "WscDefaultSSID%d", i + 1);
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 33, pBuffer, FALSE))
+ {
+ NdisZeroMemory(&pAd->ApCfg.MBSSID[i].WscControl.WscDefaultSsid, sizeof(NDIS_802_11_SSID));
+ NdisMoveMemory(pAd->ApCfg.MBSSID[i].WscControl.WscDefaultSsid.Ssid, tmpbuf , strlen(tmpbuf));
+ pAd->ApCfg.MBSSID[i].WscControl.WscDefaultSsid.SsidLength = strlen(tmpbuf);
+ DBGPRINT(RT_DEBUG_TRACE, ("WscDefaultSSID[%d]=%s\n", i, pAd->ApCfg.MBSSID[i].WscControl.WscDefaultSsid.Ssid));
+ }
+ }
+
+ /*WscConfMode*/
+ if(RTMPGetKeyParameter("WscConfMode", tmpbuf, 10, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ INT WscConfMode = simple_strtol(macptr, 0, 10);
+
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ if (WscConfMode > 0 && WscConfMode < 8)
+ {
+ pAd->ApCfg.MBSSID[i].WscControl.WscConfMode = WscConfMode;
+ }
+ else
+ {
+ pAd->ApCfg.MBSSID[i].WscControl.WscConfMode = WSC_DISABLE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WscConfMode=%d\n", i, pAd->ApCfg.MBSSID[i].WscControl.WscConfMode));
+ }
+ }
+
+ /*WscConfStatus*/
+ if(RTMPGetKeyParameter("WscConfStatus", tmpbuf, 10, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ pAd->ApCfg.MBSSID[i].WscControl.WscConfStatus = (INT) simple_strtol(macptr, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WscConfStatus=%d\n", i, pAd->ApCfg.MBSSID[i].WscControl.WscConfStatus));
+ }
+ }
+ /*WscConfMethods*/
+ if(RTMPGetKeyParameter("WscConfMethods", tmpbuf, 32, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ pAd->ApCfg.MBSSID[i].WscControl.WscConfigMethods = (USHORT)simple_strtol(macptr, 0, 16);
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WscConfMethods=0x%x\n", i, pAd->ApCfg.MBSSID[i].WscControl.WscConfigMethods));
+ }
+ }
+
+ /*WscKeyASCII (0:Hex, 1:ASCII(random length), others: ASCII length, default 8)*/
+ if (RTMPGetKeyParameter("WscKeyASCII", tmpbuf, 10, pBuffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ INT Value;
+
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ Value = (INT) simple_strtol(tmpbuf, 0, 10);
+ if(Value==0 || Value==1)
+ pAd->ApCfg.MBSSID[i].WscControl.WscKeyASCII = Value;
+ else if(Value >= 8 && Value <=63)
+ pAd->ApCfg.MBSSID[i].WscControl.WscKeyASCII = Value;
+ else
+ pAd->ApCfg.MBSSID[i].WscControl.WscKeyASCII = 8;
+ DBGPRINT(RT_DEBUG_WARN, ("WscKeyASCII=%d\n", pAd->ApCfg.MBSSID[i].WscControl.WscKeyASCII));
+ }
+ }
+
+ if (RTMPGetKeyParameter("WscSecurityMode", tmpbuf, 50, pBuffer, TRUE))
+ {
+ for (i= 0; i<pAd->ApCfg.BssidNum; i++)
+ pAd->ApCfg.MBSSID[i].WscSecurityMode = WPAPSKTKIP;
+
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ INT tmpMode = 0;
+
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ tmpMode = (INT) simple_strtol(macptr, 0, 10);
+ if (tmpMode <= WPAPSKTKIP)
+ pAd->ApCfg.MBSSID[i].WscSecurityMode = tmpMode;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetProfileParameters I/F(ra%d) WscSecurityMode=%d\n",
+ i, pAd->ApCfg.MBSSID[i].WscSecurityMode));
+ }
+ }
+
+ /* WCNTest*/
+ if(RTMPGetKeyParameter("WCNTest", tmpbuf, 10, pBuffer, TRUE))
+ {
+ BOOLEAN bEn = FALSE;
+
+ if ((strncmp(tmpbuf, "0", 1) == 0))
+ bEn = FALSE;
+ else
+ bEn = TRUE;
+
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ pAd->ApCfg.MBSSID[i].WscControl.bWCNTest = bEn;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("WCNTest=%d\n", bEn));
+ }
+
+ /*WSC UUID Str*/
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ PWSC_CTRL pWpsCtrl = &pAd->ApCfg.MBSSID[i].WscControl;
+ snprintf(tok_str, sizeof(tok_str), "WSC_UUID_Str%d", i + 1);
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 40, pBuffer, FALSE))
+ {
+ NdisMoveMemory(&pWpsCtrl->Wsc_Uuid_Str[0], tmpbuf , strlen(tmpbuf));
+ DBGPRINT(RT_DEBUG_TRACE, ("UUID_Str[%d]=%s\n", i+1, pWpsCtrl->Wsc_Uuid_Str));
+ }
+ }
+
+ /*WSC UUID Hex*/
+ for (i = 0; i < pAd->ApCfg.BssidNum; i++)
+ {
+ PWSC_CTRL pWpsCtrl = &pAd->ApCfg.MBSSID[i].WscControl;
+ snprintf(tok_str, sizeof(tok_str), "WSC_UUID_E%d", i + 1);
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 40, pBuffer, FALSE))
+ {
+ AtoH(tmpbuf, &pWpsCtrl->Wsc_Uuid_E[0], UUID_LEN_HEX);
+ DBGPRINT(RT_DEBUG_TRACE, ("Wsc_Uuid_E[%d]", i+1));
+ hex_dump("", &pWpsCtrl->Wsc_Uuid_E[0], UUID_LEN_HEX);
+ }
+ }
+
+
+#endif /* WSC_AP_SUPPORT */
+
+
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef MCAST_RATE_SPECIFIC
+ /* McastPhyMode*/
+ if (RTMPGetKeyParameter("McastPhyMode", tmpbuf, 32, pBuffer, TRUE))
+ {
+ UCHAR PhyMode = simple_strtol(tmpbuf, 0, 10);
+ pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
+ switch (PhyMode)
+ {
+ case MCAST_DISABLE: /* disable*/
+ NdisMoveMemory(&pAd->CommonCfg.MCastPhyMode,
+ &pAd->MacTab.Content[MCAST_WCID].HTPhyMode, sizeof(HTTRANSMIT_SETTING));
+ break;
+
+ case MCAST_CCK: /* CCK*/
+ pAd->CommonCfg.MCastPhyMode.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MCastPhyMode.field.BW = BW_20;
+ break;
+
+ case MCAST_OFDM: /* OFDM*/
+ pAd->CommonCfg.MCastPhyMode.field.MODE = MODE_OFDM;
+ break;
+#ifdef DOT11_N_SUPPORT
+ case MCAST_HTMIX: /* HTMIX*/
+ pAd->CommonCfg.MCastPhyMode.field.MODE = MODE_HTMIX;
+ break;
+#endif /* DOT11_N_SUPPORT */
+
+ default:
+ DBGPRINT(RT_DEBUG_OFF, ("unknow Muticast PhyMode %d.\n", PhyMode));
+ DBGPRINT(RT_DEBUG_OFF, ("0:Disable 1:CCK, 2:OFDM, 3:HTMIX.\n"));
+ break;
+ }
+ }
+ else
+ NdisMoveMemory(&pAd->CommonCfg.MCastPhyMode,
+ &pAd->MacTab.Content[MCAST_WCID].HTPhyMode, sizeof(HTTRANSMIT_SETTING));
+
+ /* McastMcs*/
+ if (RTMPGetKeyParameter("McastMcs", tmpbuf, 32, pBuffer, TRUE))
+ {
+ UCHAR Mcs = simple_strtol(tmpbuf, 0, 10);
+ switch(pAd->CommonCfg.MCastPhyMode.field.MODE)
+ {
+ case MODE_CCK:
+ if ((Mcs <= 3) || (Mcs >= 8 && Mcs <= 11))
+ pAd->CommonCfg.MCastPhyMode.field.MCS = Mcs;
+ else
+ DBGPRINT(RT_DEBUG_OFF, ("MCS must in range of 0 ~ 3 and 8 ~ 11 for CCK Mode.\n"));
+ break;
+
+ case MODE_OFDM:
+ if (Mcs > 7)
+ DBGPRINT(RT_DEBUG_OFF, ("MCS must in range from 0 to 7 for CCK Mode.\n"));
+ else
+ pAd->CommonCfg.MCastPhyMode.field.MCS = Mcs;
+ break;
+
+ default:
+ pAd->CommonCfg.MCastPhyMode.field.MCS = Mcs;
+ break;
+ }
+ }
+ else
+ pAd->CommonCfg.MCastPhyMode.field.MCS = 0;
+#endif /* MCAST_RATE_SPECIFIC */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef WSC_INCLUDED
+
+ rtmp_read_wsc_user_parms_from_file(pAd, tmpbuf, pBuffer);
+
+ /* Wsc4digitPinCode = TRUE use 4-digit Pin code, otherwise 8-digit Pin code */
+ if (RTMPGetKeyParameter("Wsc4digitPinCode", tmpbuf, 32, pBuffer, TRUE))
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+
+ if (simple_strtol(macptr, 0, 10) != 0) //Enable
+ pAd->ApCfg.MBSSID[i].WscControl.WscEnrollee4digitPinCode = TRUE;
+ else //Disable
+ pAd->ApCfg.MBSSID[i].WscControl.WscEnrollee4digitPinCode = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Wsc4digitPinCode=%d\n", i, pAd->ApCfg.MBSSID[i].WscControl.WscEnrollee4digitPinCode));
+ }
+
+ }
+#endif // CONFIG_AP_SUPPORT //
+ }
+
+ if (RTMPGetKeyParameter("WscVendorPinCode", tmpbuf, 256, pBuffer, TRUE))
+ {
+ PWSC_CTRL pWscContrl;
+ int bSetOk;
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ pWscContrl = &pAd->ApCfg.MBSSID[BSS0].WscControl;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ bSetOk = RT_CfgSetWscPinCode(pAd, tmpbuf, pWscContrl);
+ if (bSetOk)
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - WscVendorPinCode= (%d)\n", __FUNCTION__, bSetOk));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s - WscVendorPinCode: invalid pin code(%s)\n", __FUNCTION__, tmpbuf));
+ }
+#ifdef WSC_V2_SUPPORT
+ if (RTMPGetKeyParameter("WscV2Support", tmpbuf, 32, pBuffer, TRUE))
+ {
+ UCHAR bEnable;
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if (i >= pAd->ApCfg.BssidNum)
+ break;
+ bEnable = (UCHAR)simple_strtol(macptr, 0, 10);
+ pAd->ApCfg.MBSSID[i].WscControl.WscV2Info.bEnableWpsV2 = bEnable;
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WscV2Support=%d\n", i, bEnable));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+#endif /* WSC_V2_SUPPORT */
+
+
+#endif /* WSC_INCLUDED */
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+ /* EntryLifeCheck is used to check */
+ if (RTMPGetKeyParameter("EntryLifeCheck", tmpbuf, 256, pBuffer, TRUE))
+ {
+ long LifeCheckCnt = simple_strtol(tmpbuf, 0, 10);
+ if ((LifeCheckCnt <= 65535) && (LifeCheckCnt != 0))
+ pAd->ApCfg.EntryLifeCheck = LifeCheckCnt;
+ else
+ pAd->ApCfg.EntryLifeCheck = MAC_ENTRY_LIFE_CHECK_CNT;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("EntryLifeCheck=%ld\n", pAd->ApCfg.EntryLifeCheck));
+ }
+
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#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 */
+
+
+
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ /* set GPIO pin for wake-up signal */
+ if (RTMPGetKeyParameter("WOW_GPIO", tmpbuf, 10, pBuffer, TRUE))
+ Set_WOW_GPIO(pAd, tmpbuf);
+
+ /* set WOW enable/disable */
+ if (RTMPGetKeyParameter("WOW_Enable", tmpbuf, 10, pBuffer, TRUE))
+ Set_WOW_Enable(pAd, tmpbuf);
+
+ /* set delay time for WOW really enable */
+ if (RTMPGetKeyParameter("WOW_Delay", tmpbuf, 10, pBuffer, TRUE))
+ Set_WOW_Delay(pAd, tmpbuf);
+
+ /* set GPIO pulse hold time */
+ if (RTMPGetKeyParameter("WOW_Hold", tmpbuf, 10, pBuffer, TRUE))
+ Set_WOW_Hold(pAd, tmpbuf);
+
+ /* set wakeup signal type */
+ if (RTMPGetKeyParameter("WOW_InBand", tmpbuf, 10, pBuffer, TRUE))
+ Set_WOW_InBand(pAd, tmpbuf);
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ if (RTMPGetKeyParameter("MO_FalseCCATh", tmpbuf, 10, pBuffer, TRUE))
+ {
+ Set_MO_FalseCCATh_Proc(pAd, tmpbuf);
+ }
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ }while(0);
+
+#ifdef CUSTOMER_DEMO
+ demo_mode_cfg(pAd);
+#endif /* CUSTOMER_DEMO */
+
+ 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; _len<strlen(card_id); _len++) { \
+ _char = *(txt_p + _len); \
+ if (('A' <= _char) && (_char <= 'Z')) \
+ *(txt_p+_len) = 'a'+(_char-'A'); \
+ } }
+
+ RTMP_OS_FD srcf;
+ INT retval;
+ PSTRING buffer, tmpbuf;
+ STRING card_id_buf[30], RFIC_word[30];
+ BOOLEAN flg_match_ok = FALSE;
+ INT32 card_select_method;
+ INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
+ EEPROM_ANTENNA_STRUC antenna;
+ USHORT addr01, addr23, addr45;
+ UINT8 mac[6];
+ UINT32 data, card_index;
+ UCHAR *start_ptr;
+ RTMP_OS_FS_INFO osFSInfo;
+
+ /* init*/
+ os_alloc_mem(NULL, (UCHAR **)&buffer, MAX_INI_BUFFER_SIZE);
+ if (buffer == NULL)
+ return FALSE;
+
+ os_alloc_mem(NULL, (UCHAR **)&tmpbuf, MAX_PARAM_BUFFER_SIZE);
+ if(tmpbuf == NULL)
+ {
+ os_free_mem(NULL, buffer);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ /* get RF IC type*/
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
+
+ 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) ||
+ (antenna.field.RfIcType == RFIC_5592))
+ {
+ /* 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<MAX_NUM_OF_MULTIPLE_CARD;
+ card_index++)
+ {
+ if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+ (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+ {
+ /* MAC is all-0 so the entry is available*/
+ MC_CardUsed[card_index] = 0;
+
+ if (card_free_id < 0)
+ card_free_id = card_index; /* 1st free entry*/
+ }
+ else
+ {
+ if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
+ {
+ /* we find the entry with same MAC*/
+ if (card_same_mac_id < 0)
+ card_same_mac_id = card_index; /* 1st same entry*/
+ }
+ else
+ {
+ /* MAC is not all-0 but used flag == 0*/
+ if ((MC_CardUsed[card_index] == 0) &&
+ (card_nouse_id < 0))
+ {
+ card_nouse_id = card_index; /* 1st available entry*/
+ }
+ }
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("MC> 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<MAX_NUM_OF_MULTIPLE_CARD;
+ card_index++)
+ {
+ snprintf(card_id_buf, sizeof(card_id_buf), "%02dCARDTYPE%s",
+ card_index, RFIC_word);
+
+ if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer,
+ card_id_buf)) != NULL)
+ {
+ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+
+ if (MC_CardUsed[card_index] == 0)
+ {
+ /* current the card profile is not used */
+ if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+ (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+ {
+ /* find it and no previous card use it*/
+ card_match_id = card_index;
+ break;
+ }
+ else
+ {
+ /* ever a card use it*/
+ if (card_nouse_id < 0)
+ card_nouse_id = card_index;
+ }
+ }
+ }
+ }
+
+ /* if not find a free one, use the available one*/
+ if (card_match_id < 0)
+ card_match_id = card_nouse_id;
+ break;
+ }
+ }
+
+ if (card_match_id >= 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 */
+
+
+#ifdef WSC_INCLUDED
+void rtmp_read_wsc_user_parms(
+ PWSC_CTRL pWscControl,
+ STRING *tmpbuf,
+ STRING *buffer)
+{
+ if(RTMPGetKeyParameter("WscManufacturer", tmpbuf, WSC_MANUFACTURE_LEN, buffer,TRUE))
+ {
+ NdisZeroMemory(pWscControl->RegData.SelfInfo.Manufacturer, WSC_MANUFACTURE_LEN);
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.Manufacturer, tmpbuf, strlen(tmpbuf));
+ if(pWscControl->RegData.SelfInfo.Manufacturer[0] != 0x00)
+ RTMP_SET_FLAG(pWscControl, 0x01);
+ }
+
+ /*WSC_User_ModelName*/
+ if(RTMPGetKeyParameter("WscModelName", tmpbuf, WSC_MODELNAME_LEN, buffer,TRUE))
+ {
+ NdisZeroMemory(pWscControl->RegData.SelfInfo.ModelName, WSC_MODELNAME_LEN);
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.ModelName, tmpbuf, strlen(tmpbuf));
+ if(pWscControl->RegData.SelfInfo.ModelName[0] != 0x00)
+ RTMP_SET_FLAG(pWscControl, 0x02);
+ }
+
+ /*WSC_User_DeviceName*/
+ if(RTMPGetKeyParameter("WscDeviceName", tmpbuf, WSC_DEVICENAME_LEN, buffer,TRUE))
+ {
+ NdisZeroMemory(pWscControl->RegData.SelfInfo.DeviceName, WSC_DEVICENAME_LEN);
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.DeviceName, tmpbuf, strlen(tmpbuf));
+ if(pWscControl->RegData.SelfInfo.DeviceName[0] != 0x00)
+ RTMP_SET_FLAG(pWscControl, 0x04);
+ }
+
+ /*WSC_User_ModelNumber*/
+ if(RTMPGetKeyParameter("WscModelNumber", tmpbuf, WSC_MODELNUNBER_LEN, buffer,TRUE))
+ {
+ NdisZeroMemory(pWscControl->RegData.SelfInfo.ModelNumber, WSC_MODELNUNBER_LEN);
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.ModelNumber, tmpbuf, strlen(tmpbuf));
+ if(pWscControl->RegData.SelfInfo.ModelNumber[0] != 0x00)
+ RTMP_SET_FLAG(pWscControl, 0x08);
+ }
+
+ /*WSC_User_SerialNumber*/
+ if(RTMPGetKeyParameter("WscSerialNumber", tmpbuf, WSC_SERIALNUNBER_LEN, buffer,TRUE))
+ {
+ NdisZeroMemory(pWscControl->RegData.SelfInfo.SerialNumber, WSC_SERIALNUNBER_LEN);
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.SerialNumber, tmpbuf, strlen(tmpbuf));
+ if(pWscControl->RegData.SelfInfo.SerialNumber[0] != 0x00)
+ RTMP_SET_FLAG(pWscControl, 0x10);
+ }
+}
+
+void rtmp_read_wsc_user_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+ PWSC_CTRL pWscControl;
+
+#ifdef WSC_AP_SUPPORT
+ int i=0;
+ for(i = 0; i < MAX_MBSSID_NUM(pAd); i++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[i].WscControl;
+ rtmp_read_wsc_user_parms(pWscControl, tmpbuf, buffer);
+}
+#ifdef APCLI_SUPPORT
+ pWscControl = &pAd->ApCfg.ApCliTab[0].WscControl;
+ rtmp_read_wsc_user_parms(pWscControl, tmpbuf, buffer);
+#endif /* APCLI_SUPPORT */
+#endif /* WSC_AP_SUPPORT */
+
+#ifdef WSC_STA_SUPPORT
+ pWscControl = &pAd->StaCfg.WscControl;
+ rtmp_read_wsc_user_parms(pWscControl, tmpbuf, buffer);
+#endif /* WSC_STA_SUPPORT */
+
+}
+#endif/*WSC_INCLUDED*/
+
+
+VOID rtmp_read_multest_from_file(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING tmpbuf,
+ IN PSTRING buffer)
+{
+ PSTRING macptr;
+ INT i=0, j;
+ STRING tok_str[16];
+ BOOLEAN bUsePrevFormat = FALSE;
+ UCHAR macAddress[MAC_ADDR_LEN];
+ UCHAR keyMaterial[40];
+ UCHAR KeyLen, CipherAlg = CIPHER_NONE, KeyIdx;
+ PRT_802_11_WDS_ENTRY pWdsEntry;
+
+ /*WdsPhyMode */
+ if (RTMPGetKeyParameter("WdsPhyMode", tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ if ((strncmp(macptr, "CCK", 3) == 0) || (strncmp(macptr, "cck", 3) == 0))
+ pAd->MulTestTab.WdsEntry[i].PhyMode = MODE_CCK;
+ else if ((strncmp(macptr, "OFDM", 4) == 0) || (strncmp(macptr, "ofdm", 4) == 0))
+ pAd->MulTestTab.WdsEntry[i].PhyMode = MODE_OFDM;
+#ifdef DOT11_N_SUPPORT
+ else if ((strncmp(macptr, "HTMIX", 5) == 0) || (strncmp(macptr, "htmix", 5) == 0))
+ pAd->MulTestTab.WdsEntry[i].PhyMode = MODE_HTMIX;
+ else if ((strncmp(macptr, "GREENFIELD", 10) == 0) || (strncmp(macptr, "greenfield", 10) == 0))
+ pAd->MulTestTab.WdsEntry[i].PhyMode = MODE_HTGREENFIELD;
+#endif /* DOT11_N_SUPPORT */
+ else
+ pAd->MulTestTab.WdsEntry[i].PhyMode = 0xff;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("If/wds%d - WdsPhyMode=%d\n", i, pAd->MulTestTab.WdsEntry[i].PhyMode));
+ }
+ }
+
+ /*WdsList */
+ if (RTMPGetKeyParameter("WdsList", tmpbuf, MAX_PARAM_BUFFER_SIZE, buffer, TRUE))
+ {
+ for (i=0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ if(strlen(macptr) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ continue;
+ if(strcmp(macptr,"00:00:00:00:00:00") == 0)
+ continue;
+ if(i >= MAX_WDS_ENTRY)
+ break;
+
+ for (j=0; j<ETH_LENGTH_OF_ADDRESS; j++)
+ {
+ AtoH(macptr, &macAddress[j], 1);
+ macptr=macptr+3;
+ }
+
+ {
+ INT iii;
+ LONG WdsTabIdx = -1;
+
+ for (iii = 0; iii < MAX_WDS_ENTRY; iii++)
+ {
+ if (pAd->MulTestTab.WdsEntry[iii].Valid == FALSE)
+ {
+ pAd->MulTestTab.WdsEntry[iii].Valid = TRUE;
+ pAd->MulTestTab.Size ++;
+ COPY_MAC_ADDR(pAd->MulTestTab.WdsEntry[iii].PeerWdsAddr, macAddress);
+ WdsTabIdx = iii;
+ break;
+ }
+ else if (MAC_ADDR_EQUAL(pAd->MulTestTab.WdsEntry[iii].PeerWdsAddr, macAddress))
+ {
+ WdsTabIdx = iii;
+ break;
+ }
+ }
+
+ if (iii == MAX_WDS_ENTRY)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Unable to allocate MulTestEntry.\n", __FUNCTION__));
+ }
+ }
+ }
+
+ /*WdsEncrypType */
+ if (RTMPGetKeyParameter("WdsEncrypType", tmpbuf, 128, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ if ((strncmp(macptr, "NONE", 4) == 0) || (strncmp(macptr, "none", 4) == 0))
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11WEPDisabled;
+ else if ((strncmp(macptr, "WEP", 3) == 0) || (strncmp(macptr, "wep", 3) == 0))
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11WEPEnabled;
+ else if ((strncmp(macptr, "TKIP", 4) == 0) || (strncmp(macptr, "tkip", 4) == 0))
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11Encryption2Enabled;
+ else if ((strncmp(macptr, "AES", 3) == 0) || (strncmp(macptr, "aes", 3) == 0))
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11Encryption3Enabled;
+#ifdef WAPI_SUPPORT
+ else if ((strncmp(macptr, "SMS4", 4) == 0) || (strncmp(macptr, "sms4", 4) == 0))
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionSMS4Enabled;
+#endif /* WAPI_SUPPORT */
+ else
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11WEPDisabled;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WdsEncrypType[%d]=%d(%s)\n", i, pAd->MulTestTab.WdsEntry[i].WepStatus, GetEncryptType(pAd->MulTestTab.WdsEntry[i].WepStatus)));
+ }
+
+ /* Previous WDS only supports single encryption type. */
+ /* For backward compatible, other wds link encryption type shall be the same with the first. */
+ if (i == 1)
+ {
+ for (j = 1; j < MAX_WDS_ENTRY; j++)
+ {
+ pAd->MulTestTab.WdsEntry[j].WepStatus = pAd->MulTestTab.WdsEntry[0].WepStatus;
+ DBGPRINT(RT_DEBUG_TRACE, ("@WdsEncrypType[%d]=%d(%s)\n", j, pAd->MulTestTab.WdsEntry[i].WepStatus, GetEncryptType(pAd->MulTestTab.WdsEntry[i].WepStatus)));
+ }
+ }
+ }
+
+ /* WdsKey */
+ /* This is a previous parameter and it only stores WPA key material, not WEP key */
+ if (RTMPGetKeyParameter("WdsKey", tmpbuf, 255, buffer, FALSE))
+ {
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ NdisZeroMemory(&pAd->MulTestTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+
+ if (strlen(tmpbuf) > 0)
+ bUsePrevFormat = TRUE;
+
+ /* check if the wds-0 link key material is valid */
+ if (((pAd->MulTestTab.WdsEntry[0].WepStatus == Ndis802_11Encryption2Enabled)
+ || (pAd->MulTestTab.WdsEntry[0].WepStatus == Ndis802_11Encryption3Enabled))
+ && (strlen(tmpbuf) >= 8) && (strlen(tmpbuf) <= 64))
+ {
+ RT_CfgSetWPAPSKKey(pAd, tmpbuf, strlen(tmpbuf), (PUCHAR)RALINK_PASSPHRASE, sizeof(RALINK_PASSPHRASE), keyMaterial);
+ if (pAd->MulTestTab.WdsEntry[0].WepStatus == Ndis802_11Encryption3Enabled)
+ pAd->MulTestTab.WdsEntry[0].WdsKey.CipherAlg = CIPHER_AES;
+ else
+ pAd->MulTestTab.WdsEntry[0].WdsKey.CipherAlg = CIPHER_TKIP;
+
+ NdisMoveMemory(&pAd->MulTestTab.WdsEntry[0].WdsKey.Key, keyMaterial, 16);
+ pAd->MulTestTab.WdsEntry[0].WdsKey.KeyLen = 16;
+ NdisMoveMemory(&pAd->MulTestTab.WdsEntry[0].WdsKey.RxMic, keyMaterial+16, 8);
+ NdisMoveMemory(&pAd->MulTestTab.WdsEntry[0].WdsKey.TxMic, keyMaterial+16, 8);
+ }
+
+ /* Previous WDS only supports single key-material. */
+ /* For backward compatible, other wds link key-material shall be the same with the first. */
+ if (pAd->MulTestTab.WdsEntry[0].WdsKey.KeyLen == 16)
+ {
+ for (j = 1; j < MAX_WDS_ENTRY; j++)
+ {
+ NdisMoveMemory(&pAd->MulTestTab.WdsEntry[j].WdsKey, &pAd->MulTestTab.WdsEntry[0].WdsKey, sizeof(CIPHER_KEY));
+ }
+ }
+
+ }
+
+ /* The parameters can provide different key information for each WDS-Link */
+ /* no matter WEP or WPA */
+ if (!bUsePrevFormat)
+ {
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ AP_WDS_KeyNameMakeUp(tok_str, sizeof(tok_str), i);
+
+ /* WdsXKey (X=0~MAX_WDS_ENTRY-1) */
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
+ {
+ if (pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11Encryption1Enabled)
+ {
+ /* Ascii type */
+ if (strlen(tmpbuf) == 5 || strlen(tmpbuf) == 13)
+ {
+ KeyLen = strlen(tmpbuf);
+ pAd->MulTestTab.WdsEntry[i].WdsKey.KeyLen = KeyLen;
+ NdisMoveMemory(pAd->MulTestTab.WdsEntry[i].WdsKey.Key, tmpbuf, KeyLen);
+ if (KeyLen == 5)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+
+ pAd->MulTestTab.WdsEntry[i].WdsKey.CipherAlg = CipherAlg;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d Key=%s ,type=Ascii, CipherAlg(%s)\n", i, tmpbuf, (CipherAlg == CIPHER_WEP64 ? "wep64" : "wep128")));
+ }
+ /* Hex type */
+ else if (strlen(tmpbuf) == 10 || strlen(tmpbuf) == 26)
+ {
+ KeyLen = strlen(tmpbuf);
+ pAd->MulTestTab.WdsEntry[i].WdsKey.KeyLen = KeyLen / 2;
+ AtoH(tmpbuf, pAd->MulTestTab.WdsEntry[i].WdsKey.Key, KeyLen / 2);
+ if (KeyLen == 10)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+
+ pAd->MulTestTab.WdsEntry[i].WdsKey.CipherAlg = CipherAlg;
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d Key=%s ,type=Hex, CipherAlg(%s)\n", i, tmpbuf, (CipherAlg == CIPHER_WEP64 ? "wep64" : "wep128")));
+ }
+ /* Invalid type */
+ else
+ {
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ NdisZeroMemory(&pAd->MulTestTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d has invalid key for WEP, reset encryption to OPEN\n", i));
+ }
+ }
+ else if ((pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11Encryption2Enabled)
+ || (pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11Encryption3Enabled)
+#ifdef WAPI_SUPPORT
+ || (pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11EncryptionSMS4Enabled)
+#endif /* WAPI_SUPPORT */
+ )
+ {
+ if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) <= 64))
+ {
+ RT_CfgSetWPAPSKKey(pAd, tmpbuf, strlen(tmpbuf), (PUCHAR) RALINK_PASSPHRASE, sizeof(RALINK_PASSPHRASE), keyMaterial);
+
+ if (pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ pAd->MulTestTab.WdsEntry[i].WdsKey.CipherAlg = CIPHER_AES;
+ CipherAlg = CIPHER_AES;
+ }
+#ifdef WAPI_SUPPORT
+ else if (pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11EncryptionSMS4Enabled)
+ {
+ pAd->MulTestTab.WdsEntry[i].WdsKey.CipherAlg = CIPHER_SMS4;
+ CipherAlg = CIPHER_SMS4;
+ }
+#endif /* WAPI_SUPPORT */
+ else
+ {
+ pAd->MulTestTab.WdsEntry[i].WdsKey.CipherAlg = CIPHER_TKIP;
+ CipherAlg = CIPHER_TKIP;
+ }
+
+ NdisMoveMemory(&pAd->MulTestTab.WdsEntry[i].WdsKey.Key, keyMaterial, 16);
+ pAd->MulTestTab.WdsEntry[i].WdsKey.KeyLen = 16;
+ NdisMoveMemory(&pAd->MulTestTab.WdsEntry[i].WdsKey.RxMic, keyMaterial+16, 8);
+ NdisMoveMemory(&pAd->MulTestTab.WdsEntry[i].WdsKey.TxMic, keyMaterial+16, 8);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d Key=%s, CipherAlg(%s)\n", i, tmpbuf, (CipherAlg == CIPHER_AES ? "AES" : "TKIP")));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d has invalid key for WPA, reset encryption to OPEN\n", i));
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ NdisZeroMemory(&pAd->MulTestTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+ }
+
+ }
+ else
+ {
+ pAd->MulTestTab.WdsEntry[i].WepStatus = Ndis802_11EncryptionDisabled;
+ NdisZeroMemory(&pAd->MulTestTab.WdsEntry[i].WdsKey, sizeof(CIPHER_KEY));
+ }
+ }
+ }
+ }
+
+ /* WdsDefaultKeyID */
+ if(RTMPGetKeyParameter("WdsDefaultKeyID", tmpbuf, 10, buffer, TRUE))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < MAX_WDS_ENTRY); macptr = rstrtok(NULL,";"), i++)
+ {
+ KeyIdx = (UCHAR) simple_strtol(macptr, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAd->MulTestTab.WdsEntry[i].KeyIdx = (UCHAR) (KeyIdx - 1);
+ else
+ pAd->MulTestTab.WdsEntry[i].KeyIdx = 0;
+
+ if ((pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11Encryption2Enabled)
+ || (pAd->MulTestTab.WdsEntry[i].WepStatus == Ndis802_11Encryption3Enabled))
+ pAd->MulTestTab.WdsEntry[i].KeyIdx = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF/wds%d - WdsDefaultKeyID(0~3)=%d\n", i, pAd->MulTestTab.WdsEntry[i].KeyIdx));
+ }
+ }
+}
+
+
+#ifdef SINGLE_SKU_V2
+NDIS_STATUS RTMPSetSingleSKUParameters(
+ IN RTMP_ADAPTER *pAd)
+{
+ PSTRING buffer;
+ PSTRING readline, token;
+ RTMP_OS_FD srcf;
+ INT retval;
+ PSTRING ptr;
+ int index, i;
+ CH_POWER *StartCh = NULL;
+ UCHAR MaxPwr;
+ UCHAR channel, *temp;
+ RTMP_OS_FS_INFO osFSInfo;
+
+ initList(&pAd->SingleSkuPwrList);
+
+ /* init*/
+ os_alloc_mem(NULL, (UCHAR **)&buffer, MAX_INI_BUFFER_SIZE);
+ if (buffer == NULL)
+ return FALSE;
+
+ RtmpOSFSInfoChange(&osFSInfo, TRUE);
+ /* open card information file*/
+ srcf = RtmpOSFileOpen(SINGLE_SKU_TABLE_FILE_NAME, O_RDONLY, 0);
+ if (IS_FILE_OPEN_ERR(srcf))
+ {
+ /* card information file does not exist */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("--> Error opening %s\n", SINGLE_SKU_TABLE_FILE_NAME));
+ goto free_resource;
+ }
+
+#ifdef RTMP_INTERNAL_TX_ALC
+ if (pAd->TxPowerCtrl.bInternalTxALC != TRUE)
+#endif /* RTMP_INTERNAL_TX_ALC */
+ MT7601_InitPAModeTable(pAd);
+
+ /* card information file exists so reading the card information */
+ NdisZeroMemory(buffer, 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", SINGLE_SKU_TABLE_FILE_NAME, -retval));
+ }
+ else
+ {
+
+ for ( readline = ptr = buffer, index=0; (ptr = strchr(readline, '\n')) != NULL; readline = ptr + 1, index++ )
+ {
+ *ptr = '\0';
+
+ if ( readline[0] == '#' )
+ continue;
+
+ if ( !strncmp(readline, "ch", 2) )
+ {
+
+ CH_POWER *pwr;
+
+ os_alloc_mem(NULL, (UCHAR **)&pwr, sizeof(*pwr));
+ NdisZeroMemory(pwr, sizeof(*pwr));
+
+ token= rstrtok(readline +2 ," ");
+ channel = simple_strtol(token, 0, 10);
+ pwr->StartChannel = channel;
+
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_CCK_LENGTH ; i++ )
+ {
+ token = rstrtok(NULL ," ");
+ if ( token == NULL )
+ break;
+ pwr->PwrCCK[i] = simple_strtol(token, 0, 10) * 2;
+ }
+
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_OFDM_LENGTH ; i++ )
+ {
+ token = rstrtok(NULL ," ");
+ if ( token == NULL )
+ break;
+ pwr->PwrOFDM[i] = simple_strtol(token, 0, 10) *2;
+ }
+
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ token = rstrtok(NULL ," ");
+ if ( token == NULL )
+ break;
+ pwr->PwrHT20[i] = simple_strtol(token, 0, 10) *2;
+ }
+
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ token = rstrtok(NULL ," ");
+ if ( token == NULL )
+ break;
+ pwr->PwrHT40[i] = simple_strtol(token, 0, 10) *2;
+ }
+
+
+ if ( StartCh == NULL )
+ {
+ StartCh = pwr;
+ insertTailList(&pAd->SingleSkuPwrList, (PLIST_ENTRY)pwr);
+ }
+ else
+ {
+ BOOLEAN isSame = TRUE;
+
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_CCK_LENGTH ; i++ )
+ {
+ if ( StartCh->PwrCCK[i] != pwr->PwrCCK[i] )
+ {
+ isSame = FALSE;
+ break;
+ }
+ }
+
+ if ( isSame == TRUE )
+ {
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_OFDM_LENGTH ; i++ )
+ {
+ if ( StartCh->PwrOFDM[i] != pwr->PwrOFDM[i] )
+ {
+ isSame = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ( isSame == TRUE )
+ {
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ if ( StartCh->PwrHT20[i] != pwr->PwrHT20[i] )
+ {
+ isSame = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ( isSame == TRUE )
+ {
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ if ( StartCh->PwrHT40[i] != pwr->PwrHT40[i] )
+ {
+ isSame = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ( isSame == TRUE )
+ {
+ os_free_mem(NULL, pwr);
+ }
+ else
+ {
+ StartCh = pwr;
+ insertTailList(&pAd->SingleSkuPwrList, (PLIST_ENTRY)StartCh);
+ pwr = NULL;
+ }
+
+
+ }
+
+
+ StartCh->num ++;
+ os_alloc_mem(pAd, (PUCHAR *)&temp, StartCh->num);
+ if ( StartCh->Channel != NULL )
+ {
+ NdisMoveMemory(temp, StartCh->Channel, StartCh->num-1);
+ os_free_mem(pAd, StartCh->Channel);
+ }
+ StartCh->Channel = temp;
+ StartCh->Channel[StartCh->num-1] = channel;
+ }
+ }
+
+
+ }
+
+ {
+ CH_POWER *ch;
+ ch = pAd->SingleSkuPwrList.pHead;
+ while ( ch )
+ {
+ int i;
+ DBGPRINT(RT_DEBUG_TRACE,("start ch = %d, ch->num = %d\n", ch->StartChannel, ch->num));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel: "));
+ for ( i = 0 ; i < ch->num ; i++ )
+ DBGPRINT(RT_DEBUG_TRACE,("%d ", ch->Channel[i]));
+ DBGPRINT(RT_DEBUG_TRACE,("\n"));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CCK: "));
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_CCK_LENGTH ; i++ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("%d ", ch->PwrCCK[i]));
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("\n"));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("OFDM: "));
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_OFDM_LENGTH ; i++ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("%d ", ch->PwrOFDM[i]));
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("\n"));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT20: "));
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%d ", ch->PwrHT20[i]));
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("\n"));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT40: "));
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("%d ", ch->PwrHT40[i]));
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("\n"));
+
+ ch = ch->pNext;
+ }
+ }
+
+ /* close file*/
+ retval = RtmpOSFileClose(srcf);
+
+free_resource:
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+
+ os_free_mem(NULL, buffer);
+
+}
+
+
+UCHAR GetSkuChannelBasePwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel)
+{
+ CH_POWER *ch;
+ UCHAR start_ch;
+ UCHAR base_pwr = pAd->DefaultTargetPwr;
+ UINT8 i, j;
+
+ ch = pAd->SingleSkuPwrList.pHead;
+ while (ch )
+ {
+ start_ch = ch->StartChannel;
+
+ if ( channel >= start_ch )
+ {
+ for ( j = 0; j < ch->num; j++ )
+ {
+ if ( channel == ch->Channel[j] )
+ {
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_CCK_LENGTH ; i++ )
+ {
+ if ( base_pwr > ch->PwrCCK[i] )
+ base_pwr = ch->PwrCCK[i];
+ }
+
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_OFDM_LENGTH ; i++ )
+ {
+ if ( base_pwr > ch->PwrOFDM[i] )
+ base_pwr = ch->PwrOFDM[i];
+ }
+
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ if ( base_pwr > ch->PwrHT20[i] )
+ base_pwr = ch->PwrHT20[i];
+ }
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ for ( i= 0 ; i < SINGLE_SKU_TABLE_HT_LENGTH ; i++ )
+ {
+ if ( ch->PwrHT40[i] == 0 )
+ break;
+
+ if ( base_pwr > ch->PwrHT40[i] )
+ base_pwr = ch->PwrHT40[i];
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ ch = ch->pNext;
+ }
+
+ return base_pwr;
+
+}
+
+#define SKU_PHYMODE_CCK_1M_2M 0
+#define SKU_PHYMODE_CCK_5M_11M 1
+#define SKU_PHYMODE_OFDM_6M_9M 2
+#define SKU_PHYMODE_OFDM_12M_18M 3
+#define SKU_PHYMODE_OFDM_24M_36M 4
+#define SKU_PHYMODE_OFDM_48M_54M 5
+#define SKU_PHYMODE_HT_MCS0_MCS1 6
+#define SKU_PHYMODE_HT_MCS2_MCS3 7
+#define SKU_PHYMODE_HT_MCS4_MCS5 8
+#define SKU_PHYMODE_HT_MCS6_MCS7 9
+#define SKU_PHYMODE_HT_MCS8_MCS9 10
+#define SKU_PHYMODE_HT_MCS10_MCS11 11
+#define SKU_PHYMODE_HT_MCS12_MCS13 12
+#define SKU_PHYMODE_HT_MCS14_MCS15 13
+#define SKU_PHYMODE_STBC_MCS0_MCS1 14
+#define SKU_PHYMODE_STBC_MCS2_MCS3 15
+#define SKU_PHYMODE_STBC_MCS4_MCS5 16
+#define SKU_PHYMODE_STBC_MCS6_MCS7 17
+
+
+VOID InitSkuRateDiffTable(
+ IN PRTMP_ADAPTER pAd )
+{
+ USHORT i, value;
+ CHAR BasePwr, Pwr;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + 4, value);
+ BasePwr = (value >> 8) & 0xFF;
+ BasePwr = (BasePwr > 0x1F ) ? BasePwr - 0x40: BasePwr;
+
+ for ( i = 0 ; i < 9; i++ )
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*2, value);
+ Pwr = value & 0xFF ;
+ Pwr = (Pwr > 0x1F ) ? Pwr - 0x40: Pwr;
+ pAd->SingleSkuRatePwrDiff[i *2] = Pwr - BasePwr;
+ Pwr = (value >> 8) & 0xFF;
+ Pwr = (Pwr > 0x1F ) ? Pwr - 0x40: Pwr;
+ pAd->SingleSkuRatePwrDiff[i *2 + 1] = Pwr - BasePwr;
+ }
+}
+
+INT32 GetSkuPAModePwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PAMode)
+{
+ INT32 pa_mode_pwr = 0;
+
+ switch ( PAMode )
+ {
+ case SKU_PHYMODE_CCK_1M_2M:
+ pa_mode_pwr = RF_PA_MODE_CCK_1M;
+ break;
+ case SKU_PHYMODE_CCK_5M_11M:
+ pa_mode_pwr = RF_PA_MODE_CCK_5M;
+ break;
+ case SKU_PHYMODE_OFDM_6M_9M:
+ pa_mode_pwr = RF_PA_MODE_OFDM_6M;
+ break;
+ case SKU_PHYMODE_OFDM_12M_18M:
+ pa_mode_pwr = RF_PA_MODE_OFDM_12M;
+ break;
+ case SKU_PHYMODE_OFDM_24M_36M:
+ pa_mode_pwr = RF_PA_MODE_OFDM_24M;
+ break;
+ case SKU_PHYMODE_OFDM_48M_54M:
+ pa_mode_pwr = RF_PA_MODE_OFDM_48M;
+ break;
+ case SKU_PHYMODE_HT_MCS0_MCS1:
+ case SKU_PHYMODE_STBC_MCS0_MCS1:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS0;
+ break;
+ case SKU_PHYMODE_HT_MCS2_MCS3:
+ case SKU_PHYMODE_STBC_MCS2_MCS3:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS2;
+ break;
+ case SKU_PHYMODE_HT_MCS4_MCS5:
+ case SKU_PHYMODE_STBC_MCS4_MCS5:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS4;
+ break;
+ case SKU_PHYMODE_HT_MCS6_MCS7:
+ case SKU_PHYMODE_STBC_MCS6_MCS7:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS6;
+ break;
+ case SKU_PHYMODE_HT_MCS8_MCS9:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS8;
+ break;
+ case SKU_PHYMODE_HT_MCS10_MCS11:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS10;
+ break;
+ case SKU_PHYMODE_HT_MCS12_MCS13:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS12;
+ break;
+ case SKU_PHYMODE_HT_MCS14_MCS15:
+ pa_mode_pwr = RF_PA_MODE_HT_MCS14;
+ break;
+ default:
+ break;
+ }
+
+ return pa_mode_pwr;
+}
+
+
+UCHAR GetSkuRatePwr(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR phymode,
+ IN UCHAR channel,
+ IN UCHAR bw)
+{
+ UINT8 i;
+ CH_POWER *ch;
+ UCHAR start_ch;
+ UCHAR rate_pwr = pAd->DefaultTargetPwr;
+ UCHAR max_pwr;
+ INT32 pwr_diff;
+
+ ch = pAd->SingleSkuPwrList.pHead;
+ while (ch )
+ {
+ start_ch = ch->StartChannel;
+
+ if ( channel >= start_ch )
+ {
+ for ( i = 0; i < ch->num; i++ )
+ {
+ if ( channel == ch->Channel[i] )
+ {
+ switch ( phymode )
+ {
+ case SKU_PHYMODE_CCK_1M_2M:
+ rate_pwr = ch->PwrCCK[0];
+ break;
+ case SKU_PHYMODE_CCK_5M_11M:
+ rate_pwr = ch->PwrCCK[2];
+ break;
+ case SKU_PHYMODE_OFDM_6M_9M:
+ rate_pwr = ch->PwrOFDM[0];
+ break;
+ case SKU_PHYMODE_OFDM_12M_18M:
+ rate_pwr = ch->PwrOFDM[2];
+ break;
+ case SKU_PHYMODE_OFDM_24M_36M:
+ rate_pwr = ch->PwrOFDM[4];
+ break;
+ case SKU_PHYMODE_OFDM_48M_54M:
+ rate_pwr = ch->PwrOFDM[6];
+ break;
+ case SKU_PHYMODE_HT_MCS0_MCS1:
+ case SKU_PHYMODE_STBC_MCS0_MCS1:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[0];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[0];
+ break;
+ case SKU_PHYMODE_HT_MCS2_MCS3:
+ case SKU_PHYMODE_STBC_MCS2_MCS3:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[2];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[2];
+ break;
+ case SKU_PHYMODE_HT_MCS4_MCS5:
+ case SKU_PHYMODE_STBC_MCS4_MCS5:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[4];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[4];
+ break;
+ case SKU_PHYMODE_HT_MCS6_MCS7:
+ case SKU_PHYMODE_STBC_MCS6_MCS7:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[6];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[6];
+ break;
+ case SKU_PHYMODE_HT_MCS8_MCS9:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[8];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[8];
+ break;
+ case SKU_PHYMODE_HT_MCS10_MCS11:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[10];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[10];
+ break;
+ case SKU_PHYMODE_HT_MCS12_MCS13:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[12];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[12];
+ break;
+ case SKU_PHYMODE_HT_MCS14_MCS15:
+ if ( bw == BW_20 )
+ rate_pwr = ch->PwrHT20[14];
+ else if ( bw == BW_40 )
+ rate_pwr = ch->PwrHT40[14];
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ ch = ch->pNext;
+ }
+
+ pwr_diff = GetSkuPAModePwr(pAd, phymode) + (pAd->SingleSkuRatePwrDiff[phymode] << 12) + 2048;
+ pwr_diff = pwr_diff >> 12;
+ max_pwr = pAd->DefaultTargetPwr + pwr_diff;
+
+ if ( rate_pwr > max_pwr )
+ rate_pwr = max_pwr;
+
+ return rate_pwr;
+
+}
+
+
+VOID UpdateSkuRatePwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel,
+ IN UCHAR bw,
+ IN CHAR base_pwr)
+{
+ INT32 sku_rate_pwr;
+ INT32 rate_pwr;
+ INT32 mcs_digital_pwr, pa_mode_pwr, diff_pwr;
+ UINT32 data, Adata, Gdata;
+ UCHAR BBPR4, BBPR178;
+ UCHAR i;
+ CHAR rate_table[18];
+
+ printk("channel = %d, bw = %d\n", channel, bw);
+
+ for ( i = 0 ; i < 18; i++ )
+ {
+ sku_rate_pwr = GetSkuRatePwr(pAd, i, channel, bw);
+ printk("sku_rate_pwr = %d", sku_rate_pwr);
+ sku_rate_pwr = sku_rate_pwr << 12; // sku_rate_power * 4096
+ printk("\tsku_rate_pwr = %d\n", sku_rate_pwr);
+
+ if ( i < SKU_PHYMODE_CCK_5M_11M )
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPR4);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R178, &BBPR178);
+ if ( BBPR4 & 0x20 )
+ {
+ if ( BBPR178 == 0 )
+ {
+ mcs_digital_pwr = 9830; // 8192 * 1.2
+ }
+ else
+ {
+ mcs_digital_pwr = 18022; // 8192 * 2.2
+ }
+ }
+ else
+ {
+ if ( BBPR178 == 0 )
+ {
+ mcs_digital_pwr = 24576; // 8192 * 3
+ }
+ else
+ {
+ mcs_digital_pwr = 819; /// 8192 * 0.1
+ }
+
+ }
+ }
+ else
+ {
+ mcs_digital_pwr = 0;
+ }
+
+ pa_mode_pwr = GetSkuPAModePwr(pAd, i);
+
+ printk("base_pwr = %d", base_pwr);
+ rate_pwr = base_pwr << 12;
+ printk("\t base_pwr = %d\n", rate_pwr);
+ printk("mcs_digital_pwr = %d\n", mcs_digital_pwr);
+ printk("pa_mode_pwr = %d\n", pa_mode_pwr);
+ rate_pwr = rate_pwr + mcs_digital_pwr + pa_mode_pwr;
+ printk("rate_pwr = %d\n", rate_pwr);
+ diff_pwr = sku_rate_pwr - rate_pwr;
+ printk("diff_pwr = %d", diff_pwr);
+ diff_pwr = diff_pwr >> 12;
+ printk("\tdiff_pwr = %d\n", diff_pwr);
+
+ rate_table[i] = diff_pwr -1;
+ }
+
+ for ( i = 0 ; i < 5; i++ )
+ {
+ data = 0;
+ Adata = 0;
+ Gdata = 0;
+
+ data = (rate_table[i*4] & 0x3F )+ ((rate_table[i*4 + 1] &0x3F) << 8);
+ Adata = ((rate_table[i*4] + pAd->chipCap.Apwrdelta ) & 0x3F )+ ( ((rate_table[i*4 + 1] + pAd->chipCap.Apwrdelta) & 0x3F) << 8);
+ Gdata = ((rate_table[i*4] + pAd->chipCap.Gpwrdelta ) & 0x3F ) + ( ((rate_table[i*4 + 1] + pAd->chipCap.Gpwrdelta) & 0x3F) << 8);
+
+ if ( i != 4 )
+ {
+ data |= ((rate_table[i*4 + 2] &0x3F) << 16 )+ ((rate_table[i*4 + 3] & 0x3F) << 24);
+ Adata |= ( ((rate_table[i*4 + 2] + pAd->chipCap.Apwrdelta ) & 0x3F) << 16) + ( ((rate_table[i*4 + 3] + pAd->chipCap.Apwrdelta) & 0x3F) << 24);
+ Gdata |= ( ((rate_table[i*4 + 2] + pAd->chipCap.Gpwrdelta ) & 0x3F) << 16) + ( ((rate_table[i*4 + 3] + pAd->chipCap.Gpwrdelta) & 0x3F) << 24);
+ }
+
+ /* For 20M/40M Power Delta issue */
+ pAd->Tx20MPwrCfgABand[i] = data;
+ pAd->Tx20MPwrCfgGBand[i] = data;
+ pAd->Tx40MPwrCfgABand[i] = Adata;
+ pAd->Tx40MPwrCfgGBand[i] = Gdata;
+
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%08x, Adata = %08x, Gdata = %08x \n", data, Adata, Gdata));
+ }
+
+ /* Extra set MAC registers to compensate Tx power if any */
+ RTMP_CHIP_ASIC_EXTRA_POWER_OVER_MAC(pAd);
+
+}
+
+
+#endif /* SINGLE_SKU_V2 */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_radar.c b/cleopatre/devkit/mt7601udrv/common/cmm_radar.c
new file mode 100644
index 0000000000..c13f1e07e3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_radar.c
@@ -0,0 +1,329 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_radar.c
+
+ Abstract:
+ CS/DFS common functions.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+#include "rt_config.h"
+
+/*----- 802.11H -----*/
+
+/* Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()*/
+/* Before switch channel, driver needs doing channel switch announcement.*/
+VOID RadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd)
+{
+ /* need to check channel availability, after switch channel*/
+ if (pAd->Dot11_H.RDMode != RD_SILENCE_MODE)
+ return;
+
+ /* channel availability check time is 60sec, use 65 for assurance*/
+ if (pAd->Dot11_H.RDCount++ > pAd->Dot11_H.ChMovingTime)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
+ AsicEnableBssSync(pAd);
+ pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
+ return;
+ }
+}
+
+/*
+ ========================================================================
+
+ 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; i<pAd->ChannelListNum; i++)
+ {
+ if (Ch == pAd->ChannelList[i].Channel)
+ {
+ result = pAd->ChannelList[i].DfsReq;
+ break;
+ }
+ }
+
+ return result;
+}
+
+ULONG JapRadarType(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+
+ if (pAd->CommonCfg.RDDurRegion != JAP)
+ {
+ return pAd->CommonCfg.RDDurRegion;
+ }
+
+ for (i=0; i<15; i++)
+ {
+ if (pAd->CommonCfg.Channel == Channel[i])
+ {
+ break;
+ }
+ }
+
+ if (i < 4)
+ return JAP_W53;
+ else if (i < 15)
+ return JAP_W56;
+ else
+ return JAP; /* W52*/
+
+}
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ Channel switching count down process upon radar detection
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ ========================================================================
+*/
+VOID ChannelSwitchingCountDownProc(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():Channel Switching...(%d/%d)\n",
+ __FUNCTION__, pAd->Dot11_H.CSCount, pAd->Dot11_H.CSPeriod));
+
+ pAd->Dot11_H.CSCount++;
+ if (pAd->Dot11_H.CSCount >= pAd->Dot11_H.CSPeriod)
+ {
+#ifdef DFS_SUPPORT
+ pAd->CommonCfg.RadarDetect.DFSAPRestart = 1;
+ schedule_dfs_task(pAd);
+#else
+ APStop(pAd);
+ APStartUp(pAd);
+#endif /* !DFS_SUPPORT */
+ }
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+/*
+ ==========================================================================
+ Description:
+ Set channel switch Period
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_CSPeriod_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->Dot11_H.CSPeriod = (USHORT) simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CSPeriod_Proc::(CSPeriod=%d)\n", pAd->Dot11_H.CSPeriod));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ change channel moving time for DFS testing.
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 set ChMovTime=[value]
+ ==========================================================================
+*/
+INT Set_ChMovingTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT8 Value;
+
+ Value = (UINT8) simple_strtol(arg, 0, 10);
+
+ pAd->Dot11_H.ChMovingTime = Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: %d\n", __FUNCTION__,
+ pAd->Dot11_H.ChMovingTime));
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Reset channel block status.
+ Arguments:
+ pAd Pointer to our adapter
+ arg Not used
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 set ChMovTime=[value]
+ ==========================================================================
+*/
+INT Set_BlockChReset_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Reset channel block status.\n", __FUNCTION__));
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ pAd->ChannelList[i].RemainingTimeForUse = 0;
+
+ return TRUE;
+}
+
+
+#if defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT)
+
+INT Set_RadarShow_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+#ifdef DFS_SUPPORT
+ int i;
+ UINT8 idx;
+ PRADAR_DETECT_STRUCT pRadarDetect = &pAd->CommonCfg.RadarDetect;
+ PDFS_PROGRAM_PARAM pDfsProgramParam = &pRadarDetect->DfsProgramParam;
+ PDFS_SW_DETECT_PARAM pDfsSwParam = &pRadarDetect->DfsSwParam;
+
+ printk("DFSUseTasklet = %d\n", pRadarDetect->use_tasklet);
+ printk("McuRadarDebug = %x\n", (unsigned int)pRadarDetect->McuRadarDebug);
+ printk("PollTime = %d\n", pRadarDetect->PollTime);
+ printk("ChEnable = %d (0x%x)\n", pDfsProgramParam->ChEnable, pDfsProgramParam->ChEnable);
+ printk("DeltaDelay = %d\n", pDfsProgramParam->DeltaDelay);
+ printk("Fcc5Thrd = %d\n", pDfsSwParam->fcc_5_threshold);
+ printk("PeriodErr = %d\n", pDfsSwParam->dfs_period_err);
+ printk("MaxPeriod = %d\n", (unsigned int)pDfsSwParam->dfs_max_period);
+ printk("Ch0LErr = %d\n", pDfsSwParam->dfs_width_ch0_err_L);
+ printk("Ch0HErr = %d\n", pDfsSwParam->dfs_width_ch0_err_H);
+ printk("Ch1Shift = %d\n", pDfsSwParam->dfs_width_diff_ch1_Shift);
+ printk("Ch2Shift = %d\n", pDfsSwParam->dfs_width_diff_ch2_Shift);
+ /*printk("CeSwCheck = %d\n", pAd->CommonCfg.ce_sw_check);*/
+ /*printk("CEStagCheck = %d\n", pAd->CommonCfg.ce_staggered_check);*/
+ /*printk("HWDFSDisabled = %d\n", pAd->CommonCfg.hw_dfs_disabled);*/
+ printk("DfsRssiHigh = %d\n", pRadarDetect->DfsRssiHigh);
+ printk("DfsRssiLow = %d\n", pRadarDetect->DfsRssiLow);
+ printk("DfsSwDisable = %u\n", pRadarDetect->bDfsSwDisable);
+ printk("CheckLoop = %d\n", pDfsSwParam->dfs_check_loop);
+ printk("DeclareThres = %d\n", pDfsSwParam->dfs_declare_thres);
+ for (i =0; i < pRadarDetect->fdf_num; i++)
+ {
+ printk("ChBusyThrd[%d] = %d\n", i, pRadarDetect->ch_busy_threshold[i]);
+ printk("RssiThrd[%d] = %d\n", i, pRadarDetect->rssi_threshold[i]);
+ }
+ for (idx=0; idx < pAd->chipCap.DfsEngineNum; idx++)
+ printk("sw_idx[%u] = %u\n", idx, pDfsSwParam->sw_idx[idx]);
+ for (idx=0; idx < pAd->chipCap.DfsEngineNum; idx++)
+ printk("hw_idx[%u] = %u\n", idx, pDfsSwParam->hw_idx[idx]);
+#ifdef DFS_DEBUG
+ printk("Total[0] = %lu\n", pDfsSwParam->TotalEntries[0]);
+ printk("Total[1] = %lu\n", pDfsSwParam->TotalEntries[1]);
+ printk("Total[2] = %lu\n", pDfsSwParam->TotalEntries[2]);
+ printk("Total[3] = %lu\n", pDfsSwParam->TotalEntries[3]);
+
+ pDfsSwParam->TotalEntries[0] = pDfsSwParam->TotalEntries[1] = pDfsSwParam->TotalEntries[2] = pDfsSwParam->TotalEntries[3] = 0;
+
+ printk("T_Matched_2 = %lu\n", pDfsSwParam->T_Matched_2);
+ printk("T_Matched_3 = %lu\n", pDfsSwParam->T_Matched_3);
+ printk("T_Matched_4 = %lu\n", pDfsSwParam->T_Matched_4);
+ printk("T_Matched_5 = %lu\n", pDfsSwParam->T_Matched_5);
+#endif /* DFS_DEBUG */
+
+ printk("pAd->Dot11_H.ChMovingTime = %d\n", pAd->Dot11_H.ChMovingTime);
+ printk("pAd->Dot11_H.RDMode = %d\n", pAd->Dot11_H.RDMode);
+#endif /* DFS_SUPPORT */
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ printk("pAd->CommonCfg.CarrierDetect.CD_State = %d\n", pAd->CommonCfg.CarrierDetect.CD_State);
+ printk("pAd->CommonCfg.CarrierDetect.criteria = %d\n", pAd->CommonCfg.CarrierDetect.criteria);
+ printk("pAd->CommonCfg.CarrierDetect.Delta = %d\n", pAd->CommonCfg.CarrierDetect.delta);
+ printk("pAd->CommonCfg.CarrierDetect.DivFlag = %d\n", pAd->CommonCfg.CarrierDetect.div_flag);
+ printk("pAd->CommonCfg.CarrierDetect.Threshold = %d(0x%x)\n", pAd->CommonCfg.CarrierDetect.threshold, pAd->CommonCfg.CarrierDetect.threshold);
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Control CCK_MRC Status
+ Arguments:
+ pAd Pointer to our adapter
+ Return Value:
+
+ ========================================================================
+*/
+VOID CckMrcStatusCtrl(IN PRTMP_ADAPTER pAd)
+{
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Enhance DFS/CS when using GLRT.
+ Arguments:
+ pAd Pointer to our adapter
+ Return Value:
+
+ ========================================================================
+*/
+VOID RadarGLRTCompensate(IN PRTMP_ADAPTER pAd)
+{
+}
+#endif /*defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT) */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_sanity.c b/cleopatre/devkit/mt7601udrv/common/cmm_sanity.c
new file mode 100644
index 0000000000..86053effc3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_sanity.c
@@ -0,0 +1,2162 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ sanity.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 add WMM support
+*/
+#include "rt_config.h"
+
+extern UCHAR CISCO_OUI[];
+
+extern UCHAR WPA_OUI[];
+extern UCHAR RSN_OUI[];
+extern UCHAR WME_INFO_ELEM[];
+extern UCHAR WME_PARM_ELEM[];
+extern UCHAR RALINK_OUI[];
+extern UCHAR BROADCOM_OUI[];
+extern UCHAR WPS_OUI[];
+
+
+
+typedef struct wsc_ie_probreq_data
+{
+ UCHAR ssid[32];
+ UCHAR macAddr[6];
+ UCHAR data[2];
+} WSC_IE_PROBREQ_DATA;
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeAddBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2)
+{
+ PMLME_ADDBA_REQ_STRUCT pInfo;
+
+ pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
+
+ if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
+ return FALSE;
+ }
+
+ /*
+ if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
+ return FALSE;
+ }
+ */
+
+ if ((pInfo->pAddr[0]&0x01) == 0x01)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeDelBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen)
+{
+ MLME_DELBA_REQ_STRUCT *pInfo;
+ pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
+
+ if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->TID & 0xf0))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
+ return FALSE;
+ }
+
+ if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN PeerAddBAReqActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PFRAME_ADDBA_REQ pAddFrame;
+ pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
+ if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+ /* we support immediate BA.*/
+#ifdef UNALIGNMENT_SUPPORT
+ {
+ BA_PARM tmpBaParm;
+
+ NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM));
+ *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm));
+ NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM));
+ }
+#else
+ *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+#endif
+ pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
+ pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
+
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+
+ 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;
+ }
+
+ 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;
+}
+
+
+BOOLEAN PeerBeaconAndProbeRspSanity_Old(
+ 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,
+ 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;
+ PFRAME_802_11 pFrame;
+ PEID_STRUCT pEid;
+ UCHAR SubType;
+ UCHAR Sanity;
+ /*UCHAR ECWMin, ECWMax;*/
+ /*MAC_CSR9_STRUC Csr9;*/
+ ULONG Length = 0;
+ UCHAR *pPeerWscIe = NULL;
+ INT PeerWscIeLen = 0;
+ UCHAR LatchRfChannel = 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;
+
+
+ os_alloc_mem(NULL, &pPeerWscIe, 512);
+ /* 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*/
+ *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, ("%s() - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
+ __FUNCTION__, (*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, ("%s() - wrong IE_SSID (len=%d)\n", __FUNCTION__, pEid->Len));
+ goto SanityCheck;
+ }
+ 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, ("%s() - wrong IE_SUPP_RATES (len=%d)\n",__FUNCTION__, pEid->Len));
+ goto SanityCheck;
+ }
+ 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 */
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s() - wrong IE_HT_CAP. pEid->Len = %d\n", __FUNCTION__, 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));
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s() - wrong IE_ADD_HT. \n", __FUNCTION__));
+ }
+
+ break;
+ case IE_SECONDARY_CH_OFFSET:
+ if (pEid->Len == 1)
+ {
+ *NewExtChannelOffset = pEid->Octet[0];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s() - wrong IE_SECONDARY_CH_OFFSET. \n", __FUNCTION__));
+ }
+
+ break;
+ case IE_FH_PARM:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(IE_FH_PARM) \n", __FUNCTION__));
+ break;
+
+ case IE_DS_PARM:
+ if(pEid->Len == 1)
+ {
+ *pChannel = *pEid->Octet;
+ Sanity |= 0x4;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() - wrong IE_DS_PARM (len=%d)\n",__FUNCTION__,pEid->Len));
+ goto SanityCheck;
+ }
+ 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, ("%s() - wrong IE_CF_PARM\n", __FUNCTION__));
+ if (pPeerWscIe)
+ os_free_mem(NULL, pPeerWscIe);
+ return FALSE;
+ }
+ break;
+
+ case IE_IBSS_PARM:
+ if(pEid->Len == 2)
+ {
+ NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() - wrong IE_IBSS_PARM\n", __FUNCTION__));
+ if (pPeerWscIe)
+ os_free_mem(NULL, pPeerWscIe);
+ return FALSE;
+ }
+ break;
+
+ 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))
+ {
+ 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.*/
+ }
+ 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)
+ )
+ {
+ if (PeerWscIeLen >= 512)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: PeerWscIeLen = %d (>= 512)\n", __FUNCTION__, PeerWscIeLen));
+ if (pPeerWscIe && (PeerWscIeLen < 512))
+ {
+ NdisMoveMemory(pPeerWscIe+PeerWscIeLen, pEid->Octet+4, pEid->Len-4);
+ PeerWscIeLen += (pEid->Len - 4);
+ }
+
+
+
+ }
+
+
+ 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 WAPI_SUPPORT
+ /* WAPI information element*/
+ case IE_WAPI:
+ if (RTMPEqualMemory(pEid->Octet + 4, WAPI_OUI, 3))
+ {
+ /* Copy to pVIE*/
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+ break;
+#endif /* WAPI_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)
+ {
+ UCHAR MaxSize;
+ UCHAR MySize = sizeof(EXT_CAP_INFO_ELEMENT);
+
+ MaxSize = min(pEid->Len, MySize);
+
+ NdisMoveMemory(pExtCapInfo,&pEid->Octet[0], MaxSize);
+ }
+ break;
+ default:
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len; /* Eid[1] + Len[1]+ content[Len]*/
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ LatchRfChannel = MsgChannel;
+
+ if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
+ {
+ if (CtrlChannel != 0)
+ *pChannel = CtrlChannel;
+ else
+ *pChannel = LatchRfChannel;
+ Sanity |= 0x4;
+ }
+
+ if (pPeerWscIe && (PeerWscIeLen > 0) && (PeerWscIeLen < 512))
+ {
+ UCHAR WscIe[] = {0xdd, 0x00, 0x00, 0x50, 0xF2, 0x04};
+ Ptr = (PUCHAR) pVIE;
+ WscIe[1] = PeerWscIeLen + 4;
+ NdisMoveMemory(Ptr + *LengthVIE, WscIe, 6);
+ NdisMoveMemory(Ptr + *LengthVIE + 6, pPeerWscIe, PeerWscIeLen);
+ *LengthVIE += (PeerWscIeLen + 6);
+ }
+
+
+SanityCheck:
+ if (pPeerWscIe)
+ os_free_mem(NULL, pPeerWscIe);
+
+ if (Sanity != 0x7)
+ {
+ DBGPRINT(RT_DEBUG_LOUD, ("%s() - missing field, Sanity=0x%02x\n", __FUNCTION__, Sanity));
+ return FALSE;
+ }
+ else
+ {
+ 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 BCN_IE_LIST *ie_list,
+ OUT USHORT *LengthVIE,
+ OUT PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ UCHAR *Ptr;
+ PFRAME_802_11 pFrame;
+ PEID_STRUCT pEid;
+ UCHAR SubType;
+ UCHAR Sanity;
+ ULONG Length = 0;
+ UCHAR *pPeerWscIe = NULL;
+ INT PeerWscIeLen = 0;
+ UCHAR LatchRfChannel = 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;
+
+
+
+ os_alloc_mem(NULL, &pPeerWscIe, 512);
+ Sanity = 0; /* Add for 3 necessary EID field check*/
+
+ ie_list->AironetCellPowerLimit = 0xFF; /* Default of AironetCellPowerLimit is 0xFF*/
+ ie_list->NewExtChannelOffset = 0xff; /*Default 0xff means no such IE*/
+ *LengthVIE = 0; /* Set the length of VIE to init value 0*/
+
+ pFrame = (PFRAME_802_11)Msg;
+
+ /* get subtype from header*/
+ SubType = (UCHAR)pFrame->Hdr.FC.SubType;
+
+ /* get Addr2 and BSSID from header*/
+ COPY_MAC_ADDR(&ie_list->Addr2[0], pFrame->Hdr.Addr2);
+ COPY_MAC_ADDR(&ie_list->Bssid[0], pFrame->Hdr.Addr3);
+
+ Ptr = pFrame->Octet;
+ Length += LENGTH_802_11;
+
+ /* get timestamp from payload and advance the pointer*/
+ NdisMoveMemory(&ie_list->TimeStamp, Ptr, TIMESTAMP_LEN);
+
+ ie_list->TimeStamp.u.LowPart = cpu2le32(ie_list->TimeStamp.u.LowPart);
+ ie_list->TimeStamp.u.HighPart = cpu2le32(ie_list->TimeStamp.u.HighPart);
+
+ Ptr += TIMESTAMP_LEN;
+ Length += TIMESTAMP_LEN;
+
+ /* get beacon interval from payload and advance the pointer*/
+ NdisMoveMemory(&ie_list->BeaconPeriod, Ptr, 2);
+ Ptr += 2;
+ Length += 2;
+
+ /* get capability info from payload and advance the pointer*/
+ NdisMoveMemory(&ie_list->CapabilityInfo, Ptr, 2);
+ Ptr += 2;
+ Length += 2;
+
+ if (CAP_IS_ESS_ON(ie_list->CapabilityInfo))
+ ie_list->BssType = BSS_INFRA;
+ else
+ ie_list->BssType = 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, ("%s() - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
+ __FUNCTION__, (*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(&ie_list->Ssid[0], pEid->Octet, pEid->Len);
+ ie_list->SsidLen = pEid->Len;
+ Sanity |= 0x1;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() - wrong IE_SSID (len=%d)\n",__FUNCTION__,pEid->Len));
+ goto SanityCheck;
+ }
+ break;
+
+ case IE_SUPP_RATES:
+ if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ Sanity |= 0x2;
+ NdisMoveMemory(&ie_list->SupRate[0], pEid->Octet, pEid->Len);
+ ie_list->SupRateLen = 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, ("%s() - wrong IE_SUPP_RATES (len=%d)\n",__FUNCTION__,pEid->Len));
+ goto SanityCheck;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (pEid->Len >= SIZE_HT_CAP_IE) /*Note: allow extension.!!*/
+ {
+ NdisMoveMemory(&ie_list->HtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
+ ie_list->HtCapabilityLen = SIZE_HT_CAP_IE; /* Nnow we only support 26 bytes.*/
+
+ *(USHORT *)(&ie_list->HtCapability.HtCapInfo) = cpu2le16(*(USHORT *)(&ie_list->HtCapability.HtCapInfo));
+#ifdef UNALIGNMENT_SUPPORT
+ {
+ EXT_HT_CAP_INFO extHtCapInfo;
+ NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&ie_list->HtCapability.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+ *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
+ NdisMoveMemory((PUCHAR)(&ie_list->HtCapability.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+ }
+#else
+ *(USHORT *)(&ie_list->HtCapability.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&ie_list->HtCapability.ExtHtCapInfo));
+#endif /* UNALIGNMENT_SUPPORT */
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s() - wrong IE_HT_CAP. pEid->Len = %d\n", __FUNCTION__, 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(&ie_list->AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+ ie_list->AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+
+ CtrlChannel = ie_list->AddHtInfo.ControlChan;
+
+ *(USHORT *)(&ie_list->AddHtInfo.AddHtInfo2) = cpu2le16(*(USHORT *)(&ie_list->AddHtInfo.AddHtInfo2));
+ *(USHORT *)(&ie_list->AddHtInfo.AddHtInfo3) = cpu2le16(*(USHORT *)(&ie_list->AddHtInfo.AddHtInfo3));
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s() - wrong IE_ADD_HT. \n", __FUNCTION__));
+ }
+
+ break;
+ case IE_SECONDARY_CH_OFFSET:
+ if (pEid->Len == 1)
+ ie_list->NewExtChannelOffset = pEid->Octet[0];
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s() - wrong IE_SECONDARY_CH_OFFSET. \n", __FUNCTION__));
+ }
+ break;
+
+ case IE_FH_PARM:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(IE_FH_PARM) \n", __FUNCTION__));
+ break;
+
+ case IE_DS_PARM:
+ if(pEid->Len == 1)
+ {
+ ie_list->Channel = *pEid->Octet;
+ Sanity |= 0x4;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() - wrong IE_DS_PARM (len=%d)\n",__FUNCTION__,pEid->Len));
+ goto SanityCheck;
+ }
+ break;
+
+ case IE_CF_PARM:
+ if(pEid->Len == 6)
+ {
+ ie_list->CfParm.bValid = TRUE;
+ ie_list->CfParm.CfpCount = pEid->Octet[0];
+ ie_list->CfParm.CfpPeriod = pEid->Octet[1];
+ ie_list->CfParm.CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
+ ie_list->CfParm.CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() - wrong IE_CF_PARM\n", __FUNCTION__));
+ if (pPeerWscIe)
+ os_free_mem(NULL, pPeerWscIe);
+ return FALSE;
+ }
+ break;
+
+ case IE_IBSS_PARM:
+ if(pEid->Len == 2)
+ {
+ NdisMoveMemory(&ie_list->AtimWin, pEid->Octet, pEid->Len);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() - wrong IE_IBSS_PARM\n", __FUNCTION__));
+ if (pPeerWscIe)
+ os_free_mem(NULL, pPeerWscIe);
+ return FALSE;
+ }
+ break;
+
+ case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+ if(pEid->Len == 3)
+ ie_list->NewChannel = 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))
+ {
+ if (pEid->Octet[3] != 0)
+ ie_list->RalinkIe = pEid->Octet[3];
+ else
+ ie_list->RalinkIe = 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.*/
+ }
+ 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*/
+ ie_list->EdcaParm.bValid = TRUE;
+ ie_list->EdcaParm.bQAck = FALSE; /* pEid->Octet[0] & 0x10;*/
+ ie_list->EdcaParm.bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20;*/
+ ie_list->EdcaParm.bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40;*/
+ ie_list->EdcaParm.EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ ie_list->EdcaParm.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*/
+ ie_list->EdcaParm.bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM*/
+ ie_list->EdcaParm.Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN*/
+ ie_list->EdcaParm.Cwmin[aci] = *(ptr+1) & 0x0f; /* b0~4 is Cwmin*/
+ ie_list->EdcaParm.Cwmax[aci] = *(ptr+1) >> 4; /* b5~8 is Cwmax*/
+ ie_list->EdcaParm.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*/
+ ie_list->EdcaParm.bValid = TRUE;
+ ie_list->EdcaParm.bQAck = FALSE; /* pEid->Octet[0] & 0x10;*/
+ ie_list->EdcaParm.bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20;*/
+ ie_list->EdcaParm.bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40;*/
+ ie_list->EdcaParm.EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ ie_list->EdcaParm.bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
+
+ /* use default EDCA parameter*/
+ ie_list->EdcaParm.bACM[QID_AC_BE] = 0;
+ ie_list->EdcaParm.Aifsn[QID_AC_BE] = 3;
+ ie_list->EdcaParm.Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
+ ie_list->EdcaParm.Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
+ ie_list->EdcaParm.Txop[QID_AC_BE] = 0;
+
+ ie_list->EdcaParm.bACM[QID_AC_BK] = 0;
+ ie_list->EdcaParm.Aifsn[QID_AC_BK] = 7;
+ ie_list->EdcaParm.Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
+ ie_list->EdcaParm.Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
+ ie_list->EdcaParm.Txop[QID_AC_BK] = 0;
+
+ ie_list->EdcaParm.bACM[QID_AC_VI] = 0;
+ ie_list->EdcaParm.Aifsn[QID_AC_VI] = 2;
+ ie_list->EdcaParm.Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
+ ie_list->EdcaParm.Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
+ ie_list->EdcaParm.Txop[QID_AC_VI] = 96; /* AC_VI: 96*32us ~= 3ms*/
+
+ ie_list->EdcaParm.bACM[QID_AC_VO] = 0;
+ ie_list->EdcaParm.Aifsn[QID_AC_VO] = 2;
+ ie_list->EdcaParm.Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
+ ie_list->EdcaParm.Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
+ ie_list->EdcaParm.Txop[QID_AC_VO] = 48; /* AC_VO: 48*32us ~= 1.5ms*/
+ }
+ else if (NdisEqualMemory(pEid->Octet, WPS_OUI, 4)
+ )
+ {
+ if (PeerWscIeLen >= 512)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: PeerWscIeLen = %d (>= 512)\n", __FUNCTION__, PeerWscIeLen));
+ if (pPeerWscIe && (PeerWscIeLen < 512))
+ {
+ NdisMoveMemory(pPeerWscIe+PeerWscIeLen, pEid->Octet+4, pEid->Len-4);
+ PeerWscIeLen += (pEid->Len - 4);
+ }
+
+ }
+
+
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(&ie_list->ExtRate[0], pEid->Octet, pEid->Len);
+ ie_list->ExtRateLen = 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)
+ ie_list->Erp = (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*/
+ ie_list->CkipFlag = *(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)
+ ie_list->AironetCellPowerLimit = *(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 WAPI_SUPPORT
+ /* WAPI information element*/
+ case IE_WAPI:
+ if (RTMPEqualMemory(pEid->Octet + 4, WAPI_OUI, 3))
+ {
+ /* Copy to pVIE*/
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+ break;
+#endif /* WAPI_SUPPORT */
+
+
+ case IE_QBSS_LOAD:
+ if (pEid->Len == 5)
+ {
+ ie_list->QbssLoad.bValid = TRUE;
+ ie_list->QbssLoad.StaNum = pEid->Octet[0] + pEid->Octet[1] * 256;
+ ie_list->QbssLoad.ChannelUtilization = pEid->Octet[2];
+ ie_list->QbssLoad.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(&ie_list->ExtCapInfo,&pEid->Octet[0], sizeof(EXT_CAP_INFO_ELEMENT) /*4*/);
+ break;
+ }
+
+#ifdef DOT11_VHT_AC
+ case IE_VHT_CAP:
+ if (pEid->Len == sizeof(VHT_CAP_IE)) {
+ NdisMoveMemory(&ie_list->vht_cap_ie, &pEid->Octet[0], sizeof(VHT_CAP_IE));
+ ie_list->vht_cap_len = pEid->Len;
+ }
+ break;
+ case IE_VHT_OP:
+ if (pEid->Len == sizeof(VHT_OP_IE)) {
+ NdisMoveMemory(&ie_list->vht_op_ie, &pEid->Octet[0], sizeof(VHT_OP_IE));
+ ie_list->vht_op_len = pEid->Len;
+ }
+ break;
+#endif /* DOT11_VHT_AC */
+
+ default:
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len; /* Eid[1] + Len[1]+ content[Len]*/
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ LatchRfChannel = MsgChannel;
+
+ if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
+ {
+ if (CtrlChannel != 0)
+ ie_list->Channel = CtrlChannel;
+ else
+ ie_list->Channel = LatchRfChannel;
+ Sanity |= 0x4;
+ }
+
+ if (pPeerWscIe && (PeerWscIeLen > 0) && (PeerWscIeLen < 512))
+ {
+ UCHAR WscIe[] = {0xdd, 0x00, 0x00, 0x50, 0xF2, 0x04};
+ Ptr = (PUCHAR) pVIE;
+ WscIe[1] = PeerWscIeLen + 4;
+ NdisMoveMemory(Ptr + *LengthVIE, WscIe, 6);
+ NdisMoveMemory(Ptr + *LengthVIE + 6, pPeerWscIe, PeerWscIeLen);
+ *LengthVIE += (PeerWscIeLen + 6);
+ }
+
+
+SanityCheck:
+ if (pPeerWscIe)
+ os_free_mem(NULL, pPeerWscIe);
+
+ if (Sanity != 0x7)
+ {
+ DBGPRINT(RT_DEBUG_LOUD, ("%s() - missing field, Sanity=0x%02x\n", __FUNCTION__, 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)
+ && (SCAN_MODE_VALID(*pScanType))
+ )
+ {
+ 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))
+ {
+ 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 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;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx = MAIN_MBSSID;
+ UCHAR Addr1[MAC_ADDR_LEN];
+#ifdef WSC_INCLUDED
+ UCHAR *pPeerWscIe = NULL;
+ UINT PeerWscIeLen = 0;
+#endif /* WSC_INCLUDED */
+#endif /* CONFIG_AP_SUPPORT */
+ UINT total_ie_len = 0;
+
+ /* to prevent caller from using garbage output value*/
+#ifdef CONFIG_AP_SUPPORT
+ apidx = apidx; /* avoid compile warning */
+#endif /* CONFIG_AP_SUPPORT */
+ *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);
+
+#ifdef CONFIG_AP_SUPPORT
+ COPY_MAC_ADDR(Addr1, &Fr->Hdr.Addr1);
+#ifdef WSC_AP_SUPPORT
+ os_alloc_mem(NULL, &pPeerWscIe, 512);
+#endif /* WSC_AP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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)
+ )
+ {
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef WSC_INCLUDED
+
+
+ WscCheckPeerDPID(pAd, Fr, eid_data, eid_len);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (PeerWscIeLen >= 512)
+ DBGPRINT(RT_DEBUG_ERROR, ("APPeerProbeReqSanity : PeerWscIeLen = %d (>= 512)\n", PeerWscIeLen));
+ if (pPeerWscIe && (PeerWscIeLen < 512))
+ {
+ NdisMoveMemory(pPeerWscIe+PeerWscIeLen, eid_data+4, eid_len-4);
+ PeerWscIeLen += (eid_len - 4);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* WSC_INCLUDED */
+ 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);
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_INCLUDED
+ if (pPeerWscIe && (PeerWscIeLen > 0))
+ {
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ if (NdisEqualMemory(Addr1, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN))
+ break;
+ }
+
+ /*
+ Due to Addr1 in Probe Request may be FF:FF:FF:FF:FF:FF
+ and we need to send out this information to external registrar.
+ Therefore we choose ra0 to send this probe req when we couldn't find apidx by Addr1.
+ */
+ if (apidx >= pAd->ApCfg.BssidNum)
+ {
+ apidx = MAIN_MBSSID;
+ }
+
+ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode & WSC_PROXY) != WSC_DISABLE)
+ {
+ int bufLen = 0;
+ PUCHAR pBuf = NULL;
+ WSC_IE_PROBREQ_DATA *pprobreq = NULL;
+
+ /*
+ PeerWscIeLen: Len of WSC IE without WSC OUI
+ */
+ bufLen = sizeof(WSC_IE_PROBREQ_DATA) + PeerWscIeLen;
+ os_alloc_mem(NULL, &pBuf, bufLen);
+ if(pBuf)
+ {
+ /*Send WSC probe req to UPnP*/
+ NdisZeroMemory(pBuf, bufLen);
+ pprobreq = (WSC_IE_PROBREQ_DATA*)pBuf;
+ if (32 >= *SsidLen) /*Well, I think that it must be TRUE!*/
+ {
+ NdisMoveMemory(pprobreq->ssid, Ssid, *SsidLen); /* SSID*/
+ NdisMoveMemory(pprobreq->macAddr, Fr->Hdr.Addr2, 6); /* Mac address*/
+ pprobreq->data[0] = PeerWscIeLen>>8; /* element ID*/
+ pprobreq->data[1] = PeerWscIeLen & 0xff; /* element Length */
+ NdisMoveMemory((pBuf+sizeof(WSC_IE_PROBREQ_DATA)), pPeerWscIe, PeerWscIeLen); /* (WscProbeReqData)*/
+ WscSendUPnPMessage(pAd, apidx,
+ WSC_OPCODE_UPNP_MGMT, WSC_UPNP_MGMT_SUB_PROBE_REQ,
+ pBuf, bufLen, 0, 0, &Fr->Hdr.Addr2[0], AP_MODE);
+ }
+ os_free_mem(NULL, pBuf);
+ }
+ }
+ }
+ if (pPeerWscIe)
+ os_free_mem(NULL, pPeerWscIe);
+#endif /* WSC_INCLUDED */
+#endif /* CONFIG_AP_SUPPORT */
+
+ return TRUE;
+}
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_sync.c b/cleopatre/devkit/mt7601udrv/common/cmm_sync.c
new file mode 100644
index 0000000000..5c81fb6286
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_sync.c
@@ -0,0 +1,494 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_sync.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 modified for rt2561/2661
+*/
+#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 (!WMODE_5G_ONLY(pAd->CommonCfg.PhyMode))
+ {
+ 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];
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (N_ChannelGroupCheck(pAd, pAd->ChannelList[index + i].Channel))
+ pAd->ChannelList[index + i].Flags |= CHANNEL_40M_CAP;
+#endif /* DOT11_N_SUPPORT */
+
+ pAd->ChannelList[index+i].MaxTxPwr = 20;
+ }
+
+ index += num;
+
+ os_free_mem(NULL, pChannelList);
+ os_free_mem(NULL, pChannelListFlag);
+ }
+ bRegionFound = FALSE;
+ num = 0;
+ }
+
+ if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ {
+ 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};
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR q=0;
+#endif /* CONFIG_AP_SUPPORT */
+ 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);
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ for (i = 0; i < num; i++)
+ {
+ if((pAd->CommonCfg.bIEEE80211H == 0)|| ((pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RDDurRegion != FCC)))
+ {
+ pChannelList[q] = GetChannel_5GHZ(pChDesc, i);
+ pChannelListFlag[q] = GetChannelFlag(pChDesc, i);
+ q++;
+ }
+ /*Based on the requiremnt of FCC, some channles could not be used anymore when test DFS function.*/
+ else if ((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->CommonCfg.RDDurRegion == FCC) &&
+ (pAd->Dot11_H.bDFSIndoor == 1))
+ {
+ if((GetChannel_5GHZ(pChDesc, i) < 116) || (GetChannel_5GHZ(pChDesc, i) > 128))
+ {
+ pChannelList[q] = GetChannel_5GHZ(pChDesc, i);
+ pChannelListFlag[q] = GetChannelFlag(pChDesc, i);
+ q++;
+ }
+ }
+ else if ((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->CommonCfg.RDDurRegion == FCC) &&
+ (pAd->Dot11_H.bDFSIndoor == 0))
+ {
+ if((GetChannel_5GHZ(pChDesc, i) < 100) || (GetChannel_5GHZ(pChDesc, i) > 140) )
+ {
+ pChannelList[q] = GetChannel_5GHZ(pChDesc, i);
+ pChannelListFlag[q] = GetChannelFlag(pChDesc, i);
+ q++;
+ }
+ }
+
+ }
+ num = q;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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];
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (N_ChannelGroupCheck(pAd, pAd->ChannelList[index + i].Channel))
+ pAd->ChannelList[index + i].Flags |= CHANNEL_40M_CAP;
+#endif /* DOT11_N_SUPPORT */
+
+ 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 RT_CFG80211_SUPPORT
+ for (i=0;i<pAd->ChannelListNum;i++)
+ {
+ CFG80211OS_ChanInfoInit(
+ pAd->pCfg80211_CB,
+ i,
+ pAd->ChannelList[i].Channel,
+ pAd->ChannelList[i].MaxTxPwr,
+ WMODE_CAP_N(pAd->CommonCfg.PhyMode),
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_20));
+ }
+#endif /* RT_CFG80211_SUPPORT */
+
+#ifdef DBG
+ for (i=0;i<pAd->ChannelListNum;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(RTMP_ADAPTER *pAd, CHAR Rssi, UCHAR rssi_idx, UCHAR AntSel, UCHAR BW)
+{
+ UCHAR RssiOffset, LNAGain;
+
+ /* Rssi equals to zero or rssi_idx larger than 3 should be an invalid value*/
+ if (Rssi == 0 || rssi_idx >= 3)
+ return -99;
+
+ LNAGain = GET_LNA_GAIN(pAd);
+ if (pAd->LatchRfRegs.Channel > 14)
+ RssiOffset = pAd->ARssiOffset[rssi_idx];
+ else
+ RssiOffset = pAd->BGRssiOffset[rssi_idx];
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ return (Rssi - LNAGain - RssiOffset);
+ else
+#endif /* RT65xx */
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ CHAR LNA, RSSI;
+ PCHAR LNATable;
+/*
+ CHAR MainBW40LNA[] = { 1, 18, 35 };
+ CHAR MainBW20LNA[] = { 1, 18, 36 };
+ CHAR AuxBW40LNA[] = { 1, 23, 42 };
+ CHAR AuxBW20LNA[] = { 1, 23, 42 };
+*/
+ CHAR MainBW40LNA[] = { 0, 16, 34 };
+ CHAR MainBW20LNA[] = { -2, 15, 33 };
+ CHAR AuxBW40LNA[] = { -2, 16, 34 };
+ CHAR AuxBW20LNA[] = { -2, 15, 33 };
+
+ LNA = (Rssi >> 6) & 0x3;
+ RSSI = Rssi & 0x3F;
+
+ if ( (AntSel >> 7) == 0 )
+ {
+ if (BW == BW_40)
+ LNATable = MainBW40LNA;
+ else
+ LNATable = MainBW20LNA;
+ }
+ else
+ {
+ if (BW == BW_40)
+ LNATable = AuxBW40LNA;
+ else
+ LNATable = AuxBW20LNA;
+ }
+
+ if ( LNA == 3 )
+ LNA = LNATable[2];
+ else if ( LNA == 2 )
+ LNA = LNATable[1];
+ else
+ LNA = LNATable[0];
+
+ return ( 8 - LNA - RSSI - LNAGain - RssiOffset );
+ }
+ else
+#endif /* MT7601 */
+ return (-12 - RssiOffset - LNAGain - Rssi);
+}
+
+
+CHAR ConvertToSnr(RTMP_ADAPTER *pAd, UCHAR Snr)
+{
+ if (pAd->chipCap.SnrFormula == SNR_FORMULA2)
+ return (Snr * 3 + 8) >> 4;
+ else if (pAd->chipCap.SnrFormula == SNR_FORMULA3)
+ return (Snr * 3 / 16 ); /* * 0.1881 */
+ else
+ return ((0xeb - Snr) * 3) / 16 ;
+}
+
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DOT11_N_SUPPORT
+extern int DetectOverlappingPeriodicRound;
+
+VOID Handle_BSS_Width_Trigger_Events(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Now32;
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.Channel <=14))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rcv BSS Width Trigger Event: 40Mhz --> 20Mhz \n"));
+ NdisGetSystemUpTime(&Now32);
+ pAd->CommonCfg.LastRcvBSSWidthTriggerEventsTime = Now32;
+ pAd->CommonCfg.bRcvBSSWidthTriggerEvents = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
+ DetectOverlappingPeriodicRound = 31;
+ }
+}
+#endif /* DOT11_N_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_tkip.c b/cleopatre/devkit/mt7601udrv/common/cmm_tkip.c
new file mode 100644
index 0000000000..c2a1216744
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_tkip.c
@@ -0,0 +1,923 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_tkip.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Wu 02-25-02 Initial
+*/
+
+#include "rt_config.h"
+
+/* Rotation functions on 32 bit values */
+#define ROL32( A, n ) \
+ ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
+#define ROR32( A, n ) ROL32( (A), 32-(n) )
+
+UINT Tkip_Sbox_Lower[256] =
+{
+ 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
+ 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
+ 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
+ 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
+ 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
+ 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
+ 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
+ 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
+ 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
+ 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
+ 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
+ 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
+ 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
+ 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
+ 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
+ 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
+ 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
+ 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
+ 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
+ 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
+ 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
+ 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
+ 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
+ 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
+ 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
+ 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
+ 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
+ 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
+ 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
+ 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
+ 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
+ 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
+};
+
+UINT Tkip_Sbox_Upper[256] =
+{
+ 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
+ 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
+ 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
+ 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
+ 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
+ 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
+ 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
+ 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
+ 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
+ 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
+ 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
+ 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
+ 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
+ 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
+ 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
+ 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
+ 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
+ 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
+ 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
+ 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
+ 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
+ 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
+ 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
+ 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
+ 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
+ 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
+ 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
+ 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
+ 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
+ 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
+ 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
+ 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
+};
+
+
+/* Expanded IV for TKIP function.*/
+
+typedef struct GNU_PACKED _IV_CONTROL_
+{
+ union GNU_PACKED
+ {
+ struct GNU_PACKED
+ {
+ UCHAR rc0;
+ UCHAR rc1;
+ UCHAR rc2;
+
+ union GNU_PACKED
+ {
+ struct GNU_PACKED
+ {
+#ifdef RT_BIG_ENDIAN
+ UCHAR KeyID:2;
+ UCHAR ExtIV:1;
+ UCHAR Rsvd:5;
+#else
+ UCHAR Rsvd:5;
+ UCHAR ExtIV:1;
+ UCHAR KeyID:2;
+#endif
+ } field;
+ UCHAR Byte;
+ } CONTROL;
+ } field;
+
+ ULONG word;
+ } IV16;
+
+ ULONG IV32;
+} TKIP_IV, *PTKIP_IV;
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Convert from UCHAR[] to ULONG in a portable way
+
+ Arguments:
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+ULONG RTMPTkipGetUInt32(
+ IN PUCHAR pMICKey)
+{
+ ULONG res = 0;
+ INT i;
+
+ for (i = 0; i < 4; i++)
+ {
+ res |= (*pMICKey++) << (8 * i);
+ }
+
+ return res;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Convert from ULONG to UCHAR[] in a portable way
+
+ Arguments:
+ pDst pointer to destination for convert ULONG to UCHAR[]
+ val the value for convert
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipPutUInt32(
+ IN OUT PUCHAR pDst,
+ IN ULONG val)
+{
+ INT i;
+
+ for(i = 0; i < 4; i++)
+ {
+ *pDst++ = (UCHAR) (val & 0xff);
+ val >>= 8;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set the MIC Key.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipSetMICKey(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pMICKey)
+{
+ /* Set the key */
+ pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
+ pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
+ /* and reset the message */
+ pTkip->L = pTkip->K0;
+ pTkip->R = pTkip->K1;
+ pTkip->nBytesInM = 0;
+ pTkip->M = 0;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ uChar Append this uChar
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipAppendByte(
+ IN PTKIP_KEY_INFO pTkip,
+ IN UCHAR uChar)
+{
+ /* Append the byte to our word-sized buffer */
+ pTkip->M |= (uChar << (8* pTkip->nBytesInM));
+ pTkip->nBytesInM++;
+ /* Process the word if it is full. */
+ if( pTkip->nBytesInM >= 4 )
+ {
+ pTkip->L ^= pTkip->M;
+ pTkip->R ^= ROL32( pTkip->L, 17 );
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ROL32( pTkip->L, 3 );
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ROR32( pTkip->L, 2 );
+ pTkip->L += pTkip->R;
+ /* Clear the buffer */
+ pTkip->M = 0;
+ pTkip->nBytesInM = 0;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to source data for Calculate MIC Value
+ Len Indicate the length of the source data
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipAppend(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pSrc,
+ IN UINT nBytes)
+{
+ /* This is simple */
+ while(nBytes > 0)
+ {
+ RTMPTkipAppendByte(pTkip, *pSrc++);
+ nBytes--;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ the MIC Value is store in pAd->PrivateInfo.MIC
+ ========================================================================
+*/
+VOID RTMPTkipGetMIC(
+ IN PTKIP_KEY_INFO pTkip)
+{
+ /* Append the minimum padding*/
+ RTMPTkipAppendByte(pTkip, 0x5a );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ /* and then zeroes until the length is a multiple of 4 */
+ while( pTkip->nBytesInM != 0 )
+ {
+ RTMPTkipAppendByte(pTkip, 0 );
+ }
+ /* The appendByte function has already computed the result. */
+ RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
+ RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init MIC Value calculation function which include set MIC key &
+ calculate first 16 bytes (DA + SA + priority + 0)
+
+ Arguments:
+ pAd Pointer to our adapter
+ pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitMICEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN UCHAR UserPriority,
+ IN PUCHAR pMICKey)
+{
+ ULONG Priority = UserPriority;
+
+ /* Init MIC value calculation*/
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
+ /* DA*/
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
+ /* SA*/
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
+ /* Priority + 3 bytes of 0*/
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Compare MIC value of received MSDU
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to the received Plain text data
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+ Len the length of the received plain text data exclude MIC value
+
+ Return Value:
+ TRUE MIC value matched
+ FALSE MIC value mismatched
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPTkipCompareMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UCHAR UserPriority,
+ IN UINT Len)
+{
+ UCHAR OldMic[8];
+ ULONG Priority = UserPriority;
+
+ /* Init MIC value calculation*/
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+ /* DA*/
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+ /* SA*/
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+ /* Priority + 3 bytes of 0*/
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
+
+ /* Calculate MIC value from plain text data*/
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+ /* Get MIC valude from received frame*/
+ NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+ /* Get MIC value from decrypted plain data*/
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+ /* Move MIC value from MSDU, this steps should move to data path.*/
+ /* Since the MIC value might cross MPDUs.*/
+ if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); /*MIC error.*/
+
+
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware transmit function
+
+ Arguments:
+ pAd Pointer to our adapter
+ PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
+ pEncap Pointer to LLC encap data
+ LenEncap Total encap length, might be 0 which indicates no encap
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPCalculateMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pEncap,
+ IN PCIPHER_KEY pKey,
+ IN UCHAR apidx)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ PUCHAR pSrc;
+ UCHAR UserPriority;
+ UCHAR vlan_offset = 0;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ UserPriority = RTMP_GET_PACKET_UP(pPacket);
+ pSrc = pSrcBufVA;
+
+ /* determine if this is a vlan packet */
+ if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
+ vlan_offset = 4;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ /* Start Calculate MIC Value*/
+ if (apidx >= MIN_NET_DEVICE_FOR_APCLI && ((apidx - MIN_NET_DEVICE_FOR_APCLI) < MAX_APCLI_NUM) && (pAd->OpMode == OPMODE_AP))
+ { /* For packet which need to do MATConvert, we need to use the CurrentAddress of specific ApCli interface.*/
+ RTMPInitMICEngine(
+ pAd,
+ pKey->Key,
+ pSrc,
+ pAd->ApCfg.ApCliTab[apidx-MIN_NET_DEVICE_FOR_APCLI].CurrentAddress,
+ UserPriority,
+ pKey->TxMic);
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef IGMP_SNOOP_SUPPORT
+ if ((RTMP_GET_PACKET_WCID(pPacket) != MCAST_WCID) && (*pSrc & 0x01) && (pAd->OpMode == OPMODE_AP))
+ {
+ RTMPInitMICEngine(
+ pAd,
+ pKey->Key,
+ pAd->MacTab.Content[RTMP_GET_PACKET_WCID(pPacket)].Addr,
+ pSrc + 6,
+ UserPriority,
+ pKey->TxMic);
+ }
+ else
+#endif /* IGMP_SNOOP_SUPPORT */
+#endif /* CONFIG_AP_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);
+
+ /* 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.*/
+ return FALSE;
+ }
+
+ /* Update the total data length */
+ *DataByteCnt = plaintext_len;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, pHdr, DIR_READ, FALSE);
+#endif
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Use RC4 to protect the Key Data field of EAPoL frame.
+ It's defined in IEEE 802.11i-2004 p.84
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID TKIP_GTK_KEY_WRAP(
+ IN UCHAR *key,
+ IN UCHAR *iv,
+ IN UCHAR *input_text,
+ IN UINT32 input_len,
+ OUT UCHAR *output_text)
+{
+ UCHAR ekey[LEN_KEY_DESC_IV + LEN_PTK_KEK];
+/* ARC4_CTX_STRUC ARC4_CTX;*/
+ ARC4_CTX_STRUC *pARC4_CTX = NULL;
+
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&pARC4_CTX, sizeof(ARC4_CTX_STRUC));
+ if (pARC4_CTX == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return;
+ }
+
+ /* The encryption key is generated by concatenating the
+ EAPOL-Key IV field and the KEK. */
+ NdisMoveMemory(ekey, iv, LEN_KEY_DESC_IV);
+ NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], key, LEN_PTK_KEK);
+
+ /* RC4 stream cipher initialization with the KEK */
+ ARC4_INIT(pARC4_CTX, &ekey[0], LEN_KEY_DESC_IV + LEN_PTK_KEK);
+
+ /* The first 256 octets of the RC4 key stream shall be discarded */
+ ARC4_Discard_KeyLength(pARC4_CTX, 256);
+
+ /* encryption begins using the 257th key stream octet */
+ ARC4_Compute(pARC4_CTX, input_text, input_len, output_text);
+
+ if (pARC4_CTX != NULL)
+ os_free_mem(NULL, pARC4_CTX);
+}
+
+VOID TKIP_GTK_KEY_UNWRAP(
+ IN UCHAR *key,
+ IN UCHAR *iv,
+ IN UCHAR *input_text,
+ IN UINT32 input_len,
+ OUT UCHAR *output_text)
+{
+ TKIP_GTK_KEY_WRAP(key, iv, input_text, input_len, output_text);
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_video.c b/cleopatre/devkit/mt7601udrv/common/cmm_video.c
new file mode 100644
index 0000000000..1e4ec06ac2
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_video.c
@@ -0,0 +1,168 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ cmm_video.c
+
+ Abstract:
+ Ralink WiFi Driver video mode related subroutines
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+*/
+
+#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 TxSwQDepthAdjust(IN RTMP_ADAPTER *pAd, IN UINT32 qLen)
+{
+ ULONG IrqFlags;
+ INT qIdx;
+ QUEUE_HEADER *pTxQ, *pEntry;
+ PNDIS_PACKET pPacket;
+
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ pAd->TxSwQMaxLen = qLen;
+ for (qIdx = 0; qIdx < NUM_OF_TX_RING; qIdx++)
+ {
+ pTxQ = &pAd->TxSwQueue[qIdx];
+ while(pTxQ->Number >= pAd->TxSwQMaxLen)
+ {
+ pEntry = RemoveHeadQueue(pTxQ);
+ if (pEntry)
+ {
+ pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ else
+ break;
+ }
+ }
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+ DBGPRINT(RT_DEBUG_OFF, ("%s():Set TxSwQMaxLen as %d\n",
+ __FUNCTION__, pAd->TxSwQMaxLen));
+}
+
+
+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);
+
+ Set_RateAdaptInterval(pAd, "100:50");
+ TxSwQDepthAdjust(pAd, 1024);
+
+ }
+ 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);
+
+ /* reset to default rate adaptation simping interval */
+ if ((pAd->ra_interval != DEF_RA_TIME_INTRVAL) ||
+ (pAd->ra_fast_interval != DEF_QUICK_RA_TIME_INTERVAL))
+ Set_RateAdaptInterval(pAd, "500:100");
+
+ TxSwQDepthAdjust(pAd, MAX_PACKETS_IN_QUEUE);
+ }
+}
+
+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 */
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_wep.c b/cleopatre/devkit/mt7601udrv/common/cmm_wep.c
new file mode 100644
index 0000000000..51147f6b16
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_wep.c
@@ -0,0 +1,365 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_wep.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Wu 10-28-02 Initial
+*/
+
+#include "rt_config.h"
+
+UINT FCSTAB_32[256] =
+{
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate a new FCS given the current FCS and the new data.
+
+ Arguments:
+ Fcs the original FCS value
+ Cp pointer to the data which will be calculate the FCS
+ Len the length of the data
+
+ Return Value:
+ UINT - FCS 32 bits
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+UINT RTMP_CALC_FCS32(
+ IN UINT Fcs,
+ IN PUCHAR Cp,
+ IN INT Len)
+{
+ while (Len--)
+ Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
+
+ return (Fcs);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init WEP function.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pKey Pointer to the WEP KEY
+ KeyId WEP Key ID
+ KeyLen the length of WEP KEY
+ pDest Pointer to the destination which Encryption data will store in.
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitWepEngine(
+ IN PUCHAR pIv,
+ IN PUCHAR pKey,
+ IN UCHAR KeyLen,
+ OUT ARC4_CTX_STRUC *pARC4_CTX)
+{
+/* UCHAR seed[16];*/
+ PUCHAR seed = NULL;
+ UINT8 seed_len;
+
+ os_alloc_mem(NULL, (UCHAR **)&seed, sizeof(UCHAR)*16);
+ if (seed == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: seed Allocate memory fail!!!\n", __FUNCTION__));
+ return;
+ }
+
+ /* WEP seed construction */
+ NdisZeroMemory(seed, 16);
+ NdisMoveMemory(seed, pIv, 3);
+ NdisMoveMemory(&seed[3], pKey, KeyLen);
+ seed_len = 3 + KeyLen;
+
+ /* RC4 uses a pseudo-random number generator (PRNG)
+ to generate a key stream */
+ ARC4_INIT(pARC4_CTX, &seed[0], seed_len);
+
+ if (seed != NULL)
+ os_free_mem(NULL, seed);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct WEP IV header.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ It's a 4-octets header.
+
+ ========================================================================
+*/
+VOID RTMPConstructWEPIVHdr(
+ IN UINT8 key_idx,
+ IN UCHAR *pn,
+ OUT UCHAR *iv_hdr)
+{
+ NdisZeroMemory(iv_hdr, LEN_WEP_IV_HDR);
+
+ NdisMoveMemory(iv_hdr, pn, LEN_WEP_TSC);
+
+ /* Append key index */
+ iv_hdr[3] = (key_idx << 6);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ WEP MPDU cryptographic encapsulation
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ pSrc Pointer to the received data
+ Len the length of the received data
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPSoftEncryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pIvHdr,
+ IN PCIPHER_KEY pKey,
+ INOUT PUCHAR pData,
+ IN ULONG DataByteCnt)
+{
+ ARC4_CTX_STRUC *ARC4_CTX = NULL;
+ UINT FCSCRC32;
+
+ os_alloc_mem(NULL, (UCHAR **)&ARC4_CTX, sizeof(ARC4_CTX_STRUC));
+ if (ARC4_CTX == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: ARC4_CTX Allocate memory fail!!!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ if (pKey->KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The key is empty !\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ /* Initialize WEP key stream */
+ RTMPInitWepEngine(pIvHdr,
+ pKey->Key,
+ pKey->KeyLen,
+ ARC4_CTX);
+
+ /* WEP computes the ICV over the plaintext data */
+ FCSCRC32 = RTMP_CALC_FCS32(PPPINITFCS32, pData, DataByteCnt);
+ FCSCRC32 ^= 0xffffffff; /* complement */
+ FCSCRC32 = cpu2le32(FCSCRC32);
+
+ /* Append 4-bytes ICV after the MPDU data */
+ NdisMoveMemory(pData + DataByteCnt, (PUCHAR)&FCSCRC32, LEN_ICV);
+
+ /* Encrypt the MPDU plaintext data and ICV using ARC4 with a seed */
+ ARC4_Compute(ARC4_CTX, pData, DataByteCnt + LEN_ICV, pData);
+
+ if (ARC4_CTX != NULL)
+ os_free_mem(NULL, ARC4_CTX);
+
+ return TRUE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Decrypt received WEP data
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ pSrc Pointer to the received data
+ Len the length of the received data
+
+ Return Value:
+ TRUE Decrypt WEP data success
+ FALSE Decrypt WEP data failed
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPSoftDecryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PCIPHER_KEY pKey,
+ INOUT PUCHAR pData,
+ INOUT UINT16 *DataByteCnt)
+{
+ /*ARC4_CTX_STRUC ARC4_CTX;*/
+ ARC4_CTX_STRUC *ARC4_CTX = NULL;
+ PUCHAR plaintext_ptr;
+ UINT16 plaintext_len;
+ PUCHAR ciphertext_ptr;
+ UINT16 ciphertext_len;
+ UINT trailfcs;
+ UINT crc32;
+
+ os_alloc_mem(NULL, (UCHAR **)&ARC4_CTX, sizeof(ARC4_CTX_STRUC));
+ if (ARC4_CTX == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: ARC4_CTX Allocate memory fail!!!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ if (pKey->KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The key is not available !\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ /* Initialize WEP key stream */
+ RTMPInitWepEngine(pData,
+ pKey->Key,
+ pKey->KeyLen,
+ ARC4_CTX);
+
+ /* Skip the WEP IV header (4-bytes) */
+ ciphertext_ptr = pData + LEN_WEP_IV_HDR;
+ ciphertext_len = *DataByteCnt - LEN_WEP_IV_HDR;
+
+ /* Decrypt the WEP MPDU. It shall include plaintext and ICV.
+ The result output would overwrite the original WEP IV header position */
+ ARC4_Compute(ARC4_CTX,
+ ciphertext_ptr,
+ ciphertext_len,
+ pData);
+
+ /* Point to the decrypted data frame and its length shall exclude ICV length */
+ plaintext_ptr = pData;
+ plaintext_len = ciphertext_len - LEN_ICV;
+
+ /* Extract peer's the ICV */
+ NdisMoveMemory(&trailfcs, plaintext_ptr + plaintext_len, LEN_ICV);
+
+ /* WEP recomputes the ICV and
+ bit-wise compares it with the decrypted ICV from the MPDU. */
+ crc32 = RTMP_CALC_FCS32(PPPINITFCS32, plaintext_ptr, plaintext_len);
+ crc32 ^= 0xffffffff; /* complement */
+
+ if(crc32 != cpu2le32(trailfcs))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("! WEP Data CRC Error !\n")); /*CRC error.*/
+ return FALSE;
+ }
+
+ /* Update the total data length */
+ *DataByteCnt = plaintext_len;
+
+ if (ARC4_CTX != NULL)
+ os_free_mem(NULL, ARC4_CTX);
+
+ return TRUE;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/common/cmm_wpa.c b/cleopatre/devkit/mt7601udrv/common/cmm_wpa.c
new file mode 100644
index 0000000000..068ae2c4c5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/cmm_wpa.c
@@ -0,0 +1,4728 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wpa.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 03-07-22 Initial
+ Paul Lin 03-11-28 Modify for supplicant
+*/
+#include "rt_config.h"
+
+/* WPA OUI*/
+UCHAR OUI_WPA[3] = {0x00, 0x50, 0xF2};
+UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
+UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
+UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
+UCHAR OUI_WPA_WEP104[4] = {0x00, 0x50, 0xF2, 0x05};
+UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
+/* WPA2 OUI*/
+UCHAR OUI_WPA2[3] = {0x00, 0x0F, 0xAC};
+UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
+UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
+UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
+UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05};
+UCHAR OUI_WPA2_1X_SHA256[4] = {0x00, 0x0F, 0xAC, 0x05};
+UCHAR OUI_WPA2_PSK_SHA256[4] = {0x00, 0x0F, 0xAC, 0x06};
+
+
+
+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;
+
+
+ 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);
+#ifdef WSC_AP_SUPPORT
+ /*
+ a WSC enabled AP must ignore EAPOL-Start frames received from clients that associated to
+ the AP with an RSN IE or SSN IE indicating a WPA2-PSK/WPA-PSK authentication method in
+ the assication request. <<from page52 in Wi-Fi Simple Config Specification version 1.0g>>
+ */
+ if (pEntry &&
+ (pEntry->apidx == MAIN_MBSSID) &&
+ (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscConfMode != WSC_DISABLE) &&
+ ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
+ pEntry->bWscCapable)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS enabled AP: Ignore EAPOL-Start frames received from clients.\n"));
+ return;
+ }
+#endif /* WSC_AP_SUPPORT */
+ }
+
+ 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;
+
+
+ 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 or 3.*/
+ else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ && (peerKeyInfo.KeyDescVer != KEY_DESC_AES)
+ && (peerKeyInfo.KeyDescVer != KEY_DESC_EXT))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(AES) pEntry->WepStatus=%d, peerKeyInfo.KeyDescVer=%d\n", pEntry->WepStatus, peerKeyInfo.KeyDescVer));
+ 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.
+ */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ if ((peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 1) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.KeyType == GROUPKEY) &&
+ (pEapol_packet->KeyDesc.KeyDataLen[1] == 12))
+ {
+ /* This is a ralink proprietary DLS STA-Key processing*/
+ RTMPHandleSTAKey(pAd, pEntry, Elem);
+ }
+ else
+#endif /* QOS_DLS_SUPPORT */
+ if ((peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Request == 1) &&
+ (peerKeyInfo.Error == 1))
+ {
+ /* The Supplicant uses a single Michael MIC Failure Report frame */
+ /* to report a MIC failure event to the Authenticator. */
+ /* A Michael MIC Failure Report is an EAPOL-Key frame with */
+ /* the following Key Information field bits set to 1: */
+ /* MIC bit, Error bit, Request bit, Secure bit.*/
+
+ DBGPRINT(RT_DEBUG_ERROR, ("Received an Michael MIC Failure Report, active countermeasure \n"));
+ RTMP_HANDLE_COUNTER_MEASURE(pAd, pEntry);
+ }
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ 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));
+ }
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else if ((peerKeyInfo.Request == 1) && (peerKeyInfo.Error == 0))
+ {
+ INT i;
+ UCHAR apidx = pEntry->apidx;
+
+ /* Need to check KeyType for groupkey or pairwise key update, refer to 8021i P.114, */
+ if (peerKeyInfo.KeyType == GROUPKEY)
+ {
+ UINT8 Wcid;
+ PMULTISSID_STRUCT pMbssEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("REQUEST=1, ERROR=0, update group key\n"));
+
+ pMbssEntry = &pAd->ApCfg.MBSSID[apidx];
+
+ GenRandom(pAd, pMbssEntry->Bssid, pMbssEntry->GNonce);
+ pMbssEntry->DefaultKeyId = (pMbssEntry->DefaultKeyId == 1) ? 2 : 1;
+ WpaDeriveGTK(pMbssEntry->GMK,
+ pMbssEntry->GNonce,
+ pMbssEntry->Bssid,
+ pMbssEntry->GTK, LEN_TKIP_GTK);
+
+ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])
+ && (pAd->MacTab.Content[i].WpaState == AS_PTKINITDONE)
+ && (pAd->MacTab.Content[i].apidx == apidx))
+ {
+ pAd->MacTab.Content[i].GTKState = REKEY_NEGOTIATING;
+ WPAStart2WayGroupHS(pAd, &pAd->MacTab.Content[i]);
+ pAd->MacTab.Content[i].ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
+ RTMPModTimer(&pAd->MacTab.Content[i].RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
+ }
+ }
+
+ /* Get a specific WCID to record this MBSS key attribute */
+ GET_GroupKey_WCID(pAd, Wcid, apidx);
+
+ WPAInstallSharedKey(pAd,
+ pMbssEntry->GroupKeyWepStatus,
+ apidx,
+ pMbssEntry->DefaultKeyId,
+ Wcid,
+ TRUE,
+ pMbssEntry->GTK,
+ LEN_TKIP_GTK);
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("REQUEST=1, ERROR= 0, update pairwise key\n"));
+
+ NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
+
+ /* clear this entry as no-security mode*/
+ AsicRemovePairwiseKeyEntry(pAd, pEntry->Aid);
+
+ pEntry->Sst = SST_ASSOC;
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+ pEntry->WpaState = AS_INITPMK;
+ else if (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+ pEntry->WpaState = AS_INITPSK;
+
+ pEntry->GTKState = REKEY_NEGOTIATING;
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
+
+ WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ }
+ }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);
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+ RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
+ RTMP_SET_PACKET_NET_DEVICE_APCLI(pPacket, pEntry->MatchAPCLITabIdx);
+ RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid); /* to ApClient links.*/
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ {
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* send out the packet */
+ APSendPacket(pAd, pPacket);
+
+ /* Dequeue outgoing frames from TxSwQueue0..3 queue and process it*/
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+#endif /* CONFIG_AP_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, MAX_LEN_OF_RSNIE);
+ 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);
+ }
+ else if (EapolKeyInfo.KeyDescVer == KEY_DESC_EXT) /* AES-128 */
+ {
+ UINT mlen = AES_KEY128_LENGTH;
+ AES_CMAC((PUCHAR)pMsg, eapol_len, pEntry->PTK, LEN_PTK_KCK, mic, &mlen);
+ }
+
+
+ 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_EXT) || (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_AP_SUPPORT
+ UCHAR apidx = 0;
+#endif /* CONFIG_AP_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;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if ((!pEntry) || !IS_ENTRY_CLIENT(pEntry))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : The entry doesn't exist.\n"));
+ return;
+ }
+
+ if (pEntry->apidx < pAd->ApCfg.BssidNum)
+ {
+ apidx = pEntry->apidx;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : The apidx(%d) is invalid.\n", pEntry->apidx));
+ return;
+ }
+
+ /* pointer to the corresponding position*/
+ pBssid = pAd->ApCfg.MBSSID[apidx].Bssid;
+ group_cipher = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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;
+ }
+
+#ifdef WSC_AP_SUPPORT
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAd->ApCfg.MBSSID[apidx].WscControl.EntryAddr) &&
+ pAd->ApCfg.MBSSID[apidx].WscControl.EapMsgRunning)
+ {
+ pEntry->WpaState = AS_NOTUSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("This is a WSC-Enrollee. Not expect calling WPAStart4WayHS here \n"));
+ return;
+ }
+#endif /* WSC_AP_SUPPORT */
+
+ /* 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);
+
+#ifdef CONFIG_AP_SUPPORT
+ /* If PMKID match in WPA2-enterprise mode, fill PMKID into Key data field and update PMK here */
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND))
+ {
+ /* Fill in value for KDE */
+ pEapolFrame->KeyDesc.KeyData[0] = 0xDD;
+ pEapolFrame->KeyDesc.KeyData[2] = 0x00;
+ pEapolFrame->KeyDesc.KeyData[3] = 0x0F;
+ pEapolFrame->KeyDesc.KeyData[4] = 0xAC;
+ pEapolFrame->KeyDesc.KeyData[5] = 0x04;
+
+ NdisMoveMemory(&pEapolFrame->KeyDesc.KeyData[6], &pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[pEntry->PMKID_CacheIdx].PMKID, LEN_PMKID);
+ NdisMoveMemory(&pAd->ApCfg.MBSSID[apidx].PMK, &pAd->ApCfg.MBSSID[apidx].PMKIDCache.BSSIDInfo[pEntry->PMKID_CacheIdx].PMK, PMK_LEN);
+
+ pEapolFrame->KeyDesc.KeyData[1] = 0x14;/* 4+LEN_PMKID*/
+ INC_UINT16_TO_ARRARY(pEapolFrame->KeyDesc.KeyDataLen, 6 + LEN_PMKID);
+ INC_UINT16_TO_ARRARY(pEapolFrame->Body_Len, 6 + LEN_PMKID);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ UINT IfIndex = 0;
+
+ IfIndex = pEntry->MatchAPCLITabIdx;
+ if (IfIndex >= MAX_APCLI_NUM)
+ return;
+
+ pCurrentAddr = pAd->ApCfg.ApCliTab[IfIndex].CurrentAddress;
+ pmk_ptr = pAd->ApCfg.ApCliTab[IfIndex].PMK;
+ group_cipher = pAd->ApCfg.ApCliTab[IfIndex].GroupCipher;
+ rsnie_ptr = pAd->ApCfg.ApCliTab[IfIndex].RSN_IE;
+ rsnie_len = pAd->ApCfg.ApCliTab[IfIndex].RSNIE_Len;
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx = 0;
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (pEntry->apidx >= pAd->ApCfg.BssidNum)
+ return;
+ else
+ apidx = pEntry->apidx;
+
+ pBssid = pAd->ApCfg.MBSSID[apidx].Bssid;
+ pmk_ptr = pAd->ApCfg.MBSSID[apidx].PMK;
+ gtk_ptr = pAd->ApCfg.MBSSID[apidx].GTK;
+ group_cipher = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus;
+ default_key = pAd->ApCfg.MBSSID[apidx].DefaultKeyId;
+
+ /* Get Group TxTsc form Asic*/
+ RTMPGetTxTscFromAsic(pAd, apidx, TxTsc);
+
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ rsnie_len = pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0];
+ rsnie_ptr = &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][0];
+ }
+ else
+ {
+ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2))
+ {
+ rsnie_len = pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1];
+ rsnie_ptr = &pAd->ApCfg.MBSSID[apidx].RSN_IE[1][0];
+ }
+ else
+ {
+ rsnie_len = pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0];
+ rsnie_ptr = &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][0];
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* 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*/
+ if ((pmk_ptr == NULL) || (pBssid == NULL))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("%s: pmk_ptr or pBssid == NULL!\n", __FUNCTION__));
+ return;
+ }
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ UINT IfIndex = 0;
+
+ IfIndex = pEntry->MatchAPCLITabIdx;
+ if (IfIndex >= MAX_APCLI_NUM)
+ return;
+
+ pCurrentAddr = pAd->ApCfg.ApCliTab[IfIndex].CurrentAddress;
+ group_cipher = pAd->ApCfg.ApCliTab[IfIndex].GroupCipher;
+
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ APCliInstallPairwiseKey(pAd, pEntry);
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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_MULTI_CHANNEL
+ if (pAd->Multi_Channel_Enable == TRUE)
+ {
+ MultiChannelTimerStart(pAd,pEntry);
+ }
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
+ GetAuthMode(pEntry->AuthMode),
+ GetEncryptType(pEntry->WepStatus),
+ GetEncryptType(group_cipher)));
+ }
+ else
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ /* Patch issue with gateway AP*/
+ /* In WPA mode, AP doesn't send out message 1 of group-key HS.*/
+ /* So, Supplicant shall maintain a timeout action to disconnect */
+ /* this link.*/
+ /* Todo - Does it need to apply to STA ?*/
+ if (IS_ENTRY_APCLI(pEntry))
+ RTMPSetTimer(&pEntry->RetryTimer, PEER_GROUP_KEY_UPDATE_INIV);
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ /* 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;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UCHAR apidx = 0;
+
+ if (pEntry->apidx >= pAd->ApCfg.BssidNum)
+ break;
+ else
+ apidx = pEntry->apidx;
+
+ group_cipher = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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;
+
+#ifdef WSC_AP_SUPPORT
+ if (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscConfMode != WSC_DISABLE)
+ WscInformFromWPA(pEntry);
+#endif /* WSC_AP_SUPPORT */
+
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+ pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+ {
+ pEntry->GTKState = REKEY_ESTABLISHED;
+ RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DOT1X_SUPPORT
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+ {
+ UCHAR PMK_key[20];
+ UCHAR digest[80];
+
+ /* Calculate PMKID, refer to IEEE 802.11i-2004 8.5.1.2*/
+ NdisMoveMemory(&PMK_key[0], "PMK Name", 8);
+ NdisMoveMemory(&PMK_key[8], pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, MAC_ADDR_LEN);
+ NdisMoveMemory(&PMK_key[14], pEntry->Addr, MAC_ADDR_LEN);
+ RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].PMK, PMK_LEN, PMK_key, 20, digest, SHA1_DIGEST_SIZE);
+ RTMPAddPMKIDCache(pAd, pEntry->apidx, pEntry->Addr, digest, pAd->ApCfg.MBSSID[pEntry->apidx].PMK);
+ DBGPRINT(RT_DEBUG_TRACE, ("Calc PMKID=%02x:%02x:%02x:%02x:%02x:%02x\n", digest[0],digest[1],digest[2],digest[3],digest[4],digest[5]));
+ }
+#endif /* DOT1X_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UCHAR apidx = 0;
+
+ if (pEntry->apidx >= pAd->ApCfg.BssidNum)
+ return;
+ else
+ apidx = pEntry->apidx;
+
+ group_cipher = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus;
+ default_key = pAd->ApCfg.MBSSID[apidx].DefaultKeyId;
+ gnonce_ptr = pAd->ApCfg.MBSSID[apidx].GNonce;
+ gtk_ptr = pAd->ApCfg.MBSSID[apidx].GTK;
+ pBssid = pAd->ApCfg.MBSSID[apidx].Bssid;
+
+ /* Get Group TxTsc form Asic*/
+ RTMPGetTxTscFromAsic(pAd, apidx, TxTsc);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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*/
+ if (pBssid == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pBssid == NULL!\n", __FUNCTION__));
+ return;
+ }
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ UINT IfIndex = 0;
+
+ IfIndex = pEntry->MatchAPCLITabIdx;
+ if (IfIndex >= MAX_APCLI_NUM)
+ return;
+
+ pCurrentAddr = pAd->ApCfg.ApCliTab[IfIndex].CurrentAddress;
+ group_cipher = pAd->ApCfg.ApCliTab[IfIndex].GroupCipher;
+ default_key = pAd->ApCfg.ApCliTab[IfIndex].DefaultKeyId;
+
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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*/
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ /* Patch issue with gateway AP*/
+ /* In WPA mode, AP doesn't send out message 1 of group-key HS.*/
+ /* So, Supplicant shall maintain a timeout action to disconnect */
+ /* this link.*/
+ /* Todo - Does it need to apply to STA ?*/
+ if (IS_ENTRY_APCLI(pEntry))
+ RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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;
+
+
+ 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);
+
+
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DOT1X_SUPPORT
+ case EAPOL_START_1X:
+ DBGPRINT(RT_DEBUG_TRACE, ("Enqueue EAPoL-Start-1X for sta(%02x:%02x:%02x:%02x:%02x:%02x) \n", PRINT_MAC(pEntry->Addr)));
+
+ DOT1X_EapTriggerAction(pAd, pEntry);
+ break;
+#endif /* DOT1X_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid);
+ }
+#endif /* CONFIG_AP_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
+ {
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UCHAR apidx = 0;
+
+ if (pEntry->apidx >= pAd->ApCfg.BssidNum)
+ return;
+ else
+ apidx = pEntry->apidx;
+
+ group_cipher = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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;
+ }
+
+ 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;
+ }
+
+
+ /* 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;
+ }
+
+
+ /* 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (apidx < pAd->ApCfg.BssidNum)
+ {
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+#ifdef DOT1X_SUPPORT
+ pRSN_Cap->field.PreAuth = (pMbss->PreAuth == TRUE) ? 1 : 0;
+#endif /* DOT1X_SUPPORT */
+ }
+ }
+#endif /* CONFIG_AP_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 */
+#ifdef CONFIG_AP_SUPPORT
+ PUCHAR pRsnIe_ex = NULL; /* secondary RSNIE, it's ONLY used in WPA-mix mode */
+ BOOLEAN bMixRsnIe = FALSE; /* indicate WPA-mix mode is on or off*/
+ UCHAR s_offset;
+#endif /* CONFIG_AP_SUPPORT */
+ 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 */
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ if (pAd->ApCfg.ApCliTab[apcliIfidx].WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ if (AuthMode < Ndis802_11AuthModeWPA)
+ return;
+ }
+ else
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+ {
+
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* Sanity check for apidx */
+ MBSS_MR_APIDX_SANITY_CHECK(pAd, apidx);
+#ifdef HOSTAPD_SUPPORT
+ if(pAd->ApCfg.MBSSID[apidx].Hostapd)
+ return;
+#endif /* HOSTAPD_SUPPORT */
+ if ((AuthMode != Ndis802_11AuthModeWPA) &&
+ (AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (AuthMode != Ndis802_11AuthModeWPA2) &&
+ (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (AuthMode != Ndis802_11AuthModeWPA1WPA2) &&
+ (AuthMode != Ndis802_11AuthModeWPA1PSKWPA2PSK)
+#ifdef WAPI_SUPPORT
+ && (AuthMode != Ndis802_11AuthModeWAICERT)
+ && (AuthMode != Ndis802_11AuthModeWAIPSK)
+#endif /* WAPI_SUPPORT */
+ )
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(AP-ra%d)\n", apidx));
+
+ /* decide the group key encryption type */
+ if (WepStatus == Ndis802_11Encryption4Enabled)
+ {
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus = Ndis802_11Encryption2Enabled;
+ FlexibleCipher = pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher;
+ }
+ else
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus = WepStatus;
+
+ /* Initiate some related information */
+ pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0] = 0;
+ pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1] = 0;
+ NdisZeroMemory(pAd->ApCfg.MBSSID[apidx].RSN_IE[0], MAX_LEN_OF_RSNIE);
+ NdisZeroMemory(pAd->ApCfg.MBSSID[apidx].RSN_IE[1], MAX_LEN_OF_RSNIE);
+
+ /* Pointer to the first RSNIE context */
+ rsnielen_cur_p = &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0];
+ pRsnIe = pAd->ApCfg.MBSSID[apidx].RSN_IE[0];
+
+ /* Pointer to the secondary RSNIE context */
+ rsnielen_ex_cur_p = &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1];
+ pRsnIe_ex = pAd->ApCfg.MBSSID[apidx].RSN_IE[1];
+
+ /* Decide whether the authentication mode is WPA1-WPA2 mixed mode */
+ if ((AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+ (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ {
+ bMixRsnIe = TRUE;
+ }
+ break;
+ }
+#endif /* CONFIG_AP_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;
+#ifdef WAPI_SUPPORT
+ else if ((AuthMode == Ndis802_11AuthModeWAICERT) ||
+ (AuthMode == Ndis802_11AuthModeWAIPSK))
+ PrimaryRsnie = WapiIe;
+#endif /* WAPI_SUPPORT */
+ else
+ PrimaryRsnie = Wpa2Ie;
+
+#ifdef WAPI_SUPPORT
+ if (PrimaryRsnie == WapiIe)
+ {
+ RTMPInsertWapiIe(AuthMode, WepStatus, pRsnIe, &p_offset);
+ }
+ else
+#endif /* WAPI_SUPPORT */
+ {
+ /* 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*/
+ if (rsnielen_cur_p == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: rsnielen_cur_p == NULL!\n", __FUNCTION__));
+ return;
+ }
+
+ *rsnielen_cur_p = p_offset;
+
+ hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
+
+#ifdef CONFIG_AP_SUPPORT
+ if ((pAd->OpMode == OPMODE_AP)
+ )
+ {
+ /* if necessary, build the secondary RSNIE*/
+ if (bMixRsnIe)
+ {
+ /* 1. insert cipher suite*/
+ RTMPMakeRsnIeCipher(pAd, Wpa2Ie, WepStatus, apidx, bMixCipher, FlexibleCipher, pRsnIe_ex, &s_offset);
+
+ /* 2. insert AKM*/
+ RTMPMakeRsnIeAKM(pAd, Wpa2Ie, AuthMode, apidx, pRsnIe_ex, &s_offset);
+
+ /* 3. insert capability*/
+ RTMPMakeRsnIeCap(pAd, Wpa2Ie, apidx, pRsnIe_ex, &s_offset);
+
+
+ /* Update the RSNIE length*/
+ *rsnielen_ex_cur_p = s_offset;
+
+ hex_dump("The secondary RSNIE", pRsnIe_ex, (*rsnielen_ex_cur_p));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+}
+
+/*
+ ==========================================================================
+ 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));
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef IDS_SUPPORT
+ if((*(pData+4)) == EAP_CODE_REQUEST)
+ pAd->ApCfg.RcvdEapReqCount ++;
+#endif /* IDS_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ 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;
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+BOOLEAN RTMPCheckWPAframe_Hdr_Trns(
+ 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_3 + LENGTH_EAPOL_H))
+ return FALSE;
+
+
+ /* Skip LLC header */
+
+ pData += LENGTH_802_3;
+
+ /* 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));
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef IDS_SUPPORT
+ if((*(pData+4)) == EAP_CODE_REQUEST)
+ pAd->ApCfg.RcvdEapReqCount ++;
+#endif /* IDS_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ 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;
+}
+#endif /* HDR_TRANS_SUPPORT */
+
+
+/*
+ ==========================================================================
+ 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;
+
+
+ NdisZeroMemory(GTK, MAX_LEN_GTK);
+
+ /* 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_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ /* Set Group key material, TxMic and RxMic for AP-Client*/
+ if (!APCliInstallSharedKey(pAd, GTK, GTKLEN, DefaultIdx, pEntry))
+ {
+ return FALSE;
+ }
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_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 if (KeyDescVer == KEY_DESC_TKIP)
+ {
+ RT_HMAC_MD5(PTK, LEN_PTK_KCK, OutBuffer, FrameLen, mic, MD5_DIGEST_SIZE);
+ }
+ else if (KeyDescVer == KEY_DESC_EXT)
+ {
+ UINT mlen = AES_KEY128_LENGTH;
+ AES_CMAC(OutBuffer, FrameLen, PTK, LEN_PTK_KCK, mic, &mlen);
+ }
+
+ /* 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;
+
+#ifdef WAPI_SUPPORT
+ case Ndis802_11EncryptionSMS4Enabled:
+ keyIdx = *(pIV) & 0xFF;
+ break;
+#endif /* WAPI_SUPPORT */
+ }
+
+ return keyIdx;
+
+}
+
+PCIPHER_KEY RTMPSwCipherKeySelection(
+ IN RTMP_ADAPTER *pAd,
+ IN PUCHAR pIV,
+ IN RX_BLK *pRxBlk,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ PCIPHER_KEY pKey = NULL;
+ UCHAR keyIdx = 0;
+ UINT8 CipherAlg = Ndis802_11EncryptionDisabled;
+
+ 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 (pRxBlk->pRxInfo->U2M)
+ {
+ CipherAlg = pEntry->WepStatus;
+ }
+ else
+ {
+ }
+
+
+ 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 (pRxBlk->pRxInfo->U2M)
+ pKey = &pEntry->PairwiseKey;
+ else {
+ pKey = &pAd->SharedKey[pEntry->apidx][keyIdx];
+ }
+ }
+#ifdef WAPI_SUPPORT
+ else if (CipherAlg == Ndis802_11EncryptionSMS4Enabled)
+ {
+ if (pRxBlk->pRxInfo->U2M)
+ pKey = &pEntry->PairwiseKey;
+ else
+ pKey = &pAd->SharedKey[pEntry->apidx][keyIdx];
+ }
+#endif /* WAPI_SUPPORT */
+
+ 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;
+#ifdef WAPI_SUPPORT
+#ifdef SOFT_ENCRYPT
+ case CIPHER_SMS4:
+ {
+ INT ret;
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, pHdr, DIR_READ, FALSE);
+#endif
+ if ((ret = RTMPSoftDecryptSMS4(pHdr, FALSE, pKey, pData, &(*DataByteCnt))) != STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : SW decrypt SMS4 data fails(%d).\n", ret));
+ /* give up this frame*/
+ return NDIS_STATUS_FAILURE;
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, pHdr, DIR_READ, FALSE);
+#endif
+ }
+ break;
+#endif /* SOFT_ENCRYPT */
+#endif /* WAPI_SUPPORT */
+ 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;
+
+#ifdef WAPI_SUPPORT
+ if (CipherAlg == CIPHER_SMS4)
+ {
+ /* Construct and insert WPI-SMS4 IV header to MPDU header */
+ RTMPConstructWPIIVHdr(key_id, pTxIv, pHdrIv);
+ *hdr_iv_len = LEN_WPI_IV_HDR;
+ }
+ else
+#endif /* WAPI_SUPPORT */
+ 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;
+
+#ifdef WAPI_SUPPORT
+#ifdef SOFT_ENCRYPT
+ if (CipherAlg == CIPHER_SMS4)
+ {
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, pHdr, DIR_READ, FALSE);
+#endif
+ /* Encrypt the MPDU data by software*/
+ RTMPSoftEncryptSMS4(pHdr,
+ pSrcBufData,
+ SrcBufLen,
+ KeyIdx,
+ pKey->Key,
+ pKey->TxTsc);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, pHdr, DIR_READ, FALSE);
+#endif
+ *ext_len = LEN_WPI_MIC;
+ }
+ else
+#endif /* SOFT_ENCRYPT */
+#endif /* WAPI_SUPPORT */
+ if ((CipherAlg == CIPHER_WEP64) || (CipherAlg == CIPHER_WEP128))
+ {
+ /* Encrypt the MPDU data by software*/
+ RTMPSoftEncryptWEP(pAd,
+ pKey->TxTsc,
+ pKey,
+ pSrcBufData,
+ SrcBufLen);
+
+ *ext_len = LEN_ICV;
+ }
+ else if (CipherAlg == CIPHER_TKIP)
+ ;
+ else if (CipherAlg == CIPHER_AES)
+ {
+ /* Encrypt the MPDU data by software*/
+ RTMPSoftEncryptCCMP(pAd,
+ pHdr,
+ pKey->TxTsc,
+ pKey->Key,
+ pSrcBufData,
+ SrcBufLen);
+
+ *ext_len = LEN_CCMP_MIC;
+ }
+
+}
+
+PUINT8 WPA_ExtractSuiteFromRSNIE(
+ IN PUINT8 rsnie,
+ IN UINT rsnie_len,
+ IN UINT8 type,
+ OUT UINT8 *count)
+{
+ PEID_STRUCT pEid;
+ INT len;
+ PUINT8 pBuf;
+ INT offset = 0;
+
+ pEid = (PEID_STRUCT)rsnie;
+ len = rsnie_len - 2; /* exclude IE and length*/
+ pBuf = (PUINT8)&pEid->Octet[0];
+
+ /* set default value*/
+ *count = 0;
+
+ /* Check length*/
+ if ((len <= 0) || (pEid->Len != len))
+ {
+ DBGPRINT_ERR(("%s : The length is invalid\n", __FUNCTION__));
+ goto out;
+ }
+
+ /* Check WPA or WPA2*/
+ if (pEid->Eid == IE_WPA)
+ {
+ /* Check the length */
+ if (len < sizeof(RSNIE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The length is too short for WPA\n", __FUNCTION__));
+ goto out;
+ }
+ else
+ {
+ PRSNIE pRsnie;
+ UINT16 u_cnt;
+
+ pRsnie = (PRSNIE)pBuf;
+ u_cnt = cpu2le16(pRsnie->ucount);
+ offset = sizeof(RSNIE) + (LEN_OUI_SUITE * (u_cnt - 1));
+
+ if (len < offset)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) for WPA-RSN \n",
+ __FUNCTION__, offset, len));
+ goto out;
+ }
+ else
+ {
+ /* Get the group cipher*/
+ if (type == GROUP_SUITE)
+ {
+ *count = 1;
+ return pRsnie->mcast;
+ }
+ /* Get the pairwise cipher suite*/
+ else if (type == PAIRWISE_SUITE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
+ __FUNCTION__, u_cnt));
+ *count = u_cnt;
+ return pRsnie->ucast[0].oui;
+ }
+ }
+ }
+ }
+ else if (pEid->Eid == IE_RSN)
+ {
+ if (len < sizeof(RSNIE2))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The length is too short for WPA2\n", __FUNCTION__));
+ goto out;
+ }
+ else
+ {
+ PRSNIE2 pRsnie2;
+ UINT16 u_cnt;
+
+ pRsnie2 = (PRSNIE2)pBuf;
+ u_cnt = cpu2le16(pRsnie2->ucount);
+ offset = sizeof(RSNIE2) + (LEN_OUI_SUITE * (u_cnt - 1));
+
+ if (len < offset)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) for WPA2-RSN \n",
+ __FUNCTION__, offset, len));
+ goto out;
+ }
+ else
+ {
+ /* Get the group cipher*/
+ if (type == GROUP_SUITE)
+ {
+ *count = 1;
+ return pRsnie2->mcast;
+ }
+ /* Get the pairwise cipher suite*/
+ else if (type == PAIRWISE_SUITE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
+ __FUNCTION__, u_cnt));
+ *count = u_cnt;
+ return pRsnie2->ucast[0].oui;
+ }
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Unknown IE (%d)\n", __FUNCTION__, pEid->Eid));
+ goto out;
+ }
+
+ /* skip group cipher and pairwise cipher suite */
+ pBuf += offset;
+ len -= offset;
+
+ /* Ready to extract the AKM information and its count */
+ if (len < sizeof(RSNIE_AUTH))
+ {
+ DBGPRINT_ERR(("%s : The length of AKM of RSN is too short\n", __FUNCTION__));
+ goto out;
+ }
+ else
+ {
+ PRSNIE_AUTH pAkm;
+ UINT16 a_cnt;
+
+ /* pointer to AKM count */
+ pAkm = (PRSNIE_AUTH)pBuf;
+ a_cnt = cpu2le16(pAkm->acount);
+ offset = sizeof(RSNIE_AUTH) + (LEN_OUI_SUITE * (a_cnt - 1));
+
+ if (len < offset)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) for AKM \n",
+ __FUNCTION__, offset, len));
+ goto out;
+ }
+ else
+ {
+ /* Get the AKM suite */
+ if (type == AKM_SUITE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
+ __FUNCTION__, a_cnt));
+ *count = a_cnt;
+ return pAkm->auth[0].oui;
+ }
+ }
+ }
+
+ /* For WPA1, the remaining shall be ignored. */
+ if (pEid->Eid == IE_WPA)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : The remaining shall be ignored in WPA mode\n",
+ __FUNCTION__));
+ goto out;
+ }
+
+ /* skip the AKM capability */
+ pBuf += offset;
+ len -= offset;
+
+ /* Parse the RSN Capabilities */
+ if (len < sizeof(RSN_CAPABILITIES))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : The peer RSNIE doesn't include RSN-Cap\n", __FUNCTION__));
+ goto out;
+ }
+ else
+ {
+ /* Report the content of the RSN capabilities */
+ if (type == RSN_CAP_INFO)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : Extract RSN Capabilities\n", __FUNCTION__));
+ *count = 1;
+ return pBuf;
+ }
+
+ /* skip RSN capability (2-bytes) */
+ offset = sizeof(RSN_CAPABILITIES);
+ pBuf += offset;
+ len -= offset;
+ }
+
+ /* Extract PMKID-list field */
+ if (len < sizeof(UINT16))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : The peer RSNIE doesn't include PMKID list Count\n", __FUNCTION__));
+ goto out;
+ }
+ else
+ {
+ UINT16 p_count;
+ PUINT8 pPmkidList = NULL;
+
+ NdisMoveMemory(&p_count, pBuf, sizeof(UINT16));
+ p_count = cpu2le16(p_count);
+
+ /* Get count of the PMKID list */
+ if (p_count > 0)
+ {
+ PRSNIE_PMKID pRsnPmkid;
+
+ /* the expected length of PMKID-List field */
+ offset = sizeof(RSNIE_PMKID) + (LEN_PMKID * (p_count - 1));
+
+ /* sanity check about the length of PMKID-List field */
+ if (len < offset)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The expected lenght(%d) exceed the remaining length(%d) in PMKID-field \n",
+ __FUNCTION__, offset, len));
+ goto out;
+ }
+
+ /* pointer to PMKID field */
+ pRsnPmkid = (PRSNIE_PMKID)pBuf;
+ pPmkidList = pRsnPmkid->pmkid[0].list;
+
+ }
+ else
+ {
+ /* The PMKID field shall be without PMKID-List */
+ offset = sizeof(UINT16);
+ pPmkidList = NULL;
+ }
+
+
+ /* Extract PMKID list and its count */
+ if (type == PMKID_LIST)
+ {
+ *count = p_count;
+ return pPmkidList;
+ }
+
+ /* skip the PMKID field */
+ pBuf += offset;
+ len -= offset;
+
+ }
+
+
+out:
+ *count = 0;
+ return NULL;
+
+}
+
+VOID WpaShowAllsuite(
+ IN PUINT8 rsnie,
+ IN UINT rsnie_len)
+{
+ PUINT8 pSuite = NULL;
+ UINT8 count;
+
+ hex_dump("RSNIE", rsnie, rsnie_len);
+
+ /* group cipher*/
+ if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count)) != NULL)
+ {
+ hex_dump("group cipher", pSuite, 4*count);
+ }
+
+ /* pairwise cipher*/
+ if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count)) != NULL)
+ {
+ hex_dump("pairwise cipher", pSuite, 4*count);
+ }
+
+ /* AKM*/
+ if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL)
+ {
+ hex_dump("AKM suite", pSuite, 4*count);
+ }
+
+ /* PMKID*/
+ if ((pSuite = WPA_ExtractSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL)
+ {
+ hex_dump("PMKID", pSuite, LEN_PMKID);
+ }
+
+}
+
+VOID RTMPInsertRSNIE(
+ IN PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PUINT8 rsnie_ptr,
+ IN UINT8 rsnie_len,
+ IN PUINT8 pmkid_ptr,
+ IN UINT8 pmkid_len)
+{
+ PUCHAR pTmpBuf;
+ ULONG TempLen = 0;
+ UINT8 extra_len = 0;
+ UINT16 pmk_count = 0;
+ UCHAR ie_num;
+ UINT8 total_len = 0;
+ UCHAR WPA2_OUI[3]={0x00,0x0F,0xAC};
+
+ pTmpBuf = pFrameBuf;
+
+ /* PMKID-List Must larger than 0 and the multiple of 16. */
+ if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0))
+ {
+ extra_len = sizeof(UINT16) + pmkid_len;
+
+ pmk_count = (pmkid_len >> 4);
+ pmk_count = cpu2le16(pmk_count);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : no PMKID-List included(%d).\n", __FUNCTION__, pmkid_len));
+ }
+
+ if (rsnie_len != 0)
+ {
+ ie_num = IE_WPA;
+ total_len = rsnie_len;
+
+ if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI)))
+ {
+ ie_num = IE_RSN;
+ total_len += extra_len;
+ }
+
+ /* construct RSNIE body */
+ MakeOutgoingFrame(pTmpBuf, &TempLen,
+ 1, &ie_num,
+ 1, &total_len,
+ rsnie_len, rsnie_ptr,
+ END_OF_ARGS);
+
+ pTmpBuf += TempLen;
+ *pFrameLen = *pFrameLen + TempLen;
+
+ if (ie_num == IE_RSN)
+ {
+ /* Insert PMKID-List field */
+ if (extra_len > 0)
+ {
+ MakeOutgoingFrame(pTmpBuf, &TempLen,
+ 2, &pmk_count,
+ pmkid_len, pmkid_ptr,
+ END_OF_ARGS);
+
+ pTmpBuf += TempLen;
+ *pFrameLen = *pFrameLen + TempLen;
+ }
+ }
+ }
+
+ return;
+}
+
+
+VOID WPAInstallPairwiseKey(
+ PRTMP_ADAPTER pAd,
+ UINT8 BssIdx,
+ PMAC_TABLE_ENTRY pEntry,
+ BOOLEAN bAE)
+{
+ NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
+
+ /* Assign the pairwise cipher algorithm */
+ if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
+ else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (wcid-%d)\n",
+ __FUNCTION__, pEntry->Aid));
+ return;
+ }
+
+ /* Assign key material and its length */
+ pEntry->PairwiseKey.KeyLen = LEN_TK;
+ NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[OFFSET_OF_PTK_TK], LEN_TK);
+ if (pEntry->PairwiseKey.CipherAlg == CIPHER_TKIP)
+ {
+ if (bAE)
+ {
+ NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[OFFSET_OF_AP_TKIP_TX_MIC], LEN_TKIP_MIC);
+ NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[OFFSET_OF_AP_TKIP_RX_MIC], LEN_TKIP_MIC);
+ }
+ else
+ {
+ NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[OFFSET_OF_STA_TKIP_TX_MIC], LEN_TKIP_MIC);
+ NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[OFFSET_OF_STA_TKIP_RX_MIC], LEN_TKIP_MIC);
+ }
+ }
+
+#ifdef SOFT_ENCRYPT
+ if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SOFTWARE_ENCRYPT))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("===> SW_ENC ON(wcid=%d) \n", pEntry->Aid));
+ NdisZeroMemory(pEntry->PairwiseKey.TxTsc, LEN_WPA_TSC);
+ NdisZeroMemory(pEntry->PairwiseKey.RxTsc, LEN_WPA_TSC);
+ }
+ else
+#endif /* SOFT_ENCRYPT */
+ {
+ /* Add Pair-wise key to Asic */
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ (UCHAR)pEntry->Aid,
+ &pEntry->PairwiseKey);
+
+ RTMPSetWcidSecurityInfo(pAd,
+ BssIdx,
+ 0,
+ pEntry->PairwiseKey.CipherAlg,
+ (UCHAR)pEntry->Aid,
+ PAIRWISEKEYTABLE);
+ }
+
+}
+
+VOID WPAInstallSharedKey(
+ PRTMP_ADAPTER pAd,
+ UINT8 GroupCipher,
+ UINT8 BssIdx,
+ UINT8 KeyIdx,
+ UINT8 Wcid,
+ BOOLEAN bAE,
+ PUINT8 pGtk,
+ UINT8 GtkLen)
+{
+ PCIPHER_KEY pSharedKey;
+
+ if (BssIdx >= MAX_MBSSID_NUM(pAd))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The BSS-index(%d) is out of range for MBSSID link. \n",
+ __FUNCTION__, BssIdx));
+ return;
+ }
+
+ pSharedKey = &pAd->SharedKey[BssIdx][KeyIdx];
+ NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
+
+ /* Set the group cipher */
+ if (GroupCipher == Ndis802_11GroupWEP40Enabled)
+ pSharedKey->CipherAlg = CIPHER_WEP64;
+ else if (GroupCipher == Ndis802_11GroupWEP104Enabled)
+ pSharedKey->CipherAlg = CIPHER_WEP128;
+ else if (GroupCipher == Ndis802_11Encryption2Enabled)
+ pSharedKey->CipherAlg = CIPHER_TKIP;
+ else if (GroupCipher == Ndis802_11Encryption3Enabled)
+ pSharedKey->CipherAlg = CIPHER_AES;
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (IF/ra%d) \n",
+ __FUNCTION__, BssIdx));
+ return;
+ }
+
+ /* Set the key material and its length */
+ if (GroupCipher == Ndis802_11GroupWEP40Enabled ||
+ GroupCipher == Ndis802_11GroupWEP104Enabled)
+ {
+ /* Sanity check the length */
+ if ((GtkLen != LEN_WEP64) && (GtkLen != LEN_WEP128))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : (IF/ra%d) WEP key invlaid(%d) \n",
+ __FUNCTION__, BssIdx, GtkLen));
+ return;
+ }
+
+ pSharedKey->KeyLen = GtkLen;
+ NdisMoveMemory(pSharedKey->Key, pGtk, GtkLen);
+ }
+ else
+ {
+ /* Sanity check the length */
+ if (GtkLen < LEN_TK)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : (IF/ra%d) WPA key invlaid(%d) \n",
+ __FUNCTION__, BssIdx, GtkLen));
+ return;
+ }
+
+ pSharedKey->KeyLen = LEN_TK;
+ NdisMoveMemory(pSharedKey->Key, pGtk, LEN_TK);
+ if (pSharedKey->CipherAlg == CIPHER_TKIP)
+ {
+ if (bAE)
+ {
+ NdisMoveMemory(pSharedKey->TxMic, pGtk + 16, LEN_TKIP_MIC);
+ NdisMoveMemory(pSharedKey->RxMic, pGtk + 24, LEN_TKIP_MIC);
+ }
+ else
+ {
+ NdisMoveMemory(pSharedKey->TxMic, pGtk + 24, LEN_TKIP_MIC);
+ NdisMoveMemory(pSharedKey->RxMic, pGtk + 16, LEN_TKIP_MIC);
+ }
+ }
+ }
+
+ /* Update group key table(0x6C00) and group key mode(0x7000) */
+ AsicAddSharedKeyEntry(
+ pAd,
+ BssIdx,
+ KeyIdx,
+ pSharedKey);
+
+ /* When Wcid isn't zero, it means that this is a Authenticator Role.
+ Only Authenticator entity needs to set HW IE/EIV table (0x6000)
+ and WCID attribute table (0x6800) for group key. */
+ if (Wcid != 0)
+ {
+ RTMPSetWcidSecurityInfo(pAd,
+ BssIdx,
+ KeyIdx,
+ pSharedKey->CipherAlg,
+ Wcid,
+ SHAREDKEYTABLE);
+ }
+}
+
+VOID RTMPSetWcidSecurityInfo(
+ PRTMP_ADAPTER pAd,
+ UINT8 BssIdx,
+ UINT8 KeyIdx,
+ UINT8 CipherAlg,
+ UINT8 Wcid,
+ UINT8 KeyTabFlag)
+{
+ UINT32 IV = 0;
+ UINT8 IV_KEYID = 0;
+
+ /* Prepare initial IV value */
+ if (CipherAlg == CIPHER_WEP64 || CipherAlg == CIPHER_WEP128)
+ {
+ INT i;
+ UCHAR TxTsc[LEN_WEP_TSC];
+
+ /* Generate 3-bytes IV randomly for encryption using */
+ for(i = 0; i < LEN_WEP_TSC; i++)
+ TxTsc[i] = RandomByte(pAd);
+
+ /* Update HW IVEIV table */
+ IV_KEYID = (KeyIdx << 6);
+ IV = (IV_KEYID << 24) |
+ (TxTsc[2] << 16) |
+ (TxTsc[1] << 8) |
+ (TxTsc[0]);
+ }
+ else if (CipherAlg == CIPHER_TKIP || CipherAlg == CIPHER_AES)
+ {
+ /* Set IVEIV as 1 in Asic -
+ In IEEE 802.11-2007 8.3.3.4.3 described :
+ The PN shall be implemented as a 48-bit monotonically incrementing
+ non-negative integer, initialized to 1 when the corresponding
+ temporal key is initialized or refreshed. */
+ IV_KEYID = (KeyIdx << 6) | 0x20;
+ IV = (IV_KEYID << 24) | 1;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Unsupport cipher Alg (%d) for Wcid-%d \n",
+ __FUNCTION__, CipherAlg, Wcid));
+ return;
+ }
+ /* Update WCID IV/EIV table */
+ AsicUpdateWCIDIVEIV(pAd, Wcid, IV, 0);
+
+ /* Update WCID attribute entry */
+ AsicUpdateWcidAttributeEntry(pAd,
+ BssIdx,
+ KeyIdx,
+ CipherAlg,
+ Wcid,
+ KeyTabFlag);
+
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/common/crypt_aes.c b/cleopatre/devkit/mt7601udrv/common/crypt_aes.c
new file mode 100644
index 0000000000..e5050e493b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/crypt_aes.c
@@ -0,0 +1,1605 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ AES
+
+ Abstract:
+ RFC 3394: Advanced Encryption Standard (AES) Key Wrap Algorithm
+ RFC 3601: Counter with CBC-MAC (CCM)
+ RFC 4493: The AES-CMAC Algorithm
+ FIPS PUBS 197: ADVANCED ENCRYPTION STANDARD (AES)
+ NIST 800-38A: Recommendation for Block Cipher Modes of Operation
+ NIST 800-38C: The CCM Mode for Authentication and Confidentiality
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2009/05/19 Create AES-Key Wrap
+ Eddy 2009/04/20 Create AES-CMAC, AES-CCM
+ Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC
+***************************************************************************/
+
+#include "crypt_aes.h"
+
+
+/* The value given by [x^(i-1),{00},{00},{00}], with x^(i-1) being powers of x in the field GF(2^8). */
+static const UINT32 aes_rcon[] = {
+ 0x00000000, 0x01000000, 0x02000000, 0x04000000,
+ 0x08000000, 0x10000000, 0x20000000, 0x40000000,
+ 0x80000000, 0x1B000000, 0x36000000};
+
+static const UINT8 aes_sbox_enc[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7 ,0xab, 0x76, /* 0 */
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4 ,0x72, 0xc0, /* 1 */
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8 ,0x31, 0x15, /* 2 */
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27 ,0xb2, 0x75, /* 3 */
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3 ,0x2f, 0x84, /* 4 */
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c ,0x58, 0xcf, /* 5 */
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c ,0x9f, 0xa8, /* 6 */
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff ,0xf3, 0xd2, /* 7 */
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d ,0x19, 0x73, /* 8 */
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e ,0x0b, 0xdb, /* 9 */
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95 ,0xe4, 0x79, /* a */
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a ,0xae, 0x08, /* b */
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd ,0x8b, 0x8a, /* c */
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1 ,0x1d, 0x9e, /* d */
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55 ,0x28, 0xdf, /* e */
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54 ,0xbb, 0x16, /* f */
+};
+
+static const UINT8 aes_sbox_dec[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, /* 0 */
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, /* 1 */
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, /* 2 */
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, /* 3 */
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, /* 4 */
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, /* 5 */
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, /* 6 */
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, /* 7 */
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, /* 8 */
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, /* 9 */
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, /* a */
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, /* b */
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, /* c */
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, /* d */
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, /* e */
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, /* f */
+};
+
+/* ArrayIndex*{02} */
+static const UINT8 aes_mul_2[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, /* 0 */
+ 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, /* 1 */
+ 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, /* 2 */
+ 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, /* 3 */
+ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, /* 4 */
+ 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 5 */
+ 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 6 */
+ 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, /* 7 */
+ 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, /* 8 */
+ 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, /* 9 */
+ 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, /* a */
+ 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, /* b */
+ 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, /* c */
+ 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, /* d */
+ 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, /* e */
+ 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, /* f */
+};
+
+/* ArrayIndex*{03} */
+static const UINT8 aes_mul_3[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, /* 0 */
+ 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, /* 1 */
+ 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, /* 2 */
+ 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, /* 3 */
+ 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, /* 4 */
+ 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, /* 5 */
+ 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, /* 6 */
+ 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, /* 7 */
+ 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, /* 8 */
+ 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, /* 9 */
+ 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, /* a */
+ 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, /* b */
+ 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, /* c */
+ 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, /* d */
+ 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, /* e */
+ 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, /* f */
+};
+
+/* ArrayIndex*{09} */
+static const UINT8 aes_mul_9[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, /* 0 */
+ 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, /* 1 */
+ 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, /* 2 */
+ 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, /* 3 */
+ 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, /* 4 */
+ 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, /* 5 */
+ 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, /* 6 */
+ 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, /* 7 */
+ 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, /* 8 */
+ 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, /* 9 */
+ 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, /* a */
+ 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, /* b */
+ 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, /* c */
+ 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, /* d */
+ 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, /* e */
+ 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, /* f */
+};
+
+/* ArrayIndex*{0b} */
+static const UINT8 aes_mul_b[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, /* 0 */
+ 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, /* 1 */
+ 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, /* 2 */
+ 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, /* 3 */
+ 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, /* 4 */
+ 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, /* 5 */
+ 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, /* 6 */
+ 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, /* 7 */
+ 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, /* 8 */
+ 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, /* 9 */
+ 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, /* a */
+ 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, /* b */
+ 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, /* c */
+ 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, /* d */
+ 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, /* e */
+ 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, /* f */
+};
+
+/* ArrayIndex*{0d} */
+static const UINT8 aes_mul_d[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, /* 0 */
+ 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, /* 1 */
+ 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, /* 2 */
+ 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, /* 3 */
+ 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, /* 4 */
+ 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, /* 5 */
+ 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, /* 6 */
+ 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, /* 7 */
+ 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, /* 8 */
+ 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, /* 9 */
+ 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, /* a */
+ 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, /* b */
+ 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, /* c */
+ 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, /* d */
+ 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, /* e */
+ 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, /* f */
+};
+
+/* ArrayIndex*{0e} */
+static const UINT8 aes_mul_e[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, /* 0 */
+ 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, /* 1 */
+ 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, /* 2 */
+ 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, /* 3 */
+ 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, /* 4 */
+ 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, /* 5 */
+ 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, /* 6 */
+ 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, /* 7 */
+ 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, /* 8 */
+ 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, /* 9 */
+ 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, /* a */
+ 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, /* b */
+ 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, /* c */
+ 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, /* d */
+ 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, /* e */
+ 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, /* f */
+};
+
+/* For AES_CMAC */
+#define AES_MAC_LENGTH 16 /* 128-bit string */
+static UINT8 Const_Zero[16] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static UINT8 Const_Rb[16] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
+
+/*
+========================================================================
+Routine Description:
+ AES key expansion (key schedule)
+
+Arguments:
+ Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+ KeyLength The length of cipher key in bytes
+ paes_ctx Pointer to AES_CTX_STRUC
+
+Return Value:
+ paes_ctx Retrun the KeyWordExpansion of AES_CTX_STRUC
+
+Note:
+ Pseudo code for key expansion
+ ------------------------------------------
+ Nk = (key length/4);
+
+ while (i < Nk)
+ KeyWordExpansion[i] = word(key[4*i], key[4*i + 1], key[4*i + 2], key[4*i + 3]);
+ i++;
+ end while
+
+ while (i < ((key length/4 + 6 + 1)*4) )
+ temp = KeyWordExpansion[i - 1];
+ if (i % Nk ==0)
+ temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk];
+ else if ((Nk > 6) && (i % 4 == 4))
+ temp = SubWord(temp);
+ end if
+
+ KeyWordExpansion[i] = KeyWordExpansion[i - Nk]^ temp;
+ i++;
+ end while
+========================================================================
+*/
+VOID RT_AES_KeyExpansion (
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ INOUT AES_CTX_STRUC *paes_ctx)
+{
+ UINT KeyIndex = 0;
+ UINT NumberOfWordOfKey, NumberOfWordOfKeyExpansion;
+ UINT8 TempWord[AES_KEY_ROWS], Temp;
+ UINT32 Temprcon;
+
+ NumberOfWordOfKey = KeyLength >> 2;
+ while (KeyIndex < NumberOfWordOfKey)
+ {
+ paes_ctx->KeyWordExpansion[0][KeyIndex] = Key[4*KeyIndex];
+ paes_ctx->KeyWordExpansion[1][KeyIndex] = Key[4*KeyIndex + 1];
+ paes_ctx->KeyWordExpansion[2][KeyIndex] = Key[4*KeyIndex + 2];
+ paes_ctx->KeyWordExpansion[3][KeyIndex] = Key[4*KeyIndex + 3];
+ KeyIndex++;
+ }
+
+ 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++;
+ }
+}
+
+
+/*
+========================================================================
+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;
+ }
+ 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;
+ }
+ 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;
+ }
+
+ /* 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];
+ }
+
+ /* 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);
+}
+
+
+/*
+========================================================================
+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;
+ }
+ 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;
+ }
+ 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;
+ }
+
+ /* 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];
+ }
+ }
+
+ /* 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);
+}
+
+
+
+/*
+========================================================================
+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;
+ }
+
+ 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;
+ }
+ 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);
+ }
+
+ /*
+ * 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;
+ }
+ for (Temp_Index = 0; Temp_Index < MACLength; Temp_Index++)
+ MACText[Temp_Index] = Block_MAC[Temp_Index];
+}
+
+
+/*
+========================================================================
+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;
+ }
+
+ if ((NonceLength < 7) || (NonceLength > 13)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Encrypt: A valid nonce length is 7-13 bytes\n"));
+ return -2;
+ }
+
+ 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;
+ }
+
+ if (*CipherTextLength < (PlainTextLength + MACLength)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Encrypt: The CipherTextLength is not enough.\n"));
+ return -4;
+ }
+
+
+ /*
+ * 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;
+ }
+ for (Temp_Index = 0; Temp_Index < MACLength; Temp_Index++)
+ CipherText[PlainTextLength + Temp_Index] = Block_MAC[Temp_Index];
+ *CipherTextLength = PlainTextLength + MACLength;
+
+ return 0;
+}
+
+
+/*
+========================================================================
+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;
+ }
+
+ if ((NonceLength < 7) || (NonceLength > 13)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Decrypt: A valid nonce length is 7-13 bytes\n"));
+ return -2;
+ }
+
+ 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;
+ }
+
+ if (*PlainTextLength < (CipherTextLength - MACLength)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CCM_Decrypt: The PlainTextLength is not enough.\n"));
+ return -4;
+ }
+
+ /*
+ * 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;
+ }
+ *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;
+ }
+
+ return 0;
+}
+
+
+/*
+========================================================================
+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;
+ }
+
+ /* 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];
+ }
+
+ /*
+ * 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];
+ }
+}
+
+
+/*
+========================================================================
+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;
+ }
+ 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;
+ }
+
+ /* 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);
+ }
+ 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];
+ }
+ RT_AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, MACText, MACTextLength);
+}
+
+
+/* For AES_Key_Wrap */
+#define AES_KEY_WRAP_IV_LENGTH 8 /* 64-bit */
+#define AES_KEY_WRAP_BLOCK_SIZE 8 /* 64-bit */
+static UINT8 Default_IV[8] = {
+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6};
+
+/*
+========================================================================
+Routine Description:
+ AES-CBC encryption
+
+Arguments:
+ PlainText Plain text
+ PlainTextLength The length of plain text in bytes
+ Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+ KeyLength The length of cipher key in bytes
+ IV Initialization vector, it may be 16 bytes (128 bits)
+ IVLength The length of initialization vector in bytes
+ CipherTextLength The length of allocated cipher text in bytes
+
+Return Value:
+ CipherText Return cipher text
+ CipherTextLength Return the length of real used cipher text in bytes
+
+Note:
+ Reference to RFC 3602 and NIST 800-38A
+========================================================================
+*/
+VOID AES_CBC_Encrypt (
+ IN UINT8 PlainText[],
+ IN UINT PlainTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ IN UINT8 IV[],
+ IN UINT IVLength,
+ OUT UINT8 CipherText[],
+ INOUT UINT *CipherTextLength)
+{
+ UINT PaddingSize, PlainBlockStart, CipherBlockStart, CipherBlockSize;
+ UINT Index;
+ UINT8 Block[AES_BLOCK_SIZES];
+
+ /*
+ * 1. Check the input parameters
+ * - CipherTextLength > (PlainTextLength + Padding size), Padding size = block size - (PlainTextLength % block size)
+ * - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
+ * - IV length must be 16 bytes(128 bits)
+ */
+ PaddingSize = ((UINT) AES_BLOCK_SIZES) - (PlainTextLength % ((UINT)AES_BLOCK_SIZES));
+ if (*CipherTextLength < (PlainTextLength + PaddingSize)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: cipher text length is %d bytes < (plain text length %d bytes + padding size %d bytes).\n",
+ *CipherTextLength, PlainTextLength, PaddingSize));
+ return;
+ }
+ if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+ KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+ return;
+ }
+ if (IVLength != AES_CBC_IV_LENGTH) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
+ IVLength, AES_CBC_IV_LENGTH));
+ return;
+ }
+
+
+ /*
+ * 2. Main algorithm
+ * - Plain text divide into serveral blocks (16 bytes/block)
+ * - If plain text is divided with no remainder by block, add a new block and padding size = block(16 bytes)
+ * - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
+ * - Execute RT_AES_Encrypt procedure.
+ *
+ * - Padding method: The remainder bytes will be filled with padding size (1 byte)
+ */
+ PlainBlockStart = 0;
+ CipherBlockStart = 0;
+ while ((PlainTextLength - PlainBlockStart) >= AES_BLOCK_SIZES)
+ {
+ if (CipherBlockStart == 0) {
+ for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+ Block[Index] = PlainText[PlainBlockStart + Index]^IV[Index];
+ } else {
+ for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+ Block[Index] = PlainText[PlainBlockStart + Index]^CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
+ }
+
+ CipherBlockSize = *CipherTextLength - CipherBlockStart;
+ RT_AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
+
+ PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
+ CipherBlockStart += CipherBlockSize;
+ }
+
+ NdisMoveMemory(Block, (&PlainText[0] + PlainBlockStart), (PlainTextLength - PlainBlockStart));
+ NdisFillMemory((Block + (((UINT) AES_BLOCK_SIZES) -PaddingSize)), PaddingSize, (UINT8) PaddingSize);
+ if (CipherBlockStart == 0) {
+ for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+ Block[Index] ^= IV[Index];
+ } else {
+ for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+ Block[Index] ^= CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
+ }
+ CipherBlockSize = *CipherTextLength - CipherBlockStart;
+ RT_AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
+ CipherBlockStart += CipherBlockSize;
+ *CipherTextLength = CipherBlockStart;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ AES-CBC decryption
+
+Arguments:
+ CipherText Cipher text
+ CipherTextLength The length of cipher text in bytes
+ Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+ KeyLength The length of cipher key in bytes
+ IV Initialization vector, it may be 16 bytes (128 bits)
+ IVLength The length of initialization vector in bytes
+ PlainTextLength The length of allocated plain text in bytes
+
+Return Value:
+ PlainText Return plain text
+ PlainTextLength Return the length of real used plain text in bytes
+
+Note:
+ Reference to RFC 3602 and NIST 800-38A
+========================================================================
+*/
+VOID AES_CBC_Decrypt (
+ IN UINT8 CipherText[],
+ IN UINT CipherTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ IN UINT8 IV[],
+ IN UINT IVLength,
+ OUT UINT8 PlainText[],
+ INOUT UINT *PlainTextLength)
+{
+ UINT PaddingSize, PlainBlockStart, CipherBlockStart, PlainBlockSize;
+ UINT Index;
+
+ /*
+ * 1. Check the input parameters
+ * - CipherTextLength must be divided with no remainder by block
+ * - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
+ * - IV length must be 16 bytes(128 bits)
+ */
+ if ((CipherTextLength % AES_BLOCK_SIZES) != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: cipher text length is %d bytes, it can't be divided with no remainder by block size(%d).\n",
+ CipherTextLength, AES_BLOCK_SIZES));
+ return;
+ }
+ if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+ KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+ return;
+ }
+ if (IVLength != AES_CBC_IV_LENGTH) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
+ IVLength, AES_CBC_IV_LENGTH));
+ return;
+ }
+
+
+ /*
+ * 2. Main algorithm
+ * - Cypher text divide into serveral blocks (16 bytes/block)
+ * - Execute RT_AES_Decrypt procedure.
+ * - Remove padding bytes, padding size is the last byte of plain text
+ */
+ CipherBlockStart = 0;
+ PlainBlockStart = 0;
+ while ((CipherTextLength - CipherBlockStart) >= AES_BLOCK_SIZES)
+ {
+ PlainBlockSize = *PlainTextLength - PlainBlockStart;
+ RT_AES_Decrypt(CipherText + CipherBlockStart, AES_BLOCK_SIZES , Key, KeyLength, PlainText + PlainBlockStart, &PlainBlockSize);
+
+ if (PlainBlockStart == 0) {
+ for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+ PlainText[PlainBlockStart + Index] ^= IV[Index];
+ } else {
+ for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+ PlainText[PlainBlockStart + Index] ^= CipherText[CipherBlockStart + Index - ((UINT) AES_BLOCK_SIZES)];
+ }
+
+ CipherBlockStart += AES_BLOCK_SIZES;
+ PlainBlockStart += PlainBlockSize;
+ }
+
+ PaddingSize = (UINT8) PlainText[PlainBlockStart -1];
+ *PlainTextLength = PlainBlockStart - PaddingSize;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ AES key wrap algorithm
+
+Arguments:
+ PlainText Plain text
+ PlainTextLength The length of plain text in bytes
+ Key Cipher key
+ KeyLength The length of cipher key in bytes depend on block cipher (16, 24, or 32 bytes)
+
+Return Value:
+ CipherText The ciphertext
+ CipherTextLength Return the length of the ciphertext in bytes
+
+Function Value:
+ 0: Success
+ -1: The key length must be 16, 24, or 32 bytes
+ -2: Not enough memory
+
+Note:
+ Reference to RFC 3394
+========================================================================
+*/
+INT AES_Key_Wrap (
+ IN UINT8 PlainText[],
+ IN UINT PlainTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 CipherText[],
+ OUT UINT *CipherTextLength)
+{
+ UINT8 IV[8], Block_B[16], Block_Input[16];
+ UINT8 *pResult;
+ UINT Temp_Length = 0, Number_Of_Block = 0;
+ INT Index_i = 0, Index_j = 0;
+
+ /*
+ * 0. Check input parameter
+ */
+ if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Wrap: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+ KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+ return -1;
+ } /* End of if */
+ os_alloc_mem(NULL, (UCHAR **)&pResult, sizeof(UINT8)*PlainTextLength);
+/* if ((pResult = (UINT8 *) kmalloc(sizeof(UINT8)*PlainTextLength, GFP_ATOMIC)) == NULL) {
+*/
+ if (pResult == NULL) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Wrap: allocate %d bytes memory failure.\n", sizeof(UINT8)*PlainTextLength));
+ return -2;
+ } /* End of if */
+
+
+ /*
+ * 1. Initialize variables
+ */
+ Number_Of_Block = PlainTextLength / AES_KEY_WRAP_BLOCK_SIZE; /* 64 bits each block
+*/
+ NdisMoveMemory(IV, Default_IV, AES_KEY_WRAP_IV_LENGTH);
+ NdisMoveMemory(pResult, PlainText, PlainTextLength);
+
+
+ /*
+ * 2. Calculate intermediate values
+ */
+ for (Index_j = 0;Index_j < 6 ;Index_j++)
+ {
+ for (Index_i = 0;Index_i < Number_Of_Block;Index_i++)
+ {
+ NdisMoveMemory(Block_Input, IV, 8);
+ NdisMoveMemory(Block_Input + 8, pResult + (Index_i*8), 8);
+ Temp_Length = sizeof(Block_B);
+ RT_AES_Encrypt(Block_Input, AES_BLOCK_SIZES , Key, KeyLength, Block_B, &Temp_Length);
+
+ NdisMoveMemory(IV, Block_B, 8);
+ IV[7] = Block_B[7] ^ ((Number_Of_Block * Index_j) + Index_i + 1);
+ NdisMoveMemory(pResult + (Index_i*8), (Block_B + 8), 8);
+ } /* End of for */
+ } /* End of for */
+
+
+ /*
+ * 3. Output the results
+ */
+ *CipherTextLength = PlainTextLength + AES_KEY_WRAP_IV_LENGTH;
+ NdisMoveMemory(CipherText, IV, AES_KEY_WRAP_IV_LENGTH);
+ NdisMoveMemory(CipherText + AES_KEY_WRAP_IV_LENGTH, pResult, PlainTextLength);
+
+/* kfree(pResult);
+*/
+ os_free_mem(NULL, pResult);
+ return 0;
+} /* End of AES_Key_Wrap */
+
+
+/*
+========================================================================
+Routine Description:
+ AES key unwrap algorithm
+
+Arguments:
+ CipherText The ciphertext
+ CipherTextLength The length of cipher text in bytes
+ Key Cipher key
+ KeyLength The length of cipher key in bytes depend on block cipher (16, 24, or 32 bytes)
+
+Return Value:
+ PlainText Plain text
+ PlainTextLength Return the length of the plain text in bytes
+
+Function Value:
+ 0: Success
+
+Note:
+ Reference to RFC 3394
+========================================================================
+*/
+INT AES_Key_Unwrap (
+ IN UINT8 CipherText[],
+ IN UINT CipherTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 PlainText[],
+ OUT UINT *PlainTextLength)
+{
+ UINT8 IV[8], Block_B[16], Block_Input[16];
+ UINT8 *pResult;
+ UINT Temp_Length = 0, Number_Of_Block = 0, PlainLength;
+ INT Index_i = 0, Index_j = 0;
+
+ /*
+ * 0. Check input parameter
+ */
+ PlainLength = CipherTextLength - AES_KEY_WRAP_IV_LENGTH;
+ if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Unwrap: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+ KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+ return -1;
+ } /* End of if */
+ os_alloc_mem(NULL, (UCHAR **)&pResult, sizeof(UINT8)*PlainLength);
+/* if ((pResult = (UINT8 *) kmalloc(sizeof(UINT8)*PlainLength, GFP_ATOMIC)) == NULL) {
+*/
+ if (pResult == NULL) {
+ DBGPRINT(RT_DEBUG_ERROR, ("AES_Key_Unwrap: allocate %d bytes memory failure.\n", sizeof(UINT8)*PlainLength));
+ return -2;
+ } /* End of if */
+
+
+ /*
+ * 1. Initialize variables
+ */
+ Number_Of_Block = PlainLength / AES_KEY_WRAP_BLOCK_SIZE; /* 64 bits each block
+*/
+ NdisMoveMemory(IV, CipherText, AES_KEY_WRAP_IV_LENGTH);
+ NdisMoveMemory(pResult, CipherText + AES_KEY_WRAP_IV_LENGTH, PlainLength);
+
+
+ /*
+ * 2. Calculate intermediate values
+ */
+ for (Index_j = 5;Index_j >= 0 ;Index_j--)
+ {
+ for (Index_i = (Number_Of_Block - 1);Index_i >= 0;Index_i--)
+ {
+ IV[7] = IV[7] ^ ((Number_Of_Block * Index_j) + Index_i + 1);
+ NdisMoveMemory(Block_Input, IV, 8);
+ NdisMoveMemory(Block_Input + 8, pResult + (Index_i*8), 8);
+ Temp_Length = sizeof(Block_B);
+ RT_AES_Decrypt(Block_Input, AES_BLOCK_SIZES , Key, KeyLength, Block_B, &Temp_Length);
+
+ NdisMoveMemory(IV, Block_B, 8);
+ NdisMoveMemory(pResult + (Index_i*8), (Block_B + 8), 8);
+ } /* End of for */
+ } /* End of for */
+
+ /*
+ * 3. Output the results
+ */
+ *PlainTextLength = PlainLength;
+ NdisMoveMemory(PlainText, pResult, PlainLength);
+
+/* kfree(pResult);
+*/
+ os_free_mem(NULL, pResult);
+ return 0;
+} /* End of AES_Key_Unwrap */
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/crypt_arc4.c b/cleopatre/devkit/mt7601udrv/common/crypt_arc4.c
new file mode 100644
index 0000000000..382b89631e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/crypt_arc4.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+
+/****************************************************************************
+ Module Name:
+ RC4
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2009/05/13 ARC4
+***************************************************************************/
+
+#include "crypt_arc4.h"
+
+
+/*
+========================================================================
+Routine Description:
+ ARC4 initialize the key block
+
+Arguments:
+ pARC4_CTX Pointer to ARC4 CONTEXT
+ Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+ KeyLength The length of cipher key in bytes
+
+========================================================================
+*/
+VOID ARC4_INIT (
+ IN ARC4_CTX_STRUC *pARC4_CTX,
+ IN PUCHAR pKey,
+ IN UINT KeyLength)
+{
+ UINT BlockIndex = 0, SWAPIndex = 0, KeyIndex = 0;
+ UINT8 TempValue = 0;
+
+ /*Initialize the block value*/
+ pARC4_CTX->BlockIndex1 = 0;
+ pARC4_CTX->BlockIndex2 = 0;
+ for (BlockIndex = 0; BlockIndex < ARC4_KEY_BLOCK_SIZE; BlockIndex++)
+ pARC4_CTX->KeyBlock[BlockIndex] = (UINT8) BlockIndex;
+
+ /*Key schedule*/
+ for (BlockIndex = 0; BlockIndex < ARC4_KEY_BLOCK_SIZE; BlockIndex++)
+ {
+ TempValue = pARC4_CTX->KeyBlock[BlockIndex];
+ KeyIndex = BlockIndex % KeyLength;
+ SWAPIndex = (SWAPIndex + TempValue + pKey[KeyIndex]) & 0xff;
+ pARC4_CTX->KeyBlock[BlockIndex] = pARC4_CTX->KeyBlock[SWAPIndex];
+ pARC4_CTX->KeyBlock[SWAPIndex] = TempValue;
+ } /* End of for */
+
+} /* End of ARC4_INIT */
+
+
+/*
+========================================================================
+Routine Description:
+ ARC4 encryption/decryption
+
+Arguments:
+ pARC4_CTX Pointer to ARC4 CONTEXT
+ InputText Input text
+ InputTextLength The length of input text in bytes
+
+Return Value:
+ OutputBlock Return output text
+ ========================================================================
+*/
+VOID ARC4_Compute (
+ IN ARC4_CTX_STRUC *pARC4_CTX,
+ IN UINT8 InputBlock[],
+ IN UINT InputBlockSize,
+ OUT UINT8 OutputBlock[])
+{
+ UINT InputIndex = 0;
+ UINT8 TempValue = 0;
+
+ for (InputIndex = 0; InputIndex < InputBlockSize; InputIndex++)
+ {
+ pARC4_CTX->BlockIndex1 = (pARC4_CTX->BlockIndex1 + 1) & 0xff;
+ TempValue = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1];
+ pARC4_CTX->BlockIndex2 = (pARC4_CTX->BlockIndex2 + TempValue) & 0xff;
+
+ pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1] = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2];
+ pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2] = TempValue;
+
+ TempValue = (TempValue + pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1]) & 0xff;
+ OutputBlock[InputIndex] = InputBlock[InputIndex]^pARC4_CTX->KeyBlock[TempValue];
+
+ } /* End of for */
+} /* End of ARC4_Compute */
+
+
+/*
+========================================================================
+Routine Description:
+ Discard the key length
+
+Arguments:
+ pARC4_CTX Pointer to ARC4 CONTEXT
+ Length Discard the key length
+
+========================================================================
+*/
+VOID ARC4_Discard_KeyLength (
+ IN ARC4_CTX_STRUC *pARC4_CTX,
+ IN UINT Length)
+{
+ UINT Index = 0;
+ UINT8 TempValue = 0;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ pARC4_CTX->BlockIndex1 = (pARC4_CTX->BlockIndex1 + 1) & 0xff;
+ TempValue = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1];
+ pARC4_CTX->BlockIndex2 = (pARC4_CTX->BlockIndex2 + TempValue) & 0xff;
+
+ pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex1] = pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2];
+ pARC4_CTX->KeyBlock[pARC4_CTX->BlockIndex2] = TempValue;
+ } /* End of for */
+
+} /* End of ARC4_Discard_KeyLength */
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/crypt_biginteger.c b/cleopatre/devkit/mt7601udrv/common/crypt_biginteger.c
new file mode 100644
index 0000000000..f15012f727
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/crypt_biginteger.c
@@ -0,0 +1,1116 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+#include "crypt_biginteger.h"
+
+
+#ifdef __KERNEL__
+#define DEBUGPRINT(fmt, args...) printk(KERN_ERR fmt, ## args)
+#else
+#define DEBUGPRINT(fmt, args...) printf(fmt, ## args)
+#endif /* __KERNEL__ */
+
+#define UINT32_HBITS(value) (((value) >> 0x10) & 0xffff)
+#define UINT32_LBITS(value) ((value) & 0xffff)
+#define UINT32_GETBYTE(value, index) (((value) >> ((index)*8)) & 0xff)
+#define UINT64_HBITS(value) (((value) >> 0x20) & 0xffffffff)
+#define UINT64_LBITS(value) ((value) & 0xffffffff)
+
+static UINT8 WPS_DH_P_VALUE[192] =
+{
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static UINT8 WPS_DH_R_VALUE[193] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+};
+
+static UINT8 WPS_DH_X_VALUE[184] =
+{
+ 0x36, 0xf0, 0x25, 0x5d, 0xde, 0x97, 0x3d, 0xcb,
+ 0x3b, 0x39, 0x9d, 0x74, 0x7f, 0x23, 0xe3, 0x2e,
+ 0xd6, 0xfd, 0xb1, 0xf7, 0x75, 0x98, 0x33, 0x8b,
+ 0xfd, 0xf4, 0x41, 0x59, 0xc4, 0xec, 0x64, 0xdd,
+ 0xae, 0xb5, 0xf7, 0x86, 0x71, 0xcb, 0xfb, 0x22,
+ 0x10, 0x6a, 0xe6, 0x4c, 0x32, 0xc5, 0xbc, 0xe4,
+ 0xcf, 0xd4, 0xf5, 0x92, 0x0d, 0xa0, 0xeb, 0xc8,
+ 0xb0, 0x1e, 0xca, 0x92, 0x92, 0xae, 0x3d, 0xba,
+ 0x1b, 0x7a, 0x4a, 0x89, 0x9d, 0xa1, 0x81, 0x39,
+ 0x0b, 0xb3, 0xbd, 0x16, 0x59, 0xc8, 0x12, 0x94,
+ 0xf4, 0x00, 0xa3, 0x49, 0x0b, 0xf9, 0x48, 0x12,
+ 0x11, 0xc7, 0x94, 0x04, 0xa5, 0x76, 0x60, 0x5a,
+ 0x51, 0x60, 0xdb, 0xee, 0x83, 0xb4, 0xe0, 0x19,
+ 0xb6, 0xd7, 0x99, 0xae, 0x13, 0x1b, 0xa4, 0xc2,
+ 0x3d, 0xff, 0x83, 0x47, 0x5e, 0x9c, 0x40, 0xfa,
+ 0x67, 0x25, 0xb7, 0xc9, 0xe3, 0xaa, 0x2c, 0x65,
+ 0x96, 0xe9, 0xc0, 0x57, 0x02, 0xdb, 0x30, 0xa0,
+ 0x7c, 0x9a, 0xa2, 0xdc, 0x23, 0x5c, 0x52, 0x69,
+ 0xe3, 0x9d, 0x0c, 0xa9, 0xdf, 0x7a, 0xad, 0x44,
+ 0x61, 0x2a, 0xd6, 0xf8, 0x8f, 0x69, 0x69, 0x92,
+ 0x98, 0xf3, 0xca, 0xb1, 0xb5, 0x43, 0x67, 0xfb,
+ 0x0e, 0x8b, 0x93, 0xf7, 0x35, 0xdc, 0x8c, 0xd8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+};
+
+static UINT8 WPS_DH_RRModP_VALUE[192] =
+{
+ 0xe3, 0xb3, 0x3c, 0x72, 0x59, 0x54, 0x1c, 0x01,
+ 0xee, 0x9c, 0x9a, 0x21, 0x6c, 0xc1, 0xeb, 0xd2,
+ 0xae, 0x59, 0x41, 0x04, 0x79, 0x29, 0xa1, 0xc7,
+ 0xe9, 0xc3, 0xfa, 0x02, 0xcc, 0x24, 0x56, 0xef,
+ 0x10, 0x26, 0x30, 0xfa, 0x9a, 0x36, 0xa5, 0x1f,
+ 0x57, 0xb5, 0x93, 0x48, 0x67, 0x98, 0x44, 0x60,
+ 0x0b, 0xe4, 0x96, 0x47, 0xa8, 0x7c, 0x7b, 0x37,
+ 0xf8, 0x05, 0x65, 0x64, 0x96, 0x9b, 0x7f, 0x02,
+ 0xdc, 0x54, 0x1a, 0x4e, 0xd4, 0x05, 0x3f, 0x54,
+ 0xd6, 0x2a, 0x0e, 0xea, 0xb2, 0x70, 0x52, 0x1b,
+ 0x22, 0xc2, 0x96, 0xe9, 0xd4, 0x6f, 0xec, 0x23,
+ 0x8e, 0x1a, 0xbd, 0x78, 0x02, 0x23, 0xb7, 0x6b,
+ 0xb8, 0xfe, 0x61, 0x21, 0x19, 0x6b, 0x7e, 0x88,
+ 0x1c, 0x72, 0x9c, 0x7e, 0x04, 0xb9, 0xf7, 0x96,
+ 0x07, 0xcd, 0x0a, 0x62, 0x8e, 0x43, 0x41, 0x30,
+ 0x04, 0xa5, 0x41, 0xff, 0x93, 0xae, 0x1c, 0xeb,
+ 0xb0, 0x04, 0xa7, 0x50, 0xdb, 0x10, 0x2d, 0x39,
+ 0xb9, 0x05, 0x2b, 0xb4, 0x7a, 0x58, 0xf1, 0x70,
+ 0x7e, 0x8c, 0xd2, 0xac, 0x98, 0xb5, 0xfb, 0x62,
+ 0x8f, 0x23, 0x31, 0xb1, 0x3b, 0x01, 0xe0, 0x18,
+ 0xf4, 0x66, 0xee, 0x5f, 0xbc, 0xd4, 0x9d, 0x68,
+ 0xd0, 0xab, 0x92, 0xe1, 0x83, 0x97, 0xf2, 0x45,
+ 0x8e, 0x0e, 0x3e, 0x21, 0x67, 0x47, 0x8c, 0x73,
+ 0xf1, 0x15, 0xd2, 0x7d, 0x32, 0xc6, 0x95, 0xe0,
+};
+
+static UINT8 Value_0[1] = {0x00};
+static UINT8 Value_1[1] = {0x01};
+static PBIG_INTEGER pBI_U = NULL, pBI_S = NULL, pBI_O = NULL;
+static UINT Bits_Of_R = 0;
+
+
+VOID BigInteger_Print (
+ IN PBIG_INTEGER pBI)
+{
+ int i = 0, j = 0;
+
+ if ((pBI == NULL) || (pBI->pIntegerArray == NULL))
+ return;
+
+ if (strlen(pBI->Name) != 0)
+ DEBUGPRINT("Name=%s\n", pBI->Name);
+ DEBUGPRINT("AllocSize=%d, ArrayLength=%d, IntegerLength=%d, Signed=%d\n", pBI->AllocSize, pBI->ArrayLength, pBI->IntegerLength, pBI->Signed);
+ for (i = (pBI->ArrayLength - 1), j = 0;i >=0;i--,j++) {
+ DEBUGPRINT("%08x, ", pBI->pIntegerArray[i]);
+ if ((j%8) == 7)
+ DEBUGPRINT("\n");
+ } /* End od for */
+ DEBUGPRINT("\n\n");
+} /* End of BigInteger_Print */
+
+
+VOID BigInteger_Init (
+ INOUT PBIG_INTEGER *pBI)
+{
+ if (*pBI != NULL)
+ BigInteger_Free(pBI);
+
+ os_alloc_mem(NULL, (UCHAR **)pBI, sizeof(BIG_INTEGER));
+/* if ((*pBI = (PBIG_INTEGER) kmalloc(sizeof(BIG_INTEGER), GFP_ATOMIC)) == NULL) { */
+ if (*pBI == NULL) {
+ DEBUGPRINT("BigInteger_Init: allocate %d bytes memory failure.\n", (sizeof(BIG_INTEGER)));
+ return;
+ } /* End of if */
+
+ NdisZeroMemory(*pBI, sizeof(BIG_INTEGER));
+ (*pBI)->pIntegerArray = NULL;
+ (*pBI)->Signed = 1;
+} /* End of BigInteger_Init */
+
+
+VOID BigInteger_Free_AllocSize (
+ IN PBIG_INTEGER *pBI)
+{
+ if ((*pBI != NULL) && ((*pBI)->pIntegerArray != NULL)) {
+/* kfree((*pBI)->pIntegerArray); */
+ os_free_mem(NULL, (*pBI)->pIntegerArray);
+ NdisZeroMemory(*pBI, sizeof(BIG_INTEGER));
+ (*pBI)->pIntegerArray = NULL;
+ (*pBI)->Signed = 1;
+ } /* End of if */
+} /* End of BigInteger_Free_AllocSize */
+
+
+VOID BigInteger_Free (
+ IN PBIG_INTEGER *pBI)
+{
+ if (*pBI != NULL) {
+ BigInteger_Free_AllocSize(pBI);
+/* kfree(*pBI); */
+ os_free_mem(NULL, *pBI);
+ } /* End of if */
+
+ *pBI = NULL;
+} /* End of BigInteger_Free */
+
+
+VOID BigInteger_AllocSize (
+ IN PBIG_INTEGER *pBI,
+ IN INT Length)
+{
+ UINT ArrayLength = 0;
+
+ if (Length <= 0)
+ return;
+
+ if (*pBI == NULL)
+ BigInteger_Init(pBI);
+
+ /* Caculate array size */
+ ArrayLength = Length >> 0x2;
+ if ((Length & 0x3) != 0)
+ ArrayLength++;
+
+ if (((*pBI)->pIntegerArray != NULL) && ((*pBI)->AllocSize < (sizeof(UINT32)*ArrayLength)))
+ BigInteger_Free_AllocSize(pBI);
+
+ if ((*pBI)->pIntegerArray == NULL) {
+ os_alloc_mem(NULL, (UCHAR **)&((*pBI)->pIntegerArray), sizeof(UINT32)*ArrayLength);
+/* if (((*pBI)->pIntegerArray = (UINT32 *) kmalloc(sizeof(UINT32)*ArrayLength, GFP_ATOMIC)) == NULL) { */
+ if ((*pBI)->pIntegerArray == NULL) {
+ DEBUGPRINT("BigInteger_AllocSize: allocate %d bytes memory failure.\n", (sizeof(UINT32)*ArrayLength));
+ return;
+ } /* End of if */
+ (*pBI)->AllocSize = sizeof(UINT32)*ArrayLength;
+ } /* End of if */
+
+ NdisZeroMemory((*pBI)->pIntegerArray, (*pBI)->AllocSize);
+ (*pBI)->ArrayLength = ArrayLength;
+ (*pBI)->IntegerLength = Length;
+} /* End of BigInteger_AllocSize */
+
+
+VOID BigInteger_ClearHighBits (
+ IN PBIG_INTEGER pBI)
+{
+ INT BIArrayIndex, ShiftIndex = 0;
+ UINT8 value;
+
+ if ((pBI == NULL) || (pBI->pIntegerArray == NULL))
+ return;
+
+ BIArrayIndex = pBI->ArrayLength - 1;
+ while ((BIArrayIndex >= 0) && (pBI->pIntegerArray[BIArrayIndex] == 0))
+ BIArrayIndex--;
+
+ if (BIArrayIndex >= 0) {
+ value = 0;
+ ShiftIndex = 4;
+ while (value == 0) {
+ ShiftIndex--;
+ value = UINT32_GETBYTE(pBI->pIntegerArray[BIArrayIndex], ShiftIndex);
+ } /* End of while */
+ } /* End of if */
+
+ if (BIArrayIndex < 0) {
+ pBI->IntegerLength = 1;
+ pBI->ArrayLength = 1;
+ pBI->Signed = 1;
+ } else {
+ pBI->IntegerLength = (BIArrayIndex*4) + ShiftIndex + 1;
+ pBI->ArrayLength = BIArrayIndex + 1;
+ } /* End of if */
+} /* End of BigInteger_ClearHighBits */
+
+
+VOID BigInteger_BI2Bin (
+ IN PBIG_INTEGER pBI,
+ OUT UINT8 *pValue,
+ OUT UINT *Length)
+{
+ INT ValueIndex, BIArrayIndex, ShiftIndex;
+ UINT32 Number;
+
+ if (pBI == NULL) {
+ DEBUGPRINT("BigInteger_BI2Bin: pBI is NUll\n");
+ *Length = 0;
+ return;
+ } /* End of if */
+
+ if (*Length < (sizeof(UINT8) * pBI->IntegerLength)) {
+ DEBUGPRINT("BigInteger_BI2Bin: length(%d) is not enough.\n", *Length);
+ *Length = 0;
+ return;
+ } /* End of if */
+
+ if (pBI->pIntegerArray == NULL) {
+ *Length = 0;
+ return;
+ } /* End of if */
+
+ BigInteger_ClearHighBits(pBI);
+ if ((ShiftIndex = pBI->IntegerLength & 0x3) == 0)
+ ShiftIndex = 4;
+ BIArrayIndex = pBI->ArrayLength - 1;
+ ValueIndex = 0;
+
+ Number = pBI->pIntegerArray[BIArrayIndex];
+ while (ValueIndex < pBI->IntegerLength)
+ {
+ pValue[ValueIndex++] = (UINT8) UINT32_GETBYTE(Number, ShiftIndex - 1);
+ if ((--ShiftIndex) == 0) {
+ ShiftIndex = 4;
+ BIArrayIndex--;
+ Number = pBI->pIntegerArray[BIArrayIndex];
+ } /* End of if */
+ } /* End of while */
+ *Length = pBI->IntegerLength;
+} /* End of BigInteger_BI2Bin */
+
+
+VOID BigInteger_Bin2BI (
+ IN UINT8 *pValue,
+ IN UINT Length,
+ OUT PBIG_INTEGER *pBI)
+{
+ INT ValueIndex, BIArrayIndex, ShiftIndex;
+ UINT32 Number;
+
+ BigInteger_AllocSize(pBI, Length);
+
+ if ((*pBI)->pIntegerArray != NULL) {
+ Number = 0;
+ if ((ShiftIndex = Length & 0x3) == 0)
+ ShiftIndex = 4;
+ BIArrayIndex = (*pBI)->ArrayLength - 1;
+ ValueIndex = 0;
+ while (ValueIndex < Length)
+ {
+ Number = (Number << 8) | (UINT8) pValue[ValueIndex++];
+ if ((--ShiftIndex) == 0) {
+ (*pBI)->pIntegerArray[BIArrayIndex] = Number;
+ ShiftIndex = 4;
+ BIArrayIndex--;
+ Number = 0;
+ } /* End of if */
+ } /* End of while */
+ } /* End of if */
+} /* End of BigInteger_Bin2BI */
+
+
+/* Calculate the bits of BigInteger, the highest bit is 1 */
+VOID BigInteger_BitsOfBI (
+ IN PBIG_INTEGER pBI,
+ OUT UINT *Bits_Of_P)
+{
+ UINT32 Number, Index;
+
+ Number = pBI->pIntegerArray[pBI->ArrayLength - 1];
+ Index = 0;
+ while ((!(Number & 0x80000000)) && (Index < 32)) {
+ Number <<= 1;
+ Index++;
+ } /* End of while */
+ *Bits_Of_P = (pBI->ArrayLength*sizeof(UINT32)) - Index;
+} /* End of BigInteger_BitsOfBN */
+
+
+INT BigInteger_GetBitValue (
+ IN PBIG_INTEGER pBI,
+ IN UINT Index)
+{
+ UINT Array = 0;
+ UINT Shift = 0;
+
+ if (Index > 0) {
+ Array = (Index - 1) >> 0x5;
+ Shift = (Index - 1) & 0x1F;
+ }
+ if (Array > pBI->ArrayLength)
+ return 0;
+
+ return ((pBI->pIntegerArray[Array] >> Shift) & 0x1);
+} /* End of BigInteger_GetBitValue */
+
+
+UINT8 BigInteger_GetByteValue (
+ IN PBIG_INTEGER pBI,
+ IN UINT Index)
+{
+ UINT Array = 0;
+ UINT Shift = 0;
+
+ if (Index > 0) {
+ Array = (Index - 1) >> 0x2;
+ Shift = (Index - 1) & 0x3;
+ }
+ if ((Array > pBI->ArrayLength) || (Index > pBI->IntegerLength))
+ return 0;
+
+
+ return (UINT8) UINT32_GETBYTE(pBI->pIntegerArray[Array], Shift - 1);
+} /* End of BigInteger_GetByteValue */
+
+
+VOID BigInteger_Copy (
+ IN PBIG_INTEGER pBI_Copied,
+ OUT PBIG_INTEGER *pBI_Result)
+{
+ BigInteger_AllocSize(pBI_Result, pBI_Copied->IntegerLength);
+ NdisCopyMemory((*pBI_Result)->pIntegerArray, pBI_Copied->pIntegerArray, (sizeof(UINT32)*(*pBI_Result)->ArrayLength));
+ (*pBI_Result)->ArrayLength = pBI_Copied->ArrayLength;
+ (*pBI_Result)->IntegerLength = pBI_Copied->IntegerLength;
+ (*pBI_Result)->Signed = pBI_Copied->Signed;
+} /* End of BigInteger_Copy */
+
+
+INT BigInteger_UnsignedCompare (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand)
+{
+ INT BIArrayIndex;
+
+ if (pFirstOperand->IntegerLength > pSecondOperand->IntegerLength)
+ return 1;
+
+ if (pFirstOperand->IntegerLength < pSecondOperand->IntegerLength)
+ return -1;
+
+ if (pFirstOperand->IntegerLength == pSecondOperand->IntegerLength) {
+ for(BIArrayIndex = (pFirstOperand->ArrayLength - 1);BIArrayIndex >= 0 ; BIArrayIndex--)
+ {
+ if (pFirstOperand->pIntegerArray[BIArrayIndex] > pSecondOperand->pIntegerArray[BIArrayIndex])
+ return 1;
+ else if (pFirstOperand->pIntegerArray[BIArrayIndex] < pSecondOperand->pIntegerArray[BIArrayIndex])
+ return -1;
+ } /* End of for */
+ } /* End of if */
+
+ return 0;
+} /* End of BigInteger_Compare */
+
+
+VOID BigInteger_Add (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result)
+{
+ INT CompareResult;
+ UINT32 BIArrayIndex;
+ UINT64 Sum, Carry;
+ PBIG_INTEGER pTempBI = NULL;
+
+ if ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+ || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+ DEBUGPRINT("BigInteger_Add: first or second operand is NULL.\n");
+ return;
+ } /* End of if */
+
+ if (*pBI_Result == NULL)
+ BigInteger_Init(pBI_Result);
+
+ CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
+ if ((CompareResult == 0) & ((pFirstOperand->Signed * pSecondOperand->Signed) < 0)) {
+ BigInteger_AllocSize(pBI_Result, 1);
+ return ;
+ } /* End of if */
+
+ /*
+ * Singed table
+ * A + B || A > B || A < B
+ * ------------------------
+ * + + || + || +
+ * + - || + || -
+ * - + || - || +
+ * - - || - || -
+ */
+ if ((pFirstOperand->Signed * pSecondOperand->Signed) > 0) {
+ if (pFirstOperand->IntegerLength > pSecondOperand->IntegerLength) {
+ BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength + 1);
+ } else {
+ BigInteger_AllocSize(pBI_Result, pSecondOperand->IntegerLength + 1);
+ } /* End of if */
+
+ Carry = 0;
+ for (BIArrayIndex=0; BIArrayIndex < (*pBI_Result)->ArrayLength; BIArrayIndex++)
+ {
+
+ Sum = 0;
+ if (BIArrayIndex < pFirstOperand->ArrayLength)
+ Sum += (UINT64) pFirstOperand->pIntegerArray[BIArrayIndex];
+
+ if (BIArrayIndex < pSecondOperand->ArrayLength)
+ Sum += (UINT64) pSecondOperand->pIntegerArray[BIArrayIndex];
+
+ Sum += Carry;
+ Carry = Sum >> 32;
+ (*pBI_Result)->pIntegerArray[BIArrayIndex] = (UINT32) (Sum & 0xffffffffUL);
+ } /* End of for */
+ (*pBI_Result)->Signed = pFirstOperand->Signed;
+ BigInteger_ClearHighBits(*pBI_Result);
+ } else {
+ if ((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == -1)) {
+ BigInteger_Copy(pSecondOperand, &pTempBI);
+ pTempBI->Signed = 1;
+ BigInteger_Sub(pFirstOperand, pTempBI, pBI_Result);
+ } else if ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == 1)) {
+ BigInteger_Copy(pFirstOperand, &pTempBI);
+ pTempBI->Signed = 1;
+ BigInteger_Sub(pSecondOperand, pTempBI, pBI_Result);
+ } /* End of if */
+ } /* End of if */
+
+ BigInteger_Free(&pTempBI);
+} /* End of BigInteger_Add */
+
+
+VOID BigInteger_Sub (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result)
+{
+ INT CompareResult;
+ UINT32 BIArrayIndex, Carry;
+ PBIG_INTEGER pTempBI = NULL, pTempBI2 = NULL;
+
+ if ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+ || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+ DEBUGPRINT("BigInteger_Sub: first or second operand is NULL.\n");
+ return;
+ } /* End of if */
+
+ if (*pBI_Result == NULL)
+ BigInteger_Init(pBI_Result);
+
+ CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
+ if ((CompareResult == 0) & ((pFirstOperand->Signed * pSecondOperand->Signed) > 0)) {
+ BigInteger_AllocSize(pBI_Result, 1);
+ return ;
+ } /* End of if */
+
+ BigInteger_Init(&pTempBI);
+ BigInteger_Init(&pTempBI2);
+
+ /*
+ * Singed table
+ * A - B || A > B || A < B
+ * ------------------------
+ * + + || + || -
+ * + - || + || +
+ * - + || - || -
+ * - - || - || +
+ */
+ if ((pFirstOperand->Signed * pSecondOperand->Signed) > 0) {
+ if (CompareResult == 1) {
+ BigInteger_Copy(pFirstOperand, &pTempBI);
+ BigInteger_Copy(pSecondOperand, &pTempBI2);
+ } else if (CompareResult == -1) {
+ BigInteger_Copy(pSecondOperand, &pTempBI);
+ BigInteger_Copy(pFirstOperand, &pTempBI2);
+ } /* End of if */
+
+ BigInteger_Copy(pTempBI, pBI_Result);
+ Carry = 0;
+ for (BIArrayIndex=0; BIArrayIndex < (*pBI_Result)->ArrayLength; BIArrayIndex++)
+ {
+ if (BIArrayIndex < pTempBI2->ArrayLength) {
+ if ((*pBI_Result)->pIntegerArray[BIArrayIndex] >= (pTempBI2->pIntegerArray[BIArrayIndex] - Carry)) {
+ (*pBI_Result)->pIntegerArray[BIArrayIndex] = (*pBI_Result)->pIntegerArray[BIArrayIndex] - pTempBI2->pIntegerArray[BIArrayIndex] - Carry;
+ Carry = 0;
+ } else {
+ (*pBI_Result)->pIntegerArray[BIArrayIndex] = 0xffffffffUL - pTempBI2->pIntegerArray[BIArrayIndex] - Carry + (*pBI_Result)->pIntegerArray[BIArrayIndex] + 1;
+ Carry = 1;
+ } /* End of if */
+ } else {
+ if ((*pBI_Result)->pIntegerArray[BIArrayIndex] >= Carry) {
+ (*pBI_Result)->pIntegerArray[BIArrayIndex] -= Carry;
+ Carry = 0;
+ } else {
+ (*pBI_Result)->pIntegerArray[BIArrayIndex] = 0xffffffffUL - Carry;
+ Carry = 1;
+ } /* End of if */
+ } /* End of if */
+ } /* End of for */
+
+ if (((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == 1) & (CompareResult == -1))
+ || ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == -1) & (CompareResult == 1)))
+ (*pBI_Result)->Signed = -1;
+
+ BigInteger_ClearHighBits(*pBI_Result);
+ } else {
+ if ((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == -1)) {
+ BigInteger_Copy(pSecondOperand, &pTempBI);
+ pTempBI->Signed = 1;
+ BigInteger_Add(pFirstOperand, pTempBI, pBI_Result);
+ } else if ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == 1)) {
+ BigInteger_Copy(pFirstOperand, &pTempBI);
+ pTempBI->Signed = 1;
+ BigInteger_Add(pTempBI, pSecondOperand, pBI_Result);
+ (*pBI_Result)->Signed = -1;
+ } /* End of if */
+ } /* End of if */
+
+ BigInteger_Free(&pTempBI);
+ BigInteger_Free(&pTempBI2);
+} /* End of BigInteger_Sub */
+
+
+VOID BigInteger_Mul (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result)
+{
+
+ UINT32 BIFirstIndex, BISecondIndex;
+ UINT64 FirstValue, SecondValue, Sum, Carry;
+
+ if ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+ || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+ DEBUGPRINT("BigInteger_Mul: first or second operand is NULL.\n");
+ return;
+ } /* End of if */
+
+ /* The first or second operand is zero */
+ if (((pFirstOperand->IntegerLength == 1) && (pFirstOperand->pIntegerArray[0] == 0))
+ ||((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 0))) {
+ BigInteger_AllocSize(pBI_Result, 1);
+ goto output;
+ } /* End of if */
+
+ /* The first or second operand is one */
+ if ((pFirstOperand->IntegerLength == 1) && (pFirstOperand->pIntegerArray[0] == 1)) {
+ BigInteger_Copy(pSecondOperand, pBI_Result);
+ goto output;
+ } /* End of if */
+ if ((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 1)) {
+ BigInteger_Copy(pFirstOperand, pBI_Result);
+ goto output;
+ } /* End of if */
+
+ BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength + pSecondOperand->IntegerLength);
+
+ for (BIFirstIndex=0; BIFirstIndex < pFirstOperand->ArrayLength; BIFirstIndex++)
+ {
+ Carry = 0;
+ FirstValue = (UINT64) pFirstOperand->pIntegerArray[BIFirstIndex];
+ if (FirstValue == 0) {
+ continue;
+ } else {
+ for (BISecondIndex=0; BISecondIndex < pSecondOperand->ArrayLength; BISecondIndex++)
+ {
+ SecondValue = ((UINT64) pSecondOperand->pIntegerArray[BISecondIndex])*FirstValue;
+ Sum = (UINT64) ((*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] + SecondValue + Carry);
+ Carry = Sum >> 32;
+ (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] = (UINT32) (Sum & 0xffffffffUL);
+ } /* End of for */
+ while (Carry != 0) {
+ Sum = (UINT64) (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex];
+ Sum += Carry;
+
+ Carry = Sum >> 32;
+ (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] = (UINT32) (Sum & 0xffffffffUL);
+ BISecondIndex++;
+ } /* End of while */
+ } /* End of if */
+ } /* End of for */
+
+output:
+ (*pBI_Result)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
+ BigInteger_ClearHighBits(*pBI_Result);
+} /* End of BigInteger_Mul */
+
+
+VOID BigInteger_Square (
+ IN PBIG_INTEGER pBI,
+ OUT PBIG_INTEGER *pBI_Result)
+{
+ INT BIFirstIndex, BISecondIndex;
+ UINT32 HBITS_Value, LBITS_Value, Temp1_Value, Temp2_Value, Carry32;
+ UINT32 *Point_Of_S, *Point_Of_Result, *Point_Of_BI;
+ UINT64 Result64_1, Result64_2, Carry64, TempValue64;
+
+ if ((pBI == NULL) || (pBI->pIntegerArray == NULL)) {
+ DEBUGPRINT("\tBigInteger_Square: the operand is NULL.\n");
+ return;
+ } /* End of if */
+
+ /* The operand is zero */
+ if ((pBI->IntegerLength == 1) && (pBI->pIntegerArray[0] == 0)) {
+ BigInteger_AllocSize(pBI_Result, 1);
+ goto output;
+ } /* End of if */
+
+ BigInteger_AllocSize(pBI_Result, (pBI->IntegerLength*2) + 20);
+ BigInteger_AllocSize(&pBI_S, (pBI->IntegerLength*2) + 20);
+ BigInteger_AllocSize(&pBI_O, (pBI->IntegerLength*2) + 20);
+
+ /*
+ * Input: pBI = {a_0, a_1, a_2, a_3, ..., a_n}
+ * Step1. calculate a_0^2, a_1^2, a_2^2, a_3^2 ... a_n^2
+ */
+ Point_Of_S = pBI_S->pIntegerArray;
+ for (BIFirstIndex=0; BIFirstIndex < pBI->ArrayLength; BIFirstIndex++)
+ {
+ HBITS_Value = UINT32_HBITS(pBI->pIntegerArray[BIFirstIndex]);
+ LBITS_Value = UINT32_LBITS(pBI->pIntegerArray[BIFirstIndex]);
+ Temp1_Value = HBITS_Value*LBITS_Value;
+ Temp2_Value = (Temp1_Value & 0x7fff) << 0x11;
+ Point_Of_S[0] = (LBITS_Value*LBITS_Value) + Temp2_Value;
+ Point_Of_S[1] = (HBITS_Value*HBITS_Value) + ((Temp1_Value >> 0xf) & 0x1ffff);
+ if (Point_Of_S[0] < Temp2_Value)
+ Point_Of_S[1] += 1;
+
+ Point_Of_S += 2;
+ } /* End of for */
+
+ /*
+ * Step2. calculate a_0*{a_1, a_2, a_3, a_4, ..., a_n}
+ */
+ Point_Of_BI = pBI->pIntegerArray;
+ Point_Of_Result = (*pBI_Result)->pIntegerArray;
+ Point_Of_Result[0] = 0;
+ TempValue64 = (UINT64) Point_Of_BI[0];
+ Point_Of_Result++;
+ Carry64 = 0;
+ for (BIFirstIndex=1; BIFirstIndex < pBI->ArrayLength; BIFirstIndex++)
+ {
+ Result64_1 = (UINT64) Point_Of_BI[BIFirstIndex]*TempValue64;
+ Result64_1 += Carry64;
+ Carry64 = (Result64_1 >> 32);
+ Point_Of_Result[0] = (UINT32) (Result64_1 & 0xffffffffUL);
+ Point_Of_Result++;
+ } /* End of for */
+ if (Carry64 > 0)
+ Point_Of_Result[0] = (UINT32) (Carry64 & 0xffffffffUL);
+
+ /*
+ * Step3. calculate
+ * a_1*{a_2, a_3, a_4, ..., a_n}
+ * a_2*{a_3, a_4, a_5, ..., a_n}
+ * a_3*{a_4, a_5, a_6, ..., a_n}
+ * a_4*{a_5, a_6, a_7, ..., a_n}
+ * ...
+ * a_n-1*{a_n}
+ */
+ Point_Of_BI = pBI->pIntegerArray;
+ for (BIFirstIndex=1; BIFirstIndex < (pBI->ArrayLength - 1); BIFirstIndex++)
+ {
+ Point_Of_Result = (*pBI_Result)->pIntegerArray;
+ Point_Of_Result += (BIFirstIndex*2) + 1;
+ TempValue64 = (UINT64) Point_Of_BI[BIFirstIndex];
+ Carry64 = 0;
+ for (BISecondIndex=(BIFirstIndex + 1); BISecondIndex < pBI->ArrayLength; BISecondIndex++)
+ {
+ Result64_1 = ((UINT64) Point_Of_Result[0]) + Carry64;
+ Result64_2 = (UINT64) Point_Of_BI[BISecondIndex]*TempValue64;
+ Carry64 = (Result64_1 >> 32);
+ Result64_1 = (Result64_1 & 0xffffffffUL);
+ Result64_1 = Result64_1 + Result64_2;
+ Carry64 += (Result64_1 >> 32);
+ Point_Of_Result[0] = (UINT32) (Result64_1 & 0xffffffffUL);
+ Point_Of_Result++;
+ } /* End of for */
+ if (Carry64 > 0)
+ Point_Of_Result[0] += (UINT32) (Carry64 & 0xffffffffUL);
+ } /* End of for */
+
+ BigInteger_ClearHighBits(*pBI_Result);
+ BigInteger_Copy(*pBI_Result, &pBI_O);
+
+ Carry32 = 0;
+ for (BIFirstIndex=0; BIFirstIndex < pBI_O->ArrayLength; BIFirstIndex++) {
+ pBI_O->pIntegerArray[BIFirstIndex] = (pBI_O->pIntegerArray[BIFirstIndex] << 1) | Carry32;
+ if (pBI_O->pIntegerArray[BIFirstIndex] < (*pBI_Result)->pIntegerArray[BIFirstIndex])
+ Carry32 = 1;
+ else
+ Carry32 = 0;
+ } /* End of for */
+ pBI_O->pIntegerArray[BIFirstIndex] = Carry32;
+ pBI_O->IntegerLength++;
+ pBI_O->ArrayLength++;
+ BigInteger_ClearHighBits(pBI_O);
+
+ BigInteger_Add(pBI_O, pBI_S, pBI_Result);
+output:
+ (*pBI_Result)->Signed = 1;
+ BigInteger_ClearHighBits(*pBI_Result);
+} /* End of BigInteger_Square */
+
+
+VOID BigInteger_Div (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result,
+ OUT PBIG_INTEGER *pBI_Remainder)
+{
+ INT CompareResult;
+ INT Index, MulIndex, ComputeSize;
+ UINT32 MulStart;
+ UINT AllocLength, ArrayIndex, ShiftIndex;
+ PBIG_INTEGER pTempBI = NULL, pTempBI2 = NULL, pMulBI = NULL;
+ UINT8 SecondHighByte;
+
+ if ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+ || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+ DEBUGPRINT("BigInteger_Div: first or second operand is NULL.\n");
+ return;
+ } /* End of if */
+
+ /* The second operand is zero */
+ if ((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 0)) {
+ DEBUGPRINT("BigInteger_Div: second operand is zero.\n");
+ return;
+ } /* End of if */
+
+ if (*pBI_Result == NULL)
+ BigInteger_Init(pBI_Result);
+ if (*pBI_Remainder == NULL)
+ BigInteger_Init(pBI_Remainder);
+
+ /* The second operand is one */
+ if ((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 1)) {
+ BigInteger_Copy(pFirstOperand, pBI_Result);
+ BigInteger_Bin2BI(Value_0, 1, pBI_Remainder);
+ goto output;
+ } /* End of if */
+
+ CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
+ if (CompareResult == 0) {
+ BigInteger_Bin2BI(Value_1, 1, pBI_Result);
+ BigInteger_Bin2BI(Value_0, 1, pBI_Remainder);
+ goto output;
+ } else if (CompareResult == -1) {
+ BigInteger_Bin2BI(Value_0, 1, pBI_Result);
+ BigInteger_Copy(pFirstOperand, pBI_Remainder);
+ goto output;
+ } /* End of if */
+ BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength - pSecondOperand->IntegerLength + 1);
+ BigInteger_AllocSize(pBI_Remainder, pSecondOperand->IntegerLength);
+
+ AllocLength = (UINT) (pFirstOperand->IntegerLength << 1);
+ BigInteger_AllocSize(&pTempBI, AllocLength);
+ BigInteger_AllocSize(&pTempBI2, AllocLength);
+ BigInteger_AllocSize(&pMulBI, AllocLength);
+
+ BigInteger_Copy(pFirstOperand, pBI_Remainder);
+ SecondHighByte = BigInteger_GetByteValue(pSecondOperand, pSecondOperand->IntegerLength);
+ ComputeSize = (INT) pFirstOperand->IntegerLength - pSecondOperand->IntegerLength + 1;
+ for (Index = (INT) ComputeSize;Index >= 0;Index--) {
+ if (BigInteger_UnsignedCompare(*pBI_Remainder, pSecondOperand) == -1)
+ break;
+
+ if (((pSecondOperand->IntegerLength + Index) - (*pBI_Remainder)->IntegerLength) <= 1) {
+ BigInteger_AllocSize(&pMulBI, Index + 1);
+ ArrayIndex = 0;
+ if (Index > 0)
+ ArrayIndex = (UINT) (Index - 1) >> 2 ;
+ ShiftIndex = (Index & 0x03);
+ if (ShiftIndex == 0)
+ ShiftIndex = 4;
+ ShiftIndex--;
+ MulStart = 0;
+ MulStart = (BigInteger_GetByteValue((*pBI_Remainder), pFirstOperand->IntegerLength + Index - ComputeSize + 1) & 0xFF) << 8;
+ MulStart = MulStart | (BigInteger_GetByteValue((*pBI_Remainder), pFirstOperand->IntegerLength + Index - ComputeSize) & 0xFF);
+ if (MulStart < (UINT32) SecondHighByte)
+ continue;
+
+ MulStart = MulStart / (UINT32) SecondHighByte;
+
+ if (MulStart > 0xFF)
+ MulStart = 0x100;
+
+ for (MulIndex = (INT) MulStart;MulIndex <= 0x101;MulIndex++) { /* 0xFFFF / 0xFF = 0x101 */
+ if ((MulIndex > 0xFF) && (ShiftIndex == 3))
+ pMulBI->pIntegerArray[ArrayIndex + 1] = 0x01;
+ pMulBI->pIntegerArray[ArrayIndex] = ((UINT) MulIndex << (8*ShiftIndex));
+ BigInteger_Mul(pSecondOperand, pMulBI , &pTempBI);
+ CompareResult = BigInteger_UnsignedCompare(*pBI_Remainder, pTempBI);
+ if (CompareResult < 1) {
+ if (MulIndex > 1) {
+ if (CompareResult != 0) {
+ if ((MulIndex == 0x100) && (ShiftIndex == 3))
+ pMulBI->pIntegerArray[ArrayIndex + 1] = 0;
+ pMulBI->pIntegerArray[ArrayIndex] = ((UINT) (MulIndex - 1) << (8*ShiftIndex));
+ } /* End of if */
+
+ BigInteger_Mul(pSecondOperand, pMulBI, &pTempBI);
+ BigInteger_Sub(*pBI_Remainder, pTempBI, &pTempBI2);
+ BigInteger_Copy(pTempBI2, pBI_Remainder);
+ BigInteger_Add(*pBI_Result, pMulBI, &pTempBI2);
+ BigInteger_Copy(pTempBI2, pBI_Result);
+ } /* End of if */
+ break;
+ } /* End of if */
+
+ if ((MulIndex >= 0x100) && (ShiftIndex == 3))
+ pMulBI->pIntegerArray[ArrayIndex++] = 0;
+ pMulBI->pIntegerArray[ArrayIndex] = 0;
+ } /* End of for */
+ } /* End of if */
+ } /* End of for */
+
+ BigInteger_Free(&pTempBI);
+ BigInteger_Free(&pTempBI2);
+ BigInteger_Free(&pMulBI);
+output:
+ (*pBI_Result)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
+ (*pBI_Remainder)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
+ BigInteger_ClearHighBits(*pBI_Result);
+ BigInteger_ClearHighBits(*pBI_Remainder);
+} /* End of BigInteger_Div */
+
+
+VOID BigInteger_Montgomery_Reduction (
+ IN PBIG_INTEGER pBI_A,
+ IN PBIG_INTEGER pBI_P,
+ IN PBIG_INTEGER pBI_R,
+ OUT PBIG_INTEGER *pBI_Result)
+{
+ UINT32 *Point_P, *Point_Result;
+ UINT32 LoopCount;
+ UINT64 Result64_1, Result64_2, Carry64, TempValue64;
+ INT FirstLoop, SecondLoop;
+
+ BigInteger_AllocSize(pBI_Result, pBI_A->IntegerLength+ pBI_P->IntegerLength + 20);
+ BigInteger_Copy(pBI_A, pBI_Result);
+
+ Point_P = pBI_P->pIntegerArray;
+ Point_Result = (*pBI_Result)->pIntegerArray;
+
+ LoopCount = Bits_Of_R >> 0x5;
+ for (FirstLoop = 0;FirstLoop < LoopCount;FirstLoop++) {
+ Carry64 = 0;
+ TempValue64 = (UINT64) Point_Result[0];
+ for (SecondLoop = 0;SecondLoop < pBI_P->ArrayLength;SecondLoop++) {
+ Result64_1 = ((UINT64) Point_Result[SecondLoop]) + Carry64;
+ Result64_2 = (UINT64) Point_P[SecondLoop]*TempValue64;
+ Carry64 = (Result64_1 >> 32);
+ Result64_1 = (Result64_1 & 0xffffffffUL);
+ Result64_1 = Result64_1 + Result64_2;
+ Carry64 += (Result64_1 >> 32);
+ Point_Result[SecondLoop] = (UINT32) (Result64_1 & 0xffffffffUL);
+ } /* End of for */
+ while (Carry64 != 0) {
+ Result64_1 = ((UINT64) Point_Result[SecondLoop]) + Carry64;
+ Carry64 = Result64_1 >> 32;
+ Point_Result[SecondLoop] = (UINT32) (Result64_1 & 0xffffffffUL);
+ SecondLoop++;
+ } /* End of while */
+ Point_Result++;
+ } /* End of for */
+
+ for (FirstLoop = 0;FirstLoop <= LoopCount;FirstLoop++) {
+ (*pBI_Result)->pIntegerArray[FirstLoop] = (*pBI_Result)->pIntegerArray[FirstLoop + LoopCount];
+ } /* End of for */
+ if ((*pBI_Result)->pIntegerArray[LoopCount] != 0)
+ (*pBI_Result)->ArrayLength = LoopCount + 1;
+ else
+ (*pBI_Result)->ArrayLength = LoopCount;
+
+ (*pBI_Result)->IntegerLength = (*pBI_Result)->ArrayLength*4;
+ BigInteger_ClearHighBits(*pBI_Result);
+
+ if (BigInteger_UnsignedCompare(*pBI_Result, pBI_P) >= 0) {
+ BigInteger_Sub(*pBI_Result, pBI_P, &pBI_U);
+ BigInteger_Copy(pBI_U, pBI_Result);
+ } /* End of if */
+ BigInteger_ClearHighBits(*pBI_Result);
+} /* End of BigInteger_Montgomery_Reduction */
+
+
+VOID BigInteger_Montgomery_ExpMod (
+ IN PBIG_INTEGER pBI_G,
+ IN PBIG_INTEGER pBI_E,
+ IN PBIG_INTEGER pBI_P,
+ OUT PBIG_INTEGER *pBI_Result)
+{
+ UINT Bits_Of_P;
+ UINT32 Index, Index2, AllocLength;
+ UINT32 Sliding_Value , Sliding_HighValue, Sliding_LowValue;
+ PBIG_INTEGER pBI_Temp1 = NULL, pBI_Temp2 = NULL;
+ PBIG_INTEGER pBI_X = NULL, pBI_R = NULL, pBI_RR = NULL, pBI_1 = NULL;
+ BIG_INTEGER *pBI_A[SLIDING_WINDOW];
+ UINT8 *pRValue = NULL;
+
+ AllocLength = (pBI_G->IntegerLength + pBI_E->IntegerLength + pBI_P->IntegerLength + 300);
+ BigInteger_AllocSize(&pBI_Temp1, AllocLength);
+ BigInteger_AllocSize(&pBI_Temp2, AllocLength);
+
+ /* Calculate the bits of P and E, the highest bit is 1 */
+ BigInteger_BitsOfBI(pBI_P, &Bits_Of_P);
+
+ if ((pBI_G->IntegerLength == 1) && (pBI_G->pIntegerArray[0] == 0)) {
+ BigInteger_Bin2BI(Value_0, 1, pBI_Result);
+ goto memory_free;
+ } /* End of if */
+
+ if ((pBI_G->IntegerLength == 1) && (pBI_G->pIntegerArray[0] == 1)) {
+ BigInteger_Div(pBI_G, pBI_P, &pBI_Temp1, pBI_Result);
+ goto memory_free;
+ } /* End of if */
+
+ if ((pBI_E->IntegerLength == 1) && (pBI_E->pIntegerArray[0] == 1)) {
+ BigInteger_Div(pBI_G, pBI_P, &pBI_Temp1, pBI_Result);
+ goto memory_free;
+ } /* End of if */
+
+ if ((pBI_E->IntegerLength == 1) && (pBI_E->pIntegerArray[0] == 2)) {
+ BigInteger_Mul(pBI_G, pBI_G, &pBI_Temp1);
+ BigInteger_Div(pBI_Temp1, pBI_P, &pBI_Temp2, pBI_Result);
+ goto memory_free;
+ } /* End of if */
+
+ /*
+ * Main algorithm
+ */
+ BigInteger_Init(&pBI_R);
+ BigInteger_Init(&pBI_RR);
+ BigInteger_Bin2BI(Value_1, 1, &pBI_1);
+ BigInteger_AllocSize(&pBI_X, AllocLength);
+ BigInteger_AllocSize(&pBI_U, AllocLength); /* for BigInteger_Montgomery_Reduction */
+ BigInteger_AllocSize(&pBI_S, AllocLength); /* for BigInteger_Square */
+ BigInteger_AllocSize(&pBI_O, AllocLength); /* for BigInteger_Square */
+
+ for (Index = 0; Index < SLIDING_WINDOW; Index++) {
+ pBI_A[Index] = NULL;
+ BigInteger_AllocSize(&pBI_A[Index], 193);
+ } /* End of for */
+ BigInteger_Bin2BI(WPS_DH_P_VALUE, 192, &pBI_Temp1);
+ if (NdisCmpMemory(pBI_P->pIntegerArray, pBI_Temp1->pIntegerArray, pBI_P->IntegerLength) == 0) {
+ BigInteger_Bin2BI(WPS_DH_X_VALUE, 184, &pBI_X);
+ BigInteger_Bin2BI(WPS_DH_R_VALUE, 193, &pBI_R);
+ BigInteger_Bin2BI(WPS_DH_RRModP_VALUE, 192, &pBI_RR);
+ Bits_Of_R = 1537;
+ } else {
+ if ((Bits_Of_P % 8) == 0) {
+ AllocLength = pBI_P->IntegerLength + 1;
+ } else {
+ AllocLength = pBI_P->IntegerLength;
+ } /* End of if */
+/* pRValue = (UINT8 *) kmalloc(sizeof(UINT8)*AllocLength, GFP_ATOMIC); */
+ os_alloc_mem(NULL, (UCHAR **)&pRValue, sizeof(UINT8)*AllocLength);
+ if (pRValue == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
+ goto memory_free;
+ }
+ NdisZeroMemory(pRValue, sizeof(UINT8)*AllocLength);
+ pRValue[0] = (UINT8) (1 << (Bits_Of_P & 0x7));
+ BigInteger_Bin2BI(pRValue, AllocLength , &pBI_R);
+
+ BigInteger_Mul(pBI_R, pBI_R, &pBI_Temp1);
+ BigInteger_Div(pBI_Temp1, pBI_P, &pBI_A[1], &pBI_RR);
+
+ /* X = 1*R (mod P) */
+ BigInteger_Div(pBI_R, pBI_P, &pBI_Temp2, &pBI_X);
+ } /* End of if */
+
+ /* A = G*R (mod P) => A = MonMod(G, R^2 mod P) */
+ BigInteger_Mul(pBI_G, pBI_RR, &pBI_Temp1);
+ BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P , pBI_R, &pBI_A[1]);
+ for (Index = 2; Index < SLIDING_WINDOW; Index++) {
+ BigInteger_Mul(pBI_A[Index - 1], pBI_A[1], &pBI_Temp1);
+ BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_A[Index]);
+ } /* End of for */
+
+ for (Index = pBI_E->IntegerLength ; Index > 0 ; Index--) {
+ for (Index2 = 0; Index2 < 4 ; Index2++) {
+ BigInteger_Square(pBI_X, &pBI_Temp1);
+ BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+ } /* End of for */
+
+ Sliding_Value = BigInteger_GetByteValue(pBI_E, Index);
+ Sliding_HighValue = (Sliding_Value >> 4);
+ if (Sliding_HighValue != 0) {
+ BigInteger_Mul(pBI_A[Sliding_HighValue], pBI_X, &pBI_Temp1);
+ BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+ } /* End of if */
+
+ for (Index2 = 0; Index2 < 4 ; Index2++) {
+ BigInteger_Square(pBI_X, &pBI_Temp1);
+ BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+ } /* End of for */
+
+ Sliding_LowValue = Sliding_Value & 0x0f;
+ if (Sliding_LowValue != 0) {
+ BigInteger_Mul(pBI_A[Sliding_LowValue], pBI_X, &pBI_Temp1);
+ BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+ } /* End of if */
+ } /* End of for */
+ BigInteger_Montgomery_Reduction(pBI_X, pBI_P , pBI_R, pBI_Result);
+
+ BigInteger_Free(&pBI_X);
+ BigInteger_Free(&pBI_1);
+ BigInteger_Free(&pBI_U);
+ BigInteger_Free(&pBI_S);
+ BigInteger_Free(&pBI_O);
+ for(Index = 0; Index < SLIDING_WINDOW; Index++)
+ BigInteger_Free(&pBI_A[Index]);
+ if (pRValue != NULL)
+/* kfree(pRValue); */
+ os_free_mem(NULL, pRValue);
+
+memory_free:
+ BigInteger_Free(&pBI_R);
+ BigInteger_Free(&pBI_RR);
+ BigInteger_Free(&pBI_Temp1);
+ BigInteger_Free(&pBI_Temp2);
+} /* End of BigInteger_Montgomery_ExpMod */
+
+/* End of crypt_biginteger.c */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/crypt_dh.c b/cleopatre/devkit/mt7601udrv/common/crypt_dh.c
new file mode 100644
index 0000000000..0939143fe5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/crypt_dh.c
@@ -0,0 +1,227 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ DH
+
+ Abstract:
+ RFC 2631: Diffie-Hellman Key Agreement Method
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2009/01/21 Create Diffie-Hellman
+***************************************************************************/
+
+
+#include "crypt_dh.h"
+#include "crypt_biginteger.h"
+
+
+/*
+========================================================================
+Routine Description:
+ Diffie-Hellman public key generation
+
+Arguments:
+ GValue Array in UINT8
+ GValueLength The length of G in bytes
+ PValue Array in UINT8
+ PValueLength The length of P in bytes
+ PrivateKey Private key
+ PrivateKeyLength The length of Private key in bytes
+
+Return Value:
+ PublicKey Public key
+ PublicKeyLength The length of public key in bytes
+
+Note:
+ Reference to RFC2631
+ PublicKey = G^PrivateKey (mod P)
+========================================================================
+*/
+void DH_PublicKey_Generate (
+ IN UINT8 GValue[],
+ IN UINT GValueLength,
+ IN UINT8 PValue[],
+ IN UINT PValueLength,
+ IN UINT8 PrivateKey[],
+ IN UINT PrivateKeyLength,
+ OUT UINT8 PublicKey[],
+ INOUT UINT *PublicKeyLength)
+{
+ PBIG_INTEGER pBI_G = NULL;
+ PBIG_INTEGER pBI_P = NULL;
+ PBIG_INTEGER pBI_PrivateKey = NULL;
+ PBIG_INTEGER pBI_PublicKey = NULL;
+
+ /*
+ * 1. Check the input parameters
+ * - GValueLength, PValueLength and PrivateLength must be large than zero
+ * - PublicKeyLength must be large or equal than PValueLength
+ * - PValue must be odd
+ *
+ * - PValue must be prime number (no implement)
+ * - GValue must be greater than 0 but less than the PValue (no implement)
+ */
+ if (GValueLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: G length is (%d)\n", GValueLength));
+ return;
+ } /* End of if */
+ if (PValueLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P length is (%d)\n", PValueLength));
+ return;
+ } /* End of if */
+ if (PrivateKeyLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: private key length is (%d)\n", PrivateKeyLength));
+ return;
+ } /* End of if */
+ if (*PublicKeyLength < PValueLength) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: public key length(%d) must be large or equal than P length(%d)\n",
+ *PublicKeyLength, PValueLength));
+ return;
+ } /* End of if */
+ if (!(PValue[PValueLength - 1] & 0x1)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P value must be odd\n"));
+ return;
+ } /* End of if */
+
+ /*
+ * 2. Transfer parameters to BigInteger structure
+ */
+ BigInteger_Init(&pBI_G);
+ BigInteger_Init(&pBI_P);
+ BigInteger_Init(&pBI_PrivateKey);
+ BigInteger_Init(&pBI_PublicKey);
+ BigInteger_Bin2BI(GValue, GValueLength, &pBI_G);
+ BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
+ BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
+
+ /*
+ * 3. Calculate PublicKey = G^PrivateKey (mod P)
+ * - BigInteger Operation
+ * - Montgomery reduction
+ */
+ BigInteger_Montgomery_ExpMod(pBI_G, pBI_PrivateKey, pBI_P, &pBI_PublicKey);
+
+ /*
+ * 4. Transfer BigInteger structure to char array
+ */
+ BigInteger_BI2Bin(pBI_PublicKey, PublicKey, PublicKeyLength);
+
+ BigInteger_Free(&pBI_G);
+ BigInteger_Free(&pBI_P);
+ BigInteger_Free(&pBI_PrivateKey);
+ BigInteger_Free(&pBI_PublicKey);
+} /* End of DH_PublicKey_Generate */
+
+
+/*
+========================================================================
+Routine Description:
+ Diffie-Hellman secret key generation
+
+Arguments:
+ PublicKey Public key
+ PublicKeyLength The length of Public key in bytes
+ PValue Array in UINT8
+ PValueLength The length of P in bytes
+ PrivateKey Private key
+ PrivateKeyLength The length of Private key in bytes
+
+Return Value:
+ SecretKey Secret key
+ SecretKeyLength The length of secret key in bytes
+
+Note:
+ Reference to RFC2631
+ SecretKey = PublicKey^PrivateKey (mod P)
+========================================================================
+*/
+void DH_SecretKey_Generate (
+ IN UINT8 PublicKey[],
+ IN UINT PublicKeyLength,
+ IN UINT8 PValue[],
+ IN UINT PValueLength,
+ IN UINT8 PrivateKey[],
+ IN UINT PrivateKeyLength,
+ OUT UINT8 SecretKey[],
+ INOUT UINT *SecretKeyLength)
+{
+ PBIG_INTEGER pBI_P = NULL;
+ PBIG_INTEGER pBI_SecretKey = NULL;
+ PBIG_INTEGER pBI_PrivateKey = NULL;
+ PBIG_INTEGER pBI_PublicKey = NULL;
+
+ /*
+ * 1. Check the input parameters
+ * - PublicKeyLength, PValueLength and PrivateLength must be large than zero
+ * - SecretKeyLength must be large or equal than PValueLength
+ * - PValue must be odd
+ *
+ * - PValue must be prime number (no implement)
+ */
+ if (PublicKeyLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: public key length is (%d)\n", PublicKeyLength));
+ return;
+ } /* End of if */
+ if (PValueLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P length is (%d)\n", PValueLength));
+ return;
+ } /* End of if */
+ if (PrivateKeyLength == 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: private key length is (%d)\n", PrivateKeyLength));
+ return;
+ } /* End of if */
+ if (*SecretKeyLength < PValueLength) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: secret key length(%d) must be large or equal than P length(%d)\n",
+ *SecretKeyLength, PValueLength));
+ return;
+ } /* End of if */
+ if (!(PValue[PValueLength - 1] & 0x1)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P value must be odd\n"));
+ return;
+ } /* End of if */
+
+ /*
+ * 2. Transfer parameters to BigInteger structure
+ */
+ BigInteger_Init(&pBI_P);
+ BigInteger_Init(&pBI_PrivateKey);
+ BigInteger_Init(&pBI_PublicKey);
+ BigInteger_Init(&pBI_SecretKey);
+
+ BigInteger_Bin2BI(PublicKey, PublicKeyLength, &pBI_PublicKey);
+ BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
+ BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
+
+ /*
+ * 3. Calculate SecretKey = PublicKey^PrivateKey (mod P)
+ * - BigInteger Operation
+ * - Montgomery reduction
+ */
+ BigInteger_Montgomery_ExpMod(pBI_PublicKey, pBI_PrivateKey, pBI_P, &pBI_SecretKey);
+
+ /*
+ * 4. Transfer BigInteger structure to char array
+ */
+ BigInteger_BI2Bin(pBI_SecretKey, SecretKey, SecretKeyLength);
+
+ BigInteger_Free(&pBI_P);
+ BigInteger_Free(&pBI_PrivateKey);
+ BigInteger_Free(&pBI_PublicKey);
+ BigInteger_Free(&pBI_SecretKey);
+} /* End of DH_SecretKey_Generate */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/crypt_hmac.c b/cleopatre/devkit/mt7601udrv/common/crypt_hmac.c
new file mode 100644
index 0000000000..2e3a6dcc08
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/crypt_hmac.c
@@ -0,0 +1,282 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ HMAC
+
+ Abstract:
+ FIPS 198: The Keyed-Hash Message Authentication Code (HMAC)
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2008/11/24 Create HMAC-SHA1, HMAC-SHA256
+***************************************************************************/
+
+#include "crypt_hmac.h"
+
+
+#ifdef HMAC_SHA1_SUPPORT
+/*
+========================================================================
+Routine Description:
+ HMAC using SHA1 hash function
+
+Arguments:
+ key Secret key
+ key_len The length of the key in bytes
+ message Message context
+ message_len The length of message in bytes
+ macLen Request the length of message authentication code
+
+Return Value:
+ mac Message authentication code
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_HMAC_SHA1 (
+ IN const UINT8 Key[],
+ IN UINT KeyLen,
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 MAC[],
+ IN UINT MACLen)
+{
+ SHA1_CTX_STRUC sha_ctx1;
+ SHA1_CTX_STRUC sha_ctx2;
+ UINT8 K0[SHA1_BLOCK_SIZE];
+ UINT8 Digest[SHA1_DIGEST_SIZE];
+ UINT index;
+
+ NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC));
+ NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC));
+ /*
+ * If the length of K = B(Block size): K0 = K.
+ * If the length of K > B: hash K to obtain an L byte string,
+ * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+ * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+ */
+ NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
+ if (KeyLen <= SHA1_BLOCK_SIZE)
+ NdisMoveMemory(K0, Key, KeyLen);
+ else
+ RT_SHA1(Key, KeyLen, K0);
+ /* End of if */
+
+ /* Exclusive-Or K0 with ipad */
+ /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
+ for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+ K0[index] ^= 0x36;
+ /* End of for */
+
+ RT_SHA1_Init(&sha_ctx1);
+ /* H(K0^ipad) */
+ RT_SHA1_Append(&sha_ctx1, K0, sizeof(K0));
+ /* H((K0^ipad)||text) */
+ RT_SHA1_Append(&sha_ctx1, Message, MessageLen);
+ RT_SHA1_End(&sha_ctx1, Digest);
+
+ /* Exclusive-Or K0 with opad and remove ipad */
+ /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
+ for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+ K0[index] ^= 0x36^0x5c;
+ /* End of for */
+
+ RT_SHA1_Init(&sha_ctx2);
+ /* H(K0^opad) */
+ RT_SHA1_Append(&sha_ctx2, K0, sizeof(K0));
+ /* H( (K0^opad) || H((K0^ipad)||text) ) */
+ RT_SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
+ RT_SHA1_End(&sha_ctx2, Digest);
+
+ if (MACLen > SHA1_DIGEST_SIZE)
+ NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
+ else
+ NdisMoveMemory(MAC, Digest, MACLen);
+} /* End of RT_HMAC_SHA1 */
+#endif /* HMAC_SHA1_SUPPORT */
+
+
+#ifdef HMAC_SHA256_SUPPORT
+/*
+========================================================================
+Routine Description:
+ HMAC using SHA256 hash function
+
+Arguments:
+ key Secret key
+ key_len The length of the key in bytes
+ message Message context
+ message_len The length of message in bytes
+ macLen Request the length of message authentication code
+
+Return Value:
+ mac Message authentication code
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_HMAC_SHA256 (
+ IN const UINT8 Key[],
+ IN UINT KeyLen,
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 MAC[],
+ IN UINT MACLen)
+{
+ SHA256_CTX_STRUC sha_ctx1;
+ SHA256_CTX_STRUC sha_ctx2;
+ UINT8 K0[SHA256_BLOCK_SIZE];
+ UINT8 Digest[SHA256_DIGEST_SIZE];
+ UINT index;
+
+ NdisZeroMemory(&sha_ctx1, sizeof(SHA256_CTX_STRUC));
+ NdisZeroMemory(&sha_ctx2, sizeof(SHA256_CTX_STRUC));
+ /*
+ * If the length of K = B(Block size): K0 = K.
+ * If the length of K > B: hash K to obtain an L byte string,
+ * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+ * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+ */
+ NdisZeroMemory(K0, SHA256_BLOCK_SIZE);
+ if (KeyLen <= SHA256_BLOCK_SIZE) {
+ NdisMoveMemory(K0, Key, KeyLen);
+ } else {
+ RT_SHA256(Key, KeyLen, K0);
+ }
+
+ /* Exclusive-Or K0 with ipad */
+ /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
+ for (index = 0; index < SHA256_BLOCK_SIZE; index++)
+ K0[index] ^= 0x36;
+ /* End of for */
+
+ RT_SHA256_Init(&sha_ctx1);
+ /* H(K0^ipad) */
+ RT_SHA256_Append(&sha_ctx1, K0, sizeof(K0));
+ /* H((K0^ipad)||text) */
+ RT_SHA256_Append(&sha_ctx1, Message, MessageLen);
+ RT_SHA256_End(&sha_ctx1, Digest);
+
+ /* Exclusive-Or K0 with opad and remove ipad */
+ /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
+ for (index = 0; index < SHA256_BLOCK_SIZE; index++)
+ K0[index] ^= 0x36^0x5c;
+ /* End of for */
+
+ RT_SHA256_Init(&sha_ctx2);
+ /* H(K0^opad) */
+ RT_SHA256_Append(&sha_ctx2, K0, sizeof(K0));
+ /* H( (K0^opad) || H((K0^ipad)||text) ) */
+ RT_SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE);
+ RT_SHA256_End(&sha_ctx2, Digest);
+
+ if (MACLen > SHA256_DIGEST_SIZE)
+ NdisMoveMemory(MAC, Digest,SHA256_DIGEST_SIZE);
+ else
+ NdisMoveMemory(MAC, Digest, MACLen);
+
+} /* End of RT_HMAC_SHA256 */
+#endif /* HMAC_SHA256_SUPPORT */
+
+
+#ifdef HMAC_MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+ HMAC using MD5 hash function
+
+Arguments:
+ key Secret key
+ key_len The length of the key in bytes
+ message Message context
+ message_len The length of message in bytes
+ macLen Request the length of message authentication code
+
+Return Value:
+ mac Message authentication code
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_HMAC_MD5(
+ IN const UINT8 Key[],
+ IN UINT KeyLen,
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 MAC[],
+ IN UINT MACLen)
+{
+ MD5_CTX_STRUC md5_ctx1;
+ MD5_CTX_STRUC md5_ctx2;
+ UINT8 K0[MD5_BLOCK_SIZE];
+ UINT8 Digest[MD5_DIGEST_SIZE];
+ UINT index;
+
+ NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC));
+ NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC));
+ /*
+ * If the length of K = B(Block size): K0 = K.
+ * If the length of K > B: hash K to obtain an L byte string,
+ * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+ * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+ */
+ NdisZeroMemory(K0, MD5_BLOCK_SIZE);
+ if (KeyLen <= MD5_BLOCK_SIZE) {
+ NdisMoveMemory(K0, Key, KeyLen);
+ } else {
+ RT_MD5(Key, KeyLen, K0);
+ }
+
+ /* Exclusive-Or K0 with ipad */
+ /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
+ for (index = 0; index < MD5_BLOCK_SIZE; index++)
+ K0[index] ^= 0x36;
+ /* End of for */
+
+ RT_MD5_Init(&md5_ctx1);
+ /* H(K0^ipad) */
+ RT_MD5_Append(&md5_ctx1, K0, sizeof(K0));
+ /* H((K0^ipad)||text) */
+ RT_MD5_Append(&md5_ctx1, Message, MessageLen);
+ RT_MD5_End(&md5_ctx1, Digest);
+
+ /* Exclusive-Or K0 with opad and remove ipad */
+ /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
+ for (index = 0; index < MD5_BLOCK_SIZE; index++)
+ K0[index] ^= 0x36^0x5c;
+ /* End of for */
+
+ RT_MD5_Init(&md5_ctx2);
+ /* H(K0^opad) */
+ RT_MD5_Append(&md5_ctx2, K0, sizeof(K0));
+ /* H( (K0^opad) || H((K0^ipad)||text) ) */
+ RT_MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
+ RT_MD5_End(&md5_ctx2, Digest);
+
+ if (MACLen > MD5_DIGEST_SIZE)
+ NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
+ else
+ NdisMoveMemory(MAC, Digest, MACLen);
+} /* End of RT_HMAC_SHA256 */
+#endif /* HMAC_MD5_SUPPORT */
+
+
+/* End of crypt_hmac.c */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/crypt_md5.c b/cleopatre/devkit/mt7601udrv/common/crypt_md5.c
new file mode 100644
index 0000000000..a49c1113d9
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/crypt_md5.c
@@ -0,0 +1,356 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ MD5
+
+ Abstract:
+ RFC1321: The MD5 Message-Digest Algorithm
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2008/11/24 Create md5
+***************************************************************************/
+
+#include "rt_config.h"
+
+
+#ifdef MD5_SUPPORT
+/*
+ * F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
+#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
+
+#define ROUND1(a, b, c, d, x, s, ac) { \
+ (a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \
+ (a) = ROTL32((a),(s)); \
+ (a) += (b); \
+}
+#define ROUND2(a, b, c, d, x, s, ac) { \
+ (a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \
+ (a) = ROTL32((a),(s)); \
+ (a) += (b); \
+}
+#define ROUND3(a, b, c, d, x, s, ac) { \
+ (a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \
+ (a) = ROTL32((a),(s)); \
+ (a) += (b); \
+}
+#define ROUND4(a, b, c, d, x, s, ac) { \
+ (a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \
+ (a) = ROTL32((a),(s)); \
+ (a) += (b); \
+}
+static const UINT32 MD5_DefaultHashValue[4] = {
+ 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
+};
+#endif /* MD5_SUPPORT */
+
+
+#ifdef MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Initial Md5_CTX_STRUC
+
+Arguments:
+ pMD5_CTX Pointer to Md5_CTX_STRUC
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_MD5_Init (
+ IN MD5_CTX_STRUC *pMD5_CTX)
+{
+ NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
+ sizeof(MD5_DefaultHashValue));
+ NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+ pMD5_CTX->BlockLen = 0;
+ pMD5_CTX->MessageLen = 0;
+} /* End of RT_MD5_Init */
+
+
+/*
+========================================================================
+Routine Description:
+ MD5 computation for one block (512 bits)
+
+Arguments:
+ pMD5_CTX Pointer to Md5_CTX_STRUC
+
+Return Value:
+ None
+
+Note:
+ T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
+========================================================================
+*/
+VOID RT_MD5_Hash (
+ IN MD5_CTX_STRUC *pMD5_CTX)
+{
+ UINT32 X_i;
+ UINT32 X[16];
+ UINT32 a,b,c,d;
+
+ /* Prepare the message schedule, {X_i} */
+ NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
+ for (X_i = 0; X_i < 16; X_i++)
+ X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
+ /* End of for */
+
+ /* MD5 hash computation */
+ /* Initialize the working variables */
+ a = pMD5_CTX->HashValue[0];
+ b = pMD5_CTX->HashValue[1];
+ c = pMD5_CTX->HashValue[2];
+ d = pMD5_CTX->HashValue[3];
+
+ /*
+ * Round 1
+ * Let [abcd k s i] denote the operation
+ * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
+ */
+ ROUND1(a, b, c, d, X[ 0], 7, 0xd76aa478); /* 1 */
+ ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */
+ ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */
+ ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */
+ ROUND1(a, b, c, d, X[ 4], 7, 0xf57c0faf); /* 5 */
+ ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */
+ ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */
+ ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */
+ ROUND1(a, b, c, d, X[ 8], 7, 0x698098d8); /* 9 */
+ ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */
+ ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
+ ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
+ ROUND1(a, b, c, d, X[12], 7, 0x6b901122); /* 13 */
+ ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
+ ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
+ ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
+
+ /*
+ * Round 2
+ * Let [abcd k s i] denote the operation
+ * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
+ */
+ ROUND2(a, b, c, d, X[ 1], 5, 0xf61e2562); /* 17 */
+ ROUND2(d, a, b, c, X[ 6], 9, 0xc040b340); /* 18 */
+ ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
+ ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */
+ ROUND2(a, b, c, d, X[ 5], 5, 0xd62f105d); /* 21 */
+ ROUND2(d, a, b, c, X[10], 9, 0x2441453); /* 22 */
+ ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
+ ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */
+ ROUND2(a, b, c, d, X[ 9], 5, 0x21e1cde6); /* 25 */
+ ROUND2(d, a, b, c, X[14], 9, 0xc33707d6); /* 26 */
+ ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */
+ ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */
+ ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905); /* 29 */
+ ROUND2(d, a, b, c, X[ 2], 9, 0xfcefa3f8); /* 30 */
+ ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */
+ ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
+
+ /*
+ * Round 3
+ * Let [abcd k s t] denote the operation
+ * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
+ */
+ ROUND3(a, b, c, d, X[ 5], 4, 0xfffa3942); /* 33 */
+ ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */
+ ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
+ ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
+ ROUND3(a, b, c, d, X[ 1], 4, 0xa4beea44); /* 37 */
+ ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */
+ ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */
+ ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
+ ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6); /* 41 */
+ ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */
+ ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */
+ ROUND3(b, c, d, a, X[ 6], 23, 0x4881d05); /* 44 */
+ ROUND3(a, b, c, d, X[ 9], 4, 0xd9d4d039); /* 45 */
+ ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
+ ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
+ ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */
+
+ /*
+ * Round 4
+ * Let [abcd k s t] denote the operation
+ * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
+ */
+ ROUND4(a, b, c, d, X[ 0], 6, 0xf4292244); /* 49 */
+ ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */
+ ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
+ ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */
+ ROUND4(a, b, c, d, X[12], 6, 0x655b59c3); /* 53 */
+ ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */
+ ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
+ ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */
+ ROUND4(a, b, c, d, X[ 8], 6, 0x6fa87e4f); /* 57 */
+ ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
+ ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */
+ ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
+ ROUND4(a, b, c, d, X[ 4], 6, 0xf7537e82); /* 61 */
+ ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
+ ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */
+ ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */
+
+ /* Compute the i^th intermediate hash value H^(i) */
+ pMD5_CTX->HashValue[0] += a;
+ pMD5_CTX->HashValue[1] += b;
+ pMD5_CTX->HashValue[2] += c;
+ pMD5_CTX->HashValue[3] += d;
+
+ NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+ pMD5_CTX->BlockLen = 0;
+} /* End of RT_MD5_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+ The message is appended to block. If block size > 64 bytes, the MD5_Hash
+will be called.
+
+Arguments:
+ pMD5_CTX Pointer to MD5_CTX_STRUC
+ message Message context
+ messageLen The length of message in bytes
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_MD5_Append (
+ IN MD5_CTX_STRUC *pMD5_CTX,
+ IN const UINT8 Message[],
+ IN UINT MessageLen)
+{
+ UINT appendLen = 0;
+ UINT diffLen = 0;
+
+ while (appendLen != MessageLen) {
+ diffLen = MessageLen - appendLen;
+ if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
+ NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+ Message + appendLen, diffLen);
+ pMD5_CTX->BlockLen += diffLen;
+ appendLen += diffLen;
+ }
+ else
+ {
+ NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+ Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+ appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+ pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
+ RT_MD5_Hash(pMD5_CTX);
+ } /* End of if */
+ } /* End of while */
+ pMD5_CTX->MessageLen += MessageLen;
+} /* End of RT_MD5_Append */
+
+
+/*
+========================================================================
+Routine Description:
+ 1. Append bit 1 to end of the message
+ 2. Append the length of message in rightmost 64 bits
+ 3. Transform the Hash Value to digest message
+
+Arguments:
+ pMD5_CTX Pointer to MD5_CTX_STRUC
+
+Return Value:
+ digestMessage Digest message
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_MD5_End (
+ IN MD5_CTX_STRUC *pMD5_CTX,
+ OUT UINT8 DigestMessage[])
+{
+ UINT index;
+ UINT64 message_length_bits;
+
+ /* append 1 bits to end of the message */
+ NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
+
+ /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+ if (pMD5_CTX->BlockLen > 55)
+ RT_MD5_Hash(pMD5_CTX);
+ /* End of if */
+
+ /* Append the length of message in rightmost 64 bits */
+ message_length_bits = pMD5_CTX->MessageLen*8;
+ message_length_bits = cpu2le64(message_length_bits);
+ NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
+ RT_MD5_Hash(pMD5_CTX);
+
+ /* Return message digest, transform the UINT32 hash value to bytes */
+ for (index = 0; index < 4;index++)
+ pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]);
+ /* End of for */
+ NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
+} /* End of RT_MD5_End */
+
+
+/*
+========================================================================
+Routine Description:
+ MD5 algorithm
+
+Arguments:
+ message Message context
+ messageLen The length of message in bytes
+
+Return Value:
+ digestMessage Digest message
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_MD5 (
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 DigestMessage[])
+{
+ MD5_CTX_STRUC md5_ctx;
+
+ NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC));
+ RT_MD5_Init(&md5_ctx);
+ RT_MD5_Append(&md5_ctx, Message, MessageLen);
+ RT_MD5_End(&md5_ctx, DigestMessage);
+} /* End of RT_MD5 */
+
+#endif /* MD5_SUPPORT */
+
+
+/* End of crypt_md5.c */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/crypt_sha2.c b/cleopatre/devkit/mt7601udrv/common/crypt_sha2.c
new file mode 100644
index 0000000000..75de87cd3f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/crypt_sha2.c
@@ -0,0 +1,555 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ SHA2
+
+ Abstract:
+ FIPS 180-2: Secure Hash Standard (SHS)
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2008/11/24 Create SHA1
+ Eddy 2008/07/23 Create SHA256
+***************************************************************************/
+
+#include "rt_config.h"
+
+
+/* Basic operations */
+#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */
+#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
+
+/* Basic functions */
+#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
+#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
+#define Parity(x,y,z) (x ^ y ^ z)
+
+#ifdef SHA1_SUPPORT
+/* SHA1 constants */
+#define SHA1_MASK 0x0000000f
+static const UINT32 SHA1_K[4] = {
+ 0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
+};
+static const UINT32 SHA1_DefaultHashValue[5] = {
+ 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
+};
+#endif /* SHA1_SUPPORT */
+
+
+#ifdef SHA256_SUPPORT
+/* SHA256 functions */
+#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22))
+#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25))
+#define Sigma_256_0(x) (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3))
+#define Sigma_256_1(x) (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10))
+/* SHA256 constants */
+static const UINT32 SHA256_K[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+ 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+ 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+ 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+ 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+ 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+ 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+ 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+ 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+ 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+ 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+ 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+ 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+static const UINT32 SHA256_DefaultHashValue[8] = {
+ 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
+ 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
+};
+#endif /* SHA256_SUPPORT */
+
+
+#ifdef SHA1_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Initial SHA1_CTX_STRUC
+
+Arguments:
+ pSHA_CTX Pointer to SHA1_CTX_STRUC
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA1_Init (
+ IN SHA1_CTX_STRUC *pSHA_CTX)
+{
+ NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
+ sizeof(SHA1_DefaultHashValue));
+ NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+ pSHA_CTX->MessageLen = 0;
+ pSHA_CTX->BlockLen = 0;
+} /* End of RT_SHA1_Init */
+
+
+/*
+========================================================================
+Routine Description:
+ SHA1 computation for one block (512 bits)
+
+Arguments:
+ pSHA_CTX Pointer to SHA1_CTX_STRUC
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA1_Hash (
+ IN SHA1_CTX_STRUC *pSHA_CTX)
+{
+ UINT32 W_i,t;
+ UINT32 W[80];
+ UINT32 a,b,c,d,e,T,f_t = 0;
+
+ /* Prepare the message schedule, {W_i}, 0 < t < 15 */
+ NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+ for (W_i = 0; W_i < 16; W_i++) {
+ W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
+ } /* End of for */
+
+ for (W_i = 16; W_i < 80; W_i++) {
+ W[W_i] = ROTL32((W[W_i - 3] ^ W[W_i - 8] ^ W[W_i - 14] ^ W[W_i - 16]),1);
+ } /* End of for */
+
+
+ /* SHA256 hash computation */
+ /* Initialize the working variables */
+ a = pSHA_CTX->HashValue[0];
+ b = pSHA_CTX->HashValue[1];
+ c = pSHA_CTX->HashValue[2];
+ d = pSHA_CTX->HashValue[3];
+ e = pSHA_CTX->HashValue[4];
+
+ /* 80 rounds */
+ for (t = 0;t < 20;t++) {
+ f_t = Ch(b,c,d);
+ T = ROTL32(a,5) + f_t + e + SHA1_K[0] + W[t];
+ e = d;
+ d = c;
+ c = ROTL32(b,30);
+ b = a;
+ a = T;
+ } /* End of for */
+ for (t = 20;t < 40;t++) {
+ f_t = Parity(b,c,d);
+ T = ROTL32(a,5) + f_t + e + SHA1_K[1] + W[t];
+ e = d;
+ d = c;
+ c = ROTL32(b,30);
+ b = a;
+ a = T;
+ } /* End of for */
+ for (t = 40;t < 60;t++) {
+ f_t = Maj(b,c,d);
+ T = ROTL32(a,5) + f_t + e + SHA1_K[2] + W[t];
+ e = d;
+ d = c;
+ c = ROTL32(b,30);
+ b = a;
+ a = T;
+ } /* End of for */
+ for (t = 60;t < 80;t++) {
+ f_t = Parity(b,c,d);
+ T = ROTL32(a,5) + f_t + e + SHA1_K[3] + W[t];
+ e = d;
+ d = c;
+ c = ROTL32(b,30);
+ b = a;
+ a = T;
+ } /* End of for */
+
+
+ /* Compute the i^th intermediate hash value H^(i) */
+ pSHA_CTX->HashValue[0] += a;
+ pSHA_CTX->HashValue[1] += b;
+ pSHA_CTX->HashValue[2] += c;
+ pSHA_CTX->HashValue[3] += d;
+ pSHA_CTX->HashValue[4] += e;
+
+ NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+ pSHA_CTX->BlockLen = 0;
+} /* End of RT_SHA1_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+ The message is appended to block. If block size > 64 bytes, the SHA1_Hash
+will be called.
+
+Arguments:
+ pSHA_CTX Pointer to SHA1_CTX_STRUC
+ message Message context
+ messageLen The length of message in bytes
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA1_Append (
+ IN SHA1_CTX_STRUC *pSHA_CTX,
+ IN const UINT8 Message[],
+ IN UINT MessageLen)
+{
+ UINT appendLen = 0;
+ UINT diffLen = 0;
+
+ while (appendLen != MessageLen) {
+ diffLen = MessageLen - appendLen;
+ if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) {
+ NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+ Message + appendLen, diffLen);
+ pSHA_CTX->BlockLen += diffLen;
+ appendLen += diffLen;
+ }
+ else
+ {
+ NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+ Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+ appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+ pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
+ RT_SHA1_Hash(pSHA_CTX);
+ } /* End of if */
+ } /* End of while */
+ pSHA_CTX->MessageLen += MessageLen;
+} /* End of RT_SHA1_Append */
+
+
+/*
+========================================================================
+Routine Description:
+ 1. Append bit 1 to end of the message
+ 2. Append the length of message in rightmost 64 bits
+ 3. Transform the Hash Value to digest message
+
+Arguments:
+ pSHA_CTX Pointer to SHA1_CTX_STRUC
+
+Return Value:
+ digestMessage Digest message
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA1_End (
+ IN SHA1_CTX_STRUC *pSHA_CTX,
+ OUT UINT8 DigestMessage[])
+{
+ UINT index;
+ UINT64 message_length_bits;
+
+ /* Append bit 1 to end of the message */
+ NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
+
+ /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+ if (pSHA_CTX->BlockLen > 55)
+ RT_SHA1_Hash(pSHA_CTX);
+ /* End of if */
+
+ /* Append the length of message in rightmost 64 bits */
+ message_length_bits = pSHA_CTX->MessageLen*8;
+ message_length_bits = cpu2be64(message_length_bits);
+ NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
+ RT_SHA1_Hash(pSHA_CTX);
+
+ /* Return message digest, transform the UINT32 hash value to bytes */
+ for (index = 0; index < 5;index++)
+ pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
+ /* End of for */
+ NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
+} /* End of RT_SHA1_End */
+
+
+/*
+========================================================================
+Routine Description:
+ SHA1 algorithm
+
+Arguments:
+ message Message context
+ messageLen The length of message in bytes
+
+Return Value:
+ digestMessage Digest message
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA1 (
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 DigestMessage[])
+{
+
+ SHA1_CTX_STRUC sha_ctx;
+
+ NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC));
+ RT_SHA1_Init(&sha_ctx);
+ RT_SHA1_Append(&sha_ctx, Message, MessageLen);
+ RT_SHA1_End(&sha_ctx, DigestMessage);
+} /* End of RT_SHA1 */
+#endif /* SHA1_SUPPORT */
+
+
+#ifdef SHA256_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Initial SHA256_CTX_STRUC
+
+Arguments:
+ pSHA_CTX Pointer to SHA256_CTX_STRUC
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA256_Init (
+ IN SHA256_CTX_STRUC *pSHA_CTX)
+{
+ NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue,
+ sizeof(SHA256_DefaultHashValue));
+ NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+ pSHA_CTX->MessageLen = 0;
+ pSHA_CTX->BlockLen = 0;
+} /* End of RT_SHA256_Init */
+
+
+/*
+========================================================================
+Routine Description:
+ SHA256 computation for one block (512 bits)
+
+Arguments:
+ pSHA_CTX Pointer to SHA256_CTX_STRUC
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA256_Hash (
+ IN SHA256_CTX_STRUC *pSHA_CTX)
+{
+ UINT32 W_i,t;
+ UINT32 W[64];
+ UINT32 a,b,c,d,e,f,g,h,T1,T2;
+
+ /* Prepare the message schedule, {W_i}, 0 < t < 15 */
+ NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+ for (W_i = 0; W_i < 16; W_i++)
+ W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
+ /* End of for */
+
+ /* SHA256 hash computation */
+ /* Initialize the working variables */
+ a = pSHA_CTX->HashValue[0];
+ b = pSHA_CTX->HashValue[1];
+ c = pSHA_CTX->HashValue[2];
+ d = pSHA_CTX->HashValue[3];
+ e = pSHA_CTX->HashValue[4];
+ f = pSHA_CTX->HashValue[5];
+ g = pSHA_CTX->HashValue[6];
+ h = pSHA_CTX->HashValue[7];
+
+ /* 64 rounds */
+ for (t = 0;t < 64;t++) {
+ if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */
+ W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16];
+ /* End of if */
+ T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t];
+ T2 = Zsigma_256_0(a) + Maj(a,b,c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+ } /* End of for */
+
+ /* Compute the i^th intermediate hash value H^(i) */
+ pSHA_CTX->HashValue[0] += a;
+ pSHA_CTX->HashValue[1] += b;
+ pSHA_CTX->HashValue[2] += c;
+ pSHA_CTX->HashValue[3] += d;
+ pSHA_CTX->HashValue[4] += e;
+ pSHA_CTX->HashValue[5] += f;
+ pSHA_CTX->HashValue[6] += g;
+ pSHA_CTX->HashValue[7] += h;
+
+ NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+ pSHA_CTX->BlockLen = 0;
+} /* End of RT_SHA256_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+ The message is appended to block. If block size > 64 bytes, the SHA256_Hash
+will be called.
+
+Arguments:
+ pSHA_CTX Pointer to SHA256_CTX_STRUC
+ message Message context
+ messageLen The length of message in bytes
+
+Return Value:
+ None
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA256_Append (
+ IN SHA256_CTX_STRUC *pSHA_CTX,
+ IN const UINT8 Message[],
+ IN UINT MessageLen)
+{
+ UINT appendLen = 0;
+ UINT diffLen = 0;
+
+ while (appendLen != MessageLen) {
+ diffLen = MessageLen - appendLen;
+ if ((pSHA_CTX->BlockLen + diffLen) < SHA256_BLOCK_SIZE) {
+ NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+ Message + appendLen, diffLen);
+ pSHA_CTX->BlockLen += diffLen;
+ appendLen += diffLen;
+ }
+ else
+ {
+ NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+ Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
+ appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
+ pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE;
+ RT_SHA256_Hash(pSHA_CTX);
+ } /* End of if */
+ } /* End of while */
+ pSHA_CTX->MessageLen += MessageLen;
+} /* End of RT_SHA256_Append */
+
+
+/*
+========================================================================
+Routine Description:
+ 1. Append bit 1 to end of the message
+ 2. Append the length of message in rightmost 64 bits
+ 3. Transform the Hash Value to digest message
+
+Arguments:
+ pSHA_CTX Pointer to SHA256_CTX_STRUC
+
+Return Value:
+ digestMessage Digest message
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA256_End (
+ IN SHA256_CTX_STRUC *pSHA_CTX,
+ OUT UINT8 DigestMessage[])
+{
+ UINT index;
+ UINT64 message_length_bits;
+
+ /* Append bit 1 to end of the message */
+ NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
+
+ /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+ if (pSHA_CTX->BlockLen > 55)
+ RT_SHA256_Hash(pSHA_CTX);
+ /* End of if */
+
+ /* Append the length of message in rightmost 64 bits */
+ message_length_bits = pSHA_CTX->MessageLen*8;
+ message_length_bits = cpu2be64(message_length_bits);
+ NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
+ RT_SHA256_Hash(pSHA_CTX);
+
+ /* Return message digest, transform the UINT32 hash value to bytes */
+ for (index = 0; index < 8;index++)
+ pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
+ /* End of for */
+ NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE);
+} /* End of RT_SHA256_End */
+
+
+/*
+========================================================================
+Routine Description:
+ SHA256 algorithm
+
+Arguments:
+ message Message context
+ messageLen The length of message in bytes
+
+Return Value:
+ digestMessage Digest message
+
+Note:
+ None
+========================================================================
+*/
+VOID RT_SHA256 (
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 DigestMessage[])
+{
+ SHA256_CTX_STRUC sha_ctx;
+
+ NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC));
+ RT_SHA256_Init(&sha_ctx);
+ RT_SHA256_Append(&sha_ctx, Message, MessageLen);
+ RT_SHA256_End(&sha_ctx, DigestMessage);
+} /* End of RT_SHA256 */
+#endif /* SHA256_SUPPORT */
+
+
+/* End of crypt_sha2.c */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/ee_efuse.c b/cleopatre/devkit/mt7601udrv/common/ee_efuse.c
new file mode 100644
index 0000000000..0067ca2362
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/ee_efuse.c
@@ -0,0 +1,1893 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ee_efuse.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifdef RTMP_EFUSE_SUPPORT
+
+#include "rt_config.h"
+
+#if defined(RT65xx) || defined(MT7601)
+/* eFuse registers */
+#define EFUSE_CTRL 0x24
+#define EFUSE_DATA0 0x28
+#define EFUSE_DATA1 0x2c
+#define EFUSE_DATA2 0x30
+#define EFUSE_DATA3 0x34
+#else
+/* eFuse registers */
+#define EFUSE_CTRL 0x0580
+#define EFUSE_DATA0 0x0590
+#define EFUSE_DATA1 0x0594
+#define EFUSE_DATA2 0x0598
+#define EFUSE_DATA3 0x059c
+#endif /* RT65xx */
+
+
+#define EFUSE_CTRL_3290 0x24
+#define EFUSE_DATA0_3290 0x28
+#define EFUSE_DATA1_3290 0x2c
+#define EFUSE_DATA2_3290 0x30
+#define EFUSE_DATA3_3290 0x34
+
+#ifdef RT65xx
+#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
+#define EFUSE_BUFFER_PATH "/var/lib/share/MT7650/RT30xxEEPROM.bin"
+#define MAX_EEPROM_BIN_FILE_SIZE 512
+#endif /* RT65xx */
+
+#ifdef MT7601
+#define EFUSE_EEPROM_DEFULT_FILE "MT7601EEPROM.bin"
+#define EFUSE_BUFFER_PATH "/var/lib/share/MT7601/MT7601EEPROM.bin"
+#define MAX_EEPROM_BIN_FILE_SIZE 512
+#endif /* MT7601 */
+
+#ifdef RTMP_MAC
+#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
+#define EFUSE_BUFFER_PATH "/var/lib/share/RT2870/RT30xxEEPROM.bin"
+#define MAX_EEPROM_BIN_FILE_SIZE 512
+#endif /* RTMP_MAC */
+
+#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);
+
+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;
+ UINT32 efuse_ctrl_reg = EFUSE_CTRL;
+
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuse_ctrl_reg = EFUSE_CTRL_3290;
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+
+ RTMP_IO_READ32(pAd, efuse_ctrl_reg, &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_reg, 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_reg, &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<Length/2; i++)
+ *(pData+2*i) = 0xffff;
+ }
+ else
+ {
+ /*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)*/
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuseDataOffset = EFUSE_DATA0_3290 + (Offset & 0xC);
+ else
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+ efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
+ /*data hold 4 bytes data.*/
+ /*In RTMP_IO_READ32 will automatically execute 32-bytes swapping*/
+ RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+ /*Decide the upper 2 bytes or the bottom 2 bytes.*/
+ /* Little-endian S | S Big-endian*/
+ /* addr 3 2 1 0 | 0 1 2 3*/
+ /* Ori-V D C B A | A B C D*/
+ /*After swapping*/
+ /* D C B A | D C B A*/
+ /*Return 2-bytes*/
+ /*The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.*/
+ /*For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.*/
+#ifdef RT_BIG_ENDIAN
+ data = data << (8*((Offset & 0x3)^0x2));
+#else
+ data = data >> (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;
+ UINT32 efuse_ctrl_reg = EFUSE_CTRL;
+
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuse_ctrl_reg = EFUSE_CTRL_3290;
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+
+ RTMP_IO_READ32(pAd, efuse_ctrl_reg, &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_reg, 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*/
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuseDataOffset = EFUSE_DATA0_3290 + (Offset & 0xC) ;
+ else
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+ 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:
+
+========================================================================
+*/
+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<Length; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
+ }
+}
+
+/*
+========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+========================================================================
+*/
+NTSTATUS eFuseRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUSHORT pData,
+ IN USHORT Length)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ UCHAR EFSROM_AOUT;
+ int i;
+
+ for(i=0; i<Length; i+=2)
+ {
+ EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pData[i/2]);
+ }
+ return Status;
+}
+
+/*
+========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+========================================================================
+*/
+static VOID eFusePhysicalWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData)
+{
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ int i;
+ USHORT efuseDataOffset;
+ UINT32 data, eFuseDataBuffer[4];
+ UINT32 efuse_ctrl_reg = EFUSE_CTRL;
+
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuse_ctrl_reg = EFUSE_CTRL_3290;
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+
+ /*Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.*/
+
+ /*read current values of 16-byte block */
+ RTMP_IO_READ32(pAd, efuse_ctrl_reg, &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.*/
+ 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_reg, data);
+
+ /*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.*/
+ i = 0;
+ while(i < 500)
+ {
+ RTMP_IO_READ32(pAd, efuse_ctrl_reg, &eFuseCtrlStruc.word);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ /*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)*/
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuseDataOffset = EFUSE_DATA0_3290;
+ else
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuseDataOffset += 4;
+ else
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+ efuseDataOffset -= 4;
+ }
+
+ /*Update the value, the offset is multiple of 2, length is 2*/
+ efuseDataOffset = (Offset & 0xc) >> 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;
+ }
+
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ efuseDataOffset = EFUSE_DATA0;
+#else
+ efuseDataOffset = EFUSE_DATA3;
+#endif
+
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT3290(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ efuseDataOffset += 4;
+ else
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+ efuseDataOffset -= 4;
+ }
+
+ /*Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/
+ // TODO: shiang, for below line, windows driver didn't have this read, why we have ??
+ RTMP_IO_READ32(pAd, efuse_ctrl_reg, &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_reg, 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_reg, &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);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* invalidate the low byte*/
+ for (i=0; i<8; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+ }
+ }
+ while (!bWriteSuccess&&Loop<2);
+ if(!bWriteSuccess)
+ DBGPRINT(RT_DEBUG_ERROR,("Efsue Write Failed!!\n"));
+ return TRUE;
+}
+
+
+/*
+========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+========================================================================
+*/
+static VOID eFuseWritePhysical(
+ IN PRTMP_ADAPTER pAd,
+ PUSHORT lpInBuffer,
+ ULONG nInBufferSize,
+ PUCHAR lpOutBuffer,
+ ULONG nOutBufferSize
+)
+{
+ USHORT* pInBuf = (USHORT*)lpInBuffer;
+ int i;
+ /*USHORT* pOutBuf = (USHORT*)ioBuffer;*/
+ USHORT Offset = pInBuf[0]; /* addr*/
+ USHORT Length = pInBuf[1]; /* length*/
+ USHORT* pValueX = &pInBuf[2]; /* value ... */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWritePhysical Offset=0x%x, length=%d\n", Offset, Length));
+
+ {
+ /* Little-endian S | S Big-endian*/
+ /* addr 3 2 1 0 | 0 1 2 3*/
+ /* Ori-V D C B A | A B C D*/
+ /* After swapping*/
+ /* D C B A | D C B A*/
+ /* Both the little and big-endian use the same sequence to write data.*/
+ /* Therefore, we only need swap data when read the data.*/
+ for (i=0; i<Length; i+=2)
+ {
+ eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+ }
+ }
+}
+
+
+/*
+========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+========================================================================
+*/
+NTSTATUS eFuseWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUSHORT pData,
+ IN USHORT length)
+{
+ int i;
+ USHORT* pValueX = (PUSHORT) pData; /*value ... */
+ PUSHORT OddWriteByteBuf;
+/* OddWriteByteBuf=(PUSHORT)kmalloc(sizeof(USHORT)*2, MEM_ALLOC_FLAG);*/
+ os_alloc_mem(NULL, (UCHAR **)&OddWriteByteBuf, sizeof(USHORT)*2);
+ /* The input value=3070 will be stored as following*/
+ /* Little-endian S | S Big-endian*/
+ /* addr 1 0 | 0 1 */
+ /* Ori-V 30 70 | 30 70 */
+ /* After swapping*/
+ /* 30 70 | 70 30*/
+ /* Casting*/
+ /* 3070 | 7030 (x)*/
+ /* The swapping should be removed for big-endian*/
+ if (OddWriteByteBuf == NULL)
+ return FALSE;
+ if((Offset%2)!=0)
+ {
+ length+=2;
+ Offset-=1;
+ eFuseRead(pAd,Offset,OddWriteByteBuf,2);
+ eFuseRead(pAd,Offset+2,(OddWriteByteBuf+1),2);
+ *OddWriteByteBuf&=0x00ff;
+ *OddWriteByteBuf|=((*pData)&0xff)<<8;
+ *(OddWriteByteBuf+1)&=0xff00;
+ *(OddWriteByteBuf+1)|=(*pData&0xff00)>>8;
+ pValueX=OddWriteByteBuf;
+
+ }
+
+ for(i=0; i<length; i+=2)
+ {
+ eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+ }
+/* kfree(OddWriteByteBuf);*/
+ os_free_mem(NULL, OddWriteByteBuf);
+ return TRUE;
+}
+
+
+/*
+========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+========================================================================
+*/
+INT set_eFuseGetFreeBlockCount_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT efusefreenum=0;
+ if (pAd->bUseEfuse == 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; i<pAd->chipCap.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_OFF, ("FileName=%s\n",src));
+
+ RtmpOSFSInfoChange(&osfsInfo, TRUE);
+
+ srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+ if (IS_FILE_OPEN_ERR(srcf))
+ {
+ DBGPRINT_ERR(("--> 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;ReadedByte<TotalByte;ReadedByte++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[ReadedByte]&0xff));
+ if((ReadedByte+1)%2==0)
+ PDATA[ReadedByte/2%8]=((buffer[ReadedByte]<<8)&0xff00)|(buffer[ReadedByte-1]&0xff);
+ if(ReadedByte%16==0)
+ {
+ CompareBuf=buffer[ReadedByte]&0xff;
+
+ }
+ else
+ {
+ CompareBuf&=(buffer[ReadedByte]&0xff);
+ if((ReadedByte+1)%16==0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",CompareBuf,ReadedByte/16));
+
+ if(CompareBuf!=0xff)
+ eFuseWriteRegistersFromBin(pAd,(USHORT)ReadedByte-15, 16, PDATA);
+ else
+ {
+ if(eFuseReadRegisters(pAd,ReadedByte, 2,(PUSHORT)&DATA)!=0x3f)
+ eFuseWriteRegistersFromBin(pAd,(USHORT)ReadedByte-15, 16, PDATA);
+ }
+ /*
+ for(l=0;l<8;l++)
+ printk("%04x ",PDATA[l]);
+ printk("\n");
+ */
+ NdisZeroMemory(PDATA,16);
+ }
+ }
+ }
+
+ return TRUE;
+
+closeFile:
+ if (srcf)
+ if (RtmpOSFileClose(srcf) != 0)
+ retval = FALSE;
+
+recoverFS:
+ RtmpOSFSInfoChange(&osfsInfo, FALSE);
+
+
+ if (memPtr)
+/* kfree(memPtr);*/
+ os_free_mem(NULL, memPtr);
+
+ return retval;
+}
+
+
+static NTSTATUS eFuseWriteRegistersFromBin(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData)
+{
+ USHORT i,StartBlock=0,EndBlock=0;
+ USHORT eFuseData;
+ USHORT LogicalAddress, BlkNum = 0xffff;
+ UCHAR EFSROM_AOUT,Loop=0;
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ USHORT efuseDataOffset;
+ UINT32 data,tempbuffer;
+ USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+ UINT32 buffer[4];
+ BOOLEAN bWriteSuccess = TRUE;
+ BOOLEAN bNotWrite=TRUE;
+ BOOLEAN bAllocateNewBlk=TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
+ /*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;
+ }
+
+ 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);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* invalidate the low byte*/
+ for (i=0; i<8; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+ }
+
+ }
+ while(!bWriteSuccess&&Loop<2);
+
+ return TRUE;
+}
+
+
+int rtmp_ee_efuse_read16(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ OUT USHORT *pValue)
+{
+
+ if (pAd->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(RTMP_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))
+ {
+ int ret;
+ 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;
+ ret = eFuseLoadEEPROM(pAd);
+
+ if ( ret == FALSE )
+ {
+ if ( pAd->chipCap.EFUSE_DEFAULT_BIN != NULL )
+ {
+ NdisMoveMemory(pAd->EEPROMImage, pAd->chipCap.EFUSE_DEFAULT_BIN, pAd->chipCap.EFUSE_DEFAULT_BIN_SIZE);
+ }
+ }
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ UINT16 NicConfig, FrequencyOffset;
+ UINT16 EfuseValue;
+
+ eFuseReadRegisters(pAd, EEPROM_FREQ_OFFSET, 2, &FrequencyOffset);
+ eFuseReadRegisters(pAd, EEPROM_NIC1_OFFSET, 2, &NicConfig);
+
+ if ( (NicConfig == 0x0) && ( FrequencyOffset != 0xFFFF ) )
+ {
+ /* Calibration Free IC, but E-Fuse is empty */
+ DBGPRINT(RT_DEBUG_OFF, ("Calibration Free IC, Load calibration data...\n"));
+
+ pAd->EEPROMImage[EEPROM_FREQ_OFFSET] = (UCHAR)(FrequencyOffset & 0xFF);
+
+ eFuseReadRegisters(pAd, EEPROM_TX0_TSSI_SLOPE, 2, &EfuseValue);
+ *(UINT16 *)(&pAd->EEPROMImage[EEPROM_TX0_TSSI_SLOPE]) = EfuseValue;
+ eFuseReadRegisters(pAd, EEPROM_TX0_TSSI_OFFSET_GROUP1, 2, &EfuseValue);
+ *(UINT16 *)(&pAd->EEPROMImage[EEPROM_TX0_TSSI_OFFSET_GROUP1]) = EfuseValue;
+ eFuseReadRegisters(pAd, EEPROM_TX0_TSSI_OFFSET, 2, &EfuseValue);
+ pAd->EEPROMImage[EEPROM_TX0_TSSI_OFFSET] = (UCHAR)(EfuseValue & 0xFF);;
+
+ eFuseReadRegisters(pAd, EEPROM_G_TARGET_POWER, 2, &EfuseValue);
+ pAd->EEPROMImage[EEPROM_G_TARGET_POWER + 1] = (UCHAR)(EfuseValue >> 8);
+
+ pAd->bCalFreeIC = TRUE;
+ }
+ else
+ {
+ pAd->bCalFreeIC = FALSE;
+ }
+ }
+#endif /* MT7601 */
+
+ }
+ else
+ {
+ pAd->bFroceEEPROMBuffer = FALSE;
+ pAd->bCalFreeIC = FALSE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse and force to use EEPROM Buffer Mode=%x\n",pAd->bFroceEEPROMBuffer));
+
+ // alan debug
+ //pAd->bFroceEEPROMBuffer = TRUE;
+ //eFuseLoadEEPROM(pAd);
+
+ return 0;
+}
+
+
+INT efuse_probe(RTMP_ADAPTER *pAd)
+{
+ UINT32 eFuseCtrl, ctrl_reg;
+
+
+ if (WaitForAsicReady(pAd) == FALSE)
+ return -1;
+
+ pAd->bUseEfuse=FALSE;
+#ifdef RT65xx
+ // TODO: shiang-6590, find a better naming for EFUSE_CTRL_3290!!
+ if (IS_RT65XX(pAd))
+ ctrl_reg = EFUSE_CTRL_3290;
+ else
+#endif /* RT65xx */
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ ctrl_reg = EFUSE_CTRL_3290;
+ else
+#endif /* MT7601 */
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ ctrl_reg = EFUSE_CTRL_3290;
+ else
+#endif /* RT3290 */
+ ctrl_reg = EFUSE_CTRL;
+ RTMP_IO_READ32(pAd, ctrl_reg, &eFuseCtrl);
+
+ //pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
+
+ pAd->bUseEfuse = TRUE;
+
+ return 0;
+}
+
+
+#ifdef RALINK_ATE
+INT Set_LoadEepromBufferFromEfuse_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT bEnable = simple_strtol(arg, 0, 10);
+ UINT free_blk = 0;
+
+ if (bEnable < 0)
+ return FALSE;
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Load EEPROM buffer from efuse, and change to BIN buffer mode\n"));
+
+ /* If the number of the used block is less than 5, assume the efuse is not well-calibrated, and force to use buffer mode */
+ eFuseGetFreeBlockCount(pAd, &free_blk);
+ if (free_blk > (pAd->chipCap.EFUSE_USAGE_MAP_SIZE - 5))
+ return FALSE;
+
+ NdisZeroMemory(pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE);
+ eFuseRead(pAd, 0, (PUSHORT)&pAd->EEPROMImage[0], MAX_EEPROM_BIN_FILE_SIZE);
+
+ /* Change to BIN eeprom buffer mode */
+ pAd->bFroceEEPROMBuffer = TRUE;
+
+ return TRUE;
+ }
+}
+#endif /* RALINK_ATE */
+
+
+#endif /* RTMP_EFUSE_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/ee_prom.c b/cleopatre/devkit/mt7601udrv/common/ee_prom.c
new file mode 100644
index 0000000000..a40a03a1d2
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/ee_prom.c
@@ -0,0 +1,265 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ee_prom.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
+#include "rt_config.h"
+
+
+
+/* IRQL = PASSIVE_LEVEL*/
+static inline VOID RaiseClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x)
+{
+ *x = *x | EESK;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+ RTMPusecDelay(1); /* Max frequency = 1MHz in Spec. definition */
+}
+
+/* IRQL = PASSIVE_LEVEL*/
+static inline VOID LowerClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x)
+{
+ *x = *x & ~EESK;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+ RTMPusecDelay(1);
+}
+
+/* IRQL = PASSIVE_LEVEL*/
+static inline USHORT ShiftInBits(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x,i;
+ USHORT data=0;
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~( EEDO | EEDI);
+
+ for(i=0; i<16; i++)
+ {
+ data = data << 1;
+ RaiseClock(pAd, &x);
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ LowerClock(pAd, &x); /*prevent read failed*/
+
+ x &= ~(EEDI);
+ if(x & EEDO)
+ data |= 1;
+ }
+
+ return data;
+}
+
+
+/* IRQL = PASSIVE_LEVEL*/
+static inline VOID ShiftOutBits(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT data,
+ IN USHORT count)
+{
+ UINT32 x,mask;
+
+ mask = 0x01 << (count - 1);
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~(EEDO | EEDI);
+
+ do
+ {
+ x &= ~EEDI;
+ if(data & mask) x |= EEDI;
+
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ mask = mask >> 1;
+ } while(mask);
+
+ x &= ~EEDI;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+}
+
+
+/* IRQL = PASSIVE_LEVEL*/
+static inline VOID EEpromCleanup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~(EECS | EEDI);
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+}
+
+
+static inline VOID EWEN(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ /* reset bits and set EECS*/
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ /* kick a pulse*/
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ /* output the read_opcode and six pulse in that order */
+ ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
+ ShiftOutBits(pAd, 0, 6);
+
+ EEpromCleanup(pAd);
+}
+
+
+static inline VOID EWDS(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ /* reset bits and set EECS*/
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ /* kick a pulse*/
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ /* output the read_opcode and six pulse in that order */
+ ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
+ ShiftOutBits(pAd, 0, 6);
+
+ EEpromCleanup(pAd);
+}
+
+
+/* IRQL = PASSIVE_LEVEL*/
+int rtmp_ee_prom_read16(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ OUT USHORT *pValue)
+{
+ UINT32 x;
+ USHORT data;
+
+
+
+ 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_RT2860(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);
+
+
+ *pValue = data;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+int rtmp_ee_prom_write16(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN USHORT Data)
+{
+ UINT32 x;
+
+
+
+ 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_RT2860(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);
+
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/eeprom.c b/cleopatre/devkit/mt7601udrv/common/eeprom.c
new file mode 100644
index 0000000000..500c255644
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/eeprom.c
@@ -0,0 +1,85 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ eeprom.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#include "rt_config.h"
+
+
+INT RtmpChipOpsEepromHook(RTMP_ADAPTER *pAd, INT infType)
+{
+ RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+ UINT32 e2p_csr;
+
+#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 RTMP_EFUSE_SUPPORT
+ efuse_probe(pAd);
+ if(pAd->bUseEfuse)
+ {
+ pChipOps->eeinit = eFuse_init;
+ pChipOps->eeread = rtmp_ee_efuse_read16;
+ pChipOps->eewrite = rtmp_ee_efuse_write16;
+ DBGPRINT(RT_DEBUG_OFF, ("NVM is EFUSE\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("Efuse Size=0x%x [Range:%x-%x] \n",
+ pAd->chipCap.EFUSE_USAGE_MAP_SIZE,
+ pAd->chipCap.EFUSE_USAGE_MAP_START,
+ pAd->chipCap.EFUSE_USAGE_MAP_END));
+
+ return 0 ;
+ }
+ else
+ {
+ pAd->bFroceEEPROMBuffer = FALSE;
+ DBGPRINT(RT_DEBUG_OFF, ("NVM is EEPROM\n"));
+ }
+#endif /* RTMP_EFUSE_SUPPORT */
+
+ switch(infType)
+ {
+
+
+#ifdef RTMP_USB_SUPPORT
+ case RTMP_DEV_INF_USB:
+ pChipOps->eeinit = NULL;
+ pChipOps->eeread = RTUSBReadEEPROM16;
+ pChipOps->eewrite = RTUSBWriteEEPROM16;
+ DBGPRINT(RT_DEBUG_OFF, ("pChipOps->eeread = RTUSBReadEEPROM16\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("pChipOps->eewrite = RTUSBWriteEEPROM16\n"));
+ break;
+#endif /* RTMP_USB_SUPPORT */
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
+ break;
+ }
+
+ return 0;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/common/frq_cal.c b/cleopatre/devkit/mt7601udrv/common/frq_cal.c
new file mode 100644
index 0000000000..ac05d39051
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/frq_cal.c
@@ -0,0 +1,28 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ frq_cal.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/igmp_snoop.c b/cleopatre/devkit/mt7601udrv/common/igmp_snoop.c
new file mode 100644
index 0000000000..47e458243f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/igmp_snoop.c
@@ -0,0 +1,1511 @@
+#ifdef IGMP_SNOOP_SUPPORT
+
+#include "rt_config.h"
+#include "ipv6.h"
+#include "igmp_snoop.h"
+
+UINT16 IPv6MulticastFilterExclued[] =
+{
+ IPV6_NEXT_HEADER_ICMPV6, /* ICMPv6. */
+ IPV6_NEXT_HEADER_PIM, /* PIM. */
+};
+#define IPV6_MULTICAST_FILTER_EXCLUED_SIZE \
+ (sizeof(IPv6MulticastFilterExclued) / sizeof(UINT16))
+
+static inline void initFreeEntryList(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PLIST_HEADER pList)
+{
+ int i;
+
+ for (i = 0; i < FREE_MEMBER_POOL_SIZE; i++)
+ insertTailList(pList, (PLIST_ENTRY)&(pMulticastFilterTable->freeMemberPool[i]));
+
+ return;
+}
+
+static inline PMEMBER_ENTRY AllocaGrpMemberEntry(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable)
+{
+ PMEMBER_ENTRY pMemberEntry;
+
+ RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+
+ pMemberEntry = (PMEMBER_ENTRY)removeHeadList(&pMulticastFilterTable->freeEntryList);
+
+ RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+
+ return (PMEMBER_ENTRY)pMemberEntry;
+}
+
+static inline VOID FreeGrpMemberEntry(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PMEMBER_ENTRY pEntry)
+{
+ RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+
+ insertTailList(&pMulticastFilterTable->freeEntryList, (PLIST_ENTRY)pEntry);
+
+ RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+}
+
+static VOID IGMPTableDisplay(
+ IN PRTMP_ADAPTER pAd);
+
+static BOOLEAN isIgmpMacAddr(
+ IN PUCHAR pMacAddr);
+
+static VOID InsertIgmpMember(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PLIST_HEADER pList,
+ IN PUCHAR pMemberAddr);
+
+static VOID DeleteIgmpMember(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PLIST_HEADER pList,
+ IN PUCHAR pMemberAddr);
+
+static VOID DeleteIgmpMemberList(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PLIST_HEADER pList);
+
+
+/*
+ ==========================================================================
+ Description:
+ This routine init the entire IGMP table.
+ ==========================================================================
+ */
+VOID MulticastFilterTableInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
+{
+ /* Initialize MAC table and allocate spin lock */
+/* *ppMulticastFilterTable = kmalloc(sizeof(MULTICAST_FILTER_TABLE), MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)ppMulticastFilterTable, sizeof(MULTICAST_FILTER_TABLE));
+ if (*ppMulticastFilterTable == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for Multicase filter table, size=%d\n",
+ __FUNCTION__, sizeof(MULTICAST_FILTER_TABLE)));
+ return;
+ }
+
+ NdisZeroMemory(*ppMulticastFilterTable, sizeof(MULTICAST_FILTER_TABLE));
+ NdisAllocateSpinLock(pAd, &((*ppMulticastFilterTable)->MulticastFilterTabLock));
+
+ NdisAllocateSpinLock(pAd, &((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
+ initList(&((*ppMulticastFilterTable)->freeEntryList));
+ initFreeEntryList(*ppMulticastFilterTable, &((*ppMulticastFilterTable)->freeEntryList));
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine reset the entire IGMP table.
+ ==========================================================================
+ */
+VOID MultiCastFilterTableReset(
+ IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
+{
+ if(*ppMulticastFilterTable == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+ return;
+ }
+
+ NdisFreeSpinLock(&((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
+ NdisFreeSpinLock(&((*ppMulticastFilterTable)->MulticastFilterTabLock));
+/* kfree(*ppMulticastFilterTable); */
+ os_free_mem(NULL, *ppMulticastFilterTable);
+ *ppMulticastFilterTable = NULL;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Display all entrys in IGMP table
+ ==========================================================================
+ */
+static VOID IGMPTableDisplay(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+ MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
+ PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+
+ if (pMulticastFilterTable == NULL)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+ return;
+ }
+
+ /* if FULL, return */
+ if (pMulticastFilterTable->Size == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Table empty.\n"));
+ return;
+ }
+
+ /* allocate one MAC entry */
+ RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+ for (i = 0; i< MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
+ {
+ /* pick up the first available vacancy */
+ if (pMulticastFilterTable->Content[i].Valid == TRUE)
+ {
+ PMEMBER_ENTRY pMemberEntry = NULL;
+ pEntry = &pMulticastFilterTable->Content[i];
+
+ DBGPRINT(RT_DEBUG_OFF, ("IF(%s) entry #%d, type=%s, GrpId=(%02x:%02x:%02x:%02x:%02x:%02x) memberCnt=%d\n",
+ RTMP_OS_NETDEV_GET_DEVNAME(pEntry->net_dev), i, (pEntry->type==0 ? "static":"dynamic"),
+ PRINT_MAC(pEntry->Addr), IgmpMemberCnt(&pEntry->MemberList)));
+
+ pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
+ while (pMemberEntry)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("member mac=(%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ PRINT_MAC(pMemberEntry->Addr)));
+
+ pMemberEntry = pMemberEntry->pNext;
+ }
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Add and new entry into MAC table
+ ==========================================================================
+ */
+BOOLEAN MulticastFilterTableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pGrpId,
+ IN PUCHAR pMemberAddr,
+ IN PNET_DEV dev,
+ IN MulticastFilterEntryType type)
+{
+ UCHAR HashIdx;
+ int i;
+ MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL, *pCurrEntry, *pPrevEntry;
+ PMEMBER_ENTRY pMemberEntry;
+ PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+
+ if (pMulticastFilterTable == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ /* if FULL, return */
+ if (pMulticastFilterTable->Size >= MAX_LEN_OF_MULTICAST_FILTER_TABLE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table full. max-entries = %d\n",
+ __FUNCTION__, MAX_LEN_OF_MULTICAST_FILTER_TABLE));
+ return FALSE;
+ }
+
+ /* check the rule is in table already or not. */
+ if ((pEntry = MulticastFilterTableLookup(pMulticastFilterTable, pGrpId, dev)))
+ {
+ /* doesn't indicate member mac address. */
+ if(pMemberAddr == NULL)
+ {
+ return FALSE;
+ }
+
+ pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
+
+ while (pMemberEntry)
+ {
+ if (MAC_ADDR_EQUAL(pMemberAddr, pMemberEntry->Addr))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: already in Members list.\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ pMemberEntry = pMemberEntry->pNext;
+ }
+ }
+
+ RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+ do
+ {
+ ULONG Now;
+ /* the multicast entry already exist but doesn't include the member yet. */
+ if (pEntry != NULL && pMemberAddr != NULL)
+ {
+ InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+ break;
+ }
+
+ /* allocate one MAC entry */
+ for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
+ {
+ /* pick up the first available vacancy */
+ pEntry = &pMulticastFilterTable->Content[i];
+ NdisGetSystemUpTime(&Now);
+ if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
+ && ((Now - pEntry->lastTime) > IGMPMAC_TB_ENTRY_AGEOUT_TIME))
+ {
+ PMULTICAST_FILTER_TABLE_ENTRY pHashEntry;
+
+ HashIdx = MULTICAST_ADDR_HASH_INDEX(pEntry->Addr);
+ pHashEntry = pMulticastFilterTable->Hash[HashIdx];
+
+ if ((pEntry->net_dev == pHashEntry->net_dev)
+ && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
+ {
+ pMulticastFilterTable->Hash[HashIdx] = pHashEntry->pNext;
+ pMulticastFilterTable->Size --;
+ DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
+ } else
+ {
+ while (pHashEntry->pNext)
+ {
+ pPrevEntry = pHashEntry;
+ pHashEntry = pHashEntry->pNext;
+ if ((pEntry->net_dev == pHashEntry->net_dev)
+ && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
+ {
+ pPrevEntry->pNext = pHashEntry->pNext;
+ pMulticastFilterTable->Size --;
+ DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+ break;
+ }
+ }
+ }
+ pEntry->Valid = FALSE;
+ DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+ }
+
+ if (pEntry->Valid == FALSE)
+ {
+ NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+ pEntry->Valid = TRUE;
+
+ COPY_MAC_ADDR(pEntry->Addr, pGrpId);
+ pEntry->net_dev = dev;
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ pEntry->type = type;
+ initList(&pEntry->MemberList);
+ if (pMemberAddr != NULL)
+ InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+
+ pMulticastFilterTable->Size ++;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MulticastFilterTableInsertEntry -IF(%s) allocate entry #%d, Total= %d\n", RTMP_OS_NETDEV_GET_DEVNAME(dev), i, pMulticastFilterTable->Size));
+ break;
+ }
+ }
+
+ /* add this MAC entry into HASH table */
+ if (pEntry)
+ {
+ HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
+ if (pMulticastFilterTable->Hash[HashIdx] == NULL)
+ {
+ pMulticastFilterTable->Hash[HashIdx] = pEntry;
+ } else
+ {
+ pCurrEntry = pMulticastFilterTable->Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+ }while(FALSE);
+
+ RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Delete a specified client from MAC table
+ ==========================================================================
+ */
+BOOLEAN MulticastFilterTableDeleteEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pGrpId,
+ IN PUCHAR pMemberAddr,
+ IN PNET_DEV dev)
+{
+ USHORT HashIdx;
+ MULTICAST_FILTER_TABLE_ENTRY *pEntry, *pPrevEntry;
+ PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+
+ if (pMulticastFilterTable == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+ do
+ {
+ HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
+ pPrevEntry = pEntry = pMulticastFilterTable->Hash[HashIdx];
+
+ while (pEntry && pEntry->Valid)
+ {
+ if ((pEntry->net_dev == dev)
+ && MAC_ADDR_EQUAL(pEntry->Addr, pGrpId))
+ break;
+ else
+ {
+ pPrevEntry = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ /* check the rule is in table already or not. */
+ if (pEntry && (pMemberAddr != NULL))
+ {
+ /*USHORT Aid = MCAST_WCID; */
+ /*SST Sst = SST_ASSOC; */
+ /*UCHAR PsMode = PWR_ACTIVE, Rate; */
+ /*if(APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate)) */
+ DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+ if (IgmpMemberCnt(&pEntry->MemberList) > 0)
+ break;
+ }
+
+ if (pEntry)
+ {
+ if (pEntry == pMulticastFilterTable->Hash[HashIdx])
+ {
+ pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
+ DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+ NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+ pMulticastFilterTable->Size --;
+ DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+ NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+ pMulticastFilterTable->Size --;
+ DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: the Group doesn't exist.\n", __FUNCTION__));
+ }
+ } while(FALSE);
+
+ RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Look up the MAC address in the IGMP table. Return NULL if not found.
+ Return:
+ pEntry - pointer to the MAC entry; NULL is not found
+ ==========================================================================
+*/
+PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PUCHAR pAddr,
+ IN PNET_DEV dev)
+{
+ ULONG HashIdx, Now;
+ PMULTICAST_FILTER_TABLE_ENTRY pEntry = NULL, pPrev = NULL;
+
+ if (pMulticastFilterTable == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+ HashIdx = MULTICAST_ADDR_HASH_INDEX(pAddr);
+ pEntry = pPrev = pMulticastFilterTable->Hash[HashIdx];
+
+ while (pEntry && pEntry->Valid)
+ {
+ if ((pEntry->net_dev == dev)
+ && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ break;
+ }
+ else
+ {
+ NdisGetSystemUpTime(&Now);
+ if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
+ && RTMP_TIME_AFTER(Now, pEntry->lastTime+IGMPMAC_TB_ENTRY_AGEOUT_TIME))
+ {
+ /* Remove the aged entry */
+ if (pEntry == pMulticastFilterTable->Hash[HashIdx])
+ {
+ pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
+ pPrev = pMulticastFilterTable->Hash[HashIdx];
+ DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+ NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+ pMulticastFilterTable->Size --;
+ pEntry = pPrev;
+ DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+ }
+ else
+ {
+ pPrev->pNext = pEntry->pNext;
+ DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+ NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+ pMulticastFilterTable->Size --;
+ pEntry = pPrev->pNext;
+ DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+ }
+ }
+ else
+ {
+ pPrev = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+ return pEntry;
+}
+
+VOID IGMPSnooping(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pSrcMacAddr,
+ IN PUCHAR pIpHeader,
+ IN PNET_DEV pDev)
+{
+ INT i;
+ INT IpHeaderLen;
+ UCHAR GroupType;
+ UINT16 numOfGroup;
+ UCHAR IgmpVerType;
+ PUCHAR pIgmpHeader;
+ PUCHAR pGroup;
+ UCHAR AuxDataLen;
+ UINT16 numOfSources;
+ PUCHAR pGroupIpAddr;
+ UCHAR GroupMacAddr[6];
+ PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
+
+ if(isIgmpPkt(pDstMacAddr, pIpHeader))
+ {
+ IpHeaderLen = (*(pIpHeader + 2) & 0x0f) * 4;
+ pIgmpHeader = pIpHeader + 2 + IpHeaderLen;
+ IgmpVerType = (UCHAR)(*(pIgmpHeader));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IGMP type=%0x\n", IgmpVerType));
+
+ switch(IgmpVerType)
+ {
+ case IGMP_V1_MEMBERSHIP_REPORT: /* IGMP version 1 membership report. */
+ case IGMP_V2_MEMBERSHIP_REPORT: /* IGMP version 2 membership report. */
+ pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
+ ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+ DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+ MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+ break;
+
+ case IGMP_LEAVE_GROUP: /* IGMP version 1 and version 2 leave group. */
+ pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
+ ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+ DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+ MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+ break;
+
+ case IGMP_V3_MEMBERSHIP_REPORT: /* IGMP version 3 membership report. */
+ numOfGroup = ntohs(*((UINT16 *)(pIgmpHeader + 6)));
+ pGroup = (PUCHAR)(pIgmpHeader + 8);
+ for (i=0; i < numOfGroup; i++)
+ {
+ GroupType = (UCHAR)(*pGroup);
+ AuxDataLen = (UCHAR)(*(pGroup + 1));
+ numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
+ pGroupIpAddr = (PUCHAR)(pGroup + 4);
+ DBGPRINT(RT_DEBUG_TRACE, ("IGMPv3 Type=%d, ADL=%d, numOfSource=%d\n",
+ GroupType, AuxDataLen, numOfSources));
+ ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+ DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2],
+ GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+
+ do
+ {
+ if ((GroupType == MODE_IS_EXCLUDE)
+ || (GroupType == CHANGE_TO_EXCLUDE_MODE)
+ || (GroupType == ALLOW_NEW_SOURCES))
+ {
+ MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+ break;
+ }
+
+ if ((GroupType == CHANGE_TO_INCLUDE_MODE)
+ || (GroupType == MODE_IS_INCLUDE)
+ || (GroupType == BLOCK_OLD_SOURCES))
+ {
+ if(numOfSources == 0)
+ MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+ else
+ MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+ break;
+ }
+ } while(FALSE);
+ pGroup += (8 + (numOfSources * 4) + AuxDataLen);
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("unknow IGMP Type=%d\n", IgmpVerType));
+ break;
+ }
+ }
+
+ return;
+}
+
+
+static BOOLEAN isIgmpMacAddr(
+ IN PUCHAR pMacAddr)
+{
+ if((pMacAddr[0] == 0x01)
+ && (pMacAddr[1] == 0x00)
+ && (pMacAddr[2] == 0x5e))
+ return TRUE;
+ return FALSE;
+}
+
+BOOLEAN isIgmpPkt(
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pIpHeader)
+{
+ UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
+ UCHAR IgmpProtocol;
+
+ if(!isIgmpMacAddr(pDstMacAddr))
+ return FALSE;
+
+ if(IpProtocol == ETH_P_IP)
+ {
+ IgmpProtocol = (UCHAR)*(pIpHeader + 11);
+ if(IgmpProtocol == IGMP_PROTOCOL_DESCRIPTOR)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static VOID InsertIgmpMember(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PLIST_HEADER pList,
+ IN PUCHAR pMemberAddr)
+{
+ PMEMBER_ENTRY pMemberEntry;
+
+ if(pList == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ if (pMemberAddr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
+ return;
+ }
+
+ if((pMemberEntry = (PMEMBER_ENTRY)AllocaGrpMemberEntry(pMulticastFilterTable)) != NULL)
+ {
+ NdisZeroMemory(pMemberEntry, sizeof(MEMBER_ENTRY));
+ COPY_MAC_ADDR(pMemberEntry->Addr, pMemberAddr);
+ insertTailList(pList, (PLIST_ENTRY)pMemberEntry);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s Member Mac=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
+ pMemberEntry->Addr[0], pMemberEntry->Addr[1], pMemberEntry->Addr[2],
+ pMemberEntry->Addr[3], pMemberEntry->Addr[4], pMemberEntry->Addr[5]));
+ }
+ return;
+}
+
+static VOID DeleteIgmpMember(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PLIST_HEADER pList,
+ IN PUCHAR pMemberAddr)
+{
+ PMEMBER_ENTRY pCurEntry;
+
+ if (pList == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ if (pList->pHead == NULL)
+ {
+ return;
+ }
+
+ if (pMemberAddr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
+ return;
+ }
+
+ pCurEntry = (PMEMBER_ENTRY)pList->pHead;
+ while (pCurEntry)
+ {
+ PMEMBER_ENTRY pCurEntryNext = pCurEntry->pNext;
+ if(MAC_ADDR_EQUAL(pMemberAddr, pCurEntry->Addr))
+ {
+ delEntryList(pList, (PLIST_ENTRY)pCurEntry);
+ FreeGrpMemberEntry(pMulticastFilterTable, pCurEntry);
+ break;
+ }
+ pCurEntry = pCurEntryNext;
+ }
+
+ return;
+}
+
+static VOID DeleteIgmpMemberList(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PLIST_HEADER pList)
+{
+ PMEMBER_ENTRY pCurEntry, pPrvEntry;
+
+ if (pList == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ if (pList->pHead == NULL)
+ {
+ return;
+ }
+
+ pPrvEntry = pCurEntry = (PMEMBER_ENTRY)pList->pHead;
+ while (pCurEntry)
+ {
+ delEntryList(pList, (PLIST_ENTRY)pCurEntry);
+ pPrvEntry = pCurEntry;
+ pCurEntry = pCurEntry->pNext;
+ FreeGrpMemberEntry(pMulticastFilterTable, pPrvEntry);
+ }
+
+ initList(pList);
+ return;
+}
+
+
+UCHAR IgmpMemberCnt(
+ IN PLIST_HEADER pList)
+{
+ if(pList == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+ return 0;
+ }
+
+ return getListSize(pList);
+}
+
+VOID IgmpGroupDelMembers(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pMemberAddr,
+ IN PNET_DEV pDev)
+{
+ INT i;
+ MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
+ PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+
+ for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
+ {
+ /* pick up the first available vacancy */
+ pEntry = &pMulticastFilterTable->Content[i];
+ if (pEntry->Valid == TRUE)
+ {
+ if(pMemberAddr != NULL)
+ {
+ RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+ DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+ RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+ }
+
+ if((pEntry->type == MCAT_FILTER_DYNAMIC)
+ && (IgmpMemberCnt(&pEntry->MemberList) == 0))
+ MulticastFilterTableDeleteEntry(pAd, pEntry->Addr, pMemberAddr, pDev);
+ }
+ }
+}
+
+INT Set_IgmpSn_Enable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT Enable;
+
+ Enable = (UINT) simple_strtol(arg, 0, 10);
+
+ pAd->ApCfg.IgmpSnoopEnable = (BOOLEAN)(Enable == 0 ? FALSE : TRUE);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %s\n", __FUNCTION__, Enable == TRUE ? "Enable IGMP Snooping":"Disable IGMP Snooping"));
+
+ return TRUE;
+}
+
+INT Set_IgmpSn_AddEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i;
+ BOOLEAN bGroupId = 1;
+ PSTRING value;
+ PSTRING thisChar;
+ UCHAR IpAddr[4];
+ UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+ UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
+ PUCHAR *pAddr = (PUCHAR *)&Addr;
+ PNET_DEV pDev;
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ ifIndex = pObj->ioctl_if;
+
+ pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
+
+ while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+ {
+ /* refuse the Member if it's not a MAC address. */
+ if((bGroupId == 0) && (strlen(thisChar) != 17))
+ continue;
+
+ if(strlen(thisChar) == 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ {
+ for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; /*Invalid */
+
+ AtoH(value, &Addr[i++], 1);
+ }
+
+ if(i != 6)
+ return FALSE; /*Invalid */
+ }
+ else
+ {
+ for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
+ {
+ if((strlen(value) > 0) && (strlen(value) <= 3))
+ {
+ int ii;
+ for(ii=0; ii<strlen(value); ii++)
+ if (!isxdigit(*(value + ii)))
+ return FALSE;
+ }
+ else
+ return FALSE; /*Invalid */
+
+ IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
+ i++;
+ }
+
+ if(i != 4)
+ return FALSE; /*Invalid */
+
+ ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
+ }
+
+ if(bGroupId == 1)
+ COPY_MAC_ADDR(GroupId, Addr);
+
+ /* Group-Id must be a MCAST address. */
+ if((bGroupId == 1) && IS_MULTICAST_MAC_ADDR(Addr))
+ MulticastFilterTableInsertEntry(pAd, GroupId, NULL, pDev, MCAT_FILTER_STATIC);
+ /* Group-Member must be a UCAST address. */
+ else if ((bGroupId == 0) && !IS_MULTICAST_MAC_ADDR(Addr))
+ MulticastFilterTableInsertEntry(pAd, GroupId, Addr, pDev, MCAT_FILTER_STATIC);
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X) is not a acceptable address.\n",
+ __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
+ return FALSE;
+ }
+
+ bGroupId = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
+ __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
+
+ }
+
+ return TRUE;
+}
+
+INT Set_IgmpSn_DelEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT i, memberCnt = 0;
+ BOOLEAN bGroupId = 1;
+ PSTRING value;
+ PSTRING thisChar;
+ UCHAR IpAddr[4];
+ UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+ UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
+ PUCHAR *pAddr = (PUCHAR *)&Addr;
+ PNET_DEV pDev;
+ POS_COOKIE pObj;
+ UCHAR ifIndex;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ ifIndex = pObj->ioctl_if;
+
+ pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
+
+ while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+ {
+ /* refuse the Member if it's not a MAC address. */
+ if((bGroupId == 0) && (strlen(thisChar) != 17))
+ continue;
+
+ if(strlen(thisChar) == 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */
+ {
+ for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; /*Invalid */
+
+ AtoH(value, &Addr[i++], 1);
+ }
+
+ if(i != 6)
+ return FALSE; /*Invalid */
+ }
+ else
+ {
+ for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
+ {
+ if((strlen(value) > 0) && (strlen(value) <= 3))
+ {
+ int ii;
+ for(ii=0; ii<strlen(value); ii++)
+ if (!isxdigit(*(value + ii)))
+ return FALSE;
+ }
+ else
+ return FALSE; /*Invalid */
+
+ IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
+ i++;
+ }
+
+ if(i != 4)
+ return FALSE; /*Invalid */
+
+ ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
+ }
+
+ if(bGroupId == 1)
+ COPY_MAC_ADDR(GroupId, Addr);
+ else
+ memberCnt++;
+
+ if (memberCnt > 0 )
+ MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, Addr, pDev);
+
+ bGroupId = 0;
+ }
+
+ if(memberCnt == 0)
+ MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, NULL, pDev);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
+ __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
+
+ return TRUE;
+}
+
+INT Set_IgmpSn_TabDisplay_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ IGMPTableDisplay(pAd);
+ return TRUE;
+}
+
+void rtmp_read_igmp_snoop_from_file(
+ IN PRTMP_ADAPTER pAd,
+ PSTRING tmpbuf,
+ PSTRING buffer)
+{
+ /*IgmpSnEnable */
+ if(RTMPGetKeyParameter("IgmpSnEnable", tmpbuf, 128, buffer, TRUE))
+ {
+ if ((strncmp(tmpbuf, "0", 1) == 0))
+ pAd->ApCfg.IgmpSnoopEnable = FALSE;
+ else if ((strncmp(tmpbuf, "1", 1) == 0))
+ pAd->ApCfg.IgmpSnoopEnable = TRUE;
+ else
+ pAd->ApCfg.IgmpSnoopEnable = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, (" IGMP Snooping Enable=%d\n", pAd->ApCfg.IgmpSnoopEnable));
+ }
+}
+
+NDIS_STATUS IgmpPktInfoQuery(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrcBufVA,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID,
+ OUT INT *pInIgmpGroup,
+ OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry)
+{
+ if(IS_MULTICAST_MAC_ADDR(pSrcBufVA))
+ {
+ BOOLEAN IgmpMldPkt = FALSE;
+ PUCHAR pIpHeader = pSrcBufVA + 12;
+
+ if(ntohs(*((UINT16 *)(pIpHeader))) == ETH_P_IPV6)
+ IgmpMldPkt = IPv6MulticastFilterExcluded(pSrcBufVA, pIpHeader);
+ else
+ IgmpMldPkt = isIgmpPkt(pSrcBufVA, pIpHeader);
+
+ if (IgmpMldPkt)
+ {
+ *ppGroupEntry = NULL;
+ *pInIgmpGroup = IGMP_PKT;
+ }
+ else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA,
+ get_netdev_from_bssid(pAd, FromWhichBSSID))) == NULL)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ *pInIgmpGroup = IGMP_IN_GROUP;
+ }
+ else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA))
+ {
+ PUCHAR pDstIpAddr = pSrcBufVA + 30; /* point to Destination of Ip address of IP header. */
+ UCHAR GroupMacAddr[6];
+ PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
+
+ ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+ if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr,
+ get_netdev_from_bssid(pAd, FromWhichBSSID))) != NULL)
+ {
+ *pInIgmpGroup = IGMP_IN_GROUP;
+ }
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+NDIS_STATUS IgmpPktClone(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN INT IgmpPktInGroup,
+ IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry,
+ IN UCHAR QueIdx,
+ IN UINT8 UserPriority,
+ IN PNET_DEV pNetDev)
+{
+ PNDIS_PACKET pSkbClone = NULL;
+ PMEMBER_ENTRY pMemberEntry = NULL;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+ USHORT Aid;
+ SST Sst = SST_ASSOC;
+ UCHAR PsMode = PWR_ACTIVE;
+ UCHAR Rate;
+ unsigned long IrqFlags;
+ INT MacEntryIdx;
+ BOOLEAN bContinue;
+ PUCHAR pMemberAddr = NULL;
+
+ bContinue = FALSE;
+
+ if ((IgmpPktInGroup == IGMP_IN_GROUP)
+ && (pGroupEntry == NULL))
+ return NDIS_STATUS_FAILURE;
+
+ if (IgmpPktInGroup == IGMP_IN_GROUP)
+ {
+ pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead;
+ if (pMemberEntry != NULL)
+ {
+ pMemberAddr = pMemberEntry->Addr;
+ pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate);
+ bContinue = TRUE;
+ }
+ }
+ else if (IgmpPktInGroup == IGMP_PKT)
+ {
+ PUCHAR src_addr = GET_OS_PKT_DATAPTR(pPacket);
+ src_addr += 6;
+
+ for(MacEntryIdx=1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++)
+ {
+ pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr;
+ pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate);
+ if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)
+ && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev
+ && (!NdisEqualMemory(src_addr, pMacEntry->Addr, MAC_ADDR_LEN)))
+ {
+ pMemberAddr = pMacEntry->Addr;
+ bContinue = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+ /* check all members of the IGMP group. */
+ while(bContinue == TRUE)
+ {
+ if (pMacEntry && (Sst == SST_ASSOC) && (pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED))
+ {
+ OS_PKT_CLONE(pAd, pPacket, pSkbClone, MEM_ALLOC_FLAG);
+ if ((pSkbClone)
+ )
+ {
+ RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)pMacEntry->Aid);
+ /* Pkt type must set to PKTSRC_NDIS. */
+ /* It cause of the deason that APHardTransmit() */
+ /* doesn't handle PKTSRC_DRIVER pkt type in version 1.3.0.0. */
+ RTMP_SET_PACKET_SOURCE(pSkbClone, PKTSRC_NDIS);
+ }
+ else
+ {
+ if (IgmpPktInGroup == IGMP_IN_GROUP)
+ {
+ pMemberEntry = pMemberEntry->pNext;
+ if (pMemberEntry != NULL)
+ {
+ pMemberAddr = pMemberEntry->Addr;
+ pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate);
+ bContinue = TRUE;
+ }
+ else
+ bContinue = FALSE;
+ }
+ else if (IgmpPktInGroup == IGMP_PKT)
+ {
+ PUCHAR src_addr = GET_OS_PKT_DATAPTR(pPacket);
+ src_addr += 6;
+ for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++)
+ {
+ pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr;
+ pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate);
+ if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)
+ && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev
+ && (!NdisEqualMemory(src_addr, pMacEntry->Addr, MAC_ADDR_LEN)))
+ {
+ pMemberAddr = pMacEntry->Addr;
+ bContinue = TRUE;
+ break;
+ }
+ }
+ if (MacEntryIdx == MAX_NUMBER_OF_MAC)
+ bContinue = FALSE;
+ }
+ else
+ bContinue = FALSE;
+
+ continue;
+ }
+
+ if (PsMode == PWR_SAVE)
+ {
+ APInsertPsQueue(pAd, pSkbClone, pMacEntry, QueIdx);
+ }
+ else
+ {
+ /* insert the pkt to TxSwQueue. */
+ if (pAd->TxSwQueue[QueIdx].Number >= pAd->TxSwQMaxLen)
+ {
+#ifdef BLOCK_NET_IF
+ StopNetIfQueue(pAd, QueIdx, pSkbClone);
+#endif /* BLOCK_NET_IF */
+ RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone));
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+ }
+ }
+#ifdef DOT11_N_SUPPORT
+ RTMP_BASetup(pAd, pMacEntry, UserPriority);
+#endif /* DOT11_N_SUPPORT */
+ }
+
+ if (IgmpPktInGroup == IGMP_IN_GROUP)
+ {
+ pMemberEntry = pMemberEntry->pNext;
+ if (pMemberEntry != NULL)
+ {
+ pMemberAddr = pMemberEntry->Addr;
+ pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate);
+ bContinue = TRUE;
+ }
+ else
+ bContinue = FALSE;
+ }
+ else if (IgmpPktInGroup == IGMP_PKT)
+ {
+ for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++)
+ {
+ pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr;
+ pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate);
+ if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)
+ && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev)
+ {
+ pMemberAddr = pMacEntry->Addr;
+ bContinue = TRUE;
+ break;
+ }
+ }
+ if (MacEntryIdx == MAX_NUMBER_OF_MAC)
+ bContinue = FALSE;
+ }
+ else
+ bContinue = FALSE;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+static inline BOOLEAN isMldMacAddr(
+ IN PUCHAR pMacAddr)
+{
+ return ((pMacAddr[0] == 0x33) && (pMacAddr[1] == 0x33)) ? TRUE : FALSE;
+}
+
+static inline BOOLEAN IsSupportedMldMsg(
+ IN UINT8 MsgType)
+{
+ BOOLEAN result = FALSE;
+ switch(MsgType)
+ {
+ case MLD_V1_LISTENER_REPORT:
+ case MLD_V1_LISTENER_DONE:
+ case MLD_V2_LISTERNER_REPORT:
+ result = TRUE;
+ break;
+ default:
+ result = FALSE;
+ break;
+ }
+
+ return result;
+}
+
+BOOLEAN isMldPkt(
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pIpHeader,
+ OUT UINT8 *pProtoType,
+ OUT PUCHAR *pMldHeader)
+{
+ BOOLEAN result = FALSE;
+ UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
+
+ if(!isMldMacAddr(pDstMacAddr))
+ return FALSE;
+
+ if(IpProtocol != ETH_P_IPV6)
+ return FALSE;
+
+ /* skip protocol (2 Bytes). */
+ pIpHeader += 2;
+ do
+ {
+ PRT_IPV6_HDR pIpv6Hdr = (PRT_IPV6_HDR)(pIpHeader);
+ UINT8 nextProtocol = pIpv6Hdr->nextHdr;
+ UINT32 offset = IPV6_HDR_LEN;
+
+ while(nextProtocol != IPV6_NEXT_HEADER_ICMPV6)
+ {
+ if(IPv6ExtHdrHandle((RT_IPV6_EXT_HDR *)(pIpHeader + offset), &nextProtocol, &offset) == FALSE)
+ break;
+ }
+
+ if(nextProtocol == IPV6_NEXT_HEADER_ICMPV6)
+ {
+ PRT_ICMPV6_HDR pICMPv6Hdr = (PRT_ICMPV6_HDR)(pIpHeader + offset);
+ if (IsSupportedMldMsg(pICMPv6Hdr->type) == TRUE)
+ {
+ if (pProtoType != NULL)
+ *pProtoType = pICMPv6Hdr->type;
+ if (pMldHeader != NULL)
+ *pMldHeader = (PUCHAR)pICMPv6Hdr;
+ result = TRUE;
+ }
+ }
+ }while(FALSE);
+
+ return result;
+}
+
+BOOLEAN IPv6MulticastFilterExcluded(
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pIpHeader)
+{
+ BOOLEAN result = FALSE;
+ UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
+ INT idx;
+ UINT8 nextProtocol;
+
+ if(!IS_IPV6_MULTICAST_MAC_ADDR(pDstMacAddr))
+ return FALSE;
+
+ if(IpProtocol != ETH_P_IPV6)
+ return FALSE;
+
+ /* skip protocol (2 Bytes). */
+ pIpHeader += 2;
+ do
+ {
+ PRT_IPV6_HDR pIpv6Hdr = (PRT_IPV6_HDR)(pIpHeader);
+ UINT32 offset = IPV6_HDR_LEN;
+
+ nextProtocol = pIpv6Hdr->nextHdr;
+ while(nextProtocol == IPV6_NEXT_HEADER_HOP_BY_HOP)
+ {
+ if(IPv6ExtHdrHandle((RT_IPV6_EXT_HDR *)(pIpHeader + offset), &nextProtocol, &offset) == FALSE)
+ break;
+ }
+ } while(FALSE);
+
+ for (idx = 0; idx < IPV6_MULTICAST_FILTER_EXCLUED_SIZE; idx++)
+ {
+ if (nextProtocol == IPv6MulticastFilterExclued[idx])
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/* MLD v1 messages have the following format:
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Code | Checksum |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Maximum Response Delay | Reserved |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ + +
+ | |
+ + Multicast Address +
+ | |
+ + +
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+/* Version 3 Membership Report Message
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type = 143 | Reserved | Checksum |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Reserved | Number of Group Records (M) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ . .
+ . Multicast Address Record [1] .
+ . .
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ . .
+ . Multicast Address Record [2] .
+ . .
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | . |
+ . . .
+ | . |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ . .
+ . Multicast Address Record [M] .
+ . .
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+ where each Group Record has the following internal format:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Record Type | Aux Data Len | Number of Sources (N) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ * *
+ | |
+ * Multicast Address *
+ | |
+ * *
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ * *
+ | |
+ * Source Address [1] *
+ | |
+ * *
+ | |
+ +- -+
+ | |
+ * *
+ | |
+ * Source Address [2] *
+ | |
+ * *
+ | |
+ +- -+
+ . . .
+ . . .
+ . . .
+ +- -+
+ | |
+ * *
+ | |
+ * Source Address [N] *
+ | |
+ * *
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ . .
+ . Auxiliary Data .
+ . .
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+VOID MLDSnooping(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pSrcMacAddr,
+ IN PUCHAR pIpHeader,
+ IN PNET_DEV pDev)
+{
+ INT i;
+ UCHAR GroupType;
+ UINT16 numOfGroup;
+ PUCHAR pGroup;
+ UCHAR AuxDataLen;
+ UINT16 numOfSources;
+ PUCHAR pGroupIpAddr;
+ UCHAR GroupMacAddr[6];
+ PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
+
+ UINT8 MldType;
+ PUCHAR pMldHeader;
+
+ if(isMldPkt(pDstMacAddr, pIpHeader, &MldType, &pMldHeader) == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MLD type=%0x\n", MldType));
+
+ switch(MldType)
+ {
+ case MLD_V1_LISTENER_REPORT:
+ /* skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes). */
+ pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
+ ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
+ DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+ MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+ break;
+
+ case MLD_V1_LISTENER_DONE:
+ /* skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes). */
+ pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
+ ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
+ DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+ MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+ break;
+
+ case MLD_V2_LISTERNER_REPORT: /* IGMP version 3 membership report. */
+ numOfGroup = ntohs(*((UINT16 *)(pMldHeader + 6)));
+ pGroup = (PUCHAR)(pMldHeader + 8);
+ for (i=0; i < numOfGroup; i++)
+ {
+ GroupType = (UCHAR)(*pGroup);
+ AuxDataLen = (UCHAR)(*(pGroup + 1));
+ numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
+ pGroupIpAddr = (PUCHAR)(pGroup + 4);
+ DBGPRINT(RT_DEBUG_TRACE, ("MLDv2 Type=%d, ADL=%d, numOfSource=%d\n",
+ GroupType, AuxDataLen, numOfSources));
+ ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
+ DBGPRINT(RT_DEBUG_TRACE, ("MLD Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2],
+ GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+
+ do
+ {
+ if ((GroupType == MODE_IS_EXCLUDE)
+ || (GroupType == CHANGE_TO_EXCLUDE_MODE)
+ || (GroupType == ALLOW_NEW_SOURCES))
+ {
+ MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+ break;
+ }
+
+ if ((GroupType == CHANGE_TO_INCLUDE_MODE)
+ || (GroupType == MODE_IS_INCLUDE)
+ || (GroupType == BLOCK_OLD_SOURCES))
+ {
+ if(numOfSources == 0)
+ MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+ else
+ MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+ break;
+ }
+ } while(FALSE);
+ /* skip 4 Bytes (Record Type, Aux Data Len, Number of Sources) + a IPv6 address. */
+ pGroup += (4 + IPV6_ADDR_LEN + (numOfSources * 16) + AuxDataLen);
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("unknow MLD Type=%d\n", MldType));
+ break;
+ }
+ }
+
+ return;
+}
+
+
+#endif /* IGMP_SNOOP_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/common/image.bin b/cleopatre/devkit/mt7601udrv/common/image.bin
new file mode 100644
index 0000000000..f357c59ab4
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/image.bin
Binary files differ
diff --git a/cleopatre/devkit/mt7601udrv/common/misc.c b/cleopatre/devkit/mt7601udrv/common/misc.c
new file mode 100644
index 0000000000..72ca956049
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/misc.c
@@ -0,0 +1,35 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2009, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ misc.c
+
+ Abstract:
+
+ Handling Misc Problem
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sean Wang 2009-08-12 Create
+ John Li 2009-11-30 Modified
+*/
+
+#include "rt_config.h"
+#include "misc.h"
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/mlme.c b/cleopatre/devkit/mt7601udrv/common/mlme.c
new file mode 100644
index 0000000000..e43726b26e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/mlme.c
@@ -0,0 +1,4000 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ mlme.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-08-25 Modify from RT2500 code base
+ John Chang 2004-09-06 modified for RT2600
+*/
+
+#include "rt_config.h"
+#include <stdarg.h>
+
+
+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};
+
+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 */
+};
+
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+UINT32 CW_MAX_IN_BITS;
+#endif /* CONFIG_APSTA_MIXED_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};
+
+
+UCHAR dot11_max_sup_rate(INT SupRateLen, UCHAR *SupRate, INT ExtRateLen, UCHAR *ExtRate)
+{
+ INT idx;
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+
+ /* 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;
+ }
+
+ if (ExtRateLen > 0 && ExtRate != NULL)
+ {
+ for (idx = 0; idx < ExtRateLen; idx++) {
+ if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
+ }
+ }
+
+ return MaxSupportedRateIn500Kbps;
+}
+
+
+UCHAR dot11_2_ra_rate(UCHAR MaxSupportedRateIn500Kbps)
+{
+ UCHAR MaxSupportedRate;
+
+ 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;
+ }
+
+ return MaxSupportedRate;
+}
+
+
+/*
+ ==========================================================================
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* init AP state machines*/
+ APAssocStateMachineInit(pAd, &pAd->Mlme.ApAssocMachine, pAd->Mlme.ApAssocFunc);
+ APAuthStateMachineInit(pAd, &pAd->Mlme.ApAuthMachine, pAd->Mlme.ApAuthFunc);
+ APSyncStateMachineInit(pAd, &pAd->Mlme.ApSyncMachine, pAd->Mlme.ApSyncFunc);
+
+#ifdef APCLI_SUPPORT
+ /* init apcli state machines*/
+ ASSERT(APCLI_AUTH_FUNC_SIZE == APCLI_MAX_AUTH_MSG * APCLI_MAX_AUTH_STATE);
+ ApCliAuthStateMachineInit(pAd, &pAd->Mlme.ApCliAuthMachine, pAd->Mlme.ApCliAuthFunc);
+
+ ASSERT(APCLI_ASSOC_FUNC_SIZE == APCLI_MAX_ASSOC_MSG * APCLI_MAX_ASSOC_STATE);
+ ApCliAssocStateMachineInit(pAd, &pAd->Mlme.ApCliAssocMachine, pAd->Mlme.ApCliAssocFunc);
+
+ ASSERT(APCLI_SYNC_FUNC_SIZE == APCLI_MAX_SYNC_MSG * APCLI_MAX_SYNC_STATE);
+ ApCliSyncStateMachineInit(pAd, &pAd->Mlme.ApCliSyncMachine, pAd->Mlme.ApCliSyncFunc);
+
+ ASSERT(APCLI_CTRL_FUNC_SIZE == APCLI_MAX_CTRL_MSG * APCLI_MAX_CTRL_STATE);
+ ApCliCtrlStateMachineInit(pAd, &pAd->Mlme.ApCliCtrlMachine, pAd->Mlme.ApCliCtrlFunc);
+
+#endif /* APCLI_SUPPORT */
+ }
+
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef WSC_INCLUDED
+ /* Init Wsc state machine */
+ ASSERT(WSC_FUNC_SIZE == MAX_WSC_MSG * MAX_WSC_STATE);
+ WscStateMachineInit(pAd, &pAd->Mlme.WscMachine, pAd->Mlme.WscFunc);
+#endif /* WSC_INCLUDED */
+
+ 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);
+
+#ifdef CONFIG_MULTI_CHANNEL
+ pAd->Mlme.StaStayTick = 0;
+ pAd->Mlme.P2pStayTick = 0;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ /* 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);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* Init APSD periodic timer*/
+ RTMPInitTimer(pAd, &pAd->Mlme.APSDPeriodicTimer, GET_TIMER_FUNCTION(APSDPeriodicExec), pAd, TRUE);
+ RTMPSetTimer(&pAd->Mlme.APSDPeriodicTimer, 50);
+
+ /* Init APQuickResponseForRateUp timer.*/
+ RTMPInitTimer(pAd, &pAd->ApCfg.ApQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(APQuickResponeForRateUpExec), pAd, FALSE);
+ pAd->ApCfg.ApQuickResponeForRateUpTimerRunning = FALSE;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ } while (FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
+
+ return Status;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ main loop of the MLME
+ Pre:
+ Mlme has to be initialized, and there are something inside the queue
+ Note:
+ This function is invoked from MPSetInformation and MPReceive;
+ This task guarantee only one MlmeHandler will run.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeHandler(RTMP_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) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_SUSPEND))
+ {
+ 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*/
+
+ case ACTION_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine,
+ Elem, pAd->Mlme.ActMachine.CurrState);
+ break;
+
+#ifdef CONFIG_AP_SUPPORT
+ /* AP state amchines*/
+
+ case AP_ASSOC_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.ApAssocMachine,
+ Elem, pAd->Mlme.ApAssocMachine.CurrState);
+ break;
+
+ case AP_AUTH_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.ApAuthMachine,
+ Elem, pAd->Mlme.ApAuthMachine.CurrState);
+ break;
+
+ case AP_SYNC_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.ApSyncMachine,
+ Elem, pAd->Mlme.ApSyncMachine.CurrState);
+ break;
+
+#ifdef APCLI_SUPPORT
+ case APCLI_AUTH_STATE_MACHINE:
+ apcliIfIndex = Elem->Priv;
+ if(isValidApCliIf(apcliIfIndex))
+ StateMachinePerformAction(pAd, &pAd->Mlme.ApCliAuthMachine, Elem,
+ (pAd->ApCfg.ApCliTab[apcliIfIndex].AuthCurrState));
+ break;
+
+ case APCLI_ASSOC_STATE_MACHINE:
+ apcliIfIndex = Elem->Priv;
+ if(isValidApCliIf(apcliIfIndex))
+ StateMachinePerformAction(pAd, &pAd->Mlme.ApCliAssocMachine, Elem,
+ (pAd->ApCfg.ApCliTab[apcliIfIndex].AssocCurrState));
+ break;
+
+ case APCLI_SYNC_STATE_MACHINE:
+ apcliIfIndex = Elem->Priv;
+ if(isValidApCliIf(apcliIfIndex))
+ StateMachinePerformAction(pAd, &pAd->Mlme.ApCliSyncMachine, Elem,
+ (pAd->ApCfg.ApCliTab[apcliIfIndex].SyncCurrState));
+ break;
+
+ case APCLI_CTRL_STATE_MACHINE:
+ apcliIfIndex = Elem->Priv;
+ if(isValidApCliIf(apcliIfIndex))
+ StateMachinePerformAction(pAd, &pAd->Mlme.ApCliCtrlMachine, Elem,
+ (pAd->ApCfg.ApCliTab[apcliIfIndex].CtrlCurrState));
+ break;
+#endif /* APCLI_SUPPORT */
+
+#endif /* CONFIG_AP_SUPPORT */
+ case WPA_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.WpaMachine, Elem, pAd->Mlme.WpaMachine.CurrState);
+ break;
+#ifdef WSC_INCLUDED
+ case WSC_STATE_MACHINE:
+ if (pAd->pWscElme)
+ {
+ RTMP_SEM_LOCK(&pAd->WscElmeLock);
+ NdisMoveMemory(pAd->pWscElme, Elem, sizeof(MLME_QUEUE_ELEM));
+ RTMP_SEM_UNLOCK(&pAd->WscElmeLock);
+/*#ifdef KTHREAD_SUPPORT*/
+/* WAKE_UP(&(pAd->wscTask));*/
+/*#else*/
+/* RTMP_SEM_EVENT_UP(&(pAd->wscTask.taskSema));*/
+/*#endif*/
+ RtmpOsTaskWakeUp(&(pAd->wscTask));
+ }
+ break;
+#endif /* WSC_INCLUDED */
+
+
+ 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);
+
+
+ RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ RTMPCancelTimer(&pAd->Mlme.APSDPeriodicTimer, &Cancelled);
+
+ if (pAd->ApCfg.ApQuickResponeForRateUpTimerRunning == TRUE)
+ RTMPCancelTimer(&pAd->ApCfg.ApQuickResponeForRateUpTimer, &Cancelled);
+
+#ifdef APCLI_SUPPORT
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ProbeTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->ApCliMlmeAux.ApCliAuthTimer, &Cancelled);
+
+#ifdef WSC_AP_SUPPORT
+ if (pAd->ApCfg.ApCliTab[BSS0].WscControl.WscProfileRetryTimerRunning)
+ {
+ pAd->ApCfg.ApCliTab[BSS0].WscControl.WscProfileRetryTimerRunning = FALSE;
+ RTMPCancelTimer(&pAd->ApCfg.ApCliTab[BSS0].WscControl.WscProfileRetryTimer, &Cancelled);
+ }
+#endif /* WSC_AP_SUPPORT */
+#endif /* APCLI_SUPPORT */
+ RTMPCancelTimer(&pAd->MlmeAux.APScanTimer, &Cancelled);
+ }
+
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+ 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 (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ if (pAd->WOW_Cfg.bEnable == FALSE)
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_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 MICROWAVE_OVEN_SUPPORT
+ /* update False CCA count to an array */
+ NICUpdateRxStatusCnt1(pAd, pAd->Mlme.PeriodicRound%10);
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ /* No More 0x84 MCU CMD from v.30 FW*/
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ //printk("MO_Cfg.bEnable=%d \n", pAd->CommonCfg.MO_Cfg.bEnable);
+ if (pAd->CommonCfg.MO_Cfg.bEnable)
+ {
+ UINT8 stage = pAd->Mlme.PeriodicRound%10;
+
+ if (stage == MO_MEAS_PERIOD)
+ {
+ ASIC_MEASURE_FALSE_CCA(pAd);
+ pAd->CommonCfg.MO_Cfg.nPeriod_Cnt = 0;
+ }
+ else if (stage == MO_IDLE_PERIOD)
+ {
+ UINT16 Idx;
+
+ for (Idx = MO_MEAS_PERIOD + 1; Idx < MO_IDLE_PERIOD + 1; Idx++)
+ pAd->CommonCfg.MO_Cfg.nFalseCCACnt += pAd->RalinkCounters.FalseCCACnt_100MS[Idx];
+
+ //printk("%s: fales cca1 %d\n", __FUNCTION__, pAd->CommonCfg.MO_Cfg.nFalseCCACnt);
+ if (pAd->CommonCfg.MO_Cfg.nFalseCCACnt > pAd->CommonCfg.MO_Cfg.nFalseCCATh)
+ ASIC_MITIGATE_MICROWAVE(pAd);
+
+ }
+ }
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+#ifdef INF_AMAZON_SE
+#ifdef RTMP_MAC_USB
+ SoftwareFlowControl(pAd);
+#endif /* RTMP_MAC_USB */
+#endif /* INF_AMAZON_SE */
+
+
+ /* 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;
+
+
+ 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);
+#ifdef CONFIG_AP_SUPPORT
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+ if (pAd->CommonCfg.CarrierDetect.Enable)
+ CarrierDetectionPeriodicStateCtrl(pAd);
+#endif /* CARRIER_DETECTION_FIRMWARE_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* RTMP_MAC_USB */
+
+#ifdef CONFIG_MULTI_CHANNEL
+ /*
+ Use StayTicks to call MlmeDynamicTxRateSwitching
+ */
+ if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
+ {
+
+ if (INFRA_ON(pAd)
+ && ((pAd->MultiChannelFlowCtl & EDCA_AC0_DEQUEUE_DISABLE) == 0))
+ {
+ pAd->Mlme.StaStayTick++;
+ }
+
+ if (P2P_CLI_ON(pAd)
+ && ((pAd->MultiChannelFlowCtl & HCCA_DEQUEUE_DISABLE) == 0))
+ {
+ pAd->Mlme.P2pStayTick++;
+ }
+
+ if ((pAd->P2pCfg.bStartP2pConnect == FALSE)
+#ifdef CONFIG_MULTI_CHANNEL
+ && (pAd->Multi_Channel_Enable == TRUE)
+#endif /* CONFIG_MULTI_CHANNEL */
+)
+ MlmeDynamicTxRateSwitching(pAd);
+ }
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+ /* by default, execute every 500ms */
+ if ((pAd->ra_interval) &&
+ ((pAd->Mlme.PeriodicRound % (pAd->ra_interval / 100)) == 0) &&
+ RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/
+ )
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APMlmeDynamicTxRateSwitching(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+#ifdef DFS_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+#ifdef RTMP_MAC_USB
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE))
+ NewUsbTimerCB_Radar(pAd);
+ }
+#endif /* RTMP_MAC_USB */
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* DFS_SUPPORT */
+
+
+
+
+ /* Normal 1 second Mlme PeriodicExec.*/
+ if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
+ {
+ pAd->Mlme.OneSecPeriodicRound ++;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ dynamic_tune_be_tx_op(pAd, 50); /* change form 100 to 50 for WMM WiFi test @20070504*/
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /*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
+#ifndef CONFIG_MULTI_CHANNEL
+ RTUSBWatchDog(pAd);
+#endif /* !CONFIG_MULTI_CHANNEL */
+#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 (pAd->RalinkCounters.MgmtRingFullCount >= 2)
+ RTMP_SET_FLAG(pAd, fRTMP_HW_ERR);
+ else
+ pAd->RalinkCounters.MgmtRingFullCount = 0;
+ */
+
+ /* The time period for checking antenna is according to traffic*/
+ {
+ if (pAd->Mlme.bEnableAutoAntennaCheck)
+ {
+ TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ /* dynamic adjust antenna evaluation period according to the traffic*/
+ if (TxTotalCnt > 50)
+ {
+ if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
+ AsicEvaluateRxAnt(pAd);
+ }
+ else
+ {
+ if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
+ AsicEvaluateRxAnt(pAd);
+ }
+ }
+ }
+
+#ifdef VIDEO_TURBINE_SUPPORT
+ /*
+ VideoTurbineUpdate(pAd);
+ VideoTurbineDynamicTune(pAd);
+ */
+#endif /* VIDEO_TURBINE_SUPPORT */
+
+#ifdef VCORECAL_SUPPORT
+ {
+ if ((pAd->Mlme.OneSecPeriodicRound % 10) == 0)
+ AsicVCORecalibration(pAd);
+ }
+#endif /* VCORECAL_SUPPORT */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ APMlmePeriodicExec(pAd);
+
+ if ((pAd->RalinkCounters.OneSecBeaconSentCnt == 0)
+ && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ && ((pAd->CommonCfg.bIEEE80211H != 1)
+ || (pAd->Dot11_H.RDMode != RD_SILENCE_MODE))
+#ifdef WDS_SUPPORT
+ && (pAd->WdsTab.Mode != WDS_BRIDGE_MODE)
+#endif /* WDS_SUPPORT */
+#ifdef CARRIER_DETECTION_SUPPORT
+ && (isCarrierDetectExist(pAd) == FALSE)
+#endif /* CARRIER_DETECTION_SUPPORT */
+ )
+ pAd->macwd ++;
+ else
+ pAd->macwd = 0;
+
+ if (pAd->macwd > 1)
+ {
+ int count = 0;
+ BOOLEAN MAC_ready = FALSE;
+ UINT32 MacCsr12 = 0;
+
+ /* Disable MAC*/
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+ /* polling MAC status*/
+ while (count < 10)
+ {
+ RTMPusecDelay(1000); /* 1 ms*/
+ RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
+
+ /* if MAC is idle*/
+ if ((MacCsr12 & 0x03) == 0)
+ {
+ MAC_ready = TRUE;
+ break;
+ }
+ count ++;
+ }
+
+ if (MAC_ready)
+ {
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+ RTMPusecDelay(1);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("Warning, MAC isn't ready \n"));
+ }
+
+ {
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
+ }
+
+ DBGPRINT(RT_DEBUG_WARN, ("MAC specific condition \n"));
+
+#ifdef AP_QLOAD_SUPPORT
+ Show_QoSLoad_Proc(pAd, NULL);
+#endif /* AP_QLOAD_SUPPORT */
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+ MlmeResetRalinkCounters(pAd);
+
+
+ RTMP_MLME_HANDLER(pAd);
+ }
+
+#ifdef WSC_INCLUDED
+ WSC_HDR_BTN_MR_HANDLE(pAd);
+#endif /* WSC_INCLUDED */
+
+
+
+ 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);
+}
+
+
+
+/*
+ ==========================================================================
+ 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*/
+
+
+
+ if (pMacEntry != NULL)
+ {
+ pRssiSample = &pMacEntry->RssiSample;
+ OneSecTxNoRetryOkCount = pMacEntry->OneSecTxNoRetryOkCount;
+ OneSecTxRetryOkCount = pMacEntry->OneSecTxRetryOkCount;
+ OneSecTxFailCount = pMacEntry->OneSecTxFailCount;
+ OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
+ OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
+ }
+ else
+ {
+ pRssiSample = &pAd->MacTab.Content[0].RssiSample;
+ OneSecTxNoRetryOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount;
+ OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
+ OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
+ OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
+ OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
+ }
+
+ 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*/
+ {
+ /* 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_AP_SUPPORT
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ if (pMacEntry != NULL)
+ pMacEntry->ChannelQuality = (ChannelQuality > 100) ? 100 : ChannelQuality;
+ }
+#endif /* CONFIG_AP_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 == WMODE_A)*/
+ 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;
+ }
+
+ if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
+ {
+ /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+ return;
+ }
+
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ sup_p[i] &= 0x7f;
+ ext_p[i] &= 0x7f;
+ }
+
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ if (bitmap & (1 << i))
+ {
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (sup_p[j] == rate[i])
+ sup_p[j] |= 0x80;
+ }
+
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (ext_p[j] == rate[i])
+ ext_p[j] |= 0x80;
+ }
+ }
+ }
+}
+
+/*
+ bLinkUp is to identify the inital link speed.
+ TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
+*/
+VOID MlmeUpdateTxRates(
+ IN RTMP_ADAPTER *pAd,
+ IN BOOLEAN bLinkUp,
+ IN UCHAR apidx)
+{
+ int i, num;
+ UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
+ UCHAR MinSupport = RATE_54;
+ ULONG BasicRateBitmap = 0;
+ UCHAR CurrBasicRate = RATE_1;
+ UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
+ HTTRANSMIT_SETTING *pHtPhy = NULL, *pMaxHtPhy = NULL, *pMinHtPhy = NULL;
+ BOOLEAN *auto_rate_cur_p;
+ UCHAR HtMcs = MCS_AUTO;
+
+ /* find max desired rate*/
+ UpdateBasicRateBitmap(pAd);
+
+ num = 0;
+ auto_rate_cur_p = NULL;
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ switch (pAd->CommonCfg.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_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ UCHAR idx = apidx - MIN_NET_DEVICE_FOR_APCLI;
+
+ if (idx < MAX_APCLI_NUM)
+ {
+ pHtPhy = &pAd->ApCfg.ApCliTab[idx].HTPhyMode;
+ pMaxHtPhy = &pAd->ApCfg.ApCliTab[idx].MaxHTPhyMode;
+ pMinHtPhy = &pAd->ApCfg.ApCliTab[idx].MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->ApCfg.ApCliTab[idx].bAutoTxRateSwitch;
+ HtMcs = pAd->ApCfg.ApCliTab[idx].DesiredTransmitSetting.field.MCS;
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): invalid idx(%d)\n", __FUNCTION__, idx));
+ return;
+ }
+ }
+#endif /* APCLI_SUPPORT */
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef WDS_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ UCHAR idx = apidx - MIN_NET_DEVICE_FOR_WDS;
+
+ if (idx < MAX_WDS_ENTRY)
+ {
+ pHtPhy = &pAd->WdsTab.WdsEntry[idx].HTPhyMode;
+ pMaxHtPhy = &pAd->WdsTab.WdsEntry[idx].MaxHTPhyMode;
+ pMinHtPhy = &pAd->WdsTab.WdsEntry[idx].MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->WdsTab.WdsEntry[idx].bAutoTxRateSwitch;
+ HtMcs = pAd->WdsTab.WdsEntry[idx].DesiredTransmitSetting.field.MCS;
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): invalid apidx(%d)\n", __FUNCTION__, apidx));
+ return;
+ }
+ }
+#endif /* WDS_SUPPORT */
+
+ if ((apidx < pAd->ApCfg.BssidNum) &&
+ (apidx < MAX_MBSSID_NUM(pAd)) &&
+ (apidx < HW_BEACON_MAX_NUM))
+ {
+ pHtPhy = &pAd->ApCfg.MBSSID[apidx].HTPhyMode;
+ pMaxHtPhy = &pAd->ApCfg.MBSSID[apidx].MaxHTPhyMode;
+ pMinHtPhy = &pAd->ApCfg.MBSSID[apidx].MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch;
+ HtMcs = pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.MCS;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): invalid apidx(%d)\n", __FUNCTION__, apidx));
+ }
+ break;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ } while(FALSE);
+
+ pAd->CommonCfg.MaxDesiredRate = MaxDesire;
+
+ if (pMinHtPhy == NULL)
+ return;
+ 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)
+ *auto_rate_cur_p = FALSE;
+ else
+ *auto_rate_cur_p = TRUE;
+
+ if (HtMcs != MCS_AUTO)
+ *auto_rate_cur_p = FALSE;
+ else
+ *auto_rate_cur_p = TRUE;
+
+ {
+ 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<SupRateLen; i++)
+ {
+ switch (pSupRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 0; break;
+ case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 1; break;
+ case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 2; break;
+ case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 3; break;
+ case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 1 << 4; break;
+ case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 5; break;
+ case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 1 << 6; break;
+ case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 7; break;
+ case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 1 << 8; break;
+ case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 9; break;
+ case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 10; break;
+ case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 1 << 11; break;
+ default: Rate = RATE_1; break;
+ }
+
+ if (MaxSupport < Rate)
+ MaxSupport = Rate;
+
+ if (MinSupport > Rate)
+ MinSupport = Rate;
+ }
+
+ for (i=0; i<ExtRateLen; i++)
+ {
+ switch (pExtRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 0; break;
+ case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 1; break;
+ case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 2; break;
+ case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 3; break;
+ case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 1 << 4; break;
+ case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 5; break;
+ case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 1 << 6; break;
+ case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 7; break;
+ case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 1 << 8; break;
+ case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 9; break;
+ case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 10; break;
+ case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 1 << 11; break;
+ default: Rate = RATE_1;
+ break;
+ }
+ if (MaxSupport < Rate)
+ MaxSupport = Rate;
+
+ if (MinSupport > Rate)
+ MinSupport = Rate;
+ }
+
+ RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
+
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ if (BasicRateBitmap & (0x01 << i))
+ CurrBasicRate = (UCHAR)i;
+ pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s():[MaxSupport = %d] = MaxDesire %d Mbps\n",
+ __FUNCTION__, 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ dbm =0;
+#endif /* CONFIG_AP_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;
+
+ /* 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ pMaxHtPhy->field.MCS = MaxDesire;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ else
+ {
+ pMaxHtPhy->field.MODE = MODE_OFDM;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[MaxDesire];
+ }
+#endif /* CONFIG_AP_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
+ {
+ if (WMODE_CAP(pAd->CommonCfg.PhyMode, WMODE_B) &&
+ pAd->CommonCfg.Channel <= 14)
+ {
+ pAd->CommonCfg.MlmeRate = RATE_1;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+ pAd->CommonCfg.RtsRate = RATE_11;
+ }
+ 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];
+ }
+
+ /* 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;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MCAST_RATE_SPECIFIC
+ {
+ /* set default value if MCastPhyMode is not initialized */
+ HTTRANSMIT_SETTING tPhyMode;
+
+ memset(&tPhyMode, 0, sizeof(HTTRANSMIT_SETTING));
+ if (memcmp(&pAd->CommonCfg.MCastPhyMode, &tPhyMode, sizeof(HTTRANSMIT_SETTING)) == 0)
+ {
+ memmove(&pAd->CommonCfg.MCastPhyMode, &pAd->MacTab.Content[MCAST_WCID].HTPhyMode,
+ sizeof(HTTRANSMIT_SETTING));
+ }
+ }
+#endif /* MCAST_RATE_SPECIFIC */
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, (" %s(): (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
+ __FUNCTION__, 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, (" %s(): (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
+ __FUNCTION__, RateIdToMbps[pAd->CommonCfg.TxRate],
+ RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
+ __FUNCTION__, 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 RTMP_ADAPTER *pAd,
+ IN UCHAR apidx)
+{
+ UCHAR StbcMcs;
+ RT_HT_CAPABILITY *pRtHtCap = NULL;
+ RT_PHY_INFO *pActiveHtPhy = NULL;
+ ULONG BasicMCS;
+ RT_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,("%s()===> \n", __FUNCTION__));
+
+ auto_rate_cur_p = NULL;
+
+ do
+ {
+#ifdef CONFIG_AP_SUPPORT
+
+#ifdef APCLI_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ UCHAR idx = apidx - MIN_NET_DEVICE_FOR_APCLI;
+
+ if (idx < MAX_APCLI_NUM)
+ {
+ pDesireHtPhy = &pAd->ApCfg.ApCliTab[idx].DesiredHtPhyInfo;
+ pActiveHtPhy = &pAd->ApCfg.ApCliTab[idx].DesiredHtPhyInfo;
+ pHtPhy = &pAd->ApCfg.ApCliTab[idx].HTPhyMode;
+ pMaxHtPhy = &pAd->ApCfg.ApCliTab[idx].MaxHTPhyMode;
+ pMinHtPhy = &pAd->ApCfg.ApCliTab[idx].MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->ApCfg.ApCliTab[idx].bAutoTxRateSwitch;
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): invalid idx(%d)\n", __FUNCTION__, idx));
+ return;
+ }
+ }
+#endif /* APCLI_SUPPORT */
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef WDS_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ UCHAR idx = apidx - MIN_NET_DEVICE_FOR_WDS;
+
+ if (idx < MAX_WDS_ENTRY)
+ {
+ pDesireHtPhy = &pAd->WdsTab.WdsEntry[idx].DesiredHtPhyInfo;
+ pActiveHtPhy = &pAd->WdsTab.WdsEntry[idx].DesiredHtPhyInfo;
+ pHtPhy = &pAd->WdsTab.WdsEntry[idx].HTPhyMode;
+ pMaxHtPhy = &pAd->WdsTab.WdsEntry[idx].MaxHTPhyMode;
+ pMinHtPhy = &pAd->WdsTab.WdsEntry[idx].MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->WdsTab.WdsEntry[idx].bAutoTxRateSwitch;
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): invalid apidx(%d)\n", __FUNCTION__, apidx));
+ return;
+ }
+ }
+#endif /* WDS_SUPPORT */
+
+ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < HW_BEACON_MAX_NUM))
+ {
+ pDesireHtPhy = &pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo;
+ pActiveHtPhy = &pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo;
+ pHtPhy = &pAd->ApCfg.MBSSID[apidx].HTPhyMode;
+ pMaxHtPhy = &pAd->ApCfg.MBSSID[apidx].MaxHTPhyMode;
+ pMinHtPhy = &pAd->ApCfg.MBSSID[apidx].MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): invalid apidx(%d)\n", __FUNCTION__, apidx));
+ }
+ break;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ } while (FALSE);
+
+ {
+ if ((!pDesireHtPhy) || 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) && (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;
+ }
+
+ pMaxHtPhy->field.MCS = get_ht_max_mcs(pAd, &pDesireHtPhy->MCSSet[0],
+ &pActiveHtPhy->MCSSet[0]);
+
+ /* 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.*/
+
+
+ /* 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, (" %s():<---.AMsduSize = %d \n", __FUNCTION__, 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,("%s():<=== \n", __FUNCTION__));
+}
+
+
+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; i<MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ NdisFreeSpinLock(&pAd->BATable.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(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 BCN_IE_LIST *ie_list,
+ IN CHAR Rssi,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ COPY_MAC_ADDR(pBss->Bssid, ie_list->Bssid);
+ /* Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID*/
+ pBss->Hidden = 1;
+ if (ie_list->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(ie_list->Ssid, ZeroSsid, ie_list->SsidLen) == 0)
+ {
+ NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pBss->Ssid, ie_list->Ssid, ie_list->SsidLen);
+ pBss->SsidLen = ie_list->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 = ie_list->BssType;
+ pBss->BeaconPeriod = ie_list->BeaconPeriod;
+ if (ie_list->BssType == BSS_INFRA)
+ {
+ if (ie_list->CfParm.bValid)
+ {
+ pBss->CfpCount = ie_list->CfParm.CfpCount;
+ pBss->CfpPeriod = ie_list->CfParm.CfpPeriod;
+ pBss->CfpMaxDuration = ie_list->CfParm.CfpMaxDuration;
+ pBss->CfpDurRemaining = ie_list->CfParm.CfpDurRemaining;
+ }
+ }
+ else
+ {
+ pBss->AtimWin = ie_list->AtimWin;
+ }
+
+ NdisGetSystemUpTime(&pBss->LastBeaconRxTime);
+ pBss->CapabilityInfo = ie_list->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(ie_list->SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ if (ie_list->SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ NdisMoveMemory(pBss->SupRate, ie_list->SupRate, ie_list->SupRateLen);
+ else
+ NdisMoveMemory(pBss->SupRate, ie_list->SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ pBss->SupRateLen = ie_list->SupRateLen;
+ ASSERT(ie_list->ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ if (ie_list->ExtRateLen > MAX_LEN_OF_SUPPORTED_RATES)
+ ie_list->ExtRateLen = MAX_LEN_OF_SUPPORTED_RATES;
+ NdisMoveMemory(pBss->ExtRate, ie_list->ExtRate, ie_list->ExtRateLen);
+ pBss->NewExtChanOffset = ie_list->NewExtChannelOffset;
+ pBss->ExtRateLen = ie_list->ExtRateLen;
+ pBss->Channel = ie_list->Channel;
+ pBss->CentralChannel = ie_list->Channel;
+ pBss->Rssi = Rssi;
+ /* Update CkipFlag. if not exists, the value is 0x0*/
+ pBss->CkipFlag = ie_list->CkipFlag;
+
+ /* New for microsoft Fixed IEs*/
+ NdisMoveMemory(pBss->FixIEs.Timestamp, &ie_list->TimeStamp, 8);
+ pBss->FixIEs.BeaconInterval = ie_list->BeaconPeriod;
+ pBss->FixIEs.Capabilities = ie_list->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 (ie_list->HtCapabilityLen> 0)
+ {
+ pBss->HtCapabilityLen = ie_list->HtCapabilityLen;
+ NdisMoveMemory(&pBss->HtCapability, &ie_list->HtCapability, ie_list->HtCapabilityLen);
+ if (ie_list->AddHtInfoLen > 0)
+ {
+ pBss->AddHtInfoLen = ie_list->AddHtInfoLen;
+ NdisMoveMemory(&pBss->AddHtInfo, &ie_list->AddHtInfo, ie_list->AddHtInfoLen);
+
+ pBss->CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo,
+ &ie_list->HtCapability);
+ }
+
+#ifdef DOT11_VHT_AC
+ if (ie_list->vht_cap_len) {
+ NdisMoveMemory(&pBss->vht_cap_ie, &ie_list->vht_cap_ie, ie_list->vht_cap_len);
+ pBss->vht_cap_len = ie_list->vht_cap_len;
+ }
+
+ if (ie_list->vht_op_len) {
+ VHT_OP_IE *vht_op;
+
+ NdisMoveMemory(&pBss->vht_op_ie, &ie_list->vht_op_ie, ie_list->vht_op_len);
+ pBss->vht_op_len = ie_list->vht_op_len;
+ vht_op = &ie_list->vht_op_ie;
+ if ((vht_op->vht_op_info.ch_width > 0) &&
+ (ie_list->AddHtInfo.AddHtInfo.ExtChanOffset != EXTCHA_NONE) &&
+ (ie_list->HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pBss->CentralChannel != ie_list->AddHtInfo.ControlChan))
+ {
+ UCHAR cent_ch;
+
+ cent_ch = vht_cent_ch_freq(pAd, ie_list->AddHtInfo.ControlChan);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():VHT cent_ch=%d, vht_op_info->center_freq_1=%d, Bss->CentralChannel=%d, change from CentralChannel to cent_ch!\n",
+ __FUNCTION__, cent_ch, vht_op->vht_op_info.center_freq_1, pBss->CentralChannel));
+ pBss->CentralChannel = vht_op->vht_op_info.center_freq_1;
+ }
+ }
+#endif /* DOT11_VHT_AC */
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ BssCipherParse(pBss);
+
+ /* new for QOS*/
+ if (ie_list->EdcaParm.bValid)
+ NdisMoveMemory(&pBss->EdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM));
+ else
+ pBss->EdcaParm.bValid = FALSE;
+ if (ie_list->QosCapability.bValid)
+ NdisMoveMemory(&pBss->QosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM));
+ else
+ pBss->QosCapability.bValid = FALSE;
+ if (ie_list->QbssLoad.bValid)
+ NdisMoveMemory(&pBss->QbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM));
+ else
+ pBss->QbssLoad.bValid = FALSE;
+
+ {
+ PEID_STRUCT pEid;
+ USHORT Length = 0;
+
+#ifdef WSC_INCLUDED
+ pBss->WpsAP = 0x00;
+ pBss->WscDPIDFromWpsAP = 0xFFFF;
+#endif /* WSC_INCLUDED */
+
+ 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 WSC_INCLUDED
+ pBss->WpsAP |= WPS_AP;
+ WscCheckWpsIeFromWpsAP(pAd,
+ pEid,
+ &pBss->WscDPIDFromWpsAP);
+#endif /* WSC_INCLUDED */
+ break;
+ }
+ break;
+
+ }
+ 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 BCN_IE_LIST *ie_list,
+ IN CHAR Rssi,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ ULONG Idx;
+
+
+ Idx = BssTableSearch(Tab, ie_list->Bssid, ie_list->Channel);
+ 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, ie_list->Bssid) ||
+ SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, ie_list->Ssid, ie_list->SsidLen)
+#ifdef APCLI_SUPPORT
+ || MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, ie_list->Bssid)
+ || SSID_EQUAL(pAd->ApCliMlmeAux.Ssid, pAd->ApCliMlmeAux.SsidLen, ie_list->Ssid, ie_list->SsidLen)
+#endif /* APCLI_SUPPORT */
+ )
+ {
+ Idx = Tab->BssOverlapNr;
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], ie_list, Rssi, LengthVIE, pVIE);
+ 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], ie_list, Rssi, LengthVIE, pVIE);
+ Tab->BssNr++;
+ }
+ else
+ {
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], ie_list, Rssi, LengthVIE, pVIE);
+ }
+
+ return Idx;
+}
+
+
+
+
+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;
+
+#ifdef WAPI_SUPPORT
+ /* Init WAPI setting*/
+ pBss->WAPI.PairCipher = Ndis802_11WEPDisabled;
+ pBss->WAPI.PairCipherAux = Ndis802_11WEPDisabled;
+ pBss->WAPI.GroupCipher = Ndis802_11WEPDisabled;
+ pBss->WAPI.RsnCapability = 0;
+ pBss->WAPI.bMixMode = FALSE;
+#endif /* WAPI_SUPPORT */
+
+ 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 += 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;
+#ifdef WAPI_SUPPORT
+ case IE_WAPI:
+ pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
+
+ /* 0. The version number must be 1*/
+ if (le2cpu16(pRsnHeader->Version) != 1)
+ break;
+ pTmp += sizeof(RSN_IE_HEADER_STRUCT);
+
+ /* 1. Get AKM suite counts*/
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+ pTmp += sizeof(USHORT);
+
+ /* 2. Get AKM ciphers*/
+ pAKM = (PAKM_SUITE_STRUCT) pTmp;
+ if (!RTMPEqualMemory(pTmp, WAPI_OUI, 3))
+ break;
+
+ switch (pAKM->Type)
+ {
+ case 1:
+ /* Support WAI certificate authentication*/
+ pBss->AuthMode = Ndis802_11AuthModeWAICERT;
+ break;
+ case 2:
+ /* Support WAI PSK*/
+ pBss->AuthMode = Ndis802_11AuthModeWAIPSK;
+ break;
+ default:
+ break;
+ }
+ pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
+
+ /* 3. Get pairwise cipher counts*/
+ NdisMoveMemory(&Count, pTmp, sizeof(USHORT));
+ Count = cpu2le16(Count);
+ pTmp += sizeof(USHORT);
+
+ /* 4. Get pairwise cipher*/
+ /* Parsing all unicast cipher suite*/
+ while (Count > 0)
+ {
+ if (!RTMPEqualMemory(pTmp, WAPI_OUI, 3))
+ break;
+
+ /* Skip OUI*/
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ TmpCipher = Ndis802_11WEPDisabled;
+ switch (pCipher->Type)
+ {
+ case 1:
+ TmpCipher = Ndis802_11EncryptionSMS4Enabled;
+ break;
+ default:
+ break;
+ }
+
+ if (TmpCipher > pBss->WAPI.PairCipher)
+ {
+ /* Move the lower cipher suite to PairCipherAux*/
+ pBss->WAPI.PairCipherAux = pBss->WAPI.PairCipher;
+ pBss->WAPI.PairCipher = TmpCipher;
+ }
+ else
+ {
+ pBss->WAPI.PairCipherAux = TmpCipher;
+ }
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
+ Count--;
+ }
+
+ /* 5. Check group cipher*/
+ if (!RTMPEqualMemory(pTmp, WAPI_OUI, 3))
+ break;
+
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ /* Parse group cipher*/
+ switch (pCipher->Type)
+ {
+ case 1:
+ pBss->WAPI.GroupCipher = Ndis802_11EncryptionSMS4Enabled;
+ break;
+ default:
+ break;
+ }
+ /* set to correct offset for next parsing*/
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
+
+ /* update the encryption type*/
+ pBss->WepStatus = pBss->WAPI.PairCipher;
+
+ /* update the WAPI capability*/
+ pBss->WAPI.RsnCapability = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ break;
+#endif /* WAPI_SUPPORT */
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ COPY_MAC_ADDR(pHdr80211->Addr2, pBssid);
+#endif /* CONFIG_AP_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 <int arg_size, arg> 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 UCHAR AntSel,
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ /* Beacon must be handled by ap-sync state machine.*/
+ /* Probe-rsp must be handled by apcli-sync state machine.*/
+ /* Those packets don't need to check its MAC address.*/
+ do
+ {
+ /*
+ 1. When P2P GO On and receive Probe Response, preCheckMsgTypeSubset function will
+ enquene Probe response to APCli sync state machine
+ Solution: when GO On skip preCheckMsgTypeSubset redirect to APMsgTypeSubst
+ 2. When P2P Cli On and receive Probe Response, preCheckMsgTypeSubset function will
+ enquene Probe response to APCli sync state machine
+ Solution: handle MsgType == APCLI_MT2_PEER_PROBE_RSP on ApCli Sync state machine
+ when ApCli on idle state.
+ */
+
+ if (!MAC_ADDR_EQUAL(pFrame->Hdr.Addr1, pAd->CurrentAddress) &&
+ preCheckMsgTypeSubset(pAd, pFrame, &Machine, &MsgType))
+ break;
+
+ if (!MAC_ADDR_EQUAL(pFrame->Hdr.Addr1, pAd->CurrentAddress) &&
+ !MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, ZERO_MAC_ADDR)
+ && MAC_ADDR_EQUAL(pAd->ApCliMlmeAux.Bssid, pFrame->Hdr.Addr2))
+ {
+ if (ApCliMsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+ break;
+ }
+ else
+ {
+ if (APMsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+ break;
+ }
+
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d, STA-%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pFrame->Hdr.FC.SubType, PRINT_MAC(pFrame->Hdr.Addr2)));
+ return FALSE;
+
+ } while (FALSE);
+#else
+ if (!APMsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
+ return FALSE;
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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].AntSel = AntSel;
+ 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;
+}
+
+#ifdef WSC_INCLUDED
+/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
+ * \param *Queue The MLME Queue
+ * \param TimeStampLow The lower 32 bit of timestamp, here we used for eventID.
+ * \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
+ */
+BOOLEAN MlmeEnqueueForWsc(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG eventID,
+ IN LONG senderID,
+ IN ULONG Machine,
+ IN ULONG MsgType,
+ IN ULONG MsgLen,
+ IN VOID *Msg)
+{
+ INT Tail;
+ /*ULONG IrqFlags;*/
+ MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> MlmeEnqueueForWsc\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 FALSE;
+
+ /* First check the size, it MUST not exceed the mlme queue size*/
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForWsc: msg too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+
+ if (MlmeQueueFull(Queue, 1))
+ {
+
+ return FALSE;
+ }
+
+ /* 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 = eventID;
+ Queue->Entry[Tail].TimeStamp.u.HighPart = senderID;
+ if (Msg != NULL)
+ NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+
+ NdisReleaseSpinLock(&(Queue->Lock));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- MlmeEnqueueForWsc\n"));
+
+ return TRUE;
+}
+#endif /* WSC_INCLUDED */
+
+/*! \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)
+{
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
+
+
+
+ /* 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);
+
+
+}
+
+/*! \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
+
+ */
+
+/* ===========================================================================================*/
+/* 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, seed = 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;
+
+ /*get seed by RSSI or SNR related info */
+ seed = rtmp_bbp_get_random_seed(pAd);
+
+ return value ^ seed ^ 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,
+ INOUT UCHAR SupRate[],
+ INOUT UCHAR *SupRateLen)
+{
+ UCHAR RateIdx, i, j;
+ UCHAR NewRate[12], NewRateLen;
+
+ NewRateLen = 0;
+
+ if (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+ 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);
+}
+
+
+/*
+ ========================================================================
+
+ 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 (WMODE_B):
+ ProperMlmeRate = RATE_11;
+ MinimumRate = RATE_1;
+ break;
+ case (WMODE_B | WMODE_G):
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_B | WMODE_G | WMODE_GN | WMODE_A |WMODE_AN):
+ case (WMODE_B | WMODE_G | WMODE_GN):
+#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 (WMODE_A):
+#ifdef DOT11_N_SUPPORT
+ case (WMODE_GN): /* rt2860 need to check mlmerate for 802.11n*/
+ case (WMODE_G | WMODE_GN):
+ case (WMODE_A | WMODE_G | WMODE_GN | WMODE_AN):
+ case (WMODE_A |WMODE_AN):
+ case (WMODE_AN):
+#endif /* DOT11_N_SUPPORT */
+ ProperMlmeRate = RATE_24;
+ MinimumRate = RATE_6;
+ break;
+ case (WMODE_A |WMODE_B | WMODE_G):
+ ProperMlmeRate = RATE_24;
+ if (pAd->MlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ break;
+ default:
+ ProperMlmeRate = RATE_1;
+ MinimumRate = RATE_1;
+ break;
+ }
+
+
+#ifdef DOT11_VHT_AC
+ if (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+ {
+ ProperMlmeRate = RATE_11;
+ MinimumRate = RATE_1;
+ }
+ else
+ {
+ if (WMODE_CAP(pAd->CommonCfg.PhyMode, WMODE_B))
+ {
+ if ((pAd->MlmeAux.SupRateLen == 4) && (pAd->MlmeAux.ExtRateLen == 0))
+ ProperMlmeRate = RATE_11; /* B only AP */
+ else
+ ProperMlmeRate = RATE_24;
+
+ if (pAd->MlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ }
+ else
+ {
+ ProperMlmeRate = RATE_24;
+ MinimumRate = RATE_6;
+ }
+ }
+#endif /* DOT11_VHT_AC */
+
+ 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 RTMPAvgRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN RSSI_SAMPLE *pRssi)
+{
+ CHAR Rssi;
+
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ Rssi = (pRssi->AvgRssi0 + pRssi->AvgRssi1 + pRssi->AvgRssi2)/3;
+ }
+ else if(pAd->Antenna.field.RxPath == 2)
+ {
+ Rssi = (pRssi->AvgRssi0 + pRssi->AvgRssi1)>>1;
+ }
+ else
+ {
+ Rssi = pRssi->AvgRssi0;
+ }
+
+ return Rssi;
+}
+
+
+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 RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+#ifdef RTMP_MAC_USB
+#endif /* RTMP_MAC_USB */
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_NIC_NOT_EXIST |
+ fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
+ || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+ )
+ return;
+
+#ifdef RT3290
+ if (IS_RT3290(pAd) && (pAd->RalinkCounters.OneSecTransmittedByteCount >= 500))
+ return;
+#endif /* RT3290 */
+
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+/* if (pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_DISABLE)*/
+ /* for SmartBit 64-byte stream test */
+ if (pAd->MacTab.Size > 0)
+ APAsicEvaluateRxAnt(pAd);
+ return;
+ }
+#endif /* CONFIG_AP_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 RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_NIC_NOT_EXIST)
+ || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+ )
+ return;
+
+ {
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+/* if (pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_DISABLE)*/
+ APAsicRxAntEvalTimeout(pAd);
+ return;
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ if (pEntry)
+ {
+ if (IS_ENTRY_CLIENT(pEntry))
+ result = pAd->ApCfg.MBSSID[pEntry->apidx].bAutoTxRateSwitch;
+#ifdef WDS_SUPPORT
+ else if (IS_ENTRY_WDS(pEntry))
+ result = pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].bAutoTxRateSwitch;
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ else if (IS_ENTRY_APCLI(pEntry))
+ result = pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].bAutoTxRateSwitch;
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+ return result;
+}
+
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ INT apidx = 0;
+
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ if (pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch)
+ return TRUE;
+ }
+#ifdef WDS_SUPPORT
+ for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++)
+ {
+ if (pAd->WdsTab.WdsEntry[apidx].bAutoTxRateSwitch)
+ return TRUE;
+ }
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++)
+ {
+ if (pAd->ApCfg.ApCliTab[apidx].bAutoTxRateSwitch)
+ return TRUE;
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ if (pEntry)
+ {
+ if (IS_ENTRY_CLIENT(pEntry))
+ tx_mode = (UCHAR)pAd->ApCfg.MBSSID[pEntry->apidx].DesiredTransmitSetting.field.FixedTxMode;
+#ifdef WDS_SUPPORT
+ else if (IS_ENTRY_WDS(pEntry))
+ tx_mode = (UCHAR)pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].DesiredTransmitSetting.field.FixedTxMode;
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ else if (IS_ENTRY_APCLI(pEntry))
+ tx_mode = (UCHAR)pAd->ApCfg.ApCliTab[pEntry->MatchAPCLITabIdx].DesiredTransmitSetting.field.FixedTxMode;
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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, get_phymode_str(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : the fixed TxMode is invalid \n", __FUNCTION__));
+ }
+}
+
+
+
+VOID RTMPSetAGCInitValue(RTMP_ADAPTER *pAd, UCHAR BandWidth)
+{
+ if (pAd->chipOps.ChipAGCInit != NULL)
+ pAd->chipOps.ChipAGCInit(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; IdChan<pAd->ChannelListNum; IdChan++)
+ {
+ if (pAd->ChannelList[IdChan].Channel == ChanNum)
+ {
+ if ((pAd->ChannelList[IdChan].Flags & Property) == Property)
+ return TRUE;
+
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/multi_channel.c b/cleopatre/devkit/mt7601udrv/common/multi_channel.c
new file mode 100644
index 0000000000..2474e80885
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/multi_channel.c
@@ -0,0 +1,1012 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ multi_channel.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+
+#include "rt_config.h"
+
+#ifdef CONFIG_MULTI_CHANNEL
+
+UINT32 SwitchTime1, SwitchTime2, SwitchTime3, SwitchTime4, SwitchTime5, SwitchTime6, SwitchTime7, SwitchTime8;
+UINT32 TempTimeLo, TempTimeHi;
+
+extern INT Set_P2pCli_Enable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+extern INT Set_P2p_OpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+VOID RtmpPrepareHwNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN BOOLEAN bQosNull,
+ IN BOOLEAN bEOSP,
+ IN UCHAR OldUP,
+ IN UCHAR OpMode,
+ IN UCHAR PwrMgmt,
+ IN BOOLEAN bWaitACK,
+ IN CHAR Index)
+{
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ TXWI_STRUC *pTxWI;
+ TXINFO_STRUC *pTxInfo;
+ PUCHAR pNullFrame;
+ PHEADER_802_11 pNullFr;
+ UINT32 frameLen;
+ UINT32 totalLen;
+ UCHAR *ptr;
+ UINT i;
+ UINT32 longValue;
+ UCHAR MlmeRate;
+
+#ifdef RT_BIG_ENDIAN
+ NDIS_STATUS NState;
+ PUCHAR pNullFrBuf;
+#endif /* RT_BIG_ENDIAN */
+
+
+ NdisZeroMemory(pAd->NullFrBuf, sizeof(pAd->NullFrBuf));
+ pTxWI = (TXWI_STRUC *)&pAd->NullFrBuf[0];
+ pNullFrame = &pAd->NullFrBuf[TXWISize];
+
+ pNullFr = (PHEADER_802_11) pNullFrame;
+ frameLen = sizeof(HEADER_802_11);
+
+ pNullFr->FC.Type = BTYPE_DATA;
+ pNullFr->FC.SubType = SUBTYPE_NULL_FUNC;
+ pNullFr->FC.ToDs = 1;
+ pNullFr->FC.FrDs = 0;
+
+ COPY_MAC_ADDR(pNullFr->Addr1, pEntry->Addr);
+ {
+ COPY_MAC_ADDR(pNullFr->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pNullFr->Addr3, pAd->CommonCfg.Bssid);
+ }
+
+ pNullFr->FC.PwrMgmt = PwrMgmt;
+
+ pNullFr->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, pAd->CommonCfg.TxRate, 14);
+
+ /* sequence is increased in MlmeHardTx */
+ pNullFr->Sequence = pAd->Sequence;
+ pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; /* next sequence */
+
+ if (bQosNull)
+ {
+ UCHAR *qos_p = ((UCHAR *)pNullFr) + frameLen;
+
+ pNullFr->FC.SubType = SUBTYPE_QOS_NULL;
+
+ /* copy QOS control bytes */
+ qos_p[0] = ((bEOSP) ? (1 << 4) : 0) | OldUP;
+ qos_p[1] = 0;
+ frameLen += 2;
+ } /* End of if */
+
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, pEntry->Aid, frameLen,
+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+
+ dumpTxWI(pAd, pTxWI);
+
+ if (bWaitACK)
+ pTxWI->TxWITXRPT = 1;
+
+ hex_dump("RtmpPrepareHwNullFrame", pAd->NullFrBuf, TXWISize + frameLen);
+
+ totalLen = TXWISize + frameLen;
+ pAd->NullFrLen = totalLen;
+ ptr = pAd->NullFrBuf;
+
+#ifdef RT_BIG_ENDIAN
+ NState = os_alloc_mem(pAd, (PUCHAR *) &pNullFrBuf, 100);
+ if ( NState == NDIS_STATUS_FAILURE )
+ return;
+
+ NdisZeroMemory(pNullFrame, 100);
+ NdisMoveMemory(pNullFrBuf, pAd->NullFrBuf, totalLen);
+ RTMPWIEndianChange(pAd, pNullFrBuf, TYPE_TXWI);
+ RTMPFrameEndianChange(pAd, (PUCHAR)pNullFrBuf + TXWISize, DIR_WRITE, FALSE);
+
+ ptr = pNullFrBuf;
+#endif /* RT_BIG_ENDIAN */
+
+
+ for (i= 0; i< totalLen; i+=4)
+ {
+ longValue = *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+ //hex_dump("null frame before",&longValue, 4);
+
+ if (Index == 0)
+ RTMP_IO_WRITE32(pAd, pAd->NullBufOffset[0] + i, longValue);
+ else if (Index == 1)
+ RTMP_IO_WRITE32(pAd, pAd->NullBufOffset[1] + i, longValue);
+
+ //RTMP_IO_WRITE32(pAd, 0xB700 + i, longValue);
+ //RTMP_IO_WRITE32(pAd, 0xB780 + i, longValue);
+
+ ptr += 4;
+ }
+
+
+
+}
+
+
+VOID RTMPHwSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull,
+ IN USHORT PwrMgmt,
+ IN CHAR Index)
+{
+
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ NDIS_STATUS NState;
+ PHEADER_802_11 pNullFr;
+ UCHAR *ptr;
+ UINT32 longValue;
+#ifdef RT_BIG_ENDIAN
+ PUCHAR pNullFrame;
+#endif /* RT_BIG_ENDIAN */
+ UINT32 Data=0;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - Send NULL Frame @%d Mbps...%d \n", __FUNCTION__, RateIdToMbps[pAd->CommonCfg.TxRate],PwrMgmt));
+
+ pNullFr = (PHEADER_802_11)((&pAd->NullFrBuf[0]) +TXWISize);
+
+ pNullFr->FC.PwrMgmt = PwrMgmt;
+
+ pNullFr->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
+
+ /* sequence is increased in MlmeHardTx */
+ pNullFr->Sequence = pAd->Sequence;
+ pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; /* next sequence */
+
+ //hex_dump("RtmpPrepareHwNullFrame", pAd->NullFrBuf, pAd->NullFrLen);
+
+ if (Index == 0)
+ {
+ ptr = pAd->NullFrBuf + TXWISize;
+
+#ifdef RT_BIG_ENDIAN
+ longValue = (*ptr << 8) + *(ptr + 1) + (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+#else
+ longValue = *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+#endif /* RT_BIG_ENDIAN */
+ RTMP_IO_WRITE32(pAd, pAd->NullBufOffset[0] + TXWISize, longValue);
+
+ ptr = pAd->NullFrBuf + TXWISize + 20; // update Sequence
+ longValue = *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+ RTMP_IO_WRITE32(pAd, pAd->NullBufOffset[0] + TXWISize + 20, longValue);
+
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xffffff1f; /* Null 2 frame buffer select bit[5:7]=0 */
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+ }
+ else if (Index == 1)
+ {
+ ptr = pAd->NullFrBuf + TXWISize;
+#ifdef RT_BIG_ENDIAN
+ longValue = (*ptr << 8) + *(ptr + 1) + (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+#else
+ longValue = *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+#endif /* RT_BIG_ENDIAN */
+ RTMP_IO_WRITE32(pAd, pAd->NullBufOffset[1] + TXWISize, longValue);
+
+ ptr = pAd->NullFrBuf + TXWISize + 20; // update Sequence
+ longValue = *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+ RTMP_IO_WRITE32(pAd, pAd->NullBufOffset[1] + TXWISize + 20, longValue);
+
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xffffff1f; /* Null 2 frame buffer select bit[5:7]=1 */
+ Data |= 0x20; /* Null 2 frame buffer select bit[5:7]=1 */
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+ }
+
+ RTMP_IO_WRITE32(pAd, PBF_CTRL, 0x04);
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Send out a NULL frame to a specified STA at a higher TX rate. The
+ purpose is to ensure the designated client is okay to received at this
+ rate.
+ ==========================================================================
+ */
+VOID RtmpEnqueueLastNullFrame(
+ 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,
+ IN UCHAR PwrMgmt,
+ IN UCHAR OpMode)
+{
+ UCHAR NullFrame[48];
+ ULONG Length;
+ PHEADER_802_11 pHeader_802_11;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ pEntry = MacTableLookup(pAd, pAddr);
+
+ if (pEntry == NULL)
+ {
+ 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, pEntry->Addr);
+ {
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+ }
+
+ pHeader_802_11->FC.PwrMgmt = PwrMgmt;
+
+ 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 */
+ }
+}
+
+
+
+
+VOID MCC_ChangeAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
+ RtmpOsTaskWakeUp(&(pAd->MultiChannelTask));
+}
+
+VOID ConcurrentP2PConnectTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ int i;
+ RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
+ PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
+
+ pAd->Mlme.ConcurrentP2PConnectTimerRunning = FALSE;
+ pAd->P2pCfg.bStartP2pConnect = FALSE;
+
+ if (pAd->P2pCfg.bStartP2pConnect)
+ {
+ P2pStopConnectThis(pAd);
+ pAd->StaCfg.bAutoReconnect = TRUE;
+ pP2PCtrl->bSentProbeRSP = FALSE;
+ P2pStopScan(pAd);
+
+ P2pGroupTabInit(pAd);
+ pP2PCtrl->GoFormCurrentState = P2P_GO_FORM_IDLE;
+
+ /* Restore P2P WSC Mode / Config Method */
+ pP2PCtrl->WscMode = WSC_PIN_MODE; /* PIN */
+ pP2PCtrl->ConfigMethod = 0x188;
+ pP2PCtrl->Dpid = DEV_PASS_ID_NOSPEC;
+
+ if (P2P_CLI_ON(pAd))
+ {
+
+ Set_P2pCli_Enable_Proc(pAd, "0");
+
+ }
+
+ Set_P2p_OpMode_Proc(pAd, "0");
+ pAd->ApCfg.ApCliTab[0].WscControl.WscConfStatus = WSC_SCSTATE_UNCONFIGURED;
+ pAd->ApCfg.MBSSID[0].WscControl.WscConfStatus = WSC_SCSTATE_UNCONFIGURED;
+ OS_WAIT(200);
+
+ if (INFRA_ON(pAd))
+ MultiChannelSwitchToRa(pAd);
+
+ }
+}
+
+
+
+static VOID MACBuffer_Change(
+ RTMP_ADAPTER *pAd,
+ BOOLEAN hcca_to_edca,
+ BOOLEAN edca_to_hcca)
+{
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ UINT i = 0;
+ UINT32 MacValue, Data, Data2;
+ INT ret;
+ UINT32 MTxCycle;
+ UINT32 TimeStamp;
+ BOOLEAN bBlockIn2Out=FALSE;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
+ INT ext_ch;
+
+// RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic2, ret);
+ if (edca_to_hcca)
+ RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev);
+ if (hcca_to_edca)
+ RTMP_OS_NETDEV_STOP_QUEUE(pApCliEntry->dev);
+// RTMP_SEM_EVENT_UP(&pAd->reg_atomic2);
+
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET);
+
+ /* Disable EDCA or HCCA dequeue */
+ if (edca_to_hcca)
+ {
+ pAd->MultiChannelFlowCtl |= EDCA_AC0_DEQUEUE_DISABLE;// 1
+ }
+ if(hcca_to_edca)
+ {
+ pAd->MultiChannelFlowCtl |= HCCA_DEQUEUE_DISABLE;//16
+ }
+
+
+ RTMP_IO_READ32(pAd, WMM_CTRL, &Data);
+
+ if(edca_to_hcca)
+ Data |= 0x80000000;/* bit 31 set to 1 */ /* WMM Channel switch to EDCA2 */
+ if(hcca_to_edca)
+ Data &= 0x7fffffff;/* bit 31 set to 0 */ /* WMM Channel switch to EDCA1 */
+
+
+ RTMP_IO_WRITE32(pAd, WMM_CTRL, Data);
+
+ /* Polling EDCA or EDCA2 Out-Q until empty */
+
+ for (MTxCycle = 0;; MTxCycle++)
+ {
+ if (!bBlockIn2Out)
+ {
+ RTMP_IO_READ32(pAd, 0x438, &Data);
+ if ((edca_to_hcca) && (((Data >> 16) & 0xff) == 0))
+ {
+ /* Disable EDCA1 In-Q to Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xffffEfff;/* bit 12 set to 0 */ //zero modify 20120807
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+ bBlockIn2Out=TRUE;
+ }
+ else if ((hcca_to_edca) && (((Data >> 24) & 0xff) == 0))
+ {
+ /* Disable HCCA/EDCA2 In-Q to Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xffffDfff;/* set bit 13 set to 0 */ //zero modify 20120807
+ //Data |= ((1 << 10) | (1 << 11));
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+ bBlockIn2Out=TRUE;
+ }
+ else
+ RTMPusecDelay(50);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, TXQ_STA, &Data);
+ if ((edca_to_hcca) && (((Data >> 19) & 0x1f) == 0))
+ break;
+ else if ((hcca_to_edca) && (((Data >> 27) & 0x1f) == 0))
+ break;
+ else
+ RTMPusecDelay(50);
+ }
+
+ }
+
+ if (MTxCycle >= 2000)
+ {
+ if(edca_to_hcca)
+ DBGPRINT(RT_DEBUG_ERROR, ("Polling EDCA Out-Q max(%x)\n", Data));
+ if(hcca_to_edca)
+ DBGPRINT(RT_DEBUG_ERROR, ("Polling HCCA Out-Q max\n"));
+
+ }
+
+ if(edca_to_hcca)
+ RTMPHwSendNullFrame(pAd,
+ pAd->CommonCfg.TxRate,
+ (pAd->CommonCfg.bWmmCapable & pAd->CommonCfg.APEdcaParm.bValid),
+ PWR_SAVE, 0);
+
+ if(hcca_to_edca)
+ RTMPHwSendNullFrame(pAd,
+ pAd->CommonCfg.TxRate,
+ (pAd->CommonCfg.bWmmCapable & pAd->CommonCfg.APEdcaParm.bValid),
+ PWR_SAVE, 1);
+
+
+ RtmpOsMsDelay(20);
+ /* Disable all Tx Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xfffffff3;/* bit 3 and bit 2 set to 0 */ //zero modify 20120807
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+
+
+
+ if(hcca_to_edca)
+ {
+ if (pAd->StaCfg.BW == BW_40)
+ {
+ if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+ ext_ch = EXTCHA_ABOVE;
+
+ else
+ ext_ch = EXTCHA_BELOW;
+ }
+ else
+ {
+ ext_ch = EXTCHA_NONE;
+ }
+
+ AsicSetChannel(pAd, pAd->CommonCfg.CentralChannel, pAd->StaCfg.BW, ext_ch, FALSE);
+
+ }
+
+ if(edca_to_hcca)
+ {
+ if (pAd->P2pCfg.BW == BW_40)
+ {
+ if (pAd->ApCliMlmeAux.CentralChannel > pAd->ApCliMlmeAux.Channel)
+ ext_ch = EXTCHA_ABOVE;
+ else
+ ext_ch = EXTCHA_BELOW;
+
+ }
+ else
+ {
+ ext_ch = EXTCHA_NONE;
+ }
+
+ AsicSetChannel(pAd, pAd->ApCliMlmeAux.CentralChannel, pAd->P2pCfg.BW, ext_ch, FALSE);
+
+ }
+
+
+
+ if(edca_to_hcca)
+ RTMPHwSendNullFrame(pAd,
+ pAd->CommonCfg.TxRate,
+ (pAd->CommonCfg.bWmmCapable & pAd->CommonCfg.APEdcaParm.bValid),
+ PWR_ACTIVE, 1);
+
+ if(hcca_to_edca)
+ RTMPHwSendNullFrame(pAd,
+ pAd->CommonCfg.TxRate,
+ (pAd->CommonCfg.bWmmCapable & pAd->CommonCfg.APEdcaParm.bValid),
+ PWR_ACTIVE, 0);
+
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &SwitchTime7);
+
+ /* Enable EDCA or EDCA2 Tx In-Q and Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ if(edca_to_hcca)
+ Data |= ((1 << 3) | (1 << 13));/* bit 3 and bit 13 set to 1 */
+
+ if(hcca_to_edca)
+ Data |= ((1 << 2) | (1 << 12));/* bit 2 and bit 12 set to 1 */
+
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &SwitchTime8);
+
+ if ((i == 10) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Multi Channel Switch Retry count exhausted\n"));
+ }
+
+ /* Enable EDCA or EDCA2 dequeue */
+ if(hcca_to_edca)
+ pAd->MultiChannelFlowCtl &= ~EDCA_AC0_DEQUEUE_DISABLE; // 0
+
+ if(edca_to_hcca)
+ pAd->MultiChannelFlowCtl &= ~HCCA_DEQUEUE_DISABLE; // 0
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET);
+
+// RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic2, ret);
+
+ if(hcca_to_edca)
+ RTMP_OS_NETDEV_WAKE_QUEUE(pAd->net_dev);
+
+ if(edca_to_hcca)
+ RTMP_OS_NETDEV_WAKE_QUEUE(pApCliEntry->dev);
+
+// RTMP_SEM_EVENT_UP(&pAd->reg_atomic2);
+
+
+}
+
+
+static VOID ProcessEDCAToHCCA(
+ RTMP_ADAPTER *pAd)
+{
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
+
+ UINT32 Data;
+
+ if ((pApCliEntry->Valid) && INFRA_ON(pAd))
+ {
+ MACBuffer_Change(pAd,FALSE, TRUE);
+ RTMPSetTimer(&pAd->Mlme.MCCTimer, pAd->Mlme.HCCAToEDCATimerValue);
+ }
+}
+
+
+static VOID ProcessHCCAToEDCA(
+ PRTMP_ADAPTER pAd)
+{
+ UINT32 MacValue;
+ UINT32 i = 0;
+ INT ret;
+ BOOLEAN bBlockIn2Out=FALSE;
+ UINT32 Data;
+
+ if (P2P_INF_ON(pAd) && P2P_GO_ON(pAd))
+ {
+ ;//APUpdateAllBeaconFrame(pAd);
+ }
+ else
+ {
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
+
+ if ((pApCliEntry->Valid) && INFRA_ON(pAd))
+ {
+ MACBuffer_Change(pAd,TRUE, FALSE);
+ RTMPSetTimer(&pAd->Mlme.MCCTimer, pAd->Mlme.EDCAToHCCATimerValue);
+ }
+ }
+}
+
+static INT MultiChannelTaskThread(
+ IN ULONG Context)
+{
+ RTMP_OS_TASK *pTask;
+ RTMP_ADAPTER *pAd;
+ INT Status = 0;
+
+ pTask = (RTMP_OS_TASK *)Context;
+ pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask);
+
+ if (pAd == NULL)
+ return 0;
+
+ RtmpOSTaskCustomize(pTask);
+
+
+ while (pTask && !RTMP_OS_TASK_IS_KILLED(pTask))
+ {
+ if (RtmpOSTaskWait(pAd, pTask, &Status) == FALSE)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+
+ if (Status != 0)
+ break;
+
+
+ if (INFRA_ON(pAd) && P2P_CLI_ON(pAd))
+ {
+ if (pAd->LatchRfRegs.Channel == pAd->ApCliMlmeAux.CentralChannel)
+ pAd->MultiChannelAction = HCCA_TO_EDCA;
+ else if (pAd->LatchRfRegs.Channel == pAd->CommonCfg.CentralChannel)
+ pAd->MultiChannelAction = EDCA_TO_HCCA;
+
+ }
+ else if (INFRA_ON(pAd))
+ {
+ // reset to default switct to ra0
+ // MultiChannelSwitchToRa(pAd);
+ }
+ else if (P2P_CLI_ON(pAd))
+ {
+ // reset to default switch to p2p0
+ // MultiChannelSwitchToP2P(pAd);
+
+ }
+
+
+#ifdef RTMP_MAC_USB
+ /* device had been closed */
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ break;
+#endif /* RTMP_MAC_USB */
+ if (pAd->MultiChannelAction == HCCA_TO_EDCA)
+ ProcessHCCAToEDCA(pAd);
+ else if (pAd->MultiChannelAction == EDCA_TO_HCCA)
+ ProcessEDCAToHCCA(pAd);
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Unkown Action(=%d)\n", __FUNCTION__, pAd->MultiChannelAction));
+
+
+
+ }
+
+ if (pTask)
+ RtmpOSTaskNotifyToExit(pTask);
+
+ return 0;
+}
+
+NDIS_STATUS MultiChannelThreadInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS status = NDIS_STATUS_FAILURE;
+ RTMP_OS_TASK *pTask;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s\n", __FUNCTION__));
+
+ pTask = &pAd->MultiChannelTask;
+ pAd->MultiChannelAction = 0xFF;
+ pAd->Mlme.HCCAToEDCATimerValue = HCCA_TIMEOUT;
+ pAd->Mlme.EDCAToHCCATimerValue = EDCA_TIMEOUT;
+ pAd->P2pCfg.bStartP2pConnect = FALSE;
+ pAd->MultiChannelFlowCtl = 0;
+
+ RTMPInitTimer(pAd, &pAd->Mlme.MCCTimer, GET_TIMER_FUNCTION(MCC_ChangeAction), pAd, FALSE);
+ RTMPInitTimer(pAd, &pAd->Mlme.ConcurrentP2PConnectTimer, GET_TIMER_FUNCTION(ConcurrentP2PConnectTimeout), pAd, FALSE);
+
+ RTMP_OS_TASK_INIT(pTask, "MultiChannelTask", pAd);
+ status = RtmpOSTaskAttach(pTask, MultiChannelTaskThread, (ULONG)&pAd->MultiChannelTask);
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, status=%d!\n", __FUNCTION__, status));
+
+ return status;
+}
+
+BOOLEAN MultiChannelThreadExit(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT ret;
+
+ MultiChannelTimerStop(pAd);
+
+ ret = RtmpOSTaskKill(&pAd->MultiChannelTask);
+ if (ret == NDIS_STATUS_FAILURE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: kill multi-channel task failed!\n", __FUNCTION__));
+ }
+ return TRUE;
+}
+
+VOID MultiChannelTimerStop(
+ IN PRTMP_ADAPTER pAd)
+{
+
+ BOOLEAN bCancelled = FALSE;
+ PAPCLI_STRUCT pApCliEntry = NULL;
+
+
+ pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
+ pAd->MultiChannelAction = 0xFF;
+ RTMPCancelTimer(&pAd->Mlme.MCCTimer, &bCancelled);
+
+ RTMP_OS_NETDEV_WAKE_QUEUE(pAd->net_dev);
+ RTMP_OS_NETDEV_WAKE_QUEUE(pApCliEntry->dev);
+
+ OS_WAIT(200);
+}
+
+VOID MultiChannelTimerStart(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+
+ BOOLEAN bCancelled = FALSE;
+
+ if (pAd->P2pCfg.bStartP2pConnect)
+ {
+ pAd->P2pCfg.bStartP2pConnect = FALSE;
+
+ pAd->StaCfg.ReConnectCountDown = 5;
+
+ if (pAd->Mlme.ConcurrentP2PConnectTimerRunning)
+ {
+ printk("iversondebug MultiChannelTimer start3 \n");
+
+ RTMPCancelTimer(&pAd->Mlme.ConcurrentP2PConnectTimer, &bCancelled);
+ pAd->Mlme.ConcurrentP2PConnectTimerRunning = FALSE;
+ }
+ }
+
+ RTMPSetTimer(&pAd->Mlme.MCCTimer, 200);
+
+ pAd->Mlme.P2pStayTick = 0;
+ pAd->Mlme.StaStayTick = 0;
+}
+
+VOID MultiChannelSwitchToRa(
+ IN PRTMP_ADAPTER pAd)
+{
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
+ INT ext_ch;
+
+
+// MACBuffer_Change(pAd,TRUE, FALSE);
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UINT32 MacValue, Data, Data2;
+ INT ret,i;
+ UINT32 MTxCycle;
+ BOOLEAN bBlockIn2Out=FALSE;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
+
+ RTMP_OS_NETDEV_STOP_QUEUE(pApCliEntry->dev);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET);
+ pAd->MultiChannelFlowCtl |= HCCA_DEQUEUE_DISABLE;//16
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &SwitchTime1);
+ RTMP_IO_READ32(pAd, WMM_CTRL, &Data);
+
+ Data &= 0x7fffffff;/* bit 31 set to 0 */ /* WMM Channel switch to EDCA1 */
+
+ RTMP_IO_WRITE32(pAd, WMM_CTRL, Data);
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &SwitchTime2);
+
+ /* Polling EDCA or EDCA2 Out-Q until empty */
+
+ for (MTxCycle = 0;; MTxCycle++)
+ {
+ if (!bBlockIn2Out)
+ {
+ RTMP_IO_READ32(pAd, 0x438, &Data);
+ if ((((Data >> 24) & 0xff) == 0))
+ {
+ /* Disable HCCA/EDCA2 In-Q to Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xffffDfff;/* set bit 13 set to 0 */ //zero modify 20120807
+ //Data |= ((1 << 10) | (1 << 11));
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+ bBlockIn2Out=TRUE;
+ }
+ else
+ RTMPusecDelay(50);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, TXQ_STA, &Data);
+ if ((((Data >> 27) & 0x1f) == 0))
+ break;
+ else
+ RTMPusecDelay(50);
+ }
+
+ }
+
+ if (MTxCycle >= 2000)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Polling HCCA Out-Q max\n"));
+
+ }
+
+ RtmpOsMsDelay(20);
+ /* Disable all Tx Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xfffffff3;/* bit 3 and bit 2 set to 0 */ //zero modify 20120807
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+
+
+ if (pAd->StaCfg.BW == BW_40)
+ {
+ if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+ ext_ch = EXTCHA_ABOVE;
+ else
+ ext_ch = EXTCHA_BELOW;
+ }
+ else
+ {
+ ext_ch = EXTCHA_NONE;
+ }
+
+ AsicSetChannel(pAd, pAd->CommonCfg.CentralChannel, pAd->StaCfg.BW, ext_ch, FALSE);
+
+
+
+
+ RTMPHwSendNullFrame(pAd,
+ pAd->CommonCfg.TxRate,
+ (pAd->CommonCfg.bWmmCapable & pAd->CommonCfg.APEdcaParm.bValid),
+ PWR_ACTIVE, 0);
+
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &SwitchTime7);
+
+ /* Enable EDCA or EDCA2 Tx In-Q and Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data |= ((1 << 2) | (1 << 12));/* bit 2 and bit 12 set to 1 */
+
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+
+ if ((i == 10) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Multi Channel Switch Retry count exhausted\n"));
+ }
+
+ /* Enable EDCA or EDCA2 dequeue */
+
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET);
+
+ pAd->MultiChannelFlowCtl = 0;
+
+ RTMP_OS_NETDEV_WAKE_QUEUE(pAd->net_dev);
+
+}
+
+VOID MultiChannelSwitchToP2P(
+ IN PRTMP_ADAPTER pAd)
+{
+ PAPCLI_STRUCT pApCliEntry = NULL;
+ pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0];
+ INT ext_ch;
+
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UINT i = 0;
+ UINT32 MacValue, Data, Data2;
+ INT ret;
+ UINT32 MTxCycle;
+ BOOLEAN bBlockIn2Out=FALSE;
+
+
+ RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET);
+
+ /* Disable EDCA or HCCA dequeue */
+ pAd->MultiChannelFlowCtl |= EDCA_AC0_DEQUEUE_DISABLE;// 1
+
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &SwitchTime1);
+
+ RTMP_IO_READ32(pAd, WMM_CTRL, &Data);
+
+ Data |= 0x80000000;/* bit 31 set to 1 */ /* WMM Channel switch to EDCA2 */
+
+ RTMP_IO_WRITE32(pAd, WMM_CTRL, Data);
+
+ /* Polling EDCA or EDCA2 Out-Q until empty */
+
+ for (MTxCycle = 0;; MTxCycle++)
+ {
+ if (!bBlockIn2Out)
+ {
+ RTMP_IO_READ32(pAd, 0x438, &Data);
+ if ((((Data >> 16) & 0xff) == 0))
+ {
+ /* Disable EDCA1 In-Q to Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xffffEfff;/* bit 12 set to 0 */ //zero modify 20120807
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+ bBlockIn2Out=TRUE;
+ }
+ else
+ RTMPusecDelay(50);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, TXQ_STA, &Data);
+ if ((((Data >> 19) & 0x1f) == 0))
+ break;
+ else
+ RTMPusecDelay(50);
+ }
+
+ }
+
+ if (MTxCycle >= 2000)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Polling EDCA Out-Q max(%x)\n", Data));
+ }
+
+
+ RtmpOsMsDelay(20);
+ /* Disable all Tx Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data &= 0xfffffff3;/* bit 3 and bit 2 set to 0 */ //zero modify 20120807
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+
+
+ if (pAd->P2pCfg.BW == BW_40)
+ {
+ if (pAd->ApCliMlmeAux.CentralChannel > pAd->ApCliMlmeAux.Channel)
+ ext_ch = EXTCHA_ABOVE;
+ else
+ ext_ch = EXTCHA_BELOW;
+
+ }
+ else
+ {
+ ext_ch = EXTCHA_NONE;
+ }
+
+ AsicSetChannel(pAd, pAd->ApCliMlmeAux.CentralChannel, pAd->P2pCfg.BW, ext_ch, FALSE);
+
+
+
+
+ RTMPHwSendNullFrame(pAd,
+ pAd->CommonCfg.TxRate,
+ (pAd->CommonCfg.bWmmCapable & pAd->CommonCfg.APEdcaParm.bValid),
+ PWR_ACTIVE, 1);
+
+ /* Enable EDCA or EDCA2 Tx In-Q and Out-Q */
+ RTMP_IO_READ32(pAd, PBF_CFG, &Data);
+ Data |= ((1 << 3) | (1 << 13));/* bit 3 and bit 13 set to 1 */
+
+
+ RTMP_IO_WRITE32(pAd, PBF_CFG, Data);
+
+ if ((i == 10) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Multi Channel Switch Retry count exhausted\n"));
+ }
+
+ /* Enable EDCA or EDCA2 dequeue */
+ pAd->MultiChannelFlowCtl = 0; // 0
+
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET);
+
+ RTMP_OS_NETDEV_WAKE_QUEUE(pApCliEntry->dev);
+
+
+}
+
+
+#endif /* CONFIG_MULTI_CHANNEL */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/netif_block.c b/cleopatre/devkit/mt7601udrv/common/netif_block.c
new file mode 100644
index 0000000000..98f06c0299
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/netif_block.c
@@ -0,0 +1,121 @@
+#ifdef BLOCK_NET_IF
+
+#include "rt_config.h"
+#include "netif_block.h"
+
+static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
+static LIST_HEADER freeNetIfEntryList;
+
+void initblockQueueTab(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+
+ initList(&freeNetIfEntryList);
+ for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
+ insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
+
+ for (i=0; i < NUM_OF_TX_RING; i++)
+ initList(&pAd->blockQueueTab[i].NetIfList);
+
+ return;
+}
+
+BOOLEAN blockNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+ IN PNET_DEV pNetDev)
+{
+ PNETIF_ENTRY pNetIfEntry = NULL;
+
+ if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
+ {
+ RTMP_OS_NETDEV_STOP_QUEUE(pNetDev);
+ pNetIfEntry->pNetDev = pNetDev;
+ insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
+
+ pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_STOP_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+VOID releaseNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
+{
+ PNETIF_ENTRY pNetIfEntry = NULL;
+ PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
+
+ while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) != NULL)
+ {
+ PNET_DEV pNetDev = pNetIfEntry->pNetDev;
+ RTMP_OS_NETDEV_WAKE_QUEUE(pNetDev);
+ insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_WAKE_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
+ }
+ pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
+ return;
+}
+
+
+VOID StopNetIfQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ PNET_DEV NetDev = NULL;
+ UCHAR IfIdx = 0;
+ BOOLEAN valid = FALSE;
+
+
+#ifdef APCLI_SUPPORT
+ if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_APCLI) % MAX_APCLI_NUM;
+ NetDev = pAd->ApCfg.ApCliTab[IfIdx].dev;
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
+ NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
+ }
+ else
+#endif /* WDS_SUPPORT */
+ {
+#ifdef MBSS_SUPPORT
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM(pAd);
+ NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
+ }
+ else
+ {
+ IfIdx = MAIN_MBSSID;
+ NetDev = pAd->net_dev;
+ }
+#else
+ IfIdx = MAIN_MBSSID;
+ NetDev = pAd->net_dev;
+#endif
+ }
+
+ /* WMM support 4 software queues.*/
+ /* One software queue full doesn't mean device have no capbility to transmit packet.*/
+ /* So disable block Net-If queue function while WMM enable.*/
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ valid = (pAd->ApCfg.MBSSID[IfIdx].bWmmCapable == TRUE) ? FALSE : TRUE;
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (valid)
+ blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
+ return;
+}
+
+#endif /* BLOCK_NET_IF */
diff --git a/cleopatre/devkit/mt7601udrv/common/ps.c b/cleopatre/devkit/mt7601udrv/common/ps.c
new file mode 100644
index 0000000000..a719627e30
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/ps.c
@@ -0,0 +1,370 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related POWER SAVE function body.
+
+***************************************************************************/
+
+#include "rt_config.h"
+
+
+/*
+ ========================================================================
+ Routine Description:
+ This routine is used to do insert packet into power-saveing queue.
+
+ Arguments:
+ pAd: Pointer to our adapter
+ pPacket: Pointer to send packet
+ pMacEntry: portint to entry of MacTab. the pMacEntry store attribute of client (STA).
+ QueIdx: Priority queue idex.
+
+ Return Value:
+ NDIS_STATUS_SUCCESS:If succes to queue the packet into TxSwQueue.
+ NDIS_STATUS_FAILURE: If failed to do en-queue.
+========================================================================
+*/
+NDIS_STATUS RtmpInsertPsQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN MAC_TABLE_ENTRY *pMacEntry,
+ IN UCHAR QueIdx)
+{
+ ULONG IrqFlags;
+#ifdef UAPSD_SUPPORT
+ /* put the U-APSD packet to its U-APSD queue by AC ID */
+ UINT32 ac_id = QueIdx - QID_AC_BE; /* should be >= 0 */
+
+
+ if (UAPSD_MR_IS_UAPSD_AC(pMacEntry, ac_id))
+ {
+ UAPSD_PacketEnqueue(pAd, pMacEntry, pPacket, ac_id);
+
+ }
+ else
+#endif /* UAPSD_SUPPORT */
+ {
+ if (pMacEntry->PsQueue.Number >= MAX_PACKETS_IN_PS_QUEUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("legacy ps> queue a packet!\n"));
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ InsertTailQueue(&pMacEntry->PsQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+ }
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ /* mark corresponding TIM bit in outgoing BEACON frame */
+#ifdef UAPSD_SUPPORT
+ if (UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(pMacEntry, QueIdx))
+ {
+ /* 1. the station is UAPSD station;
+ 2. one of AC is non-UAPSD (legacy) AC;
+ 3. the destinated AC of the packet is UAPSD AC. */
+ /* So we can not set TIM bit due to one of AC is legacy AC */
+ }
+ else
+#endif /* UAPSD_SUPPORT */
+ {
+ WLAN_MR_TIM_BIT_SET(pAd, pMacEntry->apidx, pMacEntry->Aid);
+
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ This routine is used to clean up a specified power-saving queue. It's
+ used whenever a wireless client is deleted.
+ ==========================================================================
+ */
+VOID RtmpCleanupPsQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_HEADER pQueue)
+{
+ PQUEUE_ENTRY pEntry;
+ PNDIS_PACKET pPacket;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RtmpCleanupPsQueue (0x%08lx)...\n", (ULONG)pQueue));
+
+ while (pQueue->Head)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("RtmpCleanupPsQueue %ld...\n",pQueue->Number));
+
+ pEntry = RemoveHeadQueue(pQueue);
+ /*pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx); */
+ pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RtmpCleanupPsQueue pkt = %lx...\n", (ULONG)pPacket));
+ }
+}
+
+
+/*
+ ========================================================================
+ Description:
+ This routine frees all packets in PSQ that's destined to a specific DA.
+ BCAST/MCAST in DTIMCount=0 case is also handled here, just like a PS-POLL
+ is received from a WSTA which has MAC address FF:FF:FF:FF:FF:FF
+ ========================================================================
+*/
+VOID RtmpHandleRxPsPoll(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN USHORT Aid,
+ IN BOOLEAN isActive)
+{
+ PQUEUE_ENTRY pEntry;
+ PMAC_TABLE_ENTRY pMacEntry;
+ unsigned long IrqFlags;
+
+ /*DBGPRINT(RT_DEBUG_TRACE,("rcv PS-POLL (AID=%d) from %02x:%02x:%02x:%02x:%02x:%02x\n", */
+ /* Aid, pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5])); */
+
+ pMacEntry = &pAd->MacTab.Content[Aid];
+ if (RTMPEqualMemory(pMacEntry->Addr, pAddr, MAC_ADDR_LEN))
+ {
+ /*
+ Sta is change to Power Active stat.
+ Reset ContinueTxFailCnt
+ */
+ pMacEntry->ContinueTxFailCnt = 0;
+
+#ifdef UAPSD_SUPPORT
+ if (UAPSD_MR_IS_ALL_AC_UAPSD(isActive, pMacEntry))
+ {
+ /*
+ IEEE802.11e spec.
+ 11.2.1.7 Receive operation for STAs in PS mode during the CP
+ When a non-AP QSTA that is using U-APSD and has all ACs
+ delivery-enabled detects that the bit corresponding to its AID
+ is set in the TIM, the non-AP QSTA shall issue a trigger frame
+ or a PS-Poll frame to retrieve the buffered MSDU or management
+ frames.
+
+ WMM Spec. v1.1a 070601
+ 3.6.2 U-APSD STA Operation
+ 3.6.2.3 In case one or more ACs are not
+ delivery-enabled ACs, the WMM STA may retrieve MSDUs and
+ MMPDUs belonging to those ACs by sending PS-Polls to the WMM AP.
+ In case all ACs are delivery enabled ACs, WMM STA should only
+ use trigger frames to retrieve MSDUs and MMPDUs belonging to
+ those ACs, and it should not send PS-Poll frames.
+
+ Different definitions in IEEE802.11e and WMM spec.
+ But we follow the WiFi WMM Spec.
+ */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("All AC are UAPSD, can not use PS-Poll\n"));
+ return; /* all AC are U-APSD, can not use PS-Poll */
+ } /* End of if */
+#endif /* UAPSD_SUPPORT */
+
+ /*NdisAcquireSpinLock(&pAd->MacTabLock); */
+ /*NdisAcquireSpinLock(&pAd->TxSwQueueLock); */
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ if (isActive == FALSE)
+ {
+ if (pMacEntry->PsQueue.Head)
+ {
+#ifdef UAPSD_SUPPORT
+ UINT32 NumOfOldPsPkt;
+ NumOfOldPsPkt = pAd->TxSwQueue[QID_AC_BE].Number;
+#endif /* UAPSD_SUPPORT */
+
+ pEntry = RemoveHeadQueue(&pMacEntry->PsQueue);
+ if ( pMacEntry->PsQueue.Number >=1 )
+ RTMP_SET_PACKET_MOREDATA(RTPKT_TO_OSPKT(pEntry), TRUE);
+ InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QID_AC_BE], pEntry);
+
+#ifdef UAPSD_SUPPORT
+ /* we need to call RTMPDeQueuePacket() immediately as below */
+ if (NumOfOldPsPkt != pAd->TxSwQueue[QID_AC_BE].Number)
+ {
+ if (RTMP_GET_PACKET_DHCP(RTPKT_TO_OSPKT(pEntry)) ||
+ RTMP_GET_PACKET_EAPOL(RTPKT_TO_OSPKT(pEntry)) ||
+ RTMP_GET_PACKET_WAI(RTPKT_TO_OSPKT(pEntry)))
+ {
+ /*
+ These packets will use 1M/6M rate to send.
+ If you use 1M(2.4G)/6M(5G) to send, no statistics
+ count in NICUpdateFifoStaCounters().
+
+ So we can not count it for UAPSD; Or the SP will
+ not closed until timeout.
+ */
+ ;
+ }
+ else
+ UAPSD_MR_MIX_PS_POLL_RCV(pAd, pMacEntry);
+ }
+#endif /* UAPSD_SUPPORT */
+ }
+ else
+ {
+ /*
+ or transmit a (QoS) Null Frame;
+
+ In addtion, in Station Keep Alive mechanism, we need to
+ send a QoS Null frame to detect the station live status.
+ */
+ BOOLEAN bQosNull = FALSE;
+
+ if (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ bQosNull = TRUE;
+
+ RtmpEnqueueNullFrame(pAd, pMacEntry->Addr, pMacEntry->CurrTxRate,
+ Aid, pMacEntry->apidx, bQosNull, TRUE, 0);
+ }
+ }
+ else
+ {
+#ifdef UAPSD_SUPPORT
+ /* deliver all queued UAPSD packets */
+ UAPSD_AllPacketDeliver(pAd, pMacEntry);
+
+ /* end the SP if exists */
+ UAPSD_MR_ENTRY_RESET(pAd, pMacEntry);
+#endif /* UAPSD_SUPPORT */
+
+ while(pMacEntry->PsQueue.Head)
+ {
+/* if (pAd->TxSwQueue[QID_AC_BE].Number <= */
+/* (pAd->PortCfg.TxQueueSize + (MAX_PACKETS_IN_PS_QUEUE>>1))) */
+ {
+ pEntry = RemoveHeadQueue(&pMacEntry->PsQueue);
+ InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QID_AC_BE], pEntry);
+ }
+/* else */
+/* break; */
+ /* End of if */
+ } /* End of while */
+ } /* End of if */
+
+ /*NdisReleaseSpinLock(&pAd->TxSwQueueLock); */
+ /*NdisReleaseSpinLock(&pAd->MacTabLock); */
+
+ if ((Aid > 0) && (Aid < MAX_LEN_OF_MAC_TABLE) &&
+ (pMacEntry->PsQueue.Number == 0))
+ {
+ /* clear corresponding TIM bit because no any PS packet */
+#ifdef CONFIG_AP_SUPPORT
+ WLAN_MR_TIM_BIT_CLEAR(pAd, pMacEntry->apidx, Aid);
+#endif /* CONFIG_AP_SUPPORT */
+ pMacEntry->PsQIdleCount = 0;
+ }
+
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+ /* Dequeue outgoing frames from TxSwQueue0..3 queue and process it */
+ /* TODO: 2004-12-27 it's not a good idea to handle "More Data" bit here. because the */
+ /* RTMPDeQueue process doesn't guarantee to de-queue the desired MSDU from the corresponding */
+ /* TxSwQueue/PsQueue when QOS in-used. We should consider "HardTransmt" this MPDU */
+ /* using MGMT queue or things like that. */
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("rcv PS-POLL (AID=%d not match) from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ Aid, pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]));
+
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Update the station current power save mode. Calling this routine also
+ prove the specified client is still alive. Otherwise AP will age-out
+ this client once IdleCount exceeds a threshold.
+ ==========================================================================
+ */
+BOOLEAN RtmpPsIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN ULONG Wcid,
+ IN UCHAR Psm)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR old_psmode;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ return PWR_ACTIVE;
+ }
+
+ pEntry = &pAd->MacTab.Content[Wcid];
+ old_psmode = pEntry->PsMode;
+/* if (pEntry) */
+ {
+ /*
+ Change power save mode first because we will call
+ RTMPDeQueuePacket() in RtmpHandleRxPsPoll().
+
+ Or when Psm = PWR_ACTIVE, we will not do Aggregation in
+ RTMPDeQueuePacket().
+ */
+ pEntry->NoDataIdleCount = 0;
+ pEntry->PsMode = Psm;
+
+ if ((old_psmode == PWR_ACTIVE) && (Psm == PWR_SAVE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("RtmpPsIndicate - %02x:%02x:%02x:%02x:%02x:%02x sleep!\n",
+ pAddr[0],pAddr[1],pAddr[2],pAddr[3],pAddr[4],pAddr[5]));
+ }
+
+ if ((old_psmode == PWR_SAVE) && (Psm == PWR_ACTIVE))
+ {
+ /* TODO: For RT2870, how to handle about the BA when STA in PS mode???? */
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("RtmpPsIndicate - %02x:%02x:%02x:%02x:%02x:%02x wakes up, "
+ "act like rx PS-POLL\n",
+ pAddr[0],pAddr[1],pAddr[2],pAddr[3],pAddr[4],pAddr[5]));
+
+ /* sleep station awakes, move all pending frames from PSQ to TXQ if any */
+ RtmpHandleRxPsPoll(pAd, pAddr, pEntry->Aid, TRUE);
+ }
+
+ /* move to above section */
+/* pEntry->NoDataIdleCount = 0; */
+/* pEntry->PsMode = Psm; */
+ }
+/* else */
+/* { */
+ /* not in table, try to learn it ???? why bother? */
+/* } */
+ return old_psmode;
+}
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rt2860.bin.dfs b/cleopatre/devkit/mt7601udrv/common/rt2860.bin.dfs
new file mode 100644
index 0000000000..dcdc97bf98
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rt2860.bin.dfs
Binary files differ
diff --git a/cleopatre/devkit/mt7601udrv/common/rt2860.bin.old b/cleopatre/devkit/mt7601udrv/common/rt2860.bin.old
new file mode 100644
index 0000000000..5a058e1455
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rt2860.bin.old
Binary files differ
diff --git a/cleopatre/devkit/mt7601udrv/common/rt2870_wow.bin b/cleopatre/devkit/mt7601udrv/common/rt2870_wow.bin
new file mode 100644
index 0000000000..bfae0f0ab0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rt2870_wow.bin
Binary files differ
diff --git a/cleopatre/devkit/mt7601udrv/common/rt_channel.c b/cleopatre/devkit/mt7601udrv/common/rt_channel.c
new file mode 100644
index 0000000000..52b241bf29
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rt_channel.c
@@ -0,0 +1,2057 @@
+/*
+
+*/
+#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
+
+/*Albania*/
+CH_DESP Country_AL_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Algeria*/
+CH_DESP Country_DZ_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Argentina*/
+CH_DESP Country_AR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Armenia*/
+CH_DESP Country_AM_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 18, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 18, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Aruba*/
+CH_DESP Country_AW_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Australia*/
+CH_DESP Country_AU_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Austria*/
+CH_DESP Country_AT_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Azerbaijan*/
+CH_DESP Country_AZ_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 18, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 18, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Bahrain*/
+CH_DESP Country_BH_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 149, 5, 20, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Bangladesh*/
+CH_DESP Country_BD_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Barbados*/
+CH_DESP Country_BB_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Belarus*/
+CH_DESP Country_BY_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Belgium*/
+CH_DESP Country_BE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Belize*/
+CH_DESP Country_BZ_ChDesp[] =
+{
+ { 1, 13, 30, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Bolivia*/
+CH_DESP Country_BO_ChDesp[] =
+{
+ { 1, 13, 30, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Bosnia and Herzegovina*/
+CH_DESP Country_BA_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Brazil*/
+CH_DESP Country_BR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Brunei Darussalam*/
+CH_DESP Country_BN_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Bulgaria*/
+CH_DESP Country_BG_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 2, 23, BOTH, TRUE}, /*5250~5290MHz, Ch 52~56, Max BW: 40 */
+ { 100, 11, 30, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Cambodia*/
+CH_DESP Country_KH_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Canada*/
+CH_DESP Country_CA_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Chile*/
+CH_DESP Country_CL_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 20, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*China*/
+CH_DESP Country_CN_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Colombia*/
+CH_DESP Country_CO_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Costa Rica*/
+CH_DESP Country_CR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Croatia*/
+CH_DESP Country_HR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Cyprus*/
+CH_DESP Country_CY_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Czech Republic*/
+CH_DESP Country_CZ_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2400~2483.5MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, IDOR, FALSE}, /*5150~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5350MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5470~5725MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Denmark*/
+CH_DESP Country_DK_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Dominican Republic*/
+CH_DESP Country_DO_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Ecuador*/
+CH_DESP Country_EC_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Egypt*/
+CH_DESP Country_EG_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*El Salvador*/
+CH_DESP Country_SV_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Estonia*/
+CH_DESP Country_EE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Finland*/
+CH_DESP Country_FI_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*France*/
+CH_DESP Country_FR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Georgia*/
+CH_DESP Country_GE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 18, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 18, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Germany*/
+CH_DESP Country_DE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2400~2483.5MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5150~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5350MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5470~5725MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Greece*/
+CH_DESP Country_GR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Greenland*/
+CH_DESP Country_GL_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Grenada*/
+CH_DESP Country_GD_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Guam*/
+CH_DESP Country_GU_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Guatemala*/
+CH_DESP Country_GT_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Haiti*/
+CH_DESP Country_HT_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Honduras*/
+CH_DESP Country_HN_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Hong Kong*/
+CH_DESP Country_HK_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Hungary*/
+CH_DESP Country_HU_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Iceland*/
+CH_DESP Country_IS_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*India*/
+CH_DESP Country_IN_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 20, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Indonesia*/
+CH_DESP Country_ID_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Iran, Islamic Republic of*/
+CH_DESP Country_IR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Ireland*/
+CH_DESP Country_IE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Israel*/
+CH_DESP Country_IL_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, IDOR, FALSE}, /*5150~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, IDOR, TRUE}, /*5250~5350MHz, Ch 52~64, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Italy*/
+CH_DESP Country_IT_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Jamaica*/
+CH_DESP Country_JM_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Japan*/
+CH_DESP Country_JP_ChDesp[] =
+{
+ { 1, 14, 20, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 20 */
+ /*2457~2482MHz, Ch10~13, Max BW: 20 */
+ /*2474~2494MHz, Ch14, Max BW: 20, No OFDM */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 23, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Jordan*/
+CH_DESP Country_JO_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 18, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Kazakhstan*/
+CH_DESP Country_KZ_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Kenya*/
+CH_DESP Country_KE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Korea, Democratic People's Republic of*/
+CH_DESP Country_KP_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, TRUE}, /*5160~5250MHz, Ch 36~48, Max BW: 40 */
+ { 36, 8, 20, BOTH, FALSE}, /*5170~5330MHz, Ch 36~64, Max BW: 40 */
+ { 100, 7, 30, BOTH, TRUE}, /*5490~5630MHz, Ch 100~124, Max BW: 40 */
+ { 149, 4, 30, BOTH, FALSE}, /*5735~5815MHz, Ch 149~161, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Korea, Republic of*/
+CH_DESP Country_KR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 20 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 100, 7, 30, BOTH, TRUE}, /*5490~5630MHz, Ch 100~124, Max BW: 40 */
+ { 149, 4, 30, BOTH, FALSE}, /*5735~5815MHz, Ch 149~161, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Kuwait*/
+CH_DESP Country_KW_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Latvia*/
+CH_DESP Country_LV_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Lebanon*/
+CH_DESP Country_LB_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Liechtenstein*/
+CH_DESP Country_LI_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Lithuania*/
+CH_DESP Country_LT_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Luxembourg*/
+CH_DESP Country_LU_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Macao*/
+CH_DESP Country_MO_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Macedonia, Republic of*/
+CH_DESP Country_MK_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Malaysia*/
+CH_DESP Country_MY_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 52, 4, 30, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Malta*/
+CH_DESP Country_MT_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Mexico*/
+CH_DESP Country_MX_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Monaco*/
+CH_DESP Country_MC_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 18, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 18, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Morocco*/
+CH_DESP Country_MA_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Nepal*/
+CH_DESP Country_NP_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Netherlands*/
+CH_DESP Country_NL_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Netherlands Antilles*/
+CH_DESP Country_AN_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*New Zealand*/
+CH_DESP Country_NZ_ChDesp[] =
+{
+ { 1, 13, 30, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Norway*/
+CH_DESP Country_NO_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Oman*/
+CH_DESP Country_OM_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Pakistan*/
+CH_DESP Country_PK_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Panama*/
+CH_DESP Country_PA_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Papua New Guinea*/
+CH_DESP Country_PG_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Peru*/
+CH_DESP Country_PE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Philippines*/
+CH_DESP Country_PH_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Poland*/
+CH_DESP Country_PL_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Portuga*/
+CH_DESP Country_PT_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Puerto Rico*/
+CH_DESP Country_PR_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Qatar*/
+CH_DESP Country_QA_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Romania*/
+CH_DESP Country_RO_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Russian Federation*/
+CH_DESP Country_RU_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Saint Barth'elemy*/
+CH_DESP Country_BL_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 18, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 18, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Saudi Arabia*/
+CH_DESP Country_SA_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 23, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 23, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Singapore*/
+CH_DESP Country_SG_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 149, 5, 20, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Slovakia*/
+CH_DESP Country_SK_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Slovenia*/
+CH_DESP Country_SI_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*South Africa*/
+CH_DESP Country_ZA_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Spain*/
+CH_DESP Country_ES_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Sri Lanka*/
+CH_DESP Country_LK_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 20 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Sweden*/
+CH_DESP Country_SE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Switzerland*/
+CH_DESP Country_CH_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Syrian Arab Republic*/
+CH_DESP Country_SY_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Taiwan*/
+CH_DESP Country_TW_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 56, 3, 17, IDOR, TRUE}, /*5270~5330MHz, Ch 56~64, Max BW: 40 */
+ { 149, 4, 30, BOTH, FALSE}, /*5735~5815MHz, Ch 149~161, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Thailand*/
+CH_DESP Country_TH_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Trinidad and Tobago*/
+CH_DESP Country_TT_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Tunisia*/
+CH_DESP Country_TN_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Turkey*/
+CH_DESP Country_TR_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 20 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 20 */
+ { 0}, /* end*/
+};
+/*Ukraine*/
+CH_DESP Country_UA_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*United Arab Emirates*/
+CH_DESP Country_AE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*United Kingdom*/
+CH_DESP Country_GB_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, IDOR, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 27, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*United States*/
+CH_DESP Country_US_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, IDOR, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 5, 20, BOTH, TRUE}, /*5490~5600MHz, Ch 100~116, Max BW: 40 */
+ { 132, 3, 20, BOTH, TRUE}, /*5650~5710MHz, Ch 132~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Uruguay*/
+CH_DESP Country_UY_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Uzbekistan*/
+CH_DESP Country_UZ_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /*2402~2472MHz, Ch 1~11, Max BW: 40 */
+ { 36, 4, 17, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 100, 11, 20, BOTH, TRUE}, /*5490~5710MHz, Ch 100~140, Max BW: 40 */
+ { 149, 5, 30, BOTH, FALSE}, /*5735~5835MHz, Ch 149~165, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Venezuela*/
+CH_DESP Country_VE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 149, 4, 23, BOTH, FALSE}, /*5735~5815MHz, Ch 149~161, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Viet Nam*/
+CH_DESP Country_VN_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 36, 4, 20, BOTH, FALSE}, /*5170~5250MHz, Ch 36~48, Max BW: 40 */
+ { 52, 4, 20, BOTH, TRUE}, /*5250~5330MHz, Ch 52~64, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Yemen*/
+CH_DESP Country_YE_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+/*Zimbabwe*/
+CH_DESP Country_ZW_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /*2402~2482MHz, Ch 1~13, Max BW: 40 */
+ { 0}, /* end*/
+};
+
+/* Group Region */
+/*Europe*/
+CH_DESP Country_EU_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13 */
+ { 36, 4, 17, BOTH, FALSE}, /* 5G band 1, ch 36~48*/
+ { 0}, /* end*/
+};
+/*North America*/
+CH_DESP Country_NA_ChDesp[] =
+{
+ { 1, 11, 27, BOTH, FALSE}, /* 2.4 G, ch 1~11*/
+ { 36, 4, 17, IDOR, FALSE}, /* 5G band 1, ch 36~48*/
+ { 149, 5, 30, BOTH, FALSE}, /* 5G band 4, ch 149~165*/
+ { 0}, /* end*/
+};
+/*World Wide*/
+CH_DESP Country_WO_ChDesp[] =
+{
+ { 1, 13, 20, BOTH, FALSE}, /* 2.4 G, ch 1~13*/
+ { 36, 4, 17, BOTH, FALSE}, /* 5G band 1, ch 36~48*/
+ { 149, 5, 22, BOTH, FALSE}, /* 5G band 4, ch 149~165*/
+ { 0}, /* end*/
+};
+
+CH_REGION ChRegion[] =
+{
+ {"AL", CE, Country_AL_ChDesp}, /* Albania */
+ {"DZ", CE, Country_DZ_ChDesp}, /* Algeria */
+ {"AR", CE, Country_AR_ChDesp}, /* Argentina */
+ {"AM", CE, Country_AM_ChDesp}, /* Armenia */
+ {"AW", CE, Country_AW_ChDesp}, /* Aruba */
+ {"AU", CE, Country_AU_ChDesp}, /* Australia */
+ {"AT", CE, Country_AT_ChDesp}, /* Austria */
+ {"AZ", CE, Country_AZ_ChDesp}, /* Azerbaijan */
+ {"BH", CE, Country_BH_ChDesp}, /* Bahrain */
+ {"BD", CE, Country_BD_ChDesp}, /* Bangladesh */
+ {"BB", CE, Country_BB_ChDesp}, /* Barbados */
+ {"BY", CE, Country_BY_ChDesp}, /* Belarus */
+ {"BE", CE, Country_BE_ChDesp}, /* Belgium */
+ {"BZ", CE, Country_BZ_ChDesp}, /* Belize */
+ {"BO", CE, Country_BO_ChDesp}, /* Bolivia */
+ {"BA", CE, Country_BA_ChDesp}, /* Bosnia and Herzegovina */
+ {"BR", CE, Country_BR_ChDesp}, /* Brazil */
+ {"BN", CE, Country_BN_ChDesp}, /* Brunei Darussalam */
+ {"BG", CE, Country_BG_ChDesp}, /* Bulgaria */
+ {"KH", CE, Country_KH_ChDesp}, /* Cambodia */
+ {"CA", FCC,Country_CA_ChDesp}, /* Canada */
+ {"CL", CE, Country_CL_ChDesp}, /* Chile */
+ {"CN", CE, Country_CN_ChDesp}, /* China */
+ {"CO", CE, Country_CO_ChDesp}, /* Colombia */
+ {"CR", CE, Country_CR_ChDesp}, /* Costa Rica */
+ {"HR", CE, Country_HR_ChDesp}, /* Croatia */
+ {"CY", CE, Country_CY_ChDesp}, /* Cyprus */
+ {"CZ", CE, Country_CZ_ChDesp}, /* Czech Republic */
+ {"DK", CE, Country_DK_ChDesp}, /* Denmark */
+ {"DO", CE, Country_DO_ChDesp}, /* Dominican Republic */
+ {"EC", CE, Country_EC_ChDesp}, /* Ecuador */
+ {"EG", CE, Country_EG_ChDesp}, /* Egypt */
+ {"SV", CE, Country_SV_ChDesp}, /* El Salvador */
+ {"EE", CE, Country_EE_ChDesp}, /* Estonia */
+ {"FI", CE, Country_FI_ChDesp}, /* Finland */
+ {"FR", CE, Country_FR_ChDesp}, /* France */
+ {"GE", CE, Country_GE_ChDesp}, /* Georgia */
+ {"DE", CE, Country_DE_ChDesp}, /* Germany */
+ {"GR", CE, Country_GR_ChDesp}, /* Greece */
+ {"GL", CE, Country_GL_ChDesp}, /* Greenland */
+ {"GD", CE, Country_GD_ChDesp}, /* Grenada */
+ {"GU", CE, Country_GU_ChDesp}, /* Guam */
+ {"GT", CE, Country_GT_ChDesp}, /* Guatemala */
+ {"HT", CE, Country_HT_ChDesp}, /* Haiti */
+ {"HN", CE, Country_HN_ChDesp}, /* Honduras */
+ {"HK", CE, Country_HK_ChDesp}, /* Hong Kong */
+ {"HU", CE, Country_HU_ChDesp}, /* Hungary */
+ {"IS", CE, Country_IS_ChDesp}, /* Iceland */
+ {"IN", CE, Country_IN_ChDesp}, /* India */
+ {"ID", CE, Country_ID_ChDesp}, /* Indonesia */
+ {"IR", CE, Country_IR_ChDesp}, /* Iran, Islamic Republic of */
+ {"IE", CE, Country_IE_ChDesp}, /* Ireland */
+ {"IL", CE, Country_IL_ChDesp}, /* Israel */
+ {"IT", CE, Country_IT_ChDesp}, /* Italy */
+ {"JM", CE, Country_JM_ChDesp}, /* Jamaica */
+ {"JP", JAP,Country_JP_ChDesp}, /* Japan */
+ {"JO", CE, Country_JO_ChDesp}, /* Jordan */
+ {"KZ", CE, Country_KZ_ChDesp}, /* Kazakhstan */
+ {"KE", CE, Country_KE_ChDesp}, /* Kenya */
+ {"KP", CE, Country_KP_ChDesp}, /* Korea, Democratic People's Republic of */
+ {"KR", CE, Country_KR_ChDesp}, /* Korea, Republic of */
+ {"KW", CE, Country_KW_ChDesp}, /* Kuwait */
+ {"LV", CE, Country_LV_ChDesp}, /* Latvia */
+ {"LB", CE, Country_LB_ChDesp}, /* Lebanon */
+ {"LI", CE, Country_LI_ChDesp}, /* Liechtenstein */
+ {"LT", CE, Country_LT_ChDesp}, /* Lithuania */
+ {"LU", CE, Country_LU_ChDesp}, /* Luxembourg */
+ {"MO", CE, Country_MO_ChDesp}, /* Macao */
+ {"MK", CE, Country_MK_ChDesp}, /* Macedonia, Republic of */
+ {"MY", CE, Country_MY_ChDesp}, /* Malaysia */
+ {"MT", CE, Country_MT_ChDesp}, /* Malta */
+ {"MX", CE, Country_MX_ChDesp}, /* Mexico */
+ {"MC", CE, Country_MC_ChDesp}, /* Monaco */
+ {"MA", CE, Country_MA_ChDesp}, /* Morocco */
+ {"NP", CE, Country_NP_ChDesp}, /* Nepal */
+ {"NL", CE, Country_NL_ChDesp}, /* Netherlands */
+ {"AN", CE, Country_AN_ChDesp}, /* Netherlands Antilles */
+ {"NZ", CE, Country_NZ_ChDesp}, /* New Zealand */
+ {"NO", CE, Country_NO_ChDesp}, /* Norway */
+ {"OM", CE, Country_OM_ChDesp}, /* Oman */
+ {"PK", CE, Country_PK_ChDesp}, /* Pakistan */
+ {"PA", CE, Country_PA_ChDesp}, /* Panama */
+ {"PG", CE, Country_PG_ChDesp}, /* Papua New Guinea */
+ {"PE", CE, Country_PE_ChDesp}, /* Peru */
+ {"PH", CE, Country_PH_ChDesp}, /* Philippines */
+ {"PL", CE, Country_PL_ChDesp}, /* Poland */
+ {"PT", CE, Country_PT_ChDesp}, /* Portuga l*/
+ {"PR", CE, Country_PR_ChDesp}, /* Puerto Rico */
+ {"QA", CE, Country_QA_ChDesp}, /* Qatar */
+ {"RO", CE, Country_RO_ChDesp}, /* Romania */
+ {"RU", CE, Country_RU_ChDesp}, /* Russian Federation */
+ {"BL", CE, Country_BL_ChDesp}, /* Saint Barth'elemy */
+ {"SA", CE, Country_SA_ChDesp}, /* Saudi Arabia */
+ {"SG", CE, Country_SG_ChDesp}, /* Singapore */
+ {"SK", CE, Country_SK_ChDesp}, /* Slovakia */
+ {"SI", CE, Country_SI_ChDesp}, /* Slovenia */
+ {"ZA", CE, Country_ZA_ChDesp}, /* South Africa */
+ {"ES", CE, Country_ES_ChDesp}, /* Spain */
+ {"LK", CE, Country_LK_ChDesp}, /* Sri Lanka */
+ {"SE", CE, Country_SE_ChDesp}, /* Sweden */
+ {"CH", CE, Country_CH_ChDesp}, /* Switzerland */
+ {"SY", CE, Country_SY_ChDesp}, /* Syrian Arab Republic */
+ {"TW", FCC,Country_TW_ChDesp}, /* Taiwan */
+ {"TH", CE, Country_TH_ChDesp}, /* Thailand */
+ {"TT", CE, Country_TT_ChDesp}, /* Trinidad and Tobago */
+ {"TN", CE, Country_TN_ChDesp}, /* Tunisia */
+ {"TR", CE, Country_TR_ChDesp}, /* Turkey */
+ {"UA", CE, Country_UA_ChDesp}, /* Ukraine */
+ {"AE", CE, Country_AE_ChDesp}, /* United Arab Emirates */
+ {"GB", CE, Country_GB_ChDesp}, /* United Kingdom */
+ {"US", FCC,Country_US_ChDesp}, /* United States */
+ {"UY", CE, Country_UY_ChDesp}, /* Uruguay */
+ {"UZ", CE, Country_UZ_ChDesp}, /* Uzbekistan */
+ {"VE", CE, Country_VE_ChDesp}, /* Venezuela */
+ {"VN", CE, Country_VN_ChDesp}, /* Viet Nam */
+ {"YE", CE, Country_YE_ChDesp}, /* Yemen */
+ {"ZW", CE, Country_ZW_ChDesp}, /* Zimbabwe */
+ {"EU", CE, Country_EU_ChDesp}, /* Europe */
+ {"NA", FCC,Country_NA_ChDesp}, /* North America */
+ {"WO", CE, Country_WO_ChDesp}, /* World Wide */
+ {"" , 0, NULL} , /* 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++;
+ }
+
+ /* Default: use WO*/
+ if (pChRegion == NULL)
+ pChRegion = GetChRegion("WO");
+
+ return pChRegion;
+}
+
+static VOID ChBandCheck(
+ IN UCHAR PhyMode,
+ OUT PUCHAR pChType)
+{
+ *pChType = 0;
+ if (WMODE_CAP_5G(PhyMode))
+ *pChType |= BAND_5G;
+ if (WMODE_CAP_2G(PhyMode))
+ *pChType |= BAND_24G;
+
+ if (*pChType == 0)
+ *pChType = BAND_24G;
+}
+
+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;
+ if (!strncmp((PSTRING) pAd->CommonCfg.CountryCode, "JP", 2))
+ {
+ /* for JP, ch14 can only be used when PhyMode is "B only" */
+ if ( (channel==14) &&
+ (!WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B)))
+ {
+ pChDesp->NumOfCh--;
+ break;
+ }
+ }
+/*New FCC spec restrict the used channel under DFS */
+#ifdef CONFIG_AP_SUPPORT
+ if ((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->CommonCfg.RDDurRegion == FCC) &&
+ (pAd->Dot11_H.bDFSIndoor == 1))
+ {
+ if (RESTRICTION_BAND_1(pAd))
+ continue;
+ }
+ else if ((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->CommonCfg.RDDurRegion == FCC) &&
+ (pAd->Dot11_H.bDFSIndoor == 0))
+ {
+ if ((channel >= 100) && (channel <= 140))
+ continue;
+ }
+
+#endif /* CONFIG_AP_SUPPORT */
+ for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
+ {
+ if (channel == pAd->TxPower[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;
+#ifdef DOT11_N_SUPPORT
+ if (N_ChannelGroupCheck(pAd, pAd->ChannelList[j].Channel))
+ pAd->ChannelList[j].Flags |= CHANNEL_40M_CAP;
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef RT_CFG80211_SUPPORT
+ CFG80211OS_ChanInfoInit(
+ pAd->pCfg80211_CB,
+ j,
+ pAd->ChannelList[j].Channel,
+ pAd->ChannelList[j].MaxTxPwr,
+ WMODE_CAP_N(pAd->CommonCfg.PhyMode),
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_20));
+#endif /* RT_CFG80211_SUPPORT */
+
+ 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);
+
+ if (pAd->CommonCfg.pChDesp != NULL)
+ pChDesp = (PCH_DESP) pAd->CommonCfg.pChDesp;
+ else
+ pChDesp = pChRegion->pChDesp;
+
+ for (i = 0; pChDesp[i].FirstChannel != 0; i++)
+ {
+ if (pChDesp[i].FirstChannel == 0)
+ break;
+
+ if (ChType == BAND_5G)
+ {
+ if (pChDesp[i].FirstChannel <= 14)
+ continue;
+ }
+ else if (ChType == BAND_24G)
+ {
+ if (pChDesp[i].FirstChannel > 14)
+ continue;
+ }
+
+ if ((pChDesp[i].Geography == BOTH)
+ || (Geography == BOTH)
+ || (pChDesp[i].Geography == Geography))
+ {
+ if (pChDesp[i].FirstChannel > 14)
+ increment = 4;
+ else
+ increment = 1;
+ if (pAd->CommonCfg.DfsType != MAX_RD_REGION)
+ regulatoryDomain = pAd->CommonCfg.DfsType;
+ else
+ regulatoryDomain = pChRegion->DfsType;
+ offset = FillChList(pAd, &pChDesp[i], 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;
+
+ if (pAd->CommonCfg.pChDesp != NULL)
+ pChDesp = (PCH_DESP) pAd->CommonCfg.pChDesp;
+ else
+ pChDesp = pChRegion->pChDesp;
+
+ for (i=0; pChRegion->pChDesp[i].FirstChannel != 0; i++)
+ {
+ if (pChDesp[i].FirstChannel == 0)
+ break;
+
+ if (ChType == BAND_5G)
+ {
+ if (pChDesp[i].FirstChannel <= 14)
+ continue;
+ }
+ else if (ChType == BAND_24G)
+ {
+ if (pChDesp[i].FirstChannel > 14)
+ continue;
+ }
+
+ if ((pChDesp[i].Geography == BOTH) ||
+ (pChDesp[i].Geography == pAd->CommonCfg.Geography))
+ {
+ MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
+ 1, &pChDesp[i].FirstChannel,
+ 1, &pChDesp[i].NumOfCh,
+ 1, &pChDesp[i].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;
+}
+
+BOOLEAN N_ChannelGroupCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ BOOLEAN RetVal = FALSE;
+
+ 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))
+ {
+ RetVal = TRUE;
+ }
+ else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
+ (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
+ {
+ RetVal = TRUE;
+ }
+ }
+ else
+ {
+ do
+ {
+ UCHAR ExtCh;
+
+ if (Channel == 14)
+ {
+ RetVal = FALSE;
+ break;
+ }
+
+ ExtCh = GetExtCh(Channel, EXTCHA_ABOVE);
+ if (IsValidChannel(pAd, ExtCh))
+ RetVal = TRUE;
+ else
+ {
+ ExtCh = GetExtCh(Channel, EXTCHA_BELOW);
+ if (IsValidChannel(pAd, ExtCh))
+ RetVal = TRUE;
+ }
+ } while(FALSE);
+ }
+
+ return RetVal;
+}
+
+
+VOID N_ChannelCheck(RTMP_ADAPTER *pAd)
+{
+ INT idx;
+ UCHAR Channel = pAd->CommonCfg.Channel;
+ static const UCHAR wfa_ht_ch_ext[] = {
+ 36, EXTCHA_ABOVE, 40, EXTCHA_BELOW,
+ 44, EXTCHA_ABOVE, 48, EXTCHA_BELOW,
+ 52, EXTCHA_ABOVE, 56, EXTCHA_BELOW,
+ 60, EXTCHA_ABOVE, 64, EXTCHA_BELOW,
+ 100, EXTCHA_ABOVE, 104, EXTCHA_BELOW,
+ 108, EXTCHA_ABOVE, 112, EXTCHA_BELOW,
+ 116, EXTCHA_ABOVE, 120, EXTCHA_BELOW,
+ 124, EXTCHA_ABOVE, 128, EXTCHA_BELOW,
+ 132, EXTCHA_ABOVE, 136, EXTCHA_BELOW,
+ 149, EXTCHA_ABOVE, 153, EXTCHA_BELOW,
+ 157, EXTCHA_ABOVE, 161, EXTCHA_BELOW,
+ 0, 0};
+
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (Channel > 14)
+ {
+ idx = 0;
+ while(wfa_ht_ch_ext[idx] != 0) {
+ if (wfa_ht_ch_ext[idx] == Channel) {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = wfa_ht_ch_ext[idx + 1];
+ break;
+ }
+ idx += 2;
+ };
+ if (wfa_ht_ch_ext[idx] == 0)
+ 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()*/
+ }
+ }
+ }
+}
+
+
+UCHAR N_SetCenCh(RTMP_ADAPTER *pAd, UCHAR prim_ch)
+{
+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ pAd->CommonCfg.CentralChannel = prim_ch + 2;
+ else
+ {
+ if (prim_ch == 14)
+ pAd->CommonCfg.CentralChannel = prim_ch - 1;
+ else
+ pAd->CommonCfg.CentralChannel = prim_ch - 2;
+ }
+ }
+ else
+ pAd->CommonCfg.CentralChannel = prim_ch;
+
+ return pAd->CommonCfg.CentralChannel;
+}
+#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 (WMODE_CAP_N(pAd->CommonCfg.PhyMode) && (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 (WMODE_CAP_N(pAd->CommonCfg.PhyMode) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) &&
+ (channel == 1 || channel == 11))
+ return (pAd->ChannelList[i].MaxTxPwr - pAd->CommonCfg.BandedgeDelta - deltaTxStreamPwr);
+ else
+#endif /* DOT11_N_SUPPORT */
+ return (pAd->ChannelList[i].MaxTxPwr - deltaTxStreamPwr);
+ }
+ else if (pAd->ChannelList[i].RegulatoryDomain == CE)
+ {
+ return (pAd->ChannelList[i].MaxTxPwr - pAd->CommonCfg.AntGain - deltaTxStreamPwr);
+ }
+ else
+ return 0xff;
+ }
+ else
+#endif /* SINGLE_SKU */
+ return pAd->ChannelList[i].MaxTxPwr;
+}
+
+
+/* for OS_ABL */
+VOID RTMP_MapChannelID2KHZ(
+ IN UCHAR Ch,
+ OUT UINT32 *pFreq)
+{
+ int chIdx;
+ for (chIdx = 0; chIdx < CH_HZ_ID_MAP_NUM; chIdx++)
+ {
+ if ((Ch) == CH_HZ_ID_MAP[chIdx].channel)
+ {
+ (*pFreq) = CH_HZ_ID_MAP[chIdx].freqKHz * 1000;
+ break;
+ }
+ }
+ if (chIdx == CH_HZ_ID_MAP_NUM)
+ (*pFreq) = 2412000;
+}
+
+/* for OS_ABL */
+VOID RTMP_MapKHZ2ChannelID(
+ IN ULONG Freq,
+ OUT INT *pCh)
+{
+ int chIdx;
+ for (chIdx = 0; chIdx < CH_HZ_ID_MAP_NUM; chIdx++)
+ {
+ if ((Freq) == CH_HZ_ID_MAP[chIdx].freqKHz)
+ {
+ (*pCh) = CH_HZ_ID_MAP[chIdx].channel;
+ break;
+ }
+ }
+ if (chIdx == CH_HZ_ID_MAP_NUM)
+ (*pCh) = 1;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rt_os_util.c b/cleopatre/devkit/mt7601udrv/common/rt_os_util.c
new file mode 100644
index 0000000000..954f64e133
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rt_os_util.c
@@ -0,0 +1,161 @@
+/****************************************************************************
+
+ Module Name:
+ rt_os_util.c
+
+ Abstract:
+ All functions provided from UTIL module are put here (OS independent).
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#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;
+}
+
+
+#if defined(WPA_SUPPLICANT_SUPPORT) || defined(APCLI_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 /* defined(WPA_SUPPLICANT_SUPPORT) || defined(APCLI_WPA_SUPPLICANT_SUPPORT) */
+
+
+
+
+
+
+INT32 RtPrivIoctlSetVal(VOID)
+{
+ return (INT32)RTPRIV_IOCTL_SET;
+}
+
+
+#ifdef RTMP_USB_SUPPORT
+PVOID RtmpInitCompletion(VOID)
+{
+ struct completion *comp = NULL;
+ os_alloc_mem(NULL, (UCHAR **)&comp, sizeof(struct completion));
+ init_completion(comp);
+ return (PVOID)comp;
+}
+
+
+ULONG RtmpWaitForCompletionTimeout(VOID *Completion, ULONG Expire)
+{
+ return wait_for_completion_timeout((struct completion *)Completion, Expire);
+}
+
+
+VOID RtmpComplete(VOID *Completion)
+{
+ complete((struct completion *)Completion);
+}
+#endif /* RTMP_USB_SUPPORT */
+
+ULONG RtmpMsecsToJiffies(UINT32 msecs)
+{
+ return msecs_to_jiffies(msecs);
+}
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rt_rf.c b/cleopatre/devkit/mt7601udrv/common/rt_rf.c
new file mode 100644
index 0000000000..98a02d589a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rt_rf.c
@@ -0,0 +1,33 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_rf.c
+
+ Abstract:
+ Ralink Wireless driver RF related functions
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
+#include "rt_config.h"
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rtmp_init.c b/cleopatre/devkit/mt7601udrv/common/rtmp_init.c
new file mode 100644
index 0000000000..52278f2f38
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rtmp_init.c
@@ -0,0 +1,3849 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_init.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+#include "rt_config.h"
+
+#ifdef OS_ABL_FUNC_SUPPORT
+/* Os utility link: printk, scanf */
+RTMP_OS_ABL_OPS RaOsOps, *pRaOsOps = &RaOsOps;
+#endif /* OS_ABL_FUNC_SUPPORT */
+
+#define RT3090A_DEFAULT_INTERNAL_LNA_GAIN 0x0A
+UCHAR NUM_BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+#ifdef DBG
+char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128","CKIP152","SMS4"};
+#endif
+
+
+/*
+ ASIC register initialization sets
+*/
+RTMP_REG_PAIR MACRegTable[] = {
+#ifndef MT7601
+#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 */
+#endif /* MT7601 */
+
+ {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.*/
+#ifndef MT7601
+ {LED_CFG, 0x7f031e46}, /* Gary, 2006-08-23*/
+#endif /* MT7601 */
+
+#ifdef RLT_MAC
+
+#ifdef MT7601
+#ifdef CONFIG_MULTI_CHANNEL
+ {TX_MAX_PCNT, 0x1f1f1f1f/*0x1fbf1f1f */},
+#else
+ {TX_MAX_PCNT, 0x1fbf1f1f},
+#endif /* CONFIG_MULTI_CHANNEL */
+ {RX_MAX_PCNT, 0x9f},
+#else
+ {TX_MAX_PCNT, 0xbfbf3f1f},
+ {RX_MAX_PCNT, 0x9f},
+#endif
+
+// TODO: shiang-6590, need set this in FPGA mode
+#ifdef RTMP_MAC_USB
+#endif /* RTMP_MAC_USB */
+#else
+#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 */
+#endif /* RLT_MAC */
+
+ /*{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
+#ifndef MT7601
+ {PBF_CFG, 0xf40006}, /* Only enable Queue 2*/
+ {WPDMA_GLO_CFG, 0x00000030}, // MT7601U not support WPDMA
+#endif /* MT7601 */
+ {MM40_PROT_CFG, 0x3F44084}, /* Initial Auto_Responder, because QA will turn off Auto-Responder*/
+#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, 0x01092b20}, // enable RTS fall back
+
+ {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},
+#if defined(RT65xx) || defined(MT7601)
+ {PWR_PIN_CFG, 0x00000000},
+#else
+ {PWR_PIN_CFG, 0x00000003}, /* patch for 2880-E*/
+#endif /* defined(RT65xx) || defined(MT7601) */
+};
+
+#ifdef CONFIG_AP_SUPPORT
+RTMP_REG_PAIR APMACRegTable[] = {
+ {WMM_AIFSN_CFG, 0x00001173},
+ {WMM_CWMIN_CFG, 0x00002344},
+ {WMM_CWMAX_CFG, 0x000034a6},
+ {WMM_TXOP0_CFG, 0x00100020},
+ {WMM_TXOP1_CFG, 0x002F0038},
+ {TBTT_SYNC_CFG, 0x00012000},
+#ifdef STREAM_MODE_SUPPORT
+ {TX_CHAIN_ADDR0_L, 0xFFFFFFFF}, /* Broadcast frames are in stream mode*/
+ {TX_CHAIN_ADDR0_H, 0x3FFFF},
+#endif /* STREAM_MODE_SUPPORT */
+};
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
+#ifdef CONFIG_AP_SUPPORT
+#define NUM_AP_MAC_REG_PARMS (sizeof(APMACRegTable) / sizeof(RTMP_REG_PAIR))
+#endif /* CONFIG_AP_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);
+
+ pAd->OS_Cookie = handle;
+#ifdef WORKQUEUE_BH
+ ((POS_COOKIE)(handle))->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);
+
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+
+ for (index =0 ; index < NUM_OF_TX_RING; index++)
+ {
+ NdisAllocateSpinLock(pAd, &pAd->TxSwQueueLock[index]);
+ NdisAllocateSpinLock(pAd, &pAd->DeQueueLock[index]);
+ pAd->DeQueueRunning[index] = FALSE;
+ }
+
+#ifdef RESOURCE_PRE_ALLOC
+ /*
+ move this function from rt28xx_init() to here. now this function only allocate memory and
+ leave the initialization job to RTMPInitTxRxRingMemory() which called in rt28xx_init().
+ */
+ Status = RTMPAllocTxRxRingMemory(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("Failed to allocate memory - TxRxRing\n"));
+ break;
+ }
+#endif /* RESOURCE_PRE_ALLOC */
+
+ NdisAllocateSpinLock(pAd, &pAd->irq_lock);
+
+
+ NdisAllocateSpinLock(pAd, &TimerSemLock);
+
+
+
+#ifdef RALINK_ATE
+#ifdef RTMP_MAC_USB
+ RTMP_OS_ATMOIC_INIT(&pAd->BulkOutRemained, &pAd->RscAtomicMemList);
+ RTMP_OS_ATMOIC_INIT(&pAd->BulkInRemained, &pAd->RscAtomicMemList);
+#endif /* RTMP_MAC_USB */
+#endif /* RALINK_ATE */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef UAPSD_SUPPORT
+/* UAPSD_Init(pAd); move to rt28xx_init*/
+#endif /* UAPSD_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* assign function pointers*/
+#ifdef MAT_SUPPORT
+ /* init function pointers, used in OS_ABL */
+/* RTMP_MATOpsInit(pAd); move to rt28xx_init*/
+#endif /* MAT_SUPPORT */
+ } 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 parameters from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID NICReadEEPROMParameters(RTMP_ADAPTER *pAd, PSTRING mac_addr)
+{
+ 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"));
+
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ RT3290_eeprom_access_grant(pAd, TRUE);
+#endif /* RT3290 */
+
+ if (pAd->chipOps.eeinit)
+ {
+ pAd->chipOps.eeinit(pAd);
+#ifdef RTMP_EFUSE_SUPPORT
+#ifdef RALINK_ATE
+ if(!pAd->bFroceEEPROMBuffer && pAd->bEEPROMFile)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("--> NICReadEEPROMParameters::(Efuse)Load to EEPROM Buffer Mode\n"));
+ eFuseLoadEEPROM(pAd);
+ }
+#endif /* RALINK_ATE */
+#endif /* RTMP_EFUSE_SUPPORT */
+ }
+
+ /* 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; j<MAC_ADDR_LEN; j++)
+ {
+ AtoH(macptr, &pAd->CurrentAddress[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);
+
+#ifdef HDR_TRANS_SUPPORT
+ RTMP_IO_WRITE32(pAd, HT_MAC_ADDR_DW0, csr2.word);
+ csr3.word &= 0xff00ffff;
+ csr3.word |= 0x00410000; // HW test code
+ RTMP_IO_WRITE32(pAd, HT_MAC_ADDR_DW1, csr3.word);
+#endif /* HDR_TRANS_SUPPORT */
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("Current MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+ PRINT_MAC(pAd->CurrentAddress)));
+
+ /* 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));
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ if (Version.field.Version > MT7601_VALID_EEPROM_VERSION)
+ {
+ DBGPRINT_ERR(("MT7601 E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, MT7601_VALID_EEPROM_VERSION));
+ }
+
+ }
+ else
+#endif /* MT7601 */
+ 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;
+
+ /* if not return early. cause fail at emulation.*/
+ /* Init the channel number for TX channel power*/
+#ifdef RT8592
+ if (IS_RT8592(pAd))
+ RT85592_ReadChannelPwr(pAd);
+ else
+#endif /* RT8592 */
+#ifdef RT65xx
+ if (IS_RT6590(pAd))
+ RT6590_ReadChannelPwr(pAd);
+ else
+#endif /* RT65xx */
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ MT7601_ReadChannelPwr(pAd);
+ else
+#endif /* MT7601 */
+ RTMPReadChannelPwr(pAd);
+
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_COUNTRY_REGION, value); /* Country Region*/
+ pAd->EEPROMDefaultValue[EEPROM_COUNTRY_REG_OFFSET] = value;
+ }
+
+#if defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290)
+ RT28xx_EEPROM_READ16(pAd, EEPROM_NIC3_OFFSET, value);
+ pAd->EEPROMDefaultValue[EEPROM_NIC_CFG3_OFFSET] = value;
+ pAd->NicConfig3.word = pAd->EEPROMDefaultValue[EEPROM_NIC_CFG3_OFFSET];
+#endif /* defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290) */
+
+// TODO: check this after receive TC6008 EEPROM format
+#if !defined(RT65xx) && !defined(MT7601)
+ 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;
+ }
+#endif /* !defined(RT65xx) && !defined(MT7601) */
+
+ /* 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];
+
+#ifdef RT65xx
+ if (IS_RT8592(pAd)) {
+ DBGPRINT(RT_DEBUG_OFF, ("RT85592: Antenna.RfIcType=%d, TxPath=%d, RxPath=%d\n",
+ Antenna.field.RfIcType, Antenna.field.TxPath, Antenna.field.RxPath));
+ // TODO: fix me!!
+ Antenna.word = 0;
+ Antenna.field.BoardType = 0;
+ Antenna.field.RfIcType = 0xf;
+ Antenna.field.TxPath = 2;
+ Antenna.field.RxPath = 2;
+ }
+ else if (IS_RT65XX(pAd)) {
+ // TODO: shiang-6590, now we force the ant as 1*1, remove it after EEPROM is ready!
+ Antenna.word = 0;
+ Antenna.field.BoardType = 0;
+ Antenna.field.RfIcType = 0xf;
+ Antenna.field.TxPath = 1;
+ Antenna.field.RxPath = 1;
+ }
+#endif /* RT65xx */
+
+ /* must be put here, because RTMP_CHIP_ANTENNA_INFO_DEFAULT_RESET() will clear *
+ * EPROM 0x34~3 */
+#ifdef TXRX_SW_ANTDIV_SUPPORT
+ /* EEPROM 0x34[15:12] = 0xF is invalid, 0x2~0x3 is TX/RX SW AntDiv */
+ if (((Antenna.word & 0xFF00) != 0xFF00) && (Antenna.word & 0x2000))
+ {
+ pAd->chipCap.bTxRxSwAntDiv = TRUE; /* for GPIO switch */
+ DBGPRINT(RT_DEBUG_OFF, ("\x1b[mAntenna word %X/%d, AntDiv %d\x1b[m\n",
+ Antenna.word, Antenna.field.BoardType, pAd->NicConfig2.field.AntDiversity));
+ }
+#endif /* TXRX_SW_ANTDIV_SUPPORT */
+
+
+ // TODO: shiang, why we only check oxff00??
+ if ((Antenna.word & 0xFF00) == 0xFF00)
+/* 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 WSC_INCLUDED
+ /* WSC hardware push button function 0811 */
+ //if ((pAd->MACVersion == 0x28600100) || (pAd->MACVersion == 0x28700100))
+ WSC_HDR_BTN_MR_HDR_SUPPORT_SET(pAd, NicConfig2.field.EnableWPSPBC);
+#endif /* WSC_INCLUDED */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (NicConfig2.word == 0xffff)
+ NicConfig2.word = 0;
+ }
+#endif /* CONFIG_AP_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;
+
+#ifdef RT65xx
+ // TODO: shiang-6590, currently we don't have eeprom value, so directly force to set it as 0xff
+ if (IS_RT8592(pAd)) {
+ pAd->Mlme.RealRxPath = 2;
+ pAd->RfIcType = RFIC_UNKNOWN;
+ }
+ else if (IS_RT65XX(pAd)) {
+ pAd->Mlme.RealRxPath = 1;
+ pAd->RfIcType = RFIC_UNKNOWN;
+ }
+#endif /* RT65xx */
+
+ /* check if the chip supports 5G band */
+ if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ {
+ if (!RFIC_IS_5G_BAND(pAd))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,
+ ("%s():Err! chip not support 5G band %d!\n",
+ __FUNCTION__, 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 */
+ pAd->RFICType = RFIC_24GHZ;
+ }
+ pAd->RFICType = RFIC_24GHZ | RFIC_5GHZ;
+ }
+ else
+ pAd->RFICType = RFIC_24GHZ;
+
+ RTMP_NET_DEV_NICKNAME_INIT(pAd);
+
+#ifdef RT65xx
+ if (IS_RT6590(pAd))
+ {
+ ; // TODO: wait TC6008 EEPROM format
+ }
+ else
+#endif /* RT65xx */
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ ; // move to MT7601_InitDesiredTSSITable
+ }
+ else
+#endif /* MT7601 */
+ /* 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));
+ }
+
+#ifdef RT65xx
+ if (IS_RT6590(pAd))
+ {
+ ; // TODO: wait TC6008 EEPROM format
+ }
+ else
+#endif /* RT65xx */
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ ; // MT7601 not support A Band
+ }
+ else
+#endif /* MT7601 */
+ /* 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;
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET_COMPERSATION, value);
+ value = (value >> 8) & 0xFF;
+ if ( value != 0xFF )
+ {
+ if ( value & 0x80 )
+ pAd->RfFreqOffset -= (value & 0x7F);
+ else
+ pAd->RfFreqOffset += value;
+ }
+
+ }
+#endif /* MT7601 */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
+
+ // 40M BW in 2.4GHz band (37h)
+ if ( pAd->NicConfig2.field.BW40MAvailForG )
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: BW_20\n"));
+ }
+
+ /*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->BGRssiOffset[0] = value & 0x00ff;
+ pAd->BGRssiOffset[1] = (value >> 8);
+ }
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ ; // MT7601 not support BGRssiOffset[2]
+ }
+ else
+#endif /* MT7601 */
+ {
+ 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->BGRssiOffset[2] = value & 0x00ff;
+ pAd->ALNAGain1 = (value >> 8);
+ }
+
+#ifdef RT65xx
+ if (IS_RT6590(pAd))
+ {
+ /*
+ MT7650 E1 doesn't support external LNA.
+ 2012/04/12
+ */
+ ; // TODO: wait TC6008 EEPROM format
+ }
+ else
+#endif /* RT65xx */
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
+ pAd->BLNAGain = value & 0x00ff;
+ pAd->ALNAGain0 = (value >> 8);
+ }
+
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ ; // MT7601 not support A Band
+ }
+ else
+#endif /* MT7601 */
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
+ pAd->ARssiOffset[0] = value & 0x00ff;
+ pAd->ARssiOffset[1] = (value >> 8);
+ }
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ ; // MT7601 not support A Band
+ }
+ else
+#endif /* MT7601 */
+ {
+ RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
+ pAd->ARssiOffset[2] = 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/b/g RSSI 0/1/2 offset.*/
+ for (i =0 ; i < 3; i++)
+ {
+ if ((pAd->BGRssiOffset[i] < -10) || (pAd->BGRssiOffset[i] > 10))
+ pAd->BGRssiOffset[i] = 0;
+
+ if ((pAd->ARssiOffset[i] < -10) || (pAd->ARssiOffset[i] > 10))
+ pAd->ARssiOffset[i] = 0;
+ }
+
+
+#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);
+ }
+
+ /*
+ Some dongle has old EEPROM value, use ModuleTxpower for saving correct value fo DefineMaxTxPwr.
+ ModuleTxpower will override DefineMaxTxPwr (value from EEPROM) if ModuleTxpower is not zero.
+ */
+ if (pAd->CommonCfg.ModuleTxpower > 0)
+ pAd->CommonCfg.DefineMaxTxPwr = pAd->CommonCfg.ModuleTxpower;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("TX Power set for SINGLE SKU MODE is : 0x%04x \n", pAd->CommonCfg.DefineMaxTxPwr));
+
+ pAd->CommonCfg.bSKUMode = FALSE;
+ if ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF) <= 0x50)
+ {
+ if (IS_RT3883(pAd))
+ pAd->CommonCfg.bSKUMode = TRUE;
+ else if ((pAd->CommonCfg.AntGain > 0) && (pAd->CommonCfg.BandedgeDelta >= 0))
+ pAd->CommonCfg.bSKUMode = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Single SKU Mode is %s\n",
+ pAd->CommonCfg.bSKUMode ? "Enable" : "Disable"));
+#endif /* SINGLE_SKU */
+
+#ifdef SINGLE_SKU_V2
+ InitSkuRateDiffTable(pAd);
+#endif /* SINGLE_SKU_V2 */
+
+
+#ifdef RTMP_INTERNAL_TX_ALC
+#ifdef RT65xx
+ if (IS_RT6590(pAd))
+ {
+ ; // TODO: wait TC6008 EEPROM format
+ }
+ else
+#endif /* RT65xx */
+ {
+ /*
+ 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_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 */
+
+
+
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ RT3290_eeprom_access_grant(pAd, FALSE);
+#endif /* RT3290 */
+
+ 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)
+{
+ USHORT i;
+#ifdef RALINK_ATE
+ USHORT value;
+#endif /* RALINK_ATE */
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
+
+#if !defined(RT65xx) && !defined(MT7601)
+ 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);
+ }
+ }
+#endif /* #if !defined(RT65xx) && !defined(MT7601) */
+
+ NicConfig2.word = pAd->NicConfig2.word;
+
+ /* finally set primary ant */
+ AntCfgInit(pAd);
+
+ RTMP_CHIP_ASIC_INIT_TEMPERATURE_COMPENSATION(pAd);
+
+ if (pAd->chipOps.AsicRfInit)
+ pAd->chipOps.AsicRfInit(pAd);
+
+
+#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_TX_ALC.
+ */
+
+ /* Internal Tx ALC */
+ if (((NicConfig2.field.DynamicTxAgcControl == 1) &&
+ (NicConfig2.field.bInternalTxALC == 1)) ||
+ ((!IS_RT3390(pAd)) && (!IS_RT3350(pAd)) &&
+ (!IS_RT3352(pAd)) && (!IS_RT5350(pAd)) && (!IS_RT5390(pAd)) && (!IS_RT3290(pAd)) && (!IS_MT7601(pAd))))
+ {
+ /*
+ If both DynamicTxAgcControl and bInternalTxALC are enabled,
+ it is a wrong configuration.
+ If the chipset does not support Internal TX 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 //
+
+ rtmp_bbp_set_rxpath(pAd, pAd->Antenna.field.RxPath);
+
+
+ RTMP_EEPROM_ASIC_INIT(pAd);
+
+
+ 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"));
+}
+
+
+#ifdef DBG
+VOID dump_pdma_reg(RTMP_ADAPTER *pAd)
+{
+
+
+}
+#endif /* DBG */
+
+
+
+
+VOID AsicInitBcnBuf(IN RTMP_ADAPTER *pAd)
+{
+ int idx;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+
+ for (idx = 0; idx < pChipCap->BcnMaxHwNum; idx++)
+ pAd->BeaconOffset[idx] = pChipCap->BcnBase[idx];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("< Beacon Information: >\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\tFlgIsSupSpecBcnBuf = %s\n", pChipCap->FlgIsSupSpecBcnBuf ? "TRUE" : "FALSE"));
+ DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxHwNum = %d\n", pChipCap->BcnMaxHwNum));
+ DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxNum = %d\n", pChipCap->BcnMaxNum));
+ DBGPRINT(RT_DEBUG_TRACE, ("\tBcnMaxHwSize = 0x%x\n", pChipCap->BcnMaxHwSize));
+ DBGPRINT(RT_DEBUG_TRACE, ("\tWcidHwRsvNum = %d\n", pChipCap->WcidHwRsvNum));
+ for (idx = 0; idx < pChipCap->BcnMaxHwNum; idx++) {
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\tBcnBase[%d] = 0x%x, pAd->BeaconOffset[%d]=0x%x\n",
+ idx, pChipCap->BcnBase[idx], idx, pAd->BeaconOffset[idx]));
+ }
+
+
+#ifdef RLT_MAC
+ {
+ RTMP_REG_PAIR bcn_mac_reg_tb[] = {
+ {BCN_OFFSET0, 0x18100800},
+ {BCN_OFFSET1, 0x38302820},
+ {BCN_OFFSET2, 0x58504840},
+ {BCN_OFFSET3, 0x78706860},
+ };
+ for (idx = 0; idx < 4; idx ++)
+ {
+ RTMP_IO_WRITE32(pAd, (USHORT)bcn_mac_reg_tb[idx].Register,
+ bcn_mac_reg_tb[idx].Value);
+ }
+ }
+#endif /* RLT_MAC */
+
+}
+
+
+/*
+ ========================================================================
+
+ 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;
+ ULONG j=0;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
+
+ /* Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits */
+retry:
+
+ if (AsicWaitPDMAIdle(pAd, 100, 1000) != TRUE) {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return NDIS_STATUS_FAILURE;
+ }
+
+
+
+ /* 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 (pAd->chipOps.loadFirmware)
+ {
+ if (j++ == 0)
+ {
+ NICLoadFirmware(pAd);
+ goto retry;
+ }
+ }
+ return NDIS_STATUS_FAILURE;
+ }
+
+
+
+ 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;
+ UINT32 MACValue = 0;
+#ifdef RTMP_MAC_USB
+ UINT32 Counter = 0;
+ USB_DMA_CFG_STRUC UsbCfg;
+#endif /* RTMP_MAC_USB */
+ USHORT KeyIdx;
+
+#ifdef RLT_MAC
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+#endif
+
+ 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.*/
+ if (WaitForAsicReady(pAd) != TRUE)
+ return NDIS_STATUS_FAILURE;
+
+ // TODO: shiang, how about the value setting of pAd->MACVersion?? Original it assigned here
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():MACVersion[Ver:Rev=0x%08x]\n",
+ __FUNCTION__, pAd->MACVersion));
+
+
+ if ( !IS_MT7601(pAd) )
+ {
+ /* turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.*/
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MACValue);
+ MACValue &= (~0x2000);
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MACValue);
+ }
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
+
+#ifdef RTMP_MAC
+ RTUSBVenderReset(pAd);
+#endif
+ RTMPusecDelay(1000);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+#endif /* RTMP_MAC_USB */
+
+#ifdef RTMP_MAC_USB
+ UsbCfg.word = 0;
+
+ /* USB1.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;
+
+ UsbCfg.field.RxBulkEn = 1;
+ UsbCfg.field.TxBulkEn = 1;
+
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word);
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ UsbCfg.field.UDMA_RX_WL_DROP = 1;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word);
+
+ UsbCfg.field.UDMA_RX_WL_DROP = 0;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word);
+
+ }
+
+#endif /* MT7601 */
+
+#ifdef RLT_MAC
+ /* Select Q2 to receive command response */
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
+ AndesFunSetOP(pAd, Q_SELECT, pChipCap->CmdRspRxRing);
+ RTUSBBulkCmdRspEventReceive(pAd);
+
+ RTUSBBulkReceive(pAd);
+#endif /* RLT_MAC */
+#endif /* RTMP_MAC_USB */
+
+#if defined(RTMP_MAC_USB) && defined(RLT_MAC)
+
+ AndesRandomWritePair(pAd, MACRegTable, NUM_MAC_REG_PARMS);
+#else
+
+ /* Initialize MAC register to default value*/
+ for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
+ {
+ RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
+ }
+#endif /* defined(RTMP_MAC_USB) && defined(RLT_MAC) */
+
+ AsicInitBcnBuf(pAd);
+
+ /* re-set specific MAC registers for individual chip */
+ if (pAd->chipOps.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, &MACValue);
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return NDIS_STATUS_FAILURE;
+
+ if ((MACValue & 0x03) == 0) /* if BB.RF is stable*/
+ break;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG = Busy = %x\n", MACValue));
+ RTMPusecDelay(1000);
+ } while (Index++ < 100);
+
+
+#ifdef RTMP_MAC_USB
+ if ( !IS_MT7601(pAd) )
+ {
+ /* The commands to firmware should be after these commands, these commands will init firmware*/
+ /* PCI and USB are not the same because PCI driver needs to wait for PCI bus ready*/
+ RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, 0, FALSE); /* initialize BBP R/W access agent. */
+ RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0, FALSE);
+ RTUSBWriteMACRegister(pAd, H2M_INT_SRC, 0, FALSE);
+ AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00, FALSE); /* reset rf by MCU supported by new firmware */
+ }
+#endif /* RTMP_MAC_USB */
+
+ /* Wait to be stable.*/
+ RTMPusecDelay(1000);
+ pAd->LastMCUCmd = 0x72;
+
+ NICInitBBP(pAd);
+
+
+ if ((IS_RT3883(pAd)) || IS_RT65XX(pAd) || IS_MT7601(pAd) ||
+ ((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);
+#if defined(RT2883) || defined(RT3883) || defined(RT3593) || defined(RT65xx) || defined(MT7601)
+ if (IS_RT2883(pAd) || IS_RT3883(pAd) || IS_RT3593(pAd) || IS_RT65XX(pAd) || IS_MT7601(pAd))
+ {
+ csr |= 0x3fff;
+ }
+ else
+#endif /* defined(RT2883) || defined(RT3883) || defined(RT3593) */
+ {
+ csr &= 0xFFF;
+ csr |= 0x2000;
+ }
+ RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
+ }
+
+#ifdef RTMP_MAC_USB
+#ifdef RLT_MAC
+ {
+ UINT32 MACValue[128 * 2];
+
+ for (Index = 0; Index < 128 * 2; Index+=2)
+ {
+ MACValue[Index] = 0xffffffff;
+ MACValue[Index + 1] = 0x00ffffff;
+ }
+
+ AndesBurstWrite(pAd, MAC_WCID_BASE, MACValue, 128 * 2);
+
+ }
+#else
+ {
+ 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, FALSE);
+ }
+ }
+
+#endif /* RLT_MAC */
+#endif /* RTMP_MAC_USB */
+
+
+ /* Clear raw counters*/
+ NicResetRawCounters(pAd);
+
+ /* 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)
+ {
+#if defined(RTMP_MAC_USB) && defined(RLT_MAC)
+ {
+ UINT32 MACValue[4];
+
+ for (Index = 0; Index < 4; Index++)
+ MACValue[Index] = 0;
+
+ AndesBurstWrite(pAd, SHARED_KEY_MODE_BASE, MACValue, 4);
+ }
+
+ /* Clear all pairwise key table when initial*/
+ {
+ UINT32 MACValue[256];
+
+ for (Index = 0; Index < 256; Index++)
+ MACValue[Index] = 1;
+
+ AndesBurstWrite(pAd, MAC_WCID_ATTRIBUTE_BASE, MACValue, 256);
+ }
+#else
+
+ printk("SHARED_KEY_MODE_BASE = %x\n", SHARED_KEY_MODE_BASE);
+ printk("MAC_WCID_ATTRIBUTE_BASE = %x\n", MAC_WCID_ATTRIBUTE_BASE);
+ 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);
+ }
+#endif /* defined(RTMP_MAC_USB) && defined(RLT_MAC) */
+ }
+
+ /* 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)
+ {
+ /* clear all on-chip BEACON frame space */
+#ifdef CONFIG_AP_SUPPORT
+ INT i, apidx;
+ for (apidx = 0; apidx < HW_BEACON_MAX_COUNT(pAd); apidx++)
+ {
+ if (pAd->BeaconOffset[apidx] > 0) {
+ // TODO: shiang-6590, if we didn't define MBSS_SUPPORT, the pAd->BeaconOffset[x] may set as 0 when chipCap.BcnMaxHwNum != HW_BEACON_MAX_COUNT
+ for (i = 0; i < HW_BEACON_OFFSET; i+=4)
+ RTMP_CHIP_UPDATE_BEACON(pAd, pAd->BeaconOffset[apidx] + i, 0x00, 4);
+ }
+#ifdef RTMP_MAC_USB
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (pAd->CommonCfg.pBeaconSync)
+ pAd->CommonCfg.pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << apidx)));
+ }
+#endif /* RTMP_MAC_USB */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+#ifdef RTMP_MAC_USB
+ AsicDisableSync(pAd);
+
+ /* Clear raw counters*/
+ NicResetRawCounters(pAd);
+
+ /* 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 RT3290
+ if (IS_RT3290(pAd))
+ {
+ UINT32 coex_val;
+ //halt wlan tx when bt_rx_busy asserted
+ RTMP_IO_READ32(pAd, COEXCFG2, &coex_val);
+ coex_val |= 0x100;
+ RTMP_IO_WRITE32(pAd, COEXCFG2, coex_val);
+ }
+#endif /* RT3290 */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID NICUpdateFifoStaCounters(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_STA_FIFO_STRUC StaFifo;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ 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
+#endif /* RTMP_MAC_USB */
+
+
+#ifdef RT65xx
+ // TODO: shiang-6590, for 8592 now we have tx-status report packet from hardware!!
+ if (IS_RT65XX(pAd))
+ return;
+#endif /* RT65xx */
+
+
+ do
+ {
+ RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
+
+ if (StaFifo.field.bValid == 0)
+ break;
+
+ wcid = (UCHAR)StaFifo.field.wcid;
+
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFIFO) {
+ dbQueueEnqueue(0x73, (UCHAR *)(&StaFifo.word));
+ }
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+ /* 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
+#ifdef TXBF_SUPPORT
+ /* Update BF statistics*/
+ if (pAd->chipCap.FlgHwTxBfCap)
+ {
+ int succMCS = (StaFifo.field.SuccessRate & 0x7F);
+ int origMCS = pid;
+
+ if (succMCS==32)
+ origMCS = 32;
+#ifdef DOT11N_SS3_SUPPORT
+ if (succMCS>origMCS && pEntry->HTCapability.MCSSet[2]==0xff)
+ origMCS += 16;
+#endif /* DOT11N_SS3_SUPPORT */
+
+ if (succMCS>origMCS)
+ origMCS = succMCS+1;
+
+ /* MCS16 falls back to MCS8*/
+ if (origMCS>=16 && succMCS<=8)
+ succMCS += 8;
+
+ /* MCS8 falls back to 0 */
+ if (origMCS >= 8 && succMCS == 0)
+ succMCS += 7;
+
+ reTry = origMCS-succMCS;
+
+ if (StaFifo.field.eTxBF) {
+ if (StaFifo.field.TxSuccess)
+ pEntry->TxBFCounters.ETxSuccessCount++;
+ else
+ pEntry->TxBFCounters.ETxFailCount++;
+ pEntry->TxBFCounters.ETxRetryCount += reTry;
+ }
+ else if (StaFifo.field.iTxBF) {
+ if (StaFifo.field.TxSuccess)
+ pEntry->TxBFCounters.ITxSuccessCount++;
+ else
+ pEntry->TxBFCounters.ITxFailCount++;
+ pEntry->TxBFCounters.ITxRetryCount += reTry;
+ }
+ else {
+ if (StaFifo.field.TxSuccess)
+ pEntry->TxBFCounters.TxSuccessCount++;
+ else
+ pEntry->TxBFCounters.TxFailCount++;
+ pEntry->TxBFCounters.TxRetryCount += reTry;
+ }
+ }
+#endif /* TXBF_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef UAPSD_SUPPORT
+ UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
+#endif /* UAPSD_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; tid<NUM_OF_TID; tid++)
+ BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, FALSE);
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ /* fix WDS Jam issue*/
+ if(IS_ENTRY_WDS(pEntry)
+ && (pEntry->LockEntryTx == FALSE)
+ && (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Entry %02x:%02x:%02x:%02x:%02x:%02x Blocked!! (Fail Cnt = %d)\n",
+ PRINT_MAC(pEntry->Addr), pEntry->ContinueTxFailCnt ));
+
+ pEntry->LockEntryTx = TRUE;
+ }
+#endif /* WDS_SUPPORT */
+ }
+ }
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else
+ {
+#ifdef DOT11_N_SUPPORT
+ if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
+ {
+ pEntry->NoBADataCountDown--;
+ if (pEntry->NoBADataCountDown==0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+ pEntry->FIFOCount = 0;
+ pEntry->OneSecTxNoRetryOkCount++;
+
+
+ /* update NoDataIdleCount when sucessful send packet to STA.*/
+ pEntry->NoDataIdleCount = 0;
+ pEntry->ContinueTxFailCnt = 0;
+#ifdef WDS_SUPPORT
+ pEntry->LockEntryTx = FALSE;
+#endif /* WDS_SUPPORT */
+
+ }
+
+ succMCS = StaFifo.field.SuccessRate & 0x7F;
+#ifdef DOT11N_SS3_SUPPORT
+ if (pEntry->HTCapability.MCSSet[2] == 0xff)
+ {
+ if (succMCS > pid)
+ pid = pid + 16;
+ }
+#endif /* DOT11N_SS3_SUPPORT */
+
+ 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
+ if (pid >= 16 && succMCS <= 8)
+ succMCS += (2 - (succMCS >> 3)) * 7;
+#endif /* DOT11N_SS3_SUPPORT */
+
+ reTry = pid - succMCS;
+
+ if (reTry > 0)
+ {
+ /* MCS8 falls back to 0 */
+ if (pid>=8 && succMCS==0)
+ reTry -= 7;
+ else if ((pid >= 12) && succMCS <=7)
+ reTry -= 4;
+
+ pEntry->OneSecTxRetryOkCount += reTry;
+ }
+
+ i++; /* ASIC store 16 stack*/
+ } while ( i < (TX_RING_SIZE<<1) );
+
+}
+
+
+#ifdef FIFO_EXT_SUPPORT
+BOOLEAN NicGetMacFifoTxCnt(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ if (pEntry->Aid >= 1 && pEntry->Aid <= 8)
+ {
+ WCID_TX_CNT_STRUC wcidTxCnt;
+ UINT32 regAddr;
+
+ regAddr = WCID_TX_CNT_0 + (pEntry->Aid - 1) * 4;
+ RTMP_IO_READ32(pAd, regAddr, &wcidTxCnt.word);
+
+ pEntry->fifoTxSucCnt += wcidTxCnt.field.succCnt;
+ pEntry->fifoTxRtyCnt += wcidTxCnt.field.reTryCnt;
+ }
+
+ return TRUE;
+}
+
+
+VOID AsicFifoExtSet(IN RTMP_ADAPTER *pAd)
+{
+ if (pAd->chipCap.FlgHwFifoExtCap)
+ {
+ RTMP_IO_WRITE32(pAd, WCID_MAPPING_0, 0x04030201);
+ RTMP_IO_WRITE32(pAd, WCID_MAPPING_1, 0x08070605);
+ }
+}
+
+
+VOID AsicFifoExtEntryClean(
+ IN RTMP_ADAPTER * pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ WCID_TX_CNT_STRUC wcidTxCnt;
+ UINT32 regAddr;
+
+ if (pAd->chipCap.FlgHwFifoExtCap)
+ {
+ /* We clean the fifo info when MCS is 0 and Aid is from 1~8 */
+ if (pEntry->Aid >=1 && pEntry->Aid <= 8)
+ {
+ regAddr = WCID_TX_CNT_0 + (pEntry->Aid - 1) * 4;
+ RTMP_IO_READ32(pAd, regAddr, &wcidTxCnt.word);
+ }
+ }
+}
+#endif /* FIFO_EXT_SUPPORT */
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read Tx statistic raw counters from hardware registers and record to
+ related software variables for later on query
+
+ Arguments:
+ pAd Pointer to our adapter
+ pStaTxCnt0 Pointer to record "TX_STA_CNT0" (0x170c)
+ pStaTxCnt1 Pointer to record "TX_STA_CNT1" (0x1710)
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID NicGetTxRawCounters(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_STA_CNT0_STRUC *pStaTxCnt0,
+ IN TX_STA_CNT1_STRUC *pStaTxCnt1)
+{
+
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &pStaTxCnt0->word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &pStaTxCnt1->word);
+
+ pAd->bUpdateBcnCntDone = TRUE; /* not appear in Rory's code */
+ pAd->RalinkCounters.OneSecBeaconSentCnt += pStaTxCnt0->field.TxBeaconCount;
+ pAd->RalinkCounters.OneSecTxRetryOkCount += pStaTxCnt1->field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += pStaTxCnt1->field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += pStaTxCnt0->field.TxFailCount;
+
+#ifdef STATS_COUNT_SUPPORT
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += pStaTxCnt1->field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += pStaTxCnt1->field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += pStaTxCnt0->field.TxFailCount;
+#endif /* STATS_COUNT_SUPPORT */
+
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Clean all Tx/Rx statistic raw counters from hardware registers
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID NicResetRawCounters(RTMP_ADAPTER *pAd)
+{
+ UINT32 Counter;
+
+ 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);
+}
+
+
+/*
+ ========================================================================
+
+ 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_NAG_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;
+
+ if(RTMP_TEST_FLAG(pAd, fRTMP_PS_MCU_SLEEP))
+ 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);
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT
+ if ((pAd->CommonCfg.CarrierDetect.Enable == FALSE) || (pAd->OpMode == OPMODE_STA))
+#endif /* CARRIER_DETECTION_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ {
+#ifdef MICROWAVE_OVEN_SUPPORT
+ /* Update RX PLCP error counter*/
+ pAd->PrivateInfo.PhyRxErrCnt += NICSumPLCPErrCnt(pAd); /* get PLCP error count per sec */
+ /* Update False CCA counter*/
+ pAd->RalinkCounters.OneSecFalseCCACnt += NICSumFalseCCACnt(pAd); /* get FalseCCA count per sec */
+ pAd->RalinkCounters.FalseCCACnt += pAd->RalinkCounters.OneSecFalseCCACnt;
+#else
+ 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;
+ pAd->RalinkCounters.FalseCCACnt += RxStaCnt1.field.FalseCca;
+
+#endif /* MICROWAVE_OVEN_SUPPORT */
+ }
+
+#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*/
+ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1);
+ RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
+ }
+
+
+ /*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)
+{
+ 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);
+
+}
+
+
+/*
+ ========================================================================
+
+ 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(RTMP_ADAPTER *pAd)
+{
+ UINT i;
+#ifdef CONFIG_AP_SUPPORT
+ UINT j;
+#endif /* CONFIG_AP_SUPPORT */
+/* EDCA_PARM DefaultEdcaParm;*/
+ UINT key_index, bss_index;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
+
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+
+ /* part I. intialize common configuration*/
+ pAd->CommonCfg.BasicRateBitmap = 0xF;
+ pAd->CommonCfg.BasicRateBitmapOld = 0xF;
+#ifdef CONFIG_MULTI_CHANNEL
+ pAd->Multi_Channel_Enable = FALSE;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+#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));
+
+#endif /* RTMP_MAC_USB */
+
+ for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
+ {
+ for(bss_index = 0; bss_index < MAX_MBSSID_NUM(pAd) + MAX_P2P_NUM; bss_index++)
+ {
+ pAd->SharedKey[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*/
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+ pAd->TxPowerCtrl.bInternalTxALC = FALSE; /* Off by default */
+ pAd->TxPowerCtrl.idxTxPowerTable = 0;
+ pAd->TxPowerCtrl.idxTxPowerTable2 = 0;
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+ pAd->TxPowerCtrl.LookupTableIndex = 0;
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+
+ 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 = pAd->CommonCfg.PhyMode;
+
+
+#ifdef CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ 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;
+ pAd->CommonCfg.CarrierDetect.recheck1 = CARRIER_DETECT_RECHECK_TIME;
+ pAd->CommonCfg.CarrierDetect.CarrierGoneThreshold = CARRIER_GONE_TRESHOLD;
+ pAd->CommonCfg.CarrierDetect.VGA_Mask = CARRIER_DETECT_DEFAULT_MASK;
+ pAd->CommonCfg.CarrierDetect.Packet_End_Mask = CARRIER_DETECT_DEFAULT_MASK;
+ pAd->CommonCfg.CarrierDetect.Rx_PE_Mask = CARRIER_DETECT_DEFAULT_MASK;
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#ifdef DFS_SUPPORT
+ pAd->CommonCfg.RadarDetect.bDfsInit = FALSE;
+#endif /* DFS_SUPPORT */
+
+ pAd->Dot11_H.ChMovingTime = 65;
+
+#ifdef UAPSD_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+{
+ UINT32 IdMbss;
+
+ for(IdMbss=0; IdMbss<HW_BEACON_MAX_NUM; IdMbss++)
+ UAPSD_INFO_INIT(&pAd->ApCfg.MBSSID[IdMbss].UapsdInfo);
+}
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+ 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, TXWISize);
+
+#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;
+ pAd->CommonCfg.Bss2040NeedFallBack = 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;
+#ifdef GREENAP_SUPPORT
+ pAd->ApCfg.bGreenAPEnable=FALSE;
+ pAd->ApCfg.bGreenAPActive = FALSE;
+ pAd->ApCfg.GreenAPLevel= GREENAP_WITHOUT_ANY_STAS_CONNECT;
+#endif /* GREENAP_SUPPORT */
+ 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 STREAM_MODE_SUPPORT
+ if (pAd->chipCap.FlgHwStreamMode)
+ {
+ pAd->CommonCfg.StreamMode = 3;
+ pAd->CommonCfg.StreamModeMCS = 0x0B0B;
+ }
+#endif /* STREAM_MODE_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ pAd->CommonCfg.ETxBfNoncompress = 0;
+ pAd->CommonCfg.ETxBfIncapable = 0;
+#endif /* TXBF_SUPPORT */
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ pAd->CommonCfg.lowTrafficThrd = 2;
+ pAd->CommonCfg.TrainUpRule = 2; // 1;
+ pAd->CommonCfg.TrainUpRuleRSSI = -70; // 0;
+ pAd->CommonCfg.TrainUpLowThrd = 90;
+ pAd->CommonCfg.TrainUpHighThrd = 110;
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+
+
+#ifdef CFO_TRACK
+#endif /* CFO_TRACK */
+
+#ifdef DBG_CTRL_SUPPORT
+ pAd->CommonCfg.DebugFlags = 0;
+#endif /* DBG_CTRL_SUPPORT */
+
+#ifdef WAPI_SUPPORT
+ pAd->CommonCfg.wapi_usk_rekey_method = REKEY_METHOD_DISABLE;
+ pAd->CommonCfg.wapi_msk_rekey_method = REKEY_METHOD_DISABLE;
+ pAd->CommonCfg.wapi_msk_rekey_cnt = 0;
+#endif /* WAPI_SUPPORT */
+
+#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;
+
+ /* Frequency for rate adaptation */
+ pAd->ra_interval = DEF_RA_TIME_INTRVAL;
+ pAd->ra_fast_interval = DEF_QUICK_RA_TIME_INTERVAL;
+
+#ifdef AGS_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_AGS)
+ pAd->ra_fast_interval = AGS_QUICK_RA_TIME_INTERVAL;
+#endif /* AGS_SUPPORT */
+
+ /* Tx Sw queue length setting */
+ pAd->TxSwQMaxLen = MAX_PACKETS_IN_QUEUE;
+
+ pAd->CommonCfg.bRalinkBurstMode = FALSE;
+
+
+ /* 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 = (WMODE_B | WMODE_G); /* default PHY mode*/
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); /* CCK use LONG preamble*/
+
+
+ /* Default for extra information is not valid*/
+ pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+
+ /* Default Config change flag*/
+ pAd->bConfigChanged = FALSE;
+
+ /* */
+ /* part III. AP configurations*/
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* Set MBSS Default Configurations*/
+ pAd->ApCfg.BssidNum = MAX_MBSSID_NUM(pAd);
+ for(j = BSS0; j < pAd->ApCfg.BssidNum; j++)
+ {
+ pAd->ApCfg.MBSSID[j].AuthMode = Ndis802_11AuthModeOpen;
+ pAd->ApCfg.MBSSID[j].WepStatus = Ndis802_11EncryptionDisabled;
+ pAd->ApCfg.MBSSID[j].GroupKeyWepStatus = Ndis802_11EncryptionDisabled;
+ pAd->ApCfg.MBSSID[j].DefaultKeyId = 0;
+ pAd->ApCfg.MBSSID[j].WpaMixPairCipher = MIX_CIPHER_NOTUSE;
+ pAd->ApCfg.MBSSID[j].RekeyCountDown = 0; /* it's used for WPA rekey */
+
+#ifdef DOT1X_SUPPORT
+ pAd->ApCfg.MBSSID[j].IEEE8021X = FALSE;
+ pAd->ApCfg.MBSSID[j].PreAuth = FALSE;
+
+ /* PMK cache setting*/
+ pAd->ApCfg.MBSSID[j].PMKCachePeriod = (10 * 60 * OS_HZ); /* unit : tick(default: 10 minute)*/
+ NdisZeroMemory(&pAd->ApCfg.MBSSID[j].PMKIDCache, sizeof(NDIS_AP_802_11_PMKID));
+
+ /* dot1x related per BSS */
+ pAd->ApCfg.MBSSID[j].radius_srv_num = 0;
+ pAd->ApCfg.MBSSID[j].NasIdLen = 0;
+#endif /* DOT1X_SUPPORT */
+
+ /* VLAN related */
+ pAd->ApCfg.MBSSID[j].VLAN_VID = 0;
+
+ /* Default MCS as AUTO*/
+ pAd->ApCfg.MBSSID[j].bAutoTxRateSwitch = TRUE;
+ pAd->ApCfg.MBSSID[j].DesiredTransmitSetting.field.MCS = MCS_AUTO;
+
+ /* Default is zero. It means no limit.*/
+ pAd->ApCfg.MBSSID[j].MaxStaNum = 0;
+ pAd->ApCfg.MBSSID[j].StaCount = 0;
+
+#ifdef WSC_AP_SUPPORT
+ pAd->ApCfg.MBSSID[j].WscSecurityMode = 0xff;
+ {
+ PWSC_CTRL pWscControl;
+ INT idx;
+#ifdef WSC_V2_SUPPORT
+ PWSC_V2_INFO pWscV2Info;
+#endif /* WSC_V2_SUPPORT */
+ /*
+ WscControl cannot be zero here, because WscControl timers are initial in MLME Initialize
+ and MLME Initialize is called before UserCfgInit.
+
+ */
+ pWscControl = &pAd->ApCfg.MBSSID[j].WscControl;
+ NdisZeroMemory(&pWscControl->RegData, sizeof(WSC_REG_DATA));
+ NdisZeroMemory(&pAd->CommonCfg.WscStaPbcProbeInfo, sizeof(WSC_STA_PBC_PROBE_INFO));
+ pWscControl->WscMode = 1;
+ pWscControl->WscConfStatus = 1;
+#ifdef WSC_V2_SUPPORT
+ pWscControl->WscConfigMethods= 0x238C;
+#else
+ pWscControl->WscConfigMethods= 0x0084;
+#endif /* WSC_V2_SUPPORT */
+ pWscControl->RegData.ReComputePke = 1;
+ pWscControl->lastId = 1;
+ /* pWscControl->EntryIfIdx = (MIN_NET_DEVICE_FOR_MBSSID | j); */
+ pWscControl->pAd = pAd;
+ pWscControl->WscRejectSamePinFromEnrollee = FALSE;
+ pAd->CommonCfg.WscPBCOverlap = FALSE;
+ pWscControl->WscConfMode = 0;
+ pWscControl->WscStatus = 0;
+ pWscControl->WscState = 0;
+ pWscControl->WscPinCode = 0;
+ pWscControl->WscLastPinFromEnrollee = 0;
+ pWscControl->WscEnrollee4digitPinCode = FALSE;
+ pWscControl->WscEnrolleePinCode = 0;
+ pWscControl->WscSelReg = 0;
+ pWscControl->WscUseUPnP = 0;
+ pWscControl->bWCNTest = FALSE;
+ pWscControl->WscKeyASCII = 0; /* default, 0 (64 Hex) */
+
+ /*
+ Enrollee 192 random bytes for DH key generation
+ */
+ for (idx = 0; idx < 192; idx++)
+ pWscControl->RegData.EnrolleeRandom[idx] = RandomByte(pAd);
+
+ /* Enrollee Nonce, first generate and save to Wsc Control Block*/
+ for (idx = 0; idx < 16; idx++)
+ {
+ pWscControl->RegData.SelfNonce[idx] = RandomByte(pAd);
+ }
+ NdisZeroMemory(&pWscControl->WscDefaultSsid, sizeof(NDIS_802_11_SSID));
+ NdisZeroMemory(&pWscControl->Wsc_Uuid_Str[0], UUID_LEN_STR);
+ NdisZeroMemory(&pWscControl->Wsc_Uuid_E[0], UUID_LEN_HEX);
+ pWscControl->bCheckMultiByte = FALSE;
+ pWscControl->bWscAutoTigeer = FALSE;
+ pWscControl->bWscFragment = FALSE;
+ pWscControl->WscFragSize = 128;
+ pWscControl->WscRxBufLen = 0;
+ pWscControl->pWscRxBuf = NULL;
+ os_alloc_mem(pAd, &pWscControl->pWscRxBuf, MGMT_DMA_BUFFER_SIZE);
+ if (pWscControl->pWscRxBuf)
+ NdisZeroMemory(pWscControl->pWscRxBuf, MGMT_DMA_BUFFER_SIZE);
+ pWscControl->WscTxBufLen = 0;
+ pWscControl->pWscTxBuf = NULL;
+ os_alloc_mem(pAd, &pWscControl->pWscTxBuf, MGMT_DMA_BUFFER_SIZE);
+ if (pWscControl->pWscTxBuf)
+ NdisZeroMemory(pWscControl->pWscTxBuf, MGMT_DMA_BUFFER_SIZE);
+ initList(&pWscControl->WscPeerList);
+ NdisAllocateSpinLock(pAd, &pWscControl->WscPeerListSemLock);
+ pWscControl->PinAttackCount = 0;
+ pWscControl->bSetupLock = FALSE;
+#ifdef WSC_V2_SUPPORT
+ pWscV2Info = &pWscControl->WscV2Info;
+ pWscV2Info->bWpsEnable = TRUE;
+ pWscV2Info->ExtraTlv.TlvLen = 0;
+ pWscV2Info->ExtraTlv.TlvTag = 0;
+ pWscV2Info->ExtraTlv.pTlvData = NULL;
+ pWscV2Info->ExtraTlv.TlvType = TLV_ASCII;
+ pWscV2Info->bEnableWpsV2 = TRUE;
+ pWscControl->SetupLockTime = WSC_WPS_AP_SETUP_LOCK_TIME;
+ pWscControl->MaxPinAttack = WSC_WPS_AP_MAX_PIN_ATTACK;
+#endif /* WSC_V2_SUPPORT */
+
+ }
+#endif /* WSC_AP_SUPPORT */
+
+
+ for(i = 0; i < WLAN_MAX_NUM_OF_TIM; i++)
+ pAd->ApCfg.MBSSID[j].TimBitmaps[i] = 0;
+ }
+ pAd->ApCfg.DtimCount = 0;
+ pAd->ApCfg.DtimPeriod = DEFAULT_DTIM_PERIOD;
+
+ pAd->ApCfg.ErpIeContent = 0;
+
+ pAd->ApCfg.StaIdleTimeout = MAC_TABLE_AGEOUT_TIME;
+
+#ifdef IDS_SUPPORT
+ /* Default disable IDS threshold and reset all IDS counters*/
+ pAd->ApCfg.IdsEnable = FALSE;
+ pAd->ApCfg.AuthFloodThreshold = 0;
+ pAd->ApCfg.AssocReqFloodThreshold = 0;
+ pAd->ApCfg.ReassocReqFloodThreshold = 0;
+ pAd->ApCfg.ProbeReqFloodThreshold = 0;
+ pAd->ApCfg.DisassocFloodThreshold = 0;
+ pAd->ApCfg.DeauthFloodThreshold = 0;
+ pAd->ApCfg.EapReqFloodThreshold = 0;
+ RTMPClearAllIdsCounter(pAd);
+#endif /* IDS_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ APWdsInitialize(pAd);
+#endif /* WDS_SUPPORT*/
+
+#ifdef WSC_INCLUDED
+ pAd->WriteWscCfgToDatFile = 0xFF;
+ pAd->WriteWscCfgToAr9DatFile = FALSE;
+#ifdef CONFIG_AP_SUPPORT
+ pAd->bWscDriverAutoUpdateCfg = TRUE;
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* WSC_INCLUDED */
+
+#ifdef APCLI_SUPPORT
+ pAd->ApCfg.FlgApCliIsUapsdInfoUpdated = FALSE;
+
+ for(j = 0; j < MAX_APCLI_NUM; j++)
+ {
+ pAd->ApCfg.ApCliTab[j].AuthMode = Ndis802_11AuthModeOpen;
+ pAd->ApCfg.ApCliTab[j].WepStatus = Ndis802_11WEPDisabled;
+ pAd->ApCfg.ApCliTab[j].bAutoTxRateSwitch = TRUE;
+ pAd->ApCfg.ApCliTab[j].DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ pAd->ApCfg.ApCliTab[j].UapsdInfo.bAPSDCapable = FALSE;
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ pAd->ApCfg.ApCliTab[j].IEEE8021X=FALSE;
+ pAd->ApCfg.ApCliTab[j].IEEE8021x_required_keys=FALSE;
+ pAd->ApCfg.ApCliTab[j].bRSN_IE_FromWpaSupplicant=FALSE;
+ pAd->ApCfg.ApCliTab[j].bLostAp=FALSE;
+ pAd->ApCfg.ApCliTab[j].bScanReqIsFromWebUI=FALSE;
+ pAd->ApCfg.ApCliTab[j].bConfigChanged=FALSE;
+ pAd->ApCfg.ApCliTab[j].DesireSharedKeyId=0;
+ pAd->ApCfg.ApCliTab[j].WpaSupplicantUP=WPA_SUPPLICANT_DISABLE;
+ pAd->ApCfg.ApCliTab[j].WpaSupplicantScanCount=0;
+ pAd->ApCfg.ApCliTab[j].pWpsProbeReqIe=NULL;
+ pAd->ApCfg.ApCliTab[j].WpsProbeReqIeLen=0;
+ pAd->ApCfg.ApCliTab[j].pWpaAssocIe=NULL;
+ pAd->ApCfg.ApCliTab[j].WpaAssocIeLen=0;
+ pAd->ApCfg.ApCliTab[j].SavedPMKNum=0;
+ RTMPZeroMemory(pAd->ApCfg.ApCliTab[j].SavedPMK, (PMKID_NO * sizeof(BSSID_INFO)));
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+ }
+#endif /* APCLI_SUPPORT */
+ pAd->ApCfg.EntryClientCount = 0;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef IP_ASSEMBLY
+ if (pAd->OpMode == OPMODE_STA)
+ {
+ pAd->StaCfg.bFragFlag = TRUE;
+ }
+#endif /* IP_ASSEMBLY */
+
+ /* 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);*/
+
+
+ pAd->CommonCfg.bWiFiTest = FALSE;
+
+#ifdef CONFIG_AP_SUPPORT
+ pAd->ApCfg.EntryLifeCheck = MAC_ENTRY_LIFE_CHECK_CNT;
+
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ pAd->RxAnt.Pair1PrimaryRxAnt = 0;
+ pAd->RxAnt.Pair1SecondaryRxAnt = 1;
+
+ pAd->RxAnt.EvaluatePeriod = 0;
+ pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
+#ifdef CONFIG_AP_SUPPORT
+ pAd->RxAnt.Pair1AvgRssiGroup1[0] = pAd->RxAnt.Pair1AvgRssiGroup1[1] = 0;
+ pAd->RxAnt.Pair1AvgRssiGroup2[0] = pAd->RxAnt.Pair1AvgRssiGroup2[1] = 0;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef TXRX_SW_ANTDIV_SUPPORT
+ pAd->chipCap.bTxRxSwAntDiv = FALSE;
+#endif /* TXRX_SW_ANTDIV_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) */
+
+
+#ifdef WSC_INCLUDED
+ NdisZeroMemory(&pAd->CommonCfg.WscStaPbcProbeInfo, sizeof(WSC_STA_PBC_PROBE_INFO));
+ pAd->CommonCfg.WscPBCOverlap = FALSE;
+#endif /* WSC_INCLUDED */
+
+
+
+#ifdef WFD_SUPPORT
+ WfdCfgInit(pAd);
+#endif /* WFD_SUPPORT */
+
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ pAd->WOW_Cfg.bEnable = FALSE;
+ pAd->WOW_Cfg.bWOWFirmware = FALSE; /* load normal firmware */
+ pAd->WOW_Cfg.bInBand = TRUE; /* use in-band signal */
+ pAd->WOW_Cfg.nSelectedGPIO = 1;
+ pAd->WOW_Cfg.nDelay = 3; /* (3+1)*3 = 12 sec */
+ pAd->WOW_Cfg.nHoldTime = 1; /* 1*10 = 10 ms */
+ DBGPRINT(RT_DEBUG_OFF, ("WOW Enable %d, WOWFirmware %d\n", pAd->WOW_Cfg.bEnable, pAd->WOW_Cfg.bWOWFirmware));
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+ /* 802.11H and DFS related params*/
+ pAd->Dot11_H.CSCount = 0;
+ pAd->Dot11_H.CSPeriod = 10;
+ pAd->Dot11_H.RDMode = RD_NORMAL_MODE;
+ pAd->Dot11_H.bDFSIndoor = 1;
+
+
+#ifdef FPGA_MODE
+ pAd->fpga_on = 0x0;
+ pAd->tx_kick_cnt = 0;
+ pAd->data_phy = 0;
+ pAd->data_mcs = 0;
+ pAd->data_bw = 0;
+ pAd->data_gi = 0;
+#endif /* FPGA_MODE */
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ if (pAd->OpMode == OPMODE_AP)
+ pAd->CommonCfg.MO_Cfg.bEnable = TRUE;
+ else
+ pAd->CommonCfg.MO_Cfg.bEnable = FALSE;
+ pAd->CommonCfg.MO_Cfg.nFalseCCATh = MO_FALSE_CCA_TH;
+#endif /* MICROWAVE_OVEN_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++;
+ }
+}
+
+
+/*
+========================================================================
+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);
+}
+
+
+VOID RTMP_AllTimerListRelease(RTMP_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)));
+ pObjOld = pObj;
+ pObj = pObj->pNext;
+ RTMPReleaseTimer(pObjOld->pRscObj, &Cancel);
+ 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)
+{
+ UINT32 rx_filter_flag;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
+
+ RT28XXDMAEnable(pAd);
+
+ /* enable RX of MAC block*/
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ rx_filter_flag = APNORMAL;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef IDS_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (pAd->ApCfg.IdsEnable)
+ rx_filter_flag &= (~0x4); /* Don't drop those not-U2M frames*/
+ }
+#endif /* IDS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); /* enable RX of DMA block*/
+ }
+
+ {
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+//+++Add by shiang for debug for pbf_loopback
+ //RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2c);
+//---Add by shiang for debug
+//+++Add by shiang for debug invalid RxWI->WCID
+#ifdef RT8592
+#endif /* RT8592 */
+//---Add by shiang for debug invalid RxWI->WCID
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
+}
+
+
+void CfgInitHook(PRTMP_ADAPTER pAd)
+{
+ /*pAd->bBroadComHT = TRUE;*/
+}
+
+
+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));
+
+ RtmpChipOpsHook(pAd);
+
+ /* MCU related */
+ ChipOpsMCUHook(pAd, pAd->chipCap.MCUType);
+
+ /* set eeprom related hook functions */
+ status = RtmpChipOpsEepromHook(pAd, infType);
+
+ return status;
+}
+
+
+#ifdef RTMP_MAC_USB
+BOOLEAN PairEP(RTMP_ADAPTER *pAd, UINT8 EP, UINT8 Index, UINT8 InOut)
+{
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ if (Index == 0 && InOut == 0)
+ {
+ pChipCap->CommandBulkOutAddr = EP;
+ DBGPRINT(RT_DEBUG_OFF, ("Endpoint(%x) is for In-band Command\n", EP));
+ return TRUE;
+ }
+
+ if (Index > 0 && Index < 5 && InOut == 0)
+ {
+ pChipCap->WMM0ACBulkOutAddr[Index - 1] = EP;
+ DBGPRINT(RT_DEBUG_OFF, ("Endpoint(%x) is for WMM0 AC%d\n", EP, Index - 1));
+ return TRUE;
+ }
+
+ if (Index == 5 && InOut == 0)
+ {
+ pChipCap->WMM1ACBulkOutAddr = EP;
+ DBGPRINT(RT_DEBUG_OFF, ("Endpoint(%x) is for WMM1 AC0\n", EP));
+ return TRUE;
+ }
+
+ if (Index == 0 && InOut == 1)
+ {
+ pChipCap->DataBulkInAddr = EP;
+ DBGPRINT(RT_DEBUG_OFF, ("Endpoint(%x) is for Data-In\n", EP));
+ return TRUE;
+ }
+
+
+ if (Index == 1 && InOut == 1)
+ {
+ pChipCap->CommandRspBulkInAddr = EP;
+ DBGPRINT(RT_DEBUG_OFF, ("Endpoint(%x) is for Command Rsp\n", EP));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif /* RTMP_MAC_USB */
+
+
+INT RtmpRaDevCtrlInit(VOID *pAdSrc, RTMP_INF_TYPE infType)
+{
+ RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)pAdSrc;
+ UINT8 i;
+
+ /* Assign the interface type. We need use it when do register/EEPROM access.*/
+ pAd->infType = infType;
+
+
+#ifdef CONFIG_AP_SUPPORT
+ pAd->OpMode = OPMODE_AP;
+ DBGPRINT(RT_DEBUG_TRACE, ("AP Driver version-%s\n", AP_DRIVER_VERSION));
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef RTMP_MAC_USB
+ RTMP_SEM_EVENT_INIT(&(pAd->UsbVendorReq_semaphore), &pAd->RscSemMemList);
+ RTMP_SEM_EVENT_INIT(&(pAd->reg_atomic), &pAd->RscSemMemList);
+ RTMP_SEM_EVENT_INIT(&(pAd->hw_atomic), &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 RTMP_MAC_USB
+ for (i = 0; i < 6; i++)
+ {
+ if (!PairEP(pAd, pAd->BulkOutEpAddr[i], i, 0))
+ DBGPRINT(RT_DEBUG_ERROR, ("Invalid bulk out ep(%x)\n", pAd->BulkOutEpAddr[i]));
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ if (!PairEP(pAd, pAd->BulkInEpAddr[i], i, 1))
+ DBGPRINT(RT_DEBUG_ERROR, ("Invalid bulk in ep(%x)\n", pAd->BulkInEpAddr[i]));
+ }
+
+#endif
+
+#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_AP_SUPPORT
+ strcpy(pAd->MC_FileName, AP_PROFILE_PATH);
+#endif /* CONFIG_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
+}
+#endif /* MULTIPLE_CARD_SUPPORT */
+
+#if defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_SUPPORT)
+ if (pAd->chipCap.asic_caps | fASIC_CAP_CSO)
+ RTMP_SET_MORE_FLAG(pAd, fASIC_CAP_CSO);
+#endif /* defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_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->reg_atomic));
+ RTMP_SEM_EVENT_DESTORY(&(pAd->hw_atomic));
+
+
+ if (pAd->UsbVendorReqBuf)
+ os_free_mem(pAd, pAd->UsbVendorReqBuf);
+#endif /* RTMP_MAC_USB */
+
+ /*
+ Free ProbeRespIE Table
+ */
+ for (index = 0; index < MAX_LEN_OF_BSS_TABLE; index++)
+ {
+ if (pAd->ProbeRespIE[index].pIe)
+ os_free_mem(pAd, pAd->ProbeRespIE[index].pIe);
+ }
+
+#ifdef RESOURCE_PRE_ALLOC
+ RTMPFreeTxRxRingMemory(pAd);
+#endif /* RESOURCE_PRE_ALLOC */
+
+#ifdef RT65xx
+ if (IS_RT6590(pAd) && (pAd->WlanFunCtrl.field.WLAN_EN == 1))
+ {
+ ral_wlan_chip_onoff(pAd, FALSE, FALSE);
+ }
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd) && (pAd->WlanFunCtrl.field.WLAN_EN == 1) )
+ {
+ MT7601_WLAN_ChipOnOff(pAd, FALSE, FALSE);
+ }
+#endif /* MT7601 */
+
+ RTMPFreeAdapter(pAd);
+
+ return TRUE;
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID RTMP_11N_D3_TimerInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMPInitTimer(pAd, &pAd->CommonCfg.Bss2040CoexistTimer, GET_TIMER_FUNCTION(Bss2040CoexistTimeOut), pAd, FALSE);
+}
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#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)
+{
+#ifdef RT8592
+ if (IS_RT8592(pAd))
+ return;
+#endif /* RT8592 */
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ return;
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ return;
+#endif /* MT7601 */
+ _RTMP_BBP_IO_READ8_BY_REG_ID(pAd, Offset, pValue);
+}
+
+VOID RTMP_BBP_IO_READ8(
+ PRTMP_ADAPTER pAd,
+ UCHAR Offset,
+ UINT8 *pValue,
+ BOOLEAN FlgValidMCR)
+{
+#ifdef RT8592
+ if (IS_RT8592(pAd))
+ return;
+#endif /* RT8592 */
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ return;
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ return;
+#endif /* MT7601 */
+
+ _RTMP_BBP_IO_READ8(pAd, Offset, pValue, FlgValidMCR);
+}
+
+VOID RTMP_BBP_IO_WRITE8_BY_REG_ID(
+ PRTMP_ADAPTER pAd,
+ UINT32 Offset,
+ UINT8 Value)
+{
+#ifdef RT8592
+ if (IS_RT8592(pAd))
+ return;
+#endif /* RT8592 */
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ return;
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ return;
+#endif /* MT7601 */
+
+ _RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, Offset, Value);
+}
+
+VOID RTMP_BBP_IO_WRITE8(
+ PRTMP_ADAPTER pAd,
+ UCHAR Offset,
+ UINT8 Value,
+ BOOLEAN FlgValidMCR)
+{
+#ifdef RT8592
+ if (IS_RT8592(pAd))
+ return;
+#endif /* RT8592 */
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ return;
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ return;
+#endif /* MT7601 */
+
+ _RTMP_BBP_IO_WRITE8(pAd, Offset, Value, FlgValidMCR);
+}
+#endif /* VENDOR_FEATURE3_SUPPORT */
+
+
+
+VOID AntCfgInit(
+IN PRTMP_ADAPTER pAd)
+{
+
+
+#ifdef TXRX_SW_ANTDIV_SUPPORT
+ /* EEPROM 0x34[15:12] = 0xF is invalid, 0x2~0x3 is TX/RX SW AntDiv */
+ DBGPRINT(RT_DEBUG_OFF, ("%s: bTxRxSwAntDiv %d\n", __FUNCTION__, pAd->chipCap.bTxRxSwAntDiv));
+ if (pAd->chipCap.bTxRxSwAntDiv)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Antenna word %X/%d, AntDiv %d\n",
+ pAd->Antenna.word, pAd->Antenna.field.BoardType, pAd->NicConfig2.field.AntDiversity));
+ }
+#endif /* TXRX_SW_ANTDIV_SUPPORT */
+
+ {
+ 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 */
+ {/* eeprom on, but sw ant div support is not enabled: default ant is main */
+ pAd->RxAnt.Pair1PrimaryRxAnt = 0;
+ pAd->RxAnt.Pair1SecondaryRxAnt = 1;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("%s: primary/secondary ant %d/%d\n",
+ __FUNCTION__,
+ pAd->RxAnt.Pair1PrimaryRxAnt,
+ pAd->RxAnt.Pair1SecondaryRxAnt));
+}
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+VOID NICUpdateRxStatusCnt1(
+IN PRTMP_ADAPTER pAd,
+IN UCHAR Idx)
+{
+ RX_STA_CNT1_STRUC RxStaCnt1;
+
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
+
+ if (Idx < MLME_TASK_EXEC_MULTIPLE)
+ {
+ pAd->RalinkCounters.FalseCCACnt_100MS[Idx] = RxStaCnt1.field.FalseCca;
+ pAd->RalinkCounters.PLCPErrCnt_100MS[Idx] = RxStaCnt1.field.PlcpErr;
+ }
+}
+
+UINT32 NICSumFalseCCACnt(
+IN PRTMP_ADAPTER pAd)
+{
+ UCHAR Idx;
+ UINT32 FalseCCACnt = 0;
+
+ for (Idx = 0; Idx < MLME_TASK_EXEC_MULTIPLE; Idx++)
+ FalseCCACnt += pAd->RalinkCounters.FalseCCACnt_100MS[Idx];
+
+ return FalseCCACnt;
+}
+
+UINT32 NICSumPLCPErrCnt(
+IN PRTMP_ADAPTER pAd)
+{
+ UCHAR Idx;
+ UINT32 PLCPErrCnt = 0;
+
+ for (Idx = 0; Idx < MLME_TASK_EXEC_MULTIPLE; Idx++)
+ PLCPErrCnt += pAd->RalinkCounters.PLCPErrCnt_100MS[Idx];
+
+ return PLCPErrCnt;
+}
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rtmp_init_inf.c b/cleopatre/devkit/mt7601udrv/common/rtmp_init_inf.c
new file mode 100644
index 0000000000..b33bab78e2
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rtmp_init_inf.c
@@ -0,0 +1,1094 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_init_inf.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+#include "rt_config.h"
+
+
+
+
+#ifdef LINUX
+#ifdef OS_ABL_FUNC_SUPPORT
+/* Utilities provided from NET module */
+RTMP_NET_ABL_OPS RtmpDrvNetOps, *pRtmpDrvNetOps = &RtmpDrvNetOps;
+RTMP_PCI_CONFIG RtmpPciConfig, *pRtmpPciConfig = &RtmpPciConfig;
+RTMP_USB_CONFIG RtmpUsbConfig, *pRtmpUsbConfig = &RtmpUsbConfig;
+
+VOID RtmpDrvOpsInit(
+ OUT VOID *pDrvOpsOrg,
+ INOUT VOID *pDrvNetOpsOrg,
+ IN RTMP_PCI_CONFIG *pPciConfig,
+ IN RTMP_USB_CONFIG *pUsbConfig)
+{
+ RTMP_DRV_ABL_OPS *pDrvOps = (RTMP_DRV_ABL_OPS *)pDrvOpsOrg;
+#ifdef RTMP_USB_SUPPORT
+ RTMP_NET_ABL_OPS *pDrvNetOps = (RTMP_NET_ABL_OPS *)pDrvNetOpsOrg;
+#endif /* RTMP_USB_SUPPORT */
+
+
+ /* init PCI/USB configuration in different OS */
+ if (pPciConfig != NULL)
+ RtmpPciConfig = *pPciConfig;
+
+ if (pUsbConfig != NULL)
+ RtmpUsbConfig = *pUsbConfig;
+
+ /* init operators provided from us (DRIVER module) */
+ pDrvOps->RTMPAllocAdapterBlock = RTMPAllocAdapterBlock;
+ pDrvOps->RTMPFreeAdapter = RTMPFreeAdapter;
+
+ pDrvOps->RtmpRaDevCtrlExit = RtmpRaDevCtrlExit;
+ pDrvOps->RtmpRaDevCtrlInit = RtmpRaDevCtrlInit;
+
+ pDrvOps->RTMPSendPackets = RTMPSendPackets;
+#ifdef MBSS_SUPPORT
+ pDrvOps->MBSS_PacketSend = MBSS_PacketSend;
+#endif /* MBSS_SUPPORT */
+#ifdef WDS_SUPPORT
+ pDrvOps->WDS_PacketSend = WDS_PacketSend;
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ pDrvOps->APC_PacketSend = APC_PacketSend;
+#endif /* APCLI_SUPPORT */
+
+ pDrvOps->RTMP_COM_IoctlHandle = RTMP_COM_IoctlHandle;
+#ifdef CONFIG_AP_SUPPORT
+ pDrvOps->RTMP_AP_IoctlHandle = RTMP_AP_IoctlHandle;
+#endif /* CONFIG_AP_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;
+#ifdef CONFIG_MULTI_CHANNEL
+ pRtmpDrvNetOps->RtmpDrvUsbBulkOutHCCANullFrameComplete = RTUSBBulkOutHCCANullFrameComplete;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+/* pRtmpDrvNetOps->RtmpDrvUsbBulkOutRTSFrameComplete = RTUSBBulkOutRTSFrameComplete;*/
+ pRtmpDrvNetOps->RtmpDrvUsbBulkOutPsPollComplete = RTUSBBulkOutPsPollComplete;
+ pRtmpDrvNetOps->RtmpDrvUsbBulkRxComplete = RTUSBBulkRxComplete;
+ pRtmpDrvNetOps->RtmpDrvUsbBulkCmdRspEventComplete = RTUSBBulkCmdRspEventComplete;
+ *pDrvNetOps = *pRtmpDrvNetOps;
+#endif /* RTMP_USB_SUPPORT */
+}
+
+RTMP_BUILD_DRV_OPS_FUNCTION_BODY
+
+#endif /* OS_ABL_FUNC_SUPPORT */
+#endif /* LINUX */
+
+
+int rt28xx_init(VOID *pAdSrc, PSTRING pDefaultMac, PSTRING pHostName)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pAdSrc;
+ UINT index;
+ NDIS_STATUS Status;
+
+ if (pAd == NULL)
+ return FALSE;
+
+// TODO: shiang-6590, fix me, we need a better place for this function call
+#ifdef RT6570
+ if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
+ ral_wlan_chip_onoff(pAd, TRUE, FALSE);
+#endif /* RT6570 */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd) && (pAd->WlanFunCtrl.field.WLAN_EN == 0))
+ MT7601_WLAN_ChipOnOff(pAd, TRUE, FALSE);
+#endif /* MT7601U */
+//---
+
+#ifdef RT3290
+ DBGPRINT(RT_DEBUG_OFF, ("MACVersion=0x%x\n", pAd->MACVersion));
+ if (IS_RT3290(pAd))
+ {
+ UINT32 MacRegValue;
+ OSCCTL_STRUC osCtrl = {.word = 0};
+ CMB_CTRL_STRUC cmbCtrl = {.word = 0};
+ WLAN_FUN_CTRL_STRUC WlanFunCtrl = {.word = 0};
+
+ RTMPEnableWlan(pAd, TRUE, TRUE);
+
+ RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &WlanFunCtrl.word);
+ if (WlanFunCtrl.field.WLAN_EN == TRUE)
+ {
+ WlanFunCtrl.field.PCIE_APP0_CLK_REQ = TRUE;
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word);
+ }
+
+ //Enable ROSC_EN first then CAL_REQ
+ RTMP_IO_READ32(pAd, OSCCTL, &osCtrl.word);
+ osCtrl.field.ROSC_EN = TRUE; /* HW force */
+ RTMP_IO_WRITE32(pAd, OSCCTL, osCtrl.word);
+
+ osCtrl.field.ROSC_EN = TRUE; /* HW force */
+ osCtrl.field.CAL_REQ = TRUE;
+ osCtrl.field.REF_CYCLE = 0x27;
+ RTMP_IO_WRITE32(pAd, OSCCTL, osCtrl.word);
+
+ RTMP_IO_READ32(pAd, CMB_CTRL, &cmbCtrl.word);
+ pAd->CmbCtrl.word = cmbCtrl.word;
+
+ /* Overwrite default Coex Parameter */
+ RTMP_IO_READ32(pAd, COEXCFG0, &MacRegValue);
+ MacRegValue &= ~(0xFF000000);
+ MacRegValue |= 0x5E000000;
+ RTMP_IO_WRITE32(pAd, COEXCFG0, MacRegValue);
+ }
+
+ if (IS_RT3290LE(pAd))
+ {
+ PLL_CTRL_STRUC PllCtrl;
+ RTMP_IO_READ32(pAd, PLL_CTRL, &PllCtrl.word);
+ PllCtrl.field.VCO_FIXED_CURRENT_CONTROL = 0x1;
+ RTMP_IO_WRITE32(pAd, PLL_CTRL, PllCtrl.word);
+ }
+#endif /* RT3290 */
+
+
+ /* reset Adapter flags*/
+ RTMP_CLEAR_FLAGS(pAd);
+
+ /* Init BssTab & ChannelInfo tabbles for auto channel select.*/
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ AutoChBssTableInit(pAd);
+ ChannelInfoInit(pAd);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#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;
+ if (WaitForAsicReady(pAd) != TRUE)
+ goto err1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MAC[Ver:Rev=0x%08x]\n", pAd->MACVersion));
+
+
+ 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);
+
+#ifdef RLT_MAC
+ /* Initialze MCU control before load fw */
+ MCUCtrlInit(pAd);
+#endif /* RLT_MAC */
+
+ /* Load MCU firmware*/
+ Status = NICLoadFirmware(pAd);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
+ goto err1;
+ }
+
+ /* 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;
+ }
+
+#ifdef WLAN_SKB_RECYCLE
+ skb_queue_head_init(&pAd->rx0_recycle);
+#endif /* WLAN_SKB_RECYCLE */
+
+ 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;
+
+ CfgInitHook(pAd);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APInitialize(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+#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;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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*/
+
+ DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
+
+ /* We should read EEPROM for all cases. rt2860b*/
+ NICReadEEPROMParameters(pAd, (PSTRING)pDefaultMac);
+
+ DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
+
+#ifdef LED_CONTROL_SUPPORT
+ /* Send LED Setting to MCU */
+ RTMPInitLEDMode(pAd);
+#endif /* LED_CONTROL_SUPPORT */
+
+ NICInitAsicFromEEPROM(pAd); /* rt2860b */
+
+#ifdef RALINK_ATE
+ if (ATEInit(pAd) != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): ATE initialization failed !\n", __FUNCTION__));
+ goto err6;
+ }
+#endif /* RALINK_ATE */
+
+
+#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_OFF, ("bAutoTxAgcG = %d\n", pAd->bAutoTxAgcG));
+
+ if (pAd->chipCap.bTempCompTxALC && pAd->bAutoTxAgcG)
+ InitLookupTable(pAd);
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+
+ /* Set PHY to appropriate mode*/
+ RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode);
+
+ /* 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 */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef AP_QLOAD_SUPPORT
+ QBSS_LoadInit(pAd);
+#endif /* AP_QLOAD_SUPPORT */
+ }
+#endif /* CONFIG_AP_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, FALSE);
+ RTMPusecDelay(10000);
+#endif /* RTMP_MAC_USB */
+
+#ifdef RALINK_ATE
+#endif /* RALINK_ATE */
+
+#ifdef CONFIG_AP_SUPPORT
+
+ /* Initialize RF register to default value*/
+
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /*
+ 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))
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+ }
+ }
+ 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 CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (pAd->ApCfg.bAutoChannelAtBootup || (pAd->CommonCfg.Channel == 0))
+ {
+ /* Enable Interrupt first due to we need to scan channel to receive beacons.*/
+ RTMP_IRQ_ENABLE(pAd);
+#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; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
+ {
+ RTUSBBulkReceive(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
+ }
+
+#endif /* RTMP_MAC_USB */
+ /* Now Enable RxTx*/
+ RTMPEnableRxTx(pAd);
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+ /* Let BBP register at 20MHz to do scan */
+ rtmp_bbp_set_bw(pAd, BW_20);
+ DBGPRINT(RT_DEBUG_ERROR, ("SYNC - BBP R4 to 20MHz.l\n"));
+
+ /* Now we can receive the beacon and do the listen beacon*/
+ /* use default BW to select channel*/
+ pAd->CommonCfg.Channel = AP_AUTO_CH_SEL(pAd, pAd->ApCfg.AutoChannelAlg);
+ pAd->ApCfg.bAutoChannelAtBootup = FALSE;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ /* If WMODE_CAP_N(phymode) and BW=40 check extension channel, after select channel */
+ N_ChannelCheck(pAd);
+
+#ifdef DOT11N_DRAFT3
+ /*
+ We only do this Overlapping BSS Scan when system up, for the
+ other situation of channel changing, we depends on station's
+ report to adjust ourself.
+ */
+ if (pAd->CommonCfg.bForty_Mhz_Intolerant == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Disable 20/40 BSSCoex Channel Scan(BssCoex=%d, 40MHzIntolerant=%d)\n",
+ pAd->CommonCfg.bBssCoexEnable,
+ pAd->CommonCfg.bForty_Mhz_Intolerant));
+ }
+ else if(pAd->CommonCfg.bBssCoexEnable == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Enable 20/40 BSSCoex Channel Scan(BssCoex=%d)\n",
+ pAd->CommonCfg.bBssCoexEnable));
+ APOverlappingBSSScan(pAd);
+ }
+
+ RTMP_11N_D3_TimerInit(pAd);
+/* RTMPInitTimer(pAd, &pAd->CommonCfg.Bss2040CoexistTimer, GET_TIMER_FUNCTION(Bss2040CoexistTimeOut), pAd, FALSE);*/
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+ APStartUp(pAd);
+ DBGPRINT(RT_DEBUG_OFF, ("Main bssid = %02x:%02x:%02x:%02x:%02x:%02x\n",
+ PRINT_MAC(pAd->ApCfg.MBSSID[BSS0].Bssid)));
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#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; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
+ {
+ RTUSBBulkReceive(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
+ }
+#endif /* RTMP_MAC_USB */
+ }/* end of else*/
+
+ /* Set up the Mac address*/
+#ifdef CONFIG_AP_SUPPORT
+ RtmpOSNetDevAddrSet(pAd->OpMode, pAd->net_dev, &pAd->CurrentAddress[0], NULL);
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* Various AP function init*/
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#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, pAd->net_dev); os abl move to rt_main_dev.c*/
+#endif /* MBSS_SUPPORT */
+
+#ifdef WDS_SUPPORT
+/* RT28xx_WDS_Init(pAd, pAd->net_dev);*/
+#endif /* WDS_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+/* RT28xx_ApCli_Init(pAd, pAd->net_dev);*/
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef UAPSD_SUPPORT
+ UAPSD_Init(pAd);
+#endif /* UAPSD_SUPPORT */
+
+ /* assign function pointers*/
+#ifdef MAT_SUPPORT
+ /* init function pointers, used in OS_ABL */
+ RTMP_MATOpsInit(pAd);
+#endif /* MAT_SUPPORT */
+
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef MAT_SUPPORT
+ MATEngineInit(pAd);
+#endif /* MAT_SUPPORT */
+
+#ifdef CLIENT_WDS
+ CliWds_ProxyTabInit(pAd);
+#endif /* CLIENT_WDS */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* auto-fall back settings */
+#ifdef RANGE_EXTEND
+ RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, 0xedcba980);
+#endif // RANGE_EXTEND //
+#ifdef DOT11N_SS3_SUPPORT
+ if (pAd->CommonCfg.TxStream >= 3)
+ {
+ RTMP_IO_WRITE32(pAd, TX_FBK_CFG_3S_0, 0x12111008);
+ RTMP_IO_WRITE32(pAd, TX_FBK_CFG_3S_1, 0x16151413);
+ }
+#endif /* DOT11N_SS3_SUPPORT */
+
+#ifdef STREAM_MODE_SUPPORT
+ RtmpStreamModeInit(pAd);
+#endif /* STREAM_MODE_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef TXBF_SUPPORT
+ if (pAd->CommonCfg.ITxBfTimeout)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R179, 0x02);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, pAd->CommonCfg.ITxBfTimeout & 0xFF);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R180, 1);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R182, (pAd->CommonCfg.ITxBfTimeout>>8) & 0xFF);
+ }
+
+ if (pAd->CommonCfg.ETxBfTimeout)
+ {
+ RTMP_IO_WRITE32(pAd, TX_TXBF_CFG_3, pAd->CommonCfg.ETxBfTimeout);
+ }
+#endif /* TXBF_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+
+
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ {
+ WLAN_FUN_CTRL_STRUC WlanFunCtrl = {.word = 0};
+ RTMP_MAC_PWRSV_EN(pAd, TRUE, TRUE);
+ //
+ // Too much time for reading efuse(enter/exit L1), and our device will hang up
+ // Enable L1
+ //
+ RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &WlanFunCtrl.word);
+ if (WlanFunCtrl.field.WLAN_EN == TRUE)
+ {
+ WlanFunCtrl.field.PCIE_APP0_CLK_REQ = FALSE;
+ RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word);
+ }
+ }
+#endif /* RT3290 */
+
+ DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status));
+
+ return TRUE;
+
+/*err7:
+ APStop(pAd);*/
+err6:
+
+#ifdef IGMP_SNOOP_SUPPORT
+ MultiCastFilterTableReset(&pAd->pMulticastFilterTable);
+#endif /* IGMP_SNOOP_SUPPORT */
+
+ MeasureReqTabExit(pAd);
+ TpcReqTabExit(pAd);
+err5:
+ RtmpNetTaskExit(pAd);
+ UserCfgExit(pAd);
+err4:
+ MlmeHalt(pAd);
+ //RTMP_TimerListRelease(pAd);
+ RTMP_AllTimerListRelease(pAd);
+err3:
+ RtmpMgmtTaskExit(pAd);
+#ifdef RTMP_TIMER_TASK_SUPPORT
+ NdisFreeSpinLock(&pAd->TimerQLock);
+#endif /* RTMP_TIMER_TASK_SUPPORT */
+err2:
+#ifdef RESOURCE_PRE_ALLOC
+ RTMPResetTxRxRingMemory(pAd);
+#else
+ RTMPFreeTxRxRingMemory(pAd);
+#endif /* RESOURCE_PRE_ALLOC */
+
+err1:
+
+#ifdef RLT_MAC
+ MCUCtrlExit(pAd);
+#endif /* RLT_MAC */
+
+#ifdef CONFIG_AP_SUPPORT
+ /* Free BssTab & ChannelInfo tabbles.*/
+ AutoChBssTableDestroy(pAd);
+ ChannelInfoDestroy(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef RT3290
+ if (IS_RT3290(pAd))
+ RTMPEnableWlan(pAd, FALSE, FALSE);
+#endif /* RT3290 */
+
+#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 init fail !!!\n"));
+ return FALSE;
+}
+
+
+VOID RTMPDrvOpen(
+ IN VOID *pAdSrc)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc;
+
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP);
+
+
+#ifdef FPGA_MODE
+#ifdef CUSTOMER_DEMO
+ set_fpga_mode(pAd, "6");
+#endif /* CUSTOMER_DEMO */
+#endif /* FPGA_MODE */
+
+ /* 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, &reg); /* clear garbage interrupts*/
+ printk("0x1300 = %08x\n", reg);
+ }
+
+ {
+/* u32 reg;*/
+/* UINT8 byte;*/
+/* u16 tmp;*/
+
+/* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);*/
+
+/* tmp = 0x0805;*/
+/* reg = (reg & 0xffff0000) | tmp;*/
+/* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);*/
+
+ }
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef BG_FT_SUPPORT
+ BG_FTPH_Init();
+#endif /* BG_FT_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+//+++Add by shiang for debug
+ DBGPRINT(RT_DEBUG_OFF, ("%s(1):Check if PDMA is idle!\n", __FUNCTION__));
+ AsicWaitPDMAIdle(pAd, 5, 10);
+//---Add by shiang for debug
+
+//+++Add by shiang for debug
+ DBGPRINT(RT_DEBUG_OFF, ("%s(2):Check if PDMA is idle!\n", __FUNCTION__));
+ AsicWaitPDMAIdle(pAd, 5, 10);
+//---Add by shiang for debug
+
+
+#ifdef WSC_INCLUDED
+#ifdef CONFIG_AP_SUPPORT
+ if ((pAd->OpMode == OPMODE_AP)
+ )
+ {
+ INT index;
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+#ifdef HOSTAPD_SUPPORT
+ if (pAd->ApCfg.MBSSID[index].Hostapd == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WPS is control by hostapd now.\n"));
+ }
+ else
+#endif /*HOSTAPD_SUPPORT*/
+ {
+ PWSC_CTRL pWscControl;
+ UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ pWscControl = &pAd->ApCfg.MBSSID[index].WscControl;
+ DBGPRINT(RT_DEBUG_TRACE, ("Generate UUID for apidx(%d)\n", index));
+ if (NdisEqualMemory(&pWscControl->Wsc_Uuid_E[0], zeros16, UUID_LEN_HEX))
+ WscGenerateUUID(pAd, &pWscControl->Wsc_Uuid_E[0], &pWscControl->Wsc_Uuid_Str[0], index, FALSE);
+ WscInit(pAd, FALSE, index);
+ }
+ }
+
+#ifdef APCLI_SUPPORT
+ for(index = 0; index < MAX_APCLI_NUM; index++)
+ {
+ PWSC_CTRL pWpsCtrl = &pAd->ApCfg.ApCliTab[index].WscControl;
+
+ pWpsCtrl->pAd = pAd;
+ NdisZeroMemory(pWpsCtrl->EntryAddr, MAC_ADDR_LEN);
+ pWpsCtrl->WscConfigMethods= 0x018C;
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_WSC_INIT, 0, (VOID *)&pAd->ApCfg.ApCliTab[index], index);
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* WSC hardware push button function 0811 */
+ WSC_HDR_BTN_Init(pAd);
+#endif /* WSC_INCLUDED */
+
+#ifdef CONFIG_MULTI_CHANNEL
+ MultiChannelThreadInit(pAd);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+}
+
+
+VOID RTMPDrvClose(
+ IN VOID *pAdSrc,
+ IN VOID *net_dev)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc;
+ BOOLEAN Cancelled;
+ UINT32 i = 0;
+
+
+ Cancelled = FALSE;
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef BG_FT_SUPPORT
+ BG_FTPH_Remove();
+#endif /* BG_FT_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+#if ((defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)) && defined(WOW_IFDOWN_SUPPORT)
+ if (pAd->WOW_Cfg.bEnable == FALSE)
+#endif /* ((defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)) && defined(WOW_IFDOWN_SUPPORT) */
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ }
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ if (pAd->CommonCfg.pChDesp != NULL)
+ os_free_mem(NULL, pAd->CommonCfg.pChDesp);
+ pAd->CommonCfg.pChDesp = NULL;
+ pAd->CommonCfg.DfsType = MAX_RD_REGION;
+#endif /* EXT_BUILD_CHANNEL_LIST */
+ pAd->CommonCfg.bCountryFlag = FALSE;
+
+
+
+#ifdef WDS_SUPPORT
+ WdsDown(pAd);
+#endif /* WDS_SUPPORT */
+
+ for (i = 0 ; i < NUM_OF_TX_RING; i++)
+ {
+ while (pAd->DeQueueRunning[i] == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i));
+ RTMPusecDelay(1000);
+ }
+ }
+
+#ifdef RTMP_MAC_USB
+ RtmpOsUsbEmptyUrbCheck(&pAd->wait, &pAd->BulkInLock, &pAd->PendingRx);
+
+#endif /* RTMP_MAC_USB */
+
+#ifdef CONFIG_AP_SUPPORT
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef RTMP_MAC_USB
+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+#endif /* RTMP_MAC_USB */
+
+#ifdef DOT11N_DRAFT3
+ if (pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_TIMER_FIRED)
+ {
+ RTMPCancelTimer(&pAd->CommonCfg.Bss2040CoexistTimer, &Cancelled);
+ pAd->CommonCfg.Bss2040CoexistFlag = 0;
+ }
+#endif /* DOT11N_DRAFT3 */
+
+ /* PeriodicTimer already been canceled by MlmeHalt() API.*/
+ /*RTMPCancelTimer(&pAd->PeriodicTimer, &Cancelled);*/
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* Stop Mlme state machine*/
+ MlmeHalt(pAd);
+
+ /* Close net tasklets*/
+ RtmpNetTaskExit(pAd);
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef MAT_SUPPORT
+ MATEngineExit(pAd);
+#endif /* MAT_SUPPORT */
+
+#ifdef CLIENT_WDS
+ CliWds_ProxyTabDestory(pAd);
+#endif /* CLIENT_WDS */
+ /* Shutdown Access Point function, release all related resources */
+ APShutdown(pAd);
+
+/*#ifdef AUTO_CH_SELECT_ENHANCE*/
+ /* Free BssTab & ChannelInfo tabbles.*/
+/* AutoChBssTableDestroy(pAd); */
+/* ChannelInfoDestroy(pAd); */
+/*#endif AUTO_CH_SELECT_ENHANCE */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ MeasureReqTabExit(pAd);
+ TpcReqTabExit(pAd);
+
+#ifdef LED_CONTROL_SUPPORT
+ RTMPExitLEDMode(pAd);
+#endif // LED_CONTROL_SUPPORT
+
+ /* Close kernel threads*/
+ RtmpMgmtTaskExit(pAd);
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* must after RtmpMgmtTaskExit(); Or pAd->pChannelInfo will be NULL */
+ /* Free BssTab & ChannelInfo tabbles.*/
+ AutoChBssTableDestroy(pAd);
+ ChannelInfoDestroy(pAd);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef RLT_MAC
+ MCUCtrlExit(pAd);
+#endif /* RLT_MAC */
+
+ /* Free IRQ*/
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+ }
+
+#ifdef SINGLE_SKU_V2
+ {
+ CH_POWER *ch, *ch_temp;
+ ch = pAd->SingleSkuPwrList.pHead;
+ while (ch )
+ {
+ ch_temp = ch->pNext;
+ delEntryList(&pAd->SingleSkuPwrList, (PLIST_ENTRY)ch);
+ os_free_mem(NULL, ch->Channel);
+ os_free_mem(NULL, ch);
+ ch = ch_temp;
+ }
+ }
+#endif /* SINGLE_SKU_V2 */
+
+ /* 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 WLAN_SKB_RECYCLE
+ skb_queue_purge(&pAd->rx0_recycle);
+#endif /* WLAN_SKB_RECYCLE */
+
+#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 */
+
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+/*+++Modify by woody to solve the bulk fail+++*/
+
+ /* 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);
+ RTMP_AllTimerListRelease(pAd);
+
+#ifdef CONFIG_MULTI_CHANNEL
+ MultiChannelThreadExit(pAd);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+ NdisFreeSpinLock(&pAd->TimerQLock);
+#endif /* RTMP_TIMER_TASK_SUPPORT */
+}
+
+
+VOID RTMPInfClose(
+ IN VOID *pAdSrc)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc;
+
+
+#ifdef CONFIG_AP_SUPPORT
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = FALSE;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* kick out all STAs behind the bss.*/
+ MbssKickOutStas(pAd, MAIN_MBSSID, REASON_DISASSOC_INACTIVE);
+ }
+
+ APMakeAllBssBeacon(pAd);
+ APUpdateAllBeaconFrame(pAd);
+#endif /* CONFIG_AP_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;
+}
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rtmp_timer.c b/cleopatre/devkit/mt7601udrv/common/rtmp_timer.c
new file mode 100644
index 0000000000..b3ece739e0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rtmp_timer.c
@@ -0,0 +1,358 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2008, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_timer.c
+
+ Abstract:
+ task for timer handling
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Shiang Tu 08-28-2008 init version
+
+*/
+
+#include "rt_config.h"
+
+
+BUILD_TIMER_FUNCTION(MlmePeriodicExec);
+/*BUILD_TIMER_FUNCTION(MlmeRssiReportExec);*/
+BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+BUILD_TIMER_FUNCTION(APSDPeriodicExec);
+BUILD_TIMER_FUNCTION(EnqueueStartForPSKExec);
+
+
+
+#ifdef CONFIG_MULTI_CHANNEL
+BUILD_TIMER_FUNCTION(MCC_ChangeAction);
+BUILD_TIMER_FUNCTION(ConcurrentP2PConnectTimeout);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+#ifdef RTMP_MAC_USB
+BUILD_TIMER_FUNCTION(BeaconUpdateExec);
+#endif /* RTMP_MAC_USB */
+
+#ifdef CONFIG_AP_SUPPORT
+extern VOID APDetectOverlappingExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BUILD_TIMER_FUNCTION(APDetectOverlappingExec);
+
+#ifdef DOT11N_DRAFT3
+BUILD_TIMER_FUNCTION(Bss2040CoexistTimeOut);
+#endif /* DOT11N_DRAFT3 */
+
+BUILD_TIMER_FUNCTION(GREKEYPeriodicExec);
+BUILD_TIMER_FUNCTION(CMTimerExec);
+BUILD_TIMER_FUNCTION(WPARetryExec);
+#ifdef AP_SCAN_SUPPORT
+BUILD_TIMER_FUNCTION(APScanTimeout);
+#endif /* AP_SCAN_SUPPORT */
+BUILD_TIMER_FUNCTION(APQuickResponeForRateUpExec);
+#ifdef IDS_SUPPORT
+BUILD_TIMER_FUNCTION(RTMPIdsPeriodicExec);
+#endif /* IDS_SUPPORT */
+
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef WSC_INCLUDED
+BUILD_TIMER_FUNCTION(WscEAPOLTimeOutAction);
+BUILD_TIMER_FUNCTION(Wsc2MinsTimeOutAction);
+BUILD_TIMER_FUNCTION(WscUPnPMsgTimeOutAction);
+BUILD_TIMER_FUNCTION(WscM2DTimeOutAction);
+
+BUILD_TIMER_FUNCTION(WscPBCTimeOutAction);
+BUILD_TIMER_FUNCTION(WscScanTimeOutAction);
+BUILD_TIMER_FUNCTION(WscProfileRetryTimeout);
+#ifdef WSC_LED_SUPPORT
+BUILD_TIMER_FUNCTION(WscLEDTimer);
+BUILD_TIMER_FUNCTION(WscSkipTurnOffLEDTimer);
+#endif /* WSC_LED_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+BUILD_TIMER_FUNCTION(WscUpdatePortCfgTimeout);
+#ifdef WSC_V2_SUPPORT
+BUILD_TIMER_FUNCTION(WscSetupLockTimeout);
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#endif /* WSC_INCLUDED */
+
+
+
+#ifdef TXBF_SUPPORT
+BUILD_TIMER_FUNCTION(eTxBfProbeTimerExec);
+#endif /* TXBF_SUPPORT */
+
+
+#ifdef RALINK_ATE
+BUILD_TIMER_FUNCTION(ATEPeriodicExec);
+#endif /* RALINK_ATE */
+
+#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 <TIMER_QUEUE_SIZE_MAX; i++)
+ {
+ pQNode->pNext = pEntry;
+ pEntry = pQNode;
+ pQNode++;
+ }
+ pAd->TimerQ.pQPollFreeList = pEntry;
+ pAd->TimerQ.pQHead = NULL;
+ pAd->TimerQ.pQTail = NULL;
+ pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
+ RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+ }
+}
+#endif /* RTMP_TIMER_TASK_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rtusb_bulk.c b/cleopatre/devkit/mt7601udrv/common/rtusb_bulk.c
new file mode 100644
index 0000000000..31a2b2f6d5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rtusb_bulk.c
@@ -0,0 +1,1693 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtusb_bulk.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-25-2004 created
+
+*/
+
+#ifdef RTMP_MAC_USB
+
+
+#include "rt_config.h"
+/* Match total 6 bulkout endpoint to corresponding queue.*/
+
+#ifdef CONFIG_MULTI_CHANNEL
+UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_HCCA, FIFO_MGMT};
+#else
+UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+
+
+#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;i<NUM_OF_TX_RING;i++)
+ {
+
+ if (pAd->TxContext[i].CurWritePosition>=pAd->TxContext[i].ENextBulkOutPosition)
+ {
+ PacketsInQueueSize=pAd->TxContext[i].CurWritePosition-pAd->TxContext[i].ENextBulkOutPosition;
+ }
+ else
+ {
+ PacketsInQueueSize=MAX_TXBULK_SIZE-pAd->TxContext[i].ENextBulkOutPosition+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 (RunningQueueNo<pAd->LastRunningQueueNo)
+ {
+ 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;QueIdx<NUM_OF_TX_RING;QueIdx++)
+ {
+ HighWorkingAcCount=0;
+ for (i=0;i<NUM_OF_TX_RING;i++)
+ {
+ if (QueIdx==i)
+ continue;
+
+ if (pAd->BulkOutDataFlag[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 */
+
+
+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;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ 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,
+ pChipCap->WMM0ACBulkOutAddr[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*/
+ if (BulkOutPipeId == MGMTPIPEIDX) //Use EP9
+ {
+ RTUSB_FILL_TX_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ pChipCap->CommandBulkOutAddr,
+ pSrc,
+ pTxContext->BulkOutSize,
+ Func,
+ pTxContext,
+ pTxContext->data_dma);
+
+ }
+ else
+ {
+ RTUSB_FILL_TX_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ pChipCap->WMM0ACBulkOutAddr[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;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ pUrb = pTxContext->pUrb;
+ ASSERT(pUrb);
+
+ /* Store BulkOut PipeId*/
+ pTxContext->BulkOutPipeId = BulkOutPipeId;
+
+ pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
+
+ /*Initialize a tx bulk urb*/
+ if (BulkOutPipeId == 4) //Use EP9
+ {
+
+ RTUSB_FILL_HTTX_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ pChipCap->WMM1ACBulkOutAddr,
+ pSrc,
+ BulkOutSize,
+ Func,
+ pTxContext,
+ (pTxContext->data_dma + pTxContext->NextBulkOutPosition));
+ }
+ else
+ {
+ RTUSB_FILL_HTTX_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ pChipCap->WMM0ACBulkOutAddr[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;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ 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,
+ pChipCap->DataBulkInAddr,
+ &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
+ RX_bulk_size - (pAd->NextRxBulkInPosition),
+ RtmpUsbBulkRxComplete,
+ (void *)pRxContext,
+ (pRxContext->data_dma + pAd->NextRxBulkInPosition));
+}
+
+
+VOID RTUSBInitCmdRspEventDesc(
+ PRTMP_ADAPTER pAd,
+ PCMD_RSP_CONTEXT pCmdRspEventContext)
+{
+ PURB pUrb = pCmdRspEventContext->pUrb;
+ POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ //printk("%s, Bulk In add = 0x%x\n", __FUNCTION__, pAd->BulkInEpAddr[1]);
+ /* Initialize command response event URB */
+ RTUSB_FILL_RX_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ pChipCap->CommandRspBulkInAddr,
+ pCmdRspEventContext->CmdRspBuffer,
+ CMD_RSP_BULK_SIZE,
+ RTUSBBulkCmdRspEventComplete,
+ (void *)pCmdRspEventContext,
+ pCmdRspEventContext->data_dma);
+
+}
+
+
+/*
+ ========================================================================
+
+ 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;
+ TXINFO_STRUC *pTxInfo, *pLastTxInfo = NULL;
+ TXWI_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 = (TXINFO_STRUC *)&pWirelessPkt[TmpBulkEndPos];
+ pTxWI = (TXWI_STRUC *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
+
+ if (pAd->bForcePrintTX == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->TxWIAMPDU));
+
+ /* 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->TxWIPHYMODE == 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
+ {
+
+
+#ifdef RT65xx
+ if (((ThisBulkSize&0xfffe0000) != 0) || ((ThisBulkSize&0x10000) == 0x10000))
+#else
+ if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
+#endif /* RT65xx */
+ { /* 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;
+ }
+
+#ifndef CONFIG_MULTI_CHANNEL
+ if (pTxInfo->TxInfoQSEL != FIFO_EDCA)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n",
+ __FUNCTION__, pTxInfo->TxInfoQSEL));
+ 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));
+ }
+#endif /* !CONFIG_MULTI_CHANNEL */
+
+ if (pTxInfo->TxInfoPktLen <= 8)
+ {
+ BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+ DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, TxInfoPktLen==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->TxInfoPktLen=%d!\n", pTxInfo->TxInfoPktLen));*/
+ return;
+ }
+
+ /* Increase Total transmit byte counter*/
+ pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->TxWIMPDUByteCnt;
+ pAd->RalinkCounters.TransmittedByteCount += pTxWI->TxWIMPDUByteCnt;
+
+ pLastTxInfo = pTxInfo;
+
+ /* Make sure we use EDCA QUEUE. */
+#ifndef CONFIG_MULTI_CHANNEL
+ pTxInfo->TxInfoQSEL = FIFO_EDCA;
+#endif /* !CONFIG_MULTI_CHANNEL */
+ ThisBulkSize += (pTxInfo->TxInfoPktLen+4);
+ TmpBulkEndPos += (pTxInfo->TxInfoPktLen+4);
+
+ if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
+ pTxInfo->TxInfoUDMANextVld = 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->TxInfoSwLstRnd == 1)
+ {
+ if (pHTTXContext->CurWritePosition == 8)
+ pTxInfo->TxInfoUDMANextVld = 0;
+ pTxInfo->TxInfoSwLstRnd = 0;
+
+ bTxQLastRound = TRUE;
+ pHTTXContext->ENextBulkOutPosition = 8;
+
+ #ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+ RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
+ #endif /* RT_BIG_ENDIAN */
+
+ break;
+ }
+#endif /* USB_BULK_BUF_ALIGMENT */
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+ RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
+#endif /* RT_BIG_ENDIAN */
+
+ }while (TRUE);
+
+ /* adjust the pTxInfo->TxInfoUDMANextVld value of last pTxInfo.*/
+ if (pLastTxInfo)
+ {
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
+#endif /* RT_BIG_ENDIAN */
+ pLastTxInfo->TxInfoUDMANextVld = 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[0]);
+ 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);
+
+}
+
+
+#ifdef CONFIG_MULTI_CHANNEL
+
+USBHST_STATUS RTUSBBulkOutHCCANullFrameComplete(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->hcca_null_frame_complete_task, (unsigned long)pURB);
+ RTMP_OS_TASKLET_SCHE(&pObj->hcca_null_frame_complete_task);
+
+}
+
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+
+/*
+ ========================================================================
+
+ 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*/
+#ifdef CONFIG_MULTI_CHANNEL
+ if (pAd->Multi_Channel_Enable == TRUE)
+ RTUSBInitTxDesc(pAd, pPsPollContext, 0, (usb_complete_t)RtmpUsbBulkOutPsPollComplete);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+ 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));
+ }
+}
+
+
+VOID BulkInCmdRspEvent(RTMP_ADAPTER *pAd)
+{
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+ PURB pURB;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->CmdRspLock, IrqFlags);
+ if ( (pCmdRspEventContext->Readable == TRUE) || (pCmdRspEventContext->InUse == TRUE))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+ return;
+ }
+ pCmdRspEventContext->InUse = TRUE;
+ pCmdRspEventContext->IRPPending = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+
+ RTUSBInitCmdRspEventDesc(pAd, pCmdRspEventContext);
+ pURB = pCmdRspEventContext->pUrb;
+
+ if ((ret = RTUSB_SUBMIT_URB(pURB)) != 0)
+ {
+ RTMP_IRQ_LOCK(&pAd->CmdRspLock, IrqFlags);
+ pCmdRspEventContext->InUse = FALSE;
+ pCmdRspEventContext->IRPPending = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("%s success\n", __FUNCTION__));
+ }
+
+}
+
+
+/*
+ ========================================================================
+
+ 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)
+ && !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE))
+ 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APRxDoneInterruptHandle(pAd);
+#endif /* CONFIG_AP_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)
+ && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE)))))
+ {
+
+ DoBulkIn(pAd);
+ }
+
+}
+
+#ifdef RLT_MAC
+VOID RTUSBBulkCmdRspEventReceive(PRTMP_ADAPTER pAd)
+{
+ unsigned long IrqFlags;
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+
+ RTMP_IRQ_LOCK(&pAd->CmdRspLock, IrqFlags);
+ if ((pCmdRspEventContext->InUse) == FALSE && (pCmdRspEventContext->Readable == TRUE))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+ CmdRspEventHandle(pAd);
+
+
+ RTMP_IRQ_LOCK(&pAd->CmdRspLock, IrqFlags);
+ pCmdRspEventContext->Readable = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+ }
+
+ if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) )
+ BulkInCmdRspEvent(pAd);
+}
+#endif /* RTL_MAC */
+
+/*
+ ========================================================================
+
+ 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);
+
+}
+
+//void RTUSBBulkCmdRspEventComplete(purbb_t pURB)
+USBHST_STATUS RTUSBBulkCmdRspEventComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
+{
+
+ PRX_CONTEXT pCmdRspEventContext;
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+
+ pCmdRspEventContext = (PRX_CONTEXT)RTMP_OS_USB_CONTEXT_GET(pURB);
+ pAd = pCmdRspEventContext->pAd;
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ RTMP_NET_TASK_DATA_ASSIGN(&pObj->cmd_rsp_event_task, (unsigned long)pURB);
+ RTMP_OS_TASKLET_SCHE(&pObj->cmd_rsp_event_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]);
+ }
+ }
+#ifdef CONFIG_MULTI_CHANNEL
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_HCCA))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ || P2P_GO_ON(pAd) || P2P_CLI_ON(pAd)
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, HCCA_PIPE, pAd->NextBulkOutIndex[HCCA_PIPE]);
+ }
+ }
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+ /* 7. Null frame is the last*/
+ else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
+ {
+#ifdef CONFIG_MULTI_CHANNEL
+ if (INFRA_ON(pAd) && (pAd->CommonCfg.Channel == pAd->LatchRfRegs.Channel ||
+ pAd->CommonCfg.CentralChannel== pAd->LatchRfRegs.Channel ))
+#else
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+#endif /* CONFIG_MULTI_CHANNEL */
+ {
+ RTUSBBulkOutNullFrame(pAd);
+ }
+ }
+#ifdef CONFIG_MULTI_CHANNEL
+ else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL_HCCA))
+ {
+ if (INFRA_ON(pAd) && (pAd->CommonCfg.Channel == pAd->LatchRfRegs.Channel ||
+ pAd->CommonCfg.CentralChannel== pAd->LatchRfRegs.Channel ))
+ RTUSBBulkOutNullFrame(pAd);
+ }
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+
+
+ /* 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;
+ PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext;
+ 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--;*/
+ }
+ }
+
+ if (pCmdRspEventContext->IRPPending == TRUE)
+ {
+ printk("unlink cmd rsp urb\n");
+ RTUSB_UNLINK_URB(pCmdRspEventContext->pUrb);
+ pCmdRspEventContext->IRPPending = FALSE;
+ pCmdRspEventContext->InUse = FALSE;
+ }
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCancelPendingBulkOutIRP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PHT_TX_CONTEXT pHTTXContext;
+ PTX_CONTEXT pMLMEContext;
+ PTX_CONTEXT pNullContext;
+ PTX_CONTEXT pPsPollContext;
+ UINT i, Idx;
+/* unsigned int IrqFlags;*/
+/* NDIS_SPIN_LOCK *pLock;*/
+/* BOOLEAN *pPending;*/
+
+
+/* pLock = &pAd->BulkOutLock[MGMTPIPEIDX];*/
+/* pPending = &pAd->BulkOutPending[MGMTPIPEIDX];*/
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ pHTTXContext = &(pAd->TxContext[Idx]);
+
+ if (pHTTXContext->IRPPending == TRUE)
+ {
+
+ /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/
+ /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/
+ /* when the last IRP on the list has been cancelled; that's how we exit this loop*/
+
+
+ RTUSB_UNLINK_URB(pHTTXContext->pUrb);
+
+ /* Sleep 200 microseconds to give cancellation time to work*/
+ RTMPusecDelay(200);
+ }
+
+#ifdef RALINK_ATE
+ pHTTXContext->bCopySavePad = 0;
+ pHTTXContext->CurWritePosition = 0;
+ pHTTXContext->CurWriteRealPos = 0;
+ pHTTXContext->bCurWriting = FALSE;
+ pHTTXContext->NextBulkOutPosition = 0;
+ pHTTXContext->ENextBulkOutPosition = 0;
+#endif /* RALINK_ATE */
+ pAd->BulkOutPending[Idx] = FALSE;
+ }
+
+ /*RTMP_IRQ_LOCK(pLock, IrqFlags);*/
+ for (i = 0; i < MGMT_RING_SIZE; i++)
+ {
+ pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+ if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
+ {
+
+ /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/
+ /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/
+ /* when the last IRP on the list has been cancelled; that's how we exit this loop*/
+
+
+ RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+ pMLMEContext->IRPPending = FALSE;
+
+ /* Sleep 200 microsecs to give cancellation time to work*/
+ RTMPusecDelay(200);
+ }
+ }
+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+ /*RTMP_IRQ_UNLOCK(pLock, IrqFlags);*/
+
+ pNullContext = &(pAd->NullContext);
+ if (pNullContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pNullContext->pUrb);
+
+ pPsPollContext = &(pAd->PsPollContext);
+ if (pPsPollContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pPsPollContext->pUrb);
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
+ pAd->BulkOutPending[Idx] = FALSE;
+ NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
+ }
+}
+
+#endif /* RTMP_MAC_USB */
diff --git a/cleopatre/devkit/mt7601udrv/common/rtusb_data.c b/cleopatre/devkit/mt7601udrv/common/rtusb_data.c
new file mode 100644
index 0000000000..321cc5a219
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rtusb_data.c
@@ -0,0 +1,31 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2005, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtusb_data.c
+
+ Abstract:
+ Ralink USB driver Tx/Rx functions.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan 03-25-2006 created
+
+*/
+
+
diff --git a/cleopatre/devkit/mt7601udrv/common/rtusb_dev_id.c b/cleopatre/devkit/mt7601udrv/common/rtusb_dev_id.c
new file mode 100644
index 0000000000..d3e03736a0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rtusb_dev_id.c
@@ -0,0 +1,48 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rtusb_dev_id.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#define RTMP_MODULE_OS
+
+/*#include "rt_config.h"*/
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rt_os_net.h"
+
+
+/* module table */
+USB_DEVICE_ID rtusb_dev_id[] = {
+#ifdef RT6570
+ {USB_DEVICE(0x148f,0x6570)}, /* Ralink 6570 */
+#endif /* RT6570 */
+ {USB_DEVICE(0x148f, 0x7650)}, /* MT7650 */
+#ifdef MT7601U
+ {USB_DEVICE(0x148f,0x6370)}, /* Ralink 6370 */
+ {USB_DEVICE(0x148f,0x7601)}, /* MT 6370 */
+#endif /* MT7601U */
+ { }/* Terminating entry */
+};
+
+INT const rtusb_usb_id_len = sizeof(rtusb_dev_id) / sizeof(USB_DEVICE_ID);
+MODULE_DEVICE_TABLE(usb, rtusb_dev_id);
diff --git a/cleopatre/devkit/mt7601udrv/common/rtusb_io.c b/cleopatre/devkit/mt7601udrv/common/rtusb_io.c
new file mode 100644
index 0000000000..11148338d9
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/rtusb_io.c
@@ -0,0 +1,2021 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtusb_io.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-25-2004 created
+*/
+
+#ifdef RTMP_MAC_USB
+
+
+#include "rt_config.h"
+
+#define MAX_VENDOR_REQ_RETRY_COUNT 10
+
+/*
+ ========================================================================
+
+ Routine Description: NIC initialization complete
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+
+static NTSTATUS RTUSBFirmwareRun(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x8,
+ 0,
+ NULL,
+ 0);
+
+ return Status;
+}
+
+
+
+/*
+ ========================================================================
+
+ Routine Description: Get current firmware operation mode (Return Value)
+
+ Arguments:
+
+ Return Value:
+ 0 or 1 = Downloaded by host driver
+ others = Driver doesn't download firmware
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBFirmwareOpmode(
+ IN PRTMP_ADAPTER pAd,
+ OUT PULONG pValue)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x1,
+ 0x11,
+ 0,
+ pValue,
+ 4);
+ return Status;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Write Firmware to NIC.
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBFirmwareWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFwImage,
+ IN ULONG FwLen)
+{
+ UINT32 MacReg;
+ NTSTATUS Status;
+/* ULONG i;*/
+ USHORT writeLen;
+ /*ULONG FMode = 0;*/
+
+
+ Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
+
+
+ /* write firmware */
+ writeLen = FwLen;
+#ifdef USB_FIRMWARE_MULTIBYTE_WRITE
+ DBGPRINT(RT_DEBUG_TRACE, ("USB_FIRMWARE_MULTIBYTE_WRITE defined! Write_Bytes = %d\n", MULTIWRITE_BYTES));
+ RTUSBMultiWrite_nBytes(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen, MULTIWRITE_BYTES);
+#else
+ DBGPRINT(RT_DEBUG_TRACE, ("USB_FIRMWARE_MULTIBYTE_WRITE not defined!\n"));
+ RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen, FALSE);
+#endif
+ Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff, FALSE);
+ Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff, FALSE);
+
+ /* change 8051 from ROM to RAM */
+ Status = RTUSBFirmwareRun(pAd);
+
+
+ return Status;
+}
+
+
+NTSTATUS RTUSBVenderReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+
+ pAd->VendorResetFlag = TRUE;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x1,
+ 0,
+ NULL,
+ 0);
+
+ pAd->VendorResetFlag = FALSE;
+
+ 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,
+ IN BOOLEAN bWriteHigh)
+{
+ 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, bWriteHigh);
+ index +=2;
+ length -= 2;
+ pSrc = pSrc + 2;
+ }while(length > 0);
+
+ return Status;
+}
+
+
+NTSTATUS RTUSBSingleWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN USHORT Value,
+ IN BOOLEAN WriteHigh)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ (WriteHigh == TRUE) ? 0x10 : 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 RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN UINT32 Value,
+ IN BOOLEAN bWriteHigh)
+{
+ NTSTATUS Status;
+ UINT32 localVal;
+
+ localVal = Value;
+ Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff), bWriteHigh);
+ Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16), bWriteHigh);
+
+ return Status;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Read 8-bit BBP register via firmware
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN PUCHAR pValue)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ int i, k, ret;
+
+
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
+ if (ret != 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ for (i=0; i<MAX_BUSY_COUNT; i++)
+ {
+ RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == BUSY)
+ continue;
+
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 1;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = Id;
+ RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word, FALSE);
+ AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0, TRUE);
+ for (k=0; k<MAX_BUSY_COUNT; k++)
+ {
+ RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == IDLE)
+ break;
+ }
+ if ((BbpCsr.field.Busy == IDLE) &&
+ (BbpCsr.field.RegNum == Id))
+ {
+ *pValue = (UCHAR)BbpCsr.field.Value;
+ break;
+ }
+ }
+
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+
+ if (BbpCsr.field.Busy == BUSY)
+ {
+ DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
+ *pValue = pAd->BbpWriteLatch[Id];
+ return STATUS_UNSUCCESSFUL;
+ }
+ return STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Write 8-bit BBP register via firmware
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN UCHAR Value)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ int BusyCnt;
+ int ret;
+
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
+ if (ret != 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
+ {
+ RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == BUSY)
+ continue;
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 0;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.Value = Value;
+ BbpCsr.field.RegNum = Id;
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
+ AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0, TRUE);
+ pAd->BbpWriteLatch[Id] = Value;
+ break;
+ }
+
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+
+ if (BusyCnt == MAX_BUSY_COUNT)
+ {
+ DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
+ return STATUS_UNSUCCESSFUL;
+ }
+ return STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Write RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 Value)
+{
+ RF_CSR_CFG0_STRUC PhyCsr4;
+ UINT i = 0;
+ NTSTATUS status;
+
+ NdisZeroMemory(&PhyCsr4, sizeof(RF_CSR_CFG0_STRUC));
+
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, status);
+ if (status != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", status));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ status = STATUS_UNSUCCESSFUL;
+ 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"));
+ goto done;
+ }
+
+ RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value, FALSE);
+ status = STATUS_SUCCESS;
+
+done:
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+
+ return status;
+}
+
+
+/*
+ ========================================================================
+
+ 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;
+ USHORT Value;
+
+ 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, FALSE);
+ RTUSBWriteMACRegister(pAd, 0x404, 0x30, FALSE);
+ /*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;
+ }
+
+
+ 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 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_MCU_SLEEP))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MCU has entered sleep mode\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+
+ int RetryCount = 0; /* RTUSB_CONTROL_MSG retry counts*/
+ ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
+
+ RTMP_SEM_EVENT_WAIT(&(pAd->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 && !pAd->VendorResetFlag) {
+ 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 && !pAd->VendorResetFlag) && (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 */
+
+
+ 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, FALSE);
+
+ /* 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, FALSE);
+ 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[0]);
+
+ 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 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);
+
+ /* It must be removed. Or ATE will have no RX success. */
+ 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, FALSE);
+ /* 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, FALSE);
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+static NTSTATUS DelAsicWcidHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ RT_SET_ASIC_WCID SetAsicWcid;
+ SetAsicWcid = *((PRT_SET_ASIC_WCID)(CMDQelmt->buffer));
+
+ if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
+ return NDIS_STATUS_FAILURE;
+
+ AsicDelWcidTab(pAd, (UCHAR)SetAsicWcid.WCID);
+
+ 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;
+}
+
+
+
+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;
+}
+
+
+static NTSTATUS UpdateProtectHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ PRT_ASIC_PROTECT_INFO pAsicProtectInfo;
+
+ pAsicProtectInfo = (PRT_ASIC_PROTECT_INFO)CMDQelmt->buffer;
+ AsicUpdateProtect(pAd, pAsicProtectInfo->OperationMode, pAsicProtectInfo->SetMask,
+ pAsicProtectInfo->bDisableBGProtect, pAsicProtectInfo->bNonGFExist);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+static NTSTATUS APUpdateCapabilityAndErpieHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ APUpdateCapabilityAndErpIe(pAd);
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef CONFIG_AP_SUPPORT
+static NTSTATUS _802_11_CounterMeasureHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+
+ pEntry = (MAC_TABLE_ENTRY *)CMDQelmt->buffer;
+ HandleCounterMeasure(pAd, pEntry);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+static NTSTATUS APEnableTXBurstHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ EDCA_AC_CFG_STRUC Ac0Cfg;
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::CMDTHREAD_AP_ENABLE_TX_BURST \n"));
+
+ RTUSBReadMACRegister(pAd, EDCA_AC0_CFG, &Ac0Cfg.word);
+ Ac0Cfg.field.AcTxop = 0x20;
+ RTUSBWriteMACRegister(pAd, EDCA_AC0_CFG, Ac0Cfg.word, FALSE);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static NTSTATUS APDisableTXBurstHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ EDCA_AC_CFG_STRUC Ac0Cfg;
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::CMDTHREAD_AP_DISABLE_TX_BURST \n"));
+
+ RTUSBReadMACRegister(pAd, EDCA_AC0_CFG, &Ac0Cfg.word);
+ Ac0Cfg.field.AcTxop = 0x0;
+ RTUSBWriteMACRegister(pAd, EDCA_AC0_CFG, Ac0Cfg.word, FALSE);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static NTSTATUS APAdjustEXPAckTimeHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::CMDTHREAD_AP_ADJUST_EXP_ACK_TIME \n"));
+ RTUSBWriteMACRegister(pAd, EXP_ACK_TIME, 0x005400ca, FALSE);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+static NTSTATUS APRecoverEXPAckTimeHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::CMDTHREAD_AP_RECOVER_EXP_ACK_TIME \n"));
+ RTUSBWriteMACRegister(pAd, EXP_ACK_TIME, 0x002400ca, FALSE);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* CONFIG_AP_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 WSC_INCLUDED
+#ifdef WSC_LED_SUPPORT
+/*WPS LED MODE 10*/
+static NTSTATUS LEDWPSMode10Hdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ UINT WPSLedMode10 = *((PUINT)(CMDQelmt->buffer));
+
+ DBGPRINT(RT_DEBUG_INFO, ("WPS LED mode 10::ON or Flash or OFF : %x\n", WPSLedMode10));
+
+ switch(WPSLedMode10)
+ {
+ case LINK_STATUS_WPS_MODE10_TURN_ON:
+ RTMPSetLEDStatus(pAd, LED_WPS_MODE10_TURN_ON);
+ break;
+ case LINK_STATUS_WPS_MODE10_FLASH:
+ RTMPSetLEDStatus(pAd,LED_WPS_MODE10_FLASH);
+ break;
+ case LINK_STATUS_WPS_MODE10_TURN_OFF:
+ RTMPSetLEDStatus(pAd, LED_WPS_MODE10_TURN_OFF);
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_INFO, ("WPS LED mode 10:: No this status %d!!!\n", WPSLedMode10));
+ break;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* WSC_LED_SUPPORT */
+#endif /* WSC_INCLUDED */
+
+
+#ifdef CONFIG_AP_SUPPORT
+static NTSTATUS ChannelRescanHdlr(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("cmd> Re-scan channel! \n"));
+
+ pAd->CommonCfg.Channel = AP_AUTO_CH_SEL(pAd, TRUE);
+#ifdef DOT11_N_SUPPORT
+ /* If WMODE_CAP_N(phymode) and BW=40 check extension channel, after select channel */
+ N_ChannelCheck(pAd);
+#endif /* DOT11_N_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("cmd> Switch to %d! \n", pAd->CommonCfg.Channel));
+ APStop(pAd);
+ APStartUp(pAd);
+
+#ifdef AP_QLOAD_SUPPORT
+ QBSS_LoadAlarmResume(pAd);
+#endif /* AP_QLOAD_SUPPORT */
+
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* CONFIG_AP_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 */
+
+
+
+#ifdef STREAM_MODE_SUPPORT
+static NTSTATUS UpdateTXChainAddress(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ AsicUpdateTxChainAddress(pAd, CMDQelmt->buffer);
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* STREAM_MODE_SUPPORT */
+
+#ifdef RLT_MAC
+extern CMD_RSP_HANDLER CmdRspHandlerTable[];
+
+static NTSTATUS CmdRspEventCallback(IN PRTMP_ADAPTER pAd, IN PCmdQElmt CMDQelmt)
+{
+ RXFCE_INFO_CMD *pFceInfo = CMDQelmt->buffer;
+
+ (*CmdRspHandlerTable[pFceInfo->evt_type])(pAd, CMDQelmt->buffer + sizeof(*pFceInfo));
+
+ return NDIS_STATUS_SUCCESS;
+}
+#endif /* RLT_MAC */
+
+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*/
+ DelAsicWcidHdlr, /* CMDTHREAD_DEL_ASIC_WCID*/
+ SetClientMACEntryHdlr, /* CMDTHREAD_SET_CLIENT_MAC_ENTRY*/
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+#ifdef CONFIG_AP_SUPPORT
+ APUpdateCapabilityAndErpieHdlr, /* CMDTHREAD_AP_UPDATE_CAPABILITY_AND_ERPIE*/
+ APEnableTXBurstHdlr, /* CMDTHREAD_AP_ENABLE_TX_BURST*/
+ APDisableTXBurstHdlr, /* CMDTHREAD_AP_DISABLE_TX_BURST*/
+ APAdjustEXPAckTimeHdlr, /* CMDTHREAD_AP_ADJUST_EXP_ACK_TIME*/
+ APRecoverEXPAckTimeHdlr, /* CMDTHREAD_AP_RECOVER_EXP_ACK_TIME*/
+ ChannelRescanHdlr, /* CMDTHREAD_CHAN_RESCAN*/
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef LED_CONTROL_SUPPORT
+ SetLEDStatusHdlr, /* CMDTHREAD_SET_LED_STATUS*/
+#else
+ NULL,
+#endif /* LED_CONTROL_SUPPORT */
+
+#ifdef WSC_INCLUDED
+#ifdef WSC_LED_SUPPORT
+ LEDWPSMode10Hdlr, /* CMDTHREAD_LED_WPS_MODE10*/
+#else
+ NULL,
+#endif /* WSC_LED_SUPPORT */
+
+#else
+ NULL,
+#endif /* WSC_INCLUDED */
+
+ /* 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*/
+
+ NULL,
+
+#ifdef CONFIG_AP_SUPPORT
+ _802_11_CounterMeasureHdlr, /* CMDTHREAD_802_11_COUNTER_MEASURE*/
+#else
+ NULL,
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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 */
+
+ NULL,
+
+ NULL,
+
+#ifdef STREAM_MODE_SUPPORT
+ UpdateTXChainAddress, /* CMDTHREAD_UPDATE_TX_CHAIN_ADDRESS */
+#else
+ NULL,
+#endif
+
+#ifdef RLT_MAC
+ CmdRspEventCallback, /* CMDTHREAD_RESPONSE_EVENT_CALLBACK */
+#endif /* RLT_MAC */
+};
+
+
+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;
+
+
+ return;
+
+ if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+
+ 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[0]);
+
+ if (pMLMEContext->IRPPending)
+ {
+ ASSERT(pMLMEContext->IRPPending);
+ pUrb = pMLMEContext->pUrb;
+ }
+ else if (pNULLContext->IRPPending)
+ {
+ ASSERT(pNULLContext->IRPPending);
+ pUrb = pNULLContext->pUrb;
+ }
+ else if (pPsPollContext->IRPPending)
+ {
+ ASSERT(pPsPollContext->IRPPending);
+ pUrb = pPsPollContext->pUrb;
+ }
+ }
+
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
+ if (pUrb)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
+ /* unlink it now*/
+ RTUSB_UNLINK_URB(pUrb);
+ /* Sleep 200 microseconds to give cancellation time to work*/
+ RTMPusecDelay(200);
+ needDumpSeq = TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
+ }
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+ }
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ /* For Sigma debug, dump the ba_reordering sequence.*/
+ if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ USHORT Idx;
+ PBA_REC_ENTRY pBAEntry = NULL;
+ UCHAR count = 0;
+ struct reordering_mpdu *mpdu_blk;
+
+ Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
+
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+ mpdu_blk = pBAEntry->list.next;
+ while (mpdu_blk)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
+ mpdu_blk = mpdu_blk->next;
+ count++;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+}
+
+#endif /* RTMP_MAC_USB */
diff --git a/cleopatre/devkit/mt7601udrv/common/scan.c b/cleopatre/devkit/mt7601udrv/common/scan.c
new file mode 100644
index 0000000000..fc2b90dc7e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/scan.c
@@ -0,0 +1,415 @@
+/*
+
+*/
+
+#include "rt_config.h"
+
+
+#ifdef SCAN_SUPPORT
+static INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode)
+{
+ INT bw, ch;
+
+ if (pAd->CommonCfg.BBPCurrentBW != pAd->hw_cfg.bbp_bw)
+ {
+ rtmp_bbp_set_bw(pAd, pAd->hw_cfg.bbp_bw);
+
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ ch = pAd->CommonCfg.CentralChannel;
+ }
+ else
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ ch = pAd->CommonCfg.Channel;
+
+ }
+
+ switch(pAd->CommonCfg.BBPCurrentBW)
+ {
+ case BW_80:
+ bw = 80;
+ break;
+ case BW_40:
+ bw = 40;
+ break;
+ case BW_10:
+ bw = 10;
+ break;
+ case BW_20:
+ default:
+ bw =20;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to %dMHz channel %d, Total BSS[%02d]\n",
+ bw, ch, pAd->ScanTab.BssNr));
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (OpMode == OPMODE_AP)
+ {
+
+ pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE;
+ RTMPResumeMsduTransmission(pAd);
+
+ /* iwpriv set auto channel selection*/
+ /* scanned all channels*/
+ if (pAd->ApCfg.bAutoChannelAtBootup==TRUE)
+ {
+ pAd->CommonCfg.Channel = SelectBestChannel(pAd, pAd->ApCfg.AutoChannelAlg);
+ pAd->ApCfg.bAutoChannelAtBootup = FALSE;
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+#endif /* DOT11_N_SUPPORT */
+ APStop(pAd);
+ APStartUp(pAd);
+ }
+
+ if (!((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE)))
+ AsicEnableBssSync(pAd);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ return TRUE;
+}
+
+
+
+static INT scan_active(RTMP_ADAPTER *pAd, UCHAR OpMode, UCHAR ScanType)
+{
+ UCHAR *frm_buf = NULL;
+ HEADER_802_11 Hdr80211;
+ ULONG FrameLen = 0;
+ UCHAR SsidLen = 0;
+
+
+ if (MlmeAllocateMemory(pAd, &frm_buf) != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ if (OpMode == OPMODE_AP)
+ pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE;
+#endif /* CONFIG_AP_SUPPORT */
+ return FALSE;
+ }
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (ScanType == SCAN_2040_BSS_COEXIST)
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("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)
+#ifdef WSC_STA_SUPPORT
+ || ((ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_STA))
+#endif /* WSC_STA_SUPPORT */
+ )
+ SsidLen = pAd->MlmeAux.SsidLen;
+
+ {
+#ifdef CONFIG_AP_SUPPORT
+ /*IF_DEV_CONFIG_OPMODE_ON_AP(pAd) */
+ if (OpMode == OPMODE_AP)
+ {
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR,
+ pAd->ApCfg.MBSSID[0].Bssid);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ MakeOutgoingFrame(frm_buf, &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(frm_buf + FrameLen, &Tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->CommonCfg.ExtRateLen,
+ pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
+ END_OF_ARGS);
+ FrameLen += Tmp;
+ }
+ }
+#ifdef DOT11_N_SUPPORT
+ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ 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(frm_buf + FrameLen, &Tmp,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(frm_buf + 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(frm_buf + FrameLen, &Tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(frm_buf + 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(frm_buf + FrameLen, &Tmp,
+ 1, &ExtHtCapIe,
+ 1, &HtLen,
+ 1, &pAd->CommonCfg.BSSCoexist2040.word,
+ END_OF_ARGS);
+
+ FrameLen += Tmp;
+ }
+#endif /* DOT11N_DRAFT3 */
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) &&
+ (pAd->MlmeAux.Channel > 14)) {
+ FrameLen += build_vht_ies(pAd, (UCHAR *)(frm_buf + FrameLen), SUBTYPE_PROBE_REQ);
+ }
+#endif /* DOT11_VHT_AC */
+
+#ifdef WSC_STA_SUPPORT
+ if (OpMode == OPMODE_STA)
+ {
+ BOOLEAN bHasWscIe = FALSE;
+ /*
+ Append WSC information in probe request if WSC state is running
+ */
+ if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) &&
+ (pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE) &&
+ (pAd->StaCfg.WscControl.bWscTrigger == TRUE))
+ bHasWscIe = TRUE;
+#ifdef WSC_V2_SUPPORT
+ else if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) &&
+ (pAd->StaCfg.WscControl.WscV2Info.bEnableWpsV2))
+ bHasWscIe = TRUE;
+#endif /* WSC_V2_SUPPORT */
+
+
+ if (bHasWscIe)
+ {
+ UCHAR *pWscBuf = NULL, WscIeLen = 0;
+ ULONG WscTmpLen = 0;
+
+ os_alloc_mem(NULL, (UCHAR **)&pWscBuf, 512);
+ if (pWscBuf != NULL)
+ {
+ NdisZeroMemory(pWscBuf, 512);
+ WscBuildProbeReqIE(pAd, STA_MODE, pWscBuf, &WscIeLen);
+
+ MakeOutgoingFrame(frm_buf + FrameLen, &WscTmpLen,
+ WscIeLen, pWscBuf,
+ END_OF_ARGS);
+
+ FrameLen += WscTmpLen;
+ os_free_mem(NULL, pWscBuf);
+ }
+ else
+ DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__));
+ }
+ }
+
+#endif /* WSC_STA_SUPPORT */
+
+
+
+ MiniportMMRequest(pAd, 0, frm_buf, FrameLen);
+
+
+ MlmeFreeMemory(pAd, frm_buf);
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Scan next channel
+ ==========================================================================
+ */
+VOID ScanNextChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR OpMode)
+{
+ UCHAR ScanType = pAd->MlmeAux.ScanType;
+ UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
+ BOOLEAN ScanPending = FALSE;
+ RALINK_TIMER_STRUCT *sc_timer;
+ UINT stay_time = 0;
+ UCHAR ImprovedScan_MaxScanChannelCnt;
+
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode. */
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+
+
+
+ if ((pAd->MlmeAux.Channel == 0) || ScanPending)
+ {
+ scan_ch_restore(pAd, OpMode);
+ }
+#ifdef RTMP_MAC_USB
+#endif /* RTMP_MAC_USB */
+ else
+ {
+
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+
+ /* Check if channel if passive scan under current regulatory domain */
+ if (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_PASSIVE_SCAN) == TRUE)
+ ScanType = SCAN_PASSIVE;
+
+
+ if (OpMode == OPMODE_AP)
+ sc_timer = &pAd->MlmeAux.APScanTimer;
+ else
+ sc_timer = &pAd->MlmeAux.ScanTimer;
+
+ /* 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)
+ stay_time = FAST_ACTIVE_SCAN_TIME;
+ else /* must be SCAN_PASSIVE or SCAN_ACTIVE*/
+ {
+
+#ifdef CONFIG_AP_SUPPORT
+ if ((OpMode == OPMODE_AP) && (pAd->ApCfg.bAutoChannelAtBootup))
+ stay_time = AUTO_CHANNEL_SEL_TIMEOUT;
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode) &&
+ WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ {
+ if (pAd->MlmeAux.Channel > 14)
+ stay_time = ScanTimeIn5gChannel;
+ else
+ stay_time = MIN_CHANNEL_TIME;
+ }
+#ifdef WIFI_P2P_CONCURRENT_FAST_SCAN
+ /* If this is not PASSIVE scan && Fast scan is enabled, we shorten the chanenl dwell time */
+ else if (ScanType != SCAN_PASSIVE && pAd->StaCfg.bImprovedScan)
+ stay_time = FAST_ACTIVE_SCAN_TIME;
+#endif /* WIFI_P2P_CONCURRENT_FAST_SCAN */
+ else
+ stay_time = MAX_CHANNEL_TIME;
+ }
+
+ RTMPSetTimer(sc_timer, stay_time);
+
+ if (SCAN_MODE_ACT(ScanType))
+ {
+ if (scan_active(pAd, OpMode, ScanType) == FALSE)
+ return;
+ }
+
+ /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse*/
+
+#ifdef CONFIG_AP_SUPPORT
+ if (OpMode == OPMODE_AP)
+ pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_LISTEN;
+#endif /* CONFIG_AP_SUPPORT */
+ }
+}
+
+
+BOOLEAN ScanRunning(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN rv = FALSE;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef AP_SCAN_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ rv = ((pAd->Mlme.ApSyncMachine.CurrState == AP_SCAN_LISTEN) ? TRUE : FALSE);
+#endif /* AP_SCAN_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ return rv;
+}
+
+#endif /* SCAN_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/spectrum.c b/cleopatre/devkit/mt7601udrv/common/spectrum.c
new file mode 100644
index 0000000000..7f94ed9098
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/spectrum.c
@@ -0,0 +1,2393 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ action.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Fonchi Wu 2008 created for 802.11h
+ */
+
+#include "rt_config.h"
+#include "action.h"
+
+
+/* The regulatory information in the USA (US) */
+DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] =
+{
+/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
+ {0, {0, 0, {0}}}, /* Invlid entry*/
+ {1, {4, 16, {36, 40, 44, 48}}},
+ {2, {4, 23, {52, 56, 60, 64}}},
+ {3, {4, 29, {149, 153, 157, 161}}},
+ {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
+ {5, {5, 30, {149, 153, 157, 161, 165}}},
+ {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
+ {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
+ {8, {5, 17, {11, 13, 15, 17, 19}}},
+ {9, {5, 30, {11, 13, 15, 17, 19}}},
+ {10, {2, 20, {21, 25}}},
+ {11, {2, 33, {21, 25}}},
+ {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}}
+};
+#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+/* The regulatory information in Europe */
+DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] =
+{
+/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
+ {0, {0, 0, {0}}}, /* Invalid entry*/
+ {1, {4, 20, {36, 40, 44, 48}}},
+ {2, {4, 20, {52, 56, 60, 64}}},
+ {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
+ {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}
+};
+#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+/* The regulatory information in Japan */
+DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] =
+{
+/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
+ {0, {0, 0, {0}}}, /* Invalid entry*/
+ {1, {4, 22, {34, 38, 42, 46}}},
+ {2, {3, 24, {8, 12, 16}}},
+ {3, {3, 24, {8, 12, 16}}},
+ {4, {3, 24, {8, 12, 16}}},
+ {5, {3, 24, {8, 12, 16}}},
+ {6, {3, 22, {8, 12, 16}}},
+ {7, {4, 24, {184, 188, 192, 196}}},
+ {8, {4, 24, {184, 188, 192, 196}}},
+ {9, {4, 24, {184, 188, 192, 196}}},
+ {10, {4, 24, {184, 188, 192, 196}}},
+ {11, {4, 22, {184, 188, 192, 196}}},
+ {12, {4, 24, {7, 8, 9, 11}}},
+ {13, {4, 24, {7, 8, 9, 11}}},
+ {14, {4, 24, {7, 8, 9, 11}}},
+ {15, {4, 24, {7, 8, 9, 11}}},
+ {16, {6, 24, {183, 184, 185, 187, 188, 189}}},
+ {17, {6, 24, {183, 184, 185, 187, 188, 189}}},
+ {18, {6, 24, {183, 184, 185, 187, 188, 189}}},
+ {19, {6, 24, {183, 184, 185, 187, 188, 189}}},
+ {20, {6, 17, {183, 184, 185, 187, 188, 189}}},
+ {21, {6, 24, {6, 7, 8, 9, 10, 11}}},
+ {22, {6, 24, {6, 7, 8, 9, 10, 11}}},
+ {23, {6, 24, {6, 7, 8, 9, 10, 11}}},
+ {24, {6, 24, {6, 7, 8, 9, 10, 11}}},
+ {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
+ {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
+ {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
+ {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
+ {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}}},
+ {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}},
+ {31, {1, 23, {14}}},
+ {32, {4, 22, {52, 56, 60, 64}}}
+};
+#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+UINT8 GetRegulatoryMaxTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 channel)
+{
+ ULONG RegulatoryClassLoop, ChIdx;
+ UINT8 RegulatoryClass;
+ UINT8 MaxRegulatoryClassNum;
+ PDOT11_REGULATORY_INFORMATION pRegulatoryClass;
+ PSTRING pCountry = (PSTRING)(pAd->CommonCfg.CountryCode);
+
+
+ if (strncmp(pCountry, "US", 2) == 0)
+ {
+ MaxRegulatoryClassNum = USA_REGULATORY_INFO_SIZE;
+ pRegulatoryClass = &USARegulatoryInfo[0];
+ }
+ else if (strncmp(pCountry, "JP", 2) == 0)
+ {
+ MaxRegulatoryClassNum = JP_REGULATORY_INFO_SIZE;
+ pRegulatoryClass = &JapanRegulatoryInfo[0];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
+ __FUNCTION__, pCountry));
+ return 0xff;
+ }
+
+ for (RegulatoryClassLoop = 0;
+ RegulatoryClassLoop<MAX_NUM_OF_REGULATORY_CLASS;
+ RegulatoryClassLoop++)
+ {
+ PDOT11_CHANNEL_SET pChannelSet;
+
+ RegulatoryClass = pAd->CommonCfg.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; ChIdx<pChannelSet->NumberOfChannels; 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 /* SINGLE_SKU */
+
+ /* check Tx Power setting from UI. */
+ if (pAd->CommonCfg.TxPowerPercentage > 90)
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */
+ CurTxPwr -= 1;
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */
+ CurTxPwr -= 3;
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */
+ CurTxPwr -= 6;
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */
+ CurTxPwr -= 9;
+ else /* reduce Pwr for 12 dB. */
+ CurTxPwr -= 12;
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ if (pAd->CommonCfg.CentralChannel > 14)
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+ }
+ }
+
+
+ switch(HTTxMode.field.MODE)
+ {
+ case MODE_CCK:
+ case MODE_OFDM:
+ Value = TxPwr[1];
+ TxPwrRef = (Value & 0x00000f00) >> 8;
+
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case MODE_HTMIX:
+ case MODE_HTGREENFIELD:
+ if (pAd->CommonCfg.TxStream == 1)
+ {
+ Value = TxPwr[2];
+ TxPwrRef = (Value & 0x00000f00) >> 8;
+ }
+ else if (pAd->CommonCfg.TxStream == 2)
+ {
+ Value = TxPwr[3];
+ TxPwrRef = (Value & 0x00000f00) >> 8;
+ }
+ break;
+#endif /* DOT11_N_SUPPORT */
+ }
+
+ PhyMode =
+#ifdef DOT11_N_SUPPORT
+ (HTTxMode.field.MODE == MODE_HTGREENFIELD)
+ ? MODE_HTMIX :
+#endif /* DOT11_N_SUPPORT */
+ HTTxMode.field.MODE;
+
+ for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++)
+ {
+ if ((TxPwrCfg[Idx].Mode == PhyMode)
+ && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS))
+ {
+ Value = TxPwr[TxPwrCfg[Idx].req];
+ DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask)
+ >> TxPwrCfg[Idx].shift);
+ CurTxPwr -= DaltaPwr;
+ break;
+ }
+ }
+
+ return CurTxPwr;
+}
+
+
+NDIS_STATUS MeasureReqTabInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ NdisAllocateSpinLock(pAd, &pAd->CommonCfg.MeasureReqTabLock);
+
+/* pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);*/
+ os_alloc_mem(pAd, (UCHAR **)&(pAd->CommonCfg.pMeasureReqTab), sizeof(MEASURE_REQ_TAB));
+ if (pAd->CommonCfg.pMeasureReqTab)
+ NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__));
+ Status = NDIS_STATUS_FAILURE;
+ }
+
+ return Status;
+}
+
+VOID MeasureReqTabExit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
+
+ if (pAd->CommonCfg.pMeasureReqTab)
+/* kfree(pAd->CommonCfg.pMeasureReqTab);*/
+ os_free_mem(NULL, pAd->CommonCfg.pMeasureReqTab);
+ pAd->CommonCfg.pMeasureReqTab = NULL;
+
+ return;
+}
+
+PMEASURE_REQ_ENTRY MeasureReqLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ UINT HashIdx;
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+
+ if (pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+ HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ pEntry = pTab->Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (pEntry->DialogToken == DialogToken)
+ break;
+ else
+ {
+ pPrevEntry = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+ return pEntry;
+}
+
+PMEASURE_REQ_ENTRY MeasureReqInsert(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ INT i;
+ ULONG HashIdx;
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
+ ULONG Now;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ pEntry = MeasureReqLookUp(pAd, DialogToken);
+ if (pEntry == NULL)
+ {
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry = &pTab->Content[i];
+
+ if ((pEntry->Valid == TRUE)
+ && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
+ {
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ /* update Hash list*/
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+ pTab->Size--;
+
+ break;
+ }
+
+ if (pEntry->Valid == FALSE)
+ break;
+ }
+
+ if (i < MAX_MEASURE_REQ_TAB_SIZE)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ pEntry->Valid = TRUE;
+ pEntry->DialogToken = DialogToken;
+ pTab->Size++;
+ }
+ else
+ {
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__));
+ }
+
+ /* add this Neighbor entry into HASH table*/
+ if (pEntry)
+ {
+ HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ if (pTab->Hash[HashIdx] == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pTab->Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ }
+
+ return pEntry;
+}
+
+VOID MeasureReqDelete(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ /* if empty, return*/
+ if (pTab->Size == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
+ return;
+ }
+
+ pEntry = MeasureReqLookUp(pAd, DialogToken);
+ if (pEntry != NULL)
+ {
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ /* update Hash list*/
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+ pTab->Size--;
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ }
+
+ return;
+}
+
+NDIS_STATUS TpcReqTabInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ NdisAllocateSpinLock(pAd, &pAd->CommonCfg.TpcReqTabLock);
+
+/* pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);*/
+ os_alloc_mem(pAd, (UCHAR **)&(pAd->CommonCfg.pTpcReqTab), sizeof(TPC_REQ_TAB));
+ if (pAd->CommonCfg.pTpcReqTab)
+ NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__));
+ Status = NDIS_STATUS_FAILURE;
+ }
+
+ return Status;
+}
+
+VOID TpcReqTabExit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
+
+ if (pAd->CommonCfg.pTpcReqTab)
+/* kfree(pAd->CommonCfg.pTpcReqTab);*/
+ os_free_mem(NULL, pAd->CommonCfg.pTpcReqTab);
+ pAd->CommonCfg.pTpcReqTab = NULL;
+
+ return;
+}
+
+static PTPC_REQ_ENTRY TpcReqLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ UINT HashIdx;
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL;
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+
+ if (pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+ HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ pEntry = pTab->Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (pEntry->DialogToken == DialogToken)
+ break;
+ else
+ {
+ pPrevEntry = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+ return pEntry;
+}
+
+
+static PTPC_REQ_ENTRY TpcReqInsert(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ INT i;
+ ULONG HashIdx;
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
+ ULONG Now;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ pEntry = TpcReqLookUp(pAd, DialogToken);
+ if (pEntry == NULL)
+ {
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+ for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry = &pTab->Content[i];
+
+ if ((pEntry->Valid == TRUE)
+ && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
+ {
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ /* update Hash list*/
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+ pTab->Size--;
+
+ break;
+ }
+
+ if (pEntry->Valid == FALSE)
+ break;
+ }
+
+ if (i < MAX_TPC_REQ_TAB_SIZE)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ pEntry->Valid = TRUE;
+ pEntry->DialogToken = DialogToken;
+ pTab->Size++;
+ }
+ else
+ {
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__));
+ }
+
+ /* add this Neighbor entry into HASH table*/
+ if (pEntry)
+ {
+ HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ if (pTab->Hash[HashIdx] == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pTab->Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+ }
+
+ return pEntry;
+}
+
+static VOID TpcReqDelete(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ /* if empty, return*/
+ if (pTab->Size == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
+ return;
+ }
+
+ pEntry = TpcReqLookUp(pAd, DialogToken);
+ if (pEntry != NULL)
+ {
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+ /* update Hash list*/
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+ pTab->Size--;
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get Current TimeS tamp.
+
+ Parametrs:
+
+ Return : Current Time Stamp.
+ ==========================================================================
+ */
+static UINT64 GetCurrentTimeStamp(
+ IN PRTMP_ADAPTER pAd)
+{
+ /* get current time stamp.*/
+ return 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get Current Transmit Power.
+
+ Parametrs:
+
+ Return : Current Time Stamp.
+ ==========================================================================
+ */
+static UINT8 GetCurTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 Wcid)
+{
+ return 16; /* 16 dBm */
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get Current Transmit Power.
+
+ Parametrs:
+
+ Return : Current Time Stamp.
+ ==========================================================================
+ */
+VOID InsertChannelRepIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PSTRING pCountry,
+ IN UINT8 RegulatoryClass)
+{
+ ULONG TempLen;
+ UINT8 Len;
+ UINT8 IEId = IE_AP_CHANNEL_REPORT;
+ PUCHAR pChListPtr = NULL;
+ PDOT11_CHANNEL_SET pChannelSet = NULL;
+
+ Len = 1;
+ if (strncmp(pCountry, "US", 2) == 0)
+ {
+ if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n",
+ __FUNCTION__, RegulatoryClass));
+ return;
+ }
+ pChannelSet = &USARegulatoryInfo[RegulatoryClass].ChannelSet;
+ }
+ else if (strncmp(pCountry, "JP", 2) == 0)
+ {
+ if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n",
+ __FUNCTION__, RegulatoryClass));
+ return;
+ }
+
+ pChannelSet = &JapanRegulatoryInfo[RegulatoryClass].ChannelSet;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
+ __FUNCTION__, pCountry));
+ return;
+ }
+
+ /* no match channel set. */
+ if (pChannelSet == NULL)
+ return;
+
+ /* empty channel set. */
+ if (pChannelSet->NumberOfChannels == 0)
+ return;
+
+ Len += pChannelSet->NumberOfChannels;
+ pChListPtr = pChannelSet->ChannelList;
+
+ if (Len > 1)
+ {
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &IEId,
+ 1, &Len,
+ 1, &RegulatoryClass,
+ Len -1, pChListPtr,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+ }
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Dialog Token into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Dialog token.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID InsertDialogToken(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 DialogToken)
+{
+ ULONG TempLen;
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &DialogToken,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert TPC Request IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+
+ Return : None.
+ ==========================================================================
+ */
+ static VOID InsertTpcReqIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen)
+{
+ ULONG TempLen;
+ UINT8 Len = 0;
+ UINT8 ElementID = IE_TPC_REQUEST;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert TPC Report IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Transmit Power.
+ 4. Link Margin.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID InsertTpcReportIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin)
+{
+ ULONG TempLen;
+ UINT8 Len = sizeof(TPC_REPORT_INFO);
+ UINT8 ElementID = IE_TPC_REPORT;
+ TPC_REPORT_INFO TpcReportIE;
+
+ TpcReportIE.TxPwr = TxPwr;
+ TpcReportIE.LinkMargin = LinkMargin;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, &TpcReportIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Measure Request IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Measure Token.
+ 4. Measure Request Mode.
+ 5. Measure Request Type.
+ 6. Measure Channel.
+ 7. Measure Start time.
+ 8. Measure Duration.
+
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertMeasureReqIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 Len,
+ IN PMEASURE_REQ_INFO pMeasureReqIE)
+{
+ ULONG TempLen;
+ UINT8 ElementID = IE_MEASUREMENT_REQUEST;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ sizeof(MEASURE_REQ_INFO), pMeasureReqIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Measure Report IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Measure Token.
+ 4. Measure Request Mode.
+ 5. Measure Request Type.
+ 6. Length of Report Infomation
+ 7. Pointer of Report Infomation Buffer.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertMeasureReportIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PMEASURE_REPORT_INFO pMeasureReportIE,
+ IN UINT8 ReportLnfoLen,
+ IN PUINT8 pReportInfo)
+{
+ ULONG TempLen;
+ UINT8 Len;
+ UINT8 ElementID = IE_MEASUREMENT_REPORT;
+
+ Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, pMeasureReportIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
+ {
+ MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
+ ReportLnfoLen, pReportInfo,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+ }
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID MakeMeasurementReqFrame(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pOutBuffer,
+ OUT PULONG pFrameLen,
+ IN UINT8 TotalLen,
+ IN UINT8 Category,
+ IN UINT8 Action,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT16 NumOfRepetitions)
+{
+ ULONG TempLen;
+ MEASURE_REQ_INFO MeasureReqIE;
+
+ InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action);
+
+ /* fill Dialog Token*/
+ InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken);
+
+ /* fill Number of repetitions. */
+ if (Category == CATEGORY_RM)
+ {
+ MakeOutgoingFrame((pOutBuffer+*pFrameLen), &TempLen,
+ 2, &NumOfRepetitions,
+ END_OF_ARGS);
+
+ *pFrameLen += TempLen;
+ }
+
+ /* prepare Measurement IE.*/
+ NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
+ MeasureReqIE.Token = MeasureToken;
+ MeasureReqIE.ReqMode.word = MeasureReqMode;
+ MeasureReqIE.ReqType = MeasureReqType;
+ InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen,
+ TotalLen, &MeasureReqIE);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 ReportInfoLen,
+ IN PUINT8 pReportInfo)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ HEADER_802_11 ActHdr;
+ MEASURE_REPORT_INFO MeasureRepIE;
+
+ /* build action frame header.*/
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
+
+ /* fill Dialog Token*/
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ /* prepare Measurement IE.*/
+ NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
+ MeasureRepIE.Token = MeasureToken;
+ MeasureRepIE.ReportMode = MeasureReqMode;
+ MeasureRepIE.ReportType = MeasureReqType;
+ InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UCHAR DialogToken)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ /* build action frame header.*/
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
+
+ /* fill Dialog Token*/
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ /* Insert TPC Request IE.*/
+ InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ /* build action frame header.*/
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
+
+ /* fill Dialog Token*/
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ /* Insert TPC Request IE.*/
+ InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+#ifdef WDS_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Insert Channel Switch Announcement IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. channel switch announcement mode.
+ 4. new selected channel.
+ 5. channel switch announcement count.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertChSwAnnIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewChannel,
+ IN UINT8 ChSwCnt)
+{
+ ULONG TempLen;
+ ULONG Len = sizeof(CH_SW_ANN_INFO);
+ UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+ CH_SW_ANN_INFO ChSwAnnIE;
+
+ ChSwAnnIE.ChSwMode = ChSwMode;
+ ChSwAnnIE.Channel = NewChannel;
+ ChSwAnnIE.ChSwCnt = ChSwCnt;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, &ChSwAnnIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Channel Switch Announcement action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+ 2. Channel switch announcement mode.
+ 2. a New selected channel.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueChSwAnn(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewCh)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ /* build action frame header.*/
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory*/
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
+
+ InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+#endif /* WDS_SUPPORT */
+
+static BOOLEAN DfsRequirementCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 Channel)
+{
+ BOOLEAN Result = FALSE;
+ INT i;
+
+ do
+ {
+ /* check DFS procedure is running.*/
+ /* make sure DFS procedure won't start twice.*/
+ if (pAd->Dot11_H.RDMode != RD_NORMAL_MODE)
+ {
+ Result = FALSE;
+ break;
+ }
+
+ /* check the new channel carried from Channel Switch Announcemnet is valid.*/
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if ((Channel == pAd->ChannelList[i].Channel)
+ &&(pAd->ChannelList[i].RemainingTimeForUse == 0))
+ {
+ /* found radar signal in the channel. the channel can't use at least for 30 minutes.*/
+ pAd->ChannelList[i].RemainingTimeForUse = 1800;/*30 min = 1800 sec*/
+ Result = TRUE;
+ break;
+ }
+ }
+ } while(FALSE);
+
+ return Result;
+}
+
+VOID NotifyChSwAnnToPeerAPs(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRA,
+ IN PUCHAR pTA,
+ IN UINT8 ChSwMode,
+ IN UINT8 Channel)
+{
+#ifdef WDS_SUPPORT
+ if (!((pRA[0] & 0xff) == 0xff)) /* is pRA a broadcase address.*/
+ {
+ INT i;
+ /* info neighbor APs that Radar signal found throgh WDS link.*/
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ if (ValidWdsEntry(pAd, i))
+ {
+ PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr;
+
+ /* DA equal to SA. have no necessary orignal AP which found Radar signal.*/
+ if (MAC_ADDR_EQUAL(pTA, pDA))
+ continue;
+
+ /* send Channel Switch Action frame to info Neighbro APs.*/
+ EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel);
+ }
+ }
+ }
+#endif /* WDS_SUPPORT */
+}
+
+static VOID StartDFSProcedure(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN UINT8 ChSwMode)
+{
+ /* start DFS procedure*/
+ pAd->CommonCfg.Channel = Channel;
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+#endif /* DOT11_N_SUPPORT */
+ pAd->Dot11_H.RDMode = RD_SWITCHING_MODE;
+ pAd->Dot11_H.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;
+
+ 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_AP_SUPPORT
+ /* ChSwAnn need check.*/
+ if ((pAd->OpMode == OPMODE_AP) &&
+ (DfsRequirementCheck(pAd, ChSwAnnInfo.Channel) == TRUE))
+ {
+ NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, ChSwAnnInfo.ChSwMode, ChSwAnnInfo.Channel);
+ StartDFSProcedure(pAd, ChSwAnnInfo.Channel, ChSwAnnInfo.ChSwMode);
+ }
+#endif /* CONFIG_AP_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, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20),
+ ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20));
+
+ /* 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;
+}
+
+#ifdef CONFIG_AP_SUPPORT
+INT Set_PwrConstraint(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+
+typedef struct __PWR_CONSTRAIN_CFG
+{
+ CHAR Attenuation;
+ ULONG TxPowerPercentage;
+} PWR_CONSTRAIN_CFG;
+
+ PWR_CONSTRAIN_CFG PwrConstrainTab[] =
+ {
+ {0, 100},
+ {1, 70},
+ {4, 50},
+ {6, 20},
+ {10, 10},
+ {13, 5}
+ };
+#define PWR_CONSTRAION_TAB_SIZE \
+ (sizeof(PwrConstrainTab)/sizeof(PWR_CONSTRAIN_CFG))
+
+ INT Idx;
+ LONG Value;
+ CHAR MaxTxPwr;
+ CHAR CurTxPwr;
+ CHAR DaltaPwr;
+
+ Value = (UINT) simple_strtol(arg, 0, 10);
+ MaxTxPwr = GetRegulatoryMaxTxPwr(pAd, pAd->CommonCfg.Channel) - (CHAR)Value;
+ CurTxPwr = RTMP_GetTxPwr(pAd, pAd->MacTab.Content[0].HTPhyMode);
+ DaltaPwr = CurTxPwr - MaxTxPwr;
+
+ if (pAd->CommonCfg.TxPowerPercentage > 90)
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */
+ DaltaPwr += 1;
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */
+ DaltaPwr += 3;
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */
+ DaltaPwr += 6;
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */
+ DaltaPwr += 9;
+ else /* reduce Pwr for 12 dB. */
+ DaltaPwr += 12;
+
+ DBGPRINT(RT_DEBUG_OFF, ("MaxTxPwr=%d, CurTxPwr=%d, DaltaPwr=%d\n",
+ MaxTxPwr, CurTxPwr, DaltaPwr));
+
+ for (Idx = 0; Idx < PWR_CONSTRAION_TAB_SIZE; Idx++)
+ {
+ if (DaltaPwr < PwrConstrainTab[Idx].Attenuation)
+ {
+ pAd->CommonCfg.PwrConstraint = Value;
+ pAd->CommonCfg.TxPowerPercentage =
+ PwrConstrainTab[Idx].TxPowerPercentage;
+
+ break;
+ }
+ }
+
+ if (Idx == PWR_CONSTRAION_TAB_SIZE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, \
+ ("Power constraint value be in range from 0 to 13dB\n"));
+ }
+
+
+ return TRUE;
+}
+
+
+static PDOT11_REGULATORY_INFORMATION GetRugClassRegion(
+ IN PSTRING pCountryCode,
+ IN UINT8 RugClass)
+{
+ PDOT11_REGULATORY_INFORMATION pRugClass;
+
+ pRugClass = NULL;
+ do
+ {
+ if (strncmp(pCountryCode, "US", 2) == 0)
+ {
+ if (RugClass >= USA_REGULATORY_INFO_SIZE)
+ break;
+ pRugClass = &USARegulatoryInfo[RugClass];
+ }
+
+ if (strncmp(pCountryCode, "JP", 2) == 0)
+ {
+ if (RugClass >= JP_REGULATORY_INFO_SIZE)
+ break;
+ pRugClass = &JapanRegulatoryInfo[RugClass];
+
+ }
+ } while (FALSE);
+
+ return pRugClass;
+}
+
+VOID RguClass_BuildBcnChList(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf,
+ OUT PULONG pBufLen)
+{
+ INT loop;
+ ULONG TmpLen;
+ PDOT11_REGULATORY_INFORMATION pRguClassRegion;
+ PDOT11_CHANNEL_SET pChList;
+
+ for (loop = 0 ;loop < MAX_NUM_OF_REGULATORY_CLASS; loop++)
+ {
+ if (pAd->CommonCfg.RegulatoryClass[loop] == 0)
+ break;
+
+ pRguClassRegion = GetRugClassRegion(
+ (PSTRING)pAd->CommonCfg.CountryCode,
+ pAd->CommonCfg.RegulatoryClass[loop]);
+
+ pChList = &pRguClassRegion->ChannelSet;
+
+ if (pRguClassRegion == NULL)
+ return;
+
+ MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
+ 1, &pChList->ChannelList[0],
+ 1, &pChList->NumberOfChannels,
+ 1, &pChList->MaxTxPwr,
+ END_OF_ARGS);
+
+ *pBufLen += TmpLen;
+ }
+
+ return;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/txpower.c b/cleopatre/devkit/mt7601udrv/common/txpower.c
new file mode 100644
index 0000000000..74e3cc8be7
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/txpower.c
@@ -0,0 +1,1172 @@
+/*
+
+*/
+
+#include "rt_config.h"
+
+
+#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 AsicGetTxPowerOffset(RTMP_ADAPTER *pAd, ULONG *TxPwr)
+{
+ CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC;
+ DBGPRINT(RT_DEBUG_INFO, ("-->AsicGetTxPowerOffset\n"));
+
+ NdisZeroMemory(&CfgOfTxPwrCtrlOverMAC, sizeof(CfgOfTxPwrCtrlOverMAC));
+
+ CfgOfTxPwrCtrlOverMAC.NumOfEntries = 5; /* MAC 0x1314, 0x1318, 0x131C, 0x1320 and 1324 */
+
+#ifdef DOT11_VHT_AC
+ if (pAd->CommonCfg.BBPCurrentBW == BW_80 &&
+ pAd->CommonCfg.Channel > 14)
+ {
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx80MPwrCfgABand[0];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx80MPwrCfgABand[1];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx80MPwrCfgABand[2];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx80MPwrCfgABand[3];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx80MPwrCfgABand[4];
+ }
+ else
+#endif /* DOT11_VHT_AC */
+ 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));
+
+ DBGPRINT(RT_DEBUG_INFO, ("<--AsicGetTxPowerOffset\n"));
+}
+
+
+VOID AsicGetAutoAgcOffsetForExternalTxAlc(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1)
+{
+ BBP_R49_STRUC BbpR49;
+ BOOLEAN bAutoTxAgc = FALSE;
+ UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep, idx;
+ PCHAR pTxAgcCompensate = NULL;
+ CHAR DeltaPwr = 0;
+
+ DBGPRINT(RT_DEBUG_INFO, ("-->%s\n", __FUNCTION__));
+
+ BbpR49.byte = 0;
+
+ /* 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)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte);
+
+ /* TSSI representation */
+ if (IS_RT3071(pAd) || IS_RT3390(pAd) || IS_RT3090A(pAd) || IS_RT3572(pAd)) /* 5-bits */
+ {
+ BbpR49.byte = (BbpR49.byte & 0x1F);
+ }
+
+ /* (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 */
+
+ *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 if (BbpR49.byte < pTssiPlusBoundary[1])
+ {
+ /* Reading is smaller than the reference value */
+ /* Check for how large we need to increase the Tx power */
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49.byte >= pTssiPlusBoundary[idx]) /* Found the range*/
+ break;
+ }
+
+ /* The index is the step we should increase, idx = 0 means there is nothing to compensate */
+ *pTxAgcCompensate = TxAgcStep * (idx-1);
+ DeltaPwr += (*pTxAgcCompensate);
+ DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49.byte, TssiRef, TxAgcStep, idx-1));
+ }
+ else
+ {
+ *pTxAgcCompensate = 0;
+ DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49.byte, TssiRef, TxAgcStep, 0));
+ }
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ DeltaPwr += (*pTxAgcCompensate);
+ }
+
+
+ *pDeltaPwr = DeltaPwr;
+ *pAgcCompensate = *pTxAgcCompensate;
+
+ DBGPRINT(RT_DEBUG_INFO, ("<--%s\n", __FUNCTION__));
+}
+
+
+/*
+ ==========================================================================
+ 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 AsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ CHAR Value;
+ CHAR Rssi = -127;
+ CHAR DeltaPwr = 0;
+ CHAR TxAgcCompensate = 0;
+ CHAR DeltaPowerByBbpR1 = 0;
+ 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 SINGLE_SKU
+ CHAR TotalDeltaPowerOri = 0;
+ UCHAR SingleSKUBbpR1Offset = 0;
+ ULONG SingleSKUTotalDeltaPwr[MAX_TXPOWER_ARRAY_SIZE] = {0};
+#endif /* SINGLE_SKU */
+
+
+
+ /* Get Tx rate offset table which from EEPROM 0xDEh ~ 0xEFh */
+ RTMP_CHIP_ASIC_TX_POWER_OFFSET_GET(pAd, (PULONG)&CfgOfTxPwrCtrlOverMAC);
+ /* Get temperature compensation delta power value */
+ RTMP_CHIP_ASIC_AUTO_AGC_OFFSET_GET(
+ pAd, &DeltaPwr, &TotalDeltaPower, &TxAgcCompensate, &DeltaPowerByBbpR1);
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: DeltaPwr=%d, TotalDeltaPower=%d, TxAgcCompensate=%d, DeltaPowerByBbpR1=%d\n",
+ __FUNCTION__,
+ DeltaPwr,
+ TotalDeltaPower,
+ TxAgcCompensate,
+ DeltaPowerByBbpR1));
+
+ /* Get delta power based on the percentage specified from UI */
+ //AsicPercentageDeltaPower(pAd, Rssi, &DeltaPwr,&DeltaPowerByBbpR1);
+
+ /* The transmit power controlled by the BBP */
+ TotalDeltaPower += DeltaPowerByBbpR1;
+ /* The transmit power controlled by the MAC */
+ TotalDeltaPower += DeltaPwr;
+
+#ifdef SINGLE_SKU
+ if (pAd->CommonCfg.bSKUMode == TRUE)
+ {
+ /* Re calculate delta power while enabling Single SKU */
+ GetSingleSkuDeltaPower(pAd, &TotalDeltaPower, (PULONG)&SingleSKUTotalDeltaPwr, &SingleSKUBbpR1Offset);
+
+ TotalDeltaPowerOri = TotalDeltaPower;
+ }
+ else
+#endif /* SINGLE_SKU */
+ {
+ AsicCompensatePowerViaBBP(pAd, &TotalDeltaPower);
+ }
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ return;
+#endif /* MT7601 */
+
+ /* Power will be updated each 4 sec. */
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+/*****************************************************************************/
+ /* Set new Tx power for different Tx rates */
+ for (i=0; i < CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ TX_POWER_CONTROL_OVER_MAC_ENTRY *pTxPwrEntry;
+ ULONG reg_val;
+
+ pTxPwrEntry = &CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i];
+ reg_val = pTxPwrEntry->RegisterValue;
+ if (reg_val != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ CHAR _upbound, _lowbound, t_pwr;
+ BOOLEAN _bValid;
+
+ _lowbound = 0;
+ _bValid = TRUE;
+
+ Value = (CHAR)((reg_val >> j*4) & 0x0F);
+#ifdef SINGLE_SKU
+ if (pAd->CommonCfg.bSKUMode == TRUE)
+ {
+ TotalDeltaPower = SingleSKUBbpR1Offset + TotalDeltaPowerOri - (CHAR)((SingleSKUTotalDeltaPwr[i] >> j*4) & 0x0F);
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: BbpR1Offset(%d) + TX ALC(%d) - SingleSKU[%d/%d](%d) = TotalDeltaPower(%d)\n",
+ __FUNCTION__, SingleSKUBbpR1Offset,
+ TotalDeltaPowerOri, i, j,
+ (CHAR)((SingleSKUTotalDeltaPwr[i] >> j*4) & 0x0F),
+ TotalDeltaPower));
+ }
+#endif /* SINGLE_SKU */
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+ /* The upper bounds of MAC 0x1314 ~ 0x1324 are variable */
+ if ((pAd->TxPowerCtrl.bInternalTxALC == TRUE)^(pAd->chipCap.bTempCompTxALC == TRUE))
+ {
+ switch (0x1314 + (i * 4))
+ {
+ case 0x1314:
+ _upbound = 0xe;
+ break;
+
+ case 0x1318:
+ _upbound = (j <= 3) ? 0xc : 0xe;
+ break;
+
+ case 0x131C:
+ _upbound = ((j == 0) || (j == 2) || (j == 3)) ? 0xc : 0xe;
+ break;
+
+ case 0x1320:
+ _upbound = (j == 1) ? 0xe : 0xc;
+ break;
+
+ case 0x1324:
+ _upbound = 0xc;
+ break;
+
+ default:
+ {
+ /* do nothing */
+ _bValid = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknown register = 0x%x\n", __FUNCTION__, (0x1314 + (i * 4))));
+ }
+ break;
+ }
+ }
+ else
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+ _upbound = 0xc;
+
+ if (_bValid)
+ {
+ t_pwr = Value + TotalDeltaPower;
+ if (t_pwr < _lowbound)
+ Value = _lowbound;
+ else if (t_pwr > _upbound)
+ Value = _upbound;
+ else
+ Value = t_pwr;
+ }
+
+ /* Fill new value into the corresponding MAC offset */
+ reg_val = (reg_val & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+
+ pTxPwrEntry->RegisterValue = reg_val;
+ RTMP_IO_WRITE32(pAd, pTxPwrEntry->MACRegisterOffset, pTxPwrEntry->RegisterValue);
+
+ }
+ }
+
+ /* Extra set MAC registers to compensate Tx power if any */
+ RTMP_CHIP_ASIC_EXTRA_POWER_OVER_MAC(pAd);
+ }
+
+}
+
+
+#ifdef SINGLE_SKU
+VOID GetSingleSkuDeltaPower(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pTotalDeltaPower,
+ INOUT PULONG pSingleSKUTotalDeltaPwr,
+ INOUT PUCHAR pSingleSKUBbpR1Offset)
+{
+ INT i, j;
+ CHAR Value;
+ CHAR MinValue = 127;
+ UCHAR BbpR1 = 0;
+ UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
+ UCHAR AdjustMaxTxPwr[(MAX_TX_PWR_CONTROL_OVER_MAC_REGISTERS * 8)];
+ CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC = {0};
+
+ /* Get TX rate offset table which from EEPROM 0xDEh ~ 0xEFh */
+ RTMP_CHIP_ASIC_TX_POWER_OFFSET_GET(pAd, (PULONG)&CfgOfTxPwrCtrlOverMAC);
+
+ /* Handle regulatory max. TX power constraint */
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8); /* 5G band */
+ }
+ else
+ {
+ TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF); /* 2.4G band */
+ }
+
+ CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
+
+ /* Use OFDM 6M as the criterion */
+ criterion = (UCHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue & 0x000F0000) >> 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d\n",
+ __FUNCTION__, criterion, TxPwrInEEPROM, CountryTxPwr));
+
+ /* Adjust max. TX power according to the relationship of TX power in EEPROM */
+ for (i=0; i<CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ if (i == 0)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F);
+
+ if (j < 4)
+ {
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4; /* CCK has 4dBm larger than OFDM */
+ }
+ else
+ {
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, (Default)Value=%d, %d\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ else
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F);
+
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, (Default)Value=%d, %d\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ }
+
+ /* Adjust TX power according to the relationship */
+ for (i=0; i<CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ if (CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F);
+
+ /* The TX power is larger than the regulatory, the power should be restrained */
+ if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
+ {
+ Value = (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
+
+ if (Value > 0xF)
+ {
+ /* The output power is larger than Country Regulatory over 15dBm, the origianl design has overflow case */
+ DBGPRINT(RT_DEBUG_ERROR,("%s: Value overflow - %d\n", __FUNCTION__, Value));
+ }
+
+ *(pSingleSKUTotalDeltaPwr+i) = (*(pSingleSKUTotalDeltaPwr+i) & ~(0x0000000F << j*4)) | (Value << j*4);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, (Exceed)Value=%d, %d\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, Value=%d, %d, no change\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ }
+ }
+
+ /* Calculate the min. TX power */
+ for(i=0; i<CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ if (CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ CHAR PwrChange;
+ /*
+ After Single SKU, each data rate offset power value is saved in TotalDeltaPwr[].
+ PwrChange will add SingleSKUDeltaPwr and TotalDeltaPwr[] for each data rate to calculate
+ the final adjust output power value which is saved in MAC Reg. and BBP_R1.
+ */
+
+ /*
+ Value / TxPwr[] is get from eeprom 0xDEh ~ 0xEFh and increase or decrease the
+ 20/40 Bandwidth Delta Value in eeprom 0x50h.
+ */
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> 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)((*(pSingleSKUTotalDeltaPwr+i) >> j*4) & 0x0F); /* 0 ~ 15 */
+ PwrChange -= *pTotalDeltaPower;
+
+ Value -= PwrChange;
+
+ if (MinValue > Value)
+ MinValue = Value;
+ }
+ }
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+ /* Depend on the min. TX power to adjust and prevent the value of MAC_TX_PWR_CFG less than 0 */
+ if ((MinValue < 0) && (MinValue >= -6))
+ {
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_6dBm;
+ *pSingleSKUBbpR1Offset = 6;
+ }
+ else if ((MinValue < -6)&&(MinValue >= -12))
+ {
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_12dBm;
+ *pSingleSKUBbpR1Offset = 12;
+ }
+ else if (MinValue < -12)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s: ASIC limit..\n", __FUNCTION__));
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_12dBm;
+ *pSingleSKUBbpR1Offset = 12;
+ }
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: <After BBP R1> TotalDeltaPower = %d dBm, BbpR1 = 0x%02X \n", __FUNCTION__, *pTotalDeltaPower, BbpR1));
+}
+#endif /* SINGLE_SKU */
+
+
+VOID AsicPercentageDeltaPower(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ INOUT PCHAR pDeltaPwr,
+ INOUT PCHAR pDeltaPowerByBbpR1)
+{
+ /*
+ 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 */
+ {
+ }
+ 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; */
+ {
+ *pDeltaPwr -= 1;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW DeltaPwr -= 3; */
+ {
+ *pDeltaPwr -= 3;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW DeltaPwr -= 6; */
+ {
+ *pDeltaPowerByBbpR1 -= 6; /* -6 dBm */
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW DeltaPwr -= 9; */
+ {
+ *pDeltaPowerByBbpR1 -= 6; /* -6 dBm */
+ *pDeltaPwr -= 3;
+ }
+ else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW DeltaPwr -= 12; */
+ {
+ *pDeltaPowerByBbpR1 -= 12; /* -12 dBm */
+ }
+}
+
+
+VOID AsicCompensatePowerViaBBP(
+ IN PRTMP_ADAPTER pAd,
+ INOUT PCHAR pTotalDeltaPower)
+{
+ UCHAR mdsm_drop_pwr;
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: <Before BBP R1> TotalDeltaPower = %d dBm\n", __FUNCTION__, *pTotalDeltaPower));
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ return;
+ }
+#endif /* MT7601 */
+
+ if (*pTotalDeltaPower <= -12)
+ {
+ *pTotalDeltaPower += 12;
+ mdsm_drop_pwr = MDSM_DROP_TX_POWER_BY_12dBm;
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: Drop the transmit power by 12 dBm (BBP R1)\n", __FUNCTION__));
+ }
+ else if ((*pTotalDeltaPower <= -6) && (*pTotalDeltaPower > -12))
+ {
+ *pTotalDeltaPower += 6;
+ mdsm_drop_pwr = MDSM_DROP_TX_POWER_BY_6dBm;
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: Drop the transmit power by 6 dBm (BBP R1)\n", __FUNCTION__));
+ }
+ else
+ {
+ /* Control the the transmit power by using the MAC only */
+ mdsm_drop_pwr = MDSM_NORMAL_TX_POWER;
+ }
+
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ {
+ UINT32 bbp_val = 0;
+
+ RTMP_BBP_IO_READ32(pAd, TXBE_R4, &bbp_val);
+ bbp_val &= (~0x3);
+ bbp_val |= mdsm_drop_pwr;
+ RTMP_BBP_IO_WRITE32(pAd, TXBE_R4, bbp_val);
+ DBGPRINT(RT_DEBUG_INFO, ("%s: <After TXBE_R4> TotalDeltaPower = %d dBm, TXBE_R4 = 0x%0x\n", __FUNCTION__, *pTotalDeltaPower, bbp_val));
+ }
+ else
+#endif /* RT65xx */
+ {
+ UCHAR BbpR1 = 0;
+
+ /* 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;
+ BbpR1 |= mdsm_drop_pwr;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: <After BBP R1> TotalDeltaPower = %d dBm, BbpR1 = 0x%02X \n", __FUNCTION__, *pTotalDeltaPower, BbpR1));
+ }
+}
+
+
+/*
+ ========================================================================
+
+ 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(RTMP_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;
+
+
+
+
+#ifdef RT8592
+ if (IS_RT8592(pAd)) {
+ RT85592ReadTxPwrPerRate(pAd);
+ return;
+ }
+#endif /* RT8592 */
+
+#ifdef RT65xx
+ if (IS_RT6590(pAd)) {
+ RT6590ReadTxPwrPerRate(pAd);
+ return;
+ }
+#endif /* RT65xx */
+
+
+#ifdef MT7601
+ if (IS_MT7601(pAd)) {
+ MT7601_ReadTxPwrPerRate(pAd);
+ return;
+ }
+#endif /* MT7601 */
+
+ /* For default one, go here!! */
+ {
+
+ /* 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));
+ }
+ }
+
+ /* Extra set MAC registers to compensate Tx power if any */
+ RTMP_CHIP_ASIC_EXTRA_POWER_OVER_MAC(pAd);
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read initial channel power parameters from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPReadChannelPwr(RTMP_ADAPTER *pAd)
+{
+ UINT32 i, choffset;
+ EEPROM_TX_PWR_STRUC Power;
+ EEPROM_TX_PWR_STRUC Power2;
+
+ /* Read Tx power value for all channels*/
+ /* Value from 1 - 0x7f. Default value is 24.*/
+ /* Power value : 2.4G 0x00 (0) ~ 0x1F (31)*/
+ /* : 5.5G 0xF9 (-7) ~ 0x0F (15)*/
+
+ /* 0. 11b/g, ch1 - ch 14*/
+ for (i = 0; i < 7; i++)
+ {
+
+ { /* Default routine. RT3070 and RT3370 run here. */
+ 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;
+ }
+ }
+
+
+ {
+ if (IS_RT5592(pAd))
+ return;
+
+ /* 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;
+
+
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/common/uapsd.c b/cleopatre/devkit/mt7601udrv/common/uapsd.c
new file mode 100644
index 0000000000..f75164acbd
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/uapsd.c
@@ -0,0 +1,2074 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related WMM UAPSD function body.
+
+ Two EOSP sent mechanism:
+ 1. Use DMA Done to do the check.
+ a. safe but not accuracy, because maybe all packets are still in hardware
+ DMA, not yet be sent to air, but DMA Done are all 1
+ b. in USB chip, the data completion does not mean a packet is sent, it
+ means a block of data is sent, so we need to use another method to
+ know how many packets are sent in the data completion function
+
+ 2. Use TX Statistics to do the check.
+ a. unsafe but accuracy, because too many traffic are sent before TX Done
+ Interrupt occurs and the statistics count will be overwrited.
+ b. management frames will not be counted
+ c. frames using 1Mbps (CCK) will no be counted
+ d. legacy ps frame sent after a PS-Poll frame is also be counted, we
+ need to handle the mix mode case: some AC are legacy PS and some AC
+ are UAPSD
+ e. in USB chip, only one statistics counter for all station entries;
+ so only use DMA Done mechanism in USB device; but in PCI chip,
+ one statistics counter for each station entries.
+
+ All ACs have two UAPSD modes:
+ 1. Delivery-enabled
+ meaningful mode for AC in AP
+
+ 2. Trigger-enabled
+ meaningful mode for AC in STA
+
+ Only WMM ACM is used, we need to discriminate between Delivery-enabled and
+ Trigger-enabled AC, or all AC are Delivery/Trigger-enabled or not
+ Delivery/Trigger-enabled.
+
+***************************************************************************/
+
+#define MODULE_WMM_UAPSD
+#include "rt_config.h"
+
+#ifdef UAPSD_SUPPORT
+#include "uapsd.h"
+
+/*#define UAPSD_DEBUG */
+
+/* used to enable or disable UAPSD power save queue maintain mechanism */
+UCHAR gUAPSD_FlgNotQueueMaintain;
+
+#ifdef UAPSD_DEBUG
+UINT32 gUAPSD_SP_CloseAbnormalNum;
+#endif /* UAPSD_DEBUG */
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+/* all unit: us */
+
+UCHAR gUAPSD_TimingFlag;
+UINT32 gUAPSD_TimingIndexUapsd;
+UINT32 gUAPSD_TimingLoopIndex;
+
+/* ISR start timestamp */
+UINT64 gUAPSD_TimingIsr[UAPSD_TIMING_RECORD_MAX];
+
+/* Tasklet start timestamp */
+UINT64 gUAPSD_TimingTasklet[UAPSD_TIMING_RECORD_MAX];
+
+UINT64 gUAPSD_TimingTrgRcv[UAPSD_TIMING_RECORD_MAX];
+UINT64 gUAPSD_TimingMov2Tx[UAPSD_TIMING_RECORD_MAX];
+UINT64 gUAPSD_TimingTx2Air[UAPSD_TIMING_RECORD_MAX];
+
+UINT32 gUAPSD_TimingSumIsr2Tasklet;
+UINT32 gUAPSD_TimingSumTrig2Txqueue;
+UINT32 gUAPSD_TimingSumTxqueue2Air;
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+
+
+#ifdef VENDOR_FEATURE3_SUPPORT
+static VOID UAPSD_InsertTailQueueAc(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN QUEUE_HEADER *pQueueHeader,
+ IN QUEUE_ENTRY *pQueueEntry);
+#endif /* VENDOR_FEATURE3_SUPPORT */
+
+
+
+
+/*
+========================================================================
+Routine Description:
+ UAPSD Module Init.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_Init(
+ IN PRTMP_ADAPTER pAd)
+{
+ /* allocate a lock resource for SMP environment */
+ NdisAllocateSpinLock(pAd, &pAd->UAPSDEOSPLock);
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> allocate a spinlock!\n"));
+#endif /* UAPSD_DEBUG */
+
+#ifdef UAPSD_DEBUG
+ gUAPSD_SP_CloseAbnormalNum = 0;
+#endif /* UAPSD_DEBUG */
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+ gUAPSD_TimingFlag = 0; /* default: DISABLE */
+ gUAPSD_TimingIndexUapsd = 0;
+ gUAPSD_TimingLoopIndex = 0;
+
+
+ gUAPSD_TimingSumIsr2Tasklet = 0;
+ gUAPSD_TimingSumTrig2Txqueue = 0;
+ gUAPSD_TimingSumTxqueue2Air = 0;
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+}
+
+
+/*
+========================================================================
+Routine Description:
+ UAPSD Module Release.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_Release(
+ IN PRTMP_ADAPTER pAd)
+{
+ /* free the lock resource for SMP environment */
+ NdisFreeSpinLock(&pAd->UAPSDEOSPLock);
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> release a spinlock!\n"));
+#endif /* UAPSD_DEBUG */
+} /* End of UAPSD_Release */
+
+/*
+========================================================================
+Routine Description:
+ Check if ASIC can enter sleep mode. Not software sleep.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpAsicSleepHandle(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN FlgCanAsicSleep = TRUE;
+
+
+
+} /* End of RtmpAsicSleepHandle */
+
+
+
+/*
+========================================================================
+Routine Description:
+ Close current Service Period.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry Close the SP of the entry
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_SP_Close(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ if ((pEntry != NULL) && (pEntry->PsMode == PWR_SAVE))
+ {
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+ if (pEntry->bAPSDFlagSPStart != 0)
+ {
+ /* SP is started for the station */
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> [3] close SP!\n"));
+#endif /* UAPSD_DEBUG */
+
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ {
+ /*
+ SP will be closed, should not have EOSP frame
+ if exists, release it
+ */
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> [3] Free EOSP (UP = %d)!\n",
+ RTMP_GET_PACKET_UP(
+ QUEUE_ENTRY_TO_PACKET(pEntry->pUAPSDEOSPFrame))));
+#endif /* UAPSD_DEBUG */
+
+ RELEASE_NDIS_PACKET(pAd,
+ QUEUE_ENTRY_TO_PACKET(pEntry->pUAPSDEOSPFrame),
+ NDIS_STATUS_FAILURE);
+ pEntry->pUAPSDEOSPFrame = NULL;
+ } /* End of if */
+
+ /* re-init SP related parameters */
+ pEntry->UAPSDTxNum = 0;
+ //pEntry->bAPSDFlagSPStart = 0;
+ pEntry->bAPSDFlagEOSPOK = 0;
+ pEntry->bAPSDFlagLegacySent = 0;
+ UAPSD_SP_END(pAd, pEntry);
+
+#ifdef RTMP_MAC_USB
+ pEntry->UAPSDTagOffset[QID_AC_BE] = 0;
+ pEntry->UAPSDTagOffset[QID_AC_BK] = 0;
+ pEntry->UAPSDTagOffset[QID_AC_VI] = 0;
+ pEntry->UAPSDTagOffset[QID_AC_VO] = 0;
+#endif /* RTMP_MAC_USB */
+ } /* End of if */
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ } /* End of if */
+} /* End of UAPSD_SP_Close */
+
+/*
+========================================================================
+Routine Description:
+ Check if the SP for entry is closed.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry the peer entry
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+BOOLEAN UAPSD_SP_IsClosed(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ BOOLEAN FlgIsSpClosed = TRUE;
+
+
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+ if ((pEntry != NULL) && (pEntry->PsMode == PWR_SAVE))
+ {
+ if (pEntry->bAPSDFlagSPStart != 0)
+ FlgIsSpClosed = FALSE;
+ }
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+
+ return FlgIsSpClosed;
+}
+
+/*
+========================================================================
+Routine Description:
+ Deliver all queued packets.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+
+Return Value:
+ None
+
+Note:
+ SMP protection by caller for packet enqueue.
+========================================================================
+*/
+VOID UAPSD_AllPacketDeliver(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ QUEUE_HEADER *pQueApsd;
+ PQUEUE_ENTRY pQueEntry;
+ UCHAR QueIdList[WMM_NUM_OF_AC] = { QID_AC_BE, QID_AC_BK,
+ QID_AC_VI, QID_AC_VO };
+ INT32 IdAc, QueId; /* must be signed, can not be unsigned */
+
+
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+ /* check if the EOSP frame is yet transmitted out */
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ {
+ /* queue the EOSP frame to SW queue to be transmitted */
+ QueId = RTMP_GET_PACKET_UAPSD_QUE_ID(
+ QUEUE_ENTRY_TO_PACKET(pEntry->pUAPSDEOSPFrame));
+
+ if (QueId > QID_AC_VO)
+ {
+ /* should not be here, only for sanity */
+ QueId = QID_AC_BE;
+ } /* End of if */
+
+ UAPSD_INSERT_QUEUE_AC(pAd, pEntry, &pAd->TxSwQueue[QueId],
+ pEntry->pUAPSDEOSPFrame);
+
+ pEntry->pUAPSDEOSPFrame = NULL;
+ pEntry->UAPSDTxNum = 0;
+ } /* End of if */
+
+ /* deliver ALL U-APSD packets from AC3 to AC0 (AC0 to AC3 is also ok) */
+ for(IdAc=(WMM_NUM_OF_AC-1); IdAc>=0; IdAc--)
+ {
+ pQueApsd = &(pEntry->UAPSDQueue[IdAc]);
+ QueId = QueIdList[IdAc];
+
+ while(pQueApsd->Head)
+ {
+ pQueEntry = RemoveHeadQueue(pQueApsd);
+ UAPSD_INSERT_QUEUE_AC(pAd, pEntry, &pAd->TxSwQueue[QueId], pQueEntry);
+ } /* End of while */
+ } /* End of for */
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+} /* End of UAPSD_AllPacketDeliver */
+
+
+/*
+========================================================================
+Routine Description:
+ Parse the UAPSD field in WMM element in (re)association request frame.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+ *pElm QoS information field
+ FlgApsdCapable TRUE: Support UAPSD
+
+Return Value:
+ None
+
+Note:
+ No protection is needed.
+
+ 1. Association -> TSPEC:
+ use static UAPSD settings in Association
+ update UAPSD settings in TSPEC
+
+ 2. Association -> TSPEC(11r) -> Reassociation:
+ update UAPSD settings in TSPEC
+ backup static UAPSD settings in Reassociation
+
+ 3. Association -> Reassociation:
+ update UAPSD settings in TSPEC
+ backup static UAPSD settings in Reassociation
+========================================================================
+*/
+VOID UAPSD_AssocParse(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR *pElm,
+ IN BOOLEAN FlgApsdCapable)
+{
+ PQBSS_STA_INFO_PARM pQosInfo;
+ UCHAR UAPSD[4];
+ UINT32 IdApsd;
+
+
+ /* check if the station enables UAPSD function */
+ if ((pEntry) && (FlgApsdCapable == TRUE))
+ {
+ /* backup its UAPSD parameters */
+ pQosInfo = (PQBSS_STA_INFO_PARM) pElm;
+
+
+ UAPSD[QID_AC_BE] = pQosInfo->UAPSD_AC_BE;
+ UAPSD[QID_AC_BK] = pQosInfo->UAPSD_AC_BK;
+ UAPSD[QID_AC_VI] = pQosInfo->UAPSD_AC_VI;
+ UAPSD[QID_AC_VO] = pQosInfo->UAPSD_AC_VO;
+
+ pEntry->MaxSPLength = pQosInfo->MaxSPLength;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("apsd> UAPSD %d %d %d %d!\n",
+ pQosInfo->UAPSD_AC_BE, pQosInfo->UAPSD_AC_BK,
+ pQosInfo->UAPSD_AC_VI, pQosInfo->UAPSD_AC_VO));
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("apsd> MaxSPLength = %d\n", pEntry->MaxSPLength));
+
+ /* use static UAPSD setting of association request frame */
+ for(IdApsd=0; IdApsd<4; IdApsd++)
+ {
+ pEntry->bAPSDCapablePerAC[IdApsd] = UAPSD[IdApsd];
+ pEntry->bAPSDDeliverEnabledPerAC[IdApsd] = UAPSD[IdApsd];
+
+ } /* End of for */
+
+ if ((pEntry->bAPSDCapablePerAC[QID_AC_BE] == 0) &&
+ (pEntry->bAPSDCapablePerAC[QID_AC_BK] == 0) &&
+ (pEntry->bAPSDCapablePerAC[QID_AC_VI] == 0) &&
+ (pEntry->bAPSDCapablePerAC[QID_AC_VO] == 0))
+ {
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE);
+ }
+ else
+ {
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE);
+ } /* End of if */
+
+ if ((pEntry->bAPSDCapablePerAC[QID_AC_BE] == 1) &&
+ (pEntry->bAPSDCapablePerAC[QID_AC_BK] == 1) &&
+ (pEntry->bAPSDCapablePerAC[QID_AC_VI] == 1) &&
+ (pEntry->bAPSDCapablePerAC[QID_AC_VO] == 1))
+ {
+ /* all AC are U-APSD */
+ DBGPRINT(RT_DEBUG_TRACE, ("apsd> all AC are UAPSD\n"));
+ pEntry->bAPSDAllAC = 1;
+ }
+ else
+ {
+ /* at least one AC is not U-APSD */
+ DBGPRINT(RT_DEBUG_TRACE, ("apsd> at least one AC is not UAPSD %d %d %d %d\n",
+ pEntry->bAPSDCapablePerAC[QID_AC_BE],
+ pEntry->bAPSDCapablePerAC[QID_AC_BK],
+ pEntry->bAPSDCapablePerAC[QID_AC_VI],
+ pEntry->bAPSDCapablePerAC[QID_AC_VO]));
+ pEntry->bAPSDAllAC = 0;
+ } /* End of if */
+
+ pEntry->VirtualTimeout = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("apsd> MaxSPLength = %d\n", pEntry->MaxSPLength));
+ } /* End of if */
+} /* End of UAPSD_AssocParse */
+
+
+/*
+========================================================================
+Routine Description:
+ Enqueue a UAPSD packet.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+ pPacket UAPSD dnlink packet
+ IdAc UAPSD AC ID (0 ~ 3)
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_PacketEnqueue(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PNDIS_PACKET pPacket,
+ IN UINT32 IdAc)
+{
+ /*
+ 1. the STATION is UAPSD STATION;
+ 2. AC ID is legal;
+ 3. the AC is UAPSD AC.
+ so we queue the packet to its UAPSD queue
+ */
+
+ /* [0] ~ [3], QueIdx base is QID_AC_BE */
+ QUEUE_HEADER *pQueUapsd;
+
+
+ /* check if current queued UAPSD packet number is too much */
+ if (pEntry == NULL)
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> pEntry == NULL!\n"));
+ return;
+ } /* End of if */
+
+ pQueUapsd = &(pEntry->UAPSDQueue[IdAc]);
+
+ if (pQueUapsd->Number >= MAX_PACKETS_IN_UAPSD_QUEUE)
+ {
+ /* too much queued pkts, free (discard) the tx packet */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("uapsd> many(%ld) WCID(%d) AC(%d)\n",
+ pQueUapsd->Number,
+ RTMP_GET_PACKET_WCID(pPacket),
+ IdAc));
+
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ else
+ {
+ /* queue the tx packet to the U-APSD queue of the AC */
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+ InsertTailQueue(pQueUapsd, PACKET_TO_QUEUE_ENTRY(pPacket));
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+
+#ifdef UAPSD_DEBUG
+ if (RTMP_GET_PACKET_MGMT_PKT(pPacket) == 1)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ps> mgmt to uapsd queue...\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("ps> data (0x%08lx) (AC%d) to uapsd queue (num of pkt = %ld)...\n",
+ (ULONG)pPacket, IdAc,
+ pQueUapsd->Number));
+ } /* End of if */
+#endif /* UAPSD_DEBUG */
+ } /* End of if */
+} /* End of UAPSD_PacketEnqueue */
+
+
+
+/*
+========================================================================
+Routine Description:
+ Maintenance our UAPSD PS queue. Release all queued packet if timeout.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+
+Return Value:
+ None
+
+Note:
+ If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance()
+========================================================================
+*/
+VOID UAPSD_QueueMaintenance(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ QUEUE_HEADER *pQue;
+ UINT32 IdAc;
+ BOOLEAN FlgUapsdPkt, FlgEospPkt;
+#ifdef RTMP_MAC_USB
+ ULONG IrqFlags;
+#endif /* RTMP_MAC_USB */
+
+
+ /* sanity check */
+ if (gUAPSD_FlgNotQueueMaintain)
+ return;
+ /* End of if */
+
+ if (pEntry->PsMode != PWR_SAVE)
+ return; /* UAPSD packet only for power-save STA, not active STA */
+ /* End of if */
+
+ /* init */
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+ pQue = pEntry->UAPSDQueue;
+ FlgUapsdPkt = 0;
+ FlgEospPkt = 0;
+
+ /* check if more than one U-APSD packets exists */
+ for(IdAc=0; IdAc<WMM_NUM_OF_AC; IdAc++)
+ {
+ if (pQue[IdAc].Head != NULL)
+ {
+ /*
+ At least one U-APSD packets exists so we need to check if
+ queued U-APSD packets are timeout.
+ */
+ FlgUapsdPkt = 1;
+ break;
+ } /* End of if */
+ } /* End of for */
+
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ FlgEospPkt = 1;
+ /* End of if */
+
+ /* check if any queued UAPSD packet exists */
+ if (FlgUapsdPkt || FlgEospPkt)
+ {
+#ifdef RTMP_MAC_USB
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+#endif /* RTMP_MAC_USB */
+
+ pEntry->UAPSDQIdleCount ++;
+
+ if (pEntry->UAPSDQIdleCount > pAd->MacTab.MsduLifeTime)
+ {
+ if (FlgUapsdPkt)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("uapsd> UAPSD queue timeout! clean all queued frames...\n"));
+ } /* End of if */
+
+ if (FlgEospPkt)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("uapsd> UAPSD EOSP timeout! clean the EOSP frame!\n"));
+ } /* End of if */
+
+ /* UAPSDQIdleCount will be 0 after trigger frame is received */
+
+ /* clear all U-APSD packets */
+ if (FlgUapsdPkt)
+ {
+ for(IdAc=0; IdAc<WMM_NUM_OF_AC; IdAc++)
+ RtmpCleanupPsQueue(pAd, &pQue[IdAc]);
+ /* End of for */
+ } /* End of if */
+
+ /* free the EOSP frame */
+ pEntry->UAPSDTxNum = 0;
+
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ {
+ RELEASE_NDIS_PACKET(pAd,
+ QUEUE_ENTRY_TO_PACKET(pEntry->pUAPSDEOSPFrame),
+ NDIS_STATUS_FAILURE);
+ pEntry->pUAPSDEOSPFrame = NULL;
+ } /* End of if */
+
+ pEntry->bAPSDFlagEOSPOK = 0;
+ //pEntry->bAPSDFlagSPStart = 0;
+ pEntry->bAPSDFlagLegacySent = 0;
+ UAPSD_SP_END(pAd, pEntry);
+
+ /* clear idle counter */
+ pEntry->UAPSDQIdleCount = 0;
+
+#ifdef CONFIG_AP_SUPPORT
+ /* check TIM bit */
+ if (pEntry->PsQueue.Number == 0)
+ {
+ WLAN_MR_TIM_BIT_CLEAR(pAd, pEntry->apidx, pEntry->Aid);
+ } /* End of if */
+#endif /* CONFIG_AP_SUPPORT */
+ } /* End of if */
+
+#ifdef RTMP_MAC_USB
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+#endif /* RTMP_MAC_USB */
+ }
+ else
+ {
+ /* clear idle counter */
+ pEntry->UAPSDQIdleCount = 0;
+ } /* End of if (FlgUapsdPkt) */
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+
+ /* virtual timeout handle */
+ RTMP_PS_VIRTUAL_TIMEOUT_HANDLE(pEntry);
+} /* End of UAPSD_QueueMaintenance */
+
+
+/*
+========================================================================
+Routine Description:
+ Close SP in Tx Done, not Tx DMA Done.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry destination entry
+ FlgSuccess 0:tx success, 1:tx fail
+
+Return Value:
+ None
+
+Note:
+ For RT28xx series, for packetID=0 or multicast frame, no statistics
+ count can be got, ex: ARP response or DHCP packets, we will use
+ low rate to set (CCK, MCS=0=packetID).
+ So SP will not be close until UAPSD_EPT_SP_INT timeout.
+
+ So if the tx rate is 1Mbps for a entry, we will use DMA done, not
+ use UAPSD_SP_AUE_Handle().
+========================================================================
+*/
+VOID UAPSD_SP_AUE_Handle(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR FlgSuccess)
+{
+#ifdef UAPSD_SP_ACCURATE
+ USHORT QueId;
+
+
+ if (pEntry == NULL)
+ return;
+ /* End of if */
+
+ if (pEntry->PsMode == PWR_ACTIVE)
+ {
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> aux: Station actives! Close SP!\n"));
+#endif /* UAPSD_DEBUG */
+ //pEntry->bAPSDFlagSPStart = 0;
+ pEntry->bAPSDFlagEOSPOK = 0;
+ UAPSD_SP_END(pAd, pEntry);
+ return;
+ } /* End of if */
+
+ if (pEntry->PsMode == PWR_SAVE)
+ {
+ BOOLEAN FlgEosp;
+
+
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+ if (pEntry->bAPSDFlagSpRoughUse != 0)
+ {
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ return; /* use DMA mechanism, not statistics count mechanism */
+ } /* End of if */
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> aux: Tx Num = %d\n", pEntry->UAPSDTxNum));
+#endif /* UAPSD_DEBUG */
+
+ FlgEosp = FALSE;
+
+ if (pEntry->bAPSDFlagSPStart == 0)
+ {
+ /*
+ When SP is not started, all packets are from legacy PS queue.
+ One downlink packet for one PS-Poll packet.
+ */
+ pEntry->bAPSDFlagLegacySent = 0;
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> legacy PS packet is sent!\n"));
+#endif /* UAPSD_DEBUG */
+ }
+ else
+ {
+#ifdef UAPSD_TIMING_RECORD_FUNC
+ UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_TX2AIR);
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+ } /* End of if */
+
+ /* record current time */
+ UAPSD_TIME_GET(pAd, pEntry->UAPSDTimeStampLast);
+
+ /* Note: UAPSDTxNum does NOT include the EOSP packet */
+ if (pEntry->UAPSDTxNum > 0)
+ {
+ /* some UAPSD packets are not yet transmitted */
+
+ if (pEntry->UAPSDTxNum == 1)
+ {
+ /* this is the last UAPSD packet */
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ {
+ /* transmit the EOSP frame */
+ PNDIS_PACKET pPkt;
+
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> aux: send EOSP frame...\n"));
+#endif /* UAPSD_DEBUG */
+
+ pPkt = QUEUE_ENTRY_TO_PACKET(pEntry->pUAPSDEOSPFrame);
+ QueId = RTMP_GET_PACKET_UAPSD_QUE_ID(pPkt);
+
+ if (QueId > QID_AC_VO)
+ {
+ /* should not be here, only for sanity */
+ QueId = QID_AC_BE;
+ } /* End of if */
+
+ UAPSD_INSERT_QUEUE_AC(pAd, pEntry, &pAd->TxSwQueue[QueId],
+ pEntry->pUAPSDEOSPFrame);
+
+ pEntry->pUAPSDEOSPFrame = NULL;
+ FlgEosp = TRUE;
+ } /* End of if */
+ } /* End of if */
+
+ /* a UAPSD frame is transmitted so decrease the counter */
+ pEntry->UAPSDTxNum --;
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+
+ /* maybe transmit the EOSP frame */
+ if (FlgEosp == TRUE)
+ {
+ POS_COOKIE pCookie;
+
+ pCookie = (POS_COOKIE) pAd->OS_Cookie;
+
+ /*
+ Too many functions call NICUpdateFifoStaCounters() and
+ NICUpdateFifoStaCounters() will call UAPSD_SP_AUE_Handle(),
+ if we call RTMPDeQueuePacket() here, double-IRQ LOCK will
+ occur. so we need to activate a tasklet to send EOSP frame.
+
+ ex: RTMPDeQueuePacket() --> RTMPFreeTXDUponTxDmaDone() -->
+ NICUpdateFifoStaCounters() --> UAPSD_SP_AUE_Handle() -->
+ RTMPDeQueuePacket() ERROR! or
+
+ RTMPHandleTxRingDmaDoneInterrupt() -->
+ RTMP_IRQ_LOCK() -->
+ RTMPFreeTXDUponTxDmaDone() -->
+ NICUpdateFifoStaCounters() -->
+ UAPSD_SP_AUE_Handle() -->
+ RTMPDeQueuePacket() -->
+ DEQUEUE_LOCK() -->
+ RTMP_IRQ_LOCK() ERROR!
+ */
+ RTMP_OS_TASKLET_SCHE(&pCookie->uapsd_eosp_sent_task);
+ }
+ /* must return here; Or double unlock UAPSDEOSPLock */
+ return;
+ }
+ else
+ {
+ /* UAPSDTxNum == 0 so the packet is the EOSP packet */
+
+ if (pAd->bAPSDFlagSPSuspend == 1)
+ {
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> aux: SP is suspend, keep SP if exists!\n"));
+#endif /* UAPSD_DEBUG */
+
+ /* keep SP, not to close SP */
+ pEntry->bAPSDFlagEOSPOK = 1;
+ }
+
+ if ((pEntry->bAPSDFlagSPStart != 0) &&
+ (pAd->bAPSDFlagSPSuspend == 0))
+ {
+ //pEntry->bAPSDFlagSPStart = 0;
+ pEntry->bAPSDFlagEOSPOK = 0;
+ UAPSD_SP_END(pAd, pEntry);
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> aux: close a SP.\n\n\n"));
+#endif /* UAPSD_DEBUG */
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ }
+#endif /* UAPSD_SP_ACCURATE */
+}
+
+
+
+/*
+========================================================================
+Routine Description:
+ Close current Service Period.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+ When we receive EOSP frame tx done interrupt and a uplink packet
+ from the station simultaneously, we will regard it as a new trigger
+ frame because the packet is received when EOSP frame tx done interrupt.
+
+ We can not sure the uplink packet is sent after old SP or in the old SP.
+ So we must close the old SP in receive done ISR to avoid the problem.
+========================================================================
+*/
+VOID UAPSD_SP_CloseInRVDone(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 IdEntry;
+ int FirstWcid = 0;
+
+
+ if (pAd->MacTab.fAnyStationInPsm == FALSE)
+ return; /* no any station is in power save mode */
+ /* End of if */
+
+
+ /* check for all CLIENT's UAPSD Service Period */
+ for(IdEntry = FirstWcid; IdEntry < MAX_LEN_OF_MAC_TABLE; IdEntry++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[IdEntry];
+
+
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+ /* check if SP is started and EOSP is transmitted ok */
+ if ((pEntry->bAPSDFlagSPStart != 0) &&
+ (pEntry->bAPSDFlagEOSPOK != 0))
+ {
+ /*
+ 1. SP is started;
+ 2. EOSP frame is sent ok.
+ */
+
+ /*
+ We close current SP for the STATION so we can receive new
+ trigger frame from the STATION again.
+ */
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE,("uapsd> close SP in UAPSD_SP_CloseInRVDone()!\n\n\n"));
+#endif /* UAPSD_DEBUG */
+
+ //pEntry->bAPSDFlagSPStart = 0;
+ pEntry->bAPSDFlagEOSPOK = 0;
+ pEntry->bAPSDFlagLegacySent = 0;
+ UAPSD_SP_END(pAd, pEntry);
+ } /* End of if */
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ } /* End of for */
+} /* End of UAPSD_SP_CloseInRVDone */
+
+
+
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+/*
+========================================================================
+Routine Description:
+ Enable/Disable Timing Record Function.
+
+Arguments:
+ pAd Pointer to our adapter
+ Flag 1 (Enable) or 0 (Disable)
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_TimingRecordCtrl(
+ IN UINT32 Flag)
+{
+ if (gUAPSD_TimingFlag == UAPSD_TIMING_CTRL_SUSPEND)
+ return;
+ /* End of if */
+
+ gUAPSD_TimingFlag = Flag;
+} /* End of UAPSD_TimingRecordCtrl */
+
+
+/*
+========================================================================
+Routine Description:
+ Record some timings.
+
+Arguments:
+ pAd Pointer to our adapter
+ Type The timing is for what type
+
+Return Value:
+ None
+
+Note:
+ UAPSD_TIMING_RECORD_ISR
+ UAPSD_TIMING_RECORD_TASKLET
+ UAPSD_TIMING_RECORD_TRG_RCV
+ UAPSD_TIMING_RECORD_MOVE2TX
+ UAPSD_TIMING_RECORD_TX2AIR
+========================================================================
+*/
+VOID UAPSD_TimingRecord(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 Type)
+{
+ UINT32 Index;
+
+ if (gUAPSD_TimingFlag == UAPSD_TIMING_CTRL_STOP)
+ return;
+ /* End of if */
+
+ if ((gUAPSD_TimingFlag == UAPSD_TIMING_CTRL_SUSPEND) &&
+ (Type != UAPSD_TIMING_RECORD_TX2AIR))
+ {
+ return;
+ } /* End of if */
+
+ Index = gUAPSD_TimingIndexUapsd;
+
+ switch(Type)
+ {
+ case UAPSD_TIMING_RECORD_ISR:
+ /* start to record the timing */
+ UAPSD_TIMESTAMP_GET(pAd, gUAPSD_TimingIsr[Index]);
+ break;
+
+ case UAPSD_TIMING_RECORD_TASKLET:
+ UAPSD_TIMESTAMP_GET(pAd, gUAPSD_TimingTasklet[Index]);
+ break;
+
+ case UAPSD_TIMING_RECORD_TRG_RCV:
+ if (gUAPSD_TimingLoopIndex == 0)
+ {
+ /*
+ The trigger frame is the first received frame.
+ The received time will be the time recorded in ISR.
+ */
+ gUAPSD_TimingTrgRcv[Index] = gUAPSD_TimingIsr[Index];
+ }
+ else
+ {
+ /*
+ Some packets are handled before the trigger frame so
+ we record next one.
+ */
+ UAPSD_TIMING_RECORD_STOP();
+ } /* End of if */
+ break;
+
+ case UAPSD_TIMING_RECORD_MOVE2TX:
+ UAPSD_TIMESTAMP_GET(pAd, gUAPSD_TimingMov2Tx[Index]);
+
+ /* prepare to wait for tx done */
+ UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_SUSPEND);
+ break;
+
+ case UAPSD_TIMING_RECORD_TX2AIR:
+ UAPSD_TIMESTAMP_GET(pAd, gUAPSD_TimingTx2Air[Index]);
+
+ /* sum the delay */
+ gUAPSD_TimingSumIsr2Tasklet += \
+ (UINT32)(gUAPSD_TimingTasklet[Index] - gUAPSD_TimingIsr[Index]);
+ gUAPSD_TimingSumTrig2Txqueue += \
+ (UINT32)(gUAPSD_TimingMov2Tx[Index] - gUAPSD_TimingTrgRcv[Index]);
+ gUAPSD_TimingSumTxqueue2Air += \
+ (UINT32)(gUAPSD_TimingTx2Air[Index] - gUAPSD_TimingMov2Tx[Index]);
+
+ /* display average delay */
+ if ((Index % UAPSD_TIMING_RECORD_DISPLAY_TIMES) == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> Isr2Tasklet=%d, Trig2Queue=%d, Queue2Air=%d micro seconds\n",
+ gUAPSD_TimingSumIsr2Tasklet/
+ UAPSD_TIMING_RECORD_DISPLAY_TIMES,
+ gUAPSD_TimingSumTrig2Txqueue/
+ UAPSD_TIMING_RECORD_DISPLAY_TIMES,
+ gUAPSD_TimingSumTxqueue2Air/
+ UAPSD_TIMING_RECORD_DISPLAY_TIMES));
+ gUAPSD_TimingSumIsr2Tasklet = 0;
+ gUAPSD_TimingSumTrig2Txqueue = 0;
+ gUAPSD_TimingSumTxqueue2Air = 0;
+ } /* End of if */
+
+ /* ok, a record is finished; prepare to record the next one */
+ gUAPSD_TimingIndexUapsd ++;
+
+ if (gUAPSD_TimingIndexUapsd >= UAPSD_TIMING_RECORD_MAX)
+ gUAPSD_TimingIndexUapsd = 0;
+ /* End of if */
+
+ /* stop the record */
+ gUAPSD_TimingFlag = UAPSD_TIMING_CTRL_STOP;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("sam> Isr->Tasklet:%d, Trig->TxQueue:%d, TxQueue->TxDone:%d\n",
+ (UINT32)(gUAPSD_TimingTasklet[Index] - gUAPSD_TimingIsr[Index]),
+ (UINT32)(gUAPSD_TimingMov2Tx[Index] - gUAPSD_TimingTrgRcv[Index]),
+ (UINT32)(gUAPSD_TimingTx2Air[Index] - gUAPSD_TimingMov2Tx[Index])));
+ break;
+ } /* End of switch */
+} /* End of UAPSD_TimingRecord */
+
+
+/*
+========================================================================
+Routine Description:
+ Record the loop index for received packet handle.
+
+Arguments:
+ pAd Pointer to our adapter
+ LoopIndex The RxProcessed in APRxDoneInterruptHandle()
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_TimeingRecordLoopIndex(
+ IN UINT32 LoopIndex)
+{
+ gUAPSD_TimingLoopIndex = LoopIndex;
+} /* End of UAPSD_TimeingRecordLoopIndex */
+
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+
+
+/*
+========================================================================
+Routine Description:
+ Handle PS-Poll Frame.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry the source STATION
+
+Return Value:
+ TRUE Handle OK
+ FALSE Handle FAIL
+
+Note:
+========================================================================
+*/
+BOOLEAN UAPSD_PsPollHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ QUEUE_HEADER *pAcPsQue;
+ QUEUE_HEADER *pAcSwQue;
+ PQUEUE_ENTRY pQuedEntry;
+ PNDIS_PACKET pQuedPkt;
+ UINT32 AcQueId;
+ /*
+ AC ID = VO > VI > BK > BE
+ so we need to change BE & BK
+ => AC priority = VO > VI > BE > BK
+ */
+ UINT32 AcPriority[WMM_NUM_OF_AC] = { 1, 0, 2, 3 };
+ UCHAR QueIdList[WMM_NUM_OF_AC] = { QID_AC_BE, QID_AC_BK,
+ QID_AC_VI, QID_AC_VO };
+ BOOLEAN FlgQueEmpty;
+ INT32 IdAc; /* must be signed, can not use unsigned */
+ UINT32 Aid, QueId;
+
+
+ /* sanity check */
+ if (pEntry == NULL)
+ return FALSE; /* fatal error */
+ /* End of if */
+
+ /* init */
+ FlgQueEmpty = TRUE;
+ pAcSwQue = NULL;
+ pQuedPkt = NULL;
+
+ /* sanity check */
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+ if (pEntry->bAPSDAllAC == 0)
+ {
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ return FALSE; /* not all AC are delivery-enabled */
+ } /* End of if */
+
+ if (pEntry->bAPSDFlagSPStart != 0)
+ {
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ return FALSE; /* its service period is not yet ended */
+ } /* End of if */
+
+ /* from highest priority AC3 --> AC2 --> AC0 --> lowest priority AC1 */
+ for (IdAc=(WMM_NUM_OF_AC-1); IdAc>=0; IdAc--)
+ {
+ AcQueId = AcPriority[IdAc];
+
+ /*
+ NOTE: get U-APSD queue pointer here to speed up, do NOT use
+ pEntry->UAPSDQueue[AcQueId] throughout codes because
+ compiler will compile it to many assembly codes.
+ */
+ pAcPsQue = &pEntry->UAPSDQueue[AcQueId];
+
+ /* check if any U-APSD packet is queued for the AC */
+ if (pAcPsQue->Head == NULL)
+ continue;
+ /* End of if */
+
+ /* at least one U-APSD packet exists here */
+
+ /* put U-APSD packets to the AC software queue */
+ if ((pAcPsQue->Head != NULL) && (pQuedPkt == NULL))
+ {
+ /* get AC software queue */
+ QueId = QueIdList[AcQueId];
+ pAcSwQue = &pAd->TxSwQueue[QueId];
+
+ /* get the U-APSD packet */
+ pQuedEntry = RemoveHeadQueue(pAcPsQue);
+ pQuedPkt = QUEUE_ENTRY_TO_PACKET(pQuedEntry);
+
+ if (pQuedPkt != NULL)
+ {
+ /*
+ WMM Specification V1.1 3.6.1.7
+ The More Data bit (b13) of the directed MSDU or MMPDU
+ associated with delivery-enabled ACs and destined for
+ that WMM STA indicates that more frames are buffered for
+ the delivery-enabled ACs.
+ */
+ RTMP_SET_PACKET_MOREDATA(pQuedPkt, TRUE);
+
+ /* set U-APSD flag & its software queue ID */
+ RTMP_SET_PACKET_UAPSD(pQuedPkt, TRUE, QueId);
+ } /* End of if */
+ } /* End of while */
+
+ if (pAcPsQue->Head != NULL)
+ {
+ /* still have packets in queue */
+ FlgQueEmpty = FALSE;
+ break;
+ } /* End of if */
+ } /* End of for */
+
+ if (pQuedPkt != NULL)
+ {
+ if (FlgQueEmpty == TRUE)
+ {
+ /*
+ No any more queued U-APSD packet so clear More Data bit of
+ the last frame.
+ */
+ RTMP_SET_PACKET_MOREDATA(pQuedPkt, FALSE);
+ } /* End of if */
+
+ UAPSD_INSERT_QUEUE_AC(pAd, pEntry, pAcSwQue, pQuedPkt);
+ } /* End of if */
+
+ /* clear corresponding TIM bit */
+
+ /* get its AID for the station */
+ Aid = pEntry->Aid;
+
+ if ((pEntry->bAPSDAllAC == 1) && (FlgQueEmpty == TRUE))
+ {
+ /* all AC are U-APSD and no any U-APSD packet is queued, set TIM */
+
+#ifdef CONFIG_AP_SUPPORT
+ /* clear TIM bit */
+ if ((Aid > 0) && (Aid < MAX_LEN_OF_MAC_TABLE))
+ {
+ WLAN_MR_TIM_BIT_CLEAR(pAd, pEntry->apidx, Aid);
+ } /* End of if */
+#endif /* CONFIG_AP_SUPPORT */
+ } /* End of if */
+
+ /* reset idle timeout here whenever a trigger frame is received */
+ pEntry->UAPSDQIdleCount = 0;
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+
+ /* Dequeue outgoing frames from TxSwQueue0..3 queue and process it */
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ return TRUE;
+}
+
+/*
+========================================================================
+Routine Description:
+ Get the queue status for delivery-enabled AC.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry the peer entry
+ pFlgIsAnyPktForBK TRUE: At lease a BK packet is queued
+ pFlgIsAnyPktForBE TRUE: At lease a BE packet is queued
+ pFlgIsAnyPktForVI TRUE: At lease a VI packet is queued
+ pFlgIsAnyPktForVO TRUE: At lease a VO packet is queued
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_QueueStatusGet(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ OUT BOOLEAN *pFlgIsAnyPktForBK,
+ OUT BOOLEAN *pFlgIsAnyPktForBE,
+ OUT BOOLEAN *pFlgIsAnyPktForVI,
+ OUT BOOLEAN *pFlgIsAnyPktForVO)
+{
+ /* init */
+ *pFlgIsAnyPktForBK = FALSE;
+ *pFlgIsAnyPktForBE = FALSE;
+ *pFlgIsAnyPktForVI = FALSE;
+ *pFlgIsAnyPktForVO = FALSE;
+
+ /* sanity check */
+ if (pEntry == NULL)
+ return;
+
+ /* get queue status */
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+ if (pEntry->UAPSDQueue[QID_AC_BK].Head != NULL)
+ *pFlgIsAnyPktForBK = TRUE;
+ if (pEntry->UAPSDQueue[QID_AC_BE].Head != NULL)
+ *pFlgIsAnyPktForBE = TRUE;
+ if (pEntry->UAPSDQueue[QID_AC_VI].Head != NULL)
+ *pFlgIsAnyPktForVI = TRUE;
+ if (pEntry->UAPSDQueue[QID_AC_VO].Head != NULL)
+ *pFlgIsAnyPktForVO = TRUE;
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+}
+
+/*
+========================================================================
+Routine Description:
+ Handle UAPSD Trigger Frame.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry the source STATION
+ UpOfFrame the UP of the trigger frame
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_TriggerFrameHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR UpOfFrame)
+{
+ QUEUE_HEADER *pAcPsQue;
+ QUEUE_HEADER *pAcSwQue, *pLastAcSwQue;
+ PQUEUE_ENTRY pQuedEntry;
+ PNDIS_PACKET pQuedPkt;
+
+ UINT32 AcQueId;
+ UINT32 TxPktNum, SpMaxLen;
+ /*
+ AC ID = VO > VI > BK > BE
+ so we need to change BE & BK
+ => AC priority = VO > VI > BE > BK
+ */
+ UINT32 AcPriority[WMM_NUM_OF_AC] = { 1, 0, 2, 3 };
+ /* 0: deliver all U-APSD packets */
+ UINT32 SpLenMap[WMM_NUM_OF_AC] = { 0, 2, 4, 6 };
+ UCHAR QueIdList[WMM_NUM_OF_AC] = { QID_AC_BE, QID_AC_BK,
+ QID_AC_VI, QID_AC_VO };
+ BOOLEAN FlgQueEmpty;
+ BOOLEAN FlgNullSnd;
+ BOOLEAN FlgMgmtFrame;
+ UINT32 Aid, QueId;
+ INT32 IdAc; /* must be signed, can not use unsigned */
+/* ULONG FlgIrq; */
+
+#ifdef UAPSD_SP_ACCURATE
+ ULONG TimeNow;
+#endif /* UAPSD_SP_ACCURATE */
+
+
+ /* sanity check for Service Period of the STATION */
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("\nuapsd> bAPSDFlagLegacySent = %d!\n",
+ pEntry->bAPSDFlagLegacySent));
+#endif /* UAPSD_DEBUG */
+
+ if (pEntry->bAPSDFlagSPStart != 0)
+ {
+ /*
+ reset ContinueTxFailCnt
+ */
+ pEntry->ContinueTxFailCnt = 0;
+
+ /*
+ WMM Specification V1.1 3.6.1.5
+ A Trigger Frame received by the WMM AP from a WMM STA that
+ already has an USP underway shall not trigger the start of a new
+ USP.
+ */
+
+ /*
+ Current SP for the STATION is not yet ended so the packet is
+ normal DATA packet.
+ */
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> sorry! SP is not yet closed!\n"));
+#endif /* UAPSD_DEBUG */
+
+#ifdef UAPSD_SP_ACCURATE
+ /*
+ The interval between the data frame from QSTA and last confirmed
+ packet from QAP in UAPSD_SP_AUE_Handle() is too large so maybe
+ we suffer the worse case.
+
+ Currently, if we send any packet with 1Mbps in 2.4GHz and 6Mbps
+ in 5GHz, no any statistics count for the packet so the SP can
+ not be closed.
+ */
+ UAPSD_TIME_GET(pAd, TimeNow);
+
+ if ((TimeNow - pEntry->UAPSDTimeStampLast) >= UAPSD_EPT_SP_INT)
+ {
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> SP period is too large so SP is closed first!"
+ " (%lu %lu %lu)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",
+ TimeNow, pEntry->UAPSDTimeStampLast,
+ (TimeNow - pEntry->UAPSDTimeStampLast)));
+
+ gUAPSD_SP_CloseAbnormalNum ++;
+#endif /* UAPSD_DEBUG */
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ UAPSD_SP_Close(pAd, pEntry);
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+ }
+ else
+ {
+#endif /* UAPSD_SP_ACCURATE */
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ return;
+
+#ifdef UAPSD_SP_ACCURATE
+ }
+#endif /* UAPSD_SP_ACCURATE */
+ }
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+ UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_TRG_RCV);
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+
+#ifdef UAPSD_DEBUG
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> EOSP is not NULL!\n"));
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ return;
+ }
+#endif /* UAPSD_DEBUG */
+
+ if (pEntry->MaxSPLength >= 4)
+ {
+ /* fatal error, should be 0 ~ 3 so reset it to 0 */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("uapsd> MaxSPLength >= 4 (%d)!\n", pEntry->MaxSPLength));
+ pEntry->MaxSPLength = 0;
+ }
+
+
+#ifdef UAPSD_SP_ACCURATE
+ /* mark the start time for the SP */
+ UAPSD_TIME_GET(pAd, pEntry->UAPSDTimeStampLast);
+
+
+ /* check if current rate of the entry is 1Mbps (2.4GHz) or 6Mbps (5GHz) */
+
+#ifdef RTMP_MAC_USB
+ /* always use rough mechanism */
+ pEntry->bAPSDFlagSpRoughUse = 1;
+#endif /* RTMP_MAC_USB */
+#else
+
+ pEntry->bAPSDFlagSpRoughUse = 1;
+#endif /* UAPSD_SP_ACCURATE */
+
+
+ /* sanity Check for UAPSD condition */
+ if (UpOfFrame >= 8)
+ UpOfFrame = 1; /* shout not be here */
+
+ /* get the AC ID of incoming packet */
+ AcQueId = MapUserPriorityToAccessCategory[UpOfFrame];
+
+ /* check whether the AC is trigger-enabled AC */
+ if (pEntry->bAPSDCapablePerAC[AcQueId] == 0)
+ {
+ /*
+ WMM Specification V1.1 Page 4
+ Trigger Frame: A QoS Data or QoS Null frame from a WMM STA in
+ Power Save Mode associated with an AC the WMM STA has configured
+ to be a trigger-enabled AC.
+
+ A QoS Data or QoS Null frame that indicates transition to/from
+ Power Save Mode is not considered to be a Trigger Frame and the
+ AP shall not respond with a QoS Null frame.
+ */
+
+ /*
+ ERROR! the AC does not belong to a trigger-enabled AC or
+ the ACM of the AC is set.
+ */
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+ return;
+ }
+
+
+ /* enqueue U-APSD packets to AC software queues */
+
+ /*
+ Protect TxSwQueue0 & McastPsQueue because use them in
+ interrupt context.
+ */
+/* RTMP_IRQ_LOCK(FlgIrq); */
+
+ /* init */
+ FlgQueEmpty = TRUE;
+ TxPktNum = 0;
+ SpMaxLen = SpLenMap[pEntry->MaxSPLength];
+ pAcSwQue = NULL;
+ pLastAcSwQue = NULL;
+ pQuedPkt = NULL;
+ FlgMgmtFrame = 0;
+
+ /* from highest priority AC3 --> AC2 --> AC0 --> lowest priority AC1 */
+ for (IdAc=(WMM_NUM_OF_AC-1); IdAc>=0; IdAc--)
+ {
+ AcQueId = AcPriority[IdAc];
+
+ /* check if the AC is delivery-enable AC */
+ if (pEntry->bAPSDDeliverEnabledPerAC[AcQueId] == 0)
+ continue;
+
+ /*
+ NOTE: get U-APSD queue pointer here to speed up, do NOT use
+ pEntry->UAPSDQueue[AcQueId] throughout codes because
+ compiler will compile it to many assembly codes.
+ */
+ pAcPsQue = &pEntry->UAPSDQueue[AcQueId];
+
+ /* check if any U-APSD packet is queued for the AC */
+ if (pAcPsQue->Head == NULL)
+ continue;
+
+ /* at least one U-APSD packet exists here */
+
+ /* get AC software queue */
+ QueId = QueIdList[AcQueId];
+ pAcSwQue = &pAd->TxSwQueue[QueId];
+
+ /* put U-APSD packets to the AC software queue */
+ while(pAcPsQue->Head)
+ {
+ /* check if Max SP Length != 0 */
+ if (SpMaxLen != 0)
+ {
+ /*
+ WMM Specification V1.1 3.6.1.7
+ At each USP for a WMM STA, the WMM AP shall attempt to
+ transmit at least one MSDU or MMPDU, but no more than the
+ value encoded in the Max SP Length field in the QoS Info
+ Field of a WMM Information Element from delivery-enabled
+ ACs, that are destined for the WMM STA.
+ */
+ if (TxPktNum >= SpMaxLen)
+ {
+ /*
+ Some queued U-APSD packets still exists so we will
+ not clear MoreData bit of the packet.
+ */
+ FlgQueEmpty = FALSE;
+ break;
+ }
+ }
+
+ /* count U-APSD packet number */
+ TxPktNum ++;
+
+ /* queue last U-APSD packet */
+ if (pQuedPkt != NULL)
+ {
+ /* enqueue U-APSD packet to transmission software queue */
+
+ /*
+ WMM Specification V1.1 3.6.1.7
+ Each buffered frame shall be delivered using the access
+ parameters of its AC.
+ */
+ UAPSD_INSERT_QUEUE_AC(pAd, pEntry, pLastAcSwQue, pQuedPkt);
+ }
+
+ /* get the U-APSD packet */
+ pQuedEntry = RemoveHeadQueue(pAcPsQue);
+ pQuedPkt = QUEUE_ENTRY_TO_PACKET(pQuedEntry);
+
+ if (pQuedPkt != NULL)
+ {
+ if (RTMP_GET_PACKET_MGMT_PKT(pQuedPkt) == 1)
+ FlgMgmtFrame = 1;
+
+ /*
+ WMM Specification V1.1 3.6.1.7
+ The More Data bit (b13) of the directed MSDU or MMPDU
+ associated with delivery-enabled ACs and destined for
+ that WMM STA indicates that more frames are buffered for
+ the delivery-enabled ACs.
+ */
+ RTMP_SET_PACKET_MOREDATA(pQuedPkt, TRUE);
+
+ /* set U-APSD flag & its software queue ID */
+ RTMP_SET_PACKET_UAPSD(pQuedPkt, TRUE, QueId);
+ }
+
+ /* backup its software queue pointer */
+ pLastAcSwQue = pAcSwQue;
+ }
+
+ if (FlgQueEmpty == FALSE)
+ {
+ /* FlgQueEmpty will be FALSE only when TxPktNum >= SpMaxLen */
+ break;
+ }
+ }
+
+ /*
+ For any mamagement UAPSD frame, we use DMA to do SP check
+ because no any FIFO statistics for management frame.
+ */
+ if (FlgMgmtFrame)
+ pEntry->bAPSDFlagSpRoughUse = 1;
+
+ /*
+ No need to protect EOSP handle code because we will be here
+ only when last SP is ended.
+ */
+ FlgNullSnd = FALSE;
+
+ if (TxPktNum >= 1)
+ {
+ if (FlgQueEmpty == TRUE)
+ {
+ /*
+ No any more queued U-APSD packet so clear More Data bit of
+ the last frame.
+ */
+ RTMP_SET_PACKET_MOREDATA(pQuedPkt, FALSE);
+ }
+ }
+
+ //pEntry->bAPSDFlagSPStart = 1; /* set the SP start flag */
+ UAPSD_SP_START(pAd, pEntry); /* set the SP start flag */
+ pEntry->bAPSDFlagEOSPOK = 0;
+
+#ifdef UAPSD_DEBUG
+{
+ ULONG DebugTimeNow;
+
+ UAPSD_TIME_GET(pAd, DebugTimeNow);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> start a SP (Tx Num = %d) (Rough SP = %d) "
+ "(Has Any Mgmt = %d) (Abnormal = %d) (Time = %lu)\n",
+ TxPktNum, pEntry->bAPSDFlagSpRoughUse, FlgMgmtFrame,
+ gUAPSD_SP_CloseAbnormalNum, DebugTimeNow));
+}
+#endif /* UAPSD_DEBUG */
+
+ if (TxPktNum <= 1)
+ {
+ /* if no data needs to tx, respond with QosNull for the trigger frame */
+ pEntry->pUAPSDEOSPFrame = NULL;
+ pEntry->UAPSDTxNum = 0;
+
+ if (TxPktNum <= 0)
+ {
+ FlgNullSnd = TRUE;
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("uapsd> No data, send a Qos-Null frame with ESOP bit on and "
+ "UP=%d to end USP\n", UpOfFrame));
+#endif /* RELEASE_EXCLUDE */
+ }
+ else
+ {
+ /* only one packet so send it directly */
+ RTMP_SET_PACKET_EOSP(pQuedPkt, TRUE);
+ UAPSD_INSERT_QUEUE_AC(pAd, pEntry, pLastAcSwQue, pQuedPkt);
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("uapsd> Only one packet with UP = %d\n",
+ RTMP_GET_PACKET_UP(pQuedPkt)));
+#endif /* RELEASE_EXCLUDE */
+ } /* End of if */
+
+ /*
+ We will send the QoS Null frame below and we will hande the
+ QoS Null tx done in RTMPFreeTXDUponTxDmaDone().
+ */
+ }
+ else
+ {
+ /* more than two U-APSD packets */
+
+ /*
+ NOTE: EOSP bit != !MoreData bit because Max SP Length,
+ we can not use MoreData bit to decide EOSP bit.
+ */
+
+ /*
+ Backup the EOSP frame and
+ we will transmit the EOSP frame in RTMPFreeTXDUponTxDmaDone().
+ */
+ RTMP_SET_PACKET_EOSP(pQuedPkt, TRUE);
+
+ pEntry->pUAPSDEOSPFrame = (PQUEUE_ENTRY)pQuedPkt;
+ pEntry->UAPSDTxNum = TxPktNum-1; /* skip the EOSP frame */
+ }
+
+#ifdef UAPSD_DEBUG
+ if ((pEntry->pUAPSDEOSPFrame != NULL) &&
+ (RTMP_GET_PACKET_MGMT_PKT(pEntry->pUAPSDEOSPFrame) == 1))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> The EOSP frame is a management frame.\n"));
+ }
+#endif /* UAPSD_DEBUG */
+
+
+#ifdef UAPSD_SP_ACCURATE
+ /* count for legacy PS packet */
+
+ /*
+ Note: A worse case for mix mode (UAPSD + legacy PS):
+ PS-Poll --> legacy ps packet --> trigger frame --> QoS Null frame
+ (QSTA) (QAP) (QSTA) (QAP)
+
+ where statistics handler is NICUpdateFifoStaCounters().
+
+ If we receive the trigger frame before the legacy ps packet is sent to
+ the air, when we call statistics handler in tx done, it maybe the
+ legacy ps statistics, not the QoS Null frame statistics, so we will
+ do UAPSD counting fail.
+
+ We need to count the legacy PS here if it is not yet sent to the air.
+ */
+
+ /*
+ Note: in addition, only one legacy PS need to count because one legacy
+ packet for one PS-Poll packet; if we receive a trigger frame from a
+ station, it means that only one legacy ps packet is possible not sent
+ to the air, it is impossible more than 2 legacy packets are not yet
+ sent to the air.
+ */
+
+ if ((pEntry->bAPSDFlagSpRoughUse == 0) &&
+ (pEntry->bAPSDFlagLegacySent != 0))
+ {
+ pEntry->UAPSDTxNum ++;
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> A legacy PS is sent! UAPSDTxNum = %d\n",
+ pEntry->UAPSDTxNum));
+#endif /* UAPSD_DEBUG */
+ }
+#endif /* UAPSD_SP_ACCURATE */
+
+
+ /* clear corresponding TIM bit */
+
+ /* get its AID for the station */
+ Aid = pEntry->Aid;
+
+ if ((pEntry->bAPSDAllAC == 1) && (FlgQueEmpty == 1))
+ {
+ /* all AC are U-APSD and no any U-APSD packet is queued, set TIM */
+
+#ifdef CONFIG_AP_SUPPORT
+ /* clear TIM bit */
+ if ((Aid > 0) && (Aid < MAX_LEN_OF_MAC_TABLE))
+ {
+ WLAN_MR_TIM_BIT_CLEAR(pAd, pEntry->apidx, Aid);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ /* reset idle timeout here whenever a trigger frame is received */
+ pEntry->UAPSDQIdleCount = 0;
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+
+
+ /* check if NULL Frame is needed to be transmitted */
+
+ /* it will be crashed, when spin locked in kernel 2.6 */
+ if (FlgNullSnd)
+ {
+ /* bQosNull = bEOSP = TRUE = 1 */
+
+ /*
+ Use management queue to tx QoS Null frame to avoid delay so
+ us_of_frame is not used.
+ */
+ RtmpEnqueueNullFrame(pAd, pEntry->Addr, pEntry->CurrTxRate,
+ Aid, pEntry->apidx, TRUE, TRUE, UpOfFrame);
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> end a SP by a QoS Null frame!\n"));
+#endif /* UAPSD_DEBUG */
+ }
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+ UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_MOVE2TX);
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+
+ /* Dequeue outgoing frames from TxSwQueue0..3 queue and process it */
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+}
+
+
+#ifdef RTMP_MAC_USB
+/*
+========================================================================
+Routine Description:
+ Tag current offset of the AC in USB URB tx buffer.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pPkt the tx packet
+ Wcid destination entry id
+ PktOffset USB tx buffer offset
+
+Return Value:
+ None
+
+Note:
+ Only for RT2870.
+========================================================================
+*/
+VOID UAPSD_TagFrame(
+ IN RTMP_ADAPTER *pAd,
+ IN NDIS_PACKET *pPkt,
+ IN UCHAR Wcid,
+ IN UINT32 PktOffset)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR AcQueId;
+
+
+ if ((Wcid == MCAST_WCID) || (Wcid >= MAX_LEN_OF_MAC_TABLE))
+ return; /* the frame is broadcast/multicast frame */
+ /* End of if */
+
+ pEntry = &pAd->MacTab.Content[Wcid];
+
+ if (pEntry->bAPSDFlagSPStart == 0)
+ return; /* SP is not started */
+ /* End of if */
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> prepare to tag the frame...\n"));
+#endif /* UAPSD_DEBUG */
+
+ if (RTMP_GET_PACKET_UAPSD_Flag(pPkt) == TRUE)
+ {
+ /* mark the latest USB tx buffer offset for the priority */
+ AcQueId = RTMP_GET_PACKET_UAPSD_QUE_ID(pPkt);
+ pEntry->UAPSDTagOffset[AcQueId] = PktOffset;
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> tag offset = %d\n", PktOffset));
+#endif /* UAPSD_DEBUG */
+ } /* End of if */
+} /* End of UAPSD_TagFrame */
+
+
+/*
+========================================================================
+Routine Description:
+ Check if UAPSD packets are tx ok.
+
+Arguments:
+ pAd Pointer to our adapter
+ AcQueId TX completion for the AC (0 ~ 3)
+ bulkStartPos
+ bulkEnPos
+
+Return Value:
+ None
+
+Note:
+ Only for RT2870.
+========================================================================
+*/
+VOID UAPSD_UnTagFrame(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR AcQueId,
+ IN UINT32 bulkStartPos,
+ IN UINT32 bulkEnPos)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ UINT32 IdEntry;
+ UINT32 TxPktTagOffset;
+ UINT16 QueId;
+ int FirstWcid = 1;
+
+
+ RTMP_SEM_LOCK(&pAd->UAPSDEOSPLock);
+
+ /* loop for all entries to check whether we need to close their SP */
+ for(IdEntry = FirstWcid; IdEntry < MAX_LEN_OF_MAC_TABLE; IdEntry++)
+ {
+ pEntry = &pAd->MacTab.Content[IdEntry];
+
+ if ((IS_ENTRY_CLIENT(pEntry)
+ )
+ && (pEntry->bAPSDFlagSPStart == 1) &&
+ (pEntry->UAPSDTagOffset[AcQueId] != 0))
+ {
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_ERROR, ("uapsd> bulkStartPos = %d\n", bulkStartPos));
+ DBGPRINT(RT_DEBUG_ERROR, ("uapsd> bulkEnPos = %d\n", bulkEnPos));
+ DBGPRINT(RT_DEBUG_ERROR, ("uapsd> record offset = %d\n", pEntry->UAPSDTagOffset[AcQueId]));
+#endif /* UAPSD_DEBUG */
+
+ /*
+ 1. tx tag is in [bulkStartPos, bulkEnPos];
+ 2. when bulkEnPos < bulkStartPos
+ */
+ TxPktTagOffset = pEntry->UAPSDTagOffset[AcQueId];
+
+ if (((TxPktTagOffset >= bulkStartPos) &&
+ (TxPktTagOffset <= bulkEnPos)) ||
+ ((bulkEnPos < bulkStartPos) &&
+ (TxPktTagOffset >= bulkStartPos)) ||
+ ((bulkEnPos < bulkStartPos) &&
+ (TxPktTagOffset <= bulkEnPos)))
+ {
+ /* ok, some UAPSD frames of the AC are transmitted */
+ pEntry->UAPSDTagOffset[AcQueId] = 0;
+
+ if (pEntry->UAPSDTxNum == 0)
+ {
+ /* ok, all UAPSD frames are transmitted */
+ //pEntry->bAPSDFlagSPStart = 0;
+ pEntry->bAPSDFlagEOSPOK = 0;
+ UAPSD_SP_END(pAd, pEntry);
+
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ {
+ /* should not be here */
+ RELEASE_NDIS_PACKET(pAd,
+ QUEUE_ENTRY_TO_PACKET(pEntry->pUAPSDEOSPFrame),
+ NDIS_STATUS_FAILURE);
+ pEntry->pUAPSDEOSPFrame = NULL;
+ } /* End of if */
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_ERROR, ("uapsd> [1] close SP (%d)!\n", AcQueId));
+#endif /* UAPSD_DEBUG */
+ continue; /* check next station */
+ } /* End of if */
+
+ if ((pEntry->UAPSDTagOffset[QID_AC_BE] == 0) &&
+ (pEntry->UAPSDTagOffset[QID_AC_BK] == 0) &&
+ (pEntry->UAPSDTagOffset[QID_AC_VI] == 0) &&
+ (pEntry->UAPSDTagOffset[QID_AC_VO] == 0))
+ {
+ /*
+ OK, UAPSD frames of all AC for the entry are transmitted
+ except the EOSP frame.
+ */
+
+ if (pEntry->pUAPSDEOSPFrame != NULL)
+ {
+ /* transmit the EOSP frame */
+ PNDIS_PACKET pPkt;
+
+ pPkt = QUEUE_ENTRY_TO_PACKET(pEntry->pUAPSDEOSPFrame);
+ QueId = RTMP_GET_PACKET_UAPSD_QUE_ID(pPkt);
+
+ if (QueId > QID_AC_VO)
+ {
+ /* should not be here, only for sanity */
+ QueId = QID_AC_BE;
+ } /* End of if */
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_ERROR, ("uapsd> enqueue the EOSP frame...\n"));
+#endif /* UAPSD_DEBUG */
+
+ UAPSD_INSERT_QUEUE_AC(pAd, pEntry,
+ &pAd->TxSwQueue[QueId],
+ pEntry->pUAPSDEOSPFrame);
+
+ pEntry->pUAPSDEOSPFrame = NULL;
+
+ /*
+ The EOSP frame will be put into ASIC to tx
+ in RTMPHandleTxRingDmaDoneInterrupt(),
+ not the function.
+ */
+
+ /* de-queue packet here to speed up EOSP frame response */
+ printk("%s:: ----> RTMPDeQueuePacket\n", __FUNCTION__);
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+ else
+ {
+ /* only when 1 data frame with EOSP = 1 is transmitted */
+ //pEntry->bAPSDFlagSPStart = 0;
+ pEntry->bAPSDFlagEOSPOK = 0;
+ UAPSD_SP_END(pAd, pEntry);
+
+#ifdef UAPSD_DEBUG
+ DBGPRINT(RT_DEBUG_ERROR, ("uapsd> [2] close SP (%d)!\n", AcQueId));
+#endif /* UAPSD_DEBUG */
+ } /* End of if */
+
+ /* no any EOSP frames are queued and prepare to close the SP */
+ pEntry->UAPSDTxNum = 0;
+ } /* End of if */
+ } /* End of if */
+ } /* End of if */
+ } /* End of for */
+
+ RTMP_SEM_UNLOCK(&pAd->UAPSDEOSPLock);
+} /* End of UAPSD_UnTagFrame */
+#endif /* RTMP_MAC_USB */
+
+
+#ifdef VENDOR_FEATURE3_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Queue packet to a AC software queue.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry The station
+ pQueueHeader The software queue header of the AC
+ bulkEnPos The packet entry
+
+Return Value:
+ None
+
+Note:
+ Only for code size reduce purpose.
+========================================================================
+*/
+static VOID UAPSD_InsertTailQueueAc(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN QUEUE_HEADER *pQueueHeader,
+ IN QUEUE_ENTRY *pQueueEntry)
+{
+ InsertTailQueueAc(pAd, pEntry, pQueueHeader, pQueueEntry);
+} /* End of InsertTailQueueAc */
+#endif /* VENDOR_FEATURE3_SUPPORT */
+
+#endif /* UAPSD_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/vht.c b/cleopatre/devkit/mt7601udrv/common/vht.c
new file mode 100644
index 0000000000..c75757b069
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/vht.c
@@ -0,0 +1,400 @@
+/*
+
+*/
+
+#include "rt_config.h"
+
+
+/*
+ IEEE 802.11AC D2.0 sec 22.3.14
+ Channelization, Table 22-21
+
+ A VHT channel is specified by the four PLME MIB fields
+ (Fields to specify VHT channels).
+
+ dot11CurrentChannelBandwidth:
+ Channel bandwidth. Possible values are
+ cbw20, cbw40, cbw80, cbw160 and cbw80p80.
+ dot11CurrentChannelCenterFrequencyIndex1:
+ In 20 MHz, 40 MHz, 80 MHz and 160 MHz channels, denotes the channel
+ center frequency.
+ In 80+80 MHz channels, denotes the center frequency of the frequency
+ segment 1, which is the frequency segment containing the primary
+ channel..
+ Valid range = 1, ¡K, 200.
+ dot11CurrentChannelCenterFrequencyIndex2:
+ In 80+80 MHz channels, denotes the center frequency of the frequency
+ segment 2, which is the frequency segment that does not contain the
+ primary channel.
+ Valid range = 1, ¡K, 200.
+ Undefined for 20 MHz, 40 MHz, 80 MHz and 160 MHz channels.
+ dot11CurrentPrimaryChannel:
+ Denotes the location of the primary 20 MHz channel.
+ Valid range = 1, ¡K, 200.
+
+
+ Formula:
+ A channel center frequency of 5.000 GHz shall be indicated by
+ dot11ChannelStartingFactor = 8000, and
+ dot11CurrentPrimaryChannel = 200.
+
+ Channel starting frequency
+ = dot11ChannelStartingFactor ¡Ñ 0500 kHz.
+
+ Channel center frequency [MHz]
+ = Channel starting frequency + 5 * dot11CurrentChannelCenterFrequencyIndex
+
+ Primary 20 MHz channel center frequency [MHz]
+ = Channel starting frequency + 5 * dot11CurrentPrimaryChannel
+
+ ex: a channel specified by:
+ dot11CurrentChannelBandwidth = 80 MHz
+ dot11CurrentChannelCenterFrequencyIndex1 = 42
+ dot11CurrentPrimaryChannel = 36
+
+ =>is an 80 MHz channel with a center frequency of 5210 MHz and
+ the primary 20 MHz channel centered at 5180 MHz.
+
+*/
+struct vht_ch_layout{
+ UCHAR ch_low_bnd;
+ UCHAR ch_up_bnd;
+ UCHAR cent_freq_idx;
+};
+
+static struct vht_ch_layout vht_ch_80M[]={
+ {36, 48, 42},
+ {52, 64, 58},
+ {100,112, 106},
+ {116, 128, 122},
+ {132, 144, 138},
+ {149, 161, 155},
+ {0, 0 ,0},
+};
+
+
+
+
+VOID dump_vht_cap(RTMP_ADAPTER *pAd, VHT_CAP_IE *vht_ie)
+{
+ VHT_CAP_INFO *vht_cap = &vht_ie->vht_cap;
+ VHT_MCS_SET *vht_mcs = &vht_ie->mcs_set;
+
+ DBGPRINT(RT_DEBUG_OFF, ("Dump VHT_CAP IE\n"));
+ hex_dump("VHT CAP IE Raw Data", (UCHAR *)vht_ie, sizeof(VHT_CAP_IE));
+
+ DBGPRINT(RT_DEBUG_OFF, ("VHT Capabilities Info Field\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMaximum MPDU Length=%d\n", vht_cap->max_mpdu_len));
+ DBGPRINT(RT_DEBUG_OFF, ("\tSupported Channel Width=%d\n", vht_cap->ch_width));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRxLDPC=%d\n", vht_cap->rx_ldpc));
+ DBGPRINT(RT_DEBUG_OFF, ("\tShortGI_80M=%d\n", vht_cap->sgi_80M));
+ DBGPRINT(RT_DEBUG_OFF, ("\tShortGI_160M=%d\n", vht_cap->sgi_160M));
+ DBGPRINT(RT_DEBUG_OFF, ("\tTxSTBC=%d\n", vht_cap->tx_stbc));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRxSTBC=%d\n", vht_cap->rx_stbc));
+ DBGPRINT(RT_DEBUG_OFF, ("\tSU BeamformerCap=%d\n", vht_cap->bfer_cap_su));
+ DBGPRINT(RT_DEBUG_OFF, ("\tSU BeamformeeCap=%d\n", vht_cap->bfee_cap_su));
+ DBGPRINT(RT_DEBUG_OFF, ("\tCompressedSteeringNumOfBeamformerAnt=%d\n", vht_cap->cmp_st_num_bfer));
+ DBGPRINT(RT_DEBUG_OFF, ("\tNumber of Sounding Dimensions=%d\n", vht_cap->num_snd_dimension));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMU BeamformerCap=%d\n", vht_cap->bfer_cap_mu));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMU BeamformeeCap=%d\n", vht_cap->bfee_cap_mu));
+ DBGPRINT(RT_DEBUG_OFF, ("\tVHT TXOP PS=%d\n", vht_cap->vht_txop_ps));
+ DBGPRINT(RT_DEBUG_OFF, ("\t+HTC-VHT Capable=%d\n", vht_cap->htc_vht_cap));
+ DBGPRINT(RT_DEBUG_OFF, ("\tMaximum A-MPDU Length Exponent=%d\n", vht_cap->max_ampdu_exp));
+ DBGPRINT(RT_DEBUG_OFF, ("\tVHT LinkAdaptation Capable=%d\n", vht_cap->vht_link_adapt));
+
+ DBGPRINT(RT_DEBUG_OFF, ("VHT Supported MCS Set Field\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRx Highest SupDataRate=%d\n", vht_mcs->rx_high_rate));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRxMCS Map_1SS=%d\n", vht_mcs->rx_mcs_map.mcs_ss1));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRxMCS Map_2SS=%d\n", vht_mcs->rx_mcs_map.mcs_ss2));
+ DBGPRINT(RT_DEBUG_OFF, ("\tTx Highest SupDataRate=%d\n", vht_mcs->tx_high_rate));
+ DBGPRINT(RT_DEBUG_OFF, ("\tTxMCS Map_1SS=%d\n", vht_mcs->tx_mcs_map.mcs_ss1));
+ DBGPRINT(RT_DEBUG_OFF, ("\tTxMCS Map_2SS=%d\n", vht_mcs->tx_mcs_map.mcs_ss2));
+}
+
+
+VOID dump_vht_op(RTMP_ADAPTER *pAd, VHT_OP_IE *vht_ie)
+{
+ VHT_OP_INFO *vht_op = &vht_ie->vht_op_info;
+ VHT_MCS_MAP *vht_mcs = &vht_ie->basic_mcs_set;
+
+ DBGPRINT(RT_DEBUG_OFF, ("Dump VHT_OP IE\n"));
+ hex_dump("VHT OP IE Raw Data", (UCHAR *)vht_ie, sizeof(VHT_OP_IE));
+
+ DBGPRINT(RT_DEBUG_OFF, ("VHT Operation Info Field\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("\tChannelWidth=%d\n", vht_op->ch_width));
+ DBGPRINT(RT_DEBUG_OFF, ("\tChannelCenterFrequency Seg 1=%d\n", vht_op->center_freq_1));
+ DBGPRINT(RT_DEBUG_OFF, ("\tChannelCenterFrequency Seg 1=%d\n", vht_op->center_freq_2));
+
+ DBGPRINT(RT_DEBUG_OFF, ("VHT Basic MCS Set Field\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRxMCS Map_1SS=%d\n", vht_mcs->mcs_ss1));
+ DBGPRINT(RT_DEBUG_OFF, ("\tRxMCS Map_2SS=%d\n", vht_mcs->mcs_ss2));
+}
+
+
+/*
+ Currently we only consider about VHT 80MHz!
+*/
+UCHAR vht_cent_ch_freq(RTMP_ADAPTER *pAd, UCHAR prim_ch)
+{
+ INT idx = 0;
+
+
+ if (pAd->CommonCfg.vht_bw < VHT_BW_80 || prim_ch < 36)
+ {
+ pAd->CommonCfg.vht_cent_ch = 0;
+ pAd->CommonCfg.vht_cent_ch2 = 0;
+ return prim_ch;
+ }
+
+ while (vht_ch_80M[idx].ch_up_bnd != 0)
+ {
+ if (prim_ch >= vht_ch_80M[idx].ch_low_bnd &&
+ prim_ch <= vht_ch_80M[idx].ch_up_bnd)
+ {
+ pAd->CommonCfg.vht_cent_ch = vht_ch_80M[idx].cent_freq_idx;
+ return vht_ch_80M[idx].cent_freq_idx;
+ }
+ idx++;
+ }
+
+ return prim_ch;
+}
+
+
+INT vht_mode_adjust(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, VHT_CAP_IE *cap, VHT_OP_IE *op)
+{
+ pEntry->MaxHTPhyMode.field.MODE = MODE_VHT;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+
+ if (op->vht_op_info.ch_width >= 1 && pEntry->MaxHTPhyMode.field.BW == BW_40)
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_80;
+ pEntry->MaxHTPhyMode.field.ShortGI = (cap->vht_cap.sgi_80M);
+ pEntry->MaxHTPhyMode.field.STBC = (cap->vht_cap.rx_stbc > 1 ? 1 : 0);
+ }
+
+ return TRUE;
+}
+
+
+INT get_vht_op_ch_width(RTMP_ADAPTER *pAd)
+{
+
+ return TRUE;
+}
+
+
+/********************************************************************
+ Procedures for 802.11 AC Information elements
+********************************************************************/
+/*
+ Defined in IEEE 802.11AC
+
+ Appeared in Beacon, ProbResp frames
+*/
+INT build_quiet_channel(RTMP_ADAPTER *pAd, UCHAR *buf)
+{
+ INT len = 0;
+
+
+ return len;
+}
+
+
+/*
+ Defined in IEEE 802.11AC
+
+ Appeared in Beacon, ProbResp frames
+*/
+INT build_ext_bss_load(RTMP_ADAPTER *pAd, UCHAR *buf)
+{
+ INT len = 0;
+
+
+ return len;
+}
+
+
+/*
+ Defined in IEEE 802.11AC
+
+ Appeared in Beacon, ProbResp frames
+*/
+INT build_ext_pwr_constraint(RTMP_ADAPTER *pAd, UCHAR *buf)
+{
+ INT len = 0;
+
+
+ return len;
+}
+
+
+/*
+ Defined in IEEE 802.11AC
+
+ Appeared in Beacon, ProbResp frames
+*/
+INT build_vht_pwr_envelope(RTMP_ADAPTER *pAd, UCHAR *buf)
+{
+ INT len = 0;
+
+
+ return len;
+}
+
+
+/*
+ Defined in IEEE 802.11AC
+
+ Appeared in Beacon, (Re)AssocResp, ProbResp frames
+*/
+INT build_vht_op_ie(RTMP_ADAPTER *pAd, UCHAR *buf)
+{
+ VHT_OP_IE vht_op;
+
+ NdisZeroMemory((UCHAR *)&vht_op, sizeof(VHT_OP_IE));
+ vht_op.vht_op_info.ch_width = (pAd->CommonCfg.vht_bw == VHT_BW_80 ? 1: 0);
+ switch (vht_op.vht_op_info.ch_width)
+ {
+ case 0:
+ vht_op.vht_op_info.center_freq_1 = 0;
+ vht_op.vht_op_info.center_freq_2 = 0;
+ break;
+ case 1:
+ case 2:
+ vht_op.vht_op_info.center_freq_1 = pAd->CommonCfg.vht_cent_ch;
+ vht_op.vht_op_info.center_freq_2 = 0;
+ break;
+ case 3:
+ vht_op.vht_op_info.center_freq_1 = pAd->CommonCfg.vht_cent_ch;
+ vht_op.vht_op_info.center_freq_2 = pAd->CommonCfg.vht_cent_ch2;
+ break;
+ }
+
+ vht_op.basic_mcs_set.mcs_ss1 = 3;
+ vht_op.basic_mcs_set.mcs_ss2 = 3;
+ vht_op.basic_mcs_set.mcs_ss3 = 3;
+ vht_op.basic_mcs_set.mcs_ss4 = 3;
+ vht_op.basic_mcs_set.mcs_ss5 = 3;
+ vht_op.basic_mcs_set.mcs_ss6 = 3;
+ vht_op.basic_mcs_set.mcs_ss7 = 3;
+ vht_op.basic_mcs_set.mcs_ss8 = 3;
+ switch (pAd->CommonCfg.RxStream)
+ {
+ case 2:
+ vht_op.basic_mcs_set.mcs_ss2 = 0;
+ case 1:
+ vht_op.basic_mcs_set.mcs_ss1 = 0;
+ break;
+ }
+
+ NdisMoveMemory((UCHAR *)buf, (UCHAR *)&vht_op, sizeof(VHT_OP_IE));
+
+ return sizeof(VHT_OP_IE);
+}
+
+
+/*
+ Defined in IEEE 802.11AC
+
+ Appeared in Beacon, (Re)AssocReq, (Re)AssocResp, ProbReq/Resp frames
+*/
+INT build_vht_cap_ie(RTMP_ADAPTER *pAd, UCHAR *buf)
+{
+ VHT_CAP_IE vht_cap_ie;
+
+ NdisZeroMemory((UCHAR *)&vht_cap_ie, sizeof(VHT_CAP_IE));
+ vht_cap_ie.vht_cap.max_mpdu_len = 0; // TODO: Ask Jerry about hardware limitation.
+ vht_cap_ie.vht_cap.ch_width = 0; /* not support 160 or 80 + 80 MHz */
+ vht_cap_ie.vht_cap.sgi_80M = 1;
+ vht_cap_ie.vht_cap.htc_vht_cap = 1;
+ vht_cap_ie.vht_cap.max_ampdu_exp = 3; // TODO: Ask Jerry about the hardware limitation, currently set as 64K
+ vht_cap_ie.vht_cap.tx_stbc = 1;
+ vht_cap_ie.vht_cap.rx_stbc = 2; // TODO: is it depends on the number of our antennas?
+ vht_cap_ie.vht_cap.tx_ant_consistency = 1;
+ vht_cap_ie.vht_cap.rx_ant_consistency = 1;
+
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss1 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss2 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss3 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss4 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss5 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss6 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss7 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss8 = VHT_MCS_CAP_NA;
+
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss1 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss2 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss3 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss4 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss5 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss6 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss7 = VHT_MCS_CAP_NA;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss8 = VHT_MCS_CAP_NA;
+
+
+ switch (pAd->CommonCfg.RxStream)
+ {
+ case 1:
+ vht_cap_ie.mcs_set.rx_high_rate = 292;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss1 = VHT_MCS_CAP_7;
+ break;
+ case 2:
+ vht_cap_ie.mcs_set.rx_high_rate = 585;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss1 = VHT_MCS_CAP_7;
+ vht_cap_ie.mcs_set.rx_mcs_map.mcs_ss2 = VHT_MCS_CAP_7;
+ break;
+ default:
+ vht_cap_ie.mcs_set.rx_high_rate = 0;
+ break;
+ }
+
+ switch (pAd->CommonCfg.TxStream)
+ {
+ case 1:
+ vht_cap_ie.mcs_set.tx_high_rate = 292;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss1 = VHT_MCS_CAP_7;
+ break;
+ case 2:
+ vht_cap_ie.mcs_set.tx_high_rate = 585;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss1 = VHT_MCS_CAP_7;
+ vht_cap_ie.mcs_set.tx_mcs_map.mcs_ss2 = VHT_MCS_CAP_7;
+ break;
+ default:
+ vht_cap_ie.mcs_set.tx_high_rate = 0;
+ break;
+ }
+
+ NdisMoveMemory(buf, (UCHAR *)&vht_cap_ie, sizeof(VHT_CAP_IE));
+
+ return sizeof(VHT_CAP_IE);
+}
+
+
+INT build_vht_ies(RTMP_ADAPTER *pAd, UCHAR *buf, UCHAR frm)
+{
+ INT len = 0;
+ EID_STRUCT eid_hdr;
+
+
+ eid_hdr.Eid = IE_VHT_CAP;
+ eid_hdr.Len = sizeof(VHT_CAP_IE);
+ NdisMoveMemory(buf, (UCHAR *)&eid_hdr, 2);
+ len = 2;
+
+ len += build_vht_cap_ie(pAd, (UCHAR *)(buf + len));
+ if (frm == SUBTYPE_BEACON || frm == SUBTYPE_PROBE_RSP ||
+ frm == SUBTYPE_ASSOC_RSP || frm == SUBTYPE_REASSOC_RSP)
+ {
+ eid_hdr.Eid = IE_VHT_OP;
+ eid_hdr.Len = sizeof(VHT_OP_IE);
+ NdisMoveMemory((UCHAR *)(buf + len), (UCHAR *)&eid_hdr, 2);
+ len +=2;
+
+ len += build_vht_op_ie(pAd, (UCHAR *)(buf + len));
+ }
+
+ return len;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/common/wapi.c b/cleopatre/devkit/mt7601udrv/common/wapi.c
new file mode 100644
index 0000000000..8c93cfe646
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/wapi.c
@@ -0,0 +1,1185 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wapi.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Albert 2008-4-3 Supoort WAPI protocol
+*/
+/*#include <linux/stdio.h> */
+/*#include <linux/stdlib.h> */
+/*#include <linux/string.h> */
+/*#include <linux/time.h> */
+
+#ifdef WAPI_SUPPORT
+
+#include "rt_config.h"
+
+/* WAPI AKM OUI */
+UCHAR OUI_WAI_CERT_AKM[4] = {0x00, 0x14, 0x72, 0x01};
+UCHAR OUI_WAI_PSK_AKM[4] = {0x00, 0x14, 0x72, 0x02};
+
+/* WAPI CIPHER OUI */
+UCHAR OUI_WPI_CIPHER_SMS4[4] = {0x00, 0x14, 0x72, 0x01};
+
+UCHAR WAPI_TYPE[] = {0x88, 0xb4};
+
+/* IV default value */
+UCHAR AE_BCAST_PN[LEN_WAPI_TSC] = {0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
+ 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c};
+UCHAR ASUE_UCAST_PN[LEN_WAPI_TSC] = {0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
+ 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c};
+UCHAR AE_UCAST_PN[LEN_WAPI_TSC] = {0x37, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
+ 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c};
+
+BUILD_TIMER_FUNCTION(RTMPWapiUskRekeyPeriodicExec);
+BUILD_TIMER_FUNCTION(RTMPWapiMskRekeyPeriodicExec);
+
+static void kd_hmac_sha256(
+ unsigned char *key,
+ unsigned int key_len,
+ unsigned char *text,
+ unsigned int text_len,
+ unsigned char *output,
+ unsigned int output_len)
+{
+ int i;
+
+ for (i = 0; output_len/SHA256_DIGEST_SIZE; i++, output_len -= SHA256_DIGEST_SIZE)
+ {
+ RT_HMAC_SHA256(key, key_len, text, text_len, &output[i*SHA256_DIGEST_SIZE], SHA256_DIGEST_SIZE);
+ text = &output[i*SHA256_DIGEST_SIZE];
+ text_len = SHA256_DIGEST_SIZE;
+ }
+
+ if (output_len > 0)
+ RT_HMAC_SHA256(key, key_len, text, text_len, &output[i*SHA256_DIGEST_SIZE], output_len);
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WAPI IE in RSN-IE.
+ It only shall be called by RTMPMakeRSNIE.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ AuthMode - indicate the authentication mode
+ WepStatus - indicate the encryption type
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInsertWapiIe(
+ IN UINT AuthMode,
+ IN UINT WepStatus,
+ OUT PUCHAR pWIe,
+ OUT UCHAR *w_len)
+{
+ WAPIIE *pWapiHdr = (WAPIIE*)pWIe;
+ WAPIIE_UCAST *pWIE_ucast;
+ WAPIIE_MCAST *pWIE_mcast;
+
+ *w_len = 0;
+
+ /* Assign the verson as 1 */
+ pWapiHdr->version = 1;
+
+ /* Set the AKM count and suite */
+ pWapiHdr->acount = 1;
+ switch (AuthMode)
+ {
+ case Ndis802_11AuthModeWAICERT:
+ NdisMoveMemory(pWapiHdr->auth[0].oui, OUI_WAI_CERT_AKM, 4);
+ break;
+
+ case Ndis802_11AuthModeWAIPSK:
+ NdisMoveMemory(pWapiHdr->auth[0].oui, OUI_WAI_PSK_AKM, 4);
+ break;
+ }
+
+ /* swap for big-endian platform */
+ pWapiHdr->version = cpu2le16(pWapiHdr->version);
+ pWapiHdr->acount = cpu2le16(pWapiHdr->acount);
+
+ /* update current length */
+ (*w_len) += sizeof(WAPIIE);
+
+ /* Set the unicast cipher and count */
+ pWIE_ucast = (WAPIIE_UCAST*)(pWIe + (*w_len));
+ pWIE_ucast->ucount = 1;
+ NdisMoveMemory(pWIE_ucast->ucast[0].oui, OUI_WPI_CIPHER_SMS4, 4);
+
+ /* swap for big-endian platform */
+ pWIE_ucast->ucount = cpu2le16(pWIE_ucast->ucount);
+
+ /* update current length */
+ (*w_len) += sizeof(WAPIIE_UCAST);
+
+ /* Set the multicast cipher and capability */
+ pWIE_mcast = (WAPIIE_MCAST*)(pWIe + (*w_len));
+ NdisMoveMemory(pWIE_mcast->mcast, OUI_WPI_CIPHER_SMS4, 4);
+ pWIE_mcast->capability = 0; /* Todo AlbertY - support pre-authentication */
+
+ /* update current length */
+ (*w_len) += sizeof(WAPIIE_MCAST);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check whether the received frame is WAPI frame.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ pData - the received frame
+ DataByteCount - the received frame's length
+
+ Return:
+ TRUE - This frame is WAPI frame
+ FALSE - otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPCheckWAIframe(
+ IN PUCHAR pData,
+ IN ULONG DataByteCount)
+{
+ if(DataByteCount < (LENGTH_802_1_H + LENGTH_WAI_H))
+ return FALSE;
+
+
+ /* Skip LLC header */
+ if (NdisEqualMemory(SNAP_802_1H, pData, 6))
+ {
+ pData += 6;
+ }
+ /* Skip 2-bytes EAPoL type */
+ if (NdisEqualMemory(WAPI_TYPE, pData, 2))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> Receive a WAI frame \n"));
+ pData += 2;
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Check whether the cipher is SMS4.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ apidx - interface index
+
+ Return:
+ TRUE - The cipher is SMS4
+ FALSE - otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPIsWapiCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx)
+{
+ NDIS_802_11_ENCRYPTION_STATUS cipher_mode = Ndis802_11EncryptionDisabled;
+
+ /* Currently, WAPI only support MBSS */
+ if (apidx >= MAX_MBSSID_NUM(pAd) + MAX_P2P_NUM)
+ return FALSE;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (apidx < MAX_MBSSID_NUM(pAd))
+ cipher_mode = pAd->ApCfg.MBSSID[apidx].WepStatus;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (cipher_mode == Ndis802_11EncryptionSMS4Enabled)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert the WPI-SMS4 IV header
+
+ +-------+------+-------------+
+ | KeyId | resv | sequence PN |
+ +-------+------+-------------+
+
+ Arguments:
+
+ Return:
+
+ ==========================================================================
+*/
+VOID RTMPConstructWPIIVHdr(
+ IN UCHAR key_id,
+ IN UCHAR *tx_iv,
+ OUT UCHAR *iv_hdr)
+{
+ iv_hdr[0] = key_id;
+ iv_hdr[1] = 0x00;
+
+ NdisMoveMemory(&iv_hdr[2], tx_iv, LEN_WAPI_TSC);
+}
+
+VOID RTMPDeriveWapiGTK(
+ IN PUCHAR nmk,
+ OUT PUCHAR gtk_ptr)
+{
+ const char group_context[100] = "multicast or station key expansion for station unicast and multicast and broadcast";
+
+ NdisZeroMemory(gtk_ptr, 32);
+ kd_hmac_sha256(nmk,
+ 16,
+ (UCHAR *)group_context,
+ strlen(group_context),
+ gtk_ptr,
+ 32);
+}
+
+VOID RT_SMS4_TEST(
+ IN UINT8 test)
+{
+ CIPHER_KEY CipherKey;
+ UINT16 data_len;
+ UINT8 rcvd_data[50];
+ UINT8 mac_hdr_qos[] = {0x88, 0x42, 0x00, 0x00, 0x08, 0xda, 0x75, 0x84,
+ 0xd0, 0xcc, 0x27, 0xe8, 0x72, 0xaa, 0x2c, 0xb9,
+ 0x6b, 0xbb, 0xea, 0x35, 0xa4, 0x20, 0x1e, 0xd2,
+ 0xcf, 0x14};
+
+ UINT8 payload_qos[] = {0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00};
+ UINT8 pn[] = {0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76,
+ 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89};
+ UINT8 key[] = {0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
+ 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe};
+
+ RTMPSoftEncryptSMS4(mac_hdr_qos,
+ payload_qos,
+ 1,
+ 1,
+ key,
+ pn);
+
+ hex_dump("encrypted payload", payload_qos, 17);
+
+ NdisZeroMemory(&CipherKey, sizeof(CIPHER_KEY));
+ NdisMoveMemory(CipherKey.Key, key, 16);
+ NdisMoveMemory(CipherKey.TxMic, &key[16], 8);
+ NdisMoveMemory(CipherKey.RxMic, &key[24], 8);
+ CipherKey.KeyLen = 16;
+
+
+ NdisZeroMemory(rcvd_data, 50);
+ rcvd_data[0] = 1;
+ data_len = 2;
+ NdisMoveMemory(&rcvd_data[data_len], pn, 16);
+ data_len += 16;
+ NdisMoveMemory(&rcvd_data[data_len], payload_qos, 17);
+ data_len += 17;
+
+
+ if (RTMPSoftDecryptSMS4(mac_hdr_qos,
+ FALSE,
+ &CipherKey,
+ rcvd_data,
+ &data_len) == 0)
+ hex_dump("decrypted payload", rcvd_data, data_len);
+ else
+ printk("decrypted fail\n");
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ In kernel mode read parameters from file
+
+ Arguments:
+ src the location of the file.
+ dest put the parameters to the destination.
+ Length size to read.
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+void rtmp_read_wapi_parms_from_file(
+ IN PRTMP_ADAPTER pAd,
+ PSTRING tmpbuf,
+ PSTRING buffer)
+{
+ UINT32 ip_addr;
+#ifdef CONFIG_AP_SUPPORT
+ INT apidx = 0;
+#endif /* CONFIG_AP_SUPPORT */
+ STRING tok_str[32];
+ INT idx;
+
+ PCOMMON_WAPI_INFO pInfo = &pAd->CommonCfg.comm_wapi_info;
+
+ /* wapi interface name */
+ if (RTMPGetKeyParameter("Wapiifname", tmpbuf, 32, buffer, TRUE))
+ {
+ if (strlen(tmpbuf) > 0)
+ {
+ NdisMoveMemory(pInfo->wapi_ifname, tmpbuf, strlen(tmpbuf));
+ pInfo->wapi_ifname_len = strlen(tmpbuf);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wapiifname=%s, len=%d\n",
+ pInfo->wapi_ifname,
+ pInfo->wapi_ifname_len));
+ }
+ }
+
+
+ /* WapiAsCertPath */
+ if (RTMPGetKeyParameter("WapiAsCertPath", tmpbuf, 128, buffer, TRUE))
+ {
+ if (strlen(tmpbuf) > 0)
+ {
+ NdisMoveMemory(pInfo->as_cert_path[0], tmpbuf, strlen(tmpbuf));
+ pInfo->as_cert_path_len[0] = strlen(tmpbuf);
+ pInfo->as_cert_no = 1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiAsCertPath=%s, len=%d\n",
+ pInfo->as_cert_path[0],
+ pInfo->as_cert_path_len[0]));
+ }
+ }
+
+ /* WapiAsCertPath2 ~ WapiAsCertPath10 */
+ for (idx = 1; idx < MAX_ID_NO; idx++)
+ {
+ sprintf(tok_str, "WapiAsCertPath%d", idx + 1);
+
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE))
+ {
+ if (strlen(tmpbuf) > 0)
+ {
+ NdisMoveMemory(pInfo->as_cert_path[idx], tmpbuf, strlen(tmpbuf));
+ pInfo->as_cert_path_len[idx] = strlen(tmpbuf);
+ pInfo->as_cert_no++;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiAsCertPath%d=%s, len=%d\n",
+ idx+1,
+ pInfo->as_cert_path[idx],
+ pInfo->as_cert_path_len[idx]));
+ }
+ }
+ }
+
+ /* WapiCaCertPath */
+ if (RTMPGetKeyParameter("WapiCaCertPath", tmpbuf, 128, buffer, TRUE))
+ {
+ if (strlen(tmpbuf) > 0)
+ {
+ NdisMoveMemory(pInfo->ca_cert_path, tmpbuf, strlen(tmpbuf));
+ pInfo->ca_cert_path_len = strlen(tmpbuf);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiCaCertPath=%s, len=%d\n",
+ pInfo->ca_cert_path,
+ pInfo->ca_cert_path_len));
+ }
+ }
+
+ /* WapiUserCertPath */
+ if (RTMPGetKeyParameter("WapiUserCertPath", tmpbuf, 128, buffer, TRUE))
+ {
+ if (strlen(tmpbuf) > 0)
+ {
+ NdisMoveMemory(pInfo->user_cert_path, tmpbuf, strlen(tmpbuf));
+ pInfo->user_cert_path_len = strlen(tmpbuf);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiUserCertPath=%s, len=%d\n",
+ pInfo->user_cert_path,
+ pInfo->user_cert_path_len));
+ }
+ }
+
+ /* WapiAsIpAddr */
+ if (RTMPGetKeyParameter("WapiAsIpAddr", tmpbuf, 32, buffer, TRUE))
+ {
+ if (rtinet_aton(tmpbuf, &ip_addr))
+ {
+ pInfo->wapi_as_ip = ip_addr;
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiAsIpAddr=%s(%x)\n", tmpbuf, pInfo->wapi_as_ip));
+ }
+ }
+
+ /* WapiAsPort */
+ if (RTMPGetKeyParameter("WapiAsPort", tmpbuf, 32, buffer, TRUE))
+ {
+ pInfo->wapi_as_port = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiAsPort=%d\n", pInfo->wapi_as_port));
+ }
+
+ /* WapiUskRekeyMethod */
+ if (RTMPGetKeyParameter("WapiUskRekeyMethod", tmpbuf, 32, buffer, TRUE))
+ {
+ if ((strcmp(tmpbuf, "TIME") == 0) || (strcmp(tmpbuf, "time") == 0))
+ pAd->CommonCfg.wapi_usk_rekey_method = REKEY_METHOD_TIME;
+ else if ((strcmp(tmpbuf, "PKT") == 0) || (strcmp(tmpbuf, "pkt") == 0))
+ pAd->CommonCfg.wapi_usk_rekey_method = REKEY_METHOD_PKT;
+ else
+ pAd->CommonCfg.wapi_usk_rekey_method = REKEY_METHOD_DISABLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiUskRekeyMethod=%d\n", pAd->CommonCfg.wapi_usk_rekey_method));
+ }
+
+ /* WapiUskRekeyThreshold */
+ if (RTMPGetKeyParameter("WapiUskRekeyThreshold", tmpbuf, 32, buffer, TRUE))
+ {
+ pAd->CommonCfg.wapi_usk_rekey_threshold = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiUskRekeyThreshold=%d\n", pAd->CommonCfg.wapi_usk_rekey_threshold));
+ }
+
+ /* WapiMskRekeyMethod */
+ if (RTMPGetKeyParameter("WapiMskRekeyMethod", tmpbuf, 32, buffer, TRUE))
+ {
+ if ((strcmp(tmpbuf, "TIME") == 0) || (strcmp(tmpbuf, "time") == 0))
+ pAd->CommonCfg.wapi_msk_rekey_method = REKEY_METHOD_TIME;
+ else if ((strcmp(tmpbuf, "PKT") == 0) || (strcmp(tmpbuf, "pkt") == 0))
+ pAd->CommonCfg.wapi_msk_rekey_method = REKEY_METHOD_PKT;
+ else
+ pAd->CommonCfg.wapi_msk_rekey_method = REKEY_METHOD_DISABLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiMskRekeyMethod=%d\n", pAd->CommonCfg.wapi_msk_rekey_method));
+ }
+
+ /* WapiMskRekeyThreshold */
+ if (RTMPGetKeyParameter("WapiMskRekeyThreshold", tmpbuf, 32, buffer, TRUE))
+ {
+ pAd->CommonCfg.wapi_msk_rekey_threshold = simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("WapiMskRekeyThreshold=%d\n", pAd->CommonCfg.wapi_msk_rekey_threshold));
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ STRING tok_str[16];
+
+ /* WapiPskX */
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ snprintf(tok_str, sizeof(tok_str), "WapiPsk%d", apidx + 1);
+
+ NdisZeroMemory(pAd->ApCfg.MBSSID[apidx].WAPIPassPhrase, 64);
+ pAd->ApCfg.MBSSID[apidx].WAPIPassPhraseLen = 0;
+ if(RTMPGetKeyParameter(tok_str, tmpbuf, 65, buffer, FALSE))
+ {
+ if (strlen(tmpbuf) >= 8 && strlen(tmpbuf) <= 64)
+ {
+ NdisMoveMemory(pAd->ApCfg.MBSSID[apidx].WAPIPassPhrase, tmpbuf, strlen(tmpbuf));
+ pAd->ApCfg.MBSSID[apidx].WAPIPassPhraseLen = strlen(tmpbuf);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) WapiPsk=(%s), len=%d\n", apidx, tmpbuf, strlen(tmpbuf)));
+ }
+ else
+ {
+ if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAIPSK)
+ {
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen;
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11EncryptionDisabled;
+ }
+ DBGPRINT(RT_DEBUG_ERROR, ("IF(ra%d) The length of WAPI PSKPassPhrase is invalid(len=%d). \n", apidx, strlen(tmpbuf)));
+ }
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+ /* WapiPskType */
+ if (RTMPGetKeyParameter("WapiPskType", tmpbuf, 32, buffer, TRUE))
+ {
+ INT err;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ PSTRING macptr;
+
+ for (apidx = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), apidx++)
+ {
+ err = 0;
+
+ if (apidx >= pAd->ApCfg.BssidNum)
+ break;
+
+ /* HEX */
+ if(simple_strtol(macptr, 0, 10) == 0)
+ {
+ pAd->ApCfg.MBSSID[apidx].WapiPskType = HEX_MODE;
+
+ if (pAd->ApCfg.MBSSID[apidx].WAPIPassPhraseLen % 2 != 0)
+ {
+ err = 1;
+ DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) The WAPI-PSK key length MUST be even in Hex mode\n", apidx));
+ }
+ }
+ /* ASCII */
+ else
+ {
+ pAd->ApCfg.MBSSID[apidx].WapiPskType = ASCII_MODE;
+ }
+
+ if (err)
+ {
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen;
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11EncryptionDisabled;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) WapiPskType=%s\n", apidx, (pAd->ApCfg.MBSSID[apidx].WapiPskType == HEX_MODE) ? "HEX" : "ASCII"));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ }
+
+ /* Sanity check - USK rekey parameter */
+ if (pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_DISABLE ||
+ pAd->CommonCfg.wapi_usk_rekey_threshold == 0)
+ {
+ pAd->CommonCfg.wapi_usk_rekey_method = REKEY_METHOD_DISABLE;
+ pAd->CommonCfg.wapi_usk_rekey_threshold = 0;
+ }
+
+ /* Sanity check - MSK rekey parameter */
+ if (pAd->CommonCfg.wapi_msk_rekey_method == REKEY_METHOD_DISABLE ||
+ pAd->CommonCfg.wapi_msk_rekey_threshold == 0)
+ {
+ pAd->CommonCfg.wapi_msk_rekey_method = REKEY_METHOD_DISABLE;
+ pAd->CommonCfg.wapi_msk_rekey_threshold = 0;
+ }
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ It only shall be queried by wapi daemon for querying the related
+ configuration. This routine process the WAPI configuration for per BSS.
+
+ ==========================================================================
+*/
+static VOID RTMPQueryWapiConfPerBss(
+ IN PRTMP_ADAPTER pAd,
+ IN PWAPI_CONF wapi_conf_ptr,
+ IN UCHAR apidx)
+{
+ PMBSS_WAPI_INFO pConf = &wapi_conf_ptr->mbss_wapi_info[apidx];
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[apidx];
+
+ if (pMbss->MSSIDDev != NULL)
+ {
+ PNET_DEV dev = pMbss->MSSIDDev;
+
+ NdisMoveMemory(pConf->ifname, RtmpOsGetNetDevName(dev), strlen(RtmpOsGetNetDevName(dev)));
+ pConf->ifname_len = strlen(RtmpOsGetNetDevName(dev));
+ }
+ else
+ {
+ STRING slot_name[IFNAMSIZ];
+
+ snprintf(slot_name, sizeof(slot_name), "ra%d", apidx);
+ NdisMoveMemory(pConf->ifname, slot_name, strlen(slot_name));
+ pConf->ifname_len = strlen(slot_name);
+ }
+
+ /* Decide the authentication mode */
+ if (pMbss->AuthMode == Ndis802_11AuthModeWAICERT)
+ pConf->auth_mode = WAPI_AUTH_CERT;
+ else if (pMbss->AuthMode == Ndis802_11AuthModeWAIPSK)
+ pConf->auth_mode = WAPI_AUTH_PSK;
+ else
+ pConf->auth_mode = WAPI_AUTH_DISABLE;
+
+ /* Fill in WAI pre-shared key */
+ if (pMbss->WAPIPassPhraseLen > 0)
+ {
+ if (pMbss->WapiPskType == HEX_MODE)
+ {
+ pConf->psk_len = pMbss->WAPIPassPhraseLen / 2;
+ AtoH((PSTRING) pMbss->WAPIPassPhrase, (PUCHAR) pConf->psk, pConf->psk_len);
+ }
+ else
+ {
+ pConf->psk_len = pMbss->WAPIPassPhraseLen;
+ NdisMoveMemory(pConf->psk, pMbss->WAPIPassPhrase, pConf->psk_len);
+ }
+ }
+
+ /* Fill in WIE */
+ if (pMbss->RSNIE_Len[0] > 0)
+ {
+ pConf->wie_len = pMbss->RSNIE_Len[0] + 2;
+
+ pConf->wie[0] = IE_WAPI;
+ pConf->wie[1] = pMbss->RSNIE_Len[0];
+ NdisMoveMemory(&pConf->wie[2], pMbss->RSN_IE[0], pMbss->RSNIE_Len[0]);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ It only shall be queried by wapi daemon for querying the related
+ configuration.
+ Arguments:
+ pAd Pointer to our adapter
+ wrq Pointer to the ioctl argument
+ ==========================================================================
+*/
+VOID RTMPIoctlQueryWapiConf(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+{
+ UCHAR apidx;
+ UCHAR *buf = NULL;
+ PWAPI_CONF pConf;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlQueryWapiConf==>\n"));
+
+ /* Allocate memory for WAPI configuration */
+ os_alloc_mem(NULL, (PUCHAR *)&buf, sizeof(WAPI_CONF));
+
+ if (buf == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: allocate memory fail\n", __FUNCTION__));
+ return;
+ }
+
+ pConf = (PWAPI_CONF)buf;
+
+ NdisZeroMemory((PUCHAR)pConf, sizeof(WAPI_CONF));
+
+ /* get MBSS number */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ pConf->mbss_num = pAd->ApCfg.BssidNum;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* Set common configuration */
+ NdisMoveMemory(&pConf->comm_wapi_info, &pAd->CommonCfg.comm_wapi_info, sizeof(COMMON_WAPI_INFO));
+
+ for (apidx = 0; apidx < pConf->mbss_num; apidx++)
+ {
+ RTMPQueryWapiConfPerBss(pAd, pConf, apidx);
+ }
+
+ wrq->u.data.length = sizeof(WAPI_CONF);
+ if (copy_to_user(wrq->u.data.pointer, pConf, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+
+ os_free_mem(NULL, buf);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Timer execution function for periodically updating WAPI key.
+ Return:
+ ==========================================================================
+*/
+VOID RTMPWapiUskRekeyPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ UINT32 tmp_cnt = 0;
+ PMAC_TABLE_ENTRY pEntry = (PMAC_TABLE_ENTRY)FunctionContext;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pEntry->pAd;
+
+
+ if (pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_TIME)
+ {
+ tmp_cnt = (++pEntry->wapi_usk_rekey_cnt);
+ }
+ else if (pAd->CommonCfg.wapi_usk_rekey_method == REKEY_METHOD_PKT)
+ {
+ /* the unit is 1K packets */
+ tmp_cnt = pEntry->wapi_usk_rekey_cnt/1000;
+ }
+ else
+ return;
+
+ /* Trigger rekey procedure */
+ if (tmp_cnt > pAd->CommonCfg.wapi_usk_rekey_threshold)
+ {
+ pEntry->wapi_usk_rekey_cnt = 0;
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_UPDATE_USK);
+ }
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Timer execution function for periodically updating WAPI key.
+ Return:
+ ==========================================================================
+*/
+VOID RTMPWapiMskRekeyPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ UINT i;
+ UINT32 tmp_cnt = 0;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+
+
+ /* if no any WAPI STA associated, don't do anything. */
+ if (pAd->MacTab.fAnyWapiStation == FALSE)
+ return;
+
+ /* increase counter for TIME method */
+ if (pAd->CommonCfg.wapi_msk_rekey_method == REKEY_METHOD_TIME)
+ {
+ tmp_cnt = (++pAd->CommonCfg.wapi_msk_rekey_cnt);
+ }
+ else if (pAd->CommonCfg.wapi_msk_rekey_method == REKEY_METHOD_PKT)
+ {
+ /* the unit is 1K packets */
+ tmp_cnt = pAd->CommonCfg.wapi_msk_rekey_cnt/1000;
+ }
+ else
+ return;
+
+ if (tmp_cnt > pAd->CommonCfg.wapi_msk_rekey_threshold)
+ {
+ pAd->CommonCfg.wapi_msk_rekey_cnt = 0;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ INT apidx = 0;
+ UINT cnt;
+
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ UINT m_wcid;
+
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = pAd->ApCfg.MBSSID[apidx].DefaultKeyId == 0 ? 1 : 0;
+ inc_iv_byte(pAd->ApCfg.MBSSID[apidx].key_announce_flag, LEN_WAPI_TSC, 1);
+
+ /* Generate NMK randomly */
+ for (cnt = 0; cnt < 16; cnt++)
+ pAd->ApCfg.MBSSID[apidx].NMK[cnt] = RandomByte(pAd);
+
+ RTMPDeriveWapiGTK(pAd->ApCfg.MBSSID[apidx].NMK, pAd->ApCfg.MBSSID[apidx].GTK);
+
+ GET_GroupKey_WCID(pAd, m_wcid, apidx);
+ /* Install Shared key */
+ WAPIInstallSharedKey(pAd,
+ pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus,
+ apidx,
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId,
+ m_wcid,
+ pAd->ApCfg.MBSSID[apidx].GTK);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+
+ pEntry = &pAd->MacTab.Content[i];
+ if (IS_ENTRY_CLIENT(pEntry) &&
+ (pEntry->WepStatus == Ndis802_11EncryptionSMS4Enabled) &&
+ (pEntry->PortSecured == WPA_802_1X_PORT_SECURED))
+ {
+ WAPI_InternalCmdAction(pAd,
+ pEntry->AuthMode,
+ pEntry->apidx,
+ pEntry->Addr,
+ WAI_MLME_UPDATE_MSK);
+ }
+ }
+ }
+
+}
+
+
+VOID RTMPInitWapiRekeyTimerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ if (pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" RTMPInitWapiRekeyTimerAction : WAPI USK rekey timer (wcid-%d) \n", pEntry->Aid));
+ RTMPInitTimer(pAd, &pEntry->WapiUskRekeyTimer, GET_TIMER_FUNCTION(RTMPWapiUskRekeyPeriodicExec), pEntry, TRUE);
+ pEntry->WapiUskRekeyTimerRunning = FALSE;
+ }
+ else
+ {
+ RTMPInitTimer(pAd, &pAd->CommonCfg.WapiMskRekeyTimer, GET_TIMER_FUNCTION(RTMPWapiMskRekeyPeriodicExec), pAd, TRUE);
+ pAd->CommonCfg.WapiMskRekeyTimerRunning = FALSE;
+ }
+}
+
+VOID RTMPStartWapiRekeyTimerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ if (pEntry)
+ {
+ if ((pAd->CommonCfg.wapi_usk_rekey_method != REKEY_METHOD_DISABLE) &&
+ (pAd->CommonCfg.wapi_usk_rekey_threshold > 0))
+ {
+ /* Regularly check the timer */
+ if (pEntry->WapiUskRekeyTimerRunning == FALSE)
+ {
+ RTMPSetTimer(&pEntry->WapiUskRekeyTimer, WAPI_KEY_UPDATE_EXEC_INTV);
+
+ pEntry->WapiUskRekeyTimerRunning = TRUE;
+ pEntry->wapi_usk_rekey_cnt = 0;
+ DBGPRINT(RT_DEBUG_TRACE, (" RTMPStartWapiRekeyTimerAction : WAPI USK rekey timer is started (%d) \n", pAd->CommonCfg.wapi_usk_rekey_threshold));
+ }
+ }
+ }
+ else
+ {
+ if ((pAd->CommonCfg.wapi_msk_rekey_method != REKEY_METHOD_DISABLE) &&
+ (pAd->CommonCfg.wapi_msk_rekey_threshold > 0))
+ {
+ /* Regularly check the timer */
+ if (pAd->CommonCfg.WapiMskRekeyTimerRunning == FALSE)
+ {
+ RTMPSetTimer(&pAd->CommonCfg.WapiMskRekeyTimer, WAPI_KEY_UPDATE_EXEC_INTV);
+
+ pAd->CommonCfg.WapiMskRekeyTimerRunning = TRUE;
+ pAd->CommonCfg.wapi_msk_rekey_cnt = 0;
+ DBGPRINT(RT_DEBUG_TRACE, (" RTMPStartWapiRekeyTimerAction : WAPI MSK rekey timer is started \n"));
+ }
+ }
+ }
+
+}
+
+VOID RTMPCancelWapiRekeyTimerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ if(pEntry)
+ {
+ if (pEntry->WapiUskRekeyTimerRunning == TRUE)
+ {
+ BOOLEAN Cancelled;
+
+ RTMPCancelTimer(&pEntry->WapiUskRekeyTimer, &Cancelled);
+ pEntry->wapi_usk_rekey_cnt = 0;
+ pEntry->WapiUskRekeyTimerRunning = FALSE;
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.WapiMskRekeyTimerRunning == TRUE)
+ {
+ BOOLEAN Cancelled;
+
+ RTMPCancelTimer(&pAd->CommonCfg.WapiMskRekeyTimer, &Cancelled);
+ pAd->CommonCfg.wapi_msk_rekey_cnt = 0;
+ pAd->CommonCfg.WapiMskRekeyTimerRunning = FALSE;
+ }
+ }
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare a L2 frame to wapi daemon to trigger WAPI state machine
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN WAPI_InternalCmdAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AuthMode,
+ IN UCHAR apidx,
+ IN PUCHAR pAddr,
+ IN UCHAR flag)
+{
+ if ((AuthMode == Ndis802_11AuthModeWAICERT) ||
+ (AuthMode == Ndis802_11AuthModeWAIPSK))
+ {
+ UCHAR WAPI_IE[] = {0x88, 0xb4};
+ UINT8 frame_len = LENGTH_802_3 + 12; /* 12 indicates the WAPI internal command length */
+ UCHAR FrameBuf[frame_len];
+ UINT8 offset = 0;
+
+ /* Init the frame buffer */
+ NdisZeroMemory(FrameBuf, frame_len);
+
+ /* Prepare the 802.3 header */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ MAKE_802_3_HEADER(FrameBuf, pAd->ApCfg.MBSSID[apidx].Bssid, pAddr, WAPI_IE);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ offset += LENGTH_802_3;
+
+ /* Prepare the specific WAPI header */
+ NdisMoveMemory(&FrameBuf[offset], RALINK_OUI, 3);
+ offset += 3;
+
+ /* Set the state of this command */
+ FrameBuf[offset] = flag;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Trigger WAPI for this sta(%02x:%02x:%02x:%02x:%02x:%02x)\n", PRINT_MAC(pAddr)));
+
+ /* Report to upper layer */
+ if (RTMP_L2_FRAME_TX_ACTION(pAd, apidx, FrameBuf, frame_len) == FALSE)
+ return FALSE;
+
+ }
+
+ return TRUE;
+}
+
+
+VOID RTMPGetWapiTxTscFromAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT Wcid,
+ OUT UCHAR *tx_tsc)
+{
+ USHORT offset;
+ int i;
+
+ if (IS_HW_WAPI_SUPPORT(pAd))
+ {
+ NdisZeroMemory(tx_tsc, LEN_WAPI_TSC);
+
+ /* Read IVEIV from Asic */
+ offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
+ for (i=0 ; i < HW_IVEIV_ENTRY_SIZE; i++)
+ RTMP_IO_READ8(pAd, offset+i, &tx_tsc[i]);
+
+ /* Read WAPI PM from Asic */
+ offset = WAPI_PN_TABLE_BASE + (Wcid * WAPI_PN_ENTRY_SIZE);
+ for (i=0 ; i < WAPI_PN_ENTRY_SIZE; i++)
+ RTMP_IO_READ8(pAd, offset+i, &tx_tsc[HW_IVEIV_ENTRY_SIZE + i]);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : WCID(%d) ", __FUNCTION__, Wcid));
+ hex_dump("TxTsc", tx_tsc, LEN_WAPI_TSC);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s : Not support HW_WAPI_PN_TABLE\n",
+ __FUNCTION__));
+ }
+
+}
+
+
+VOID WAPIInstallPairwiseKey(
+ PRTMP_ADAPTER pAd,
+ PMAC_TABLE_ENTRY pEntry,
+ BOOLEAN bAE)
+{
+ PCIPHER_KEY pKey;
+
+ pKey = &pEntry->PairwiseKey;
+ NdisZeroMemory(pKey, sizeof(CIPHER_KEY));
+
+ /* Assign the pairwise cipher algorithm */
+ if (pEntry->WepStatus == Ndis802_11EncryptionSMS4Enabled)
+ pKey->CipherAlg = CIPHER_SMS4;
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (wcid-%d)\n",
+ __FUNCTION__, pEntry->Aid));
+ return;
+ }
+
+ /* Prepare pair-wise key material */
+ pKey->KeyLen = LEN_TK;
+ NdisMoveMemory(pKey->Key, &pEntry->PTK[0], 16);
+ NdisMoveMemory(pKey->TxMic, &pEntry->PTK[16], 8);
+ NdisMoveMemory(pKey->RxMic, &pEntry->PTK[24], 8);
+
+ /* Initial TSC for unicast */
+ if (bAE)
+ NdisMoveMemory(pKey->TxTsc, AE_UCAST_PN, LEN_WAPI_TSC);
+ else
+ NdisMoveMemory(pKey->TxTsc, ASUE_UCAST_PN, LEN_WAPI_TSC);
+ NdisZeroMemory(pKey->RxTsc, LEN_WAPI_TSC);
+
+ /* HW_WAPI is supported in RT3883 or later */
+ if (IS_HW_WAPI_SUPPORT(pAd))
+ {
+ UINT32 CONST_WAPI_PN = 0x5C365C36;
+
+ /* Set unicast packet's PN to Asic. */
+ if (bAE)
+ AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, CONST_WAPI_PN + 1, CONST_WAPI_PN);
+ else
+ AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, CONST_WAPI_PN, CONST_WAPI_PN);
+ AsicUpdateWAPIPN(pAd, pEntry->Aid, CONST_WAPI_PN, CONST_WAPI_PN);
+
+ /* Add Pair-wise key to Asic */
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ (UCHAR)pEntry->Aid,
+ &pEntry->PairwiseKey);
+
+ /* update WCID attribute table and IVEIV table for this entry */
+ AsicUpdateWcidAttributeEntry(
+ pAd,
+ pEntry->apidx,
+ pEntry->usk_id,
+ pEntry->PairwiseKey.CipherAlg,
+ (UCHAR)pEntry->Aid,
+ PAIRWISEKEYTABLE);
+ }
+
+}
+
+
+VOID WAPIInstallSharedKey(
+ PRTMP_ADAPTER pAd,
+ UINT8 GroupCipher,
+ UINT8 BssIdx,
+ UINT8 KeyIdx,
+ UINT8 Wcid,
+ PUINT8 pGtk)
+{
+ UINT32 CONST_WAPI_PN = 0x5C365C36;
+ PCIPHER_KEY pSharedKey;
+
+ if (BssIdx >= MAX_MBSSID_NUM(pAd) + MAX_P2P_NUM)
+ {
+ 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));
+
+ if (GroupCipher == Ndis802_11EncryptionSMS4Enabled)
+ pSharedKey->CipherAlg = CIPHER_SMS4;
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : fails (IF/ra%d) \n",
+ __FUNCTION__, BssIdx));
+ return;
+ }
+
+ /* Assign key material into SW key table */
+ pSharedKey->KeyLen = LEN_TK;
+ NdisMoveMemory(pSharedKey->Key, pGtk, LEN_TK);
+ NdisMoveMemory(pSharedKey->TxMic, pGtk + 16, LEN_TKIP_MIC);
+ NdisMoveMemory(pSharedKey->RxMic, pGtk + 24, LEN_TKIP_MIC);
+
+ /* Initial TSC for B/Mcast */
+ NdisMoveMemory(pSharedKey->TxTsc, AE_BCAST_PN, LEN_WAPI_TSC);
+ NdisZeroMemory(pSharedKey->RxTsc, LEN_WAPI_TSC);
+
+ /* HW_WAPI is supported in RT3883 or later */
+ if (IS_HW_WAPI_SUPPORT(pAd))
+ {
+ /* Install Group Key to MAC ASIC */
+ 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),
+ WAPI PN table (0x7800)
+ and WCID attribute table (0x6800) for group key. */
+ if (Wcid != 0)
+ {
+ /* Set 16-bytes PN to Asic. */
+ AsicUpdateWCIDIVEIV(pAd, Wcid, CONST_WAPI_PN, CONST_WAPI_PN);
+ AsicUpdateWAPIPN(pAd, Wcid, CONST_WAPI_PN, CONST_WAPI_PN);
+
+ /* update Group key information to ASIC */
+ AsicUpdateWcidAttributeEntry(
+ pAd,
+ BssIdx,
+ KeyIdx,
+ pSharedKey->CipherAlg,
+ Wcid,
+ SHAREDKEYTABLE);
+ }
+ }
+}
+
+#endif /* WAPI_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/wfd.c b/cleopatre/devkit/mt7601udrv/common/wfd.c
new file mode 100644
index 0000000000..6e612323f9
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/wfd.c
@@ -0,0 +1,823 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+
+#ifdef WFD_SUPPORT
+
+#ifdef OS_ABL_SUPPORT
+#ifdef RT_CFG80211_SUPPORT
+#include <linux/version.h>
+#include <net/cfg80211.h>
+#endif /* RT_CFG80211_SUPPORT */
+#endif /* OS_ABL_SUPPORT */
+
+#include "rt_config.h"
+#include "wfd_cmm.h"
+#ifdef OS_ABL_SUPPORT
+#ifdef RT_CFG80211_SUPPORT
+#include "cfg80211.h"
+#endif /* RT_CFG80211_SUPPORT */
+#endif /* OS_ABL_SUPPORT */
+
+UCHAR WIFIDISPLAY_OUI[] = {0x50, 0x6f, 0x9a, 0x0a};
+
+INT Set_WfdEnable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ BOOLEAN bEnable;
+
+ bEnable = simple_strtol(arg, 0, 10);
+
+ if (bEnable == TRUE)
+ {
+ pAd->StaCfg.WfdCfg.bWfdEnable = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: Enable WFD Support!\n", __FUNCTION__));
+ }
+ else
+ {
+ pAd->StaCfg.WfdCfg.bWfdEnable = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Disable WFD Support!\n", __FUNCTION__));
+ }
+
+ return TRUE;
+}
+
+#ifdef RT_CFG80211_SUPPORT
+INT Set_WfdInsertIe_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ BOOLEAN bEnable;
+ CFG80211_CB *pCfg80211_CB = NULL;
+
+ pAd->StaCfg.WfdCfg.bSuppInsertWfdIe = FALSE;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ if (pAd->pCfg80211_CB != NULL)
+ {
+ pCfg80211_CB = (CFG80211_CB *)pAd->pCfg80211_CB;
+ if (pCfg80211_CB->pCfg80211_Wdev != NULL)
+ {
+ if ((pCfg80211_CB->pCfg80211_Wdev->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) ||
+ (pCfg80211_CB->pCfg80211_Wdev->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO)))
+ {
+ bEnable = simple_strtol(arg, 0, 10);
+
+ if (bEnable == TRUE)
+ {
+ pAd->StaCfg.WfdCfg.bSuppInsertWfdIe = TRUE;
+ pAd->StaCfg.WfdCfg.bWfdEnable = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: Enable Insert WFD IE Support for wpa_supplicant!\n", __FUNCTION__));
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Disable Insert WFD IE Support for wpa_supplicant!\n", __FUNCTION__));
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Interface mode not support Insert WFD IE for wpa_supplicant!\n", __FUNCTION__));
+
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: pCfg80211_CB->pCfg80211_Wdev is NULL. Not Support Insert WFD IE for wpa_supplicant!\n", __FUNCTION__));
+
+ }
+ else
+#endif
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: pAd->pCfg80211_CB is NULL. Not Support Insert WFD IE for wpa_supplicant!\n", __FUNCTION__));
+
+ return TRUE;
+}
+#endif /* RT_CFG80211_SUPPORT */
+
+INT Set_WfdDeviceType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR DeviceType;
+
+ DeviceType = simple_strtol(arg, 0, 10);
+
+ if (DeviceType <= WFD_SOURCE_PRIMARY_SINK)
+ {
+ pAd->StaCfg.WfdCfg.DeviceType = DeviceType;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Device Type Not Support!!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: Device Type = %d\n", __FUNCTION__, pAd->StaCfg.WfdCfg.DeviceType));
+
+ return TRUE;
+}
+
+
+INT Set_WfdCouple_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR coupled;
+
+ if (simple_strtol(arg, 0, 10) == 0)
+ coupled = WFD_COUPLED_NOT_SUPPORT;
+ else if (simple_strtol(arg, 0, 10) == 1)
+ coupled = WFD_COUPLED_SUPPORT;
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Coupled out of range!!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ switch (pAd->StaCfg.WfdCfg.DeviceType)
+ {
+ case WFD_SOURCE:
+ pAd->StaCfg.WfdCfg.SourceCoupled = coupled;
+ break;
+ case WFD_PRIMARY_SINK:
+ case WFD_SECONDARY_SINK:
+ pAd->StaCfg.WfdCfg.SinkCoupled = coupled;
+ break;
+ case WFD_SOURCE_PRIMARY_SINK:
+ pAd->StaCfg.WfdCfg.SourceCoupled = coupled;
+ pAd->StaCfg.WfdCfg.SinkCoupled = coupled;
+ break;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: Device Type = %d, Source Coupled = %d, Sink Coupled = %d\n", __FUNCTION__,
+ pAd->StaCfg.WfdCfg.DeviceType, pAd->StaCfg.WfdCfg.SourceCoupled, pAd->StaCfg.WfdCfg.SinkCoupled));
+
+ return TRUE;
+}
+
+INT Set_WfdSessionAvailable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAd->StaCfg.WfdCfg.SessionAvail= WFD_SESSION_NOT_AVAILABLE;
+ else if (simple_strtol(arg, 0, 10) == 1)
+ pAd->StaCfg.WfdCfg.SessionAvail = WFD_SESSION_AVAILABLE;
+ else
+ {
+ pAd->StaCfg.WfdCfg.SessionAvail = WFD_SESSION_NOT_AVAILABLE;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Session Available out of range, using default\n", __FUNCTION__, pAd->StaCfg.WfdCfg.SessionAvail));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: Session Available = %d\n", __FUNCTION__, pAd->StaCfg.WfdCfg.SessionAvail));
+
+ return TRUE;
+}
+
+INT Set_WfdCP_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAd->StaCfg.WfdCfg.CP = WFD_CP_NOT_SUPPORT;
+ else if (simple_strtol(arg, 0, 10) == 1)
+ pAd->StaCfg.WfdCfg.CP = WFD_CP_HDCP20;
+ else
+ {
+ pAd->StaCfg.WfdCfg.CP = WFD_CP_NOT_SUPPORT;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Content Protection out of range, using default\n", __FUNCTION__, pAd->StaCfg.WfdCfg.CP));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: Content Protection = %d\n", __FUNCTION__, pAd->StaCfg.WfdCfg.CP));
+
+ return TRUE;
+}
+
+
+INT Set_WfdRtspPort_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT32 RtspPort;
+
+ RtspPort = simple_strtol(arg, 0, 10);
+
+ if ((RtspPort < 0) || (65535 < RtspPort))
+ {
+ pAd->StaCfg.WfdCfg.RtspPort = WFD_RTSP_DEFAULT_PORT;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: RTSP Port out of range, using default\n", __FUNCTION__, pAd->StaCfg.WfdCfg.RtspPort));
+ }
+ else
+ pAd->StaCfg.WfdCfg.RtspPort = RtspPort;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: RTSP Port = %d\n", __FUNCTION__, pAd->StaCfg.WfdCfg.RtspPort));
+
+ return TRUE;
+}
+
+
+INT Set_WfdMaxThroughput_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ INT32 Throughput;
+
+ Throughput = simple_strtol(arg, 0, 10);
+
+ if ((Throughput <= 0)|| (65535 < Throughput))
+ {
+ pAd->StaCfg.WfdCfg.MaxThroughput = WFD_MAX_THROUGHPUT_DEFAULT;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: Max Throughput out of range, using default\n", __FUNCTION__, pAd->StaCfg.WfdCfg.MaxThroughput));
+ }
+ else
+ pAd->StaCfg.WfdCfg.MaxThroughput = Throughput;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: Max Throughput = %d\n", __FUNCTION__, pAd->StaCfg.WfdCfg.MaxThroughput));
+
+ return TRUE;
+}
+
+INT Set_WfdLocalIp_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRT_WFD_CONFIG pWFDCtrl = &pAd->StaCfg.WfdCfg;
+ UINT32 ip_addr;
+
+ rtinet_aton(arg, &ip_addr);
+ printk("IP = %04x\n", ip_addr);
+ pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie[0] = WFD_LOCAL_IP_ADDR_VERSION_IPV4;
+ RTMPMoveMemory(&pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie[1], &ip_addr, sizeof(UINT32));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: local IP Address = %d.%d.%d.%d\n", __FUNCTION__,
+ pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie[1],
+ pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie[2],
+ pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie[3],
+ pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie[4]));
+
+ return TRUE;
+}
+
+INT Set_PeerRtspPort_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ PRT_WFD_CONFIG pWFDCtrl = &pAd->StaCfg.WfdCfg;
+ UINT32 ip_addr;
+
+ MAC_TABLE_ENTRY *pEntry;
+ USHORT RtspPort = WFD_RTSP_DEFAULT_PORT;
+ UCHAR P2pIdx = P2P_NOT_FOUND;
+ PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
+ INT i;
+
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - P2P peer rtsp port get...\n", __FUNCTION__));
+ if (P2P_GO_ON(pAd) || P2P_CLI_ON(pAd))
+ {
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (IS_P2P_GO_ENTRY(pEntry) || IS_P2P_CLI_ENTRY(pEntry))
+ {
+ P2pIdx = P2pGroupTabSearch(pAd, pEntry->Addr);
+ DBGPRINT(RT_DEBUG_TRACE, ("P2P Entry[%d][%02x:%02x:%02x:%02x:%02x:%02x]\n", pEntry->P2pInfo.p2pIndex, PRINT_MAC(pEntry->Addr)));
+ DBGPRINT(RT_DEBUG_TRACE, ("RTSP_PORT = %d.\n", pAd->P2pTable.Client[pEntry->P2pInfo.p2pIndex].WfdEntryInfo.rtsp_port));
+ if (P2pIdx != P2P_NOT_FOUND)
+ RtspPort = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.rtsp_port;
+ else
+ {
+ RtspPort = WFD_RTSP_DEFAULT_PORT;
+ DBGPRINT(RT_DEBUG_ERROR, ("OID_802_11_P2P_PEER_RTSP_PORT::P2P not found, use default RTSP port\n"));
+ }
+ if (pEntry->P2pInfo.p2pIndex < MAX_P2P_GROUP_SIZE)
+ P2PPrintP2PEntry(pAd, pEntry->P2pInfo.p2pIndex);
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("OID_802_11_P2P_PEER_RTSP_PORT bssid: %02x:%02x:%02x:%02x:%02x:%02x.\n", PRINT_MAC(pP2PCtrl->CurrentAddress)));
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_P2P_PEER_RTSP_PORT (=%d)\n", RtspPort));
+
+ return TRUE;
+}
+
+
+VOID WfdMakeWfdIE(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG WfdIeBitmap,
+ OUT PUCHAR pOutBuf,
+ OUT PULONG pIeLen)
+{
+ PRT_WFD_CONFIG pWFDCtrl = &pAd->StaCfg.WfdCfg;
+ UCHAR WfdIEFixed[6] = {0xdd, 0x0c, 0x50, 0x6f, 0x9a, 0x0a}; /* Length will be modified later */
+ PUCHAR pData, pBuf;
+ ULONG TempLen;
+ ULONG Len = 0;
+ INT index, i = 0;
+
+ pData = pOutBuf;
+ *pIeLen = 0;
+
+ if (!pWFDCtrl->bWfdEnable)
+ return;
+
+ RTMPMoveMemory(pData, &WfdIEFixed[0], 6);
+ pData += 6;
+ Len += 6;
+
+ for (index = 0; index < SUBID_WFD_END; index++)
+ {
+ if (WfdIeBitmap & (0x1 << index))
+ {
+ /* To append to WFD Subelement */
+ TempLen = 0;
+ TempLen = InsertWfdSubelmtTlv(pAd, index, NULL, pData, ACTION_WIFI_DIRECT);
+ DBGPRINT(RT_DEBUG_INFO, ("%s(%d) ---->\n", __FUNCTION__, TempLen));
+ for (i=0; i<TempLen; i++)
+ DBGPRINT(RT_DEBUG_INFO, ("%02x ", *(pData+i)));
+ DBGPRINT(RT_DEBUG_INFO, ("\n"));
+
+ Len += TempLen;
+ pData += TempLen;
+ }
+
+ }
+
+ *(pOutBuf+1) = (Len-2);
+ *pIeLen = Len;
+
+ return;
+}
+
+
+ULONG InsertWfdSubelmtTlv(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR SubId,
+ IN PUCHAR pInBuffer,
+ IN PUCHAR pOutBuffer,
+ IN UINT Action)
+{
+ PRT_WFD_CONFIG pWFDCtrl = &pAd->StaCfg.WfdCfg;
+ PUCHAR pDest;
+ ULONG Length, tmpValue = 0;
+ USHORT EidLen = 0;
+
+ pDest = pOutBuffer;
+ RTMPZeroMemory(pDest, 255);
+ *pDest = SubId;
+ pDest += 1;
+ Length = 0;
+
+ switch (SubId)
+ {
+ case SUBID_WFD_DEVICE_INFO:
+ {
+ WFD_DEVICE_INFO DevInfo;
+ PUSHORT pDevInfo = &DevInfo;
+
+ RTMPZeroMemory(&DevInfo, sizeof(WFD_DEVICE_INFO));
+
+ EidLen = SUBID_WFD_DEVICE_INFO_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ DevInfo.DeviceType = pWFDCtrl->DeviceType;
+ DevInfo.SourceCoupled = pWFDCtrl->SourceCoupled;
+ DevInfo.SinkCoupled = pWFDCtrl->SinkCoupled;
+ DevInfo.SessionAvail = pWFDCtrl->SessionAvail;
+ DevInfo.WSD = pWFDCtrl->WSD;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
+ DevInfo.PC = pWFDCtrl->PC;
+ else
+ DevInfo.PC = WFD_PC_P2P;
+ DevInfo.CP = pWFDCtrl->CP;
+ DevInfo.TimeSync = pWFDCtrl->TimeSync;
+ /* RTMPMoveMemory(pDest + 1, &DevInfo, sizeof(WFD_DEVICE_INFO)); */
+ tmpValue = cpu2be16(*pDevInfo);
+ RTMPMoveMemory((pDest + 2), &tmpValue, 2);
+ tmpValue = cpu2be16(pWFDCtrl->RtspPort);
+ RTMPMoveMemory((pDest + 4), &tmpValue, 2);
+ tmpValue = cpu2be16(pWFDCtrl->MaxThroughput);
+ RTMPMoveMemory((pDest + 6), &tmpValue, 2);
+ Length = 9;
+ break;
+ }
+ case SUBID_WFD_ASSOCIATED_BSSID:
+ {
+ UCHAR AllZero[MAC_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+
+ if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ EidLen = SUBID_WFD_ASSOCIATED_BSSID_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ Length = EidLen + 3;
+ if (!NdisEqualMemory(AllZero, pAd->CommonCfg.Bssid, MAC_ADDR_LEN) &&
+ (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ RTMPMoveMemory(pDest + 2, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+ }
+ }
+ else
+ {
+ if (!NdisEqualMemory(AllZero, pAd->CommonCfg.Bssid, MAC_ADDR_LEN))
+ {
+ EidLen = SUBID_WFD_ASSOCIATED_BSSID_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ RTMPMoveMemory(pDest + 2, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+ Length = EidLen + 3;
+ }
+ }
+ break;
+ }
+ case SUBID_WFD_AUDIO_FORMATS:
+ {
+ if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ EidLen = SUBID_WFD_AUDIO_FORMATS_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ Length = EidLen + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_VIDEO_FORMATS:
+ {
+ if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ EidLen = SUBID_WFD_VIDEO_FORMATS_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ Length = EidLen + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_3D_VIDEO_FORMATS:
+ {
+ if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ EidLen = SUBID_WFD_3D_VIDEO_FORMATS_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ Length = EidLen + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_CONTENT_PROTECTION:
+ {
+ if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ EidLen = SUBID_WFD_CONTENT_PROTECTION_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ Length = EidLen + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_COUPLED_SINK_INFO:
+ {
+// if ((pWFDCtrl->DeviceType != WFD_SOURCE ) && (pWFDCtrl->SinkCoupled == WFD_COUPLED_SUPPORT))
+ {
+ WFD_COUPLED_SINK_INFO SinkInfo;
+
+ RTMPZeroMemory(&SinkInfo, sizeof(WFD_COUPLED_SINK_INFO));
+ EidLen = SUBID_WFD_COUPLED_SINK_INFO_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ SinkInfo.CoupledStat = pWFDCtrl->CoupledSinkStatus.CoupledStat;
+ RTMPMoveMemory(pDest + 2, &SinkInfo, sizeof(WFD_COUPLED_SINK_INFO));
+ Length = EidLen + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_EXTENDED_CAP:
+ {
+ if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ EidLen = SUBID_WFD_EXTENDED_CAP_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ Length = EidLen + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_LOCAL_IP_ADDR:
+ {
+ if ((Action == ACTION_GAS_INITIAL_REQ) || (Action == ACTION_GAS_INITIAL_RSP))
+ {
+ EidLen = SUBID_WFD_LOCAL_IP_ADDR_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ Length = EidLen + 3;
+ }
+ else
+ {
+ EidLen = SUBID_WFD_LOCAL_IP_ADDR_LEN;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ RTMPMoveMemory(pDest + 2, &pWFDCtrl->wfd_serv_disc_query_info.wfd_local_ip_ie, SUBID_WFD_LOCAL_IP_ADDR_LEN);
+ Length = EidLen + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_SESSION_INFO:
+ {
+ INT i = 0, NumOfDev = 0;
+ UCHAR P2pIdx = P2P_NOT_FOUND;
+ PRT_P2P_TABLE Tab = &pAd->P2pTable;
+
+ if (P2P_GO_ON(pAd)
+#ifdef RT_CFG80211_SUPPORT
+ || (pWFDCtrl->bSuppGoOn)
+#endif /* RT_CFG80211_SUPPORT */
+ )
+ {
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
+ P2pIdx = P2pGroupTabSearch(pAd, pEntry->Addr);
+
+ if ((P2pIdx < MAX_P2P_GROUP_SIZE) && (Tab->Client[P2pIdx].WfdEntryInfo.bWfdClient == TRUE))
+ NumOfDev++;
+ }
+
+ EidLen = 24*NumOfDev;
+ tmpValue = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest, &tmpValue, 2);
+ DBGPRINT(RT_DEBUG_INFO, ("%s:: NumOfDev = %d, Len = %d\n", __FUNCTION__, NumOfDev, *pDest));
+
+ pDest+=2;
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
+ P2pIdx = P2pGroupTabSearch(pAd, pEntry->Addr);
+
+ if ((P2pIdx < MAX_P2P_GROUP_SIZE) && (Tab->Client[P2pIdx].WfdEntryInfo.bWfdClient == TRUE))
+ {
+ INT j = 0;
+ WFD_SESSION_INFO SessionInfo;
+
+ RTMPZeroMemory(&SessionInfo, sizeof(WFD_SESSION_INFO));
+
+ SessionInfo.Length = 23;
+ RTMPMoveMemory(&SessionInfo.DeviceAddr[0], &pAd->P2pTable.Client[P2pIdx].addr[0], MAC_ADDR_LEN);
+ RTMPMoveMemory(&SessionInfo.Bssid[0], &pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.assoc_addr[0], MAC_ADDR_LEN);
+ /* Below is the WFD Device Information */
+ SessionInfo.WfdDevInfo.DeviceType = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_devive_type;
+ SessionInfo.WfdDevInfo.SourceCoupled = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.source_coupled;
+ SessionInfo.WfdDevInfo.SinkCoupled = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.sink_coupled;
+ SessionInfo.WfdDevInfo.SessionAvail = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.session_avail;
+ SessionInfo.WfdDevInfo.WSD = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_service_discovery;
+ SessionInfo.WfdDevInfo.PC = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_PC;
+ SessionInfo.WfdDevInfo.TimeSync = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.wfd_time_sync;
+ SessionInfo.MaxThroughput = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.max_throughput;
+ SessionInfo.CoupledSinkInfo = pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.coupled_sink_status;
+
+ /*
+ So far we cannot know the address of coupled devices,
+ the coupled address will be filled "0" until WiFi Display spec. is ready for this part.
+ */
+ RTMPMoveMemory(&SessionInfo.CoupledPeerAddr[0], &pAd->P2pTable.Client[P2pIdx].WfdEntryInfo.coupled_peer_addr[0], MAC_ADDR_LEN);
+ RTMPMoveMemory(pDest, &SessionInfo, sizeof(WFD_SESSION_INFO));
+
+ for (j = 0; j < 24; j++)
+ DBGPRINT(RT_DEBUG_INFO, ("%02x ", *(pDest+j)));
+ DBGPRINT(RT_DEBUG_INFO, ("\n"));
+
+ pDest += 24;
+ }
+ }
+
+ Length = 24*NumOfDev + 3;
+ }
+ break;
+ }
+ case SUBID_WFD_ALTERNATE_MAC_ADDR:
+ {
+ UCHAR AllZero[MAC_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+
+ if (!NdisEqualMemory(AllZero, pAd->CurrentAddress, MAC_ADDR_LEN))
+ {
+ EidLen = SUBID_WFD_ALTERNATE_MAC_ADDR_LEN;
+ *((PUSHORT) (pDest)) = cpu2be16(EidLen);
+ RTMPMoveMemory(pDest + 2, pAd->CurrentAddress, MAC_ADDR_LEN);
+ Length = EidLen + 3;
+ }
+
+ break;
+ }
+ default:
+ *pDest = 0;
+ Length = 0;
+ break;
+ }
+
+ return Length;
+}
+
+VOID WfdParseSubElmt(
+ IN PRTMP_ADAPTER pAd,
+ IN PWFD_ENTRY_INFO pWfdEntryInfo,
+ IN VOID *Msg,
+ IN ULONG MsgLen)
+{
+ PWFD_COUPLED_SINK_INFO pSinkInfo;
+ PWFD_DEVICE_INFO pWfd_info;
+ WFD_DEVICE_INFO DevInfo;
+ PP2PEID_STRUCT pWfdEid;
+ PEID_STRUCT pEid;
+ PUCHAR pWfdIe = NULL;
+ ULONG AccuWfdIELen;
+ ULONG AccuIeLen = 0;
+ ULONG Length = 0;
+ ULONG AttriLen;
+ UCHAR offset;
+ BOOLEAN bTdlsEntry = FALSE;
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s ----->\n", __FUNCTION__));
+
+//QQ TBD, p2p widi need to parse rtsp port!
+ {
+ if ((!pAd->StaCfg.WfdCfg.bWfdEnable) || (MsgLen == 0))
+ return;
+ }
+
+// hex_dump("WfdParseSubElmt::", Msg, MsgLen);
+ pEid = (PEID_STRUCT)Msg;
+ AccuIeLen = pEid->Len + 2;
+// printk("MsgLen = %d. AccuIeLen = %d.\n", MsgLen, AccuIeLen);
+ while ((ULONG)(AccuIeLen) <= MsgLen)
+ {
+ if (RTMPEqualMemory(&pEid->Octet[0], WIFIDISPLAY_OUI, 4))
+ {
+ /* Get Request content capability */
+ pWfdIe = pWfdEid = (PP2PEID_STRUCT) &pEid->Octet[4];
+ AccuWfdIELen = pEid->Len;
+// printk("AccuWfdIeLen = %d. EidLen = %04x\n", AccuWfdIELen, pEid->Len);
+ /* The value of AccuP2PIELen shall reduce the length of OUI (4) */
+ AccuWfdIELen -= 4;
+
+ AttriLen = pWfdEid->Len[1] + (pWfdEid->Len[0] << 8);
+ Length = 0;
+// printk("AttriLen = %d. WfdEid = %d. WfdEidLen = %x %x\n", AttriLen, pWfdEid->Eid, pWfdEid->Len[1], pWfdEid->Len[0]);
+ pWfdEntryInfo->bWfdClient = TRUE; /* Set the P2P client as the WFD device */
+
+// while (Length <=(Length + 3 + AttriLen) <= AccuWfdIELen)
+ while (Length <= AccuWfdIELen)
+ {
+// printk(">> Eid = %d.\n", pWfdEid->Eid);
+ switch (pWfdEid->Eid)
+ {
+ case SUBID_WFD_DEVICE_INFO:
+ {
+ pWfd_info = &(pWfdEid->Octet[0]);
+ RTMPMoveMemory(&DevInfo, pWfdIe, sizeof(WFD_DEVICE_INFO));
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_device_info_ie, pWfdEid->Octet, SUBID_WFD_DEVICE_INFO_LEN);
+ cpu2le16(&DevInfo);
+
+ pWfdEntryInfo->wfd_devive_type = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 0) & 0x3);
+ pWfdEntryInfo->source_coupled = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 2) & 0x1);
+ pWfdEntryInfo->sink_coupled = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 3) & 0x1);
+ pWfdEntryInfo->session_avail = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 4) & 0x3);
+ pWfdEntryInfo->wfd_service_discovery = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 6) & 0x1);
+ pWfdEntryInfo->wfd_PC = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 7) & 0x1);
+ pWfdEntryInfo->wfd_CP = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 8) & 0x1);
+ pWfdEntryInfo->wfd_time_sync = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 9) & 0x1);
+ pWfdEntryInfo->sink_audio_unsupport = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 10) & 0x1);
+ pWfdEntryInfo->source_audio_only= ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 11) & 0x1);
+ pWfdEntryInfo->tdls_persistent_group = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 12) & 0x1);
+ pWfdEntryInfo->rtsp_port = be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[2])));
+ pWfdEntryInfo->max_throughput = be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[4])));
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_DEVICE_INFO\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_ASSOCIATED_BSSID:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_associate_bssid_ie, pWfdEid->Octet, SUBID_WFD_ASSOCIATED_BSSID_LEN);
+ RTMPMoveMemory(&pWfdEntryInfo->assoc_addr, pWfdEid->Octet, MAC_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_ASSOCIATED_BSSID\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_AUDIO_FORMATS:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_audio_format_ie, pWfdEid->Octet, SUBID_WFD_AUDIO_FORMATS_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_AUDIO_FORMATS\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_VIDEO_FORMATS:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_video_format_ie, pWfdEid->Octet, SUBID_WFD_VIDEO_FORMATS_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_VIDEO_FORMATS\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_3D_VIDEO_FORMATS:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_3d_video_format_ie, pWfdEid->Octet, SUBID_WFD_3D_VIDEO_FORMATS_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_3D_VIDEO_FORMATS\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_CONTENT_PROTECTION:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_content_proctection, pWfdEid->Octet, SUBID_WFD_CONTENT_PROTECTION_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_CONTENT_PROTECTION\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_COUPLED_SINK_INFO:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_couple_sink_info_ie, pWfdEid->Octet, SUBID_WFD_COUPLED_SINK_INFO_LEN);
+ RTMPMoveMemory(&pWfdEntryInfo->coupled_sink_status, pWfdEid->Octet, SUBID_WFD_COUPLED_SINK_INFO_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_COUPLED_SINK_INFO\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_EXTENDED_CAP:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_extent_capability_ie, &pWfdEid->Octet, SUBID_WFD_EXTENDED_CAP_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_EXTENDED_CAP\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_LOCAL_IP_ADDR:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_local_ip_ie, &pWfdEid->Octet, SUBID_WFD_LOCAL_IP_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_LOCAL_IP_ADDR\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_SESSION_INFO:
+ {
+ /* TODO : allocate memory to store the parsed WFD device tables */
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_session_info_ie, &pWfdEid->Octet, SUBID_WFD_DEVICE_INFO_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_SESSION_INFO\n", __FUNCTION__));
+ break;
+ }
+ case SUBID_WFD_ALTERNATE_MAC_ADDR:
+ {
+ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_alternate_mac_addr_ie, &pWfdEid->Octet, SUBID_WFD_ALTERNATE_MAC_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_ALTERNATE_MAC_ADDR\n", __FUNCTION__));
+ break;
+ }
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, (" SUBID_WFD_ unknown Eid = %x \n", pWfdEid->Eid));
+ hex_dump("WfdParseSubElement::", Msg, MsgLen);
+ break;
+ }
+// printk("<< Length = %d. AttriLen = %d. AccuWfdIELen = %d.\n", Length, AttriLen, AccuWfdIELen);
+ Length = Length + 3 + AttriLen; /* Eid[1] + Len[2] + content[Len] */
+// printk(">> Length = %d. AttriLen = %d. AccuWfdIELen = %d.\n", Length, AttriLen, AccuWfdIELen);
+ if (Length >= AccuWfdIELen)
+ break;
+
+ pWfdEid = (PP2PEID_STRUCT)((UCHAR*)pWfdEid + 3 + AttriLen);
+ AttriLen = pWfdEid->Len[1] + (pWfdEid->Len[0] << 8);
+ }
+
+ }
+ /* Already reach the final IE and stop finding next Eid. */
+ if (AccuIeLen >= MsgLen)
+ break;
+
+ /* Forward buffer to next pEid */
+ if (RTMPEqualMemory(&pEid->Octet[0], WIFIDISPLAY_OUI, 4))
+ {
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + pEid->Len + 2);
+ }
+
+ /*
+ Since we get the next pEid,
+ Predict the accumulated IeLen after adding the next pEid's length.
+ The accumulated IeLen is for checking length.
+ */
+ if (RTMPEqualMemory(&pEid->Octet[0], WIFIDISPLAY_OUI, 4))
+ {
+ AccuIeLen += (pEid->Len + 2);
+ }
+ }
+ return;
+}
+
+VOID WfdCfgInit(
+
+ IN PRTMP_ADAPTER pAd)
+{
+ PRT_WFD_CONFIG pWfdcfg = &pAd->StaCfg.WfdCfg;
+
+ RTMPZeroMemory(&pAd->StaCfg.WfdCfg, sizeof(RT_WFD_CONFIG));
+ pWfdcfg->bWfdEnable = TRUE;
+#ifdef RT_CFG80211_SUPPORT
+ pWfdcfg->bSuppInsertWfdIe = FALSE;
+ pWfdcfg->bSuppGoOn = FALSE;
+#endif /* RT_CFG80211_SUPPORT */
+ pWfdcfg->DeviceType = WFD_PRIMARY_SINK;
+ pWfdcfg->SessionAvail = WFD_SESSION_AVAILABLE;
+ pWfdcfg->PeerSessionAvail = WFD_SESSION_AVAILABLE;
+ pWfdcfg->PeerPC = WFD_PC_TDLS;
+ pWfdcfg->TdlsSecurity = WFD_TDLS_STRONG_SECURITY;
+ pWfdcfg->RtspPort = WFD_RTSP_DEFAULT_PORT;
+}
+#endif /* WFD_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/common/wsc.c b/cleopatre/devkit/mt7601udrv/common/wsc.c
new file mode 100644
index 0000000000..ec738598ef
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/wsc.c
@@ -0,0 +1,9058 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wsc.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 06-08-08 Initial
+ Snowpin Lee 06-09-12 Do modifications and Add APIs for AP
+ Snowpin Lee 07-04-19 Do modifications and Add APIs for STA
+ Snowpin Lee 07-05-17 Do modifications and Add APIs for AP Client
+*/
+
+#include "rt_config.h"
+
+#ifdef WSC_INCLUDED
+#include "wsc_tlv.h"
+/*#ifdef LINUX */
+/*#include <net/iw_handler.h> */
+/*#endif*/
+
+#define WSC_UPNP_MSG_TIMEOUT (150 * OS_HZ)
+#define RTMP_WSC_NLMSG_SIGNATURE_LEN 8
+#define MAX_WEPKEYNAME_LEN 20
+#define MAX_WEPKEYTYPE_LEN 20
+
+#ifndef PF_NOFREEZE
+#define PF_NOFREEZE 0
+#endif
+
+char WSC_MSG_SIGNATURE[]={"RAWSCMSG"};
+
+extern UCHAR WPS_OUI[];
+extern UCHAR RALINK_OUI[];
+
+
+#if defined(__ECOS) && defined(BRANCH_ADV)
+extern int CFG_set(int id, void *val);
+extern int CFG_str2id(char * var);
+extern int CFG_commit(int id);
+#else
+#define CFG_set(a, b) {}
+#define CFG_str2id(a) {}
+#define CFG_commit(a) {}
+#endif /*__ECOS && BRANCH_ADV */
+
+UINT8 WPS_DH_G_VALUE[1] = {0x02};
+UINT8 WPS_DH_P_VALUE[192] =
+{
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+/* General used field */
+UCHAR STA_Wsc_Pri_Dev_Type[8] = {0x00, 0x01, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01};
+
+#ifdef CONFIG_AP_SUPPORT
+UCHAR AP_Wsc_Pri_Dev_Type[8] = {0x00, 0x06, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01};
+
+VOID WscDelWPARetryTimer(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef APCLI_SUPPORT
+
+VOID WscApCliLinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl);
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+BOOLEAN WscCheckNonce(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN BOOLEAN bFlag,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscEapActionDisabled(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscGetConfigErrFromNack(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *pElem,
+ OUT USHORT *pConfigError);
+
+INT WscSetAuthMode(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CurOpMode,
+ IN UCHAR apidx,
+ IN PSTRING arg);
+
+INT WscSetEncrypType(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CurOpMode,
+ IN UCHAR apidx,
+ IN PSTRING arg);
+
+VOID WscSendNACK(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl);
+
+static INT wsc_write_dat_file_thread(IN ULONG data);
+
+
+VOID WscDelListEntryByMAC(
+ PLIST_HEADER pWscEnList,
+ IN PUCHAR pMacAddr);
+
+NDIS_802_11_AUTHENTICATION_MODE WscGetAuthMode(
+ IN USHORT authFlag);
+
+NDIS_802_11_WEP_STATUS WscGetWepStatus(
+ IN USHORT encryFlag);
+
+/*
+ Standard UUID generation procedure. The UUID format generated by this function is base on UUID std. version 1.
+ It's a 16 bytes, one-time global unique number. and can show in string format like this:
+ 550e8400-e29b-41d4-a716-446655440000
+
+ The format of uuid is:
+ uuid = <time_low> "-"
+ <time_mid> "-"
+ <time_high_and_version> "-"
+ <clock_seq_high_and_reserved>
+ <clock_seq_low> "-"
+ <node>
+ time_low = 4*<hex_octet>
+ time_mid = 2*<hex_octet>
+ time_high_and_version = 2*<hex_octet>
+ clock_seq_high_and_reserved = <hex_octet>
+ clock_seq_low = <hex_octet>
+ node = 6*<hex_octet>
+ hex_octet = <hex_digit> <hex_digit>
+ hex_digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
+ |"a"|"b"|"c"|"d"|"e"|"f"
+ |"A"|"B"|"C"|"D"|"E"|"F"
+ Note:
+ Actually, to IOT with JumpStart, we fix the first 10 bytes of UUID string!!!!
+*/
+INT WscGenerateUUID(
+ RTMP_ADAPTER *pAd,
+ UCHAR *uuidHexStr,
+ UCHAR *uuidAscStr,
+ int apIdx,
+ BOOLEAN bUseCurrentTime)
+{
+
+ WSC_UUID_T uuid_t;
+ unsigned long long uuid_time;
+ int i;
+ UINT16 clkSeq;
+ char uuidTmpStr[UUID_LEN_STR+2];
+
+
+ /* Get the current time. */
+ if (bUseCurrentTime)
+ {
+ NdisGetSystemUpTime((ULONG *)&uuid_time);
+ }
+ else
+ uuid_time = 2860; /*xtime.tv_sec; // Well, we fix this to make JumpStart happy! */
+ uuid_time *= 10000000;
+ uuid_time += 0x01b21dd213814000LL;
+
+
+
+ uuid_t.timeLow = (UINT32)uuid_time & 0xFFFFFFFF;
+ uuid_t.timeMid = (UINT16)((uuid_time >>32) & 0xFFFF);
+ uuid_t.timeHi_Version = (UINT16)((uuid_time >> 48) & 0x0FFF);
+ uuid_t.timeHi_Version |= (1 << 12);
+
+ /* Get the clock sequence. */
+ clkSeq = (UINT16)(0x0601/*jiffies*/ & 0xFFFF); /* Again, we fix this to make JumpStart happy! */
+
+ uuid_t.clockSeqLow = clkSeq & 0xFF;
+ uuid_t.clockSeqHi_Var = (clkSeq & 0x3F00) >> 8;
+ uuid_t.clockSeqHi_Var |= 0x80;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* copy the Mac address as the value of node */
+ NdisMoveMemory(&uuid_t.node[0], &pAd->ApCfg.MBSSID[apIdx].Bssid[0], sizeof(uuid_t.node));
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* Create the UUID ASCII string. */
+ memset(uuidTmpStr, 0, sizeof(uuidTmpStr));
+ snprintf(uuidTmpStr, sizeof(uuidTmpStr), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (unsigned int)uuid_t.timeLow, uuid_t.timeMid, uuid_t.timeHi_Version, uuid_t.clockSeqHi_Var, uuid_t.clockSeqLow,
+ uuid_t.node[0], uuid_t.node[1], uuid_t.node[2], uuid_t.node[3], uuid_t.node[4], uuid_t.node[5]);
+ if (strlen(uuidTmpStr) > UUID_LEN_STR)
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR:UUID String size too large!\n"));
+ strncpy((PSTRING)uuidAscStr, uuidTmpStr, UUID_LEN_STR);
+
+ /* Create the UUID Hex format number */
+ uuid_t.timeLow = cpu2be32(uuid_t.timeLow);
+ NdisMoveMemory(&uuidHexStr[0], &uuid_t.timeLow, 4);
+ uuid_t.timeMid = cpu2be16(uuid_t.timeMid);
+ NdisMoveMemory(&uuidHexStr[4], &uuid_t.timeMid, 2);
+ uuid_t.timeHi_Version = cpu2be16(uuid_t.timeHi_Version);
+ NdisMoveMemory(&uuidHexStr[6], &uuid_t.timeHi_Version, 2);
+ NdisMoveMemory(&uuidHexStr[8], &uuid_t.clockSeqHi_Var, 1);
+ NdisMoveMemory(&uuidHexStr[9], &uuid_t.clockSeqLow, 1);
+ NdisMoveMemory(&uuidHexStr[10], &uuid_t.node[0], 6);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("The UUID Hex string is:"));
+ for (i=0; i< 16; i++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02x", (uuidHexStr[i] & 0xff)));
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("The UUID ASCII string is:%s!\n", uuidAscStr));
+ return 0;
+}
+
+VOID WscInitCommonTimers(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl)
+{
+ WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->EapolTimer, pWscControl->EapolTimerRunning, WscEAPOLTimeOutAction);
+ WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->Wsc2MinsTimer, pWscControl->Wsc2MinsTimerRunning, Wsc2MinsTimeOutAction);
+ WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->WscUPnPNodeInfo.UPnPMsgTimer, pWscControl->WscUPnPNodeInfo.bUPnPMsgTimerRunning, WscUPnPMsgTimeOutAction);
+ pWscControl->WscUPnPNodeInfo.bUPnPMsgTimerPending = FALSE;
+ WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->M2DTimer, pWscControl->bM2DTimerRunning, WscM2DTimeOutAction);
+
+#ifdef WSC_LED_SUPPORT
+ WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->WscLEDTimer, pWscControl->WscLEDTimerRunning, WscLEDTimer);
+ WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->WscSkipTurnOffLEDTimer, pWscControl->WscSkipTurnOffLEDTimerRunning, WscSkipTurnOffLEDTimer);
+#endif /* WSC_LED_SUPPORT */
+}
+
+VOID WscInitClientTimers(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWScControl)
+{
+ WSC_TIMER_INIT(pAdapter, pWScControl, &pWScControl->WscPBCTimer, pWScControl->WscPBCTimerRunning, WscPBCTimeOutAction);
+ WSC_TIMER_INIT(pAdapter, pWScControl, &pWScControl->WscScanTimer, pWScControl->WscScanTimerRunning, WscScanTimeOutAction);
+ WSC_TIMER_INIT(pAdapter, pWScControl, &pWScControl->WscProfileRetryTimer, pWScControl->WscProfileRetryTimerRunning, WscProfileRetryTimeout); /* add by johnli, fix WPS test plan 5.1.1 */
+}
+
+/*
+ ==========================================================================
+ Description:
+ wps state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ ==========================================================================
+ */
+VOID WscStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ PWSC_CTRL pWScControl;
+ StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_WSC_STATE, MAX_WSC_MSG, (STATE_MACHINE_FUNC)Drop, WSC_IDLE, WSC_MACHINE_BASE);
+ StateMachineSetAction(S, WSC_IDLE, WSC_EAPOL_START_MSG, (STATE_MACHINE_FUNC)WscEAPOLStartAction);
+ StateMachineSetAction(S, WSC_IDLE, WSC_EAPOL_PACKET_MSG, (STATE_MACHINE_FUNC)WscEAPAction);
+ StateMachineSetAction(S, WSC_IDLE, WSC_EAPOL_UPNP_MSG, (STATE_MACHINE_FUNC)WscEAPAction);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UCHAR apidx;
+
+ for (apidx = 0; apidx < MAX_MBSSID_NUM(pAd); apidx++)
+ {
+ pWScControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ pWScControl->EntryIfIdx= (MIN_NET_DEVICE_FOR_MBSSID | apidx);
+ WscInitCommonTimers(pAd, pWScControl);
+ pWScControl->WscUpdatePortCfgTimerRunning = FALSE;
+ WSC_TIMER_INIT(pAd, pWScControl, &pWScControl->WscUpdatePortCfgTimer, pWScControl->WscUpdatePortCfgTimerRunning, WscUpdatePortCfgTimeout);
+#ifdef WSC_V2_SUPPORT
+ WSC_TIMER_INIT(pAd, pWScControl, &pWScControl->WscSetupLockTimer, pWScControl->WscSetupLockTimerRunning, WscSetupLockTimeout);
+#endif /* WSC_V2_SUPPORT */
+ }
+
+#ifdef APCLI_SUPPORT
+ for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++)
+ {
+ pWScControl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ pWScControl->EntryIfIdx= (MIN_NET_DEVICE_FOR_APCLI | apidx);
+ WscInitCommonTimers(pAd, pWScControl);
+ WscInitClientTimers(pAd, pWScControl);
+ }
+#endif /* APCLI_SUPPORT */
+ }
+
+#endif /* CONFIG_AP_SUPPORT */
+
+}
+
+void WscM2DTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ /* For each state, we didn't care about the retry issue, we just send control message
+ to notify the UPnP deamon that some error happened in STATE MACHINE.
+ */
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pWscControl->pAd;
+ WSC_UPNP_NODE_INFO *pWscNodeInfo;
+#ifdef CONFIG_AP_SUPPORT
+ MAC_TABLE_ENTRY *pEntry = NULL;
+/* UCHAR apidx = MAIN_MBSSID; */
+#endif /* CONFIG_AP_SUPPORT */
+ BOOLEAN Cancelled;
+ UCHAR CurOpMode = 0xFF;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pEntry = MacTableLookup(pAd, pWscControl->EntryAddr);
+#endif /* CONFIG_AP_SUPPORT */
+ pWscNodeInfo = &pWscControl->WscUPnPNodeInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("UPnP StateMachine TimeOut(State=%d!)\n", pWscControl->WscState));
+
+ if(
+#ifdef CONFIG_AP_SUPPORT
+ (((pEntry == NULL) || (pWscNodeInfo->registrarID != 0)) && (CurOpMode == AP_MODE)) ||
+#endif /* CONFIG_AP_SUPPORT */
+ (0))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():pEntry maybe gone or already received M2 Packet!\n", __FUNCTION__));
+ goto done;
+ }
+
+ if (pWscControl->M2DACKBalance != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): waiting for M2DACK balance, extend the time!\n", __FUNCTION__));
+ /* Waiting for M2DACK balance. */
+ RTMPModTimer(&pWscControl->M2DTimer, WSC_EAP_ID_TIME_OUT);
+ pWscControl->M2DACKBalance = 0;
+ goto done;
+ }
+ else
+ {
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): send EAP-Fail to wireless Station!\n", __FUNCTION__));
+ /* Send EAPFail to Wireless Station and reset the status of Wsc. */
+ WscSendEapFail(pAd, pWscControl, TRUE);
+ /*pEntry->bWscCapable = FALSE; */
+ if (pEntry != NULL)
+ pEntry->Receive_EapolStart_EapRspId = 0;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ pWscControl->EapMsgRunning = FALSE;
+ pWscControl->WscState = WSC_STATE_OFF;
+ }
+
+done:
+ pWscControl->bM2DTimerRunning = FALSE;
+ pWscControl->M2DACKBalance = 0;
+ pWscNodeInfo->registrarID = 0;
+
+
+}
+
+
+VOID WscUPnPMsgTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ PRTMP_ADAPTER pAd;
+ WSC_UPNP_NODE_INFO *pWscNodeInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscUPnPMsgTimeOutAction\n"));
+
+ /*It shouldn't happened! */
+ if (!pWscControl)
+ return;
+
+ pAd = (PRTMP_ADAPTER)pWscControl->pAd;
+ pWscNodeInfo = &pWscControl->WscUPnPNodeInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("UPnP StateMachine TimeOut(State=%d!)\n", pWscControl->WscState));
+
+ if (pWscNodeInfo->bUPnPMsgTimerPending)
+ {
+#define WSC_UPNP_TIMER_PENDIND_WAIT 2000
+
+ RTMPModTimer(&pWscNodeInfo->UPnPMsgTimer, WSC_UPNP_TIMER_PENDIND_WAIT);
+ DBGPRINT(RT_DEBUG_TRACE, ("UPnPMsgTimer Pending......\n"));
+ }
+ else
+ {
+ int dataLen;
+ UCHAR *pWscData;
+
+ os_alloc_mem(NULL, (UCHAR **)&pWscData, WSC_MAX_DATA_LEN);
+/* if( (pWscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) != NULL) */
+ if (pWscData != NULL)
+ {
+ memset(pWscData, 0, WSC_MAX_DATA_LEN);
+ dataLen = BuildMessageNACK(pAd, pWscControl, pWscData);
+ WscSendUPnPMessage(pAd, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_NORMAL,
+ pWscData, dataLen, 0, 0, &pAd->CurrentAddress[0], AP_MODE);
+/* kfree(pWscData); */
+ os_free_mem(NULL, pWscData);
+ }
+
+ pWscNodeInfo->bUPnPInProgress = FALSE;
+ pWscNodeInfo->bUPnPMsgTimerPending = FALSE;
+ pWscNodeInfo->bUPnPMsgTimerRunning = FALSE;
+ pWscControl->WscState = WSC_STATE_OFF;
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+
+ RTMPSendWirelessEvent(pAd, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscUPnPMsgTimeOutAction\n"));
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ This function processes EapolStart packets from wps stations
+ or enqueued by self.
+
+ Return:
+ None
+ ==========================================================================
+*/
+VOID WscEAPOLStartAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ PWSC_CTRL pWpsCtrl = NULL;
+ PHEADER_802_11 pHeader;
+ PWSC_PEER_ENTRY pWscPeer = NULL;
+ UCHAR CurOpMode = 0xFF;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscEAPOLStartAction\n"));
+
+ pHeader = (PHEADER_802_11)Elem->Msg;
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+
+ /* Cannot find this wps station in MacTable of WPS AP. */
+ if (pEntry == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("pEntry is NULL.\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLStartAction\n"));
+ return;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pWpsCtrl = &pAd->ApCfg.MBSSID[pEntry->apidx].WscControl;
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (pWpsCtrl == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pWpsCtrl == NULL!\n", __FUNCTION__));
+ return;
+ }
+
+ RTMP_SEM_LOCK(&pWpsCtrl->WscPeerListSemLock);
+ WscInsertPeerEntryByMAC(&pWpsCtrl->WscPeerList, pEntry->Addr);
+ RTMP_SEM_UNLOCK(&pWpsCtrl->WscPeerListSemLock);
+
+ WscMaintainPeerList(pAd, pWpsCtrl);
+
+ /*
+ Check this STA is first one or not
+ */
+ if (pWpsCtrl->WscPeerList.size != 0)
+ {
+ pWscPeer = (PWSC_PEER_ENTRY)pWpsCtrl->WscPeerList.pHead;
+ if (NdisEqualMemory(pEntry->Addr, pWscPeer->mac_addr, MAC_ADDR_LEN) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("This is not first WSC peer, ignore this EAPOL_Start!\n"));
+ hex_dump("pEntry->Addr", pEntry->Addr, MAC_ADDR_LEN);
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscApShowPeerList(pAd, NULL);
+#endif /* CONFIG_AP_SUPPORT */
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLStartAction\n"));
+ return;
+ }
+ }
+
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscState = %d\n", pWpsCtrl->WscState));
+ if ((pEntry->Receive_EapolStart_EapRspId == 0) ||
+ (pWpsCtrl->WscState <= WSC_STATE_WAIT_REQ_ID))
+ {
+ /* Receive the first EapolStart packet of this wps station. */
+ pEntry->Receive_EapolStart_EapRspId |= WSC_ENTRY_GET_EAPOL_START;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPOLStartAction - receive EAPOL-Start from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pEntry->Addr[0],
+ pEntry->Addr[1],
+ pEntry->Addr[2],
+ pEntry->Addr[3],
+ pEntry->Addr[4],
+ pEntry->Addr[5]));
+
+ /* EapolStart packet is sent by station means this station wants to do wps process with AP. */
+ pWpsCtrl->EapMsgRunning = TRUE;
+ /* Update EntryAddr again */
+ NdisMoveMemory(pWpsCtrl->EntryAddr, pEntry->Addr, MAC_ADDR_LEN);
+
+ if (pEntry->bWscCapable == FALSE)
+ pEntry->bWscCapable = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPOLStartAction(ra%d) - send EAP-Req(Id) to %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pEntry->apidx,
+ pEntry->Addr[0],
+ pEntry->Addr[1],
+ pEntry->Addr[2],
+ pEntry->Addr[3],
+ pEntry->Addr[4],
+ pEntry->Addr[5]));
+
+ /* Send EAP-Request/Id to station */
+ WscSendEapReqId(pAd, pEntry, CurOpMode);
+ if (!pWpsCtrl->EapolTimerRunning)
+ {
+ pWpsCtrl->EapolTimerRunning = TRUE;
+ /* Set WPS_EAP Messages timeout function. */
+ RTMPSetTimer(&pWpsCtrl->EapolTimer, WSC_EAP_ID_TIME_OUT);
+ }
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Ignore EAPOL-Start.\n"));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLStartAction\n"));
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ This is state machine function when receiving EAP packets
+ which is WPS Registration Protocol.
+
+ There are two roles at our AP, as an
+ 1. Enrollee
+ 2. Internal Registrar
+ 3. Proxy
+
+ There are two roles at our Station, as an
+ 1. Enrollee
+ 2. External Registrar
+
+ Running Scenarios:
+ -----------------------------------------------------------------
+ 1a. Adding an AP as an Enrollee to a station as an External Registrar (EAP)
+ [External Registrar]<----EAP--->[Enrollee_AP]
+ -----------------------------------------------------------------
+ 2a. Adding a station as an Enrollee to an AP with built-in Registrar (EAP)
+ [Registrar_AP]<----EAP--->[Enrollee_STA]
+ -----------------------------------------------------------------
+ 3a. Adding an Enrollee with External Registrar (UPnP/EAP)
+ [External Registrar]<----UPnP--->[Proxy_AP]<---EAP--->[Enrollee_STA]
+ -----------------------------------------------------------------
+
+ Return:
+ None
+ ==========================================================================
+*/
+VOID WscEAPAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR MsgType;
+ BOOLEAN bUPnPMsg, Cancelled;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR MacAddr[MAC_ADDR_LEN] = {0};
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx = MAIN_MBSSID;
+#endif /* CONFIG_AP_SUPPORT */
+ PWSC_CTRL pWscControl = NULL;
+ PWSC_UPNP_NODE_INFO pWscUPnPNodeInfo = NULL;
+ UCHAR CurOpMode = 0xFF;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscEAPAction\n"));
+
+ /* The first 6 bytes in Elem->Msg is the MAC address of wps peer. */
+ memmove(MacAddr, Elem->Msg, MAC_ADDR_LEN);
+ memmove(Elem->Msg, Elem->Msg+6, Elem->MsgLen);
+
+#ifdef DBG
+ hex_dump("(WscEAPAction)Elem->MsgLen", Elem->Msg, Elem->MsgLen);
+#endif /* DBG */
+
+ MsgType = WscRxMsgType(pAdapter, Elem);
+ bUPnPMsg = Elem->MsgType == WSC_EAPOL_UPNP_MSG ? TRUE : FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Addr: %02x:%02x:%02x:%02x:%02x:%02x, MsgType: 0x%02X, bUPnPMsg: %s\n",
+ PRINT_MAC(MacAddr), MsgType, bUPnPMsg ? "TRUE" : "FALSE"));
+
+ if (!bUPnPMsg)
+ pEntry = MacTableLookup(pAdapter, MacAddr);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (!bUPnPMsg)
+ {
+ if (pEntry)
+ {
+ if (IS_ENTRY_CLIENT(pEntry) && pEntry->apidx >= pAdapter->ApCfg.BssidNum)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Unknow apidex(=%d).\n", pEntry->apidx));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n"));
+ return;
+ }
+ else
+ {
+ apidx = pEntry->apidx;
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: apidex=%d.\n", pEntry->apidx));
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: pEntry is NULL.\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n"));
+ return;
+ }
+#ifdef APCLI_SUPPORT
+ /* for ap-client packets */
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ pWscControl = &pAdapter->ApCfg.ApCliTab[apidx].WscControl;
+ else
+#endif /* APCLI_SUPPORT */
+ pWscControl = &pAdapter->ApCfg.MBSSID[apidx].WscControl;
+ }
+ else
+ {
+ int i;
+ for (i = 0 ; i < MAX_MBSSID_NUM(pAdapter); i++)
+ {
+ if(NdisEqualMemory(pAdapter->ApCfg.MBSSID[i].Bssid, MacAddr, MAC_ADDR_LEN))
+ {
+ apidx = i;
+ break;
+ }
+ }
+ pWscControl = &pAdapter->ApCfg.MBSSID[apidx].WscControl;
+ pWscUPnPNodeInfo = &pAdapter->ApCfg.MBSSID[apidx].WscControl.WscUPnPNodeInfo;
+ pWscUPnPNodeInfo->bUPnPMsgTimerPending = TRUE;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (pWscControl == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pWscControl == NULL!\n", __FUNCTION__));
+ return;
+ }
+
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ {
+ if ((MsgType == WSC_MSG_EAP_REG_RSP_ID) || (MsgType == WSC_MSG_EAP_ENR_RSP_ID))
+ {
+ if (((pEntry->Receive_EapolStart_EapRspId & WSC_ENTRY_GET_EAP_RSP_ID) == WSC_ENTRY_GET_EAP_RSP_ID)
+ && (pWscControl->WscState > WSC_STATE_WAIT_M1))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Already receive EAP_RSP(Identitry) from this STA, ignore it.\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n"));
+ return;
+ }
+ else
+ pEntry->Receive_EapolStart_EapRspId |= WSC_ENTRY_GET_EAP_RSP_ID;
+ }
+ }
+
+ pWscControl->EapolTimerPending = TRUE;
+
+#ifdef WSC_V2_SUPPORT
+ if (MsgType == WSC_MSG_EAP_FRAG_ACK)
+ {
+ WscSendEapFragData(pAdapter, pWscControl, pEntry);
+ return;
+ }
+ else
+#endif /* WSC_V2_SUPPORT */
+ if (MsgType == WSC_MSG_EAP_REG_RSP_ID)
+ {
+ /* Receive EAP-Response/Id from external registrar, so the role of AP is enrollee. */
+ if (((pWscControl->WscConfMode & WSC_ENROLLEE) != 0) ||
+ (((pWscControl->WscConfMode & WSC_PROXY) != 0) && bUPnPMsg))
+ {
+ pWscControl->WscActionMode= WSC_ENROLLEE;
+ pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0;
+ MsgType = WSC_MSG_EAP_RSP_ID;
+ WscEapEnrolleeAction(pAdapter, Elem, WSC_MSG_EAP_RSP_ID, pEntry, pWscControl);
+ }
+ }
+ else if (MsgType == WSC_MSG_EAP_ENR_RSP_ID)
+ {
+ /* Receive EAP-Response/Id from wps enrollee station, so the role of AP is Registrar or Proxy. */
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Rx Identity\n"));
+ pWscControl->WscActionMode = WSC_REGISTRAR;
+ if (bUPnPMsg)
+ {
+ /* Receive enrollee identity from UPnP */
+ }
+ else
+ {
+#ifdef CONFIG_AP_SUPPORT
+ /* Receive enrollee identity from EAP */
+ if ((pWscControl->WscMode == WSC_PBC_MODE)
+ )
+ {
+ /*
+ Some WPS PBC Station select AP from UI directly; doesn't do PBC scan.
+ Need to check DPID from STA again here.
+ */
+ WscPBC_DPID_FromSTA(pAdapter, pWscControl->EntryAddr);
+ WscPBCSessionOverlapCheck(pAdapter);
+ if ((pAdapter->CommonCfg.WscStaPbcProbeInfo.WscPBCStaProbeCount == 1) &&
+ !NdisEqualMemory(pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], &ZERO_MAC_ADDR[0], MAC_ADDR_LEN) &&
+ (NdisEqualMemory(pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], &pWscControl->EntryAddr[0], 6) == FALSE))
+ {
+ pAdapter->CommonCfg.WscPBCOverlap = TRUE;
+ }
+ if (pAdapter->CommonCfg.WscPBCOverlap)
+ {
+ hex_dump("EntryAddr", pWscControl->EntryAddr, 6);
+ hex_dump("StaMacAddr0", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], 6);
+ hex_dump("StaMacAddr1", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[1], 6);
+ hex_dump("StaMacAddr2", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[2], 6);
+ hex_dump("StaMacAddr3", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[3], 6);
+ }
+ }
+
+ if ((pWscControl->WscMode == WSC_PBC_MODE) &&
+ (pAdapter->CommonCfg.WscPBCOverlap == TRUE))
+ {
+ /* PBC session overlap */
+ pWscControl->WscStatus = STATUS_WSC_PBC_SESSION_OVERLAP;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_PBC_SESSION_OVERLAP, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: PBC Session Overlap!\n"));
+ }
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ if ((pWscControl->WscConfMode & WSC_PROXY_REGISTRAR) != 0)
+ {
+ /* Notify UPnP daemon before send Eap-Req(wsc-start) */
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: pEntry->Addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ __FUNCTION__, PRINT_MAC(pEntry->Addr)));
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ WscSendUPnPConfReqMsg(pAdapter, (pWscControl->EntryIfIdx & 0x0F),
+ (PUCHAR)pAdapter->ApCfg.MBSSID[pEntry->apidx].Ssid, pEntry->Addr, 2, 0, CurOpMode);
+ /* Reset the UPnP timer and status. */
+ if (pWscControl->bM2DTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pWscControl->M2DTimer, &Cancelled);
+ pWscControl->bM2DTimerRunning = FALSE;
+ }
+ pWscControl->WscUPnPNodeInfo.registrarID = 0;
+ pWscControl->M2DACKBalance = 0;
+ WscDelWPARetryTimer(pAdapter);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ pWscControl->EapMsgRunning = TRUE;
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_M1;
+ /* send EAP WSC_START */
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ {
+ pWscControl->bWscLastOne = TRUE;
+ if (CurOpMode == AP_MODE)
+ WscSendMessage(pAdapter, WSC_OPCODE_START, NULL, 0, pWscControl, AP_MODE, EAP_CODE_REQ);
+ else
+ {
+ if (ADHOC_ON(pAdapter) && (pWscControl->WscConfMode == WSC_REGISTRAR))
+ WscSendMessage(pAdapter, WSC_OPCODE_START, NULL, 0, pWscControl, STA_MODE, EAP_CODE_REQ);
+ else
+ WscSendMessage(pAdapter, WSC_OPCODE_START, NULL, 0, pWscControl, STA_MODE, EAP_CODE_RSP);
+ }
+ }
+ }
+ }
+ }
+ else if (MsgType == WSC_MSG_EAP_REQ_ID)
+ {
+ /* Receive EAP_Req/Identity from WPS AP or WCN */
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP_Req/Identity from WPS AP or WCN\n"));
+ if (bUPnPMsg && (pWscControl->WscConfMode == WSC_ENROLLEE))
+ {
+ pWscControl->WscActionMode = WSC_ENROLLEE;
+ pWscControl->WscUseUPnP = 1;
+ WscEapEnrolleeAction(pAdapter, Elem, WSC_MSG_EAP_REQ_START, pEntry, pWscControl);
+ }
+ else
+ {
+ /* Receive EAP_Req/Identity from WPS AP */
+ if (pEntry != NULL)
+ WscSendEapRspId(pAdapter, pEntry, pWscControl);
+ }
+
+ if (!bUPnPMsg)
+ {
+ if ((pWscControl->WscState < WSC_STATE_WAIT_M1) ||
+ (pWscControl->WscState > WSC_STATE_WAIT_ACK))
+ {
+ if (pWscControl->WscConfMode == WSC_REGISTRAR)
+ pWscControl->WscState = WSC_STATE_WAIT_M1;
+ else
+ pWscControl->WscState = WSC_STATE_WAIT_WSC_START;
+ }
+ }
+ }
+ else if (MsgType == WSC_MSG_EAP_REQ_START)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP_Req(Wsc_Start) from WPS AP\n"));
+
+ /* Receive EAP_Req(Wsc_Start) from WPS AP */
+ if (pWscControl->WscConfMode == WSC_ENROLLEE)
+ {
+ pWscControl->WscActionMode = WSC_ENROLLEE;
+ pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0;
+ WscEapEnrolleeAction(pAdapter, Elem, WSC_MSG_EAP_REQ_START, pEntry, pWscControl);
+
+ if (!pWscControl->EapolTimerRunning)
+ {
+ pWscControl->EapolTimerRunning = TRUE;
+ RTMPSetTimer(&pWscControl->EapolTimer, WSC_EAP_ID_TIME_OUT);
+ }
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Ignore EAP_Req(Wsc_Start) from WPS AP\n"));
+ }
+ else if (MsgType == WSC_MSG_EAP_FAIL)
+ {
+ /* Receive EAP_Fail from WPS AP */
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP_Fail from WPS AP\n"));
+
+ if (pWscControl->WscState >= WSC_STATE_WAIT_EAPFAIL)
+ {
+ pWscControl->WscState = WSC_STATE_OFF;
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ pWscControl->WscConfMode = WSC_DISABLE;
+ /* Bring apcli interface down first */
+ if(pEntry && IS_ENTRY_APCLI(pEntry) && pAdapter->ApCfg.ApCliTab[BSS0].Enable == TRUE )
+ {
+ pAdapter->ApCfg.ApCliTab[pEntry->apidx].Enable = FALSE;
+ ApCliIfDown(pAdapter);
+ pAdapter->ApCfg.ApCliTab[pEntry->apidx].Enable = TRUE;
+ }
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if (pWscControl->WscState == WSC_STATE_RX_M2D)
+ {
+ /* Wait M2; */
+ }
+ else if ((pWscControl->WscState <= WSC_STATE_WAIT_REQ_ID) &&
+ (pWscControl->WscState != WSC_STATE_FAIL))
+ {
+ /* Ignore. D-Link DIR-628 AP sometimes would send EAP_Fail to station after Link UP first then send EAP_Req/Identity. */
+ }
+ else
+ {
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+
+
+ pWscControl->WscConfMode = WSC_DISABLE;
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_OFF;
+
+ }
+ }
+ else if (MsgType == WSC_MSG_M1)
+ {
+ UINT32 rv = 0;
+ /*
+ If Buffalo WPS STA doesn't receive M2D from AP, Buffalo WPS STA will stop to do WPS.
+ Therefore we need to receive M1 and send M2D without trigger.
+ */
+ if ((pWscControl->WscConfMode & WSC_REGISTRAR) != 0)
+ {
+ pWscControl->WscActionMode = WSC_REGISTRAR;
+ /* If Message is from EAP, but UPnP Registrar is in progress now, ignore EAP_M1 */
+ if (!bUPnPMsg && pWscControl->WscUPnPNodeInfo.bUPnPInProgress)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("UPnP Registrar is working now, ignore EAP M1.\n"));
+ goto out;
+ }
+ else
+ WscEapRegistrarAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ rv = 1;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (!bUPnPMsg) && (CurOpMode == AP_MODE))
+ {
+ if ((pWscControl->bWscTrigger
+ )
+ && (pWscControl->WscState >= WSC_STATE_WAIT_M3))
+ ;
+ else
+ {
+ pWscControl->WscActionMode = WSC_PROXY;
+ WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ }
+ }
+ else if ((!pWscControl->bWscTrigger) && ((pWscControl->WscConfMode & WSC_PROXY) == 0) && (pAdapter->OpMode == OPMODE_AP))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscTrigger is FALSE, ignore EAP M1.\n"));
+ goto out;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if (MsgType == WSC_MSG_M3 ||
+ MsgType == WSC_MSG_M5 ||
+ MsgType == WSC_MSG_M7 ||
+ MsgType == WSC_MSG_WSC_DONE)
+ {
+ BOOLEAN bNonceMatch = WscCheckNonce(pAdapter, Elem, TRUE, pWscControl);
+ if (((pWscControl->WscConfMode & WSC_REGISTRAR) != 0) &&
+ (pWscControl->bWscTrigger
+ ) &&
+ bNonceMatch)
+ {
+ /* If Message is from EAP, but UPnP Registrar is in progress now, ignore EAP Messages */
+ if (!bUPnPMsg && pWscControl->WscUPnPNodeInfo.bUPnPInProgress)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("UPnP Registrar is working now, ignore EAP Messages.\n"));
+ goto out;
+ }
+ else
+ {
+ pWscControl->WscActionMode = WSC_REGISTRAR;
+ WscEapRegistrarAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ }
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (!bUPnPMsg) && (CurOpMode == AP_MODE))
+ {
+ pWscControl->WscActionMode = WSC_PROXY;
+ WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if (MsgType == WSC_MSG_M2 ||
+ MsgType == WSC_MSG_M2D ||
+ MsgType == WSC_MSG_M4 ||
+ MsgType == WSC_MSG_M6 ||
+ MsgType == WSC_MSG_M8)
+ {
+ BOOLEAN bNonceMatch = WscCheckNonce(pAdapter, Elem, FALSE, pWscControl);
+ BOOLEAN bGoWPS = FALSE;
+
+ if ((CurOpMode == AP_MODE) ||
+ ((CurOpMode == STA_MODE) &&
+ (pWscControl->bWscTrigger
+ )))
+ bGoWPS = TRUE;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((CurOpMode == AP_MODE) &&
+ ((pWscControl->WscV2Info.bWpsEnable == FALSE) && (pWscControl->WscV2Info.bEnableWpsV2)))
+ bGoWPS = FALSE;
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (((pWscControl->WscConfMode & WSC_ENROLLEE) != 0) &&
+ bGoWPS &&
+ bNonceMatch)
+ {
+ pWscControl->WscActionMode = WSC_ENROLLEE;
+ pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0;
+ if (MsgType == WSC_MSG_M2)
+ {
+ BOOLEAN bReadOwnPIN = TRUE;
+#ifdef CONFIG_AP_SUPPORT
+ /* WPS Enrollee AP only supports PIN without trigger */
+ if (CurOpMode == AP_MODE)
+ {
+ if (pWscControl->bWscTrigger == FALSE)
+ {
+ pWscControl->WscMode = 1;
+ WscGetConfWithoutTrigger(pAdapter, pWscControl, FALSE);
+ }
+ else
+ {
+ WscBuildBeaconIE(pAdapter,
+ pWscControl->WscConfStatus,
+ TRUE,
+ pWscControl->WscMode,
+ pWscControl->WscConfigMethods,
+ (pWscControl->EntryIfIdx & 0x0F),
+ NULL,
+ 0,
+ AP_MODE);
+ WscBuildProbeRespIE(pAdapter,
+ WSC_MSGTYPE_AP_WLAN_MGR,
+ pWscControl->WscConfStatus,
+ TRUE,
+ pWscControl->WscMode,
+ pWscControl->WscConfigMethods,
+ pWscControl->EntryIfIdx,
+ NULL,
+ 0,
+ AP_MODE);
+ APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (bReadOwnPIN)
+ {
+ pWscControl->WscPinCodeLen = pWscControl->WscEnrolleePinCodeLen;
+ WscGetRegDataPIN(pAdapter, pWscControl->WscEnrolleePinCode, pWscControl);
+ DBGPRINT(RT_DEBUG_TRACE, ("(%d) WscEnrolleePinCode: %08u\n", bReadOwnPIN, pWscControl->WscEnrolleePinCode));
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("WscPinCode: %08u\n", pWscControl->WscPinCode));
+ }
+ /* If Message is from EAP, but UPnP Registrar is in progress now, ignore EAP Messages */
+ if (!bUPnPMsg && pWscControl->WscUPnPNodeInfo.bUPnPInProgress)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("UPnP Registrar is working now, ignore EAP Messages.\n"));
+ goto out;
+ }
+ else
+ WscEapEnrolleeAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (bUPnPMsg) && (CurOpMode == AP_MODE))
+ {
+ pWscControl->WscActionMode = WSC_PROXY;
+ WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if (MsgType == WSC_MSG_WSC_ACK)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscState: %d\n", pWscControl->WscState));
+ if (((pWscControl->WscConfMode & WSC_REGISTRAR) != 0) &&
+ pWscControl->WscState <= WSC_STATE_SENT_M2D)
+ {
+ if (WscCheckNonce(pAdapter, Elem, TRUE, pWscControl))
+ {
+ if (pWscControl->M2DACKBalance > 0)
+ pWscControl->M2DACKBalance--;
+ pWscControl->WscState = WSC_STATE_INIT;
+ pWscControl->EapMsgRunning = FALSE;
+ }
+ }
+ else
+ {
+ if (((pWscControl->WscConfMode & WSC_ENROLLEE) != 0) &&
+ WscCheckNonce(pAdapter, Elem, FALSE, pWscControl))
+ {
+ pWscControl->WscActionMode = WSC_ENROLLEE;
+ pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0;
+ WscEapEnrolleeAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (CurOpMode == AP_MODE))
+ {
+ pWscControl->WscActionMode = WSC_PROXY;
+ WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ }
+ else if (MsgType == WSC_MSG_WSC_NACK)
+ {
+ BOOLEAN bReSetWscIE = FALSE;
+ if (bUPnPMsg && (pWscControl->WscState == WSC_STATE_WAIT_M8) &&
+ (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED))
+ {
+ // Some external sta will send NACK when AP is configured.
+ // bWscTrigger should be set FALSE, otherwise Proxy will send NACK to enrollee.
+ pWscControl->bWscTrigger = FALSE;
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ bReSetWscIE = TRUE;
+ }
+ if (!bUPnPMsg &&
+ (WscCheckNonce(pAdapter, Elem, FALSE, pWscControl) || WscCheckNonce(pAdapter, Elem, TRUE, pWscControl)))
+ {
+ USHORT config_error = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive NACK from WPS client.\n"));
+ WscGetConfigErrFromNack(pAdapter, Elem, &config_error);
+ /*
+ If a PIN authentication or communication error occurs,
+ the Registrar MUST warn the user and MUST NOT automatically reuse the PIN.
+ Furthermore, if the Registrar detects this situation and prompts the user for a new PIN from the Enrollee device,
+ it MUST NOT accept the same PIN again without warning the user of a potential attack.
+ */
+ if ((pWscControl->WscState >= WSC_STATE_WAIT_M5) && (config_error != WSC_ERROR_SETUP_LOCKED))
+ {
+ pWscControl->WscRejectSamePinFromEnrollee = TRUE;
+ pWscControl->WscPinCode = 0;
+
+ if (pWscControl->WscState < WSC_STATE_WAIT_M8)
+ {
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ bReSetWscIE = TRUE;
+ }
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ if ((pWscControl->WscState == WSC_STATE_OFF)
+ && (CurOpMode == AP_MODE)
+ && (pWscControl->RegData.SelfInfo.ConfigError != WSC_ERROR_NO_ERROR))
+ {
+ bReSetWscIE = TRUE;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if ((pWscControl->WscState == WSC_STATE_WAIT_M8) &&
+ (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED))
+ {
+ /* Some external sta will send NACK when AP is configured. */
+ /* bWscTrigger should be set FALSE, otherwise Proxy will send NACK to enrollee. */
+ pWscControl->bWscTrigger = FALSE;
+ bReSetWscIE = TRUE;
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ pWscControl->WscRejectSamePinFromEnrollee = FALSE;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_SUCCESS, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else if ((CurOpMode == AP_MODE) &&
+ (pWscControl->WscState == WSC_STATE_WAIT_DONE) &&
+ (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED) &&
+ (pAdapter->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled))
+ {
+ bReSetWscIE = TRUE;
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+ }
+
+ if ((CurOpMode == AP_MODE) && bReSetWscIE)
+ {
+ WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode);
+ WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, CurOpMode);
+ APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F);
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled);
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+ }
+ if (pWscControl->bWscTrigger)
+ pWscControl->bWscTrigger = FALSE;
+ }
+#endif // CONFIG_AP_SUPPORT //
+
+ if ((CurOpMode == AP_MODE)
+ || ((ADHOC_ON(pAdapter)) && (pWscControl->WscConfMode == WSC_REGISTRAR))
+ )
+ {
+ WscSendEapFail(pAdapter, pWscControl, TRUE);
+ pWscControl->WscState = WSC_STATE_FAIL;
+ }
+
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+ pWscControl->RegData.ReComputePke = 1;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unsupported Msg Type (%02X)\n", MsgType));
+ //sync by 7610
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+ pWscControl->RegData.SelfInfo.ConfigError = WSC_ERROR_NO_ERROR;
+ WscSendNACK(pAdapter, pEntry, pWscControl);
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, BSS0, 0);
+ goto out;
+ }
+
+ if (bUPnPMsg)
+ {
+ /* Messages from UPnP */
+ if (pWscUPnPNodeInfo->bUPnPMsgTimerRunning)
+ RTMPModTimer(&pWscUPnPNodeInfo->UPnPMsgTimer, WSC_UPNP_MSG_TIME_OUT);
+ }
+ else
+ {
+ if ((pWscControl->EapMsgRunning == TRUE) &&
+ (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ /* Messages from EAP */
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ pWscControl->EapolTimerRunning = TRUE;
+ }
+ }
+
+ if (bUPnPMsg && pWscControl->EapolTimerRunning)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if ((pWscControl->WscActionMode == WSC_PROXY) && (CurOpMode == AP_MODE))
+ {
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ {
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+ }
+ }
+
+out:
+ if (bUPnPMsg)
+ pWscUPnPNodeInfo->bUPnPMsgTimerPending = FALSE;
+
+ pWscControl->EapolTimerPending = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n"));
+}
+
+/*
+ ============================================================================
+ Enrollee Enrollee Enrollee
+ ============================================================================
+*/
+VOID WscEapEnrolleeAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl)
+{
+ INT DataLen = 0, rv = 0, DH_Len = 0;
+ UCHAR OpCode, bssIdx;
+ PUCHAR WscData = NULL;
+ BOOLEAN bUPnPMsg, bUPnPStatus = FALSE, Cancelled;
+ WSC_UPNP_NODE_INFO *pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo;
+ UINT MaxWscDataLen = WSC_MAX_DATA_LEN;
+ UCHAR CurOpMode = 0xFF;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction Enter!\n"));
+
+ bUPnPMsg = Elem->MsgType == WSC_EAPOL_UPNP_MSG ? TRUE : FALSE;
+ OpCode = bUPnPMsg ? WSC_OPCODE_UPNP_MASK : 0;
+ bssIdx = 0;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif // CONFIG_AP_SUPPORT //
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ /* Early check. */
+ if ((pWscControl->WscActionMode != WSC_ENROLLEE) ||
+ (pWscControl->WscUseUPnP && pEntry) ||
+ ((pWscControl->WscUseUPnP == 0) && (!pEntry)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("EarlyCheckFailed: pWscControl->WscActionMode=%d, Configured=%d, WscUseUPnP=%d, pEntry=%p!\n",
+ pWscControl->WscActionMode, pWscControl->WscConfStatus, pWscControl->WscUseUPnP, pEntry));
+ goto Fail;
+ }
+ bssIdx = (pWscControl->EntryIfIdx & 0x0F);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ DBGPRINT(RT_DEBUG_TRACE, ("MsgType=0x%x, WscState=%d, bUPnPMsg=%d!\n", MsgType, pWscControl->WscState, bUPnPMsg));
+
+ if (bUPnPMsg)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if ((MsgType == WSC_MSG_EAP_RSP_ID) && (CurOpMode == AP_MODE))
+ {
+ /* let it pass */
+ } else
+#endif /* CONFIG_AP_SUPPORT */
+ if(MsgType ==WSC_MSG_M2 && pWscUPnPInfo->bUPnPInProgress == FALSE)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ MAC_TABLE_ENTRY *tempEntry;
+ tempEntry = MacTableLookup(pAdapter, &pWscControl->EntryAddr[0]);
+ if (tempEntry)
+ {
+ if((tempEntry->Receive_EapolStart_EapRspId & WSC_ENTRY_GET_EAP_RSP_ID) == WSC_ENTRY_GET_EAP_RSP_ID)
+ {
+ goto Done;
+ }
+ }
+ /* else cannot find the pEntry, so we need to handle this msg. */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ pWscUPnPInfo->bUPnPInProgress = TRUE;
+ /* Set the WscState as "WSC_STATE_WAIT_RESP_ID" because UPnP start from this state. */
+ /* pWscControl->WscState = WSC_STATE_WAIT_RESP_ID; */
+ RTMPSetTimer(&pWscUPnPInfo->UPnPMsgTimer, WSC_UPNP_MSG_TIME_OUT);
+ pWscUPnPInfo->bUPnPMsgTimerRunning = TRUE;
+ }
+ else
+ {
+ /* For other messages, we must make sure pWscUPnPInfo->bUPnPInProgress== TRUE */
+ if (pWscUPnPInfo->bUPnPInProgress == FALSE)
+ {
+ goto Done;
+ }
+ }
+ }
+
+#ifdef WSC_V2_SUPPORT
+ MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen;
+#endif /* WSC_V2_SUPPORT */
+ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen);
+/* if( (WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) == NULL) */
+ if (WscData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscData Allocate failed!\n"));
+ goto Fail;
+ }
+ NdisZeroMemory(WscData, MaxWscDataLen);
+
+ switch (MsgType)
+ {
+ case WSC_MSG_EAP_RSP_ID:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx Identity(ReComputePke=%d)\n", pWscControl->RegData.ReComputePke));
+ case WSC_MSG_EAP_REQ_START:
+ if (MsgType == WSC_MSG_EAP_REQ_START)
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx Wsc_Start(ReComputePke=%d)\n", pWscControl->RegData.ReComputePke));
+
+ if (pWscControl->RegData.ReComputePke == 1)
+ {
+ INT idx;
+ DH_Len = sizeof(pWscControl->RegData.Pke);
+ /* Enrollee 192 random bytes for DH key generation */
+ for (idx = 0; idx < 192; idx++)
+ pWscControl->RegData.EnrolleeRandom[idx] = RandomByte(pAdapter);
+ RT_DH_PublicKey_Generate (
+ WPS_DH_G_VALUE, sizeof(WPS_DH_G_VALUE),
+ WPS_DH_P_VALUE, sizeof(WPS_DH_P_VALUE),
+ pWscControl->RegData.EnrolleeRandom, sizeof(pWscControl->RegData.EnrolleeRandom),
+ pWscControl->RegData.Pke, (UINT *) &DH_Len);
+
+ pWscControl->RegData.ReComputePke = 0;
+ }
+
+ OpCode |= WSC_OPCODE_MSG;
+
+ DataLen = BuildMessageM1(pAdapter, pWscControl, WscData);
+ if(!bUPnPMsg)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ WscDelWPARetryTimer(pAdapter);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ pWscControl->EapMsgRunning = TRUE;
+ pWscControl->WscStatus = STATUS_WSC_EAP_M1_SENT;
+ }
+ else
+ /* Sometime out-of-band registrars (ex: Vista) get M1 for collecting information of device. */
+ pWscControl->WscStatus = STATUS_WSC_IDLE;
+
+ /* Change the state to next one */
+ if (pWscControl->WscState < WSC_STATE_SENT_M1)
+ pWscControl->WscState = WSC_STATE_SENT_M1;
+
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M1, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ break;
+
+ case WSC_MSG_M2:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M2\n"));
+
+ /* Receive M2, if we are at WSC_STATE_WAIT_M2 start, process it immediately */
+ if (pWscControl->WscState == WSC_STATE_SENT_M1 ||
+ pWscControl->WscState == WSC_STATE_RX_M2D)
+ {
+ /* Process M2 */
+ pWscControl->WscStatus = STATUS_WSC_EAP_M2_RECEIVED;
+
+ NdisMoveMemory(pWscControl->RegData.PeerInfo.MacAddr, pWscControl->EntryAddr, 6);
+ if ((rv = ProcessMessageM2(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, (pWscControl->EntryIfIdx & 0x0F), &pWscControl->RegData)))
+ {
+ goto Fail;
+ }
+ else
+ {
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((CurOpMode == AP_MODE) && pWscControl->bSetupLock)
+ {
+ rv = WSC_ERROR_SETUP_LOCKED;
+ goto Fail;
+ }
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ OpCode |= WSC_OPCODE_MSG;
+ DataLen = BuildMessageM3(pAdapter, pWscControl, WscData);
+ pWscControl->WscStatus = STATUS_WSC_EAP_M3_SENT;
+
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_M4;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M3, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+ }
+ break;
+
+ case WSC_MSG_M2D:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M2D\n"));
+
+ /* Receive M2D, if we are at WSC_STATE_WAIT_M2 start, process it immediately */
+ if (pWscControl->WscState == WSC_STATE_SENT_M1 ||
+ pWscControl->WscState == WSC_STATE_RX_M2D)
+ {
+ if ((rv = ProcessMessageM2D(pAdapter, Elem->Msg, Elem->MsgLen, &pWscControl->RegData)))
+ goto Fail;
+
+ pWscControl->WscStatus = STATUS_WSC_EAP_M2D_RECEIVED;
+
+ if ((CurOpMode == STA_MODE)
+ )
+ {
+ /* When external registrar is Marvell station, */
+ /* wps station sends NACK may confuse or reset Marvell wps state machine. */
+ OpCode |= WSC_OPCODE_ACK;
+ DataLen = BuildMessageACK(pAdapter, pWscControl, WscData);
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_ACK, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+ else
+ {
+
+ /* For VISTA SP1 internal registrar test */
+ OpCode |= WSC_OPCODE_NACK;
+ pWscControl->RegData.SelfInfo.ConfigError = WSC_ERROR_NO_ERROR;
+ DataLen = BuildMessageNACK(pAdapter, pWscControl, WscData);
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_NACK, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_RX_M2D;
+ }
+ break;
+
+ case WSC_MSG_M4:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M4\n"));
+
+ /* Receive M4, if we are at WSC_STATE_WAIT_M4 start, process it immediately */
+ if (pWscControl->WscState == WSC_STATE_WAIT_M4)
+ {
+ /* Process M4 */
+ pWscControl->WscStatus = STATUS_WSC_EAP_M4_RECEIVED;
+ if ((rv = ProcessMessageM4(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData)))
+ {
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscCheckPinAttackCount(pAdapter, pWscControl);
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ goto Fail;
+ }
+ else
+ {
+ OpCode |= WSC_OPCODE_MSG;
+ DataLen = BuildMessageM5(pAdapter, pWscControl, WscData);
+ pWscControl->WscStatus = STATUS_WSC_EAP_M5_SENT;
+
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_M6;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M5, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+ }
+ break;
+
+ case WSC_MSG_M6:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M6\n"));
+
+ /* Receive M6, if we are at WSC_STATE_WAIT_M6 start, process it immediately */
+ if (pWscControl->WscState == WSC_STATE_WAIT_M6)
+ {
+ /* Process M6 */
+ pWscControl->WscStatus = STATUS_WSC_EAP_M6_RECEIVED;
+ if ((rv=ProcessMessageM6(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData)))
+ {
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscCheckPinAttackCount(pAdapter, pWscControl);
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ goto Fail;
+ }
+ else
+ {
+ OpCode |= WSC_OPCODE_MSG;
+
+ DataLen = BuildMessageM7(pAdapter, pWscControl, WscData);
+ pWscControl->WscStatus = STATUS_WSC_EAP_M7_SENT;
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_M8;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M7, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ /*
+ Complete WPS with this STA. Delete it from WscPeerList for others STA to do WSC with AP
+ */
+ if (pEntry)
+ {
+ RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock);
+ WscDelListEntryByMAC(&pWscControl->WscPeerList, pEntry->Addr);
+ RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock);
+ }
+ }
+ }
+ break;
+
+ case WSC_MSG_M8:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M8\n"));
+
+ /* Receive M8, if we are at WSC_STATE_WAIT_M6 start, process it immediately */
+ if (pWscControl->WscState == WSC_STATE_WAIT_M8)
+ {
+ /* Process M8 */
+ pWscControl->WscStatus = STATUS_WSC_EAP_M8_RECEIVED;
+ if ((rv=ProcessMessageM8(pAdapter, Elem->Msg, Elem->MsgLen, pWscControl)))
+ goto Fail;
+ else
+ {
+ OpCode |= WSC_OPCODE_DONE;
+ DataLen = BuildMessageDONE(pAdapter, pWscControl, WscData);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ /* Change the state to next one */
+#ifdef APCLI_SUPPORT
+ /* Ap Client only supports Inband(EAP)-Enrollee. */
+ if (!bUPnPMsg && pEntry && IS_ENTRY_APCLI(pEntry))
+ pWscControl->WscState = WSC_STATE_WAIT_EAPFAIL;
+ else
+#endif /* APCLI_SUPPORT */
+ pWscControl->WscState = WSC_STATE_WAIT_ACK;
+ //sync by 7610
+ //pWscControl->RegData.ReComputePke = 0;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_DONE, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+ }
+ break;
+
+#ifdef CONFIG_AP_SUPPORT
+ case WSC_MSG_WSC_ACK:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx ACK\n"));
+
+ /* Receive ACK */
+ if (pWscControl->WscState == WSC_STATE_WAIT_ACK)
+ {
+ /* Process ACK */
+ pWscControl->WscStatus = STATUS_WSC_EAP_RAP_RSP_ACK;
+ /* Send out EAP-Fail */
+ WscSendEapFail(pAdapter, pWscControl, FALSE);
+ pWscControl->WscState = WSC_STATE_CONFIGURED;
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ }
+ break;
+#endif /* CONFIG_AP_SUPPORT */
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Unsupported Msg Type\n"));
+ break;
+ }
+
+ if (bUPnPMsg)
+ {
+ if ((MsgType == WSC_MSG_M8) && (pWscControl->WscState == WSC_STATE_WAIT_ACK))
+ {
+ pWscControl->EapMsgRunning = FALSE;
+ pWscControl->WscState = WSC_STATE_CONFIGURED;
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ if(pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled);
+ pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE;
+ }
+ pWscUPnPInfo->bUPnPInProgress = FALSE;
+ pWscUPnPInfo->registrarID = 0;
+ }
+ }
+ else
+ {
+ if (((MsgType == WSC_MSG_WSC_ACK) && (pWscControl->WscState == WSC_STATE_CONFIGURED)) ||
+ ((MsgType == WSC_MSG_M8) && (pWscControl->WscState == WSC_STATE_WAIT_ACK)))
+ {
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+ pWscControl->EapMsgRunning = FALSE;
+ /*NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); */
+ }
+ }
+
+ if(OpCode > WSC_OPCODE_UPNP_MASK)
+ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA,
+ WSC_UPNP_DATA_SUB_NORMAL, WscData, DataLen,
+ Elem->TimeStamp.u.LowPart, Elem->TimeStamp.u.HighPart,
+ &pAdapter->CurrentAddress[0], CurOpMode);
+ else if(OpCode > 0 && OpCode < WSC_OPCODE_UPNP_MASK)
+ {
+ if (pWscControl->WscState != WSC_STATE_CONFIGURED)
+ {
+#ifdef WSC_V2_SUPPORT
+ pWscControl->WscTxBufLen = 0;
+ pWscControl->pWscCurBufIdx = NULL;
+ pWscControl->bWscLastOne = TRUE;
+ if (pWscControl->bWscFragment && (DataLen > pWscControl->WscFragSize))
+ {
+ ASSERT(DataLen < MGMT_DMA_BUFFER_SIZE);
+ NdisMoveMemory(pWscControl->pWscTxBuf, WscData, DataLen);
+ pWscControl->WscTxBufLen = DataLen;
+ NdisZeroMemory(WscData, DataLen);
+ pWscControl->bWscLastOne = FALSE;
+ pWscControl->bWscFirstOne = TRUE;
+ NdisMoveMemory(WscData, pWscControl->pWscTxBuf, pWscControl->WscFragSize);
+ DataLen = pWscControl->WscFragSize;
+ pWscControl->WscTxBufLen -= pWscControl->WscFragSize;
+ pWscControl->pWscCurBufIdx = (pWscControl->pWscTxBuf + pWscControl->WscFragSize);
+ }
+#endif /* WSC_V2_SUPPORT */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ else
+ WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ else
+ bUPnPStatus = TRUE;
+
+Fail:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : rv = %d\n", rv));
+ if (rv)
+ {
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((CurOpMode == AP_MODE) && pWscControl->bSetupLock)
+ rv = WSC_ERROR_SETUP_LOCKED;
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (rv <= WSC_ERROR_DEV_PWD_AUTH_FAIL)
+ pWscControl->RegData.SelfInfo.ConfigError = rv;
+ else if ((rv == WSC_ERROR_HASH_FAIL) || (rv == WSC_ERROR_HMAC_FAIL))
+ pWscControl->RegData.SelfInfo.ConfigError = WSC_ERROR_DECRYPT_CRC_FAIL;
+
+ switch(rv)
+ {
+ case WSC_ERROR_DEV_PWD_AUTH_FAIL:
+ pWscControl->WscStatus = STATUS_WSC_ERROR_DEV_PWD_AUTH_FAIL;
+ break;
+ default:
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+ break;
+ }
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ if (bUPnPMsg)
+ {
+ if (pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled);
+ pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE;
+ }
+ pWscUPnPInfo->bUPnPInProgress = FALSE;
+ }
+ else
+ WscSendNACK(pAdapter, pEntry, pWscControl);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ pWscControl->WscState = WSC_STATE_OFF;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /*NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); */
+ /*pWscControl->WscMode = 1; */
+
+ bUPnPStatus = FALSE;
+ }
+
+Done:
+ if(WscData)
+ os_free_mem(NULL, WscData);
+ if(bUPnPMsg && (bUPnPStatus == FALSE))
+ WscUPnPErrHandle(pAdapter, pWscControl, Elem->TimeStamp.u.LowPart);
+
+ rv = 0;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (((bUPnPMsg || (pEntry && IS_ENTRY_CLIENT(pEntry)))
+ && (pWscControl->WscState == WSC_STATE_CONFIGURED || pWscControl->WscState == WSC_STATE_WAIT_ACK))
+#ifdef APCLI_SUPPORT
+ ||((!bUPnPMsg && pEntry && IS_ENTRY_APCLI(pEntry)) && (pWscControl->WscState == WSC_STATE_WAIT_EAPFAIL || pWscControl->WscState == WSC_STATE_CONFIGURED))
+#endif /* APCLI_SUPPORT */
+ )
+ {
+ rv = 1;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (rv == 1)
+ {
+#ifdef WSC_LED_SUPPORT
+ UCHAR WPSLEDStatus;
+#endif /* WSC_LED_SUPPORT */
+
+ pWscControl->bWscTrigger = FALSE;
+ pWscControl->RegData.ReComputePke = 1;
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled);
+ }
+ if ((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED)
+#ifdef CONFIG_AP_SUPPORT
+ || (pWscControl->bWCNTest == TRUE)
+#ifdef WSC_V2_SUPPORT
+ || (pWscControl->WscV2Info.bEnableWpsV2 && ((CurOpMode == AP_MODE) && !pWscControl->bSetupLock))
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ )
+ {
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ pWscControl->WscConfStatus = WSC_SCSTATE_CONFIGURED;
+ pWscControl->WscMode = 1;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_SUCCESS, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ pWscControl->RegData.SelfInfo.ScState = pWscControl->WscConfStatus;
+#ifdef APCLI_SUPPORT
+ if (!bUPnPMsg && pEntry && IS_ENTRY_APCLI(pEntry))
+ {
+ POS_COOKIE pObj = (POS_COOKIE) pAdapter->OS_Cookie;
+ INT old_if_type = pObj->ioctl_if_type;
+ pObj->ioctl_if_type = INT_APCLI;
+ WscWriteConfToApCliCfg(pAdapter, pWscControl, &pWscControl->WscProfile.Profile[0], TRUE);
+ pObj->ioctl_if_type = old_if_type;
+/*#ifdef KTHREAD_SUPPORT */
+/* WAKE_UP(&(pAdapter->wscTask)); */
+/*#else */
+/* RTMP_SEM_EVENT_UP(&(pAdapter->wscTask.taskSema)); */
+/*#endif */
+ RtmpOsTaskWakeUp(&(pAdapter->wscTask));
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ {
+ RTMPSetTimer(&pWscControl->WscUpdatePortCfgTimer, 1000);
+ pWscControl->WscUpdatePortCfgTimerRunning = TRUE;
+ }
+
+ if (bUPnPMsg || (pEntry && IS_ENTRY_CLIENT(pEntry)))
+ {
+ WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode);
+ WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode);
+ APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ }
+#ifdef WSC_LED_SUPPORT
+ /* The protocol is finished. */
+ WPSLEDStatus = LED_WPS_SUCCESS;
+ RTMPSetLED(pAdapter, WPSLEDStatus);
+#endif /* WSC_LED_SUPPORT */
+ }
+}
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ ============================================================================
+ Proxy Proxy Proxy
+ ============================================================================
+*/
+VOID WscEapApProxyAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl)
+{
+ PUCHAR WscData = NULL;
+ BOOLEAN sendToUPnP = FALSE, bUPnPStatus = FALSE, Cancelled;
+ int reqID = 0;
+ WSC_UPNP_NODE_INFO *pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo;
+ UINT MaxWscDataLen = WSC_MAX_DATA_LEN;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction Enter!\n"));
+
+ if (Elem->MsgType == WSC_EAPOL_UPNP_MSG)
+ {
+ reqID = Elem->TimeStamp.u.LowPart;
+ if(reqID > 0)
+ sendToUPnP = TRUE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction():pEntry=%p, ElemMsgType=%ld, MsgType=%d!\n", pEntry, Elem->MsgType, MsgType));
+
+ if ((pWscControl->WscActionMode != WSC_PROXY) ||
+ ((Elem->MsgType == WSC_EAPOL_PACKET_MSG) && (pEntry == NULL)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("EarlyCheckFailed: gWscActionMode=%d, pEntry=%p!\n", pWscControl->WscActionMode, pEntry));
+ goto Fail;
+ }
+
+#ifdef WSC_V2_SUPPORT
+ MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen;
+#endif /* WSC_V2_SUPPORT */
+ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen);
+/* if ((WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) == NULL) */
+ if (WscData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscData Allocate failed!\n"));
+ goto Fail;
+ }
+ NdisZeroMemory(WscData, MaxWscDataLen);
+
+ /* Base on state doing the Msg, State change diagram */
+ if (Elem->MsgType == WSC_EAPOL_UPNP_MSG)
+ { /* WSC message send from UPnP. */
+ switch (MsgType)
+ {
+ case WSC_MSG_M2:
+ case WSC_MSG_M4:
+ case WSC_MSG_M6:
+ case WSC_MSG_M8:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WscMsg(%d) from UPnP, eventID=0x%x!\n", MsgType, reqID));
+ WscSendMessage(pAdapter, WSC_OPCODE_MSG, Elem->Msg, Elem->MsgLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+
+ /*Notify the UPnP daemon which remote registar is negotiating with enrollee. */
+ if (MsgType == WSC_MSG_M2)
+ {
+ pWscUPnPInfo->registrarID = Elem->TimeStamp.u.HighPart;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s():registrarID=0x%x!\n", __FUNCTION__, pWscUPnPInfo->registrarID));
+ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_MGMT, WSC_UPNP_MGMT_SUB_REG_SELECT,
+ (PUCHAR)(&pWscUPnPInfo->registrarID), sizeof(UINT), 0, 0, NULL, AP_MODE);
+
+ /*Reset the UPnP timer and status. */
+ if (pWscControl->bM2DTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pWscControl->M2DTimer, &Cancelled);
+ pWscControl->bM2DTimerRunning = FALSE;
+ }
+ pWscControl->M2DACKBalance = 0;
+ pWscUPnPInfo->registrarID = 0;
+ }
+ if (MsgType == WSC_MSG_M8)
+ {
+ WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, AP_MODE);
+ APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F);
+ }
+ break;
+
+ case WSC_MSG_M2D:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WscMsg M2D(%d) from UPnP, eventID=0x%x!\n", MsgType, reqID));
+
+ /*If it's send by UPnP Action, response ok directly to remote UPnP Control Point! */
+ if (reqID > 0)
+ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_ACK,
+ 0, 0, reqID, 0, NULL, AP_MODE);
+
+ /*Send M2D to wireless station. */
+ WscSendMessage(pAdapter, WSC_OPCODE_MSG, Elem->Msg, Elem->MsgLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+ pWscControl->M2DACKBalance++;
+ if ((pWscUPnPInfo->registrarID == 0) && (pWscControl->bM2DTimerRunning == FALSE))
+ {
+ /* Add M2D timer used to trigger the EAPFail Packet! */
+ RTMPSetTimer(&pWscControl->M2DTimer, WSC_UPNP_M2D_TIME_OUT);
+ pWscControl->bM2DTimerRunning = TRUE;
+ }
+ break;
+
+ case WSC_MSG_WSC_NACK:
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Recv WscMsg(%d) from UPnP, request EventID=%d! drop it!\n", MsgType, reqID));
+ break;
+ }
+ }
+ else
+ { /*WSC msg send from EAP. */
+ switch (MsgType)
+ {
+ case WSC_MSG_M1:
+ case WSC_MSG_M3:
+ case WSC_MSG_M5:
+ case WSC_MSG_M7:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WscMsg(%d) from EAP\n", MsgType));
+ /*This msg send to event-based external registrar */
+ if (MsgType == WSC_MSG_M1)
+ {
+ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_TO_ALL,
+ Elem->Msg, Elem->MsgLen, 0, 0, &pWscControl->EntryAddr[0], AP_MODE);
+ pWscControl->WscState = WSC_STATE_SENT_M1;
+ }
+ else
+ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_TO_ALL,
+ Elem->Msg, Elem->MsgLen, 0, pWscUPnPInfo->registrarID,
+ &pWscControl->EntryAddr[0], AP_MODE);
+
+ break;
+
+ case WSC_MSG_WSC_ACK:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WSC_ACK from EAP\n"));
+
+ /* The M2D must appeared before the ACK, so we just need sub it when (pWscUPnPInfo->M2DACKBalance > 0) */
+ if (pWscControl->M2DACKBalance > 0)
+ pWscControl->M2DACKBalance--;
+ break;
+
+ case WSC_MSG_WSC_DONE:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WSC_DONE from EAP\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: send WSC_DONE to UPnP Registrar!\n"));
+ /*Send msg to event-based external registrar */
+ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_TO_ONE,
+ Elem->Msg, Elem->MsgLen, 0,
+ pWscUPnPInfo->registrarID, &pWscControl->EntryAddr[0], AP_MODE);
+
+ /*Send EAPFail to wireless station to finish the whole process. */
+ WscSendEapFail(pAdapter, pWscControl, FALSE);
+
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+
+ pEntry->bWscCapable = FALSE;
+ pWscControl->EapMsgRunning = FALSE;
+ NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN);
+
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled);
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Recv WSC Msg(%d) from EAP , it's impossible, drop it!\n", MsgType));
+ break;
+ }
+ }
+
+Fail:
+ if (WscData)
+ os_free_mem(NULL, WscData);
+ if (sendToUPnP && (bUPnPStatus == FALSE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Need to send UPnP but bUPnPStatus is false!MsgType=%d, regID=0x%x!\n", MsgType, reqID));
+ WscUPnPErrHandle(pAdapter, pWscControl, reqID);
+ }
+
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+/*
+ ============================================================================
+ Registrar Registrar Registrar
+ ============================================================================
+*/
+VOID WscEapRegistrarAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl)
+{
+ INT DataLen = 0, rv = 0;
+ UCHAR OpCode = 0;
+ UCHAR *WscData = NULL;
+ BOOLEAN bUPnPMsg, bUPnPStatus = FALSE, Cancelled;
+ WSC_UPNP_NODE_INFO *pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo;
+ UINT MaxWscDataLen = WSC_MAX_DATA_LEN;
+ UCHAR CurOpMode = 0xFF;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction Enter!\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif // CONFIG_AP_SUPPORT //
+
+
+ bUPnPMsg = Elem->MsgType == WSC_EAPOL_UPNP_MSG ? TRUE : FALSE;
+
+ if(bUPnPMsg)
+ {
+ if(MsgType == WSC_MSG_M1)
+ { /* It's a M1 message, we may need to initialize our state machine. */
+ if ((pWscControl->WscActionMode == WSC_REGISTRAR)
+ && (pWscControl->EntryIfIdx == WSC_INIT_ENTRY_APIDX)
+ && (pWscControl->WscState < WSC_STATE_WAIT_M1)
+ && (pWscUPnPInfo->bUPnPInProgress == FALSE))
+ {
+ pWscUPnPInfo->bUPnPInProgress = TRUE;
+ /*Set the WscState as "WSC_STATE_WAIT_RESP_ID" because UPnP start from this state. */
+ pWscControl->WscState = WSC_STATE_WAIT_M1;
+ RTMPSetTimer(&pWscUPnPInfo->UPnPMsgTimer, WSC_UPNP_MSG_TIME_OUT);
+ pWscUPnPInfo->bUPnPMsgTimerRunning = TRUE;
+ }
+ }
+ OpCode = WSC_OPCODE_UPNP_MASK;
+
+ } else {
+ if (pWscControl->EapolTimerRunning)
+ pWscControl->EapolTimerRunning = FALSE;
+
+ }
+
+#ifdef WSC_V2_SUPPORT
+ MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen;
+#endif /* WSC_V2_SUPPORT */
+ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen);
+/* if( (WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) == NULL) */
+ if (WscData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscData Allocate failed!\n"));
+ goto Fail;
+ }
+ NdisZeroMemory(WscData, MaxWscDataLen);
+
+ /* Base on state doing the Msg, State change diagram */
+ switch (MsgType)
+ {
+ case WSC_MSG_M1:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M1\n"));
+
+ /* Receive M1, if we are at WSC_STATE_WAIT_M1 start, process it immediately */
+ pWscControl->WscStatus = STATUS_WSC_EAP_M1_RECEIVED;
+ if (pWscControl->WscState == WSC_STATE_WAIT_M1)
+ {
+ OpCode |= WSC_OPCODE_MSG;
+
+ /* Process M1 */
+ if ((rv=ProcessMessageM1(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData)))
+ goto Fail;
+ else
+ {
+ BOOLEAN bSendM2D = TRUE;
+
+
+ if (pWscControl->bWscTrigger && (!pWscControl->bWscAutoTigeer))
+ {
+ if (((pWscControl->WscMode == WSC_PBC_MODE) || (pWscControl->WscMode == WSC_SMPBC_MODE))
+ || (pWscControl->WscMode == WSC_PIN_MODE && pWscControl->WscPinCode != 0))
+ bSendM2D = FALSE;
+ }
+
+ if (bSendM2D)
+ {
+ DataLen = BuildMessageM2D(pAdapter, pWscControl, WscData);
+ pWscControl->WscState = WSC_STATE_SENT_M2D;
+ pWscControl->M2DACKBalance++;
+ if (pWscControl->bM2DTimerRunning == FALSE)
+ {
+ // Add M2D timer used to trigger the EAPFail Packet!
+ RTMPSetTimer(&pWscControl->M2DTimer, WSC_UPNP_M2D_TIME_OUT);
+ pWscControl->bM2DTimerRunning = TRUE;
+ }
+ }
+ else
+ {
+ pWscControl->WscStatus = STATUS_WSC_EAP_M2_SENT;
+ DataLen = BuildMessageM2(pAdapter, pWscControl, WscData);
+
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_M3;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M2, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+ }
+ }
+ break;
+
+ case WSC_MSG_M3:
+ /* Receive M3 */
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M3\n"));
+ if (pWscControl->WscState == WSC_STATE_WAIT_M3)
+ {
+ pWscControl->WscStatus = STATUS_WSC_EAP_M3_RECEIVED;
+
+ if((rv = ProcessMessageM3(pAdapter, Elem->Msg, Elem->MsgLen, &pWscControl->RegData)))
+ goto Fail;
+ else
+ {
+ OpCode |= WSC_OPCODE_MSG;
+ DataLen = BuildMessageM4(pAdapter, pWscControl, WscData);
+ pWscControl->WscStatus = STATUS_WSC_EAP_M4_SENT;
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_M5;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M4, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+ }
+ break;
+
+ case WSC_MSG_M5:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M5\n"));
+ if (pWscControl->WscState == WSC_STATE_WAIT_M5)
+ {
+ pWscControl->WscStatus = STATUS_WSC_EAP_M5_RECEIVED;
+
+ if ((rv=ProcessMessageM5(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData)))
+ goto Fail;
+ else
+ {
+ OpCode |= WSC_OPCODE_MSG;
+ DataLen = BuildMessageM6(pAdapter, pWscControl, WscData);
+ pWscControl->WscStatus = STATUS_WSC_EAP_M6_SENT;
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_M7;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M6, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ }
+ }
+ break;
+ case WSC_MSG_M7:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M7\n"));
+ if (pWscControl->WscState == WSC_STATE_WAIT_M7)
+ {
+ pWscControl->WscStatus = STATUS_WSC_EAP_M7_RECEIVED;
+ if ((rv=ProcessMessageM7(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData)))
+ goto Fail;
+ else
+ {
+ if (
+#ifdef CONFIG_AP_SUPPORT
+ (CurOpMode == AP_MODE) ||
+#endif /* CONFIG_AP_SUPPORT */
+ (0))
+ {
+ OpCode |= WSC_OPCODE_MSG;
+ DataLen = BuildMessageM8(pAdapter, pWscControl, WscData);
+ pWscControl->WscStatus = STATUS_WSC_EAP_M8_SENT;
+ /* Change the state to next one */
+ pWscControl->WscState = WSC_STATE_WAIT_DONE;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M8, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+
+ if (pWscControl->WscV2Info.bEnableWpsV2 && (CurOpMode == AP_MODE))
+ WscAddEntryToAclList(pAdapter, pEntry->apidx, pEntry->Addr);
+#endif /* WSC_V2_SUPPORT */
+ /*
+ 1. Complete WPS with this STA. Delete it from WscPeerList for others STA to do WSC with AP
+ 2. Some WPS STA will send dis-assoc close to WSC_DONE
+ then AP will miss WSC_DONE from STA; hence we need to call WscDelListEntryByMAC here.
+ */
+ if (pEntry && (CurOpMode == AP_MODE))
+ {
+ RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock);
+ WscDelListEntryByMAC(&pWscControl->WscPeerList, pEntry->Addr);
+ RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ }
+ break;
+
+ case WSC_MSG_WSC_DONE:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx DONE\n"));
+ if (pWscControl->WscState == WSC_STATE_WAIT_DONE)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ pWscControl->WscStatus = STATUS_WSC_EAP_RAP_RSP_DONE_SENT;
+ /* Send EAP-Fail */
+ WscSendEapFail(pAdapter, pWscControl, FALSE);
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ pWscControl->WscState = WSC_STATE_CONFIGURED;
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_SUCCESS, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ pWscControl->EapMsgRunning = FALSE;
+ }
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Unsupported Msg Type\n"));
+ if (WscData)
+ os_free_mem(NULL, WscData);
+ return;
+ }
+
+ if(OpCode > WSC_OPCODE_UPNP_MASK)
+ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_NORMAL,
+ WscData, DataLen,
+ Elem->TimeStamp.u.LowPart, Elem->TimeStamp.u.HighPart, &pWscControl->EntryAddr[0], CurOpMode);
+ else if(OpCode > 0 && OpCode < WSC_OPCODE_UPNP_MASK)
+ {
+#ifdef WSC_V2_SUPPORT
+ pWscControl->WscTxBufLen = 0;
+ pWscControl->pWscCurBufIdx = NULL;
+ pWscControl->bWscLastOne = TRUE;
+ if (pWscControl->bWscFragment && (DataLen > pWscControl->WscFragSize))
+ {
+ ASSERT(DataLen < MGMT_DMA_BUFFER_SIZE);
+ NdisMoveMemory(pWscControl->pWscTxBuf, WscData, DataLen);
+ pWscControl->WscTxBufLen = DataLen;
+ NdisZeroMemory(WscData, DataLen);
+ pWscControl->bWscLastOne = FALSE;
+ pWscControl->bWscFirstOne = TRUE;
+ NdisMoveMemory(WscData, pWscControl->pWscTxBuf, pWscControl->WscFragSize);
+ DataLen = pWscControl->WscFragSize;
+ pWscControl->WscTxBufLen -= pWscControl->WscFragSize;
+ pWscControl->pWscCurBufIdx = (pWscControl->pWscTxBuf + pWscControl->WscFragSize);
+ }
+#endif /* WSC_V2_SUPPORT */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (pWscControl->WscState != WSC_STATE_CONFIGURED)
+ WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ }
+ else
+ bUPnPStatus = TRUE;
+
+ if(bUPnPMsg)
+ {
+ if(pWscControl->WscState == WSC_STATE_SENT_M2D)
+ { /*After M2D, reset the status of State Machine. */
+ pWscControl->WscState = WSC_STATE_WAIT_UPNP_START;
+ pWscUPnPInfo->bUPnPInProgress = FALSE;
+ }
+ }
+Fail:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : rv = %d\n", rv));
+ if (rv)
+ {
+ if (rv <= WSC_ERROR_DEV_PWD_AUTH_FAIL)
+ {
+ pWscControl->RegData.SelfInfo.ConfigError = rv;
+ }
+ else if ((rv == WSC_ERROR_HASH_FAIL) || (rv == WSC_ERROR_HMAC_FAIL))
+ pWscControl->RegData.SelfInfo.ConfigError = WSC_ERROR_DECRYPT_CRC_FAIL;
+
+ switch(rv)
+ {
+ case WSC_ERROR_HASH_FAIL:
+ pWscControl->WscStatus = STATUS_WSC_ERROR_HASH_FAIL;
+ break;
+ case WSC_ERROR_HMAC_FAIL:
+ pWscControl->WscStatus = STATUS_WSC_ERROR_HMAC_FAIL;
+ break;
+ default:
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+ break;
+ }
+ RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+ if (bUPnPMsg)
+ {
+ if (pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE)
+ {
+ RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled);
+ pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE;
+ }
+ pWscUPnPInfo->bUPnPInProgress = FALSE;
+ }
+ else
+ {
+ DataLen = BuildMessageNACK(pAdapter, pWscControl, WscData);
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+ pEntry->bWscCapable = FALSE;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+ }
+ /*
+ If a PIN authentication or communication error occurs after sending message M6,
+ the Registrar MUST warn the user and MUST NOT automatically reuse the PIN.
+ Furthermore, if the Registrar detects this situation and prompts the user for a new PIN from the Enrollee device,
+ it MUST NOT accept the same PIN again without warning the user of a potential attack.
+ */
+ if (pWscControl->WscState >= WSC_STATE_WAIT_M7)
+ {
+ pWscControl->WscRejectSamePinFromEnrollee = TRUE;
+ pWscControl->WscPinCode = 0;
+ }
+ pWscControl->WscState = WSC_STATE_OFF;
+ pWscControl->WscStatus = STATUS_WSC_IDLE;
+ /*NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); */
+ /*pWscControl->WscMode = 1; */
+ bUPnPStatus = FALSE;
+ }
+
+ if(WscData)
+ os_free_mem(NULL, WscData);
+
+ if(bUPnPMsg && (bUPnPStatus == FALSE))
+ WscUPnPErrHandle(pAdapter, pWscControl, Elem->TimeStamp.u.LowPart);
+
+ if (pWscControl->WscState == WSC_STATE_CONFIGURED)
+ {
+#ifdef WSC_LED_SUPPORT
+ UCHAR WPSLEDStatus;
+#endif /* WSC_LED_SUPPORT */
+
+ pWscControl->bWscTrigger = FALSE;
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled);
+ }
+ if (bUPnPMsg)
+ {
+ if (pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE)
+ { RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled);
+ pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE;
+ }
+ pWscUPnPInfo->bUPnPInProgress = FALSE;
+ pWscUPnPInfo->registrarID = 0;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else
+ {
+ if (CurOpMode == AP_MODE)
+ {
+ WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pEntry->apidx, NULL, 0, CurOpMode);
+ WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, CurOpMode);
+ APUpdateBeaconFrame(pAdapter, pEntry->apidx);
+
+ }
+ }
+ NdisZeroMemory(&pAdapter->CommonCfg.WscStaPbcProbeInfo, sizeof(WSC_STA_PBC_PROBE_INFO));
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (INFRA_ON(pAdapter) ||
+ (
+ (pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) &&
+ ((CurOpMode == AP_MODE) || (ADHOC_ON(pAdapter)))
+ )
+ )
+ {
+ pWscControl->WscConfStatus = WSC_SCSTATE_CONFIGURED;
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ {
+ /*
+ Use ApplyProfileIdx to inform WscUpdatePortCfgTimer AP acts registrar.
+ */
+ pWscControl->WscProfile.ApplyProfileIdx |= 0x8000;
+ RTMPSetTimer(&pWscControl->WscUpdatePortCfgTimer, 1000);
+ pWscControl->WscUpdatePortCfgTimerRunning = TRUE;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+#ifdef WSC_LED_SUPPORT
+ /* The protocol is finished. */
+ WPSLEDStatus = LED_WPS_SUCCESS;
+ RTMPSetLED(pAdapter, WPSLEDStatus);
+#endif /* WSC_LED_SUPPORT */
+ {
+ pWscControl->WscPinCode = 0;
+ pWscControl->WscMode = 1;
+ }
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+
+ return;
+ }
+}
+
+VOID WscTimeOutProcess(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN INT nWscState,
+ IN PWSC_CTRL pWscControl)
+{
+ INT WscMode;
+ UCHAR CurOpMode = 0xFF;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif // CONFIG_AP_SUPPORT //
+
+
+ if (nWscState == WSC_STATE_WAIT_ACK)
+ pWscControl->WscState = WSC_STATE_CONFIGURED;
+ else if (nWscState == WSC_STATE_WAIT_RESP_ID)
+ pWscControl->WscState = WSC_STATE_OFF;
+ else if (nWscState == WSC_STATE_RX_M2D)
+ {
+ pWscControl->WscState = WSC_STATE_FAIL;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ {
+ WscSendEapFail(pAd, pWscControl, TRUE);
+ }
+#ifdef APCLI_SUPPORT
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ {
+ WscApCliLinkDown(pAd, pWscControl);
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ pWscControl->EapolTimerRunning = FALSE;
+ pWscControl->WscRetryCount = 0;
+
+
+ return;
+ }
+ else if (nWscState == WSC_STATE_WAIT_EAPFAIL)
+ {
+ pWscControl->WscState = WSC_STATE_OFF;
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ pWscControl->WscConfMode = WSC_DISABLE;
+ }
+ else
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if ((pWscControl->WscActionMode == WSC_PROXY) && (pAd->OpMode == OPMODE_AP))
+ {
+ pWscControl->WscState = WSC_STATE_OFF;
+ }
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ pWscControl->WscState = WSC_STATE_FAIL;
+ }
+
+ if (nWscState == WSC_STATE_WAIT_M8)
+ pWscControl->bWscTrigger = FALSE;
+ pWscControl->WscRetryCount = 0;
+ NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN);
+ pWscControl->EapolTimerRunning = FALSE;
+ if (pWscControl->WscMode == 1)
+ WscMode = DEV_PASS_ID_PIN;
+ else
+ WscMode = DEV_PASS_ID_PBC;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if ((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) &&
+ ((nWscState == WSC_STATE_WAIT_DONE) || (nWscState == WSC_STATE_WAIT_ACK)))
+ {
+ pWscControl->bWscTrigger = FALSE;
+ pWscControl->WscConfStatus = WSC_SCSTATE_CONFIGURED;
+ WscBuildBeaconIE(pAd, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, pWscControl->EntryIfIdx, NULL, 0, CurOpMode);
+ pAd->WriteWscCfgToDatFile = pWscControl->EntryIfIdx;
+ WscWriteConfToPortCfg(pAd,
+ pWscControl,
+ &pWscControl->WscProfile.Profile[0],
+ FALSE);
+ {
+ APStop(pAd);
+ APStartUp(pAd);
+ }
+
+/*#ifdef KTHREAD_SUPPORT */
+/* WAKE_UP(&(pAd->wscTask)); */
+/*#else */
+/* RTMP_SEM_EVENT_UP(&(pAd->wscTask.taskSema)); */
+/*#endif */
+ RtmpOsTaskWakeUp(&(pAd->wscTask));
+ }
+ else
+ {
+ if (pEntry && IS_ENTRY_CLIENT(pEntry))
+ {
+ pEntry->bWscCapable = FALSE;
+ WscSendEapFail(pAd, pWscControl, TRUE);
+ }
+
+ WscBuildBeaconIE(pAd, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, pWscControl->EntryIfIdx, NULL, 0, CurOpMode);
+ }
+#ifdef APCLI_SUPPORT
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ {
+ WscApCliLinkDown(pAd, pWscControl);
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscTimeOutProcess\n"));
+}
+
+VOID WscEAPOLTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PUCHAR WscData = NULL;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+ PWSC_CTRL pWscControl = NULL;
+ PRTMP_ADAPTER pAd = NULL;
+ UINT MaxWscDataLen = WSC_MAX_DATA_LEN;
+ UCHAR CurOpMode = 0xFF;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscEAPOLTimeOutAction\n"));
+
+ if (FunctionContext == 0)
+ {
+ return;
+ }
+ else
+ {
+ pWscControl = (PWSC_CTRL)FunctionContext;
+ pAd = (PRTMP_ADAPTER)pWscControl->pAd;
+ if (pAd == NULL)
+ {
+ return;
+ }
+ pEntry = MacTableLookup(pWscControl->pAd, pWscControl->EntryAddr);
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif // CONFIG_AP_SUPPORT //
+
+
+ if ((CurOpMode == AP_MODE) || ADHOC_ON(pAd))
+ {
+ if (pEntry == NULL)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ /*
+ Some WPS Client will send dis-assoc close to WSC_DONE.
+ If AP misses WSC_DONE, WPS Client still sends dis-assoc to AP.
+ AP driver needs to check wsc_state here for considering WPS process with this client is completed.
+ */
+ if ((CurOpMode == AP_MODE) &&
+ ((pWscControl->WscState == WSC_STATE_WAIT_DONE) || (pWscControl->WscState == WSC_STATE_WAIT_ACK)))
+ {
+ pWscControl->WscStatus = STATUS_WSC_CONFIGURED;
+ pWscControl->bWscTrigger = FALSE;
+ pWscControl->RegData.ReComputePke = 1;
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ BOOLEAN Cancelled;
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled);
+ }
+ WscTimeOutProcess(pAd, NULL, pWscControl->WscState, pWscControl);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ pWscControl->EapolTimerRunning = FALSE;
+ NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("sta is left.\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLTimeOutAction\n"));
+ return;
+ }
+ }
+
+ if (!pWscControl->EapolTimerRunning)
+ {
+ pWscControl->WscRetryCount = 0;
+ goto out;
+ }
+
+ if (pWscControl->EapolTimerPending)
+ {
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ DBGPRINT(RT_DEBUG_TRACE, ("EapolTimer Pending......\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLTimeOutAction\n"));
+ return;
+ }
+
+#ifdef WSC_V2_SUPPORT
+ MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen;
+#endif /* WSC_V2_SUPPORT */
+ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen);
+/* if ((WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC))!= NULL) */
+ if (WscData != NULL)
+ NdisZeroMemory(WscData, WSC_MAX_DATA_LEN);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (pEntry && IS_ENTRY_CLIENT(pEntry) && (pWscControl->WscState <= WSC_STATE_CONFIGURED) && (pWscControl->WscActionMode != WSC_PROXY))
+ {
+ /* A timer in the AP should cause to be disconnected after 5 seconds if a */
+ /* valid EAP-Rsp/Identity indicating WPS is not received. */
+ /* << from WPS EAPoL and RSN handling.doc >> */
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_RESP_ID, pWscControl);
+
+ /* If do disassocation here, it will affect connection of non-WPS clients. */
+ goto out;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscState = %d\n", pWscControl->WscState));
+ switch(pWscControl->WscState)
+ {
+ case WSC_STATE_WAIT_REQ_ID:
+ /* For IWSC case, keep sending EAPOL_START until 2 mins timeout */
+ if ((pWscControl->WscRetryCount >= 2)
+ )
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_REQ_ID, pWscControl);
+ else
+ {
+ pWscControl->WscRetryCount++;
+ WscSendEapolStart(pAd, pEntry->Addr, CurOpMode);
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_WSC_START:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_WSC_START, pWscControl);
+ else
+ {
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_M1:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M1, pWscControl);
+ else
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_START, NULL, 0, pWscControl, AP_MODE, EAP_CODE_REQ);
+#endif /* CONFIG_AP_SUPPORT */
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_SENT_M1:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M2, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_ENROLLEE)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (IS_ENTRY_CLIENT(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+ else if (IS_ENTRY_APCLI(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_RX_M2D:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_RX_M2D, pWscControl);
+ else
+ {
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_PIN:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_PIN, pWscControl);
+ else
+ {
+ pWscControl->WscRetryCount++;
+ DBGPRINT(RT_DEBUG_TRACE, ("No PIN CODE, cannot send M2 out!\n"));
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_M3:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M3, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_REGISTRAR)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_M4:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M4, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_ENROLLEE)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (IS_ENTRY_CLIENT(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+ else if (IS_ENTRY_APCLI(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_M5:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M5, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_REGISTRAR)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_M6:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M6, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_ENROLLEE)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (IS_ENTRY_CLIENT(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+ else if (IS_ENTRY_APCLI(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_M7:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M7, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_REGISTRAR)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_M8:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M8, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_ENROLLEE)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (IS_ENTRY_CLIENT(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+ else if (IS_ENTRY_APCLI(pEntry))
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+ case WSC_STATE_WAIT_DONE:
+ if (pWscControl->WscRetryCount >= 2)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_DONE, pWscControl);
+ else
+ {
+ if (pWscControl->WscActionMode == WSC_REGISTRAR)
+ {
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ);
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ pWscControl->WscRetryCount++;
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT);
+ }
+ break;
+#ifdef CONFIG_AP_SUPPORT
+ /* Only AP_Enrollee needs to wait EAP_ACK */
+ case WSC_STATE_WAIT_ACK:
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_ACK, pWscControl);
+ break;
+#endif /* CONFIG_AP_SUPPORT */
+ case WSC_STATE_WAIT_EAPFAIL:
+ /* Wait 2 seconds */
+ if (pWscControl->WscRetryCount >= 1)
+ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_EAPFAIL, pWscControl);
+ else
+ {
+ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_EAP_FAIL_TIME_OUT);
+ pWscControl->WscRetryCount++;
+ }
+ break;
+ default:
+ break;
+ }
+
+out:
+ if (WscData)
+ os_free_mem(NULL, WscData);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLTimeOutAction\n"));
+}
+
+VOID Wsc2MinsTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ PRTMP_ADAPTER pAd = NULL;
+#ifdef CONFIG_AP_SUPPORT
+ INT IsAPConfigured = 0;
+#endif /* CONFIG_AP_SUPPORT */
+ BOOLEAN Cancelled;
+ UCHAR CurOpMode = 0xFF;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> Wsc2MinsTimeOutAction\n"));
+ if (pWscControl != NULL)
+ {
+ pAd = (PRTMP_ADAPTER)pWscControl->pAd;
+
+ if (pAd == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd is NULL!\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- Wsc2MinsTimeOutAction\n"));
+ return;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wsc2MinsTimerRunning is %s\n",
+ pWscControl->Wsc2MinsTimerRunning ? "TRUE, reset WscState to WSC_STATE_OFF":"FALSE"));
+
+#ifdef WSC_LED_SUPPORT
+ /* 120 seconds WPS walk time expiration. */
+ pWscControl->bWPSWalkTimeExpiration = TRUE;
+#endif /* WSC_LED_SUPPORT */
+
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ pWscControl->bWscTrigger = FALSE;
+ pWscControl->EapolTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ IsAPConfigured = pWscControl->WscConfStatus;
+ if ((pWscControl->EntryIfIdx & 0x0F) < pAd->ApCfg.BssidNum)
+ {
+ WscBuildBeaconIE(pWscControl->pAd, IsAPConfigured, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode);
+ WscBuildProbeRespIE(pWscControl->pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, CurOpMode);
+ APUpdateBeaconFrame(pWscControl->pAd, pWscControl->EntryIfIdx & 0x0F);
+ }
+ if ((pWscControl->WscConfMode & WSC_PROXY) == 0)
+ { /* Proxy mechanism is disabled */
+ pWscControl->WscState = WSC_STATE_OFF;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ pWscControl->WscMode = 1;
+ pWscControl->WscRetryCount = 0;
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+
+ pWscControl->WscSelReg = 0;
+ pWscControl->WscStatus = STATUS_WSC_IDLE;
+
+ RTMPSendWirelessEvent(pAd, IW_WSC_2MINS_TIMEOUT, NULL, (pWscControl->EntryIfIdx & 0x0F), 0);
+
+ if (pWscControl->WscScanTimerRunning)
+ {
+ pWscControl->WscScanTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscScanTimer, &Cancelled);
+ }
+ if (pWscControl->WscPBCTimerRunning)
+ {
+ pWscControl->WscPBCTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled);
+ }
+ }
+
+#ifdef WSC_LED_SUPPORT
+ /* if link is up, there shall be nothing wrong */
+ /* perhaps we will set another flag to do it */
+ if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+ (pWscControl->WscState == WSC_STATE_OFF) &&
+ (pWscControl->WscStatus == STATUS_WSC_CONFIGURED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscConnectTimeout --> Connection OK\n"));
+ }
+ else
+ {
+ UCHAR WPSLEDStatus;
+
+ pWscControl->WscStatus = STATUS_WSC_FAIL;
+ pWscControl->WscState = WSC_STATE_OFF;
+
+ /* WPS LED mode 7, 8, 11 or 12. */
+ if ((LED_MODE(pAd) == WPS_LED_MODE_7) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_8) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_11) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_12))
+ {
+ pWscControl->bSkipWPSTurnOffLED = FALSE;
+
+ /* Turn off the WPS LED modoe due to the maximum WPS processing time is expired (120 seconds). */
+ WPSLEDStatus = LED_WPS_TURN_LED_OFF;
+ RTMPSetLED(pAd, WPSLEDStatus);
+ }
+ else if ((LED_MODE(pAd) == WPS_LED_MODE_9) /* WPS LED mode 9. */
+ )
+ {
+ if (pWscControl->WscMode == WSC_PIN_MODE) /* PIN method. */
+ {
+ /* The NIC using PIN method fails to finish the WPS handshaking within 120 seconds. */
+ WPSLEDStatus = LED_WPS_ERROR;
+ RTMPSetLED(pAd, WPSLEDStatus);
+ /* Turn off the WPS LED after 15 seconds. */
+ RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_FAIL_LED_PATTERN_TIMEOUT);
+
+ /* The Ralink UI would make RT_OID_DISCONNECT_REQUEST request while it receive STATUS_WSC_EAP_FAILED. */
+ /* Allow the NIC to turn off the WPS LED after WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT seconds. */
+ pWscControl->bSkipWPSTurnOffLED = TRUE;
+ RTMPSetTimer(&pWscControl->WscSkipTurnOffLEDTimer, WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: The NIC using PIN method fails to finish the WPS handshaking within 120 seconds.\n", __FUNCTION__));
+ }
+ else if (pWscControl->WscMode == WSC_PBC_MODE) /* PBC method. */
+ {
+ switch (pWscControl->WscLastWarningLEDMode) /* Based on last WPS warning LED mode. */
+ {
+ case 0:
+ case LED_WPS_ERROR:
+ case LED_WPS_SESSION_OVERLAP_DETECTED:
+ /* Failed to find any partner. */
+ WPSLEDStatus = LED_WPS_ERROR;
+ RTMPSetLED(pAd, WPSLEDStatus);
+
+ /* Turn off the WPS LED after 15 seconds. */
+ RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_FAIL_LED_PATTERN_TIMEOUT);
+
+ /* The Ralink UI would make RT_OID_DISCONNECT_REQUEST request while it receive STATUS_WSC_EAP_FAILED. */
+ /* Allow the NIC to turn off the WPS LED after WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT seconds. */
+ pWscControl->bSkipWPSTurnOffLED = TRUE;
+ RTMPSetTimer(&pWscControl->WscSkipTurnOffLEDTimer, WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Last WPS LED status is LED_WPS_ERROR.\n", __FUNCTION__));
+ break;
+
+ default:
+ /* do nothing. */
+ break;
+ }
+ }
+ else
+ {
+ /* do nothing. */
+ }
+ }
+ else
+ {
+ /* do nothing. */
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscConnectTimeout --> Fail to connect\n"));
+ }
+#endif /* WSC_LED_SUPPORT */
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- Wsc2MinsTimeOutAction\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Classify EAP message type for enrolee
+
+ Arguments:
+ pAd - NIC Adapter pointer
+ Elem - The EAP packet
+
+ Return Value:
+ Received EAP message type
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+UCHAR WscRxMsgType(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PMLME_QUEUE_ELEM pElem)
+{
+ USHORT Length;
+ PUCHAR pData;
+ USHORT WscType, WscLen;
+ STRING id_data[] = {"hello"};
+ STRING fail_data[] = {"EAP_FAIL"};
+ STRING wsc_start[] = {"WSC_START"};
+#ifdef WSC_V2_SUPPORT
+ STRING wsc_frag_ack[] = "WSC_FRAG_ACK";
+#endif /* WSC_V2_SUPPORT */
+ STRING regIdentity[] = {"WFA-SimpleConfig-Registrar"};
+ STRING enrIdentity[] = {"WFA-SimpleConfig-Enrollee"};
+
+ if (pElem->Msg[0] == 'W' && pElem->Msg[1] == 'F' && pElem->Msg[2] == 'A')
+ {
+ /* Eap-Rsp(Identity) */
+ if (memcmp(regIdentity, pElem->Msg, strlen(regIdentity)) == 0)
+ return WSC_MSG_EAP_REG_RSP_ID;
+ else if (memcmp(enrIdentity, pElem->Msg, strlen(enrIdentity)) == 0)
+ return WSC_MSG_EAP_ENR_RSP_ID;
+ }
+ else if (NdisEqualMemory(id_data, pElem->Msg, pElem->MsgLen))
+ {
+ /* Eap-Req/Identity(hello) */
+ return WSC_MSG_EAP_REQ_ID;
+ }
+ else if (NdisEqualMemory(fail_data, pElem->Msg, pElem->MsgLen))
+ {
+ /* Eap-Fail */
+ return WSC_MSG_EAP_FAIL;
+ }
+ else if (NdisEqualMemory(wsc_start, pElem->Msg, pElem->MsgLen))
+ {
+ /* Eap-Req(Wsc_Start) */
+ return WSC_MSG_EAP_REQ_START;
+ }
+#ifdef WSC_V2_SUPPORT
+ else if (NdisEqualMemory(wsc_frag_ack, pElem->Msg, pElem->MsgLen))
+ {
+ /* WSC FRAG ACK */
+ return WSC_MSG_EAP_FRAG_ACK;
+ }
+#endif /* WSC_V2_SUPPORT */
+ else
+ { /* Eap-Esp(Messages) */
+ pData = pElem->Msg;
+ Length = (USHORT)pElem->MsgLen;
+
+ /* the first TLV item in EAP Messages must be WSC_IE_VERSION */
+ NdisMoveMemory(&WscType, pData, 2);
+ if (ntohs(WscType) != WSC_ID_VERSION)
+ goto out;
+
+ /* Not Wsc Start, We have to look for WSC_IE_MSG_TYPE to classify M2 ~ M8, the remain size must large than 4 */
+ while (Length > 4)
+ {
+ /* arm-cpu has packet alignment issue, it's better to use memcpy to retrieve data */
+ NdisMoveMemory(&WscType, pData, 2);
+ NdisMoveMemory(&WscLen, pData + 2, 2);
+ WscLen = ntohs(WscLen);
+ if (ntohs(WscType) == WSC_ID_MSG_TYPE)
+ {
+ return(*(pData + 4)); /* Found the message type */
+ }
+ else
+ {
+ pData += (WscLen + 4);
+ Length -= (WscLen + 4);
+ }
+ }
+ }
+
+out:
+ return WSC_MSG_UNKNOWN;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Classify WSC 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
+
+ Note:
+ All these constants are defined in wsc.h
+ For supplicant, there is only EAPOL Key message avaliable
+
+ ========================================================================
+*/
+BOOLEAN WscMsgTypeSubst(
+ IN UCHAR EAPType,
+ IN UCHAR EAPCode,
+ OUT INT *MsgType)
+{
+ switch (EAPType)
+ {
+ case EAPPacket:
+ *MsgType = WSC_EAPOL_PACKET_MSG;
+ break;
+ case EAPOLStart:
+ *MsgType = WSC_EAPOL_START_MSG;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscMsgTypeSubst : unsupported EAP Type(%d); \n", EAPType));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+VOID WscInitRegistrarPair(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN UCHAR apidx)
+{
+ UCHAR CurOpMode = 0xff;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscInitRegistrarPair\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif // CONFIG_AP_SUPPORT //
+
+
+ pWscControl->WscActionMode = 0;
+
+ /* 1. Version */
+ /*pWscControl->RegData.SelfInfo.Version = WSC_VERSION; */
+
+ /* 2. UUID Enrollee, last 6 bytes use MAC */
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.Uuid[0], &pWscControl->Wsc_Uuid_E[0], UUID_LEN_HEX);
+
+ /* 3. MAC address */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (apidx >= HW_BEACON_MAX_NUM)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("%s: apidx >= HW_BEACON_MAX_NUM!\n", __FUNCTION__));
+ apidx = 0;
+ }
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr, pAdapter->ApCfg.MBSSID[apidx].Bssid, 6);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 4. Device Name */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (!RTMP_TEST_FLAG(pWscControl, 0x04))
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.DeviceName, AP_WSC_DEVICE_NAME, sizeof(AP_WSC_DEVICE_NAME));
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* 5. Manufacture woody */
+ if (!RTMP_TEST_FLAG(pWscControl, 0x01))
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.Manufacturer, WSC_MANUFACTURE, sizeof(WSC_MANUFACTURE));
+
+ /* 6. Model Name */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (!RTMP_TEST_FLAG(pWscControl, 0x02))
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.ModelName, AP_WSC_MODEL_NAME, sizeof(AP_WSC_MODEL_NAME));
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* 7. Model Number */
+
+ if (!RTMP_TEST_FLAG(pWscControl, 0x08))
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.ModelNumber, WSC_MODEL_NUMBER, sizeof(WSC_MODEL_NUMBER));
+
+ /* 8. Serial Number */
+ if (!RTMP_TEST_FLAG(pWscControl, 0x10))
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.SerialNumber, WSC_MODEL_SERIAL, sizeof(WSC_MODEL_SERIAL));
+
+ /* 9. Authentication Type Flags */
+ /* Open(=1), WPAPSK(=2),Shared(=4), WPA2PSK(=20),WPA(=8),WPA2(=10) */
+ /* (0x01 | 0x02 | 0x04 | 0x20 | 0x08 | 0x10) = 0x3F */
+ /* WCN vista logo will check this flags. */
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ /*
+ AuthTypeFlags only needs to include Open and WPA2PSK in WSC 2.0.
+ */
+ pWscControl->RegData.SelfInfo.AuthTypeFlags = cpu2be16(0x0021);
+ else
+#endif /* WSC_V2_SUPPORT */
+ pWscControl->RegData.SelfInfo.AuthTypeFlags = cpu2be16(0x003F);
+
+ /* 10. Encryption Type Flags */
+ /* None(=1), WEP(=2), TKIP(=4), AES(=8) */
+ /* (0x01 | 0x02 | 0x04 | 0x08) = 0x0F */
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ /*
+ EncrTypeFlags only needs to include None and AES in WSC 2.0.
+ */
+ pWscControl->RegData.SelfInfo.EncrTypeFlags = cpu2be16(0x0009);
+ else
+#endif /* WSC_V2_SUPPORT */
+ pWscControl->RegData.SelfInfo.EncrTypeFlags = cpu2be16(0x000F);
+
+ /* 11. Connection Type Flag */
+ pWscControl->RegData.SelfInfo.ConnTypeFlags = 0x01; /* ESS */
+
+ /* 12. Associate state */
+ pWscControl->RegData.SelfInfo.AssocState = cpu2be16(0x0000); /* Not associated */
+
+ /* 13. Configure Error */
+ pWscControl->RegData.SelfInfo.ConfigError = cpu2be16(0x0000); /* No error */
+
+ /* 14. OS Version */
+ pWscControl->RegData.SelfInfo.OsVersion = cpu2be32(0x80000000); /* first bit must be 1 */
+
+ /* 15. RF Band */
+ /* Some WPS AP would check RfBand value in M1, ex. D-Link DIR-628 */
+ pWscControl->RegData.SelfInfo.RfBand = 0x00;
+ if (WMODE_CAP_5G(pAdapter->CommonCfg.PhyMode))
+ pWscControl->RegData.SelfInfo.RfBand |= WSC_RFBAND_50GHZ; /* 5.0G */
+
+ if (WMODE_CAP_2G(pAdapter->CommonCfg.PhyMode))
+ pWscControl->RegData.SelfInfo.RfBand |= WSC_RFBAND_24GHZ; /* 2.4G */
+
+ /* 16. Config Method */
+ pWscControl->RegData.SelfInfo.ConfigMethods = cpu2be16(pWscControl->WscConfigMethods);
+ /*pWscControl->RegData.EnrolleeInfo.ConfigMethods = cpu2be16(WSC_CONFIG_METHODS); // Label, Display, PBC */
+ /*pWscControl->RegData.EnrolleeInfo.ConfigMethods = cpu2be16(0x0084); // Label, Display, PBC */
+
+ /* 17. Simple Config State */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pWscControl->RegData.SelfInfo.ScState = pWscControl->WscConfStatus;
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 18. Device Password ID */
+ if (pWscControl->WscMode == WSC_PIN_MODE)
+ {
+ pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_PIN); /* PIN mode */
+ }
+ else
+ {
+ pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_PBC); /* PBC */
+ }
+
+ /* 19. SSID */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.Ssid, pAdapter->ApCfg.MBSSID[apidx].Ssid, pAdapter->ApCfg.MBSSID[apidx].SsidLen);
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 20. Primary Device Type */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_APCLI)
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.PriDeviceType, &STA_Wsc_Pri_Dev_Type[0], 8);
+ else
+ NdisMoveMemory(&pWscControl->RegData.SelfInfo.PriDeviceType, &AP_Wsc_Pri_Dev_Type[0], 8);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscInitRegistrarPair\n"));
+}
+
+VOID WscSendEapReqId(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR CurOpMode)
+{
+ UCHAR Header802_3[14];
+ USHORT Length;
+ IEEE8021X_FRAME Ieee_8021x;
+ EAP_FRAME EapFrame;
+ UCHAR *pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ UCHAR Data[] = "hello";
+ UCHAR Id;
+ PWSC_CTRL pWpsCtrl = NULL;
+
+ NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);
+
+ /* 1. Send EAP-Rsp Id */
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapReqId\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ pWpsCtrl = &pAd->ApCfg.MBSSID[pEntry->apidx].WscControl;
+ MAKE_802_3_HEADER(Header802_3,
+ &pEntry->Addr[0],
+ &pAd->ApCfg.MBSSID[pEntry->apidx].Bssid[0],
+ EAPOL);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (pWpsCtrl == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pWpsCtrl == NULL!\n"));
+ return;
+ }
+
+ /* Length, -1 NULL pointer of string */
+ Length = sizeof(EAP_FRAME) + sizeof(Data) - 1;
+
+ /* Zero 802.1x body */
+ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x));
+ Ieee_8021x.Version = EAPOL_VER;
+ Ieee_8021x.Type = EAPPacket;
+ Ieee_8021x.Length = cpu2be16(Length);
+
+ /* Zero EAP frame */
+ NdisZeroMemory(&EapFrame, sizeof(EapFrame));
+ /* RFC 3748 Ch 4.1: recommended to initalize Identifier with a
+ * random number */
+ Id = RandomByte(pAd);
+ if (Id == pWpsCtrl->lastId)
+ Id += 1;
+ EapFrame.Code = EAP_CODE_REQ;
+ EapFrame.Id = Id;
+ EapFrame.Length = cpu2be16(Length);
+ EapFrame.Type = EAP_TYPE_ID;
+ pWpsCtrl->lastId = Id;
+
+ /* Out buffer for transmitting EAP-Req(Identity) */
+/* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
+ if(pOutBuffer == NULL)
+ return;
+
+ FrameLen = 0;
+
+ /* Make Transmitting frame */
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(IEEE8021X_FRAME), &Ieee_8021x,
+ sizeof(EapFrame), &EapFrame,
+ (sizeof(Data) - 1), Data,
+ END_OF_ARGS);
+
+ /* Copy frame to Tx ring */
+ RTMPToWirelessSta(pAd, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE);
+
+ pWpsCtrl->WscRetryCount = 0;
+ if (pOutBuffer)
+/* kfree(pOutBuffer); */
+ os_free_mem(NULL, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapReqId\n"));
+}
+
+/*
+ ========================================================================
+
+ 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 WscSendEapolStart(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pBssid,
+ IN UCHAR CurOpMode)
+{
+ IEEE8021X_FRAME Packet;
+ UCHAR Header802_3[14];
+ MAC_TABLE_ENTRY *pEntry;
+
+ pEntry = MacTableLookup(pAdapter, pBssid);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapolStart\n"));
+
+ NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);
+
+ /* 1. Change the authentication to open and encryption to none if necessary. */
+
+ /* init 802.3 header and Fill Packet */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ MAKE_802_3_HEADER(Header802_3,
+ pBssid,
+ &pAdapter->ApCfg.ApCliTab[0].CurrentAddress[0],
+ EAPOL);
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* Zero message 2 body */
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.Version = EAPOL_VER;
+ Packet.Type = EAPOLStart;
+ Packet.Length = cpu2be16(0);
+
+ if (pEntry)
+ RTMPToWirelessSta(pAdapter, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)&Packet, 4, TRUE);
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ /* Update WSC status */
+ pAdapter->ApCfg.ApCliTab[0].WscControl.WscStatus = STATUS_WSC_EAPOL_START_SENT;
+ pAdapter->ApCfg.ApCliTab[0].WscControl.WscState = WSC_STATE_WAIT_REQ_ID;
+ if (!pAdapter->ApCfg.ApCliTab[0].WscControl.EapolTimerRunning)
+ {
+ pAdapter->ApCfg.ApCliTab[0].WscControl.EapolTimerRunning = TRUE;
+ RTMPSetTimer(&pAdapter->ApCfg.ApCliTab[0].WscControl.EapolTimer, WSC_EAPOL_START_TIME_OUT);
+ }
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapolStart\n"));
+}
+
+VOID WscSendEapRspId(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PWSC_CTRL pWscControl)
+{
+ UCHAR Header802_3[14];
+ USHORT Length = 0;
+ IEEE8021X_FRAME Ieee_8021x;
+ EAP_FRAME EapFrame;
+ UCHAR *pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ UCHAR regIdentity[] = "WFA-SimpleConfig-Registrar-1-0";
+ UCHAR enrIdentity[] = "WFA-SimpleConfig-Enrollee-1-0";
+ UCHAR CurOpMode = 0xff;
+
+ NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);
+
+ /* 1. Send EAP-Rsp Id */
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapRspId\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ MAKE_802_3_HEADER(Header802_3,
+ &pEntry->Addr[0],
+ &pAdapter->ApCfg.ApCliTab[0].CurrentAddress[0],
+ EAPOL);
+ Length = sizeof(EAP_FRAME) + sizeof(enrIdentity) - 1;
+ pWscControl->WscConfMode = WSC_ENROLLEE; /* Ap Client only support Enrollee now. 20070518 */
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* Zero 802.1x body */
+ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x));
+ Ieee_8021x.Version = EAPOL_VER;
+ Ieee_8021x.Type = EAPPacket;
+ Ieee_8021x.Length = cpu2be16(Length);
+
+ /* Zero EAP frame */
+ NdisZeroMemory(&EapFrame, sizeof(EapFrame));
+ EapFrame.Code = EAP_CODE_RSP;
+ EapFrame.Id = pWscControl->lastId;
+ EapFrame.Length = cpu2be16(Length);
+ EapFrame.Type = EAP_TYPE_ID;
+
+ /* Out buffer for transmitting EAP-Req(Identity) */
+/* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
+ if(pOutBuffer == NULL)
+ return;
+
+ FrameLen = 0;
+
+ if (pWscControl->WscConfMode == WSC_REGISTRAR)
+ {
+ /* Make Transmitting frame */
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(IEEE8021X_FRAME), &Ieee_8021x,
+ sizeof(EapFrame), &EapFrame,
+ (sizeof(regIdentity) - 1), regIdentity,
+ END_OF_ARGS);
+ }
+ else if (pWscControl->WscConfMode == WSC_ENROLLEE)
+ {
+ /* Make Transmitting frame */
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(IEEE8021X_FRAME), &Ieee_8021x,
+ sizeof(EapFrame), &EapFrame,
+ (sizeof(enrIdentity) - 1), enrIdentity,
+ END_OF_ARGS);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscConfMode(%d) is not WSC_REGISTRAR nor WSC_ENROLLEE.\n", pWscControl->WscConfMode));
+ goto out;
+ }
+
+ /* Copy frame to Tx ring */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ RTMPToWirelessSta(pAdapter, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE);
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ pWscControl->WscRetryCount = 0;
+ if (!pWscControl->EapolTimerRunning)
+ {
+ pWscControl->EapolTimerRunning = TRUE;
+ RTMPSetTimer(&pWscControl->EapolTimer, WSC_EAP_ID_TIME_OUT);
+ }
+out:
+ if (pOutBuffer)
+/* kfree(pOutBuffer); */
+ os_free_mem(NULL, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapRspId\n"));
+}
+
+VOID WscUPnPErrHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN UINT eventID)
+{
+ int dataLen;
+ UCHAR *pWscData;
+ UCHAR CurOpMode;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Into WscUPnPErrHandle, send WSC_OPCODE_UPNP_CTRL with eventID=0x%x!\n", eventID));
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif // CONFIG_AP_SUPPORT //
+
+
+ os_alloc_mem(NULL, (UCHAR **)&pWscData, WSC_MAX_DATA_LEN);
+ if (pWscData != NULL)
+ {
+ NdisZeroMemory(pWscData, WSC_MAX_DATA_LEN);
+
+ dataLen = BuildMessageNACK(pAd, pWscControl, pWscData);
+ WscSendUPnPMessage(pAd, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_NORMAL,
+ pWscData, dataLen, eventID, 0, NULL, CurOpMode);
+
+ os_free_mem(NULL, pWscData);
+ }
+ else
+ {
+ WscSendUPnPMessage(pAd, (pWscControl->EntryIfIdx & 0x0F),
+ WSC_OPCODE_UPNP_CTRL, 0, NULL, 0, eventID, 0, NULL, CurOpMode);
+ }
+}
+
+/*
+ Format of iwcustom msg WSC clientJoin message:
+ 1. SSID which station want to probe(32 bytes):
+ <SSID string>
+ *If the length if SSID string is small than 32 bytes, fill 0x0 for remaining bytes.
+ 2. sender MAC address(6 bytes):
+ 3. Status:
+ Set as 1 means change APStatus as 1.
+ Set as 2 means change STAStatus as 1.
+ Set as 3 means trigger msg.
+
+ 32 6 1
+ +----------+--------+------+
+ |SSIDString| SrcMAC |Status|
+*/
+int WscSendUPnPConfReqMsg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apIdx,
+ IN PUCHAR ssidStr,
+ IN PUCHAR macAddr,
+ IN INT Status,
+ IN UINT eventID,
+ IN UCHAR CurOpMode)
+{
+ UCHAR pData[39] = {0};
+
+
+ strncpy((PSTRING) pData, (PSTRING)ssidStr, strlen((PSTRING) ssidStr));
+ NdisMoveMemory(&pData[32], macAddr, MAC_ADDR_LEN);
+ pData[38] = Status;
+ WscSendUPnPMessage(pAd, apIdx, WSC_OPCODE_UPNP_MGMT, WSC_UPNP_MGMT_SUB_CONFIG_REQ,
+ &pData[0], 39, eventID, 0, NULL, CurOpMode);
+
+ return 0;
+}
+
+
+/*
+ NETLINK tunnel msg format send to WSCUPnP handler in user space:
+ 1. Signature of following string(Not include the quote, 8 bytes)
+ "RAWSCMSG"
+ 2. eID: eventID (4 bytes)
+ the ID of this message(4 bytes)
+ 3. aID: ackID (4 bytes)
+ means that which event ID this mesage was response to.
+ 4. TL: Message Total Length (4 bytes)
+ Total length of this message.
+ 5. F: Flag (2 bytes)
+ used to notify some specific character of this msg segment.
+ Bit 1: fragment
+ set as 1 if netlink layer have more segment of this Msg need to send.
+ Bit 2~15: reserve, should set as 0 now.
+ 5. SL: Segment Length(2 bytes)
+ msg actual length in this segment, The SL may not equal the "TL" field if "F" ==1
+ 6. devMac: device mac address(6 bytes)
+ Indicate the netdevice which this msg belong. For the wscd in user space will
+ depends this address dispatch the msg to correct UPnP Device instance to handle it.
+ 7. "WSC_MSG" info:
+
+ 8 4 4 4 2 2 6 variable length(MAXIMUM=232)
+ +------------+----+----+----+--+--+------+------------------------+
+ | Signature |eID |aID | TL | F | SL|devMac| WSC_MSG |
+
+*/
+int WscSendUPnPMessage(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR devIfIdx,
+ IN USHORT msgType,
+ IN USHORT msgSubType,
+ IN PUCHAR pData,
+ IN INT dataLen,
+ IN UINT eventID,
+ IN UINT toIPAddr,
+ IN PUCHAR pMACAddr,
+ IN UCHAR CurOpMode)
+{
+/* union iwreq_data wrqu; */
+ RTMP_WSC_NLMSG_HDR *pNLMsgHdr;
+ RTMP_WSC_MSG_HDR *pWscMsgHdr;
+
+ UCHAR hdrBuf[42]; /*RTMP_WSC_NLMSG_HDR_LEN + RTMP_WSC_MSG_HDR_LEN */
+ int totalLen, leftLen, copyLen;
+ PUCHAR pBuf = NULL, pBufPtr = NULL, pPos = NULL;
+ PUCHAR pDevAddr = NULL;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR bssIdx = devIfIdx;
+#endif /* CONFIG_AP_SUPPORT */
+ ULONG Now;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendUPnPMessage\n"));
+
+ if ((msgType & WSC_OPCODE_UPNP_MASK) != WSC_OPCODE_UPNP_MASK)
+ return FALSE;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+#ifdef APCLI_SUPPORT
+ if (devIfIdx & MIN_NET_DEVICE_FOR_APCLI)
+ {
+ bssIdx &= (~MIN_NET_DEVICE_FOR_APCLI);
+ if (bssIdx >= MAX_APCLI_NUM)
+ return FALSE;
+ pDevAddr = &pAd->ApCfg.ApCliTab[bssIdx].CurrentAddress[0];
+ }
+ else
+#endif /* APCLI_SUPPORT */
+ pDevAddr = &pAd->ApCfg.MBSSID[bssIdx].Bssid[0];
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (pDevAddr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pDevAddr == NULL!\n"));
+ return FALSE;
+ }
+
+ /*Prepare the NLMsg header */
+ memset(hdrBuf, 0, sizeof(hdrBuf));
+ pNLMsgHdr = (RTMP_WSC_NLMSG_HDR *)hdrBuf;
+ memcpy(pNLMsgHdr, WSC_MSG_SIGNATURE, RTMP_WSC_NLMSG_SIGNATURE_LEN);
+
+ NdisGetSystemUpTime(&Now);
+ pNLMsgHdr->envID = Now;
+ pNLMsgHdr->ackID = eventID;
+ pNLMsgHdr->msgLen = dataLen + RTMP_WSC_MSG_HDR_LEN;
+
+ /*
+ In order to support multiple wscd, we need this new field to notify
+ the wscd which interface this msg send from.
+ */
+ NdisMoveMemory(&pNLMsgHdr->devAddr[0], pDevAddr, MAC_ADDR_LEN);
+
+ /*Prepare the WscMsg header */
+ pWscMsgHdr = (RTMP_WSC_MSG_HDR *)(hdrBuf + sizeof(RTMP_WSC_NLMSG_HDR));
+ switch(msgType)
+ {
+ case WSC_OPCODE_UPNP_DATA:
+ pWscMsgHdr->msgType = WSC_OPCODE_UPNP_DATA;
+ break;
+ case WSC_OPCODE_UPNP_MGMT:
+ pWscMsgHdr->msgType = WSC_OPCODE_UPNP_MGMT;
+ break;
+ case WSC_OPCODE_UPNP_CTRL:
+ pWscMsgHdr->msgType = WSC_OPCODE_UPNP_CTRL;
+ break;
+ default:
+ return FALSE;
+ }
+ pWscMsgHdr->msgSubType = msgSubType;
+ pWscMsgHdr->ipAddr = toIPAddr;
+ pWscMsgHdr->msgLen = dataLen;
+
+ if ((pWscMsgHdr->msgType == WSC_OPCODE_UPNP_DATA) &&
+ (eventID == 0) &&
+ (pMACAddr != NULL) &&
+ (NdisEqualMemory(pMACAddr, ZERO_MAC_ADDR, MAC_ADDR_LEN) == FALSE))
+ {
+ pWscMsgHdr->msgSubType |= WSC_UPNP_DATA_SUB_INCLUDE_MAC;
+ pNLMsgHdr->msgLen += MAC_ADDR_LEN;
+ pWscMsgHdr->msgLen += MAC_ADDR_LEN;
+ }
+
+ /*Allocate memory and copy the msg. */
+ totalLen = leftLen = pNLMsgHdr->msgLen;
+ pPos = pData;
+ os_alloc_mem(NULL, (UCHAR **)&pBuf, IWEVCUSTOM_MSG_MAX_LEN);
+/* if((pBuf = kmalloc(IWEVCUSTOM_MSG_MAX_LEN, GFP_ATOMIC)) != NULL) */
+ if (pBuf != NULL)
+ {
+ int firstSeg = 1;
+
+ while(leftLen)
+ {
+ /*Prepare the payload */
+ memset(pBuf, 0, IWEVCUSTOM_MSG_MAX_LEN);
+
+ pNLMsgHdr->segLen = (leftLen > IWEVCUSTOM_PAYLOD_MAX_LEN ? IWEVCUSTOM_PAYLOD_MAX_LEN : leftLen);
+ leftLen -= pNLMsgHdr->segLen;
+ pNLMsgHdr->flags = (leftLen > 0 ? 1 : 0);
+
+ memcpy(pBuf, pNLMsgHdr, RTMP_WSC_NLMSG_HDR_LEN);
+ pBufPtr = &pBuf[RTMP_WSC_NLMSG_HDR_LEN];
+
+ if(firstSeg){
+ memcpy(pBufPtr, pWscMsgHdr, RTMP_WSC_MSG_HDR_LEN);
+ pBufPtr += RTMP_WSC_MSG_HDR_LEN;
+ copyLen = (pNLMsgHdr->segLen - RTMP_WSC_MSG_HDR_LEN);
+ if ((pWscMsgHdr->msgSubType & WSC_UPNP_DATA_SUB_INCLUDE_MAC) == WSC_UPNP_DATA_SUB_INCLUDE_MAC)
+ {
+ NdisMoveMemory(pBufPtr, pMACAddr, MAC_ADDR_LEN);
+ pBufPtr += MAC_ADDR_LEN;
+ copyLen -= MAC_ADDR_LEN;
+ }
+ NdisMoveMemory(pBufPtr, pPos, copyLen);
+ pPos += copyLen;
+ firstSeg = 0;
+ } else {
+ NdisMoveMemory(pBufPtr, pPos, pNLMsgHdr->segLen);
+ pPos += pNLMsgHdr->segLen;
+ }
+
+ /*Send WSC Msg to wscd, msg length = pNLMsgHdr->segLen + sizeof(RTMP_WSC_NLMSG_HDR) */
+ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_WSC_UPNP_EVENT_FLAG, NULL, pBuf, pNLMsgHdr->segLen + sizeof(RTMP_WSC_NLMSG_HDR));
+ }
+
+/* kfree(pBuf); */
+ os_free_mem(NULL, pBuf);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendUPnPMessage\n"));
+ return TRUE;
+}
+
+
+VOID WscSendMessage(
+ IN PRTMP_ADAPTER pAdapter,
+ IN UCHAR OpCode,
+ IN PUCHAR pData,
+ IN INT Len,
+ IN PWSC_CTRL pWscControl,
+ IN UCHAR OpMode,
+ IN UCHAR EapType)
+{
+ /* Inb-EAP Message */
+ UCHAR Header802_3[14];
+ USHORT Length, MsgLen;
+ IEEE8021X_FRAME Ieee_8021x;
+ EAP_FRAME EapFrame;
+ WSC_FRAME WscFrame;
+ UCHAR *pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ MAC_TABLE_ENTRY *pEntry;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR bssIdx = (pWscControl->EntryIfIdx & 0x0F);
+#endif /* CONFIG_AP_SUPPORT */
+ UCHAR CurOpMode = 0xFF;
+
+ if ((Len <= 0) && (OpCode != WSC_OPCODE_START) && (OpCode != WSC_OPCODE_FRAG_ACK))
+ return;
+
+ /* Send message */
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendMessage\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+ NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (OpMode == AP_MODE)
+ {
+ MAKE_802_3_HEADER(Header802_3, &pWscControl->EntryAddr[0], &pAdapter->ApCfg.MBSSID[bssIdx].Bssid[0], EAPOL);
+ }
+#ifdef APCLI_SUPPORT
+ else if (OpMode == AP_CLIENT_MODE)
+ {
+ MAKE_802_3_HEADER(Header802_3, &pWscControl->EntryAddr[0], &pAdapter->ApCfg.ApCliTab[0].CurrentAddress[0], EAPOL);
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* Length = EAP + WSC_Frame + Payload */
+ Length = sizeof(EAP_FRAME) + sizeof(WSC_FRAME) + Len;
+
+ if (pWscControl->bWscFragment && (pWscControl->bWscFirstOne))
+ {
+ Length += 2;
+ MsgLen = pWscControl->WscTxBufLen + Len;
+ MsgLen = htons(MsgLen);
+ }
+
+ /* Zero 802.1x body */
+ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x));
+ Ieee_8021x.Version = EAPOL_VER;
+ Ieee_8021x.Type = EAPPacket;
+ Ieee_8021x.Length = cpu2be16(Length);
+
+ /* Zero EAP frame */
+ NdisZeroMemory(&EapFrame, sizeof(EapFrame));
+
+ if (EapType == EAP_CODE_REQ)
+ {
+ EapFrame.Code = EAP_CODE_REQ;
+ EapFrame.Id = ++(pWscControl->lastId);
+ }
+ else
+ {
+ EapFrame.Code = EAP_CODE_RSP;
+ EapFrame.Id = pWscControl->lastId; /* same as eap_req id */
+ }
+
+ EapFrame.Length = cpu2be16(Length);
+ EapFrame.Type = EAP_TYPE_WSC;
+
+ /* Zero WSC Frame */
+ NdisZeroMemory(&WscFrame, sizeof(WscFrame));
+ WscFrame.SMI[0] = 0x00;
+ WscFrame.SMI[1] = 0x37;
+ WscFrame.SMI[2] = 0x2A;
+ WscFrame.VendorType = cpu2be32(WSC_VENDOR_TYPE);
+ WscFrame.OpCode = OpCode;
+ WscFrame.Flags = 0x00;
+ if (pWscControl->bWscFragment && (pWscControl->bWscLastOne == FALSE))
+ WscFrame.Flags |= WSC_MSG_FLAG_MF;
+
+ if (pWscControl->bWscFragment && (pWscControl->bWscFirstOne))
+ {
+ WscFrame.Flags |= WSC_MSG_FLAG_LF;
+ }
+
+ /* Out buffer for transmitting message */
+ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
+ if(pOutBuffer == NULL)
+ return;
+
+ FrameLen = 0;
+
+ /* Make Transmitting frame */
+ if (pData && (Len > 0))
+ {
+ if (pWscControl->bWscFragment && (pWscControl->bWscFirstOne))
+ {
+ UCHAR LF_Len = 2;
+ ULONG TmpLen = 0;
+
+ pWscControl->bWscFirstOne = FALSE;
+ MakeOutgoingFrame(pOutBuffer, &TmpLen,
+ sizeof(IEEE8021X_FRAME), &Ieee_8021x,
+ sizeof(EapFrame), &EapFrame,
+ sizeof(WscFrame), &WscFrame,
+ LF_Len, &MsgLen,
+ END_OF_ARGS);
+
+ FrameLen += TmpLen;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ Len, pData,
+ END_OF_ARGS);
+
+ FrameLen += TmpLen;
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(IEEE8021X_FRAME), &Ieee_8021x,
+ sizeof(EapFrame), &EapFrame,
+ sizeof(WscFrame), &WscFrame,
+ Len, pData,
+ END_OF_ARGS);
+ }
+ }
+ else
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(IEEE8021X_FRAME), &Ieee_8021x,
+ sizeof(EapFrame), &EapFrame,
+ sizeof(WscFrame), &WscFrame,
+ END_OF_ARGS);
+
+ /* Copy frame to Tx ring */
+ pEntry = MacTableLookup(pAdapter, &pWscControl->EntryAddr[0]);
+
+ if (pEntry)
+ RTMPToWirelessSta(pAdapter, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE);
+ else
+ DBGPRINT(RT_DEBUG_WARN, ("pEntry is NULL\n"));
+
+ if (pOutBuffer)
+ os_free_mem(NULL, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendMessage\n"));
+}
+
+VOID WscBuildBeaconIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR b_configured,
+ IN BOOLEAN b_selRegistrar,
+ IN USHORT devPwdId,
+ IN USHORT selRegCfgMethods,
+ IN UCHAR apidx,
+ IN UCHAR *pAuthorizedMACs,
+ IN UCHAR AuthorizedMACsLen,
+ IN UCHAR CurOpMode)
+{
+ WSC_IE_HEADER ieHdr;
+/* UCHAR Data[256]; */
+ UCHAR *Data = NULL;
+ PUCHAR pData;
+ INT Len = 0, templen = 0;
+ USHORT tempVal = 0;
+ PWSC_CTRL pWpsCtrl = NULL;
+ PWSC_REG_DATA pReg = NULL;
+
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&Data, 256);
+ if (Data == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pWpsCtrl = &pAd->ApCfg.MBSSID[apidx & 0x0F].WscControl;
+#endif /* CONFIG_AP_SUPPORT */
+
+ pReg = &pWpsCtrl->RegData;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscBuildBeaconIE\n"));
+ /* WSC IE HEader */
+ ieHdr.elemId = 221;
+ ieHdr.length = 4;
+ ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2;
+ ieHdr.oui[3] = 0x04;
+
+ pData = (PUCHAR) &Data[0];
+ Len = 0;
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Simple Config State */
+ templen = AppendWSCTLV(WSC_ID_SC_STATE, pData, (UINT8 *)&b_configured, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((CurOpMode == AP_MODE) && pWpsCtrl->bSetupLock)
+ {
+ // AP Setup Lock
+ templen = AppendWSCTLV(WSC_ID_AP_SETUP_LOCKED, pData, (UINT8 *)&pWpsCtrl->bSetupLock, 0);
+ pData += templen;
+ Len += templen;
+ }
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ if ( b_selRegistrar )
+ {
+ /* 3.Selected Registrar */
+ templen = AppendWSCTLV(WSC_ID_SEL_REGISTRAR, pData, (UINT8 *)&b_selRegistrar, 0);
+ pData += templen;
+ Len += templen;
+
+ /*4. Device Password ID */
+ tempVal = htons(devPwdId);
+ templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 5. Selected Registrar Config Methods */
+ tempVal = selRegCfgMethods;
+ tempVal = htons(tempVal);
+ templen = AppendWSCTLV(WSC_ID_SEL_REG_CFG_METHODS, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+ }
+
+ /* 6. UUID last 6 bytes use MAC */
+ templen = AppendWSCTLV(WSC_ID_UUID_E, pData, &pWpsCtrl->Wsc_Uuid_E[0], 0);
+ pData += templen;
+ Len += templen;
+
+ /* 7. RF Bands */
+ if (CurOpMode == AP_MODE)
+ {
+ if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ tempVal = 2;
+ else
+ tempVal = 1;
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel > 14)
+ tempVal = 2;
+ else
+ tempVal = 1;
+ }
+
+#ifdef RT_BIG_ENDIAN
+ tempVal =SWAP16(tempVal);
+#endif /* RT_BIG_ENDIAN */
+ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWpsCtrl->WscV2Info.bEnableWpsV2)
+ {
+ PWSC_TLV pWscTLV = &pWpsCtrl->WscV2Info.ExtraTlv;
+ WscGenV2Msg(pWpsCtrl,
+ b_selRegistrar,
+ pAuthorizedMACs,
+ AuthorizedMACsLen,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+
+
+ ieHdr.length = ieHdr.length + Len;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ memcpy(pAd->ApCfg.MBSSID[apidx].WscIEBeacon.Value, &ieHdr, sizeof(WSC_IE_HEADER));
+ memcpy(pAd->ApCfg.MBSSID[apidx].WscIEBeacon.Value + sizeof(WSC_IE_HEADER), Data, Len);
+ pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen = sizeof(WSC_IE_HEADER) + Len;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (Data != NULL)
+ os_free_mem(NULL, Data);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscBuildBeaconIE\n"));
+}
+
+VOID WscBuildProbeRespIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR respType,
+ IN UCHAR scState,
+ IN BOOLEAN b_selRegistrar,
+ IN USHORT devPwdId,
+ IN USHORT selRegCfgMethods,
+ IN UCHAR apidx,
+ IN UCHAR *pAuthorizedMACs,
+ IN INT AuthorizedMACsLen,
+ IN UCHAR CurOpMode)
+{
+ WSC_IE_HEADER ieHdr;
+/* UCHAR Data[512]; */
+ UCHAR *Data = NULL;
+ PUCHAR pData;
+ INT Len = 0, templen = 0;
+ USHORT tempVal = 0;
+ PWSC_CTRL pWpsCtrl = NULL;
+ PWSC_REG_DATA pReg = NULL;
+
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&Data, 512);
+ if (Data == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pWpsCtrl = &pAd->ApCfg.MBSSID[apidx & 0x0F].WscControl;
+#endif /* CONFIG_AP_SUPPORT */
+
+ pReg = &pWpsCtrl->RegData;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscBuildProbeRespIE, apidx = %x\n", apidx));
+
+ /* WSC IE Header */
+ ieHdr.elemId = 221;
+ ieHdr.length = 4;
+ ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2;
+ ieHdr.oui[3] = 0x04;
+
+ pData = (PUCHAR) &Data[0];
+ Len = 0;
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Simple Config State */
+ templen = AppendWSCTLV(WSC_ID_SC_STATE, pData, (UINT8 *)&scState, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((CurOpMode == AP_MODE) && pWpsCtrl->bSetupLock)
+ {
+ // AP Setup Lock
+ templen = AppendWSCTLV(WSC_ID_AP_SETUP_LOCKED, pData, (UINT8 *)&pWpsCtrl->bSetupLock, 0);
+ pData += templen;
+ Len += templen;
+ }
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ if ( b_selRegistrar )
+ {
+ /* 3. Selected Registrar */
+ templen = AppendWSCTLV(WSC_ID_SEL_REGISTRAR, pData, (UINT8 *)&b_selRegistrar, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. Device Password ID */
+ tempVal = htons(devPwdId);
+ templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 5. Selected Registrar Config Methods */
+ tempVal = htons(selRegCfgMethods);
+ templen = AppendWSCTLV(WSC_ID_SEL_REG_CFG_METHODS, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+
+ }
+
+ /* 6. Response Type WSC_ID_RESP_TYPE */
+ templen = AppendWSCTLV(WSC_ID_RESP_TYPE, pData, (UINT8 *)&respType, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 7. UUID last 6 bytes use MAC */
+ templen = AppendWSCTLV(WSC_ID_UUID_E, pData, &pWpsCtrl->Wsc_Uuid_E[0], 0);
+ pData += templen;
+ Len += templen;
+
+ /* 8. Manufacturer */
+ NdisZeroMemory(pData, 64 + 4);
+ templen = AppendWSCTLV(WSC_ID_MANUFACTURER, pData, pReg->SelfInfo.Manufacturer, strlen((PSTRING) pReg->SelfInfo.Manufacturer));
+ pData += templen;
+ Len += templen;
+
+ /* 9. Model Name */
+ NdisZeroMemory(pData, 32 + 4);
+ templen = AppendWSCTLV(WSC_ID_MODEL_NAME, pData, pReg->SelfInfo.ModelName, strlen((PSTRING) pReg->SelfInfo.ModelName));
+ pData += templen;
+ Len += templen;
+
+ /* 10. Model Number */
+ NdisZeroMemory(pData, 32 + 4);
+ templen = AppendWSCTLV(WSC_ID_MODEL_NUMBER, pData, pReg->SelfInfo.ModelNumber, strlen((PSTRING) pReg->SelfInfo.ModelNumber));
+ pData += templen;
+ Len += templen;
+
+ /* 11. Serial Number */
+ NdisZeroMemory(pData, 32 + 4);
+ templen = AppendWSCTLV(WSC_ID_SERIAL_NUM, pData, pReg->SelfInfo.SerialNumber, strlen((PSTRING) pReg->SelfInfo.SerialNumber));
+ pData += templen;
+ Len += templen;
+
+ /* 12. Primary Device Type */
+ templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 13. Device Name */
+ NdisZeroMemory(pData, 32 + 4);
+ templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, pReg->SelfInfo.DeviceName, strlen((PSTRING) pReg->SelfInfo.DeviceName));
+ pData += templen;
+ Len += templen;
+
+ /* 14. Config Methods */
+ /*tempVal = htons(0x008a); */
+ /*tempVal = htons(0x0084); */
+ {
+ /*
+ WSC 1.0 WCN logo testing will check the value of config method in probe response and M1.
+ Config method shall be identical in probe response and M1.
+ */
+#ifdef WSC_V2_SUPPORT
+ if (pWpsCtrl->WscV2Info.bEnableWpsV2)
+ tempVal = pWpsCtrl->WscConfigMethods & 0xF97F;
+ else
+#endif /* WSC_V2_SUPPORT */
+ tempVal = pWpsCtrl->WscConfigMethods & 0x00FF;
+ }
+
+ tempVal = htons(tempVal);
+ templen = AppendWSCTLV(WSC_ID_CONFIG_METHODS, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+
+
+ /* 15. RF Bands */
+ if (CurOpMode == AP_MODE)
+ {
+ if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ tempVal = 2;
+ else
+ tempVal = 1;
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel > 14)
+ tempVal = 2;
+ else
+ tempVal = 1;
+ }
+#ifdef RT_BIG_ENDIAN
+ tempVal =SWAP16(tempVal);
+#endif /* RT_BIG_ENDIAN */
+ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWpsCtrl->WscV2Info.bEnableWpsV2)
+ {
+ PWSC_TLV pWscTLV = &pWpsCtrl->WscV2Info.ExtraTlv;
+ WscGenV2Msg(pWpsCtrl,
+ b_selRegistrar,
+ pAuthorizedMACs,
+ AuthorizedMACsLen,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+
+ if (Len > 251)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Len is overflow!\n"));
+ }
+
+ ieHdr.length = ieHdr.length + Len;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ memcpy(pAd->ApCfg.MBSSID[apidx & 0xF].WscIEProbeResp.Value, &ieHdr, sizeof(WSC_IE_HEADER));
+ memcpy(pAd->ApCfg.MBSSID[apidx & 0xF].WscIEProbeResp.Value + sizeof(WSC_IE_HEADER), Data, Len);
+ pAd->ApCfg.MBSSID[apidx & 0xF].WscIEProbeResp.ValueLen = sizeof(WSC_IE_HEADER) + Len;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (Data != NULL)
+ os_free_mem(NULL, Data);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscBuildProbeRespIE\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Ap send EAP-Fail to station
+
+ Arguments:
+ pAd - NIC Adapter pointer
+ Id - ID between EAP-Req and EAP-Rsp pair
+ pEntry - The Station Entry information
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID WscSendEapFail(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN BOOLEAN bSendDeAuth)
+{
+ UCHAR Header802_3[14];
+ USHORT Length;
+ IEEE8021X_FRAME Ieee_8021x;
+ EAP_FRAME EapFrame;
+ UCHAR *pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F);
+#endif /* CONFIG_AP_SUPPORT */
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR CurOpMode = 0xFF;
+
+ NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);
+
+ /* 1. Send EAP-Rsp Id */
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapFail\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ MAKE_802_3_HEADER(Header802_3,
+ &pWscControl->EntryAddr[0],
+ &pAd->ApCfg.MBSSID[apidx].Bssid[0],
+ EAPOL);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* Length, -1 type size, Eap-Fail doesn't need Type item */
+ Length = sizeof(EAP_FRAME) - sizeof(UCHAR);
+
+ /* Zero 802.1x body */
+ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x));
+ Ieee_8021x.Version = EAPOL_VER;
+ Ieee_8021x.Type = EAPPacket;
+ Ieee_8021x.Length = cpu2be16(Length);
+
+ /* Zero EAP frame */
+ NdisZeroMemory(&EapFrame, sizeof(EapFrame));
+ EapFrame.Code = EAP_CODE_FAIL;
+ EapFrame.Id = pWscControl->lastId;
+ EapFrame.Length = cpu2be16(Length);
+
+ /* Out buffer for transmitting EAP-Req(Identity) */
+/* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
+ if(pOutBuffer == NULL)
+ return;
+
+ FrameLen = 0;
+
+ /* Make Transmitting frame */
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(IEEE8021X_FRAME), &Ieee_8021x,
+ sizeof(EapFrame)-1, &EapFrame, END_OF_ARGS);
+
+ pEntry = MacTableLookup(pAd, &pWscControl->EntryAddr[0]);
+ /* Copy frame to Tx ring */
+ RTMPToWirelessSta(pAd, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE);
+
+
+ if (pOutBuffer)
+/* kfree(pOutBuffer); */
+ os_free_mem(NULL, pOutBuffer);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (pEntry && bSendDeAuth && (CurOpMode == AP_MODE))
+ {
+ MlmeDeAuthAction(pAd, pEntry, REASON_DEAUTH_STA_LEAVING, TRUE);
+ }
+ if (pEntry == NULL)
+ {
+ /*
+ If STA dis-connect un-normally, reset EntryAddr here.
+ */
+ NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapFail\n"));
+}
+
+#ifdef CONFIG_AP_SUPPORT
+VOID WscBuildAssocRespIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ApIdx,
+ IN UCHAR Reason,
+ OUT PUCHAR pOutBuf,
+ OUT PUCHAR pIeLen)
+{
+ WSC_IE_HEADER ieHdr;
+/* UCHAR Data[512] = {0}; */
+ UCHAR *Data = NULL;
+ PUCHAR pData;
+ INT Len = 0, templen = 0;
+ UINT8 tempVal = 0;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pAd->ApCfg.MBSSID[ApIdx].WscControl.RegData;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscBuildAssocRespIE\n"));
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&Data, 512);
+ if (Data == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return;
+ }
+ Data[0] = 0;
+
+ /* WSC IE Header */
+ ieHdr.elemId = 221;
+ ieHdr.length = 4;
+ ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50;
+ ieHdr.oui[2] = 0xF2; ieHdr.oui[3] = 0x04;
+
+ pData = (PUCHAR) &Data[0];
+ Len = 0;
+
+ /* Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Request Type */
+ tempVal = WSC_MSGTYPE_AP_WLAN_MGR;
+ templen = AppendWSCTLV(WSC_ID_RESP_TYPE, pData, (UINT8 *)&tempVal, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef WSC_V2_SUPPORT
+ if (pAd->ApCfg.MBSSID[ApIdx].WscControl.WscV2Info.bEnableWpsV2)
+ {
+ WscGenV2Msg(&pAd->ApCfg.MBSSID[ApIdx].WscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+ }
+#endif /* WSC_V2_SUPPORT */
+
+
+ ieHdr.length = ieHdr.length + Len;
+ NdisMoveMemory(pOutBuf, &ieHdr, sizeof(WSC_IE_HEADER));
+ NdisMoveMemory(pOutBuf + sizeof(WSC_IE_HEADER), Data, Len);
+ *pIeLen = sizeof(WSC_IE_HEADER) + Len;
+
+ if (Data != NULL)
+ os_free_mem(NULL, Data);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscBuildAssocRespIE\n"));
+}
+
+
+VOID WscSelectedRegistrar(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pReginfo,
+ IN UINT Length,
+ IN UCHAR apidx)
+{
+ PUCHAR pData;
+ INT IsAPConfigured;
+ UCHAR wsc_version, wsc_sel_reg = 0;
+ USHORT wsc_dev_pass_id = 0, wsc_sel_reg_conf_mthd = 0;
+ USHORT WscType, WscLen;
+ PUCHAR pAuthorizedMACs = NULL;
+ UCHAR AuthorizedMACsLen = 0;
+ PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+
+ pData = (PUCHAR)pReginfo;
+
+ if (Length < 4)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscSelectedRegistrar --> Unknown IE \n"));
+ return;
+ }
+
+ hex_dump("WscSelectedRegistrar - Reginfo", pReginfo, Length);
+ while (Length > 4)
+ {
+ /* arm-cpu has packet alignment issue, it's better to use memcpy to retrieve data */
+ NdisMoveMemory(&WscType, pData, 2);
+ NdisMoveMemory(&WscLen, pData + 2, 2);
+ WscLen = ntohs(WscLen);
+ pData += 4;
+ Length -= 4;
+ switch (ntohs(WscType))
+ {
+ case WSC_ID_VERSION:
+ wsc_version = *pData;
+ break;
+
+ case WSC_ID_SEL_REGISTRAR:
+ wsc_sel_reg = *pData;
+ break;
+
+ case WSC_ID_DEVICE_PWD_ID:
+ NdisMoveMemory(&wsc_dev_pass_id, pData, sizeof(USHORT));
+ wsc_dev_pass_id = be2cpu16(wsc_dev_pass_id);
+ break;
+
+ case WSC_ID_SEL_REG_CFG_METHODS:
+ NdisMoveMemory(&wsc_sel_reg_conf_mthd, pData, sizeof(USHORT));
+ wsc_sel_reg_conf_mthd = be2cpu16(wsc_sel_reg_conf_mthd);
+ break;
+
+ case WSC_ID_VENDOR_EXT:
+#ifdef WSC_V2_SUPPORT
+ if (pWscCtrl->WscV2Info.bEnableWpsV2 && (WscLen > 0))
+ {
+ /*
+ Find WFA_EXT_ID_AUTHORIZEDMACS
+ */
+ os_alloc_mem(NULL, &pAuthorizedMACs, WscLen);
+ if (pAuthorizedMACs)
+ {
+ NdisZeroMemory(pAuthorizedMACs, WscLen);
+ WscParseV2SubItem(WFA_EXT_ID_AUTHORIZEDMACS, pData, WscLen, pAuthorizedMACs, &AuthorizedMACsLen);
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscSelectedRegistrar --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ IsAPConfigured = pWscCtrl->WscConfStatus;
+
+ if (wsc_sel_reg == 0x01)
+ {
+ pWscCtrl->WscSelReg = 1;
+ WscBuildBeaconIE(pAd, WSC_SCSTATE_CONFIGURED, TRUE, wsc_dev_pass_id, wsc_sel_reg_conf_mthd, apidx, pAuthorizedMACs, AuthorizedMACsLen, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, TRUE, wsc_dev_pass_id, wsc_sel_reg_conf_mthd, pWscCtrl->EntryIfIdx, pAuthorizedMACs, AuthorizedMACsLen, AP_MODE);
+#ifdef WSC_V2_SUPPORT
+ hex_dump("WscSelectedRegistrar - AuthorizedMACs::", pAuthorizedMACs, AuthorizedMACsLen);
+ if ((AuthorizedMACsLen == 6) &&
+ (NdisEqualMemory(pAuthorizedMACs, BROADCAST_ADDR, MAC_ADDR_LEN) == FALSE) &&
+ (NdisEqualMemory(pAuthorizedMACs, ZERO_MAC_ADDR, MAC_ADDR_LEN) == FALSE) &&
+ (pWscCtrl->WscState <= WSC_STATE_WAIT_M3))
+ {
+ PWSC_PEER_ENTRY pWscPeer = NULL;
+ NdisMoveMemory(pWscCtrl->EntryAddr, pAuthorizedMACs, MAC_ADDR_LEN);
+ RTMP_SEM_LOCK(&pWscCtrl->WscPeerListSemLock);
+ WscClearPeerList(&pWscCtrl->WscPeerList);
+ os_alloc_mem(pAd, (UCHAR **)&pWscPeer, sizeof(WSC_PEER_ENTRY));
+ if (pWscPeer)
+ {
+ NdisZeroMemory(pWscPeer, sizeof(WSC_PEER_ENTRY));
+ NdisMoveMemory(pWscPeer->mac_addr, pAuthorizedMACs, MAC_ADDR_LEN);
+ NdisGetSystemUpTime(&pWscPeer->receive_time);
+ insertTailList(&pWscCtrl->WscPeerList,
+ (PLIST_ENTRY)pWscPeer);
+ DBGPRINT(RT_DEBUG_TRACE, ("WscSelectedRegistrar --> Add this MAC to WscPeerList\n"));
+ }
+ ASSERT(pWscPeer != NULL);
+ RTMP_SEM_UNLOCK(&pWscCtrl->WscPeerListSemLock);
+ }
+#endif /* WSC_V2_SUPPORT */
+ }
+ else
+ {
+ pWscCtrl->WscSelReg = 0;
+ WscBuildBeaconIE(pAd, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, apidx, NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscCtrl->EntryIfIdx, NULL, 0, AP_MODE);
+ }
+ APUpdateBeaconFrame(pAd, apidx);
+
+#ifdef WSC_V2_SUPPORT
+ if (pAuthorizedMACs)
+ os_free_mem(NULL, pAuthorizedMACs);
+#endif /* WSC_V2_SUPPORT */
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+VOID WscProfileRetryTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAdapter = NULL;
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ BOOLEAN bReConnect = TRUE;
+ UCHAR CurOpMode = 0xFF;
+
+ if (pWscControl == NULL)
+ return;
+
+ pAdapter = pWscControl->pAd;
+
+ if (pAdapter != NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscProfileRetryTimeout:: WSC profile retry timeout index: %d\n", pWscControl->WscProfile.ApplyProfileIdx));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+
+#ifdef APCLI_SUPPORT
+ if( (CurOpMode == AP_MODE)
+ && (pAdapter->ApCfg.ApCliTab[BSS0].CtrlCurrState == APCLI_CTRL_CONNECTED)
+ && (pAdapter->ApCfg.ApCliTab[BSS0].SsidLen != 0))
+ {
+ INT i;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[i];
+
+ if ( IS_ENTRY_APCLI(pEntry) &&
+ (pEntry->Sst == SST_ASSOC) &&
+ (pEntry->PortSecured == WPA_802_1X_PORT_SECURED))
+ {
+ bReConnect = FALSE;
+ }
+ }
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ if ((CurOpMode == STA_MODE) && INFRA_ON(pAdapter) && (pAdapter->IndicateMediaState == NdisMediaStateConnected))
+ {
+ pWscControl->WscProfileRetryTimerRunning = FALSE;
+ bReConnect = FALSE;
+ }
+
+ if (bReConnect)
+ {
+ if (pWscControl->WscProfile.ApplyProfileIdx < pWscControl->WscProfile.ProfileCnt-1)
+ pWscControl->WscProfile.ApplyProfileIdx++;
+ else
+ pWscControl->WscProfile.ApplyProfileIdx = 0;
+
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ BOOLEAN apcliEn;
+ WscWriteConfToApCliCfg(pAdapter,
+ pWscControl,
+ &pWscControl->WscProfile.Profile[pWscControl->WscProfile.ApplyProfileIdx],
+ TRUE);
+
+ apcliEn = pAdapter->ApCfg.ApCliTab[BSS0].Enable;
+
+ /* bring apcli interface down first */
+ if(apcliEn == TRUE )
+ {
+ pAdapter->ApCfg.ApCliTab[BSS0].Enable = FALSE;
+ ApCliIfDown(pAdapter);
+ pAdapter->ApCfg.ApCliTab[BSS0].Enable = TRUE;
+ }
+ }
+#endif /* APCLI_SUPPORT */
+
+
+ pAdapter->WriteWscCfgToDatFile = (pWscControl->EntryIfIdx & 0x0F);
+/*#ifdef KTHREAD_SUPPORT */
+/* WAKE_UP(&(pAdapter->wscTask)); */
+/*#else */
+/* RTMP_SEM_EVENT_UP(&(pAdapter->wscTask.taskSema)); */
+/*#endif */
+ RtmpOsTaskWakeUp(&(pAdapter->wscTask));
+ DBGPRINT(RT_DEBUG_TRACE, ("WscProfileRetryTimeout:: WSC profile retry index: %d\n", pWscControl->WscProfile.ApplyProfileIdx));
+ }
+ }
+}
+
+VOID WscPBCTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ RTMP_ADAPTER *pAd = NULL;
+ BOOLEAN Cancelled;
+
+ DBGPRINT(RT_DEBUG_OFF, ("-----> WscPBCTimeOutAction\n"));
+
+ if (pWscControl != NULL)
+ pAd = pWscControl->pAd;
+
+ if (pAd != NULL)
+ {
+
+ if (pWscControl->WscPBCTimerRunning)
+ {
+ pWscControl->WscPBCTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled);
+ }
+
+ WscPBCExec(pAd, FALSE, pWscControl);
+
+ /* call Mlme handler to execute it */
+ RTMP_MLME_HANDLER(pAd);
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("<----- WscPBCTimeOutAction\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Exec scan after scan timer expiration
+
+ Arguments:
+ FunctionContext NIC Adapter pointer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID WscScanTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = NULL;
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+
+ if (pWscControl == NULL)
+ return;
+
+ pAd = pWscControl->pAd;
+
+ if (pAd != NULL)
+ {
+ /* call to execute the scan actions */
+ WscScanExec(pAd, pWscControl);
+
+ /* register 10 second timer for PBC or PIN connection execution */
+ if (pWscControl->WscMode == WSC_PBC_MODE)
+ {
+ /* Prevent infinite loop if conncet time out didn't stop the repeat scan */
+ if (pWscControl->WscState != WSC_STATE_OFF)
+ {
+ RTMPSetTimer(&pWscControl->WscPBCTimer, 10000);
+ pWscControl->WscPBCTimerRunning = TRUE;
+ }
+ }
+ else if (pWscControl->WscMode == WSC_PIN_MODE)
+ {
+ /* Prevent infinite loop if conncet time out didn't stop the repeat scan */
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("!!! WscScanTimeOutAction !!!\n"));
+
+ /* call Mlme handler to execute it */
+ RTMP_MLME_HANDLER(pAd);
+ }
+}
+
+BOOLEAN ValidateChecksum(
+ IN UINT PIN)
+{
+ UINT accum = 0;
+
+ 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);
+ accum += 1 * ((PIN / 1) % 10);
+
+ return (0 == (accum % 10));
+} /* ValidateChecksum */
+
+/*
+ Generate 4-digit random number, ex:1234
+*/
+UINT WscRandomGen4digitPinCode(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT iPin;
+
+ iPin = RandomByte2(pAd) * 256 * 256 + RandomByte2(pAd) * 256 + RandomByte2(pAd);
+ iPin = iPin % 10000;
+
+ return iPin;
+}
+
+UINT WscRandomGeneratePinCode(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx)
+{
+ UINT iPin;
+ UINT checksum;
+
+ iPin = RandomByte(pAd) * 256 * 256 + RandomByte(pAd) * 256 + RandomByte(pAd);
+
+ iPin = iPin % 10000000;
+
+
+ checksum = ComputeChecksum( iPin );
+ iPin = iPin*10 + checksum;
+
+ return iPin;
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+VOID WscInformFromWPA(
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ /* WPA_STATE_MACHINE informs this Entry is already WPA_802_1X_PORT_SECURED. */
+ RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)pEntry->pAd;
+ BOOLEAN Cancelled;
+
+ if (pEntry->apidx >= pAd->ApCfg.BssidNum)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscInformFromWPA\n"));
+
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr))
+ {
+ NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, MAC_ADDR_LEN);
+ RTMPCancelTimer(&pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EapolTimer, &Cancelled);
+ pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EapolTimerRunning = FALSE;
+ pEntry->bWscCapable = FALSE;
+ pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscState = WSC_STATE_CONFIGURED;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Reset EntryIfIdx to %d\n", WSC_INIT_ENTRY_APIDX));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscInformFromWPA\n"));
+}
+
+VOID WscDelWPARetryTimer(
+ IN PRTMP_ADAPTER pAd)
+{
+ PMAC_TABLE_ENTRY pEntry;
+ UCHAR apidx = MAIN_MBSSID;
+ BOOLEAN Cancelled;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscDelWPARetryTimer\n"));
+
+ pEntry = MacTableLookup(pAd, pAd->ApCfg.MBSSID[apidx].WscControl.EntryAddr);
+
+ if (pEntry)
+ {
+ RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+ pEntry->WpaState = AS_NOTUSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscDelWPARetryTimer\n"));
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID WscStop(
+ IN PRTMP_ADAPTER pAd,
+#ifdef CONFIG_AP_SUPPORT
+ IN BOOLEAN bFromApCli,
+#endif /* CONFIG_AP_SUPPORT */
+ IN PWSC_CTRL pWscControl)
+{
+ PWSC_UPNP_NODE_INFO pWscUPnPInfo;
+ BOOLEAN Cancelled;
+#ifdef WSC_LED_SUPPORT
+ UCHAR WPSLEDStatus;
+#endif /* WSC_LED_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ MAC_TABLE_ENTRY *pEntry;
+#endif /* CONFIG_AP_SUPPORT */
+ UCHAR CurOpMode = 0xff;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+ pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo;
+
+ if(pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE)
+ {
+ pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled);
+ pWscUPnPInfo->bUPnPMsgTimerPending = FALSE;
+ }
+ if(pWscControl->bM2DTimerRunning)
+ {
+ pWscControl->bM2DTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->M2DTimer, &Cancelled);
+ }
+
+ pWscUPnPInfo->bUPnPInProgress = FALSE;
+ pWscControl->M2DACKBalance = 0;
+ pWscUPnPInfo->registrarID = 0;
+
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled);
+ }
+
+ if (pWscControl->WscUpdatePortCfgTimerRunning)
+ {
+ pWscControl->WscUpdatePortCfgTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscUpdatePortCfgTimer, &Cancelled);
+ }
+
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+#ifdef CONFIG_AP_SUPPORT
+//sync by 7610
+ if ((pWscControl->EntryIfIdx & 0x0F)< pAd->ApCfg.BssidNum)
+ {
+ pEntry = MacTableLookup(pAd, pWscControl->EntryAddr);
+
+ if (CurOpMode == AP_MODE)
+ {
+ if (pEntry && !bFromApCli)
+ {
+ pEntry->bWscCapable = FALSE;
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN);
+
+ pWscControl->WscSelReg = 0;
+ if ( (pWscControl->WscStatus == STATUS_WSC_CONFIGURED) ||
+ (pWscControl->WscStatus == STATUS_WSC_FAIL) ||
+ (pWscControl->WscStatus == STATUS_WSC_PBC_TOO_MANY_AP))
+ ;
+ else
+ pWscControl->WscStatus = STATUS_WSC_NOTUSED;
+ pWscControl->WscState = WSC_STATE_OFF;
+ pWscControl->lastId = 1;
+ pWscControl->EapMsgRunning = FALSE;
+ pWscControl->EapolTimerPending = FALSE;
+ pWscControl->bWscTrigger = FALSE;
+
+ if (pWscControl->WscScanTimerRunning)
+ {
+ pWscControl->WscScanTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscScanTimer, &Cancelled);
+ }
+
+ if (pWscControl->WscPBCTimerRunning)
+ {
+ pWscControl->WscPBCTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled);
+ }
+
+
+#ifdef WSC_LED_SUPPORT
+ if (pWscControl->WscLEDTimerRunning)
+ {
+ pWscControl->WscLEDTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscLEDTimer, &Cancelled);
+ }
+ if (pWscControl->WscSkipTurnOffLEDTimerRunning)
+ {
+ pWscControl->WscSkipTurnOffLEDTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscSkipTurnOffLEDTimer, &Cancelled);
+ }
+ /* Reset the WPS walk time. */
+ pWscControl->bWPSWalkTimeExpiration = FALSE;
+ WPSLEDStatus = LED_WPS_TURN_LED_OFF;
+ RTMPSetLED(pAd, WPSLEDStatus);
+#endif /* WSC_LED_SUPPORT */
+//sync by 7610
+}
+
+VOID WscInit(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromApCli,
+ IN UCHAR BssIndex)
+{
+ IN PWSC_CTRL pWscControl = NULL;
+ UCHAR CurOpMode = AP_MODE;
+
+#ifdef CONFIG_AP_SUPPORT
+ INT IsAPConfigured;
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if (bFromApCli)
+ pWscControl = &pAd->ApCfg.ApCliTab[BssIndex & 0x0F].WscControl;
+ else
+#endif /* APCLI_SUPPORT */
+ pWscControl = &pAd->ApCfg.MBSSID[BssIndex & 0x0F].WscControl;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (pWscControl == NULL)
+ return;
+
+ if (pWscControl->WscEnrolleePinCode == 0)
+ {
+ if (pWscControl->WscEnrollee4digitPinCode)
+ {
+ pWscControl->WscEnrolleePinCodeLen = 4;
+ pWscControl->WscEnrolleePinCode = WscRandomGen4digitPinCode(pAd);
+ }
+ else
+ {
+ pWscControl->WscEnrolleePinCode = GenerateWpsPinCode(pAd, bFromApCli, BssIndex);
+ pWscControl->WscEnrolleePinCodeLen = 8;
+ }
+ }
+ pWscControl->RegData.SelfInfo.Version = WSC_VERSION;
+#ifdef WSC_V2_SUPPORT
+ pWscControl->RegData.SelfInfo.Version2 = WSC_V2_VERSION;
+#endif /* WSC_V2_SUPPORT */
+
+ pWscControl->bWscLastOne = FALSE;
+ pWscControl->bWscFirstOne = FALSE;
+
+
+ pWscControl->WscStatus = STATUS_WSC_IDLE;
+#ifdef CONFIG_AP_SUPPORT
+ if (((CurOpMode == AP_MODE) &&
+ (pWscControl->WscConfMode == WSC_DISABLE))
+#ifdef WSC_V2_SUPPORT
+ || ((pWscControl->WscV2Info.bWpsEnable == FALSE) && pWscControl->WscV2Info.bEnableWpsV2)
+#endif /* WSC_V2_SUPPORT */
+ )
+ {
+ if (CurOpMode == AP_MODE)
+ {
+#ifdef APCLI_SUPPORT
+ if (!bFromApCli)
+#endif /* APCLI_SUPPORT */
+ {
+ pAd->ApCfg.MBSSID[BssIndex & 0x0F].WscIEBeacon.ValueLen = 0;
+ pAd->ApCfg.MBSSID[BssIndex & 0x0F].WscIEProbeResp.ValueLen = 0;
+ }
+ }
+ }
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ {
+
+ WscInitRegistrarPair(pAd, pWscControl, BssIndex);
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+#ifdef APCLI_SUPPORT
+ if (!bFromApCli)
+#endif /* APCLI_SUPPORT */
+ {
+ IsAPConfigured = pWscControl->WscConfStatus;
+ WscBuildBeaconIE(pAd, IsAPConfigured, FALSE, 0, 0, (BssIndex & 0x0F), NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, BssIndex, NULL, 0, AP_MODE);
+ APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+}
+
+USHORT WscGetAuthType(
+ IN NDIS_802_11_AUTHENTICATION_MODE authType)
+{
+ switch(authType)
+ {
+ case Ndis802_11AuthModeOpen:
+ return WSC_AUTHTYPE_OPEN;
+ case Ndis802_11AuthModeWPAPSK:
+ return WSC_AUTHTYPE_WPAPSK;
+ case Ndis802_11AuthModeShared:
+ return WSC_AUTHTYPE_SHARED;
+ case Ndis802_11AuthModeWPANone:
+ return WSC_AUTHTYPE_WPANONE;
+ case Ndis802_11AuthModeWPA:
+ return WSC_AUTHTYPE_WPA;
+ case Ndis802_11AuthModeWPA1WPA2:
+ return (WSC_AUTHTYPE_WPA | WSC_AUTHTYPE_WPA2);
+ case Ndis802_11AuthModeWPA2:
+ return WSC_AUTHTYPE_WPA2;
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ return (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK);
+ case Ndis802_11AuthModeWPA2PSK:
+ return WSC_AUTHTYPE_WPA2PSK;
+ default:
+ return WSC_AUTHTYPE_OPEN;
+ }
+}
+
+USHORT WscGetEncryType(
+ IN NDIS_802_11_WEP_STATUS encryType)
+{
+ switch(encryType)
+ {
+ case Ndis802_11WEPDisabled:
+ return WSC_ENCRTYPE_NONE;
+ case Ndis802_11WEPEnabled:
+ return WSC_ENCRTYPE_WEP;
+ case Ndis802_11Encryption2Enabled:
+ return WSC_ENCRTYPE_TKIP;
+ case Ndis802_11Encryption4Enabled:
+ return (WSC_ENCRTYPE_AES | WSC_ENCRTYPE_TKIP);
+ default:
+ case Ndis802_11Encryption3Enabled:
+ return WSC_ENCRTYPE_AES;
+ }
+}
+
+PSTRING WscGetAuthTypeStr(
+ IN USHORT authFlag)
+{
+ switch(authFlag)
+ {
+ case WSC_AUTHTYPE_OPEN:
+ return "OPEN";
+ case WSC_AUTHTYPE_WPAPSK:
+ return "WPAPSK";
+ case WSC_AUTHTYPE_SHARED:
+ return "SHARED";
+ case WSC_AUTHTYPE_WPANONE:
+ return "WPANONE";
+ case WSC_AUTHTYPE_WPA:
+ return "WPA";
+ case WSC_AUTHTYPE_WPA2:
+ return "WPA2";
+ default:
+ case (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK):
+ return "WPAPSKWPA2PSK";
+ case WSC_AUTHTYPE_WPA2PSK:
+ return "WPA2PSK";
+ case (WSC_AUTHTYPE_OPEN | WSC_AUTHTYPE_SHARED):
+ return "WEPAUTO";
+ }
+}
+
+PSTRING WscGetEncryTypeStr(
+ IN USHORT encryFlag)
+{
+ switch(encryFlag)
+ {
+ case WSC_ENCRTYPE_NONE:
+ return "NONE";
+ case WSC_ENCRTYPE_WEP:
+ return "WEP";
+ case WSC_ENCRTYPE_TKIP:
+ return "TKIP";
+ default:
+ case (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES):
+ return "TKIPAES";
+ case WSC_ENCRTYPE_AES:
+ return "AES";
+ }
+}
+
+NDIS_802_11_AUTHENTICATION_MODE WscGetAuthMode(
+ IN USHORT authFlag)
+{
+ switch(authFlag)
+ {
+ case WSC_AUTHTYPE_OPEN:
+ return Ndis802_11AuthModeOpen;
+ case WSC_AUTHTYPE_WPAPSK:
+ return Ndis802_11AuthModeWPAPSK;
+ case WSC_AUTHTYPE_SHARED:
+ return Ndis802_11AuthModeShared;
+ case WSC_AUTHTYPE_WPANONE:
+ return Ndis802_11AuthModeWPANone;
+ case WSC_AUTHTYPE_WPA:
+ return Ndis802_11AuthModeWPA;
+ case WSC_AUTHTYPE_WPA2:
+ return Ndis802_11AuthModeWPA2;
+ default:
+ case (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK):
+ return Ndis802_11AuthModeWPA1PSKWPA2PSK;
+ case WSC_AUTHTYPE_WPA2PSK:
+ return Ndis802_11AuthModeWPA2PSK;
+ }
+}
+
+NDIS_802_11_WEP_STATUS WscGetWepStatus(
+ IN USHORT encryFlag)
+{
+ switch(encryFlag)
+ {
+ case WSC_ENCRTYPE_NONE:
+ return Ndis802_11WEPDisabled;
+ case WSC_ENCRTYPE_WEP:
+ return Ndis802_11WEPEnabled;
+ case WSC_ENCRTYPE_TKIP:
+ return Ndis802_11Encryption2Enabled;
+ default:
+ case (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES):
+ return Ndis802_11Encryption4Enabled;
+ case WSC_ENCRTYPE_AES:
+ return Ndis802_11Encryption3Enabled;
+ }
+}
+
+void WscWriteConfToPortCfg(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN PWSC_CREDENTIAL pCredential,
+ IN BOOLEAN bEnrollee)
+{
+ UCHAR CurApIdx = MAIN_MBSSID;
+ UCHAR CurOpMode = AP_MODE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToPortCfg\n"));
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ CurApIdx = (pWscControl->EntryIfIdx & 0x0F);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ if (bEnrollee || (CurOpMode == AP_MODE))
+ {
+ if (CurOpMode == AP_MODE)
+ {
+ NdisZeroMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength);
+ pAd->ApCfg.MBSSID[CurApIdx].SsidLen = pCredential->SSID.SsidLength;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ra%d - AuthType: %u, EncrType: %u\n", CurApIdx, pCredential->AuthType, pCredential->EncrType));
+ if (pCredential->AuthType & (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK | WSC_AUTHTYPE_WPANONE))
+ {
+ if (!(pCredential->EncrType & (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AuthType is WPAPSK or WPA2PAK.\n"
+ "Get illegal EncrType(%d) from External Registrar, set EncrType to TKIP\n",
+ pCredential->EncrType));
+ pCredential->EncrType = WSC_ENCRTYPE_TKIP;
+ }
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_V2_SUPPORT
+ if ((CurOpMode == AP_MODE) && (pWscControl->WscV2Info.bEnableWpsV2))
+ {
+ if (pCredential->AuthType == WSC_AUTHTYPE_WPAPSK)
+ pCredential->AuthType = (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK);
+ if (pCredential->EncrType == WSC_ENCRTYPE_TKIP)
+ pCredential->EncrType = (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES);
+ }
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ WscSetAuthMode(pAd, CurOpMode, CurApIdx, WscGetAuthTypeStr(pCredential->AuthType));
+ WscSetEncrypType(pAd, CurOpMode, CurApIdx, WscGetEncryTypeStr(pCredential->EncrType));
+ if (pCredential->EncrType != WSC_ENCRTYPE_NONE)
+ {
+ if (pCredential->EncrType & (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES))
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = 1;
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (pCredential->KeyLength >= 8 && pCredential->KeyLength <= 64)
+ {
+ UCHAR *pPMKBuf = NULL, *pSSIDStr = NULL;
+ INT ssidLen = 0;
+ STRING PassphraseStr[65] = {0};
+
+ pWscControl->WpaPskLen = pCredential->KeyLength;
+ RTMPZeroMemory(pWscControl->WpaPsk, 64);
+ RTMPMoveMemory(pWscControl->WpaPsk, pCredential->Key, pWscControl->WpaPskLen);
+ //sync by 7610
+ RTMPMoveMemory(PassphraseStr, pCredential->Key, pWscControl->WpaPskLen);
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ pPMKBuf = pAd->ApCfg.MBSSID[CurApIdx].PMK;
+ pSSIDStr = (PUCHAR)pAd->ApCfg.MBSSID[CurApIdx].Ssid;
+ ssidLen = pAd->ApCfg.MBSSID[CurApIdx].SsidLen;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ RT_CfgSetWPAPSKKey(pAd, pCredential->Key, pWscControl->WpaPskLen, pSSIDStr, ssidLen, pPMKBuf);
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPskLen = %d\n", pWscControl->WpaPskLen));
+ }
+ else
+ {
+ pWscControl->WpaPskLen = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK: Invalid Key Length (%d)\n", pCredential->KeyLength));
+ }
+ }
+ else if (pCredential->EncrType == WSC_ENCRTYPE_WEP)
+ {
+ UCHAR WepKeyId = 0;
+ USHORT WepKeyLen = pCredential->KeyLength;
+
+ if ((pCredential->KeyIndex >= 1) && (pCredential->KeyIndex <= 4))
+ {
+ WepKeyId = (pCredential->KeyIndex - 1); /* KeyIndex = 1 ~ 4 */
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = WepKeyId;
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 5 or 13 ASCII characters */
+ /* 10 or 26 Hex characters */
+ if (WepKeyLen == 5 || WepKeyLen == 13 || WepKeyLen == 10 || WepKeyLen == 26)
+ {
+ if (WepKeyLen == 5 || WepKeyLen == 13)
+ {
+ pAd->SharedKey[CurApIdx][WepKeyId].KeyLen = (UCHAR)WepKeyLen;
+ memcpy(pAd->SharedKey[CurApIdx][WepKeyId].Key,
+ pCredential->Key,
+ WepKeyLen);
+ if (WepKeyLen == 5)
+ pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP64;
+ else
+ pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP128;
+ }
+ else
+ {
+ pAd->SharedKey[CurApIdx][WepKeyId].KeyLen = (UCHAR)(WepKeyLen/2);
+ AtoH((PSTRING) pCredential->Key, pAd->SharedKey[CurApIdx][WepKeyId].Key, WepKeyLen/2);
+ if (WepKeyLen == 10)
+ pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP64;
+ else
+ pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP128;
+ }
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("WEP: Invalid Key Length (%d)\n", pCredential->KeyLength));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unsupport default key index (%d)\n", WepKeyId));
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = 0;
+#endif /* CONFIG_AP_SUPPORT */
+
+ }
+ }
+ }
+#ifdef CONFIG_AP_SUPPORT
+ }
+ else
+ {
+ if (CurOpMode == AP_MODE)
+ {
+ pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = 1;
+ WscSetAuthMode(pAd, CurOpMode, CurApIdx, "WPAPSKWPA2PSK");
+ WscSetEncrypType(pAd, CurOpMode, CurApIdx, "TKIPAES");
+ pWscControl->WpaPskLen = (INT)pCredential->KeyLength;
+ NdisZeroMemory(pWscControl->WpaPsk, 64);
+ NdisMoveMemory(pWscControl->WpaPsk, pCredential->Key, pWscControl->WpaPskLen);
+ /* Copy SSID */
+ NdisZeroMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength);
+ pAd->ApCfg.MBSSID[CurApIdx].SsidLen = pCredential->SSID.SsidLength;
+ /*
+ Hex Key
+ */
+ if(pWscControl->WscKeyASCII == 0)
+ {
+ AtoH((PSTRING) pWscControl->WpaPsk, pAd->ApCfg.MBSSID[CurApIdx].PMK, 32);
+ }
+ else
+ {
+ UCHAR keyMaterial[40] = {0};
+
+ RtmpPasswordHash((PSTRING)pWscControl->WpaPsk,
+ (PUCHAR) pAd->ApCfg.MBSSID[CurApIdx].Ssid,
+ pAd->ApCfg.MBSSID[CurApIdx].SsidLen,
+ keyMaterial);
+ NdisMoveMemory(pAd->ApCfg.MBSSID[CurApIdx].PMK, keyMaterial, 32);
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- ra%d - WscWriteConfToPortCfg\n", CurApIdx));
+}
+
+
+VOID WscWriteSsidToDatFile(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING pTempStr,
+ IN BOOLEAN bNewFormat,
+ IN UCHAR CurOpMode)
+{
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx;
+#endif /* CONFIG_AP_SUPPORT */
+ INT offset = 0;
+
+ if (bNewFormat == FALSE)
+ {
+ NdisZeroMemory(pTempStr, 512);
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ if (apidx == 0)
+ {
+ NdisMoveMemory(pTempStr, "SSID=", strlen("SSID="));
+ offset = strlen(pTempStr);
+ }
+ else
+ {
+ offset = strlen(pTempStr);
+ NdisMoveMemory(pTempStr + offset, ";", 1);
+ offset += 1;
+ }
+ NdisMoveMemory(pTempStr + offset, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else
+ {
+ STRING item_str[10] = {0};
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ snprintf(item_str, sizeof(item_str), "SSID%d", (apidx + 1));
+ if (rtstrstr(pTempStr, item_str))
+ {
+ NdisZeroMemory(pTempStr, 512);
+ NdisMoveMemory(pTempStr, item_str, strlen(item_str));
+ offset = strlen(pTempStr);
+ NdisMoveMemory(pTempStr + offset, "=", 1);
+ offset += 1;
+ NdisMoveMemory(pTempStr + offset, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen);
+ }
+ NdisZeroMemory(item_str, 10);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+}
+
+
+VOID WscWriteWpaPskToDatFile(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING pTempStr,
+ IN BOOLEAN bNewFormat)
+{
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx;
+#endif /* CONFIG_AP_SUPPORT */
+ PWSC_CTRL pWscControl;
+ INT offset = 0;
+
+ if (bNewFormat == FALSE)
+ {
+ NdisZeroMemory(pTempStr, 512);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ if (apidx == 0)
+ {
+ NdisMoveMemory(pTempStr, "WPAPSK=", strlen("WPAPSK="));
+ offset = strlen(pTempStr);
+ }
+ else
+ {
+ offset = strlen(pTempStr);
+ NdisMoveMemory(pTempStr + offset, ";", 1);
+ offset += 1;
+ }
+ NdisMoveMemory(pTempStr + offset, pWscControl->WpaPsk, pWscControl->WpaPskLen);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else
+ {
+ STRING item_str[10] = {0};
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ snprintf(item_str, sizeof(item_str), "WPAPSK%d", (apidx + 1));
+ if (rtstrstr(pTempStr, item_str))
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ NdisZeroMemory(pTempStr, 512);
+ NdisMoveMemory(pTempStr, item_str, strlen(item_str));
+ offset = strlen(pTempStr);
+ NdisMoveMemory(pTempStr + offset, "=", 1);
+ offset += 1;
+ NdisMoveMemory(pTempStr + offset, pWscControl->WpaPsk, pWscControl->WpaPskLen);
+ }
+ NdisZeroMemory(item_str, 10);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+}
+
+BOOLEAN WscCheckNonce(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *pElem,
+ IN BOOLEAN bFlag,
+ IN PWSC_CTRL pWscControl)
+{
+ USHORT Length;
+ PUCHAR pData;
+ USHORT WscType, WscLen, WscId;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscCheckNonce\n"));
+
+ if (bFlag)
+ {
+ /* check Registrar Nonce */
+ WscId = WSC_ID_REGISTRAR_NONCE;
+ DBGPRINT(RT_DEBUG_TRACE, ("check Registrar Nonce\n"));
+ }
+ else
+ {
+ /* check Enrollee Nonce */
+ WscId = WSC_ID_ENROLLEE_NONCE;
+ DBGPRINT(RT_DEBUG_TRACE, ("check Enrollee Nonce\n"));
+ }
+
+ pData = pElem->Msg;
+ Length = pElem->MsgLen;
+
+ /* We have to look for WSC_IE_MSG_TYPE to classify M2 ~ M8, the remain size must large than 4 */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ char ZeroNonce[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ if (WscType == WscId)
+ {
+ if (RTMPCompareMemory(pWscControl->RegData.SelfNonce, pData, 16) == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Nonce match!!\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n"));
+ return TRUE;
+ }
+ else if (NdisEqualMemory(pData, ZeroNonce, 16))
+ {
+ /* Intel external registrar will send WSC_NACK with enrollee nonce */
+ /* "10 1A 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" */
+ /* when AP is configured and user selects not to configure AP. */
+ DBGPRINT(RT_DEBUG_TRACE, ("Zero Enrollee Nonce!!\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n"));
+ return TRUE;
+ }
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Nonce mismatch!!\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n"));
+ return FALSE;
+}
+
+VOID WscGetRegDataPIN(
+ IN PRTMP_ADAPTER pAdapter,
+ IN UINT PinCode,
+ IN PWSC_CTRL pWscControl)
+{
+ UCHAR tempPIN[9] = {0};
+
+ if ((pWscControl->WscMode == WSC_PBC_MODE) ||
+ (pWscControl->WscMode == WSC_SMPBC_MODE))
+ pWscControl->WscPinCode = 0;
+ else
+ pWscControl->WscPinCode = PinCode;
+
+ memset(pWscControl->RegData.PIN, 0, 8);
+
+ if (pWscControl->WscPinCode == 0)
+ {
+ snprintf((PSTRING) tempPIN, sizeof(tempPIN), "00000000");
+ memcpy(pWscControl->RegData.PIN, tempPIN, 8);
+ pWscControl->RegData.PinCodeLen = 8;
+ }
+ else
+ {
+ if ( pWscControl->WscPinCodeLen == 4)
+ {
+ UCHAR temp4PIN[5] = {0};
+ snprintf((PSTRING) temp4PIN, sizeof(temp4PIN), "%04u", pWscControl->WscPinCode);
+ memcpy(pWscControl->RegData.PIN, temp4PIN, 4);
+ pWscControl->RegData.PinCodeLen = 4;
+ }
+ else
+ {
+ snprintf((PSTRING) tempPIN, sizeof(tempPIN), "%08u", pWscControl->WscPinCode);
+ memcpy(pWscControl->RegData.PIN, tempPIN, 8);
+ pWscControl->RegData.PinCodeLen = 8;
+ }
+ }
+ hex_dump("WscGetRegDataPIN - PIN", pWscControl->RegData.PIN, 8);
+}
+
+VOID WscEapActionDisabled(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl)
+{
+ INT DataLen = 0;
+ UCHAR *WscData = NULL;
+ /*BOOLEAN Cancelled;*/
+
+ os_alloc_mem(NULL, &WscData, 256);
+
+ if (WscData == NULL)
+ return;
+
+ DataLen = BuildMessageNACK(pAdapter, pWscControl, WscData);
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ {
+ if (pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_APCLI)
+ WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ else
+ WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ if (WscData)
+ os_free_mem(NULL, WscData);
+
+ /* RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); */
+ /* pWscControl->EapolTimerRunning = FALSE; */
+}
+
+VOID WscGetConfigErrFromNack(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *pElem,
+ OUT USHORT *pConfigError)
+{
+ USHORT Length = 0;
+ PUCHAR pData;
+ USHORT WscType, WscLen, ConfigError = 0;
+
+ pData = pElem->Msg;
+ Length = pElem->MsgLen;
+
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ if (WscType == WSC_ID_CONFIG_ERROR)
+ {
+ NdisMoveMemory(&ConfigError, pData, sizeof(USHORT));
+ DBGPRINT(RT_DEBUG_TRACE, ("WSC_ID_CONFIG_ERROR: %d\n", ntohs(ConfigError)));
+ *pConfigError = ntohs(ConfigError);
+ return;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("WSC_ID_CONFIG_ERROR is missing\n"));
+}
+
+INT WscSetAuthMode(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CurOpMode,
+ IN UCHAR apidx,
+ IN PSTRING arg)
+{
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ UINT32 i;
+
+ if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen;
+ else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeShared;
+ else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA;
+ else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA2PSK;
+ else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA2;
+ else if ((strcmp(arg, "WPA1WPA2") == 0) || (strcmp(arg, "wpa1wpa2") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA1WPA2;
+ else if ((strcmp(arg, "WPAPSKWPA2PSK") == 0) || (strcmp(arg, "wpapskwpa2psk") == 0))
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA1PSKWPA2PSK;
+ else
+ {
+ pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Unknow AuthMode (%s), set AuthMode to OPEN\n", __FUNCTION__, arg));
+ }
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]))
+ {
+ pAd->MacTab.Content[i].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ }
+ pAd->ApCfg.MBSSID[apidx].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ /*RTMPMakeRSNIE(pAd, pAd->ApCfg.MBSSID[apidx].AuthMode, pAd->ApCfg.MBSSID[apidx].WepStatus, apidx); */
+
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 0;
+
+ if(pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) %s::(AuthMode=%d)\n", apidx, __FUNCTION__, pAd->ApCfg.MBSSID[apidx].AuthMode));
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ return TRUE;
+}
+
+INT WscSetEncrypType(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CurOpMode,
+ IN UCHAR apidx,
+ IN PSTRING arg)
+{
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+
+ if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPDisabled;
+ else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPEnabled;
+ else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption2Enabled;
+ else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption3Enabled;
+ else if ((strcmp(arg, "TKIPAES") == 0) || (strcmp(arg, "tkipaes") == 0))
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption4Enabled;
+ else
+ {
+ pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPDisabled;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Unknow EncrypType (%s), set EncrypType to NONE\n", __FUNCTION__, arg));
+ }
+
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus >= Ndis802_11Encryption2Enabled)
+ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 0;
+
+ /*RTMPMakeRSNIE(pAd, pAd->ApCfg.MBSSID[apidx].AuthMode, pAd->ApCfg.MBSSID[apidx].WepStatus, apidx); */
+ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) %s::(EncrypType=%d)\n", apidx, __FUNCTION__, pAd->ApCfg.MBSSID[apidx].WepStatus));
+
+ return TRUE;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ return TRUE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Push PBC from HW/SW Buttton
+
+ Arguments:
+ pAd - NIC Adapter pointer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+
+VOID WscPushPBCAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl)
+{
+ BOOLEAN Cancelled;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscPushPBCAction\n"));
+
+ /* 0. PBC mode, disregard the SSID information, we have to get the current AP list */
+ /* and check the beacon for Push buttoned AP. */
+
+ /* 1. Cancel old timer to prevent use push continuously */
+ if (pWscControl->Wsc2MinsTimerRunning)
+ {
+ pWscControl->Wsc2MinsTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled);
+ }
+ if (pWscControl->WscScanTimerRunning)
+ {
+ pWscControl->WscScanTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscScanTimer, &Cancelled);
+ }
+ if (pWscControl->WscPBCTimerRunning)
+ {
+ pWscControl->WscPBCTimerRunning = FALSE;
+ RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled);
+ }
+
+ /* Set WSC state to WSC_STATE_INIT */
+ pWscControl->WscState = WSC_STATE_START;
+ pWscControl->WscStatus = STATUS_WSC_SCAN_AP;
+
+ /* Init Registrar pair structures */
+ WscInitRegistrarPair(pAd, pWscControl, BSS0);
+
+ /* For PBC, the PIN is all '0' */
+ WscGetRegDataPIN(pAd, pWscControl->WscPinCode, pWscControl);
+
+ /* 2. Set 2 min timout routine */
+ RTMPSetTimer(&pWscControl->Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT);
+ pWscControl->Wsc2MinsTimerRunning = TRUE;
+ pWscControl->bWscTrigger = TRUE; /* start work */
+
+
+ /* 3. Call WscScan subroutine */
+ WscScanExec(pAd, pWscControl);
+
+ /* 4. Set 10 second timer to invoke PBC connection actions. */
+ RTMPSetTimer(&pWscControl->WscPBCTimer, 10000);
+ pWscControl->WscPBCTimerRunning = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscPushPBCAction\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Doing an active scan with empty SSID, the scanened list will
+ be processed in PBCexec or PINexec routines
+
+ Arguments:
+ pAd - NIC Adapter pointer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID WscScanExec(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl)
+{
+#ifdef WSC_LED_SUPPORT
+ UCHAR WPSLEDStatus;
+#endif /* WSC_LED_SUPPORT */
+
+ /* Prevent infinite loop if conncet time out didn't stop the repeat scan */
+ if ((pWscControl->WscStatus == STATUS_WSC_FAIL) ||
+ (pWscControl->WscState == WSC_STATE_OFF))
+ return;
+
+ DBGPRINT(RT_DEBUG_OFF, ("!!! WscScanExec !!!\n"));
+
+ pWscControl->WscStatus = STATUS_WSC_SCAN_AP;
+
+#ifdef WSC_LED_SUPPORT
+ /* The protocol is connecting to a partner. */
+ WPSLEDStatus = LED_WPS_IN_PROCESS;
+ RTMPSetLED(pAd, WPSLEDStatus);
+#endif /* WSC_LED_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE);
+ }
+#endif /* APCLI_SUPPORT */
+
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Doing PBC conenction verification, it will check current BSS list
+ and find the correct number of PBC AP. If only 1 exists, it will
+ start to make connection. Otherwise, it will set a scan timer
+ to perform another scan for next PBC connection execution.
+
+ Arguments:
+ pAd - NIC Adapter pointer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN WscPBCExec(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromM2,
+ IN PWSC_CTRL pWscControl)
+{
+#ifdef WSC_LED_SUPPORT
+ UCHAR WPSLEDStatus;
+#endif /* WSC_LED_SUPPORT */
+ UCHAR CurOpMode = AP_MODE;
+
+ if (pWscControl == NULL)
+ return FALSE;
+
+
+ DBGPRINT(RT_DEBUG_OFF, ("-----> WscPBCExec !!!\n"));
+
+ /* 1. Search the qualified SSID from current SSID list */
+ WscPBCBssTableSort(pAd, pWscControl);
+
+ /* 2. Check the qualified AP for connection, if more than 1 AP avaliable, report error. */
+ if (pWscControl->WscPBCBssCount != 1)
+ {
+ /* Set WSC state to WSC_FAIL */
+ pWscControl->WscState = WSC_STATE_FAIL;
+ if (pWscControl->WscPBCBssCount== 0)
+ {
+ pWscControl->WscStatus = STATUS_WSC_PBC_NO_AP;
+#ifdef WSC_LED_SUPPORT
+ /* Failed to find any partner. */
+ WPSLEDStatus = LED_WPS_ERROR;
+ RTMPSetLED(pAd, WPSLEDStatus);
+#ifdef CONFIG_WIFI_LED_SUPPORT
+ if (LED_MODE(pAd) == WPS_LED_MODE_SHARE)
+ RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_FAIL_WIFI_LED_TIMEOUT);
+#endif /* CONFIG_WIFI_LED_SUPPORT */
+
+#endif /* WSC_LED_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_OFF, ("WscPBCExec --> AP list is %d, wait for next time\n",
+ pWscControl->WscPBCBssCount));
+
+ {
+ /* 2.1. Set 1 second timer to invoke another scan */
+ RTMPSetTimer(&pWscControl->WscScanTimer, 1000);
+ pWscControl->WscScanTimerRunning = TRUE;
+ }
+ }
+ else
+ {
+ pWscControl->WscStatus = STATUS_WSC_PBC_TOO_MANY_AP;
+ RTMPSendWirelessEvent(pAd, IW_WSC_PBC_SESSION_OVERLAP, NULL, BSS0, 0);
+
+#ifdef WSC_LED_SUPPORT
+ if (LED_MODE(pAd) == WPS_LED_MODE_9) /* WPS LED mode 9. */
+ {
+ /* In case of the WPS LED mode 9, the UI would abort the connection attempt by making the RT_OID_802_11_WSC_SET_WPS_STATE_MACHINE_TERMINATION request. */
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Skip the WPS session overlap detected LED indication.\n", __FUNCTION__));
+ }
+ else /* Other LED mode. */
+ {
+ /* Session overlap detected. */
+ WPSLEDStatus = LED_WPS_SESSION_OVERLAP_DETECTED;
+ RTMPSetLED(pAd, WPSLEDStatus);
+
+
+ }
+#endif /* WSC_LED_SUPPORT */
+
+ /*
+ 20101210 - According to the response from WFA:
+ The station shall not continue scanning waiting for only one registrar to appear
+ */
+ DBGPRINT(RT_DEBUG_TRACE, ("WscPBCExec --> AP list is %d, stop WPS process!\n",
+ pWscControl->WscPBCBssCount));
+
+ WscStop(pAd,
+#ifdef CONFIG_AP_SUPPORT
+ FALSE,
+#endif /* CONFIG_AP_SUPPORT */
+ pWscControl);
+ pWscControl->WscConfMode = WSC_DISABLE;
+ RTMPZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+ pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
+ RTMPMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
+ }
+
+ /* 2.2 We have to quit for now */
+ return FALSE;
+ }
+
+ if (bFromM2)
+ return TRUE;
+
+
+ /* 3. Now we got the intend AP, Set the WSC state and enqueue the SSID connection command */
+ pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
+
+
+#ifdef WSC_LED_SUPPORT
+ /* The protocol is connecting to a partner. */
+ WPSLEDStatus = LED_WPS_IN_PROCESS;
+ RTMPSetLED(pAd, WPSLEDStatus);
+#endif /* WSC_LED_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ STRING ChStr[5] = {0};
+
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr,
+ pAd->ApCfg.ApCliTab[BSS0].CurrentAddress,
+ MAC_ADDR_LEN);
+
+ snprintf(ChStr, sizeof(ChStr), "%d", pAd->MlmeAux.Channel);
+ Set_Channel_Proc(pAd, ChStr);
+
+ /* bring apcli interface down first */
+ if(pAd->ApCfg.ApCliTab[BSS0].Enable == TRUE)
+ {
+ pAd->ApCfg.ApCliTab[BSS0].Enable = FALSE;
+ ApCliIfDown(pAd);
+ }
+ pAd->ApCfg.ApCliTab[BSS0].Enable = TRUE;
+ }
+#endif /* APCLI_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_OFF, ("<----- WscPBCExec !!!\n"));
+ return TRUE;
+}
+
+BOOLEAN WscBssWpsIESearchForPBC(
+ PRTMP_ADAPTER pAd,
+ PWSC_CTRL pWscControl,
+ PBSS_ENTRY pInBss,
+ UUID_BSSID_CH_INFO ApUuidBssid[],
+ INT VarIeLen,
+ PUCHAR pVar)
+{
+ INT j = 0, Len = 0, idx = 0;
+ BOOLEAN bFound, bSameAP, bSelReg;
+ PUCHAR pData = NULL;
+ PBEACON_EID_STRUCT pEid;
+ USHORT DevicePasswordID;
+ PWSC_IE pWscIE;
+ UUID_BSSID_CH_INFO TmpInfo;
+ UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ pData = pVar;
+ bFound = FALSE;
+ bSameAP = FALSE;
+ bSelReg = FALSE;
+ Len = VarIeLen;
+ NdisZeroMemory(&TmpInfo, sizeof(UUID_BSSID_CH_INFO));
+ while ((Len > 0) && (bFound == FALSE))
+ {
+ pEid = (PBEACON_EID_STRUCT) pData;
+
+ /* No match, skip the Eid and move forward, IE_WFA_WSC = 0xdd */
+ if (pEid->Eid != IE_WFA_WSC)
+ {
+ /* Set the offset and look for next IE */
+ pData += (pEid->Len + 2);
+ Len -= (pEid->Len + 2);
+ continue;
+ }
+ else
+ {
+ /* Found IE with 0xdd */
+ /* check for WSC OUI -- 00 50 f2 04 */
+ if ((NdisEqualMemory(pEid->Octet, WPS_OUI, 4) == FALSE)
+ )
+ {
+ /* Set the offset and look for next IE */
+ pData += (pEid->Len + 2);
+ Len -= (pEid->Len + 2);
+ continue;
+ }
+ }
+
+ /* 3. Found AP with WSC IE in beacons, skip 6 bytes = 1 + 1 + 4 */
+ pData += 6;
+ Len -= 6;
+
+ /* 4. Start to look the PBC type within WSC VarIE */
+ while (Len > 0)
+ {
+ /* Check for WSC IEs */
+ pWscIE = (PWSC_IE) pData;
+
+ if (be2cpu16(pWscIE->Type) == WSC_ID_SEL_REGISTRAR)
+ {
+ hex_dump("SelReg:", pData, 5);
+ bSelReg = pWscIE->Data[0];
+ DBGPRINT(RT_DEBUG_TRACE, ("bSelReg = %d\n", bSelReg));
+ }
+
+
+ /* Check for device password ID, PBC = 0x0004, SMPBC = 0x0006 */
+ if (be2cpu16(pWscIE->Type) == WSC_ID_DEVICE_PWD_ID)
+ {
+ /* Found device password ID */
+#ifdef WINBOND
+ /*The Winbond's platform will fail to retrive 2-bytes data, if use the original */
+ /*be2cpu16<-- */
+ DevicePasswordID = WINBON_GET16((PUCHAR)&pWscIE->Data[0]);
+#else
+ DevicePasswordID = be2cpu16(get_unaligned((USHORT *)&pWscIE->Data[0]));
+ /*DevicePasswordID = be2cpu16(*((USHORT *) &pWscIE->Data[0])); */
+#endif /* WINBOND */
+ DBGPRINT(RT_DEBUG_TRACE, ("WscPBCBssTableSort : DevicePasswordID = 0x%04x\n", DevicePasswordID));
+ if (((pWscControl->WscMode == WSC_PBC_MODE) && (DevicePasswordID == DEV_PASS_ID_PBC)) ||
+ ((pWscControl->WscMode == WSC_SMPBC_MODE) && (DevicePasswordID == DEV_PASS_ID_SMPBC)))
+ {
+ /* Found matching PBC AP in current list, add it into table and add the count */
+ bFound = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DPID=PBC Found --> \n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("# Bssid %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pInBss->Bssid[0], pInBss->Bssid[1], pInBss->Bssid[2], pInBss->Bssid[3], pInBss->Bssid[4], pInBss->Bssid[5]));
+
+ if (pInBss->Channel > 14)
+ TmpInfo.Band = WSC_RFBAND_50GHZ;
+ else
+ TmpInfo.Band = WSC_RFBAND_24GHZ;
+
+ RTMPMoveMemory(&TmpInfo.Bssid[0], &pInBss->Bssid[0], MAC_ADDR_LEN);
+ TmpInfo.Channel = pInBss->Channel;
+ RTMPZeroMemory(&TmpInfo.Ssid[0], MAX_LEN_OF_SSID);
+ RTMPMoveMemory(&TmpInfo.Ssid[0], &pInBss->Ssid[0], pInBss->SsidLen);
+ TmpInfo.SsidLen = pInBss->SsidLen;
+ }
+ }
+
+ /* UUID_E is optional for beacons, but mandatory for probe-request */
+ if (be2cpu16(pWscIE->Type) == WSC_ID_UUID_E)
+ {
+ /* Avoid error UUID-E storage from PIN mode */
+ RTMPMoveMemory(&TmpInfo.Uuid[0], (UCHAR *)(pData+4), 16);
+ }
+
+ /* Set the offset and look for PBC information */
+ /* Since Type and Length are both short type, we need to offset 4, not 2 */
+ pData += (be2cpu16(pWscIE->Length) + 4);
+ Len -= (be2cpu16(pWscIE->Length) + 4);
+ }
+
+
+ if ((bFound == TRUE) && (bSelReg == TRUE))
+ {
+ if (pWscControl->WscPBCBssCount == 8)
+ {
+ break;
+ }
+
+ if (pWscControl->WscPBCBssCount > 0)
+ {
+ for (j = 0; j < pWscControl->WscPBCBssCount; j++)
+ {
+ if (RTMPCompareMemory(&ApUuidBssid[j].Uuid[0], &TmpInfo.Uuid[0], 16) == 0)
+ {
+ if (RTMPCompareMemory(&TmpInfo.Uuid[0], zeros16, 16) != 0)
+ {
+ /*
+ Same UUID, indicate concurrent AP
+ We can indicate 1 AP only.
+ */
+ bSameAP = TRUE;
+ break;
+ }
+ else if (RTMPCompareMemory(&TmpInfo.Uuid[0], zeros16, 16) == 0)
+ {
+ if (ApUuidBssid[j].Band != TmpInfo.Band)
+ {
+ if (RTMPCompareMemory(&ApUuidBssid[j].Bssid[0], &TmpInfo.Bssid[0], 5) == 0)
+ {
+ /*
+ Zero UUID at different band, and first 5bytes of two BSSIDs are the same.
+ Indicate concurrent AP, we can indicate 1 AP only.
+ */
+ bSameAP = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ else if ((RTMPCompareMemory(&TmpInfo.Uuid[0], zeros16, 16) == 0) ||
+ (RTMPCompareMemory(&ApUuidBssid[j].Uuid[0], zeros16, 16) == 0))
+ {
+ if ((RTMPCompareMemory(&ApUuidBssid[j].Bssid[0], &TmpInfo.Bssid[0], 5) == 0) &&
+ (ApUuidBssid[j].Band != TmpInfo.Band))
+ {
+ INT tmpDiff = (INT)(ApUuidBssid[j].Bssid[5] - TmpInfo.Bssid[5]);
+ /*
+ Zero UUID and Non-zero UUID at different band, and two BSSIDs are very close.
+ Indicate concurrent AP, we can indicate 1 AP only.
+ */
+ if ((tmpDiff <= 4) ||
+ (tmpDiff >= -4))
+ {
+ bSameAP = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (bSameAP)
+ {
+ if ((pWscControl->WpsApBand == PREFERRED_WPS_AP_PHY_TYPE_2DOT4_G_FIRST) &&
+ (TmpInfo.Band == WSC_RFBAND_24GHZ) &&
+ (ApUuidBssid[j].Band != TmpInfo.Band))
+ {
+ RTMPMoveMemory(&(ApUuidBssid[j].Bssid[0]), &TmpInfo.Bssid[0], MAC_ADDR_LEN);
+ RTMPZeroMemory(&(ApUuidBssid[j].Ssid[0]), MAX_LEN_OF_SSID);
+ RTMPMoveMemory(&(ApUuidBssid[j].Ssid[0]), &TmpInfo.Ssid[0], TmpInfo.SsidLen);
+ ApUuidBssid[j].SsidLen = TmpInfo.SsidLen;
+ ApUuidBssid[j].Channel = TmpInfo.Channel;
+ }
+ else if ((pWscControl->WpsApBand == PREFERRED_WPS_AP_PHY_TYPE_5_G_FIRST) &&
+ (TmpInfo.Band == WSC_RFBAND_50GHZ) &&
+ (ApUuidBssid[j].Band != TmpInfo.Band))
+ {
+ RTMPMoveMemory(&(ApUuidBssid[j].Bssid[0]), &TmpInfo.Bssid[0], MAC_ADDR_LEN);
+ RTMPZeroMemory(&(ApUuidBssid[j].Ssid[0]), MAX_LEN_OF_SSID);
+ RTMPMoveMemory(&(ApUuidBssid[j].Ssid[0]), &TmpInfo.Ssid[0], TmpInfo.SsidLen);
+ ApUuidBssid[j].SsidLen = TmpInfo.SsidLen;
+ ApUuidBssid[j].Channel = TmpInfo.Channel;
+ }
+ }
+
+ if (bSameAP == FALSE)
+ {
+ UCHAR index = pWscControl->WscPBCBssCount;
+
+ /* Store UUID */
+ RTMPMoveMemory(&(ApUuidBssid[index].Uuid[0]), &TmpInfo.Uuid[0], 16);
+ RTMPMoveMemory(&(ApUuidBssid[index].Bssid[0]), &pInBss->Bssid[0], MAC_ADDR_LEN);
+ RTMPZeroMemory(&(ApUuidBssid[index].Ssid[0]), MAX_LEN_OF_SSID);
+ RTMPMoveMemory(&(ApUuidBssid[index].Ssid[0]), &pInBss->Ssid[0], pInBss->SsidLen);
+ ApUuidBssid[index].SsidLen = pInBss->SsidLen;
+ ApUuidBssid[index].Channel = pInBss->Channel;
+ if (ApUuidBssid[index].Channel > 14)
+ ApUuidBssid[index].Band = WSC_RFBAND_50GHZ;
+ else
+ ApUuidBssid[index].Band = WSC_RFBAND_24GHZ;
+ DBGPRINT(RT_DEBUG_ERROR, ("UUID-E= "));
+ for(idx=0; idx<16; idx++)
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("%02x ", ApUuidBssid[index].Uuid[idx]));
+ DBGPRINT(RT_DEBUG_ERROR, ("\n"));
+
+ pWscControl->WscPBCBssCount++;
+ }
+ }
+ }
+
+ return (bFound && bSelReg);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Find WSC PBC activated AP list
+
+ Arguments:
+ pAd - NIC Adapter pointer
+ OutTab - Qualified AP BSS table
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ All these constants are defined in wsc.h
+
+ ========================================================================
+*/
+VOID WscPBCBssTableSort(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl)
+{
+ INT i;
+ PBSS_ENTRY pInBss;
+/* UUID_BSSID_CH_INFO ApUuidBssid[8]; */
+ UUID_BSSID_CH_INFO *ApUuidBssid = NULL;
+ BOOLEAN rv = FALSE;
+ UCHAR CurOpMode = AP_MODE;
+
+
+#ifdef APCLI_SUPPORT
+if (CurOpMode == AP_MODE)
+ pWscControl = &pAd->ApCfg.ApCliTab[BSS0].WscControl;
+#endif /* APCLI_SUPPORT */
+
+
+ if (pWscControl == NULL)
+ return;
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&ApUuidBssid, sizeof(UUID_BSSID_CH_INFO)*8);
+ if (ApUuidBssid == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return;
+ }
+
+ NdisZeroMemory(&ApUuidBssid[0], sizeof(UUID_BSSID_CH_INFO));
+ pWscControl->WscPBCBssCount = 0;
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ /* BSS entry for VarIE processing */
+ pInBss = (PBSS_ENTRY) &pAd->ScanTab.BssEntry[i];
+
+ /* 1. Check VarIE length */
+ if (pInBss->VarIELen == 0)
+ continue;
+
+
+ /* 2. Search for WSC IE - 0xdd xx 00 50 f2 04 */
+ rv = WscBssWpsIESearchForPBC(pAd,
+ pWscControl,
+ pInBss,
+ ApUuidBssid,
+ pInBss->VarIELen,
+ pInBss->VarIEs);
+ if (rv == FALSE)
+ {
+ WscBssWpsIESearchForPBC(pAd,
+ pWscControl,
+ pInBss,
+ ApUuidBssid,
+ pInBss->VarIeFromProbeRspLen,
+ pInBss->pVarIeFromProbRsp);
+ }
+ }
+
+ if (pWscControl->WscPBCBssCount == 1)
+ {
+ RTMPZeroMemory(&pWscControl->WscSsid, sizeof(NDIS_802_11_SSID));
+ RTMPMoveMemory(pWscControl->WscSsid.Ssid, ApUuidBssid[0].Ssid, ApUuidBssid[0].SsidLen);
+ pWscControl->WscSsid.SsidLength = ApUuidBssid[0].SsidLen;
+ RTMPZeroMemory(pWscControl->WscBssid, MAC_ADDR_LEN);
+ RTMPMoveMemory(pWscControl->WscBssid, ApUuidBssid[0].Bssid, MAC_ADDR_LEN);
+ pAd->MlmeAux.Channel = ApUuidBssid[0].Channel;
+
+#ifdef APCLI_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ NdisZeroMemory(pAd->ApCfg.ApCliTab[BSS0].CfgSsid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->ApCfg.ApCliTab[BSS0].CfgSsid, ApUuidBssid[0].Ssid, ApUuidBssid[0].SsidLen);
+ pAd->ApCfg.ApCliTab[BSS0].CfgSsidLen = (UCHAR)ApUuidBssid[0].SsidLen;
+ }
+#endif /* APCLI_SUPPORT */
+
+ }
+
+ if (ApUuidBssid != NULL)
+ os_free_mem(NULL, ApUuidBssid);
+
+ DBGPRINT(RT_DEBUG_OFF, ("WscPBCBssTableSort : Total %d PBC Registrar Found\n", pWscControl->WscPBCBssCount));
+}
+
+VOID WscGenRandomKey(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ INOUT PUCHAR pKey,
+ INOUT PUSHORT pKeyLen)
+{
+ UCHAR tempRandomByte = 0;
+ UCHAR idx = 0;
+ UCHAR keylen = 0;
+ UCHAR retry = 0;
+
+ NdisZeroMemory(pKey, 64);
+
+ /*
+ Hex Key 64 digital
+ */
+ if(pWscControl->WscKeyASCII == 0)
+ {
+ UCHAR tmpStrB[3];
+ for (idx = 0; idx < 32; idx++)
+ {
+ NdisZeroMemory(&tmpStrB[0], sizeof(tmpStrB));
+ tempRandomByte = RandomByte(pAd);
+ snprintf((PSTRING) &tmpStrB[0], 3, "%02x", tempRandomByte);
+ NdisMoveMemory(pKey+(idx*2), &tmpStrB[0], 2);
+ }
+ *pKeyLen = 64;
+ }
+ else
+ {
+ /*
+ ASCII Key, random length
+ */
+ if(pWscControl->WscKeyASCII == 1)
+ {
+ do{
+ keylen = RandomByte(pAd);
+ keylen = keylen % 64;
+ if(retry++ > 20)
+ keylen = 8;
+ }while(keylen < 8);
+ }
+ else
+ keylen = pWscControl->WscKeyASCII;
+
+ /*
+ Generate printable ASCII (decimal 33 to 126)
+ */
+ for(idx = 0; idx < keylen; idx++)
+ {
+ tempRandomByte = RandomByte(pAd)%94+33;
+ *(pKey+idx) = tempRandomByte;
+ }
+ *pKeyLen = keylen;
+ }
+}
+
+VOID WscCreateProfileFromCfg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR OpMode,
+ IN PWSC_CTRL pWscControl,
+ OUT PWSC_PROFILE pWscProfile)
+{
+ UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F);
+ USHORT authType = 0, encyType = 0;
+ UCHAR WepKeyId = 0;
+ PWSC_CREDENTIAL pCredential = NULL;
+ UCHAR CurOpMode = AP_MODE;
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if ((OpMode & 0x0F) == AP_MODE)
+ {
+ /*
+ AP needs to choose the STA's authType and encyType in two cases.
+ 1. AP is unconfigurated (authType and encyType will be updated to mixed mode by WscWriteConfToPortCfg() )
+ 2. AP's authType is mixed mode, we should choose the suitable authType and encyType to STA
+ STA's authType and encyType depend on WscSecurityMode flag
+ */
+
+ if (((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED ) ||
+ (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) &&
+ (OpMode & REGISTRAR_ACTION))
+ {
+ switch (pAd->ApCfg.MBSSID[apidx].WscSecurityMode)
+ {
+ case WPAPSKTKIP:
+ authType = WSC_AUTHTYPE_WPAPSK;
+ encyType = WSC_ENCRTYPE_TKIP;
+ break;
+ case WPAPSKAES:
+ authType = WSC_AUTHTYPE_WPAPSK;
+ encyType = WSC_ENCRTYPE_AES;
+ break;
+ case WPA2PSKTKIP:
+ authType = WSC_AUTHTYPE_WPA2PSK;
+ encyType = WSC_ENCRTYPE_TKIP;
+ break;
+ case WPA2PSKAES:
+ authType = WSC_AUTHTYPE_WPA2PSK;
+ encyType = WSC_ENCRTYPE_AES;
+ break;
+ default:
+ authType = (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK);
+ encyType = (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES);
+ break;
+ }
+
+ if (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED)
+ {
+ /*
+ Although AuthMode is mixed mode, cipher maybe not mixed mode.
+ We need to correct cipher here.
+ */
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption2Enabled)
+ encyType = WSC_ENCRTYPE_TKIP;
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption3Enabled)
+ encyType = WSC_ENCRTYPE_AES;
+ }
+ }
+ else
+ {
+ authType = WscGetAuthType(pAd->ApCfg.MBSSID[apidx].AuthMode);
+ encyType = WscGetEncryType(pAd->ApCfg.MBSSID[apidx].WepStatus);
+ }
+ WepKeyId = pAd->ApCfg.MBSSID[apidx].DefaultKeyId;
+ }
+#ifdef APCLI_SUPPORT
+ else if (OpMode == AP_CLIENT_MODE)
+ {
+ apidx = apidx & 0x0F;
+ authType = WscGetAuthType(pAd->ApCfg.ApCliTab[apidx].AuthMode);
+ encyType = WscGetEncryType(pAd->ApCfg.ApCliTab[apidx].WepStatus);
+ WepKeyId = pAd->ApCfg.ApCliTab[apidx].DefaultKeyId;
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscGetDefaultProfileForM8\n"));
+
+ pCredential = &pWscProfile->Profile[0]; /*Only support one credential now. 20070515 */
+ NdisZeroMemory(pCredential, sizeof(WSC_CREDENTIAL));
+ pWscProfile->ProfileCnt = 1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: pWscControl->WscConfStatus = %d, OpMode = %d\n",
+ __FUNCTION__, pWscControl->WscConfStatus, OpMode));
+
+ /* NewKey, NewKeyIndex for M8 */
+ if ((WSC_SCSTATE_UNCONFIGURED == pWscControl->WscConfStatus) &&
+ ((((OpMode & 0x0F) == AP_MODE)
+ ) && (OpMode & REGISTRAR_ACTION)))
+ {
+ pCredential->KeyIndex = 1;
+ if ((OpMode & 0x0F) == STA_MODE)
+ {
+ {
+ WscGenRandomKey(pAd, pWscControl, pCredential->Key, &pCredential->KeyLength);
+ authType = WSC_AUTHTYPE_WPA2PSK;
+ encyType = WSC_ENCRTYPE_AES;
+ }
+ }
+ else
+ WscGenRandomKey(pAd, pWscControl, pCredential->Key, &pCredential->KeyLength);
+ }
+ else
+ {
+ pCredential->KeyIndex = 1;
+ pCredential->KeyLength = 0;
+ NdisZeroMemory(pCredential->Key, 64);
+ switch (encyType)
+ {
+ case WSC_ENCRTYPE_NONE:
+ break;
+ case WSC_ENCRTYPE_WEP:
+ pCredential->KeyIndex = (WepKeyId + 1);
+ if (((OpMode & 0x0F) == AP_MODE || (OpMode & 0x0F) == STA_MODE) && pAd->SharedKey[apidx][WepKeyId].KeyLen)
+ {
+ INT i;
+ for (i=0; i<pAd->SharedKey[apidx][WepKeyId].KeyLen; i++)
+ {
+ snprintf((PSTRING) pCredential->Key, 64, "%s%02x", pCredential->Key, pAd->SharedKey[apidx][WepKeyId].Key[i]);
+ }
+ pCredential->KeyLength = pAd->SharedKey[apidx][WepKeyId].KeyLen*2;
+ }
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ else if ((OpMode == AP_CLIENT_MODE) && (pAd->ApCfg.ApCliTab[apidx].SharedKey[WepKeyId].KeyLen) &&
+ (CurOpMode == AP_MODE))
+ {
+ INT i;
+ for (i=0; i<pAd->ApCfg.ApCliTab[apidx].SharedKey[WepKeyId].KeyLen; i++)
+ {
+ snprintf((PSTRING) pCredential->Key, 64, "%s%02x", pCredential->Key, pAd->ApCfg.ApCliTab[apidx].SharedKey[WepKeyId].Key[i]);
+ }
+ pCredential->KeyLength = pAd->SharedKey[apidx][WepKeyId].KeyLen*2;
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+ break;
+ case WSC_ENCRTYPE_TKIP:
+ case WSC_ENCRTYPE_AES:
+ case (WSC_ENCRTYPE_AES | WSC_ENCRTYPE_TKIP):
+ pCredential->KeyLength = pWscControl->WpaPskLen;
+ memcpy(pCredential->Key,
+ pWscControl->WpaPsk,
+ pWscControl->WpaPskLen);
+ break;
+ }
+ }
+
+ pCredential->AuthType = authType;
+ pCredential->EncrType = encyType;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if ((OpMode & 0x0F) == AP_MODE)
+ {
+ NdisMoveMemory(pCredential->MacAddr, pAd->ApCfg.MBSSID[apidx].Bssid, 6);
+ if ((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) &&
+ (pWscControl->WscDefaultSsid.SsidLength > 0) &&
+ (pWscControl->WscDefaultSsid.SsidLength < 33))
+ {
+ NdisMoveMemory(pCredential->SSID.Ssid, pWscControl->WscDefaultSsid.Ssid, pWscControl->WscDefaultSsid.SsidLength);
+ pCredential->SSID.SsidLength = pWscControl->WscDefaultSsid.SsidLength;
+ }
+ else
+ {
+ NdisMoveMemory(pCredential->SSID.Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen);
+ pCredential->SSID.SsidLength = pAd->ApCfg.MBSSID[apidx].SsidLen;
+ }
+ }
+#ifdef APCLI_SUPPORT
+ else if (OpMode == AP_CLIENT_MODE)
+ {
+ NdisMoveMemory(pCredential->MacAddr, APCLI_ROOT_BSSID_GET(pAd, pAd->ApCfg.ApCliTab[apidx].MacTabWCID), 6);
+ NdisMoveMemory(pCredential->SSID.Ssid, pAd->ApCfg.ApCliTab[apidx].Ssid, pAd->ApCfg.ApCliTab[apidx].SsidLen);
+ pCredential->SSID.SsidLength = pAd->ApCfg.ApCliTab[apidx].SsidLen;
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2 && (OpMode & REGISTRAR_ACTION))
+ NdisMoveMemory(pCredential->MacAddr, pWscControl->EntryAddr, 6);
+#endif /* WSC_V2_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCreateProfileFromCfg\n"));
+
+}
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+void WscWriteConfToApCliCfg(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN PWSC_CREDENTIAL pCredential,
+ IN BOOLEAN bEnrollee)
+{
+ UCHAR CurApIdx = BSS0;
+ APCLI_STRUCT *pApCliTab;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToApCliCfg\n"));
+
+ CurApIdx = (pWscControl->EntryIfIdx & 0x0F);
+ {
+ pApCliTab = &pAd->ApCfg.ApCliTab[CurApIdx];
+
+ NdisZeroMemory(pApCliTab->Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pApCliTab->Ssid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength);
+ pApCliTab->SsidLen = pCredential->SSID.SsidLength;
+
+ NdisZeroMemory(pApCliTab->CfgSsid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pApCliTab->CfgSsid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength);
+ pApCliTab->CfgSsidLen = pCredential->SSID.SsidLength;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AuthType: %d, EncrType: %d\n", pCredential->AuthType, pCredential->EncrType));
+ if ((pCredential->AuthType == WSC_AUTHTYPE_WPAPSK) ||
+ (pCredential->AuthType == WSC_AUTHTYPE_WPA2PSK))
+ {
+ if ((pCredential->EncrType != WSC_ENCRTYPE_TKIP) && (pCredential->EncrType != WSC_ENCRTYPE_AES))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AuthType is WPAPSK or WPA2PAK.\n"
+ "Get illegal EncrType(%d) from External Registrar, set EncrType to TKIP\n",
+ pCredential->EncrType));
+ pCredential->EncrType = WSC_ENCRTYPE_TKIP;
+ }
+ }
+ Set_ApCli_AuthMode_Proc(pAd, WscGetAuthTypeStr(pCredential->AuthType));
+ Set_ApCli_EncrypType_Proc(pAd, WscGetEncryTypeStr(pCredential->EncrType));
+
+ if (pCredential->EncrType != WSC_ENCRTYPE_NONE)
+ {
+ if (pCredential->EncrType & (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES))
+ {
+ pApCliTab->DefaultKeyId = 0;
+
+ if (pCredential->KeyLength >= 8 && pCredential->KeyLength <= 64)
+ {
+ pWscControl->WpaPskLen = (INT) pCredential->KeyLength;
+ NdisZeroMemory(pWscControl->WpaPsk, 64);
+ NdisMoveMemory(pWscControl->WpaPsk, pCredential->Key, pWscControl->WpaPskLen);
+ RT_CfgSetWPAPSKKey(pAd, (PSTRING) pCredential->Key, pWscControl->WpaPskLen,
+ (PUCHAR)pApCliTab->Ssid, pApCliTab->SsidLen,
+ pApCliTab->PMK);
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPskLen = %d\n", pWscControl->WpaPskLen));
+ }
+ else
+ {
+ pWscControl->WpaPskLen = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK: Invalid Key Length (%d)\n", pCredential->KeyLength));
+ }
+ }
+ else if (pCredential->EncrType == WSC_ENCRTYPE_WEP)
+ {
+ CHAR WepKeyId = 0;
+ USHORT WepKeyLen = pCredential->KeyLength;
+
+ WepKeyId = (pCredential->KeyIndex - 1); /* KeyIndex = 1 ~ 4 */
+ if ((WepKeyId >= 0) && (WepKeyId <=3))
+ {
+ pApCliTab->DefaultKeyId = WepKeyId;
+
+ /* 5 or 13 ASCII characters */
+ /* 10 or 26 Hex characters */
+ if (WepKeyLen == 5 || WepKeyLen == 13 || WepKeyLen == 10 || WepKeyLen == 26)
+ {
+ if (WepKeyLen == 5 || WepKeyLen == 13)
+ {
+ pApCliTab->SharedKey[WepKeyId].KeyLen = WepKeyLen;
+ memcpy(pApCliTab->SharedKey[WepKeyId].Key,
+ pCredential->Key,WepKeyLen);
+ if (WepKeyLen == 5)
+ pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP64;
+ else
+ pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP128;
+ }
+ else
+ {
+ pApCliTab->SharedKey[WepKeyId].KeyLen = (UCHAR) WepKeyLen/2;
+ AtoH((PSTRING) pCredential->Key, pApCliTab->SharedKey[WepKeyId].Key, WepKeyLen/2);
+ if (WepKeyLen == 10)
+ pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP64;
+ else
+ pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP128;
+ }
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("WEP: Invalid Key Length (%d)\n", pCredential->KeyLength));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unsupport default key index (%d), use key Index 1.\n", WepKeyId));
+ pApCliTab->DefaultKeyId = WepKeyId = 0;
+ }
+ }
+ }
+ }
+
+ if (pWscControl->WscProfile.ProfileCnt > 1)
+ {
+ pWscControl->WscProfileRetryTimerRunning = TRUE;
+ RTMPSetTimer(&pWscControl->WscProfileRetryTimer, WSC_PROFILE_RETRY_TIME_OUT);
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscWriteConfToApCliCfg\n"));
+}
+
+VOID WscApCliLinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl)
+{
+ UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F);
+ UCHAR mac_addr[MAC_ADDR_LEN];
+ BOOLEAN apcliEn = pAd->ApCfg.ApCliTab[apidx].Enable;
+
+ NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr,
+ pAd->ApCfg.ApCliTab[apidx].CurrentAddress,
+ 6);
+
+ /* bring apcli interface down first */
+ if(apcliEn == TRUE )
+ {
+ pAd->ApCfg.ApCliTab[apidx].Enable = FALSE;
+ ApCliIfDown(pAd);
+ }
+ pAd->ApCfg.ApCliTab[apidx].Enable = apcliEn;
+ memcpy(mac_addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, MAC_ADDR_LEN);
+ pWscControl->WscStatus = STATUS_WSC_LINK_UP;
+ pWscControl->bWscTrigger = TRUE;
+}
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID WpsSmProcess(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ int HeaderLen = LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME);
+ PHEADER_802_11 pHeader;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+ int apidx = MAIN_MBSSID;
+ PWSC_CTRL pWpsCtrl = NULL;
+ UCHAR CurOpMode = 0xFF;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ CurOpMode = AP_MODE;
+ }
+#endif // CONFIG_AP_SUPPORT //
+
+
+ if (CurOpMode == 0xFF)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("Unkown OpMode (CurOpMode=0x%02x)\n", CurOpMode));
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("CurOpMode=0x%02x\n", CurOpMode));
+
+ pHeader = (PHEADER_802_11)Elem->Msg;
+
+ if (Elem->MsgType == WSC_EAPOL_PACKET_MSG)
+ {
+ if ((pEntry = MacTableLookup(pAd, pHeader->Addr2)))
+ apidx = pEntry->apidx;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+#ifdef APCLI_SUPPORT
+ if (pEntry && IS_ENTRY_APCLI(pEntry))
+ pWpsCtrl = &pAd->ApCfg.ApCliTab[apidx].WscControl;
+ else
+#endif /* APCLI_SUPPORT */
+ pWpsCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if((Elem->MsgType == WSC_EAPOL_UPNP_MSG) && (Elem->MsgLen > HeaderLen))
+ { /*The WSC msg from UPnP daemon */
+ PUCHAR pData;
+ UCHAR MacAddr[MAC_ADDR_LEN]= {0};
+
+ /* Skip the (802.11 + 802.1h + 802.1x + EAP) header */
+ pData = (PUCHAR) &Elem->Msg[HeaderLen];
+ Elem->MsgLen -= HeaderLen;
+ /* The Addr1 of UPnP-Msg used to indicate the MAC address of the AP interface. Now always be ra0. */
+ NdisMoveMemory(MacAddr, pHeader->Addr1, MAC_ADDR_LEN);
+ NdisMoveMemory(Elem->Msg, MacAddr, MAC_ADDR_LEN);
+ NdisMoveMemory(Elem->Msg+6, pData, Elem->MsgLen);
+
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ }
+ else if (Elem->MsgType == WSC_EAPOL_START_MSG)
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ else if (pEntry && (Elem->MsgType == WSC_EAPOL_PACKET_MSG))
+ { /* WSC_STATE_MACHINE can service only one station at one time */
+ PSTRING pData;
+ PEAP_FRAME pEapFrame;
+ /* Skip the EAP LLC header */
+ pData = (PSTRING) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+ pEapFrame = (PEAP_FRAME)(pData + sizeof(IEEE8021X_FRAME));
+ pData += sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("%s:: EAPOL Packet. Code = %d. Type = %d\n",
+ __FUNCTION__, pEapFrame->Code, pEapFrame->Type));
+ if (pEapFrame->Code == EAP_CODE_FAIL)
+ { /* EAP-Fail */
+ STRING fail_data[] = "EAP_FAIL";
+ NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN);
+ NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, fail_data, strlen(fail_data));
+ Elem->MsgLen = strlen(fail_data);
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ return;
+ }
+ else if ((pEapFrame->Code == EAP_CODE_REQ) && (pEapFrame->Type == EAP_TYPE_ID))
+ { /* EAP-Req (Identity) */
+ STRING id_data[] = "hello";
+
+ pWpsCtrl->lastId = pEapFrame->Id;
+ NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN);
+ NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, id_data, strlen(id_data));
+ Elem->MsgLen = strlen(id_data);
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ return;
+ }
+ else if ((pEapFrame->Code == EAP_CODE_REQ) && (pEapFrame->Type == EAP_TYPE_WSC))
+ { /* EAP-Req (Messages) */
+ if (Elem->MsgLen <= HeaderLen)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Elem->MsgLen(%ld) <= HeaderLen(%d) !!\n", Elem->MsgLen, HeaderLen));
+ return;
+ }
+
+ pWpsCtrl->lastId = pEapFrame->Id;
+ Elem->MsgLen -= (LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME));
+ if (WscCheckWSCHeader((PUCHAR)pData))
+ {
+ PWSC_FRAME pWsc = (PWSC_FRAME) pData;
+
+ NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN);
+ if (pWsc->OpCode == WSC_OPCODE_FRAG_ACK)
+ {
+ /*
+ Send rest WSC frag data
+ */
+ STRING wsc_frag_ack[] = "WSC_FRAG_ACK";
+
+ NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, wsc_frag_ack, strlen(wsc_frag_ack));
+ Elem->MsgLen = strlen(wsc_frag_ack);
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ }
+ else if (pWsc->OpCode == WSC_OPCODE_START)
+ {
+ STRING wsc_start[] = "WSC_START";
+
+ NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, wsc_start, strlen(wsc_start));
+ Elem->MsgLen = strlen(wsc_start);
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ }
+ else
+ {
+ if (pWsc->Flags & WSC_MSG_FLAG_LF)
+ {
+ pData += (sizeof(WSC_FRAME) + 2);
+ Elem->MsgLen -= (sizeof(WSC_FRAME) + 2);
+ }
+ else
+ {
+ pData += sizeof(WSC_FRAME);
+ Elem->MsgLen -= sizeof(WSC_FRAME);
+ }
+
+ if ((pWpsCtrl->WscRxBufLen + Elem->MsgLen) < (MGMT_DMA_BUFFER_SIZE-6))
+ {
+ NdisMoveMemory((pWpsCtrl->pWscRxBuf + pWpsCtrl->WscRxBufLen), pData, Elem->MsgLen);
+ pWpsCtrl->WscRxBufLen += Elem->MsgLen;
+ }
+#ifdef WSC_V2_SUPPORT
+ if (pWsc->Flags & WSC_MSG_FLAG_MF)
+ WscSendEapFragAck(pAd, pWpsCtrl, pEntry);
+ else
+#endif /* WSC_V2_SUPPORT */
+ {
+ NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, pWpsCtrl->pWscRxBuf, pWpsCtrl->WscRxBufLen);
+ Elem->MsgLen = pWpsCtrl->WscRxBufLen;
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ pWpsCtrl->WscRxBufLen = 0;
+ NdisZeroMemory(pWpsCtrl->pWscRxBuf, MGMT_DMA_BUFFER_SIZE);
+ }
+ }
+ return;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ERROR: WscCheckWSCHeader() return FALSE!\n"));
+ return;
+ }
+ }
+
+ if (Elem->MsgLen <= HeaderLen)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Elem->MsgLen(%ld) <= HeaderLen(%d) !!\n", Elem->MsgLen, HeaderLen));
+ return;
+ }
+
+ Elem->MsgLen -= (LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME));
+ NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN);
+ if (IS_ENTRY_CLIENT(pEntry) &&
+ (pEapFrame->Code == EAP_CODE_RSP) &&
+ (pEapFrame->Type == EAP_TYPE_ID))
+ {
+ if (strstr(pData, "SimpleConfig"))
+ {
+ /* EAP-Rsp (Identity) */
+ NdisMoveMemory(Elem->Msg+6, pData, Elem->MsgLen);
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ return;
+ }
+ else
+ {
+ BOOLEAN Cancelled;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPCancelTimer EapolTimer!!\n"));
+ NdisZeroMemory(pWpsCtrl->EntryAddr, MAC_ADDR_LEN);
+ pWpsCtrl->EapolTimerRunning = FALSE;
+ RTMPCancelTimer(&pWpsCtrl->EapolTimer, &Cancelled);
+ return;
+ }
+ }
+ else
+ {
+ if (WscCheckWSCHeader((PUCHAR) pData))
+ {
+ /* EAP-Rsp (Messages) */
+ PWSC_FRAME pWsc = (PWSC_FRAME) pData;
+ if (pWsc->OpCode == WSC_OPCODE_FRAG_ACK)
+ {
+ /*
+ Send rest frag data
+ */
+ STRING wsc_frag_ack[] = "WSC_FRAG_ACK";
+ NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, wsc_frag_ack, strlen(wsc_frag_ack));
+ Elem->MsgLen = strlen(wsc_frag_ack);
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ }
+ else
+ {
+ if (pWsc->Flags & WSC_MSG_FLAG_LF)
+ {
+ pData += (sizeof(WSC_FRAME) + 2);
+ Elem->MsgLen -= (sizeof(WSC_FRAME) + 2);
+ }
+ else
+ {
+ pData += sizeof(WSC_FRAME);
+ Elem->MsgLen -= sizeof(WSC_FRAME);
+ }
+
+ if ((pWpsCtrl->WscRxBufLen + Elem->MsgLen) < (MGMT_DMA_BUFFER_SIZE-6))
+ {
+ NdisMoveMemory((pWpsCtrl->pWscRxBuf + pWpsCtrl->WscRxBufLen), pData, Elem->MsgLen);
+ pWpsCtrl->WscRxBufLen += Elem->MsgLen;
+ }
+#ifdef WSC_V2_SUPPORT
+ if (pWsc->Flags & WSC_MSG_FLAG_MF)
+ WscSendEapFragAck(pAd, pWpsCtrl, pEntry);
+ else
+#endif /* WSC_V2_SUPPORT */
+ {
+ //NdisMoveMemory(Elem->Msg+6, pData, Elem->MsgLen);
+ NdisMoveMemory(Elem->Msg+6, pWpsCtrl->pWscRxBuf, pWpsCtrl->WscRxBufLen);
+ Elem->MsgLen = pWpsCtrl->WscRxBufLen;
+ StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState);
+ pWpsCtrl->WscRxBufLen = 0;
+ NdisZeroMemory(pWpsCtrl->pWscRxBuf, MGMT_DMA_BUFFER_SIZE);
+ }
+ }
+ return;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ERROR: WscCheckWSCHeader() return FALSE!\n"));
+ return;
+ }
+ }
+ }
+ else
+ DBGPRINT(RT_DEBUG_WARN, ("Unknow Message Type (=%lu)\n", Elem->MsgType));
+}
+
+#ifdef CONFIG_AP_SUPPORT
+INT WscGetConfWithoutTrigger(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN BOOLEAN bFromUPnP)
+{
+ INT WscMode;
+ INT IsAPConfigured;
+ PWSC_UPNP_NODE_INFO pWscUPnPNodeInfo;
+ UCHAR apIdx;
+
+#ifdef LINUX
+#endif /* LINUX */
+
+
+ /* TODO: Is it possible ApCli call this fucntion?? */
+ apIdx = (pWscControl->EntryIfIdx & 0x0F);
+
+ IsAPConfigured = pWscControl->WscConfStatus;
+ pWscUPnPNodeInfo = &pWscControl->WscUPnPNodeInfo;
+
+ if (pWscControl->WscConfMode == WSC_DISABLE)
+ {
+ pWscControl->bWscTrigger = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetConfForUpnp:: WPS is disabled.\n"));
+ return FALSE;
+ }
+
+ if (bFromUPnP)
+ WscStop(pAd, FALSE, pWscControl);
+
+ if (pWscControl->WscMode == 1)
+ WscMode = DEV_PASS_ID_PIN;
+ else
+ WscMode = DEV_PASS_ID_PBC;
+
+ WscBuildBeaconIE(pAd, IsAPConfigured, TRUE, WscMode, pWscControl->WscConfigMethods, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, TRUE, WscMode, pWscControl->WscConfigMethods, pWscControl->EntryIfIdx, NULL, 0, AP_MODE);
+ APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F);
+
+ /* 2mins time-out timer */
+ RTMPSetTimer(&pWscControl->Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT);
+ pWscControl->Wsc2MinsTimerRunning = TRUE;
+ pWscControl->WscStatus = STATUS_WSC_LINK_UP;
+ if (bFromUPnP)
+ WscSendUPnPConfReqMsg(pAd, apIdx, (PUCHAR)pAd->ApCfg.MBSSID[apIdx].Ssid,
+ pAd->ApCfg.MBSSID[apIdx].Bssid, 3, 0, AP_MODE);
+
+ pWscControl->bWscTrigger = TRUE;
+ pWscControl->bWscAutoTigeer = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: trigger WSC state machine\n", __FUNCTION__));
+
+ return TRUE;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID WscSendNACK(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl)
+{
+ INT DataLen = 0;
+ PUCHAR pWscData = NULL;
+ BOOLEAN Cancelled;
+ UCHAR CurOpMode = AP_MODE;
+
+
+ os_alloc_mem(NULL, (UCHAR **)&pWscData, WSC_MAX_DATA_LEN);
+ if (pWscData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscSendNACK:: WscData Allocate failed!\n"));
+ return;
+ }
+
+ NdisZeroMemory(pWscData, WSC_MAX_DATA_LEN);
+ DataLen = BuildMessageNACK(pAdapter, pWscControl, pWscData);
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (pEntry &&
+ (IS_ENTRY_APCLI(pEntry)
+ )
+ )
+ WscSendMessage(pAdapter, WSC_OPCODE_NACK, pWscData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ else
+ WscSendMessage(pAdapter, WSC_OPCODE_NACK, pWscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+ pWscControl->RegData.ReComputePke = 1;
+
+ if (pWscData)
+ os_free_mem(NULL, pWscData);
+}
+
+#ifdef WSC_INCLUDED
+VOID WscCheckWpsIeFromWpsAP(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT pEid,
+ OUT PUSHORT pDPIDFromAP)
+{
+ PUCHAR pData;
+ SHORT Len = 0;
+ PWSC_IE pWscIE;
+ USHORT DevicePasswordID;
+
+ if (NdisEqualMemory(pEid->Octet, WPS_OUI, 4)
+ )
+ {
+ pData = (PUCHAR) pEid->Octet + 4;
+ Len = (SHORT)(pEid->Len - 4);
+
+ while (Len > 0)
+ {
+ WSC_IE WscIE;
+ NdisMoveMemory(&WscIE, pData, sizeof(WSC_IE));
+ /* Check for WSC IEs */
+ pWscIE = &WscIE;
+
+ /* Check for device password ID, PIN = 0x0000, PBC = 0x0004 */
+ if (pDPIDFromAP && be2cpu16(pWscIE->Type) == WSC_ID_DEVICE_PWD_ID)
+ {
+ /* Found device password ID */
+ NdisMoveMemory(&DevicePasswordID, pData + 4, sizeof(DevicePasswordID));
+ DevicePasswordID = be2cpu16(DevicePasswordID);
+ DBGPRINT(RT_DEBUG_INFO, ("WscCheckWpsIeFromWpsAP : DevicePasswordID = 0x%04x\n", DevicePasswordID));
+ if (DevicePasswordID == DEV_PASS_ID_PIN)
+ {
+ /* PIN */
+ *pDPIDFromAP = DEV_PASS_ID_PIN;
+ }
+ else if (DevicePasswordID == DEV_PASS_ID_PBC)
+ {
+ /* PBC */
+ *pDPIDFromAP = DEV_PASS_ID_PBC;
+ }
+ }
+
+
+ /* Set the offset and look for PBC information */
+ /* Since Type and Length are both short type, we need to offset 4, not 2 */
+ pData += (be2cpu16(pWscIE->Length) + 4);
+ Len -= (be2cpu16(pWscIE->Length) + 4);
+ }
+ }
+
+ return;
+}
+#endif /* WSC_INCLUDED */
+
+
+VOID WscPBCSessionOverlapCheck(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG now;
+ PWSC_STA_PBC_PROBE_INFO pWscStaPbcProbeInfo = &pAd->CommonCfg.WscStaPbcProbeInfo;
+
+ pAd->CommonCfg.WscPBCOverlap = FALSE;
+ if (pWscStaPbcProbeInfo->WscPBCStaProbeCount > 1)
+ {
+ UCHAR i;
+
+ for (i = 0; i < MAX_PBC_STA_TABLE_SIZE; i++)
+ {
+ NdisGetSystemUpTime(&now);
+ if (pWscStaPbcProbeInfo->Valid[i] &&
+ RTMP_TIME_AFTER(now, pWscStaPbcProbeInfo->ReciveTime[i] + 120*OS_HZ))
+ {
+ NdisZeroMemory(&(pWscStaPbcProbeInfo->StaMacAddr[i][0]), MAC_ADDR_LEN);
+ pWscStaPbcProbeInfo->ReciveTime[i] = 0;
+ pWscStaPbcProbeInfo->Valid[i] = FALSE;
+ pWscStaPbcProbeInfo->WscPBCStaProbeCount--;
+ }
+ }
+
+ if (pWscStaPbcProbeInfo->WscPBCStaProbeCount > 1)
+ pAd->CommonCfg.WscPBCOverlap = TRUE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscPBCSessionOverlapCheck : WscPBCStaProbeCount = %d\n",
+ pWscStaPbcProbeInfo->WscPBCStaProbeCount));
+ return;
+}
+
+VOID WscPBC_DPID_FromSTA(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pMacAddr)
+{
+ INT Index = 0;
+ UCHAR tab_idx;
+ BOOLEAN bAddEntry = FALSE;
+ ULONG now;
+ PWSC_STA_PBC_PROBE_INFO pWscStaPbcProbeInfo = &pAd->CommonCfg.WscStaPbcProbeInfo;
+
+ NdisGetSystemUpTime(&now);
+ if (pWscStaPbcProbeInfo->WscPBCStaProbeCount == 0)
+ bAddEntry = TRUE;
+ else
+ {
+ for (tab_idx = 0; tab_idx < MAX_PBC_STA_TABLE_SIZE; tab_idx++)
+ {
+ if (NdisEqualMemory(pMacAddr, pWscStaPbcProbeInfo->StaMacAddr[tab_idx], MAC_ADDR_LEN))
+ {
+ pWscStaPbcProbeInfo->ReciveTime[tab_idx] = now;
+ return;
+ }
+ }
+
+ for (tab_idx = 0; tab_idx < MAX_PBC_STA_TABLE_SIZE; tab_idx++)
+ {
+ if (RTMP_TIME_AFTER(now, pWscStaPbcProbeInfo->ReciveTime[tab_idx] + 120*OS_HZ) ||
+ NdisEqualMemory(pWscStaPbcProbeInfo->StaMacAddr[tab_idx], &ZERO_MAC_ADDR[0], MAC_ADDR_LEN))
+ {
+ if (pWscStaPbcProbeInfo->Valid[tab_idx] == FALSE)
+ {
+ Index = tab_idx;
+ bAddEntry = TRUE;
+ break;
+ }
+ else
+ {
+ pWscStaPbcProbeInfo->ReciveTime[tab_idx] = now;
+ NdisMoveMemory(pWscStaPbcProbeInfo->StaMacAddr[tab_idx], pMacAddr, MAC_ADDR_LEN);
+ return;
+ }
+ }
+ }
+ }
+
+ if (bAddEntry)
+ {
+ pWscStaPbcProbeInfo->WscPBCStaProbeCount++;
+ pWscStaPbcProbeInfo->ReciveTime[Index] = now;
+ pWscStaPbcProbeInfo->Valid[Index] = TRUE;
+ NdisMoveMemory(pWscStaPbcProbeInfo->StaMacAddr[Index], pMacAddr, MAC_ADDR_LEN);
+ }
+}
+
+void WscWriteConfToDatFile(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CurOpMode)
+{
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+ INT index = 0;
+ UCHAR apidx = (pAd->WriteWscCfgToDatFile & 0x0F);
+#endif /* CONFIG_AP_SUPPORT */
+ PWSC_CTRL pWscControl = NULL;
+ PWSC_CREDENTIAL pCredentail = NULL;
+ STRING WepKeyName[MAX_WEPKEYNAME_LEN] = {0};
+ STRING WepKeyFormatName[MAX_WEPKEYNAME_LEN] = {0};
+ INT tempStrLen = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToDatFile(CurOpMode = %d)\n", CurOpMode));
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ if (apidx > pAd->ApCfg.BssidNum)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscWriteConfToDatFile (wrong apidx = %d)\n", apidx));
+ return;
+ }
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ fileName = AP_PROFILE_PATH;
+
+ snprintf((PSTRING) WepKeyName, sizeof(WepKeyName), "Key%dStr%d=", pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1, apidx+1);
+ snprintf((PSTRING) WepKeyFormatName, sizeof(WepKeyFormatName), "Key%dType=", pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ 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;
+ BOOLEAN bNewFormat = TRUE;
+
+ 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) ||
+ strncmp(pTempStr, "SSID1=", strlen("SSID1=")) == 0 ||
+ strncmp(pTempStr, "SSID2=", strlen("SSID2=")) == 0 ||
+ strncmp(pTempStr, "SSID3=", strlen("SSID3=")) == 0 ||
+ strncmp(pTempStr, "SSID4=", strlen("SSID4=")) == 0
+ )
+ {
+ if (rtstrstr(pTempStr, "SSID="))
+ bNewFormat = FALSE;
+
+ WscWriteSsidToDatFile(pAd, pTempStr, bNewFormat, CurOpMode);
+ }
+ else if (strncmp(pTempStr, "AuthMode=", strlen("AuthMode=")) == 0)
+ {
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "AuthMode=");
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ if (pAd->ApCfg.MBSSID[index].SsidLen)
+ {
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode));
+ else
+ snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode));
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if (strncmp(pTempStr, "EncrypType=", strlen("EncrypType=")) == 0)
+ {
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "EncrypType=");
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus));
+ else
+ snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus));
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if ((strncmp(pTempStr, "WPAPSK=", strlen("WPAPSK=")) == 0) ||
+ (strncmp(pTempStr, "WPAPSK1=", strlen("WPAPSK1=")) == 0) ||
+ (strncmp(pTempStr, "WPAPSK2=", strlen("WPAPSK2=")) == 0) ||
+ (strncmp(pTempStr, "WPAPSK3=", strlen("WPAPSK3=")) == 0) ||
+ (strncmp(pTempStr, "WPAPSK4=", strlen("WPAPSK4=")) == 0))
+ {
+ bNewFormat = TRUE;
+ if (strstr(pTempStr, "WPAPSK="))
+ bNewFormat = FALSE;
+ WscWriteWpaPskToDatFile(pAd, pTempStr, bNewFormat);
+ }
+ else if (strncmp(pTempStr, "WscConfMode=", strlen("WscConfMode=")) == 0)
+ {
+ snprintf(pTempStr, 512, "WscConfMode=");
+#ifdef CONFIG_AP_SUPPORT
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[index].WscControl;
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfMode);
+ else
+ snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfMode);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if (strncmp(pTempStr, "WscConfStatus=", strlen("WscConfStatus=")) == 0)
+ {
+ snprintf(pTempStr, 512, "WscConfStatus=");
+#ifdef CONFIG_AP_SUPPORT
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[index].WscControl;
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfStatus);
+ else
+ snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfStatus);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+ else if (strncmp(pTempStr, "DefaultKeyID=", strlen("DefaultKeyID=")) == 0)
+ {
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "DefaultKeyID=");
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%d", pTempStr, pAd->ApCfg.MBSSID[index].DefaultKeyId+1);
+ else
+ snprintf(pTempStr, 512, "%s;%d", pTempStr, pAd->ApCfg.MBSSID[index].DefaultKeyId+1);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+#ifdef CONFIG_AP_SUPPORT
+ else if ((strncmp(pTempStr, WepKeyFormatName, strlen(WepKeyFormatName)) == 0) &&
+ (CurOpMode == AP_MODE))
+ {
+ pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0];
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)
+ {
+ UCHAR idx = 0, KeyType[4] = {0};
+ PSTRING ptr2, temp_ptr;
+
+ ptr2 = rtstrstr(pTempStr, "=");
+ temp_ptr = pTempStr;
+ pTempStr = ptr2+1;
+ KeyType[0] = (UCHAR)(*pTempStr - 0x30);
+ for (idx = 1; idx < 4; idx++)
+ {
+ ptr2 = rtstrstr(pTempStr, ";");
+ if (ptr2 == NULL)
+ break;
+ pTempStr = ptr2+1;
+ if ((pTempStr != NULL) ||
+ (*pTempStr == '0') ||
+ (*pTempStr == '1'))
+ KeyType[idx] = (UCHAR)(*pTempStr - 0x30);
+ }
+ pTempStr = temp_ptr;
+ NdisZeroMemory(pTempStr, 512);
+ NdisMoveMemory(pTempStr, WepKeyFormatName, strlen(WepKeyFormatName));
+ for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++)
+ {
+ if (idx == apidx)
+ snprintf(pTempStr, 512, "%s0", pTempStr);
+ else
+ snprintf(pTempStr, 512, "%s%d", pTempStr, KeyType[idx]);
+
+ if (apidx < (pAd->ApCfg.BssidNum - 1))
+ snprintf(pTempStr, 512, "%s;", pTempStr);
+ }
+ }
+ }
+ else if ((strncmp(pTempStr, WepKeyName, strlen(WepKeyName)) == 0) &&
+ (CurOpMode == AP_MODE))
+ {
+ pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0];
+ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)
+ {
+ NdisZeroMemory(pTempStr, 512);
+ NdisMoveMemory(pTempStr, WepKeyName, strlen(WepKeyName));
+ tempStrLen = strlen(pTempStr);
+ if (pCredentail->KeyLength)
+ {
+ if ((pCredentail->KeyLength == 5) ||
+ (pCredentail->KeyLength == 13))
+ {
+ int jjj=0;
+ for (jjj=0; jjj<pCredentail->KeyLength; jjj++)
+ snprintf(pTempStr, 512, "%s%02x", pTempStr, pCredentail->Key[jjj]);
+ }
+ else if ((pCredentail->KeyLength == 10) ||
+ (pCredentail->KeyLength == 26))
+ {
+ NdisMoveMemory(pTempStr + tempStrLen, pCredentail->Key, pCredentail->KeyLength);
+ }
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ 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, ("<----- WscWriteConfToDatFile\n"));
+ return;
+}
+
+#ifdef CONFIG_AP_SUPPORT
+void WscWriteConfToAR9File(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CurOpMode)
+{
+ PSTRING fileName = NULL;
+ RTMP_OS_FD file_w;
+ RTMP_OS_FS_INFO osFSInfo;
+ INT offset = 0;
+ INT datoffset = 0;
+ PSTRING pTempStr = 0;
+ PSTRING pDatStr = 0;
+#ifdef CONFIG_AP_SUPPORT
+ INT index = 0;
+ UCHAR apidx = MAIN_MBSSID;
+#endif /* CONFIG_AP_SUPPORT */
+ PWSC_CTRL pWscControl = NULL;
+ PWSC_CREDENTIAL pCredentail = NULL;
+ STRING WepKeyName[MAX_WEPKEYNAME_LEN] = {0};
+ STRING WepKeyFormatName[MAX_WEPKEYTYPE_LEN] = {0};
+ INT tempStrLen = 0;
+ STRING item_str[10] = {0};
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToAR9File\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ fileName = "/var/wps_profile.dat";
+
+ snprintf((PSTRING) WepKeyName, sizeof(WepKeyName), "Key%dStr1=", pAd->ApCfg.MBSSID[MAIN_MBSSID].DefaultKeyId+1);
+ snprintf((PSTRING) WepKeyFormatName, sizeof(WepKeyFormatName), "Key%dType=", pAd->ApCfg.MBSSID[MAIN_MBSSID].DefaultKeyId+1);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ RtmpOSFSInfoChange(&osFSInfo, TRUE);
+ file_w = RtmpOSFileOpen(fileName, O_WRONLY|O_CREAT, 0);
+ if (IS_FILE_OPEN_ERR(file_w))
+ {
+ goto WriteFileOpenErr;
+ }
+ else
+ {
+ os_alloc_mem(NULL, (UCHAR **)&pTempStr, 512);
+ if (!pTempStr)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("pTempStr kmalloc fail. (512)\n"));
+ RtmpOSFileClose(file_w);
+ goto WriteErr;
+ }
+ os_alloc_mem(NULL, (UCHAR **)&pDatStr, 4096);
+ if (!pDatStr)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("pDatStr kmalloc fail. (4096)\n"));
+ RtmpOSFileClose(file_w);
+ goto WriteErr;
+ }
+
+ /*for (;;) */
+ {
+ NdisZeroMemory(pTempStr, 512);
+ NdisZeroMemory(pDatStr, 4096);
+ {
+ {
+ NdisZeroMemory(item_str, 10);
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ snprintf(item_str, sizeof(item_str), "SSID%d", (apidx + 1));
+ {
+ NdisMoveMemory(pTempStr, item_str, strlen(item_str));
+ offset = strlen(pTempStr);
+ NdisMoveMemory(pTempStr + offset, "=", 1);
+ offset += 1;
+ NdisMoveMemory(pTempStr + offset, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen);
+ offset += pAd->ApCfg.MBSSID[apidx].SsidLen;
+ NdisMoveMemory(pTempStr + offset, "\n", 1);
+ offset += 1;
+ }
+ NdisZeroMemory(item_str, 10);
+ }
+ }
+ NdisMoveMemory(pDatStr,pTempStr,offset);
+ datoffset += offset;
+
+ {
+ offset=0;
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "AuthMode=");
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ if (pAd->ApCfg.MBSSID[index].SsidLen)
+ {
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode));
+ else
+ snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode));
+ }
+ }
+ snprintf(pTempStr, 512, "%s\n", pTempStr);
+ offset=strlen(pTempStr);
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ {
+ offset=0;
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "EncrypType=");
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus));
+ else
+ snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus));
+ }
+ snprintf(pTempStr, 512, "%s\n", pTempStr);
+ offset=strlen(pTempStr);
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ {
+ offset=0;
+ NdisZeroMemory(pTempStr, 512);
+ NdisZeroMemory(item_str, 10);
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ snprintf(item_str, sizeof(item_str), "WPAPSK%d", (apidx + 1));
+ /*if (rtstrstr(pTempStr, item_str)) */
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl;
+ NdisMoveMemory(pTempStr, item_str, strlen(item_str));
+ offset = strlen(pTempStr);
+ NdisMoveMemory(pTempStr + offset, "=", 1);
+ offset += 1;
+ NdisMoveMemory(pTempStr + offset, pWscControl->WpaPsk, pWscControl->WpaPskLen);
+ offset += pWscControl->WpaPskLen;
+ NdisMoveMemory(pTempStr + offset, "\n", 1);
+ offset += 1;
+ }
+ NdisZeroMemory(item_str, 10);
+ }
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+ }
+
+ {
+ offset=0;
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "WscConfMode=");
+#ifdef CONFIG_AP_SUPPORT
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[index].WscControl;
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfMode);
+ else
+ snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfMode);
+ }
+ snprintf(pTempStr, 512, "%s\n", pTempStr);
+ offset=strlen(pTempStr);
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ {
+ offset=0;
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "WscConfStatus=");
+#ifdef CONFIG_AP_SUPPORT
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[index].WscControl;
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfStatus);
+ else
+ snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfStatus);
+ }
+ snprintf(pTempStr, 512, "%s\n", pTempStr);
+ offset=strlen(pTempStr);
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+#endif /* CONFIG_AP_SUPPORT */
+ }
+
+ {
+ offset=0;
+ NdisZeroMemory(pTempStr, 512);
+ snprintf(pTempStr, 512, "DefaultKeyID=");
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (index = 0; index < pAd->ApCfg.BssidNum; index++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[index].WscControl;
+ if (index == 0)
+ snprintf(pTempStr, 512, "%s%d", pTempStr, pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1);
+ else
+ snprintf(pTempStr, 512, "%s;%d", pTempStr, pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1);
+ }
+ snprintf(pTempStr, 512, "%s\n", pTempStr);
+ offset=strlen(pTempStr);
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+ }
+
+#endif /* CONFIG_AP_SUPPORT */
+ }
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ for (index = 1; index <= 4; index++)
+ {
+ snprintf(WepKeyFormatName, sizeof(WepKeyFormatName), "Key%dType=", index);
+ /*if (rtstrstr(pTempStr, WepKeyFormatName)) */
+ {
+ NdisZeroMemory(pTempStr, 512);
+ offset=0;
+ NdisMoveMemory(pTempStr, WepKeyFormatName, strlen(WepKeyFormatName));
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ if (pAd->ApCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11WEPEnabled)
+ {
+ pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0];
+ if ((pCredentail->KeyLength == 5) ||
+ (pCredentail->KeyLength == 13))
+ snprintf(pTempStr, 512, "%s1", pTempStr); /* ASCII */
+ else
+ snprintf(pTempStr, 512, "%s0", pTempStr); /* Hex */
+ }
+ if (apidx < (pAd->ApCfg.BssidNum - 1))
+ snprintf(pTempStr, 512, "%s;", pTempStr);
+ }
+ snprintf(pTempStr, 512, "%s\n", pTempStr);
+ offset=strlen(pTempStr);
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+ }
+
+ snprintf(WepKeyName, sizeof(WepKeyName), "Key%dStr=", index);
+ /*if (rtstrstr(pTempStr, WepKeyName)) */
+ {
+ NdisZeroMemory(pTempStr, 512);
+ offset=0;
+ NdisMoveMemory(pTempStr, WepKeyName, strlen(WepKeyName));
+ tempStrLen = strlen(pTempStr);
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0];
+ if (pCredentail->KeyLength)
+ {
+ NdisMoveMemory(pTempStr + tempStrLen, pCredentail->Key, pCredentail->KeyLength);
+ tempStrLen = strlen(pTempStr);
+ }
+ if (apidx < (pAd->ApCfg.BssidNum - 1))
+ NdisMoveMemory(pTempStr + tempStrLen, ";", 1);
+ tempStrLen += 1;
+ }
+ snprintf(pTempStr, 512, "%s\n", pTempStr);
+ offset=strlen(pTempStr);
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+ }
+
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ snprintf(WepKeyName, sizeof(WepKeyName), "Key%dStr%d=", index, (apidx + 1));
+ if ((pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled))
+ {
+ NdisZeroMemory(pTempStr, 512);
+ NdisMoveMemory(pTempStr, WepKeyName, strlen(WepKeyName));
+ tempStrLen = strlen(pTempStr);
+ pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0];
+ NdisMoveMemory(pTempStr + tempStrLen, pCredentail->Key, pCredentail->KeyLength);
+ NdisMoveMemory(pTempStr + tempStrLen+pCredentail->KeyLength, "\n", 1);
+ }
+ offset=tempStrLen+pCredentail->KeyLength+1;
+ NdisMoveMemory(pDatStr+datoffset,pTempStr,offset);
+ datoffset += offset;
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ RtmpOSFileWrite(file_w, pDatStr, datoffset);
+ /*RtmpOSFileWrite(file_w, "\n", 1); */
+ }
+ }
+ RtmpOSFileClose(file_w);
+ }
+
+WriteErr:
+ if (pTempStr)
+/* kfree(pTempStr); */
+ os_free_mem(NULL, pTempStr);
+ if (pDatStr)
+/* kfree(pDatStr); */
+ os_free_mem(NULL, pDatStr);
+
+WriteFileOpenErr:
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscWriteConfToAR9File\n"));
+ return;
+}
+#endif/*CONFIG_AP_SUPPORT*/
+
+static INT wsc_write_dat_file_thread (
+ IN ULONG Context)
+{
+ RTMP_OS_TASK *pTask;
+ RTMP_ADAPTER *pAd;
+ int Status = 0;
+
+ pTask = (RTMP_OS_TASK *)Context;
+ pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask);
+
+ if (pAd == NULL)
+ return 0;
+
+ RtmpOSTaskCustomize(pTask);
+
+ while (pTask && !RTMP_OS_TASK_IS_KILLED(pTask))
+ {
+ RTMPusecDelay(2000);
+
+ if (RtmpOSTaskWait(pAd, pTask, &Status) == FALSE)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+
+ if (Status != 0)
+ break;
+
+#ifdef RTMP_MAC_USB
+ /* device had been closed */
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ break;
+#endif /* RTMP_MAC_USB */
+
+ if (pAd->pWscElme && (pAd->pWscElme->MsgLen != 0))
+ {
+ MLME_QUEUE_ELEM *pElme;
+ os_alloc_mem(pAd, (UCHAR **)&pElme, sizeof(MLME_QUEUE_ELEM));
+ if (pElme)
+ {
+ NdisZeroMemory(pElme, sizeof(MLME_QUEUE_ELEM));
+ RTMP_SEM_LOCK(&pAd->WscElmeLock);
+ NdisMoveMemory(pElme, pAd->pWscElme, sizeof(MLME_QUEUE_ELEM));
+ pAd->pWscElme->MsgLen = 0;
+ NdisZeroMemory(pAd->pWscElme->Msg, MGMT_DMA_BUFFER_SIZE);
+ RTMP_SEM_UNLOCK(&pAd->WscElmeLock);
+ WpsSmProcess(pAd, pElme);
+ os_free_mem(NULL, pElme);
+ }
+ }
+
+ if (pAd->WriteWscCfgToDatFile != 0xFF)
+ {
+ UCHAR CurOpMode = AP_MODE;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ WscWriteConfToDatFile(pAd, CurOpMode);
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef INF_AR9
+#ifdef AR9_MAPI_SUPPORT
+ WscWriteConfToAR9File(pAd, CurOpMode);
+#endif /*AR9_MAPI_SUPPORT*/
+#endif /* INF_AR9 */
+#endif/*CONFIG_AP_SUPPORT*/
+ pAd->WriteWscCfgToDatFile = 0xFF;
+ }
+ }
+
+ if (pTask)
+ RtmpOSTaskNotifyToExit(pTask);
+
+ return 0;
+}
+
+
+/*
+ * This kernel thread init in the probe fucntion, so we should kill it when do remove module.
+ */
+BOOLEAN WscThreadExit(RTMP_ADAPTER *pAd)
+{
+ INT ret;
+
+ /*
+ This kernel thread init in the probe fucntion, so kill it when do remove module.
+ */
+ ret = RtmpOSTaskKill(&pAd->wscTask);
+ if (ret == NDIS_STATUS_FAILURE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("kill wsc task failed!\n"));
+ }
+
+ if (pAd->pHmacData)
+ {
+ os_free_mem(NULL, pAd->pHmacData);
+ pAd->pHmacData = NULL;
+ }
+ if (pAd->pWscElme)
+ {
+ os_free_mem(NULL, pAd->pWscElme);
+ pAd->pWscElme = NULL;
+ }
+ NdisFreeSpinLock(&pAd->WscElmeLock);
+#ifdef CONFIG_AP_SUPPORT
+ if ((pAd->OpMode == OPMODE_AP)
+ )
+ {
+ INT ap_idx;
+ UCHAR MaxBssidNum = MAX_MBSSID_NUM(pAd);
+
+ for (ap_idx = 0; ap_idx < MaxBssidNum; ap_idx++)
+ {
+ BOOLEAN Cancelled;
+ PWSC_CTRL pWpsCtrl = &pAd->ApCfg.MBSSID[ap_idx].WscControl;
+ WscStop(pAd, FALSE, pWpsCtrl);
+ //sync by 7610
+#ifdef WSC_V2_SUPPORT
+ if (pWpsCtrl->WscSetupLockTimerRunning)
+ {
+ pWpsCtrl->WscSetupLockTimerRunning = FALSE;
+ RTMPCancelTimer(&pWpsCtrl->WscSetupLockTimer, &Cancelled);
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ pWpsCtrl->WscRxBufLen = 0;
+ if (pWpsCtrl->pWscRxBuf)
+ {
+ os_free_mem(pAd, pWpsCtrl->pWscRxBuf);
+ pWpsCtrl->pWscRxBuf = NULL;
+ }
+ pWpsCtrl->WscTxBufLen = 0;
+ if (pWpsCtrl->pWscTxBuf)
+ {
+ os_free_mem(pAd, pWpsCtrl->pWscTxBuf);
+ pWpsCtrl->pWscTxBuf = NULL;
+ }
+#ifdef WSC_V2_SUPPORT
+ if (pWpsCtrl->WscV2Info.ExtraTlv.pTlvData)
+ {
+ os_free_mem(NULL, pWpsCtrl->WscV2Info.ExtraTlv.pTlvData);
+ pWpsCtrl->WscV2Info.ExtraTlv.pTlvData = NULL;
+ }
+#endif // WSC_V2_SUPPORT //
+ WscClearPeerList(&pWpsCtrl->WscPeerList);
+ NdisFreeSpinLock(&pWpsCtrl->WscPeerListSemLock);
+ }
+#ifdef APCLI_SUPPORT
+ {
+ INT index;
+ WscStop(pAd, TRUE, &pAd->ApCfg.ApCliTab[BSS0].WscControl);
+
+ for(index = 0; index < MAX_APCLI_NUM; index++)
+ {
+ PWSC_CTRL pWpsCtrl = &pAd->ApCfg.ApCliTab[index].WscControl;
+
+ pWpsCtrl->WscTxBufLen = 0;
+ if (pWpsCtrl->pWscTxBuf)
+ os_free_mem(pAd, pWpsCtrl->pWscTxBuf);
+ pWpsCtrl->WscRxBufLen = 0;
+ if (pWpsCtrl->pWscRxBuf)
+ os_free_mem(pAd, pWpsCtrl->pWscRxBuf);
+ WscClearPeerList(&pWpsCtrl->WscPeerList);
+ NdisFreeSpinLock(&pWpsCtrl->WscPeerListSemLock);
+ }
+ }
+#endif // APCLI_SUPPORT //
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* WSC hardware push button function 0811 */
+ WSC_HDR_BTN_Stop(pAd);
+ return TRUE;
+}
+
+
+/*
+ * This kernel thread init in the probe function.
+ */
+NDIS_STATUS WscThreadInit(RTMP_ADAPTER *pAd)
+{
+ NDIS_STATUS status = NDIS_STATUS_FAILURE;
+ RTMP_OS_TASK *pTask;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-->WscThreadInit()\n"));
+
+ pTask = &pAd->wscTask;
+
+
+ RTMP_OS_TASK_INIT(pTask, "RtmpWscTask", pAd);
+ status = RtmpOSTaskAttach(pTask, wsc_write_dat_file_thread, (ULONG)&pAd->wscTask);
+ if (status == NDIS_STATUS_SUCCESS)
+ {
+ os_alloc_mem(NULL, &pAd->pHmacData, sizeof(CHAR)*(2048));
+ if (pAd->pHmacData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wsc HmacData memory alloc failed!\n"));
+ status = FALSE;
+ }
+ NdisAllocateSpinLock(pAd, &pAd->WscElmeLock);
+ os_alloc_mem(NULL, (UCHAR **)&pAd->pWscElme, sizeof(MLME_QUEUE_ELEM));
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("<--WscThreadInit(), status=%d!\n", status));
+
+ return status;
+}
+
+
+/* WSC hardware push button function 0811 */
+/*
+========================================================================
+Routine Description:
+ Initialize the PUSH PUTTION Check Module.
+
+Arguments:
+ ad_p - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID WSC_HDR_BTN_Init(
+ IN PRTMP_ADAPTER pAd)
+{
+ pAd->CommonCfg.WscHdrPshBtnCheckCount = 0;
+} /* End of WSC_HDR_BTN_Init */
+
+
+/*
+========================================================================
+Routine Description:
+ Stop the PUSH PUTTION Check Module.
+
+Arguments:
+ ad_p - WLAN control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID WSC_HDR_BTN_Stop(
+ IN PRTMP_ADAPTER pAd)
+{
+ pAd->CommonCfg.WscHdrPshBtnCheckCount = 0;
+} /* End of WSC_HDR_BTN_Stop */
+
+
+/*
+========================================================================
+Routine Description:
+ Start the PUSH PUTTION Check thread.
+
+Arguments:
+ *Context - WLAN control block pointer
+
+Return Value:
+ 0 - terminate the thread successfully
+
+Note:
+========================================================================
+*/
+#ifdef CONFIG_AP_SUPPORT
+extern INT Set_AP_WscMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+extern INT Set_AP_WscGetConf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif /* CONFIG_AP_SUPPORT */
+
+/*#ifdef CONFIG_STA_SUPPORT */
+
+VOID WSC_HDR_BTN_CheckHandler(
+ IN PRTMP_ADAPTER pAd)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ BOOLEAN flg_pressed;
+
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ MT7601_WSC_HDR_BTN_MR_PRESS_FLG_GET(pAd, flg_pressed);
+ }
+ else
+#endif /* MT7601 */
+ WSC_HDR_BTN_MR_PRESS_FLG_GET(pAd, flg_pressed);
+
+ if (flg_pressed)
+ {
+ /* the button is pressed */
+ if (pAd->CommonCfg.WscHdrPshBtnCheckCount == WSC_HDR_BTN_CONT_TIMES)
+ {
+ /* we only handle once until the button is released */
+ pAd->CommonCfg.WscHdrPshBtnCheckCount = 0;
+
+ /* execute WSC PBC function */
+ DBGPRINT(RT_DEBUG_ERROR, ("wsc> execute WSC PBC...\n"));
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ pObj->ioctl_if = 0;
+ Set_AP_WscMode_Proc(pAd, (PUCHAR)"2"); /* 2: PBC */
+ Set_AP_WscGetConf_Proc(pAd, (PUCHAR)"1"); /* 1: Trigger */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ return;
+ }
+
+ pAd->CommonCfg.WscHdrPshBtnCheckCount ++;
+ }
+ else
+ {
+ /* the button is released */
+ pAd->CommonCfg.WscHdrPshBtnCheckCount = 0;
+ }
+}
+
+#ifdef WSC_LED_SUPPORT
+/* */
+/* Support WPS LED mode (mode 7, mode 8 and mode 9). */
+/* Ref: User Feedback (page 80, WPS specification 1.0) */
+/* */
+BOOLEAN WscSupportWPSLEDMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ if ((LED_MODE(pAd) == WPS_LED_MODE_7) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_8) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_9) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_11) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_12)
+#ifdef CONFIG_WIFI_LED_SUPPORT
+ ||(LED_MODE(pAd) == WPS_LED_MODE_SHARE)
+#endif /* CONFIG_WIFI_LED_SUPPORT */
+ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Support WPS LED mode (The WPS LED mode = %d).\n",
+ __FUNCTION__, LED_MODE(pAd)));
+ return TRUE; /* Support WPS LED mode. */
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Not support WPS LED mode (The WPS LED mode = %d).\n",
+ __FUNCTION__, LED_MODE(pAd)));
+ return FALSE; /* Not support WPS LED mode. */
+ }
+}
+
+BOOLEAN WscSupportWPSLEDMode10(
+ IN PRTMP_ADAPTER pAd)
+{
+ if ((LED_MODE(pAd) == WPS_LED_MODE_10)){
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Support WPS LED mode (The WPS LED mode = %d).\n",
+ __FUNCTION__, LED_MODE(pAd)));
+ return TRUE; /*Support WPS LED mode 10. */
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Not support WPS LED mode (The WPS LED mode = %d).\n",
+ __FUNCTION__, LED_MODE(pAd)));
+ return FALSE; /* Not support WPS LED mode 10. */
+ }
+}
+
+/* */
+/* Whether the WPS AP has security setting or not. */
+/* Note that this function is valid only after the WPS handshaking. */
+/* */
+BOOLEAN WscAPHasSecuritySetting(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl)
+{
+ BOOLEAN bAPHasSecuritySetting = FALSE;
+ UCHAR currentIdx = MAIN_MBSSID;
+
+#ifdef CONFIG_AP_SUPPORT
+ currentIdx = (pWscControl->EntryIfIdx & 0x0F);
+#endif /* CONFIG_AP_SUPPORT */
+
+ switch (pWscControl->WscProfile.Profile[currentIdx].EncrType)
+ {
+ case WSC_ENCRTYPE_NONE:
+ {
+ bAPHasSecuritySetting = FALSE;
+ break;
+ }
+
+ case WSC_ENCRTYPE_WEP:
+ case WSC_ENCRTYPE_TKIP:
+ case (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES):
+ case WSC_ENCRTYPE_AES:
+ {
+ bAPHasSecuritySetting = TRUE;
+ break;
+ }
+
+ default:
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Incorrect encryption types (%d)\n",
+ __FUNCTION__, pWscControl->WscProfile.Profile[currentIdx].EncrType));
+ ASSERT(FALSE);
+ break;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: WSC Entryption Type = %d\n",
+ __FUNCTION__, pWscControl->WscProfile.Profile[currentIdx].EncrType));
+
+ return bAPHasSecuritySetting;
+}
+
+
+/* */
+/* After the NIC connects with a WPS AP or not, */
+/* the WscLEDTimer timer controls the LED behavior according to LED mode. */
+/* */
+VOID WscLEDTimer(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pWscControl->pAd;
+ UCHAR WPSLEDStatus = 0;
+
+ /* WPS LED mode 7, 8, 11 and 12. */
+ if ((LED_MODE(pAd) == WPS_LED_MODE_7) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_8) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_11) ||
+ (LED_MODE(pAd) == WPS_LED_MODE_12))
+ {
+ WPSLEDStatus = LED_WPS_TURN_LED_OFF;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Turn off the WPS successful LED pattern.\n", __FUNCTION__));
+ }
+ else if ((LED_MODE(pAd) == WPS_LED_MODE_9) /* WPS LED mode 9. */
+#ifdef CONFIG_WIFI_LED_SUPPORT
+ || (LED_MODE(pAd) == WPS_LED_MODE_SHARE)
+#endif /* CONFIG_WIFI_LED_SUPPORT */
+ )
+ {
+ switch (pWscControl->WscLEDMode) /* Last WPS LED state. */
+ {
+
+
+ /* Turn off the blue LED after 300 seconds. */
+ case LED_WPS_SUCCESS:
+ WPSLEDStatus = LED_WPS_TURN_LED_OFF;
+
+ /* Turn on/off the WPS success LED according to AP's encryption algorithm after one second. */
+ RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_TURN_OFF_LED_TIMEOUT);
+ pWscControl->WscLEDTimerRunning = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_SUCCESS => LED_WPS_TURN_LED_OFF\n", __FUNCTION__));
+ break;
+
+ /* After turn off the blue LED for one second. */
+ /* AP uses an encryption algorithm: */
+ /* a) YES: Turn on the blue LED. */
+ /* b) NO: Turn off the blue LED. */
+ case LED_WPS_TURN_LED_OFF:
+ if ((pWscControl->WscState == WSC_STATE_OFF) &&
+ (pWscControl->WscStatus == STATUS_WSC_CONFIGURED))
+ {
+ if (WscAPHasSecuritySetting(pAd, pWscControl) == TRUE) /* The NIC connects with an AP using an encryption algorithm. */
+ {
+ /* Turn WPS success LED. */
+ WPSLEDStatus = LED_WPS_TURN_ON_BLUE_LED;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_TURN_LED_OFF => LED_WPS_TURN_ON_BLUE_LED\n", __FUNCTION__));
+ }
+ else /* The NIC connects with an AP using OPEN-NONE. */
+ {
+ /* Turn off the WPS LED. */
+ WPSLEDStatus = LED_WPS_TURN_LED_OFF;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_TURN_LED_OFF => LED_WPS_TURN_LED_OFF\n", __FUNCTION__));
+ }
+ }
+ break;
+
+ /* Turn off the amber LED after 15 seconds. */
+ case LED_WPS_ERROR:
+ WPSLEDStatus = LED_WPS_TURN_LED_OFF; /* Turn off the WPS LED. */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_ERROR/LED_WPS_SESSION_OVERLAP_DETECTED => LED_WPS_TURN_LED_OFF\n", __FUNCTION__));
+ break;
+ /* Turn off the amber LED after ~3 seconds. */
+ case LED_WPS_SESSION_OVERLAP_DETECTED:
+ WPSLEDStatus = LED_WPS_TURN_LED_OFF; /* Turn off the WPS LED. */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_SESSION_OVERLAP_DETECTED => LED_WPS_TURN_LED_OFF\n", __FUNCTION__));
+ break;
+
+ default:
+ /* do nothing. */
+ break;
+ }
+
+ if (WPSLEDStatus)
+ RTMPSetLED(pAd, WPSLEDStatus);
+ }
+ else
+ {
+ /* do nothing. */
+ }
+}
+
+
+VOID WscSkipTurnOffLEDTimer(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+
+ /* Allow the NIC to turn off the WPS LED again. */
+ pWscControl->bSkipWPSTurnOffLED = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: Allow the NIC to turn off the WPS LED again.\n", __FUNCTION__));
+}
+
+#endif /* WSC_LED_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+VOID WscUpdatePortCfgTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ PRTMP_ADAPTER pAd = NULL;
+ BOOLEAN /* bRestart = TRUE,*/ bEnrollee = TRUE;
+ PWSC_CREDENTIAL pCredential = NULL;
+ PMULTISSID_STRUCT pMbss = NULL;
+
+ if (pWscControl == NULL)
+ return;
+
+ pCredential = (PWSC_CREDENTIAL) &pWscControl->WscProfile.Profile[0];
+ pAd = (PRTMP_ADAPTER)pWscControl->pAd;
+
+ if (pAd == NULL)
+ return;
+
+ pMbss = &pAd->ApCfg.MBSSID[pWscControl->EntryIfIdx & 0x0F];
+ if (WscGetAuthMode(pCredential->AuthType) == pMbss->AuthMode &&
+ WscGetWepStatus(pCredential->EncrType) == pMbss->WepStatus &&
+ NdisEqualMemory(pMbss->Ssid, pCredential->SSID.Ssid, pMbss->SsidLen) &&
+ NdisEqualMemory(pWscControl->WpaPsk, pCredential->Key, pCredential->KeyLength))
+ {
+ return;
+ }
+
+ if (pWscControl->WscProfile.ApplyProfileIdx & 0x8000)
+ bEnrollee = FALSE;
+ WscWriteConfToPortCfg(pAd,
+ pWscControl,
+ &pWscControl->WscProfile.Profile[0],
+ bEnrollee);
+ pWscControl->WscProfile.ApplyProfileIdx &= 0x7FFF;
+ {
+ pAd->WriteWscCfgToDatFile = (pWscControl->EntryIfIdx & 0x0F);
+ APStop(pAd);
+ APStartUp(pAd);
+ }
+
+/*#ifdef KTHREAD_SUPPORT */
+/* WAKE_UP(&(pAd->wscTask)); */
+/*#else */
+/* RTMP_SEM_EVENT_UP(&(pAd->wscTask.taskSema)); */
+/*#endif */
+ RtmpOsTaskWakeUp(&(pAd->wscTask));
+
+ return;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID WscCheckPeerDPID(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 Fr,
+ IN PUCHAR eid_data,
+ IN INT eid_len)
+{
+ WSC_IE *pWscIE;
+ PUCHAR pData = NULL;
+ INT Len = 0;
+ USHORT DevicePasswordID;
+ PWSC_CTRL pWscCtrl = NULL;
+
+ pData = eid_data + 4;
+ Len = eid_len - 4;
+ while (Len > 0)
+ {
+ WSC_IE WscIE;
+ NdisMoveMemory(&WscIE, pData, sizeof(WSC_IE));
+ /* Check for WSC IEs*/
+ pWscIE = &WscIE;
+
+ /* Check for device password ID, PBC = 0x0004*/
+ if (be2cpu16(pWscIE->Type) == WSC_ID_DEVICE_PWD_ID)
+ {
+ /* Found device password ID*/
+ NdisMoveMemory(&DevicePasswordID, pData + 4, sizeof(DevicePasswordID));
+ DevicePasswordID = be2cpu16(DevicePasswordID);
+ DBGPRINT(RT_DEBUG_INFO, ("%s : DevicePasswordID = 0x%04x\n", __FUNCTION__, DevicePasswordID));
+ if (DevicePasswordID == DEV_PASS_ID_PBC) /* Check for PBC value*/
+ {
+ WscPBC_DPID_FromSTA(pAd, Fr->Hdr.Addr2);
+ hex_dump("PBC STA:", Fr->Hdr.Addr2, MAC_ADDR_LEN);
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+ }
+ else if (DevicePasswordID == DEV_PASS_ID_PIN)
+ {
+#ifdef CONFIG_AP_SUPPORT
+ if ((pAd->OpMode == OPMODE_AP)
+ )
+ {
+ UCHAR ap_idx = 0;
+ for (ap_idx = 0; ap_idx < pAd->ApCfg.BssidNum; ap_idx++)
+ {
+ if (NdisEqualMemory(Fr->Hdr.Addr1, pAd->ApCfg.MBSSID[ap_idx].Bssid, MAC_ADDR_LEN))
+ break;
+ }
+
+ if (ap_idx >= pAd->ApCfg.BssidNum)
+ {
+ break;
+ }
+
+ pWscCtrl = &pAd->ApCfg.MBSSID[ap_idx].WscControl;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /*
+ WSC 2.0 STA will send probe request with WPS IE anyway.
+ Do NOT add this STA to WscPeerList after AP is triggered to do PBC.
+ */
+ if (pWscCtrl &&
+ (!pWscCtrl->bWscTrigger || (pWscCtrl->WscMode != WSC_PBC_MODE)))
+ {
+ RTMP_SEM_LOCK(&pWscCtrl->WscPeerListSemLock);
+ WscInsertPeerEntryByMAC(&pWscCtrl->WscPeerList, Fr->Hdr.Addr2);
+ RTMP_SEM_UNLOCK(&pWscCtrl->WscPeerListSemLock);
+ }
+ }
+
+ break;
+ }
+
+
+ /* Set the offset and look for PBC information*/
+ /* Since Type and Length are both short type, we need to offset 4, not 2*/
+ pData += (be2cpu16(pWscIE->Length) + 4);
+ Len -= (be2cpu16(pWscIE->Length) + 4);
+ }
+}
+
+VOID WscClearPeerList(
+ IN PLIST_HEADER pWscEnList)
+{
+ PLIST_ENTRY pEntry = NULL;
+
+ pEntry = pWscEnList->pHead;
+
+ while (pEntry != NULL)
+ {
+ removeHeadList(pWscEnList);
+ os_free_mem(NULL, pEntry);
+ pEntry = pWscEnList->pHead;
+ }
+
+ return;
+}
+
+PWSC_PEER_ENTRY WscFindPeerEntry(
+ PLIST_HEADER pWscEnList,
+ IN PUCHAR pMacAddr)
+{
+ PWSC_PEER_ENTRY pPeerEntry = NULL;
+ PLIST_ENTRY pListEntry = NULL;
+
+ pListEntry = pWscEnList->pHead;
+ pPeerEntry = (PWSC_PEER_ENTRY)pListEntry;
+ while (pPeerEntry != NULL)
+ {
+ if (NdisEqualMemory(pPeerEntry->mac_addr, pMacAddr, MAC_ADDR_LEN))
+ return pPeerEntry;
+ pListEntry = pListEntry->pNext;
+ pPeerEntry = (PWSC_PEER_ENTRY)pListEntry;
+ }
+
+ return NULL;
+}
+
+VOID WscInsertPeerEntryByMAC(
+ PLIST_HEADER pWscEnList,
+ IN PUCHAR pMacAddr)
+{
+ PWSC_PEER_ENTRY pWscPeer = NULL;
+
+ pWscPeer = WscFindPeerEntry(pWscEnList, pMacAddr);
+ if (pWscPeer)
+ {
+ NdisGetSystemUpTime(&pWscPeer->receive_time);
+ }
+ else
+ {
+ os_alloc_mem(NULL, (UCHAR **)&pWscPeer, sizeof(WSC_PEER_ENTRY));
+ if (pWscPeer)
+ {
+ NdisZeroMemory(pWscPeer, sizeof(WSC_PEER_ENTRY));
+ pWscPeer->pNext = NULL;
+ NdisMoveMemory(pWscPeer->mac_addr, pMacAddr, MAC_ADDR_LEN);
+ NdisGetSystemUpTime(&pWscPeer->receive_time);
+ insertTailList(pWscEnList, (PLIST_ENTRY)pWscPeer);
+ }
+ ASSERT(pWscPeer != NULL);
+ }
+}
+
+#ifdef CONFIG_AP_SUPPORT
+INT WscApShowPeerList(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR ApIdx = 0;
+ PWSC_CTRL pWscControl = NULL;
+ PWSC_PEER_ENTRY pPeerEntry = NULL;
+ PLIST_ENTRY pListEntry = NULL;
+ PLIST_HEADER pWscEnList = NULL;
+
+ for (ApIdx = 0; ApIdx < pAd->ApCfg.BssidNum; ApIdx++)
+ {
+ pWscControl = &pAd->ApCfg.MBSSID[ApIdx].WscControl;
+ pWscEnList = &pWscControl->WscPeerList;
+
+ if (pWscEnList->size != 0)
+ {
+ WscMaintainPeerList(pAd, pWscControl);
+ RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock);
+ pListEntry = pWscEnList->pHead;
+ pPeerEntry = (PWSC_PEER_ENTRY)pListEntry;
+ while (pPeerEntry != NULL)
+ {
+ printk("MAC:%02x:%02x:%02x:%02x:%02x:%02x\tReveive Time:%lu\n",
+ pPeerEntry->mac_addr[0],
+ pPeerEntry->mac_addr[1],
+ pPeerEntry->mac_addr[2],
+ pPeerEntry->mac_addr[3],
+ pPeerEntry->mac_addr[4],
+ pPeerEntry->mac_addr[5],
+ pPeerEntry->receive_time);
+ pListEntry = pListEntry->pNext;
+ pPeerEntry = (PWSC_PEER_ENTRY)pListEntry;
+ }
+ RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock);
+ }
+ printk("\n");
+ }
+
+ return TRUE;
+}
+#endif // CONFIG_AP_SUPPORT //
+
+
+VOID WscMaintainPeerList(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWpsCtrl)
+{
+ PWSC_PEER_ENTRY pPeerEntry = NULL;
+ PLIST_ENTRY pListEntry = NULL, pTempListEntry = NULL;
+ PLIST_HEADER pWscEnList = NULL;
+ ULONG now_time = 0;
+
+ RTMP_SEM_LOCK(&pWpsCtrl->WscPeerListSemLock);
+ pWscEnList = &pWpsCtrl->WscPeerList;
+
+
+ NdisGetSystemUpTime(&now_time);
+ pListEntry = pWscEnList->pHead;
+ pPeerEntry = (PWSC_PEER_ENTRY)pListEntry;
+
+ while (pPeerEntry != NULL)
+ {
+ if (RTMP_TIME_AFTER(now_time, pPeerEntry->receive_time + (30 * OS_HZ)))
+ {
+ pTempListEntry = pListEntry->pNext;
+ delEntryList(pWscEnList, pListEntry);
+ os_free_mem(pAd, pPeerEntry);
+ pListEntry = pTempListEntry;
+ }
+ else
+ pListEntry = pListEntry->pNext;
+ pPeerEntry = (PWSC_PEER_ENTRY)pListEntry;
+ }
+
+ RTMP_SEM_UNLOCK(&pWpsCtrl->WscPeerListSemLock);
+ return;
+}
+
+VOID WscDelListEntryByMAC(
+ PLIST_HEADER pWscEnList,
+ IN PUCHAR pMacAddr)
+{
+ PLIST_ENTRY pListEntry = NULL;
+ pListEntry = (PLIST_ENTRY)WscFindPeerEntry(pWscEnList, pMacAddr);
+ if (pListEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscDelListEntryByMAC : pMacAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(pMacAddr)));
+ delEntryList(pWscEnList, pListEntry);
+ os_free_mem(NULL, pListEntry);
+ }
+}
+
+VOID WscAssignEntryMAC(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWpsCtrl)
+{
+ PWSC_PEER_ENTRY pPeerEntry = NULL;
+
+ WscMaintainPeerList(pAd, pWpsCtrl);
+
+ RTMP_SEM_LOCK(&pWpsCtrl->WscPeerListSemLock);
+ pPeerEntry = (PWSC_PEER_ENTRY)pWpsCtrl->WscPeerList.pHead;
+
+ NdisZeroMemory(pWpsCtrl->EntryAddr, MAC_ADDR_LEN);
+ if (pPeerEntry)
+ {
+ NdisMoveMemory(pWpsCtrl->EntryAddr, pPeerEntry->mac_addr, MAC_ADDR_LEN);
+ }
+ RTMP_SEM_UNLOCK(&pWpsCtrl->WscPeerListSemLock);
+}
+
+
+/*
+ Get WSC IE data from WSC Peer by Tag.
+*/
+BOOLEAN WscGetDataFromPeerByTag(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pIeData,
+ IN INT IeDataLen,
+ IN USHORT WscTag,
+ OUT PUCHAR pWscBuf,
+ OUT PUSHORT pWscBufLen)
+{
+ PUCHAR pData = pIeData;
+ INT Len = 0;
+ USHORT DataLen = 0;
+ PWSC_IE pWscIE;
+
+ Len = IeDataLen;
+
+ while (Len > 0)
+ {
+ WSC_IE WscIE;
+ NdisMoveMemory(&WscIE, pData, sizeof(WSC_IE));
+ // Check for WSC IEs
+ pWscIE = &WscIE;
+
+ if (be2cpu16(pWscIE->Type) == WscTag)
+ {
+ DataLen = be2cpu16(pWscIE->Length);
+ if (pWscBufLen)
+ *pWscBufLen = DataLen;
+ NdisMoveMemory(pWscBuf, pData + 4, DataLen);
+ return TRUE;
+ }
+
+ // Set the offset and look for next WSC Tag information
+ // Since Type and Length are both short type, we need to offset 4, not 2
+ pData += (be2cpu16(pWscIE->Length) + 4);
+ Len -= (be2cpu16(pWscIE->Length) + 4);
+ }
+
+ return FALSE;
+}
+
+#endif /* WSC_INCLUDED */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/wsc_tlv.c b/cleopatre/devkit/mt7601udrv/common/wsc_tlv.c
new file mode 100644
index 0000000000..495e71e7f0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/wsc_tlv.c
@@ -0,0 +1,4002 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wsc.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 06-08-08 Initial
+ JuemingChen 06-10-30 Do modifications and Add APIs for AP
+*/
+
+#include "rt_config.h"
+
+#ifdef WSC_INCLUDED
+#include "wsc_tlv.h"
+
+static UCHAR Wsc_Personal_String[] = "Wi-Fi Easy and Secure Key Derivation";
+
+#define IV_ENCR_DATA_LEN_512 512
+#define IV_ENCR_DATA_LEN_144 144
+
+#define WSC_TLV_ENT(TLV_PARA) (0x00ff & TLV_PARA)
+#define WSC_TLV_BYTE1(TLV_PARA) (0x000f & TLV_PARA)
+#define WSC_TLV_BYTE2(TLV_PARA) (0x000f & (TLV_PARA >> 4))
+
+/* Global reusable buffer */
+static WSC_TLV_0B wsc_tlv_0b[]=
+{
+ {/*0,*/0},
+ /*AP Channel*/ {/*0x1001,*/ 2}, /* WSC_ID_AP_CHANNEL */
+ /*Association State*/ {/*0x1002,*/ 2}, /* WSC_ID_ASSOC_STATE */
+ /*Authentication Type*/ {/*0x1003,*/ 2}, /* WSC_ID_AUTH_TYPE */
+ /*Authentication Type Flags*/ {/*0x1004,*/ 2}, /* WSC_ID_AUTH_TYPE_FLAGS */
+ /*Authenticator*/ {/*0x1005,*/ 8}, /* WSC_ID_AUTHENTICATOR */
+ {/*0,*/0},
+ {/*0,*/0},
+ /*Config Methods*/ {/*0x1008,*/ 2}, /* WSC_ID_CONFIG_METHODS */
+ /*Configuration Error*/ {/*0x1009,*/ 2}, /* WSC_ID_CONFIG_ERROR */
+ /*Confirmation URL4*/ {/*0x100A,*/ 0x40}, /* <= 64B WSC_ID_CONF_URL4 */
+ /*Confirmation URL6*/ {/*0x100B,*/ 0x4C}, /* <= 76B WSC_ID_CONF_URL6 */
+ /*Connection Type*/ {/*0x100C,*/ 1}, /* WSC_ID_CONN_TYPE */
+ /*Connection Type Flags*/ {/*0x100D,*/ 1}, /* WSC_ID_CONN_TYPE_FLAGS */
+ /*Credential*/ {/*0x100E,*/ 0xff}, /* WSC_ID_CREDENTIAL */
+ /*Encryption Type*/ {/*0x100F,*/ 2}, /* WSC_ID_ENCR_TYPE */
+ /*Encryption Type Flags*/ {/*0x1010,*/ 2}, /* WSC_ID_ENCR_TYPE_FLAGS */
+ /*Device Name*/ {/*0x1011,*/ 0x20}, /* <= 32B WSC_ID_DEVICE_NAME */
+ /*Device Password ID*/ {/*0x1012,*/ 2}, /* WSC_ID_DEVICE_PWD_ID */
+ {/*0,*/0},
+ /*E-Hash1*/ {/*0x1014,*/ 32}, /* WSC_ID_E_HASH1 */
+ /*E-Hash2*/ {/*0x1015,*/ 32}, /* WSC_ID_E_HASH2 */
+ /*E-SNonce1*/ {/*0x1016,*/ 16}, /* WSC_ID_E_SNONCE1 */
+ /*E-SNonce2*/ {/*0x1017,*/ 16}, /* WSC_ID_E_SNONCE2 */
+ /*Encrypted Settings*/ {/*0x1018,*/ 0xff}, /* WSC_ID_ENCR_SETTINGS */
+ {/*0,*/0},
+ /*Enrollee Nonce*/ {/*0x101A,*/ 16}, /* WSC_ID_ENROLLEE_NONCE */
+ /*Feature_ID*/ {/*0x101B,*/ 4}, /* WSC_ID_FEATURE_ID */
+ /*Identity*/ {/*0x101C,*/ 0x50}, /* <= 80B WSC_ID_IDENTITY */
+ {/*0,*/0}, /* WSC_ID_IDENTITY_PROOF */
+ /*Key Wrap Authenticator*/ {/*0x101E,*/ 8}, /* WSC_ID_KEY_WRAP_AUTH */
+ /*Key Identifier*/ {/*0x101F,*/ 16}, /* WSC_ID_KEY_IDENTIFIER */
+ /*MAC Address*/ {/*0x1020,*/ 6}, /* WSC_ID_MAC_ADDR */
+ /*Manufacturer*/ {/*0x1021,*/ 0x40}, /* <= 64B WSC_ID_MANUFACTURER */
+ /*Message Type*/ {/*0x1022,*/ 1}, /* WSC_ID_MSG_TYPE */
+ /*Model Name*/ {/*0x1023,*/ 0x20}, /* <= 32B WSC_ID_MODEL_NAME */
+ /*Model Number*/ {/*0x1024,*/ 0x20}, /* <= 32B WSC_ID_MODEL_NUMBER */
+ {/*0,*/0},
+ /*Network Index*/ {/*0x1026,*/ 1}, /* WSC_ID_NW_INDEX */
+
+ /*
+ Windows 7 WCN test only accept Len of Network Key item in credentail is zero
+ when auth type of AP is OPEN/NONE
+ */
+ /*Network Key*/ {/*0x1027,*/ 0}, /* <= 64B WSC_ID_NW_KEY */
+
+ /*Network Key Index*/ {/*0x1028,*/ 1}, /* WSC_ID_NW_KEY_INDEX */
+ /*New Device Name*/ {/*0x1029,*/ 0x20}, /* <= 32B WSC_ID_NEW_DEVICE_NAME */
+ /*New Password*/ {/*0x102A,*/ 0x40}, /* <= 64B WSC_ID_NEW_PWD */
+ {/*0,*/0},
+ /*OOB Device Password*/ {/*0x102C,*/ 0x3A}, /* <= 58B WSC_ID_OOB_DEV_PWD */
+ /*OS Version*/ {/*0x102D,*/ 4}, /* WSC_ID_OS_VERSION */
+ {/*0,*/0},
+ /*Power Level*/ {/*0x102F,*/ 1}, /* WSC_ID_POWER_LEVEL */
+ /*PSK Current*/ {/*0x1030,*/ 1}, /* WSC_ID_PSK_CURRENT */
+ /*PSK Max*/ {/*0x1031,*/ 1}, /* WSC_ID_PSK_MAX */
+ /*Public Key*/ {/*0x1032,*/ 192}, /* WSC_ID_PUBLIC_KEY */
+ /*Radio Enabled*/ {/*0x1033,*/ 1}, /* WSC_ID_RADIO_ENABLED */
+ /*Reboot*/ {/*0x1034,*/ 1}, /* WSC_ID_REBOOT */
+ /*Registrar Current*/ {/*0x1035,*/ 1}, /* WSC_ID_REGISTRAR_CURRENT */
+ /*Registrar Established*/ {/*0x1036,*/ 1}, /* WSC_ID_REGISTRAR_ESTBLSHD */
+ {/*0,*/0}, /* WSC_ID_REGISTRAR_LIST */
+ /*Registrar Max*/ {/*0x1038,*/ 1}, /* WSC_ID_REGISTRAR_MAX */
+ /*Registrar Nonce*/ {/*0x1039,*/ 16}, /* WSC_ID_REGISTRAR_NONCE */
+ /*Request Type*/ {/*0x103A,*/ 1}, /* WSC_ID_REQ_TYPE */
+ /*Response Type*/ {/*0x103B,*/ 1}, /* WSC_ID_RESP_TYPE */
+ /*RF Bands*/ {/*0x103C,*/ 1}, /* WSC_ID_RF_BAND */
+ /*R-Hash1*/ {/*0x103D,*/ 32}, /* WSC_ID_R_HASH1 */
+ /*R-Hash2*/ {/*0x103E,*/ 32}, /* WSC_ID_R_HASH2 */
+ /*R-SNonce1*/ {/*0x103F,*/ 16}, /* WSC_ID_R_SNONCE1 */
+ /*R-SNonce2*/ {/*0x1040,*/ 16}, /* WSC_ID_R_SNONCE2 */
+ /*Selected Registrar*/ {/*0x1041,*/ 1}, /* WSC_ID_SEL_REGISTRAR */
+ /*Serial Number*/ {/*0x1042,*/ 0x20}, /* <= 32B WSC_ID_SERIAL_NUM */
+ {/*0,*/0},
+ /*Simple Config State*/ {/*0x1044,*/ 1}, /* WSC_ID_SC_STATE */
+ /*SSID*/ {/*0x1045,*/ 0x20}, /* <= 32B WSC_ID_SSID */
+ /*Total Networks*/ {/*0x1046,*/ 1}, /* WSC_ID_TOT_NETWORKS */
+ /*UUID-E*/ {/*0x1047,*/ 16}, /* WSC_ID_UUID_E */
+ /*UUID-R*/ {/*0x1048,*/ 16}, /* WSC_ID_UUID_R */
+ /*WPS Vendor Extension*/ {/*0x1049,*/ 0x400}, /* WSC_ID_VENDOR_EXT */
+ /*Version*/ {/*0x104A,*/ 1}, /* WSC_ID_VERSION */
+ /*X.509 Certificate Request*/ {/*0x104B,*/ 0xff}, /* WSC_ID_X509_CERT_REQ */
+ /*X.509 Certificate*/ {/*0x104C,*/ 0xff}, /* WSC_ID_X509_CERT */
+ /*EAP Identity*/ {/*0x104D,*/ 0x40}, /* <= 64B WSC_ID_EAP_IDENTITY */
+ /*Message Counter*/ {/*0x104E,*/ 8}, /* WSC_ID_MSG_COUNTER */
+ /*Public Key Hash*/ {/*0x104F,*/ 20}, /* WSC_ID_PUBKEY_HASH */
+ /*Rekey Key*/ {/*0x1050,*/ 32}, /* WSC_ID_REKEY_KEY */
+ /*Key Lifetime*/ {/*0x1051,*/ 4}, /* WSC_ID_KEY_LIFETIME */
+ /*Permitted Config Methods*/ {/*0x1052,*/ 2}, /* WSC_ID_PERM_CFG_METHODS */
+ /*Selected Registrar Config Method*/{/*0x1053,*/ 2}, /* WSC_ID_SEL_REG_CFG_METHODS */
+ /*Primary Device Type*/ {/*0x1054,*/ 8}, /* WSC_ID_PRIM_DEV_TYPE */
+ {/*0,*/0}, /* WSC_ID_SEC_DEV_TYPE_LIST */
+ /*Portable Device*/ {/*0x1056,*/ 1}, /* WSC_ID_PORTABLE_DEVICE */
+ /*AP Setup Locked*/ {/*0x1057,*/ 1}, /* WSC_ID_AP_SETUP_LOCKED */
+ {/*0,*/0}, /* WSC_ID_APP_LIST */
+ /*EAP Type*/ {/*0x1059,*/ 0x08}, /* <= 8B WSC_ID_EAP_TYPE */
+ {/*0,*/0},
+ {/*0,*/0},
+ {/*0,*/0},
+ {/*0,*/0},
+ {/*0,*/0},
+ {/*0,*/0},
+ /*Initialization Vector*/ {/*0x1060,*/ 32}, /* WSC_ID_INIT_VECTOR */
+ /*Key Provided Automatically*/ {/*0x1061,*/ 1}, /* WSC_ID_KEY_PROVIDED_AUTO */
+ /*802.1X Enabled*/ {/*0x1062,*/ 1}, /* WSC_ID_8021X_ENABLED */
+ /*<Reserved for WFA> 0x106F ¡V 0x1FFF*/
+ /*<Unavailable> 0x000 ¡V 0x0FFF,0x2000 ¡V 0xFFFF*/
+};
+
+extern UINT8 WPS_DH_G_VALUE[1];
+extern UINT8 WPS_DH_P_VALUE[192];
+
+int AppendWSCTLV(USHORT index, OUT UCHAR * obuf, IN UCHAR * ibuf, IN USHORT varlen)
+{
+ USHORT len, dataLen, tag = cpu2be16(index);
+
+ /*
+ The max len of WPS Vendor Extension is 1024B
+ */
+ dataLen = ( varlen != (USHORT)0 ) ? varlen : wsc_tlv_0b[WSC_TLV_ENT(index)].len;
+
+ NdisMoveMemory(obuf, &tag, 2);
+ len = cpu2be16(dataLen);
+ memcpy(obuf + 2, &len, 2);
+ if (dataLen != 0)
+ memcpy(obuf + 4, ibuf, dataLen);
+ return (dataLen + 4);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process elements encryption settings
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ 1. Recv M4 M5 M6 M7
+
+ ========================================================================
+*/
+static VOID WscParseEncrSettings(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pPlainData,
+ IN INT PlainLength,
+ IN PWSC_CTRL pWscControl)
+{
+ USHORT WscType, WscLen, HmacLen;
+ PUCHAR pData;
+ UCHAR Hmac[8], Temp[32];
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+
+ HmacLen = (USHORT)(PlainLength - 12);
+ pData = pPlainData;
+
+ /* Start to process WSC IEs */
+ while (PlainLength > 4)
+ {
+ WSC_IE TLV_Encr;
+ memcpy((UINT8 *)&TLV_Encr, pData, 4);
+ WscType = be2cpu16(TLV_Encr.Type);
+ WscLen = be2cpu16(TLV_Encr.Length);
+ pData += 4;
+ PlainLength -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_E_SNONCE1:
+ /* for verification with our enrollee nonce */
+ NdisMoveMemory(pReg->Es1, pData, WscLen);
+ break;
+
+ case WSC_ID_E_SNONCE2:
+ /* for verification with our enrollee nonce */
+ NdisMoveMemory(pReg->Es2, pData, WscLen);
+ break;
+
+ case WSC_ID_R_SNONCE1:
+ /* for verification with our enrollee nonce */
+ NdisMoveMemory(pReg->Rs1, pData, WscLen);
+ break;
+
+ case WSC_ID_R_SNONCE2:
+ /* for verification with our enrollee nonce */
+ NdisMoveMemory(pReg->Rs2, pData, WscLen);
+ break;
+
+ case WSC_ID_KEY_WRAP_AUTH:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ break;
+
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscParseEncrSettings --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ PlainLength -= WscLen;
+ }
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pPlainData, HmacLen, Temp, SHA256_DIGEST_SIZE);
+
+ if (RTMPEqualMemory(Hmac, Temp, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("WscParseEncrSettings --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Temp[0])), (UINT)cpu2be32(*((PUINT) &Temp[4]))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process credentials within AP encryption settings
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ 1. Recv M8
+
+ ========================================================================
+*/
+static BOOLEAN WscProcessCredential(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pPlainData,
+ IN INT PlainLength,
+ IN PWSC_CTRL pWscControl)
+{
+ USHORT WscType, WscLen, Cnt = 0, CurrentIdx=0, Idx, tmpVal = 0;
+ PUCHAR pData, pTmp;
+ PWSC_PROFILE pProfile;
+#ifdef WSC_V2_SUPPORT
+ BOOLEAN bReject = FALSE;
+#endif /* WSC_V2_SUPPORT */
+
+ pData = pPlainData;
+
+ /* Cleanup Old contents */
+ NdisZeroMemory(&pWscControl->WscProfile, sizeof(WSC_PROFILE));
+
+ pProfile = (PWSC_PROFILE) &pWscControl->WscProfile;
+ /*CurrentIdx = pWscControl->EntryIfIdx; */
+
+ /* Init Profile number */
+ Cnt = 0;
+
+ hex_dump("WscProcessCredential - PlainData", pPlainData, PlainLength);
+ /* Start to process WSC IEs within credential */
+ while (PlainLength > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ PlainLength -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_NW_INDEX:
+ /* A new profile, add the cnt and save to database */
+ CurrentIdx = Cnt; /* since the index start from 0, we have to minus 1 */
+ Cnt++;
+ break;
+
+ case WSC_ID_SSID:
+ /* Find the exact length of SSID without null terminator */
+ pTmp = pData;
+ for (Idx = 0; Idx < WscLen; Idx++)
+ {
+ if (*(pTmp++) == 0x0)
+ break;
+ }
+ pProfile->Profile[CurrentIdx].SSID.SsidLength = Idx;
+ if (RTMPCheckStrPrintAble((CHAR *)pData, Idx) || (pWscControl->bCheckMultiByte == FALSE))
+ NdisMoveMemory(pProfile->Profile[CurrentIdx].SSID.Ssid, pData, pProfile->Profile[CurrentIdx].SSID.SsidLength);
+ else
+ return FALSE;
+ break;
+
+ case WSC_ID_AUTH_TYPE:
+ tmpVal = get_unaligned((PUSHORT) pData);
+ pProfile->Profile[CurrentIdx].AuthType = cpu2be16(tmpVal); /*cpu2be16(*((PUSHORT) pData));//(UINT8 *)&pReg->RegistrarInfo.AuthTypeFlags */
+ break;
+
+ case WSC_ID_ENCR_TYPE:
+ tmpVal = get_unaligned((PUSHORT) pData);
+ pProfile->Profile[CurrentIdx].EncrType = cpu2be16(tmpVal);/*cpu2be16(*((PUSHORT) pData));//(UINT8 *)&pReg->RegistrarInfo.EncrTypeFlags */
+ break;
+
+ case WSC_ID_NW_KEY_INDEX:
+ /* Netork Key Index: 1 ~ 4 */
+ pProfile->Profile[CurrentIdx].KeyIndex = (*pData);
+ break;
+
+ case WSC_ID_NW_KEY:
+ if (WscLen == 0)
+ break;
+
+ if (RTMPCheckStrPrintAble((CHAR *)pData, WscLen) || (pWscControl->bCheckMultiByte == FALSE))
+ {
+ pProfile->Profile[CurrentIdx].KeyLength = WscLen;
+ NdisMoveMemory(pProfile->Profile[CurrentIdx].Key, pData, pProfile->Profile[CurrentIdx].KeyLength);
+ }
+ else
+ return FALSE;
+ break;
+
+ case WSC_ID_MAC_ADDR:
+ /*
+ Some AP (ex. Buffalo WHR-G300N WPS AP) would change BSSID during WPS processing.
+ STA shall not change MacAddr of credential form AP.
+ */
+ RTMPMoveMemory(pProfile->Profile[CurrentIdx].MacAddr, pData, MAC_ADDR_LEN);
+ break;
+
+ case WSC_ID_KEY_WRAP_AUTH:
+ /* Not used here, since we already verify it at decryption */
+ break;
+
+ case WSC_ID_CREDENTIAL:
+ /* Credential IE, The WscLen include all length within profile, we need to modify it */
+ /* to be able to parse all profile fields */
+ WscLen = 0;
+ break;
+
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("WscProcessCredential --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ PlainLength -= WscLen;
+ }
+
+ /* Svae the total number */
+ pProfile->ProfileCnt = (UINT)Cnt;
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /*
+ Check all credentials
+ */
+ for (Idx = 0; Idx < pProfile->ProfileCnt; Idx++)
+ {
+ PWSC_CREDENTIAL pCredential = &pProfile->Profile[Idx];
+ /*if ((pCredential->EncrType != WSC_ENCRTYPE_WEP) && (pCredential->EncrType != WSC_ENCRTYPE_TKIP)) */
+ if (pCredential->EncrType == WSC_ENCRTYPE_WEP)
+ {
+ bReject = TRUE;
+ /* Cleanup contents */
+ NdisZeroMemory(&pWscControl->WscProfile, sizeof(WSC_PROFILE));
+ }
+ }
+
+ if (bReject)
+ return FALSE;
+ }
+#endif /* WSC_V2_SUPPORT */
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscProcessCredential --> %d profile retrieved from credential\n", Cnt));
+ return TRUE;
+}
+
+/* return 0 to success ,1 to failed */
+int WscDeriveKey (
+ unsigned char *kdk, unsigned int kdk_len,
+ unsigned char *prsnlString, unsigned int str_len,
+ unsigned char *key, unsigned int keyBits )
+{
+ unsigned int i = 0, iterations = 0;
+ unsigned char input[64], output[128];
+ unsigned char hmac[32];
+ unsigned int temp;
+
+ iterations = ((keyBits/8) + 32 - 1)/32;
+
+ /*Prepare the input buffer. During the iterations, we need only replace the */
+ /*value of i at the start of the buffer. */
+ temp = cpu2be32(i);
+ memcpy(input, &temp, 4);
+ memcpy(input+4, prsnlString, str_len);
+
+ temp = cpu2be32(keyBits);
+ memcpy(input+4+str_len, &temp, 4);
+
+ for(i = 0; i < iterations; i++)
+ {
+ /*Set the current value of i at the start of the input buffer */
+ temp = cpu2be32(i+1); /*i should start at 1 */
+ memcpy(input,&temp,4);
+ RT_HMAC_SHA256(kdk, kdk_len, input, 4+str_len+4, hmac, SHA256_DIGEST_SIZE);
+ memcpy(output+i*32, hmac, 32);
+ }
+
+ /*Sanity check */
+ if(keyBits/8 > (32*iterations))
+ {
+
+ return 1; /*failed */
+ }
+
+ memcpy(key, output, 80);
+
+ return 0; /*success */
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M1 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx EAP-Req(ID)
+ 1. Change the correct parameters
+ 2. Build M1
+
+ ========================================================================
+*/
+int BuildMessageM1(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[1];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+ INT idx;
+ USHORT ConfigError = 0, ConfigMethods = 0;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+ UCHAR CurOpMode = 0xFF;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M1 */
+ TB[0] = WSC_ID_MESSAGE_M1;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. UUID_E, last 6 bytes use MAC */
+ /*templen = AppendWSCTLV(WSC_ID_UUID_E, pData, pReg->EnrolleeInfo.Uuid, 0); */
+ templen = AppendWSCTLV(WSC_ID_UUID_E, pData, &pWscControl->Wsc_Uuid_E[0], 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. MAC address */
+ templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, pReg->SelfInfo.MacAddr, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Enrollee Nonce, first generate and save to Wsc Control Block */
+ for (idx = 0; idx < 16; idx++)
+ {
+ pReg->SelfNonce[idx] = RandomByte(pAdapter);
+ pReg->EnrolleeNonce[idx] = pReg->SelfNonce[idx];
+ }
+ /* 5. Enrollee Nonce, first generate and save to Wsc Control Block */
+ NdisMoveMemory(pReg->EnrolleeNonce, pReg->SelfNonce, 16);
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->SelfNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 6. Public Key, 192 bytes */
+ templen = AppendWSCTLV(WSC_ID_PUBLIC_KEY, pData, pReg->Pke, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 7. Authentication Type Flags */
+ templen = AppendWSCTLV(WSC_ID_AUTH_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.AuthTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 8. Encryption Type Flags */
+ templen = AppendWSCTLV(WSC_ID_ENCR_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.EncrTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 9. Connection Type Flag ESS */
+ templen = AppendWSCTLV(WSC_ID_CONN_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.ConnTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /*10. Config Method */
+ /*pReg->SelfInfo.ConfigMethods = cpu2be16(pWscControl->WscConfigMethods);*/
+ ConfigMethods = pWscControl->WscConfigMethods;
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /*
+ AP MUST NOT support using PBC to add an external Registrar
+ */
+ if (CurOpMode == AP_MODE)
+ {
+ ConfigMethods = (pWscControl->WscConfigMethods & 0x210F); //sync by 7610
+ }
+ }
+ else
+#endif /* WSC_V2_SUPPORT */
+ {
+ /*
+ WSC 1.0 WCN logo testing has AP PBC Enrollee testing item.
+ We cannot remove PBC capability here.
+ */
+ ConfigMethods = (pWscControl->WscConfigMethods & 0x00FF);
+ }
+
+ ConfigMethods = cpu2be16(ConfigMethods);
+ templen = AppendWSCTLV(WSC_ID_CONFIG_METHODS, pData, (UINT8 *)&ConfigMethods, 0);
+ pData += templen;
+ Len += templen;
+
+ /*11. Simple Config State (Not Configured) */
+ if (CurOpMode == AP_MODE)
+ pReg->SelfInfo.ScState = pWscControl->WscConfStatus;
+ templen = AppendWSCTLV(WSC_ID_SC_STATE, pData, (UINT8 *)&pReg->SelfInfo.ScState, 0);
+ pData += templen;
+ Len += templen;
+
+ /*12. Manufacture */
+ templen = AppendWSCTLV(WSC_ID_MANUFACTURER, pData, pReg->SelfInfo.Manufacturer, strlen((PSTRING) pReg->SelfInfo.Manufacturer));
+ pData += templen;
+ Len += templen;
+
+ /*13. Model Name */
+ templen = AppendWSCTLV(WSC_ID_MODEL_NAME, pData, pReg->SelfInfo.ModelName, strlen((PSTRING) pReg->SelfInfo.ModelName));
+ pData += templen;
+ Len += templen;
+
+ /*14. Model Number */
+ templen = AppendWSCTLV(WSC_ID_MODEL_NUMBER, pData, pReg->SelfInfo.ModelNumber, strlen((PSTRING) pReg->SelfInfo.ModelNumber));
+ pData += templen;
+ Len += templen;
+
+ /*15. Serial Number */
+ templen = AppendWSCTLV(WSC_ID_SERIAL_NUM, pData, pReg->SelfInfo.SerialNumber, strlen((PSTRING) pReg->SelfInfo.SerialNumber));
+ pData += templen;
+ Len += templen;
+
+ /*16. Primary Device Type */
+ templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0);
+ pData += templen;
+ Len += templen;
+
+ /*17. Device Name */
+ templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, pReg->SelfInfo.DeviceName, strlen((PSTRING) pReg->SelfInfo.DeviceName));
+ pData += templen;
+ Len += templen;
+
+ /*18. RF Band */
+ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, (UINT8 *)&pReg->SelfInfo.RfBand, 0);
+ pData += templen;
+ Len += templen;
+
+ /*19. Associate state (Not associated) */
+ templen = AppendWSCTLV(WSC_ID_ASSOC_STATE, pData, (UINT8 *)&pReg->SelfInfo.AssocState, 0);
+ pData += templen;
+ Len += templen;
+
+ /*20. Device Password ID */
+ templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&pReg->SelfInfo.DevPwdId, 0);
+ pData += templen;
+ Len += templen;
+
+ /*21. Configure Error */
+ templen = AppendWSCTLV(WSC_ID_CONFIG_ERROR, pData, (UINT8 *)&ConfigError, 0);
+ pData += templen;
+ Len += templen;
+
+ /*22. OS Version Not associated) */
+ templen = AppendWSCTLV(WSC_ID_OS_VERSION, pData, (UINT8 *)&pReg->SelfInfo.OsVersion, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+
+
+#ifdef WSC_V2_SUPPORT
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscControl->WscV2Info.bEnableWpsV2 && pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+#endif /* WSC_V2_SUPPORT */
+ //sync by 7610
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM1 - bUPnPMsgTimerRunning = %d, pWscControl->WscUseUPnP = %d, pWscControl->EapMsgRunning = %d\n",
+ pWscControl->WscUPnPNodeInfo.bUPnPMsgTimerRunning,
+ pWscControl->WscUseUPnP,
+ pWscControl->EapMsgRunning));
+
+ /* Fixed WCN vista logo 2 registrar test item issue. */
+ /* Also prevent that WCN GetDeviceInfo disturbs EAP processing. */
+ if (pWscControl->WscUPnPNodeInfo.bUPnPMsgTimerRunning ||
+ (pWscControl->WscUseUPnP && pWscControl->EapMsgRunning))
+ ;
+ else
+ {
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+ }
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM1.\n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M2 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M1
+ 1. Change the correct parameters
+ 2. Build M2
+
+ ========================================================================
+*/
+int BuildMessageM2(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[1];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf, pAuth;
+ PWSC_REG_DATA pReg;
+ UCHAR DHKey[32], KDK[32], KdkInput[38], KdfKey[80];
+ INT DH_Len;
+ INT HmacLen = 0;
+ INT idx;
+ USHORT ConfigMethods;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+ pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+
+ DH_Len = sizeof(pReg->SecretKey);
+ RT_DH_SecretKey_Generate (
+ pReg->Pke, sizeof(pReg->Pke),
+ WPS_DH_P_VALUE, sizeof(WPS_DH_P_VALUE),
+ pReg->EnrolleeRandom, sizeof(pReg->EnrolleeRandom),
+ pReg->SecretKey, (UINT *) &DH_Len);
+ RT_SHA256(&pReg->SecretKey[0], 192, &DHKey[0]);
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M2 */
+ TB[0] = WSC_ID_MESSAGE_M2;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* fixed config Windows 7 issue */
+ /* Enrollee Nonce, first generate and save to Wsc Control Block */
+ for (idx = 0; idx < 16; idx++)
+ {
+ pReg->SelfNonce[idx] = RandomByte(pAdapter);
+ pReg->RegistrarNonce[idx] = pReg->SelfNonce[idx];
+ }
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* UUID, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_UUID_R, pData, pReg->SelfInfo.Uuid, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Publikc Key */
+ templen = AppendWSCTLV(WSC_ID_PUBLIC_KEY, pData, pReg->Pkr, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Authentication Type Flags */
+ templen = AppendWSCTLV(WSC_ID_AUTH_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.AuthTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Encrypt Type */
+ templen = AppendWSCTLV(WSC_ID_ENCR_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.EncrTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Connection Type */
+ templen = AppendWSCTLV(WSC_ID_CONN_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.ConnTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Config Method */
+ ConfigMethods = pWscControl->WscConfigMethods;
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ //sync by 7610
+ /*
+ In WPS 2.0.0
+ In Test Item 4.1.1 ,Step 13
+ On the sniffer device, verify that the M2 message that the APUT sends includes
+ the Configuration Methods attribute. The Configuration Methods attribute in the
+ WSC IE must reflect the correct configuration methods that the Internal Registrar
+ supports.
+ */
+ }
+ else
+ {
+ ConfigMethods = (pWscControl->WscConfigMethods & 0x00FF);
+ }
+#endif /* WSC_V2_SUPPORT */
+ ConfigMethods = cpu2be16(ConfigMethods);
+ templen = AppendWSCTLV(WSC_ID_CONFIG_METHODS, pData, (UINT8 *)&ConfigMethods, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Manufacture Name */
+ templen = AppendWSCTLV(WSC_ID_MANUFACTURER, pData, pReg->SelfInfo.Manufacturer, strlen((PSTRING) pReg->SelfInfo.Manufacturer));
+ pData += templen;
+ Len += templen;
+
+ /* Model Name */
+ templen = AppendWSCTLV(WSC_ID_MODEL_NAME, pData, pReg->SelfInfo.ModelName, strlen((PSTRING) pReg->SelfInfo.ModelName));
+ pData += templen;
+ Len += templen;
+
+ /* Model Number */
+ templen = AppendWSCTLV(WSC_ID_MODEL_NUMBER, pData, pReg->SelfInfo.ModelNumber, strlen((PSTRING) pReg->SelfInfo.ModelNumber));
+ pData += templen;
+ Len += templen;
+
+ /* Serial Number */
+ templen = AppendWSCTLV(WSC_ID_SERIAL_NUM, pData, pReg->SelfInfo.SerialNumber, strlen((PSTRING) pReg->SelfInfo.SerialNumber));
+ pData += templen;
+ Len += templen;
+
+ /* Prime Device Type */
+ templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Device Name */
+ templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, pReg->SelfInfo.DeviceName, strlen((PSTRING) pReg->SelfInfo.DeviceName));
+ pData += templen;
+ Len += templen;
+
+ /* RF Band */
+ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, (UINT8 *)&pReg->SelfInfo.RfBand, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Assoc State */
+ templen = AppendWSCTLV(WSC_ID_ASSOC_STATE, pData, (UINT8 *)&pReg->SelfInfo.AssocState, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Config Error */
+ templen = AppendWSCTLV(WSC_ID_CONFIG_ERROR, pData, (UINT8 *)&pReg->SelfInfo.ConfigError, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Device Password ID */
+ templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&pReg->SelfInfo.DevPwdId, 0);
+ pData += templen;
+ Len += templen;
+
+ /* OS Version */
+ templen = AppendWSCTLV(WSC_ID_OS_VERSION, pData, (UINT8 *)&pReg->SelfInfo.OsVersion, 0);
+ pData += templen;
+ Len += templen;
+
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ /* Create KDK input data */
+ NdisMoveMemory(&KdkInput[0], &pReg->EnrolleeNonce[0], 16);
+ NdisMoveMemory(&KdkInput[16], &pReg->PeerInfo.MacAddr[0], 6);
+ NdisMoveMemory(&KdkInput[22], pReg->RegistrarNonce, 16);
+
+ /* Generate the KDK */
+ RT_HMAC_SHA256(DHKey, 32, KdkInput, 38, KDK, SHA256_DIGEST_SIZE);
+
+ /* KDF */
+ WscDeriveKey(KDK, 32, Wsc_Personal_String, (sizeof(Wsc_Personal_String) - 1), KdfKey, 640);
+
+ /* Assign Key from KDF */
+ NdisMoveMemory(pReg->AuthKey, &KdfKey[0], 32);
+ NdisMoveMemory(pReg->KeyWrapKey, &KdfKey[32], 16);
+ NdisMoveMemory(pReg->Emsk, &KdfKey[48], 32);
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = Len + pReg->LastRx.Length;
+ if (pAdapter->pHmacData)
+ {
+ pAuth = (PUCHAR) pAdapter->pHmacData;
+ NdisMoveMemory(pAuth, pReg->LastRx.Data, pReg->LastRx.Length);
+ pAuth += pReg->LastRx.Length;
+ NdisMoveMemory(pAuth, pbuf, Len);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+ /* 22. Hmac */
+ templen = AppendWSCTLV(WSC_ID_AUTHENTICATOR, pData, KDK, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM2.\n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M2D Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M1 process Error
+ 1. Change the correct parameters
+ 2. Build M2D
+
+ ========================================================================
+*/
+int BuildMessageM2D(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[1];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M2D */
+ TB[0] = WSC_ID_MESSAGE_M2D;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->SelfNonce, 0);
+ /*templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0); */
+ pData += templen;
+ Len += templen;
+
+ /* UUID, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_UUID_R, pData, pReg->SelfInfo.Uuid, 0);
+ pData += templen;
+ Len += templen;
+
+
+ /* 7. Authentication Type Flags */
+ templen = AppendWSCTLV(WSC_ID_AUTH_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.AuthTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Encrypt Type */
+ templen = AppendWSCTLV(WSC_ID_ENCR_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.EncrTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Connection Type */
+ templen = AppendWSCTLV(WSC_ID_CONN_TYPE_FLAGS, pData, (UINT8 *)&pReg->SelfInfo.ConnTypeFlags, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Config Methods */
+ templen = AppendWSCTLV(WSC_ID_CONFIG_METHODS, pData, (UINT8 *)&pReg->SelfInfo.ConfigMethods, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Manufacturer Name */
+ templen = AppendWSCTLV(WSC_ID_MANUFACTURER, pData, pReg->SelfInfo.Manufacturer, strlen((PSTRING) pReg->SelfInfo.Manufacturer));
+ pData += templen;
+ Len += templen;
+
+ /* Model Name */
+ templen = AppendWSCTLV(WSC_ID_MODEL_NAME, pData, pReg->SelfInfo.ModelName, strlen((PSTRING) pReg->SelfInfo.ModelName));
+ pData += templen;
+ Len += templen;
+
+ /* Model Number */
+ templen = AppendWSCTLV(WSC_ID_MODEL_NUMBER, pData, pReg->SelfInfo.ModelNumber, strlen((PSTRING) pReg->SelfInfo.ModelNumber));
+ pData += templen;
+ Len += templen;
+
+ /* Serial Number */
+ templen = AppendWSCTLV(WSC_ID_SERIAL_NUM, pData, pReg->SelfInfo.SerialNumber, strlen((PSTRING) pReg->SelfInfo.SerialNumber));
+ pData += templen;
+ Len += templen;
+
+ /* Prime Device Type */
+ templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Device Name */
+ templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, pReg->SelfInfo.DeviceName, strlen((PSTRING) pReg->SelfInfo.DeviceName));
+ pData += templen;
+ Len += templen;
+
+ /* RF Band */
+ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, (UINT8 *)&pReg->SelfInfo.RfBand, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Assoc State */
+ templen = AppendWSCTLV(WSC_ID_ASSOC_STATE, pData, (UINT8 *)&pReg->SelfInfo.AssocState, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Config Error */
+ templen = AppendWSCTLV(WSC_ID_CONFIG_ERROR, pData, (UINT8 *)&pReg->SelfInfo.ConfigError, 0);
+ pData += templen;
+ Len += templen;
+
+ /* OS Version */
+ templen = AppendWSCTLV(WSC_ID_OS_VERSION, pData, (UINT8 *)&pReg->SelfInfo.OsVersion, 0);
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM2D.\n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M3 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M2
+ 1. Change the correct parameters
+ 2. Build M3
+
+ ========================================================================
+*/
+int BuildMessageM3(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[32];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf, pAuth;
+ PWSC_REG_DATA pReg = NULL;
+ INT HmacLen;
+ UCHAR *pHash=NULL;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+/* pHash = kmalloc(512, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&pHash, 512);
+ if(NULL == pHash)
+ return Len;
+ pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M3 */
+ TB[0] = WSC_ID_MESSAGE_M3;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. E-Hash1 */
+ /* */
+ /* Generate PSK1 */
+ if (pReg->PinCodeLen == 4)
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pReg->PIN, 2, TB, SHA256_DIGEST_SIZE);
+ else
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pReg->PIN, 4, TB, SHA256_DIGEST_SIZE);
+
+ /* Copy first 16 bytes to PSK1 */
+ NdisMoveMemory(pReg->Psk1, TB, 16);
+
+ /* Create input for E-Hash1 */
+ NdisMoveMemory(pHash, pReg->Es1, 16);
+ NdisMoveMemory(pHash + 16, pReg->Psk1, 16);
+ NdisMoveMemory(pHash + 32, pReg->Pke, 192);
+ NdisMoveMemory(pHash + 224, pReg->Pkr, 192);
+
+ /* Generate E-Hash1 */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pHash, 416, pReg->EHash1, SHA256_DIGEST_SIZE);
+
+ templen = AppendWSCTLV(WSC_ID_E_HASH1, pData, pReg->EHash1, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 5. E-Hash2 */
+ /* */
+ /* Generate PSK2 */
+ if (pReg->PinCodeLen == 4)
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &pReg->PIN[2], 2, TB, SHA256_DIGEST_SIZE);
+ else
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &pReg->PIN[4], 4, TB, SHA256_DIGEST_SIZE);
+
+ /* Copy first 16 bytes to PSK2 */
+ NdisMoveMemory(pReg->Psk2, TB, 16);
+
+ /* Create input for E-Hash2 */
+ NdisMoveMemory(pHash, pReg->Es2, 16);
+ NdisMoveMemory(pHash + 16, pReg->Psk2, 16);
+ NdisMoveMemory(pHash + 32, pReg->Pke, 192);
+ NdisMoveMemory(pHash + 224, pReg->Pkr, 192);
+
+ /* Generate E-Hash2 */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pHash, 416, pReg->EHash2, SHA256_DIGEST_SIZE);
+
+ templen = AppendWSCTLV(WSC_ID_E_HASH2, pData, pReg->EHash2, 0);
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ /*
+ Generate authenticator
+ Combine last TX & RX message contents and validate the HMAC
+ */
+ HmacLen = Len + pReg->LastRx.Length;
+ if (pAdapter->pHmacData)
+ {
+ pAuth = (PUCHAR) pAdapter->pHmacData;
+ NdisMoveMemory(pAuth, pReg->LastRx.Data, pReg->LastRx.Length);
+ pAuth += pReg->LastRx.Length;
+ NdisMoveMemory(pAuth, pbuf, Len);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, TB, SHA256_DIGEST_SIZE);
+ }
+
+ templen = AppendWSCTLV(WSC_ID_AUTHENTICATOR, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+
+ if(NULL != pHash)
+/* kfree(pHash); */
+ os_free_mem(NULL, pHash);
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM3 : \n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M4 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M3
+ 1. Change the correct parameters
+ 2. Build M4
+
+ ========================================================================
+*/
+int BuildMessageM4(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[32];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf, pAuth;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+ INT HmacLen;
+ UCHAR KDK[32];
+ UCHAR Plain[128]; /*, IV_EncrData[144];//IV len 16,EncrData len 128 */
+ UCHAR *IV_EncrData = NULL;/*IV len 16,EncrData len 128 */
+ INT PlainLen = 0, EncrLen;
+ UCHAR *pHash=NULL;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+/* pHash = kmalloc(512, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&pHash, 512);
+ if(NULL == pHash)
+ return Len;
+
+ os_alloc_mem(NULL, (UCHAR **)&IV_EncrData, IV_ENCR_DATA_LEN_144);
+ if (IV_EncrData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M4 */
+ TB[0] = WSC_ID_MESSAGE_M4;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. R-Hash1 */
+ /* */
+ /* Generate PSK1 */
+ if (pReg->PinCodeLen == 4)
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pReg->PIN, 2, TB, SHA256_DIGEST_SIZE);
+ else
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pReg->PIN, 4, TB, SHA256_DIGEST_SIZE);
+
+ /* Copy first 16 bytes to PSK1 */
+ NdisMoveMemory(pReg->Psk1, TB, 16);
+
+ /* Create input for R-Hash1 */
+ NdisMoveMemory(pHash, pReg->Es1, 16);
+ NdisMoveMemory(pHash + 16, pReg->Psk1, 16);
+ NdisMoveMemory(pHash + 32, pReg->Pke, 192);
+ NdisMoveMemory(pHash + 224, pReg->Pkr, 192);
+
+ /* Generate R-Hash1 */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pHash, 416, pReg->RHash1, SHA256_DIGEST_SIZE);
+
+ templen = AppendWSCTLV(WSC_ID_R_HASH1, pData, pReg->RHash1, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 5. R-Hash2 */
+ /* */
+ /* Generate PSK2 */
+ if (pReg->PinCodeLen == 4)
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &pReg->PIN[2], 2, TB, SHA256_DIGEST_SIZE);
+ else
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &pReg->PIN[4], 4, TB, SHA256_DIGEST_SIZE);
+
+ /* Copy first 16 bytes to PSK2 */
+ NdisMoveMemory(pReg->Psk2, TB, 16);
+
+ /* Create input for R-Hash2 */
+ NdisMoveMemory(pHash, pReg->Es2, 16);
+ NdisMoveMemory(pHash + 16, pReg->Psk2, 16);
+ NdisMoveMemory(pHash + 32, pReg->Pke, 192);
+ NdisMoveMemory(pHash + 224, pReg->Pkr, 192);
+
+ /* Generate R-Hash2 */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pHash, 416, pReg->RHash2, SHA256_DIGEST_SIZE);
+
+ templen = AppendWSCTLV(WSC_ID_R_HASH2, pData, pReg->RHash2, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 6a. Encrypted R-S1 */
+ /* Prepare plain text */
+ PlainLen += AppendWSCTLV(WSC_ID_R_SNONCE1, &Plain[0], pReg->Es1, 0);
+
+ /* Generate HMAC */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &Plain[0], PlainLen, TB, SHA256_DIGEST_SIZE);
+ PlainLen += AppendWSCTLV(WSC_ID_KEY_WRAP_AUTH, &Plain[PlainLen], TB, 0);
+
+ /* 6b. Encrypted Settings */
+ /* Encrypt data */
+ EncrLen = IV_ENCR_DATA_LEN_144 - 16;
+ AES_CBC_Encrypt(Plain, PlainLen,pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),&IV_EncrData[0], 16, (UINT8 *) &IV_EncrData[16], (UINT *) &EncrLen);
+ templen = AppendWSCTLV(WSC_ID_ENCR_SETTINGS, pData, &IV_EncrData[0], 16 + EncrLen);/*IVLen + EncrLen */
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ /*
+ Combine last TX & RX message contents and validate the HMAC
+ We have to exclude last 12 bytes from last receive since it's authenticator value
+ */
+ HmacLen = Len + pReg->LastRx.Length;
+ if (pAdapter->pHmacData)
+ {
+ pAuth = (PUCHAR) pAdapter->pHmacData;
+ NdisMoveMemory(pAuth, pReg->LastRx.Data, pReg->LastRx.Length);
+ pAuth += pReg->LastRx.Length;
+ NdisMoveMemory(pAuth, pbuf, Len);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+
+ templen = AppendWSCTLV(WSC_ID_AUTHENTICATOR, pData, KDK, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+
+LabelErr:
+ if(NULL != pHash)
+/* kfree(pHash); */
+ os_free_mem(NULL, pHash);
+
+ pWscControl->WscRetryCount = 0;
+
+ if (IV_EncrData != NULL)
+ os_free_mem(NULL, IV_EncrData);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM4 : \n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M5 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M4
+ 1. Change the correct parameters
+ 2. Build M5
+
+ ========================================================================
+*/
+int BuildMessageM5(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[32];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+ PUCHAR pAuth;
+ INT HmacLen;
+ UCHAR Plain[128]; /*, IV_EncrData[144];//IV len 16,EncrData len 128 */
+ UCHAR *IV_EncrData = NULL;/*IV len 16,EncrData len 128 */
+ INT PlainLen=0, EncrLen;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&IV_EncrData, IV_ENCR_DATA_LEN_144);
+ if (IV_EncrData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return 0;
+ }
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M5 */
+ TB[0] = WSC_ID_MESSAGE_M5;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4a. Encrypted E-S1 */
+ /* Prepare plain text */
+ PlainLen += AppendWSCTLV(WSC_ID_E_SNONCE1, &Plain[0], pReg->Es1, 0);
+
+ /* Generate HMAC */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &Plain[0], PlainLen, TB, SHA256_DIGEST_SIZE);
+ PlainLen += AppendWSCTLV(WSC_ID_KEY_WRAP_AUTH, &Plain[PlainLen], TB, 0);
+
+ /* 4b. Encrypted Settings */
+ /* Encrypt data */
+ EncrLen = IV_ENCR_DATA_LEN_144 - 16;
+ AES_CBC_Encrypt(Plain, PlainLen,pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),&IV_EncrData[0], 16, (UINT8 *) &IV_EncrData[16], (UINT *) &EncrLen);
+ templen = AppendWSCTLV(WSC_ID_ENCR_SETTINGS, pData, &IV_EncrData[0], 16 + EncrLen);/*IVLen + EncrLen */
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ /*
+ Generate authenticator
+ Combine last TX & RX message contents and validate the HMAC
+ */
+ HmacLen = Len + pReg->LastRx.Length;
+ if (pAdapter->pHmacData)
+ {
+ pAuth = (PUCHAR) pAdapter->pHmacData;
+ NdisMoveMemory(pAuth, pReg->LastRx.Data, pReg->LastRx.Length);
+ pAuth += pReg->LastRx.Length;
+ NdisMoveMemory(pAuth, pbuf, Len);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, TB, SHA256_DIGEST_SIZE);
+ }
+
+ templen = AppendWSCTLV(WSC_ID_AUTHENTICATOR, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+
+ pWscControl->WscRetryCount = 0;
+
+ if (IV_EncrData != NULL)
+ os_free_mem(NULL, IV_EncrData);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM5 : \n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M6 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M5
+ 1. Change the correct parameters
+ 2. Build M6
+
+ ========================================================================
+*/
+int BuildMessageM6(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[32];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf, pAuth;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+ INT HmacLen;
+ UCHAR KDK[32];
+ UCHAR Plain[128]; /*, IV_EncrData[144];//IV len 16,EncrData len 128 */
+ UCHAR *IV_EncrData = NULL;/*IV len 16,EncrData len 128 */
+ INT PlainLen = 0, EncrLen;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&IV_EncrData, 144);
+ if (IV_EncrData == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ return 0;
+ }
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M6 */
+ TB[0] = WSC_ID_MESSAGE_M6;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4a. Encrypted R-S2 */
+ /* Prepare plain text */
+ PlainLen += AppendWSCTLV(WSC_ID_R_SNONCE2, &Plain[0], pReg->Es2, 0);
+
+ /* Generate HMAC */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &Plain[0], PlainLen, TB, SHA256_DIGEST_SIZE);
+ PlainLen += AppendWSCTLV(WSC_ID_KEY_WRAP_AUTH, &Plain[PlainLen], TB, 0);
+
+ /* 4b. Encrypted Settings */
+ /* Encrypt data */
+ EncrLen = IV_ENCR_DATA_LEN_144 - 16;
+ AES_CBC_Encrypt(Plain, PlainLen,pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),&IV_EncrData[0], 16, (UINT8 *) &IV_EncrData[16], (UINT *) &EncrLen);
+ templen = AppendWSCTLV(WSC_ID_ENCR_SETTINGS, pData, &IV_EncrData[0], 16 + EncrLen);/*IVLen + EncrLen */
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ /*
+ Combine last TX & RX message contents and validate the HMAC
+ We have to exclude last 12 bytes from last receive since it's authenticator value
+ */
+ HmacLen = Len + pReg->LastRx.Length;
+ if (pAdapter->pHmacData)
+ {
+ pAuth = (PUCHAR) pAdapter->pHmacData;
+ NdisMoveMemory(pAuth, pReg->LastRx.Data, pReg->LastRx.Length);
+ pAuth += pReg->LastRx.Length;
+ NdisMoveMemory(pAuth, pbuf, Len);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+
+ templen = AppendWSCTLV(WSC_ID_AUTHENTICATOR, pData, KDK, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+
+ pWscControl->WscRetryCount = 0;
+
+ if (IV_EncrData != NULL)
+ os_free_mem(NULL, IV_EncrData);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM6 : \n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M7 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M6
+ 1. Change the correct parameters
+ 2. Build M7
+
+ ========================================================================
+*/
+int BuildMessageM7(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[32];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf, pAuth;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+ INT HmacLen;
+ UCHAR Plain[256], *IV_EncrData=NULL;/*IV len 16 ,EncrData len */
+ INT PlainLen=0, EncrLen;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+ UCHAR CurOpMode = 0xFF;
+
+/* IV_EncrData = kmalloc(512, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&IV_EncrData, IV_ENCR_DATA_LEN_512);
+ if(NULL == IV_EncrData)
+ return 0;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M7 */
+ TB[0] = WSC_ID_MESSAGE_M7;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4a. Encrypted E-S2 */
+ /* Prepare plain text */
+ PlainLen += AppendWSCTLV(WSC_ID_E_SNONCE2, &Plain[0], pReg->Es2, 0);
+
+ /* Marvell WPS AP doesn't accept STA includes profile in M7. 20070604 */
+ if ((CurOpMode == AP_MODE) &&
+ (pWscControl->EntryIfIdx < MIN_NET_DEVICE_FOR_APCLI))
+ {
+ USHORT authType;
+ USHORT encyType;
+ PWSC_CREDENTIAL pCredential = &pWscControl->WscProfile.Profile[0];
+ WscCreateProfileFromCfg(pAdapter, ENROLLEE_ACTION | AP_MODE, pWscControl, &pWscControl->WscProfile);
+
+ authType = pCredential->AuthType;
+ encyType = pCredential->EncrType;
+ /*
+ Some Win7 WSC 1.0 STA has problem to receive mixed authType and encyType.
+ We need to check STA is WSC 1.0 or WSC 2.0 here.
+ If STA is WSC 1.0, re-assign authType and encyType.
+ */
+ if (pWscControl->RegData.PeerInfo.Version2 == 0)
+ {
+ if (authType == (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK))
+ authType = WSC_AUTHTYPE_WPA2PSK;
+ if (encyType == (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES))
+ encyType = WSC_ENCRTYPE_AES;
+ }
+ authType = cpu2be16(authType);
+ encyType = cpu2be16(encyType);
+ PlainLen += AppendWSCTLV(WSC_ID_SSID, &Plain[PlainLen], pCredential->SSID.Ssid, pCredential->SSID.SsidLength);
+ PlainLen += AppendWSCTLV(WSC_ID_MAC_ADDR, &Plain[PlainLen], pCredential->MacAddr, 0);
+ PlainLen += AppendWSCTLV(WSC_ID_AUTH_TYPE, &Plain[PlainLen], (UINT8 *)&authType, 0);
+ PlainLen += AppendWSCTLV(WSC_ID_ENCR_TYPE, &Plain[PlainLen], (UINT8 *)&encyType, 0);
+ PlainLen += AppendWSCTLV(WSC_ID_NW_KEY_INDEX, &Plain[PlainLen], &pCredential->KeyIndex, 0);
+ PlainLen += AppendWSCTLV(WSC_ID_NW_KEY, &Plain[PlainLen], pCredential->Key, pCredential->KeyLength);
+ }
+
+ /* Generate HMAC */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &Plain[0], PlainLen, TB, SHA256_DIGEST_SIZE);
+ PlainLen += AppendWSCTLV(WSC_ID_KEY_WRAP_AUTH, &Plain[PlainLen], TB, 0);
+
+ /* 4b. Encrypted Settings */
+ /* Encrypt data */
+ EncrLen = IV_ENCR_DATA_LEN_512 - 16;
+ AES_CBC_Encrypt(Plain, PlainLen,pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),&IV_EncrData[0], 16, (UINT8 *) &IV_EncrData[16], (UINT *) &EncrLen);
+ templen = AppendWSCTLV(WSC_ID_ENCR_SETTINGS, pData, IV_EncrData, 16 + EncrLen);/*IVLen + EncrLen */
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ /*
+ Generate authenticator
+ Combine last TX & RX message contents and validate the HMAC
+ */
+ HmacLen = Len + pReg->LastRx.Length;
+ if (pAdapter->pHmacData)
+ {
+ pAuth = (PUCHAR) pAdapter->pHmacData;
+ NdisMoveMemory(pAuth, pReg->LastRx.Data, pReg->LastRx.Length);
+ pAuth += pReg->LastRx.Length;
+ NdisMoveMemory(pAuth, pbuf, Len);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, TB, SHA256_DIGEST_SIZE);
+ }
+
+ templen = AppendWSCTLV(WSC_ID_AUTHENTICATOR, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* Copy the content to Regdata for lasttx information */
+ pReg->LastTx.Length = Len;
+ NdisMoveMemory(pReg->LastTx.Data, pbuf, Len);
+
+ if(NULL != IV_EncrData)
+/* kfree(IV_EncrData); */
+ os_free_mem(NULL, IV_EncrData);
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM7 : \n"));
+ return Len;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build WSC M8 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after M7
+ 1. Change the correct parameters
+ 2. Build M8
+
+ ========================================================================
+*/
+int BuildMessageM8(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+/* UCHAR TB[256]; */
+ UCHAR *TB = NULL;
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf, pAuth;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+ INT HmacLen;
+ UCHAR KDK[32];
+ UCHAR /* Plain[300], */ *IV_EncrData=NULL;/*IV len 16 ,EncrData len */
+ UCHAR *Plain = NULL;
+ INT CerLen = 0, PlainLen = 0, EncrLen;
+ PWSC_CREDENTIAL pCredential = NULL;
+ USHORT AuthType = 0;
+ USHORT EncrType = 0;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F);
+#endif /* CONFIG_AP_SUPPORT */
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+ UCHAR CurOpMode = 0xFF;
+
+/* IV_EncrData = kmalloc(512, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&IV_EncrData, IV_ENCR_DATA_LEN_512);
+ if(NULL == IV_EncrData)
+ return 0;
+
+ os_alloc_mem(NULL, (UCHAR **)&TB, 256);
+ if (TB == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+ os_alloc_mem(NULL, (UCHAR **)&Plain, 300);
+ if (Plain == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, M8 */
+ TB[0] = WSC_ID_MESSAGE_M8;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef CONFIG_AP_SUPPORT
+ if (CurOpMode == AP_MODE)
+ {
+ WscCreateProfileFromCfg(pAdapter, REGISTRAR_ACTION | AP_MODE, pWscControl, &pWscControl->WscProfile);
+ pCredential = &pAdapter->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0];
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* 4a. Encrypted R-S1 */
+ CerLen += AppendWSCTLV(WSC_ID_NW_INDEX, &TB[0], (PUCHAR)"1", 0);
+
+ if (pCredential == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pWscControl == NULL!\n", __FUNCTION__));
+ goto LabelErr;
+ }
+
+ AuthType = pCredential->AuthType;
+ EncrType = pCredential->EncrType;
+ /*
+ Some Win7 WSC 1.0 STA has problem to receive mixed authType and encyType.
+ We need to check STA is WSC 1.0 or WSC 2.0 here.
+ If STA is WSC 1.0, re-assign authType and encyType.
+ */
+ if (pWscControl->RegData.PeerInfo.Version2 == 0)
+ {
+ if (AuthType == (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK))
+ AuthType = WSC_AUTHTYPE_WPA2PSK;
+ if (EncrType == (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES))
+ EncrType = WSC_ENCRTYPE_AES;
+ }
+
+ AuthType = cpu2be16(AuthType);
+ EncrType = cpu2be16(EncrType);
+ CerLen += AppendWSCTLV(WSC_ID_SSID, &TB[CerLen], pCredential->SSID.Ssid, pCredential->SSID.SsidLength);
+ CerLen += AppendWSCTLV(WSC_ID_AUTH_TYPE, &TB[CerLen], (UINT8 *)&AuthType, 0);
+ CerLen += AppendWSCTLV(WSC_ID_ENCR_TYPE, &TB[CerLen], (UINT8 *)&EncrType, 0);
+ CerLen += AppendWSCTLV(WSC_ID_NW_KEY_INDEX, &TB[CerLen], &pCredential->KeyIndex, 0);
+ CerLen += AppendWSCTLV(WSC_ID_NW_KEY, &TB[CerLen], pCredential->Key, pCredential->KeyLength);
+ CerLen += AppendWSCTLV(WSC_ID_MAC_ADDR, &TB[CerLen], pCredential->MacAddr, 0);
+
+ /* Prepare plain text */
+ if ((CurOpMode == AP_MODE)
+ )
+ {
+ /* Reguired attribute item in M8 if Enrollee is STA. */
+ PlainLen += AppendWSCTLV(WSC_ID_CREDENTIAL, &Plain[0], TB, CerLen);
+ }
+
+ /* Generate HMAC */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, &Plain[0], PlainLen, TB, SHA256_DIGEST_SIZE);
+ PlainLen += AppendWSCTLV(WSC_ID_KEY_WRAP_AUTH, &Plain[PlainLen], TB, 0);
+
+ /* 4b. Encrypted Settings */
+ /* Encrypt data */
+ EncrLen = IV_ENCR_DATA_LEN_512 - 16;
+ AES_CBC_Encrypt(Plain, PlainLen,pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),&IV_EncrData[0], 16, (UINT8 *) &IV_EncrData[16], (UINT *) &EncrLen);
+ templen = AppendWSCTLV(WSC_ID_ENCR_SETTINGS, pData, IV_EncrData, 16 + EncrLen);/*IVLen + EncrLen */
+ pData += templen;
+ Len += templen;
+
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ /*
+ Combine last TX & RX message contents and validate the HMAC
+ We have to exclude last 12 bytes from last receive since it's authenticator value
+ */
+ HmacLen = Len + pReg->LastRx.Length;
+ if (pAdapter->pHmacData)
+ {
+ pAuth = (PUCHAR) pAdapter->pHmacData;
+ NdisMoveMemory(pAuth, pReg->LastRx.Data, pReg->LastRx.Length);
+ pAuth += pReg->LastRx.Length;
+ NdisMoveMemory(pAuth, pbuf, Len);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+
+ templen = AppendWSCTLV(WSC_ID_AUTHENTICATOR, pData, KDK, 0);
+ pData += templen;
+ Len += templen;
+
+LabelErr:
+ if(NULL != IV_EncrData)
+/* kfree(IV_EncrData); */
+ os_free_mem(NULL, IV_EncrData);
+
+ pWscControl->WscRetryCount = 0;
+
+ if (TB != NULL)
+ os_free_mem(NULL, TB);
+ if (Plain != NULL)
+ os_free_mem(NULL, Plain);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageM8 : \n"));
+ return Len;
+}
+
+int BuildMessageDONE(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[1];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, WSC DONE */
+ TB[0] = WSC_MSG_WSC_DONE;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageDONE : \n"));
+ return Len;
+}
+
+int BuildMessageACK(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[1];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, WSC ACK */
+ TB[0] = WSC_MSG_WSC_ACK;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageACK : \n"));
+ return Len;
+}
+
+int BuildMessageNACK(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf)
+{
+ UCHAR TB[2];
+ INT Len = 0, templen = 0;
+ PUCHAR pData = (PUCHAR)pbuf;
+ PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData;
+ USHORT ConfigError = htons(pReg->SelfInfo.ConfigError);
+#ifdef WSC_V2_SUPPORT
+ PWSC_TLV pWscTLV = &pWscControl->WscV2Info.ExtraTlv;
+#endif /* WSC_V2_SUPPORT */
+
+ /* 1. Version */
+ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 2. Message Type, WSC NACK */
+ TB[0] = WSC_ID_MESSAGE_NACK;
+ templen = AppendWSCTLV(WSC_ID_MSG_TYPE, pData, TB, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 3. Enrollee Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_ENROLLEE_NONCE, pData, pReg->EnrolleeNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 4. Registrar Nonce, 16 bytes */
+ templen = AppendWSCTLV(WSC_ID_REGISTRAR_NONCE, pData, pReg->RegistrarNonce, 0);
+ pData += templen;
+ Len += templen;
+
+ /* 5. Error */
+ templen = AppendWSCTLV(WSC_ID_CONFIG_ERROR, pData, (UINT8 *)&ConfigError, 0);
+ pData += templen;
+ Len += templen;
+
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ /* Version2 */
+ WscGenV2Msg(pWscControl,
+ FALSE,
+ NULL,
+ 0,
+ &pData,
+ &Len);
+
+ /* Extra attribute that is not defined in WSC Sepc. */
+ if (pWscTLV->pTlvData && pWscTLV->TlvLen)
+ {
+ templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen);
+ pData += templen;
+ Len += templen;
+ }
+ }
+#endif /* WSC_V2_SUPPORT */
+
+ pWscControl->WscRetryCount = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("BuildMessageNACK : \n"));
+ return Len;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M1 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - recv buffer
+ Length - recv Length
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M1
+ 1. Change the correct parameters
+ 2. Process M1
+
+ ========================================================================
+*/
+int ProcessMessageM1(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR, DH_Len = 0, idx;
+ PUCHAR pData = NULL;
+ USHORT WscType, WscLen, FieldCheck[7]={0,0,0,0,0,0,0};
+ UCHAR CurOpMode = 0xFF;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ pReg->PeerInfo.Version2 = 0;
+
+ DH_Len = sizeof(pReg->Pkr);
+ /* Enrollee 192 random bytes for DH key generation */
+ for (idx = 0; idx < 192; idx++)
+ pWscControl->RegData.EnrolleeRandom[idx] = RandomByte(pAdapter);
+
+ RT_DH_PublicKey_Generate (
+ WPS_DH_G_VALUE, sizeof(WPS_DH_G_VALUE),
+ WPS_DH_P_VALUE, sizeof(WPS_DH_P_VALUE),
+ pWscControl->RegData.EnrolleeRandom, sizeof(pWscControl->RegData.EnrolleeRandom),
+ pReg->Pkr, (UINT *) &DH_Len);
+
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_UUID_E))] |= (1 << WSC_TLV_BYTE1(WSC_ID_UUID_E));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MAC_ADDR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MAC_ADDR));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PUBLIC_KEY))] |= (1 << WSC_TLV_BYTE1(WSC_ID_PUBLIC_KEY));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTH_TYPE_FLAGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_AUTH_TYPE_FLAGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_TYPE_FLAGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_TYPE_FLAGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONN_TYPE_FLAGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_CONN_TYPE_FLAGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_METHODS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_METHODS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_SC_STATE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_SC_STATE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MANUFACTURER))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MANUFACTURER));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NAME))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NAME));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NUMBER))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NUMBER));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_SERIAL_NUM))] |= (1 << WSC_TLV_BYTE1(WSC_ID_SERIAL_NUM));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PRIM_DEV_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_PRIM_DEV_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_NAME))] |= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_NAME));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_RF_BAND))] |= (1 << WSC_TLV_BYTE1(WSC_ID_RF_BAND));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ASSOC_STATE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ASSOC_STATE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_ERROR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_ERROR));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_PWD_ID))] |= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_PWD_ID));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_OS_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_OS_VERSION));
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ NdisZeroMemory(&pWscControl->WscPeerInfo, sizeof(WSC_PEER_DEV_INFO));
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M1 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M1 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ break;
+
+ case WSC_ID_UUID_E:
+ NdisMoveMemory(pReg->PeerInfo.Uuid, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_UUID_E))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_UUID_E));
+ break;
+
+ case WSC_ID_MAC_ADDR:
+ NdisMoveMemory(pReg->PeerInfo.MacAddr, pData, WscLen);
+ NdisMoveMemory(pWscControl->WscPeerInfo.WscPeerMAC, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MAC_ADDR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MAC_ADDR));
+ break;
+
+ case WSC_ID_ENROLLEE_NONCE:
+ NdisMoveMemory(pReg->EnrolleeNonce, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ break;
+
+ case WSC_ID_PUBLIC_KEY:
+ /* Get Enrollee Public Key */
+ NdisMoveMemory(pReg->Pke, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PUBLIC_KEY))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_PUBLIC_KEY));
+ break;
+
+ case WSC_ID_AUTH_TYPE_FLAGS:
+ pReg->PeerInfo.AuthTypeFlags = *((PUSHORT) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTH_TYPE_FLAGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_AUTH_TYPE_FLAGS));
+ break;
+
+ case WSC_ID_ENCR_TYPE_FLAGS:
+ pReg->PeerInfo.EncrTypeFlags = *((PUSHORT) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_TYPE_FLAGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_TYPE_FLAGS));
+ break;
+
+ case WSC_ID_CONN_TYPE_FLAGS:
+ pReg->PeerInfo.ConnTypeFlags = *pData;
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONN_TYPE_FLAGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_CONN_TYPE_FLAGS));
+ break;
+
+ case WSC_ID_CONFIG_METHODS:
+ pReg->PeerInfo.ConfigMethods = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_METHODS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_METHODS));
+ break;
+
+ case WSC_ID_SC_STATE:
+ pReg->PeerInfo.ScState = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_SC_STATE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_SC_STATE));
+ break;
+
+ case WSC_ID_MANUFACTURER:
+ NdisMoveMemory(&pReg->PeerInfo.Manufacturer, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerManufacturer, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MANUFACTURER))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MANUFACTURER));
+ break;
+
+ case WSC_ID_MODEL_NAME:
+ NdisMoveMemory(&pReg->PeerInfo.ModelName, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerModelName, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NAME))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NAME));
+ break;
+
+ case WSC_ID_MODEL_NUMBER:
+ NdisMoveMemory(&pReg->PeerInfo.ModelNumber, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerModelNumber, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NUMBER))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NUMBER));
+ break;
+
+ case WSC_ID_SERIAL_NUM:
+ NdisMoveMemory(&pReg->PeerInfo.SerialNumber, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerSerialNumber, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_SERIAL_NUM))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_SERIAL_NUM));
+ break;
+
+ case WSC_ID_PRIM_DEV_TYPE:
+ NdisMoveMemory(&pReg->PeerInfo.PriDeviceType, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PRIM_DEV_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_PRIM_DEV_TYPE));
+ break;
+
+ case WSC_ID_DEVICE_NAME:
+ NdisMoveMemory(&pReg->PeerInfo.DeviceName, pData, WscLen);
+ NdisMoveMemory(pWscControl->WscPeerInfo.WscPeerDeviceName, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_NAME))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_NAME));
+ break;
+
+ case WSC_ID_RF_BAND:
+ pReg->PeerInfo.RfBand = *pData;
+ /*if() ret = WSC_ERROR_CHAN24_NOT_SUPP; */
+ /*if() ret = WSC_ERROR_CHAN50_NOT_SUPP; */
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_RF_BAND))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_RF_BAND));
+ break;
+
+ case WSC_ID_ASSOC_STATE:
+ pReg->PeerInfo.AssocState = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ASSOC_STATE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ASSOC_STATE));
+ break;
+
+ case WSC_ID_CONFIG_ERROR:
+ pReg->PeerInfo.ConfigError = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_ERROR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_ERROR));
+ break;
+
+ case WSC_ID_DEVICE_PWD_ID:
+ DBGPRINT(RT_DEBUG_TRACE, (" WPS Registrar DPID %04x\n",pReg->SelfInfo.DevPwdId));
+ if(WSC_DEVICEPWDID_DEFAULT == get_unaligned((PUSHORT) pData))/**(PUSHORT) pData) */
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx WPS DPID PIN\n"));
+ pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_PIN);
+ }
+ else if(WSC_DEVICEPWDID_PUSH_BTN == get_unaligned((PUSHORT) pData))/**(PUSHORT) pData) */
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx WPS DPID PBC\n"));
+ pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_PBC);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx WPS DPID unsupport\n"));
+ }
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_PWD_ID))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_PWD_ID));
+ break;
+
+ case WSC_ID_OS_VERSION:
+ pReg->PeerInfo.OsVersion = get_unalignedlong((PULONG) pData);/**((PULONG) pData); */
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_OS_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_OS_VERSION));
+ break;
+
+ case WSC_ID_VENDOR_EXT:
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ UCHAR tmp_data_len = 0;
+ WscParseV2SubItem(WFA_EXT_ID_VERSION2, pData, WscLen, &pReg->PeerInfo.Version2, &tmp_data_len);
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM1 --> Version2 = %x\n", pReg->PeerInfo.Version2));
+ }
+#endif // WSC_V2_SUPPORT //
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM1 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ if( FieldCheck[0] || FieldCheck[1] || FieldCheck[2] || FieldCheck[3] || FieldCheck[4] || FieldCheck[5] || FieldCheck[6] )
+ ret = WSC_ERROR_WANTING_FIELD;
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM1 : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M2 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M2
+ 1. Change the correct parameters
+ 2. Process M2
+
+ ========================================================================
+*/
+int ProcessMessageM2(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ IN UCHAR apidx,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ INT HmacLen;
+ UCHAR Hmac[8] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, KDK[32];
+ UCHAR DHKey[32], KdkInput[38], KdfKey[80];
+ INT DH_Len;
+ PUCHAR pData = NULL;
+ USHORT WscType, WscLen, FieldCheck[7]={0,0,0,0,0,0,0};
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR CurOpMode = 0xFF;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ CurOpMode = AP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ pReg->PeerInfo.Version2 = 0;
+
+ RTMPZeroMemory(KDK, 32);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_REGISTRAR_NONCE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_REGISTRAR_NONCE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_UUID_R))] |= (1 << WSC_TLV_BYTE1(WSC_ID_UUID_R));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PUBLIC_KEY))] |= (1 << WSC_TLV_BYTE1(WSC_ID_PUBLIC_KEY));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTH_TYPE_FLAGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_AUTH_TYPE_FLAGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_TYPE_FLAGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_TYPE_FLAGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONN_TYPE_FLAGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_CONN_TYPE_FLAGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_METHODS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_METHODS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MANUFACTURER))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MANUFACTURER));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NAME))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NAME));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NUMBER))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NUMBER));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_SERIAL_NUM))] |= (1 << WSC_TLV_BYTE1(WSC_ID_SERIAL_NUM));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PRIM_DEV_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_PRIM_DEV_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_NAME))] |= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_NAME));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_RF_BAND))] |= (1 << WSC_TLV_BYTE1(WSC_ID_RF_BAND));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ASSOC_STATE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ASSOC_STATE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_ERROR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_ERROR));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_PWD_ID))] |= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_PWD_ID));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_OS_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_OS_VERSION));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ pEntry = MacTableLookup(pAdapter, pReg->PeerInfo.MacAddr);
+
+ NdisZeroMemory(&pWscControl->WscPeerInfo, sizeof(WSC_PEER_DEV_INFO));
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M2 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ break;
+
+ case WSC_ID_ENROLLEE_NONCE:
+ /* for verification with our enrollee nonce */
+ if (RTMPCompareMemory(pReg->SelfNonce, pData, WscLen) != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M2 Compare enrollee nonce mismatched \n"));
+ }
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ break;
+
+ case WSC_ID_REGISTRAR_NONCE:
+ NdisMoveMemory(pReg->RegistrarNonce, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_REGISTRAR_NONCE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_REGISTRAR_NONCE));
+ break;
+
+ case WSC_ID_UUID_R:
+ NdisMoveMemory(pReg->PeerInfo.Uuid, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_UUID_R))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_UUID_R));
+ break;
+
+ case WSC_ID_PUBLIC_KEY:
+ /* Get Registrar Public Key */
+ NdisMoveMemory(&pReg->Pkr, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PUBLIC_KEY))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_PUBLIC_KEY));
+ break;
+
+ case WSC_ID_AUTH_TYPE_FLAGS:
+ pReg->PeerInfo.AuthTypeFlags = get_unaligned((PUSHORT) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTH_TYPE_FLAGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_AUTH_TYPE_FLAGS));
+ break;
+
+ case WSC_ID_ENCR_TYPE_FLAGS:
+ pReg->PeerInfo.EncrTypeFlags = get_unaligned((PUSHORT) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_TYPE_FLAGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_TYPE_FLAGS));
+ break;
+
+ case WSC_ID_CONN_TYPE_FLAGS:
+ pReg->PeerInfo.ConnTypeFlags = *pData;
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONN_TYPE_FLAGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_CONN_TYPE_FLAGS));
+ break;
+
+ case WSC_ID_CONFIG_METHODS:
+ pReg->PeerInfo.ConfigMethods = get_unaligned((PUSHORT) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_METHODS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_METHODS));
+ break;
+
+ case WSC_ID_MANUFACTURER:
+ NdisMoveMemory(&pReg->PeerInfo.Manufacturer, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerManufacturer, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MANUFACTURER))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MANUFACTURER));
+ break;
+
+ case WSC_ID_MODEL_NAME:
+ NdisMoveMemory(&pReg->PeerInfo.ModelName, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerModelName, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NAME))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NAME));
+ break;
+
+ case WSC_ID_MODEL_NUMBER:
+ NdisMoveMemory(&pReg->PeerInfo.ModelNumber, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerModelNumber, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MODEL_NUMBER))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MODEL_NUMBER));
+ break;
+
+ case WSC_ID_SERIAL_NUM:
+ NdisMoveMemory(&pReg->PeerInfo.SerialNumber, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerSerialNumber, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_SERIAL_NUM))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_SERIAL_NUM));
+ break;
+
+ case WSC_ID_PRIM_DEV_TYPE:
+ NdisMoveMemory(&pReg->PeerInfo.PriDeviceType, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_PRIM_DEV_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_PRIM_DEV_TYPE));
+ break;
+
+ case WSC_ID_DEVICE_NAME:
+ NdisMoveMemory(&pReg->PeerInfo.DeviceName, pData, WscLen);
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerDeviceName, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_NAME))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_NAME));
+ break;
+
+ case WSC_ID_RF_BAND:
+ pReg->PeerInfo.RfBand = *pData;
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_RF_BAND))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_RF_BAND));
+ break;
+
+ case WSC_ID_ASSOC_STATE:
+ pReg->PeerInfo.AssocState = get_unaligned((PUSHORT) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ASSOC_STATE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ASSOC_STATE));
+ break;
+
+ case WSC_ID_CONFIG_ERROR:
+ pReg->PeerInfo.ConfigError = get_unaligned((PUSHORT) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_CONFIG_ERROR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_CONFIG_ERROR));
+ break;
+
+ case WSC_ID_DEVICE_PWD_ID:
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_DEVICE_PWD_ID))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_DEVICE_PWD_ID));
+ break;
+
+ case WSC_ID_OS_VERSION:
+ pReg->PeerInfo.OsVersion = get_unalignedlong((PULONG) pData);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_OS_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_OS_VERSION));
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+ break;
+
+ case WSC_ID_VENDOR_EXT:
+#ifdef WSC_V2_SUPPORT
+ if (pWscControl->WscV2Info.bEnableWpsV2)
+ {
+ UCHAR tmp_data_len = 0;
+ WscParseV2SubItem(WFA_EXT_ID_VERSION2, pData, WscLen, &pReg->PeerInfo.Version2, &tmp_data_len);
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM2 --> Version2 = %x\n", pReg->PeerInfo.Version2));
+ }
+#endif // WSC_V2_SUPPORT //
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM2 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ NdisMoveMemory(&pWscControl->WscPeerInfo.WscPeerMAC, &pWscControl->RegData.PeerInfo.MacAddr, 6);
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+
+ DH_Len = sizeof(pReg->SecretKey);
+ RT_DH_SecretKey_Generate (
+ pReg->Pkr, sizeof(pReg->Pkr),
+ WPS_DH_P_VALUE, sizeof(WPS_DH_P_VALUE),
+ pReg->EnrolleeRandom, sizeof(pReg->EnrolleeRandom),
+ pReg->SecretKey, (UINT *) &DH_Len);
+
+ /* Compute the DHKey based on the DH secret */
+ RT_SHA256(&pReg->SecretKey[0], 192, &DHKey[0]);
+
+ /* Create KDK input data */
+ NdisMoveMemory(&KdkInput[0], pReg->SelfNonce, 16);
+
+ NdisMoveMemory(&KdkInput[16], pReg->SelfInfo.MacAddr, 6);
+
+ NdisMoveMemory(&KdkInput[22], pReg->RegistrarNonce, 16);
+
+ /* Generate the KDK */
+ RT_HMAC_SHA256(DHKey, 32, KdkInput, 38, KDK, SHA256_DIGEST_SIZE);
+
+ /* KDF */
+ WscDeriveKey(KDK, 32, Wsc_Personal_String, (sizeof(Wsc_Personal_String) - 1), KdfKey, 640);
+
+ /* Assign Key from KDF */
+ NdisMoveMemory(pReg->AuthKey, &KdfKey[0], 32);
+ NdisMoveMemory(pReg->KeyWrapKey, &KdfKey[32], 16);
+ NdisMoveMemory(pReg->Emsk, &KdfKey[48], 32);
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = pReg->LastTx.Length + pReg->LastRx.Length - 12;
+ if (pAdapter->pHmacData)
+ {
+ NdisMoveMemory(pAdapter->pHmacData, pReg->LastTx.Data, pReg->LastTx.Length);
+ NdisMoveMemory(pAdapter->pHmacData + pReg->LastTx.Length, pReg->LastRx.Data, pReg->LastRx.Length - 12);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+
+ if (RTMPEqualMemory(Hmac, KDK, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ProcessMessageM2 --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) KDK)), (UINT)cpu2be32(*((PUINT)(KDK + 4)))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ ret = WSC_ERROR_HMAC_FAIL;
+ }
+
+ if( FieldCheck[0] || FieldCheck[1] || FieldCheck[2] || FieldCheck[3] || FieldCheck[4] || FieldCheck[5] || FieldCheck[6] )
+ ret = WSC_ERROR_WANTING_FIELD;
+
+/* out : */
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM2 : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M2D Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - rewrite buffer
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M2D
+ 1. Change the correct parameters
+ 2. Process M2D
+
+ ========================================================================
+*/
+int ProcessMessageM2D(
+ IN PRTMP_ADAPTER pAdapter,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ PUCHAR pData = NULL;
+ USHORT WscType, WscLen;
+
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M2D != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ break;
+
+ case WSC_ID_ENROLLEE_NONCE:
+ /* for verification with our enrollee nonce */
+ if (RTMPCompareMemory(pReg->EnrolleeNonce, pData, WscLen) != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M2 Compare enrollee nonce mismatched \n"));
+ }
+ break;
+
+ case WSC_ID_REGISTRAR_NONCE:
+ NdisMoveMemory(pReg->RegistrarNonce, pData, WscLen);
+ break;
+
+ case WSC_ID_UUID_R:
+ NdisMoveMemory(pReg->PeerInfo.Uuid, pData, WscLen);
+ break;
+
+ case WSC_ID_PUBLIC_KEY:
+ /* There shall be no Public transmitted in M2D */
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM2D --> Receive WSC_ID_PUBLIC_KEY!! werid!\n"));
+ break;
+
+ case WSC_ID_AUTH_TYPE_FLAGS:
+ pReg->PeerInfo.AuthTypeFlags = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ break;
+
+ case WSC_ID_ENCR_TYPE_FLAGS:
+ pReg->PeerInfo.EncrTypeFlags = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ break;
+
+ case WSC_ID_CONN_TYPE_FLAGS:
+ pReg->PeerInfo.ConnTypeFlags = *pData;
+ break;
+
+ case WSC_ID_CONFIG_METHODS:
+ pReg->PeerInfo.ConfigMethods = be2cpu16(get_unaligned((PUSHORT) pData));/*be2cpu16(*((PUSHORT) pData)); */
+ break;
+
+ case WSC_ID_MANUFACTURER:
+ NdisMoveMemory(&pReg->PeerInfo.Manufacturer, pData, WscLen);
+ break;
+
+ case WSC_ID_MODEL_NAME:
+ NdisMoveMemory(&pReg->PeerInfo.ModelName, pData, WscLen);
+ break;
+
+ case WSC_ID_MODEL_NUMBER:
+ NdisMoveMemory(&pReg->PeerInfo.ModelNumber, pData, WscLen);
+ break;
+
+ case WSC_ID_SERIAL_NUM:
+ NdisMoveMemory(&pReg->PeerInfo.SerialNumber, pData, WscLen);
+ break;
+
+ case WSC_ID_PRIM_DEV_TYPE:
+ NdisMoveMemory(&pReg->PeerInfo.PriDeviceType, pData, WscLen);
+ break;
+
+ case WSC_ID_DEVICE_NAME:
+ NdisMoveMemory(&pReg->PeerInfo.DeviceName, pData, WscLen);
+ break;
+
+ case WSC_ID_RF_BAND:
+ pReg->PeerInfo.RfBand = *pData;
+ break;
+
+ case WSC_ID_ASSOC_STATE:
+ pReg->PeerInfo.AssocState = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ break;
+
+ case WSC_ID_CONFIG_ERROR:
+ pReg->PeerInfo.ConfigError = get_unaligned((PUSHORT) pData);/**((PUSHORT) pData); */
+ break;
+
+ case WSC_ID_DEVICE_PWD_ID:
+ break;
+
+ case WSC_ID_OS_VERSION:
+ pReg->PeerInfo.OsVersion = get_unalignedlong((PULONG)pData);
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ /* No authenticator in M2D */
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM2D --> Unknown IE 0x%04x\n", WscType));
+ break;
+
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM2D : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M3 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - recv buffer
+ Length - recv Length
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M3
+ 1. Change the correct parameters
+ 2. Process M3
+
+ ========================================================================
+*/
+int ProcessMessageM3(
+ IN PRTMP_ADAPTER pAdapter,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ INT HmacLen;
+ UCHAR Hmac[8] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, KDK[32];
+ PUCHAR pData = NULL;
+ USHORT WscType, WscLen, FieldCheck[7]={0,0,0,0,0,0,0};
+
+ RTMPZeroMemory(KDK, 32);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_REGISTRAR_NONCE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_REGISTRAR_NONCE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_E_HASH1))] |= (1 << WSC_TLV_BYTE1(WSC_ID_E_HASH1));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_E_HASH2))] |= (1 << WSC_TLV_BYTE1(WSC_ID_E_HASH2));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M3 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M3 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ break;
+
+ case WSC_ID_REGISTRAR_NONCE:
+ /* for verification with our Registrar nonce */
+ if (RTMPCompareMemory(pReg->RegistrarNonce, pData, WscLen) != 0)
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M3 Compare Registrar nonce mismatched \n"));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_REGISTRAR_NONCE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_REGISTRAR_NONCE));
+ break;
+
+ case WSC_ID_E_HASH1:
+ NdisMoveMemory(&pReg->EHash1[0], pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_E_HASH1))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_E_HASH1));
+ break;
+
+ case WSC_ID_E_HASH2:
+ NdisMoveMemory(&pReg->EHash2[0], pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_E_HASH2))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_E_HASH2));
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM3 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = pReg->LastTx.Length + pReg->LastRx.Length - 12;
+ if (pAdapter->pHmacData)
+ {
+ NdisMoveMemory(pAdapter->pHmacData, pReg->LastTx.Data, pReg->LastTx.Length);
+ NdisMoveMemory(pAdapter->pHmacData + pReg->LastTx.Length, pReg->LastRx.Data, pReg->LastRx.Length - 12);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+
+ if (RTMPEqualMemory(Hmac, KDK, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ProcessMessageM3 --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) KDK)), (UINT)cpu2be32(*((PUINT)(KDK + 4)))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ ret = WSC_ERROR_HMAC_FAIL;
+ }
+
+ if( FieldCheck[0] || FieldCheck[1] || FieldCheck[2] || FieldCheck[3] || FieldCheck[4] || FieldCheck[5] || FieldCheck[6] )
+ ret = WSC_ERROR_WANTING_FIELD;
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM3 : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M4 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - recv buffer
+ Length - recv Length
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M4
+ 1. Change the correct parameters
+ 2. Process M4
+
+ ========================================================================
+*/
+int ProcessMessageM4(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ INT HmacLen;
+ UCHAR Hmac[8] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, KDK[32], RHash[32];
+ INT EncrLen;
+ PUCHAR pData = NULL;
+ UCHAR *IV_DecrData=NULL;/*IV len 16 ,DecrData len */
+ UCHAR *pHash=NULL;/*Reuse IV_DecrData memory */
+ USHORT WscType, WscLen, FieldCheck[7]={0,0,0,0,0,0,0};
+
+ RTMPZeroMemory(KDK, 32);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_R_HASH1))] |= (1 << WSC_TLV_BYTE1(WSC_ID_R_HASH1));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_R_HASH2))] |= (1 << WSC_TLV_BYTE1(WSC_ID_R_HASH2));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_SETTINGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_SETTINGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+
+/* IV_DecrData = kmalloc(512, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&IV_DecrData, 512);
+ if(NULL == IV_DecrData)
+ {
+ ret = WSC_ERROR_CAN_NOT_ALLOCMEM;
+ return ret;
+ }
+ pHash = IV_DecrData;
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M4 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ break;
+
+ case WSC_ID_ENROLLEE_NONCE:
+ /* for verification with our enrollee nonce */
+ if (RTMPCompareMemory(pReg->EnrolleeNonce, pData, WscLen) != 0)
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M4 Compare enrollee nonce mismatched \n"));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ break;
+
+ case WSC_ID_R_HASH1:
+ NdisMoveMemory(&pReg->RHash1, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_R_HASH1))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_R_HASH1));
+ break;
+
+ case WSC_ID_R_HASH2:
+ NdisMoveMemory(&pReg->RHash2, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_R_HASH2))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_R_HASH2));
+ break;
+
+ case WSC_ID_ENCR_SETTINGS:
+ /* There shall have smoe kind of length check */
+ if (WscLen <= 16)
+ break;
+ if (WscLen > 512)
+ {
+ /* ApEncrSetting is not enough */
+ DBGPRINT(RT_DEBUG_TRACE, ("ApEncrSettings array size is not enough, require %d\n", WscLen));
+ break;
+ }
+ NdisMoveMemory(IV_DecrData, pData, WscLen);
+ EncrLen = sizeof(pReg->ApEncrSettings);
+ AES_CBC_Decrypt(IV_DecrData + 16, (WscLen - 16),pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),IV_DecrData, 16, (UINT8 *) pReg->ApEncrSettings, (UINT *) &EncrLen);
+ DBGPRINT(RT_DEBUG_TRACE, ("M4 ApEncrSettings len = %d\n ", EncrLen));
+
+ /* Parse encryption settings */
+ WscParseEncrSettings(pAdapter, pReg->ApEncrSettings, EncrLen, pWscControl);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_SETTINGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_SETTINGS));
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM4 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ /* Verify R-Hash1 */
+ /* Create input for R-Hash1 */
+ NdisMoveMemory(pHash, pReg->Rs1, 16);
+ NdisMoveMemory(pHash + 16, pReg->Psk1, 16);
+ NdisMoveMemory(pHash + 32, pReg->Pke, 192);
+ NdisMoveMemory(pHash + 224, pReg->Pkr, 192);
+
+ /* Generate R-Hash1 */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pHash, 416, RHash, SHA256_DIGEST_SIZE);
+
+ if (RTMPCompareMemory(pReg->RHash1, RHash, 32) != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM4 --> RHash1 not matched\n"));
+ ret = WSC_ERROR_DEV_PWD_AUTH_FAIL;
+ goto out;
+ }
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = pReg->LastTx.Length + pReg->LastRx.Length - 12;
+ if (pAdapter->pHmacData)
+ {
+ NdisMoveMemory(pAdapter->pHmacData, pReg->LastTx.Data, pReg->LastTx.Length);
+ NdisMoveMemory(pAdapter->pHmacData + pReg->LastTx.Length, pReg->LastRx.Data, pReg->LastRx.Length - 12);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+
+ if (RTMPEqualMemory(Hmac, KDK, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ProcessMessageM4 --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) KDK)), (UINT)cpu2be32(*((PUINT)(KDK + 4)))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ ret = WSC_ERROR_HMAC_FAIL;
+ }
+
+ if( FieldCheck[0] || FieldCheck[1] || FieldCheck[2] || FieldCheck[3] || FieldCheck[4] || FieldCheck[5] || FieldCheck[6] )
+ ret = WSC_ERROR_WANTING_FIELD;
+out :
+ if(NULL != IV_DecrData)
+/* kfree(IV_DecrData); */
+ os_free_mem(NULL, IV_DecrData);
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM4 : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M5 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - recv buffer
+ Length - recv Length
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M5
+ 1. Change the correct parameters
+ 2. Process M5
+
+ ========================================================================
+*/
+int ProcessMessageM5(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ INT HmacLen;
+ UCHAR Hmac[8] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, KDK[32], EHash[32];
+ INT EncrLen;
+ PUCHAR pData = NULL;
+ UCHAR *IV_DecrData=NULL;/*IV len 16 ,DecrData len */
+ UCHAR *pHash=NULL;/*Reuse IV_DecrData memory */
+ USHORT WscType, WscLen, FieldCheck[7]={0,0,0,0,0,0,0};
+
+ RTMPZeroMemory(KDK, 32);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_REGISTRAR_NONCE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_REGISTRAR_NONCE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_SETTINGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_SETTINGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+
+/* IV_DecrData = kmalloc(512, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&IV_DecrData, 512);
+ if(NULL == IV_DecrData)
+ {
+ ret = WSC_ERROR_CAN_NOT_ALLOCMEM;
+ return ret;
+ }
+ pHash = IV_DecrData;
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M5 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ break;
+
+ case WSC_ID_REGISTRAR_NONCE:
+ /* for verification with our Registrar nonce */
+ if (RTMPCompareMemory(pReg->RegistrarNonce, pData, WscLen) != 0)
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M5 Compare Registrar nonce mismatched \n"));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_REGISTRAR_NONCE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_REGISTRAR_NONCE));
+ break;
+
+ case WSC_ID_ENCR_SETTINGS:
+ /* There shall have smoe kind of length check */
+ if (WscLen <= 16)
+ break;
+ if (WscLen > 512)
+ {
+ /* ApEncrSetting is not enough */
+ DBGPRINT(RT_DEBUG_TRACE, ("ApEncrSettings array size is not enough, require %d\n", WscLen));
+ break;
+ }
+ NdisMoveMemory(IV_DecrData, pData, WscLen);
+ EncrLen = sizeof(pReg->ApEncrSettings);
+ AES_CBC_Decrypt(IV_DecrData + 16, (WscLen - 16),pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),IV_DecrData, 16, (UINT8 *) pReg->ApEncrSettings, (UINT *) &EncrLen);
+ DBGPRINT(RT_DEBUG_TRACE, ("M5 ApEncrSettings len = %d\n ", EncrLen));
+
+ /* Parse encryption settings */
+ WscParseEncrSettings(pAdapter, pReg->ApEncrSettings, EncrLen, pWscControl);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_SETTINGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_SETTINGS));
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM4 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = pReg->LastTx.Length + pReg->LastRx.Length - 12;
+ if (pAdapter->pHmacData)
+ {
+ NdisMoveMemory(pAdapter->pHmacData, pReg->LastTx.Data, pReg->LastTx.Length);
+ NdisMoveMemory(pAdapter->pHmacData + pReg->LastTx.Length, pReg->LastRx.Data, pReg->LastRx.Length - 12);
+ }
+
+ /* Verify E-Hash1 */
+ /* Create input for E-Hash1 */
+ NdisMoveMemory(pHash, pReg->Es1, 16);
+ NdisMoveMemory(pHash + 16, pReg->Psk1, 16);
+ NdisMoveMemory(pHash + 32, pReg->Pke, 192);
+ NdisMoveMemory(pHash + 224, pReg->Pkr, 192);
+
+ /* Generate E-Hash1 */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pHash, 416, EHash, SHA256_DIGEST_SIZE);
+
+ if (RTMPCompareMemory(pReg->EHash1, EHash, 32) != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM5 --> EHash1 not matched\n"));
+ pReg->SelfInfo.ConfigError = WSC_ERROR_HASH_FAIL;
+ ret = WSC_ERROR_HASH_FAIL;
+ goto out;
+ }
+
+ if (pAdapter->pHmacData)
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+
+ if (RTMPEqualMemory(Hmac, KDK, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ProcessMessageM5 --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) KDK)), (UINT)cpu2be32(*((PUINT)(KDK + 4)))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ ret = WSC_ERROR_HMAC_FAIL;
+ }
+ if( FieldCheck[0] || FieldCheck[1] || FieldCheck[2] || FieldCheck[3] || FieldCheck[4] || FieldCheck[5] || FieldCheck[6] )
+ ret = WSC_ERROR_WANTING_FIELD;
+out :
+ if(NULL != IV_DecrData)
+/* kfree(IV_DecrData); */
+ os_free_mem(NULL, IV_DecrData);
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM5 : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M6 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - recv buffer
+ Length - recv Length
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M6
+ 1. Change the correct parameters
+ 2. Process M6
+
+ ========================================================================
+*/
+int ProcessMessageM6(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ INT HmacLen;
+ UCHAR Hmac[8] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, KDK[32], RHash[32];
+ INT EncrLen;
+ PUCHAR pData = NULL;
+ UCHAR *IV_DecrData=NULL;/*IV len 16 ,DecrData len */
+ UCHAR *pHash=NULL;/*Reuse IV_DecrData memory */
+ USHORT WscType, WscLen, FieldCheck[7]={0,0,0,0,0,0,0};
+
+ RTMPZeroMemory(KDK, 32);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] |= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_SETTINGS))] |= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_SETTINGS));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] |= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+
+/* IV_DecrData = kmalloc(512, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&IV_DecrData, 512);
+ if(NULL == IV_DecrData)
+ {
+ ret = WSC_ERROR_CAN_NOT_ALLOCMEM;
+ return ret;
+ }
+ pHash = IV_DecrData;
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = cpu2be16(TLV_Recv.Type);
+ WscLen = cpu2be16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_VERSION))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_VERSION));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M6 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_MSG_TYPE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_MSG_TYPE));
+ break;
+
+ case WSC_ID_ENROLLEE_NONCE:
+ /* for verification with our enrollee nonce */
+ if (RTMPCompareMemory(pReg->EnrolleeNonce, pData, WscLen) != 0)
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M6 Compare enrollee nonce mismatched \n"));
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENROLLEE_NONCE))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENROLLEE_NONCE));
+ break;
+
+ case WSC_ID_ENCR_SETTINGS:
+ /* There shall have smoe kind of length check */
+ if (WscLen <= 16)
+ break;
+ if (WscLen > 512)
+ {
+ /* ApEncrSetting is not enough */
+ DBGPRINT(RT_DEBUG_TRACE, ("ApEncrSettings array size is not enough, require %d\n", WscLen));
+ break;
+ }
+ NdisMoveMemory(IV_DecrData, pData, WscLen);
+ EncrLen = sizeof(pReg->ApEncrSettings);
+ AES_CBC_Decrypt(IV_DecrData + 16, (WscLen - 16),pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),IV_DecrData, 16, (UINT8 *) pReg->ApEncrSettings, (UINT *) &EncrLen);
+ DBGPRINT(RT_DEBUG_TRACE, ("M6 ApEncrSettings len = %d\n ", EncrLen));
+
+ /* Parse encryption settings */
+ WscParseEncrSettings(pAdapter, pReg->ApEncrSettings, EncrLen, pWscControl);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_ENCR_SETTINGS))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_ENCR_SETTINGS));
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ FieldCheck[(WSC_TLV_BYTE2(WSC_ID_AUTHENTICATOR))] ^= (1 << WSC_TLV_BYTE1(WSC_ID_AUTHENTICATOR));
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM6 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ /* Verify R-Hash2 */
+ /* Create input for R-Hash1 */
+ NdisMoveMemory(pHash, pReg->Rs2, 16);
+ NdisMoveMemory(pHash + 16, pReg->Psk2, 16);
+ NdisMoveMemory(pHash + 32, pReg->Pke, 192);
+ NdisMoveMemory(pHash + 224, pReg->Pkr, 192);
+
+ /* Generate R-Hash2 */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pHash, 416, RHash, SHA256_DIGEST_SIZE);
+
+ if (RTMPCompareMemory(pReg->RHash2, RHash, 32) != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM6 --> RHash2 not matched\n"));
+ ret = WSC_ERROR_DEV_PWD_AUTH_FAIL;
+ goto out;
+ }
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = pReg->LastTx.Length + pReg->LastRx.Length - 12;
+ if (pAdapter->pHmacData)
+ {
+ NdisMoveMemory(pAdapter->pHmacData, pReg->LastTx.Data, pReg->LastTx.Length);
+ NdisMoveMemory(pAdapter->pHmacData+ pReg->LastTx.Length, pReg->LastRx.Data, pReg->LastRx.Length - 12);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+
+ if (RTMPEqualMemory(Hmac, KDK, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ProcessMessageM6 --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) KDK)), (UINT)cpu2be32(*((PUINT)(KDK + 4)))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ ret = WSC_ERROR_HMAC_FAIL;
+ }
+
+ if( FieldCheck[0] || FieldCheck[1] || FieldCheck[2] || FieldCheck[3] || FieldCheck[4] || FieldCheck[5] || FieldCheck[6] )
+ ret = WSC_ERROR_WANTING_FIELD;
+out:
+ if(NULL != IV_DecrData)
+/* kfree(IV_DecrData); */
+ os_free_mem(NULL, IV_DecrData);
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM6 : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M7 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - recv buffer
+ Length - recv Length
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M7
+ 1. Change the correct parameters
+ 2. Process M7
+
+ ========================================================================
+*/
+int ProcessMessageM7(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ INT HmacLen;
+ UCHAR Hmac[8] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, KDK[32];
+ INT EncrLen;
+ PUCHAR pData = NULL;
+ USHORT WscType, WscLen;
+ UCHAR *IV_DecrData=NULL;/*IV len 16 ,DecrData len */
+
+ RTMPZeroMemory(KDK, 32);
+/* IV_DecrData = kmalloc(1024, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&IV_DecrData, 1024);
+ if(NULL == IV_DecrData)
+ {
+ ret = WSC_ERROR_CAN_NOT_ALLOCMEM;
+ return ret;
+ }
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M2 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M7 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ break;
+
+ case WSC_ID_REGISTRAR_NONCE:
+ /* for verification with our Registrar nonce */
+ if (RTMPCompareMemory(pReg->RegistrarNonce, pData, WscLen) != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M5 Compare Registrar nonce mismatched \n"));
+ }
+ break;
+
+ case WSC_ID_ENCR_SETTINGS:
+ /* There shall have smoe kind of length check */
+ if (WscLen <= 16)
+ break;
+ if (WscLen > 1024)
+ {
+ /* ApEncrSetting is not enough */
+ DBGPRINT(RT_DEBUG_TRACE, ("ApEncrSettings array size is not enough, require %d\n", WscLen));
+ break;
+ }
+ NdisMoveMemory(IV_DecrData, pData, WscLen);
+ EncrLen = sizeof(pReg->ApEncrSettings);
+ AES_CBC_Decrypt(IV_DecrData + 16, (WscLen - 16),pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),IV_DecrData, 16, (UINT8 *) pReg->ApEncrSettings, (UINT *) &EncrLen);
+ DBGPRINT(RT_DEBUG_TRACE, ("M7 ApEncrSettings len = %d\n ", EncrLen));
+
+
+ /* Parse encryption settings */
+ WscParseEncrSettings(pAdapter, pReg->ApEncrSettings, EncrLen, pWscControl);
+
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM7 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = pReg->LastTx.Length + pReg->LastRx.Length - 12;
+ if (pAdapter->pHmacData)
+ {
+ NdisMoveMemory(pAdapter->pHmacData, pReg->LastTx.Data, pReg->LastTx.Length);
+ NdisMoveMemory(pAdapter->pHmacData + pReg->LastTx.Length, pReg->LastRx.Data, pReg->LastRx.Length - 12);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+ if (RTMPEqualMemory(Hmac, KDK, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ProcessMessageM7 --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) KDK)), (UINT)cpu2be32(*((PUINT)(KDK + 4)))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ ret = WSC_ERROR_HMAC_FAIL;
+ }
+
+ if(NULL != IV_DecrData)
+/* kfree(IV_DecrData); */
+ os_free_mem(NULL, IV_DecrData);
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM7 : \n"));
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process WSC M8 Message
+
+ Arguments:
+ pAdapter - NIC Adapter pointer
+ pbuf - recv buffer
+ Length - recv Length
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ Actions after Rx M8
+ 1. Change the correct parameters
+ 2. Process M8
+
+ ========================================================================
+*/
+int ProcessMessageM8(
+ IN PRTMP_ADAPTER pAdapter,
+ IN VOID *precv,
+ IN INT Length,
+ IN PWSC_CTRL pWscControl)
+{
+ int ret = WSC_ERROR_NO_ERROR;
+ INT HmacLen;
+ UCHAR Hmac[8] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, KDK[32];
+ INT EncrLen;
+ PUCHAR pData = NULL;
+ USHORT WscType, WscLen;
+ UCHAR *IV_DecrData=NULL;/*IV len 16 ,DecrData len */
+ PWSC_REG_DATA pReg = &pWscControl->RegData;
+
+ RTMPZeroMemory(KDK, 32);
+/* IV_DecrData = kmalloc(1024, MEM_ALLOC_FLAG); */
+ os_alloc_mem(NULL, (UCHAR **)&IV_DecrData, 1024);
+ if(NULL == IV_DecrData)
+ {
+ ret = WSC_ERROR_CAN_NOT_ALLOCMEM;
+ return ret;
+ }
+ /* Copy the content to Regdata for lastRx information */
+ /* Length must include authenticator IE size */
+ pReg->LastRx.Length = Length;
+ NdisMoveMemory(pReg->LastRx.Data, precv, Length);
+ pData = pReg->LastRx.Data;
+
+ /* Start to process WSC IEs */
+ while (Length > 4)
+ {
+ WSC_IE TLV_Recv;
+ memcpy((UINT8 *)&TLV_Recv, pData, 4);
+ WscType = be2cpu16(TLV_Recv.Type);
+ WscLen = be2cpu16(TLV_Recv.Length);
+ pData += 4;
+ Length -= 4;
+
+ /* Parse M8 WSC type and store to RegData structure */
+ switch (WscType)
+ {
+ case WSC_ID_VERSION:
+ if(pReg->SelfInfo.Version != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Version mismatched %02x\n",*pData));
+ break;
+
+ case WSC_ID_MSG_TYPE:
+ if(WSC_ID_MESSAGE_M8 != *pData)
+ DBGPRINT(RT_DEBUG_ERROR, ("Rx WPS Message Type mismatched %02x\n",*pData));
+ break;
+
+ case WSC_ID_ENROLLEE_NONCE:
+ /* for verification with our enrollee nonce */
+ if (RTMPCompareMemory(pReg->EnrolleeNonce, pData, WscLen) != 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Rx M8 Compare enrollee nonce mismatched \n"));
+ }
+ break;
+
+ case WSC_ID_ENCR_SETTINGS:
+ /* There shall have smoe kind of length check */
+ if (WscLen <= 16)
+ break;
+ if (WscLen > 1024)
+ {
+ /* ApEncrSetting is not enough */
+ DBGPRINT(RT_DEBUG_TRACE, ("ApEncrSettings array size is not enough, require %d\n", WscLen));
+ break;
+ }
+ NdisMoveMemory(IV_DecrData, pData, WscLen);
+ EncrLen = sizeof(pReg->ApEncrSettings);
+ AES_CBC_Decrypt(IV_DecrData + 16, (WscLen - 16),pReg->KeyWrapKey,sizeof(pReg->KeyWrapKey),IV_DecrData, 16, (UINT8 *) pReg->ApEncrSettings, (UINT *) &EncrLen);
+ DBGPRINT(RT_DEBUG_TRACE, ("M8 ApEncrSettings len = %d\n ", EncrLen));
+
+ /* Parse encryption settings */
+ if (WscProcessCredential(pAdapter, pReg->ApEncrSettings, EncrLen, pWscControl) == FALSE)
+ {
+ if(NULL != IV_DecrData)
+ os_free_mem(NULL, IV_DecrData);
+ return WSC_ERROR_SETUP_LOCKED;
+ }
+
+ break;
+
+ case WSC_ID_AUTHENTICATOR:
+ NdisMoveMemory(Hmac, pData, WscLen);
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM8 --> Unknown IE 0x%04x\n", WscType));
+ break;
+ }
+
+ /* Offset to net WSC Ie */
+ pData += WscLen;
+ Length -= WscLen;
+ }
+
+ /* Combine last TX & RX message contents and validate the HMAC */
+ /* We have to exclude last 12 bytes from last receive since it's authenticator value */
+ HmacLen = pReg->LastTx.Length + pReg->LastRx.Length - 12;
+ if (pAdapter->pHmacData)
+ {
+ NdisMoveMemory(pAdapter->pHmacData, pReg->LastTx.Data, pReg->LastTx.Length);
+ NdisMoveMemory(pAdapter->pHmacData + pReg->LastTx.Length, pReg->LastRx.Data, pReg->LastRx.Length - 12);
+
+ /* Validate HMAC, reuse KDK buffer */
+ RT_HMAC_SHA256(pReg->AuthKey, 32, pAdapter->pHmacData, HmacLen, KDK, SHA256_DIGEST_SIZE);
+ }
+ if (RTMPEqualMemory(Hmac, KDK, 8) != 1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ProcessMessageM8 --> HMAC not match\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("MD --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) KDK)), (UINT)cpu2be32(*((PUINT)(KDK + 4)))));
+ DBGPRINT(RT_DEBUG_TRACE, ("calculated --> 0x%08x-%08x\n", (UINT)cpu2be32(*((PUINT) &Hmac[0])), (UINT)cpu2be32(*((PUINT) &Hmac[4]))));
+ ret = WSC_ERROR_HMAC_FAIL;
+ }
+
+ if(NULL != IV_DecrData)
+/* kfree(IV_DecrData); */
+ os_free_mem(NULL, IV_DecrData);
+ DBGPRINT(RT_DEBUG_TRACE, ("ProcessMessageM8 : \n"));
+ return ret;
+}
+
+#endif /* WSC_INCLUDED */
+
diff --git a/cleopatre/devkit/mt7601udrv/common/wsc_ufd.c b/cleopatre/devkit/mt7601udrv/common/wsc_ufd.c
new file mode 100644
index 0000000000..6f50290593
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/wsc_ufd.c
@@ -0,0 +1,598 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wsc_ufd.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+*/
+
+#include "rt_config.h"
+
+#ifdef WSC_INCLUDED
+
+static const STRING *XML_DECLARE_START = "<?xml";
+static const STRING *XML_DECLARE_END = "?>";
+static const STRING *XML_SSID_START = "<ssid";
+static const STRING *XML_SSID_END = "</ssid>";
+static const STRING *XML_AUTH_START = "<authentication>";
+static const STRING *XML_AUTH_END = "</authentication>";
+static const STRING *XML_ENCR_START = "<encryption>";
+static const STRING *XML_ENCR_END = "</encryption>";
+static const STRING *XML_KEY_START = "<networkKey";
+static const STRING *XML_KEY_END = "</networkKey>";
+static const STRING *XML_KEY_INDEX_START = "<keyIndex>";
+static const STRING *XML_KEY_INDEX_END = "</keyIndex>";
+
+static const STRING *XML_GUID_MARK = "CFG_GUID";
+static const STRING *XML_AP_GUID_MARK = "CFG_AP_GUID";
+static const STRING *XML_SSID_MARK = "CFG_SSID";
+static const STRING *XML_AUTH_MARK = "CFG_AUTH";
+static const STRING *XML_ENCR_MARK = "CFG_ENCR";
+static const STRING *XML_KEY_MARK = "CFG_KEY";
+
+static const STRING *XML_TEMPLATE =
+"<?xml version=\"1.0\"?>\n"
+"<wirelessProfile>\n"
+" <config>\n"
+" <configId>CFG_GUID"
+"</configId>\n"
+" <configAuthorId>CFG_AP_GUID"
+"</configAuthorId>\n"
+" <configAuthor>Ralink WPS AP</configAuthor>\n"
+" </config>\n"
+" <ssid xml:space=\"preserve\">CFG_SSID"
+"</ssid>\n"
+" <connectionType>ESS</connectionType>\n"
+" <channel2Dot4>0</channel2Dot4>\n"
+" <channel5Dot0>0</channel5Dot0>\n"
+" <primaryProfile>\n"
+" <authentication>CFG_AUTH"
+"</authentication>\n"
+" <encryption>CFG_ENCR"
+"</encryption>\n"
+" <networkKey xml:space=\"preserve\">CFG_KEY"
+"</networkKey>\n"
+" <keyProvidedAutomatically>0</keyProvidedAutomatically>\n"
+" <ieee802Dot1xEnabled>0</ieee802Dot1xEnabled>\n"
+" </primaryProfile>\n"
+"</wirelessProfile>\n";
+
+
+static struct {
+ PSTRING auth_str;
+ USHORT auth_type;
+} *PWSC_UFD_AUTH_TYPE, WSC_UFD_AUTH_TYPE[] = {
+ {"open", WSC_AUTHTYPE_OPEN},
+ {"shared", WSC_AUTHTYPE_SHARED},
+ {"WPA", WSC_AUTHTYPE_WPA},
+ {"WPA2", WSC_AUTHTYPE_WPA2},
+ {"WPAPSK", WSC_AUTHTYPE_WPAPSK},
+ {"WPA2PSK", WSC_AUTHTYPE_WPA2PSK},
+ {NULL,}
+};
+
+
+static struct {
+ PSTRING encr_str;
+ USHORT encr_type;
+} *PWSC_UFD_ENCR_TYPE, WSC_UFD_ENCR_TYPE[] = {
+ {"none", WSC_ENCRTYPE_NONE},
+ {"WEP", WSC_ENCRTYPE_WEP},
+ {"TKIP", WSC_ENCRTYPE_TKIP},
+ {"AES", WSC_ENCRTYPE_AES},
+ {NULL,}
+};
+
+
+BOOLEAN WscPassXmlDeclare(
+ INOUT STRING **pXmlData)
+{
+ STRING *ptr;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("======> WscPassXmlDeclare\n"));
+
+ ptr = rtstrstr(*pXmlData, (PSTRING)XML_DECLARE_START);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscPassXmlDeclare: missing XML Declare <?xml\n"));
+ return FALSE;
+ }
+
+ ptr = rtstrstr(*pXmlData, (PSTRING)XML_DECLARE_END);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("XML syntax error: missing XML Declare ?>\n"));
+ return FALSE;
+ }
+
+ (*pXmlData) = ptr + strlen(XML_DECLARE_END);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<====== WscPassXmlDeclare\n"));
+
+ return TRUE;
+}
+
+
+BOOLEAN WscGetXmlSSID(
+ IN STRING *pXmlData,
+ OUT NDIS_802_11_SSID *pSsid)
+{
+ STRING *ptr, *pBuffer = pXmlData;
+
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_SSID_START);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlSSID: missing <ssid\n"));
+ return FALSE;
+ }
+
+ pBuffer = ptr + strlen(XML_SSID_START);
+
+ ptr = rtstrstr(pBuffer, ">");
+ if (ptr)
+ {
+ pBuffer = ptr + 1;
+ }
+
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_SSID_END);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlSSID: missing </ssid>\n"));
+ return FALSE;
+ }
+
+ pSsid->SsidLength = (UINT)(ptr - pBuffer);
+ RTMPZeroMemory(pSsid->Ssid, NDIS_802_11_LENGTH_SSID);
+ if ((pSsid->SsidLength > 0) && (pSsid->SsidLength < 33))
+ {
+ RTMPMoveMemory(pSsid->Ssid, pBuffer, pSsid->SsidLength);
+ }
+ else
+ {
+ pSsid->SsidLength = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN WscGetXmlAuth(
+ IN STRING *pXmlData,
+ OUT USHORT *pAuthType)
+{
+ STRING *ptr, *pBuffer = pXmlData;
+ STRING AuthStr[10] = {0};
+ UINT AuthStrLen = 0;
+
+ *pAuthType = 0;
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_AUTH_START);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlAuth: missing %s\n", XML_AUTH_START));
+ return FALSE;
+ }
+
+ pBuffer = ptr + strlen(XML_AUTH_START);
+
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_AUTH_END);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlAuth: missing %s\n", XML_AUTH_END));
+ return FALSE;
+ }
+
+ AuthStrLen = (UINT)(ptr - pBuffer);
+ if ((AuthStrLen > 0) && (AuthStrLen <= 10))
+ {
+ RTMPMoveMemory(AuthStr, pBuffer, AuthStrLen);
+
+ for (PWSC_UFD_AUTH_TYPE = WSC_UFD_AUTH_TYPE; PWSC_UFD_AUTH_TYPE->auth_str; PWSC_UFD_AUTH_TYPE++)
+ {
+ if (strcmp(AuthStr, PWSC_UFD_AUTH_TYPE->auth_str) == 0)
+ {
+ *pAuthType = PWSC_UFD_AUTH_TYPE->auth_type;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOLEAN WscGetXmlEncr(
+ IN STRING *pXmlData,
+ OUT USHORT *pEncrType)
+{
+ STRING *ptr, *pBuffer = pXmlData;
+ STRING EncrStr[10] = {0};
+ UINT EncrStrLen = 0;
+
+ *pEncrType = 0;
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_ENCR_START);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlEncr: missing %s\n", XML_ENCR_START));
+ return FALSE;
+ }
+
+ pBuffer = ptr + strlen(XML_ENCR_START);
+
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_ENCR_END);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlEncr: missing %s\n", XML_ENCR_END));
+ return FALSE;
+ }
+
+ EncrStrLen = (UINT)(ptr - pBuffer);
+ if ((EncrStrLen > 0) && (EncrStrLen <= 10))
+ {
+ RTMPMoveMemory(EncrStr, pBuffer, EncrStrLen);
+
+ for (PWSC_UFD_ENCR_TYPE = WSC_UFD_ENCR_TYPE; PWSC_UFD_ENCR_TYPE->encr_str; PWSC_UFD_ENCR_TYPE++)
+ {
+ if (strcmp(EncrStr, PWSC_UFD_ENCR_TYPE->encr_str) == 0)
+ {
+ *pEncrType = PWSC_UFD_ENCR_TYPE->encr_type;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOLEAN WscGetXmlKey(
+ IN STRING *pXmlData,
+ OUT UCHAR *pKey,
+ OUT USHORT *pKeyLen)
+{
+ STRING *ptr, *pBuffer = pXmlData;
+ UINT KeyLen = 0;
+
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_KEY_START);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlKey: missing %s\n", XML_KEY_START));
+ return FALSE;
+ }
+
+ pBuffer = ptr + strlen(XML_KEY_START);
+
+ ptr = rtstrstr(pBuffer, ">");
+ if (ptr)
+ {
+ pBuffer = ptr + 1;
+ }
+
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_KEY_END);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlKey: missing %s\n", XML_KEY_END));
+ return FALSE;
+ }
+
+ KeyLen = (UINT)(ptr - pBuffer);
+ if ((KeyLen >= 8) && (KeyLen <= 64))
+ {
+ RTMPMoveMemory(pKey, pBuffer, KeyLen);
+ *pKeyLen = KeyLen;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN WscGetXmlKeyIndex(
+ IN STRING *pXmlData,
+ OUT UCHAR *pKeyIndex)
+{
+ STRING *ptr, *pBuffer = pXmlData;
+
+ *pKeyIndex = 1;
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_KEY_INDEX_START);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlKeyIndex: missing %s\n", XML_KEY_INDEX_START));
+ return FALSE;
+ }
+
+ pBuffer = ptr + strlen(XML_KEY_INDEX_START);
+
+ ptr = rtstrstr(pBuffer, (PSTRING)XML_KEY_INDEX_END);
+ if (ptr == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlKeyIndex: missing %s\n", XML_KEY_INDEX_END));
+ return FALSE;
+ }
+
+ *pKeyIndex = *(--ptr) - 0x30;
+
+ return TRUE;
+}
+
+
+
+BOOLEAN WscReadProfileFromUfdFile(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR ApIdx,
+ IN PSTRING pUfdFileName)
+{
+ PWSC_CREDENTIAL pCredential = &pAd->ApCfg.MBSSID[ApIdx].WscControl.WscProfile.Profile[0];
+ RTMP_OS_FS_INFO osFSInfo;
+ RTMP_OS_FD file_r;
+ ssize_t rv, fileLen = 0;
+ PSTRING pXmlData = NULL;
+ BOOLEAN RV = TRUE;
+
+ if (pUfdFileName == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s: pUfdFileName is NULL\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+ file_r = RtmpOSFileOpen(pUfdFileName, O_RDONLY, 0);
+ if (IS_FILE_OPEN_ERR(file_r))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s: Error opening file %s\n", __FUNCTION__, pUfdFileName));
+ return FALSE;
+ }
+ else
+ {
+ char tempStr[64] = {0};
+ while((rv = RtmpOSFileRead(file_r, tempStr, 64)) > 0)
+ {
+ fileLen += rv;
+ }
+ os_alloc_mem(pAd, (UCHAR **)&pXmlData, fileLen+1);
+ if (pXmlData == NULL)
+ {
+ RtmpOSFileClose(file_r);
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+ DBGPRINT(RT_DEBUG_TRACE, ("pXmlData kmalloc fail. (fileLen = %d)\n", fileLen));
+ return FALSE;
+ }
+ RTMPZeroMemory(pXmlData, fileLen+1);
+ RtmpOSFileSeek(file_r, 0);
+ rv = RtmpOSFileRead(file_r, (PSTRING)pXmlData, fileLen);
+ RtmpOSFileClose(file_r);
+ if (rv != fileLen)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSFileRead fail, fileLen = %d\n", fileLen));
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+ goto ReadErr;
+ }
+ }
+
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscReadProfileFromUfdFile\n"));
+ if (WscPassXmlDeclare(&pXmlData))
+ {
+ if (WscGetXmlSSID(pXmlData, &pCredential->SSID))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SSID = %s(%d)\n", pCredential->SSID.Ssid, pCredential->SSID.SsidLength));
+ }
+ else
+ {
+ RV = FALSE;
+ goto FreeXmlData;
+ }
+
+ if (WscGetXmlAuth(pXmlData, &pCredential->AuthType))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Credential.AuthType = 0x%04x\n", pCredential->AuthType));
+ }
+ else
+ {
+ RV = FALSE;
+ goto FreeXmlData;
+ }
+
+ if (WscGetXmlEncr(pXmlData, &pCredential->EncrType))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Credential.EncrType = 0x%04x\n", pCredential->EncrType));
+ }
+ else
+ {
+ RV = FALSE;
+ goto FreeXmlData;
+ }
+
+ pCredential->KeyLength = 0;
+ RTMPZeroMemory(pCredential->Key, 64);
+ if (WscGetXmlKey(pXmlData, pCredential->Key, &pCredential->KeyLength))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Credential.Key = %s (%d)\n", pCredential->Key, pCredential->KeyLength));
+ }
+ else
+ {
+ RV = FALSE;
+ goto FreeXmlData;
+ }
+
+ /*
+ If we cannot find keyIndex in .wfc file, use default value 1.
+ */
+ if (WscGetXmlKeyIndex(pXmlData, &pCredential->KeyIndex))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("pCredential->KeyIndex = %d\n", pCredential->KeyIndex));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WscReadProfileFromUfdFile OK\n"));
+
+ WscWriteConfToPortCfg(pAd,
+ &pAd->ApCfg.MBSSID[ApIdx].WscControl,
+ &pAd->ApCfg.MBSSID[ApIdx].WscControl.WscProfile.Profile[0], TRUE);
+
+ pAd->WriteWscCfgToDatFile = ApIdx;
+
+ RtmpOsTaskWakeUp(&(pAd->wscTask));
+
+FreeXmlData:
+ if (pXmlData)
+ os_free_mem(NULL, pXmlData);
+
+ return RV;
+ }
+
+ReadErr:
+ if (pXmlData)
+ os_free_mem(NULL, pXmlData);
+ return FALSE;
+}
+
+
+BOOLEAN WscWriteProfileToUfdFile(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ApIdx,
+ IN PSTRING pUfdFileName)
+{
+ PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[ApIdx].WscControl;
+ PWSC_CREDENTIAL pCredential = &pWscControl->WscProfile.Profile[0];
+ RTMP_OS_FS_INFO osFSInfo;
+ RTMP_OS_FD file_w;
+ PSTRING offset, pXmlTemplate = (PSTRING)XML_TEMPLATE;
+ BOOLEAN bFound = FALSE, bRtn = TRUE;
+ UCHAR Guid[UUID_LEN_HEX];
+ UCHAR Guid_Str[UUID_LEN_STR];
+
+ if (pUfdFileName == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s: pUfdFileName is NULL\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+ file_w = RtmpOSFileOpen(pUfdFileName, O_WRONLY|O_TRUNC|O_CREAT, 0);
+ if (IS_FILE_OPEN_ERR(file_w))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s: Error opening file %s\n", __FUNCTION__, pUfdFileName));
+ return FALSE;
+ }
+ else
+ {
+ WscCreateProfileFromCfg(pAd, AP_MODE, pWscControl, &pWscControl->WscProfile);
+
+ WscGenerateUUID(pAd, &Guid[0], &Guid_Str[0], ApIdx, TRUE);
+
+ if ((offset = rtstrstr(pXmlTemplate, (PSTRING)XML_GUID_MARK)) != NULL)
+ {
+ RtmpOSFileWrite(file_w, (PSTRING)pXmlTemplate, (int)(offset - pXmlTemplate));
+ RtmpOSFileWrite(file_w, (PSTRING)&Guid_Str[0], (int)UUID_LEN_STR);
+ pXmlTemplate = offset + strlen(XML_GUID_MARK);
+ }
+
+ if ((offset = rtstrstr(pXmlTemplate, (PSTRING)XML_AP_GUID_MARK)) != NULL)
+ {
+ RtmpOSFileWrite(file_w, (PSTRING)pXmlTemplate, (int)(offset - pXmlTemplate));
+ RtmpOSFileWrite(file_w, (PSTRING)&pWscControl->Wsc_Uuid_Str[0], (int)UUID_LEN_STR);
+ pXmlTemplate = offset + strlen(XML_AP_GUID_MARK);
+ }
+ if ((offset = rtstrstr(pXmlTemplate, (PSTRING)XML_SSID_MARK)) != NULL)
+ {
+ RtmpOSFileWrite(file_w, (PSTRING)pXmlTemplate, (int)(offset - pXmlTemplate));
+ RtmpOSFileWrite(file_w, (PSTRING)&pCredential->SSID.Ssid[0], (int)pCredential->SSID.SsidLength);
+ pXmlTemplate = offset + strlen(XML_SSID_MARK);
+ }
+ if ((offset = rtstrstr(pXmlTemplate, (PSTRING)XML_AUTH_MARK)) != NULL)
+ {
+ RtmpOSFileWrite(file_w, (PSTRING)pXmlTemplate, (int)(offset - pXmlTemplate));
+ for (PWSC_UFD_AUTH_TYPE = WSC_UFD_AUTH_TYPE; PWSC_UFD_AUTH_TYPE->auth_str; PWSC_UFD_AUTH_TYPE++)
+ {
+ if (PWSC_UFD_AUTH_TYPE->auth_type == pCredential->AuthType)
+ {
+ RtmpOSFileWrite(file_w,
+ (PSTRING)PWSC_UFD_AUTH_TYPE->auth_str,
+ (int)strlen(PWSC_UFD_AUTH_TYPE->auth_str));
+ bFound = TRUE;
+ break;
+ }
+ }
+ pXmlTemplate = offset + strlen(XML_AUTH_MARK);
+ if (bFound == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s: Unknow Auth Type(=%x)\n", __FUNCTION__, pCredential->AuthType));
+ bRtn = FALSE;
+ goto out;
+ }
+ }
+ if ((offset = rtstrstr(pXmlTemplate, (PSTRING)XML_ENCR_MARK)) != NULL)
+ {
+ bFound = FALSE;
+ RtmpOSFileWrite(file_w, (PSTRING)pXmlTemplate, (int)(offset - pXmlTemplate));
+ for (PWSC_UFD_ENCR_TYPE = WSC_UFD_ENCR_TYPE; PWSC_UFD_ENCR_TYPE->encr_str; PWSC_UFD_ENCR_TYPE++)
+ {
+ if (PWSC_UFD_ENCR_TYPE->encr_type == pCredential->EncrType)
+ {
+ RtmpOSFileWrite(file_w,
+ (PSTRING)PWSC_UFD_ENCR_TYPE->encr_str,
+ (int)strlen(PWSC_UFD_ENCR_TYPE->encr_str));
+ bFound = TRUE;
+ }
+ }
+ pXmlTemplate = offset + strlen(XML_ENCR_MARK);
+ if (bFound == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s: Unknow Encr Type(=%x)\n", __FUNCTION__, pCredential->EncrType));
+ bRtn = FALSE;
+ goto out;
+ }
+ }
+ if ((offset = rtstrstr(pXmlTemplate, (PSTRING)XML_KEY_MARK)) != NULL)
+ {
+ if (pCredential->EncrType != WSC_ENCRTYPE_NONE)
+ {
+ RtmpOSFileWrite(file_w, (PSTRING)pXmlTemplate, (int)(offset - pXmlTemplate));
+ RtmpOSFileWrite(file_w,
+ (PSTRING)pCredential->Key,
+ (int)pCredential->KeyLength);
+ pXmlTemplate = offset + strlen(XML_KEY_MARK);
+ }
+ else
+ {
+ RtmpOSFileWrite(file_w, (PSTRING)XML_ENCR_END, (int)strlen(XML_ENCR_END));
+ RtmpOSFileWrite(file_w, (PSTRING)"\n", (int)1);
+ pXmlTemplate = offset + strlen(XML_KEY_MARK) + strlen(XML_KEY_END) + 1; /* 1: '\n' */
+ }
+ }
+ RtmpOSFileWrite(file_w, (PSTRING)pXmlTemplate, (int)strlen(pXmlTemplate));
+ }
+
+out:
+ RtmpOSFileClose(file_w);
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+
+ return bRtn;
+}
+
+
+#endif /* WSC_INCLUDED */
diff --git a/cleopatre/devkit/mt7601udrv/common/wsc_v2.c b/cleopatre/devkit/mt7601udrv/common/wsc_v2.c
new file mode 100644
index 0000000000..8165dd7b04
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/wsc_v2.c
@@ -0,0 +1,408 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wsc_v2.c
+*/
+
+#include "rt_config.h"
+
+#ifdef WSC_V2_SUPPORT
+#include "wsc_tlv.h"
+
+BOOLEAN WscAppendV2SubItem(
+ IN UCHAR SubID,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ OUT PUCHAR pOutBuf,
+ OUT PUCHAR pOutBufLen);
+
+#ifdef CONFIG_AP_SUPPORT
+VOID WscOnOff(
+ IN PRTMP_ADAPTER pAd,
+ IN INT ApIdx,
+ IN BOOLEAN bOff)
+{
+ PWSC_V2_INFO pWpsV2Info = &pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscControl.WscV2Info;
+ if (bOff)
+ {
+ /*
+ AP must not support WEP in WPS V2
+ */
+ pWpsV2Info->bWpsEnable = FALSE;
+ pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscIEBeacon.ValueLen = 0;
+ pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscIEProbeResp.ValueLen = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("WscOnOff - OFF.\n"));
+ }
+ else
+ {
+ pWpsV2Info->bWpsEnable = TRUE;
+ if (pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscControl.WscConfMode != WSC_DISABLE)
+ {
+ INT IsAPConfigured;
+ IsAPConfigured = pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscControl.WscConfStatus;
+ WscBuildBeaconIE(pAd, IsAPConfigured, FALSE, 0, 0, (ApIdx & 0x0F), NULL, 0, AP_MODE);
+ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, ApIdx, NULL, 0, AP_MODE);
+ DBGPRINT(RT_DEBUG_TRACE, ("WscOnOff - ON.\n"));
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("WscOnOff - bWpsEnable = %d\n", pWpsV2Info->bWpsEnable));
+}
+
+VOID WscAddEntryToAclList(
+ IN PRTMP_ADAPTER pAd,
+ IN INT ApIdx,
+ IN PUCHAR pMacAddr)
+{
+ PRT_802_11_ACL pACL = NULL;
+ INT i;
+ BOOLEAN bFound = FALSE;
+
+ pACL = &pAd->ApCfg.MBSSID[ApIdx].AccessControlList;
+
+ if ((pACL->Policy == 0) ||
+ (pACL->Policy == 2))
+ return;
+
+ if (pACL->Num >= (MAX_NUM_OF_ACL_LIST - 1))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("The AccessControlList is full, and no more entry can join the list!\n"));
+ return;
+ }
+
+ for (i=0; i<pACL->Num; i++)
+ {
+ if (NdisEqualMemory(pACL->Entry[i].Addr, pMacAddr, MAC_ADDR_LEN))
+ bFound = TRUE;
+ }
+ if (bFound == FALSE)
+ {
+ NdisMoveMemory(pACL->Entry[i].Addr, pMacAddr, MAC_ADDR_LEN);
+ pACL->Num++;
+ }
+}
+
+VOID WscSetupLockTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
+ PRTMP_ADAPTER pAd = NULL;
+
+ if (pWscControl == NULL)
+ return;
+
+ pAd = (PRTMP_ADAPTER)pWscControl->pAd;
+
+ if (pAd == NULL)
+ return;
+
+ pWscControl->bSetupLock = FALSE;
+ pWscControl->WscSetupLockTimerRunning = FALSE;
+ pWscControl->PinAttackCount = 0;
+
+ WscBuildBeaconIE(pAd,
+ pWscControl->WscConfStatus,
+ FALSE,
+ 0,
+ 0,
+ (pWscControl->EntryIfIdx & 0xF),
+ NULL,
+ 0,
+ AP_MODE);
+ WscBuildProbeRespIE(pAd,
+ WSC_MSGTYPE_AP_WLAN_MGR,
+ pWscControl->WscConfStatus,
+ FALSE,
+ 0,
+ 0,
+ pWscControl->EntryIfIdx,
+ NULL,
+ 0,
+ AP_MODE);
+
+ APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F);
+ DBGPRINT(RT_DEBUG_TRACE, ("WscSetupLockTimeout!\n"));
+
+ return;
+}
+
+VOID WscCheckPinAttackCount(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl)
+{
+ BOOLEAN bCancelled;
+
+ if ((pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_APCLI)
+ )
+ {
+ /*
+ APCLI and P2P CLI don't need to do PIN attack checking.
+ */
+ return;
+ }
+
+ /*
+ If a static PIN is used,
+ the AP must track multiple failed attempts to authenticate an external Registrar and then enter a lock-down state
+ (This state is signified by setting the attribute AP Setup Locked to TRUE).
+ After at most 10 failed, consecutive attempts, with no time limitation, from any number of external Registrars,
+ the AP shall revert to a locked down state, and the AP shall remain in the locked down state indefinitely
+ (i.e., until the user intervenes to unlock AP's PIN for use by external Registrars)
+ */
+ pWscControl->PinAttackCount++;
+ if (pWscControl->PinAttackCount >= pWscControl->MaxPinAttack)
+ {
+ pWscControl->bSetupLock = TRUE;
+ if (pWscControl->WscSetupLockTimerRunning)
+ {
+ RTMPCancelTimer(&pWscControl->WscSetupLockTimer, &bCancelled);
+ pWscControl->WscSetupLockTimerRunning = FALSE;
+ }
+
+ if (pWscControl->PinAttackCount < WSC_LOCK_FOREVER_PIN_ATTACK)
+ {
+ pWscControl->WscSetupLockTimerRunning = TRUE;
+ RTMPSetTimer(&pWscControl->WscSetupLockTimer, pWscControl->SetupLockTime*60*1000);
+ }
+ //pWscControl->PinAttackCount = 0;
+
+ WscBuildBeaconIE(pAd,
+ pWscControl->WscConfStatus,
+ FALSE,
+ 0,
+ 0,
+ (pWscControl->EntryIfIdx & 0xF),
+ NULL,
+ 0,
+ AP_MODE);
+ WscBuildProbeRespIE(pAd,
+ WSC_MSGTYPE_AP_WLAN_MGR,
+ pWscControl->WscConfStatus,
+ FALSE,
+ 0,
+ 0,
+ pWscControl->EntryIfIdx,
+ NULL,
+ 0,
+ AP_MODE);
+
+ APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F);
+ }
+}
+
+#endif /* CONFIG_AP_SUPPORT */
+
+/*
+ Vendor ID: 0x00372A
+ Subelements ID (one-octet)
+ Version2 0x00
+ AuthorizedMACs 0x01
+ Network Key Shareable 0x02
+ Request to Enroll 0x03
+ Settings Delay Time 0x04
+ Reserved for future use 0x05 to 0xFF
+ Length (one-octet) - number of octets in the payload of this subelment
+ Version2 1B
+ AuthorizedMACs <=30B
+ Network Key Shareable Bool
+ Request to Enroll Bool
+ Settings Delay Time 1B
+*/
+BOOLEAN WscGenV2Msg(
+ IN PWSC_CTRL pWpsCtrl,
+ IN BOOLEAN bSelRegistrar,
+ IN PUCHAR pAuthorizedMACs,
+ IN INT AuthorizedMACsLen,
+ OUT UCHAR **pOutBuf,
+ OUT INT *pOutBufLen)
+{
+ PUCHAR pWscV2Msg = NULL;
+ USHORT WscV2MsgLen = 0;
+ PWSC_REG_DATA pReg = &pWpsCtrl->RegData;
+ INT templen = 0;
+
+ os_alloc_mem(NULL, (UCHAR **)&pWscV2Msg, 128);
+ if (pWscV2Msg)
+ {
+ UCHAR TmpLen = 0;
+ pWscV2Msg[0] = 0x00;
+ pWscV2Msg[1] = 0x37;
+ pWscV2Msg[2] = 0x2A;
+
+ /* Version2 */
+ WscAppendV2SubItem(WFA_EXT_ID_VERSION2, &pReg->SelfInfo.Version2, 1, pWscV2Msg+3, &TmpLen);
+ WscV2MsgLen += (3 + (USHORT)TmpLen);
+
+ if (bSelRegistrar)
+ {
+ /*
+ Authorized MACs
+ Registrars (both internal and external) shall add the AuthorizedMACs subelement,
+ this applies to all Configuration Methods, including PIN, PBC and NFC.
+ */
+ if (pAuthorizedMACs)
+ {
+ WscAppendV2SubItem( WFA_EXT_ID_AUTHORIZEDMACS,
+ pAuthorizedMACs,
+ AuthorizedMACsLen,
+ pWscV2Msg+WscV2MsgLen,
+ &TmpLen );
+ WscV2MsgLen += (USHORT)TmpLen;
+ }
+ else
+ {
+ WscAppendV2SubItem( WFA_EXT_ID_AUTHORIZEDMACS,
+ BROADCAST_ADDR,
+ MAC_ADDR_LEN,
+ pWscV2Msg+WscV2MsgLen,
+ &TmpLen );
+ WscV2MsgLen += (USHORT)TmpLen;
+ }
+ }
+
+ templen = AppendWSCTLV(WSC_ID_VENDOR_EXT, (*pOutBuf), (UINT8 *)pWscV2Msg, WscV2MsgLen);
+ (*pOutBuf) += templen;
+ (*pOutBufLen) += templen;
+
+ os_free_mem(NULL, pWscV2Msg);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOLEAN WscAppendV2SubItem(
+ IN UCHAR SubID,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ OUT PUCHAR pOutBuf,
+ OUT PUCHAR pOutBufLen)
+{
+ PUCHAR pBuf = NULL;
+ os_alloc_mem(NULL, &pBuf, DataLen + 10);
+ if (pBuf)
+ {
+ pBuf[0] = SubID;
+ pBuf[1] = DataLen;
+ NdisMoveMemory(pBuf+2, pData, DataLen);
+ *pOutBufLen = (DataLen + 2);
+ NdisMoveMemory(pOutBuf, pBuf, *pOutBufLen);
+ os_free_mem(NULL, pBuf);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOLEAN WscParseV2SubItem(
+ IN UCHAR SubID,
+ IN PUCHAR pData,
+ IN USHORT DataLen,
+ OUT PUCHAR pOutBuf,
+ OUT PUCHAR pOutBufLen)
+{
+ PEID_STRUCT pEid;
+ USHORT Length = 0;
+ pEid = (PEID_STRUCT) (pData + 3);
+ hex_dump("WscParseV2SubItem - pData", (pData+3), DataLen-3);
+ while ((Length + 2 + pEid->Len) <= (DataLen-3))
+ {
+ if (pEid->Eid == SubID)
+ {
+ *pOutBufLen = pEid->Len;
+ NdisMoveMemory(pOutBuf, &pEid->Octet[0], pEid->Len);
+ return TRUE;
+ }
+ Length = Length + 2 + pEid->Len;
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+ return FALSE;
+}
+
+VOID WscSendEapFragAck(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ if (pEntry == NULL)
+ {
+ ASSERT(pEntry!=NULL);
+ return;
+ }
+ if (IS_ENTRY_CLIENT(pEntry))
+ {
+ pWscControl->bWscLastOne = TRUE;
+ if (pAdapter->OpMode == OPMODE_AP)
+ WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, AP_MODE, EAP_CODE_REQ);
+ else
+ {
+ if (ADHOC_ON(pAdapter) && (pWscControl->WscConfMode == WSC_REGISTRAR))
+ WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, STA_MODE, EAP_CODE_REQ);
+ else
+ WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, STA_MODE, EAP_CODE_RSP);
+ }
+ }
+ else if (IS_ENTRY_APCLI(pEntry))
+ WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, AP_CLIENT_MODE, EAP_CODE_REQ);
+}
+
+VOID WscSendEapFragData(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ INT DataLen = 0;
+ PUCHAR pData = NULL;
+
+ if (pEntry == NULL)
+ {
+ ASSERT(pEntry!=NULL);
+ return;
+ }
+
+ pData = pWscControl->pWscCurBufIdx;
+ pWscControl->bWscLastOne = TRUE;
+ if (pWscControl->WscTxBufLen > pWscControl->WscFragSize)
+ {
+ pWscControl->bWscLastOne = FALSE;
+ DataLen = pWscControl->WscFragSize;
+ pWscControl->WscTxBufLen -= pWscControl->WscFragSize;
+ pWscControl->pWscCurBufIdx = (pWscControl->pWscCurBufIdx + pWscControl->WscFragSize);
+ }
+ else
+ {
+ DataLen = pWscControl->WscTxBufLen;
+ pWscControl->pWscCurBufIdx = NULL;
+ pWscControl->WscTxBufLen = 0;
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
+ {
+ if (IS_ENTRY_APCLI(pEntry))
+ WscSendMessage(pAdapter, WSC_OPCODE_MSG, pData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
+ else
+ WscSendMessage(pAdapter, WSC_OPCODE_MSG, pData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ);
+ }
+#endif // CONFIG_AP_SUPPORT //
+
+}
+
+#endif /* WSC_V2_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/action.h b/cleopatre/devkit/mt7601udrv/include/action.h
new file mode 100644
index 0000000000..4922e7419f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/action.h
@@ -0,0 +1,54 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ aironet.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 04-06-15 Initial
+*/
+
+#ifndef __ACTION_H__
+#define __ACTION_H__
+
+typedef struct GNU_PACKED __HT_INFO_OCTET {
+#ifdef RT_BIG_ENDIAN
+ UCHAR Reserved:5;
+ UCHAR STA_Channel_Width:1;
+ UCHAR Forty_MHz_Intolerant:1;
+ UCHAR Request:1;
+#else
+ UCHAR Request:1;
+ UCHAR Forty_MHz_Intolerant:1;
+ UCHAR STA_Channel_Width:1;
+ UCHAR Reserved:5;
+#endif
+} HT_INFORMATION_OCTET;
+
+typedef struct GNU_PACKED __FRAME_HT_INFO {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ HT_INFORMATION_OCTET HT_Info;
+} FRAME_HT_INFO, *PFRAME_HT_INFO;
+
+#endif /* __ACTION_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/ags.h b/cleopatre/devkit/mt7601udrv/include/ags.h
new file mode 100644
index 0000000000..0840400be6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ags.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All AGS (Adaptive Group Switching) Related Structure & Definition
+
+***************************************************************************/
+
+#ifndef __AGS_H__
+#define __AGS_H__
+
+
+extern UCHAR AGS1x1HTRateTable[];
+extern UCHAR AGS2x2HTRateTable[];
+extern UCHAR AGS3x3HTRateTable[];
+#ifdef DOT11_VHT_AC
+extern UCHAR Ags1x1VhtRateTable[];
+extern UCHAR Ags2x2VhtRateTable[];
+#endif /* DOT11_VHT_AC */
+
+#define AGS_TX_QUALITY_WORST_BOUND 8
+#define AGS_QUICK_RA_TIME_INTERVAL 50 /* 50ms */
+
+/* The size, in bytes, of an AGS entry in the rate switch table */
+#define SIZE_OF_AGS_RATE_TABLE_ENTRY 9
+
+typedef struct _RTMP_RA_AGS_TB {
+ UCHAR ItemNo;
+
+ UCHAR STBC:1;
+ UCHAR ShortGI:1;
+ UCHAR BW:2;
+ UCHAR Mode:3;
+ UCHAR Rsv1:1;
+
+ UCHAR Nss:2; // NSS_XXX (VHT only)
+ UCHAR rsv2:6; // Reserved
+
+ UCHAR CurrMCS;
+ UCHAR TrainUp;
+ UCHAR TrainDown;
+ UCHAR downMcs;
+ UCHAR upMcs3;
+ UCHAR upMcs2;
+ UCHAR upMcs1;
+}RTMP_RA_AGS_TB;
+
+
+/* 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) ((__pAd)->rateAlg == RATE_ALG_AGS)
+
+#ifdef DOT11_VHT_AC
+#define AGS_IS_USING(__pAd, __pRateTable) \
+ (SUPPORT_AGS(__pAd) && \
+ ((__pRateTable == AGS1x1HTRateTable) ||\
+ (__pRateTable == AGS2x2HTRateTable) ||\
+ (__pRateTable == AGS3x3HTRateTable) ||\
+ (__pRateTable == Ags1x1VhtRateTable) ||\
+ (__pRateTable == Ags2x2VhtRateTable)))
+#else
+#define AGS_IS_USING(__pAd, __pRateTable) \
+ (SUPPORT_AGS(__pAd) && \
+ ((__pRateTable == AGS1x1HTRateTable) || \
+ (__pRateTable == AGS2x2HTRateTable) || \
+ (__pRateTable == AGS3x3HTRateTable)))
+#endif /* DOT11_VHT_AC */
+
+#endif /* __AGS_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ap.h b/cleopatre/devkit/mt7601udrv/include/ap.h
new file mode 100644
index 0000000000..22c122d238
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap.h
@@ -0,0 +1,454 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap.h
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+ James Tan 09-06-2002 modified (Revise NTCRegTable)
+ John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
+*/
+#ifndef __AP_H__
+#define __AP_H__
+
+
+
+
+/* ============================================================= */
+/* Common definition */
+/* ============================================================= */
+#define MBSS_VLAN_INFO_GET( \
+ __pAd, __VLAN_VID, __VLAN_Priority, __FromWhichBSSID) \
+{ \
+ if ((__FromWhichBSSID < __pAd->ApCfg.BssidNum) && \
+ (__FromWhichBSSID < HW_BEACON_MAX_NUM) && \
+ (__pAd->ApCfg.MBSSID[__FromWhichBSSID].VLAN_VID != 0)) \
+ { \
+ __VLAN_VID = __pAd->ApCfg.MBSSID[__FromWhichBSSID].VLAN_VID; \
+ __VLAN_Priority = __pAd->ApCfg.MBSSID[__FromWhichBSSID].VLAN_Priority; \
+ } \
+}
+
+/* ============================================================= */
+/* 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 RTMP_ADAPTER *pAd,
+ IN RXINFO_STRUC *pRxInfo,
+ 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 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 APCls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader);
+
+/*
+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 */
+
+#ifdef CONFIG_AP_SUPPORT
+BOOLEAN BeaconTransmitRequired(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN MULTISSID_STRUCT *pMbss);
+#endif /* CONFIG_AP_SUPPORT */
+
+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);
+
+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 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 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 INT MsgLen,
+ IN IE_LISTS *ie_lists);
+
+
+BOOLEAN PeerDisassocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT UINT16 *SeqNum,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerDeauthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT UINT16 *SeqNum,
+ OUT USHORT *Reason);
+
+BOOLEAN APPeerAuthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr1,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Alg,
+ OUT USHORT *Seq,
+ OUT USHORT *Status,
+ OUT CHAR *ChlgText
+ );
+
+
+#ifdef DOT1X_SUPPORT
+/* ap_cfg.h */
+INT Set_OwnIPAddr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_EAPIfName_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PreAuthIfName_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+/* Define in ap.c */
+BOOLEAN DOT1X_InternalCmdAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UINT8 cmd);
+
+BOOLEAN DOT1X_EapTriggerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+#endif /* DOT1X_SUPPORT */
+#endif /* __AP_H__ */
+
+VOID AP_E2PROM_IOCTL_PostCtrl(
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN PSTRING msg);
+
+VOID IAPP_L2_UpdatePostCtrl(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 *mac_p,
+ IN INT bssid);
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_apcli.h b/cleopatre/devkit/mt7601udrv/include/ap_apcli.h
new file mode 100644
index 0000000000..9874a86a4f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_apcli.h
@@ -0,0 +1,275 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_apcli.h
+
+ Abstract:
+ Support AP-Client function.
+
+ Revision History:
+ Who When What
+ -------------- ---------- ----------------------------------------------
+ Shiang, Fonchi 02-13-2007 created
+*/
+
+#ifndef _AP_APCLI_H_
+#define _AP_APCLI_H_
+
+#ifdef APCLI_SUPPORT
+
+#include "rtmp.h"
+
+#define AUTH_TIMEOUT 300 /* unit: msec */
+#define ASSOC_TIMEOUT 300 /* unit: msec */
+/*#define JOIN_TIMEOUT 2000 // unit: msec // not used in Ap-client mode, remove it */
+#define PROBE_TIMEOUT 1000 /* unit: msec */
+
+#define APCLI_ROOT_BSSID_GET(pAd, wcid) ((pAd)->MacTab.Content[(wcid)].Addr)
+
+/* sanity check for apidx */
+#define APCLI_MR_APIDX_SANITY_CHECK(idx) \
+{ \
+ if ((idx) >= MAX_APCLI_NUM) \
+ { \
+ (idx) = 0; \
+ DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apcli-idx > MAX_APCLI_NUM!\n", __FUNCTION__)); \
+ } \
+}
+
+typedef struct _APCLI_MLME_JOIN_REQ_STRUCT {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR SsidLen;
+ UCHAR Ssid[MAX_LEN_OF_SSID];
+} APCLI_MLME_JOIN_REQ_STRUCT;
+
+typedef struct _STA_CTRL_JOIN_REQ_STRUCT {
+ USHORT Status;
+} APCLI_CTRL_MSG_STRUCT, *PSTA_CTRL_MSG_STRUCT;
+
+BOOLEAN isValidApCliIf(
+ SHORT ifIndex);
+
+/* */
+/* Private routines in apcli_ctrl.c */
+/* */
+VOID ApCliCtrlStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+/* */
+/* Private routines in apcli_sync.c */
+/* */
+VOID ApCliSyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+/* */
+/* Private routines in apcli_auth.c */
+/* */
+VOID ApCliAuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+/* */
+/* Private routines in apcli_assoc.c */
+/* */
+VOID ApCliAssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+MAC_TABLE_ENTRY *ApCliTableLookUpByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddrs);
+
+
+BOOLEAN ApCliAllowToSendPacket(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pPacket,
+ OUT UCHAR *pWcid);
+
+BOOLEAN ApCliValidateRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT pEid_ptr,
+ IN USHORT eid_len,
+ IN USHORT idx);
+
+
+VOID ApCli_Remove(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT28xx_ApCli_Close(
+ IN PRTMP_ADAPTER pAd);
+
+
+
+INT ApCliIfLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+
+INT ApCli_VirtualIF_PacketSend(
+ IN PNDIS_PACKET skb_p,
+ IN PNET_DEV dev_p);
+
+INT ApCli_VirtualIF_Ioctl(
+ IN PNET_DEV dev_p,
+ IN OUT VOID *rq_p,
+ IN INT cmd);
+
+
+VOID ApCliMgtMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid,
+ IN USHORT ifIndex);
+
+#ifdef DOT11_N_SUPPORT
+BOOLEAN ApCliCheckHt(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT IfIndex,
+ IN OUT HT_CAPABILITY_IE *pHtCapability,
+ IN OUT ADD_HT_INFO_IE *pAddHtInfo);
+#endif /* DOT11_N_SUPPORT */
+
+BOOLEAN ApCliLinkUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ifIndex);
+
+VOID ApCliLinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ifIndex);
+
+VOID ApCliIfUp(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ApCliIfDown(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ApCliIfMonitor(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ApCliMsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType);
+
+BOOLEAN preCheckMsgTypeSubset(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType);
+
+BOOLEAN ApCliPeerAssocRspSanity(
+ 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 UCHAR *pCkipFlag);
+
+VOID ApCliPeerPairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ApCliPeerPairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ApCliPeerGroupMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+BOOLEAN ApCliCheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ IN MAC_TABLE_ENTRY *pEntry,
+ OUT UCHAR *Offset);
+
+BOOLEAN ApCliParseKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR IfIdx,
+ IN UCHAR bPairewise);
+
+BOOLEAN ApCliHandleRxBroadcastFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR FromWhichBSSID);
+
+VOID APCliInstallPairwiseKey(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN APCliInstallSharedKey(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyLen,
+ IN UCHAR DefaultKeyIdx,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID ApCliUpdateMlmeRate(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APCli_Init(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_OS_NETDEV_OP_HOOK *pNetDevOps);
+
+BOOLEAN ApCli_Open(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV dev_p);
+
+BOOLEAN ApCli_Close(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV dev_p);
+
+BOOLEAN ApCliWaitProbRsp(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT ifIndex);
+
+#endif /* APCLI_SUPPORT */
+
+#endif /* _AP_APCLI_H_ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_autoChSel.h b/cleopatre/devkit/mt7601udrv/include/ap_autoChSel.h
new file mode 100644
index 0000000000..4eed2ac303
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_autoChSel.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Abstract:
+
+
+ */
+
+#include "ap_autoChSel_cmm.h"
+
+#ifndef __AUTOCHSELECT_H__
+#define __AUTOCHSELECT_H__
+
+#define AP_AUTO_CH_SEL(__P, __O) APAutoSelectChannel((__P), (__O))
+
+ULONG AutoChBssSearchWithSSID(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR Bssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel);
+
+VOID APAutoChannelInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID UpdateChannelInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN int ch,
+ IN ChannelSel_Alg Alg);
+
+ULONG AutoChBssInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR ChannelNo,
+ IN UCHAR ExtChOffset,
+ IN CHAR Rssi);
+
+VOID AutoChBssTableInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ChannelInfoInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AutoChBssTableDestroy(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ChannelInfoDestroy(
+ IN PRTMP_ADAPTER pAd);
+
+VOID CheckPhyModeIsABand(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR SelectBestChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN ChannelSel_Alg Alg);
+
+UCHAR APAutoSelectChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN ChannelSel_Alg Alg);
+
+#endif /* __AUTOCHSELECT_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_autoChSel_cmm.h b/cleopatre/devkit/mt7601udrv/include/ap_autoChSel_cmm.h
new file mode 100644
index 0000000000..21a822a8fc
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_autoChSel_cmm.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Abstract:
+
+
+ */
+
+
+#ifndef __AUTOCHSELECT_CMM_H__
+#define __AUTOCHSELECT_CMM_H__
+
+#define RSSI_TO_DBM_OFFSET 120 /* RSSI-115 = dBm */
+
+
+typedef struct {
+ ULONG dirtyness[MAX_NUM_OF_CHANNELS+1];
+ ULONG ApCnt[MAX_NUM_OF_CHANNELS+1];
+ UINT32 FalseCCA[MAX_NUM_OF_CHANNELS+1];
+ BOOLEAN SkipList[MAX_NUM_OF_CHANNELS+1];
+#ifdef AP_QLOAD_SUPPORT
+ UINT32 chanbusytime[MAX_NUM_OF_CHANNELS+1]; /* QLOAD ALARM */
+#endif /* AP_QLOAD_SUPPORT */
+ BOOLEAN IsABand;
+} CHANNELINFO, *PCHANNELINFO;
+
+typedef struct {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR Channel;
+ UCHAR ExtChOffset;
+ CHAR Rssi;
+} BSSENTRY, *PBSSENTRY;
+
+typedef struct {
+ UCHAR BssNr;
+ BSSENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
+} BSSINFO, *PBSSINFO;
+
+typedef enum ChannelSelAlg
+{
+ ChannelAlgRandom, /*use by Dfs */
+ ChannelAlgApCnt,
+ ChannelAlgCCA
+} ChannelSel_Alg;
+
+#endif /* __AUTOCHSELECT_CMM_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_cfg.h b/cleopatre/devkit/mt7601udrv/include/ap_cfg.h
new file mode 100644
index 0000000000..81be09272b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_cfg.h
@@ -0,0 +1,167 @@
+#ifndef __AP_CFG_H__
+#define __AP_CFG_H__
+
+
+#include "rt_config.h"
+
+INT RTMPAPPrivIoctlSet(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr);
+
+INT RTMPAPPrivIoctlShow(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr);
+
+#ifdef INF_AR9
+#ifdef AR9_MAPI_SUPPORT
+INT RTMPAPPrivIoctlAR9Show(
+ IN RTMP_ADAPTER *pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr);
+
+VOID RTMPAR9IoctlGetMacTable(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlGetSTAT2(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlGetRadioDynInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+#endif /*AR9_MAPI_SUPPORT*/
+#endif/* INF_AR9 */
+
+INT RTMPAPSetInformation(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT RTMP_IOCTL_INPUT_STRUCT *rq,
+ IN INT cmd);
+
+INT RTMPAPQueryInformation(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT RTMP_IOCTL_INPUT_STRUCT *rq,
+ IN INT cmd);
+
+VOID RTMPIoctlStatistics(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+
+VOID RTMPIoctlGetMacTable(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+
+VOID RTMPAPIoctlE2PROM(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+#ifdef DBG
+VOID RTMPAPIoctlBBP(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPAPIoctlMAC(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+
+#endif /* DBG */
+
+VOID RtmpDrvMaxRateGet(
+ IN VOID *pReserved,
+/* IN PHTTRANSMIT_SETTING pHtPhyMode, */
+ IN UINT8 MODE,
+ IN UINT8 ShortGI,
+ IN UINT8 BW,
+ IN UINT8 MCS,
+ OUT UINT32 *pRate);
+
+#ifdef WSC_AP_SUPPORT
+VOID RTMPIoctlWscProfile(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlWscProfile(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+/*add by woody */
+#ifdef INF_AR9
+#ifdef AR9_MAPI_SUPPORT
+VOID RTMPAR9IoctlWscProfile(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlWscPINCode(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+
+VOID RTMPIoctlWscStatus(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlGetWscDynInfo(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlGetWscRegsDynInfo(
+ IN PRTMP_ADAPTER pAdapter,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+#endif/*AR9_MAPI_SUPPORT*/
+#endif/* INF_AR9 */
+#endif /* WSC_AP_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+VOID RTMPIoctlQueryBaTable(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT1X_SUPPORT
+VOID RTMPIoctlStaticWepCopy(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlRadiusData(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlAddWPAKey(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlAddPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+VOID RTMPIoctlSetIdleTimeout(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+#endif /* DOT1X_SUPPORT */
+
+INT ApCfg_Set_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PSTRING arg);
+
+INT ApCfg_Set_MaxStaNum_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PSTRING arg);
+
+INT ApCfg_Set_IdleTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+VOID RTMPApCliAddKey(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PNDIS_APCLI_802_11_KEY pApcliKey);
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif /* APCLI_SUPPORT */
+#endif /* __AP_CFG_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_diversity.h b/cleopatre/devkit/mt7601udrv/include/ap_diversity.h
new file mode 100644
index 0000000000..30ba044c10
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_diversity.h
@@ -0,0 +1,142 @@
+/***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_diversity.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------
+ YY Huang 06-10-2008 Init for RT3052.
+*/
+
+#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"
+
+/*
+ * 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; i<MAX_BUSY_COUNT; i++) \
+ { \
+ RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);\
+ if (BbpCsr.field.Busy == BUSY) \
+ continue; \
+ BbpCsr.word = 0; \
+ BbpCsr.field.fRead = 1; \
+ BbpCsr.field.BBP_RW_MODE = 1; \
+ BbpCsr.field.Busy = 1; \
+ BbpCsr.field.RegNum = _I; \
+ RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);\
+ AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0, FALSE); \
+ RTMPusecDelay(10); \
+ for (k=0; k<MAX_BUSY_COUNT; k++) \
+ { \
+ RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
+ if (BbpCsr.field.Busy == IDLE) \
+ break; \
+ else \
+ printk("MCU busy\n"); \
+ } \
+ if ((BbpCsr.field.Busy == IDLE) && \
+ (BbpCsr.field.RegNum == _I)) \
+ { \
+ *(_pV) = (UCHAR)BbpCsr.field.Value; \
+ break; \
+ } \
+ } \
+ if (BbpCsr.field.Busy == BUSY) \
+ { \
+ DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \
+ *(_pV) = (_A)->BbpWriteLatch[_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 RTMP_ADAPTER *pAd);
+
+VOID RT3XXX_AntDiversity_Fini(
+ IN RTMP_ADAPTER *pAd);
+
+VOID AntDiversity_Update_Rssi_Sample(
+ IN RTMP_ADAPTER *pAd,
+ IN RSSI_SAMPLE *pRssi,
+ IN RXWI_STRUC *pRxWI);
+
+
+#endif
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_ids.h b/cleopatre/devkit/mt7601udrv/include/ap_ids.h
new file mode 100644
index 0000000000..6d7d23d341
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_ids.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ap_ids.c
+
+ Abstract:
+ IDS definition
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ */
+
+VOID RTMPIdsPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN RTMPSpoofedMgmtDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2,
+ IN UCHAR AntSel);
+
+VOID RTMPConflictSsidDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2,
+ IN UCHAR AntSel);
+
+BOOLEAN RTMPReplayAttackDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2,
+ IN UCHAR AntSel,
+ IN UCHAR BW);
+
+VOID RTMPUpdateStaMgmtCounter(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT type);
+
+VOID RTMPClearAllIdsCounter(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPIdsStart(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPIdsStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID rtmp_read_ids_from_file(
+ IN PRTMP_ADAPTER pAd,
+ char *tmpbuf,
+ char *buffer);
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_mbss.h b/cleopatre/devkit/mt7601udrv/include/ap_mbss.h
new file mode 100644
index 0000000000..7e07e920d2
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_mbss.h
@@ -0,0 +1,86 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_mbss.h
+
+ Abstract:
+ Support multi-BSS function.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sample Lin 01-02-2007 created
+*/
+
+#ifndef MODULE_MBSS
+
+#define MBSS_EXTERN extern
+
+#else
+
+#define MBSS_EXTERN
+
+#endif /* MODULE_MBSS */
+
+
+/*
+ For MBSS, the phy mode is different;
+ So MBSS_PHY_MODE_RESET() can help us to adjust the correct mode &
+ maximum MCS for the BSS.
+*/
+#define MBSS_PHY_MODE_RESET(__BssId, __HtPhyMode) \
+ { \
+ UCHAR __PhyMode = pAd->ApCfg.MBSSID[__BssId].PhyMode; \
+ if ((__PhyMode == WMODE_B) && \
+ (__HtPhyMode.field.MODE != MODE_CCK)) \
+ { \
+ __HtPhyMode.field.MODE = MODE_CCK; \
+ __HtPhyMode.field.MCS = 3; \
+ } \
+ else if ((!WMODE_CAP_N(__PhyMode)) && \
+ (__PhyMode != WMODE_B) && \
+ (__HtPhyMode.field.MODE != MODE_OFDM)) \
+ { \
+ __HtPhyMode.field.MODE = MODE_OFDM; \
+ __HtPhyMode.field.MCS = 7; \
+ } \
+ }
+
+
+/* Public function list */
+INT Show_MbssInfo_Display_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+VOID MBSS_Init(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_OS_NETDEV_OP_HOOK *pNetDevOps);
+
+VOID MBSS_Remove(
+ IN PRTMP_ADAPTER pAd);
+
+INT MBSS_Open(
+ IN PNET_DEV pDev);
+
+INT MBSS_Close(
+ IN PNET_DEV pDev);
+
+INT32 RT28xx_MBSS_IdxGet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV pDev);
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ap_wds.h b/cleopatre/devkit/mt7601udrv/include/ap_wds.h
new file mode 100644
index 0000000000..016ea9edbe
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ap_wds.h
@@ -0,0 +1,220 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ap_wds.h
+
+ Abstract:
+ Support WDS function.
+
+ Revision History:
+ Who When What
+ ------ ---------- ----------------------------------------------
+ Fonchi 02-13-2007 created
+*/
+
+
+#ifndef _AP_WDS_H_
+#define _AP_WDS_H_
+
+#define WDS_ENTRY_RETRY_INTERVAL (100 * OS_HZ / 1000)
+
+#ifdef WDS_VLAN_SUPPORT /* support WDS VLAN */
+#define WDS_VLAN_INFO_GET( \
+ __pAd, __VLAN_VID, __VLAN_Priority, __FromWhichBSSID) \
+{ \
+ if ((__FromWhichBSSID >= MIN_NET_DEVICE_FOR_WDS) && \
+ (__FromWhichBSSID < (MIN_NET_DEVICE_FOR_WDS+MAX_WDS_ENTRY)) && \
+ (__pAd->WdsTab.WdsEntry[ \
+ __FromWhichBSSID - MIN_NET_DEVICE_FOR_WDS].VLAN_VID != 0)) \
+ { \
+ __VLAN_VID = __pAd->WdsTab.WdsEntry[ \
+ __FromWhichBSSID - MIN_NET_DEVICE_FOR_WDS].VLAN_VID; \
+ __VLAN_Priority = __pAd->WdsTab.WdsEntry[ \
+ __FromWhichBSSID - MIN_NET_DEVICE_FOR_WDS].VLAN_Priority;\
+ } \
+}
+#else
+#define WDS_VLAN_INFO_GET( \
+ __pAd, __VLAN_VID, __VLAN_Priority, __FromWhichBSSID)
+#endif /* WDS_VLAN_SUPPORT */
+
+static inline BOOLEAN WDS_IF_UP_CHECK(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG ifidx)
+{
+ if ((pAd->flg_wds_init != TRUE) ||
+ (ifidx >= MAX_WDS_ENTRY))
+ return FALSE;
+
+/* if(RTMP_OS_NETDEV_STATE_RUNNING(pAd->WdsTab.WdsEntry[ifidx].dev)) */
+/* Patch for wds ,when dirver call apmlmeperiod => APMlmeDynamicTxRateSwitching check if wds device ready */
+if ((pAd->WdsTab.WdsEntry[ifidx].dev != NULL) && (RTMP_OS_NETDEV_STATE_RUNNING(pAd->WdsTab.WdsEntry[ifidx].dev)))
+ return TRUE;
+
+ return FALSE;
+}
+
+LONG WdsEntryAlloc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+VOID WdsEntryDel(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+MAC_TABLE_ENTRY *MacTableInsertWDSEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ UINT WdsTabIdx);
+
+BOOLEAN MacTableDeleteWDSEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr);
+
+
+BOOLEAN ApWdsAllowToSendPacket(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pPacket,
+ OUT UCHAR *pWcid);
+
+MAC_TABLE_ENTRY *WdsTableLookupByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount);
+
+MAC_TABLE_ENTRY *WdsTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount);
+
+MAC_TABLE_ENTRY *FindWdsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN PUCHAR pAddr,
+ IN UINT32 PhyMode);
+
+VOID WdsTableMaintenance(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT28xx_WDS_Close(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID WdsDown(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateWdsRxWCIDTable(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateWdsEncryption(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid);
+
+VOID WdsPeerBeaconProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN USHORT CapabilityInfo,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN UCHAR MaxSupportedRateLen,
+ IN BOOLEAN bWmmCapable,
+ IN ULONG ClientRalinkIe,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen);
+
+VOID APWdsInitialize(
+ IN PRTMP_ADAPTER pAd);
+
+INT Show_WdsTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+VOID rtmp_read_wds_from_file(
+ IN PRTMP_ADAPTER pAd,
+ PSTRING tmpbuf,
+ PSTRING buffer);
+
+VOID WdsPrepareWepKeyFromMainBss(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID WDS_Init(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_OS_NETDEV_OP_HOOK *pNetDevOps);
+
+VOID WDS_Remove(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN WDS_StatsGet(
+ IN PRTMP_ADAPTER pAd,
+ IN RT_CMD_STATS *pStats);
+
+VOID AP_WDS_KeyNameMakeUp(
+ IN STRING *pKey,
+ IN UINT32 KeyMaxSize,
+ IN INT KeyId);
+
+/*
+ ==========================================================================
+ Description:
+ Check the WDS Entry is valid or not.
+ ==========================================================================
+ */
+static inline BOOLEAN ValidWdsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR WdsIndex)
+{
+ BOOLEAN result;
+ PMAC_TABLE_ENTRY pMacEntry;
+
+ do
+ {
+ if (WdsIndex >= MAX_WDS_ENTRY)
+ {
+ result = FALSE;
+ break;
+ }
+
+ if (pAd->WdsTab.WdsEntry[WdsIndex].Valid != TRUE)
+ {
+ result = FALSE;
+ break;
+ }
+
+ if ((pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID==0)
+ || (pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID >= MAX_LEN_OF_MAC_TABLE))
+ {
+ result = FALSE;
+ break;
+ }
+
+ pMacEntry = &pAd->MacTab.Content[pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID];
+ if (!IS_ENTRY_WDS(pMacEntry))
+ {
+ result = FALSE;
+ break;
+ }
+
+ result = TRUE;
+ } while(FALSE);
+
+ return result;
+}
+#endif /* _AP_WDS_H_ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/br_ftph.h b/cleopatre/devkit/mt7601udrv/include/br_ftph.h
new file mode 100644
index 0000000000..7810cf1342
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/br_ftph.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All Bridge Fast Path Related Structure & Definition.
+
+***************************************************************************/
+
+#ifndef __BR_FTPH_H__
+#define __BR_FTPH_H__
+
+/* Public function prototype */
+/*
+========================================================================
+Routine Description:
+ Init bridge fast path module.
+
+Arguments:
+ None
+
+Return Value:
+ None
+
+Note:
+ Used in module init.
+========================================================================
+*/
+VOID BG_FTPH_Init(VOID);
+
+/*
+========================================================================
+Routine Description:
+ Remove bridge fast path module.
+
+Arguments:
+ None
+
+Return Value:
+ None
+
+Note:
+ Used in module remove.
+========================================================================
+*/
+VOID BG_FTPH_Remove(VOID);
+
+/*
+========================================================================
+Routine Description:
+ Forward the received packet.
+
+Arguments:
+ pPacket - the received packet
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UINT32 BG_FTPH_PacketFromApHandle(
+ IN PNDIS_PACKET pPacket);
+
+#endif /* __BR_FTPH_H__ */
+
+/* End of br_ftph.h */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/cfg80211.h b/cleopatre/devkit/mt7601udrv/include/cfg80211.h
new file mode 100644
index 0000000000..36139d1149
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/cfg80211.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All MAC80211/CFG80211 Related Structure & Definition.
+
+***************************************************************************/
+
+#ifdef RT_CFG80211_SUPPORT
+
+#include <linux/ieee80211.h>
+
+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;
+
+ /* channel information */
+ struct ieee80211_channel ChanInfo[MAX_NUM_OF_CHANNELS];
+} CFG80211_CB;
+
+
+
+
+/*
+========================================================================
+Routine Description:
+ Register MAC80211 Module.
+
+Arguments:
+ pAd - WLAN control block pointer
+ pDev - Generic device interface
+ pNetDev - Network device
+
+Return Value:
+ NONE
+
+Note:
+ pDev != pNetDev
+ #define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev))
+
+ Can not use pNetDev to replace pDev; Or kernel panic.
+========================================================================
+*/
+BOOLEAN CFG80211_Register(
+ VOID *pAd,
+ struct device *pDev,
+ struct net_device *pNetDev);
+
+
+#endif /* RT_CFG80211_SUPPORT */
+
+/* End of cfg80211.h */
diff --git a/cleopatre/devkit/mt7601udrv/include/cfg80211extr.h b/cleopatre/devkit/mt7601udrv/include/cfg80211extr.h
new file mode 100644
index 0000000000..32032f4800
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/cfg80211extr.h
@@ -0,0 +1,201 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All MAC80211/CFG80211 Function Prototype.
+
+***************************************************************************/
+
+#ifdef RT_CFG80211_SUPPORT
+
+#define RT_CFG80211_REGISTER(__pDev, __pNetDev) \
+ CFG80211_Register(__pDev, __pNetDev);
+
+#define RT_CFG80211_BEACON_CR_PARSE(__pAd, __pVIE, __LenVIE) \
+ CFG80211_BeaconCountryRegionParse((VOID *)__pAd, __pVIE, __LenVIE);
+
+#define RT_CFG80211_CRDA_REG_HINT(__pAd, __pCountryIe, __CountryIeLen) \
+ CFG80211_RegHint((VOID *)__pAd, __pCountryIe, __CountryIeLen);
+
+#define RT_CFG80211_CRDA_REG_HINT11D(__pAd, __pCountryIe, __CountryIeLen) \
+ CFG80211_RegHint11D((VOID *)__pAd, __pCountryIe, __CountryIeLen);
+
+#define RT_CFG80211_CRDA_REG_RULE_APPLY(__pAd) \
+ CFG80211_RegRuleApply((VOID *)__pAd, NULL, __pAd->Cfg80211_Alpha2);
+
+#define RT_CFG80211_SCANNING_INFORM(__pAd, __BssIdx, __ChanId, __pFrame, \
+ __FrameLen, __RSSI) \
+ CFG80211_Scaning((VOID *)__pAd, __BssIdx, __ChanId, __pFrame, \
+ __FrameLen, __RSSI);
+
+#define RT_CFG80211_SCAN_END(__pAd, __FlgIsAborted) \
+ CFG80211_ScanEnd((VOID *)__pAd, __FlgIsAborted);
+
+#define RT_CFG80211_REINIT(__pAd) \
+ CFG80211_SupBandReInit((VOID *)__pAd); \
+
+#define RT_CFG80211_CONN_RESULT_INFORM(__pAd, __pBSSID, __pReqIe, __ReqIeLen,\
+ __pRspIe, __RspIeLen, __FlgIsSuccess) \
+ CFG80211_ConnectResultInform((VOID *)__pAd, __pBSSID, \
+ __pReqIe, __ReqIeLen, __pRspIe, __RspIeLen, __FlgIsSuccess);
+
+#define RT_CFG80211_RFKILL_STATUS_UPDATE(_pAd, _active) \
+ CFG80211_RFKillStatusUpdate(_pAd, _active);
+
+#ifdef SINGLE_SKU
+#define CFG80211_BANDINFO_FILL(__pAd, __pBandInfo) \
+{ \
+ (__pBandInfo)->RFICType = __pAd->RFICType; \
+ (__pBandInfo)->MpduDensity = __pAd->CommonCfg.BACapability.field.MpduDensity;\
+ (__pBandInfo)->TxStream = __pAd->CommonCfg.TxStream; \
+ (__pBandInfo)->RxStream = __pAd->CommonCfg.RxStream; \
+ (__pBandInfo)->MaxTxPwr = __pAd->CommonCfg.DefineMaxTxPwr; \
+ if (WMODE_EQUAL(__pAd->CommonCfg.PhyMode, WMODE_B)) \
+ (__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 (WMODE_EQUAL(__pAd->CommonCfg.PhyMode, WMODE_B)) \
+ (__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 */
+INT CFG80211DRV_IoctlHandle(
+ IN VOID *pAdSrc,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN INT cmd,
+ IN USHORT subcmd,
+ IN VOID *pData,
+ IN ULONG Data);
+
+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 CFG80211DRV_SurveyGet(
+ VOID *pAdOrg,
+ VOID *pData);
+
+VOID CFG80211DRV_PmkidConfig(
+ 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 */
+
+VOID CFG80211_UnRegister(
+ IN VOID *pAdOrg,
+ IN VOID *pNetDev);
+
+#endif /* RT_CFG80211_SUPPORT */
+
+/* End of cfg80211extr.h */
diff --git a/cleopatre/devkit/mt7601udrv/include/chip/chip_id.h b/cleopatre/devkit/mt7601udrv/include/chip/chip_id.h
new file mode 100644
index 0000000000..8df348a0ec
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/chip/chip_id.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ chip_id.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __CHIP_ID_H__
+#define __CHIP_ID_H__
+
+
+#define NIC_PCI_VENDOR_ID 0x1814
+
+#define NIC2860_PCI_DEVICE_ID 0x0601
+#define NIC2860_PCIe_DEVICE_ID 0x0681
+#define NIC2760_PCI_DEVICE_ID 0x0701 /* 1T/2R Cardbus ??? */
+#define NIC2790_PCIe_DEVICE_ID 0x0781 /* 1T/2R miniCard */
+
+#define VEN_AWT_PCIe_DEVICE_ID 0x1059
+#define VEN_AWT_PCI_VENDOR_ID 0x1A3B
+
+#define EDIMAX_PCI_VENDOR_ID 0x1432
+
+#define NIC3090_PCIe_DEVICE_ID 0x3090 /* 1T/1R miniCard */
+#define NIC3091_PCIe_DEVICE_ID 0x3091 /* 1T/2R miniCard */
+#define NIC3092_PCIe_DEVICE_ID 0x3092 /* 2T/2R miniCard */
+#define NIC3390_PCIe_DEVICE_ID 0x3390 /* 1T/1R miniCard */
+
+#define NIC3062_PCI_DEVICE_ID 0x3062 /* 2T/2R miniCard */
+#define NIC3562_PCI_DEVICE_ID 0x3562 /* 2T/2R miniCard */
+#define NIC3060_PCI_DEVICE_ID 0x3060 /* 1T/1R miniCard */
+
+#define NIC3592_PCIe_DEVICE_ID 0x3592 /* 2T/2R miniCard */
+
+
+#define NIC3593_PCI_OR_PCIe_DEVICE_ID 0x3593
+#define NIC5390_PCIe_DEVICE_ID 0x5390
+#define NIC539F_PCIe_DEVICE_ID 0x539F
+#define NIC5392_PCIe_DEVICE_ID 0x5392
+#define NIC5360_PCI_DEVICE_ID 0x5360
+#define NIC5362_PCI_DEVICE_ID 0x5362
+
+#define NIC5592_PCIe_DEVICE_ID 0x5592
+
+#define NIC3290_PCIe_DEVICE_ID 0x3290
+
+#define NIC6590_PCIe_DEVICE_ID 0x6590
+#define NIC7601_PCIe_DEVICE_ID 0x7601
+
+#define NIC8592_5592_PCIe_DEVICE_ID 0x5592
+#define NIC8592_PCIe_DEVICE_ID 0x8592
+
+#define NIC6390_PCIe_DEVICE_ID 0x6390
+
+#endif /* __CHIP_ID_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/chip/mt7601.h b/cleopatre/devkit/mt7601udrv/include/chip/mt7601.h
new file mode 100644
index 0000000000..9879003355
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/chip/mt7601.h
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt6590.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __MT7601_H__
+#define __MT7601_H__
+
+struct _RTMP_ADAPTER;
+
+#define MAC_VERSION ""
+
+#define BBP_VERSION "MT7601E2_BBP_CSD_20121019"
+#define RF_VERSION "RT6390_RF_Register_20121122"
+
+#define NIC6590_PCIe_DEVICE_ID 0x6590
+#define MAX_RF_ID 127
+#define MAC_RF_BANK 7
+
+#define MAX_CHECK_COUNT 200
+#define MT7601_VALID_EEPROM_VERSION 0x0C
+
+#define ENABLE_WLAN_FUN(__WlanFunCtrl)\
+{\
+ __WlanFunCtrl.field.WLAN_CLK_EN = 1;\
+ __WlanFunCtrl.field.WLAN_EN = 1;\
+}
+
+#define DISABLE_WLAN_FUN(__WlanFunCtrl)\
+{\
+ __WlanFunCtrl.field.PCIE_APP0_CLK_REQ = 0;\
+ __WlanFunCtrl.field.WLAN_EN = 0;\
+ __WlanFunCtrl.field.WLAN_CLK_EN = 0;\
+}
+
+#define MT7601_WSC_HDR_BTN_GPIO 0x400
+#define MT7601_WSC_HDR_BTN_MR_PRESS_FLG_GET(__pAd, __FlgIsPressed) \
+ { \
+ UINT32 __gpio_value; \
+ RTMP_IO_READ32(__pAd, WLAN_FUN_CTRL, (&__gpio_value)); \
+ if (__gpio_value & MT7601_WSC_HDR_BTN_GPIO) \
+ __FlgIsPressed = 0; \
+ else \
+ __FlgIsPressed = 1; \
+ }
+
+
+#define RF_PA_MODE0_DECODE 0
+#define RF_PA_MODE1_DECODE 8847 // 1.08 * 8192
+#define RF_PA_MODE2_DECODE -5734 // -0.7 * 8192
+#define RF_PA_MODE3_DECODE -5734 // -0.7 * 8192
+
+#define MT7601_E2_TEMPERATURE_SLOPE 39
+
+#define BW20_MCS_POWER_CCK_1M ((pAd->Tx20MPwrCfgGBand[0] & 0xFF) < 0x20)?(pAd->Tx20MPwrCfgGBand[0] & 0xFF):(CHAR)((pAd->Tx20MPwrCfgGBand[0] & 0xFF) - 0x40)
+#define BW20_MCS_POWER_CCK_2M ((pAd->Tx20MPwrCfgGBand[0] & 0xFF) < 0x20)?(pAd->Tx20MPwrCfgGBand[0] & 0xFF):(CHAR)((pAd->Tx20MPwrCfgGBand[0] & 0xFF) - 0x40)
+#define BW20_MCS_POWER_CCK_5M (((pAd->Tx20MPwrCfgGBand[0] & 0xFF00) >> 8) < 0x20)?((pAd->Tx20MPwrCfgGBand[0] & 0xFF00) >> 8):(CHAR)(((pAd->Tx20MPwrCfgGBand[0] & 0xFF00) >> 8)-0x40)
+#define BW20_MCS_POWER_CCK_11M (((pAd->Tx20MPwrCfgGBand[0] & 0xFF00) >> 8) < 0x20)?((pAd->Tx20MPwrCfgGBand[0] & 0xFF00) >> 8):(CHAR)(((pAd->Tx20MPwrCfgGBand[0] & 0xFF00) >> 8)-0x40)
+#define BW40_MCS_POWER_CCK_1M ((pAd->Tx40MPwrCfgGBand[0] & 0xFF) < 0x20)?(pAd->Tx40MPwrCfgGBand[0] & 0xFF) :(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF) < 0x20)-0x40)
+#define BW40_MCS_POWER_CCK_2M ((pAd->Tx40MPwrCfgGBand[0] & 0xFF) < 0x20)?(pAd->Tx40MPwrCfgGBand[0] & 0xFF) :(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF) < 0x20)-0x40)
+#define BW40_MCS_POWER_CCK_5M (((pAd->Tx40MPwrCfgGBand[0] & 0xFF00) >> 8) < 0x20)?((pAd->Tx40MPwrCfgGBand[0] & 0xFF00) >> 8):(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF00) >> 8)-0x40)
+#define BW40_MCS_POWER_CCK_11M (((pAd->Tx40MPwrCfgGBand[0] & 0xFF00) >> 8) < 0x20)?((pAd->Tx40MPwrCfgGBand[0] & 0xFF00) >> 8):(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF00) >> 8)-0x40)
+
+#define BW20_MCS_POWER_OFDM_6M (((pAd->Tx20MPwrCfgGBand[0] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx20MPwrCfgGBand[0] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx20MPwrCfgGBand[0] & 0xFF0000) >> 16)-0x40)
+#define BW20_MCS_POWER_OFDM_9M (((pAd->Tx20MPwrCfgGBand[0] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx20MPwrCfgGBand[0] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx20MPwrCfgGBand[0] & 0xFF0000) >> 16)-0x40)
+#define BW20_MCS_POWER_OFDM_12M (((pAd->Tx20MPwrCfgGBand[0] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx20MPwrCfgGBand[0] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx20MPwrCfgGBand[0] & 0xFF000000) >> 24)-0x40)
+#define BW20_MCS_POWER_OFDM_18M (((pAd->Tx20MPwrCfgGBand[0] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx20MPwrCfgGBand[0] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx20MPwrCfgGBand[0] & 0xFF000000) >> 24)-0x40)
+#define BW20_MCS_POWER_OFDM_24M ((pAd->Tx20MPwrCfgGBand[1] & 0xFF) < 0x20)?(pAd->Tx20MPwrCfgGBand[1] & 0xFF):(CHAR)((pAd->Tx20MPwrCfgGBand[1] & 0xFF)-0x40)
+#define BW20_MCS_POWER_OFDM_36M ((pAd->Tx20MPwrCfgGBand[1] & 0xFF) < 0x20)?(pAd->Tx20MPwrCfgGBand[1] & 0xFF):(CHAR)((pAd->Tx20MPwrCfgGBand[1] & 0xFF)-0x40)
+#define BW20_MCS_POWER_OFDM_48M (((pAd->Tx20MPwrCfgGBand[1] & 0xFF00) >> 8) < 0x20)?((pAd->Tx20MPwrCfgGBand[1] & 0xFF00) >> 8):(CHAR)(((pAd->Tx20MPwrCfgGBand[1] & 0xFF00) >> 8)-0x40)
+#define BW20_MCS_POWER_OFDM_54M (((pAd->Tx20MPwrCfgGBand[1] & 0xFF00) >> 8) < 0x20)?((pAd->Tx20MPwrCfgGBand[1] & 0xFF00) >> 8):(CHAR)(((pAd->Tx20MPwrCfgGBand[1] & 0xFF00) >> 8)-0x40)
+#define BW40_MCS_POWER_OFDM_6M (((pAd->Tx40MPwrCfgGBand[0] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx40MPwrCfgGBand[0] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF0000) >> 16)-0x40)
+#define BW40_MCS_POWER_OFDM_9M (((pAd->Tx40MPwrCfgGBand[0] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx40MPwrCfgGBand[0] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF0000) >> 16)-0x40)
+#define BW40_MCS_POWER_OFDM_12M (((pAd->Tx40MPwrCfgGBand[0] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx40MPwrCfgGBand[0] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF000000) >> 24)-0x40)
+#define BW40_MCS_POWER_OFDM_18M (((pAd->Tx40MPwrCfgGBand[0] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx40MPwrCfgGBand[0] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx40MPwrCfgGBand[0] & 0xFF000000) >> 24)-0x40)
+#define BW40_MCS_POWER_OFDM_24M ((pAd->Tx40MPwrCfgGBand[1] & 0xFF) < 0x20)?(pAd->Tx40MPwrCfgGBand[1] & 0xFF):(CHAR)((pAd->Tx40MPwrCfgGBand[1] & 0xFF)-0x40)
+#define BW40_MCS_POWER_OFDM_36M ((pAd->Tx40MPwrCfgGBand[1] & 0xFF) < 0x20)?(pAd->Tx40MPwrCfgGBand[1] & 0xFF):(CHAR)((pAd->Tx40MPwrCfgGBand[1] & 0xFF)-0x40)
+#define BW40_MCS_POWER_OFDM_48M (((pAd->Tx40MPwrCfgGBand[1] & 0xFF00) >> 8) < 0x20)?((pAd->Tx40MPwrCfgGBand[1] & 0xFF00) >> 8):(CHAR)(((pAd->Tx40MPwrCfgGBand[1] & 0xFF00) >> 8)-0x40)
+#define BW40_MCS_POWER_OFDM_54M (((pAd->Tx40MPwrCfgGBand[1] & 0xFF00) >> 8) < 0x20)?((pAd->Tx40MPwrCfgGBand[1] & 0xFF00) >> 8):(CHAR)(((pAd->Tx40MPwrCfgGBand[1] & 0xFF00) >> 8)-0x40)
+
+#define BW20_MCS_POWER_HT_MCS0 (((pAd->Tx20MPwrCfgGBand[1] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx20MPwrCfgGBand[1] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx20MPwrCfgGBand[1] & 0xFF0000) >> 16)-0x40)
+#define BW20_MCS_POWER_HT_MCS1 (((pAd->Tx20MPwrCfgGBand[1] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx20MPwrCfgGBand[1] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx20MPwrCfgGBand[1] & 0xFF0000) >> 16)-0x40)
+#define BW20_MCS_POWER_HT_MCS2 (((pAd->Tx20MPwrCfgGBand[1] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx20MPwrCfgGBand[1] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx20MPwrCfgGBand[1] & 0xFF000000) >> 24)-0x40)
+#define BW20_MCS_POWER_HT_MCS3 (((pAd->Tx20MPwrCfgGBand[1] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx20MPwrCfgGBand[1] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx20MPwrCfgGBand[1] & 0xFF000000) >> 24)-0x40)
+#define BW20_MCS_POWER_HT_MCS4 ((pAd->Tx20MPwrCfgGBand[2] & 0xFF) < 0x20)?(pAd->Tx20MPwrCfgGBand[2] & 0xFF):(CHAR)((pAd->Tx20MPwrCfgGBand[2] & 0xFF)-0x40)
+#define BW20_MCS_POWER_HT_MCS5 ((pAd->Tx20MPwrCfgGBand[2] & 0xFF) < 0x20)?(pAd->Tx20MPwrCfgGBand[2] & 0xFF):(CHAR)((pAd->Tx20MPwrCfgGBand[2] & 0xFF)-0x40)
+#define BW20_MCS_POWER_HT_MCS6 (((pAd->Tx20MPwrCfgGBand[2] & 0xFF00 ) >> 8) < 0x20)?((pAd->Tx20MPwrCfgGBand[2] & 0xFF00 ) >> 8):(CHAR)(((pAd->Tx20MPwrCfgGBand[2] & 0xFF00 ) >> 8)-0x40)
+#define BW20_MCS_POWER_HT_MCS7 (((pAd->Tx20MPwrCfgGBand[2] & 0xFF00 ) >> 8) < 0x20)?((pAd->Tx20MPwrCfgGBand[2] & 0xFF00 ) >> 8):(CHAR)(((pAd->Tx20MPwrCfgGBand[2] & 0xFF00 ) >> 8)-0x40)
+#define BW40_MCS_POWER_HT_MCS0 (((pAd->Tx40MPwrCfgGBand[1] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx40MPwrCfgGBand[1] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx40MPwrCfgGBand[1] & 0xFF0000) >> 16)-0x40)
+#define BW40_MCS_POWER_HT_MCS1 (((pAd->Tx40MPwrCfgGBand[1] & 0xFF0000) >> 16) < 0x20)?((pAd->Tx40MPwrCfgGBand[1] & 0xFF0000) >> 16):(CHAR)(((pAd->Tx40MPwrCfgGBand[1] & 0xFF0000) >> 16)-0x40)
+#define BW40_MCS_POWER_HT_MCS2 (((pAd->Tx40MPwrCfgGBand[1] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx40MPwrCfgGBand[1] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx40MPwrCfgGBand[1] & 0xFF000000) >> 24)-0x40)
+#define BW40_MCS_POWER_HT_MCS3 (((pAd->Tx40MPwrCfgGBand[1] & 0xFF000000) >> 24) < 0x20)?((pAd->Tx40MPwrCfgGBand[1] & 0xFF000000) >> 24):(CHAR)(((pAd->Tx40MPwrCfgGBand[1] & 0xFF000000) >> 24)-0x40)
+#define BW40_MCS_POWER_HT_MCS4 ((pAd->Tx40MPwrCfgGBand[2] & 0xFF) < 0x20)?(pAd->Tx40MPwrCfgGBand[2] & 0xFF):(CHAR)((pAd->Tx40MPwrCfgGBand[2] & 0xFF)-0x40)
+#define BW40_MCS_POWER_HT_MCS5 ((pAd->Tx40MPwrCfgGBand[2] & 0xFF) < 0x20)?(pAd->Tx40MPwrCfgGBand[2] & 0xFF):(CHAR)((pAd->Tx40MPwrCfgGBand[2] & 0xFF)-0x40)
+#define BW40_MCS_POWER_HT_MCS6 (((pAd->Tx40MPwrCfgGBand[2] & 0xFF00) >> 8) < 0x20)?((pAd->Tx40MPwrCfgGBand[2] & 0xFF00) >> 8):(CHAR)(((pAd->Tx40MPwrCfgGBand[2] & 0xFF00) >> 8)-0x40)
+#define BW40_MCS_POWER_HT_MCS7 (((pAd->Tx40MPwrCfgGBand[2] & 0xFF00) >> 8) < 0x20)?((pAd->Tx40MPwrCfgGBand[2] & 0xFF00) >> 8):(CHAR)(((pAd->Tx40MPwrCfgGBand[2] & 0xFF00) >> 8)-0x40)
+
+#define RF_PA_MODE_CCK_1M (pAd->chipCap.PAModeCCK[0])
+#define RF_PA_MODE_CCK_2M (pAd->chipCap.PAModeCCK[1])
+#define RF_PA_MODE_CCK_5M (pAd->chipCap.PAModeCCK[2])
+#define RF_PA_MODE_CCK_11M (pAd->chipCap.PAModeCCK[3])
+
+#define RF_PA_MODE_OFDM_6M (pAd->chipCap.PAModeOFDM[0])
+#define RF_PA_MODE_OFDM_9M (pAd->chipCap.PAModeOFDM[1])
+#define RF_PA_MODE_OFDM_12M (pAd->chipCap.PAModeOFDM[2])
+#define RF_PA_MODE_OFDM_18M (pAd->chipCap.PAModeOFDM[3])
+#define RF_PA_MODE_OFDM_24M (pAd->chipCap.PAModeOFDM[4])
+#define RF_PA_MODE_OFDM_36M (pAd->chipCap.PAModeOFDM[5])
+#define RF_PA_MODE_OFDM_48M (pAd->chipCap.PAModeOFDM[6])
+#define RF_PA_MODE_OFDM_54M (pAd->chipCap.PAModeOFDM[7])
+
+#define RF_PA_MODE_HT_MCS0 (pAd->chipCap.PAModeHT[0])
+#define RF_PA_MODE_HT_MCS1 (pAd->chipCap.PAModeHT[1])
+#define RF_PA_MODE_HT_MCS2 (pAd->chipCap.PAModeHT[2])
+#define RF_PA_MODE_HT_MCS3 (pAd->chipCap.PAModeHT[3])
+#define RF_PA_MODE_HT_MCS4 (pAd->chipCap.PAModeHT[4])
+#define RF_PA_MODE_HT_MCS5 (pAd->chipCap.PAModeHT[5])
+#define RF_PA_MODE_HT_MCS6 (pAd->chipCap.PAModeHT[6])
+#define RF_PA_MODE_HT_MCS7 (pAd->chipCap.PAModeHT[7])
+#define RF_PA_MODE_HT_MCS8 (pAd->chipCap.PAModeHT[8])
+#define RF_PA_MODE_HT_MCS9 (pAd->chipCap.PAModeHT[9])
+#define RF_PA_MODE_HT_MCS10 (pAd->chipCap.PAModeHT[10])
+#define RF_PA_MODE_HT_MCS11 (pAd->chipCap.PAModeHT[11])
+#define RF_PA_MODE_HT_MCS12 (pAd->chipCap.PAModeHT[12])
+#define RF_PA_MODE_HT_MCS13 (pAd->chipCap.PAModeHT[13])
+#define RF_PA_MODE_HT_MCS14 (pAd->chipCap.PAModeHT[14])
+#define RF_PA_MODE_HT_MCS15 (pAd->chipCap.PAModeHT[15])
+
+enum TEMPERATURE_MODE {
+ TEMPERATURE_MODE_NORMAL,
+ TEMPERATURE_MODE_LOW,
+ TEMPERATURE_MODE_HIGH,
+};
+
+#ifdef RTMP_INTERNAL_TX_ALC
+#define DEFAULT_BO 4
+#define LIN2DB_ERROR_CODE (-10000)
+
+VOID MT7601_TssiDcGainCalibration(struct _RTMP_ADAPTER *pAd);
+
+typedef struct _MT7601_TX_ALC_DATA {
+ INT32 PowerDiffPre;
+ INT32 MT7601_TSSI_T0_Delta_Offset;
+ INT16 TSSI_DBOFFSET_HVGA;
+ INT16 TSSI0_DB;
+ UCHAR TssiSlope;
+ CHAR TssiDC0;
+ CHAR TssiDC0_HVGA;
+ UINT32 InitTxAlcCfg1;
+ BOOLEAN TSSI_USE_HVGA;
+ BOOLEAN TssiTriggered;
+ CHAR MT7601_TSSI_OFFSET[3];
+} MT7601_TX_ALC_DATA, *PMT7601_TX_ALC_DATA;
+
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+/*
+ rsv: Reserved
+ tcp: packet type, tcp : 1, udp:0
+ tups: TCP/UDP header start offset (in unit of DWORD)
+ ips: IP start offset (in unit of byte), base address of ips is the beginning of TXWI
+ mss: Max Segment size (in unit of byte)
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct _TSO_INFO_{
+ UINT32 mss:16;
+ UINT32 ips:8;
+ UINT32 tups:6;
+ UINT32 tcp:1;
+ UINT32 rsv:1;
+}TSO_INFO;
+#else
+typedef struct _TSO_INFO_{
+ UINT32 rsv:1;
+ UINT32 tcp:1;
+ UINT32 tups:6;
+ UINT32 ips:8;
+ UINT32 mss:16;
+}TSO_INFO;
+#endif /* RT_BIG_ENDIAN */
+
+/*
+ * Frequency plan item for MT7601
+ * K_R17[7:0]: sdm_k[7:0]
+ * K_R18[7:0]: sdm_k[15:8]
+ * K_R19[1:0]: sdm_k[17:16]
+ * K_R19[3]: sdm_clk_sel
+ * R_R20[7:0]: sdm_n[7:0]
+ */
+typedef struct _MT7601_FREQ_ITEM {
+ UINT8 Channel;
+ UINT8 K_R17;
+ UINT8 K_R18;
+ UINT8 K_R19;
+ UINT8 N_R20;
+} MT7601_FREQ_ITEM;
+
+#define RF_G_BAND 0x01
+#define RF_A_BAND 0x02
+#define RF_A_BAND_LB 0x04
+#define RF_A_BAND_MB 0x08
+#define RF_A_BAND_HB 0x10
+typedef struct _RT6590_RF_SWITCH_ITEM {
+ UCHAR Bank;
+ UCHAR Register;
+ UCHAR Band; /* G_Band, A_Band_LB, A_Band_MB, A_Band_HB */
+ UCHAR BW;
+ UCHAR Value;
+} RT6590_RF_SWITCH_ITEM, *PRT6590_RF_SWITCH_ITEM;
+
+VOID MT7601_Init(struct _RTMP_ADAPTER *pAd);
+VOID MT7601_RXDC_CAL(struct _RTMP_ADAPTER *pAd);
+INT MT7601_ReadChannelPwr(struct _RTMP_ADAPTER *pAd);
+VOID MT7601_ReadTxPwrPerRate(struct _RTMP_ADAPTER *pAd);
+VOID MT7601_INIT_CAL(struct _RTMP_ADAPTER *pAd);
+NTSTATUS MT7601DisableTxRx(struct _RTMP_ADAPTER *pAd, UCHAR Level);
+VOID dump_bw_info(struct _RTMP_ADAPTER *pAd);
+VOID MT7601AsicTemperatureCompensation(IN struct _RTMP_ADAPTER *pAd, IN BOOLEAN bPowerOn);
+#ifdef RTMP_INTERNAL_TX_ALC
+INT16 lin2dBd(UINT16 linearValue);
+VOID MT7601_EnableTSSI(struct _RTMP_ADAPTER *pAd);
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(SINGLE_SKU_V2)
+VOID MT7601_InitPAModeTable(struct _RTMP_ADAPTER *pAd);
+#endif /* defined(RTMP_INTERNAL_TX_ALC) || defined(SINGLE_SKU_V2) */
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+VOID MT7601_AsicMitigateMicrowave(
+ IN struct _RTMP_ADAPTER *pAd);
+
+VOID MT7601_AsicMeasureFalseCCA(
+ IN struct _RTMP_ADAPTER *pAd);
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+INT MT7601_Read_Temperature(
+ struct _RTMP_ADAPTER *pAd,
+ OUT CHAR* Temperature);
+
+INT MT7601_Bootup_Read_Temperature(
+ struct _RTMP_ADAPTER *pAd,
+ OUT CHAR* Temperature);
+
+VOID MT7601SetRxAnt(
+ struct _RTMP_ADAPTER *pAd,
+ IN UCHAR Ant);
+#endif /* __MT7601_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/chip/rt28xx.h b/cleopatre/devkit/mt7601udrv/include/chip/rt28xx.h
new file mode 100644
index 0000000000..3eacae6497
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/chip/rt28xx.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt28xx.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RT28XX_H__
+#define __RT28XX_H__
+
+#ifdef RT28xx
+
+VOID RT28xx_ChipSwitchChannel(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan);
+
+#endif /* RT28xx */
+
+#endif /*__RT28XX_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/chip/rt3290.h b/cleopatre/devkit/mt7601udrv/include/chip/rt3290.h
new file mode 100644
index 0000000000..2ca19e68e6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/chip/rt3290.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt3290.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RT3290_H__
+#define __RT3290_H__
+
+#ifdef RT3290
+
+#error "For RT3290, you should define the compile flag -DRTMP_PCI_SUPPORT"
+
+#error "For RT3290, you should define the compile flag -DRTMP_MAC_PCI"
+
+#error "For RT3290, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
+
+#error "For RT3290, you should define the compile flag -DRT30xx"
+
+#include "chip/mac_pci.h"
+#include "chip/rt30xx.h"
+
+struct _RTMP_ADAPTER;
+
+
+#define NIC3290_PCIe_DEVICE_ID 0x3290
+
+
+#define RT3290_CHECK_SW_EEP_BUSY(pAd) \
+{ \
+ UINT32 _val, _cnt = 0; \
+ do { \
+ RTMP_IO_FORCE_READ32(pAd, WLAN_FUN_INFO, &_val); \
+ if ((_val & 0x80000000) == 0 || (_val == 0xffffffff)) \
+ break; \
+ _cnt++; \
+ DBGPRINT_ERR(("RT3290: EEP is busy!!!! BusyCnt%d : fail\n", _cnt)); \
+ RTMPusecDelay(500); \
+ } while (_cnt<300); \
+} \
+
+#define RT3290_CURRENT_LEAKAGE(_pAd,_A,_e) \
+{ \
+ if (IS_RT3290(_pAd)) \
+ { \
+ UINT32 btFunInfo, _val = 0; \
+ RTMP_IO_FORCE_READ32(_pAd, _A, &_val); \
+ if (_e) \
+ _val &= ~(EESK|EEDI); \
+ else \
+ { \
+ _val &= ~(EESK); \
+ _val |= EEDI; \
+ } \
+ RT3290_CHECK_SW_EEP_BUSY(_pAd); \
+ RTMP_IO_FORCE_READ32(_pAd, BT_FUN_INFO, &btFunInfo); \
+ btFunInfo |= 0x80000000; \
+ RTMP_IO_FORCE_WRITE32(_pAd, BT_FUN_INFO, btFunInfo); \
+ \
+ RTMP_IO_FORCE_WRITE32(_pAd, _A, _V); \
+ \
+ btFunInfo &= ~(0x80000000); \
+ RTMP_IO_FORCE_WRITE32(_pAd, BT_FUN_INFO, btFunInfo); \
+ } \
+}
+
+
+VOID MlmeAntSelection(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN ULONG AccuTxTotalCnt,
+ IN ULONG TxErrorRatio,
+ IN ULONG TxSuccess,
+ IN CHAR Rssi);
+
+INT RT3290_eeprom_access_grant(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN BOOLEAN bGetCtrl);
+
+VOID RTMP_MAC_PWRSV_EN(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN BOOLEAN EnterIdle,
+ IN BOOLEAN use40M);
+
+VOID RTMPEnableWlan(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN BOOLEAN bOn,
+ IN BOOLEAN bResetWLAN);
+
+VOID RT3290_Init(
+ IN struct _RTMP_ADAPTER *pAd);
+
+#endif /* RT3290 */
+
+#endif /* __RT5390_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/chip/rt6590.h b/cleopatre/devkit/mt7601udrv/include/chip/rt6590.h
new file mode 100644
index 0000000000..4841680b1c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/chip/rt6590.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt6590.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RT6590_H__
+#define __RT6590_H__
+
+struct _RTMP_ADAPTER;
+
+#define NIC6590_PCIe_DEVICE_ID 0x6590
+#define MAX_RF_ID 127
+#define MAC_RF_BANK 7
+
+/*
+ rsv: Reserved
+ tcp: packet type, tcp : 1, udp:0
+ tups: TCP/UDP header start offset (in unit of DWORD)
+ ips: IP start offset (in unit of byte), base address of ips is the beginning of TXWI
+ mss: Max Segment size (in unit of byte)
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct _TSO_INFO_{
+ UINT32 mss:16;
+ UINT32 ips:8;
+ UINT32 tups:6;
+ UINT32 tcp:1;
+ UINT32 rsv:1;
+}TSO_INFO;
+#else
+typedef struct _TSO_INFO_{
+ UINT32 rsv:1;
+ UINT32 tcp:1;
+ UINT32 tups:6;
+ UINT32 ips:8;
+ UINT32 mss:16;
+}TSO_INFO;
+#endif /* RT_BIG_ENDIAN */
+
+
+/*
+ * Frequency plan item for RT85592
+ * N: R9[4], R8[7:0]
+ * K: R7[7], R9[3:0]
+ * mod: R9[7:5], R11[3:2] (eg. mod=8 => 0x0, mod=10 => 0x2)
+ * R: R11[1:0] (eg. R=1 => 0x0, R=3 => 0x2)
+ */
+typedef struct _RT8592_FREQ_ITEM {
+ UINT8 Channel;
+ UINT16 N;
+ UINT8 K;
+ UINT8 mod;
+ UINT8 R;
+} RT8592_FREQ_ITEM;
+
+#define RT6590_RF_VER "MT7650_WiFi_RF_Register_20120516.xls"
+//#define RT6590_BBP_VER "TC6008_BBP_CR_20120518.xls"
+#define RT6590_BBP_VER "TC6008_BBP_CR_20120522.xls"
+
+/*
+ Rdiv: R24[1:0] (2-bits)
+ PLL_N: R29[7:0], R30[0] (9-bits)
+ PLL_K(Nominator): R31[4:0] (5-bits)
+ Non-Sigma: !SDM R31[7:5] (3-bits)
+ Den: (Denomina - 8) R32[4:0] (5-bits)
+ Loop Filter Config: R33, R34
+ Pll_idiv: frac comp R35[6:0] (7-bits)
+
+ 5G only
+ Pll_LDO: R16 [6:4] = <010>
+*/
+typedef struct _RT6590_FREQ_ITEM {
+ UINT8 Channel;
+ UINT8 Band;
+ UINT16 PLL_N;
+ UINT8 PLL_K;
+ UINT8 Rdiv;
+ UINT8 NonSigma;
+ UINT8 Den;
+ UINT8 LFC_R33;
+ UINT8 LFC_R34;
+ UINT32 Pll_idiv;
+ UINT8 Pll_LDO; // 5G only
+} RT6590_FREQ_ITEM;
+
+#define RF_G_BAND 0x01
+#define RF_A_BAND 0x02
+#define RF_A_BAND_LB 0x04
+#define RF_A_BAND_MB 0x08
+#define RF_A_BAND_HB 0x10
+typedef struct _RT6590_RF_SWITCH_ITEM {
+ UCHAR Bank;
+ UCHAR Register;
+ UCHAR Band; /* G_Band, A_Band_LB, A_Band_MB, A_Band_HB */
+ UCHAR BW;
+ UCHAR Value;
+} RT6590_RF_SWITCH_ITEM, *PRT6590_RF_SWITCH_ITEM;
+
+typedef struct _RT6590_DCOC_Table {
+ UCHAR Band; /* G_Band, A_Band_LB, A_Band_MB, A_Band_HB */
+ RTMP_REG_PAIR RegDate;
+} RT6590_DOCO_Table, *PRT6590_DOCO_Table;
+
+VOID RT6590_Init(struct _RTMP_ADAPTER *pAd);
+INT RT6590_ReadChannelPwr(struct _RTMP_ADAPTER *pAd);
+
+#ifdef RT8592
+VOID RT85592_Init(struct _RTMP_ADAPTER *pAd);
+INT RT85592_ReadChannelPwr(struct _RTMP_ADAPTER *pAd);
+VOID RT85592ReadTxPwrPerRate(struct _RTMP_ADAPTER *pAd);
+#endif /* RT8592 */
+VOID RT6590ReadTxPwrPerRate(struct _RTMP_ADAPTER *pAd);
+
+VOID dump_bw_info(struct _RTMP_ADAPTER *pAd);
+
+#endif /* __RT6590_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/chip/rtmp_phy.h b/cleopatre/devkit/mt7601udrv/include/chip/rtmp_phy.h
new file mode 100644
index 0000000000..632909fbd1
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/chip/rtmp_phy.h
@@ -0,0 +1,693 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_phy.h
+
+ Abstract:
+ Ralink Wireless Chip PHY(BBP/RF) related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_PHY_H__
+#define __RTMP_PHY_H__
+
+
+#include "mac_ral/rf_ctrl.h"
+#ifdef RLT_MAC
+#include "phy/rlt_phy.h"
+#endif /* RLT_MAC */
+
+/*
+ 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
+#define RF_R64 64
+#define RF_R65 65
+#define RF_R66 66
+#define RF_R67 67
+#define RF_R68 68
+#define RF_R69 69
+#define RF_R70 70
+#define RF_R71 71
+#define RF_R72 72
+#define RF_R73 73
+#define RF_R74 74
+#define RF_R75 75
+#define RF_R126 126
+#define RF_R127 127
+
+
+/* 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_5592 14 /* 2.4G/5G */
+#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_5592) || \
+ (__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_R10 10 /* Rate report */
+#define BBP_R14 14 /* RX configure */
+#define BBP_R16 16
+#define BBP_R17 17 /* RX sensibility */
+#define BBP_R18 18
+#define BBP_R20 20
+#define BBP_R21 21
+#define BBP_R22 22
+#define BBP_R23 23
+#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_R58 58
+#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_R74 74
+#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_R85 85
+#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_R99 99
+#define BBP_R101 101
+#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_R129 129
+#define BBP_R130 130
+#define BBP_R131 131
+#define BBP_R133 133
+#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_R158 158 /* Calibration register are accessed through R158 and R159 */
+#define BBP_R159 159
+#define BBP_R160 160 /* Tx BF control */
+#define BBP_R161 161
+#define BBP_R162 162
+#define BBP_R163 163
+#define BBP_R164 164
+#define BBP_R165 165
+#define BBP_R166 166
+#define BBP_R167 167
+
+#define BBP_R173 173
+#define BBP_R174 174
+#define BBP_R175 175
+#define BBP_R176 176
+#define BBP_R177 177
+#define BBP_R178 178
+#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_R195 195
+#define BBP_R196 196
+#define BBP_R241 241
+#define BBP_R242 242
+#define BBP_R244 244
+#define BBP_R250 250
+#define BBP_R253 253
+#define BBP_R254 254
+#define BBP_R255 255
+
+#define BBPR94_DEFAULT 0x06 /* Add 1 value will gain 1db */
+
+typedef enum{
+ RX_CHAIN_0 = 1<<0,
+ RX_CHAIN_1 = 1<<1,
+ RX_CHAIN_2 = 1<<2,
+ RX_CHAIN_ALL = 0xf
+}RX_CHAIN_IDX;
+
+#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) || defined(RT3290) //for hw antenna diversity (PPAD)
+ #define MAX_BBP_ID 255
+#elif defined(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 */
+
+
+/*****************************************************************************
+ BBP register Read/Write marco definitions.
+ we read/write the bbp value by register's ID.
+ Generate PER to test BA
+ *****************************************************************************/
+
+#ifdef CARRIER_DETECTION_SUPPORT
+/*TONE_RADAR_DETECT_V2*/
+#define RTMP_CARRIER_IO_READ8(_A, _I, _V) \
+{ \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, BBP_R184, _I); \
+ RTMP_BBP_IO_READ8_BY_REG_ID(_A, BBP_R185, _V); \
+}
+#define RTMP_CARRIER_IO_WRITE8(_A, _I, _V) \
+{ \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, BBP_R184, _I); \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, BBP_R185, _V); \
+}
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#ifdef DFS_SUPPORT
+#define RTMP_DFS_IO_READ8(_A, _I, _V) \
+{ \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, BBP_R140, _I); \
+ RTMP_BBP_IO_READ8_BY_REG_ID(_A, BBP_R141, _V); \
+}
+
+#define RTMP_DFS_IO_WRITE8(_A, _I, _V) \
+{ \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, BBP_R140, _I); \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, BBP_R141, _V); \
+}
+#endif /*DFS_SUPPORT*/
+
+#ifdef RTMP_MAC_USB
+#ifndef MT7601
+#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 /* MT7601 */
+#endif /* RTMP_MAC_USB */
+
+#ifdef MT7601
+NDIS_STATUS MT7601_BBP_write(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN UCHAR regID,
+ IN UCHAR value);
+
+NDIS_STATUS MT7601_BBP_read(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN UCHAR regID,
+ IN UCHAR *pValue);
+
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) MT7601_BBP_read(_A, _I, _pV)
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) MT7601_BBP_write(_A, _I, _V)
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) MT7601_BBP_write(_A, _I, _V)
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) MT7601_BBP_read(_A, _I, _pV)
+#endif /* MT7601 */
+
+
+
+#if defined(RT30xx) || defined(MT7601)
+
+#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); \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
+ \
+ /* disable MMPS MAC control register */ \
+ RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
+ _macData &= ~(0x09); \
+ 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); \
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
+ \
+ /* enable MMPS MAC control register */ \
+ RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
+ _macData |= (0x09); \
+ RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \
+ }while(0)
+#endif /* defined(RT30xx) || defined(MT7601) */
+
+
+struct _RMTP_ADAPTER;
+
+INT rtmp_bbp_set_bw(struct _RTMP_ADAPTER *pAd, INT bw);
+INT rtmp_bbp_set_ctrlch(struct _RTMP_ADAPTER *pAd, INT ext_ch);
+INT rtmp_bbp_set_rxpath(struct _RTMP_ADAPTER *pAd, INT rxpath);
+INT rtmp_bbp_set_txdac(struct _RTMP_ADAPTER *pAd, INT tx_dac);
+INT rtmp_bbp_set_mmps(struct _RTMP_ADAPTER *pAd, BOOLEAN ReduceCorePower);
+INT rtmp_bbp_is_ready(struct _RTMP_ADAPTER *pAd);
+INT rtmp_bbp_set_agc(struct _RTMP_ADAPTER *pAd, UCHAR agc, RX_CHAIN_IDX idx);
+INT rtmp_bbp_get_agc(struct _RTMP_ADAPTER *pAd, CHAR *agc, RX_CHAIN_IDX idx);
+INT rtmp_bbp_set_filter_coefficient_ctrl(struct _RTMP_ADAPTER *pAd, UCHAR Channel);
+UCHAR rtmp_bbp_get_random_seed(struct _RTMP_ADAPTER *pAd);
+
+NDIS_STATUS NICInitBBP(struct _RTMP_ADAPTER *pAd);
+
+#endif /* __RTMP_PHY_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/chlist.h b/cleopatre/devkit/mt7601udrv/include/chlist.h
new file mode 100644
index 0000000000..4eeb7757e9
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/chlist.h
@@ -0,0 +1,150 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ chlist.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __CHLIST_H__
+#define __CHLIST_H__
+
+#include "rtmp_type.h"
+#include "rtmp_def.h"
+
+
+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 *pChDesp;
+} CH_REGION, *PCH_REGION;
+
+extern CH_REGION ChRegion[];
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+#ifdef SINGLE_SKU_V2
+#define SINGLE_SKU_TABLE_LENGTH (SINGLE_SKU_TABLE_CCK_LENGTH+SINGLE_SKU_TABLE_OFDM_LENGTH+(SINGLE_SKU_TABLE_HT_LENGTH*2))
+
+#define SINGLE_SKU_TABLE_CCK_LENGTH 4
+#define SINGLE_SKU_TABLE_OFDM_LENGTH 8
+#define SINGLE_SKU_TABLE_HT_LENGTH 16
+
+typedef struct _CH_POWER_{
+ struct _CH_POWER_ *pNext;
+ UCHAR StartChannel;
+ UCHAR num;
+ UCHAR *Channel;
+ UCHAR PwrCCK[SINGLE_SKU_TABLE_CCK_LENGTH];
+ UCHAR PwrOFDM[SINGLE_SKU_TABLE_OFDM_LENGTH];
+ UCHAR PwrHT20[SINGLE_SKU_TABLE_HT_LENGTH];
+ UCHAR PwrHT40[SINGLE_SKU_TABLE_HT_LENGTH];
+}CH_POWER;
+#endif /* SINGLE_SKU_V2 */
+
+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))
+
+/* Check if it is Japan W53(ch52,56,60,64) channel. */
+#define JapanChannelCheck(_ch) ((_ch == 52) || (_ch == 56) || (_ch == 60) || (_ch == 64))
+
+
+#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(RTMP_ADAPTER *pAd);
+UCHAR N_SetCenCh(RTMP_ADAPTER *pAd, UCHAR channel);
+BOOLEAN N_ChannelGroupCheck(RTMP_ADAPTER *pAd, UCHAR channel);
+
+#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__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/client_wds.h b/cleopatre/devkit/mt7601udrv/include/client_wds.h
new file mode 100644
index 0000000000..691583498e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/client_wds.h
@@ -0,0 +1,59 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ client_wds.h
+
+ Abstract:
+*/
+
+#ifndef __CLIENT_WDS_H__
+#define __CLIENT_WDS_H__
+
+#include "client_wds_cmm.h"
+
+VOID CliWds_ProxyTabInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID CliWds_ProxyTabDestory(
+ IN PRTMP_ADAPTER pAd);
+
+PCLIWDS_PROXY_ENTRY CliWdsEntyAlloc(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID CliWdsEntyFree(
+ IN PRTMP_ADAPTER pAd,
+ IN PCLIWDS_PROXY_ENTRY pCliWdsEntry);
+
+
+PUCHAR CliWds_ProxyLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pMac);
+
+
+VOID CliWds_ProxyTabUpdate(
+ IN PRTMP_ADAPTER pAd,
+ IN SHORT Aid,
+ IN PUCHAR pMac);
+
+
+VOID CliWds_ProxyTabMaintain(
+ IN PRTMP_ADAPTER pAd);
+
+#endif /* __CLIENT_WDS_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/client_wds_cmm.h b/cleopatre/devkit/mt7601udrv/include/client_wds_cmm.h
new file mode 100644
index 0000000000..5043b1ae3d
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/client_wds_cmm.h
@@ -0,0 +1,46 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ client_wds_cmm.h
+
+ Abstract:
+*/
+
+#ifndef __CLIENT_WDS_CMM_H__
+#define __CLIENT_WDS_CMM_H__
+
+#include "rtmp_def.h"
+
+#ifdef CLIENT_WDS
+
+
+#define CLI_WDS_ENTRY_AGEOUT 5000 /* seconds */
+
+#define CLIWDS_POOL_SIZE 128
+#define CLIWDS_HASH_TAB_SIZE 64 /* the legth of hash table must be power of 2. */
+typedef struct _CLIWDS_PROXY_ENTRY {
+ struct _CLIWDS_PROXY_ENTRY * pNext;
+ ULONG LastRefTime;
+ SHORT Aid;
+ UCHAR Addr[MAC_ADDR_LEN];
+} CLIWDS_PROXY_ENTRY, *PCLIWDS_PROXY_ENTRY;
+
+#endif /* CLIENT_WDS */
+
+#endif /* __CLIENT_WDS_CMM_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/crypt_aes.h b/cleopatre/devkit/mt7601udrv/include/crypt_aes.h
new file mode 100644
index 0000000000..ab763ceb21
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/crypt_aes.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ AES
+
+ Abstract:
+ RFC 3394: Advanced Encryption Standard (AES) Key Wrap Algorithm
+ RFC 3601: Counter with CBC-MAC (CCM)
+ RFC 4493: The AES-CMAC Algorithm
+ FIPS PUBS 197: ADVANCED ENCRYPTION STANDARD (AES)
+ NIST 800-38A: Recommendation for Block Cipher Modes of Operation
+ NIST 800-38C: The CCM Mode for Authentication and Confidentiality
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2009/05/19 Create AES-Key Wrap
+ Eddy 2009/04/20 Create AES-CMAC, AES-CCM
+ Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC
+***************************************************************************/
+
+#ifndef __CRYPT_AES_H__
+#define __CRYPT_AES_H__
+
+#include "rt_config.h"
+
+
+/* AES definition & structure */
+#define AES_STATE_ROWS 4 /* Block size: 4*4*8 = 128 bits */
+#define AES_STATE_COLUMNS 4
+#define AES_BLOCK_SIZES AES_STATE_ROWS*AES_STATE_COLUMNS
+#define AES_KEY_ROWS 4
+#define AES_KEY_COLUMNS 8 /*Key length: 4*{4,6,8}*8 = 128, 192, 256 bits */
+#define AES_KEY128_LENGTH 16
+#define AES_KEY192_LENGTH 24
+#define AES_KEY256_LENGTH 32
+#define AES_CBC_IV_LENGTH 16
+
+typedef struct {
+ UINT8 State[AES_STATE_ROWS][AES_STATE_COLUMNS];
+ UINT8 KeyWordExpansion[AES_KEY_ROWS][AES_KEY_ROWS*((AES_KEY256_LENGTH >> 2) + 6 + 1)];
+} AES_CTX_STRUC, *PAES_CTX_STRUC;
+
+
+/* AES operations */
+VOID RT_AES_KeyExpansion (
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ INOUT AES_CTX_STRUC *paes_ctx);
+
+VOID RT_AES_Encrypt (
+ IN UINT8 PlainBlock[],
+ IN UINT PlainBlockSize,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 CipherBlock[],
+ INOUT UINT *CipherBlockSize);
+
+VOID RT_AES_Decrypt (
+ IN UINT8 CipherBlock[],
+ IN UINT CipherBlockSize,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 PlainBlock[],
+ INOUT UINT *PlainBlockSize);
+
+/* AES Counter with CBC-MAC operations */
+VOID AES_CCM_MAC (
+ IN UINT8 Payload[],
+ IN UINT PayloadLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ IN UINT8 Nonce[],
+ IN UINT NonceLength,
+ IN UINT8 AAD[],
+ IN UINT AADLength,
+ IN UINT MACLength,
+ OUT UINT8 MACText[]);
+
+INT AES_CCM_Encrypt (
+ IN UINT8 PlainText[],
+ IN UINT PlainTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ IN UINT8 Nonce[],
+ IN UINT NonceLength,
+ IN UINT8 AAD[],
+ IN UINT AADLength,
+ IN UINT MACLength,
+ OUT UINT8 CipherText[],
+ INOUT UINT *CipherTextLength);
+
+INT AES_CCM_Decrypt (
+ IN UINT8 CipherText[],
+ IN UINT CipherTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ IN UINT8 Nonce[],
+ IN UINT NonceLength,
+ IN UINT8 AAD[],
+ IN UINT AADLength,
+ IN UINT MACLength,
+ OUT UINT8 PlainText[],
+ INOUT UINT *PlainTextLength);
+
+/* AES-CMAC operations */
+VOID AES_CMAC_GenerateSubKey (
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 SubKey1[],
+ OUT UINT8 SubKey2[]);
+
+VOID AES_CMAC (
+ IN UINT8 PlainText[],
+ IN UINT PlainTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 MACText[],
+ INOUT UINT *MACTextLength);
+
+
+
+/* AES-CBC operations */
+VOID AES_CBC_Encrypt (
+ IN UINT8 PlainText[],
+ IN UINT PlainTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ IN UINT8 IV[],
+ IN UINT IVLength,
+ OUT UINT8 CipherText[],
+ INOUT UINT *CipherTextLength);
+
+VOID AES_CBC_Decrypt (
+ IN UINT8 CipherText[],
+ IN UINT CipherTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ IN UINT8 IV[],
+ IN UINT IVLength,
+ OUT UINT8 PlainText[],
+ INOUT UINT *PlainTextLength);
+
+/* AES key wrap operations */
+INT AES_Key_Wrap (
+ IN UINT8 PlainText[],
+ IN UINT PlainTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 CipherText[],
+ OUT UINT *CipherTextLength);
+
+INT AES_Key_Unwrap (
+ IN UINT8 CipherText[],
+ IN UINT CipherTextLength,
+ IN UINT8 Key[],
+ IN UINT KeyLength,
+ OUT UINT8 PlainText [],
+ OUT UINT *PlainTextLength);
+
+
+#endif /* __CRYPT_AES_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/crypt_arc4.h b/cleopatre/devkit/mt7601udrv/include/crypt_arc4.h
new file mode 100644
index 0000000000..63d87ce356
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/crypt_arc4.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ RC4
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2009/05/13 ARC4
+***************************************************************************/
+
+#ifndef __CRYPT_ARC4_H__
+#define __CRYPT_ARC4_H__
+
+#include "rt_config.h"
+
+/* ARC4 definition & structure */
+#define ARC4_KEY_BLOCK_SIZE 256
+
+typedef struct {
+ UINT BlockIndex1;
+ UINT BlockIndex2;
+ UINT8 KeyBlock[256];
+} ARC4_CTX_STRUC, *PARC4_CTX_STRUC;
+
+/* ARC4 operations */
+VOID ARC4_INIT(
+ IN ARC4_CTX_STRUC * pARC4_CTX,
+ IN PUCHAR pKey,
+ IN UINT KeyLength);
+
+VOID ARC4_Compute(
+ IN ARC4_CTX_STRUC * pARC4_CTX,
+ IN UINT8 InputBlock[],
+ IN UINT InputBlockSize,
+ OUT UINT8 OutputBlock[]);
+
+VOID ARC4_Discard_KeyLength(
+ IN ARC4_CTX_STRUC * pARC4_CTX,
+ IN UINT Length);
+
+#endif /* __CRYPT_ARC4_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/crypt_biginteger.h b/cleopatre/devkit/mt7601udrv/include/crypt_biginteger.h
new file mode 100644
index 0000000000..8fe20c6111
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/crypt_biginteger.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ BigInteger
+
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2009/01/12 Create
+***************************************************************************/
+
+#ifndef __CRYPT_BIGINTEGER_H__
+#define __CRYPT_BIGINTEGER_H__
+
+#include "rt_config.h"
+
+
+/* BigInteger definition & structure */
+#define SLIDING_WINDOW 16
+typedef struct _BIG_INTEGER_STRUC
+{
+ STRING Name[10];
+ UINT32 *pIntegerArray;
+ UINT AllocSize;
+ UINT ArrayLength;
+ UINT IntegerLength;
+ INT Signed;
+} BIG_INTEGER, *PBIG_INTEGER;
+
+
+/* BigInteger operations */
+VOID BigInteger_Print (
+ IN PBIG_INTEGER pBI);
+
+VOID BigInteger_Init (
+ INOUT PBIG_INTEGER *pBI);
+
+VOID BigInteger_Free_AllocSize (
+ IN PBIG_INTEGER *pBI);
+
+VOID BigInteger_Free (
+ IN PBIG_INTEGER *pBI);
+
+VOID BigInteger_AllocSize (
+ IN PBIG_INTEGER *pBI,
+ IN INT Length);
+
+VOID BigInteger_ClearHighBits (
+ IN PBIG_INTEGER pBI);
+
+VOID BigInteger_BI2Bin (
+ IN PBIG_INTEGER pBI,
+ OUT UINT8 *pValue,
+ OUT UINT *Length);
+
+VOID BigInteger_Bin2BI (
+ IN UINT8 *pValue,
+ IN UINT Length,
+ OUT PBIG_INTEGER *pBI);
+
+VOID BigInteger_BitsOfBI (
+ IN PBIG_INTEGER pBI,
+ OUT UINT *Bits_Of_P);
+
+INT BigInteger_GetBitValue (
+ IN PBIG_INTEGER pBI,
+ IN UINT Index);
+
+UINT8 BigInteger_GetByteValue (
+ IN PBIG_INTEGER pBI,
+ IN UINT Index);
+
+VOID BigInteger_Copy (
+ IN PBIG_INTEGER pBI_Copied,
+ OUT PBIG_INTEGER *pBI_Result);
+
+INT BigInteger_UnsignedCompare (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand);
+
+VOID BigInteger_Add (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result);
+
+VOID BigInteger_Sub (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result);
+
+VOID BigInteger_Mul (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result);
+
+VOID BigInteger_Square (
+ IN PBIG_INTEGER pBI,
+ OUT PBIG_INTEGER *pBI_Result);
+
+VOID BigInteger_Div (
+ IN PBIG_INTEGER pFirstOperand,
+ IN PBIG_INTEGER pSecondOperand,
+ OUT PBIG_INTEGER *pBI_Result,
+ OUT PBIG_INTEGER *pBI_Remainder);
+
+VOID BigInteger_Montgomery_Reduction (
+ IN PBIG_INTEGER pBI_A,
+ IN PBIG_INTEGER pBI_P,
+ IN PBIG_INTEGER pBI_R,
+ OUT PBIG_INTEGER *pBI_Result);
+
+VOID BigInteger_Montgomery_ExpMod (
+ IN PBIG_INTEGER pBI_G,
+ IN PBIG_INTEGER pBI_E,
+ IN PBIG_INTEGER pBI_P,
+ OUT PBIG_INTEGER *pBI_Result);
+
+
+#endif /* __CRYPT_BIGINTEGER_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/crypt_dh.h b/cleopatre/devkit/mt7601udrv/include/crypt_dh.h
new file mode 100644
index 0000000000..b1cdab015c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/crypt_dh.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ DH
+
+ Abstract:
+ RFC 2631: Diffie-Hellman Key Agreement Method
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2009/01/21 Create Diffie-Hellman, Montgomery Algorithm
+***************************************************************************/
+
+#ifndef __CRYPT_DH_H__
+#define __CRYPT_DH_H__
+
+#include "rt_config.h"
+
+
+/* DH operations */
+void DH_PublicKey_Generate (
+ IN UINT8 GValue[],
+ IN UINT GValueLength,
+ IN UINT8 PValue[],
+ IN UINT PValueLength,
+ IN UINT8 PrivateKey[],
+ IN UINT PrivateKeyLength,
+ OUT UINT8 PublicKey[],
+ INOUT UINT *PublicKeyLength);
+
+void DH_SecretKey_Generate (
+ IN UINT8 PublicKey[],
+ IN UINT PublicKeyLength,
+ IN UINT8 PValue[],
+ IN UINT PValueLength,
+ IN UINT8 PrivateKey[],
+ IN UINT PrivateKeyLength,
+ OUT UINT8 SecretKey[],
+ INOUT UINT *SecretKeyLength);
+
+#define RT_DH_PublicKey_Generate(GK, GKL, PV, PVL, PriK, PriKL, PubK, PubKL) \
+ DH_PublicKey_Generate((GK), (GKL), (PV), (PVL), (PriK), (PriKL), (UINT8 *) (PubK), (UINT *) (PubKL))
+
+#define RT_DH_SecretKey_Generate(PubK, PubKL, PV, PVL, PriK, PriKL, SecK, SecKL) \
+ DH_SecretKey_Generate((PubK), (PubKL), (PV), (PVL), (PriK), (PriKL), (UINT8 *) (SecK), (UINT *) (SecKL))
+
+#define RT_DH_FREE_ALL()
+
+
+#endif /* __CRYPT_DH_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/crypt_hmac.h b/cleopatre/devkit/mt7601udrv/include/crypt_hmac.h
new file mode 100644
index 0000000000..e6dd220f84
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/crypt_hmac.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ HMAC
+
+ Abstract:
+ FIPS 198: The Keyed-Hash Message Authentication Code (HMAC)
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2008/11/24 Create HMAC-SHA1, HMAC-SHA256
+***************************************************************************/
+
+#ifndef __CRYPT_HMAC_H__
+#define __CRYPT_HMAC_H__
+
+#include "rt_config.h"
+
+
+#ifdef SHA1_SUPPORT
+#define HMAC_SHA1_SUPPORT
+VOID RT_HMAC_SHA1(
+ IN const UINT8 Key[],
+ IN UINT KeyLen,
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 MAC[],
+ IN UINT MACLen);
+#endif /* SHA1_SUPPORT */
+
+#ifdef SHA256_SUPPORT
+#define HMAC_SHA256_SUPPORT
+VOID RT_HMAC_SHA256(
+ IN const UINT8 Key[],
+ IN UINT KeyLen,
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 MAC[],
+ IN UINT MACLen);
+#endif /* SHA256_SUPPORT */
+
+#ifdef MD5_SUPPORT
+#define HMAC_MD5_SUPPORT
+VOID RT_HMAC_MD5(
+ IN const UINT8 Key[],
+ IN UINT KeyLen,
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 MAC[],
+ IN UINT MACLen);
+#endif /* MD5_SUPPORT */
+
+
+#endif /* __CRYPT_HMAC_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/crypt_md5.h b/cleopatre/devkit/mt7601udrv/include/crypt_md5.h
new file mode 100644
index 0000000000..60cf5d3bae
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/crypt_md5.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ MD5
+
+ Abstract:
+ RFC1321: The MD5 Message-Digest Algorithm
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2008/11/24 Create md5
+***************************************************************************/
+
+#ifndef __CRYPT_MD5_H__
+#define __CRYPT_MD5_H__
+
+
+/* Algorithm options */
+#define MD5_SUPPORT
+
+#ifdef MD5_SUPPORT
+#define MD5_BLOCK_SIZE 64 /* 512 bits = 64 bytes */
+#define MD5_DIGEST_SIZE 16 /* 128 bits = 16 bytes */
+typedef struct {
+ UINT32 HashValue[4];
+ UINT64 MessageLen;
+ UINT8 Block[MD5_BLOCK_SIZE];
+ UINT BlockLen;
+} MD5_CTX_STRUC, *PMD5_CTX_STRUC;
+
+VOID RT_MD5_Init(
+ IN MD5_CTX_STRUC * pMD5_CTX);
+VOID RT_MD5_Hash(
+ IN MD5_CTX_STRUC * pMD5_CTX);
+VOID RT_MD5_Append(
+ IN MD5_CTX_STRUC * pMD5_CTX,
+ IN const UINT8 Message[],
+ IN UINT MessageLen);
+VOID RT_MD5_End(
+ IN MD5_CTX_STRUC * pMD5_CTX,
+ OUT UINT8 DigestMessage[]);
+VOID RT_MD5(
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 DigestMessage[]);
+#endif /* MD5_SUPPORT */
+
+
+#endif /* __CRYPT_MD5_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/crypt_sha2.h b/cleopatre/devkit/mt7601udrv/include/crypt_sha2.h
new file mode 100644
index 0000000000..9d2e43e52f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/crypt_sha2.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+ Module Name:
+ SHA2
+
+ Abstract:
+ FIPS 180-2: Secure Hash Standard (SHS)
+
+ Revision History:
+ Who When What
+ -------- ---------- ------------------------------------------
+ Eddy 2008/11/24 Create SHA1
+ Eddy 2008/07/23 Create SHA256
+***************************************************************************/
+
+#ifndef __CRYPT_SHA2_H__
+#define __CRYPT_SHA2_H__
+
+
+/* Algorithm options */
+#define SHA1_SUPPORT
+#define SHA256_SUPPORT
+
+#ifdef SHA1_SUPPORT
+#define SHA1_BLOCK_SIZE 64 /* 512 bits = 64 bytes */
+#define SHA1_DIGEST_SIZE 20 /* 160 bits = 20 bytes */
+typedef struct _SHA1_CTX_STRUC {
+ UINT32 HashValue[5]; /* 5 = (SHA1_DIGEST_SIZE / 32) */
+ UINT64 MessageLen; /* total size */
+ UINT8 Block[SHA1_BLOCK_SIZE];
+ UINT BlockLen;
+} SHA1_CTX_STRUC, *PSHA1_CTX_STRUC;
+
+VOID RT_SHA1_Init(
+ IN SHA1_CTX_STRUC * pSHA_CTX);
+VOID RT_SHA1_Hash(
+ IN SHA1_CTX_STRUC * pSHA_CTX);
+VOID RT_SHA1_Append(
+ IN SHA1_CTX_STRUC * pSHA_CTX,
+ IN const UINT8 Message[],
+ IN UINT MessageLen);
+VOID RT_SHA1_End(
+ IN SHA1_CTX_STRUC * pSHA_CTX,
+ OUT UINT8 DigestMessage[]);
+VOID RT_SHA1(
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 DigestMessage[]);
+#endif /* SHA1_SUPPORT */
+
+#ifdef SHA256_SUPPORT
+#define SHA256_BLOCK_SIZE 64 /* 512 bits = 64 bytes */
+#define SHA256_DIGEST_SIZE 32 /* 256 bits = 32 bytes */
+typedef struct _SHA256_CTX_STRUC {
+ UINT32 HashValue[8]; /* 8 = (SHA256_DIGEST_SIZE / 32) */
+ UINT64 MessageLen; /* total size */
+ UINT8 Block[SHA256_BLOCK_SIZE];
+ UINT BlockLen;
+} SHA256_CTX_STRUC, *PSHA256_CTX_STRUC;
+
+VOID RT_SHA256_Init(
+ IN SHA256_CTX_STRUC * pSHA_CTX);
+VOID RT_SHA256_Hash(
+ IN SHA256_CTX_STRUC * pSHA_CTX);
+VOID RT_SHA256_Append(
+ IN SHA256_CTX_STRUC * pSHA_CTX,
+ IN const UINT8 Message[],
+ IN UINT MessageLen);
+VOID RT_SHA256_End(
+ IN SHA256_CTX_STRUC * pSHA_CTX,
+ OUT UINT8 DigestMessage[]);
+VOID RT_SHA256(
+ IN const UINT8 Message[],
+ IN UINT MessageLen,
+ OUT UINT8 DigestMessage[]);
+#endif /* SHA256_SUPPORT */
+
+
+#endif /* __CRYPT_SHA2_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/cs.h b/cleopatre/devkit/mt7601udrv/include/cs.h
new file mode 100644
index 0000000000..97ead5beaf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/cs.h
@@ -0,0 +1,172 @@
+#ifndef __CS_H__
+#define __CS_H__
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define CARRIER_DETECT_RECHECK_TIME 3
+#define CARRIER_GONE_TRESHOLD 10 /* Radar tone count in 1 sec */
+#define CARRIER_DETECT_THRESHOLD 0x0fffffff
+#define CARRIER_DETECT_STOP_RATIO 2
+#define CARRIER_DETECT_STOP_RECHECK_TIME 4
+#define CARRIER_DETECT_DEFAULT_MASK 20
+#define CARRIER_DETECT_DELTA 7
+#define CARRIER_DETECT_DIV_FLAG 0
+#define CD_INT_POLLING_CMD 0x67
+#define CARRIER_DETECT_CRITIRIA 7000
+
+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;
+
+typedef struct CARRIER_DETECTION_s {
+ BOOLEAN Enable;
+ UINT8 CDSessionTime;
+ UINT8 CDPeriod;
+ CD_STATE CD_State;
+ UINT8 delta;
+ UINT8 SymRund;
+ UINT8 div_flag;
+ UINT32 threshold;
+ UINT8 recheck;
+ UINT8 recheck1;
+ UINT32 TimeStamp; /*unit:16us*/
+ UINT32 criteria;
+ ULONG idle_time;
+ ULONG busy_time;
+ ULONG Debug;
+ ULONG OneSecIntCount;
+ UINT8 CarrierGoneThreshold;
+ UCHAR VGA_Mask;
+ UCHAR Packet_End_Mask;
+ UCHAR Rx_PE_Mask;
+} CARRIER_DETECTION_STRUCT, *PCARRIER_DETECTION_STRUCT;
+
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+/* Mcu command */
+#define CD_ONOFF_MCU_CMD 0x65
+#define CD_CHECKOUT_MCU_CMD 0x66
+/* share memory offsets */
+#define CD_CRITERIA 0x4CB2
+#define CD_CHECK_COUNT 0x4CB9
+#define RADAR_TONE_COUNT 0x4CBE
+#define CD_RECHECK 0x4CBF
+#undef CARRIER_DETECT_RECHECK_TIME
+#undef CARRIER_GONE_TRESHOLD
+#undef CARRIER_DETECT_THRESHOLD
+#define CARRIER_DETECT_RECHECK_TIME 5
+#define CARRIER_GONE_TRESHOLD 35
+#define CARRIER_DETECT_THRESHOLD 0x4fffffff
+
+/* Parameters needed to decide the Carrier Detect State */
+typedef struct _CARRIER_DETECT_PARAM {
+ UINT8 RadarToneCount; /* Number of radar tones in 100 msec*/
+ UINT8 ReCheck;
+} CARRIER_DETECT_PARAM, *PCARRIER_DETECT_PARAM;
+
+/* For debug print */
+typedef struct _CARRIER_DETECT_DEBUG {
+ UINT8 delta_div;
+ UINT8 internalRadarToneCount;
+ UINT16 Criteria;
+ UINT32 Threshold;
+ UINT8 Count;
+ UINT8 CheckCount;
+ UINT8 Reserved;
+ UINT8 VGA_Mask;
+ UINT8 PckMask;
+ UINT8 RxPeMask;
+ UINT8 RadarToneCount;
+ UINT8 ReCheck;
+} CARRIER_DETECT_DEBUG, *PCARRIER_DETECT_DEBUG;
+#endif /*CARRIER_DETECTION_FIRMWARE_SUPPORT*/
+
+INT isCarrierDetectExist(
+ IN PRTMP_ADAPTER pAd);
+
+INT CarrierDetectReset(
+ IN PRTMP_ADAPTER pAd);
+
+extern VOID RtmpOsMsDelay(
+ IN ULONG msec);
+
+INT Set_CarrierCriteria_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierReCheck_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierGoneThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierStopCheck_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierDelta_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierDivFlag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+/* v2 functions */
+INT Set_CarrierSymRund_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CarrierMask_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+VOID CSInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID CarrierDetectionStart(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandleRadarInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID CarrierDetectionStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ToneRadarProgram_v1(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG threshold);
+
+VOID ToneRadarProgram_v2(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG threshold);
+
+#ifdef CARRIER_DETECTION_FIRMWARE_SUPPORT
+VOID CarrierDetectionPeriodicStateCtrl(
+ IN PRTMP_ADAPTER pAd);
+#endif /* CARRIER_DETECTION_FIRMWARE_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+INT Set_CarrierDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /*CONFIG_AP_SUPPORT*/
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#endif /*__CS_H__*/
diff --git a/cleopatre/devkit/mt7601udrv/include/dfs.h b/cleopatre/devkit/mt7601udrv/include/dfs.h
new file mode 100644
index 0000000000..ce14884205
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/dfs.h
@@ -0,0 +1,571 @@
+
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ dfs.h
+
+ Abstract:
+ Support DFS function.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 03-12-2007 created
+*/
+#ifndef __DFS_H__
+#define __DFS_H__
+
+/*************************************************************************
+ *
+ * DFS Radar related definitions.
+ *
+ ************************************************************************/
+
+#ifdef DFS_SUPPORT
+#define RADAR_DEBUG_SHOW_RAW_EVENT 0x01 /* Show the 384-bytes raw data of event buffer */
+#define RADAR_DEBUG_EVENT 0x02 /* Show effective event reads out from the event buffer */
+#define RADAR_DEBUG_SILENCE 0x04
+#define RADAR_DEBUG_SW_SILENCE 0x08
+#define RADAR_DONT_SWITCH 0x10 /* Don't Switch channel when hit */
+#define RADAR_DEBUG_DONT_CHECK_BUSY 0x20
+#define RADAR_DEBUG_DONT_CHECK_RSSI 0x40
+#define RADAR_SIMULATE 0x80 /* simulate a short pulse hit this channel */
+
+/* McuCmd */
+#define DFS_ONOFF_MCU_CMD 0x64
+
+/*#define DFS_SW_RADAR_DECLARE_THRES 3*/
+#define DFS_EVENT_SIZE 6 /* Number of bytes of each DFS event */
+#define DFS_EVENT_BUFFER_SIZE 384 /* Number of bytes of a DFS event buffer */
+#define DFS_SW_RADAR_CHECK_LOOP 50
+#define DFS_SW_RADAR_SHIFT 3
+#define DFS_SW_RADAR_CH0_ERR 8
+#define DFS_SW_RADAR_PERIOD_ERR 4
+#define CE_STAGGERED_RADAR_CH0_H_ERR (DFS_SW_RADAR_CH0_ERR + 16) // the step is 16 for every 0.1 us different in width
+#define CE_STAGGERED_RADAR_DECLARE_THRES 2
+
+#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 */
+
+#define CH_BUSY_SAMPLE_POWER 3
+#define CH_BUSY_SAMPLE (1 << CH_BUSY_SAMPLE_POWER)
+#define CH_BUSY_MASK (CH_BUSY_SAMPLE - 1)
+
+#define MAX_FDF_NUMBER 5 /* max false-detection-filter number */
+
+/* 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_CHANNEL_0 1
+#define NEW_DFS_CHANNEL_1 2
+#define NEW_DFS_CHANNEL_2 4
+#define NEW_DFS_CHANNEL_3 8
+#define NEW_DFS_CHANNEL_4 16
+#define NEW_DFS_CHANNEL_5 32
+
+#define NEW_DFS_MAX_CHANNEL 5
+
+#define CE_SW_CHECK 3
+
+#define NEW_DFS_WATCH_DOG_TIME 1 /* note that carrier detection also need timer interrupt hook*/
+
+#define NEW_DFS_FCC 0x1 /* include Japan*/
+#define NEW_DFS_EU 0x2
+#define NEW_DFS_JAP 0x4
+#define NEW_DFS_JAP_W53 0x8
+#define NEW_DFS_END 0xff
+#define MAX_VALID_RADAR_W 5
+#define MAX_VALID_RADAR_T 5
+
+#define DFS_SW_RADAR_CH1_SHIFT 3
+#define DFS_SW_RADAR_CH2_SHIFT 3
+
+#define CE_STAGGERED_RADAR_PERIOD_MAX ((133333 + 125000 + 117647 + 1000) * 2)
+#define FCC_RADAR_PERIOD_MAX (((28570 << 1) + 1000) * 2)
+#define JAP_RADAR_PERIOD_MAX (((80000 << 1) + 1000) * 2)
+
+#define NEW_DFS_BANDWITH_MONITOR_TIME (NEW_DFS_CHECK_TIME / NEW_DFS_CHECK_TIME_TASKLET)
+#define NEW_DFS_CHECK_TIME 300
+#define NEW_DFS_CHECK_TIME_TASKLET 3
+
+/*#define DFS_SW_RADAR_DECLARE_THRES 3*/
+
+#define DFS_SW_RADAR_SHIFT 3
+
+#define DFS_SW_RADAR_CH0_ERR 8
+
+#define CE_STAGGERED_RADAR_CH0_H_ERR (DFS_SW_RADAR_CH0_ERR + 16) /* the step is 16 for every 0.1 us different in width*/
+
+#define CE_STAGGERED_RADAR_DECLARE_THRES 2
+
+
+/* DFS Macros */
+#define PERIOD_MATCH(a, b, c) ((a >= b)? ((a-b) <= c):((b-a) <= c))
+#define ENTRY_PLUS(a, b, c) (((a+b) < c)? (a+b) : (a+b-c))
+#define ENTRY_MINUS(a, b, c) ((a >= b)? (a - b) : (a+c-b))
+#define MAX_PROCESS_ENTRY 16
+
+#define IS_FCC_RADAR_1(HT_BW, T) (((HT_BW)? ((T > 57120) && (T < 57160)) : (T > 28560) && (T < 28580)))
+#define IS_W53_RADAR_2(HT_BW, T) (((HT_BW)? ((T > 153820) && (T < 153872)) : (T > 76910) && (T < 76936)))
+#define IS_W56_RADAR_3(HT_BW, T) (((HT_BW)? ((T > 159900) && (T < 160100)) : (T > 79950) && (T < 80050)))
+
+#define DFS_EVENT_SANITY_CHECK(_pAd, _DfsEvent) \
+ !(((_DfsEvent).EngineId >= _pAd->chipCap.DfsEngineNum) || \
+ ((_DfsEvent).TimeStamp & 0xffc00000) || \
+ ((_DfsEvent).Width & 0xe000))
+
+#define DFS_EVENT_PRINT(_DfsEvent) \
+ DBGPRINT(RT_DEBUG_ERROR, ( "EngineId = %u, Timestamp = %u, Width = %u\n", \
+ _DfsEvent.EngineId, _DfsEvent.TimeStamp, _DfsEvent.Width));
+
+
+#define DFS_EVENT_BUFF_PRINT(_StarIdx, _TableIdx, _BufSize) \
+{ \
+ UINT32 k; \
+ for (k = _StarIdx; k < _BufSize; k++) \
+ { \
+ DBGPRINT(RT_DEBUG_TRACE, ("0x%02x ", _TableIdx[k])); \
+ if(k%DFS_EVENT_SIZE == ((DFS_EVENT_SIZE-1+_StarIdx)%DFS_EVENT_SIZE)) \
+ DBGPRINT(RT_DEBUG_TRACE, ("\n")); \
+ } \
+}
+
+/* check whether we can do DFS detection or not */
+#define DFS_CHECK_FLAGS(_pAd, _pRadarDetect) \
+ !((_pAd->Dot11_H.RDMode == RD_SWITCHING_MODE) || \
+ (_pRadarDetect->bDfsInit == FALSE) || \
+ (_pRadarDetect->DFSAPRestart == 1))
+
+#ifdef RTMP_MAC_USB
+#define INIT_DFS_EVENT_BUFF_SHARED_MEMORY(_pAd, _StartOffset, _NumOfPages, _InitVal) \
+{ \
+ UINT32 i = 0; \
+ for (i = _StartOffset; i < _StartOffset + (_NumOfPages*384); i++) \
+ RTUSBSingleWrite(_pAd, i, _InitVal, FALSE); \
+ \
+ RTMP_IO_WRITE32(_pAd, BBPR127TABLE_OWNERID, 0x01010101); \
+ RTMP_IO_WRITE32(_pAd, BBPR127TABLE_OWNERID + 4, 0x01010101); \
+}
+#endif /* RTMP_MAC_USB */
+
+typedef enum _DFS_VERSION {
+ SOFTWARE_DFS = 0,
+ HARDWARE_DFS_V1,
+ HARDWARE_DFS_V2
+} DFS_VERSION;
+
+typedef struct _NewDFSValidRadar
+{
+ USHORT type;
+ USHORT channel; /* bit map*/
+ USHORT WLow;
+ USHORT WHigh;
+ USHORT W; /* for fixed width radar*/
+ USHORT WMargin;
+ ULONG TLow;
+ ULONG THigh;
+ ULONG T; /* for fixed period radar */
+ USHORT TMargin;
+}NewDFSValidRadar, *pNewDFSValidRadar;
+
+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;
+ ULONG BLow;
+ ULONG BHigh;
+} NewDFSParam, *pNewDFSParam;
+
+typedef struct _DFS_PROGRAM_PARAM{
+ NewDFSParam NewDFSTableEntry[NEW_DFS_MAX_CHANNEL*4];
+ USHORT ChEnable; /* Enabled Dfs channels (bit wise)*/
+ UCHAR DeltaDelay;
+ /* Support after dfs_func >= 2 */
+ UCHAR Symmetric_Round;
+ UCHAR VGA_Mask;
+ UCHAR Packet_End_Mask;
+ UCHAR Rx_PE_Mask;
+ ULONG RadarEventExpire[NEW_DFS_MAX_CHANNEL];
+}DFS_PROGRAM_PARAM, *PDFS_PROGRAM_PARAM;
+
+typedef struct _NewDFSTable
+{
+ USHORT type;
+ NewDFSParam entry[NEW_DFS_MAX_CHANNEL];
+}NewDFSTable, *pNewDFSTable;
+
+#ifdef DFS_DEBUG
+typedef struct _NewDFSDebugResult
+{
+ char delta_delay_shift;
+ char EL_shift;
+ char EH_shift;
+ char WL_shift;
+ char WH_shift;
+ ULONG hit_time;
+ ULONG false_time;
+}NewDFSDebugResult, *pNewDFSDebugResult;
+#endif
+
+typedef struct _DFS_EVENT{
+ UINT8 EngineId;
+ UINT32 TimeStamp;
+ UINT16 Width;
+}DFS_EVENT, *PDFS_EVENT;
+
+typedef struct _DFS_SW_DETECT_PARAM{
+ 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 */
+ USHORT dfs_width_diff_ch1_Shift;
+ USHORT dfs_width_diff_ch2_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;
+ ULONG dfs_w_counter;
+ DFS_EVENT PreDfsEvent; /* previous radar event */
+ UINT32 EvtDropAdjTime; /* timing threshold for adjacent event */
+ UINT sw_idx[NEW_DFS_MAX_CHANNEL];
+ UINT hw_idx[NEW_DFS_MAX_CHANNEL];
+ UINT pr_idx[NEW_DFS_MAX_CHANNEL];
+ USHORT dfs_t_idx[NEW_DFS_MAX_CHANNEL];
+ USHORT dfs_w_idx[NEW_DFS_MAX_CHANNEL];
+ USHORT dfs_w_last_idx[NEW_DFS_MAX_CHANNEL];
+ NewDFSDebugPort DFS_W[NEW_DFS_MAX_CHANNEL][NEW_DFS_DBG_PORT_ENT_NUM];
+ NewDFSMPeriod DFS_T[NEW_DFS_MAX_CHANNEL][NEW_DFS_MPERIOD_ENT_NUM]; /* period table */
+ /*UCHAR ce_sw_id_check;*/
+ /*USHORT ce_sw_t_diff;*/
+ /*ULONG fcc_5_counter;*/
+ /* CE Staggered radar / weather radar */
+#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
+}DFS_SW_DETECT_PARAM, *PDFS_SW_DETECT_PARAM;
+
+/***************************************************************************
+ * structure for radar detection and channel switch
+ **************************************************************************/
+typedef struct _RADAR_DETECT_STRUCT {
+ UCHAR DFSAPRestart;
+ ULONG MCURadarRegion;
+ CHAR AvgRssiReq;
+ ULONG DfsLowerLimit;
+ ULONG DfsUpperLimit;
+ ULONG upperlimit;
+ ULONG lowerlimit;
+ ULONG TimeStamp; /*unit: 1us*/
+ UCHAR ChirpCheck; /* anounce on second detection of chirp radar */
+ UCHAR bChannelSwitchInProgress; /* RDMode could cover this*/
+ BOOLEAN bDfsSwDisable; /* disable sotfwre check */
+ BOOLEAN bDfsInit; /* to indicate if dfs regs has been initialized */
+ USHORT PollTime;
+ INT DfsRssiHigh;
+ INT DfsRssiLow;
+ BOOLEAN DfsRssiHighFromCfg;
+ BOOLEAN DfsRssiLowFromCfg;
+ BOOLEAN DfsRssiHighCfgValid;
+ BOOLEAN DfsRssiLowCfgValid;
+ BOOLEAN DFSParamFromConfig;
+ BOOLEAN use_tasklet;
+ DFS_VERSION dfs_func;
+ BOOLEAN DFSWatchDogIsRunning;
+ UCHAR radarDeclared;
+ BOOLEAN SymRoundFromCfg;
+ BOOLEAN SymRoundCfgValid;
+ ULONG idle_time;
+ ULONG busy_time;
+ UCHAR ch_busy;
+ CHAR ch_busy_countdown;
+ UCHAR busy_channel;
+ UCHAR ch_busy_idle_ratio;
+ BOOLEAN BusyIdleFromCfg;
+ BOOLEAN BusyIdleCfgValid;
+ 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;
+ UCHAR fdf_num;
+ USHORT ch_busy_threshold[MAX_FDF_NUMBER];
+ INT rssi_threshold[MAX_FDF_NUMBER];
+ UCHAR McuRadarDebug;
+ USHORT McuRadarTick;
+ ULONG RadarTimeStampHigh;
+ ULONG RadarTimeStampLow;
+ UCHAR EnabledChMask; /* Bit-wise mask for enabled DFS channels */
+ DFS_PROGRAM_PARAM DfsProgramParam;
+ DFS_SW_DETECT_PARAM DfsSwParam;
+} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
+
+typedef struct _NewDFSProgParam
+{
+ UCHAR channel;
+ UCHAR mode; /* reg 0x10, Detection Mode[2:0]*/
+ USHORT avgLen; /* reg 0x11~0x12, M[7:0] & M[8]*/
+ USHORT ELow; /* reg 0x13~0x14, Energy Low[7:0] & Energy Low[11:8]*/
+ USHORT EHigh; /* reg 0x15~0x16, Energy High[7:0] & Energy High[11:8]*/
+ USHORT WLow; /* reg 0x28~0x29, Width Low[7:0] & Width Low[11:8]*/
+ USHORT WHigh; /* reg 0x2a~0x2b, Width High[7:0] & Width High[11:8]*/
+ UCHAR EpsilonW; /* reg 0x2c, Width Delta[7:0], (Width Measurement Uncertainty) */
+ ULONG TLow; /* reg 0x17~0x1a, Period Low[7:0] & Period Low[15:8] & Period Low[23:16] & Period Low[31:24]*/
+ ULONG THigh; /* reg 0x1b~0x1e, Period High[7:0] & Period High[15:8] & Period High[23:16] & Period High[31:24]*/
+ UCHAR EpsilonT; /* reg 0x27, Period Delt[7:0], (Period Measurement Uncertainty) */
+ ULONG BLow; /* reg 0x1f~0x22, Burst Low[7:0] & Burst Low[15:8] & Burst Low[23:16] & Burst Low[31:24]*/
+ ULONG BHigh; /* reg 0x23~0x26, Burst High[7:0] & Burst High[15:8] & Burst High[23:16] & Burst High[31:24] */
+}NewDFSProgParam, *pNewDFSProgParam;
+
+#ifdef CONFIG_AP_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 schedule_dfs_task(
+ IN PRTMP_ADAPTER pAd);
+
+int SWRadarCheck(
+ IN PRTMP_ADAPTER pAd, USHORT id);
+
+VOID NewRadarDetectionProgram(
+ IN PRTMP_ADAPTER pAd,
+ IN pNewDFSTable pDFS2Table);
+
+BOOLEAN DfsSwCheckOnHwDetection(
+ IN PRTMP_ADAPTER pAd,
+ IN pNewDFSTable pDFS2Table,
+ IN UINT8 DfsChannel,
+ IN ULONG RadarPeriod,
+ IN ULONG RadarWidth);
+
+INT Set_RfReg_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Show_BlockCh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RadarDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ResetRadarHwDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DfsSwDisable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DfsEnvtDropAdjTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RadarStart_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RadarStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RadarSetTbl1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RadarSetTbl2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_Fcc5Thrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ChBusyThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RssiThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PollTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PrintBusyIdle_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_RadarSim_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_BusyIdleRatio_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DfsRssiHigh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DfsRssiLow_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_EventExpire_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CEPrint_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_Ch0LErr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_MaxPeriod_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PeriodErr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_Ch0HErr_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_Ch1Shift_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_Ch2Shift_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DeclareThres_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CheckLoop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef DFS_DEBUG
+INT Set_DfsLowerLimit_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DfsUpperLimit_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_FixDfsLimit_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_AvgRssiReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_CEPrintDebug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* DFS_DEBUG */
+
+void dfs_tasklet(unsigned long data);
+
+VOID DFSInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ApRadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd);
+
+
+
+#ifdef RTMP_MAC_USB
+ VOID NewUsbTimerCB_Radar(
+ IN PRTMP_ADAPTER pAd);
+#endif /* RTMP_MAC_USB */
+
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* DFS_SUPPORT */
+
+#endif /*_DFS_H__*/
+
diff --git a/cleopatre/devkit/mt7601udrv/include/dot11ac_vht.h b/cleopatre/devkit/mt7601udrv/include/dot11ac_vht.h
new file mode 100644
index 0000000000..c35efd9050
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/dot11ac_vht.h
@@ -0,0 +1,479 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ dot11ac_vht.h
+
+ Abstract:
+ Defined IE/frame structures of 802.11ac (D1.2).
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Shiang Tu 01-11-2012 created for 11ac
+ */
+
+#ifdef DOT11_VHT_AC
+
+
+#ifndef __DOT11AC_VHT_H
+#define __DOT11AC_VHT_H
+
+#include "rtmp_type.h"
+
+
+#define IE_VHT_CAP 191
+#define IE_VHT_OP 192
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.160.2
+ VHT Capabilities Info field
+
+ max_mpdu_len: MAximun MPDU Length
+ ->Indicate the max MPDU length.
+ 0: 3895 octets(Max A-MSDU length in HT Cap set to 3839)
+ 1: 7991 octets(Max A-MSDU length in HT Cap set to 7935)
+ 2: 11454 octets(Max A-MSDU length in HT Cap set to 7935)
+ 3: reserved
+ ch_width: Supported Channel Width Set
+ ->Indicates the channel widths supported by the STA.
+ 0: the STA does not support either 160 or 80+80 MHz
+ 1: the STA support 160 MHz
+ 2: the STA support 160 MHz and 80 + 80 MHz
+ 3: reserved
+ rx_ldpc: Rx LDPC
+ -> Indicates support of receiving LDPC coded packets
+ 0: not support
+ 1: support
+ sgi_80M: Short GI for 80 MHz
+ -> Indicates short GI support for the reception of VHT+CBW80 packet
+ 0: not support
+ 1: support
+ sgi_160M: Short GI for 160 and 80 + 80 MHz
+ ->Indicates rx short GI for VHT+(CBW160 and CBW80+80) packet
+ 0: not support
+ 1: support
+ tx_stbc: Tx STBC
+ -> Indicates support for tx of at least 2x1 STBC
+ 0: not support
+ 1: support
+ rx_stbc: Rx STBC
+ -> Indicates support for rx of PPDUs using STBC
+ 0: not support
+ 1: support 1SS
+ 2: support 1SS and 2SS
+ 3: support 1SS, 2SS and 3SS
+ 4: support 1SS, 2SS, 3SS and 4SS
+ 5,6,7: reserved
+ bfer_cap_su: SU Beamformer Capable
+ ->Indicates support for operation as a single user beamformer
+ 0: not support
+ 1: support
+ bfee_cap_su: SU Beamformee Capable
+ -> Indicates support for operation as a single user beamformee
+ 0: not support
+ 1: support
+ cmp_st_num_bfer: Compressed Steering Number of Beamformer Antenna Supported
+ -> Beamformee's capability indicateing the max number of beamformer
+ antennas the beamformee can support when sending compressed
+ beamforming feedback
+ If SU beamformee capable, set to the max value minus 1.
+ otehrwise, reserved.
+ num_snd_dimension: Number of Sounding Dimensions
+ -> Beamformer's capability indicating the number of antennas used for
+ beamformed transmissions.
+ If SU beamformer capable, set to value minus 1.
+ otehrwise, reserved.
+ bfer_cap_mu: MU Beamformer Capable
+ -> Indicates support for operation as an MU beamformer
+ 0: if not supported or if sent by a non-AP STA
+ 1: supported
+ bfee_cap_mu: MU Beamformee Capable
+ -> Indicates support for operation as an MU beamformer
+ 0: if not supported or if snet by an AP
+ 1: supported
+ vht_txop_ps: VHT TXOP PS
+ -> Indicates whether or not the AP supports VHT TXOP Power Save Mode or
+ whether or not the STA is in VHT TXOP Power Save Mode
+ ->When tx by a VHT AP in the VHT Capabilities element included in Beacon,
+ ProbeResp, AssocResp, and ReassocResp, frames:
+ 0: if the VHT AP does not support VHT TXOP PS in the BSS.
+ 1: if the VHT AP support TXOP PS in the BSS.
+ ->When tx by a VHT non-AP STA in the VHT Capabilities element included
+ in AssocReq, ReassocReq and ProbReq frames:
+ 0: if the VHT STA is not in TXOP Power Save Mode.
+ 1: if the VHT STA is in TXOP Power Save Mode.
+ htc_vht_cap: +HTC-VHT Capable
+ -> Indicates whether or not the STA supports receiving an HT Control
+ field in the VHT format
+ 0: if not support
+ 1: if support
+ max_ampdu_exp: Maximum A-MPDU Length Exponent
+ -> Indicates the maximum length of A-MPDU pre-EOF padding that the STA
+ can receive.
+ ->The length defined by this field is equal to 2^(13 + max_ampdu_exp) -1
+ 0~7 : integer in the range of 0 to 7.
+ vht_link_adapt: VHT Link Adaptation Capable
+ -> Indicates whether or not the STA support link adaptation using VHT
+ variant HT Control field.
+ -> This field is ignored if the _HTC-VHT Capble field is set to 0.
+ 0: (No Feedback), if the STA does not provide VHT MFB
+ 2: (Unsolicited), if the STA provides only unsolicited VHT MFB
+ 3: (Both), if the STA can provide VHT MFB in response to VHT MRQ
+ and if the STA provides unsolicited VHT MFB.
+ 1: reserved
+ rx_ant_consistency: Rx Antenna Pattern Consistency
+ ->Indicates the possibility of Rx antenna pattern change
+ 0: if Rx antenna pattern might change during association
+ 1: if Rx antenna pattern does not change during association
+ tx_ant_consistency: Tx Antenna Pattern Consistency
+ ->Indicates the possibility of Tx antenna pattern change
+ 0: if Tx antenna pattern might change during association
+ 1: if Tx antenna pattern does not change during association
+*/
+typedef struct GNU_PACKED _VHT_CAP_INFO{
+#ifdef RT_BIG_ENDIAN
+ UINT32 rsv:2;
+ UINT32 tx_ant_consistency:1;
+ UINT32 rx_ant_consistency:1;
+ UINT32 vht_link_adapt:2;
+ UINT32 max_ampdu_exp:3;
+ UINT32 htc_vht_cap:1;
+ UINT32 vht_txop_ps:1;
+ UINT32 bfee_cap_mu:1;
+ UINT32 bfer_cap_mu:1;
+ UINT32 num_snd_dimension:3;
+
+ UINT32 cmp_st_num_bfer:3;
+ UINT32 bfee_cap_su:1;
+ UINT32 bfer_cap_su:1;
+ UINT32 rx_stbc:3;
+
+ UINT32 tx_stbc:1;
+ UINT32 sgi_160M:1;
+ UINT32 sgi_80M:1;
+ UINT32 rx_ldpc:1;
+ UINT32 ch_width:2;
+ UINT32 max_mpdu_len:2;
+#else
+ UINT32 max_mpdu_len:2; /* 0: 3895, 1: 7991, 2: 11454, 3: rsv */
+ UINT32 ch_width:2; /* */
+ UINT32 rx_ldpc:1;
+ UINT32 sgi_80M:1;
+ UINT32 sgi_160M:1;
+ UINT32 tx_stbc:1;
+
+ UINT32 rx_stbc:3;
+ UINT32 bfer_cap_su:1;
+ UINT32 bfee_cap_su:1;
+ UINT32 cmp_st_num_bfer:3;
+
+ UINT32 num_snd_dimension:3;
+ UINT32 bfer_cap_mu:1;
+ UINT32 bfee_cap_mu:1;
+ UINT32 vht_txop_ps:1;
+ UINT32 htc_vht_cap:1;
+ UINT32 max_ampdu_exp:3;
+ UINT32 vht_link_adapt:2;
+ UINT32 rx_ant_consistency:1;
+ UINT32 tx_ant_consistency:1;
+ UINT32 rsv:2;
+#endif /* RT_BIG_ENDIAN */
+}VHT_CAP_INFO;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.160.3
+ Rx MCS Map and Tx MCS map, figure 8-401bt
+
+ mcs_ss1: Max MCS for 1SS
+ mcs_ss2: Max MCS for 2SS
+ mcs_ss3: Max MCS for 3SS
+ mcs_ss4: Max MCS for 4SS
+ mcs_ss5: Max MCS for 5SS
+ mcs_ss6: Max MCS for 6SS
+ mcs_ss7: Max MCS for 7SS
+ mcs_ss8: Max MCS for 8SS
+
+ The 2-bit MAx MCS for n SS field for each number of spatial streams n = 1~8
+ is encoded as following:
+ 0: indicates support for MCS 0~7
+ 1: indicates support for MCS 0~8
+ 2: indicates support for MCS 0~9
+ 3: indicates that n spatial streams is not supported.
+ Note: some MCSs are not be valid for particular bandwidth and number of
+ spatial stream combinations.
+*/
+#define VHT_MCS_CAP_7 0
+#define VHT_MCS_CAP_8 1
+#define VHT_MCS_CAP_9 2
+#define VHT_MCS_CAP_NA 3
+
+typedef struct GNU_PACKED _VHT_MCS_MAP{
+#ifdef RT_BIG_ENDIAN
+ UINT16 mcs_ss8:2;
+ UINT16 mcs_ss7:2;
+ UINT16 mcs_ss6:2;
+ UINT16 mcs_ss5:2;
+ UINT16 mcs_ss4:2;
+ UINT16 mcs_ss3:2;
+ UINT16 mcs_ss2:2;
+ UINT16 mcs_ss1:2;
+#else
+ UINT16 mcs_ss1:2;
+ UINT16 mcs_ss2:2;
+ UINT16 mcs_ss3:2;
+ UINT16 mcs_ss4:2;
+ UINT16 mcs_ss5:2;
+ UINT16 mcs_ss6:2;
+ UINT16 mcs_ss7:2;
+ UINT16 mcs_ss8:2;
+#endif /* RT_BIG_ENDIAN */
+}VHT_MCS_MAP;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.160.3
+ VHT Supported MCS Set field, figure 8-401bs
+
+ rx_mcs_map: Rx MCS Map
+ -> Indicates the maximum MCS that can be received for each number of
+ spatial streams
+ See "VHT_MCS_MAP"
+ rx_high_rate: Rx Highest Supported Data Rate
+ -> Indicates the maximum data rate that the STA can receive
+ -> In unit of 1Mb/s where 1 represents 1Mb/s, and incrementing in steps
+ of 1 Mb/s.
+ -> If the maximum data rate expressed in Mb/s is not an integer, then
+ the value is rounded up to the next integer.
+ tx_mcs_map: Tx MCS Map
+ tx_high_rate: Tx Highest Supported Data Rate
+ -> Indicates the maximum data rate that the STA will transmit
+ -> In unit of 1Mb/s where 1 represents 1Mb/s, and incrementing in steps
+ of 1 Mb/s.
+ -> If the maximum data rate expressed in Mb/s is not an integer, then
+ the value is rounded up to the next integer.
+*/
+
+// TODO: shiang-6590, check the layout of this data structure!!!!
+typedef struct GNU_PACKED _VHT_MCS_SET{
+#ifdef RT_BIG_ENDIAN
+ UINT16 rsv2:3;
+ UINT16 tx_high_rate:13;
+ struct _VHT_MCS_MAP tx_mcs_map;
+ UINT16 rsv:3;
+ UINT16 rx_high_rate:13;
+ struct _VHT_MCS_MAP rx_mcs_map;
+#else
+ struct _VHT_MCS_MAP rx_mcs_map;
+ UINT16 rx_high_rate:13;
+ UINT16 rsv:3;
+ struct _VHT_MCS_MAP tx_mcs_map;
+ UINT16 tx_high_rate:13;
+ UINT16 rsv2:3;
+#endif /* RT_BIG_ENDIAN */
+}VHT_MCS_SET;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.160.1
+ VHT Capabilities Element structure
+
+ eid: Element ID
+ 191 (IE_VHT_CAP)
+ len: Length
+ 12
+ vht_cap: VHT Capabilities Info
+ ->contains a numner of fields that are used to advertise VHT capabilities
+ of a VHT STA
+ mcs_set: VHT supported MCS Set
+ ->Used to convey the combinations of MCSs and spatial streams a STA
+ supports for both reception and transmission.
+*/
+typedef struct GNU_PACKED _VHT_CAP_IE{
+ VHT_CAP_INFO vht_cap;
+ VHT_MCS_SET mcs_set;
+}VHT_CAP_IE;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.161
+ VHT Operation Information field, figure 8-401bv
+
+ The operation of VHT STAs in the BSS is controlled by the HT Operation
+ element and the VHT Operation element.
+
+ ch_width: Channel Width
+ -> This field, together with the HT Operation element STA Channel Width
+ field, defines the BSS operating channel width.
+ 0: for 20MHz or 40MHz operating channel width
+ 1: for 80MHz operating channel width
+ 2: for 160MHz operating channel width
+ 3: for 80+80MHz operating channel width
+ 4~255: reserved
+ center_freq_1: Channel Center Frequency Segment 1
+ -> Defines the channel center frequency for an 80 and 160MHz VHT BSS
+ and the segment 1 channel center frequency for an 80+90MHz VHT BSS.
+ -> For 80MHZ or 160MHz operating channel width, indicates the channel
+ center frequency index for the 80MHz or 160MHz channel on which the
+ VHT BSS operates.
+ ->For 80+80MHz operating channel width, indicates the channel center
+ frequency index for the 80MHz channel of frequency segment 1 on
+ which the VHT BSS operates.
+ ->Set 0 for 20MHz or 40MHz operating channel width.
+
+ center_freq_2: Channel Center Frequency Segment 2
+ -> Defines the seg 2 channel center frequency for an 80+80MHz VHT BSS
+ ->For a 80+80MHz operating channel width, indicates the channel center
+ frequency index of the 80MHz channel of frequency segment 2 on
+ which the VHT BSS operates. Reserved otherwise.
+*/
+typedef struct GNU_PACKED _VHT_OP_INFO{
+ UINT8 ch_width;
+ UINT8 center_freq_1;
+ UINT8 center_freq_2;
+}VHT_OP_INFO;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.161
+ VHT Operation element, figure 8-401bu
+
+ The operation of VHT STAs in the BSS is controlled by the HT Operation
+ element and the VHT Operation element.
+
+ eid: Element ID
+ 192 (IE_VHT_OP)
+ len: Length
+ 5
+ vht_op_info: VHT Operation Information
+ basic_mcs_set: VHT Basic MCS Set
+*/
+typedef struct GNU_PACKED _VHT_OP_IE{
+ VHT_OP_INFO vht_op_info;
+ VHT_MCS_MAP basic_mcs_set;
+}VHT_OP_IE;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.163
+ Wide Bandwidth Channel Switch element, figure 8-401bx
+
+ included in the Channel Switch Announcement frames.
+
+ new_ch_width: New STA Channel Width
+ center_freq_1: New Channel Center Frequency Segment 1
+ center_freq_2: New Channel Center Frequency Segment 2
+
+ The definition of upper subfields is the same as "VHT_OP_INFO"
+*/
+typedef struct GNU_PACKED _WIDE_BW_CH_SWITCH_IE{
+ UINT8 e_id;
+ UINT len;
+ UINT8 new_ch_width;
+ UINT8 center_freq_1;
+ UINT8 center_freq_2;
+}WIDE_BW_CH_SWITCH_IE;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.164
+ VHT Transmit Power Envelope element
+
+
+*/
+typedef struct GNU_PACKED _CH_SEG_PAIR{
+ UINT8 ch_center_freq;
+ UINT8 seg_ch_width;
+}CH_SEG_PAIR;
+
+
+/*
+ IEEE 802.11AC D2.0, sec 8.4.2.164
+ VHT Transmit Power Envelope element
+
+ max_txpwr: Maximum Transmit Power
+ -> Define the maximum transmit power limit of the tx bandwidth defined
+ by the VHT Transmit Power Envelop element. The Maximum Transmit
+ Power field is a 8 bit 2's complement signed integer in the range of
+ -64 dBm to 63.5 dBm with a 0.5 dB step.
+
+ NOTE: The following two subfields may repeated as needed.
+ center_freq_1: Channel Center Frequency Segment
+ ch_seg_width: Segment Channel Width
+*/
+typedef struct GNU_PACKED _VHT_TXPWR_ENV_IE{
+ UINT8 e_id;
+ UINT8 len;
+ UINT8 max_txpwr;
+ CH_SEG_PAIR ch_seg_pair[0];
+}VHT_TXPWR_ENV_IE;
+
+
+
+typedef struct GNU_PACKED _VHT_CONTROL{
+#ifdef RT_BIG_ENDIAN
+ UINT32 RDG:1;
+ UINT32 ACConstraint:1;
+ UINT32 unso_mfb:1;
+ UINT32 fb_tx_type:1;
+ UINT32 coding:1;
+ UINT32 gid_h:3;
+ UINT32 mfb_snr:6;
+ UINT32 mfb_bw:2;
+ UINT32 mfb_mcs:4;
+ UINT32 mfb_n_sts:3;
+ UINT32 mfsi_gidl:3;
+ UINT32 stbc_ind:1;
+ UINT32 comp_msi:2;
+ UINT32 mrq:1;
+ UINT32 rsv:1;
+ UINT32 vht:1;
+#else
+ UINT32 vht:1;
+ UINT32 rsv:1;
+ UINT32 mrq:1;
+ UINT32 comp_msi:2;
+ UINT32 stbc_ind:1;
+ UINT32 mfsi_gidl:3;
+ UINT32 mfb_n_sts:3;
+ UINT32 mfb_mcs:4;
+ UINT32 mfb_bw:2;
+ UINT32 mfb_snr:6;
+ UINT32 gid_h:3;
+ UINT32 coding:1;
+ UINT32 fb_tx_type:1;
+ UINT32 unso_mfb:1;
+ UINT32 ACConstraint:1;
+ UINT32 RDG:1;
+#endif
+}VHT_CONTROL;
+
+
+typedef struct GNU_PACKED _NDPA_PKT{
+ USHORT frm_ctrl;
+ USHORT duration;
+ UINT8 ra[MAC_ADDR_LEN];
+ UINT8 ta[MAC_ADDR_LEN];
+ UINT8 snd_seq;
+}DNPA_PKT;
+
+
+
+#endif /* __DOT11AC_VHT_H */
+
+#endif /* DOT11_VHT_AC */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/dot11i_wpa.h b/cleopatre/devkit/mt7601udrv/include/dot11i_wpa.h
new file mode 100644
index 0000000000..904036c65c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/dot11i_wpa.h
@@ -0,0 +1,291 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36 Taiyuan St., Jhubei City,
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2008, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ dot11i_wpa.h
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+
+*/
+
+#ifndef __DOT11I_WPA_H__
+#define __DOT11I_WPA_H__
+
+#include "rtmp_type.h"
+
+/* The length is the EAPoL-Key frame except key data field.
+ Please refer to 802.11i-2004 ,Figure 43u in p.78 */
+#define MIN_LEN_OF_EAPOL_KEY_MSG 95
+
+/* The related length of the EAPOL Key frame */
+#define LEN_KEY_DESC_NONCE 32
+#define LEN_KEY_DESC_IV 16
+#define LEN_KEY_DESC_RSC 8
+#define LEN_KEY_DESC_ID 8
+#define LEN_KEY_DESC_REPLAY 8
+#define LEN_KEY_DESC_MIC 16
+
+/* EAP Code Type */
+#define EAP_CODE_REQUEST 1
+#define EAP_CODE_RESPONSE 2
+#define EAP_CODE_SUCCESS 3
+#define EAP_CODE_FAILURE 4
+
+/* EAPOL frame Protocol Version */
+#define EAPOL_VER 1
+#define EAPOL_VER2 2
+
+/* EAPOL-KEY Descriptor Type */
+#define WPA1_KEY_DESC 0xfe
+#define WPA2_KEY_DESC 0x02
+
+/* Key Descriptor Version of Key Information */
+#define KEY_DESC_TKIP 1
+#define KEY_DESC_AES 2
+#define KEY_DESC_EXT 3
+
+#define IE_WPA 221
+#define IE_RSN 48
+
+#define WPA_KDE_TYPE 0xdd
+
+/*EAP Packet Type */
+#define EAPPacket 0
+#define EAPOLStart 1
+#define EAPOLLogoff 2
+#define EAPOLKey 3
+#define EAPOLASFAlert 4
+#define EAPTtypeMax 5
+
+#define PAIRWISEKEY 1
+#define GROUPKEY 0
+
+/* RSN IE Length definition */
+#define MAX_LEN_OF_RSNIE 255
+#define MIN_LEN_OF_RSNIE 18
+#define MAX_LEN_GTK 32
+#define MIN_LEN_GTK 5
+
+#define LEN_PMK 32
+#define LEN_PMKID 16
+#define LEN_PMK_NAME 16
+
+#define LEN_GMK 32
+
+#define LEN_PTK_KCK 16
+#define LEN_PTK_KEK 16
+#define LEN_TK 16 /* The length Temporal key. */
+#define LEN_TKIP_MIC 8 /* The length of TX/RX Mic of TKIP */
+#define LEN_TK2 (2 * LEN_TKIP_MIC)
+#define LEN_PTK (LEN_PTK_KCK + LEN_PTK_KEK + LEN_TK + LEN_TK2)
+
+#define LEN_TKIP_PTK LEN_PTK
+#define LEN_AES_PTK (LEN_PTK_KCK + LEN_PTK_KEK + LEN_TK)
+#define LEN_TKIP_GTK (LEN_TK + LEN_TK2)
+#define LEN_AES_GTK LEN_TK
+#define LEN_TKIP_TK (LEN_TK + LEN_TK2)
+#define LEN_AES_TK LEN_TK
+
+#define LEN_WEP64 5
+#define LEN_WEP128 13
+
+#define OFFSET_OF_PTK_TK (LEN_PTK_KCK + LEN_PTK_KEK) /* The offset of the PTK Temporal key in PTK */
+#define OFFSET_OF_AP_TKIP_TX_MIC (OFFSET_OF_PTK_TK + LEN_TK)
+#define OFFSET_OF_AP_TKIP_RX_MIC (OFFSET_OF_AP_TKIP_TX_MIC + LEN_TKIP_MIC)
+#define OFFSET_OF_STA_TKIP_RX_MIC (OFFSET_OF_PTK_TK + LEN_TK)
+#define OFFSET_OF_STA_TKIP_TX_MIC (OFFSET_OF_AP_TKIP_TX_MIC + LEN_TKIP_MIC)
+
+#define LEN_KDE_HDR 6
+#define LEN_NONCE 32
+#define LEN_PN 6
+#define LEN_TKIP_IV_HDR 8
+#define LEN_CCMP_HDR 8
+#define LEN_CCMP_MIC 8
+#define LEN_OUI_SUITE 4
+#define LEN_WEP_TSC 3
+#define LEN_WPA_TSC 6
+#define LEN_WEP_IV_HDR 4
+#define LEN_ICV 4
+
+/* It's defined in IEEE Std 802.11-2007 Table 8-4 */
+typedef enum _WPA_KDE_ID
+{
+ KDE_RESV0,
+ KDE_GTK,
+ KDE_RESV2,
+ KDE_MAC_ADDR,
+ KDE_PMKID,
+ KDE_SMK,
+ KDE_NONCE,
+ KDE_LIFETIME,
+ KDE_ERROR,
+ KDE_RESV_OTHER
+} WPA_KDE_ID;
+
+/* EAPOL Key Information definition within Key descriptor format */
+typedef struct GNU_PACKED _KEY_INFO
+{
+#ifdef RT_BIG_ENDIAN
+ UCHAR KeyAck:1;
+ UCHAR Install:1;
+ UCHAR KeyIndex:2;
+ UCHAR KeyType:1;
+ UCHAR KeyDescVer:3;
+ UCHAR Rsvd:3;
+ UCHAR EKD_DL:1; /* EKD for AP; DL for STA */
+ UCHAR Request:1;
+ UCHAR Error:1;
+ UCHAR Secure:1;
+ UCHAR KeyMic:1;
+#else
+ UCHAR KeyMic:1;
+ UCHAR Secure:1;
+ UCHAR Error:1;
+ UCHAR Request:1;
+ UCHAR EKD_DL:1; /* EKD for AP; DL for STA */
+ UCHAR Rsvd:3;
+ UCHAR KeyDescVer:3;
+ UCHAR KeyType:1;
+ UCHAR KeyIndex:2;
+ UCHAR Install:1;
+ UCHAR KeyAck:1;
+#endif
+} KEY_INFO, *PKEY_INFO;
+
+/* EAPOL Key descriptor format */
+typedef struct GNU_PACKED _KEY_DESCRIPTER
+{
+ UCHAR Type;
+ KEY_INFO KeyInfo;
+ UCHAR KeyLength[2];
+ UCHAR ReplayCounter[LEN_KEY_DESC_REPLAY];
+ UCHAR KeyNonce[LEN_KEY_DESC_NONCE];
+ UCHAR KeyIv[LEN_KEY_DESC_IV];
+ UCHAR KeyRsc[LEN_KEY_DESC_RSC];
+ UCHAR KeyId[LEN_KEY_DESC_ID];
+ UCHAR KeyMic[LEN_KEY_DESC_MIC];
+ UCHAR KeyDataLen[2];
+ UCHAR KeyData[0];
+} KEY_DESCRIPTER, *PKEY_DESCRIPTER;
+
+typedef struct GNU_PACKED _EAPOL_PACKET
+{
+ UCHAR ProVer;
+ UCHAR ProType;
+ UCHAR Body_Len[2];
+ KEY_DESCRIPTER KeyDesc;
+} EAPOL_PACKET, *PEAPOL_PACKET;
+
+typedef struct GNU_PACKED _KDE_HDR
+{
+ UCHAR Type;
+ UCHAR Len;
+ UCHAR OUI[3];
+ UCHAR DataType;
+ UCHAR octet[0];
+} KDE_HDR, *PKDE_HDR;
+
+/*802.11i D10 page 83 */
+typedef struct GNU_PACKED _GTK_KDE
+{
+#ifndef RT_BIG_ENDIAN
+ UCHAR Kid:2;
+ UCHAR tx:1;
+ UCHAR rsv:5;
+ UCHAR rsv1;
+#else
+ UCHAR rsv:5;
+ UCHAR tx:1;
+ UCHAR Kid:2;
+ UCHAR rsv1;
+#endif
+ UCHAR GTK[0];
+} GTK_KDE, *PGTK_KDE;
+
+/* For WPA1 */
+typedef struct GNU_PACKED _RSNIE {
+ UCHAR oui[4];
+ USHORT version;
+ UCHAR mcast[4];
+ USHORT ucount;
+ struct GNU_PACKED {
+ UCHAR oui[4];
+ }ucast[1];
+} RSNIE, *PRSNIE;
+
+/* For WPA2 */
+typedef struct GNU_PACKED _RSNIE2 {
+ USHORT version;
+ UCHAR mcast[4];
+ USHORT ucount;
+ struct GNU_PACKED {
+ UCHAR oui[4];
+ }ucast[1];
+} RSNIE2, *PRSNIE2;
+
+/* AKM Suite */
+typedef struct GNU_PACKED _RSNIE_AUTH {
+ USHORT acount;
+ struct GNU_PACKED {
+ UCHAR oui[4];
+ }auth[1];
+} RSNIE_AUTH,*PRSNIE_AUTH;
+
+/* PMKID List */
+typedef struct GNU_PACKED _RSNIE_PMKID {
+ USHORT pcount;
+ struct GNU_PACKED {
+ UCHAR list[16];
+ }pmkid[1];
+} RSNIE_PMKID,*PRSNIE_PMKID;
+
+typedef union GNU_PACKED _RSN_CAPABILITIES {
+ struct GNU_PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT Rsvd:8;
+ USHORT MFPC:1;
+ USHORT MFPR:1;
+ USHORT GTKSA_R_Counter:2;
+ USHORT PTKSA_R_Counter:2;
+ USHORT No_Pairwise:1;
+ USHORT PreAuth:1;
+#else
+ USHORT PreAuth:1;
+ USHORT No_Pairwise:1;
+ USHORT PTKSA_R_Counter:2;
+ USHORT GTKSA_R_Counter:2;
+ USHORT MFPR:1;
+ USHORT MFPC:1;
+ USHORT Rsvd:8;
+#endif
+ } field;
+ USHORT word;
+} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
+
+typedef struct GNU_PACKED _EAP_HDR {
+ UCHAR ProVer;
+ UCHAR ProType;
+ UCHAR Body_Len[2];
+ UCHAR code;
+ UCHAR identifier;
+ UCHAR length[2]; /* including code and identifier, followed by length-2 octets of data */
+} EAP_HDR, *PEAP_HDR;
+
+
+#endif /* __DOT11I_WPA_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/drs_extr.h b/cleopatre/devkit/mt7601udrv/include/drs_extr.h
new file mode 100644
index 0000000000..7791f22e16
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/drs_extr.h
@@ -0,0 +1,326 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All Dynamic Rate Switch Related Structure & Definition
+
+***************************************************************************/
+
+#ifndef __DRS_EXTR_H__
+#define __DRS_EXTR_H__
+
+struct _RTMP_ADAPTER;
+struct _MAC_TABLE_ENTRY;
+
+
+typedef struct _RTMP_TX_RATE {
+ UCHAR mode;
+ UCHAR bw;
+ UCHAR mcs;
+ UCHAR nss;
+ UCHAR sgi;
+ UCHAR stbc;
+}RTMP_TX_RATE;
+
+
+typedef struct _RTMP_RA_LEGACY_TB
+{
+ UCHAR ItemNo;
+#ifdef RT_BIG_ENDIAN
+ UCHAR Rsv2:1;
+ UCHAR Mode:3;
+ UCHAR BW:2;
+ UCHAR ShortGI:1;
+ UCHAR STBC:1;
+#else
+ UCHAR STBC:1;
+ UCHAR ShortGI:1;
+ UCHAR BW:2;
+ UCHAR Mode:3;
+ UCHAR Rsv2:1;
+#endif
+ UCHAR CurrMCS;
+ UCHAR TrainUp;
+ UCHAR TrainDown;
+} RTMP_RA_LEGACY_TB;
+
+#define PTX_RA_LEGACY_ENTRY(pTable, idx) ((RTMP_RA_LEGACY_TB *)&(pTable[(idx+1)*5]))
+
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+typedef struct _RTMP_RA_GRP_TB
+{
+ UCHAR ItemNo;
+#ifdef RT_BIG_ENDIAN
+ UCHAR Rsv2:1;
+ UCHAR Mode:3;
+ UCHAR BW:2;
+ UCHAR ShortGI:1;
+ UCHAR STBC:1;
+#else
+ UCHAR STBC:1;
+ UCHAR ShortGI:1;
+ UCHAR BW:2;
+ UCHAR Mode:3;
+ UCHAR Rsv2:1;
+#endif
+ UCHAR CurrMCS;
+ UCHAR TrainUp;
+ UCHAR TrainDown;
+ UCHAR downMcs;
+ UCHAR upMcs3;
+ UCHAR upMcs2;
+ UCHAR upMcs1;
+ UCHAR dataRate;
+} RTMP_RA_GRP_TB;
+
+#define PTX_RA_GRP_ENTRY(pTable, idx) ((RTMP_RA_GRP_TB *)&(pTable[(idx+1)*10]))
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#define RATE_TABLE_SIZE(pTable) ((pTable)[0]) /* Byte 0 is number of rate indices */
+#define RATE_TABLE_INIT_INDEX(pTable) ((pTable)[1]) /* Byte 1 is initial rate index */
+
+enum RATE_ADAPT_ALG{
+ RATE_ALG_LEGACY = 1,
+ RATE_ALG_GRP = 2,
+ RATE_ALG_AGS = 3,
+ RATE_ALG_MAX_NUM
+};
+
+
+typedef enum {
+ RAL_OLD_DRS,
+ RAL_NEW_DRS,
+ RAL_QUICK_DRS
+}RA_LOG_TYPE;
+
+
+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 RateSwitchTable11N1SForABand[];
+extern UCHAR RateSwitchTable11N2S[];
+extern UCHAR RateSwitchTable11N2SForABand[];
+extern UCHAR RateSwitchTable11BGN3S[];
+extern UCHAR RateSwitchTable11BGN3SForABand[];
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+extern UCHAR RateSwitchTableAdapt11N1S[];
+extern UCHAR RateSwitchTableAdapt11N2S[];
+extern UCHAR RateSwitchTableAdapt11N3S[];
+
+#define PER_THRD_ADJ 1
+
+/* ADAPT_RATE_TABLE - true if pTable is one of the Adaptive Rate Switch tables */
+#ifdef DOT11_VHT_AC
+extern UCHAR RateTableVht1S[];
+extern UCHAR RateTableVht2S[];
+
+#define ADAPT_RATE_TABLE(pTable) ((pTable)==RateSwitchTableAdapt11N1S ||\
+ (pTable)==RateSwitchTableAdapt11N2S ||\
+ (pTable)==RateSwitchTableAdapt11N3S ||\
+ (pTable)==RateTableVht1S ||\
+ (pTable)==RateTableVht2S)
+#else
+#define ADAPT_RATE_TABLE(pTable) ((pTable)==RateSwitchTableAdapt11N1S || \
+ (pTable)==RateSwitchTableAdapt11N2S || \
+ (pTable)==RateSwitchTableAdapt11N3S)
+#endif /* DOT11_VHT_AC */
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+
+/* FUNCTION */
+VOID MlmeGetSupportedMcs(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN UCHAR *pTable,
+ OUT CHAR mcs[]);
+
+UCHAR MlmeSelectTxRate(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN CHAR mcs[],
+ IN CHAR Rssi,
+ IN CHAR RssiOffset);
+
+VOID MlmeClearTxQuality(struct _MAC_TABLE_ENTRY *pEntry);
+VOID MlmeClearAllTxQuality(struct _MAC_TABLE_ENTRY *pEntry);
+VOID MlmeDecTxQuality(struct _MAC_TABLE_ENTRY *pEntry, UCHAR rateIndex);
+USHORT MlmeGetTxQuality(struct _MAC_TABLE_ENTRY *pEntry, UCHAR rateIndex);
+VOID MlmeSetTxQuality(
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR rateIndex,
+ IN USHORT txQuality);
+
+
+
+VOID MlmeOldRateAdapt(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR CurrRateIdx,
+ IN UCHAR UpRateIdx,
+ IN UCHAR DownRateIdx,
+ IN ULONG TrainUp,
+ IN ULONG TrainDown,
+ IN ULONG TxErrorRatio);
+
+VOID MlmeRestoreLastRate(
+ IN struct _MAC_TABLE_ENTRY *pEntry);
+
+VOID MlmeCheckRDG(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry);
+
+VOID RTMPSetSupportMCS(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN UCHAR OpMode,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+#ifdef DOT11_VHT_AC
+ IN UCHAR vht_cap_len,
+ IN VHT_CAP_IE *vht_cap,
+#endif /* DOT11_VHT_AC */
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen);
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+VOID MlmeSetMcsGroup(struct _RTMP_ADAPTER *pAd, struct _MAC_TABLE_ENTRY *pEnt);
+
+UCHAR MlmeSelectUpRate(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN RTMP_RA_GRP_TB *pCurrTxRate);
+
+UCHAR MlmeSelectDownRate(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR CurrRateIdx);
+
+VOID MlmeGetSupportedMcsAdapt(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR mcs23GI,
+ OUT CHAR mcs[]);
+
+UCHAR MlmeSelectTxRateAdapt(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN CHAR mcs[],
+ IN CHAR Rssi,
+ IN CHAR RssiOffset);
+
+BOOLEAN MlmeRAHybridRule(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN RTMP_RA_GRP_TB *pCurrTxRate,
+ IN ULONG NewTxOkCount,
+ IN ULONG TxErrorRatio);
+
+VOID MlmeNewRateAdapt(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR UpRateIdx,
+ IN UCHAR DownRateIdx,
+ IN ULONG TrainUp,
+ IN ULONG TrainDown,
+ IN ULONG TxErrorRatio);
+
+INT Set_PerThrdAdj_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_LowTrafficThrd_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_TrainUpRule_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_TrainUpRuleRSSI_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_TrainUpLowThrd_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_TrainUpHighThrd_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_RateTable_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+#ifdef CONFIG_AP_SUPPORT
+VOID APMlmeDynamicTxRateSwitchingAdapt(struct _RTMP_ADAPTER *pAd, ULONG idx);
+VOID APQuickResponeForRateUpExecAdapt(struct _RTMP_ADAPTER *pAd, ULONG idx);
+#endif /* CONFIG_AP_SUPPORT */
+
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+VOID APMlmeDynamicTxRateSwitching(
+ IN struct _RTMP_ADAPTER *pAd);
+
+VOID APQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID APMlmeSetTxRate(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN RTMP_RA_LEGACY_TB *pTxRate);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+VOID MlmeRAInit(struct _RTMP_ADAPTER *pAd, struct _MAC_TABLE_ENTRY *pEntry);
+VOID MlmeNewTxRate(struct _RTMP_ADAPTER *pAd, struct _MAC_TABLE_ENTRY *pEntry);
+
+VOID MlmeRALog(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN RA_LOG_TYPE raLogType,
+ IN ULONG TxErrorRatio,
+ IN ULONG TxTotalCnt);
+
+VOID MlmeSelectTxRateTable(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN struct _MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR **ppTable,
+ IN UCHAR *pTableSize,
+ IN UCHAR *pInitTxRateIdx);
+
+/* normal rate switch */
+#define RTMP_DRS_ALG_INIT(__pAd, __Alg) \
+ (__pAd)->rateAlg = __Alg;
+
+#endif /* __DRS_EXTR_H__ */
+
+/* End of drs_extr.h */
diff --git a/cleopatre/devkit/mt7601udrv/include/eeprom.h b/cleopatre/devkit/mt7601udrv/include/eeprom.h
new file mode 100644
index 0000000000..7e90d97802
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/eeprom.h
@@ -0,0 +1,321 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ eeprom.h
+
+ Abstract:
+ Miniport header file for eeprom related information
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+/* For ioctl check usage */
+#define EEPROM_IS_PROGRAMMED 0x80
+
+
+#ifdef RTMP_MAC_USB
+#define EEPROM_SIZE 0x400
+#endif /* RTMP_MAC_USB */
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_WORD_STRUC {
+ struct {
+ UCHAR Byte1; // High Byte
+ UCHAR Byte0; // Low Byte
+ } field;
+ USHORT word;
+} EEPROM_WORD_STRUC;
+#else
+typedef union _EEPROM_WORD_STRUC {
+ struct {
+ UCHAR Byte0;
+ UCHAR Byte1;
+ } field;
+ USHORT word;
+} EEPROM_WORD_STRUC;
+#endif
+
+
+/* ------------------------------------------------------------------- */
+/* 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_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
+
+
+#if defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290)
+#ifdef RTMP_USB_SUPPORT
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_NIC_CINFIG3_STRUC {
+ struct {
+ USHORT Rsv1:7; /* must be 0 */
+ USHORT CoexMethod:1;
+ USHORT TxStream:4; /* Number of Tx stream */
+ USHORT RxStream:4; /* Number of rx stream */
+ } field;
+ USHORT word;
+} EEPROM_NIC_CONFIG3_STRUC, *PEEPROM_NIC_CONFIG3_STRUC;
+#else
+typedef union _EEPROM_NIC_CINFIG3_STRUC {
+ struct {
+ USHORT RxStream:4; /* Number of rx stream */
+ USHORT TxStream:4; /* Number of Tx stream */
+ USHORT CoexMethod:1;
+ USHORT Rsv1:7; /* must be 0 */
+ } field;
+ USHORT word;
+} EEPROM_NIC_CONFIG3_STRUC, *PEEPROM_NIC_CONFIG3_STRUC;
+#endif
+#endif /* RTMP_USB_SUPPORT */
+
+#endif /* defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290) */
+
+
+
+/*
+ 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 */
+
+
+struct _RTMP_ADAPTER;
+
+
+
+#ifdef RTMP_USB_SUPPORT
+NTSTATUS RTUSBReadEEPROM16(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN USHORT offset,
+ OUT USHORT *pData);
+
+NTSTATUS RTUSBWriteEEPROM16(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN USHORT offset,
+ IN USHORT value);
+#endif /* RTMP_USB_SUPPORT */
+
+
+#if defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT)
+NDIS_STATUS rtmp_nv_init(struct _RTMP_ADAPTER *pAd);
+int rtmp_ee_flash_read(struct _RTMP_ADAPTER *pAd, USHORT Offset, USHORT *pVal);
+int rtmp_ee_flash_write(struct _RTMP_ADAPTER *pAd, USHORT Offset, USHORT data);
+VOID rtmp_ee_flash_read_all(struct _RTMP_ADAPTER *pAd, USHORT *Data);
+VOID rtmp_ee_flash_write_all(struct _RTMP_ADAPTER *pAd, USHORT *Data);
+#endif /* defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT) */
+
+
+#ifdef RTMP_EFUSE_SUPPORT
+INT eFuseLoadEEPROM(struct _RTMP_ADAPTER *pAd);
+INT eFuseWriteEeeppromBuf(struct _RTMP_ADAPTER *pAd);
+VOID eFuseGetFreeBlockCount(struct _RTMP_ADAPTER *pAd, UINT *EfuseFreeBlock);
+
+int rtmp_ee_efuse_read16(struct _RTMP_ADAPTER *pAd, USHORT Offset, USHORT *pVal);
+int rtmp_ee_efuse_write16(struct _RTMP_ADAPTER *pAd, USHORT Offset, USHORT data);
+
+
+NTSTATUS eFuseRead(struct _RTMP_ADAPTER *pAd, USHORT Offset, USHORT *pData, USHORT len);
+NTSTATUS eFuseWrite(struct _RTMP_ADAPTER *pAd, USHORT Offset, USHORT *pData, USHORT len);
+
+INT eFuse_init(struct _RTMP_ADAPTER *pAd);
+INT efuse_probe(struct _RTMP_ADAPTER *pAd);
+
+#ifdef RALINK_ATE
+INT Set_LoadEepromBufferFromEfuse_Proc(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+#endif /* RALINK_ATE */
+#endif /* RTMP_EFUSE_SUPPORT */
+
+
+/*************************************************************************
+ * Public function declarations for prom operation callback functions setting
+ ************************************************************************/
+INT RtmpChipOpsEepromHook(struct _RTMP_ADAPTER *pAd, INT infType);
+
+#endif /* __EEPROM_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/firmware.h b/cleopatre/devkit/mt7601udrv/include/firmware.h
new file mode 100644
index 0000000000..a4904e9903
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/firmware.h
@@ -0,0 +1,2396 @@
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+UCHAR FirmwareImage [] = {
+0x48, 0x00, 0x00, 0x52, 0x48, 0x00, 0x00, 0x1e, 0x48, 0x00, 0x00, 0x1c, 0x48, 0x00, 0x00, 0x1a,
+0x48, 0x00, 0x00, 0x18, 0x48, 0x00, 0x00, 0x16, 0x48, 0x00, 0x00, 0x14, 0x48, 0x00, 0x00, 0x12,
+0x48, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x0e, 0x48, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x0a,
+0x48, 0x00, 0x00, 0x08, 0x48, 0x00, 0x00, 0x06, 0x48, 0x00, 0x00, 0x04, 0x48, 0x00, 0x00, 0x02,
+0x92, 0x00, 0x48, 0x00, 0x00, 0x00, 0x92, 0x00, 0x3a, 0x0f, 0xab, 0xbc, 0x3a, 0xff, 0xbc, 0x3c,
+0x64, 0x62, 0x04, 0x02, 0x64, 0x72, 0xa4, 0x02, 0x64, 0x82, 0x00, 0x02, 0x3a, 0x6f, 0xa0, 0x3c,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x05, 0xa0, 0xb4, 0x00, 0x15, 0xf0, 0x00, 0x00, 0x46, 0x10,
+0x00, 0x04, 0x58, 0x10, 0x8f, 0xb0, 0xdd, 0x21, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x05, 0xa0,
+0xb4, 0x00, 0x05, 0xf0, 0x00, 0x00, 0x3a, 0x6f, 0xa0, 0x04, 0x64, 0x62, 0x04, 0x03, 0x64, 0x72,
+0xa4, 0x03, 0x64, 0x82, 0x00, 0x03, 0x3a, 0xff, 0xbc, 0x04, 0x3a, 0x0f, 0xab, 0x84, 0x64, 0x00,
+0x00, 0x04, 0x92, 0x00, 0x84, 0x0a, 0x64, 0x02, 0x00, 0x03, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00,
+0x02, 0x00, 0x44, 0x10, 0x04, 0x01, 0xa8, 0x41, 0x84, 0x00, 0x64, 0x02, 0x24, 0x03, 0x46, 0x0c,
+0x00, 0x00, 0x58, 0x00, 0x00, 0x02, 0x64, 0x03, 0x00, 0x03, 0x47, 0xf0, 0x00, 0x0f, 0x59, 0xff,
+0x8f, 0x00, 0x46, 0x00, 0x00, 0x08, 0x58, 0x00, 0x0b, 0x60, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10,
+0x83, 0x60, 0x84, 0x40, 0xd5, 0x02, 0xaa, 0x81, 0x4c, 0x10, 0x7f, 0xff, 0x46, 0x00, 0x00, 0x09,
+0x58, 0x00, 0x05, 0x70, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x85, 0xd4, 0x84, 0x40, 0xd5, 0x02,
+0xaa, 0x81, 0x4c, 0x10, 0x7f, 0xff, 0x48, 0x00, 0x26, 0xab, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0xb4, 0x20, 0xc1, 0x17, 0xa1, 0x41, 0x84, 0x80, 0xa9, 0x49, 0xb6, 0x25, 0xb6, 0x80,
+0xa9, 0x01, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x50, 0xa0, 0xc2, 0xb4, 0x20, 0x9e, 0x99,
+0xa8, 0x82, 0x4c, 0x10, 0x40, 0x08, 0xa0, 0x0b, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0x44,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x27, 0x80, 0x97, 0x80, 0xe0, 0xc2, 0x11, 0x80, 0x02,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0x44, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07,
+0x80, 0x97, 0x80, 0x27, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0xcc, 0xdd, 0x2f, 0xec, 0x04,
+0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x84, 0xe4, 0xdd, 0x2f, 0x46, 0x17, 0xff, 0xff, 0x58, 0x10, 0x8f, 0xff,
+0x46, 0x20, 0x00, 0x0c, 0x58, 0x21, 0x02, 0x50, 0x81, 0x00, 0x40, 0xa0, 0x04, 0x00, 0x44, 0x00,
+0xea, 0x60, 0x14, 0xa1, 0x00, 0x04, 0x80, 0xe2, 0xb4, 0xc2, 0x41, 0xc4, 0x00, 0x00, 0xd5, 0x2d,
+0xa0, 0x32, 0x40, 0x34, 0x00, 0x01, 0x4e, 0x35, 0x00, 0x20, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x81, 0x0c, 0xdd, 0x2f, 0xa4, 0x36, 0xc0, 0x10, 0x9e, 0x01, 0xac, 0x36, 0x15, 0xc3,
+0x00, 0x02, 0x05, 0xe3, 0x80, 0x01, 0xa9, 0xb9, 0xb6, 0xe6, 0x15, 0xe3, 0x00, 0x01, 0xb6, 0xde,
+0xa1, 0x7a, 0x9d, 0x29, 0xa9, 0x3a, 0xd5, 0x05, 0xa0, 0x75, 0xc1, 0x03, 0xa0, 0x34, 0xdd, 0x21,
+0x14, 0xa3, 0x80, 0x04, 0xd5, 0x09, 0xa0, 0xbc, 0x40, 0x90, 0x08, 0x01, 0x4e, 0x95, 0x00, 0x03,
+0xd5, 0x02, 0xa8, 0x3c, 0x81, 0x26, 0xb4, 0xc9, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x50,
+0x4c, 0x64, 0xff, 0xd0, 0xb4, 0xa6, 0xd6, 0x09, 0xa0, 0xf4, 0x40, 0x01, 0xa0, 0x01, 0x46, 0xf0,
+0x00, 0x00, 0x58, 0xf7, 0x81, 0x4c, 0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x60, 0x00, 0x0c, 0x58, 0x63, 0x02, 0x50, 0xa0, 0x33, 0x84, 0x20,
+0xa8, 0x72, 0xb6, 0xc6, 0xa9, 0xb1, 0xc8, 0x08, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x86, 0xd4,
+0xdd, 0x2f, 0xa8, 0x33, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0x44, 0xdd, 0x2f,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x80, 0xc0,
+0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0xa0, 0x32,
+0xc8, 0x02, 0xd5, 0x09, 0x9e, 0x01, 0xa8, 0x32, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x81, 0x80, 0xdd, 0x2f, 0x80, 0xc0, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c,
+0xdd, 0x2f, 0x80, 0x06, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xf4, 0x80, 0xc0, 0x50, 0x0f, 0x80, 0x04, 0x80, 0xe1, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x8f, 0xf8, 0xdd, 0x2f, 0xa0, 0xb2, 0x80, 0x06, 0x9c, 0x51, 0xa8, 0x72, 0x80, 0x27, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x81, 0x74, 0xdd, 0x2f, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x80, 0x0c, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x64, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x81, 0x6c,
+0xdd, 0x2f, 0x46, 0x70, 0x00, 0x09, 0x58, 0x73, 0x85, 0x90, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63,
+0x0f, 0xc0, 0x46, 0x80, 0x00, 0x00, 0x58, 0x84, 0x02, 0xbc, 0xa9, 0xf2, 0x80, 0x26, 0x46, 0x00,
+0x00, 0x0c, 0x58, 0x00, 0x02, 0x64, 0x4b, 0xe0, 0x20, 0x01, 0x50, 0x73, 0x86, 0x40, 0x46, 0x50,
+0x00, 0x0b, 0x58, 0x52, 0x8b, 0x10, 0x8c, 0xd8, 0xdf, 0xf1, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00,
+0x02, 0x74, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x81, 0x6c, 0xdd, 0x2f, 0x46, 0x70, 0x00, 0x0b,
+0x58, 0x73, 0x8b, 0x10, 0x46, 0x60, 0x00, 0x0c, 0x58, 0x63, 0x00, 0x50, 0x46, 0x80, 0x00, 0x00,
+0x58, 0x84, 0x02, 0xbc, 0xa9, 0xf2, 0x80, 0x26, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x74,
+0x4b, 0xe0, 0x20, 0x01, 0x50, 0x73, 0x80, 0xc8, 0x46, 0x50, 0x00, 0x0b, 0x58, 0x52, 0x8f, 0xc0,
+0x8c, 0xd8, 0xdf, 0xf1, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xfc, 0x84, 0xe0, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x85, 0x0c, 0xdd, 0x2f, 0x46, 0xf0,
+0x00, 0x09, 0x10, 0x77, 0x85, 0x83, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x77, 0x85, 0x84, 0x46, 0x60,
+0x00, 0x02, 0x58, 0x63, 0x08, 0xac, 0x44, 0x00, 0x00, 0x10, 0x46, 0x10, 0x00, 0x02, 0x58, 0x10,
+0x89, 0xf4, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x11, 0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x8a, 0x04,
+0xdd, 0x26, 0x84, 0x00, 0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x8a, 0x14, 0xdd, 0x26, 0x84, 0x01,
+0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x8a, 0x24, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x19, 0x46, 0x10,
+0x00, 0x02, 0x58, 0x10, 0x8a, 0x34, 0xdd, 0x26, 0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x8b, 0x30,
+0x44, 0x00, 0x00, 0x18, 0xdd, 0x26, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0xfc, 0xdd, 0x2f,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x84, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x89, 0x00,
+0xdd, 0x2f, 0x84, 0xc0, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x84, 0x88, 0xdd, 0x2f, 0x46, 0x40,
+0x00, 0x0c, 0x58, 0x42, 0x02, 0x84, 0x10, 0x72, 0x02, 0x64, 0x14, 0x62, 0x00, 0x2d, 0x80, 0x26,
+0x50, 0x02, 0x02, 0x66, 0x84, 0x48, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f,
+0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x08, 0x00, 0xa9, 0x84, 0x46, 0x20, 0x30, 0x00, 0xa0, 0xc3,
+0x40, 0x11, 0x88, 0x04, 0xa8, 0x43, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x9c, 0x3c, 0x96, 0x00, 0x96, 0x48, 0x95, 0x82, 0x99, 0x71, 0x44, 0x32, 0x0d, 0x60,
+0x99, 0x2b, 0x00, 0x31, 0x00, 0x40, 0x95, 0x25, 0x84, 0xa0, 0x38, 0x71, 0x14, 0x00, 0x99, 0xac,
+0xaf, 0xf0, 0x9d, 0x69, 0x44, 0x70, 0x00, 0x10, 0xdf, 0xf9, 0x9b, 0x94, 0x50, 0x52, 0x00, 0x18,
+0x50, 0x22, 0x00, 0x10, 0x38, 0x73, 0x08, 0x00, 0x18, 0x71, 0x00, 0x01, 0xda, 0xfc, 0x50, 0x42,
+0x00, 0x20, 0x38, 0x23, 0x14, 0x00, 0x18, 0x22, 0x80, 0x01, 0xdc, 0xfc, 0x46, 0x40, 0x01, 0x06,
+0x40, 0x20, 0x04, 0x09, 0x58, 0x42, 0x0c, 0x00, 0x99, 0x54, 0x94, 0xaa, 0x97, 0x04, 0xb4, 0x02,
+0xcc, 0x1d, 0xc9, 0x05, 0x54, 0x31, 0x80, 0x0f, 0x84, 0xd0, 0xd5, 0x39, 0x84, 0xa1, 0xd9, 0x07,
+0x54, 0x11, 0x80, 0x0f, 0x94, 0xcc, 0x44, 0x6f, 0xff, 0x0f, 0xd5, 0x31, 0x84, 0x82, 0x54, 0x31,
+0x80, 0x0f, 0x4c, 0x12, 0x40, 0x07, 0x40, 0x31, 0xa0, 0x08, 0x44, 0x6f, 0xf0, 0xff, 0xd5, 0x27,
+0x40, 0x31, 0xb0, 0x08, 0x44, 0x1f, 0x0f, 0xff, 0xd5, 0x2b, 0xc9, 0x0c, 0x46, 0x5f, 0xff, 0x0f,
+0x54, 0x31, 0x80, 0x0f, 0x58, 0x52, 0x8f, 0xff, 0x40, 0x31, 0xc0, 0x08, 0x40, 0x00, 0x14, 0x02,
+0xd5, 0x21, 0x84, 0xa1, 0xd9, 0x0a, 0x54, 0x11, 0x80, 0x0f, 0x40, 0x30, 0xd0, 0x08, 0x46, 0x1f,
+0xf0, 0xff, 0x58, 0x10, 0x8f, 0xff, 0xd5, 0x14, 0x84, 0xa2, 0xd9, 0x0c, 0x54, 0x61, 0x80, 0x0f,
+0x40, 0x33, 0x60, 0x08, 0x46, 0x6f, 0x0f, 0xff, 0x58, 0x63, 0x0f, 0xff, 0x40, 0x00, 0x18, 0x02,
+0xd5, 0x09, 0x46, 0x10, 0xff, 0xff, 0x40, 0x31, 0xf0, 0x08, 0x58, 0x10, 0x8f, 0xff, 0x40, 0x00,
+0x04, 0x02, 0x40, 0x00, 0x0c, 0x04, 0xb6, 0x02, 0x3a, 0x6f, 0x9c, 0x04, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa0, 0xbc, 0x84, 0x41, 0x96, 0x48, 0x4c, 0x11, 0x40, 0x23, 0x04, 0x80, 0x00, 0x04,
+0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xd4, 0x50, 0x64, 0x00, 0x1c, 0x80, 0x06, 0x46, 0x10,
+0x00, 0x09, 0x58, 0x10, 0x84, 0x44, 0x84, 0x46, 0x4b, 0xe0, 0x1c, 0x01, 0xc8, 0x11, 0x50, 0x84,
+0x00, 0x7c, 0x9d, 0xb6, 0x80, 0x06, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x85, 0x74, 0x84, 0x46,
+0x4b, 0xe0, 0x1c, 0x01, 0xc8, 0x05, 0x4c, 0x64, 0x7f, 0xf6, 0x84, 0x01, 0xd5, 0x02, 0x84, 0x00,
+0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x44, 0x30,
+0x01, 0x0c, 0x54, 0xa0, 0x80, 0xff, 0x42, 0x65, 0x0c, 0x24, 0x54, 0x91, 0x00, 0xff, 0x44, 0x20,
+0x00, 0x43, 0x42, 0x64, 0x88, 0x73, 0x97, 0xc0, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x03, 0xb4,
+0x99, 0xb0, 0x84, 0x20, 0x97, 0x20, 0x80, 0x06, 0x81, 0x05, 0xf4, 0x81, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x84, 0x24, 0x4c, 0x70, 0xc0, 0x04, 0x84, 0x03, 0xd5, 0x09,
+0x84, 0x46, 0x4c, 0x71, 0x40, 0x04, 0x84, 0x04, 0xd5, 0x04, 0x84, 0xab, 0xdf, 0x04, 0x84, 0x02,
+0x10, 0x03, 0x00, 0x40, 0x41, 0xe0, 0x88, 0x08, 0x11, 0xe3, 0x00, 0x41, 0x80, 0x28, 0x46, 0x70,
+0x01, 0x02, 0x58, 0x73, 0x86, 0xa4, 0x80, 0x06, 0x80, 0x5e, 0xdd, 0x27, 0x01, 0xc3, 0x00, 0x40,
+0x84, 0x23, 0x4d, 0xc0, 0xc0, 0x1b, 0xf4, 0x01, 0x50, 0x54, 0x00, 0x18, 0x50, 0x33, 0x00, 0x10,
+0x8d, 0x10, 0x51, 0xc3, 0x00, 0x18, 0xc4, 0x09, 0xb6, 0xbf, 0x80, 0x03, 0x80, 0x28, 0x84, 0x48,
+0xdd, 0x27, 0xb4, 0x3f, 0x80, 0x1c, 0xd5, 0x07, 0x80, 0x25, 0x80, 0x03, 0x84, 0x48, 0xdd, 0x27,
+0x80, 0x1c, 0x80, 0x28, 0x84, 0x48, 0xdd, 0x27, 0x80, 0x0a, 0x80, 0x29, 0x80, 0x46, 0x46, 0xf0,
+0x00, 0x00, 0x58, 0xf7, 0x84, 0x80, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa0, 0xbc, 0x44, 0x30, 0x01, 0x0c, 0x97, 0x00, 0x42, 0x62, 0x0c, 0x24, 0x46, 0x20,
+0x00, 0x0c, 0x58, 0x21, 0x03, 0xb4, 0x99, 0xb2, 0x81, 0x01, 0x80, 0x06, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x43, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0c,
+0x00, 0x07, 0x84, 0xc1, 0x84, 0xa4, 0xd8, 0x03, 0x84, 0x03, 0xd5, 0x04, 0x84, 0xa6, 0xd8, 0x24,
+0x84, 0x04, 0x45, 0xe0, 0x00, 0x10, 0x10, 0x03, 0x00, 0x40, 0x11, 0xe3, 0x00, 0x41, 0x50, 0x14,
+0x00, 0x20, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xa4, 0x80, 0x06, 0x80, 0x5e, 0x4b, 0xe0,
+0x1c, 0x01, 0x00, 0x03, 0x00, 0x40, 0x84, 0xa3, 0xd8, 0x0f, 0x50, 0x14, 0x00, 0x38, 0x84, 0x48,
+0x50, 0x03, 0x00, 0x10, 0x4b, 0xe0, 0x1c, 0x01, 0x50, 0x03, 0x00, 0x18, 0x50, 0x14, 0x00, 0x30,
+0x84, 0x48, 0x4b, 0xe0, 0x1c, 0x01, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xdc, 0x97, 0x20, 0x55, 0xc0, 0x80, 0xff, 0x54, 0x91, 0x00, 0xff, 0x96, 0xd8, 0xc4, 0x44,
+0x84, 0x23, 0x4c, 0x30, 0x80, 0x05, 0x84, 0x45, 0x4c, 0x31, 0x40, 0x70, 0x85, 0x40, 0x80, 0xe0,
+0x81, 0x2a, 0x81, 0x0a, 0x80, 0xdf, 0xd5, 0x30, 0xa6, 0x38, 0x44, 0x30, 0x00, 0xdd, 0x4c, 0x01,
+0xc0, 0x26, 0x9c, 0x3a, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x20, 0x84, 0x43, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x86, 0xd4, 0xdd, 0x2f, 0xc8, 0x19, 0xa7, 0x7d, 0x87, 0xc1, 0x4c, 0x5f,
+0x40, 0x16, 0xa7, 0x39, 0x00, 0x93, 0x80, 0x06, 0x50, 0x82, 0x7f, 0xfa, 0x54, 0x84, 0x00, 0xff,
+0x50, 0x13, 0x80, 0x08, 0x80, 0x1f, 0x80, 0x48, 0x54, 0x94, 0x80, 0x03, 0xe7, 0x10, 0xe9, 0x40,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xa6, 0xb9, 0x9c, 0x52, 0x89, 0x41,
+0x99, 0xf9, 0x54, 0xa5, 0x00, 0xff, 0xa7, 0x79, 0x9c, 0xea, 0x40, 0x01, 0xa8, 0x00, 0x40, 0xfe,
+0x00, 0x07, 0xe8, 0xcb, 0xd5, 0x0f, 0x84, 0xc5, 0x4c, 0x33, 0x40, 0x30, 0x80, 0x20, 0x80, 0x5c,
+0x80, 0x1f, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xe7, 0x24, 0xe8, 0x20,
+0x81, 0x1c, 0x46, 0x60, 0x00, 0x0c, 0x58, 0x63, 0x02, 0x84, 0x80, 0x48, 0x80, 0x3f, 0x50, 0x03,
+0x01, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x84, 0x20, 0x00, 0x03,
+0x02, 0x3d, 0x10, 0x93, 0x02, 0x3c, 0x80, 0x49, 0x50, 0x53, 0x01, 0x10, 0x80, 0x61, 0x80, 0x81,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x85, 0xd8, 0xdd, 0x2f, 0x84, 0x01, 0xd5, 0x02, 0x84, 0x00,
+0xec, 0x24, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x85, 0x20, 0x81, 0x09, 0xd5, 0xdb, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x94, 0x85, 0x40, 0x80, 0xc2, 0x55, 0xc0, 0x00, 0xff, 0x44, 0x00,
+0x02, 0x00, 0x81, 0x21, 0x14, 0xaf, 0x80, 0x19, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x81, 0x9c,
+0xdd, 0x2f, 0xa7, 0x32, 0xa6, 0x73, 0x40, 0x32, 0x20, 0x08, 0x40, 0x21, 0x84, 0x04, 0x9c, 0x94,
+0x50, 0x1f, 0x80, 0x64, 0x80, 0x66, 0x84, 0x9f, 0x50, 0x8f, 0x80, 0x54, 0x80, 0xe0, 0x46, 0xf0,
+0x00, 0x02, 0x58, 0xf7, 0x84, 0x3c, 0xdd, 0x2f, 0x80, 0x2a, 0x80, 0x08, 0x44, 0x20, 0x00, 0x10,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x84, 0x02, 0x4d, 0xc0, 0x40, 0x1a,
+0x50, 0xaf, 0x80, 0x04, 0xf3, 0x19, 0x80, 0x09, 0x80, 0x47, 0x80, 0x8a, 0x44, 0x50, 0x00, 0x14,
+0x9e, 0x6c, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x81, 0x54, 0xdd, 0x2f, 0x80, 0x08, 0x80, 0x2a,
+0x44, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xd5, 0x0d,
+0x44, 0x10, 0x00, 0x10, 0xf3, 0x19, 0x80, 0x09, 0x80, 0x88, 0x80, 0x47, 0x80, 0xa1, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x80, 0x10, 0xdd, 0x2f, 0x50, 0x1f, 0x80, 0x54, 0x44, 0x20, 0x00, 0x10,
+0x50, 0x03, 0x00, 0x51, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x80, 0x07,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x81, 0xb0, 0xdd, 0x2f, 0xec, 0x6c, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x87,
+0x84, 0xc2, 0xf6, 0x0c, 0x84, 0xe3, 0x85, 0x21, 0x84, 0xa0, 0x44, 0x00, 0x00, 0x5f, 0xaf, 0xf1,
+0x10, 0x93, 0x00, 0x00, 0xaf, 0x72, 0xae, 0x33, 0x83, 0x83, 0xf4, 0x81, 0x97, 0xc8, 0x96, 0x90,
+0x4e, 0x82, 0x00, 0x04, 0x84, 0x02, 0xd5, 0x02, 0x84, 0x1e, 0xae, 0x34, 0x46, 0x90, 0x00, 0x0c,
+0x58, 0x94, 0x82, 0x84, 0x00, 0x54, 0x82, 0x3d, 0xa7, 0x36, 0x56, 0x02, 0x80, 0x06, 0x85, 0x41,
+0x87, 0xc2, 0x40, 0x9f, 0x00, 0x1a, 0x40, 0x95, 0x00, 0x1b, 0x40, 0x12, 0x0c, 0x09, 0x94, 0x4b,
+0x40, 0x50, 0xa4, 0x04, 0xaf, 0x76, 0xe6, 0xe5, 0xe9, 0x04, 0x42, 0x52, 0x8c, 0x09, 0xd5, 0x03,
+0x58, 0x52, 0x80, 0x08, 0xaf, 0x76, 0x4e, 0x83, 0x00, 0x14, 0xe6, 0xe5, 0xe9, 0x11, 0xa7, 0x76,
+0x54, 0x01, 0x00, 0x03, 0x44, 0x3f, 0xff, 0xcf, 0x41, 0xe0, 0x10, 0x08, 0x40, 0xa2, 0x8c, 0x02,
+0x40, 0x45, 0x78, 0x04, 0x84, 0x43, 0xaf, 0x36, 0x4c, 0x71, 0x40, 0x0e, 0xd5, 0x0e, 0x84, 0x23,
+0x4c, 0x70, 0xc0, 0x07, 0xa7, 0x36, 0x58, 0x22, 0x00, 0x40, 0xae, 0xb6, 0xd5, 0x06, 0x85, 0x41,
+0x4c, 0x75, 0x00, 0x04, 0x84, 0xa5, 0xdf, 0x09, 0xa6, 0x36, 0x44, 0x1f, 0xff, 0x80, 0x40, 0x30,
+0x04, 0x04, 0x84, 0xa1, 0xae, 0xf6, 0xd7, 0x05, 0xa7, 0x35, 0x58, 0x22, 0x00, 0x01, 0xae, 0xb5,
+0x4e, 0x82, 0x00, 0x05, 0xe6, 0xe3, 0xe8, 0x04, 0xd5, 0x0d, 0xe6, 0xe5, 0xe9, 0x18, 0x01, 0xe3,
+0x00, 0x05, 0x58, 0xaf, 0x00, 0x02, 0x10, 0xa3, 0x00, 0x05, 0x4e, 0x82, 0x00, 0x11, 0x84, 0xa3,
+0xd7, 0x03, 0x84, 0xa5, 0xdf, 0x05, 0xa6, 0x75, 0x58, 0x00, 0x80, 0x10, 0xae, 0x35, 0x4e, 0x82,
+0x00, 0x07, 0x84, 0x41, 0x4c, 0x71, 0x00, 0x04, 0x84, 0xa3, 0xdf, 0x11, 0x46, 0xf0, 0x00, 0x0c,
+0x00, 0x17, 0x84, 0xc1, 0x45, 0xe0, 0x00, 0x10, 0x56, 0x30, 0x80, 0x04, 0x40, 0x5f, 0x04, 0x08,
+0x40, 0xa2, 0x8c, 0x1a, 0x40, 0xaf, 0x0c, 0x1b, 0x10, 0xa3, 0x00, 0x08, 0x50, 0x03, 0x00, 0x09,
+0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x83, 0x4c, 0x84, 0x48, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x86, 0xa4, 0xdd, 0x2f, 0xe6, 0xe4, 0xe9, 0x05, 0x4e, 0x83, 0x00, 0x26, 0x84, 0xa5, 0xdf, 0x23,
+0x46, 0xa0, 0x01, 0x02, 0x58, 0xa5, 0x06, 0xa4, 0x50, 0x03, 0x00, 0x11, 0x80, 0x3c, 0x44, 0x20,
+0x00, 0x20, 0x4b, 0xe0, 0x28, 0x01, 0x4e, 0x83, 0x00, 0x12, 0x84, 0xa5, 0xdf, 0x0f, 0x50, 0x1e,
+0x00, 0x10, 0x50, 0x03, 0x00, 0x31, 0x44, 0x20, 0x00, 0x10, 0x4b, 0xe0, 0x28, 0x01, 0x00, 0x33,
+0x00, 0x40, 0x9d, 0x5a, 0x10, 0x53, 0x00, 0x40, 0xd5, 0x08, 0x84, 0xa3, 0xdf, 0x04, 0x4e, 0x83,
+0x00, 0x05, 0xd5, 0x0c, 0x84, 0xa5, 0xdf, 0x0a, 0xf1, 0x01, 0x50, 0x03, 0x00, 0x41, 0x84, 0x46,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x50, 0x03, 0x00, 0x51, 0x84, 0x20,
+0x44, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x84, 0xa1,
+0xd7, 0x0c, 0x80, 0x09, 0x80, 0x46, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x83, 0x54, 0x46, 0xf0,
+0x00, 0x00, 0x58, 0xf7, 0x88, 0x30, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xee, 0x84, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x07, 0x08, 0x50, 0x60,
+0x00, 0x5b, 0x84, 0x20, 0x97, 0xd0, 0x50, 0x0f, 0x81, 0x60, 0x44, 0x20, 0x00, 0x10, 0xdd, 0x28,
+0x84, 0x20, 0x44, 0x20, 0x00, 0x50, 0x50, 0x0f, 0x81, 0x00, 0xdd, 0x28, 0x50, 0x9f, 0x81, 0x74,
+0x84, 0x20, 0x44, 0x20, 0x00, 0xff, 0x80, 0x1f, 0xdd, 0x28, 0x84, 0x20, 0x84, 0x42, 0x80, 0x09,
+0xdd, 0x28, 0x50, 0x13, 0x7f, 0xaa, 0x80, 0x09, 0x84, 0x42, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x86, 0xa4, 0xdd, 0x2f, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x87, 0x84, 0xc2, 0x4c, 0x70,
+0x00, 0x08, 0x84, 0x43, 0x4c, 0x71, 0x00, 0x05, 0x84, 0x65, 0x4c, 0x71, 0xc0, 0x26, 0x51, 0xcf,
+0x81, 0x50, 0x84, 0x20, 0x84, 0x48, 0x80, 0x1c, 0x50, 0xa3, 0x7f, 0xae, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x46, 0x90, 0x00, 0x02, 0x58, 0x94, 0x84, 0x14, 0x80, 0x0a,
+0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x83, 0x4c, 0x84, 0x48, 0x4b, 0xe0, 0x24, 0x01, 0x84, 0x81,
+0x4c, 0x02, 0x00, 0x09, 0x80, 0x0a, 0x80, 0x3c, 0x84, 0x48, 0x4b, 0xe0, 0x24, 0x01, 0x4e, 0x03,
+0x00, 0xcc, 0x84, 0xa1, 0xd7, 0x6a, 0x00, 0xa3, 0x7f, 0xa7, 0x00, 0x93, 0x7f, 0xa8, 0x41, 0xe5,
+0x20, 0x08, 0x50, 0xa3, 0x7f, 0xf6, 0x41, 0xcf, 0x24, 0x04, 0x80, 0x2a, 0x44, 0x20, 0x00, 0x10,
+0x46, 0x90, 0x01, 0x02, 0x58, 0x94, 0x86, 0xa4, 0x50, 0x0f, 0x81, 0x50, 0x4b, 0xe0, 0x24, 0x01,
+0x84, 0x20, 0x80, 0x0a, 0x44, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08,
+0xdd, 0x2f, 0x00, 0x0f, 0x81, 0x75, 0x84, 0x21, 0x54, 0x00, 0x00, 0x07, 0x51, 0xce, 0x00, 0x04,
+0x4c, 0x00, 0xc0, 0x18, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x84, 0x85, 0x44, 0x8c, 0x2f,
+0x10, 0xa4, 0x82, 0x3d, 0x50, 0x04, 0x80, 0xd0, 0x80, 0x7c, 0x50, 0x23, 0x7f, 0xa5, 0x50, 0x4f,
+0x81, 0x60, 0x80, 0xa1, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x80, 0x10, 0xdd, 0x2f, 0xd5, 0x21,
+0x84, 0x42, 0x4c, 0x01, 0x40, 0x1f, 0x46, 0xa0, 0x00, 0x0c, 0x58, 0xa5, 0x02, 0x84, 0x80, 0x7c,
+0x87, 0x86, 0x11, 0xc5, 0x02, 0x3d, 0x50, 0x05, 0x00, 0xd0, 0x8c, 0x2f, 0x50, 0x23, 0x7f, 0xa5,
+0x50, 0x4f, 0x81, 0x00, 0x9d, 0x4c, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x81, 0x54, 0xdd, 0x2f,
+0x50, 0x1f, 0x81, 0x00, 0x50, 0x0f, 0x81, 0x60, 0x44, 0x20, 0x00, 0x10, 0x4b, 0xe0, 0x24, 0x01,
+0x50, 0x0f, 0x81, 0x50, 0x50, 0x1f, 0x81, 0x60, 0x44, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x86, 0xd4, 0xdd, 0x2f, 0xc8, 0x60, 0xa7, 0x76, 0xa7, 0x37, 0x40, 0x32, 0xa0, 0x08,
+0x40, 0x31, 0x90, 0x04, 0x4e, 0x36, 0x00, 0x04, 0x84, 0x01, 0xd5, 0x57, 0x84, 0x23, 0x4c, 0x70,
+0xc0, 0x05, 0x4e, 0x83, 0x00, 0x06, 0xd5, 0x42, 0x84, 0x05, 0x4c, 0x70, 0x40, 0x40, 0x00, 0x5f,
+0x81, 0x75, 0x84, 0x42, 0x55, 0xe2, 0x80, 0x07, 0x80, 0x9f, 0x50, 0x03, 0x00, 0x08, 0x4d, 0xe1,
+0x40, 0x1e, 0xa6, 0x76, 0x01, 0xe3, 0x00, 0x07, 0x40, 0x90, 0xa0, 0x08, 0x40, 0x14, 0xf8, 0x04,
+0x94, 0xd3, 0x46, 0x20, 0x00, 0x0c, 0x58, 0x21, 0x03, 0x64, 0x50, 0x5f, 0x81, 0x70, 0x85, 0x20,
+0x14, 0x9f, 0x80, 0x5c, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x8e, 0x98, 0xdd, 0x2f, 0xf3, 0x5c,
+0x00, 0x4f, 0x81, 0x71, 0xae, 0xf7, 0xaf, 0x36, 0xd5, 0x0d, 0x80, 0x40, 0x46, 0x00, 0x00, 0x0c,
+0x58, 0x00, 0x03, 0x64, 0x50, 0x13, 0x7f, 0xd6, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x8c,
+0xdd, 0x2f, 0x4e, 0x83, 0x00, 0x0c, 0x84, 0x05, 0x4c, 0x70, 0x40, 0x09, 0x00, 0x5f, 0x81, 0x75,
+0x40, 0x22, 0x90, 0x09, 0x54, 0x21, 0x00, 0x03, 0xd5, 0x02, 0x84, 0x40, 0xa6, 0x77, 0x80, 0x67,
+0x80, 0x88, 0x80, 0x1f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x87, 0x2c, 0xdd, 0x2f, 0x84, 0x60,
+0x40, 0x01, 0x80, 0x06, 0xd5, 0x02, 0x84, 0x00, 0xed, 0x7c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xd4, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x84, 0x00, 0x34,
+0x82, 0x3d, 0x84, 0x45, 0x80, 0xc0, 0xf3, 0x85, 0x01, 0xc4, 0x82, 0x3c, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x8a, 0xe0, 0xdd, 0x2f, 0xc0, 0x69, 0x50, 0x13, 0x00, 0x09, 0x84, 0x48, 0x46, 0x80,
+0x01, 0x02, 0x58, 0x84, 0x06, 0xa4, 0x50, 0x04, 0x80, 0xc8, 0xdd, 0x28, 0x46, 0xf0, 0x00, 0x08,
+0x58, 0xf7, 0x89, 0x60, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x64, 0x46, 0xf0,
+0x00, 0x00, 0x58, 0xf7, 0x82, 0x78, 0xdd, 0x2f, 0x81, 0x40, 0xc0, 0x4f, 0xa1, 0xc2, 0xc7, 0x4d,
+0x84, 0xc0, 0x80, 0x26, 0x44, 0x20, 0x04, 0x00, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x87, 0x08, 0xdd, 0x2f, 0xf0, 0x05, 0x80, 0x66, 0x80, 0x86, 0x80, 0xa6, 0x80, 0x5c, 0x84, 0x26,
+0x51, 0xc3, 0x80, 0x0e, 0xb6, 0xdf, 0xf6, 0x81, 0x15, 0xcf, 0x80, 0x02, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x89, 0x04, 0xdd, 0x2f, 0x50, 0x14, 0x82, 0x3f, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x18,
+0xdd, 0x28, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x85, 0x74, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x1e,
+0xdd, 0x28, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x38, 0x84, 0x42, 0x50, 0x0f, 0x80, 0x24,
+0xdd, 0x28, 0x00, 0x2e, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x03, 0x40, 0x81, 0x20, 0x08, 0x40, 0x84,
+0x00, 0x04, 0x50, 0x1f, 0x80, 0x18, 0x84, 0x4e, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x86, 0xf0, 0xdd, 0x2f, 0x50, 0x14, 0x00, 0x12, 0x80, 0x0a, 0x96, 0x49, 0x80, 0x46, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x8f, 0xd4, 0xdd, 0x2f, 0xec, 0x2c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa0, 0xbc, 0xef, 0xf8, 0x50, 0x6f, 0x80, 0x04, 0x80, 0xe0, 0x84, 0x42, 0x81, 0x01,
+0x80, 0x06, 0x84, 0x20, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x84, 0x42,
+0x80, 0x06, 0x9c, 0x7d, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xa6, 0xb1,
+0x54, 0x01, 0x00, 0x80, 0xc0, 0x16, 0xa6, 0x30, 0x54, 0x10, 0x00, 0x0e, 0xc9, 0x04, 0x54, 0x31,
+0x00, 0x08, 0xcb, 0x0f, 0x54, 0x40, 0x00, 0x0f, 0x84, 0xa3, 0xdc, 0x0b, 0x54, 0x21, 0x00, 0x08,
+0xca, 0x08, 0x80, 0x07, 0x80, 0x28, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x8d, 0x30, 0xdd, 0x2f,
+0xec, 0x08, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x9c, 0x80, 0xc0,
+0x44, 0x00, 0x00, 0x10, 0xf3, 0x83, 0xf2, 0x88, 0xf4, 0x89, 0xf5, 0x8a, 0x4c, 0x30, 0x00, 0x0d,
+0x44, 0x20, 0x00, 0x18, 0x4c, 0x31, 0x00, 0x09, 0x41, 0xe0, 0x04, 0x08, 0x4c, 0x3f, 0x00, 0x05,
+0x84, 0x1f, 0x48, 0x00, 0x00, 0xa2, 0x8e, 0x28, 0x80, 0x01, 0x84, 0xe0, 0xf1, 0x81, 0xf7, 0x97,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x81, 0x9c, 0xdd, 0x2f, 0xf0, 0x82, 0xc8, 0x04, 0x84, 0x1e,
+0x48, 0x00, 0x00, 0x93, 0x50, 0x0f, 0x80, 0x54, 0x46, 0xa0, 0x01, 0x02, 0x58, 0xa5, 0x06, 0xa4,
+0x80, 0x26, 0x84, 0x48, 0x4b, 0xe0, 0x28, 0x01, 0xf2, 0x01, 0xf0, 0x02, 0x40, 0x91, 0x0c, 0x09,
+0x50, 0x13, 0x00, 0x08, 0x4b, 0xe0, 0x28, 0x01, 0x84, 0xe5, 0x54, 0x04, 0x80, 0xff, 0x80, 0x89,
+0x42, 0x40, 0x1c, 0x73, 0x40, 0x24, 0x8c, 0x08, 0x05, 0xef, 0x80, 0x02, 0x50, 0x31, 0x7f, 0xf8,
+0x52, 0x50, 0x00, 0x00, 0x54, 0x82, 0x80, 0xff, 0x55, 0xc2, 0x00, 0xff, 0x40, 0xaf, 0x0c, 0x00,
+0x50, 0x64, 0xff, 0xff, 0x14, 0x8f, 0x80, 0x07, 0x15, 0xcf, 0x80, 0x04, 0xf7, 0x85, 0x14, 0xaf,
+0x80, 0x0b, 0xf6, 0x86, 0xf6, 0x06, 0x04, 0xaf, 0x80, 0x0b, 0x05, 0xcf, 0x80, 0x04, 0x46, 0x90,
+0x01, 0x02, 0x58, 0x94, 0x86, 0xa4, 0x50, 0x8f, 0x80, 0x5c, 0x50, 0x7f, 0x80, 0x4c, 0xd5, 0x2f,
+0xa7, 0x0f, 0x9f, 0xb1, 0x40, 0x3e, 0x10, 0x03, 0xae, 0xcf, 0xdd, 0x29, 0x80, 0x2a, 0x84, 0x48,
+0x50, 0x0f, 0x80, 0x3c, 0xdd, 0x29, 0xf3, 0x03, 0x46, 0xf0, 0x00, 0x09, 0x04, 0x17, 0x80, 0xd8,
+0xf2, 0x08, 0x45, 0xe0, 0x00, 0x10, 0x50, 0x4f, 0x80, 0x44, 0x80, 0xa8, 0x50, 0x0f, 0x80, 0x34,
+0x15, 0xef, 0x80, 0x17, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x88, 0xac, 0xdd, 0x2f, 0x50, 0x1f,
+0x80, 0x44, 0x84, 0x48, 0x50, 0x0f, 0x80, 0x54, 0xdd, 0x29, 0x80, 0x0a, 0x80, 0x27, 0x84, 0x48,
+0xdd, 0x29, 0x50, 0x1e, 0x7f, 0xff, 0x55, 0xc0, 0x80, 0xff, 0x8f, 0x48, 0x84, 0x48, 0x50, 0x0f,
+0x80, 0x34, 0x50, 0x1f, 0x80, 0x54, 0x4e, 0x64, 0xff, 0xcd, 0x05, 0xef, 0x80, 0x04, 0xf4, 0x07,
+0xf1, 0x05, 0x40, 0x3f, 0x10, 0x00, 0x9e, 0x89, 0x96, 0x18, 0x84, 0xbf, 0xf2, 0x85, 0xf0, 0x84,
+0xda, 0xb2, 0xf2, 0x01, 0xf5, 0x0a, 0xb6, 0x45, 0xf2, 0x01, 0xf1, 0x02, 0xf0, 0x09, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xf0, 0x02, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x81, 0xb0, 0xdd, 0x2f, 0x84, 0x00, 0xec, 0x64, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xee, 0xe4, 0xb6, 0x5f, 0xf3, 0x81, 0x80, 0xc1, 0x46, 0x70, 0x01, 0x02,
+0x58, 0x73, 0x87, 0x08, 0x84, 0x20, 0x44, 0x20, 0x00, 0x60, 0x83, 0x80, 0x50, 0x0f, 0x80, 0x68,
+0x81, 0x44, 0x81, 0x25, 0x50, 0x8f, 0x80, 0xc8, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x60, 0x50, 0x0f, 0x80, 0x08, 0x4b, 0xe0, 0x1c, 0x01, 0x80, 0x08, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x40, 0x4b, 0xe0, 0x1c, 0x01, 0x5c, 0xf3, 0x00, 0x41, 0xe8, 0x0f, 0x80, 0x08, 0x80, 0x3c,
+0x80, 0x46, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x50, 0x6f, 0x80, 0xc8,
+0x51, 0xcf, 0x81, 0x08, 0x80, 0xe6, 0xd5, 0x0a, 0x80, 0x1c, 0x80, 0x26, 0x80, 0x48, 0x46, 0xf0,
+0x01, 0x03, 0x58, 0xf7, 0x8e, 0x98, 0xdd, 0x2f, 0xd5, 0xf2, 0xa6, 0x78, 0x56, 0x00, 0x80, 0x36,
+0x18, 0x03, 0x80, 0x01, 0x4c, 0x7e, 0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x68, 0x80, 0x07, 0x46, 0xf0,
+0x01, 0x03, 0x58, 0xf7, 0x8e, 0x54, 0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03, 0x58, 0x84, 0x0d, 0xc0,
+0x80, 0x07, 0x50, 0x1f, 0x80, 0xc8, 0x44, 0x20, 0x00, 0x40, 0x4b, 0xe0, 0x20, 0x01, 0xb4, 0x3f,
+0xf2, 0x01, 0x80, 0x07, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x07, 0x50, 0x1f, 0x81, 0x08, 0x46, 0xf0,
+0x01, 0x03, 0x58, 0xf7, 0x8d, 0x48, 0xdd, 0x2f, 0xa6, 0xf0, 0x56, 0x21, 0x80, 0x6a, 0x18, 0x23,
+0x00, 0x01, 0x4c, 0x6e, 0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x08, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x03,
+0x58, 0xf7, 0x8e, 0x54, 0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03, 0x58, 0x84, 0x0d, 0xc0, 0x80, 0x07,
+0x50, 0x1f, 0x80, 0xc8, 0x44, 0x20, 0x00, 0x40, 0x50, 0x6f, 0x81, 0x08, 0x4b, 0xe0, 0x20, 0x01,
+0x44, 0x20, 0x00, 0x10, 0x80, 0x07, 0x80, 0x26, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x07, 0x80, 0x26,
+0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7, 0x8d, 0x48, 0xdd, 0x2f, 0x46, 0x30, 0x01, 0x02, 0x58, 0x31,
+0x86, 0xa4, 0xe7, 0x31, 0xe9, 0x06, 0x80, 0x0a, 0x80, 0x26, 0x44, 0x20, 0x00, 0x10, 0xd5, 0x04,
+0x80, 0x0a, 0x80, 0x26, 0x80, 0x49, 0x4b, 0xe0, 0x0c, 0x01, 0xed, 0x1c, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xee, 0xcc, 0xb6, 0x5f, 0xf3, 0x81, 0x80, 0xc1,
+0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x87, 0x08, 0x84, 0x20, 0x44, 0x20, 0x00, 0x68, 0x83, 0x80,
+0x50, 0x0f, 0x80, 0x70, 0x81, 0x44, 0x81, 0x25, 0x50, 0x8f, 0x80, 0xdc, 0x4b, 0xe0, 0x1c, 0x01,
+0x84, 0x20, 0x44, 0x20, 0x00, 0x68, 0x50, 0x0f, 0x80, 0x08, 0x4b, 0xe0, 0x1c, 0x01, 0x80, 0x08,
+0x84, 0x20, 0x44, 0x20, 0x00, 0x40, 0x4b, 0xe0, 0x1c, 0x01, 0x5c, 0xf3, 0x00, 0x41, 0xe8, 0x0f,
+0x80, 0x08, 0x80, 0x3c, 0x80, 0x46, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f,
+0x50, 0x6f, 0x80, 0xdc, 0x51, 0xcf, 0x81, 0x1c, 0x80, 0xe6, 0xd5, 0x0a, 0x80, 0x1c, 0x80, 0x26,
+0x80, 0x48, 0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7, 0x81, 0xbc, 0xdd, 0x2f, 0xd5, 0xf2, 0xa6, 0x78,
+0x56, 0x00, 0x80, 0x36, 0x18, 0x03, 0x80, 0x01, 0x4c, 0x7e, 0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x70,
+0x80, 0x07, 0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7, 0x81, 0x78, 0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03,
+0x58, 0x84, 0x00, 0xe4, 0x80, 0x07, 0x50, 0x1f, 0x80, 0xdc, 0x44, 0x20, 0x00, 0x40, 0x4b, 0xe0,
+0x20, 0x01, 0xb4, 0x3f, 0xf2, 0x01, 0x80, 0x07, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x07, 0x50, 0x1f,
+0x81, 0x1c, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x8f, 0xd8, 0xdd, 0x2f, 0xa6, 0xf0, 0x56, 0x21,
+0x80, 0x6a, 0x18, 0x23, 0x00, 0x01, 0x4c, 0x6e, 0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x08, 0x80, 0x07,
+0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7, 0x81, 0x78, 0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03, 0x58, 0x84,
+0x00, 0xe4, 0x80, 0x07, 0x50, 0x1f, 0x80, 0xdc, 0x44, 0x20, 0x00, 0x40, 0x50, 0x6f, 0x81, 0x1c,
+0x4b, 0xe0, 0x20, 0x01, 0x44, 0x20, 0x00, 0x14, 0x80, 0x07, 0x80, 0x26, 0x4b, 0xe0, 0x20, 0x01,
+0x80, 0x07, 0x80, 0x26, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x8f, 0xd8, 0xdd, 0x2f, 0x46, 0x30,
+0x01, 0x02, 0x58, 0x31, 0x86, 0xa4, 0xe7, 0x35, 0xe9, 0x06, 0x80, 0x0a, 0x80, 0x26, 0x44, 0x20,
+0x00, 0x14, 0xd5, 0x04, 0x80, 0x0a, 0x80, 0x26, 0x80, 0x49, 0x4b, 0xe0, 0x0c, 0x01, 0xed, 0x34,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x04, 0x00, 0x04, 0x10, 0x00, 0x20,
+0x54, 0x10, 0x81, 0x00, 0xc1, 0x0c, 0x80, 0x60, 0x46, 0x00, 0x04, 0x00, 0x44, 0x21, 0x00, 0x00,
+0x58, 0x00, 0x02, 0x80, 0x14, 0x21, 0x80, 0x9f, 0x84, 0x20, 0xd5, 0x08, 0x80, 0x80, 0x46, 0x00,
+0x04, 0x00, 0x14, 0x12, 0x00, 0x9f, 0x58, 0x00, 0x02, 0x80, 0xb6, 0x20, 0x46, 0x30, 0x04, 0x00,
+0x58, 0x31, 0x82, 0x70, 0xb4, 0x23, 0x40, 0x50, 0xa0, 0x09, 0x40, 0x52, 0xa0, 0x08, 0xb6, 0xa3,
+0x46, 0x50, 0x04, 0x00, 0xb4, 0x83, 0x58, 0x22, 0x00, 0x80, 0xb6, 0x43, 0x04, 0x02, 0x80, 0x96,
+0x58, 0x10, 0x00, 0x03, 0x14, 0x12, 0x80, 0x96, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x04, 0x00,
+0x04, 0x20, 0x80, 0x97, 0x96, 0x14, 0xc0, 0x45, 0x80, 0x81, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10,
+0x82, 0x84, 0x04, 0x32, 0x00, 0x20, 0x04, 0x40, 0x80, 0x98, 0x54, 0x31, 0x81, 0x00, 0x58, 0x52,
+0x00, 0x40, 0x14, 0x50, 0x80, 0x98, 0xc3, 0x1d, 0x46, 0x30, 0x04, 0x00, 0x44, 0x51, 0x00, 0x00,
+0x80, 0x03, 0x14, 0x51, 0x80, 0x9f, 0x84, 0x60, 0x14, 0x30, 0x00, 0xa0, 0x46, 0x00, 0x04, 0x00,
+0x58, 0x00, 0x02, 0x70, 0xb4, 0x60, 0x92, 0x68, 0x40, 0x31, 0xa0, 0x08, 0xb6, 0x60, 0x58, 0x42,
+0x00, 0xc0, 0xb4, 0x60, 0x58, 0x51, 0x80, 0x80, 0xb6, 0xa0, 0x14, 0x40, 0x80, 0x98, 0xd5, 0x19,
+0x46, 0x40, 0x04, 0x00, 0x80, 0x04, 0x14, 0x32, 0x00, 0x9f, 0x14, 0x30, 0x00, 0xa0, 0x46, 0x00,
+0x04, 0x00, 0x58, 0x00, 0x02, 0x70, 0xb4, 0x60, 0x42, 0x52, 0x9c, 0x09, 0x92, 0x68, 0x40, 0x31,
+0xa0, 0x08, 0xb6, 0x60, 0xb4, 0x60, 0x58, 0x41, 0x80, 0x80, 0xb6, 0x80, 0x14, 0x50, 0x80, 0x98,
+0x54, 0x11, 0x10, 0x00, 0xc1, 0x06, 0x84, 0x61, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x37, 0x82, 0x44,
+0x46, 0x00, 0x04, 0x00, 0x14, 0x20, 0x00, 0x97, 0xdd, 0x9e, 0x92, 0x00, 0xc8, 0x0a, 0x46, 0xf0,
+0x00, 0x0c, 0x00, 0x07, 0x80, 0xe6, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x27, 0x80, 0xe8, 0xd5, 0x1c,
+0x84, 0xa1, 0xd8, 0x10, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x47, 0x80, 0xe6, 0x46, 0xf0, 0x00, 0x0c,
+0x00, 0x37, 0x80, 0xe8, 0x40, 0x02, 0x10, 0x09, 0x42, 0x21, 0x98, 0x0b, 0x54, 0x00, 0x00, 0x03,
+0xd5, 0x21, 0x84, 0xa2, 0xd8, 0x0e, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x07, 0x80, 0xe7, 0x46, 0xf0,
+0x00, 0x0c, 0x00, 0x27, 0x80, 0xe9, 0x54, 0x00, 0x00, 0x03, 0x42, 0x21, 0x08, 0x0b, 0xd5, 0x12,
+0x84, 0x83, 0x4c, 0x02, 0x40, 0x31, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x57, 0x80, 0xe7, 0x46, 0xf0,
+0x00, 0x0c, 0x00, 0x27, 0x80, 0xe9, 0x40, 0x02, 0x90, 0x09, 0x42, 0x21, 0x18, 0x0b, 0x40, 0x00,
+0x10, 0x02, 0x84, 0xa1, 0xd8, 0x22, 0x46, 0x50, 0x04, 0x00, 0x80, 0x25, 0x44, 0x41, 0x00, 0x00,
+0x84, 0x60, 0x14, 0x42, 0x80, 0x9f, 0x14, 0x30, 0x80, 0xa0, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10,
+0x82, 0x70, 0xb4, 0xa1, 0x40, 0x32, 0xa0, 0x09, 0x40, 0x31, 0xa0, 0x08, 0xb6, 0x61, 0x4c, 0x20,
+0x40, 0x06, 0xb4, 0x01, 0x58, 0x00, 0x00, 0x82, 0xd5, 0x04, 0xb4, 0x41, 0x58, 0x01, 0x00, 0x80,
+0xb6, 0x01, 0xd5, 0x44, 0x84, 0x00, 0x80, 0x40, 0x9e, 0x42, 0x96, 0x90, 0xe6, 0x22, 0xe8, 0x21,
+0x46, 0x30, 0x04, 0x00, 0x46, 0x00, 0x30, 0x70, 0x80, 0xa3, 0x58, 0x00, 0x03, 0x07, 0x14, 0x01,
+0x80, 0x9d, 0x14, 0x02, 0x80, 0x9e, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x70, 0xb4, 0x80,
+0x40, 0x52, 0x20, 0x09, 0x40, 0x52, 0xa0, 0x08, 0x84, 0x61, 0xb6, 0xa0, 0x4c, 0x21, 0xc0, 0x06,
+0xb4, 0x40, 0x58, 0x11, 0x00, 0x86, 0xd5, 0x21, 0xb4, 0x80, 0x58, 0x12, 0x00, 0x84, 0xd5, 0x1d,
+0x46, 0x10, 0x04, 0x00, 0x80, 0x01, 0x84, 0xa0, 0x14, 0x50, 0x80, 0x9f, 0x14, 0x50, 0x00, 0xa0,
+0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x70, 0xb4, 0x80, 0x40, 0x52, 0x20, 0x09, 0x40, 0x52,
+0xa0, 0x08, 0x84, 0x21, 0xb6, 0xa0, 0x4c, 0x20, 0xc0, 0x06, 0xb4, 0x40, 0x58, 0x11, 0x00, 0x82,
+0xd5, 0x04, 0xb4, 0x80, 0x58, 0x12, 0x00, 0x80, 0xb6, 0x20, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xe4, 0x96, 0x49, 0x40, 0x20, 0x88, 0x09, 0xf2, 0x83, 0x4e, 0x12, 0x01, 0xc4, 0x54, 0x10,
+0x80, 0x03, 0x4e, 0x13, 0x01, 0xc0, 0x46, 0x30, 0xa0, 0xa0, 0x46, 0x90, 0x04, 0x00, 0x58, 0x94,
+0x82, 0x88, 0x46, 0xa0, 0x04, 0x00, 0x58, 0x31, 0x80, 0x01, 0x14, 0x9f, 0x80, 0x02, 0x83, 0x80,
+0xf3, 0x81, 0x50, 0x8f, 0x80, 0x16, 0x81, 0x21, 0x48, 0x00, 0x01, 0xa7, 0xb4, 0xbc, 0xb4, 0xfc,
+0xb4, 0xdc, 0x40, 0x43, 0xa0, 0x09, 0x40, 0x13, 0x40, 0x09, 0x96, 0x48, 0x44, 0x00, 0x00, 0x52,
+0x97, 0xa8, 0x97, 0xe0, 0x4c, 0x10, 0x01, 0x6f, 0x5c, 0xf0, 0x80, 0x53, 0xe8, 0x0a, 0x45, 0xe0,
+0x00, 0x50, 0x4c, 0x1f, 0x00, 0x12, 0x9e, 0x81, 0x4c, 0x11, 0x41, 0x95, 0x48, 0x00, 0x01, 0x5a,
+0x9c, 0x02, 0x4c, 0x10, 0x01, 0x76, 0xe2, 0x20, 0x4e, 0xf3, 0x01, 0x68, 0x9c, 0xc1, 0x4c, 0x11,
+0xc1, 0x8a, 0x48, 0x00, 0x01, 0x7f, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x77, 0x80, 0xe0, 0x4e, 0x72,
+0x01, 0x79, 0x9f, 0x79, 0x97, 0x28, 0xe6, 0x86, 0x4e, 0xf2, 0x00, 0xaa, 0x44, 0x50, 0x00, 0x10,
+0xd6, 0x21, 0xe6, 0xd1, 0xe8, 0x06, 0xc6, 0x10, 0x84, 0xa8, 0x4c, 0x62, 0xc0, 0xa1, 0xd5, 0x66,
+0x44, 0x50, 0x00, 0x60, 0xd6, 0x13, 0x40, 0x5f, 0x04, 0x08, 0xd6, 0x12, 0x44, 0x50, 0x00, 0x20,
+0x4c, 0x62, 0xc0, 0x96, 0xd5, 0x03, 0x80, 0x06, 0xd5, 0x02, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x83, 0xac, 0xdd, 0x2f, 0x48, 0x00, 0x00, 0x8b, 0x84, 0x02, 0xd5, 0xf8, 0x84, 0x03,
+0xd5, 0xf6, 0x84, 0xa4, 0xdf, 0x1a, 0x46, 0x50, 0x04, 0x00, 0x80, 0x25, 0x44, 0x41, 0x00, 0x00,
+0x84, 0x00, 0x14, 0x42, 0x80, 0x9f, 0x14, 0x00, 0x80, 0xa0, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10,
+0x82, 0x70, 0xb4, 0x41, 0x41, 0xe1, 0x20, 0x09, 0x41, 0xef, 0x20, 0x08, 0x15, 0xe0, 0x80, 0x00,
+0xb4, 0xa1, 0x58, 0x22, 0x80, 0x80, 0xd5, 0x1a, 0x84, 0xa5, 0xdf, 0x19, 0x46, 0x20, 0x04, 0x00,
+0x80, 0x22, 0x45, 0xe1, 0x00, 0x00, 0x84, 0xa0, 0x15, 0xe1, 0x00, 0x9f, 0x14, 0x50, 0x80, 0xa0,
+0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x70, 0xb4, 0x81, 0x40, 0x02, 0x20, 0x09, 0x40, 0x00,
+0x20, 0x08, 0xb6, 0x01, 0xb4, 0x41, 0x58, 0x21, 0x00, 0x82, 0xb6, 0x41, 0x46, 0x50, 0x04, 0x00,
+0x47, 0xe0, 0x06, 0x40, 0x80, 0x65, 0x44, 0x10, 0x01, 0x90, 0x59, 0xef, 0x00, 0x64, 0x15, 0xe2,
+0x80, 0x9f, 0x14, 0x11, 0x80, 0xa0, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x70, 0xb4, 0x81,
+0x40, 0x22, 0x20, 0x09, 0x40, 0x21, 0x20, 0x08, 0xd5, 0x35, 0x84, 0xa2, 0xdf, 0x1b, 0x46, 0x40,
+0x04, 0x00, 0x46, 0x20, 0x30, 0x70, 0x83, 0xc4, 0x58, 0x21, 0x03, 0x20, 0x84, 0x21, 0x14, 0x22,
+0x00, 0x9f, 0x14, 0x1f, 0x00, 0xa0, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x70, 0xb4, 0xa1,
+0x40, 0x02, 0xa0, 0x09, 0x40, 0x00, 0x20, 0x08, 0xb6, 0x01, 0xb4, 0x81, 0x58, 0x22, 0x00, 0x80,
+0xd5, 0x1d, 0x84, 0xa3, 0xdf, 0x1c, 0x46, 0x40, 0x04, 0x00, 0x46, 0x20, 0x06, 0x40, 0x83, 0xc4,
+0x58, 0x21, 0x00, 0x64, 0x44, 0x10, 0x01, 0x90, 0x14, 0x22, 0x00, 0x9f, 0x14, 0x1f, 0x00, 0xa0,
+0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x70, 0xb4, 0xa1, 0x40, 0x22, 0xa0, 0x09, 0x40, 0x21,
+0x20, 0x08, 0xb6, 0x41, 0xb4, 0x01, 0x58, 0x20, 0x00, 0x81, 0xb6, 0x41, 0x9f, 0x7f, 0x96, 0x68,
+0xe6, 0x23, 0xe9, 0x04, 0x84, 0xac, 0x4c, 0x72, 0xc0, 0xc5, 0x84, 0xa3, 0xd6, 0x78, 0xe6, 0xc4,
+0xe8, 0x06, 0xc6, 0x0c, 0x84, 0xa1, 0x4c, 0x62, 0xc0, 0xbd, 0xd5, 0x14, 0x84, 0xae, 0xd6, 0x12,
+0x44, 0x50, 0x00, 0x62, 0x4c, 0x62, 0xc0, 0xb6, 0xd5, 0x4c, 0x46, 0x50, 0x04, 0x00, 0x46, 0x30,
+0xa1, 0x40, 0x80, 0x05, 0x58, 0x31, 0x80, 0x01, 0x14, 0x32, 0x80, 0x9f, 0x14, 0x60, 0x00, 0xa0,
+0xd5, 0x31, 0x84, 0xa7, 0xdf, 0x1c, 0x46, 0x10, 0x04, 0x00, 0x83, 0xc1, 0x46, 0x40, 0x10, 0x00,
+0x58, 0x42, 0x00, 0x01, 0x44, 0x21, 0x75, 0x30, 0x14, 0x20, 0x80, 0x9f, 0x14, 0x4f, 0x00, 0xa0,
+0x46, 0x40, 0x04, 0x00, 0x58, 0x42, 0x02, 0x70, 0xb4, 0xa4, 0x40, 0x02, 0xa0, 0x09, 0x40, 0x00,
+0x20, 0x08, 0xb6, 0x04, 0xb4, 0x44, 0x58, 0x11, 0x00, 0x80, 0xb6, 0x24, 0x50, 0x53, 0xff, 0xf8,
+0x96, 0x28, 0xe6, 0x02, 0x4e, 0xf2, 0x00, 0x86, 0x46, 0x10, 0x04, 0x00, 0x83, 0xc1, 0x46, 0x40,
+0x10, 0x00, 0x58, 0x42, 0x00, 0x01, 0x44, 0x31, 0x75, 0x30, 0x14, 0x30, 0x80, 0x9f, 0x14, 0x4f,
+0x00, 0xa0, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x70, 0x05, 0xe0, 0x00, 0x00, 0x40, 0x5f,
+0x20, 0x09, 0x40, 0x52, 0xa0, 0x08, 0xb6, 0xa0, 0xb4, 0x40, 0x58, 0x11, 0x00, 0x80, 0xd5, 0x37,
+0xe6, 0x22, 0xe8, 0x03, 0xf0, 0x01, 0xd5, 0x07, 0x84, 0xac, 0xdf, 0x63, 0x46, 0x00, 0xa0, 0xa2,
+0x58, 0x00, 0x0e, 0xe0, 0x14, 0x05, 0x00, 0xa1, 0x87, 0xc0, 0xf4, 0x02, 0x46, 0x00, 0x04, 0x00,
+0x15, 0xe2, 0x00, 0x00, 0x58, 0x00, 0x02, 0x70, 0xb4, 0xa0, 0x44, 0x2f, 0x00, 0xff, 0x40, 0x32,
+0x88, 0x02, 0xb6, 0x60, 0xb4, 0x20, 0x42, 0x10, 0xbc, 0x08, 0xd5, 0x19, 0xe6, 0x22, 0xe9, 0x03,
+0x84, 0xac, 0xdf, 0x47, 0xf0, 0x01, 0x87, 0xc0, 0x14, 0x05, 0x00, 0xa1, 0x46, 0x00, 0x04, 0x00,
+0xf4, 0x02, 0x58, 0x00, 0x02, 0x70, 0x15, 0xe2, 0x00, 0x00, 0x44, 0x3f, 0x00, 0xff, 0xb4, 0x40,
+0x40, 0x51, 0x0c, 0x02, 0xb6, 0xa0, 0xb4, 0x20, 0x42, 0x10, 0xbc, 0x08, 0xb6, 0x20, 0xd5, 0x31,
+0x46, 0xf0, 0x00, 0x0c, 0x10, 0x67, 0x80, 0xe2, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x77, 0x80, 0xe1,
+0xd5, 0x28, 0x40, 0x23, 0x20, 0x08, 0x40, 0x31, 0x1c, 0x04, 0x80, 0x28, 0x84, 0x42, 0x46, 0x00,
+0x00, 0x0c, 0x58, 0x00, 0x00, 0xe4, 0xd5, 0x16, 0x41, 0xe3, 0x20, 0x08, 0x40, 0x3f, 0x1c, 0x04,
+0x80, 0x28, 0x84, 0x42, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x00, 0xe6, 0xd5, 0x0b, 0x40, 0x43,
+0x20, 0x08, 0x40, 0x32, 0x1c, 0x04, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x00, 0xe8, 0x80, 0x28,
+0x84, 0x42, 0x12, 0x3f, 0x80, 0x0b, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f,
+0x8d, 0x21, 0x51, 0xce, 0x00, 0x04, 0xf3, 0x03, 0xe3, 0x23, 0x4e, 0xf3, 0xfe, 0x59, 0x84, 0x00,
+0xd5, 0x02, 0x84, 0x01, 0xec, 0x1c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x96, 0x49, 0x54, 0x20,
+0x80, 0x03, 0x40, 0x30, 0x88, 0x09, 0xca, 0x10, 0x5c, 0xf0, 0x80, 0xc8, 0xe8, 0x0d, 0x80, 0x20,
+0xb4, 0x40, 0x84, 0x01, 0xd5, 0x04, 0xb4, 0x81, 0x9c, 0x01, 0xab, 0x11, 0x9c, 0x4c, 0xe2, 0x03,
+0xe9, 0xfb, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0x3c,
+0xa4, 0x88, 0x84, 0xa8, 0xda, 0x16, 0x80, 0x80, 0xa2, 0xa1, 0xb4, 0xa4, 0x5c, 0xf2, 0x80, 0x40,
+0xe8, 0x10, 0x84, 0x60, 0xd5, 0x04, 0xa3, 0x91, 0x80, 0x64, 0xb6, 0xc0, 0x40, 0x21, 0x20, 0x08,
+0x92, 0x48, 0x9c, 0x04, 0x9d, 0x19, 0xdb, 0xf8, 0x94, 0x22, 0xac, 0x08, 0x84, 0x00, 0xd5, 0x02,
+0x84, 0x01, 0x3a, 0x6f, 0x98, 0x04, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x94, 0xb5, 0x20,
+0x80, 0xc0, 0x84, 0x01, 0x4c, 0x90, 0x40, 0x7f, 0x51, 0xe3, 0x00, 0x08, 0x51, 0xc3, 0x00, 0x0c,
+0x50, 0xa3, 0x00, 0x20, 0x50, 0x83, 0x00, 0x04, 0xb5, 0x08, 0xb4, 0xbe, 0xb4, 0x9c, 0xb4, 0x6a,
+0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xf0, 0x50, 0x13, 0x00, 0x14, 0x84, 0x46, 0x50, 0x0f,
+0x80, 0x60, 0x01, 0xc3, 0x00, 0x6c, 0x00, 0xa3, 0x00, 0x6d, 0xf3, 0x83, 0xf4, 0x82, 0xf5, 0x81,
+0xdd, 0x27, 0x50, 0x13, 0x00, 0x1a, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x58, 0xdd, 0x27, 0x50, 0x13,
+0x00, 0x24, 0x44, 0x20, 0x00, 0x40, 0x50, 0x0f, 0x80, 0x10, 0xdd, 0x27, 0x50, 0x13, 0x00, 0x64,
+0x50, 0x0f, 0x80, 0x50, 0x84, 0x48, 0xdd, 0x27, 0x54, 0x04, 0x00, 0x01, 0xf3, 0x03, 0xf4, 0x02,
+0xf5, 0x01, 0xc0, 0x05, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x97, 0x84, 0xd1, 0x54, 0x84, 0x00, 0x02,
+0x4e, 0x82, 0x00, 0x0b, 0x84, 0xc1, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x67, 0x84, 0xd3, 0x46, 0xf0,
+0x00, 0x0c, 0x10, 0x67, 0x84, 0xd2, 0x46, 0x60, 0x00, 0x0c, 0x58, 0x63, 0x02, 0x84, 0x14, 0x53,
+0x00, 0x95, 0x14, 0x43, 0x00, 0x96, 0x10, 0x33, 0x02, 0x3e, 0x11, 0xc3, 0x02, 0x3c, 0x10, 0xa3,
+0x02, 0x3d, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xf0, 0x50, 0x1f, 0x80, 0x60, 0x84, 0x46,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x05, 0x74, 0xdd, 0x27, 0x50, 0x1f, 0x80, 0x58, 0x84, 0x46,
+0x50, 0x03, 0x02, 0x3f, 0xdd, 0x27, 0x50, 0x1f, 0x80, 0x10, 0x44, 0x20, 0x00, 0x40, 0x50, 0x03,
+0x00, 0xd0, 0xdd, 0x27, 0x50, 0x1f, 0x80, 0x50, 0x84, 0x48, 0x50, 0x03, 0x00, 0xc8, 0xdd, 0x27,
+0x84, 0x00, 0x50, 0x13, 0x00, 0xd0, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x86, 0xa0, 0xdd, 0x2f,
+0x84, 0x00, 0xec, 0x6c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0xbc,
+0x96, 0x49, 0x54, 0x70, 0x80, 0x07, 0x40, 0xa0, 0x88, 0x09, 0xcf, 0x2e, 0x9d, 0x84, 0x46, 0x90,
+0x00, 0x05, 0x58, 0x94, 0x86, 0xf4, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x05, 0xb4, 0xd5, 0x1f,
+0xb4, 0x20, 0x40, 0x00, 0xa0, 0x08, 0x92, 0x08, 0x40, 0x20, 0xf8, 0x09, 0x4e, 0x14, 0x00, 0x0a,
+0x40, 0x00, 0xc0, 0x09, 0x84, 0x40, 0x96, 0x48, 0x96, 0x00, 0x4b, 0xe0, 0x20, 0x01, 0xd5, 0x0a,
+0x84, 0xa1, 0xda, 0x09, 0x40, 0x40, 0xc0, 0x09, 0x96, 0x20, 0x96, 0x48, 0x84, 0x40, 0x4b, 0xe0,
+0x24, 0x01, 0xc8, 0x0a, 0xb4, 0xa0, 0x9d, 0xfa, 0xb6, 0xa6, 0x8c, 0xc8, 0x9e, 0x34, 0xe2, 0xea,
+0xe9, 0xe0, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xfc, 0x96, 0x49, 0x54, 0x70, 0x80, 0x07, 0x41, 0xc0, 0x88, 0x09,
+0xcf, 0x35, 0x9d, 0x84, 0x46, 0xa0, 0x00, 0x05, 0x58, 0xa5, 0x07, 0x68, 0x46, 0x90, 0x00, 0x05,
+0x58, 0x94, 0x86, 0x6c, 0xd5, 0x26, 0xb4, 0x20, 0x9d, 0xfa, 0x40, 0x00, 0xa0, 0x08, 0x92, 0x08,
+0x40, 0x80, 0xf8, 0x09, 0x4e, 0x14, 0x00, 0x0c, 0x40, 0x00, 0xc0, 0x09, 0xb4, 0x46, 0x96, 0x00,
+0x96, 0x48, 0x4b, 0xe0, 0x24, 0x01, 0x84, 0xa1, 0xd0, 0x13, 0xd5, 0x18, 0x84, 0xa1, 0x4c, 0x82,
+0xc0, 0x0c, 0x40, 0x50, 0xc0, 0x09, 0xb4, 0x46, 0x96, 0x28, 0x96, 0x48, 0x4b, 0xe0, 0x28, 0x01,
+0x4c, 0x04, 0x00, 0x07, 0xd5, 0x0b, 0x05, 0xe3, 0x00, 0x00, 0x15, 0xe0, 0x00, 0x00, 0x8c, 0xc8,
+0x9e, 0x34, 0xe2, 0xfc, 0xe9, 0xd9, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xec, 0x04, 0x3a, 0x6f,
+0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x85, 0x0c, 0x96, 0xc9, 0x40, 0x21,
+0xa1, 0x17, 0x40, 0x11, 0x88, 0x09, 0xf1, 0x81, 0x4e, 0x83, 0x00, 0x6a, 0x50, 0x70, 0x00, 0x08,
+0x9d, 0x84, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce, 0x06, 0x6c, 0xd5, 0x5a, 0xb4, 0x20, 0x40, 0x00,
+0xa0, 0x08, 0x92, 0x08, 0x8d, 0x03, 0x40, 0x20, 0xf8, 0x09, 0x4e, 0x14, 0x00, 0x20, 0x40, 0x90,
+0xc0, 0x09, 0x54, 0x94, 0x80, 0xff, 0x54, 0xa0, 0x80, 0xff, 0x80, 0x2a, 0x84, 0x40, 0x80, 0x09,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0x80, 0x40, 0x80, 0x2a, 0x80, 0x09,
+0xca, 0x46, 0xb4, 0x66, 0xb4, 0x82, 0x05, 0xe3, 0x80, 0x00, 0x40, 0x21, 0x8c, 0x05, 0x40, 0x51,
+0x10, 0x02, 0x40, 0x22, 0xf8, 0x04, 0xdd, 0x3c, 0xd5, 0x23, 0x84, 0xa1, 0xda, 0x24, 0x40, 0x00,
+0xc0, 0x09, 0x54, 0x90, 0x00, 0xff, 0x54, 0xa0, 0x80, 0xff, 0x80, 0x2a, 0x84, 0x40, 0x80, 0x09,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0x80, 0x40, 0x80, 0x2a, 0x80, 0x09,
+0xca, 0x26, 0xb4, 0xa6, 0xb4, 0x82, 0xb4, 0x67, 0x40, 0x22, 0x94, 0x05, 0x41, 0xe1, 0x10, 0x02,
+0x40, 0x2f, 0x0c, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0x68, 0xdd, 0x2f, 0x84, 0xa1,
+0xd0, 0x0d, 0xd5, 0x15, 0xb4, 0x60, 0xb4, 0x26, 0xb4, 0x47, 0x40, 0x50, 0x84, 0x05, 0x40, 0x41,
+0x94, 0x02, 0x41, 0xe2, 0x08, 0x04, 0x15, 0xe0, 0x00, 0x00, 0x8c, 0xcc, 0x8c, 0xec, 0x05, 0xef,
+0x80, 0x01, 0x9e, 0x34, 0xe3, 0x1e, 0xe9, 0xa3, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xec, 0x0c,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x04, 0x80,
+0x80, 0x04, 0x80, 0xc1, 0x40, 0x14, 0x50, 0x09, 0x81, 0x20, 0x54, 0x10, 0x80, 0x7f, 0x44, 0x00,
+0x00, 0x14, 0x84, 0xe4, 0x4c, 0x10, 0x00, 0x6e, 0xe4, 0x35, 0xe8, 0x17, 0x84, 0xaa, 0xd1, 0x41,
+0xe4, 0x2b, 0xe8, 0x0a, 0x84, 0xa8, 0xd1, 0x2b, 0xe4, 0x29, 0xe8, 0x32, 0x84, 0xa1, 0x4c, 0x12,
+0xc0, 0xcf, 0x48, 0x00, 0x00, 0xb8, 0x84, 0x0c, 0x4c, 0x10, 0x00, 0x3f, 0xe0, 0x20, 0xe9, 0x45,
+0x9d, 0x44, 0x4c, 0x12, 0xc0, 0xc5, 0xd5, 0x4d, 0x44, 0x50, 0x00, 0x1c, 0x4c, 0x12, 0x80, 0x8b,
+0xe4, 0x3d, 0xe8, 0x0a, 0x9c, 0x82, 0x4c, 0x11, 0x00, 0xbd, 0xe0, 0x22, 0xe9, 0x52, 0x9d, 0x44,
+0x4c, 0x12, 0xc0, 0xb6, 0xd5, 0x56, 0x9c, 0xaa, 0x4c, 0x11, 0x00, 0x8d, 0xe0, 0x22, 0x4e, 0xf3,
+0x00, 0x82, 0x9d, 0x51, 0x4c, 0x12, 0xc0, 0xac, 0x48, 0x00, 0x00, 0x8d, 0xa0, 0x32, 0xa4, 0x76,
+0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x88, 0x8c, 0xdd, 0x2f, 0x48, 0x00, 0x00, 0xa4, 0xa0, 0x32,
+0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8b, 0x04, 0xdd, 0x2f, 0x48, 0x00, 0x00, 0x9b,
+0xa0, 0x32, 0xa4, 0x76, 0x54, 0x74, 0x3f, 0xff, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8a, 0x0c,
+0xdd, 0x2f, 0x48, 0x00, 0x00, 0x90, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x8a, 0x80, 0xdd, 0x2f, 0x48, 0x00, 0x00, 0x87, 0xa0, 0x32, 0x50, 0x13, 0x00, 0x0c, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x88, 0xbc, 0xdd, 0x2f, 0xa5, 0xf6, 0x54, 0x73, 0xbf, 0xff, 0xd5, 0x7a,
+0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x84, 0xec, 0xdd, 0x2f, 0xd5, 0x72,
+0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x89, 0x0c, 0xdd, 0x2f, 0xd5, 0x6a,
+0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x88, 0xf8, 0xdd, 0x2f, 0xd5, 0x62,
+0xa1, 0x32, 0x84, 0x21, 0xa2, 0xa1, 0xb4, 0x64, 0x4c, 0x20, 0xc0, 0x07, 0x46, 0xf0, 0x00, 0x0c,
+0x10, 0x37, 0x84, 0xd0, 0xd5, 0x54, 0x84, 0xa3, 0xda, 0x52, 0x96, 0xd8, 0x46, 0xf0, 0x00, 0x0c,
+0x10, 0x37, 0x84, 0xe8, 0x46, 0x20, 0x04, 0x10, 0x04, 0x01, 0x02, 0x03, 0x42, 0x20, 0x60, 0x09,
+0x42, 0x21, 0x64, 0x09, 0xcb, 0x06, 0x46, 0x00, 0x30, 0x00, 0x46, 0x10, 0x04, 0x10, 0xd5, 0x05,
+0x46, 0x00, 0x10, 0x00, 0x46, 0x10, 0x04, 0x10, 0x40, 0x51, 0x00, 0x04, 0x14, 0x50, 0x82, 0x03,
+0xd5, 0x36, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x83, 0x08, 0xdd, 0x2f,
+0xd5, 0x31, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x83, 0xec, 0xdd, 0x2f,
+0xd5, 0x29, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7, 0x80, 0x90, 0xdd, 0x2f,
+0xd5, 0x21, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x86, 0x6c, 0xdd, 0x2f,
+0xd5, 0x19, 0x03, 0xe3, 0x00, 0x06, 0xa0, 0x72, 0x5c, 0xff, 0x00, 0x04, 0xe9, 0x12, 0xb4, 0x61,
+0x84, 0xa1, 0xdb, 0x0d, 0x9d, 0x0c, 0xb4, 0x44, 0x46, 0x00, 0x00, 0x0c, 0x96, 0x50, 0x10, 0x10,
+0x00, 0xec, 0xe6, 0x22, 0xe9, 0x04, 0x84, 0xa0, 0x10, 0x50, 0x00, 0xec, 0x84, 0x00, 0xd5, 0x02,
+0x84, 0x01, 0x93, 0x10, 0x54, 0x84, 0x00, 0x0f, 0x4e, 0x83, 0x00, 0x04, 0x80, 0x08, 0xd5, 0x51,
+0x47, 0xef, 0xff, 0x0f, 0x59, 0xef, 0x0f, 0xff, 0x40, 0x53, 0xf8, 0x02, 0x40, 0x84, 0x40, 0x08,
+0x40, 0x42, 0xa0, 0x04, 0x42, 0x72, 0x78, 0x09, 0x42, 0x73, 0xfc, 0x09, 0x46, 0x3f, 0xf0, 0xff,
+0x43, 0xe3, 0xf8, 0x08, 0x54, 0x20, 0x00, 0x0f, 0x58, 0x31, 0x8f, 0xff, 0x40, 0x1f, 0x0c, 0x02,
+0x40, 0x51, 0x50, 0x08, 0x46, 0x4c, 0x6f, 0xff, 0x40, 0x20, 0x94, 0x04, 0x46, 0xf0, 0x00, 0x0c,
+0x01, 0xe7, 0x80, 0xec, 0x58, 0x42, 0x0f, 0xff, 0x46, 0x31, 0x80, 0x00, 0x40, 0x71, 0x10, 0x02,
+0x40, 0x43, 0x8c, 0x04, 0x54, 0x5f, 0x00, 0x03, 0x40, 0x02, 0xe4, 0x08, 0x42, 0x22, 0x64, 0x09,
+0x42, 0x21, 0x68, 0x09, 0x40, 0x71, 0x00, 0x04, 0x42, 0x73, 0xbc, 0x09, 0x55, 0xe3, 0xbf, 0xff,
+0x5e, 0xff, 0x00, 0x08, 0xe8, 0x07, 0x40, 0x33, 0xb8, 0x09, 0x40, 0x31, 0xb8, 0x08, 0x58, 0x71,
+0x80, 0x08, 0x54, 0x43, 0xbf, 0xff, 0x84, 0x41, 0xad, 0x36, 0x10, 0x23, 0x00, 0x0f, 0xa9, 0xf4,
+0x80, 0x09, 0x80, 0x26, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8d, 0x5c, 0xdd, 0x2f, 0x84, 0x01,
+0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xfc, 0x44, 0x20,
+0x00, 0x14, 0x80, 0xc0, 0x80, 0xe1, 0x84, 0x20, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08,
+0xdd, 0x2f, 0xa6, 0x70, 0xa6, 0xb4, 0xa6, 0x31, 0x84, 0x7e, 0x40, 0x40, 0x8c, 0x02, 0x92, 0x02,
+0x94, 0x02, 0x40, 0x51, 0x0c, 0x02, 0xaf, 0x30, 0xaf, 0x74, 0xae, 0x31, 0xa7, 0x37, 0x00, 0x33,
+0x80, 0x9d, 0x54, 0x21, 0x00, 0x02, 0xae, 0xf5, 0xa6, 0xf3, 0xa1, 0x7b, 0x00, 0x03, 0x80, 0x9e,
+0x54, 0x31, 0x80, 0x30, 0x98, 0x28, 0x96, 0x01, 0x40, 0x70, 0x20, 0x09, 0x54, 0x53, 0x80, 0x3f,
+0x92, 0x86, 0x95, 0x26, 0x40, 0x42, 0x14, 0x04, 0x58, 0x21, 0x00, 0x1c, 0x54, 0x50, 0x80, 0x08,
+0x58, 0x31, 0x80, 0x40, 0x84, 0x20, 0xaf, 0x70, 0xaf, 0x37, 0xae, 0xb4, 0xae, 0x72, 0xae, 0xf3,
+0xae, 0x36, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0xbc,
+0x44, 0x60, 0x00, 0x18, 0x10, 0x60, 0x00, 0x9e, 0x50, 0x60, 0x00, 0x24, 0x80, 0xe0, 0x84, 0x20,
+0x44, 0x20, 0x00, 0x18, 0x80, 0x06, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f,
+0xa6, 0xf0, 0x00, 0x83, 0x00, 0x01, 0x44, 0x0f, 0xff, 0xd8, 0x40, 0x44, 0x00, 0x02, 0x54, 0x51,
+0x80, 0x03, 0x58, 0x22, 0x80, 0x08, 0x58, 0x12, 0x00, 0x01, 0x84, 0x60, 0x10, 0x33, 0x00, 0x16,
+0x10, 0x33, 0x00, 0x17, 0xae, 0xb0, 0xae, 0x71, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x06, 0xf0,
+0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x84, 0xc3, 0x84, 0x46, 0x50, 0x03, 0x80, 0x28, 0x4b, 0xe0,
+0x20, 0x01, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x85, 0x74, 0x84, 0x46, 0x50, 0x03, 0x80, 0x2e,
+0x4b, 0xe0, 0x20, 0x01, 0xa0, 0x79, 0x50, 0x03, 0x80, 0x34, 0x84, 0x46, 0x4b, 0xe0, 0x20, 0x01,
+0x00, 0x03, 0x80, 0x94, 0xc0, 0x06, 0xa6, 0x71, 0x59, 0xe0, 0x80, 0x40, 0x11, 0xe3, 0x00, 0x01,
+0xa7, 0x31, 0x42, 0x22, 0x10, 0x09, 0xae, 0xb1, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x80, 0x20, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x84,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8c, 0x38, 0xdd, 0x2f, 0x84, 0x00, 0xec, 0x04, 0x3b, 0xff,
+0xfc, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0x5c, 0x81, 0x00, 0x97, 0x90, 0x40, 0x90,
+0x80, 0x13, 0x80, 0x1f, 0x84, 0x20, 0x44, 0x20, 0x00, 0xa0, 0x04, 0x74, 0x00, 0x02, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xce, 0x13, 0x46, 0x30, 0x00, 0x0c, 0x58, 0x31,
+0x82, 0x84, 0x00, 0x41, 0x81, 0x70, 0xcc, 0x05, 0x80, 0x64, 0x44, 0x20, 0x00, 0xff, 0xd5, 0x0c,
+0x00, 0x01, 0x81, 0x71, 0xc0, 0x05, 0x50, 0x31, 0x81, 0x30, 0x80, 0x46, 0xd5, 0x05, 0x84, 0x60,
+0x44, 0x20, 0x00, 0xff, 0x80, 0x83, 0x87, 0xc1, 0x50, 0x53, 0x80, 0x0e, 0x50, 0x14, 0xff, 0xf2,
+0x80, 0x1f, 0x11, 0xef, 0x80, 0x9d, 0xf3, 0xa6, 0xb7, 0x1f, 0xf5, 0x82, 0xf1, 0x83, 0x10, 0x4f,
+0x80, 0x94, 0x10, 0x2f, 0x80, 0x9c, 0xf7, 0x81, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8f, 0x0c,
+0xdd, 0x2f, 0x00, 0x0f, 0x80, 0x9e, 0x50, 0x2f, 0x80, 0x24, 0x99, 0x50, 0x9d, 0xeb, 0x92, 0xe2,
+0x95, 0xfa, 0x9b, 0x3d, 0x10, 0x4f, 0x80, 0x9f, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x06, 0xf0,
+0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x24, 0x84, 0x46, 0x80, 0x07, 0x4b, 0xe0, 0x20, 0x01,
+0xf1, 0x01, 0x9c, 0x3e, 0x8c, 0x2c, 0x84, 0x42, 0x4b, 0xe0, 0x20, 0x01, 0x00, 0x3f, 0x80, 0x9e,
+0x80, 0x3f, 0x50, 0x21, 0x80, 0x08, 0x50, 0x0f, 0x80, 0x10, 0x10, 0x2f, 0x80, 0x9e, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x8e, 0x88, 0xdd, 0x2f, 0x80, 0x1f, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x8f, 0xb0, 0xdd, 0x2f, 0x80, 0xdf, 0x84, 0x00, 0xec, 0xa4, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x17, 0x84, 0xd0, 0xc1, 0x06,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x84, 0xb0, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xbc, 0x85, 0x40, 0x14, 0xaf, 0x80, 0x0f,
+0x46, 0x60, 0x01, 0x02, 0x58, 0x63, 0x06, 0xa4, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x84, 0xc3,
+0x84, 0x46, 0x55, 0xc0, 0x00, 0xff, 0x50, 0x0f, 0x80, 0x2c, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x10,
+0x00, 0x0c, 0x58, 0x10, 0x85, 0x74, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x32, 0x4b, 0xe0, 0x18, 0x01,
+0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x38, 0x84, 0x42, 0x50, 0x0f, 0x80, 0x38, 0x4b, 0xe0,
+0x18, 0x01, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x89, 0x60, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0c,
+0x58, 0x00, 0x02, 0x64, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x78, 0xdd, 0x2f, 0x81, 0x00,
+0x44, 0x00, 0x06, 0x00, 0x04, 0x94, 0x00, 0x02, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x81, 0x9c,
+0xdd, 0x2f, 0x80, 0xe0, 0xc8, 0x0d, 0x80, 0x28, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x64,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0xbc, 0xdd, 0x2f, 0x48, 0x00, 0x00, 0xdd, 0x50, 0x64,
+0x85, 0x6a, 0x80, 0x2a, 0x44, 0x20, 0x04, 0x00, 0x80, 0x09, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x87, 0x08, 0xdd, 0x2f, 0xa6, 0x35, 0x85, 0x41, 0x58, 0x30, 0x00, 0x08, 0x84, 0xa3, 0x84, 0x9e,
+0x10, 0xa3, 0x00, 0x00, 0xaf, 0x71, 0xaf, 0x34, 0xae, 0xf5, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x07,
+0x84, 0xc1, 0x84, 0x46, 0xa6, 0x76, 0x4c, 0x01, 0x40, 0x09, 0x41, 0xe0, 0x8c, 0x09, 0x41, 0xef,
+0x0c, 0x08, 0x58, 0x1f, 0x00, 0x02, 0xd5, 0x05, 0x92, 0x23, 0x94, 0x4b, 0x58, 0x10, 0x80, 0x01,
+0xae, 0x76, 0xa6, 0x35, 0xa6, 0x76, 0x54, 0x4e, 0x00, 0x01, 0x43, 0xe0, 0x8c, 0x09, 0x94, 0xa3,
+0x40, 0xaf, 0x08, 0x04, 0x58, 0x50, 0x00, 0x05, 0x84, 0x80, 0x45, 0xc0, 0x00, 0x5f, 0x10, 0xa3,
+0x00, 0x06, 0xaf, 0x75, 0xaf, 0x32, 0x11, 0xc3, 0x00, 0x03, 0x50, 0x03, 0x00, 0x09, 0x46, 0x10,
+0x00, 0x0c, 0x58, 0x10, 0x84, 0xea, 0x84, 0x48, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xf0,
+0xdd, 0x2f, 0x46, 0x30, 0x00, 0x0c, 0x58, 0x31, 0x84, 0xf1, 0x00, 0xa1, 0x80, 0x00, 0x50, 0x55,
+0x00, 0x01, 0x55, 0xc2, 0x80, 0xff, 0x11, 0xc1, 0x80, 0x00, 0x9e, 0xd9, 0x4f, 0xc3, 0x00, 0x08,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x04, 0xe9, 0x4c, 0x30, 0x7f, 0xf1, 0xa7, 0x72, 0x01, 0xc3,
+0x00, 0x03, 0x40, 0x42, 0xa0, 0x08, 0x41, 0xe2, 0x70, 0x04, 0x50, 0x2f, 0x00, 0x04, 0x50, 0x1f,
+0x80, 0x3c, 0x80, 0x66, 0x84, 0x9f, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x84, 0x3c,
+0xdd, 0x2f, 0x46, 0x30, 0x01, 0x02, 0x58, 0x31, 0x87, 0x08, 0xf3, 0x81, 0x51, 0xcf, 0x80, 0x1c,
+0x84, 0x20, 0x44, 0x20, 0x00, 0x10, 0x80, 0x1c, 0x46, 0xa0, 0x00, 0x0c, 0x58, 0xa5, 0x02, 0x84,
+0xdd, 0x23, 0x00, 0x25, 0x02, 0x3d, 0x84, 0x26, 0xf3, 0x01, 0x4c, 0x20, 0xc0, 0x21, 0x50, 0x0f,
+0x80, 0x08, 0x84, 0x20, 0x44, 0x20, 0x00, 0x14, 0xdd, 0x23, 0xf3, 0x0f, 0x50, 0x05, 0x00, 0xd0,
+0x80, 0x47, 0x50, 0x4f, 0x80, 0x08, 0x44, 0x50, 0x00, 0x14, 0x9e, 0x6c, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x81, 0x54, 0xdd, 0x2f, 0x80, 0x1c, 0x50, 0x1f, 0x80, 0x08, 0x44, 0x20, 0x00, 0x10,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xd5, 0x0d, 0x8c, 0x2a, 0xf3, 0x0f,
+0x50, 0x05, 0x00, 0xd0, 0x80, 0x9c, 0x80, 0x47, 0x80, 0xa1, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x80, 0x10, 0xdd, 0x2f, 0x46, 0xa0, 0x01, 0x02, 0x58, 0xa5, 0x06, 0xf0, 0x50, 0x1f, 0x80, 0x1c,
+0x44, 0x20, 0x00, 0x10, 0x50, 0x03, 0x00, 0x51, 0x4b, 0xe0, 0x28, 0x01, 0xa6, 0x72, 0xa6, 0x33,
+0x40, 0x60, 0xa0, 0x08, 0x40, 0x63, 0x00, 0x04, 0x50, 0x1f, 0x80, 0x2c, 0x84, 0x4e, 0x80, 0x09,
+0x4b, 0xe0, 0x28, 0x01, 0x50, 0x23, 0x00, 0x12, 0x96, 0x51, 0x80, 0x08, 0x84, 0x40, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x8f, 0xd4, 0xdd, 0x2f, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x81, 0xb0, 0xdd, 0x2f, 0xec, 0x44, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0xc2, 0x17, 0xc0, 0x04, 0xa6, 0xc1, 0x96, 0x1c, 0xc8, 0x13, 0xa6, 0x11, 0x54, 0x20,
+0x00, 0x03, 0xca, 0x0f, 0x54, 0x40, 0x00, 0x04, 0x96, 0x20, 0xc0, 0x0c, 0xa7, 0x49, 0x54, 0x12,
+0x80, 0x03, 0x5c, 0x00, 0x80, 0x01, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x80, 0xe4, 0xdd, 0x2f,
+0x84, 0x01, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc,
+0xef, 0xdc, 0x81, 0x20, 0xa4, 0x06, 0x5c, 0xf0, 0x00, 0x39, 0xe9, 0x3f, 0x04, 0x84, 0x80, 0x02,
+0x50, 0x64, 0x00, 0x04, 0xa6, 0xb7, 0x50, 0x74, 0x00, 0x20, 0x40, 0x41, 0x18, 0x09, 0x46, 0xf0,
+0x00, 0x0c, 0x10, 0x47, 0x84, 0xe9, 0x80, 0x26, 0x80, 0x07, 0x80, 0x48, 0x46, 0xf0, 0x00, 0x02,
+0x58, 0xf7, 0x83, 0x3c, 0xdd, 0x2f, 0x84, 0xa1, 0xd0, 0x28, 0x50, 0x3f, 0x80, 0x04, 0xb7, 0x03,
+0x14, 0x91, 0x80, 0x03, 0xa9, 0x99, 0xa9, 0xda, 0xa9, 0xdc, 0x84, 0x80, 0xa6, 0x73, 0x01, 0xe3,
+0x00, 0x02, 0x54, 0x00, 0x80, 0x3f, 0x40, 0x50, 0x20, 0x08, 0x40, 0x22, 0xf8, 0x04, 0x12, 0x21,
+0x80, 0x0a, 0x12, 0x41, 0x80, 0x0b, 0x87, 0xc2, 0xa6, 0x78, 0x40, 0x00, 0x88, 0x09, 0x54, 0x50,
+0x00, 0x03, 0x4c, 0x5f, 0x00, 0x03, 0xd5, 0x07, 0x80, 0x03, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x80, 0xc0, 0xdd, 0x2f, 0x84, 0x01, 0xd5, 0x02, 0x84, 0x00, 0xec, 0x24, 0x3a, 0x6f, 0xa4, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x84, 0x60, 0xd5, 0x0e, 0x38, 0x50, 0x0c, 0x00, 0x38, 0x40, 0x8c, 0x00,
+0x9c, 0xd9, 0xe2, 0x85, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x08, 0xe2, 0xa4, 0xe8, 0x03, 0x84, 0x02,
+0xd5, 0x04, 0xe2, 0x62, 0xe9, 0xf2, 0x84, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x2f, 0x94, 0x3c,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x81, 0x20, 0x50, 0x0f, 0x80, 0x20, 0xf0, 0x81, 0x80, 0xe1,
+0x84, 0xc0, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x06, 0xa4, 0xf2, 0x01, 0x84, 0xbf, 0x9d, 0x14,
+0xf4, 0x81, 0x40, 0x04, 0x98, 0x00, 0xb4, 0x62, 0x9c, 0x64, 0x80, 0x43, 0xd3, 0x07, 0xf1, 0x81,
+0x99, 0xb3, 0xb4, 0x24, 0x4b, 0xe0, 0x20, 0x01, 0xd5, 0xf1, 0x80, 0x06, 0xb6, 0xc7, 0xec, 0x0c,
+0x3a, 0x6f, 0xa4, 0x84, 0xec, 0x10, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x84, 0x20,
+0x44, 0x20, 0x00, 0x14, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x04, 0xd0, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x80, 0xc0, 0xa0, 0x02, 0xa6, 0xc0, 0x40, 0x21, 0x90, 0x09,
+0x54, 0x11, 0x00, 0x04, 0x4e, 0x13, 0x01, 0x29, 0xa7, 0x41, 0x54, 0x42, 0x80, 0x40, 0xc4, 0x08,
+0xb5, 0x26, 0x00, 0x84, 0x80, 0x02, 0x54, 0x74, 0x00, 0x01, 0x4e, 0x72, 0x01, 0x1e, 0x9c, 0x04,
+0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xd4, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x44,
+0x84, 0x46, 0x4b, 0xe0, 0x1c, 0x01, 0xc8, 0x03, 0x84, 0xe3, 0xd5, 0x16, 0xa0, 0x32, 0x46, 0x10,
+0x00, 0x0c, 0x58, 0x10, 0x85, 0x74, 0x9c, 0x04, 0x84, 0x46, 0x4b, 0xe0, 0x1c, 0x01, 0xc8, 0x03,
+0x84, 0xe1, 0xd5, 0x0a, 0xa0, 0xf2, 0x84, 0x22, 0xa6, 0x9c, 0x55, 0xe1, 0x00, 0x01, 0x40, 0x7f,
+0x78, 0x1a, 0x40, 0x70, 0xf8, 0x1b, 0x02, 0x03, 0x00, 0x0a, 0x05, 0xe3, 0x00, 0x04, 0x50, 0x90,
+0x7f, 0xe8, 0x50, 0x2f, 0x00, 0x18, 0x12, 0x93, 0x00, 0x0a, 0xa8, 0xb4, 0x04, 0x83, 0x00, 0x02,
+0x00, 0x54, 0x00, 0x00, 0x40, 0x42, 0x90, 0x09, 0x54, 0x02, 0x00, 0x08, 0xc0, 0x1e, 0x02, 0x33,
+0x00, 0x0b, 0x58, 0x11, 0x80, 0x40, 0x96, 0x49, 0x12, 0x13, 0x00, 0x0b, 0xa6, 0x10, 0x96, 0x82,
+0x4e, 0x24, 0x00, 0x06, 0x58, 0x40, 0x80, 0x02, 0x12, 0x43, 0x00, 0x0b, 0x05, 0xe3, 0x00, 0x04,
+0x02, 0x93, 0x00, 0x0a, 0x50, 0x8f, 0x00, 0x02, 0x50, 0x54, 0xff, 0xfe, 0x14, 0x83, 0x00, 0x04,
+0x12, 0x53, 0x00, 0x0a, 0x54, 0x00, 0x00, 0x0f, 0x10, 0x03, 0x00, 0x18, 0xb4, 0x26, 0xa6, 0x89,
+0x54, 0x01, 0x00, 0x10, 0xc0, 0x12, 0x03, 0xe3, 0x00, 0x0b, 0x04, 0x93, 0x00, 0x04, 0x02, 0x83,
+0x00, 0x0a, 0x58, 0x5f, 0x00, 0x08, 0x50, 0x44, 0x80, 0x04, 0x50, 0x34, 0x7f, 0xfc, 0x12, 0x53,
+0x00, 0x0b, 0xa9, 0x34, 0x12, 0x33, 0x00, 0x0a, 0xb4, 0x26, 0xa6, 0x89, 0x54, 0x01, 0x00, 0x40,
+0xc0, 0x0a, 0x02, 0x83, 0x00, 0x0b, 0xa1, 0x74, 0x58, 0x44, 0x00, 0x10, 0x9c, 0xea, 0x12, 0x43,
+0x00, 0x0b, 0xa8, 0xf4, 0xa0, 0x34, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x06, 0xd4, 0x46, 0x10,
+0x00, 0x09, 0x58, 0x10, 0x84, 0x24, 0x84, 0x46, 0x4b, 0xe0, 0x20, 0x01, 0xc0, 0x0b, 0xa0, 0x34,
+0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x2c, 0x84, 0x46, 0x4b, 0xe0, 0x20, 0x01, 0x4e, 0x03,
+0x00, 0x8c, 0xa1, 0x34, 0x02, 0x33, 0x00, 0x0a, 0x9c, 0x66, 0x51, 0xe1, 0xff, 0xfa, 0xa8, 0x74,
+0x50, 0x8f, 0x80, 0x04, 0x13, 0xe3, 0x00, 0x0a, 0x84, 0x42, 0x80, 0x08, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x86, 0xf0, 0xdd, 0x2f, 0xa0, 0x74, 0x02, 0x03, 0x00, 0x0a, 0x9c, 0x8a, 0x50, 0x90,
+0x7f, 0xfe, 0xa8, 0xb4, 0x12, 0x93, 0x00, 0x0a, 0x80, 0x08, 0x46, 0x90, 0x01, 0x02, 0x58, 0x94,
+0x86, 0xd4, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x34, 0x84, 0x42, 0x4b, 0xe0, 0x24, 0x01,
+0xc0, 0x63, 0x80, 0x08, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x3c, 0x84, 0x42, 0x4b, 0xe0,
+0x24, 0x01, 0xc8, 0x35, 0x84, 0x22, 0x4c, 0x70, 0x80, 0x33, 0xa0, 0xb4, 0x01, 0xe1, 0x00, 0x00,
+0x54, 0x5f, 0x00, 0x0f, 0x40, 0x32, 0x84, 0x0c, 0xe6, 0x79, 0xe8, 0x4e, 0x00, 0x11, 0x00, 0x09,
+0x44, 0x50, 0x00, 0x11, 0xd9, 0x09, 0x99, 0x53, 0xa6, 0xec, 0xa6, 0xad, 0x40, 0x01, 0xa0, 0x08,
+0x40, 0x00, 0x08, 0x04, 0xd5, 0x03, 0x84, 0xa6, 0xd9, 0x3f, 0x84, 0x81, 0x4c, 0x72, 0x40, 0x06,
+0x84, 0x46, 0x4c, 0x11, 0x40, 0x06, 0xd5, 0x38, 0x84, 0x63, 0x4c, 0x71, 0xc0, 0x36, 0x44, 0x50,
+0x00, 0x11, 0xd9, 0x32, 0x44, 0x10, 0x00, 0x6e, 0x4c, 0x00, 0xc0, 0x2f, 0x80, 0x06, 0x84, 0x21,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x85, 0x80, 0xdd, 0x2f, 0xd5, 0x26, 0x50, 0x8f, 0x80, 0x04,
+0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xd4, 0x80, 0x08, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10,
+0x84, 0x40, 0x84, 0x42, 0x4b, 0xe0, 0x1c, 0x01, 0xc0, 0x17, 0x80, 0x08, 0x46, 0x10, 0x00, 0x09,
+0x58, 0x10, 0x84, 0x38, 0x84, 0x42, 0x4b, 0xe0, 0x1c, 0x01, 0xc8, 0x0e, 0xa0, 0x34, 0x84, 0xa3,
+0x01, 0xe0, 0x00, 0x01, 0x4d, 0xe2, 0xc0, 0x09, 0x02, 0x13, 0x00, 0x0a, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x8e, 0x30, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0x50, 0x00, 0x0c, 0x58, 0x52, 0x85, 0xd4, 0x46, 0xf0,
+0x00, 0x09, 0x14, 0x57, 0x81, 0x5c, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x84, 0x88, 0xdd, 0x2f,
+0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x64, 0xb4, 0x60, 0xb6, 0x60, 0xa0, 0x81, 0xa8, 0x81,
+0xa0, 0x42, 0xa8, 0x42, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x84, 0xcc, 0xdd, 0x2f, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x84, 0xf0, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x40,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x82, 0x98, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff,
+0xfc, 0x84, 0xdd, 0x9e, 0xc8, 0x02, 0xd5, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x78, 0x96, 0x40, 0x96, 0x8c,
+0xc2, 0x07, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67, 0x80, 0x3c, 0x84, 0x01, 0xd5, 0x69, 0x54, 0x30,
+0x80, 0x02, 0xc3, 0x07, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67, 0x80, 0x3d, 0x84, 0x02, 0xd5, 0x60,
+0x40, 0x60, 0x40, 0x09, 0x96, 0x70, 0x54, 0x50, 0x80, 0x02, 0xc5, 0x08, 0x46, 0xf0, 0x00, 0x0c,
+0x04, 0x67, 0x80, 0x4d, 0x44, 0x02, 0x00, 0x00, 0xd5, 0x53, 0x96, 0x8c, 0xc2, 0x08, 0x46, 0xf0,
+0x00, 0x0c, 0x04, 0x67, 0x80, 0x4c, 0x44, 0x01, 0x00, 0x00, 0xd5, 0x4a, 0x40, 0x60, 0x60, 0x09,
+0x96, 0x74, 0xc1, 0x08, 0x46, 0x00, 0x10, 0x00, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67, 0x80, 0x54,
+0xd5, 0x3f, 0x54, 0x43, 0x00, 0x02, 0xc4, 0x08, 0x46, 0x00, 0x20, 0x00, 0x46, 0xf0, 0x00, 0x0c,
+0x04, 0x67, 0x80, 0x55, 0xd5, 0x35, 0x55, 0xe3, 0x00, 0x04, 0x4f, 0xe2, 0x00, 0x09, 0x46, 0x00,
+0x40, 0x00, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67, 0x80, 0x56, 0xd5, 0x2a, 0x54, 0x13, 0x00, 0x10,
+0xc1, 0x08, 0x46, 0x01, 0x00, 0x00, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67, 0x80, 0x58, 0xd5, 0x20,
+0x54, 0x43, 0x00, 0x20, 0xc4, 0x08, 0x46, 0x02, 0x00, 0x00, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67,
+0x80, 0x59, 0xd5, 0x16, 0x55, 0xe3, 0x00, 0x40, 0x4f, 0xe2, 0x00, 0x09, 0x46, 0x04, 0x00, 0x00,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67, 0x80, 0x5a, 0xd5, 0x0b, 0x54, 0x63, 0x00, 0x80, 0x97, 0xb0,
+0xc6, 0x07, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x67, 0x80, 0x5b, 0x46, 0x08, 0x00, 0x00, 0x46, 0x30,
+0x04, 0x10, 0x58, 0x31, 0x88, 0x00, 0x14, 0x01, 0x80, 0x78, 0x84, 0x20, 0x40, 0x00, 0x98, 0x06,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x87, 0x84, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00,
+0x02, 0x84, 0xdd, 0x26, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xfc, 0x80, 0xc0, 0x5c, 0x00, 0x00, 0x20, 0x80, 0xe1, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x87, 0x84, 0xdd, 0x2f, 0x46, 0x50, 0x00, 0x0c, 0x58, 0x52, 0x80, 0xf0, 0x38, 0x72, 0x9a, 0x0a,
+0x46, 0x10, 0x04, 0x10, 0x58, 0x10, 0x88, 0x00, 0x04, 0x30, 0x80, 0x78, 0x84, 0x81, 0x40, 0x62,
+0x18, 0x0c, 0x40, 0x23, 0x0c, 0x04, 0x14, 0x20, 0x80, 0x78, 0x04, 0x00, 0x80, 0x7a, 0x40, 0x63,
+0x00, 0x04, 0x14, 0x60, 0x80, 0x7a, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x44, 0x40, 0x00, 0x40, 0x84, 0xa0, 0xf5, 0x81, 0x46, 0x10,
+0x04, 0x10, 0x10, 0x4f, 0x80, 0x04, 0x10, 0x4f, 0x80, 0x07, 0x58, 0x10, 0x88, 0x00, 0xb4, 0x61,
+0x50, 0x60, 0x00, 0x9c, 0x58, 0x01, 0x80, 0x02, 0xb6, 0x01, 0x80, 0x01, 0xf2, 0x01, 0x14, 0x20,
+0x80, 0x71, 0x04, 0x70, 0x00, 0x71, 0x42, 0x93, 0x8c, 0x0b, 0xf7, 0x81, 0x81, 0x01, 0x4e, 0x93,
+0xff, 0xfa, 0x42, 0x73, 0x84, 0x0b, 0xcf, 0xf6, 0x46, 0x90, 0x00, 0x03, 0x58, 0x94, 0x80, 0xf0,
+0x50, 0x13, 0x7f, 0x64, 0x50, 0x23, 0x7f, 0xe4, 0x50, 0x04, 0x01, 0xa0, 0x84, 0x62, 0x4b, 0xe0,
+0x24, 0x01, 0x46, 0x00, 0x04, 0x10, 0x50, 0x13, 0x7f, 0x84, 0x50, 0x23, 0x7f, 0xec, 0x58, 0x00,
+0x09, 0xb0, 0x84, 0x62, 0x4b, 0xe0, 0x24, 0x01, 0x46, 0x00, 0x04, 0x10, 0x46, 0x90, 0x00, 0x03,
+0x58, 0x94, 0x80, 0xa4, 0x50, 0x13, 0x7f, 0xa4, 0x50, 0x23, 0x7f, 0xf4, 0x58, 0x00, 0x09, 0x80,
+0x84, 0x62, 0x4b, 0xe0, 0x24, 0x01, 0x46, 0x00, 0x04, 0x10, 0x50, 0x13, 0x7f, 0xc4, 0x9e, 0xb4,
+0x58, 0x00, 0x09, 0x90, 0x84, 0x62, 0x4b, 0xe0, 0x24, 0x01, 0x84, 0x61, 0xaf, 0xf5, 0xaf, 0xf4,
+0x10, 0x34, 0x01, 0xa8, 0x10, 0x34, 0x01, 0xb8, 0x14, 0x73, 0x00, 0x09, 0xaf, 0xf7, 0xaf, 0xf6,
+0xa9, 0xf4, 0xa9, 0xf5, 0xa9, 0xf2, 0xa9, 0xf3, 0x50, 0x03, 0x00, 0x1c, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x81, 0x6c, 0xdd, 0x2f, 0x04, 0x04, 0x00, 0x71, 0x58, 0x20, 0x00, 0x05, 0xf0, 0x81,
+0x10, 0x2f, 0x80, 0x04, 0xf1, 0x01, 0x14, 0x14, 0x00, 0x71, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x42, 0x11, 0x40, 0x08, 0x14, 0x10, 0x00, 0x2d,
+0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x42, 0x11, 0x44, 0x08, 0x14, 0x10, 0x00, 0x2d,
+0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x58, 0x11, 0x00, 0x01, 0x14, 0x10, 0x00, 0x2d,
+0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x58, 0x11, 0x00, 0x02, 0x14, 0x10, 0x00, 0x2d,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0x3c, 0xef, 0xf4, 0x46, 0x00, 0x04, 0x10, 0x58, 0x00,
+0x08, 0x00, 0x50, 0x10, 0x00, 0x80, 0x85, 0x20, 0x04, 0x40, 0x00, 0x43, 0x40, 0x32, 0x40, 0x09,
+0x54, 0x31, 0x80, 0x0f, 0x80, 0x40, 0xc3, 0x64, 0x84, 0x40, 0x97, 0x5c, 0xc5, 0x5c, 0x54, 0x61,
+0x00, 0x03, 0x14, 0x60, 0x00, 0x43, 0x84, 0xc0, 0x04, 0x80, 0x00, 0x43, 0x40, 0x44, 0x20, 0x09,
+0x54, 0x42, 0x00, 0x7f, 0x40, 0x72, 0x20, 0x08, 0x40, 0x53, 0x90, 0x04, 0x14, 0x50, 0x00, 0x1d,
+0x44, 0x7f, 0xff, 0xc7, 0x04, 0xa0, 0x80, 0x02, 0xb5, 0x01, 0x14, 0xaf, 0x80, 0x01, 0x8d, 0x04,
+0x00, 0xaf, 0x80, 0x07, 0x80, 0xa4, 0x40, 0xa5, 0x1c, 0x02, 0x58, 0xa5, 0x00, 0x20, 0x10, 0xaf,
+0x80, 0x07, 0x54, 0x74, 0x00, 0x7f, 0x40, 0xa4, 0x1c, 0x09, 0x40, 0x74, 0x9c, 0x06, 0x04, 0x8f,
+0x80, 0x01, 0x88, 0xea, 0x14, 0x80, 0x80, 0x02, 0x50, 0x83, 0xff, 0xff, 0xd5, 0x08, 0x14, 0xa0,
+0x00, 0x1b, 0x9d, 0xb1, 0x04, 0xa0, 0x00, 0x1b, 0x54, 0x55, 0x00, 0x7f, 0x40, 0xa2, 0xa0, 0x08,
+0xe2, 0xc8, 0xe9, 0xf6, 0x54, 0x63, 0x80, 0x7f, 0x40, 0x63, 0x20, 0x08, 0x40, 0x52, 0xc0, 0x08,
+0x58, 0x73, 0x00, 0x02, 0x58, 0x63, 0x00, 0x18, 0x40, 0x73, 0x94, 0x04, 0x40, 0x53, 0x14, 0x04,
+0x46, 0x68, 0x0f, 0xff, 0x58, 0x63, 0x0f, 0xff, 0x40, 0x42, 0x60, 0x08, 0x40, 0x52, 0x98, 0x02,
+0x40, 0x73, 0x98, 0x02, 0x40, 0x73, 0x90, 0x04, 0x40, 0x42, 0x90, 0x04, 0x14, 0x40, 0x00, 0x44,
+0x14, 0x70, 0x00, 0x45, 0x9c, 0x91, 0x84, 0xa4, 0xd2, 0x98, 0x92, 0x61, 0xd5, 0x9f, 0x46, 0x00,
+0x20, 0x00, 0x14, 0x01, 0x00, 0x78, 0xec, 0x0c, 0x3a, 0x6f, 0xa8, 0x04, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa8, 0x3c, 0xef, 0xf4, 0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x08, 0x00, 0x50, 0x10,
+0x00, 0x80, 0x85, 0x20, 0x04, 0x40, 0x00, 0x40, 0x40, 0x32, 0x40, 0x09, 0x54, 0x31, 0x80, 0x0f,
+0x80, 0x40, 0xc3, 0x6a, 0x84, 0x40, 0x97, 0x5c, 0xc5, 0x62, 0x54, 0x61, 0x00, 0x03, 0x14, 0x60,
+0x00, 0x40, 0x84, 0xc0, 0x04, 0x80, 0x00, 0x40, 0x40, 0x44, 0x20, 0x09, 0x54, 0x42, 0x00, 0x7f,
+0x40, 0x72, 0x20, 0x08, 0x40, 0x53, 0x90, 0x04, 0x14, 0x50, 0x00, 0x1d, 0x44, 0x7f, 0xff, 0xc7,
+0x04, 0xa0, 0x80, 0x02, 0xb5, 0x01, 0x14, 0xaf, 0x80, 0x01, 0x8d, 0x04, 0x00, 0xaf, 0x80, 0x07,
+0x80, 0xa4, 0x40, 0xa5, 0x1c, 0x02, 0x58, 0xa5, 0x00, 0x28, 0x10, 0xaf, 0x80, 0x07, 0x54, 0x74,
+0x00, 0x7f, 0x40, 0xa4, 0x1c, 0x09, 0x40, 0x74, 0x9c, 0x06, 0x04, 0x8f, 0x80, 0x01, 0x88, 0xea,
+0x14, 0x80, 0x80, 0x02, 0x50, 0x83, 0xff, 0xff, 0xd5, 0x08, 0x14, 0xa0, 0x00, 0x1b, 0x9d, 0xb1,
+0x04, 0xa0, 0x00, 0x1b, 0x54, 0x55, 0x00, 0x7f, 0x40, 0xa2, 0xa0, 0x08, 0xe2, 0xc8, 0xe9, 0xf6,
+0x00, 0x8f, 0x80, 0x07, 0x54, 0x63, 0x80, 0x7f, 0x40, 0x74, 0x04, 0x09, 0x40, 0x63, 0x20, 0x08,
+0x54, 0x73, 0x80, 0x03, 0x40, 0x82, 0xc0, 0x08, 0x40, 0x73, 0x98, 0x04, 0x40, 0x53, 0xa0, 0x04,
+0x58, 0x63, 0x00, 0x02, 0x46, 0x78, 0x0f, 0xff, 0x40, 0x63, 0x20, 0x04, 0x58, 0x73, 0x8f, 0xff,
+0x40, 0x82, 0x60, 0x08, 0x40, 0x52, 0x9c, 0x02, 0x40, 0x63, 0x1c, 0x02, 0x40, 0x63, 0x20, 0x04,
+0x40, 0x42, 0xa0, 0x04, 0x14, 0x40, 0x00, 0x41, 0x14, 0x60, 0x00, 0x42, 0x9c, 0x91, 0x84, 0xa4,
+0xd2, 0x92, 0x92, 0x61, 0xd5, 0x99, 0x46, 0x00, 0x10, 0x00, 0x14, 0x01, 0x00, 0x78, 0xec, 0x0c,
+0x3a, 0x6f, 0xa8, 0x04, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0x3c, 0x04, 0x50, 0x00, 0x29,
+0x04, 0x30, 0x00, 0x2a, 0x9d, 0x2a, 0x9a, 0xa3, 0xe4, 0x42, 0x4e, 0xf3, 0x00, 0x85, 0x00, 0x30,
+0x00, 0xa2, 0x9c, 0x9c, 0x40, 0x81, 0x10, 0x08, 0x40, 0x20, 0x20, 0x00, 0xa7, 0xd7, 0x54, 0x63,
+0x80, 0x80, 0xc6, 0x79, 0xb5, 0x01, 0x50, 0x41, 0x80, 0x24, 0x38, 0x80, 0x12, 0x0a, 0x00, 0x70,
+0x80, 0x9f, 0x00, 0x50, 0x80, 0x9e, 0xa1, 0x0b, 0x99, 0xbd, 0x50, 0x73, 0x00, 0x14, 0x50, 0x50,
+0x80, 0x10, 0x02, 0x81, 0x00, 0x03, 0x95, 0x9c, 0xc4, 0x22, 0x93, 0x0e, 0x40, 0x84, 0x38, 0x08,
+0x40, 0x74, 0x1c, 0x04, 0xad, 0xd3, 0xb6, 0xa2, 0xa7, 0x17, 0x42, 0x42, 0x18, 0x09, 0xaf, 0x17,
+0x99, 0x86, 0xa1, 0x4a, 0x14, 0x53, 0x00, 0x12, 0xa1, 0x0b, 0xa4, 0x52, 0x54, 0x42, 0x3f, 0xff,
+0x92, 0x2e, 0x40, 0x10, 0xb8, 0x08, 0x40, 0x50, 0x90, 0x04, 0xad, 0x52, 0xa7, 0x17, 0xa6, 0x55,
+0x54, 0x52, 0x00, 0x7f, 0x58, 0x10, 0x80, 0x40, 0xaf, 0x57, 0xd5, 0x1b, 0x93, 0x0e, 0x40, 0x84,
+0x38, 0x08, 0x40, 0x74, 0x1c, 0x04, 0xad, 0xd3, 0x99, 0x86, 0xa6, 0x57, 0xb6, 0xa2, 0x58, 0x10,
+0x80, 0x40, 0xae, 0x57, 0x14, 0x43, 0x00, 0x12, 0xa4, 0x52, 0xa7, 0x17, 0x92, 0x2e, 0x40, 0x10,
+0xb8, 0x08, 0xac, 0x52, 0x54, 0x42, 0x00, 0x7f, 0xa6, 0x55, 0xaf, 0x17, 0x42, 0x10, 0x98, 0x09,
+0x95, 0x1c, 0xae, 0x55, 0x98, 0x44, 0x50, 0x10, 0x80, 0x48, 0xa6, 0x8e, 0x44, 0x5f, 0xff, 0xcf,
+0x40, 0x41, 0x14, 0x02, 0x58, 0x22, 0x00, 0x08, 0x9c, 0xdc, 0x84, 0x84, 0xaf, 0x0f, 0xae, 0x8e,
+0x40, 0x51, 0x90, 0x0c, 0x99, 0x05, 0xa4, 0xa3, 0xb4, 0x61, 0x54, 0x51, 0x3f, 0xff, 0x99, 0x1d,
+0xad, 0x0a, 0x46, 0x40, 0x04, 0x10, 0x00, 0x20, 0x00, 0xa2, 0x04, 0x50, 0x00, 0x2a, 0x9c, 0x51,
+0x96, 0x8c, 0x9c, 0xe9, 0x58, 0x42, 0x08, 0x00, 0x14, 0x30, 0x00, 0x2a, 0x10, 0x20, 0x00, 0xa2,
+0x10, 0x22, 0x01, 0x88, 0x3a, 0x6f, 0xa0, 0x04, 0xdd, 0x9e, 0x92, 0x00, 0x04, 0x50, 0x00, 0x2b,
+0x04, 0x30, 0x00, 0x2c, 0x9d, 0x2a, 0x9a, 0xa3, 0xe4, 0x42, 0xe9, 0x3e, 0x00, 0x30, 0x00, 0xa3,
+0x9d, 0x1e, 0x94, 0xa4, 0x98, 0x82, 0xa7, 0x57, 0x54, 0x42, 0x80, 0x80, 0xc4, 0x35, 0x50, 0x51,
+0x80, 0x26, 0x38, 0x10, 0x16, 0x0a, 0x94, 0xdc, 0xa1, 0x0a, 0x98, 0xc3, 0xb6, 0x82, 0xa1, 0x4c,
+0x14, 0x51, 0x80, 0x1b, 0xa5, 0x0e, 0xa4, 0xd3, 0x54, 0x42, 0x3f, 0xff, 0x92, 0x6e, 0x40, 0x31,
+0xb8, 0x08, 0x40, 0x51, 0x90, 0x04, 0xad, 0x53, 0xa7, 0x55, 0x00, 0x40, 0x80, 0x0f, 0xa6, 0xd7,
+0x96, 0x64, 0x95, 0x0e, 0x54, 0x11, 0x80, 0x3f, 0x40, 0x30, 0x90, 0x04, 0x54, 0x12, 0x80, 0x7f,
+0xae, 0xd7, 0xae, 0x55, 0x46, 0x10, 0x04, 0x10, 0x00, 0x50, 0x00, 0xa3, 0x04, 0x40, 0x00, 0x2c,
+0x9c, 0xa9, 0x97, 0x54, 0x9c, 0xe1, 0x58, 0x10, 0x88, 0x00, 0x14, 0x30, 0x00, 0x2c, 0x10, 0x50,
+0x00, 0xa3, 0x10, 0x50, 0x81, 0x98, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x85, 0x20,
+0x80, 0xc0, 0x46, 0x80, 0x00, 0x00, 0x58, 0x84, 0x02, 0xbc, 0xd5, 0x22, 0xa7, 0x1f, 0x54, 0x22,
+0x00, 0x80, 0xc2, 0x30, 0x38, 0x23, 0x06, 0x02, 0x38, 0x93, 0x06, 0x0a, 0x80, 0x22, 0x00, 0x31,
+0x00, 0x14, 0xcb, 0x02, 0xd5, 0x05, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x64, 0x4b, 0xe0,
+0x20, 0x01, 0x9c, 0x3e, 0x94, 0xc4, 0x99, 0xf3, 0xa6, 0xbf, 0x44, 0x4f, 0xff, 0xc0, 0x40, 0x51,
+0x10, 0x04, 0xaf, 0x7f, 0x04, 0x13, 0x00, 0x2b, 0x9c, 0x09, 0x14, 0x03, 0x00, 0x2b, 0x04, 0x23,
+0x00, 0x2b, 0x04, 0x53, 0x00, 0x2c, 0x97, 0xd4, 0x9c, 0x7e, 0x95, 0x0c, 0x41, 0xe2, 0x88, 0x01,
+0x50, 0x13, 0x80, 0x26, 0x98, 0xf4, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x74, 0x4f, 0xe6,
+0xff, 0xcf, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc,
+0xef, 0xfc, 0x85, 0x20, 0x80, 0xc0, 0x46, 0x80, 0x00, 0x00, 0x58, 0x84, 0x02, 0xbc, 0xd5, 0x1a,
+0xa6, 0xff, 0x54, 0x11, 0x80, 0x80, 0xc1, 0x28, 0x38, 0x13, 0x0a, 0x02, 0x38, 0x93, 0x0a, 0x0a,
+0x4b, 0xe0, 0x20, 0x01, 0xa6, 0x7f, 0xa6, 0xfd, 0x44, 0x0f, 0xff, 0xc0, 0x40, 0x50, 0x80, 0x04,
+0x58, 0x41, 0x80, 0x40, 0xaf, 0x7f, 0xaf, 0x3d, 0x04, 0x23, 0x00, 0x29, 0x9c, 0x11, 0x14, 0x03,
+0x00, 0x29, 0x04, 0x43, 0x00, 0x29, 0x04, 0x53, 0x00, 0x2a, 0x96, 0x64, 0x9c, 0xcc, 0x95, 0xdc,
+0x41, 0xe2, 0x90, 0x01, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x64, 0x50, 0x20, 0x80, 0x24,
+0x99, 0xf7, 0x4f, 0xe6, 0xff, 0xd7, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x83, 0x80, 0x50, 0x00, 0x00, 0xb8, 0x46, 0x40, 0x04, 0x10,
+0xf0, 0x81, 0x58, 0x42, 0x08, 0x00, 0x00, 0x7e, 0x00, 0xa1, 0x00, 0x12, 0x01, 0xbc, 0x9d, 0x7a,
+0x94, 0xac, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x64, 0x50, 0xa3, 0x80, 0x22, 0x40, 0x6e,
+0x08, 0x00, 0x4c, 0x70, 0x80, 0x55, 0xa6, 0x77, 0x55, 0xe0, 0x80, 0x80, 0x4f, 0xe2, 0x00, 0x50,
+0x02, 0x83, 0x00, 0x03, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x78, 0xdd, 0x2f,
+0x54, 0x94, 0x3f, 0xff, 0x95, 0x3c, 0x81, 0x00, 0x40, 0x3e, 0x10, 0x00, 0xf0, 0x01, 0xb4, 0x9f,
+0x4e, 0x83, 0x00, 0x07, 0xbb, 0x2d, 0x42, 0x01, 0xc4, 0x08, 0xb8, 0xad, 0xd5, 0x38, 0x39, 0xee,
+0x2a, 0x02, 0x84, 0x41, 0x12, 0x9f, 0x00, 0x06, 0x80, 0x3e, 0x04, 0x51, 0x80, 0x0b, 0x10, 0x2f,
+0x00, 0x14, 0x14, 0x5f, 0x00, 0x04, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0xbc,
+0xdd, 0x2f, 0x38, 0x8e, 0x2a, 0x0a, 0x80, 0x06, 0x84, 0x20, 0x44, 0x20, 0x00, 0x10, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xa6, 0xf7, 0x04, 0x84, 0x00, 0x02, 0x58, 0x01,
+0x80, 0x40, 0xae, 0x37, 0xa4, 0x73, 0xb7, 0x06, 0x40, 0x50, 0xb8, 0x09, 0x40, 0x52, 0xb8, 0x08,
+0x58, 0x22, 0x86, 0x40, 0xac, 0xb3, 0xb4, 0x9f, 0x10, 0x72, 0x01, 0xb8, 0x00, 0xae, 0x00, 0xa1,
+0x50, 0x75, 0x00, 0x01, 0x97, 0xbc, 0x10, 0x6e, 0x00, 0xa1, 0xd5, 0x9e, 0xec, 0x0c, 0x3a, 0x6f,
+0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x83, 0x80, 0x50, 0x00, 0x00, 0xb8,
+0x46, 0x40, 0x04, 0x10, 0xf0, 0x81, 0x58, 0x42, 0x08, 0x00, 0x00, 0x7e, 0x00, 0xa0, 0x00, 0x52,
+0x01, 0xac, 0x94, 0xbc, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x74, 0x50, 0xa3, 0x80, 0x20,
+0x40, 0x6e, 0x08, 0x00, 0xd7, 0x54, 0x01, 0xe3, 0x00, 0x07, 0x54, 0x5f, 0x00, 0x80, 0xc5, 0x4f,
+0x02, 0x83, 0x00, 0x03, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x78, 0xdd, 0x2f,
+0x98, 0x7f, 0x54, 0x94, 0x3f, 0xff, 0x81, 0x00, 0x9c, 0x09, 0x95, 0x03, 0x40, 0x3e, 0x10, 0x00,
+0xf0, 0x01, 0xb4, 0x9f, 0x4e, 0x83, 0x00, 0x06, 0x44, 0x31, 0x00, 0x00, 0xbb, 0xad, 0xd5, 0x37,
+0x39, 0xee, 0x2a, 0x02, 0x84, 0x40, 0x12, 0x9f, 0x00, 0x06, 0x80, 0x3e, 0xa1, 0x59, 0x10, 0x2f,
+0x00, 0x14, 0x14, 0x5f, 0x00, 0x04, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0xbc,
+0xdd, 0x2f, 0x38, 0x8e, 0x2a, 0x0a, 0x80, 0x06, 0x84, 0x20, 0x44, 0x20, 0x00, 0x10, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xa6, 0xf7, 0x04, 0x84, 0x00, 0x02, 0x58, 0x11,
+0x80, 0x40, 0xae, 0x77, 0xa5, 0x33, 0xb7, 0x06, 0x40, 0x52, 0x38, 0x09, 0x40, 0x52, 0xb8, 0x08,
+0x58, 0x22, 0x80, 0xc8, 0xac, 0xb3, 0xb4, 0x9f, 0x10, 0x72, 0x01, 0xa8, 0x00, 0xae, 0x00, 0xa0,
+0x50, 0x75, 0x00, 0x01, 0x97, 0xbc, 0x10, 0x6e, 0x00, 0xa0, 0xd5, 0xa0, 0xec, 0x0c, 0x3a, 0x6f,
+0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xfc, 0xb6, 0x20, 0xa8, 0xc1, 0x80, 0xc1,
+0xa0, 0x43, 0x84, 0xe0, 0x81, 0x23, 0x81, 0x02, 0xa8, 0x42, 0x47, 0xc0, 0x01, 0x02, 0x59, 0xce,
+0x07, 0x08, 0x81, 0x47, 0xd5, 0x0c, 0xdd, 0x3c, 0xa6, 0xb7, 0x44, 0x3f, 0xff, 0xc0, 0x40, 0x01,
+0x0c, 0x04, 0xae, 0x37, 0x1c, 0xa4, 0x00, 0x01, 0x9d, 0xf9, 0x8c, 0xd0, 0x80, 0x06, 0x84, 0x20,
+0x44, 0x20, 0x00, 0x10, 0xe2, 0xe9, 0xe9, 0xf0, 0xec, 0x04, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xec, 0xb6, 0x20, 0xa8, 0xc1, 0x46, 0x80, 0x04, 0x10, 0x04, 0x90,
+0x00, 0x03, 0x58, 0x84, 0x09, 0xb0, 0x14, 0x90, 0x00, 0x02, 0x44, 0x70, 0x06, 0x40, 0x83, 0x83,
+0x80, 0xc1, 0x46, 0x30, 0x00, 0x0c, 0x58, 0x31, 0x82, 0x64, 0x40, 0x10, 0x20, 0x03, 0x44, 0x50,
+0x00, 0xc8, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x74, 0x40, 0x41, 0x84, 0x1a, 0x40, 0x40,
+0x04, 0x1b, 0x40, 0x82, 0x84, 0x1b, 0x40, 0x83, 0x84, 0x1a, 0x84, 0xe0, 0xf4, 0x83, 0x81, 0x42,
+0x46, 0x40, 0x01, 0x02, 0x58, 0x42, 0x07, 0x08, 0x81, 0x27, 0x54, 0x34, 0x3f, 0xff, 0xd5, 0x26,
+0xf3, 0x81, 0xf4, 0x82, 0xdd, 0x24, 0xf0, 0x03, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x78,
+0xdd, 0x2f, 0xf3, 0x01, 0xf4, 0x02, 0xc0, 0x20, 0x12, 0x80, 0x00, 0x06, 0x10, 0x90, 0x00, 0x0e,
+0x10, 0x90, 0x00, 0x0f, 0xa6, 0x77, 0x9d, 0xf9, 0x55, 0xe0, 0x80, 0x3f, 0x11, 0xe3, 0x00, 0x07,
+0xa5, 0x73, 0x40, 0x12, 0xb8, 0x09, 0x40, 0x10, 0xb8, 0x08, 0x41, 0xe0, 0x8c, 0x04, 0x13, 0xe3,
+0x00, 0x03, 0xa0, 0x82, 0xaa, 0xb4, 0x1c, 0x05, 0x00, 0x01, 0x80, 0x06, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x10, 0xe2, 0xfc, 0xe9, 0xd6, 0xec, 0x14, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x20, 0x04, 0x00, 0x04, 0x61, 0x00, 0x09, 0x84, 0x01, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x88, 0xd0, 0xdd, 0x2f, 0x40, 0x03, 0x7c, 0x0a, 0x84, 0xa1, 0xd8, 0x0b,
+0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x04, 0xb4, 0x80, 0x54, 0x32, 0x01, 0xfd, 0x58, 0x11,
+0x80, 0x02, 0xd5, 0x08, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x04, 0xb4, 0xa0, 0x54, 0x12,
+0x81, 0xfd, 0xb6, 0x20, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xd0, 0xdd, 0x2f,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x46, 0x60,
+0x04, 0x00, 0x58, 0x63, 0x00, 0x04, 0x84, 0xe0, 0x85, 0x08, 0x46, 0x90, 0x00, 0x03, 0x58, 0x94,
+0x88, 0xd0, 0x84, 0x01, 0x4b, 0xe0, 0x24, 0x01, 0xb4, 0x46, 0x99, 0xff, 0x54, 0x11, 0x00, 0x08,
+0x84, 0x01, 0x97, 0xf8, 0xc1, 0x03, 0x40, 0x73, 0x80, 0x04, 0x05, 0xe3, 0x00, 0x00, 0x8f, 0x01,
+0x54, 0x5f, 0x01, 0xfe, 0x58, 0x42, 0x80, 0x01, 0xb6, 0x86, 0x54, 0x84, 0x00, 0xff, 0x4b, 0xe0,
+0x24, 0x01, 0xb4, 0x66, 0x54, 0x01, 0x81, 0xfe, 0xb6, 0x06, 0x4e, 0x83, 0xff, 0xe4, 0x84, 0x08,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xd0, 0xdd, 0x2f, 0x80, 0x07, 0xec, 0x04, 0x3a, 0x6f,
+0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x46, 0x60, 0x04, 0x00, 0x97, 0xc0,
+0x58, 0x63, 0x00, 0x04, 0x85, 0x28, 0x46, 0x80, 0x00, 0x03, 0x58, 0x84, 0x08, 0xd0, 0xb4, 0x46,
+0x40, 0x33, 0x9c, 0x09, 0x94, 0x5a, 0x55, 0xe1, 0x01, 0xfb, 0x40, 0x00, 0xf8, 0x04, 0xb6, 0x06,
+0x84, 0x01, 0x4b, 0xe0, 0x20, 0x01, 0xb4, 0xa6, 0x84, 0x01, 0x54, 0x42, 0x81, 0xfe, 0x40, 0x32,
+0x00, 0x04, 0xb6, 0x66, 0x8f, 0x21, 0x4b, 0xe0, 0x20, 0x01, 0xb4, 0x46, 0x84, 0x01, 0x54, 0x11,
+0x01, 0xfe, 0xb6, 0x26, 0x99, 0xff, 0x54, 0x94, 0x80, 0xff, 0x4b, 0xe0, 0x20, 0x01, 0x97, 0xf8,
+0x4e, 0x93, 0xff, 0xdf, 0x84, 0x0a, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xd0, 0xdd, 0x2f,
+0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x20, 0x04, 0x00,
+0x04, 0x01, 0x00, 0x09, 0x84, 0xa1, 0x90, 0x1f, 0xd8, 0x15, 0x46, 0x60, 0x04, 0x00, 0x58, 0x63,
+0x00, 0x04, 0xb4, 0x26, 0x55, 0xe0, 0x81, 0xfd, 0x58, 0x5f, 0x00, 0x02, 0xb6, 0xa6, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x88, 0xd0, 0xdd, 0x2f, 0xb4, 0x86, 0x54, 0x32, 0x01, 0xfd, 0xb6, 0x66,
+0xd5, 0x08, 0x80, 0xc2, 0xa0, 0xf1, 0x54, 0x21, 0x81, 0xfd, 0x58, 0x01, 0x00, 0x02, 0xa8, 0x31,
+0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xd0, 0xdd, 0x2f, 0x3a, 0x6f, 0x98, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x82, 0xe8,
+0xdd, 0x2f, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x82, 0x74, 0xdd, 0x2f, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x82, 0x08, 0xdd, 0x2f, 0x80, 0xc0, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x81, 0xb0, 0xdd, 0x2f, 0x96, 0x34, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xfc, 0x97, 0x81, 0x97, 0xca, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x82, 0xe8, 0xdd, 0x2f,
+0x84, 0x03, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x82, 0x74, 0xdd, 0x2f, 0xcf, 0x05, 0x44, 0x00,
+0xfc, 0x00, 0x40, 0x63, 0x00, 0x04, 0x46, 0x70, 0x00, 0x03, 0x58, 0x73, 0x82, 0x74, 0x40, 0x03,
+0x20, 0x09, 0x4b, 0xe0, 0x1c, 0x01, 0x96, 0x30, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x82, 0x08, 0xdd, 0x2f, 0x80, 0xc0, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x81, 0xb0,
+0xdd, 0x2f, 0x80, 0x06, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc,
+0x46, 0x60, 0x00, 0x03, 0x58, 0x63, 0x02, 0x74, 0x54, 0x80, 0x80, 0xff, 0x97, 0xc1, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x82, 0xe8, 0xdd, 0x2f, 0x84, 0x02, 0xdd, 0x26, 0x40, 0x03, 0xa0, 0x09,
+0xdd, 0x26, 0x96, 0x38, 0xdd, 0x26, 0x80, 0x08, 0xdd, 0x26, 0x46, 0x60, 0x00, 0x03, 0x58, 0x63,
+0x03, 0x44, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x81, 0xb0, 0xdd, 0x2f, 0x4b, 0xe0, 0x18, 0x01,
+0xc8, 0xfe, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x82, 0xe8, 0xdd, 0x2f, 0x84, 0x04, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x82, 0x74, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x81, 0xb0, 0xdd, 0x2f, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x82, 0xe8, 0xdd, 0x2f, 0x84, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x82, 0x74, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x81, 0xb0, 0xdd, 0x2f, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x04, 0x00, 0x80, 0x01, 0x84, 0x48,
+0x14, 0x20, 0x81, 0x06, 0x14, 0x20, 0x01, 0x0a, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x00, 0x0c,
+0x04, 0x20, 0x00, 0x5c, 0x46, 0x30, 0x04, 0x00, 0x9c, 0x51, 0x14, 0x10, 0x00, 0x5c, 0x04, 0x51,
+0x81, 0x00, 0x80, 0x03, 0x58, 0x42, 0x80, 0x11, 0x14, 0x41, 0x81, 0x00, 0x04, 0x20, 0x01, 0x06,
+0x58, 0x11, 0x00, 0x80, 0x14, 0x10, 0x01, 0x06, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x30, 0x04, 0x00,
+0x80, 0x03, 0x44, 0x20, 0x00, 0x4e, 0x44, 0x10, 0x00, 0xa8, 0x14, 0x21, 0x81, 0x04, 0x14, 0x10,
+0x01, 0x06, 0xdd, 0x9e, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x5c, 0xdd, 0x9e, 0x92, 0x00,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x05, 0x90, 0x84, 0x80, 0xb6, 0x80, 0x84, 0x21, 0xb4, 0x60,
+0xa8, 0xc1, 0xa8, 0x42, 0xb4, 0x40, 0xa1, 0x42, 0x9f, 0x29, 0x40, 0x32, 0x08, 0x02, 0x9c, 0x5a,
+0x95, 0x4a, 0x98, 0xc5, 0x46, 0x40, 0x00, 0x0c, 0x58, 0x42, 0x05, 0x7c, 0xa9, 0x19, 0xb4, 0x40,
+0x9c, 0x51, 0xb6, 0x20, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x81, 0x70,
+0xb4, 0x41, 0x98, 0x02, 0xd5, 0x03, 0x64, 0x00, 0x00, 0x00, 0xb4, 0x81, 0x9a, 0xe0, 0x4e, 0x35,
+0xff, 0xfc, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x80, 0xc0, 0x50, 0x0f, 0x80, 0x04,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0xa0, 0x32, 0xc0, 0x2d, 0x84, 0xa2,
+0xd0, 0x2b, 0x84, 0xa3, 0xd8, 0x02, 0xd5, 0x28, 0xa0, 0x33, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x57,
+0x80, 0x5d, 0xd0, 0x07, 0xa0, 0x41, 0x05, 0xe3, 0x00, 0x01, 0x40, 0x50, 0xf8, 0x00, 0xa9, 0x41,
+0xa0, 0x73, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x01, 0x74, 0x4c, 0x13, 0x40, 0x05, 0x84, 0x40,
+0xb6, 0x40, 0xd5, 0x0d, 0x05, 0xe3, 0x00, 0x04, 0x14, 0x1f, 0x00, 0x03, 0xa1, 0x33, 0xa1, 0x74,
+0xa9, 0x64, 0xb4, 0x60, 0x4c, 0x33, 0x40, 0x04, 0xa0, 0x73, 0xb6, 0x20, 0x84, 0x00, 0x84, 0x43,
+0xa8, 0x34, 0xa8, 0xb2, 0xa8, 0x33, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c,
+0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xf4, 0x80, 0xe1, 0x80, 0xc0, 0xc1, 0x7a, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0x84, 0x01, 0xa8, 0x32, 0x46, 0x30, 0x00, 0x0c, 0x04, 0x21,
+0x80, 0x5d, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x01, 0x7c, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10,
+0x81, 0x70, 0xca, 0x0b, 0xa9, 0xb3, 0xa9, 0xb4, 0x14, 0x61, 0x80, 0x5d, 0x46, 0xf0, 0x00, 0x0c,
+0x14, 0x77, 0x80, 0x5e, 0xa9, 0xf1, 0xd5, 0x39, 0xb4, 0x21, 0xb4, 0x00, 0xe2, 0x20, 0xe8, 0x03,
+0x9a, 0x01, 0xd5, 0x02, 0x9a, 0x08, 0x44, 0x10, 0x00, 0x21, 0x40, 0x00, 0x04, 0x37, 0xa0, 0x51,
+0xe2, 0x01, 0xe8, 0x03, 0x9a, 0x08, 0xd5, 0x02, 0x84, 0x00, 0xa8, 0x11, 0xa0, 0xd1, 0x46, 0xf0,
+0x00, 0x0c, 0x04, 0x17, 0x80, 0x5d, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x37, 0x80, 0x5e, 0xa0, 0x11,
+0xe2, 0xe0, 0xe8, 0x0b, 0x9a, 0x07, 0xa8, 0x11, 0x46, 0x00, 0x00, 0x0c, 0x04, 0x50, 0x00, 0x5d,
+0xda, 0x20, 0x14, 0x60, 0x00, 0x5d, 0xd5, 0x1d, 0xa0, 0x93, 0x9b, 0xf8, 0x4c, 0x20, 0xff, 0xf1,
+0xd5, 0x18, 0x14, 0x00, 0x80, 0x5e, 0xc0, 0x0c, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x81, 0x70,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x01, 0x7c, 0xb4, 0x41, 0xb6, 0x40, 0xd5, 0x03, 0x84, 0x22,
+0xa8, 0x72, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c, 0xdd, 0x2f, 0xd5, 0x16,
+0xa8, 0xb3, 0xa0, 0x14, 0x46, 0x10, 0x00, 0x0c, 0xa8, 0x34, 0x05, 0xe1, 0x00, 0x04, 0x14, 0x6f,
+0x00, 0x03, 0xa9, 0x94, 0xa9, 0xf1, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x37, 0x80, 0x5d, 0x04, 0x40,
+0x80, 0x5e, 0xa0, 0x19, 0xe2, 0x80, 0xe8, 0xd6, 0xd5, 0xe5, 0xec, 0x0c, 0x3a, 0x6f, 0x9c, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0,
+0x00, 0x04, 0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x85, 0x90,
+0xa0, 0xc9, 0xa1, 0x4a, 0xf0, 0x01, 0x9f, 0x29, 0x40, 0x22, 0x0c, 0x02, 0x9d, 0x92, 0x95, 0x72,
+0x99, 0x0d, 0xa1, 0xa1, 0xa0, 0xc9, 0x9c, 0x99, 0xa8, 0x89, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x80, 0x0c, 0xdd, 0x2f, 0x84, 0x00, 0xa8, 0x34, 0xb6, 0x06, 0xa8, 0x31, 0xa8, 0x32, 0xa8, 0x33,
+0x80, 0x06, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x17, 0x80, 0x5c, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x27,
+0x80, 0x98, 0x9a, 0x0a, 0x4e, 0x05, 0x00, 0x07, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x81, 0x88,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x04, 0x01,
+0x84, 0x21, 0xa8, 0x42, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x04, 0x01, 0x84, 0x20, 0xb6, 0x20,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x04, 0x01, 0x96, 0x00, 0xa8, 0x09, 0xdd, 0x9e, 0x92, 0x00,
+0x46, 0x00, 0x04, 0x01, 0x84, 0x22, 0xa8, 0x42, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x04, 0x01,
+0x04, 0x00, 0x81, 0x8a, 0x96, 0x04, 0xc0, 0x04, 0x84, 0x41, 0x14, 0x20, 0x81, 0x8a, 0xdd, 0x9e,
+0x46, 0x20, 0x04, 0x01, 0xa0, 0x52, 0x56, 0x00, 0x80, 0x04, 0x42, 0x00, 0x08, 0x0b, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0x50, 0x04, 0x00, 0x46, 0x60, 0x04, 0x01, 0x58, 0x63, 0x06, 0x8c,
+0x04, 0x82, 0x80, 0x80, 0xb4, 0x86, 0x46, 0x70, 0x00, 0x03, 0x58, 0x73, 0x88, 0xdc, 0x58, 0x02,
+0x00, 0x40, 0xb6, 0x06, 0x44, 0x00, 0x00, 0xff, 0xdd, 0x27, 0x44, 0x00, 0x00, 0xff, 0xdd, 0x27,
+0x44, 0x00, 0x00, 0xff, 0xdd, 0x27, 0x44, 0x00, 0x00, 0xff, 0xdd, 0x27, 0xb4, 0x66, 0x42, 0x11,
+0x98, 0x09, 0x54, 0x04, 0x00, 0x03, 0xb6, 0x26, 0xc8, 0x14, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00,
+0x02, 0x04, 0xb4, 0x80, 0x46, 0x3f, 0xf0, 0xff, 0x58, 0x22, 0x00, 0x01, 0xb6, 0x40, 0x05, 0xe0,
+0x00, 0x00, 0x58, 0x31, 0x8f, 0xff, 0x50, 0x10, 0x00, 0x08, 0x40, 0x2f, 0x0c, 0x02, 0xd5, 0x19,
+0x84, 0xa1, 0xd8, 0x1c, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x04, 0xb4, 0xa0, 0x42, 0x42,
+0x80, 0x09, 0xb6, 0x80, 0x46, 0x3f, 0xf0, 0xff, 0xb4, 0x40, 0x58, 0x31, 0x8f, 0xff, 0x41, 0xe1,
+0x0c, 0x02, 0x15, 0xe0, 0x00, 0x00, 0xb4, 0xa0, 0x50, 0x10, 0x00, 0x08, 0x42, 0x22, 0xd0, 0x08,
+0xb6, 0x40, 0xb4, 0x41, 0x58, 0x01, 0x03, 0x00, 0xb6, 0x01, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0x9c, 0x3c, 0x96, 0xd8, 0x96, 0x90, 0xcb, 0x15, 0x54, 0x21, 0x00, 0xfc, 0xd5, 0x0f,
+0x38, 0x41, 0x84, 0x02, 0x9c, 0xdc, 0x40, 0x52, 0x60, 0x09, 0x40, 0x72, 0x20, 0x09, 0x40, 0x62,
+0x40, 0x09, 0xa9, 0xc1, 0xa9, 0x82, 0xa9, 0x43, 0xb6, 0x80, 0x8c, 0x10, 0x4c, 0x31, 0x7f, 0xf2,
+0xd5, 0x0c, 0x84, 0xa1, 0xdb, 0x0a, 0x84, 0x60, 0xd5, 0x05, 0xa3, 0xc9, 0x38, 0x71, 0x80, 0x08,
+0x9c, 0xd9, 0x97, 0x18, 0xe2, 0x82, 0xe9, 0xfa, 0x3a, 0x6f, 0x9c, 0x04, 0xdd, 0x9e, 0x92, 0x00,
+0x96, 0x01, 0x96, 0x89, 0xe2, 0x02, 0xe8, 0x02, 0x80, 0x20, 0x96, 0x09, 0xdd, 0x9e, 0x92, 0x00,
+0x96, 0x00, 0x96, 0x88, 0xe2, 0x02, 0xe8, 0x02, 0x80, 0x20, 0x96, 0x08, 0xdd, 0x9e, 0x92, 0x00,
+0xd5, 0x03, 0x92, 0x00, 0x9e, 0x01, 0x96, 0x00, 0xc8, 0xfd, 0xdd, 0x9e, 0xd5, 0x08, 0x44, 0x10,
+0x00, 0xff, 0x92, 0x00, 0x9e, 0x49, 0x96, 0x48, 0xc9, 0xfd, 0x9e, 0x01, 0x96, 0x00, 0xc8, 0xf8,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0xbc, 0x96, 0x00, 0x54, 0xa0,
+0x80, 0xff, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x84, 0x4c, 0x97, 0xd1, 0x40, 0x80, 0x04, 0x00,
+0x84, 0xc0, 0x46, 0x90, 0x00, 0x03, 0x58, 0x94, 0x83, 0x7c, 0xd5, 0x09, 0x4b, 0xe0, 0x24, 0x01,
+0x9d, 0xb1, 0x9d, 0xf9, 0x18, 0x04, 0x00, 0x01, 0x97, 0xb0, 0x97, 0xf9, 0x80, 0x07, 0x84, 0x20,
+0xe2, 0xca, 0xe9, 0xf5, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0x46, 0x00, 0x04, 0x00, 0x04, 0x10, 0x00, 0x09, 0x4e, 0x14, 0x00, 0x04, 0x84, 0x21, 0xd5, 0x02,
+0x84, 0x20, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x17, 0x85, 0x89, 0x44, 0x00, 0x00, 0x11, 0x84, 0x20,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x83, 0x7c, 0xdd, 0x2f, 0x54, 0x30, 0x00, 0x0f, 0x84, 0xa2,
+0xdb, 0x0e, 0x54, 0x40, 0x00, 0x10, 0xc4, 0x09, 0x46, 0x50, 0x04, 0x00, 0x05, 0xe2, 0x80, 0x08,
+0x42, 0x6f, 0x2c, 0x09, 0x14, 0x62, 0x80, 0x08, 0x84, 0x20, 0xd5, 0x02, 0x84, 0x21, 0x46, 0xf0,
+0x00, 0x09, 0x10, 0x17, 0x85, 0x88, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x88, 0xc8, 0x47,
+0x46, 0x60, 0x00, 0x03, 0x58, 0x63, 0x08, 0xf8, 0x84, 0x02, 0x84, 0x21, 0x94, 0x83, 0xdd, 0x26,
+0x84, 0x08, 0x84, 0x26, 0x44, 0x20, 0x00, 0x12, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x24, 0x84, 0x22,
+0x9e, 0x82, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x2a, 0x84, 0x23, 0x94, 0x8b, 0xdd, 0x26, 0x44, 0x00,
+0x00, 0x2e, 0x84, 0x23, 0x44, 0x20, 0x00, 0x1b, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x35, 0x84, 0x21,
+0x44, 0x20, 0x00, 0x1e, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x39, 0x84, 0x21, 0x44, 0x20, 0x00, 0x1f,
+0xdd, 0x26, 0x44, 0x00, 0x00, 0x76, 0x84, 0x21, 0x94, 0x8d, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x7a,
+0x84, 0x21, 0x44, 0x20, 0x00, 0x21, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x78, 0x84, 0x21, 0x44, 0x20,
+0x00, 0x26, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x96, 0x84, 0x21, 0x44, 0x20, 0x00, 0x24, 0xdd, 0x26,
+0x44, 0x00, 0x00, 0x9d, 0x84, 0x21, 0x44, 0x20, 0x00, 0x25, 0xdd, 0x26, 0x3a, 0x6f, 0x98, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xec, 0x40, 0x80, 0x00, 0x13, 0x54, 0x94,
+0x00, 0xff, 0x46, 0x70, 0x04, 0x01, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x04, 0x4c, 0x97, 0x08,
+0x96, 0x92, 0x96, 0xda, 0x89, 0x20, 0x58, 0x73, 0x84, 0x00, 0x84, 0xc0, 0x47, 0xc0, 0x00, 0x03,
+0x59, 0xce, 0x03, 0x7c, 0x85, 0x47, 0xd5, 0x1a, 0xc3, 0x0b, 0xf2, 0x82, 0xf3, 0x81, 0xf4, 0x83,
+0x80, 0x08, 0x84, 0x20, 0xdd, 0x3c, 0xf2, 0x02, 0xf3, 0x01, 0xf4, 0x03, 0xd5, 0x03, 0x00, 0x04,
+0x80, 0x00, 0x9c, 0x71, 0x8d, 0x01, 0x56, 0x63, 0x00, 0x01, 0xc2, 0x03, 0x40, 0x05, 0x18, 0x1a,
+0xaa, 0x39, 0x97, 0x88, 0x40, 0x84, 0x00, 0x13, 0x8d, 0x21, 0xe2, 0xc4, 0xe9, 0xe6, 0xec, 0x14,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0, 0x00, 0x09, 0x02, 0x07, 0x82, 0xbe, 0xc8, 0x02,
+0xd5, 0x03, 0x84, 0xa1, 0xd8, 0x0b, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x07, 0x85, 0x82, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x87, 0x5c, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x85, 0xc8, 0x1c, 0x46, 0xf0, 0x00, 0x09,
+0x02, 0x07, 0x82, 0xbe, 0x84, 0xa1, 0xd8, 0x13, 0x46, 0x40, 0x04, 0x01, 0x04, 0x12, 0x01, 0xa3,
+0x46, 0x00, 0x04, 0x10, 0x59, 0xe0, 0x80, 0x08, 0x54, 0x5f, 0x00, 0xff, 0x14, 0x52, 0x01, 0xa3,
+0x58, 0x00, 0x02, 0x38, 0xb4, 0x60, 0x42, 0x11, 0xc4, 0x08, 0xd5, 0x36, 0x84, 0xa2, 0xd8, 0x50,
+0xd5, 0x49, 0x84, 0xa2, 0xd8, 0x4d, 0x46, 0xf0, 0x00, 0x09, 0x02, 0x07, 0x82, 0xbe, 0xc8, 0x48,
+0x46, 0xf0, 0x00, 0x09, 0x02, 0x07, 0x82, 0xbf, 0x44, 0x50, 0x00, 0x81, 0xd0, 0x1d, 0x5c, 0xf0,
+0x00, 0x82, 0xe8, 0x08, 0xe6, 0x0a, 0xe8, 0x03, 0xc8, 0x0f, 0xd5, 0x34, 0x9f, 0x69, 0xd8, 0x38,
+0xd5, 0x31, 0x9c, 0x6a, 0x4c, 0x00, 0x80, 0x20, 0xe2, 0x01, 0xe9, 0x18, 0x9d, 0x49, 0xd0, 0x20,
+0x9d, 0x4a, 0xd8, 0x2e, 0xd5, 0x22, 0x97, 0x40, 0x46, 0x40, 0x04, 0x01, 0x94, 0x2d, 0x58, 0x42,
+0x00, 0x08, 0x98, 0x04, 0xd5, 0x05, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x38, 0x05, 0xe0,
+0x00, 0x00, 0x58, 0x1f, 0x00, 0x40, 0xb6, 0x20, 0xd5, 0x15, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00,
+0x00, 0x58, 0xd5, 0xf6, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x78, 0xd5, 0xf1, 0x46, 0x00,
+0x04, 0x01, 0x58, 0x00, 0x00, 0x98, 0xd5, 0xec, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0xb8,
+0xd5, 0xe7, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x87, 0x5c, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x85, 0xc0, 0x05,
+0x84, 0xa2, 0x4c, 0x02, 0xc0, 0xa3, 0xd5, 0x1a, 0x46, 0xf0, 0x00, 0x09, 0x02, 0x37, 0x82, 0xbe,
+0x84, 0xa1, 0x4c, 0x32, 0xc0, 0x9b, 0x46, 0x30, 0x04, 0x01, 0x04, 0x41, 0x81, 0xa3, 0x46, 0x50,
+0x04, 0x10, 0x54, 0x22, 0x00, 0xf7, 0x14, 0x21, 0x81, 0xa3, 0x04, 0x02, 0x80, 0x8e, 0x43, 0xe0,
+0x44, 0x09, 0x15, 0xe2, 0x80, 0x8e, 0x48, 0x00, 0x00, 0x83, 0x46, 0xf0, 0x00, 0x09, 0x02, 0x57,
+0x82, 0xbe, 0x4e, 0x53, 0x00, 0x83, 0x46, 0x20, 0x00, 0x09, 0x02, 0x01, 0x02, 0xbf, 0x44, 0x50,
+0x00, 0x82, 0xd0, 0x3b, 0x5c, 0xf0, 0x00, 0x83, 0xe8, 0x07, 0xc0, 0x71, 0xe6, 0x0a, 0xe9, 0x0c,
+0x9f, 0x69, 0xd8, 0x6d, 0xd5, 0x25, 0x9c, 0x6a, 0x4c, 0x00, 0x80, 0x4a, 0xe2, 0x01, 0xe9, 0x3a,
+0x9d, 0x49, 0xd8, 0x65, 0xd5, 0x51, 0x55, 0xe0, 0x00, 0xff, 0x46, 0x50, 0x04, 0x01, 0x58, 0x52,
+0x86, 0x88, 0x58, 0x3f, 0x00, 0x60, 0x15, 0xe2, 0x80, 0x00, 0x40, 0x0f, 0x14, 0x08, 0xb6, 0x65,
+0x50, 0x12, 0xf9, 0x80, 0x41, 0xe0, 0x04, 0x00, 0xb4, 0x7e, 0x42, 0x11, 0x98, 0x09, 0xb6, 0x3e,
+0x00, 0x01, 0x05, 0x7e, 0x58, 0x40, 0x00, 0x60, 0xb6, 0x05, 0xb6, 0x85, 0xd5, 0x48, 0x46, 0x00,
+0x04, 0x01, 0x58, 0x00, 0x06, 0x88, 0x44, 0x30, 0x00, 0x11, 0x44, 0x20, 0x00, 0x71, 0xb6, 0x60,
+0x50, 0x10, 0x79, 0xb0, 0xb6, 0x40, 0xd5, 0x34, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x06, 0x88,
+0x44, 0x30, 0x00, 0x12, 0x44, 0x20, 0x00, 0x72, 0xb6, 0x60, 0x50, 0x10, 0x79, 0xd0, 0xb6, 0x40,
+0xd5, 0x27, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x06, 0x88, 0x44, 0x30, 0x00, 0x13, 0x44, 0x20,
+0x00, 0x73, 0xb6, 0x60, 0x50, 0x10, 0x79, 0xf0, 0xb6, 0x40, 0xd5, 0x1a, 0x46, 0x00, 0x04, 0x01,
+0x58, 0x00, 0x06, 0x88, 0x44, 0x30, 0x00, 0x14, 0x44, 0x20, 0x00, 0x74, 0xb6, 0x60, 0x50, 0x10,
+0x7a, 0x10, 0xb6, 0x40, 0xd5, 0x0d, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x06, 0x88, 0x44, 0x30,
+0x00, 0x15, 0x44, 0x20, 0x00, 0x75, 0xb6, 0x60, 0xb6, 0x40, 0x50, 0x10, 0x7a, 0x30, 0x05, 0xe0,
+0x80, 0x00, 0x42, 0x4f, 0x18, 0x09, 0xb6, 0x81, 0xb6, 0x60, 0xb6, 0x40, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x5c,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xf4, 0x96, 0x92, 0x97, 0xc1, 0x97, 0x8b, 0xf2, 0x81, 0x47, 0xc0, 0x00, 0x03, 0x59, 0xce,
+0x0a, 0x34, 0x46, 0xa0, 0x00, 0x03, 0x58, 0xa5, 0x07, 0x74, 0x46, 0x90, 0x00, 0x03, 0x58, 0x94,
+0x87, 0x80, 0xd5, 0x20, 0x96, 0x30, 0x44, 0x10, 0x00, 0x40, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x88, 0xc0, 0xdd, 0x2f, 0x81, 0x00, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0xa0, 0xdd, 0x2f,
+0xc0, 0xfb, 0xf3, 0x01, 0x80, 0x28, 0x84, 0x40, 0x80, 0x07, 0xdd, 0x3c, 0x50, 0x63, 0x7f, 0xc0,
+0x80, 0x08, 0x50, 0x73, 0x80, 0x40, 0x4b, 0xe0, 0x28, 0x01, 0x97, 0xb3, 0x4b, 0xe0, 0x24, 0x01,
+0x97, 0xf9, 0x4e, 0x64, 0xff, 0xe1, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x57, 0x85, 0x84, 0x40, 0x80, 0x00, 0x10,
+0x4c, 0x54, 0x40, 0x31, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x04, 0x4c, 0x44, 0x40, 0x00, 0x40,
+0x84, 0x60, 0x10, 0x30, 0x00, 0x8e, 0x10, 0x40, 0x00, 0x8d, 0x10, 0x40, 0x00, 0x3e, 0x10, 0x30,
+0x00, 0x3f, 0x10, 0x40, 0x00, 0x45, 0x10, 0x30, 0x00, 0x46, 0x10, 0x40, 0x00, 0x4c, 0x10, 0x30,
+0x00, 0x4d, 0x10, 0x40, 0x00, 0x53, 0x10, 0x30, 0x00, 0x54, 0x10, 0x40, 0x00, 0x5a, 0x10, 0x30,
+0x00, 0x5b, 0x10, 0x40, 0x00, 0x61, 0x10, 0x30, 0x00, 0x62, 0x10, 0x40, 0x00, 0x68, 0x10, 0x30,
+0x00, 0x69, 0x10, 0x40, 0x00, 0x6f, 0x10, 0x30, 0x00, 0x70, 0x10, 0x40, 0x00, 0x86, 0x10, 0x30,
+0x00, 0x87, 0x46, 0x60, 0x00, 0x09, 0x00, 0x03, 0x05, 0x80, 0x44, 0x10, 0x00, 0x40, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x88, 0xc0, 0xdd, 0x2f, 0x80, 0x20, 0x80, 0x48, 0x84, 0x60, 0x80, 0xe0,
+0x44, 0x00, 0x00, 0x28, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8a, 0x34, 0xdd, 0x2f, 0x80, 0x07,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x74, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x87, 0x80, 0xdd, 0x2f, 0x00, 0x53, 0x05, 0x80, 0x5c, 0xf2, 0x80, 0x41, 0xe9, 0x37, 0x46, 0x60,
+0x00, 0x03, 0x58, 0x63, 0x07, 0xa0, 0x4b, 0xe0, 0x18, 0x01, 0xc0, 0xfe, 0x46, 0xf0, 0x00, 0x09,
+0x00, 0x67, 0x84, 0x78, 0x84, 0xa1, 0x46, 0x00, 0x00, 0x09, 0x46, 0x20, 0x00, 0x03, 0x58, 0x21,
+0x08, 0xc0, 0xde, 0x05, 0x00, 0x00, 0x05, 0x80, 0x84, 0x2a, 0xd5, 0x05, 0x00, 0x00, 0x05, 0x80,
+0x44, 0x10, 0x00, 0x36, 0x50, 0x00, 0x7f, 0xc0, 0x96, 0x00, 0x4b, 0xe0, 0x08, 0x01, 0x84, 0x40,
+0x80, 0x20, 0x80, 0xc0, 0x80, 0x62, 0x44, 0x00, 0x00, 0x68, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x8a, 0x34, 0xdd, 0x2f, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x74, 0xdd, 0x2f,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0x46, 0x30, 0x00, 0x09, 0x58, 0x31,
+0x84, 0x4c, 0x84, 0x40, 0x84, 0x82, 0x10, 0x41, 0x80, 0x8e, 0x10, 0x21, 0x80, 0x8d, 0x10, 0x21,
+0x80, 0x3e, 0x10, 0x41, 0x80, 0x3f, 0x10, 0x21, 0x80, 0x45, 0x10, 0x41, 0x80, 0x46, 0x10, 0x21,
+0x80, 0x4c, 0x10, 0x41, 0x80, 0x4d, 0x10, 0x21, 0x80, 0x53, 0x10, 0x41, 0x80, 0x54, 0x10, 0x21,
+0x80, 0x5a, 0x10, 0x41, 0x80, 0x5b, 0x10, 0x21, 0x80, 0x61, 0x10, 0x41, 0x80, 0x62, 0x10, 0x21,
+0x80, 0x68, 0x10, 0x41, 0x80, 0x69, 0x10, 0x21, 0x80, 0x6f, 0x10, 0x41, 0x80, 0x70, 0x10, 0x21,
+0x80, 0x86, 0x10, 0x41, 0x80, 0x87, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc,
+0xef, 0xfc, 0x46, 0x80, 0x00, 0x09, 0x02, 0x04, 0x02, 0xbe, 0x84, 0xa3, 0x40, 0x10, 0x20, 0x09,
+0xd1, 0x45, 0xe6, 0x24, 0xe8, 0x07, 0x84, 0xa1, 0xd1, 0x0d, 0x84, 0xa2, 0x4c, 0x12, 0xc0, 0x98,
+0xd5, 0x34, 0x84, 0xa7, 0xd1, 0x34, 0x84, 0xaf, 0xd1, 0x14, 0x84, 0xa6, 0x4c, 0x12, 0xc0, 0x90,
+0xd5, 0x1e, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x80, 0x44, 0x10, 0x00, 0x12, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x88, 0xc0, 0xdd, 0x2f, 0x80, 0x20, 0x84, 0x00, 0x80, 0x40, 0xd5, 0x79,
+0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x80, 0x84, 0x2c, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x88, 0xc0, 0xdd, 0x2f, 0x80, 0x20, 0x44, 0x00, 0x00, 0x1c, 0xd5, 0x51, 0x46, 0xf0, 0x00, 0x09,
+0x00, 0x07, 0x85, 0x80, 0x84, 0x2a, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xc0, 0xdd, 0x2f,
+0x80, 0x20, 0x44, 0x00, 0x00, 0x12, 0xd5, 0x43, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x8d, 0xd0, 0xdd, 0x2f, 0xd5, 0x5f, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x67,
+0x85, 0x88, 0xce, 0x03, 0x96, 0x00, 0xc8, 0x05, 0x44, 0x00, 0x00, 0x9e, 0x84, 0x24, 0xd5, 0x2f,
+0x46, 0x70, 0x00, 0x03, 0x58, 0x73, 0x83, 0x7c, 0x80, 0x26, 0x50, 0x00, 0x00, 0x27, 0x4b, 0xe0,
+0x1c, 0x01, 0x81, 0x20, 0x80, 0x26, 0x44, 0x00, 0x00, 0x27, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x50,
+0x00, 0xff, 0x80, 0x20, 0xd0, 0x05, 0x00, 0x04, 0x05, 0x7c, 0xe6, 0x0d, 0xe9, 0x1a, 0x46, 0xf0,
+0x00, 0x09, 0x00, 0x07, 0x85, 0x7c, 0x84, 0xa1, 0xd8, 0x06, 0x44, 0x00, 0x00, 0xa2, 0x44, 0x10,
+0x00, 0x12, 0xd5, 0x0d, 0x84, 0xa2, 0xd8, 0x06, 0x44, 0x00, 0x00, 0xb4, 0x44, 0x10, 0x00, 0x1c,
+0xd5, 0x06, 0x84, 0xa3, 0xd8, 0x24, 0x44, 0x00, 0x00, 0xd0, 0x84, 0x28, 0x84, 0x40, 0xd5, 0x19,
+0x40, 0x00, 0xa0, 0x08, 0x55, 0xe4, 0x80, 0xff, 0x40, 0x8f, 0x00, 0x04, 0x40, 0x84, 0x00, 0x13,
+0x80, 0x26, 0x80, 0x08, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x17, 0x85, 0x80,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xc0, 0xdd, 0x2f, 0x80, 0x20, 0x84, 0x41, 0x80, 0x08,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8d, 0x5c, 0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x87, 0x5c, 0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0x40, 0x04, 0x01, 0x80, 0x64, 0x96, 0x48, 0x96, 0x00,
+0x14, 0x02, 0x01, 0x00, 0x14, 0x11, 0x81, 0x01, 0x96, 0x10, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x87, 0x74, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x84, 0x00,
+0x80, 0x20, 0x84, 0x41, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x80, 0xc0, 0xdd, 0x2f, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x09, 0x00, 0x07, 0x85, 0x82, 0x84, 0x20, 0x84, 0x41, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x80, 0xc0, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x85, 0x44, 0x50, 0x00, 0x81, 0xd0, 0x50,
+0x9d, 0x69, 0xd0, 0x0b, 0x9f, 0x6a, 0xd8, 0x44, 0x47, 0xe0, 0x04, 0x01, 0x04, 0x5f, 0x01, 0xa3,
+0x54, 0x42, 0x80, 0x08, 0xcc, 0x43, 0xd5, 0x44, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x7e,
+0x9f, 0x69, 0xd0, 0x12, 0x5c, 0xf0, 0x00, 0x82, 0xe8, 0x05, 0xc0, 0x3a, 0xe6, 0x0a, 0xe8, 0x30,
+0xd5, 0x24, 0x9c, 0x6a, 0x4c, 0x00, 0x80, 0x13, 0xe2, 0x01, 0xe9, 0x0b, 0x9d, 0x49, 0xd0, 0x13,
+0x9d, 0x4a, 0xd8, 0x26, 0xd5, 0x15, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x38, 0xd5, 0x1b,
+0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x58, 0xd5, 0x16, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00,
+0x00, 0x78, 0xd5, 0x11, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x98, 0xd5, 0x0c, 0x46, 0x00,
+0x04, 0x01, 0x58, 0x00, 0x00, 0xb8, 0xd5, 0x07, 0x46, 0x50, 0x04, 0x01, 0x95, 0x05, 0x58, 0x52,
+0x80, 0x08, 0x98, 0x25, 0x05, 0xe0, 0x00, 0x00, 0x42, 0x0f, 0x18, 0x0b, 0xd5, 0x0a, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x87, 0x5c, 0xdd, 0x2f, 0xd5, 0x0b, 0x84, 0x02, 0xd5, 0x02, 0x84, 0x00,
+0x84, 0x20, 0x84, 0x42, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x80, 0xc0, 0xdd, 0x2f, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x30, 0x04, 0x01, 0x04, 0x51, 0x81, 0x80,
+0x46, 0xf0, 0x00, 0x09, 0x10, 0x57, 0x85, 0x85, 0x80, 0x83, 0x04, 0x12, 0x01, 0x81, 0x46, 0xf0,
+0x00, 0x09, 0x10, 0x17, 0x85, 0x86, 0x80, 0xa3, 0x04, 0x21, 0x81, 0x82, 0x04, 0x42, 0x81, 0x83,
+0x96, 0x10, 0x96, 0x60, 0x40, 0x30, 0xa0, 0x08, 0x40, 0x51, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x09,
+0x12, 0x57, 0x82, 0xbe, 0x46, 0x20, 0x04, 0x01, 0x80, 0x02, 0x04, 0x11, 0x01, 0x84, 0x04, 0x30,
+0x01, 0x85, 0x97, 0x08, 0x97, 0x58, 0x40, 0x22, 0xa0, 0x08, 0x40, 0x51, 0x10, 0x04, 0x46, 0xf0,
+0x00, 0x09, 0x12, 0x57, 0x82, 0xbf, 0x80, 0x20, 0x04, 0x40, 0x81, 0x86, 0x04, 0x30, 0x01, 0x87,
+0x96, 0x60, 0x96, 0x18, 0x40, 0x40, 0x20, 0x08, 0x40, 0x32, 0x04, 0x04, 0x46, 0x00, 0x04, 0x01,
+0x46, 0xf0, 0x00, 0x09, 0x12, 0x37, 0x82, 0xc0, 0x84, 0x41, 0x84, 0x21, 0x46, 0xf0, 0x00, 0x09,
+0x14, 0x57, 0x81, 0x5d, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x27, 0x85, 0x83, 0x14, 0x10, 0x01, 0x8c,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x30, 0x04, 0x01, 0x44, 0x50, 0x00, 0xff, 0x80, 0x43, 0x14, 0x51,
+0x81, 0x8a, 0x44, 0x30, 0x00, 0x39, 0x46, 0x10, 0x04, 0x01, 0x14, 0x31, 0x01, 0x98, 0x58, 0x10,
+0x86, 0x88, 0x84, 0x80, 0x44, 0x50, 0x00, 0x10, 0x44, 0x30, 0x00, 0x70, 0x44, 0x20, 0x00, 0x60,
+0xb6, 0xa1, 0x50, 0x00, 0x80, 0x18, 0xb6, 0x61, 0xb6, 0x81, 0xb6, 0x41, 0x44, 0x10, 0x00, 0x31,
+0xb6, 0x20, 0x9d, 0x49, 0x9c, 0x4c, 0x9e, 0xca, 0x9e, 0x89, 0xb6, 0xa0, 0xb6, 0x60, 0xb6, 0x40,
+0xb6, 0x20, 0x80, 0x24, 0x50, 0x20, 0x80, 0x21, 0x84, 0xa9, 0x9c, 0x49, 0xb6, 0x40, 0xd9, 0xfb,
+0x46, 0x00, 0x04, 0x01, 0x44, 0x10, 0x00, 0x3f, 0x14, 0x10, 0x01, 0x8c, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xdc, 0x84, 0x21, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x17, 0x85, 0x84,
+0x47, 0xe0, 0x04, 0x01, 0x04, 0x3f, 0x01, 0xa3, 0x46, 0x40, 0x04, 0x00, 0x58, 0x21, 0x80, 0x01,
+0x14, 0x2f, 0x01, 0xa3, 0x80, 0xbe, 0x04, 0x02, 0x00, 0x8f, 0xf5, 0x81, 0x83, 0x85, 0xf1, 0x01,
+0x81, 0x45, 0x81, 0x25, 0x15, 0xcf, 0x80, 0x02, 0x14, 0xaf, 0x80, 0x03, 0x14, 0x9f, 0x80, 0x04,
+0x58, 0x10, 0x80, 0x58, 0xf1, 0x81, 0xf3, 0x02, 0xf2, 0x03, 0xf1, 0x04, 0x81, 0x05, 0x80, 0xe5,
+0x80, 0xc5, 0x14, 0x8f, 0x80, 0x05, 0xf7, 0x86, 0xf6, 0x87, 0x58, 0x31, 0x80, 0x78, 0x58, 0x21,
+0x00, 0x98, 0x58, 0x10, 0x80, 0xb8, 0xf3, 0x82, 0xf2, 0x83, 0xf1, 0x84, 0xf3, 0x05, 0xf2, 0x06,
+0xf1, 0x07, 0x58, 0x00, 0x02, 0x00, 0x58, 0x31, 0x80, 0x48, 0x58, 0x21, 0x00, 0x68, 0x58, 0x10,
+0x80, 0x88, 0x83, 0xc5, 0xf3, 0x85, 0xf2, 0x86, 0xf1, 0x87, 0x14, 0x02, 0x00, 0x8f, 0x44, 0x40,
+0x00, 0x8c, 0x14, 0x4f, 0x00, 0x0e, 0x9e, 0xa4, 0xf0, 0x01, 0x9e, 0xd4, 0xb6, 0x40, 0x9c, 0x51,
+0xf4, 0x02, 0x83, 0x85, 0xb6, 0x64, 0x81, 0x45, 0xf0, 0x03, 0x81, 0x25, 0xb6, 0x20, 0x81, 0x05,
+0xf4, 0x04, 0x80, 0xe5, 0xb6, 0x44, 0xf0, 0x05, 0xb6, 0x40, 0xf4, 0x06, 0xb6, 0x64, 0xf0, 0x07,
+0x46, 0x50, 0x04, 0x01, 0xb6, 0x20, 0x58, 0x52, 0x86, 0x88, 0xb9, 0xaa, 0x14, 0x15, 0x00, 0x32,
+0x44, 0x40, 0x00, 0x10, 0x14, 0x14, 0x80, 0x3a, 0x8e, 0x74, 0x14, 0x24, 0x00, 0x42, 0x94, 0x21,
+0x14, 0x13, 0x80, 0x4a, 0x84, 0x40, 0x44, 0x10, 0x00, 0x60, 0xb6, 0x85, 0xb6, 0x65, 0xb6, 0x45,
+0xb6, 0x25, 0x14, 0x03, 0x01, 0x8c, 0xec, 0x24, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x10, 0x04, 0x01, 0x04, 0x60, 0x81, 0x8c, 0x96, 0x34, 0xc0, 0x06,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x82, 0x08, 0xdd, 0x2f, 0x54, 0x23, 0x00, 0x08, 0xc2, 0x0a,
+0x46, 0x50, 0x04, 0x01, 0x80, 0x65, 0x87, 0xc8, 0x84, 0x80, 0x15, 0xe2, 0x81, 0x8c, 0x14, 0x41,
+0x81, 0xa7, 0x54, 0x03, 0x00, 0x10, 0xc0, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x82, 0xa4,
+0xdd, 0x2f, 0x54, 0x63, 0x00, 0x20, 0xc6, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x10,
+0xdd, 0x2f, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x50, 0x0f,
+0x80, 0x04, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x01,
+0x44, 0x50, 0x00, 0x80, 0x14, 0x52, 0x01, 0xa8, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x07, 0x85, 0x85,
+0x46, 0x60, 0x00, 0x09, 0x84, 0x40, 0x54, 0x00, 0x00, 0x60, 0x44, 0x10, 0x00, 0x20, 0x10, 0x23,
+0x05, 0x83, 0x4c, 0x00, 0x80, 0x20, 0x95, 0x49, 0xd0, 0x14, 0xc8, 0x1c, 0x46, 0xf0, 0x00, 0x09,
+0x00, 0x07, 0x85, 0x86, 0x84, 0x2c, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xc0, 0xdd, 0x2f,
+0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x83, 0x68, 0x38, 0x20, 0x82, 0x02, 0xdd, 0x22, 0xd5, 0x0f,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x89, 0x34, 0xdd, 0x2f, 0x96, 0xc0, 0x10, 0x33, 0x05, 0x83,
+0xd5, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x5c, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x01,
+0x84, 0xa0, 0x14, 0x52, 0x01, 0xa8, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c,
+0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xf4, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x89, 0x3c, 0xdd, 0x2f, 0x46, 0x50, 0x04, 0x01,
+0x04, 0x02, 0x81, 0xa3, 0x54, 0x00, 0x00, 0x02, 0xc8, 0x66, 0x80, 0xe5, 0xb6, 0xff, 0x80, 0xc5,
+0xb4, 0x3f, 0xf6, 0x81, 0x58, 0x10, 0x80, 0xb8, 0xb6, 0x3f, 0xf1, 0x01, 0x80, 0x45, 0x58, 0x10,
+0x80, 0x88, 0xf1, 0x81, 0x44, 0x10, 0x00, 0x8b, 0x14, 0x11, 0x00, 0x26, 0x83, 0xc2, 0xb4, 0x5f,
+0x83, 0x85, 0xb6, 0x22, 0x81, 0x45, 0xf2, 0x01, 0x81, 0x25, 0x81, 0x05, 0x80, 0xe5, 0xb6, 0x22,
+0x80, 0xc5, 0x44, 0x20, 0x00, 0xff, 0x46, 0x40, 0x04, 0x01, 0x14, 0x1f, 0x00, 0x2a, 0x58, 0x42,
+0x06, 0x88, 0xb9, 0xb2, 0x14, 0x15, 0x00, 0x3a, 0x14, 0x14, 0x80, 0x42, 0x14, 0x14, 0x00, 0x4a,
+0x14, 0x23, 0x81, 0x8a, 0x44, 0x10, 0x00, 0x39, 0x44, 0x20, 0x00, 0x10, 0x14, 0x13, 0x01, 0x98,
+0xb6, 0x44, 0x44, 0x10, 0x00, 0x70, 0x44, 0x20, 0x00, 0x60, 0xb6, 0x24, 0x50, 0x32, 0x00, 0x18,
+0xb6, 0x04, 0x84, 0x22, 0xb6, 0x44, 0x44, 0x20, 0x00, 0x31, 0x14, 0x12, 0x81, 0xa3, 0x9d, 0x12,
+0xb6, 0x43, 0x9c, 0x53, 0x9f, 0x4a, 0x9c, 0x89, 0xb6, 0xa3, 0xb6, 0x83, 0xb6, 0x23, 0xb6, 0x43,
+0x80, 0x23, 0x50, 0x50, 0x00, 0x21, 0x84, 0x69, 0x9c, 0x01, 0xb6, 0xa1, 0x4c, 0x01, 0xff, 0xfb,
+0x80, 0xa6, 0x44, 0x00, 0x00, 0x3f, 0x84, 0x20, 0x14, 0x02, 0x81, 0x8c, 0x46, 0xf0, 0x00, 0x09,
+0x10, 0x17, 0x85, 0x84, 0x80, 0x05, 0x04, 0x20, 0x01, 0xa3, 0x54, 0x41, 0x00, 0xfe, 0x14, 0x40,
+0x01, 0xa3, 0xd5, 0x38, 0x46, 0x40, 0x04, 0x00, 0x04, 0x32, 0x00, 0x85, 0x80, 0xe5, 0x46, 0x00,
+0x04, 0x01, 0x58, 0x00, 0x06, 0xa0, 0x58, 0x21, 0x80, 0x04, 0x44, 0x60, 0x00, 0x39, 0x45, 0xe0,
+0x00, 0x31, 0x45, 0xc0, 0x00, 0x32, 0x44, 0xa0, 0x00, 0x33, 0x44, 0x90, 0x00, 0x34, 0x44, 0x80,
+0x00, 0x35, 0x14, 0x22, 0x00, 0x85, 0x14, 0x63, 0x81, 0x98, 0x15, 0xe0, 0x00, 0x00, 0x15, 0xc0,
+0x00, 0x00, 0xb7, 0x40, 0xb7, 0x20, 0xb7, 0x00, 0x84, 0x20, 0x50, 0x80, 0x80, 0x21, 0x84, 0xa9,
+0x9c, 0x49, 0xb7, 0x00, 0xd9, 0xfb, 0x81, 0x27, 0x8d, 0x4c, 0x14, 0xa4, 0x81, 0x8c, 0x80, 0x07,
+0x04, 0x10, 0x01, 0xa3, 0x96, 0x4c, 0xc1, 0x02, 0x84, 0x21, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x17,
+0x85, 0x84, 0x46, 0x00, 0x04, 0x01, 0x84, 0xa0, 0x84, 0x40, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x27,
+0x85, 0x8a, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x27, 0x85, 0x83, 0x46, 0xf0, 0x00, 0x09, 0x14, 0x57,
+0x81, 0x5e, 0x14, 0x50, 0x01, 0xa8, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x37, 0x85, 0x84, 0x46, 0xf0,
+0x00, 0x09, 0x00, 0x07, 0x85, 0x88, 0x46, 0xf0, 0x00, 0x09, 0x00, 0x47, 0x85, 0x89, 0x40, 0x11,
+0xa4, 0x08, 0x40, 0x00, 0x28, 0x08, 0x40, 0x30, 0x80, 0x04, 0x58, 0x01, 0x80, 0x02, 0x40, 0x12,
+0x2c, 0x08, 0x46, 0x40, 0x04, 0x00, 0x40, 0x20, 0x04, 0x04, 0x46, 0xf0, 0x00, 0x09, 0x10, 0x57,
+0x85, 0x87, 0x14, 0x22, 0x00, 0x8f, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x60, 0x00, 0x03, 0x58, 0x63, 0x07, 0x8c, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x87, 0x68, 0xdd, 0x2f, 0x4b, 0xe0, 0x18, 0x01, 0xc0, 0xfe, 0x46, 0x00, 0x04, 0x01,
+0xb4, 0x40, 0x46, 0x00, 0x04, 0x01, 0x96, 0x90, 0x58, 0x00, 0x05, 0x00, 0x84, 0x20, 0xd5, 0x05,
+0xa3, 0x01, 0x96, 0xe0, 0x18, 0x30, 0x80, 0x01, 0xe0, 0x22, 0xe9, 0xfb, 0x47, 0xe0, 0x00, 0x09,
+0x02, 0x3f, 0x02, 0xc0, 0x84, 0x20, 0x9a, 0x1a, 0x97, 0x41, 0x40, 0x00, 0x94, 0x06, 0x12, 0x5f,
+0x02, 0xc0, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x60, 0x00, 0x03,
+0x58, 0x63, 0x07, 0x8c, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x68, 0xdd, 0x2f, 0x4b, 0xe0,
+0x18, 0x01, 0xc0, 0xfe, 0x47, 0xe0, 0x04, 0x01, 0xb4, 0xde, 0x97, 0xb0, 0x46, 0xf0, 0x00, 0x09,
+0x04, 0x07, 0x81, 0x5d, 0x46, 0x10, 0x04, 0x01, 0x80, 0x46, 0x58, 0x10, 0x85, 0x00, 0x84, 0x61,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0x60, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x09, 0x02, 0x40,
+0x82, 0xc0, 0x84, 0x00, 0x9a, 0xe6, 0x96, 0x99, 0x40, 0x00, 0x08, 0x06, 0x12, 0x20, 0x82, 0xc0,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0x60, 0x00, 0x09,
+0x58, 0x63, 0x05, 0x80, 0xa4, 0x30, 0x44, 0x10, 0x00, 0x40, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x88, 0xb0, 0xdd, 0x2f, 0x46, 0x80, 0x00, 0x09, 0x58, 0x84, 0x05, 0x74, 0x97, 0xc0, 0xb4, 0x28,
+0x46, 0x00, 0x04, 0x01, 0x80, 0x47, 0x58, 0x00, 0x04, 0x00, 0x84, 0x60, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x88, 0x60, 0xdd, 0x2f, 0xb4, 0x68, 0x80, 0x07, 0x98, 0xbb, 0xb6, 0x48, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x87, 0x74, 0xdd, 0x2f, 0xa4, 0x70, 0x84, 0x00, 0x9b, 0xcf, 0x97, 0xf9,
+0x40, 0x00, 0x1c, 0x06, 0xad, 0xf0, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xf4, 0x96, 0x02, 0xf0, 0x81, 0x84, 0xc0, 0x46, 0xa0, 0x00, 0x03, 0x58, 0xa5, 0x08, 0xb0,
+0x46, 0x70, 0x00, 0x09, 0x58, 0x73, 0x85, 0x74, 0x46, 0x90, 0x00, 0x03, 0x58, 0x94, 0x83, 0x7c,
+0xd5, 0x12, 0x00, 0x83, 0x80, 0x01, 0xa7, 0x78, 0x40, 0x44, 0x20, 0x08, 0x40, 0x02, 0x14, 0x04,
+0xb6, 0x7f, 0x4b, 0xe0, 0x24, 0x01, 0xb4, 0x7f, 0x9d, 0xb1, 0xb6, 0x03, 0x97, 0xb0, 0xb4, 0x47,
+0x9c, 0x51, 0xb6, 0x27, 0x46, 0xf0, 0x00, 0x09, 0x02, 0x07, 0x82, 0xc0, 0x44, 0x10, 0x00, 0x40,
+0x4b, 0xe0, 0x28, 0x01, 0x46, 0x10, 0x01, 0x00, 0x58, 0x10, 0x85, 0x00, 0x98, 0xb1, 0x46, 0x80,
+0x00, 0x09, 0xf1, 0x01, 0x94, 0xd2, 0xe2, 0xc0, 0xe9, 0xdd, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x87, 0x74, 0xdd, 0x2f, 0x02, 0x34, 0x02, 0xc0, 0x84, 0x00, 0x9b, 0x9e, 0x97, 0xb1,
+0x40, 0x00, 0x18, 0x06, 0x12, 0x64, 0x02, 0xc0, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x46, 0x70, 0x00, 0x03, 0x58, 0x73, 0x87, 0x8c, 0x97, 0x82,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x68, 0xdd, 0x2f, 0x4b, 0xe0, 0x1c, 0x01, 0xc0, 0xfe,
+0x46, 0x20, 0x04, 0x01, 0xb5, 0x22, 0x85, 0x00, 0x44, 0x10, 0x00, 0xfc, 0x40, 0x04, 0x18, 0x1b,
+0x40, 0x00, 0x98, 0x1a, 0x46, 0x70, 0x04, 0x01, 0xf0, 0x81, 0x54, 0x94, 0x80, 0xff, 0x58, 0x73,
+0x85, 0x00, 0x47, 0xc0, 0x00, 0x03, 0x59, 0xce, 0x04, 0x58, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63,
+0x05, 0x74, 0x46, 0xa0, 0x00, 0x03, 0x58, 0xa5, 0x03, 0xdc, 0xd5, 0x15, 0xdd, 0x3c, 0xa7, 0x31,
+0xf2, 0x01, 0xa6, 0x70, 0x40, 0x31, 0x10, 0x04, 0xa3, 0x79, 0x40, 0x01, 0xa0, 0x08, 0x40, 0x00,
+0x04, 0x04, 0x96, 0x68, 0x4b, 0xe0, 0x28, 0x01, 0xb4, 0x86, 0x8d, 0x01, 0x9c, 0xe1, 0xb6, 0x66,
+0x54, 0x84, 0x00, 0xff, 0xe3, 0x09, 0xe9, 0xeb, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x84, 0x28,
+0xdd, 0x2f, 0x46, 0x30, 0x00, 0x09, 0x02, 0x41, 0x82, 0xc0, 0x84, 0x20, 0x40, 0x02, 0x24, 0x01,
+0x97, 0x41, 0x40, 0x00, 0x94, 0x06, 0x12, 0x51, 0x82, 0xc0, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x86,
+0xa6, 0x00, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63, 0x05, 0x8a, 0x84, 0x40, 0x44, 0x10, 0x00, 0x26,
+0xae, 0xb0, 0x4c, 0x00, 0x81, 0xde, 0x5c, 0xf0, 0x00, 0x27, 0xe8, 0x35, 0x84, 0x68, 0x4c, 0x01,
+0x82, 0x45, 0xe6, 0x09, 0xe8, 0x15, 0x84, 0x83, 0x4c, 0x02, 0x01, 0x7b, 0xe6, 0x04, 0xe8, 0x08,
+0x84, 0xa1, 0xd0, 0x6e, 0x87, 0xc2, 0x4c, 0x0f, 0x42, 0x5f, 0x48, 0x00, 0x01, 0x5c, 0x84, 0x26,
+0x4c, 0x00, 0x81, 0x67, 0x84, 0x47, 0x4c, 0x01, 0x42, 0x57, 0x48, 0x00, 0x01, 0x6a, 0x84, 0x6b,
+0x4c, 0x01, 0x82, 0x35, 0xe6, 0x0c, 0xe8, 0x09, 0x84, 0x89, 0x4c, 0x02, 0x02, 0x30, 0x84, 0xaa,
+0x4c, 0x02, 0xc2, 0x4a, 0x48, 0x00, 0x02, 0x24, 0x45, 0xe0, 0x00, 0x22, 0x4c, 0x0f, 0x01, 0xa1,
+0x44, 0x10, 0x00, 0x23, 0x4c, 0x00, 0x81, 0xb8, 0x44, 0x20, 0x00, 0x20, 0x4c, 0x01, 0x42, 0x3c,
+0x48, 0x00, 0x01, 0x89, 0x44, 0x30, 0x00, 0x43, 0x4c, 0x01, 0x81, 0x79, 0x5c, 0xf0, 0x00, 0x44,
+0xe8, 0x20, 0x44, 0x40, 0x00, 0x33, 0x4c, 0x02, 0x01, 0xcc, 0x5c, 0xf0, 0x00, 0x34, 0xe8, 0x0b,
+0x44, 0x50, 0x00, 0x27, 0x4c, 0x02, 0x81, 0xa0, 0x45, 0xe0, 0x00, 0x32, 0x4c, 0x0f, 0x42, 0x24,
+0x48, 0x00, 0x01, 0xaa, 0x44, 0x10, 0x00, 0x37, 0x4c, 0x00, 0x81, 0xbb, 0x44, 0x20, 0x00, 0x42,
+0x4c, 0x01, 0x01, 0x3c, 0x44, 0x30, 0x00, 0x36, 0x4c, 0x01, 0xc2, 0x16, 0x48, 0x00, 0x01, 0xa9,
+0x44, 0x40, 0x00, 0x52, 0x4c, 0x02, 0x01, 0xb9, 0x5c, 0xf0, 0x00, 0x53, 0xe8, 0x0b, 0x44, 0x50,
+0x00, 0x46, 0x4c, 0x02, 0x81, 0x3c, 0x45, 0xe0, 0x00, 0x47, 0x4c, 0x0f, 0x42, 0x05, 0x48, 0x00,
+0x01, 0x46, 0x44, 0x10, 0x00, 0x56, 0x4c, 0x00, 0x81, 0xb6, 0x44, 0x20, 0x00, 0x57, 0x4c, 0x01,
+0x01, 0xbb, 0x44, 0x30, 0x00, 0x53, 0x4c, 0x01, 0xc1, 0xf7, 0x48, 0x00, 0x01, 0xb5, 0x46, 0x00,
+0x00, 0x09, 0x58, 0x00, 0x05, 0x7c, 0xa6, 0x00, 0x84, 0x88, 0x4c, 0x02, 0x00, 0x8b, 0xe6, 0x09,
+0xe8, 0x07, 0x84, 0xa1, 0xd0, 0x0f, 0x87, 0xc2, 0x4c, 0x0f, 0x41, 0xec, 0xd5, 0x76, 0x44, 0x10,
+0x00, 0x10, 0x4c, 0x00, 0x80, 0x89, 0x44, 0x20, 0x00, 0x12, 0x4c, 0x01, 0x41, 0xe3, 0x48, 0x00,
+0x00, 0xa3, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x00,
+0x58, 0x42, 0x02, 0x0c, 0xb4, 0x44, 0x84, 0x20, 0x58, 0x31, 0x00, 0x10, 0xb6, 0x64, 0x92, 0x00,
+0x84, 0x07, 0x9c, 0x49, 0x4c, 0x10, 0x7f, 0xfd, 0x44, 0x1f, 0xff, 0xef, 0x46, 0x00, 0x04, 0x00,
+0x40, 0x21, 0x04, 0x02, 0x58, 0x00, 0x02, 0x0c, 0xb6, 0x40, 0x47, 0xe0, 0x04, 0x00, 0x59, 0xef,
+0x02, 0x00, 0xb4, 0xbe, 0x54, 0x12, 0x80, 0x03, 0xc9, 0x12, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10,
+0x82, 0x04, 0x05, 0xe0, 0x80, 0x00, 0x46, 0x3f, 0xf0, 0xff, 0x58, 0x5f, 0x00, 0x01, 0xb6, 0xa1,
+0x58, 0x31, 0x8f, 0xff, 0xb4, 0x81, 0x40, 0x22, 0x0c, 0x02, 0xd5, 0x31, 0x84, 0x41, 0x4c, 0x11,
+0x40, 0x18, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x04, 0xb4, 0x41, 0x84, 0x9e, 0x41, 0xe1,
+0x10, 0x02, 0x15, 0xe0, 0x80, 0x00, 0x46, 0x3f, 0xf0, 0xff, 0xb4, 0xa1, 0x58, 0x31, 0x8f, 0xff,
+0x40, 0x42, 0x8c, 0x02, 0xb6, 0x81, 0x46, 0x30, 0x01, 0x00, 0xb4, 0x41, 0xd5, 0x16, 0x46, 0x10,
+0x04, 0x00, 0x58, 0x10, 0x82, 0x04, 0xb4, 0x81, 0x84, 0xbe, 0x40, 0x22, 0x14, 0x02, 0xb6, 0x41,
+0x46, 0x3f, 0xf0, 0xff, 0x05, 0xe0, 0x80, 0x00, 0x58, 0x31, 0x8f, 0xff, 0x40, 0x5f, 0x0c, 0x02,
+0xb6, 0xa1, 0x46, 0x30, 0x05, 0x00, 0xb4, 0x41, 0x40, 0x21, 0x0c, 0x04, 0xb6, 0x41, 0xb4, 0x20,
+0x58, 0x10, 0x83, 0x00, 0x48, 0x00, 0x00, 0xca, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x80,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0xb0, 0xdd, 0x2f, 0x48, 0x00, 0x01, 0x6a,
+0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x04, 0x00, 0x05, 0xe0, 0x00, 0x00, 0x58, 0x1f, 0x0c, 0x00,
+0x48, 0x00, 0x00, 0xb4, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0xa0, 0xdd, 0x2f, 0xc8, 0x09,
+0x84, 0x61, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x8a, 0xae, 0xc0, 0x48, 0x00, 0x01, 0x52,
+0x46, 0x50, 0x00, 0x09, 0x58, 0x52, 0x83, 0x64, 0xa7, 0x28, 0x46, 0x20, 0x04, 0x01, 0x58, 0x21,
+0x04, 0x00, 0xb6, 0x82, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x74, 0xdd, 0x2f,
+0x48, 0x00, 0x01, 0x40, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0x46, 0x40,
+0x04, 0x01, 0x58, 0x42, 0x06, 0x60, 0x84, 0xa0, 0xb6, 0xa4, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x86, 0xd0, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10, 0x85, 0x8a, 0xae, 0x08, 0x46, 0x40,
+0x04, 0x00, 0x58, 0x42, 0x02, 0x04, 0xb4, 0x44, 0x44, 0x3f, 0x00, 0xff, 0x40, 0x01, 0x0c, 0x02,
+0x58, 0x50, 0x44, 0x00, 0xb6, 0xa4, 0x46, 0x0f, 0xf0, 0xff, 0xb4, 0x44, 0x58, 0x00, 0x0f, 0xff,
+0x58, 0x31, 0x00, 0x01, 0xb6, 0x64, 0x46, 0x10, 0x04, 0x00, 0xb4, 0xa4, 0x58, 0x10, 0x82, 0x0c,
+0x40, 0x22, 0x80, 0x02, 0xb6, 0x44, 0xb4, 0x61, 0x58, 0x01, 0x83, 0x00, 0xb6, 0x01, 0x48, 0x00,
+0x01, 0x09, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x47, 0xe0, 0x00, 0x09, 0x59, 0xef,
+0x05, 0x7c, 0x46, 0x30, 0x04, 0x10, 0xb4, 0x20, 0x02, 0x2f, 0x00, 0x00, 0xd5, 0x22, 0x46, 0x00,
+0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x20, 0x04, 0x10, 0xb4, 0x20, 0xd5, 0x26, 0x46, 0x00,
+0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x30, 0x04, 0x10, 0xb4, 0x20, 0x46, 0x60, 0x00, 0x09,
+0x58, 0x63, 0x05, 0x8a, 0x48, 0x00, 0x00, 0xab, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74,
+0x46, 0x20, 0x00, 0x09, 0x58, 0x21, 0x05, 0x7c, 0x46, 0x30, 0x04, 0x00, 0xb4, 0x20, 0xa4, 0x90,
+0x98, 0x4b, 0xb6, 0x20, 0xac, 0x88, 0x48, 0x00, 0x00, 0xd5, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00,
+0x05, 0x74, 0x46, 0x20, 0x04, 0x00, 0xb4, 0x20, 0x98, 0xca, 0xb6, 0x60, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x87, 0x28, 0xdd, 0x2f, 0x48, 0x00, 0x00, 0xbd, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00,
+0x05, 0x74, 0x46, 0x30, 0x04, 0x00, 0xb4, 0x20, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63, 0x05, 0x8a,
+0xd5, 0x7d, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0xb4, 0x80, 0x46, 0x00, 0x00, 0x09,
+0x58, 0x00, 0x05, 0x78, 0x40, 0x12, 0x40, 0x08, 0xb6, 0x20, 0x48, 0x00, 0x00, 0xab, 0x46, 0x00,
+0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x47, 0xe0, 0x00, 0x09, 0x59, 0xef, 0x05, 0x78, 0x46, 0x50,
+0x00, 0x09, 0x58, 0x52, 0x85, 0x7c, 0xb4, 0x3e, 0xb4, 0x60, 0xa4, 0xa8, 0xd5, 0xc2, 0x46, 0x20,
+0x00, 0x09, 0x58, 0x21, 0x05, 0x78, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0xb4, 0x22,
+0xb4, 0x40, 0xd5, 0xc3, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63, 0x05, 0x78, 0x46, 0x00, 0x00, 0x09,
+0x58, 0x00, 0x05, 0x74, 0xb4, 0x26, 0xb4, 0x60, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63, 0x05, 0x8a,
+0x98, 0x4b, 0xd5, 0x45, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x40, 0x00, 0x09,
+0x58, 0x42, 0x05, 0x7c, 0x46, 0x30, 0x04, 0x20, 0xb4, 0x20, 0xa4, 0xa0, 0xd5, 0x9a, 0x46, 0x00,
+0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x20, 0x04, 0x20, 0xb4, 0x20, 0xd5, 0x9e, 0x46, 0x00,
+0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x30, 0x04, 0x20, 0xb4, 0x20, 0x46, 0x60, 0x00, 0x09,
+0x58, 0x63, 0x05, 0x8a, 0xd5, 0x23, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x50,
+0x00, 0x09, 0x58, 0x52, 0x85, 0x7c, 0x46, 0x30, 0x05, 0x00, 0xb4, 0x20, 0xa4, 0xa8, 0x48, 0xff,
+0xff, 0x79, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x20, 0x05, 0x00, 0xb4, 0x20,
+0x48, 0xff, 0xff, 0x7c, 0x46, 0x00, 0x00, 0x09, 0x58, 0x00, 0x05, 0x74, 0x46, 0x30, 0x05, 0x00,
+0xb4, 0x20, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63, 0x05, 0x8a, 0x98, 0x4b, 0xb6, 0x20, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x87, 0xa0, 0xdd, 0x2f, 0xc8, 0x02, 0xd5, 0x1a, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x87, 0x88, 0xdd, 0x2f, 0xd5, 0x25, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0x46, 0xf0,
+0x00, 0x04, 0x58, 0xf7, 0x88, 0x80, 0xdd, 0x2f, 0xd5, 0x1c, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x87, 0xa0, 0xdd, 0x2f, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63, 0x05, 0x8a, 0xc8, 0x03, 0x84, 0x01,
+0xd5, 0x10, 0x46, 0x20, 0x00, 0x09, 0x58, 0x21, 0x05, 0x86, 0x01, 0xe1, 0x00, 0x00, 0x56, 0x0f,
+0x00, 0x0b, 0x5c, 0x00, 0x00, 0x01, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x87, 0xec, 0xdd, 0x2f,
+0xae, 0x30, 0xd5, 0x07, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x5c, 0xdd, 0x2f, 0xd5, 0x06,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x80, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x09, 0x58, 0x10,
+0x85, 0x8a, 0x20, 0x00, 0x80, 0x00, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x87, 0x20, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7,
+0x83, 0x9c, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x10, 0x04, 0x52, 0x02, 0x01, 0x40, 0x22, 0xa0, 0x08,
+0x92, 0x48, 0x14, 0x22, 0x02, 0x01, 0x84, 0x0a, 0x46, 0x10, 0x00, 0x05, 0x58, 0x10, 0x81, 0xe8,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0x78, 0xdd, 0x2f, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x01, 0xc4, 0x84, 0x02, 0x46, 0x10, 0x00, 0x04, 0x58, 0x10, 0x84, 0x10, 0xdd, 0x26, 0x84, 0x01,
+0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x87, 0x8c, 0xdd, 0x26, 0x84, 0x0c, 0x46, 0x10, 0x00, 0x03,
+0x58, 0x10, 0x84, 0x9c, 0xdd, 0x26, 0x46, 0x10, 0x00, 0x01, 0x58, 0x10, 0x82, 0xfc, 0x84, 0x0f,
+0xdd, 0x26, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x05, 0xc4, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x81, 0x6c, 0xdd, 0x2f, 0x84, 0x20, 0x80, 0x81, 0x46, 0x20, 0x00, 0x08, 0x58, 0x21, 0x0b, 0x60,
+0x44, 0x30, 0x08, 0x00, 0x46, 0x00, 0x00, 0x05, 0x58, 0x00, 0x00, 0x24, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x81, 0x20, 0xdd, 0x2f, 0x84, 0x00, 0x46, 0x10, 0x00, 0x08, 0x58, 0x10, 0x8a, 0x48,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0xe4, 0xdd, 0x2f, 0x46, 0x00, 0x04, 0x00, 0x84, 0x21,
+0x14, 0x10, 0x00, 0x8c, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0xe0, 0xdd, 0x2f, 0x84, 0x00,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0x80, 0x00, 0x02,
+0x58, 0x84, 0x07, 0x84, 0x80, 0xe0, 0x5c, 0x00, 0x00, 0x10, 0x80, 0xc1, 0x4b, 0xe0, 0x20, 0x01,
+0x84, 0x20, 0x40, 0x00, 0x98, 0x06, 0x4b, 0xe0, 0x20, 0x01, 0x95, 0xfa, 0x46, 0x00, 0x00, 0x09,
+0x58, 0x00, 0x05, 0x24, 0x99, 0xf8, 0xb6, 0xc7, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xfc, 0x46, 0x70, 0x00, 0x02, 0x58, 0x73, 0x87, 0x84, 0x84, 0x01,
+0x4b, 0xe0, 0x1c, 0x01, 0x46, 0xf0, 0x00, 0x09, 0x04, 0x67, 0x81, 0x53, 0x84, 0x00, 0x40, 0x00,
+0x18, 0x06, 0x4b, 0xe0, 0x1c, 0x01, 0xdd, 0x26, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e,
+0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x05, 0xa0, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x85, 0xa8,
+0xb6, 0x20, 0x48, 0xff, 0xd8, 0x43, 0xdd, 0x9e, 0x64, 0x12, 0x00, 0x02, 0x96, 0x4c, 0x64, 0x02,
+0x00, 0x43, 0x64, 0x00, 0x00, 0x08, 0xb6, 0x20, 0xdd, 0x9e, 0x92, 0x00, 0x64, 0x12, 0x00, 0x02,
+0x42, 0x10, 0x80, 0x09, 0x40, 0x10, 0x80, 0x04, 0x64, 0x12, 0x00, 0x03, 0x64, 0x00, 0x00, 0x08,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0x64, 0x12, 0x00, 0x43, 0x64, 0x00, 0x00, 0x08,
+0x46, 0x60, 0x00, 0x0c, 0x58, 0x63, 0x05, 0xa0, 0x04, 0x03, 0x00, 0x0b, 0xc0, 0x02, 0xdd, 0x20,
+0x04, 0x03, 0x00, 0x0c, 0xc0, 0x02, 0xdd, 0x20, 0x04, 0x23, 0x00, 0x08, 0x44, 0x10, 0x03, 0x00,
+0x54, 0x01, 0x03, 0x00, 0x4c, 0x00, 0xff, 0xf2, 0x64, 0x00, 0x00, 0x00, 0xd5, 0xee, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x80, 0xc0, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x37, 0x81, 0x70, 0x40, 0x43,
+0x18, 0x05, 0x40, 0x22, 0x0c, 0x02, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x27, 0x81, 0x70,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c, 0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x80, 0xc0, 0x50, 0x0f, 0x80, 0x04,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x37,
+0x81, 0x70, 0xf0, 0x01, 0x40, 0x23, 0x0c, 0x04, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x27, 0x81, 0x70,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c, 0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0x80, 0xc1, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x07,
+0x81, 0x73, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x67, 0x81, 0x74, 0xc8, 0x08, 0x44, 0x00, 0x01, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0xa4, 0xdd, 0x2f, 0xce, 0x08, 0x44, 0x00, 0x02, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0xa4, 0xdd, 0x2f, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa8, 0xbc, 0x44, 0x50, 0x00, 0x14, 0x46, 0x60, 0x00, 0x0c, 0x58, 0x63, 0x05, 0xa8,
+0x42, 0x60, 0x94, 0x73, 0x80, 0xe0, 0x81, 0x43, 0x50, 0x03, 0x00, 0x0c, 0xa8, 0x71, 0x84, 0x20,
+0x81, 0x22, 0x81, 0x04, 0xa8, 0x72, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x81, 0x6c, 0xdd, 0x2f,
+0x50, 0x35, 0x7f, 0xb8, 0x40, 0x24, 0x8c, 0x00, 0x58, 0x44, 0x00, 0x08, 0x84, 0x0a, 0xb6, 0x46,
+0xa9, 0xd1, 0xb6, 0x82, 0xa8, 0x12, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0xa8, 0x01, 0xb6, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xa0, 0x81, 0xb6, 0x01, 0xa8, 0x89, 0xb6, 0x22, 0xa8, 0x41, 0xdd, 0x9e,
+0xb4, 0x20, 0x4c, 0x10, 0x40, 0x04, 0x84, 0x20, 0xd5, 0x07, 0xa0, 0xc9, 0xb4, 0x81, 0xb6, 0x83,
+0xb4, 0x01, 0xa0, 0x89, 0xa8, 0x81, 0x80, 0x01, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x20, 0x00, 0x09,
+0x04, 0x11, 0x01, 0x5c, 0x98, 0x01, 0x14, 0x01, 0x01, 0x5c, 0x80, 0x01, 0xdd, 0x9e, 0x92, 0x00,
+0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x85, 0xd4, 0x46, 0xf0, 0x00, 0x09, 0x14, 0x17, 0x81, 0x5c,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x50, 0x00, 0x0c, 0x58, 0x52, 0x81, 0x80, 0x38, 0x12, 0x82, 0x0a,
+0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x00, 0xa0, 0x8d, 0x84, 0x61, 0x40, 0x41, 0x80, 0x0c,
+0x40, 0x02, 0x08, 0x04, 0xa8, 0x0d, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0x00,
+0x04, 0x00, 0x58, 0x00, 0x02, 0x00, 0xa0, 0x44, 0x96, 0x08, 0x54, 0x20, 0x00, 0x08, 0xc2, 0x06,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x63, 0xd5, 0x7b, 0x54, 0x30, 0x00, 0x10, 0xc3, 0x06,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x64, 0xd5, 0x73, 0x54, 0x50, 0x00, 0x20, 0xc5, 0x06,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x65, 0xd5, 0x6b, 0x54, 0x20, 0x00, 0x02, 0xc2, 0x06,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x61, 0xd5, 0x63, 0x96, 0xc4, 0xc3, 0x06, 0x46, 0xf0,
+0x00, 0x0c, 0x04, 0x07, 0x80, 0x60, 0xd5, 0x5c, 0x54, 0x40, 0x00, 0x04, 0xc4, 0x06, 0x46, 0xf0,
+0x00, 0x0c, 0x04, 0x07, 0x80, 0x62, 0xd5, 0x54, 0x40, 0x20, 0xa0, 0x09, 0x96, 0x10, 0x55, 0xe0,
+0x00, 0x01, 0x4f, 0xe2, 0x00, 0x07, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x68, 0xd5, 0x48,
+0x54, 0x30, 0x00, 0x02, 0xc3, 0x06, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x69, 0xd5, 0x40,
+0x54, 0x40, 0x00, 0x04, 0xc4, 0x06, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x6a, 0xd5, 0x38,
+0x55, 0xe0, 0x00, 0x08, 0x4f, 0xe2, 0x00, 0x07, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x6b,
+0xd5, 0x2f, 0x54, 0x30, 0x00, 0x10, 0xc3, 0x06, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x6c,
+0xd5, 0x27, 0x54, 0x40, 0x00, 0x20, 0xc4, 0x06, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x6d,
+0xd5, 0x1f, 0x54, 0x50, 0x00, 0x40, 0xc5, 0x06, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x6e,
+0xd5, 0x17, 0x54, 0x20, 0x00, 0x80, 0xc2, 0x06, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x6f,
+0xd5, 0x0f, 0x40, 0x00, 0xc0, 0x09, 0x96, 0x00, 0x97, 0x04, 0xc4, 0x02, 0xd5, 0x05, 0x54, 0x10,
+0x00, 0x02, 0x96, 0x08, 0xc0, 0x05, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0x70, 0xdd, 0x20,
+0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x9c, 0x3c, 0x84, 0x44, 0x96, 0x49,
+0x4c, 0x11, 0x40, 0x27, 0xb4, 0x20, 0x4e, 0x14, 0x00, 0x65, 0x46, 0x50, 0x00, 0x0c, 0x84, 0xe0,
+0x00, 0x32, 0x82, 0x00, 0x10, 0x72, 0x82, 0x00, 0x46, 0x40, 0x00, 0x0c, 0x46, 0xf0, 0x00, 0x0c,
+0x00, 0x57, 0x82, 0x04, 0x00, 0x12, 0x02, 0x02, 0x40, 0x61, 0xc0, 0x08, 0x10, 0x52, 0x02, 0x02,
+0x46, 0xf0, 0x00, 0x0c, 0x10, 0x37, 0x82, 0x01, 0x40, 0x63, 0x04, 0x04, 0x84, 0x40, 0x46, 0xf0,
+0x00, 0x0c, 0x10, 0x17, 0x82, 0x03, 0xb6, 0x40, 0x80, 0x22, 0xb6, 0xc0, 0xd5, 0x43, 0xe6, 0x38,
+0xe9, 0x40, 0x80, 0x20, 0xa3, 0x49, 0x96, 0xec, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x37, 0x82, 0x05,
+0xb4, 0x81, 0x40, 0x22, 0x60, 0x09, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x27, 0x82, 0x06, 0xb4, 0xa1,
+0x40, 0x32, 0xc0, 0x09, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x37, 0x82, 0x07, 0xb4, 0x81, 0x50, 0x60,
+0x00, 0x08, 0x40, 0x22, 0x20, 0x09, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x27, 0x82, 0x08, 0xb4, 0xa1,
+0x50, 0x70, 0x00, 0x0c, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x57, 0x82, 0x09, 0xb4, 0x86, 0x50, 0x50,
+0x00, 0x10, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x47, 0x80, 0x83, 0xb4, 0xc7, 0x50, 0x40, 0x00, 0x14,
+0x46, 0xf0, 0x00, 0x0c, 0x10, 0x67, 0x82, 0x04, 0xb4, 0x65, 0x84, 0x20, 0x46, 0xf0, 0x00, 0x0c,
+0x12, 0x37, 0x81, 0x08, 0xb4, 0xe4, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x77, 0x82, 0x12, 0xd5, 0x02,
+0x84, 0x21, 0x80, 0x01, 0x3a, 0x6f, 0x9c, 0x04, 0xdd, 0x9e, 0x92, 0x00, 0x84, 0x00, 0xdd, 0x9e,
+0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xf4, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x07, 0x82, 0x05, 0xc8, 0x0f,
+0x46, 0xf0, 0x00, 0x0c, 0x12, 0x07, 0x81, 0x0a, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x07, 0x82, 0x02,
+0x46, 0xf0, 0x00, 0x0c, 0x10, 0x07, 0x82, 0x00, 0x48, 0x00, 0x00, 0xca, 0x46, 0x30, 0x00, 0x0c,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x47, 0x80, 0x5c, 0x04, 0x51, 0x80, 0x86, 0xe2, 0xa4, 0x4e, 0xf2,
+0x00, 0xbf, 0x14, 0x41, 0x80, 0x86, 0x44, 0x10, 0x00, 0xb8, 0x84, 0x41, 0x84, 0x00, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x87, 0x68, 0xdd, 0x2f, 0x50, 0x2f, 0x80, 0x04, 0x84, 0x00, 0x44, 0x10,
+0x00, 0xb9, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf2, 0x01, 0x46, 0x00,
+0x00, 0x0c, 0x58, 0x00, 0x02, 0x14, 0x97, 0xd4, 0x4e, 0x72, 0x00, 0x9f, 0xa4, 0x40, 0x46, 0xf0,
+0x00, 0x0c, 0x03, 0xe7, 0x81, 0x08, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x02, 0xe2, 0x3e,
+0xe8, 0x0d, 0x46, 0x40, 0x00, 0x0c, 0x00, 0x52, 0x02, 0x00, 0xa6, 0x80, 0x9c, 0xe9, 0x10, 0x32,
+0x02, 0x00, 0xc2, 0x0c, 0x9f, 0x91, 0xaf, 0x80, 0xd5, 0x09, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x17,
+0x82, 0x04, 0xa7, 0xc0, 0xe2, 0xe1, 0xe8, 0x02, 0xae, 0x40, 0x84, 0xa0, 0x46, 0xf0, 0x00, 0x0c,
+0x12, 0x57, 0x81, 0x0a, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0x68, 0x44, 0x10, 0x00, 0xb8,
+0x84, 0x45, 0x84, 0x00, 0xdd, 0x26, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x27, 0x82, 0x06, 0x44, 0x10,
+0x00, 0xb9, 0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xb8, 0x84, 0x42, 0x84, 0x00, 0xdd, 0x26,
+0x46, 0xf0, 0x00, 0x0c, 0x00, 0x27, 0x82, 0x09, 0x44, 0x10, 0x00, 0xb9, 0x84, 0x00, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0xb8, 0x84, 0x43, 0x84, 0x00, 0xdd, 0x26, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x27,
+0x82, 0x08, 0x44, 0x10, 0x00, 0xb9, 0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xb8, 0x84, 0x44,
+0x84, 0x00, 0xdd, 0x26, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x27, 0x82, 0x07, 0x84, 0x00, 0x44, 0x10,
+0x00, 0xb9, 0xdd, 0x26, 0x46, 0x70, 0x00, 0x0c, 0x58, 0x73, 0x82, 0x0c, 0x44, 0x10, 0x00, 0xb8,
+0x84, 0x49, 0x84, 0x00, 0xdd, 0x26, 0xa6, 0xbb, 0x44, 0x10, 0x00, 0xb9, 0x84, 0x00, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0xb8, 0x84, 0x48, 0x84, 0x00, 0xdd, 0x26, 0xa6, 0xba, 0x44, 0x10, 0x00, 0xb9,
+0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xb8, 0x84, 0x47, 0x84, 0x00, 0xdd, 0x26, 0xa6, 0xb9,
+0x44, 0x10, 0x00, 0xb9, 0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xb8, 0x84, 0x46, 0x84, 0x00,
+0xdd, 0x26, 0xa6, 0xb8, 0x44, 0x10, 0x00, 0xb9, 0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xb8,
+0x84, 0x41, 0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xb9, 0x84, 0x41, 0x84, 0x00, 0xdd, 0x26,
+0x84, 0x00, 0x44, 0x10, 0x00, 0xb8, 0x80, 0x40, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xb9, 0x84, 0x41,
+0x84, 0x00, 0xdd, 0x26, 0xd5, 0x04, 0xa5, 0xc0, 0x9d, 0xb9, 0xad, 0x80, 0xec, 0x0c, 0x3a, 0x6f,
+0x9c, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa8, 0x3c, 0xef, 0xf4, 0x46, 0x30, 0x04, 0x10, 0x54, 0x80,
+0x00, 0x0f, 0x58, 0x31, 0x85, 0x00, 0x40, 0x84, 0x38, 0x08, 0x84, 0x80, 0x54, 0x70, 0x80, 0x3f,
+0xb4, 0xa3, 0xf5, 0x81, 0x00, 0x5f, 0x80, 0x07, 0x54, 0x52, 0x80, 0x80, 0x97, 0x68, 0xcd, 0x3c,
+0xf5, 0x81, 0x00, 0x9f, 0x80, 0x07, 0x42, 0x94, 0x98, 0x09, 0x00, 0x6f, 0x80, 0x05, 0x92, 0xc6,
+0x95, 0xb6, 0x44, 0xaf, 0xff, 0x80, 0x40, 0x94, 0xa8, 0x04, 0x40, 0x63, 0x1c, 0x04, 0x10, 0x9f,
+0x80, 0x07, 0x10, 0x6f, 0x80, 0x05, 0x44, 0x9c, 0x3f, 0xff, 0xf6, 0x01, 0x40, 0x63, 0x24, 0x02,
+0x40, 0x63, 0x20, 0x04, 0xf6, 0x81, 0xb6, 0xc3, 0xb4, 0xc3, 0x9d, 0x69, 0xf6, 0x81, 0x00, 0x6f,
+0x80, 0x07, 0x54, 0x63, 0x00, 0x80, 0xc6, 0x05, 0x44, 0xa0, 0x00, 0x64, 0x4c, 0x55, 0x7f, 0xf6,
+0x00, 0x5f, 0x80, 0x07, 0x54, 0x52, 0x80, 0x80, 0xcd, 0x0f, 0x00, 0x5f, 0x80, 0x05, 0x54, 0x52,
+0x80, 0x3f, 0xd9, 0x0a, 0xf5, 0x01, 0x92, 0xae, 0x54, 0x52, 0x80, 0x0f, 0xd8, 0x05, 0x00, 0x0f,
+0x80, 0x04, 0xb6, 0x02, 0xd5, 0x05, 0x9d, 0x21, 0x44, 0x50, 0x00, 0x64, 0xdc, 0xba, 0xf1, 0x01,
+0x40, 0x00, 0xfc, 0x09, 0xec, 0x0c, 0x3a, 0x6f, 0xa8, 0x04, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc,
+0xef, 0xf8, 0x46, 0x30, 0x04, 0x10, 0x84, 0x80, 0x05, 0xe1, 0x81, 0x40, 0x9d, 0x21, 0x15, 0xef,
+0x80, 0x01, 0x00, 0x6f, 0x80, 0x07, 0x54, 0x53, 0x00, 0x80, 0xc5, 0x04, 0x44, 0x50, 0x00, 0x64,
+0xdc, 0xf4, 0x00, 0x5f, 0x80, 0x07, 0x44, 0x3f, 0xff, 0xc0, 0x41, 0xe2, 0x8c, 0x04, 0x11, 0xef,
+0x80, 0x07, 0x54, 0x40, 0x00, 0x0f, 0xf3, 0x01, 0x44, 0x6c, 0x3f, 0xff, 0x40, 0x52, 0x38, 0x08,
+0x41, 0xe1, 0x98, 0x02, 0x40, 0x3f, 0x14, 0x04, 0xf3, 0x81, 0x01, 0xef, 0x80, 0x05, 0x54, 0x40,
+0x80, 0x3f, 0x40, 0x6f, 0x18, 0x09, 0x95, 0xb6, 0x40, 0x33, 0x10, 0x04, 0x10, 0x2f, 0x80, 0x04,
+0x10, 0x3f, 0x80, 0x05, 0x46, 0x20, 0x04, 0x10, 0xf6, 0x01, 0x14, 0x61, 0x01, 0x40, 0x80, 0x5f,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0x84, 0x01, 0xec, 0x08, 0x3a, 0x6f,
+0x98, 0x84, 0xdd, 0x9e, 0xef, 0xf8, 0x46, 0x00, 0x04, 0x11, 0x58, 0x00, 0x00, 0x1c, 0x84, 0x60,
+0xb4, 0x80, 0xf4, 0x81, 0x00, 0x5f, 0x80, 0x06, 0x54, 0x42, 0x80, 0x02, 0x97, 0x20, 0xcc, 0x23,
+0xf4, 0x81, 0x10, 0x1f, 0x80, 0x05, 0x00, 0x5f, 0x80, 0x06, 0x58, 0x52, 0x80, 0x03, 0x10, 0x5f,
+0x80, 0x06, 0xf5, 0x01, 0xb6, 0xa0, 0xb4, 0xa0, 0x9d, 0x21, 0xf5, 0x81, 0x00, 0x5f, 0x80, 0x06,
+0x54, 0x52, 0x80, 0x02, 0xc5, 0x04, 0x44, 0x50, 0x00, 0x64, 0xdc, 0xf6, 0x00, 0x5f, 0x80, 0x06,
+0x54, 0x42, 0x80, 0x02, 0xcc, 0x08, 0x00, 0x5f, 0x80, 0x05, 0xd9, 0x05, 0x00, 0x0f, 0x80, 0x04,
+0xb6, 0x02, 0xd5, 0x05, 0x9c, 0xd9, 0x44, 0x50, 0x00, 0x64, 0xdb, 0xd3, 0xf1, 0x01, 0x42, 0x00,
+0xc4, 0x0b, 0xec, 0x08, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xf4, 0x46, 0x30,
+0x04, 0x11, 0x84, 0x80, 0xa1, 0x5f, 0x9d, 0x21, 0xf5, 0x81, 0x01, 0xef, 0x80, 0x06, 0x54, 0x5f,
+0x00, 0x02, 0xc5, 0x04, 0x44, 0x50, 0x00, 0x64, 0xdc, 0xf6, 0x84, 0xa0, 0x84, 0x82, 0xf5, 0x81,
+0x10, 0x2f, 0x80, 0x04, 0x10, 0x4f, 0x80, 0x06, 0x10, 0x1f, 0x80, 0x05, 0x80, 0x43, 0xf3, 0x01,
+0xa8, 0xd7, 0x80, 0x5f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0x84, 0x01,
+0xec, 0x0c, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xf4, 0x46, 0x20,
+0x04, 0x11, 0x80, 0x80, 0x84, 0x60, 0x05, 0xe1, 0x00, 0x07, 0x9c, 0xd9, 0x15, 0xef, 0x80, 0x01,
+0x00, 0x5f, 0x80, 0x06, 0x54, 0x02, 0x80, 0x02, 0xc0, 0x04, 0x44, 0x50, 0x00, 0x64, 0xdb, 0xf4,
+0x84, 0x62, 0x84, 0x00, 0xf0, 0x81, 0x10, 0x3f, 0x80, 0x06, 0x10, 0x1f, 0x80, 0x04, 0x10, 0x4f,
+0x80, 0x05, 0xf1, 0x01, 0xa8, 0x57, 0x80, 0x24, 0x80, 0x5f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x86, 0xf4, 0xdd, 0x2f, 0x84, 0x01, 0xec, 0x0c, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xc4, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x05, 0xb4, 0x84, 0x22,
+0x50, 0x2f, 0x80, 0x2c, 0x84, 0x04, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x1c, 0x50, 0x2f, 0x80, 0x28,
+0x84, 0x04, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x1d, 0x50, 0x2f, 0x80, 0x24, 0x84, 0x04, 0xdd, 0x28,
+0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x20, 0x84, 0x04, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x11,
+0x50, 0x2f, 0x80, 0x1c, 0x84, 0x05, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f, 0x80, 0x18,
+0x84, 0x05, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x14, 0x84, 0x05, 0xdd, 0x28,
+0x44, 0x10, 0x00, 0x14, 0x50, 0x2f, 0x80, 0x10, 0x84, 0x05, 0xdd, 0x28, 0x46, 0x70, 0x04, 0x10,
+0x46, 0x6f, 0xf0, 0x00, 0x46, 0xa0, 0x04, 0x10, 0x47, 0xc0, 0x00, 0x80, 0x46, 0x80, 0x04, 0x11,
+0x58, 0x73, 0x80, 0x80, 0x58, 0x63, 0x00, 0x03, 0x58, 0xa5, 0x04, 0x00, 0x59, 0xce, 0x0c, 0x00,
+0x58, 0x84, 0x02, 0x04, 0x85, 0x23, 0xb6, 0xc7, 0x15, 0xc5, 0x00, 0x00, 0xb7, 0x28, 0x46, 0x70,
+0x00, 0x03, 0x58, 0x73, 0x85, 0x28, 0x84, 0x01, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x40, 0x04, 0x10,
+0x46, 0x00, 0x04, 0x10, 0x46, 0x20, 0x18, 0xca, 0x58, 0x42, 0x05, 0x0c, 0x44, 0x50, 0x00, 0x17,
+0x44, 0x30, 0x00, 0x1f, 0x58, 0x00, 0x05, 0x04, 0x58, 0x21, 0x00, 0x08, 0x84, 0x38, 0xb6, 0xa4,
+0xb6, 0x60, 0xb6, 0x44, 0xb6, 0x20, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x06, 0x6c, 0x44, 0x10,
+0x00, 0x11, 0x44, 0x20, 0x00, 0x99, 0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20,
+0x00, 0x99, 0x84, 0x00, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x13, 0x84, 0x49, 0x84, 0x00, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x14, 0x44, 0x20, 0x00, 0x51, 0x84, 0x00, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x20,
+0x00, 0x8e, 0x84, 0x00, 0xdd, 0x26, 0x84, 0x21, 0x80, 0x41, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x01,
+0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x22, 0x44, 0x20, 0x00, 0x81, 0x84, 0x04, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x1c, 0x44, 0x20, 0x00, 0x5a, 0x84, 0x04, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x1d, 0x44, 0x20,
+0x00, 0x68, 0x84, 0x04, 0xdd, 0x26, 0x85, 0x00, 0x84, 0x01, 0x4b, 0xe0, 0x1c, 0x01, 0x83, 0x88,
+0x81, 0x48, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x87, 0xb8, 0x50, 0x6f, 0x80, 0x34, 0x84, 0x24,
+0x44, 0x00, 0x00, 0x2f, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x40, 0x44, 0x00, 0x00, 0x16, 0xdd, 0x29,
+0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0x28, 0xdd, 0x2f, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x2f, 0xdd, 0x29, 0x80, 0x46, 0x44, 0x10, 0x00, 0x31, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0x84, 0x20, 0x44, 0x00, 0x00, 0x16, 0xdd, 0x29, 0x84, 0x21,
+0x44, 0x00, 0x00, 0x15, 0xdd, 0x29, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x29, 0xf3, 0x0d,
+0x54, 0x44, 0x00, 0xff, 0x8d, 0x01, 0x44, 0x10, 0x00, 0x1d, 0x84, 0x04, 0x50, 0x24, 0x00, 0x68,
+0x40, 0xfe, 0x0c, 0x06, 0xe8, 0x03, 0x83, 0x83, 0x81, 0x44, 0x87, 0xc8, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x86, 0x6c, 0x4c, 0x8f, 0x00, 0x04, 0xdd, 0x27, 0xd5, 0xc2, 0x80, 0x4a, 0x44, 0x10,
+0x00, 0x1d, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x1c, 0x44, 0x20, 0x00, 0x59, 0x84, 0x04,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x1d, 0x84, 0x49, 0x84, 0x04, 0xdd, 0x27, 0x85, 0x00, 0x46, 0x10,
+0x00, 0x03, 0x58, 0x10, 0x85, 0x28, 0x84, 0x01, 0x4b, 0xe0, 0x04, 0x01, 0x14, 0x8f, 0x80, 0x02,
+0x81, 0x48, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x87, 0xb8, 0x50, 0x6f, 0x80, 0x34, 0x47, 0xc0,
+0x00, 0x05, 0x59, 0xce, 0x06, 0xf4, 0x84, 0x24, 0x44, 0x00, 0x00, 0x2f, 0xdd, 0x29, 0x44, 0x10,
+0x00, 0x40, 0x44, 0x00, 0x00, 0x16, 0xdd, 0x29, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x85, 0x28, 0xdd, 0x2f, 0x84, 0x20, 0x44, 0x00, 0x00, 0x2f, 0xdd, 0x29, 0x80, 0x46, 0x44, 0x10,
+0x00, 0x31, 0x84, 0x00, 0xdd, 0x3c, 0x84, 0x20, 0x44, 0x00, 0x00, 0x16, 0xdd, 0x29, 0x84, 0x21,
+0x44, 0x00, 0x00, 0x15, 0xdd, 0x29, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x29, 0x84, 0x04,
+0x54, 0x44, 0x00, 0xff, 0xf3, 0x0d, 0x8d, 0x01, 0xf5, 0x02, 0x40, 0x24, 0x00, 0x0c, 0x44, 0x10,
+0x00, 0x1c, 0x8c, 0x49, 0xe2, 0xa3, 0xe8, 0x03, 0xf3, 0x82, 0x81, 0x44, 0x84, 0x88, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x86, 0x6c, 0x4c, 0x82, 0x00, 0x04, 0xdd, 0x27, 0xd5, 0xc5, 0x40, 0x95,
+0x10, 0x08, 0x80, 0x49, 0x44, 0x10, 0x00, 0x1c, 0x84, 0x04, 0xdd, 0x27, 0x54, 0x14, 0x80, 0xff,
+0xb6, 0x3f, 0x84, 0x40, 0x84, 0x22, 0x84, 0x04, 0xdd, 0x27, 0xb4, 0xbf, 0x46, 0x60, 0x04, 0x10,
+0x46, 0x86, 0x00, 0xc2, 0x58, 0x22, 0x80, 0x08, 0x44, 0x10, 0x00, 0x1c, 0x58, 0x63, 0x05, 0x0c,
+0x84, 0x04, 0x58, 0x84, 0x00, 0x3f, 0xdd, 0x27, 0xb7, 0x06, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20,
+0x00, 0x27, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xf1, 0x84, 0x05, 0xdd, 0x27, 0x47, 0xc6,
+0x00, 0xc2, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0xa1, 0x84, 0x05, 0xdd, 0x27, 0x59, 0xce,
+0x00, 0x38, 0x44, 0x10, 0x00, 0x14, 0x84, 0x41, 0x46, 0xa0, 0x04, 0x10, 0x84, 0x05, 0xdd, 0x27,
+0x15, 0xc3, 0x00, 0x00, 0x14, 0xaf, 0x80, 0x03, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x87, 0xb8,
+0x44, 0x00, 0x00, 0x17, 0x44, 0x10, 0x00, 0x10, 0xdd, 0x29, 0xf3, 0x03, 0x84, 0x00, 0x58, 0x31,
+0x80, 0x7c, 0xf3, 0x83, 0xf0, 0x81, 0x81, 0x49, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce, 0x05, 0xb4,
+0x50, 0x9f, 0x80, 0x30, 0xf4, 0x01, 0xf2, 0x02, 0x05, 0xef, 0x80, 0x00, 0x54, 0x82, 0x00, 0x07,
+0x40, 0x24, 0x20, 0x1a, 0x41, 0xe4, 0x20, 0x1a, 0x97, 0xa0, 0xf2, 0x82, 0x15, 0xef, 0x80, 0x00,
+0xe6, 0xc8, 0xe8, 0x0f, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2b, 0x84, 0x04, 0xdd, 0x3c, 0xf5, 0x0c,
+0xf0, 0x01, 0x54, 0x32, 0x80, 0xf8, 0x44, 0x10, 0x00, 0x2b, 0x40, 0x20, 0x0c, 0x04, 0xd5, 0x24,
+0xe6, 0xd0, 0xe8, 0x10, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2b, 0x84, 0x04, 0xdd, 0x3c, 0xf2, 0x0c,
+0x40, 0x14, 0x10, 0x08, 0x54, 0x31, 0x00, 0x8f, 0x40, 0x20, 0x8c, 0x04, 0x44, 0x10, 0x00, 0x2b,
+0xd5, 0x13, 0xe6, 0xd8, 0xe8, 0x14, 0x80, 0x49, 0x44, 0x10, 0x00, 0x11, 0x84, 0x04, 0xdd, 0x3c,
+0xf3, 0x01, 0xf0, 0x0c, 0x54, 0x51, 0x80, 0x0f, 0x95, 0x2b, 0x54, 0x30, 0x00, 0xc7, 0x40, 0x22,
+0x0c, 0x04, 0x44, 0x10, 0x00, 0x11, 0x84, 0x04, 0xf3, 0x8c, 0xd5, 0x12, 0x44, 0x10, 0x00, 0x11,
+0x80, 0x49, 0x84, 0x04, 0xdd, 0x3c, 0x44, 0x50, 0x00, 0x18, 0x40, 0x03, 0x14, 0x97, 0xf1, 0x0c,
+0x84, 0x04, 0x54, 0x20, 0x80, 0xf8, 0xf2, 0x8c, 0x84, 0x2e, 0x40, 0x22, 0x08, 0x04, 0xdd, 0x27,
+0x84, 0x2a, 0x44, 0x00, 0x00, 0xf1, 0xdd, 0x2a, 0x84, 0x20, 0x44, 0x00, 0x00, 0xf2, 0xdd, 0x2a,
+0x84, 0x20, 0x84, 0x04, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x31, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x2a,
+0x84, 0x24, 0x84, 0x01, 0xdd, 0x2a, 0x84, 0x21, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x2a, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x9f, 0xdd, 0x2a, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x2a, 0x44, 0x00,
+0x00, 0x9f, 0x44, 0x10, 0x00, 0x9b, 0xdd, 0x2a, 0x84, 0x00, 0xd5, 0x0b, 0x92, 0x00, 0x87, 0xc7,
+0x9c, 0x49, 0x4c, 0x1f, 0x7f, 0xfd, 0x9c, 0x01, 0x44, 0x30, 0x01, 0x2c, 0x4c, 0x01, 0x80, 0x04,
+0x84, 0x20, 0xd5, 0xf5, 0x44, 0x00, 0x00, 0x15, 0x84, 0x21, 0xdd, 0x2a, 0x84, 0x00, 0xd5, 0x0a,
+0x92, 0x00, 0x84, 0x47, 0x9c, 0x49, 0x4c, 0x11, 0x7f, 0xfd, 0x9c, 0x01, 0x84, 0x8a, 0x4c, 0x02,
+0x00, 0x04, 0x84, 0x20, 0xd5, 0xf6, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x2a, 0x44, 0x10,
+0x00, 0xba, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x10, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x2a, 0xf3, 0x03, 0x44, 0x10, 0x00, 0x30, 0x44, 0x00, 0x00, 0x9f, 0xb4, 0x43, 0xdd, 0x2a,
+0xf5, 0x03, 0xf1, 0x02, 0xb4, 0x05, 0xe2, 0x20, 0xe8, 0x05, 0xf0, 0x82, 0x54, 0x03, 0x00, 0x07,
+0xb6, 0x1f, 0x87, 0xc7, 0x4c, 0x8f, 0x40, 0x90, 0x4c, 0x64, 0x40, 0x32, 0x80, 0x49, 0x44, 0x10,
+0x00, 0x2b, 0x84, 0x04, 0xdd, 0x3c, 0xf4, 0x0c, 0xb4, 0x5f, 0x54, 0x82, 0x00, 0xf8, 0x40, 0x61,
+0x20, 0x04, 0xf6, 0x8c, 0x80, 0x46, 0x44, 0x10, 0x00, 0x2b, 0x84, 0x04, 0xdd, 0x27, 0x80, 0x49,
+0x44, 0x10, 0x00, 0x2c, 0x84, 0x04, 0xdd, 0x3c, 0xf3, 0x0c, 0xb4, 0x1f, 0x54, 0x51, 0x80, 0xf8,
+0x40, 0x40, 0x14, 0x04, 0xf4, 0x8c, 0x80, 0x44, 0x44, 0x10, 0x00, 0x2c, 0x84, 0x04, 0xdd, 0x27,
+0x80, 0x49, 0x44, 0x10, 0x00, 0x2d, 0x84, 0x04, 0xdd, 0x3c, 0xf2, 0x0c, 0xb5, 0x1f, 0x54, 0x61,
+0x00, 0xf8, 0x44, 0x10, 0x00, 0x2d, 0x40, 0x34, 0x18, 0x04, 0xd5, 0x32, 0x84, 0x2f, 0x4c, 0x60,
+0xc0, 0x32, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2b, 0x84, 0x04, 0xdd, 0x3c, 0xf5, 0x0c, 0xb4, 0x1f,
+0x54, 0x12, 0x80, 0x8f, 0x95, 0x84, 0x40, 0x43, 0x04, 0x04, 0xf4, 0x8c, 0x80, 0x44, 0x44, 0x10,
+0x00, 0x2b, 0x84, 0x04, 0xdd, 0x27, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2c, 0x84, 0x04, 0xdd, 0x3c,
+0xf2, 0x0c, 0x44, 0x10, 0x00, 0x2c, 0x54, 0x81, 0x00, 0x8f, 0x40, 0x33, 0x20, 0x04, 0xf3, 0x8c,
+0x80, 0x43, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x2d, 0x80, 0x49, 0x84, 0x04, 0xdd, 0x3c,
+0xf0, 0x0c, 0x44, 0x10, 0x00, 0x2d, 0x54, 0x50, 0x00, 0x8f, 0x40, 0x33, 0x14, 0x04, 0x80, 0x43,
+0xd5, 0x15, 0x45, 0xe0, 0x00, 0x17, 0x4c, 0x6f, 0x40, 0x14, 0x80, 0x49, 0x44, 0x10, 0x00, 0x11,
+0x84, 0x04, 0xdd, 0x3c, 0xb4, 0x5f, 0xf3, 0x0c, 0x40, 0x81, 0x0c, 0x08, 0x54, 0x61, 0x80, 0xc3,
+0x40, 0x34, 0x18, 0x04, 0x80, 0x43, 0x44, 0x10, 0x00, 0x11, 0x84, 0x04, 0xd5, 0x12, 0x44, 0x40,
+0x00, 0x1f, 0x4c, 0x62, 0x40, 0x11, 0x84, 0x2e, 0x80, 0x49, 0x84, 0x04, 0xdd, 0x3c, 0xf6, 0x0c,
+0xb4, 0x3f, 0x54, 0x53, 0x00, 0xf8, 0x40, 0x30, 0x94, 0x04, 0x84, 0x04, 0x80, 0x43, 0x84, 0x2e,
+0xf3, 0x8c, 0xdd, 0x27, 0x04, 0x8f, 0x80, 0x01, 0x45, 0xe0, 0x00, 0x20, 0x50, 0x04, 0x00, 0x01,
+0xf0, 0x81, 0x4c, 0x0f, 0x7e, 0xb1, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x87, 0xb8, 0x84, 0x20,
+0x44, 0x00, 0x00, 0xf4, 0xdd, 0x27, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x27, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27, 0x44, 0x00, 0x00, 0x15, 0x84, 0x21, 0xdd, 0x27, 0x84, 0x00,
+0xd5, 0x0a, 0x92, 0x00, 0x84, 0x67, 0x9c, 0x49, 0x4c, 0x11, 0xff, 0xfd, 0x9c, 0x01, 0x84, 0x4a,
+0x4c, 0x01, 0x00, 0x04, 0x84, 0x20, 0xd5, 0xf6, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xf2, 0x0b, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x06, 0x6c, 0x50, 0x8f, 0x80, 0x30, 0x84, 0x22, 0x84, 0x04, 0xdd, 0x26, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x85, 0xb4, 0x80, 0x48, 0x44, 0x10, 0x00, 0x1c, 0x84, 0x04, 0x4b, 0xe0, 0x1c, 0x01,
+0xf3, 0x0a, 0xf2, 0x0c, 0x54, 0x11, 0x80, 0x1f, 0x40, 0x50, 0x88, 0x04, 0xf5, 0x8a, 0x80, 0x45,
+0x44, 0x10, 0x00, 0x1c, 0x84, 0x04, 0xdd, 0x26, 0x80, 0x48, 0x44, 0x10, 0x00, 0x1d, 0x84, 0x04,
+0x4b, 0xe0, 0x1c, 0x01, 0xf4, 0x09, 0xf0, 0x0c, 0x54, 0x22, 0x00, 0xf8, 0x40, 0x31, 0x00, 0x04,
+0xf3, 0x89, 0x80, 0x43, 0x44, 0x10, 0x00, 0x1d, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x08, 0x44, 0x10,
+0x00, 0x13, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x07, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26,
+0xf2, 0x06, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x05, 0x44, 0x10, 0x00, 0x13,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x04, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26, 0x46, 0x10,
+0x04, 0x10, 0x46, 0x40, 0x04, 0x10, 0x84, 0xa0, 0x58, 0x10, 0x85, 0x04, 0x58, 0x42, 0x05, 0x0c,
+0xb6, 0xa1, 0xb6, 0xa4, 0xec, 0x3c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0x8c, 0x96, 0x48, 0x97, 0xd0, 0x54, 0xa0, 0x00, 0xff, 0xf1, 0x83, 0x4e, 0x73, 0x05, 0x45,
+0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x05, 0xb4, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x64, 0x84, 0x05,
+0xdd, 0x26, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x60, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0x80, 0x20,
+0x50, 0x2f, 0x80, 0x5c, 0xdd, 0x26, 0x80, 0x27, 0x50, 0x2f, 0x80, 0x58, 0x84, 0x05, 0xdd, 0x26,
+0x84, 0x26, 0x50, 0x2f, 0x80, 0x54, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0x84, 0x27, 0x50, 0x2f,
+0x80, 0x50, 0xdd, 0x26, 0x81, 0x26, 0x44, 0x80, 0x00, 0x25, 0x50, 0x6f, 0x80, 0x1c, 0x80, 0x28,
+0x80, 0x46, 0x84, 0x05, 0xdd, 0x29, 0x8d, 0x01, 0x44, 0x00, 0x00, 0x2f, 0x9d, 0xb4, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x85, 0xb4, 0x4c, 0x80, 0x7f, 0xf4, 0x44, 0x10, 0x00, 0x3a, 0x50, 0x2f,
+0x80, 0x48, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x3b, 0x50, 0x2f, 0x80, 0x44, 0x84, 0x05,
+0xdd, 0x27, 0x51, 0xcf, 0x80, 0x6c, 0x44, 0x10, 0x00, 0x17, 0x50, 0x2f, 0x80, 0x4c, 0x84, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0x84, 0x20, 0x80, 0x5c, 0x84, 0x05,
+0xdd, 0x27, 0xf4, 0x1b, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x06, 0x6c, 0x58, 0x22, 0x00, 0x03,
+0x84, 0x20, 0x84, 0x05, 0x4b, 0xe0, 0x20, 0x01, 0x84, 0x21, 0x80, 0x5c, 0x84, 0x05, 0xdd, 0x27,
+0xf3, 0x1b, 0x84, 0x05, 0x58, 0x21, 0x80, 0x01, 0x84, 0x21, 0x4b, 0xe0, 0x20, 0x01, 0x81, 0x3c,
+0x84, 0xc0, 0x46, 0x80, 0x00, 0x03, 0x58, 0x84, 0x05, 0x28, 0x84, 0x01, 0x4b, 0xe0, 0x20, 0x01,
+0x80, 0x49, 0x84, 0x05, 0x84, 0x21, 0xdd, 0x27, 0xf5, 0x1b, 0x9d, 0xb1, 0x96, 0x2c, 0x44, 0x20,
+0x00, 0x28, 0xf0, 0x9b, 0x4c, 0x61, 0x00, 0x03, 0xc8, 0xf1, 0x51, 0xef, 0x80, 0x6c, 0x80, 0x5e,
+0x84, 0x20, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0xf0, 0x1b,
+0x85, 0x1c, 0x41, 0xc0, 0x20, 0x02, 0x58, 0x2e, 0x00, 0x01, 0x84, 0x20, 0x50, 0x6f, 0x80, 0x68,
+0x84, 0x05, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x86, 0xf4, 0x15, 0xcf, 0x80, 0x1b, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x86, 0x6c, 0xdd, 0x2f, 0x80, 0x46, 0x44, 0x10, 0x00, 0x17, 0x84, 0x00,
+0x4b, 0xe0, 0x24, 0x01, 0xf2, 0x1a, 0x44, 0x7f, 0xff, 0xe0, 0x40, 0x51, 0x1c, 0x02, 0xf5, 0x9a,
+0x84, 0x00, 0x58, 0x22, 0x80, 0x10, 0x44, 0x10, 0x00, 0x17, 0x4b, 0xe0, 0x24, 0x01, 0x87, 0x89,
+0x44, 0x00, 0x00, 0x27, 0x40, 0x6e, 0x28, 0x1b, 0x40, 0x60, 0x28, 0x1a, 0x44, 0x30, 0x00, 0x31,
+0x84, 0x8e, 0x85, 0x20, 0x40, 0x82, 0x28, 0x1b, 0x40, 0x81, 0xa8, 0x1a, 0xf6, 0x85, 0x14, 0x8f,
+0x80, 0x04, 0x83, 0x89, 0x81, 0x09, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x85, 0xb4, 0x46, 0x60,
+0x00, 0x05, 0x58, 0x63, 0x06, 0x6c, 0x4e, 0x93, 0x00, 0x56, 0x84, 0x28, 0x50, 0x2f, 0x80, 0x6c,
+0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0xf4, 0x1b, 0x84, 0x28, 0x54, 0x22, 0x00, 0xfb, 0x84, 0x05,
+0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x68, 0x80, 0x09, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf3, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x58, 0x11,
+0x80, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xf1, 0x05, 0xf1, 0x82,
+0x80, 0x29, 0xd5, 0x09, 0x92, 0x00, 0x84, 0xa7, 0x9c, 0x01, 0xd8, 0xfd, 0x9c, 0x49, 0x84, 0x4a,
+0x4c, 0x11, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf7, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf7, 0x1a, 0x84, 0x04, 0x54, 0x13,
+0x80, 0xe7, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x0a,
+0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01, 0x4c, 0x03, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x0a, 0x4c, 0x10,
+0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00,
+0xd5, 0x57, 0x84, 0x28, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0xf4, 0x1b,
+0x84, 0x28, 0x58, 0x22, 0x00, 0x04, 0x84, 0x05, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x15,
+0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f,
+0xf3, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x58, 0x11, 0x80, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x87, 0xb8, 0xdd, 0x2f, 0xf1, 0x04, 0xf1, 0x82, 0x84, 0x20, 0xd5, 0x09, 0x92, 0x00, 0x87, 0xc7,
+0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0xaa, 0xd1, 0x03, 0x84, 0x00, 0xd5, 0xf7,
+0x84, 0x24, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4,
+0xdd, 0x2f, 0xf7, 0x1a, 0x84, 0x04, 0x54, 0x23, 0x80, 0xe7, 0x58, 0x11, 0x00, 0x10, 0xf2, 0x9a,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00,
+0x84, 0xc7, 0x9c, 0x01, 0x4c, 0x03, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04,
+0x84, 0x00, 0xd5, 0xf6, 0x44, 0x10, 0x00, 0x15, 0x84, 0x00, 0x50, 0x2f, 0x80, 0x68, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf1, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x54, 0x10,
+0x80, 0xfe, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x85, 0xb4, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x06, 0x6c, 0x4e, 0xa2, 0x00, 0x7a,
+0x46, 0x40, 0x04, 0x10, 0x47, 0xe0, 0x04, 0x10, 0x59, 0xef, 0x05, 0x04, 0x58, 0x42, 0x05, 0x0c,
+0x44, 0x30, 0x00, 0x10, 0x44, 0x10, 0x00, 0x18, 0xb6, 0x64, 0xb6, 0x3e, 0x50, 0x2f, 0x80, 0x6c,
+0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x27, 0x05, 0xcf, 0x80, 0x1b, 0x44, 0x10, 0x00, 0x11,
+0x58, 0x2e, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xc1,
+0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0x20, 0x84, 0x05, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x14, 0x84, 0x42, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x6c,
+0x84, 0x05, 0xdd, 0x27, 0xf2, 0x1b, 0x44, 0x0f, 0xff, 0xc0, 0x40, 0x51, 0x00, 0x02, 0xf5, 0x9b,
+0x58, 0x22, 0x80, 0x3f, 0x84, 0x23, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x6c,
+0x84, 0x05, 0xdd, 0x27, 0xf4, 0x1b, 0x44, 0x3f, 0xff, 0xc0, 0x41, 0xc2, 0x0c, 0x02, 0x15, 0xcf,
+0x80, 0x1b, 0x58, 0x2e, 0x00, 0x3f, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0x80, 0x20,
+0x44, 0x20, 0x00, 0x31, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x3a, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05,
+0xdd, 0x27, 0xf2, 0x1b, 0x44, 0x0f, 0xff, 0x80, 0x40, 0x51, 0x00, 0x02, 0xf5, 0x9b, 0x80, 0x45,
+0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x3b, 0x50, 0x2f, 0x80, 0x6c,
+0x84, 0x05, 0xdd, 0x27, 0xf3, 0x1b, 0x44, 0x4f, 0xff, 0x80, 0x41, 0xc1, 0x90, 0x02, 0x15, 0xcf,
+0x80, 0x1b, 0x80, 0x5c, 0x84, 0x05, 0x44, 0x10, 0x00, 0x3b, 0xdd, 0x26, 0x87, 0x80, 0xd5, 0x6c,
+0x46, 0x10, 0x04, 0x10, 0x47, 0xe0, 0x04, 0x10, 0x59, 0xef, 0x05, 0x04, 0x84, 0xa8, 0x44, 0x80,
+0x00, 0x18, 0x58, 0x10, 0x85, 0x0c, 0xb6, 0xa1, 0xb7, 0x1e, 0x44, 0x10, 0x00, 0x11, 0x50, 0x2f,
+0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27, 0xf3, 0x1b, 0x44, 0x10, 0x00, 0x11, 0x58, 0x21, 0x80, 0x80,
+0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xf1, 0x84, 0x05, 0xdd, 0x26,
+0x80, 0x48, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x14, 0x44, 0x20,
+0x00, 0xc2, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27,
+0xf2, 0x1b, 0x44, 0x0f, 0xff, 0xc0, 0x40, 0x41, 0x00, 0x02, 0xf4, 0x9b, 0x58, 0x22, 0x00, 0x34,
+0x84, 0x23, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27,
+0xf5, 0x1b, 0x44, 0x8f, 0xff, 0xc0, 0x40, 0x32, 0xa0, 0x02, 0xf3, 0x9b, 0x58, 0x21, 0x80, 0x34,
+0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x26, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27,
+0xf2, 0x1b, 0x44, 0x0f, 0xff, 0x80, 0x40, 0x41, 0x00, 0x02, 0xf4, 0x9b, 0x80, 0x44, 0x84, 0x26,
+0x84, 0x05, 0xdd, 0x26, 0x84, 0x27, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27, 0xf7, 0x1b,
+0x44, 0x5f, 0xff, 0x80, 0x40, 0x83, 0x94, 0x02, 0x14, 0x8f, 0x80, 0x1b, 0x80, 0x48, 0x84, 0x05,
+0x84, 0x27, 0xdd, 0x26, 0x81, 0x0a, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01,
+0x4c, 0x03, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0xea, 0x4c, 0x13, 0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6,
+0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x84, 0x22, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0,
+0x18, 0x01, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x86, 0xf4, 0x50, 0x2f, 0x80, 0x68, 0x44, 0x10,
+0x00, 0x9f, 0x84, 0x00, 0x4b, 0xe0, 0x1c, 0x01, 0xf3, 0x1a, 0x84, 0x59, 0x40, 0x11, 0x88, 0x02,
+0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x68,
+0x84, 0x00, 0x4b, 0xe0, 0x1c, 0x01, 0xf4, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x58, 0x12, 0x00, 0x01,
+0x4b, 0xe0, 0x18, 0x01, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f,
+0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x44, 0x10,
+0x00, 0x15, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4,
+0xdd, 0x2f, 0xf1, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x54, 0x10, 0x80, 0xfe, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x09, 0x92, 0x00, 0x84, 0xa7, 0x9c, 0x01,
+0xd8, 0xfd, 0x9c, 0x49, 0x84, 0xca, 0x4c, 0x13, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf7, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x87, 0xb8, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x1c, 0x01,
+0x44, 0x00, 0x00, 0x9f, 0x44, 0x10, 0x00, 0x82, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0xc0, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x86, 0xf4, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0x87, 0x9c, 0x01,
+0x4c, 0x02, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x6a, 0x4c, 0x11, 0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6,
+0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x44, 0x10, 0x00, 0x9f, 0x4b, 0xe0, 0x1c, 0x01, 0xf2, 0x1a,
+0x84, 0x02, 0x4c, 0x20, 0x00, 0x08, 0x45, 0xe0, 0x00, 0x14, 0x4c, 0x6f, 0x00, 0x04, 0x9d, 0xb1,
+0xd5, 0xe3, 0x44, 0x10, 0x00, 0x39, 0x44, 0x00, 0x00, 0x9e, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x87, 0xb8, 0xdd, 0x2f, 0x44, 0x10, 0x00, 0x9f, 0x84, 0x00, 0x50, 0x2f, 0x80, 0x68, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0x00, 0x1f, 0x80, 0x68, 0x54, 0x10, 0x80, 0x7f,
+0xf1, 0x81, 0x5e, 0xf0, 0x80, 0x40, 0xe9, 0x06, 0x44, 0x6f, 0xff, 0x80, 0x40, 0x50, 0x98, 0x04,
+0xf5, 0x81, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x87, 0xb8, 0x84, 0x22, 0x44, 0x00, 0x00, 0x9e,
+0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x30, 0x00, 0x05, 0x58, 0x31, 0x86, 0xf4, 0x44, 0x10, 0x00, 0x9f,
+0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x4b, 0xe0, 0x0c, 0x01, 0xf4, 0x1a, 0x44, 0x00, 0x00, 0x9f,
+0x58, 0x12, 0x00, 0x06, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x86, 0x6c,
+0x4e, 0xa2, 0x00, 0x2a, 0x50, 0x2f, 0x80, 0x6c, 0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0xf0, 0x1b, 0x44, 0x10, 0x00, 0x3a, 0x54, 0x50,
+0x00, 0x80, 0xf5, 0x9b, 0x40, 0x2e, 0x14, 0x00, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0x50, 0x2f,
+0x80, 0x6c, 0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x85, 0xb4,
+0xdd, 0x2f, 0xf2, 0x1b, 0x44, 0x10, 0x00, 0x3b, 0x54, 0x31, 0x00, 0x80, 0x40, 0x2e, 0x0c, 0x00,
+0x84, 0x00, 0xd5, 0x24, 0x84, 0x26, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0xf4, 0x1b, 0x84, 0x26, 0x54, 0x62, 0x00, 0x80, 0xf6, 0x9b,
+0x40, 0x24, 0x18, 0x00, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x27, 0x50, 0x2f, 0x80, 0x6c,
+0x84, 0x05, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0xf1, 0x1b, 0x84, 0x05,
+0x54, 0x30, 0x80, 0x80, 0x40, 0x24, 0x0c, 0x00, 0x84, 0x27, 0xf3, 0x9b, 0x4b, 0xe0, 0x1c, 0x01,
+0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd, 0x9c, 0x49,
+0x84, 0x6a, 0x4c, 0x11, 0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f,
+0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf2, 0x1a,
+0x44, 0x00, 0x00, 0x15, 0x58, 0x11, 0x00, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8,
+0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x09, 0x92, 0x00, 0x84, 0xa7, 0x9c, 0x01, 0xd8, 0xfd, 0x9c, 0x49,
+0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf7, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f,
+0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf1, 0x1a,
+0x44, 0x00, 0x00, 0x15, 0x54, 0x10, 0x80, 0xfe, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8,
+0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01, 0x4c, 0x03, 0x7f, 0xfd,
+0x9c, 0x49, 0x84, 0x8a, 0x4c, 0x12, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x07, 0xb8, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x00,
+0x00, 0x9f, 0x44, 0x10, 0x00, 0x82, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0xc0, 0x84, 0x20, 0xd5, 0x0a,
+0x92, 0x00, 0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x6a, 0x4c, 0x11,
+0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x44, 0x10, 0x00, 0x9f,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf2, 0x1a, 0x84, 0xa2, 0xd2, 0x07,
+0x44, 0x00, 0x00, 0x14, 0x4c, 0x60, 0x00, 0x04, 0x9d, 0xb1, 0xd5, 0xe1, 0x44, 0x10, 0x00, 0x39,
+0x44, 0x00, 0x00, 0x9e, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x44, 0x10,
+0x00, 0x9f, 0x84, 0x00, 0x50, 0x2f, 0x80, 0x68, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4,
+0xdd, 0x2f, 0x00, 0x1f, 0x80, 0x68, 0x54, 0x10, 0x80, 0x7f, 0x5e, 0xf0, 0x80, 0x40, 0xe9, 0x05,
+0x44, 0x4f, 0xff, 0x80, 0x40, 0x10, 0x90, 0x04, 0x05, 0xef, 0x80, 0x01, 0xf6, 0x02, 0x40, 0x1f,
+0x04, 0x01, 0x40, 0x2e, 0x28, 0x1b, 0x40, 0x24, 0x28, 0x1a, 0xe0, 0xc1, 0xe8, 0x22, 0xca, 0x2d,
+0x4e, 0x93, 0x00, 0x12, 0x4e, 0xa2, 0x00, 0x09, 0x46, 0x70, 0x00, 0x0c, 0x58, 0x73, 0x82, 0x29,
+0x10, 0x93, 0x80, 0x00, 0xd5, 0x4e, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x28, 0x10, 0xa4,
+0x80, 0x00, 0xd5, 0x47, 0x4e, 0xa2, 0x00, 0x07, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x82, 0x2b,
+0xd5, 0x4a, 0x46, 0x30, 0x00, 0x0c, 0x58, 0x31, 0x82, 0x2a, 0x10, 0xa1, 0x80, 0x00, 0xd5, 0x4b,
+0x5e, 0xf1, 0x00, 0x3f, 0xe8, 0x0a, 0x4e, 0xa2, 0x00, 0x06, 0x51, 0xce, 0x00, 0x01, 0x48, 0xff,
+0xfe, 0xe1, 0x8d, 0x01, 0x48, 0xff, 0xfe, 0xde, 0xf5, 0x02, 0xe0, 0x25, 0xe8, 0x19, 0x44, 0x00,
+0x00, 0x3f, 0x4c, 0x20, 0x40, 0x16, 0x4e, 0x93, 0x00, 0x0b, 0x4e, 0xa2, 0x00, 0x1d, 0x46, 0x10,
+0x00, 0x0c, 0x58, 0x10, 0x82, 0x29, 0x11, 0xc0, 0x80, 0x00, 0xd5, 0x1b, 0x4e, 0xa2, 0x00, 0x26,
+0x46, 0x40, 0x00, 0x0c, 0x58, 0x42, 0x02, 0x2b, 0x11, 0xc2, 0x00, 0x00, 0xd5, 0x24, 0x4e, 0x93,
+0x00, 0x14, 0x4e, 0xa2, 0x00, 0x09, 0x47, 0xe0, 0x00, 0x0c, 0x59, 0xef, 0x02, 0x29, 0x11, 0xcf,
+0x00, 0x00, 0xd5, 0x07, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x28, 0x10, 0x84, 0x80, 0x00,
+0x85, 0x21, 0x48, 0xff, 0xfc, 0x2a, 0x4e, 0xa2, 0x00, 0x09, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10,
+0x82, 0x2b, 0x80, 0x5c, 0xae, 0x88, 0xd5, 0x07, 0x46, 0x30, 0x00, 0x0c, 0x58, 0x31, 0x82, 0x2a,
+0x10, 0x81, 0x80, 0x00, 0x8d, 0x21, 0x84, 0xa2, 0x4c, 0x92, 0xfc, 0x17, 0x46, 0x20, 0x04, 0x10,
+0x46, 0x10, 0x04, 0x10, 0x85, 0x00, 0x58, 0x21, 0x05, 0x0c, 0x58, 0x10, 0x85, 0x04, 0xb7, 0x02,
+0xb7, 0x01, 0x50, 0x2f, 0x80, 0x6c, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0xf0, 0x1b, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x06, 0x6c,
+0x54, 0x20, 0x00, 0x7f, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12,
+0x80, 0x48, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x13, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x14, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x19, 0x84, 0x23, 0x84, 0x05,
+0xdd, 0x26, 0xf2, 0x18, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0xf2, 0x17, 0x80, 0x20,
+0xdd, 0x26, 0xf2, 0x16, 0x80, 0x28, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x15, 0x84, 0x26, 0x84, 0x05,
+0xdd, 0x26, 0xf2, 0x14, 0x84, 0x05, 0x84, 0x27, 0xdd, 0x26, 0x50, 0x9f, 0x80, 0x1c, 0x44, 0x70,
+0x00, 0x25, 0x0c, 0x24, 0x80, 0x01, 0x80, 0x27, 0x84, 0x05, 0xdd, 0x26, 0x9d, 0xf9, 0x44, 0x40,
+0x00, 0x2f, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x06, 0x6c, 0x4c, 0x72, 0x7f, 0xf4, 0xf2, 0x12,
+0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0x4b, 0xe0, 0x20, 0x01, 0xf2, 0x11, 0x44, 0x10, 0x00, 0x3b,
+0x84, 0x05, 0x4b, 0xe0, 0x20, 0x01, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x50, 0x8f,
+0x80, 0x68, 0x84, 0x22, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94,
+0x86, 0xf4, 0x80, 0x48, 0x44, 0x10, 0x00, 0x9f, 0x84, 0x00, 0x4b, 0xe0, 0x24, 0x01, 0xf3, 0x1a,
+0x44, 0x00, 0x00, 0x9f, 0x54, 0x11, 0x80, 0xf9, 0xdd, 0x26, 0x80, 0x48, 0x84, 0x24, 0x84, 0x00,
+0x4b, 0xe0, 0x24, 0x01, 0xf7, 0x1a, 0x84, 0x04, 0x54, 0x13, 0x80, 0xf3, 0xdd, 0x26, 0xf1, 0x13,
+0x44, 0x00, 0x00, 0x17, 0xdd, 0x26, 0x05, 0xef, 0x80, 0x03, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73,
+0x85, 0xb4, 0x50, 0x8f, 0x80, 0x6c, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x06, 0x6c, 0x4f, 0xe3,
+0x00, 0x4c, 0x80, 0x48, 0x84, 0x26, 0x84, 0x05, 0xdd, 0x27, 0xf5, 0x1b, 0x46, 0x90, 0x00, 0x0c,
+0x58, 0x94, 0x82, 0x28, 0x54, 0x42, 0x80, 0xc0, 0x00, 0x14, 0x80, 0x00, 0xf4, 0x9b, 0x98, 0x8c,
+0x84, 0x05, 0x84, 0x26, 0xdd, 0x26, 0x80, 0x48, 0x84, 0x27, 0x84, 0x05, 0xdd, 0x27, 0xf3, 0x1b,
+0x00, 0x04, 0x80, 0x00, 0x54, 0x91, 0x80, 0xc0, 0x14, 0x9f, 0x80, 0x1b, 0x40, 0x20, 0x24, 0x00,
+0x84, 0x27, 0x84, 0x05, 0xdd, 0x26, 0x80, 0x48, 0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0xdd, 0x27,
+0xf2, 0x1b, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x29, 0x54, 0x41, 0x00, 0xc0, 0x00, 0x54,
+0x80, 0x00, 0xf4, 0x9b, 0x98, 0xac, 0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0xdd, 0x26, 0x80, 0x48,
+0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x27, 0xf1, 0x1b, 0x00, 0x04, 0x80, 0x00, 0x54, 0x50,
+0x80, 0xc0, 0xf5, 0x9b, 0x98, 0x85, 0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x03,
+0x84, 0x28, 0x84, 0x05, 0xd5, 0x49, 0x84, 0x26, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x27, 0xf1, 0x1b,
+0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x2a, 0x54, 0x40, 0x80, 0xc0, 0x00, 0x04, 0x80, 0x00,
+0xf4, 0x9b, 0x98, 0x84, 0x84, 0x26, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x27, 0x80, 0x48, 0x84, 0x05,
+0xdd, 0x27, 0xf3, 0x1b, 0x00, 0x24, 0x80, 0x00, 0x54, 0x91, 0x80, 0xc0, 0x14, 0x9f, 0x80, 0x1b,
+0x88, 0x49, 0x84, 0x27, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x3a, 0x80, 0x48, 0x84, 0x05,
+0xdd, 0x27, 0xf5, 0x1b, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x2b, 0x54, 0x42, 0x80, 0xc0,
+0x00, 0x14, 0x80, 0x00, 0xf4, 0x9b, 0x98, 0x8c, 0x84, 0x05, 0x44, 0x10, 0x00, 0x3a, 0xdd, 0x26,
+0x80, 0x48, 0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x27, 0xf0, 0x1b, 0x00, 0x24, 0x80, 0x00,
+0x54, 0x30, 0x00, 0xc0, 0xf3, 0x9b, 0x98, 0x93, 0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x26,
+0x84, 0x05, 0x84, 0x28, 0x84, 0x44, 0xdd, 0x26, 0xec, 0x74, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xcc, 0x46, 0x50, 0x04, 0x11, 0x58, 0x52, 0x80, 0x04, 0x84, 0xc0,
+0x05, 0xc2, 0x80, 0x00, 0x46, 0x30, 0x04, 0x10, 0xb6, 0xc5, 0x58, 0x31, 0x85, 0x04, 0x44, 0x40,
+0x18, 0x30, 0xb5, 0x43, 0x46, 0x00, 0x04, 0x10, 0xb6, 0x83, 0x58, 0x00, 0x05, 0x0c, 0x44, 0x10,
+0x20, 0x00, 0xb5, 0x20, 0xb6, 0x20, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x05, 0xb4, 0x50, 0x2f,
+0x80, 0x2c, 0x84, 0x24, 0x84, 0x05, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x86, 0x6c, 0xdd, 0x28,
+0x84, 0x24, 0x44, 0x20, 0x00, 0x27, 0x84, 0x05, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x28, 0x44, 0x10,
+0x00, 0x11, 0x84, 0x05, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05,
+0xdd, 0x27, 0x50, 0x2f, 0x80, 0x24, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x28, 0x44, 0x10,
+0x00, 0x12, 0x44, 0x20, 0x00, 0x83, 0x84, 0x05, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x20, 0x44, 0x10,
+0x00, 0x13, 0x84, 0x05, 0xdd, 0x28, 0x50, 0x2f, 0x80, 0x1c, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05,
+0xdd, 0x28, 0x80, 0x46, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x14,
+0x44, 0x20, 0x00, 0x20, 0x84, 0x05, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x18, 0x80, 0x06, 0x84, 0x21,
+0xdd, 0x28, 0x80, 0x46, 0x80, 0x06, 0x84, 0x21, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x14, 0x80, 0x06,
+0x44, 0x10, 0x00, 0x22, 0xdd, 0x28, 0x80, 0x06, 0x44, 0x10, 0x00, 0x22, 0x44, 0x20, 0x00, 0x13,
+0xdd, 0x27, 0x50, 0x2f, 0x80, 0x10, 0x80, 0x06, 0x44, 0x10, 0x00, 0x23, 0xdd, 0x28, 0x80, 0x46,
+0x80, 0x06, 0x44, 0x10, 0x00, 0x23, 0xdd, 0x27, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x07, 0xb8,
+0x84, 0x24, 0x44, 0x00, 0x00, 0x2f, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x16,
+0xdd, 0x28, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0x28, 0xdd, 0x2f, 0x50, 0x2f,
+0x80, 0x0c, 0x80, 0x06, 0x44, 0x10, 0x00, 0x31, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4,
+0xdd, 0x2f, 0xf2, 0x03, 0x80, 0x26, 0xf2, 0x81, 0x44, 0x00, 0x00, 0x16, 0xdd, 0x28, 0x80, 0x06,
+0x44, 0x10, 0x00, 0x23, 0x84, 0x41, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x16,
+0xdd, 0x28, 0xd5, 0x0b, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0x49, 0x4c, 0x1f, 0x7f, 0xfd, 0x9d, 0xb1,
+0x44, 0x70, 0x00, 0x3c, 0x4c, 0x63, 0x80, 0x04, 0x84, 0x20, 0xd5, 0xf5, 0x44, 0x10, 0x00, 0x31,
+0x50, 0x2f, 0x80, 0x0c, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f,
+0xf6, 0x01, 0x20, 0x7f, 0x80, 0x0c, 0x97, 0x72, 0x9a, 0x3d, 0x44, 0x40, 0x03, 0xe8, 0x42, 0x20,
+0x10, 0x24, 0x44, 0x30, 0x00, 0x2b, 0x40, 0x01, 0x0c, 0x36, 0x84, 0x2a, 0x40, 0x20, 0x04, 0xd6,
+0xe4, 0xc5, 0xe9, 0x02, 0x8c, 0x0a, 0x87, 0xca, 0x40, 0x20, 0x78, 0x16, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x06, 0x6c, 0x84, 0x27, 0x84, 0x00, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x87, 0xb8,
+0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x16, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x21, 0x44, 0x00,
+0x00, 0x15, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0x4b, 0xe0, 0x1c, 0x01,
+0xf2, 0x0b, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0a, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05,
+0xdd, 0x26, 0xf2, 0x09, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x08, 0x44, 0x10,
+0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x07, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26,
+0xf2, 0x06, 0x84, 0x21, 0x84, 0x00, 0xdd, 0x26, 0xf2, 0x05, 0x44, 0x10, 0x00, 0x22, 0x84, 0x00,
+0xdd, 0x26, 0xf2, 0x04, 0x44, 0x10, 0x00, 0x23, 0x84, 0x00, 0xdd, 0x26, 0x46, 0x20, 0x04, 0x11,
+0x46, 0x10, 0x04, 0x10, 0x46, 0x30, 0x04, 0x10, 0x58, 0x31, 0x85, 0x0c, 0x58, 0x21, 0x00, 0x04,
+0x58, 0x10, 0x85, 0x04, 0x15, 0xc1, 0x00, 0x00, 0xb7, 0x41, 0xb7, 0x23, 0x84, 0x27, 0x50, 0x2f,
+0x80, 0x08, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x85, 0xb4, 0xdd, 0x2f, 0xec, 0x34,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x46, 0x50,
+0x08, 0x21, 0x58, 0x52, 0x80, 0x04, 0xb4, 0x85, 0x46, 0x10, 0x04, 0x11, 0x84, 0x73, 0x58, 0x10,
+0x80, 0x04, 0x40, 0x22, 0x0c, 0x02, 0xb6, 0x41, 0x46, 0x10, 0x04, 0x11, 0x80, 0xc0, 0x58, 0x10,
+0x82, 0x00, 0x84, 0x00, 0xb5, 0x01, 0x54, 0x74, 0x00, 0x03, 0xc7, 0x14, 0x84, 0x40, 0xd5, 0x0b,
+0x92, 0x00, 0x85, 0x27, 0x9c, 0xd9, 0x4c, 0x34, 0xff, 0xfd, 0x9c, 0x91, 0x45, 0xe0, 0x00, 0x32,
+0x4c, 0x2f, 0x00, 0x04, 0x84, 0x60, 0xd5, 0xf5, 0x9c, 0x01, 0x44, 0x20, 0x27, 0x10, 0x4c, 0x01,
+0x7f, 0xeb, 0x84, 0xa0, 0x84, 0x24, 0x40, 0x2f, 0x84, 0x00, 0x80, 0x05, 0xf5, 0x81, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf0, 0x01, 0x44, 0x3f, 0xff, 0xe7, 0x84, 0x81,
+0x40, 0x10, 0x0c, 0x02, 0x4c, 0x62, 0x00, 0x06, 0x84, 0xe3, 0x4c, 0x63, 0xc0, 0x08, 0xd5, 0x04,
+0x58, 0x10, 0x80, 0x10, 0xd5, 0x03, 0x58, 0x10, 0x80, 0x08, 0x4c, 0x10, 0x00, 0x08, 0x84, 0x04,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x46, 0x00, 0x04, 0x11, 0x58, 0x00,
+0x00, 0x04, 0xb5, 0x00, 0x58, 0x14, 0x00, 0x0c, 0xb6, 0x20, 0xc6, 0x05, 0x85, 0x21, 0x4c, 0x64,
+0xc0, 0xbc, 0xd5, 0x5d, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x87, 0xb8, 0x44, 0x10, 0x00, 0x24,
+0x44, 0x00, 0x00, 0xc3, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x10, 0x00, 0x30, 0x44, 0x00, 0x00, 0xc4,
+0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x85, 0xb4, 0x80, 0x5f, 0x84, 0x26,
+0x84, 0x05, 0xdd, 0x27, 0xb4, 0xdf, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x82, 0x28, 0x54, 0x33,
+0x00, 0xc0, 0x00, 0x90, 0x80, 0x00, 0xb6, 0x7f, 0x40, 0x24, 0x8c, 0x00, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x06, 0x6c, 0x84, 0x26, 0x84, 0x05, 0xdd, 0x26, 0x80, 0x5f, 0x84, 0x27, 0x84, 0x05,
+0xdd, 0x27, 0xb4, 0x1f, 0x84, 0x27, 0x54, 0x40, 0x00, 0xc0, 0xb6, 0x9f, 0x40, 0x22, 0x24, 0x00,
+0x84, 0x05, 0xdd, 0x26, 0x80, 0x5f, 0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0xdd, 0x27, 0xb4, 0x7f,
+0x46, 0x50, 0x00, 0x0c, 0x58, 0x52, 0x82, 0x29, 0x54, 0x41, 0x80, 0xc0, 0x00, 0x92, 0x80, 0x00,
+0xb6, 0x9f, 0x40, 0x24, 0x90, 0x00, 0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0xdd, 0x26, 0x80, 0x5f,
+0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x27, 0xb4, 0x5f, 0x81, 0x1f, 0x54, 0x31, 0x00, 0xc0,
+0x44, 0x10, 0x00, 0x3b, 0x40, 0x21, 0xa4, 0x00, 0x84, 0x05, 0xd5, 0x5c, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x87, 0xb8, 0x44, 0x10, 0x00, 0x24, 0x44, 0x00, 0x00, 0xc3, 0x4b, 0xe0, 0x1c, 0x01,
+0x44, 0x10, 0x00, 0x3a, 0x44, 0x00, 0x00, 0xc4, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x85, 0xb4, 0x84, 0x26, 0x80, 0x5f, 0x84, 0x05, 0xdd, 0x27, 0xb4, 0xdf, 0x46, 0x10,
+0x00, 0x0c, 0x58, 0x10, 0x82, 0x2a, 0x54, 0x53, 0x00, 0xc0, 0x00, 0x90, 0x80, 0x00, 0xb6, 0xbf,
+0x40, 0x24, 0x94, 0x00, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x06, 0x6c, 0x84, 0x26, 0x84, 0x05,
+0xdd, 0x26, 0x84, 0x27, 0x80, 0x5f, 0x84, 0x05, 0xdd, 0x27, 0xb4, 0x5f, 0x84, 0x27, 0x54, 0x31,
+0x00, 0xc0, 0xb6, 0x7f, 0x40, 0x21, 0xa4, 0x00, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x3a,
+0x80, 0x5f, 0x84, 0x05, 0xdd, 0x27, 0xb4, 0x9f, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x2b,
+0x00, 0x90, 0x00, 0x00, 0x54, 0x52, 0x00, 0xc0, 0xb6, 0xbf, 0x40, 0x24, 0x94, 0x00, 0x44, 0x10,
+0x00, 0x3a, 0x84, 0x05, 0xdd, 0x26, 0x80, 0x5f, 0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x27,
+0xb4, 0x5f, 0x81, 0x1f, 0x54, 0x31, 0x00, 0xc0, 0x84, 0x05, 0x40, 0x21, 0xa4, 0x00, 0x44, 0x10,
+0x00, 0x3b, 0xb6, 0x7f, 0xdd, 0x26, 0x84, 0x01, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x84, 0x40, 0xf2, 0x81, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x97,
+0x82, 0x34, 0x54, 0x80, 0x00, 0xff, 0x46, 0x60, 0x00, 0x09, 0x58, 0x63, 0x03, 0x9c, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x86, 0x6c, 0xa7, 0x70, 0x4c, 0x54, 0x40, 0x16, 0xa6, 0xb1, 0x44, 0x10,
+0x00, 0x11, 0x84, 0x00, 0xdd, 0x27, 0xa6, 0xb2, 0x44, 0x10, 0x00, 0x12, 0x84, 0x00, 0xdd, 0x27,
+0xa6, 0xb3, 0x44, 0x10, 0x00, 0x13, 0x84, 0x00, 0xdd, 0x27, 0xa6, 0xb4, 0x84, 0x00, 0x44, 0x10,
+0x00, 0x14, 0xdd, 0x27, 0x9d, 0xb5, 0x46, 0x50, 0x00, 0x09, 0x58, 0x52, 0x83, 0xe2, 0xde, 0xe4,
+0x46, 0x50, 0x04, 0x11, 0x04, 0x22, 0x80, 0xec, 0x44, 0x0f, 0xc0, 0xc0, 0x54, 0x14, 0x80, 0x3f,
+0x41, 0xe1, 0x00, 0x02, 0x40, 0x40, 0xf8, 0x04, 0x14, 0x42, 0x80, 0xec, 0xe7, 0x0f, 0xe8, 0x1a,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x77, 0x80, 0x8e, 0x44, 0x00, 0x00, 0x3e, 0x52, 0x73, 0x80, 0x37,
+0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x80, 0x27, 0x4b, 0xe0, 0x18, 0x01, 0x80, 0x27,
+0x44, 0x00, 0x00, 0x3f, 0x4b, 0xe0, 0x18, 0x01, 0x80, 0x27, 0x44, 0x00, 0x00, 0x40, 0x4b, 0xe0,
+0x18, 0x01, 0x84, 0x24, 0x40, 0x2f, 0x84, 0x00, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x85, 0xb4, 0xdd, 0x2f, 0xf1, 0x01, 0x84, 0x00, 0x58, 0x30, 0x80, 0x80, 0x80, 0x43, 0x84, 0x24,
+0xf3, 0x81, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0x6c, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0c,
+0x00, 0x47, 0x82, 0x2e, 0x40, 0x32, 0x04, 0x09, 0x54, 0x01, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x06,
+0x58, 0xf7, 0x8d, 0x58, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x96, 0x49, 0xe6, 0x38, 0xe9, 0x36, 0x80, 0x60, 0xa2, 0x59,
+0x47, 0xe0, 0x00, 0x0c, 0x14, 0x1f, 0x00, 0x8b, 0xb4, 0xa3, 0x50, 0x20, 0x00, 0x08, 0x46, 0xf0,
+0x00, 0x0c, 0x14, 0x57, 0x80, 0x8c, 0xb4, 0x62, 0x50, 0x20, 0x00, 0x0c, 0x46, 0xf0, 0x00, 0x0c,
+0x14, 0x37, 0x80, 0x8d, 0xb4, 0xa2, 0x50, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x57,
+0x80, 0x8e, 0x50, 0x50, 0x00, 0x14, 0xb4, 0x82, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x47, 0x80, 0x8f,
+0x00, 0x0f, 0x02, 0x2c, 0xb4, 0x65, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x37, 0x80, 0x90, 0x5c, 0xf0,
+0x00, 0x37, 0xe8, 0x0a, 0x42, 0x10, 0xa0, 0x0b, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x8f, 0x90,
+0xdd, 0x2f, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xec, 0x85, 0x00, 0x14, 0x8f, 0x80, 0x03, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x07, 0xb8, 0x44, 0x10, 0x00, 0x10, 0x81, 0x40, 0x84, 0x04, 0xdd, 0x26, 0x44, 0x00,
+0x00, 0xba, 0x84, 0x21, 0xdd, 0x26, 0x84, 0xe3, 0x80, 0x66, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce,
+0x06, 0xf4, 0x50, 0x6f, 0x80, 0x08, 0xf3, 0x81, 0x80, 0x27, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x23,
+0x44, 0x10, 0x00, 0xbc, 0x84, 0x00, 0x80, 0x46, 0xdd, 0x3c, 0xf1, 0x02, 0x9d, 0xfc, 0x44, 0x00,
+0x00, 0x2f, 0x89, 0x01, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x87, 0xb8, 0xf3, 0x01, 0x4c, 0x70,
+0x7f, 0xec, 0x9e, 0x44, 0x44, 0x00, 0x00, 0xbb, 0x4b, 0xe0, 0x24, 0x01, 0x50, 0x2f, 0x80, 0x0c,
+0x44, 0x10, 0x00, 0xbc, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f,
+0x84, 0x20, 0x84, 0x04, 0x4b, 0xe0, 0x24, 0x01, 0xf0, 0x03, 0x44, 0x50, 0x00, 0x37, 0x42, 0x30,
+0x14, 0x24, 0x84, 0x96, 0x40, 0x21, 0x90, 0x36, 0x89, 0x02, 0x40, 0x04, 0x28, 0x07, 0xec, 0x14,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x4c, 0x46, 0x60,
+0x00, 0x09, 0x58, 0x63, 0x03, 0xfc, 0x83, 0xc6, 0x3a, 0x0f, 0x0c, 0x04, 0x46, 0xa0, 0x00, 0x09,
+0x58, 0xa5, 0x03, 0xf4, 0x50, 0x9f, 0x80, 0x48, 0x46, 0x50, 0x00, 0x09, 0x58, 0x52, 0x83, 0xec,
+0x51, 0xcf, 0x80, 0x64, 0x3a, 0x04, 0x8c, 0x24, 0x46, 0x20, 0x00, 0x09, 0x58, 0x21, 0x03, 0xe4,
+0x50, 0x6f, 0x80, 0x34, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x87, 0x08, 0x3a, 0x05, 0x04, 0x00,
+0x81, 0x09, 0xf0, 0x9b, 0x12, 0x1e, 0x00, 0x06, 0x3a, 0x02, 0x84, 0x00, 0x85, 0x20, 0xb4, 0x9e,
+0xb6, 0x1c, 0x12, 0x1e, 0x00, 0x02, 0x3a, 0x01, 0x04, 0x00, 0x41, 0xe2, 0x40, 0x09, 0x50, 0xaf,
+0x80, 0x5c, 0xb6, 0x0a, 0x12, 0x44, 0x00, 0x00, 0x12, 0x15, 0x00, 0x02, 0x11, 0xef, 0x80, 0x5a,
+0x14, 0x9f, 0x80, 0x2a, 0x44, 0x20, 0x00, 0x14, 0x80, 0x29, 0x80, 0x06, 0x4b, 0xe0, 0x1c, 0x01,
+0xa6, 0xf3, 0xa5, 0x73, 0x00, 0x83, 0x00, 0x04, 0x40, 0x22, 0xb8, 0x09, 0x40, 0x21, 0x38, 0x08,
+0x54, 0x41, 0x80, 0x3f, 0x54, 0x04, 0x00, 0x03, 0x44, 0x1f, 0xff, 0x80, 0x87, 0xc7, 0x58, 0x51,
+0x00, 0x18, 0x40, 0x32, 0x04, 0x04, 0x11, 0xe3, 0x00, 0x02, 0x58, 0x40, 0x00, 0x1c, 0x87, 0xc1,
+0x50, 0x8f, 0x80, 0x1c, 0x11, 0xe3, 0x00, 0x05, 0xad, 0x73, 0xae, 0xf3, 0xaf, 0x34, 0x80, 0x29,
+0x44, 0x20, 0x00, 0x18, 0x80, 0x08, 0x4b, 0xe0, 0x1c, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x24,
+0x00, 0x01, 0x54, 0x00, 0x80, 0x03, 0x58, 0x31, 0x00, 0x01, 0x58, 0x40, 0x00, 0x08, 0x10, 0x34,
+0x00, 0x01, 0x10, 0x44, 0x00, 0x00, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xf0, 0x50, 0x1f,
+0x80, 0x6c, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x20, 0xdd, 0x27, 0x80, 0x3c, 0x84, 0x46, 0x50, 0x0f,
+0x80, 0x26, 0xdd, 0x27, 0x80, 0x2a, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x2c, 0xdd, 0x27, 0x46, 0x50,
+0x04, 0x10, 0x04, 0xa2, 0x81, 0x01, 0x45, 0xcf, 0xff, 0x1f, 0x40, 0x45, 0x70, 0x02, 0x14, 0x42,
+0x81, 0x01, 0x46, 0x00, 0x04, 0x1d, 0x80, 0x26, 0x44, 0x20, 0x00, 0x14, 0xdd, 0x27, 0x46, 0x00,
+0x04, 0x1d, 0x80, 0x28, 0x44, 0x20, 0x00, 0x18, 0x58, 0x00, 0x00, 0x14, 0xdd, 0x27, 0x46, 0x00,
+0x04, 0x11, 0x84, 0x24, 0xa8, 0x41, 0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x04, 0x10, 0xb4, 0x60,
+0x80, 0x29, 0x58, 0x21, 0x80, 0x04, 0xb6, 0x40, 0xb4, 0xe0, 0x9c, 0x49, 0x55, 0xc3, 0x80, 0x40,
+0x4f, 0xc2, 0x00, 0x05, 0x44, 0x50, 0x00, 0x64, 0xd9, 0xf8, 0x46, 0x80, 0x04, 0x11, 0x85, 0x20,
+0x14, 0x94, 0x00, 0x01, 0x80, 0xc8, 0x05, 0xe3, 0x00, 0xca, 0x46, 0xa0, 0x00, 0x05, 0x58, 0xa5,
+0x07, 0xb8, 0x15, 0xef, 0x80, 0x05, 0x80, 0x29, 0x44, 0x00, 0x00, 0x1b, 0xdd, 0x2a, 0x47, 0xc0,
+0x00, 0x05, 0x59, 0xce, 0x06, 0xf4, 0x44, 0x10, 0x00, 0x41, 0x50, 0x2f, 0x80, 0xac, 0x80, 0x09,
+0xdd, 0x3c, 0xf5, 0x2b, 0x50, 0x2f, 0x80, 0xac, 0xf5, 0x84, 0x44, 0x10, 0x00, 0x42, 0x80, 0x09,
+0xdd, 0x3c, 0xf2, 0x2b, 0x44, 0x10, 0x00, 0x8c, 0xf2, 0x83, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x2a,
+0x44, 0x10, 0x00, 0x9f, 0x50, 0x2f, 0x80, 0xac, 0x80, 0x09, 0xdd, 0x3c, 0xf0, 0x2b, 0x46, 0x40,
+0x00, 0xc0, 0x58, 0x42, 0x00, 0x20, 0xf0, 0x82, 0x14, 0x43, 0x00, 0xca, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x85, 0xb4, 0x84, 0x21, 0x50, 0x2f, 0x80, 0xa4, 0x84, 0x05, 0xdd, 0x27, 0x84, 0x21,
+0x50, 0x2f, 0x80, 0xa0, 0x80, 0x09, 0xdd, 0x27, 0x80, 0x29, 0x50, 0x2f, 0x80, 0x9c, 0x84, 0x04,
+0xdd, 0x27, 0x84, 0x2b, 0x50, 0x2f, 0x80, 0x98, 0x84, 0x04, 0xdd, 0x27, 0x84, 0x2d, 0x50, 0x2f,
+0x80, 0x94, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x90, 0x84, 0x04,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x8c, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10,
+0x00, 0x16, 0x50, 0x2f, 0x80, 0x88, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x11, 0x50, 0x2f,
+0x80, 0x84, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f, 0x80, 0x80, 0x84, 0x05,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x7c, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10,
+0x00, 0x14, 0x50, 0x2f, 0x80, 0x78, 0x84, 0x05, 0xdd, 0x27, 0x84, 0x21, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x06, 0x6c, 0x80, 0x41, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x21, 0x44, 0x20, 0x00, 0xe1,
+0x80, 0x09, 0xdd, 0x26, 0x80, 0x29, 0x44, 0x20, 0x00, 0x83, 0x84, 0x04, 0xdd, 0x26, 0x84, 0x2b,
+0x44, 0x20, 0x00, 0x51, 0x84, 0x04, 0xdd, 0x26, 0x84, 0x2d, 0x44, 0x20, 0x00, 0x3c, 0x84, 0x04,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0x24, 0x84, 0x04, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x15, 0x9e, 0x8b, 0x84, 0x04, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x16, 0x44, 0x20, 0x00, 0xa1,
+0x84, 0x04, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xf1, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x13,
+0x44, 0x20, 0x00, 0xa1, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x41, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x10, 0x9c, 0x0f, 0xdd, 0x2a, 0x80, 0x29, 0x44, 0x00, 0x00, 0x6d,
+0xdd, 0x2a, 0x80, 0x29, 0x44, 0x00, 0x00, 0x6e, 0xdd, 0x2a, 0x84, 0x28, 0x14, 0x14, 0x00, 0x01,
+0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0x8c, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x40, 0x44, 0x00,
+0x00, 0x9f, 0xdd, 0x2a, 0x80, 0x29, 0x44, 0x00, 0x00, 0x1b, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x39,
+0x44, 0x00, 0x00, 0x41, 0xdd, 0x2a, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0x8c, 0xdd, 0x2a,
+0x80, 0xc9, 0x50, 0x8f, 0x80, 0xac, 0x80, 0xfc, 0x84, 0x00, 0x44, 0x10, 0x00, 0x8c, 0x80, 0x48,
+0xdd, 0x27, 0xf3, 0x2b, 0x9d, 0xb1, 0xc3, 0x04, 0x44, 0x50, 0x00, 0x64, 0xde, 0xf6, 0x46, 0x60,
+0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x84, 0x20, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x22,
+0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26, 0x84, 0x2a, 0x44, 0x00, 0x00, 0xbc, 0xdd, 0x26, 0x84, 0x23,
+0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x41, 0x44, 0x00, 0x00, 0xbc, 0xdd, 0x26,
+0x84, 0x24, 0x44, 0x00, 0x00, 0xf1, 0xdd, 0x26, 0x87, 0x85, 0x44, 0x00, 0x00, 0xf2, 0x84, 0x20,
+0xdd, 0x26, 0x85, 0x20, 0x15, 0xcf, 0x80, 0x01, 0xb7, 0x3f, 0x50, 0xaf, 0x80, 0xa8, 0x50, 0x9f,
+0x80, 0xac, 0x50, 0x8f, 0x80, 0x74, 0x84, 0x20, 0x44, 0x00, 0x00, 0x1b, 0xdd, 0x26, 0x50, 0x4f,
+0x80, 0x48, 0x38, 0x12, 0x70, 0x00, 0x44, 0x00, 0x00, 0x42, 0xdd, 0x26, 0x84, 0x24, 0x84, 0x00,
+0x80, 0x4a, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf1, 0x2a, 0x54, 0x70,
+0x80, 0x10, 0xcf, 0x05, 0x58, 0x10, 0x80, 0x10, 0x84, 0x04, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x11,
+0x44, 0x00, 0x00, 0xf4, 0xdd, 0x26, 0x84, 0x21, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x26, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x15, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x21,
+0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0xbc, 0xdd, 0x26,
+0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0x28, 0xdd, 0x2f, 0x84, 0xe0, 0x44, 0x10,
+0x00, 0xbc, 0x84, 0x00, 0x80, 0x49, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f,
+0xf0, 0x2b, 0x9d, 0xf9, 0x54, 0x10, 0x00, 0x80, 0xc1, 0x04, 0x44, 0x50, 0x00, 0x64, 0xdf, 0xf0,
+0xf1, 0x2a, 0x84, 0x04, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x26, 0x84, 0x21,
+0x44, 0x00, 0x00, 0x15, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x26, 0x84, 0x21,
+0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xff, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0xbc, 0x84, 0x00, 0x80, 0x48, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4,
+0xdd, 0x2f, 0xf1, 0x1d, 0x5c, 0xf0, 0x80, 0xb4, 0xe8, 0x08, 0x51, 0xce, 0x00, 0x01, 0x5e, 0xfe,
+0x00, 0x13, 0xe9, 0x8a, 0x48, 0x00, 0x00, 0x89, 0x5c, 0xf0, 0x80, 0xf6, 0xe9, 0x07, 0x51, 0xce,
+0x7f, 0xff, 0x4f, 0xc4, 0xff, 0x82, 0x48, 0x00, 0x00, 0x80, 0xb4, 0x9f, 0x84, 0x65, 0x40, 0x22,
+0x0c, 0xb6, 0x87, 0xc4, 0x4c, 0x5f, 0x40, 0x05, 0xf0, 0x01, 0x9c, 0x43, 0xf1, 0x81, 0xb4, 0x5f,
+0x84, 0xa5, 0xd2, 0x72, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7, 0x81, 0x10, 0xdd, 0x2f,
+0x84, 0x41, 0x4c, 0x01, 0x00, 0x09, 0x05, 0xef, 0x80, 0x00, 0x40, 0x7f, 0x08, 0x00, 0xb6, 0xff,
+0x48, 0xff, 0xff, 0x63, 0xf0, 0x2a, 0x54, 0x60, 0x00, 0x10, 0xce, 0x09, 0x58, 0x10, 0x00, 0x10,
+0x84, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x07, 0xb8, 0x84, 0x23, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x23, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x2f, 0x44, 0x00, 0x00, 0xbd, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x2f, 0x44, 0x00,
+0x00, 0xbd, 0xdd, 0x26, 0x84, 0x25, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x25, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x2f, 0x44, 0x00, 0x00, 0xbd, 0xdd, 0x26, 0x84, 0x26, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x26, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x2f, 0x44, 0x00,
+0x00, 0xbd, 0xdd, 0x26, 0x84, 0x27, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x27, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x2f, 0x44, 0x00, 0x00, 0xbd, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x1c,
+0x44, 0x00, 0x00, 0xbc, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26, 0x44, 0x00,
+0x00, 0xbc, 0x9c, 0x44, 0xdd, 0x26, 0xf1, 0x05, 0x46, 0x00, 0x04, 0x11, 0x14, 0x10, 0x00, 0xca,
+0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0xf1, 0x2a, 0x84, 0x04, 0xdd, 0x26, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x1b, 0xdd, 0x26, 0xf1, 0x04, 0x44, 0x00, 0x00, 0x41, 0xdd, 0x26, 0xf1, 0x03,
+0x44, 0x00, 0x00, 0x42, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x8c, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0xf1, 0x02, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0xf2, 0x29, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x06, 0x6c, 0x84, 0x21, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x28, 0x84, 0x21, 0x84, 0x00, 0xdd, 0x26,
+0xf2, 0x27, 0x84, 0x20, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x26, 0x84, 0x2b, 0x84, 0x04, 0xdd, 0x26,
+0xf2, 0x25, 0x84, 0x2d, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x24, 0x44, 0x10, 0x00, 0x13, 0x84, 0x04,
+0xdd, 0x26, 0xf2, 0x23, 0x44, 0x10, 0x00, 0x15, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x22, 0x44, 0x10,
+0x00, 0x16, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x21, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26,
+0xf2, 0x20, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x1f, 0x44, 0x10, 0x00, 0x13,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x1e, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26, 0x46, 0x30,
+0x04, 0x11, 0x84, 0x80, 0xa9, 0x19, 0xec, 0xb4, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x54, 0x90,
+0x00, 0xff, 0x54, 0x80, 0x80, 0xff, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0xb0, 0x97, 0xd0,
+0x4b, 0xe0, 0x18, 0x01, 0x80, 0x29, 0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0, 0x18, 0x01, 0x4e, 0x83,
+0x00, 0x07, 0x44, 0x10, 0x00, 0xb1, 0x44, 0x00, 0x00, 0x9e, 0xd5, 0x05, 0x44, 0x00, 0x00, 0x9e,
+0x44, 0x10, 0x00, 0xb2, 0x4b, 0xe0, 0x18, 0x01, 0x80, 0x27, 0x44, 0x00, 0x00, 0x9f, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x54, 0x90,
+0x00, 0xff, 0x54, 0x80, 0x80, 0xff, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0xb0, 0x80, 0xe2,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x30, 0x00, 0xb2,
+0x44, 0x40, 0x00, 0xb1, 0x40, 0x12, 0x24, 0x1a, 0x40, 0x11, 0xa4, 0x1b, 0x44, 0x00, 0x00, 0x9e,
+0xdd, 0x26, 0x80, 0x28, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x15, 0x84, 0x21,
+0xdd, 0x26, 0x84, 0x00, 0x92, 0x00, 0x84, 0x27, 0x9c, 0x01, 0x4c, 0x00, 0xff, 0xfd, 0x46, 0x60,
+0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0x4b, 0xe0, 0x18, 0x01,
+0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x00, 0x00, 0x9f, 0x44, 0x10,
+0x00, 0x9b, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x00, 0x00, 0x9b, 0xf0, 0x81, 0x50, 0x6f, 0x80, 0x04,
+0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x06, 0xf4, 0xd5, 0x11, 0x92, 0x00, 0x84, 0x47, 0x9c, 0x49,
+0x4c, 0x11, 0x7f, 0xfd, 0x9c, 0x01, 0x84, 0xaa, 0xd0, 0x03, 0x84, 0x20, 0xd5, 0xf7, 0x84, 0x00,
+0x44, 0x10, 0x00, 0x9f, 0x80, 0x46, 0x4b, 0xe0, 0x20, 0x01, 0x05, 0xef, 0x80, 0x01, 0x44, 0x30,
+0x00, 0x9b, 0x4d, 0xe1, 0xc0, 0x04, 0x84, 0x00, 0xd5, 0xf1, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x07, 0xb8, 0x44, 0x10, 0x00, 0xba, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x2a,
+0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x40, 0x04, 0x10, 0x58, 0x42, 0x00, 0x7c,
+0xb4, 0x04, 0x40, 0x10, 0x40, 0x09, 0x4e, 0x04, 0x00, 0x05, 0x44, 0x2f, 0x00, 0x00, 0x98, 0x4a,
+0x45, 0xe0, 0x80, 0x00, 0x40, 0x50, 0x78, 0x02, 0x96, 0x01, 0xc5, 0x04, 0x44, 0x3f, 0x00, 0x00,
+0x98, 0x03, 0x42, 0x10, 0x84, 0x24, 0x42, 0x10, 0x00, 0x73, 0xb6, 0x27, 0xec, 0x0c, 0x3a, 0x6f,
+0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x74, 0x96, 0x00, 0xf0, 0x81, 0x4e, 0x03,
+0x02, 0x54, 0x47, 0xc0, 0x04, 0x11, 0x46, 0x80, 0x04, 0x10, 0x46, 0x60, 0x04, 0x10, 0x46, 0xa0,
+0x00, 0xcf, 0x44, 0x51, 0x20, 0x3e, 0x58, 0x84, 0x05, 0x0c, 0x59, 0xce, 0x00, 0x04, 0x58, 0x63,
+0x05, 0x04, 0x58, 0xa5, 0x08, 0x30, 0xb6, 0x1c, 0xb6, 0xa8, 0xb7, 0x46, 0x50, 0x2f, 0x80, 0x7c,
+0xf0, 0x01, 0x84, 0x24, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf2, 0x1f,
+0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x87, 0xb8, 0x54, 0x11, 0x00, 0xe7, 0x84, 0x04, 0x4b, 0xe0,
+0x24, 0x01, 0xf0, 0x01, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x05, 0xb4, 0x50, 0x2f, 0x80, 0x70,
+0x84, 0x21, 0xdd, 0x26, 0xf0, 0x01, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x22, 0xdd, 0x26, 0xf0, 0x01,
+0x50, 0x2f, 0x80, 0x68, 0x44, 0x10, 0x00, 0x23, 0xdd, 0x26, 0xf0, 0x01, 0x50, 0x2f, 0x80, 0x64,
+0x44, 0x10, 0x00, 0x2a, 0xdd, 0x26, 0xf1, 0x01, 0x50, 0x2f, 0x80, 0x60, 0x84, 0x04, 0xdd, 0x26,
+0x50, 0x2f, 0x80, 0x5c, 0x84, 0x22, 0x84, 0x04, 0xdd, 0x26, 0x50, 0x2f, 0x80, 0x58, 0x44, 0x10,
+0x00, 0x22, 0x84, 0x04, 0xdd, 0x26, 0x50, 0x2f, 0x80, 0x54, 0x84, 0x23, 0x84, 0x05, 0xdd, 0x26,
+0x50, 0x2f, 0x80, 0x50, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0x50, 0x2f, 0x80, 0x4c, 0x44, 0x10,
+0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0x50, 0x2f, 0x80, 0x48, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05,
+0xdd, 0x26, 0x50, 0x2f, 0x80, 0x44, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0x50, 0x2f,
+0x80, 0x40, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26, 0xf0, 0x01, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x86, 0x6c, 0x84, 0x21, 0x44, 0x20, 0x00, 0x21, 0xdd, 0x27, 0xf0, 0x01, 0x84, 0x22,
+0x44, 0x20, 0x00, 0x10, 0xdd, 0x27, 0xf0, 0x01, 0x44, 0x10, 0x00, 0x23, 0x80, 0x40, 0xdd, 0x27,
+0xf0, 0x01, 0x44, 0x10, 0x00, 0x2a, 0x44, 0x20, 0x00, 0x1b, 0xdd, 0x27, 0xf1, 0x01, 0x44, 0x20,
+0x00, 0x81, 0x84, 0x04, 0xdd, 0x27, 0x84, 0x22, 0x44, 0x20, 0x00, 0x81, 0x84, 0x04, 0xdd, 0x27,
+0x44, 0x10, 0x00, 0x22, 0x44, 0x20, 0x00, 0xee, 0x84, 0x04, 0xdd, 0x27, 0x84, 0x23, 0x44, 0x20,
+0x00, 0x3f, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x20, 0x00, 0x3f, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x27,
+0x46, 0x00, 0x60, 0x12, 0x58, 0x00, 0x00, 0x3e, 0xb6, 0x08, 0x44, 0x10, 0x00, 0x40, 0x44, 0x00,
+0x00, 0x16, 0x4b, 0xe0, 0x24, 0x01, 0x50, 0x8f, 0x80, 0x80, 0xf1, 0x01, 0x80, 0x48, 0x84, 0x05,
+0xdd, 0x26, 0x04, 0x9f, 0x80, 0x20, 0xf1, 0x01, 0x54, 0x44, 0x80, 0x01, 0xf4, 0xa0, 0x80, 0x44,
+0x84, 0x05, 0xdd, 0x27, 0x80, 0x48, 0x84, 0x21, 0x84, 0x05, 0xdd, 0x26, 0xf1, 0x20, 0x84, 0x05,
+0x58, 0x30, 0x80, 0x04, 0xf3, 0xa0, 0x80, 0x43, 0x84, 0x21, 0xdd, 0x27, 0xd5, 0x0b, 0x84, 0x00,
+0x92, 0x00, 0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd, 0x84, 0x05, 0x84, 0x21, 0x80, 0x48,
+0xdd, 0x26, 0xf7, 0x20, 0x54, 0x73, 0x80, 0x04, 0xcf, 0xf3, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84,
+0x07, 0xb8, 0x80, 0x27, 0x44, 0x00, 0x00, 0x16, 0x4b, 0xe0, 0x20, 0x01, 0x44, 0x00, 0x00, 0x15,
+0x84, 0x21, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x67, 0x92, 0x00, 0x84, 0x27, 0x9c, 0xd9, 0x4c, 0x30,
+0xff, 0xfd, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce, 0x07, 0xb8, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15,
+0xdd, 0x3c, 0x80, 0x49, 0x84, 0x20, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x86, 0x6c, 0x84, 0x05,
+0xdd, 0x29, 0x46, 0x10, 0x04, 0x11, 0x44, 0x30, 0x00, 0x10, 0x58, 0x10, 0x80, 0x04, 0xb6, 0x61,
+0x44, 0x20, 0x00, 0x80, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x12,
+0x44, 0x20, 0x00, 0xd7, 0x84, 0x05, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0xa2,
+0x84, 0x05, 0xdd, 0x29, 0x44, 0x20, 0x00, 0x20, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x29,
+0x44, 0x10, 0x00, 0xaa, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x3c, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x3c, 0x44, 0x10, 0x00, 0xab, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x3c, 0x84, 0x2a, 0x44, 0x00,
+0x00, 0x9f, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0xac, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x3c, 0x44, 0x10,
+0x00, 0x3f, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0xad, 0x44, 0x00, 0x00, 0x9e,
+0xdd, 0x3c, 0x44, 0x10, 0x00, 0x3f, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x40,
+0x44, 0x00, 0x00, 0xf4, 0xdd, 0x3c, 0x50, 0x2f, 0x80, 0x7c, 0x44, 0x10, 0x00, 0x1f, 0x84, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0x04, 0x8f, 0x80, 0x1f, 0x44, 0x00,
+0x00, 0x1f, 0x58, 0x74, 0x00, 0x60, 0xf7, 0x9f, 0x80, 0x27, 0xdd, 0x3c, 0x84, 0x25, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x3c, 0x44, 0x00, 0x00, 0x9f, 0x84, 0x20, 0xdd, 0x3c, 0x46, 0x60, 0x00, 0x09,
+0x58, 0x63, 0x04, 0x14, 0x46, 0x50, 0x00, 0x09, 0x58, 0x52, 0x84, 0x18, 0x46, 0x00, 0x00, 0x09,
+0x58, 0x00, 0x04, 0x10, 0xb5, 0x45, 0xb4, 0x46, 0xb5, 0x20, 0x46, 0x40, 0x00, 0x0c, 0x58, 0x42,
+0x02, 0x20, 0x84, 0x60, 0x14, 0xaf, 0x80, 0x09, 0xf2, 0x8a, 0x14, 0x9f, 0x80, 0x0b, 0xf4, 0x85,
+0xf3, 0x82, 0x05, 0xcf, 0x80, 0x09, 0xf5, 0x02, 0x15, 0xcf, 0x80, 0x0f, 0x50, 0xaf, 0x80, 0x3c,
+0x38, 0x65, 0x14, 0x00, 0xf4, 0x0a, 0xf3, 0x0b, 0x40, 0x03, 0x64, 0x08, 0x44, 0x21, 0x20, 0x3e,
+0x46, 0x90, 0x04, 0x10, 0x40, 0x10, 0x08, 0x04, 0x58, 0x94, 0x85, 0x0c, 0xf4, 0x8e, 0xf3, 0x8d,
+0xb6, 0x29, 0x50, 0x8f, 0x80, 0x38, 0x05, 0xef, 0x80, 0x02, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce,
+0x06, 0x6c, 0x38, 0x74, 0x78, 0x00, 0x84, 0x23, 0x80, 0x47, 0x84, 0x05, 0xdd, 0x3c, 0x80, 0x47,
+0x84, 0x24, 0x84, 0x05, 0xdd, 0x3c, 0xf5, 0x02, 0x50, 0xaf, 0x80, 0x34, 0x38, 0x15, 0x14, 0x00,
+0x44, 0x00, 0x00, 0x17, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x84, 0xc0,
+0x50, 0x2f, 0x80, 0x84, 0x44, 0x00, 0x00, 0x20, 0x84, 0x85, 0x85, 0x20, 0xaf, 0x91, 0xaf, 0x90,
+0xf0, 0x84, 0xf4, 0x86, 0x50, 0x5f, 0x80, 0x74, 0xd5, 0x68, 0x81, 0x49, 0xf1, 0x03, 0xf7, 0x04,
+0xa7, 0x88, 0x45, 0xe0, 0x00, 0x20, 0x40, 0x83, 0x1c, 0x01, 0x54, 0x74, 0x00, 0x3f, 0x80, 0x1c,
+0x80, 0x27, 0x50, 0x2f, 0x80, 0x78, 0x4c, 0x6f, 0x40, 0x06, 0x14, 0x9f, 0x80, 0x1e, 0x80, 0xe6,
+0xd5, 0x08, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7, 0x88, 0xa0, 0xdd, 0x2f, 0xb4, 0xbf,
+0xf4, 0x07, 0x80, 0x45, 0x40, 0x92, 0x18, 0x00, 0x54, 0x84, 0x80, 0x3f, 0x80, 0x1c, 0x80, 0x28,
+0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7, 0x88, 0xa0, 0xdd, 0x2f, 0x04, 0x9f, 0x80, 0x1e,
+0xf4, 0x1d, 0x40, 0x04, 0xa8, 0x06, 0xf1, 0x08, 0x56, 0x50, 0x00, 0x01, 0x40, 0x22, 0x84, 0x02,
+0x40, 0x35, 0x10, 0x06, 0x40, 0x01, 0x0c, 0x02, 0xb4, 0xbf, 0xc0, 0x07, 0x05, 0xef, 0x80, 0x03,
+0x81, 0x2a, 0x10, 0x6f, 0x00, 0x00, 0xd5, 0x0a, 0xe3, 0x24, 0xe8, 0x04, 0xf6, 0x03, 0xaf, 0xf0,
+0xd5, 0x05, 0xf7, 0x03, 0x81, 0x24, 0x10, 0x83, 0x80, 0x00, 0xf3, 0x03, 0x80, 0x3c, 0x08, 0x21,
+0x80, 0x01, 0x84, 0x00, 0x51, 0xce, 0x00, 0x01, 0x85, 0x02, 0xb6, 0xbf, 0xf3, 0x83, 0x46, 0xf0,
+0x00, 0x07, 0x58, 0xf7, 0x88, 0x40, 0xdd, 0x2f, 0xb4, 0xbf, 0x4d, 0xc4, 0x7f, 0xa8, 0xf4, 0x06,
+0x84, 0x5f, 0x9e, 0x21, 0x96, 0x42, 0xf1, 0x86, 0x4c, 0x11, 0x00, 0x1c, 0x05, 0xcf, 0x80, 0x04,
+0x40, 0xae, 0x04, 0x09, 0x14, 0xaf, 0x80, 0x04, 0xf2, 0x06, 0x87, 0x80, 0xf6, 0x04, 0x56, 0x71,
+0x00, 0x05, 0x84, 0x20, 0x83, 0xdc, 0x40, 0x30, 0x9c, 0x06, 0x50, 0x8f, 0x80, 0x84, 0x41, 0xe3,
+0x1c, 0x1b, 0xf3, 0x88, 0x14, 0x8f, 0x80, 0x03, 0x81, 0x49, 0x15, 0xef, 0x80, 0x07, 0xd5, 0x87,
+0xf4, 0x05, 0x04, 0x8f, 0x80, 0x02, 0x50, 0x6f, 0x80, 0x84, 0xa7, 0xf1, 0x01, 0xe3, 0x00, 0x00,
+0x50, 0x54, 0x00, 0x01, 0x9c, 0x22, 0x85, 0x24, 0xf5, 0x82, 0xaf, 0xe1, 0x11, 0xe2, 0x00, 0x00,
+0xf0, 0x85, 0x4c, 0x54, 0xff, 0x30, 0x46, 0x90, 0x00, 0x0c, 0x58, 0x94, 0x82, 0x20, 0x85, 0x00,
+0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x87, 0xb8, 0x44, 0x10, 0x00, 0xb0, 0x44, 0x00, 0x00, 0x9e,
+0xdd, 0x27, 0x80, 0x28, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27, 0x44, 0x10, 0x00, 0xb1, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x27, 0x00, 0x14, 0x80, 0x00, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27, 0x44, 0x10,
+0x00, 0xb2, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x27, 0x00, 0x14, 0x80, 0x01, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x27, 0x8d, 0x01, 0x84, 0x64, 0x8d, 0x22, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8,
+0x4c, 0x81, 0xff, 0xdc, 0xf1, 0x01, 0x4e, 0x13, 0x00, 0x85, 0x46, 0x50, 0x04, 0x11, 0x58, 0x52,
+0x80, 0x04, 0xb6, 0x25, 0x44, 0x00, 0x00, 0xf4, 0xf1, 0x01, 0xdd, 0x26, 0xf0, 0x01, 0x50, 0x2f,
+0x80, 0x7c, 0x44, 0x10, 0x00, 0x1f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f,
+0xf1, 0x1f, 0x44, 0x00, 0x00, 0x1f, 0x54, 0x20, 0x80, 0x9f, 0xf2, 0x9f, 0x80, 0x22, 0xdd, 0x26,
+0x84, 0x28, 0x44, 0x00, 0x00, 0x1f, 0xdd, 0x26, 0xf1, 0x01, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0xf1, 0x01, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x15, 0x84, 0x21, 0xdd, 0x26,
+0xf0, 0x01, 0x92, 0x00, 0x84, 0x87, 0x9c, 0x01, 0x4c, 0x02, 0x7f, 0xfd, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x15, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0x46, 0x60, 0x04, 0x10,
+0x46, 0x00, 0x04, 0x10, 0x84, 0xe0, 0x58, 0x63, 0x05, 0x04, 0x58, 0x00, 0x05, 0x0c, 0xb6, 0xe6,
+0xb6, 0xe0, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x06, 0x6c, 0xf2, 0x1c, 0x84, 0x21, 0x80, 0x07,
+0xdd, 0x26, 0xf2, 0x1b, 0x84, 0x22, 0x80, 0x07, 0xdd, 0x26, 0xf2, 0x1a, 0x44, 0x10, 0x00, 0x23,
+0x80, 0x07, 0xdd, 0x26, 0xf2, 0x19, 0x44, 0x10, 0x00, 0x2a, 0x80, 0x07, 0xdd, 0x26, 0xf2, 0x18,
+0x80, 0x27, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x17, 0x84, 0x22, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x16,
+0x44, 0x10, 0x00, 0x22, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x15, 0x84, 0x23, 0x84, 0x05, 0xdd, 0x26,
+0xf2, 0x14, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x13, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05,
+0xdd, 0x26, 0xf2, 0x12, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x11, 0x44, 0x10,
+0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x10, 0x84, 0x05, 0x44, 0x10, 0x00, 0x14, 0xdd, 0x26,
+0xec, 0x8c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc, 0xef, 0xf8, 0x84, 0x21,
+0x80, 0xe0, 0x44, 0x00, 0x00, 0x15, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f,
+0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0x07, 0x9c, 0x91, 0x4c, 0x20, 0x7f, 0xfd, 0x9c, 0x49,
+0x84, 0x6a, 0x4c, 0x11, 0x80, 0x04, 0x84, 0x40, 0xd5, 0xf6, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x07, 0xb8, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x9b, 0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0,
+0x18, 0x01, 0x44, 0x10, 0x00, 0x9b, 0xf1, 0x81, 0x50, 0x6f, 0x80, 0x04, 0x46, 0x80, 0x00, 0x05,
+0x58, 0x84, 0x06, 0xf4, 0xd5, 0x12, 0x92, 0x00, 0x84, 0x87, 0x9c, 0x91, 0x4c, 0x22, 0x7f, 0xfd,
+0x9c, 0x49, 0x84, 0x4a, 0x4c, 0x11, 0x00, 0x04, 0x84, 0x40, 0xd5, 0xf6, 0x84, 0x00, 0x44, 0x10,
+0x00, 0x9f, 0x80, 0x46, 0x4b, 0xe0, 0x20, 0x01, 0xf5, 0x01, 0x45, 0xe0, 0x00, 0x9b, 0x4c, 0x5f,
+0x40, 0x04, 0x84, 0x20, 0xd5, 0xf2, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x44, 0x10,
+0x00, 0xba, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x14, 0x44, 0x00,
+0x00, 0x9f, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x00, 0x7c, 0xb4, 0x20,
+0x40, 0x20, 0xc0, 0x09, 0x4e, 0x14, 0x00, 0x05, 0x44, 0x3f, 0x00, 0x00, 0x98, 0x93, 0x44, 0x50,
+0x80, 0x00, 0x40, 0x40, 0x94, 0x02, 0x96, 0x49, 0xc4, 0x04, 0x45, 0xef, 0x00, 0x00, 0x88, 0x3e,
+0x42, 0x21, 0x08, 0x24, 0x42, 0x20, 0x84, 0x73, 0xb6, 0x47, 0xec, 0x08, 0x3a, 0x6f, 0xa0, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x94, 0x96, 0x00, 0xf0, 0x82, 0x4e, 0x03,
+0x02, 0x22, 0x46, 0x30, 0x04, 0x11, 0x46, 0x80, 0x04, 0x10, 0x80, 0x28, 0x46, 0x60, 0x00, 0xcf,
+0x58, 0x63, 0x08, 0x30, 0x45, 0xc0, 0x00, 0x10, 0x44, 0x91, 0x20, 0x3e, 0xa8, 0x19, 0x15, 0xc1,
+0x80, 0x01, 0x14, 0x94, 0x01, 0x43, 0x14, 0x60, 0x81, 0x41, 0x51, 0xef, 0x80, 0x64, 0x15, 0xef,
+0x80, 0x01, 0xf0, 0x02, 0x80, 0x5e, 0x46, 0xa0, 0x00, 0x05, 0x58, 0xa5, 0x06, 0xf4, 0x84, 0x24,
+0x4b, 0xe0, 0x28, 0x01, 0xf5, 0x19, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x54, 0x12,
+0x80, 0xe7, 0x84, 0x04, 0xdd, 0x26, 0xf0, 0x02, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x85, 0xb4,
+0x84, 0x21, 0x50, 0x2f, 0x80, 0x60, 0xdd, 0x27, 0xf0, 0x02, 0x84, 0x22, 0x50, 0x2f, 0x80, 0x5c,
+0xdd, 0x27, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x23, 0x50, 0x2f, 0x80, 0x58, 0xdd, 0x27, 0xf0, 0x02,
+0x44, 0x10, 0x00, 0x2a, 0x50, 0x2f, 0x80, 0x54, 0xdd, 0x27, 0xf1, 0x02, 0x50, 0x2f, 0x80, 0x50,
+0x84, 0x04, 0xdd, 0x27, 0x84, 0x22, 0x50, 0x2f, 0x80, 0x4c, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10,
+0x00, 0x22, 0x50, 0x2f, 0x80, 0x48, 0x84, 0x04, 0xdd, 0x27, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x44,
+0x84, 0x05, 0xdd, 0x27, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x40, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10,
+0x00, 0x11, 0x50, 0x2f, 0x80, 0x3c, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f,
+0x80, 0x38, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x34, 0x84, 0x05,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x14, 0x50, 0x2f, 0x80, 0x30, 0x84, 0x05, 0xdd, 0x27, 0xf0, 0x02,
+0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x86, 0x6c, 0x84, 0x21, 0x44, 0x20, 0x00, 0x21, 0xdd, 0x27,
+0xf0, 0x02, 0x80, 0x5c, 0x84, 0x22, 0xdd, 0x27, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x23, 0x80, 0x40,
+0xdd, 0x27, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x2a, 0x44, 0x20, 0x00, 0x1b, 0xdd, 0x27, 0xf1, 0x02,
+0x44, 0x20, 0x00, 0x81, 0x84, 0x04, 0xdd, 0x27, 0x84, 0x22, 0x44, 0x20, 0x00, 0x81, 0x84, 0x04,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x22, 0x44, 0x20, 0x00, 0xee, 0x84, 0x04, 0xdd, 0x27, 0x84, 0x23,
+0x44, 0x20, 0x00, 0x2d, 0x84, 0x05, 0xdd, 0x27, 0x84, 0x24, 0x44, 0x20, 0x00, 0x2d, 0x84, 0x05,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10,
+0x00, 0x12, 0x44, 0x20, 0x00, 0xd7, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20,
+0x00, 0xa2, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x20, 0x00, 0x20, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0xaa, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0xf1, 0x02, 0x44, 0x00,
+0x00, 0x9f, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xab, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x84, 0x2a,
+0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xac, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x3f, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xad, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x3f, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x40, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x26, 0xf2, 0x01, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x1f,
+0x4b, 0xe0, 0x28, 0x01, 0xf2, 0x19, 0x44, 0x00, 0x00, 0x1f, 0x58, 0x31, 0x00, 0x60, 0xf3, 0x99,
+0x80, 0x23, 0xdd, 0x26, 0x14, 0x94, 0x01, 0x43, 0x84, 0x23, 0x44, 0x20, 0x00, 0x3e, 0x84, 0x05,
+0xdd, 0x27, 0x44, 0x20, 0x00, 0x3e, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x1f,
+0x44, 0x00, 0x00, 0x17, 0xdd, 0x26, 0x84, 0x25, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x84, 0x24,
+0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x84, 0x23, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x60, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x04, 0xaf, 0x80, 0x02, 0x84, 0x05, 0x44, 0x10,
+0x00, 0x20, 0x14, 0xaf, 0x80, 0x05, 0xf0, 0x83, 0xf1, 0x84, 0x50, 0x2f, 0x80, 0x2c, 0x50, 0x5f,
+0x80, 0x28, 0x48, 0x00, 0x00, 0xdb, 0x14, 0xaf, 0x80, 0x06, 0x84, 0x01, 0x4d, 0xc0, 0x00, 0x0b,
+0xf4, 0x03, 0xe4, 0x84, 0x4e, 0xf2, 0x00, 0xba, 0x04, 0x9f, 0x80, 0x09, 0x04, 0xaf, 0x80, 0x05,
+0xd5, 0x03, 0x04, 0x9f, 0x80, 0x08, 0x05, 0xef, 0x80, 0x04, 0x40, 0x75, 0x78, 0x01, 0x96, 0xf8,
+0x4f, 0xc3, 0x00, 0x12, 0x44, 0x10, 0x00, 0x28, 0x44, 0x00, 0x00, 0x9e, 0xf2, 0x81, 0xb6, 0xbf,
+0x54, 0x71, 0x80, 0x0f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xf2, 0x01,
+0xb4, 0xbf, 0xd5, 0x10, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0x29, 0xf2, 0x81, 0xb6, 0xbf,
+0x54, 0x71, 0x80, 0x3f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xb4, 0xbf,
+0xf2, 0x01, 0x80, 0x27, 0x44, 0x00, 0x00, 0x9f, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xf6, 0x01, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7,
+0x8f, 0xe8, 0xdd, 0x2f, 0xf5, 0x04, 0x84, 0x20, 0x40, 0x50, 0xa4, 0x1b, 0x40, 0x22, 0xa8, 0x00,
+0x96, 0xd0, 0xb4, 0xbf, 0xf2, 0x01, 0x4f, 0xc3, 0x00, 0x10, 0x44, 0x10, 0x00, 0x28, 0x44, 0x00,
+0x00, 0x9e, 0x54, 0x61, 0x80, 0x0f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f,
+0xf2, 0x01, 0xb4, 0xbf, 0xd5, 0x10, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0x29, 0xf2, 0x81,
+0xb6, 0xbf, 0x54, 0x61, 0x80, 0x3f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f,
+0xb4, 0xbf, 0xf2, 0x01, 0x80, 0x26, 0x44, 0x00, 0x00, 0x9f, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xb4, 0x1f, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7,
+0x8f, 0xe8, 0xdd, 0x2f, 0xf2, 0x01, 0xb4, 0xbf, 0x4e, 0x93, 0x00, 0x08, 0xf0, 0x0b, 0xe2, 0x08,
+0xe9, 0x04, 0xf4, 0x0a, 0xe3, 0x04, 0xe9, 0x0a, 0xf3, 0x0b, 0x04, 0x8f, 0x80, 0x0a, 0xe2, 0x68,
+0xe8, 0x04, 0x81, 0x03, 0x81, 0x47, 0xd5, 0x02, 0x81, 0x46, 0x4f, 0xc3, 0x00, 0x10, 0x44, 0x10,
+0x00, 0x28, 0x44, 0x00, 0x00, 0x9e, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x87, 0xb8, 0xdd, 0x2f, 0xf2, 0x01, 0xb4, 0xbf, 0xd5, 0x0e, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10,
+0x00, 0x29, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f,
+0xb4, 0xbf, 0xf2, 0x01, 0x44, 0x00, 0x00, 0x9f, 0x80, 0x2a, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x87, 0xb8, 0xdd, 0x2f, 0xf2, 0x01, 0xb4, 0xbf, 0x4f, 0xc3, 0x00, 0x06,
+0x14, 0xaf, 0x80, 0x05, 0x04, 0xaf, 0x80, 0x06, 0x51, 0xce, 0x00, 0x01, 0x55, 0xce, 0x00, 0xff,
+0x84, 0xe2, 0x4d, 0xc3, 0xff, 0x3a, 0x05, 0xef, 0x80, 0x03, 0x14, 0x8f, 0x80, 0x07, 0x4f, 0xe7,
+0x00, 0x06, 0xf6, 0x04, 0x40, 0x13, 0x04, 0x09, 0xf1, 0x84, 0xf7, 0x03, 0x84, 0x7e, 0x9f, 0x39,
+0x96, 0x22, 0xf0, 0x83, 0x4c, 0x01, 0x80, 0x16, 0xf6, 0x03, 0x14, 0xaf, 0x80, 0x06, 0x57, 0xc3,
+0x00, 0x03, 0x56, 0x13, 0x00, 0x05, 0x5c, 0x8e, 0x00, 0x01, 0x5d, 0xe0, 0x80, 0x01, 0x14, 0x8f,
+0x80, 0x09, 0x15, 0xef, 0x80, 0x08, 0x87, 0x80, 0x04, 0x8f, 0x80, 0x07, 0x48, 0xff, 0xff, 0x17,
+0xf5, 0x05, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x57, 0x82, 0x1c, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0xa7,
+0x82, 0x1d, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x07, 0xb8, 0x44, 0x10, 0x00, 0x28, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x26, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x37, 0x82, 0x1c, 0x44, 0x00, 0x00, 0x9f,
+0x54, 0x11, 0x80, 0x0f, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x29, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0x46, 0xf0, 0x00, 0x0c, 0x00, 0x77, 0x82, 0x1d, 0x44, 0x00, 0x00, 0x9f, 0x54, 0x13, 0x80, 0x3f,
+0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x26, 0x46, 0x20, 0x04, 0x11, 0x84, 0xe0, 0xa9, 0xd1, 0x80, 0x27, 0x44, 0x00, 0x00, 0xf4,
+0xdd, 0x26, 0x50, 0x2f, 0x80, 0x64, 0x44, 0x10, 0x00, 0x1f, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x86, 0xf4, 0xdd, 0x2f, 0xf1, 0x19, 0x44, 0x00, 0x00, 0x1f, 0x54, 0x40, 0x80, 0x9f,
+0xf4, 0x99, 0x80, 0x24, 0xdd, 0x26, 0x84, 0x21, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x26, 0x84, 0x01,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x85, 0x28, 0xdd, 0x2f, 0x80, 0x27, 0x44, 0x00, 0x00, 0x15,
+0xdd, 0x26, 0xf3, 0x02, 0xcb, 0x48, 0x05, 0xef, 0x80, 0x02, 0x46, 0x40, 0x04, 0x10, 0x80, 0xc4,
+0x15, 0xe2, 0x01, 0x41, 0x15, 0xe3, 0x01, 0x43, 0x84, 0x21, 0xf2, 0x18, 0xf0, 0x02, 0x46, 0x60,
+0x00, 0x05, 0x58, 0x63, 0x06, 0x6c, 0xdd, 0x26, 0xf2, 0x17, 0xf0, 0x02, 0x84, 0x22, 0xdd, 0x26,
+0xf2, 0x16, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x23, 0xdd, 0x26, 0xf2, 0x15, 0xf0, 0x02, 0x44, 0x10,
+0x00, 0x2a, 0xdd, 0x26, 0xf2, 0x14, 0xf1, 0x02, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x13, 0x84, 0x22,
+0x84, 0x04, 0xdd, 0x26, 0xf2, 0x12, 0x44, 0x10, 0x00, 0x22, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x11,
+0x84, 0x23, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x10, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0f,
+0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0e, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05,
+0xdd, 0x26, 0xf2, 0x0d, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0c, 0x84, 0x05,
+0x94, 0x42, 0xdd, 0x26, 0xec, 0x6c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x96, 0x49, 0xe6, 0x24, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x51, 0xb4, 0x20, 0x84, 0xa4,
+0xd1, 0x22, 0xe4, 0x25, 0xe8, 0x09, 0x84, 0xa2, 0xd1, 0x15, 0xe4, 0x23, 0xe8, 0x16, 0x84, 0x01,
+0x4c, 0x10, 0x40, 0x45, 0xd5, 0x09, 0x84, 0x46, 0x4c, 0x11, 0x00, 0x2a, 0xe0, 0x22, 0xe9, 0x1e,
+0x84, 0xa7, 0xd1, 0x37, 0xd5, 0x3b, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x8a, 0xf0, 0xdd, 0x2f,
+0xd5, 0x35, 0x9d, 0x44, 0xb4, 0x05, 0xd5, 0x32, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x88, 0x10,
+0xdd, 0x2f, 0xd5, 0x2c, 0x9c, 0x44, 0x05, 0xe0, 0x80, 0x00, 0x54, 0x0f, 0x00, 0x01, 0x46, 0xf0,
+0x00, 0x07, 0x58, 0xf7, 0x89, 0xc4, 0xdd, 0x2f, 0xd5, 0x21, 0x9c, 0xc4, 0xb4, 0x43, 0x96, 0x14,
+0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x80, 0xe4, 0xdd, 0x2f, 0xd5, 0x18, 0x9c, 0x04, 0x05, 0xe0,
+0x00, 0x00, 0xb4, 0x20, 0xb4, 0x80, 0x40, 0x50, 0xa0, 0x09, 0x54, 0x0f, 0x00, 0xff, 0x96, 0x68,
+0x42, 0x22, 0x40, 0x0b, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8f, 0x0c, 0xdd, 0x2f, 0xd5, 0x06,
+0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7, 0x81, 0xb8, 0xdd, 0x2f, 0x84, 0x00, 0xec, 0x04, 0x3b, 0xff,
+0xfc, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0x3c, 0x46, 0x30, 0x04, 0x00, 0x58, 0x31, 0x80, 0x64,
+0x46, 0x00, 0x04, 0x00, 0xb4, 0x83, 0x58, 0x00, 0x00, 0x38, 0x46, 0x51, 0x00, 0x00, 0xb4, 0x60,
+0x44, 0x6f, 0xe0, 0x00, 0x40, 0x02, 0x14, 0x02, 0x96, 0x48, 0x40, 0x31, 0x98, 0x02, 0xc0, 0x04,
+0x58, 0x31, 0x80, 0x39, 0xd5, 0x03, 0x58, 0x31, 0x80, 0x19, 0x46, 0x50, 0x04, 0x00, 0x58, 0x52,
+0x80, 0x38, 0xb6, 0x65, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x08, 0xb4, 0xa0, 0xb4, 0x80,
+0x44, 0x6f, 0xef, 0xff, 0x40, 0x42, 0x18, 0x02, 0xb6, 0x80, 0x46, 0x30, 0x04, 0x00, 0x58, 0x31,
+0x80, 0x80, 0xb4, 0x83, 0x84, 0xdc, 0x40, 0x42, 0x18, 0x02, 0xb6, 0x83, 0x46, 0x00, 0x04, 0x00,
+0x58, 0x00, 0x02, 0x14, 0xb4, 0xc0, 0x46, 0x30, 0x04, 0x00, 0x42, 0x43, 0x3c, 0x08, 0xb6, 0x80,
+0x58, 0x31, 0x82, 0x58, 0xb4, 0x83, 0x46, 0x6f, 0x0f, 0xff, 0x58, 0x63, 0x0f, 0xff, 0x40, 0x42,
+0x18, 0x02, 0x46, 0x60, 0xa0, 0x00, 0x40, 0x42, 0x18, 0x04, 0x46, 0x00, 0x04, 0x00, 0xb6, 0x83,
+0x58, 0x00, 0x00, 0x88, 0xb4, 0x60, 0xc2, 0x09, 0x46, 0x4f, 0xf0, 0x00, 0x40, 0x61, 0x90, 0x02,
+0x99, 0x16, 0x42, 0x32, 0x7c, 0x08, 0xb6, 0x60, 0x46, 0x40, 0x04, 0x00, 0x58, 0x42, 0x00, 0x3c,
+0xb4, 0x04, 0x46, 0x6f, 0x00, 0x00, 0x84, 0x63, 0x40, 0x00, 0x18, 0x02, 0x4c, 0x11, 0x80, 0x15,
+0xe6, 0x24, 0xe8, 0x05, 0x84, 0x62, 0x4c, 0x11, 0xc0, 0x18, 0xd5, 0x12, 0x84, 0xc4, 0x4c, 0x13,
+0x00, 0x08, 0x84, 0x85, 0x4c, 0x12, 0x40, 0x11, 0x44, 0x60, 0xff, 0x01, 0xd5, 0x0f, 0x44, 0x10,
+0xef, 0x01, 0x98, 0x01, 0xd5, 0x0c, 0x44, 0x30, 0xe3, 0x01, 0x98, 0x03, 0xd5, 0x08, 0x44, 0x60,
+0xc0, 0x01, 0x98, 0x06, 0xd5, 0x04, 0x44, 0x60, 0x80, 0x01, 0x98, 0x06, 0x46, 0x10, 0x04, 0x00,
+0x58, 0x10, 0x80, 0x3c, 0xb6, 0x01, 0x46, 0x60, 0x04, 0x00, 0x58, 0x63, 0x02, 0x14, 0xb4, 0x06,
+0x44, 0x4f, 0xef, 0xff, 0x40, 0x30, 0x10, 0x02, 0x46, 0x10, 0x00, 0x0c, 0x58, 0x10, 0x82, 0x44,
+0x84, 0x00, 0xb6, 0x66, 0xae, 0x08, 0x64, 0x00, 0x00, 0x20, 0xa7, 0x88, 0xce, 0x02, 0xd5, 0xfc,
+0x44, 0x40, 0x03, 0xe8, 0x40, 0x21, 0x10, 0x17, 0x46, 0x30, 0x04, 0x00, 0x58, 0x31, 0x80, 0x3c,
+0xb4, 0x23, 0x44, 0x6f, 0xff, 0xbf, 0x40, 0x00, 0x98, 0x02, 0xb6, 0x03, 0x46, 0x40, 0x00, 0x0c,
+0x58, 0x42, 0x01, 0x70, 0xb4, 0xc4, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x14, 0x46, 0x00,
+0x04, 0x00, 0x58, 0x00, 0x00, 0x80, 0x46, 0x30, 0x04, 0x00, 0x58, 0x31, 0x82, 0x08, 0x98, 0x96,
+0xb6, 0x44, 0xb4, 0x81, 0x58, 0x22, 0x10, 0x00, 0xb6, 0x41, 0xb4, 0x80, 0x58, 0x22, 0x00, 0x03,
+0xb6, 0x40, 0xb6, 0xa3, 0x3a, 0x6f, 0x98, 0x04, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x96, 0x00, 0x96, 0x48, 0xc2, 0x0d, 0x46, 0xf0, 0x00, 0x0c, 0x14, 0x27, 0x80, 0x92,
+0x46, 0xf0, 0x00, 0x0c, 0x10, 0x07, 0x82, 0x47, 0x46, 0xf0, 0x00, 0x0c, 0x10, 0x17, 0x82, 0x46,
+0x46, 0xf0, 0x00, 0x0c, 0x00, 0x07, 0x82, 0x47, 0x46, 0xf0, 0x00, 0x0c, 0x00, 0x17, 0x82, 0x46,
+0x46, 0xf0, 0x00, 0x0c, 0x04, 0x27, 0x80, 0x92, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x87, 0x24,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x96, 0x49, 0xe6, 0x28, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x1f, 0x80, 0x60, 0xa2, 0x19,
+0x44, 0x20, 0x00, 0x33, 0xb4, 0x23, 0x4c, 0x01, 0x40, 0x0f, 0x84, 0x81, 0x46, 0xf0, 0x00, 0x0c,
+0x10, 0x47, 0x82, 0x45, 0x96, 0x48, 0x84, 0x40, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x88, 0xbc,
+0xdd, 0x2f, 0xd5, 0x0a, 0x44, 0x50, 0x00, 0x34, 0xd0, 0x02, 0xd5, 0x06, 0x84, 0x20, 0x46, 0xf0,
+0x00, 0x0c, 0x10, 0x17, 0x82, 0x45, 0x84, 0x00, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xf4, 0x46, 0x60, 0x00, 0x0c, 0x58, 0x63, 0x02, 0x84, 0x50, 0x0f,
+0x80, 0x04, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f, 0x04, 0x73, 0x00, 0x2d,
+0xf0, 0x01, 0x97, 0xfc, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c, 0xdd, 0x2f, 0xc7, 0x07,
+0x80, 0x06, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8e, 0x6c, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f,
+0x9c, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x46, 0x60, 0x00, 0x0c, 0x58, 0x63,
+0x02, 0x84, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0xf8, 0xdd, 0x2f,
+0x04, 0x33, 0x00, 0x2d, 0x84, 0x40, 0xb6, 0x7f, 0x14, 0x23, 0x00, 0x2d, 0xf0, 0x01, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x80, 0x0c, 0xdd, 0x2f, 0xb4, 0x3f, 0x96, 0x0c, 0xc0, 0x07, 0x80, 0x06,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8e, 0x6c, 0xdd, 0x2f, 0xb4, 0xbf, 0x54, 0x42, 0x80, 0x02,
+0xc4, 0x0a, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x84, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x8d, 0xe8, 0xdd, 0x2f, 0xb4, 0x1f, 0x41, 0xe0, 0x3c, 0x08, 0x41, 0xef, 0x7c, 0x09, 0x4f, 0xe2,
+0x00, 0x0b, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x84, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x8f, 0xc4, 0xdd, 0x2f, 0xb4, 0x7f, 0x40, 0x21, 0xb8, 0x08, 0x92, 0x5f, 0xc2, 0x0a, 0x46, 0x00,
+0x00, 0x0c, 0x58, 0x00, 0x02, 0x84, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8e, 0xe0, 0xdd, 0x2f,
+0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xfc, 0x44, 0x00,
+0x02, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x80, 0x60, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x09,
+0x00, 0x07, 0x85, 0x83, 0x84, 0xa1, 0xd8, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x84, 0x68,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0c, 0x20, 0x37, 0x82, 0x45, 0x84, 0x81, 0x4c, 0x32, 0x40, 0x0a,
+0x84, 0x00, 0x80, 0x20, 0x80, 0x40, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x88, 0xbc, 0xdd, 0x2f,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0x2c, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7,
+0x89, 0xa4, 0xdd, 0x2f, 0x46, 0xa0, 0x00, 0x00, 0x58, 0xa5, 0x02, 0x78, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x83, 0xf0, 0xdd, 0x2f, 0x46, 0x90, 0x00, 0x02, 0x58, 0x94, 0x83, 0x7c, 0x46, 0x70,
+0x00, 0x00, 0x58, 0x73, 0x82, 0xbc, 0x46, 0x80, 0x00, 0x01, 0x58, 0x84, 0x0b, 0xf8, 0xd5, 0x20,
+0x4b, 0xe0, 0x28, 0x01, 0x00, 0x10, 0x00, 0x14, 0x80, 0xc0, 0xc9, 0x0f, 0x80, 0x20, 0x46, 0x00,
+0x00, 0x0c, 0x58, 0x00, 0x02, 0x84, 0x4b, 0xe0, 0x20, 0x01, 0xc8, 0x12, 0x80, 0x26, 0x46, 0x00,
+0x00, 0x0c, 0x58, 0x00, 0x02, 0x74, 0xd5, 0x0a, 0x84, 0xa1, 0xd9, 0x0a, 0x4b, 0xe0, 0x24, 0x01,
+0x80, 0x26, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x02, 0x64, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0xf0,
+0x00, 0x0c, 0x04, 0x17, 0x80, 0xd1, 0x46, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x03, 0x3c, 0xc9, 0xd9,
+0x46, 0x50, 0x00, 0x0c, 0x05, 0xe2, 0x80, 0x93, 0x5e, 0x4f, 0x03, 0xe9, 0x50, 0x3f, 0x00, 0x01,
+0x40, 0x21, 0x90, 0x1b, 0x40, 0x20, 0x90, 0x1a, 0x46, 0xf0, 0x00, 0x0c, 0x04, 0x07, 0x80, 0xce,
+0x14, 0x22, 0x80, 0x93, 0xc8, 0x08, 0x44, 0x00, 0x02, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x80, 0xa4, 0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x41, 0x00, 0x00, 0xf0, 0x3b, 0x00, 0x00,
+0x5c, 0x37, 0x00, 0x00, 0xfc, 0x3a, 0x00, 0x00, 0x5c, 0x37, 0x00, 0x00, 0xf4, 0x38, 0x00, 0x00,
+0x5c, 0x3f, 0x00, 0x00, 0x5c, 0x37, 0x00, 0x00, 0x18, 0x41, 0x00, 0x00, 0xc0, 0x3a, 0x00, 0x00,
+0xf8, 0x40, 0x00, 0x00, 0xa8, 0x3a, 0x00, 0x00, 0x5c, 0x37, 0x00, 0x00, 0x01, 0x99, 0x99, 0x09,
+0x50, 0x02, 0x46, 0x44, 0x0a, 0x50, 0x03, 0xec, 0xee, 0x0a, 0x50, 0x04, 0x99, 0x99, 0x0b, 0x50,
+0x05, 0x46, 0x44, 0x08, 0x51, 0x06, 0xec, 0xee, 0x08, 0x51, 0x07, 0x99, 0x99, 0x09, 0x51, 0x08,
+0x46, 0x44, 0x0a, 0x51, 0x09, 0xec, 0xee, 0x0a, 0x51, 0x0a, 0x99, 0x99, 0x0b, 0x51, 0x0b, 0x46,
+0x44, 0x08, 0x52, 0x0c, 0xec, 0xee, 0x08, 0x52, 0x0d, 0x99, 0x99, 0x09, 0x52, 0x0e, 0x33, 0x33,
+0x0b, 0x52, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xaa, 0xbb, 0xcc,
+0xdd, 0xee, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00, 0x00, 0x10, 0x14, 0x18, 0x1c,
+0x20, 0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x00,
+0x1a, 0x14, 0x10, 0x10, 0x2f, 0x2c, 0x2c, 0x2c, 0x02, 0x06, 0x0a, 0x0c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0f, 0xac, 0x00, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x03, 0x00,
+0x00, 0xf8, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x88, 0x8e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x86, 0xdd, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x12, 0x01, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x40, 0x8f, 0x14, 0x01, 0x76, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x0a, 0x06,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x05, 0x0f, 0x0c, 0x00, 0x01, 0x07, 0x10, 0x02,
+0x02, 0x00, 0x00, 0x00, 0x09, 0x02, 0x4a, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x50, 0x09, 0x04, 0x00,
+0x00, 0x08, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x84, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x85,
+0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x08, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x04, 0x02, 0x00,
+0x02, 0x00, 0x07, 0x05, 0x05, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x06, 0x02, 0x00, 0x02, 0x00,
+0x07, 0x05, 0x07, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x09, 0x02, 0x00, 0x02, 0x00, 0x09, 0x04,
+0x01, 0x00, 0x05, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x00, 0x07, 0x05,
+0x82, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x83, 0x01,
+0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x01, 0x40, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x12, 0x03,
+0x4d, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x61, 0x00, 0x54, 0x00, 0x65, 0x00, 0x6b, 0x00,
+0x1c, 0x03, 0x38, 0x00, 0x30, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x31, 0x00, 0x20, 0x00,
+0x6e, 0x00, 0x20, 0x00, 0x57, 0x00, 0x4c, 0x00, 0x41, 0x00, 0x4e, 0x00, 0x08, 0x03, 0x31, 0x00,
+0x2e, 0x00, 0x30, 0x00, 0x38, 0x4f, 0x00, 0x00, 0x3c, 0x4f, 0x00, 0x00, 0x40, 0x4f, 0x00, 0x00,
+0x44, 0x4f, 0x00, 0x00, 0x48, 0x4f, 0x00, 0x00, 0x4c, 0x4f, 0x00, 0x00, 0x50, 0x4f, 0x00, 0x00,
+0x54, 0x4f, 0x00, 0x00, 0x58, 0x4f, 0x00, 0x00, 0x5c, 0x4f, 0x00, 0x00, 0x60, 0x4f, 0x00, 0x00,
+0x64, 0x4f, 0x00, 0x00, 0x68, 0x4f, 0x00, 0x00, 0x6c, 0x4f, 0x00, 0x00, 0x70, 0x4f, 0x00, 0x00,
+0x74, 0x4f, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0xb1, 0x00, 0x00, 0x00, 0x03, 0x08, 0x12, 0x20, } ;
diff --git a/cleopatre/devkit/mt7601udrv/include/frq_cal.h b/cleopatre/devkit/mt7601udrv/include/frq_cal.h
new file mode 100644
index 0000000000..60316706a3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/frq_cal.h
@@ -0,0 +1,107 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ eeprom.h
+
+ Abstract:
+ Miniport header file for eeprom related information
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+#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 */
+ UCHAR 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;
+
+#define RTMP_FREQ_CAL_DISABLE(__pAd) \
+ __pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration = FALSE;
+
+/* */
+/* 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
+
+#ifdef MT7601
+#define MT7601_HIGH_FREQUENCY_TRIGGER_POINT_CCK 19
+#define MT7601_LOW_FREQUENCY_TRIGGER_POINT_CCK -19
+#define MT7601_DECREASE_FREQUENCY_OFFSET_CCK 5
+#define MT7601_INCREASE_FREQUENCY_OFFSET_CCK -5
+
+#define MT7601_HIGH_FREQUENCY_TRIGGER_POINT_OFDM20 102
+#define MT7601_LOW_FREQUENCY_TRIGGER_POINT_OFDM20 -102
+#define MT7601_DECREASE_FREQUENCY_OFFSET_OFDM20 32
+#define MT7601_INCREASE_FREQUENCY_OFFSET_OFDM20 -32
+
+#define MT7601_HIGH_FREQUENCY_TRIGGER_POINT_OFDM40 82
+#define MT7601_LOW_FREQUENCY_TRIGGER_POINT_OFDM40 -82
+#define MT7601_DECREASE_FREQUENCY_OFFSET_OFDM40 20
+#define MT7601_INCREASE_FREQUENCY_OFFSET_OFDM40 -20
+#endif /* MT7601 */
+
+/* */
+/* 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__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/iface/iface_util.h b/cleopatre/devkit/mt7601udrv/include/iface/iface_util.h
new file mode 100644
index 0000000000..c9b8cb3d9b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/iface/iface_util.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rtmp_util.h
+
+ Abstract:
+ Common for PCI/USB/RBUS.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_UTIL_H__
+#define __RTMP_UTIL_H__
+
+/* maximum of PCI, USB, or RBUS, int PCI, it is 0 but in USB, it is 11 */
+#define RTMP_PKT_TAIL_PADDING 11 /* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */
+
+#ifdef PCI_MSI_SUPPORT
+#define RTMP_MSI_ENABLE(_pAd) \
+ { POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
+ (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; \
+ }
+
+#define RTMP_MSI_DISABLE(_pci_dev, _pHaveMsi) \
+ { \
+ if (*(_pHaveMsi) == TRUE) \
+ pci_disable_msi(_pci_dev); \
+ *(_pHaveMsi) = FALSE; \
+ }
+
+#else
+#define RTMP_MSI_ENABLE(_pAd) do{}while(0)
+#define RTMP_MSI_DISABLE(_pci_dev, _pHaveMsi) do{}while(0)
+#endif /* PCI_MSI_SUPPORT */
+
+#define RTMP_PCI_DMA_TODEVICE 0xFF00
+#define RTMP_PCI_DMA_FROMDEVICE 0xFF01
+
+
+
+
+#define UNLINK_TIMEOUT_MS 3
+
+#define USBD_TRANSFER_DIRECTION_OUT 0
+#define USBD_TRANSFER_DIRECTION_IN 0
+#define USBD_SHORT_TRANSFER_OK 0
+#define PURB purbb_t
+
+#define OS_RTUSBMlmeUp RtmpOsMlmeUp
+
+
+
+
+#endif /* __RTMP_UTIL_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/iface/rtmp_reg_pcirbs.h b/cleopatre/devkit/mt7601udrv/include/iface/rtmp_reg_pcirbs.h
new file mode 100644
index 0000000000..e3f0e2925a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/iface/rtmp_reg_pcirbs.h
@@ -0,0 +1,384 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rtmp_reg_pcirbus.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_REG_PCIRBUS_H__
+#define __RTMP_REG_PCIRBUS_H__
+
+
+// TODO: shiang, for RT3290, make sure following definition is correct to put as here
+
+#define ASIC_VERSION 0x0000
+
+#define CMB_CTRL 0x20
+#ifdef RT_BIG_ENDIAN
+typedef union _CMB_CTRL_STRUC{
+ struct{
+ UINT32 LDO0_EN:1;
+ UINT32 LDO3_EN:1;
+ UINT32 LDO_BGSEL:2;
+ UINT32 LDO_CORE_LEVEL:4;
+ UINT32 PLL_LD:1;
+ UINT32 XTAL_RDY:1;
+ UINT32 Rsv:2;
+ UINT32 LDO25_FRC_ON:1;//4
+ UINT32 LDO25_LARGEA:1;
+ UINT32 LDO25_LEVEL:2;
+ UINT32 AUX_OPT_Bit15_Two_AntennaMode:1;
+ UINT32 AUX_OPT_Bit14_TRSW1_as_GPIO:1;
+ UINT32 AUX_OPT_Bit13_GPIO7_as_GPIO:1;
+ UINT32 AUX_OPT_Bit12_TRSW0_as_WLAN_ANT_SEL:1;
+ UINT32 AUX_OPT_Bit11_Rsv:1;
+ UINT32 AUX_OPT_Bit10_NotSwap_WL_LED_ACT_RDY:1;
+ UINT32 AUX_OPT_Bit9_GPIO3_as_GPIO:1;
+ UINT32 AUX_OPT_Bit8_AuxPower_Exists:1;
+ UINT32 AUX_OPT_Bit7_KeepInterfaceClk:1;
+ UINT32 AUX_OPT_Bit6_KeepXtal_On:1;
+ UINT32 AUX_OPT_Bit5_RemovePCIePhyClk_BTOff:1;
+ UINT32 AUX_OPT_Bit4_RemovePCIePhyClk_WLANOff:1;
+ UINT32 AUX_OPT_Bit3_PLLOn_L1:1;
+ UINT32 AUX_OPT_Bit2_PCIeCoreClkOn_L1:1;
+ UINT32 AUX_OPT_Bit1_PCIePhyClkOn_L1:1;
+ UINT32 AUX_OPT_Bit0_InterfaceClk_40Mhz:1;
+ }field;
+ UINT32 word;
+}CMB_CTRL_STRUC, *PCMB_CTRL_STRUC;
+#else
+typedef union _CMB_CTRL_STRUC{
+ struct{
+ UINT32 AUX_OPT_Bit0_InterfaceClk_40Mhz:1;
+ UINT32 AUX_OPT_Bit1_PCIePhyClkOn_L1:1;
+ UINT32 AUX_OPT_Bit2_PCIeCoreClkOn_L1:1;
+ UINT32 AUX_OPT_Bit3_PLLOn_L1:1;
+ UINT32 AUX_OPT_Bit4_RemovePCIePhyClk_WLANOff:1;
+ UINT32 AUX_OPT_Bit5_RemovePCIePhyClk_BTOff:1;
+ UINT32 AUX_OPT_Bit6_KeepXtal_On:1;
+ UINT32 AUX_OPT_Bit7_KeepInterfaceClk:1;
+ UINT32 AUX_OPT_Bit8_AuxPower_Exists:1;
+ UINT32 AUX_OPT_Bit9_GPIO3_as_GPIO:1;
+ UINT32 AUX_OPT_Bit10_NotSwap_WL_LED_ACT_RDY:1;
+ UINT32 AUX_OPT_Bit11_Rsv:1;
+ UINT32 AUX_OPT_Bit12_TRSW0_as_WLAN_ANT_SEL:1;
+ UINT32 AUX_OPT_Bit13_GPIO7_as_GPIO:1;
+ UINT32 AUX_OPT_Bit14_TRSW1_as_GPIO:1;
+ UINT32 AUX_OPT_Bit15_Two_AntennaMode:1;
+ UINT32 LDO25_LEVEL:2;
+ UINT32 LDO25_LARGEA:1;
+ UINT32 LDO25_FRC_ON:1;//4
+ UINT32 Rsv:2;
+ UINT32 XTAL_RDY:1;
+ UINT32 PLL_LD:1;
+ UINT32 LDO_CORE_LEVEL:4;
+ UINT32 LDO_BGSEL:2;
+ UINT32 LDO3_EN:1;
+ UINT32 LDO0_EN:1;
+ }field;
+ UINT32 word;
+}CMB_CTRL_STRUC, *PCMB_CTRL_STRUC;
+#endif
+
+
+#define OSCCTL 0x38
+#ifdef RT_BIG_ENDIAN
+typedef union _OSCCTL_STRUC{
+ struct{
+ UINT32 ROSC_EN:1;
+ UINT32 CAL_REQ:1;
+ UINT32 CLK_32K_VLD:1;
+ UINT32 CAL_ACK:1;
+ UINT32 CAL_CNT:12;
+ UINT32 Rsv:3;
+ UINT32 REF_CYCLE:13;
+ }field;
+ UINT32 word;
+}OSCCTL_STRUC, *POSCCTL_STRUC;
+#else
+typedef union _OSCCTL_STRUC{
+ struct{
+ UINT32 REF_CYCLE:13;
+ UINT32 Rsv:3;
+ UINT32 CAL_CNT:12;
+ UINT32 CAL_ACK:1;
+ UINT32 CLK_32K_VLD:1;
+ UINT32 CAL_REQ:1;
+ UINT32 ROSC_EN:1;
+ }field;
+ UINT32 word;
+}OSCCTL_STRUC, *POSCCTL_STRUC;
+#endif
+
+
+#define COEXCFG0 0x40
+#ifdef RT_BIG_ENDIAN
+typedef union _COEXCFG0_STRUC{
+ struct{
+ UINT32 COEX_CFG1:8;
+ UINT32 COEX_CFG0:8;
+ UINT32 FIX_WL_RF_LNA:2;
+ UINT32 FIX_BT_H_PA:3;
+ UINT32 FIX_BT_L_PA:3;
+ UINT32 FIX_WL_TX_PWR:2;
+ UINT32 Rsv:3;
+ UINT32 FIX_WL_ANT_EN:1;
+ UINT32 FIX_WL_DI_ANT:1;
+ UINT32 COEX_ENT:1;
+ }field;
+ UINT32 word;
+}COEXCFG0_STRUC, *PCOEXCFG0_STRUC;
+#else
+typedef union _COEXCFG0_STRUC{
+ struct{
+ UINT32 COEX_ENT:1;
+ UINT32 FIX_WL_DI_ANT:1;
+ UINT32 FIX_WL_ANT_EN:1;
+ UINT32 Rsv:3;
+ UINT32 FIX_WL_TX_PWR:2;
+ UINT32 FIX_BT_L_PA:3;
+ UINT32 FIX_BT_H_PA:3;
+ UINT32 FIX_WL_RF_LNA:2;
+
+ UINT32 COEX_CFG0:8;
+ UINT32 COEX_CFG1:8;
+ }field;
+ UINT32 word;
+}COEXCFG0_STRUC, *PCOEXCFG0_STRUC;
+#endif
+
+
+#define COEXCFG1 0x44
+#ifdef RT_BIG_ENDIAN
+typedef union _COEXCFG1_STRUC{
+ struct{
+ UINT32 Rsv:8;
+ UINT32 DIS_WL_RF_DELY:8;
+ UINT32 DIS_WL_PA_DELY:8;
+ UINT32 DIS_WL_TR_DELY:8;
+ }field;
+ UINT32 word;
+}COEXCFG1_STRUC, *PCOEXCFG1_STRUC;
+#else
+typedef union _COEXCFG1_STRUC{
+ struct{
+ UINT32 DIS_WL_TR_DELY:8;
+ UINT32 DIS_WL_PA_DELY:8;
+ UINT32 DIS_WL_RF_DELY:8;
+ UINT32 Rsv:8;
+ }field;
+ UINT32 word;
+}COEXCFG1_STRUC, *PCOEXCFG1_STRUC;
+#endif
+
+
+#define COEXCFG2 0x48
+#ifdef RT_BIG_ENDIAN
+typedef union _COEXCFG2_STRUC{
+ struct{
+ UINT32 BT_COEX_CFG1_Bit31_Rsv:1;
+ UINT32 BT_COEX_CFG1_Bit30_Rsv:1;
+ UINT32 BT_COEX_CFG1_Bit29_HaltHighPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG1_Bit28_HaltHighPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG1_Bit27_HaltHighPriorityTx_wl_busy:1;
+ UINT32 BT_COEX_CFG1_Bit26_HaltLowPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG1_Bit25_HaltLowPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG1_Bit24_HaltLowPriorityTx_wl_busy:1;
+
+ UINT32 BT_COEX_CFG0_Bit23_Rsv:1;
+ UINT32 BT_COEX_CFG0_Bit22_Rsv:1;
+ UINT32 BT_COEX_CFG0_Bit21_HaltHighPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG0_Bit20_HaltHighPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG0_Bit19_HaltHighPriorityTx_wl_busy:1;
+ UINT32 BT_COEX_CFG0_Bit18_HaltLowPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG0_Bit17_HaltLowPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG0_Bit16_HaltLowPriorityTx_wl_busy:1;
+
+ UINT32 WL_COEX_CFG1_Bit15_LowerTxPwr_bt_high_priority:1;
+ UINT32 WL_COEX_CFG1_Bit14_Enable_Tx_free_timer:1;
+ UINT32 WL_COEX_CFG1_Bit13_Disable_TxAgg_bi_high_priority:1;
+ UINT32 WL_COEX_CFG1_Bit12_Disable_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG1_Bit11_HaltTx_bt_tx_req_l:1;
+ UINT32 WL_COEX_CFG1_Bit10_HaltTx_bt_tx_req_h:1;
+ UINT32 WL_COEX_CFG1_Bit9_HaltTx_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG1_Bit8_HaltTx_bt_rx_busy:1;
+
+ UINT32 WL_COEX_CFG0_Bit7_LowerTxPwr_bt_high_priority:1;
+ UINT32 WL_COEX_CFG0_Bit6_Enable_Tx_free_timer:1;
+ UINT32 WL_COEX_CFG0_Bit5_Disable_TxAgg_bi_high_priority:1;
+ UINT32 WL_COEX_CFG0_Bit4_Disable_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG0_Bit3_HaltTx_bt_tx_req_l:1;
+ UINT32 WL_COEX_CFG0_Bit2_HaltTx_bt_tx_req_h:1;
+ UINT32 WL_COEX_CFG0_Bit1_HaltTx_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG0_Bit0_HaltTx_bt_rx_busy:1;
+ }field;
+ UINT32 word;
+}COEXCFG2_STRUC, *PCOEXCFG2_STRUC;
+#else
+typedef union _COEXCFG2_STRUC{
+ struct{
+ UINT32 WL_COEX_CFG0_Bit0_HaltTx_bt_rx_busy:1;
+ UINT32 WL_COEX_CFG0_Bit1_HaltTx_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG0_Bit2_HaltTx_bt_tx_req_h:1;
+ UINT32 WL_COEX_CFG0_Bit3_HaltTx_bt_tx_req_l:1;
+ UINT32 WL_COEX_CFG0_Bit4_Disable_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG0_Bit5_Disable_TxAgg_bi_high_priority:1;
+ UINT32 WL_COEX_CFG0_Bit6_Enable_Tx_free_timer:1;
+ UINT32 WL_COEX_CFG0_Bit7_LowerTxPwr_bt_high_priority:1;
+
+ UINT32 WL_COEX_CFG1_Bit8_HaltTx_bt_rx_busy:1;
+ UINT32 WL_COEX_CFG1_Bit9_HaltTx_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG1_Bit10_HaltTx_bt_tx_req_h:1;
+ UINT32 WL_COEX_CFG1_Bit11_HaltTx_bt_tx_req_l:1;
+ UINT32 WL_COEX_CFG1_Bit12_Disable_bt_rx_req_h:1;
+ UINT32 WL_COEX_CFG1_Bit13_Disable_TxAgg_bi_high_priority:1;
+ UINT32 WL_COEX_CFG1_Bit14_Enable_Tx_free_timer:1;
+ UINT32 WL_COEX_CFG1_Bit15_LowerTxPwr_bt_high_priority:1;
+
+ UINT32 BT_COEX_CFG0_Bit16_HaltLowPriorityTx_wl_busy:1;
+ UINT32 BT_COEX_CFG0_Bit17_HaltLowPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG0_Bit18_HaltLowPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG0_Bit19_HaltHighPriorityTx_wl_busy:1;
+ UINT32 BT_COEX_CFG0_Bit20_HaltHighPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG0_Bit21_HaltHighPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG0_Bit22_Rsv:1;
+ UINT32 BT_COEX_CFG0_Bit23_Rsv:1;
+
+ UINT32 BT_COEX_CFG1_Bit24_HaltLowPriorityTx_wl_busy:1;
+ UINT32 BT_COEX_CFG1_Bit25_HaltLowPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG1_Bit26_HaltLowPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG1_Bit27_HaltHighPriorityTx_wl_busy:1;
+ UINT32 BT_COEX_CFG1_Bit28_HaltHighPriorityTx_wl_rx_busy:1;
+ UINT32 BT_COEX_CFG1_Bit29_HaltHighPriorityTx_wl_bcn_busy:1;
+ UINT32 BT_COEX_CFG1_Bit30_Rsv:1;
+ UINT32 BT_COEX_CFG1_Bit31_Rsv:1;
+ }field;
+ UINT32 word;
+}COEXCFG2_STRUC, *PCOEXCFG2_STRUC;
+#endif
+
+
+#define PLL_CTRL 0x50
+#ifdef RT_BIG_ENDIAN
+typedef union _PLL_CTRL_STRUC {
+ struct {
+ ULONG VBGBK_EN:1;
+ ULONG LOCK_DETECT_WINDOW_CTRL:3;
+ ULONG PFD_DELAY_CTRL:2;
+ ULONG CP_CURRENT_CTRL:2;
+ ULONG LPF_C2_CTRL:2;
+ ULONG LPF_C1_CTRL:2;
+ ULONG LPF_R1:1;
+ ULONG VCO_FIXED_CURRENT_CONTROL:3;
+ ULONG RESERVED_INPUT2:8;
+ ULONG RESERVED_INPUT1:8;
+ } field;
+ ULONG word;
+} PLL_CTRL_STRUC, *PPLL_CTRL_STRUC;
+#else
+typedef union _PLL_CTRL_STRUC {
+ struct {
+ ULONG RESERVED_INPUT1:8;
+ ULONG RESERVED_INPUT2:8;
+ ULONG VCO_FIXED_CURRENT_CONTROL:3;
+ ULONG LPF_R1:1;
+ ULONG LPF_C1_CTRL:2;
+ ULONG LPF_C2_CTRL:2;
+ ULONG CP_CURRENT_CTRL:2;
+ ULONG PFD_DELAY_CTRL:2;
+ ULONG LOCK_DETECT_WINDOW_CTRL:3;
+ ULONG VBGBK_EN:1;
+ } field;
+ ULONG word;
+} PLL_CTRL_STRUC, *PPLL_CTRL_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+
+#define WPDMA_RST_IDX 0x20c
+#ifdef RT_BIG_ENDIAN
+typedef union _WPDMA_RST_IDX_STRUC {
+ struct {
+ UINT32 :14;
+ UINT32 RST_DRX_IDX1:1;
+ UINT32 RST_DRX_IDX0:1;
+ UINT32 rsv:6;
+ UINT32 RST_DTX_IDX9:1;
+ UINT32 RST_DTX_IDX8:1;
+ UINT32 RST_DTX_IDX7:1;
+ UINT32 RST_DTX_IDX6:1;
+ 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 RST_DTX_IDX6:1;
+ UINT32 RST_DTX_IDX7:1;
+ UINT32 RST_DTX_IDX8:1;
+ UINT32 RST_DTX_IDX9:1;
+ UINT32 rsv:6;
+ UINT32 RST_DRX_IDX0:1;
+ UINT32 RST_DRX_IDX1:1;
+ UINT32 :14;
+ } 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
+
+#endif /* __RTMP_REG_PCIRBUS_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/iface/rtmp_usb.h b/cleopatre/devkit/mt7601udrv/include/iface/rtmp_usb.h
new file mode 100644
index 0000000000..80d05fe5cc
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/iface/rtmp_usb.h
@@ -0,0 +1,89 @@
+#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
+#define CMD_RSP_BULK_SIZE 1024
+
+/*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
+
+
+#define fRTUSB_BULK_OUT_DATA_HCCA 0x00100000
+#define fRTUSB_BULK_OUT_DATA_NULL_HCCA 0x00400000
+#define fRTUSB_BULK_OUT_MLME_HCCA 0x00800000
+
+
+
+/* TODO:move to ./ate/include/iface/ate_usb.h */
+#ifdef RALINK_ATE
+#define fRTUSB_BULK_OUT_DATA_ATE 0x00100000
+#endif /* RALINK_ATE */
+
+
+#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext) \
+{ \
+ if ((_txContext)->ENextBulkOutPosition == (_txContext)->CurWritePosition) \
+ { \
+ (_txContext)->bRingEmpty = TRUE; \
+ } \
+ /*NdisInterlockedDecrement(&(_p)->TxCount); */\
+}
+
+#define NT_SUCCESS(status) (((status) >=0) ? (TRUE):(FALSE))
+
+
+
+
+#define PIRP PVOID
+/*#define NDIS_OID UINT */
+#ifndef USB_ST_NOERROR
+#define USB_ST_NOERROR 0
+#endif
+
+
+/* vendor-specific control operations */
+#define CONTROL_TIMEOUT_JIFFIES ( (300 * OS_HZ) / 1000)
+/*#define UNLINK_TIMEOUT_MS 3 // os abl move */
+
+
+#define DEVICE_VENDOR_REQUEST_OUT 0x40
+#define DEVICE_VENDOR_REQUEST_IN 0xc0
+/*#define INTERFACE_VENDOR_REQUEST_OUT 0x41 */
+/*#define INTERFACE_VENDOR_REQUEST_IN 0xc1 */
+#define BULKOUT_MGMT_RESET_FLAG 0x80
+
+#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F))
+#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F))
+#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0)
+
+#endif /* __RTMP_USB_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/igmp_snoop.h b/cleopatre/devkit/mt7601udrv/include/igmp_snoop.h
new file mode 100644
index 0000000000..f51f821b6e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/igmp_snoop.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ igmp_snoop.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+
+#ifndef __RTMP_IGMP_SNOOP_H__
+#define __RTMP_IGMP_SNOOP_H__
+
+#include "link_list.h"
+
+#define IGMP_PROTOCOL_DESCRIPTOR 0x02
+#define IGMP_V1_MEMBERSHIP_REPORT 0x12
+#define IGMP_V2_MEMBERSHIP_REPORT 0x16
+#define IGMP_LEAVE_GROUP 0x17
+#define IGMP_V3_MEMBERSHIP_REPORT 0x22
+
+#define MLD_V1_LISTENER_REPORT 131
+#define MLD_V1_LISTENER_DONE 132
+#define MLD_V2_LISTERNER_REPORT 143
+
+#define IGMPMAC_TB_ENTRY_AGEOUT_TIME (120 * OS_HZ)
+
+#define MULTICAST_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) & (MAX_LEN_OF_MULTICAST_FILTER_HASH_TABLE - 1))
+
+#define IS_MULTICAST_MAC_ADDR(Addr) ((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff))
+#define IS_IPV6_MULTICAST_MAC_ADDR(Addr) ((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) == 0x33))
+#define IS_BROADCAST_MAC_ADDR(Addr) ((((Addr[0]) & 0xff) == 0xff))
+
+#define IGMP_NONE 0
+#define IGMP_PKT 1
+#define IGMP_IN_GROUP 2
+
+
+VOID MulticastFilterTableInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
+
+VOID MultiCastFilterTableReset(
+ IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
+
+BOOLEAN MulticastFilterTableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pGrpId,
+ IN PUCHAR pMemberAddr,
+ IN PNET_DEV dev,
+ IN MulticastFilterEntryType type);
+
+BOOLEAN MulticastFilterTableDeleteEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pGrpId,
+ IN PUCHAR pMemberAddr,
+ IN PNET_DEV dev);
+
+PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
+ IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+ IN PUCHAR pAddr,
+ IN PNET_DEV dev);
+
+BOOLEAN isIgmpPkt(
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pIpHeader);
+
+VOID IGMPSnooping(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pSrcMacAddr,
+ IN PUCHAR pIpHeader,
+ IN PNET_DEV pDev);
+
+BOOLEAN isMldPkt(
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pIpHeader,
+ OUT UINT8 *pProtoType,
+ OUT PUCHAR *pMldHeader);
+
+BOOLEAN IPv6MulticastFilterExcluded(
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pIpHeader);
+
+VOID MLDSnooping(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDstMacAddr,
+ IN PUCHAR pSrcMacAddr,
+ IN PUCHAR pIpHeader,
+ IN PNET_DEV pDev);
+
+UCHAR IgmpMemberCnt(
+ IN PLIST_HEADER pList);
+
+VOID IgmpGroupDelMembers(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pMemberAddr,
+ IN PNET_DEV pDev);
+
+INT Set_IgmpSn_Enable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_IgmpSn_AddEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_IgmpSn_DelEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_IgmpSn_TabDisplay_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+void rtmp_read_igmp_snoop_from_file(
+ IN PRTMP_ADAPTER pAd,
+ PSTRING tmpbuf,
+ PSTRING buffer);
+
+NDIS_STATUS IgmpPktInfoQuery(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrcBufVA,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID,
+ OUT INT *pInIgmpGroup,
+ OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry);
+
+NDIS_STATUS IgmpPktClone(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN INT IgmpPktInGroup,
+ IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry,
+ IN UCHAR QueIdx,
+ IN UINT8 UserPriority,
+ IN PNET_DEV pNetDev);
+
+#endif /* __RTMP_IGMP_SNOOP_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/ipv6.h b/cleopatre/devkit/mt7601udrv/include/ipv6.h
new file mode 100644
index 0000000000..16c9b8ea9c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/ipv6.h
@@ -0,0 +1,205 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ipv6.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __IPV6_HDR_H_
+#define __IPV6_HDR_H_
+
+#define IPV6_ADDR_LEN 16
+#define IPV6_HDR_LEN 40
+
+/* IPv6 address definition */
+#define IPV6_LINK_LOCAL_ADDR_PREFIX 0xFE8
+#define IPV6_SITE_LOCAL_ADDR_PREFIX 0xFEC
+#define IPV6_LOCAL_ADDR_PREFIX 0xFE8
+#define IPV6_MULTICAST_ADDR_PREFIX 0xFF
+#define IPV6_LOOPBACK_ADDR 0x1
+#define IPV6_UNSPECIFIED_ADDR 0x0
+
+/* defined as sequence in IPv6 header */
+#define IPV6_NEXT_HEADER_HOP_BY_HOP 0x00 /* 0 */
+#define IPV6_NEXT_HEADER_DESTINATION 0x3c /* 60 */
+#define IPV6_NEXT_HEADER_ROUTING 0x2b /* 43 */
+#define IPV6_NEXT_HEADER_FRAGMENT 0x2c /* 44 */
+#define IPV6_NEXT_HEADER_AUTHENTICATION 0x33 /* 51 */
+#define IPV6_NEXT_HEADER_ENCAPSULATION 0x32 /* 50, RFC-2406 */
+#define IPV6_NEXT_HEADER_NONE 0x3b /* 59 */
+
+#define IPV6_NEXT_HEADER_TCP 0x06
+#define IPV6_NEXT_HEADER_UDP 0x11
+#define IPV6_NEXT_HEADER_ICMPV6 0x3a
+#define IPV6_NEXT_HEADER_PIM 0x67
+
+/* ICMPv6 msg type definition */
+#define ICMPV6_MSG_TYPE_ROUTER_SOLICITATION 0x85 /* 133 */
+#define ROUTER_SOLICITATION_FIXED_LEN 8
+
+#define ICMPV6_MSG_TYPE_ROUTER_ADVERTISEMENT 0x86 /* 134 */
+#define ROUTER_ADVERTISEMENT_FIXED_LEN 16
+
+#define ICMPV6_MSG_TYPE_NEIGHBOR_SOLICITATION 0x87 /* 135 */
+#define NEIGHBOR_SOLICITATION_FIXED_LEN 24
+
+#define ICMPV6_MSG_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 /* 136 */
+#define NEIGHBOR_ADVERTISEMENT_FIXED_LEN 24
+
+#define ICMPV6_MSG_TYPE_REDIRECT 0x89 /* 137 */
+#define REDIRECT_FIXED_LEN 40
+
+/* IPv6 Address related structures */
+typedef struct rt_ipv6_addr_
+{
+ union
+ {
+ UCHAR ipv6Addr8[16];
+ USHORT ipv6Addr16[8];
+ UINT32 ipv6Addr32[4];
+ }addr;
+#define ipv6_addr addr.ipv6Addr8
+#define ipv6_addr16 addr.ipv6Addr16
+#define ipv6_addr32 addr.ipv6Addr32
+}RT_IPV6_ADDR, *PRT_IPV6_ADDR;
+
+
+#define PRINT_IPV6_ADDR(ipv6Addr) \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[0]), \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[1]), \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[2]), \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[3]), \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[4]), \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[5]), \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[6]), \
+ OS_NTOHS((ipv6Addr).ipv6_addr16[7])
+
+
+/*IPv6 Header related structures */
+typedef struct GNU_PACKED _rt_ipv6_hdr_
+{
+ UINT32 ver:4,
+ trafficClass:8,
+ flowLabel:20;
+ USHORT payload_len;
+ UCHAR nextHdr;
+ UCHAR hopLimit;
+ RT_IPV6_ADDR srcAddr;
+ RT_IPV6_ADDR dstAddr;
+}RT_IPV6_HDR, *PRT_IPV6_HDR;
+
+
+typedef struct GNU_PACKED _rt_ipv6_ext_hdr_
+{
+ UCHAR nextProto; /* Indicate the protocol type of next extension header. */
+ UCHAR extHdrLen; /* optional field for msg length of this extension header which didn't include the first "nextProto" field. */
+ UCHAR octets[1]; /* hook to extend header message body. */
+}RT_IPV6_EXT_HDR, *PRT_IPV6_EXT_HDR;
+
+
+/* ICMPv6 related structures */
+typedef struct GNU_PACKED _rt_ipv6_icmpv6_hdr_
+{
+ UCHAR type;
+ UCHAR code;
+ USHORT chksum;
+ UCHAR octets[1]; /*hook to extend header message body. */
+}RT_ICMPV6_HDR, *PRT_ICMPV6_HDR;
+
+
+typedef struct GNU_PACKED _rt_icmp6_option_hdr_
+{
+ UCHAR type;
+ UCHAR len;
+ UCHAR octet[1];
+}RT_ICMPV6_OPTION_HDR, *PRT_ICMPV6_OPTION_HDR;
+
+typedef enum{
+/* Defined ICMPv6 Option Types. */
+ TYPE_SRC_LL_ADDR = 1,
+ TYPE_TGT_LL_ADDR = 2,
+ TYPE_PREFIX_INFO = 3,
+ TYPE_REDIRECTED_HDR = 4,
+ TYPE_MTU = 5,
+}ICMPV6_OPTIONS_TYPE_DEF;
+
+
+static inline BOOLEAN IPv6ExtHdrHandle(
+ RT_IPV6_EXT_HDR *pExtHdr,
+ UCHAR *pProto,
+ UINT32 *pOffset)
+{
+ UCHAR nextProto = 0xff;
+ UINT32 extLen = 0;
+ BOOLEAN status = TRUE;
+
+ /*printk("%s(): parsing the Extension Header with Protocol(0x%x):\n", __FUNCTION__, *pProto); */
+ switch (*pProto)
+ {
+ case IPV6_NEXT_HEADER_HOP_BY_HOP:
+ /* IPv6ExtHopByHopHandle(); */
+ nextProto = pExtHdr->nextProto;
+ extLen = (pExtHdr->extHdrLen + 1) * 8;
+ break;
+
+ case IPV6_NEXT_HEADER_DESTINATION:
+ /* IPv6ExtDestHandle(); */
+ nextProto = pExtHdr->nextProto;
+ extLen = (pExtHdr->extHdrLen + 1) * 8;
+ break;
+
+ case IPV6_NEXT_HEADER_ROUTING:
+ /* IPv6ExtRoutingHandle(); */
+ nextProto = pExtHdr->nextProto;
+ extLen = (pExtHdr->extHdrLen + 1) * 8;
+ break;
+
+ case IPV6_NEXT_HEADER_FRAGMENT:
+ /* IPv6ExtFragmentHandle(); */
+ nextProto = pExtHdr->nextProto;
+ extLen = 8; /* The Fragment header length is fixed to 8 bytes. */
+ break;
+
+ case IPV6_NEXT_HEADER_AUTHENTICATION:
+ /* IPV6_NEXT_HEADER_ENCAPSULATION: */
+ /*
+ TODO: Not support. For encryption issue.
+ */
+ nextProto = 0xFF;
+ status = FALSE;
+ break;
+
+ default:
+ nextProto = 0xFF;
+ status = FALSE;
+ break;
+ }
+
+ *pProto = nextProto;
+ *pOffset += extLen;
+ /*printk("%s(): nextProto = 0x%x!, offset=0x%x!\n", __FUNCTION__, nextProto, offset); */
+
+ return status;
+
+}
+
+#endif /* __IPV6_HDR_H_ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/link_list.h b/cleopatre/devkit/mt7601udrv/include/link_list.h
new file mode 100644
index 0000000000..a262b3e05e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/link_list.h
@@ -0,0 +1,182 @@
+
+#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;
+}
+
+
+typedef struct _DL_LIST
+{
+ struct _DL_LIST *Next;
+ struct _DL_LIST *Prev;
+}DL_LIST, *PDL_LIST;
+
+static inline void DlListInit(struct _DL_LIST *List)
+{
+ List->Next = List;
+ List->Prev = List;
+}
+
+static inline void DlListAdd(struct _DL_LIST *List, struct _DL_LIST *Item)
+{
+ Item->Next = List->Next;
+ Item->Prev = List;
+ List->Next->Prev = Item;
+ List->Next = Item;
+}
+
+static inline void DlListAddTail(struct _DL_LIST *List, struct _DL_LIST *Item)
+{
+ DlListAdd(List->Prev, Item);
+}
+
+static inline void DlListDel(struct _DL_LIST *Item)
+{
+ Item->Next->Prev = Item->Prev;
+ Item->Prev->Next = Item->Next;
+ Item->Next = NULL;
+ Item->Prev = NULL;
+}
+
+static inline int DlListEmpty(struct _DL_LIST *List)
+{
+ return List->Next == List;
+}
+
+static inline unsigned int DlListLen(struct _DL_LIST *List)
+{
+ struct _DL_LIST *Item;
+ unsigned int Count = 0;
+
+ for (Item = List->Next; Item != List; Item = Item->Next)
+ Count++;
+
+ return Count;
+}
+
+
+#ifndef offsetof
+#define offsetof(type, member) ((long) &((type *) 0)->member)
+#endif
+
+#define DlListEntry(item, type, member) \
+ ((type *) ((char *) item - offsetof(type, member)))
+
+#define DlListFirst(list, type, member) \
+ (DlListEmpty((list)) ? NULL : \
+ DlListEntry((list)->Next, type, member))
+
+#define DlListForEach(item, list, type, member) \
+ for (item = DlListEntry((list)->Next, type, member); \
+ &item->member != (list); \
+ item = DlListEntry(item->member.Next, type, member))
+
+#define DlListForEachSafe(item, n, list, type, member) \
+ for (item = DlListEntry((list)->Next, type, member), \
+ n = DlListEntry(item->member.Next, type, member); \
+ &item->member != (list); \
+ item = n, n = DlListEntry(n->member.Next, type, member))
+
+
+#endif /* ___LINK_LIST_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/fce.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/fce.h
new file mode 100644
index 0000000000..3d1cdd7aed
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/fce.h
@@ -0,0 +1,70 @@
+/*
+
+*/
+
+#ifndef __FCE_H__
+#define __FCE_H__
+
+#include "rt_config.h"
+
+#define FCE_PSE_CTRL 0x0800
+#define FCE_CSO 0x0808
+#define FCE_L2_STUFF 0x080c
+#define TX_CPU_PORT_FROM_FCE_BASE_PTR 0x09A0
+#define TX_CPU_PORT_FROM_FCE_MAX_COUNT 0x09A4
+#define FCE_PDMA_GLOBAL_CONF 0x09C4
+#define TX_CPU_PORT_FROM_FCE_CPU_DESC_INDEX 0x09A8
+#define FCE_SKIP_FS 0x0A6C
+#define PER_PORT_PAUSE_ENABLE_CONTROL1 0x0A38
+
+#ifdef BIG_ENDIAN
+typedef union _L2_STUFFING_STRUC
+{
+ struct {
+ UINT32 RSV:6;
+ UINT32 OTHER_PORT:2;
+ UINT32 TS_LENGTH_EN:8;
+ UINT32 TS_CMD_QSEL_EN:8;
+ UINT32 RSV2:2;
+ UINT32 MVINF_BYTE_SWP:1;
+ UINT32 FS_WR_MPDU_LEN_EN:1;
+ UINT32 TX_L2_DE_STUFFING_EN:1;
+ UINT32 RX_L2_STUFFING_EN:1;
+ UINT32 QoS_L2_EN:1;
+ UINT32 HT_L2_EN:1;
+ } field;
+
+ UINT32 word;
+} L2_STUFFING_STRUC, *PL2_STUFFING_STRUC;
+#else
+typedef union _L2_STUFFING_STRUC
+{
+ struct {
+ UINT32 HT_L2_EN:1;
+ UINT32 QoS_L2_EN:1;
+ UINT32 RX_L2_STUFFING_EN:1;
+ UINT32 TX_L2_DE_STUFFING_EN:1;
+ UINT32 FS_WR_MPDU_LEN_EN:1;
+ UINT32 MVINF_BYTE_SWP:1;
+ UINT32 RSV2:2;
+ UINT32 TS_CMD_QSEL_EN:8;
+ UINT32 TS_LENGTH_EN:8;
+ UINT32 OTHER_PORT:2;
+ UINT32 RSV:6;
+ } field;
+
+ UINT32 word;
+} L2_STUFFING_STRUC, *PL2_STUFFING_STRUC;
+#endif
+
+#define NORMAL_PKT 0x0
+#define CMD_PKT 0x1
+
+#define FCE_WLAN_PORT 0x0
+#define FCE_CPU_RX_PORT 0x1
+#define FCE_CPU_TX_PORT 0x2
+#define FCE_HOST_PORT 0x3
+#define FCE_VIRTUAL_CPU_RX_PORT 0x4
+#define FCE_VIRTUAL_CPU_TX_PORT 0x5
+#define FCE_DISCARD 0x6
+#endif /*__FCE_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/mac_pci.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/mac_pci.h
new file mode 100644
index 0000000000..d4423ba636
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/mac_pci.h
@@ -0,0 +1,405 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ mac_pci.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __MAC_PCI_H__
+#define __MAC_PCI_H__
+
+#include "rtmp_type.h"
+
+#ifdef RLT_MAC
+#include "mac_ral/nmac/ral_nmac_pci.h"
+#endif /* RLT_MAC */
+#ifdef RTMP_MAC
+#include "mac_ral/omac/ral_omac_pci.h"
+#endif /* RTMP_MAC */
+
+#include "mac_ral/rtmp_mac.h"
+#include "chip/rtmp_phy.h"
+#include "rtmp_iface.h"
+#include "rtmp_dot11.h"
+
+
+
+#define fRTMP_ADAPTER_NEED_STOP_TX 0
+
+
+/* =================================================================================
+ PCI/RBUS TX / RX Frame Descriptors format
+
+ Memory Layout
+
+ 1. Tx Descriptor
+ TxD (12 bytes) + TXINFO (4 bytes)
+ 2. Packet Buffer
+ TXWI + 802.11
+ 31 0
+ +--------------------------------------------------------------------------+
+ | SDP0[31:0] |
+ +-+--+---------------------+-+--+-----------------------------------------+
+ |D |L0| SDL0[13:0] |B|L1| SDL1[13:0] |
+ +-+--+---------------------+-+--+-----------------------------------------+
+ | SDP1[31:0] |
+ +--------------------------------------------------------------------------+
+ | TXINFO |
+ +--------------------------------------------------------------------------+
+================================================================================= */
+/*
+ TX descriptor format for Tx Data/Mgmt Rings
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _TXD_STRUC {
+ /* Word 0 */
+ UINT32 SDPtr0;
+ /* Word 1 */
+ UINT32 DMADONE:1;
+ UINT32 LastSec0:1;
+ UINT32 SDLen0:14;
+ UINT32 Burst:1;
+ UINT32 LastSec1:1;
+ UINT32 SDLen1:14;
+ /* Word 2 */
+ UINT32 SDPtr1;
+} TXD_STRUC, *PTXD_STRUC;
+#else
+typedef struct GNU_PACKED _TXD_STRUC {
+ /* Word 0 */
+ UINT32 SDPtr0;
+ /* Word 1 */
+ UINT32 SDLen1:14;
+ UINT32 LastSec1:1;
+ UINT32 Burst:1;
+ UINT32 SDLen0:14;
+ UINT32 LastSec0:1;
+ UINT32 DMADONE:1;
+ /*Word2 */
+ UINT32 SDPtr1;
+} TXD_STRUC, *PTXD_STRUC;
+#endif
+
+
+/*
+ Rx descriptor format, Rx Ring
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXD_STRUC{
+ /* Word 0 */
+ UINT32 SDP0;
+ /* Word 1 */
+ UINT32 DDONE:1;
+ UINT32 LS0:1;
+ UINT32 SDL0:14;
+ UINT32 BURST:1;
+ UINT32 LS1:1;
+ UINT32 SDL1:14;
+ /* Word 2 */
+ UINT32 SDP1;
+}RXD_STRUC, *PRXD_STRUC;
+#else
+typedef struct GNU_PACKED _RXD_STRUC{
+ /* Word 0 */
+ UINT32 SDP0;
+ /* Word 1 */
+ UINT32 SDL1:14;
+ UINT32 LS1:1;
+ UINT32 BURST:1;
+ UINT32 SDL0:14;
+ UINT32 LS0:1;
+ UINT32 DDONE:1;
+ /* Word 2 */
+ UINT32 SDP1;
+}RXD_STRUC, *PRXD_STRUC;
+#endif
+
+
+/* ----------------- EEPROM Related MACRO ----------------- */
+
+/* 8051 firmware image for RT2860 - base address = 0x4000 */
+#define FIRMWARE_IMAGE_BASE 0x2000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 /* 8kbyte */
+
+
+/* ----------------- Frimware Related MACRO ----------------- */
+#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
+ do{ \
+ ULONG _i, _firm; \
+ /* protect 8051 we will do firmware upload */ \
+ RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000); \
+ \
+ for(_i=0; _i<_FwLen; _i+=4) \
+ { \
+ _firm = _pFwImage[_i] + \
+ (_pFwImage[_i+3] << 24) + \
+ (_pFwImage[_i+2] << 16) + \
+ (_pFwImage[_i+1] << 8); \
+ RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm); \
+ } \
+ /* do 8051 firmware reset */ \
+ RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000); \
+ RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001); \
+ \
+ /* initialize BBP R/W access agent */ \
+ RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0); \
+ RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0); \
+ }while(0)
+
+
+/* ----------------- TX Related MACRO ----------------- */
+#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0)
+#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0)
+
+
+#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+ ((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */
+#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
+ do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
+ (((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
+ /*(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1)) */
+
+
+#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) \
+ RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
+ /* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \
+ RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+ RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \
+ RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) \
+ RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
+
+#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
+ /*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/
+
+#ifdef RLT_MAC
+#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \
+ RTMP_IO_WRITE32((_pAd), TX_RING_CIDX + ((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
+#endif /* RLT_MAC */
+#ifdef RTMP_MAC
+#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \
+ RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
+/* RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
+#endif /* RTMP_MAC */
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
+ MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define GET_TXRING_FREENO(_pAd, _QueIdx) \
+ (_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx) ? \
+ (_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
+ : \
+ (_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
+
+
+#define GET_MGMTRING_FREENO(_pAd) \
+ (_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx) ? \
+ (_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
+ : \
+ (_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
+
+
+/* ----------------- RX Related MACRO ----------------- */
+
+
+/* ----------------- ASIC Related MACRO ----------------- */
+/* reset MAC of a station entry to 0x000000000000 */
+#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid) \
+ AsicDelWcidTab(pAd, Wcid);
+
+/* add this entry into ASIC RX WCID search table */
+#define RTMP_STA_ENTRY_ADD(pAd, pEntry) \
+ AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
+
+#define RTMP_UPDATE_PROTECT(_pAd, _OperationMode, _SetMask, _bDisableBGProtect, _bNonGFExist) \
+ AsicUpdateProtect(pAd, _OperationMode, _SetMask, _bDisableBGProtect, _bNonGFExist);
+
+#ifdef CONFIG_AP_SUPPORT
+#define RTMP_AP_UPDATE_CAPABILITY_AND_ERPIE(pAd) \
+ APUpdateCapabilityAndErpIe(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+/* Insert the BA bitmap to ASIC for the Wcid entry */
+#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \
+ do{ \
+ UINT32 _Value = 0, _Offset; \
+ _Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4; \
+ RTMP_IO_READ32((_pAd), _Offset, &_Value);\
+ _Value |= (0x10000<<(_TID)); \
+ RTMP_IO_WRITE32((_pAd), _Offset, _Value);\
+ }while(0)
+
+
+/* Remove the BA bitmap from ASIC for the Wcid entry */
+/* bitmap field starts at 0x10000 in ASIC WCID table */
+#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \
+ do{ \
+ UINT32 _Value = 0, _Offset; \
+ _Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4; \
+ RTMP_IO_READ32((_pAd), _Offset, &_Value); \
+ _Value &= (~(0x10000 << (_TID))); \
+ RTMP_IO_WRITE32((_pAd), _Offset, _Value); \
+ }while(0)
+
+
+/* ----------------- Interface Related MACRO ----------------- */
+
+/* */
+/* Enable & Disable NIC interrupt via writing interrupt mask register */
+/* Since it use ADAPTER structure, it have to be put after structure definition. */
+/* */
+#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd) \
+ do{ \
+ RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0); /* 0: disable */ \
+ RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \
+ }while(0)
+
+#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\
+ do{ \
+ RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/); /* 1:enable */ \
+ RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \
+ }while(0)
+
+
+#ifdef RLT_MAC
+#define RTMP_IRQ_INIT(pAd) \
+ { unsigned long _irqFlags;\
+ RTMP_INT_LOCK(&pAd->irq_lock, _irqFlags);\
+ pAd->int_enable_reg = ((DELAYINTMASK) |(RxINT|TxDataInt|TxMgmtInt));\
+ pAd->int_disable_mask = 0;\
+ pAd->int_pending = 0;\
+ RTMP_INT_UNLOCK(&pAd->irq_lock, _irqFlags);\
+ }
+#endif /* RLT_MAC */
+
+#ifdef RTMP_MAC
+#define RTMP_IRQ_INIT(pAd) \
+ { unsigned long _irqFlags;\
+ RTMP_INT_LOCK(&pAd->irq_lock, _irqFlags);\
+ pAd->int_enable_reg = ((DELAYINTMASK) | \
+ (RxINT|TxDataInt|TxMgmtInt)) & ~(0x03); \
+ pAd->int_disable_mask = 0; \
+ pAd->int_pending = 0; \
+ RTMP_INT_UNLOCK(&pAd->irq_lock, _irqFlags);\
+ }
+#endif /* RTMP_MAC */
+
+#define RTMP_IRQ_ENABLE(pAd) \
+{ /* clear garbage ints */ \
+ unsigned long _irqFlags;\
+ RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\
+ RTMP_INT_LOCK(&pAd->irq_lock, _irqFlags);\
+ RTMP_ASIC_INTERRUPT_ENABLE(pAd); \
+ RTMP_INT_UNLOCK(&pAd->irq_lock, _irqFlags);\
+}
+
+
+
+/* ----------------- MLME Related MACRO ----------------- */
+#define RTMP_MLME_HANDLER(pAd) MlmeHandler(pAd)
+
+#define RTMP_MLME_PRE_SANITY_CHECK(pAd)
+
+#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \
+ MlmeRestartStateMachine(pAd)
+
+#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\
+ HandleCounterMeasure(_pAd, _pEntry)
+
+/* ----------------- Power Save Related MACRO ----------------- */
+#define RTMP_PS_POLL_ENQUEUE(pAd) EnqueuePsPoll(pAd)
+
+
+/* For RTMPPCIePowerLinkCtrlRestore () function */
+#define RESTORE_HALT 1
+#define RESTORE_WAKEUP 2
+#define RESTORE_CLOSE 3
+
+#define PowerSafeCID 1
+#define PowerRadioOffCID 2
+#define PowerWakeCID 3
+#define CID0MASK 0x000000ff
+#define CID1MASK 0x0000ff00
+#define CID2MASK 0x00ff0000
+#define CID3MASK 0xff000000
+
+
+
+#define RTMP_MLME_RADIO_ON(pAd) \
+ RT28xxPciMlmeRadioOn(pAd);
+
+#define RTMP_MLME_RADIO_OFF(pAd) \
+ RT28xxPciMlmeRadioOFF(pAd);
+
+/* ----------------- Security Related MACRO ----------------- */
+
+/* Set Asic WCID Attribute table */
+#define RTMP_SET_WCID_SEC_INFO(_pAd, _BssIdx, _KeyIdx, _CipherAlg, _Wcid, _KeyTabFlag) \
+ RTMPSetWcidSecurityInfo(_pAd, _BssIdx, _KeyIdx, _CipherAlg, _Wcid, _KeyTabFlag)
+
+/* Set Asic WCID IV/EIV table */
+#define RTMP_ASIC_WCID_IVEIV_TABLE(_pAd, _Wcid, _uIV, _uEIV) \
+ AsicUpdateWCIDIVEIV(_pAd, _Wcid, _uIV, _uEIV)
+
+/* Set Asic WCID Attribute table (offset:0x6800) */
+#define RTMP_ASIC_WCID_ATTR_TABLE(_pAd, _BssIdx, _KeyIdx, _CipherAlg, _Wcid, _KeyTabFlag)\
+ AsicUpdateWcidAttributeEntry(_pAd, _BssIdx, _KeyIdx, _CipherAlg, _Wcid, _KeyTabFlag)
+
+/* Set Asic Pairwise key table */
+#define RTMP_ASIC_PAIRWISE_KEY_TABLE(_pAd, _WCID, _pCipherKey) \
+ AsicAddPairwiseKeyEntry(_pAd, _WCID, _pCipherKey)
+
+/* Set Asic Shared key table */
+#define RTMP_ASIC_SHARED_KEY_TABLE(_pAd, _BssIndex, _KeyIdx, _pCipherKey) \
+ AsicAddSharedKeyEntry(_pAd, _BssIndex, _KeyIdx, _pCipherKey)
+
+
+/* Remove Pairwise Key table */
+#define RTMP_REMOVE_PAIRWISE_KEY_ENTRY(_pAd, _Wcid)\
+ AsicRemovePairwiseKeyEntry(_pAd, _Wcid)
+
+#ifdef PCI_MSI_SUPPORT
+#define RTMP_OS_IRQ_RELEASE(_pAd, _NetDev) \
+{ \
+ POS_COOKIE pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
+ RtmpOSIRQRelease(_NetDev, pAd->infType, pObj->pci_dev, &_pAd->HaveMsi); \
+}
+#else
+#define RTMP_OS_IRQ_RELEASE(_pAd, _NetDev) \
+{ \
+ POS_COOKIE pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
+ RtmpOSIRQRelease(_NetDev, pAd->infType, pObj->pci_dev, NULL); \
+}
+#endif /* PCI_MSI_SUPPORT */
+
+#endif /*__MAC_PCI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/mac_usb.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/mac_usb.h
new file mode 100644
index 0000000000..792e69e39e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/mac_usb.h
@@ -0,0 +1,490 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ mac_usb.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __MAC_USB_H__
+#define __MAC_USB_H__
+
+#include "rtmp_type.h"
+#ifdef RLT_MAC
+#include "mac_ral/nmac/ral_nmac_usb.h"
+#endif /* RLT_MAC */
+#ifdef RTMP_MAC
+#include "mac_ral/omac/ral_omac_usb.h"
+#endif /* RTMP_MAC */
+
+#include "mac_ral/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 */
+#ifdef CONFIG_MULTI_CHANNEL
+#define MGMTPIPEIDX 5 /* EP6 is highest priority */
+#else
+#define MGMTPIPEIDX 0 /* EP6 is highest priority */
+#endif /* CONFIG_MULTI_CHANNEL */
+
+/* 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)
+
+
+/* =================================================================================
+ USB TX / RX Frame Descriptors format
+
+ Tx Memory Layout
+ 1. Packet Buffer
+ TxINFO(4 bytes) + TXWI( 16 bytes) + 802.11
+ 31 0
+ +--------------------------------------------------------------------------+
+ | TXINFO[31:0] |
+ +--------------------------------------------------------------------------+
+ | TxWI |
+ + +
+ | |
+ + +
+ | |
+ + +
+ | |
+ +--------------------------------------------------------------------------+
+ | 802.11 |
+ | ......... |
+ +--------------------------------------------------------------------------+
+
+
+ Rx Memory Layout
+ 1. Packet Buffer
+ RxDMALen(4 bytes) + RXWI(16 bytes) + 802.11 + RXINFO (4 bytes)
+ 31 0
+ +--------------------------------------------------------------------------+
+ | RXDMALen[31:0] |
+ +--------------------------------------------------------------------------+
+ | RxWI |
+ + +
+ | |
+ + +
+ | |
+ + +
+ | |
+ +--------------------------------------------------------------------------+
+ | 802.11 |
+ | ......... |
+ +--------------------------------------------------------------------------+
+ | RXINFO |
+ +--------------------------------------------------------------------------+
+
+================================================================================= */
+
+
+/*
+ RXINFO appends at the end of each rx packet
+*/
+#define RXDMA_FIELD_SIZE 4
+
+
+/*
+ Rx descriptor format, Rx Ring
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXD_STRUC{
+ UINT32 dma_len;
+}RXD_STRUC, *PRXD_STRUC;
+#else
+typedef struct GNU_PACKED _RXD_STRUC{
+ UINT32 dma_len;
+}RXD_STRUC, *PRXD_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;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef UAPSD_SUPPORT
+ USHORT Wcid;
+#endif /* UAPSD_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+} 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;
+
+
+typedef struct _CMD_CONTEXT
+{
+ PVOID pAd;
+ PURB pUrb;
+ ra_dma_addr_t data_dma;
+ PUCHAR TransferBuffer;
+ BOOLEAN IRPPending;
+} CMD_CONTEXT, *PCMD_CONTEXT, **PPCMD_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;
+
+
+typedef struct _CMD_RSP_CONTEXT
+{
+ PUCHAR CmdRspBuffer;
+ PVOID pAd;
+ PURB pUrb;
+ BOOLEAN IRPPending;
+ BOOLEAN InUse;
+ BOOLEAN Readable;
+ ra_dma_addr_t data_dma;
+} CMD_RSP_CONTEXT, *PCMD_RSP_CONTEXT;
+
+/******************************************************************************
+
+ USB Frimware Related MACRO
+
+******************************************************************************/
+/* 8051 firmware image for usb - use last-half base address = 0x3000 */
+#define FIRMWARE_IMAGE_BASE 0x3000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 /* 4kbyte */
+
+#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
+ RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
+
+
+
+/******************************************************************************
+
+ USB TX Related MACRO
+
+******************************************************************************/
+#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) \
+ { \
+ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ if (pAd->DeQueueRunning[QueIdx]) \
+ { \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+ DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx)); \
+ continue; \
+ } \
+ else \
+ { \
+ pAd->DeQueueRunning[QueIdx] = TRUE; \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+ } \
+ }
+
+#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \
+ do{ \
+ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ pAd->DeQueueRunning[QueIdx] = FALSE; \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ }while(0)
+
+#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+ (RTUSBFreeDescRequest(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_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
+ */
+
+#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)); \
+}
+
+
+/* Remove Pairwise Key table */
+#define RTMP_REMOVE_PAIRWISE_KEY_ENTRY(_pAd, _Wcid) \
+{ \
+ UCHAR _tWcid =_Wcid; \
+ RTEnqueueInternalCmd(_pAd, CMDTHREAD_REMOVE_PAIRWISE_KEY, &(_tWcid), sizeof(UCHAR));\
+}
+
+#define RTMP_OS_IRQ_RELEASE(_pAd, _NetDev)
+
+#endif /*__MAC_USB_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac.h
new file mode 100644
index 0000000000..93ebcca523
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac.h
@@ -0,0 +1,782 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_nmac.h
+
+ Abstract:
+ Ralink Wireless Chip RAL MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_NMAC_H__
+#define __RAL_NMAC_H__
+
+
+#include "rtmp_type.h"
+
+#ifdef MT7601
+#include "mac_ral/omac/ral_omac_rxwi.h"
+#else
+#include "mac_ral/nmac/ral_nmac_rxwi.h"
+#endif /* MT7601 */
+
+#include "mac_ral/nmac/ral_nmac_txwi.h"
+
+enum INFO_TYPE {
+ NORMAL_PACKET,
+ CMD_PACKET,
+};
+
+enum D_PORT {
+ WLAN_PORT,
+ CPU_RX_PORT,
+ CPU_TX_PORT,
+ HOST_PORT,
+ VIRTUAL_CPU_RX_PORT,
+ VIRTUAL_CPU_TX_PORT,
+ DISCARD,
+};
+
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _TXINFO_NMAC_PKT{
+ UINT32 info_type:2;
+ UINT32 d_port:3;
+ UINT32 QSEL:2;
+ UINT32 wiv:1;
+ UINT32 rsv1:2;
+ UINT32 cso:1;
+ UINT32 tso:1;
+ UINT32 pkt_80211:1;
+ UINT32 rsv0:1;
+ UINT32 tx_burst:1;
+ UINT32 next_vld:1;
+ UINT32 pkt_len:16;
+}TXINFO_NMAC_PKT;
+#else
+typedef struct GNU_PACKED _TXINFO_NMAC_PKT {
+ UINT32 pkt_len:16;
+ UINT32 next_vld:1;
+ UINT32 tx_burst:1;
+ UINT32 rsv0:1;
+ UINT32 pkt_80211:1;
+ UINT32 tso:1;
+ UINT32 cso:1;
+ UINT32 rsv1:2;
+ UINT32 wiv:1;
+ UINT32 QSEL:2;
+ UINT32 d_port:3;
+ UINT32 info_type:2;
+}TXINFO_NMAC_PKT;
+#endif /* RT_BIG_ENDIAN */
+
+#define TxInfoWIV txinfo_nmac_pkt.wiv
+#define TxInfoQSEL txinfo_nmac_pkt.QSEL
+#define TxInfoPktLen txinfo_nmac_pkt.pkt_len
+#define TxInfoSwLstRnd txinfo_nmac_pkt.rsv0
+#define TxInfoUDMATxburst txinfo_nmac_pkt.tx_burst
+#define TxInfoUDMANextVld txinfo_nmac_pkt.next_vld
+#define TxInfoPKT_80211 txinfo_nmac_pkt.pkt_80211
+#define TxInfoCSO txinfo_nmac_pkt.cso
+#define TxInfoTSO txinfo_nmac_pkt.tso
+
+
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _TXINFO_NMAC_CMD{
+ UINT32 info_type:2;
+ UINT32 d_port:3;
+ UINT32 cmd_type:7;
+ UINT32 cmd_seq:4;
+ UINT32 pkt_len:16;
+}TXINFO_NMAC_CMD;
+#else
+typedef struct GNU_PACKED _TXINFO_NMAC_CMD{
+ UINT32 pkt_len:16;
+ UINT32 cmd_seq:4;
+ UINT32 cmd_type:7;
+ UINT32 d_port:3;
+ UINT32 info_type:2;
+}TXINFO_NMAC_CMD;
+#endif /* RT_BIG_ENDIAN */
+
+
+typedef union GNU_PACKED _TXINFO_NMAC{
+ struct _TXINFO_NMAC_PKT txinfo_pkt;
+ struct _TXINFO_NMAC_CMD txinfo_cmd;
+}TXINFO_NMAC;
+
+
+/*
+ Rx Memory layout:
+
+ 1. Rx Descriptor
+ Rx Descriptor(12 Bytes) + RX_FCE_Info(4 Bytes)
+ 2. Rx Buffer
+ RxInfo(4 Bytes) + RXWI() + 802.11 packet
+*/
+
+
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXFCE_INFO{
+ UINT32 info_type:2;
+ UINT32 s_port:3;
+ UINT32 qsel:2;
+ UINT32 pcie_intr:1;
+
+ UINT32 mac_len:3;
+ UINT32 l3l4_done:1;
+ UINT32 pkt_80211:1;
+ UINT32 ip_err:1;
+ UINT32 tcp_err:1;
+ UINT32 udp_err:1;
+
+ UINT32 rsv:2;
+ UINT32 pkt_len:14;
+}RXFCE_INFO;
+#else
+typedef struct GNU_PACKED _RXFCE_INFO{
+ UINT32 pkt_len:14;
+ UINT32 rsv:2;
+
+ UINT32 udp_err:1;
+ UINT32 tcp_err:1;
+ UINT32 ip_err:1;
+ UINT32 pkt_80211:1;
+ UINT32 l3l4_done:1;
+ UINT32 mac_len:3;
+
+ UINT32 pcie_intr:1;
+ UINT32 qsel:2;
+ UINT32 s_port:3;
+ UINT32 info_type:2;
+}RXFCE_INFO;
+#endif /* RT_BIG_ENDIAN */
+
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXFCE_INFO_CMD{
+ UINT32 info_type:2;
+ UINT32 d_port:3;
+ UINT32 qsel:2;
+ UINT32 pcie_intr:1;
+ UINT32 evt_type:4;
+ UINT32 cmd_seq:4;
+ UINT32 self_gen:1;
+ UINT32 rsv:1;
+ UINT32 pkt_len:14;
+}RXFCE_INFO_CMD;
+#else
+typedef struct GNU_PACKED _RXFCE_INFO_CMD{
+ UINT32 pkt_len:14;
+ UINT32 rsv:1;
+ UINT32 self_gen:1;
+ UINT32 cmd_seq:4;
+ UINT32 evt_type:4;
+ UINT32 pcie_intr:1;
+ UINT32 qsel:2;
+ UINT32 d_port:3;
+ UINT32 info_type:2;
+}RXFCE_INFO_CMD;
+#endif
+
+
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXINFO_NMAC{
+ UINT32 ic_err:1;
+ UINT32 tc_err:1;
+ UINT32 ichk_bps:1;
+ UINT32 tchk_bps:1;
+ UINT32 rsv0:6;
+ UINT32 pn_len:3;
+ UINT32 wapi_kid:1;
+ UINT32 bssid_idx3:1;
+ UINT32 dec:1;
+ UINT32 ampdu:1;
+ UINT32 l2pad:1;
+ UINT32 rssi:1;
+ UINT32 htc:1;
+ UINT32 amsdu:1;
+ UINT32 mic_err:1;
+ UINT32 icv_err:1;
+ UINT32 crc_err:1;
+ UINT32 mybss:1;
+ UINT32 bc:1;
+ UINT32 mc:1;
+ UINT32 u2me:1;
+ UINT32 frag:1;
+ UINT32 null:1;
+ UINT32 data:1;
+ UINT32 ba:1;
+}RXINFO_NMAC;
+#else
+typedef struct GNU_PACKED _RXINFO_NMAC{
+ UINT32 ba:1;
+ UINT32 data:1;
+ UINT32 null:1;
+ UINT32 frag:1;
+ UINT32 u2me:1;
+ UINT32 mcast:1;
+ UINT32 bcast:1;
+ UINT32 mybss:1;
+ UINT32 crc_err:1;
+ UINT32 icv_err:1;
+ UINT32 mic_err:1;
+ UINT32 amsdu:1;
+ UINT32 htc:1;
+ UINT32 rssi:1;
+ UINT32 l2pad:1;
+ UINT32 ampdu:1;
+ UINT32 dec:1;
+ UINT32 bssid_idx3:1;
+ UINT32 wapi_kid:1;
+ UINT32 pn_len:3;
+ UINT32 rsv0:6;
+ UINT32 tchk_bps:1;
+ UINT32 ichk_bps:1;
+ UINT32 tc_err:1;
+ UINT32 ic_err:1;
+}RXINFO_NMAC;
+#endif /* RT_BIG_ENDIAN */
+
+
+/* ================================================================================= */
+/* Register format */
+/* ================================================================================= */
+
+
+#define WLAN_FUN_CTRL 0x80
+#ifdef RT_BIG_ENDIAN
+typedef union _WLAN_FUN_CTRL_STRUC{
+ struct{
+ UINT32 GPIO0_OUT_OE_N:8;
+ UINT32 GPIO0_OUT:8;
+ UINT32 GPIO0_IN:8;
+ UINT32 WLAN_ACC_BT:1;
+ UINT32 INV_TR_SW0:1;
+ UINT32 FRC_WL_ANT_SET:1;
+ UINT32 PCIE_APP0_CLK_REQ:1;
+ UINT32 WLAN_RESET:1;
+ UINT32 WLAN_RESET_RF:1;
+ UINT32 WLAN_CLK_EN:1;
+ UINT32 WLAN_EN:1;
+ }field;
+ UINT32 word;
+}WLAN_FUN_CTRL_STRUC, *PWLAN_FUN_CTRL_STRUC;
+#else
+typedef union _WLAN_FUN_CTRL_STRUC{
+ struct{
+ UINT32 WLAN_EN:1;
+ UINT32 WLAN_CLK_EN:1;
+ UINT32 WLAN_RESET_RF:1;
+ UINT32 WLAN_RESET:1;
+ UINT32 PCIE_APP0_CLK_REQ:1;
+ UINT32 FRC_WL_ANT_SET:1;
+ UINT32 INV_TR_SW0:1;
+ UINT32 WLAN_ACC_BT:1;
+ UINT32 GPIO0_IN:8;
+ UINT32 GPIO0_OUT:8;
+ UINT32 GPIO0_OUT_OE_N:8;
+ }field;
+ UINT32 word;
+}WLAN_FUN_CTRL_STRUC, *PWLAN_FUN_CTRL_STRUC;
+#endif
+
+
+#define WLAN_FUN_INFO 0x84
+#ifdef RT_BIG_ENDIAN
+typedef union _WLAN_FUN_INFO_STRUC{
+ struct{
+ UINT32 BT_EEP_BUSY:1; /* Read-only for WLAN Driver */
+ UINT32 Rsv1:26;
+ UINT32 COEX_MODE:5; /* WLAN function enable */
+ }field;
+ UINT32 word;
+}WLAN_FUN_INFO_STRUC, *PWLAN_FUN_INFO_STRUC;
+#else
+typedef union _WLAN_FUN_INFO_STRUC{
+ struct{
+ UINT32 COEX_MODE:5; /* WLAN function enable */
+ UINT32 Rsv1:26;
+ UINT32 BT_EEP_BUSY:1; /* Read-only for WLAN Driver */
+ }field;
+ UINT32 word;
+}WLAN_FUN_INFO_STRUC, *PWLAN_FUN_INFO_STRUC;
+#endif
+
+
+#define BT_FUN_CTRL 0xC0
+#ifdef RT_BIG_ENDIAN
+typedef union _BT_FUN_CTRL_STRUC{
+ struct{
+ UINT32 GPIO1_OUT_OE_N:8;
+ UINT32 GPIO1_OUT:8;
+ UINT32 GPIO1_IN:8;
+ UINT32 BT_ACC_WLAN:1;
+ UINT32 INV_TR_SW1:1;
+ UINT32 URXD_GPIO_MODE:1;
+ UINT32 PCIE_APP1_CLK_REQ:1;
+ UINT32 BT_RESET:1;
+ UINT32 BT_RF_EN:1;
+ UINT32 BT_CLK_EN:1;
+ UINT32 BT_EN:1;
+ }field;
+ UINT32 word;
+}BT_FUN_CTRL_STRUC, *PBT_FUN_CTRL_STRUC;
+#else
+typedef union _BT_FUN_CTRL_STRUC {
+ struct{
+ UINT32 BT_EN:1;
+ UINT32 BT_CLK_EN:1;
+ UINT32 BT_RF_EN:1;
+ UINT32 BT_RESET:1;
+ UINT32 PCIE_APP1_CLK_REQ:1;
+ UINT32 URXD_GPIO_MODE:1;
+ UINT32 INV_TR_SW1:1;
+ UINT32 BT_ACC_WLAN:1;
+ UINT32 GPIO1_IN:8;
+ UINT32 GPIO1_OUT:8;
+ UINT32 GPIO1_OUT_OE_N:8;
+ }field;
+ UINT32 word;
+}BT_FUN_CTRL_STRUC, *PBT_FUN_CTRL_STRUC;
+#endif
+
+
+#define BT_FUN_INFO 0xC4
+#ifdef RT_BIG_ENDIAN
+typedef union _BT_FUN_INFO_STRUC{
+ struct{
+ UINT32 WLAN_EEP_BUSY:1;
+ UINT32 BTPower1:7; /* Peer */
+ UINT32 BTPower0:8; /* Self */
+ UINT32 AFH_END_CH:8;
+ UINT32 AFH_START_CH:8;
+ }field;
+ UINT32 word;
+} BT_FUN_INFO_STRUC, *PBT_FUN_INFO_STRUC;
+#else
+typedef union _BT_FUN_INFO_STRUC {
+ struct{
+ UINT32 AFH_START_CH:8;
+ UINT32 AFH_END_CH:8;
+ UINT32 BTPower0:8; /* Self */
+ UINT32 BTPower1:7; /* Peer */
+ UINT32 WLAN_EEP_BUSY:1;
+ }field;
+ UINT32 word;
+}BT_FUN_INFO_STRUC, *PBT_FUN_INFO_STRUC;
+#endif
+
+// TODO: shiang, this data structure is not defined for register. may can move to other place
+typedef struct _WLAN_BT_COEX_SETTING
+{
+ BOOLEAN ampduOff;
+ BOOLEAN coexSettingRunning;
+ BOOLEAN RateSelectionForceToUseRSSI;
+ UCHAR TxQualityFlag;
+ ULONG alc;
+ ULONG slna;
+}WLAN_BT_COEX_SETTING, *PWLAN_BT_COEX_SETTING;
+
+
+#define MCU_CMD_CFG 0x0234
+
+
+#define TSO_CTRL 0x0250
+#ifdef RT_BIG_ENDIAN
+typedef union _TSO_CTRL_STRUC {
+ struct {
+ UINT32 rsv:13;
+ UINT32 TSO_WR_LEN_EN:1;
+ UINT32 TSO_SEG_EN:1;
+ UINT32 TSO_EN:1;
+ UINT32 RXWI_LEN:4;
+ UINT32 RX_L2_FIX_LEN:4;
+ UINT32 TXWI_LEN:4;
+ UINT32 TX_L2_FIX_LEN:4;
+ } field;
+ UINT32 word;
+} TSO_CTRL_STRUC;
+#else
+typedef union _TSO_CTRL_STRUC {
+ struct {
+ UINT32 TX_L2_FIX_LEN:4;
+ UINT32 TXWI_LEN:4;
+ UINT32 RX_L2_FIX_LEN:4;
+ UINT32 RXWI_LEN:4;
+ UINT32 TSO_EN:1;
+ UINT32 TSO_SEG_EN:1;
+ UINT32 TSO_WR_LEN_EN:1;
+ UINT32 rsv:13;
+ } field;
+ UINT32 word;
+} TSO_CTRL_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+
+#define TX_FBK_LIMIT 0x1398
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_FBK_LIMIT_STRUC {
+ struct {
+ UINT32 rsv:13;
+ UINT32 TX_RATE_LUT_EN:1;
+ UINT32 TX_AMPDU_UP_CLEAR:1;
+ UINT32 TX_MPDU_UP_CLEAR:1;
+ UINT32 TX_AMPDU_FBK_LIMIT:8;
+ UINT32 TX_MPDU_FBK_LIMIT:8;
+ } field;
+ UINT32 word;
+} TX_FBK_LIMIT_STRUC;
+#else
+typedef union _TX_FBK_LIMIT_STRUC {
+ struct {
+ UINT32 TX_MPDU_FBK_LIMIT:8;
+ UINT32 TX_AMPDU_FBK_LIMIT:8;
+ UINT32 TX_MPDU_UP_CLEAR:1;
+ UINT32 TX_AMPDU_UP_CLEAR:1;
+ UINT32 TX_RATE_LUT_EN:1;
+ UINT32 rsv:13;
+ } field;
+ UINT32 word;
+} TX_FBK_LIMIT_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+#define TX_PROT_CFG6 0x13E0 // VHT 20 Protection
+#define TX_PROT_CFG7 0x13E4 // VHT 40 Protection
+#define TX_PROT_CFG8 0x13E8 // VHT 80 Protection
+#define PIFS_TX_CFG 0x13EC // PIFS setting
+
+
+//----------------------------------------------------------------
+// Header Translation
+//----------------------------------------------------------------
+
+/*
+ WIFI INFO for TX translation
+ |TXINO|TXWI|WIFI INFO|802.3 MAC Header|Pyaload|
+*/
+
+#define WIFI_INFO_SIZE 4
+#ifdef RT_BIG_ENDIAN
+typedef union GNU_PACKED _WIFI_INFO_STRUC {
+ struct {
+ UINT32 More_Data:1;
+ UINT32 WEP:1;
+ UINT32 PS:1;
+ UINT32 RDG:1;
+ UINT32 QoS:1;
+ UINT32 EOSP:1;
+ UINT32 TID:4;
+ UINT32 Mode:2;
+ UINT32 VLAN:1;
+ UINT32 Rsv:3;
+ UINT32 BssIdx:4;
+ UINT32 Seq_Num:12;
+ } field;
+ UINT32 word;
+} WIFI_INFO_STRUC, *PWIFI_INFO_STRUC;
+#else
+typedef union GNU_PACKED _WIFI_INFO_STRUC {
+ struct {
+ UINT32 Seq_Num:12;
+ UINT32 BssIdx:4;
+ UINT32 Rsv:3;
+ UINT32 VLAN:1;
+ UINT32 Mode:2;
+ UINT32 TID:4;
+ UINT32 EOSP:1;
+ UINT32 QoS:1;
+ UINT32 RDG:1;
+ UINT32 PS:1;
+ UINT32 WEP:1;
+ UINT32 More_Data:1;
+ } field;
+ UINT32 word;
+} WIFI_INFO_STRUC, *PWIFI_INFO_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+/*
+ header translation control register
+ bit0 --> TX translation enable
+ bit1 --> RX translation enable
+*/
+#define HEADER_TRANS_CTRL_REG 0x0260
+#define HT_TX_ENABLE 0x1
+#define HT_RX_ENABLE 0x2
+
+#define HT_MAC_ADDR_DW0 0x02A4
+#define HT_MAC_ADDR_DW1 0x02A8
+#define HT_MAC_BSSID_DW0 0x02AC
+#define HT_MAC_BSSID_DW1 0x02B0
+
+#ifdef RT_BIG_ENDIAN
+typedef union GNU_PACKED _HDR_TRANS_CTRL_STRUC {
+ struct {
+ UINT32 Rsv:30;
+ UINT32 Rx_En:1;
+ UINT32 Tx_En:1;
+ } field;
+ UINT32 word;
+} HDR_TRANS_CTRL_STRUC, *PHDR_TRANS_CTRL_STRUC;
+#else
+typedef union GNU_PACKED _HDR_TRANS_CTRL_STRUC {
+ struct {
+ UINT32 Tx_En:1;
+ UINT32 Rx_En:1;
+ UINT32 Rsv:30;
+ } field;
+ UINT32 word;
+} HDR_TRANS_CTRL_STRUC, *PHDR_TRANS_CTRL_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+/* RX header translation enable by WCID */
+#define HT_RX_WCID_EN_BASE 0x0264
+#define HT_RX_WCID_OFFSET 32
+#if defined(MT7601)
+#define HT_RX_WCID_SIZE (HT_RX_WCID_OFFSET * 4) /* 128 WCIDs */
+#elif defined(RT65xx)
+#define HT_RX_WCID_SIZE (HT_RX_WCID_OFFSET * 8) /* 256 WCIDs */
+#endif /* defined(RT63xx) */
+#ifdef RT_BIG_ENDIAN
+typedef union GNU_PACKED _HT_RX_WCID_EN_STRUC {
+ struct {
+ UINT32 RX_WCID31_TRAN_EN:1;
+ UINT32 RX_WCID30_TRAN_EN:1;
+ UINT32 RX_WCID29_TRAN_EN:1;
+ UINT32 RX_WCID28_TRAN_EN:1;
+ UINT32 RX_WCID27_TRAN_EN:1;
+ UINT32 RX_WCID26_TRAN_EN:1;
+ UINT32 RX_WCID25_TRAN_EN:1;
+ UINT32 RX_WCID24_TRAN_EN:1;
+ UINT32 RX_WCID23_TRAN_EN:1;
+ UINT32 RX_WCID22_TRAN_EN:1;
+ UINT32 RX_WCID21_TRAN_EN:1;
+ UINT32 RX_WCID20_TRAN_EN:1;
+ UINT32 RX_WCID19_TRAN_EN:1;
+ UINT32 RX_WCID18_TRAN_EN:1;
+ UINT32 RX_WCID17_TRAN_EN:1;
+ UINT32 RX_WCID16_TRAN_EN:1;
+ UINT32 RX_WCID15_TRAN_EN:1;
+ UINT32 RX_WCID14_TRAN_EN:1;
+ UINT32 RX_WCID13_TRAN_EN:1;
+ UINT32 RX_WCID12_TRAN_EN:1;
+ UINT32 RX_WCID11_TRAN_EN:1;
+ UINT32 RX_WCID10_TRAN_EN:1;
+ UINT32 RX_WCID9_TRAN_EN:1;
+ UINT32 RX_WCID8_TRAN_EN:1;
+ UINT32 RX_WCID7_TRAN_EN:1;
+ UINT32 RX_WCID6_TRAN_EN:1;
+ UINT32 RX_WCID5_TRAN_EN:1;
+ UINT32 RX_WCID4_TRAN_EN:1;
+ UINT32 RX_WCID3_TRAN_EN:1;
+ UINT32 RX_WCID2_TRAN_EN:1;
+ UINT32 RX_WCID1_TRAN_EN:1;
+ UINT32 RX_WCID0_TRAN_EN:1;
+ } field;
+ UINT32 word;
+} HT_RX_WCID_EN_STRUC, *PHT_RX_WCID_EN_STRUC;
+#else
+typedef union GNU_PACKED _HT_RX_WCID_EN_STRUC {
+ struct {
+ UINT32 RX_WCID0_TRAN_EN:1;
+ UINT32 RX_WCID1_TRAN_EN:1;
+ UINT32 RX_WCID2_TRAN_EN:1;
+ UINT32 RX_WCID3_TRAN_EN:1;
+ UINT32 RX_WCID4_TRAN_EN:1;
+ UINT32 RX_WCID5_TRAN_EN:1;
+ UINT32 RX_WCID6_TRAN_EN:1;
+ UINT32 RX_WCID7_TRAN_EN:1;
+ UINT32 RX_WCID8_TRAN_EN:1;
+ UINT32 RX_WCID9_TRAN_EN:1;
+ UINT32 RX_WCID10_TRAN_EN:1;
+ UINT32 RX_WCID11_TRAN_EN:1;
+ UINT32 RX_WCID12_TRAN_EN:1;
+ UINT32 RX_WCID13_TRAN_EN:1;
+ UINT32 RX_WCID14_TRAN_EN:1;
+ UINT32 RX_WCID15_TRAN_EN:1;
+ UINT32 RX_WCID16_TRAN_EN:1;
+ UINT32 RX_WCID17_TRAN_EN:1;
+ UINT32 RX_WCID18_TRAN_EN:1;
+ UINT32 RX_WCID19_TRAN_EN:1;
+ UINT32 RX_WCID20_TRAN_EN:1;
+ UINT32 RX_WCID21_TRAN_EN:1;
+ UINT32 RX_WCID22_TRAN_EN:1;
+ UINT32 RX_WCID23_TRAN_EN:1;
+ UINT32 RX_WCID24_TRAN_EN:1;
+ UINT32 RX_WCID25_TRAN_EN:1;
+ UINT32 RX_WCID26_TRAN_EN:1;
+ UINT32 RX_WCID27_TRAN_EN:1;
+ UINT32 RX_WCID28_TRAN_EN:1;
+ UINT32 RX_WCID29_TRAN_EN:1;
+ UINT32 RX_WCID30_TRAN_EN:1;
+ UINT32 RX_WCID31_TRAN_EN:1;
+ } field;
+ UINT32 word;
+} HT_RX_WCID_EN_STRUC, *PHT_RX_WCID_EN_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+/* RX header translation - black list */
+#define HT_RX_BL_BASE 0x0284
+#define HT_RX_BL_OFFSET 2
+#define HT_RX_BL_SIZE 8
+#ifdef RT_BIG_ENDIAN
+typedef union GNU_PACKED _HT_RX_BLACK_LIST_STRUC {
+ struct {
+ UINT32 BLACK_ETHER_TYPE1:16;
+ UINT32 BLACK_ETHER_TYPE0:16;
+ } field;
+ UINT32 word;
+} HT_RX_BLACK_LIST_STRUC, *PHT_RX_BLACK_LIST_STRUC;
+#else
+typedef union GNU_PACKED _HT_RX_BLACK_LIST_STRUC {
+ struct {
+ UINT32 BLACK_ETHER_TYPE0:16;
+ UINT32 BLACK_ETHER_TYPE1:16;
+ } field;
+ UINT32 word;
+} HT_RX_BLACK_LIST_STRUC, *PHT_RX_BLACK_LIST_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+/* RX VLAN Mapping (TCI) */
+#define HT_BSS_VLAN_BASE 0x0294
+#define HT_BSS_VLAN_OFFSET 2
+#define HT_BSS_VLAN_SIZE 8
+#ifdef RT_BIG_ENDIAN
+typedef union GNU_PACKED _HT_BSS_VLAN_STRUC {
+ struct {
+ UINT32 TCI1_VID:12;
+ UINT32 TCI1_CFI:1;
+ UINT32 TCI1_PCP:3;
+ UINT32 TCI0_VID:12;
+ UINT32 TCI0_CFI:1;
+ UINT32 TCI0_PCP:3;
+ } field;
+ UINT32 word;
+} HT_BSS_VLAN_STRUC, *PHT_BSS_VLAN_STRUC;
+#else
+typedef union GNU_PACKED _HT_BSS_VLAN_STRUC {
+ struct {
+ UINT32 TCI0_PCP:3;
+ UINT32 TCI0_CFI:1;
+ UINT32 TCI0_VID:12;
+ UINT32 TCI1_PCP:3;
+ UINT32 TCI1_CFI:1;
+ UINT32 TCI1_VID:12;
+ } field;
+ UINT32 word;
+} HT_BSS_VLAN_STRUC, *PHT_BSS_VLAN_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+
+// TODO: shiang-6590, following definitions are dummy and not used for RT6590, shall remove/correct these!
+#define GPIO_CTRL_CFG 0x0228
+#define PBF_MAX_PCNT 0x0408 //actually, it's the TX_MAX_PCNT
+// TODO:shiang-6590 --------------------------
+
+#define PAIRWISE_KEY_TABLE_BASE 0x8000 /* 32-byte * 256-entry = -byte */
+#define HW_KEY_ENTRY_SIZE 0x20
+
+#define PAIRWISE_IVEIV_TABLE_BASE 0xa000 /* 8-byte * 256-entry = -byte */
+#define MAC_IVEIV_TABLE_BASE 0xa000 /* 8-byte * 256-entry = -byte */
+#define HW_IVEIV_ENTRY_SIZE 8
+
+#define MAC_WCID_ATTRIBUTE_BASE 0xa800 /* 4-byte * 256-entry = -byte */
+#define HW_WCID_ATTRI_SIZE 4
+
+#define SHARED_KEY_TABLE_BASE 0xac00 /* 32-byte * 16-entry = 512-byte */
+#define SHARED_KEY_MODE_BASE 0xb000 /* 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 0xb800
+#define WAPI_PN_ENTRY_SIZE 8
+
+#define RF_MISC 0x0518
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_MISC_STRUC{
+ struct{
+ UINT32 Rsv1:29;
+ UINT32 EXT_PA_EN:1;
+ UINT32 ADDAC_LDO_ADC9_EN:1;
+ UINT32 ADDAC_LDO_ADC6_EN:1;
+ }field;
+ UINT32 word;
+}RF_MISC_STRUC, *PRF_MISC_STRUC;
+#else
+typedef union _RF_MISC_STRUC{
+ struct{
+ UINT32 ADDAC_LDO_ADC6_EN:1;
+ UINT32 ADDAC_LDO_ADC9_EN:1;
+ UINT32 EXT_PA_EN:1;
+ UINT32 Rsv1:29;
+ }field;
+ UINT32 word;
+}RF_MISC_STRUC, *PRF_MISC_STRUC;
+#endif
+
+VOID ral_wlan_chip_onoff(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN BOOLEAN bOn,
+ IN BOOLEAN bResetWLAN);
+
+#ifdef MT7601
+VOID MT7601_WLAN_ChipOnOff(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN BOOLEAN bOn,
+ IN BOOLEAN bResetWLAN);
+#endif /* MT7601 */
+
+#define AUX_CLK_CFG 0x120C
+#define BB_PA_MODE_CFG0 0x1214
+#define BB_PA_MODE_CFG1 0x1218
+#define RF_PA_MODE_CFG0 0x121C
+#define RF_PA_MODE_CFG1 0x1220
+#define TX_ALC_CFG_0 0x13B0
+#define TX_ALC_CFG_1 0x13B4
+
+#define TX0_RF_GAIN_CORR 0x13A0
+#define TX0_RF_GAIN_ATTEN 0x13A8
+#define TX0_BB_GAIN_ATTEN 0x13C0
+#define TX_ALC_VGA3 0x13C8
+
+
+#if defined(RT65xx) || defined(MT7601)
+#define RESET_CTL 0x070C
+#define INT_LEVEL 0x0718
+#define COM_REG0 0x0730
+#define COM_REG1 0x0734
+#define COM_REG2 0x0738
+#define COM_REG3 0x073C
+#define PCIE_REMAP_BASE1 0x0740
+#define PCIE_REMAP_BASE2 0x0744
+#define PCIE_REMAP_BASE3 0x0748
+#define PCIE_REMAP_BASE4 0x074C
+#define LED_CTRL 0x0770
+#define LED_TX_BLINK_0 0x0774
+#define LED_TX_BLINK_1 0x0778
+#define LED0_S0 0x077C
+#define LED0_S1 0x0780
+#define SEMAPHORE_00 0x07B0
+#endif /* RT65xx */
+#endif /* __RAL_NMAC_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pbf.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pbf.h
new file mode 100644
index 0000000000..7e85dcd498
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pbf.h
@@ -0,0 +1,139 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_nmac_pbf.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_NMAC_PBF_H__
+#define __RAL_NMAC_PBF_H__
+
+
+
+/* ================================================================================= */
+/* Register format for PBF */
+/* ================================================================================= */
+
+
+/* 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 {
+ UINT32 rsv5:7; /* Reserved */
+ UINT32 CSR_TEST_EN:1;
+ UINT32 MAC_CLKSEL:2; /* MAC clock selection */
+ UINT32 PWRSV_EN:2;
+ UINT32 SHRM_SEL:1; /* Shared memory access selection */
+ UINT32 PBF_MSEL:2; /* Packet buffer memory access selection */
+ UINT32 rsv4:5;
+ UINT32 PBF_CLK_EN:1; /* PBF clock enable */
+ UINT32 MAC_CLK_EN:1; /* MAC clock enable */
+ UINT32 rsv3:6;
+ UINT32 PBF_RESET:1; /* PBF hardware reset */
+ UINT32 MAC_RESET:1; /* MAC hardware reset */
+ UINT32 rsv:2;
+ } field;
+ UINT32 word;
+} PBF_SYS_CTRL_STRUC;
+#else
+typedef union _PBF_SYS_CTRL_STRUC{
+ struct {
+ UINT32 rsv5:7; /* Reserved */
+ UINT32 CSR_TEST_EN:1;
+ UINT32 MAC_CLKSEL:2; /* MAC clock selection */
+ UINT32 PWRSV_EN:2;
+ UINT32 SHRM_SEL:1; /* Shared memory access selection */
+ UINT32 PBF_MSEL:2; /* Packet buffer memory access selection */
+ UINT32 rsv4:5;
+ UINT32 PBF_CLK_EN:1; /* PBF clock enable */
+ UINT32 MAC_CLK_EN:1; /* MAC clock enable */
+ UINT32 rsv3:6;
+ UINT32 PBF_RESET:1; /* PBF hardware reset */
+ UINT32 MAC_RESET:1; /* MAC hardware reset */
+ UINT32 rsv:2;
+ }field;
+ UINT32 word;
+} PBF_SYS_CTRL_STRUC;
+#endif
+
+
+#define PBF_CFG 0x0404
+#define TX_MAX_PCNT 0x0408
+#define RX_MAX_PCNT 0x040c
+#define PBF_CTRL 0x0410
+#define RXQ_STA 0x0430
+#define TXQ_STA 0x0434
+
+#define BCN_OFFSET0 0x041c
+#define BCN_OFFSET1 0x0420
+#define BCN_OFFSET2 0x0424
+#define BCN_OFFSET3 0x0428
+
+
+#define FCE_CTRL 0x0800
+#define FCE_PARAM 0x0804
+#define CHECKSUM_OFFLOAD 0x0808
+
+#ifdef RT_BIG_ENDIAN
+typedef union _CSO_CTRL_STRUC {
+ struct {
+ UINT32 rsv:21;
+ UINT32 stamp_seq_num_en:1;
+ UINT32 cso_bigendian:1;
+ UINT32 cso_en:1;
+ UINT32 tx_ipv6_en:1;
+ UINT32 tx_ipv4_cs_gen:1;
+ UINT32 tx_tcp_cs_gen:1;
+ UINT32 tx_udp_cs_gen:1;
+ UINT32 rx_ipv6_en:1;
+ UINT32 rx_ipv4_cs_en:1;
+ UINT32 rx_tcp_cs_en:1;
+ UINT32 rx_udp_cs_en:1;
+ } field;
+ UINT32 word;
+} CSO_CTRL_STRUC;
+#else
+typedef union _CSO_CTRL_STRUC{
+ struct {
+ UINT32 rx_udp_cs_en:1;
+ UINT32 rx_tcp_cs_en:1;
+ UINT32 rx_ipv4_cs_en:1;
+ UINT32 rx_ipv6_en:1;
+ UINT32 tx_udp_cs_gen:1;
+ UINT32 tx_tcp_cs_gen:1;
+ UINT32 tx_ipv4_cs_gen:1;
+ UINT32 tx_ipv6_en:1;
+ UINT32 cso_en:1;
+ UINT32 cso_bigendian:1;
+ UINT32 stamp_seq_num_en:1;
+ UINT32 rsv:21;
+ }field;
+ UINT32 word;
+} CSO_CTRL_STRUC;
+#endif
+
+#endif /* __RAL_NMAC_PBF_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pci.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pci.h
new file mode 100644
index 0000000000..e6ba8c7550
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pci.h
@@ -0,0 +1,368 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ral_nmac_pci.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RAL_NMAC_PCI_H__
+#define __RAL_NMAC_PCI_H__
+
+
+
+/* INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit */
+#define INT_SOURCE_CSR 0x200
+
+
+#define INT_R0_DONE (1<<0)
+#define INT_R1_DONE (1<<1)
+#define INT_T0_DONE (1<<4)
+#define INT_T1_DONE (1<<5)
+#define INT_T2_DONE (1<<6)
+#define INT_T3_DONE (1<<7)
+#define INT_T4_DONE (1<<8)
+#define INT_T5_DONE (1<<9)
+#define INT_T6_DONE (1<<10)
+#define INT_T7_DONE (1<<11)
+#define INT_T8_DONE (1<<12)
+#define INT_T9_DONE (1<<13)
+#define INT_RESVD ((1<<14) | (1<<15))
+#define INT_RX_COHE (1<<16)
+#define INT_TX_COHE (1<<17)
+#define INT_ANY_COH (1<<18)
+#define INT_MCU_CMD (1<<19)
+#define INT_TBTT_ISR (1<<20)
+#define INT_PRE_TBTT (1<<21)
+#define INT_TX_STAT (1<<22)
+#define INT_AUTO_WAKE (1<<23)
+#define INT_GP_TIMER (1<<24)
+#define INT_RESVD_2 (1<<25)
+#define INT_RX_DLY (1<<26)
+#define INT_TX_DLY (1<<27)
+#ifdef CARRIER_DETECTION_SUPPORT
+// TODO: shiang-6590, for 6590, what's the interrupt bit for TONE_RADAR?? now just give a reseved bit
+#define RT2860_INT_TONE_RADAR (1<<29)
+#endif /* CARRIER_DETECTION_SUPPORT*/
+
+ /* Delayed Rx or indivi rx */
+#define RxINT (INT_R0_DONE | INT_R1_DONE /* | INT_RX_DLY */)
+/* Delayed Tx or indivi tx */
+#define TxDataInt (INT_T0_DONE | INT_T1_DONE | INT_T2_DONE | INT_T3_DONE /*| INT_TX_DLY*/)
+
+#ifdef RT8592
+#define TxMgmtInt (INT_T5_DONE /*| INT_TX_DLY*/)
+#else
+#define TxMgmtInt (INT_T9_DONE /*| INT_TX_DLY*/)
+#endif /* RT8592 */
+
+#define RxCoherent INT_RX_COHE
+#define TxCoherent INT_TX_COHE
+#define TxRxCoherent INT_ANY_COH
+
+/* mcu */
+#define McuCommand INT_MCU_CMD
+#define PreTBTTInt INT_PRE_TBTT
+#define TBTTInt INT_TBTT_ISR
+
+/* fifo statistics full interrupt */
+#define FifoStaFullInt INT_TX_STAT
+
+/* AutoWakeupInt interrupt */
+#define AutoWakeupInt INT_AUTO_WAKE
+
+/* GPtimeout interrupt */
+#define GPTimeOutInt INT_GP_TIMER
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define RadarInt (RT2860_INT_TONE_RADAR)
+#endif /* CARRIER_DETECTION_SUPPORT*/
+
+#define INT_RX (INT_R0_DONE | INT_R1_DONE)
+
+#define INT_AC0_DLY (INT_T0_DONE)
+#define INT_AC1_DLY (INT_T1_DONE)
+#define INT_AC2_DLY (INT_T2_DONE)
+#define INT_AC3_DLY (INT_T3_DONE)
+#ifdef RT8592
+#define INT_HCCA_DLY (INT_T4_DONE)
+#define INT_MGMT_DLY (INT_T5_DONE)
+#else
+#define INT_HCCA_DLY (INT_T8_DONE)
+#define INT_MGMT_DLY (INT_T9_DONE)
+#endif /* RT8592 */
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define INT_TONE_RADAR (RT2860_INT_TONE_RADAR)
+#endif /* CARRIER_DETECTION_SUPPORT*/
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define DELAYINTMASK (0x0DFF3FF3 | (RadarInt))
+#define INTMASK (0x0DFF3FF3 | (RadarInt))
+#else
+#define DELAYINTMASK 0x0DFF3FF3
+#define INTMASK 0x0DFF3FF3
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _INT_SOURCE_CSR_STRUC {
+ struct {
+ UINT32 rsv1:4;
+ UINT32 TxDelayINT:1;
+ UINT32 RxDelayINT:1;
+ UINT32 rsv2:1;
+ UINT32 GPTimer:1;
+ UINT32 AutoWakeup:1;
+ UINT32 TXFifoStatusInt:1;
+ UINT32 PreTBTT:1;
+ UINT32 tbttInt:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 trCoherent:1;
+ UINT32 txCoherent:1;
+ UINT32 rxCoherent:1;
+ UINT32 rsv3:2;
+ UINT32 TxDone9:1;
+ UINT32 TxDone8:1;
+ UINT32 TxDone7:1;
+ UINT32 TxDone6:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 rsv4:2;
+ UINT32 RxDone1:1;
+ UINT32 RxDone:1;
+ }field;
+ UINT32 word;
+}INT_SOURCE_CSR_STRUC;
+#else
+typedef union _INT_SOURCE_CSR_STRUC {
+ struct {
+ UINT32 RxDone:1;
+ UINT32 RxDone1:1;
+ UINT32 rsv4:2;
+ UINT32 Ac0DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 TxDone6:1;
+ UINT32 TxDone7:1;
+ UINT32 TxDone8:1;
+ UINT32 TxDone9:1;
+ UINT32 rsv3:2;
+ UINT32 rxCoherent:1;
+ UINT32 txCoherent:1;
+ UINT32 trCoherent:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 tbttInt:1;
+ UINT32 PreTBTT:1;
+ UINT32 TXFifoStatusInt:1;
+ UINT32 AutoWakeup:1;
+ UINT32 GPTimer:1;
+ UINT32 rsv2:1;
+ UINT32 RxDelayINT:1;
+ UINT32 TxDelayINT:1;
+ UINT32 rsv1:4;
+ }field;
+ UINT32 word;
+}INT_SOURCE_CSR_STRUC;
+#endif /* RT_BIG_ENDIAN */
+
+
+/* INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF */
+#define INT_MASK_CSR 0x204
+#ifdef RT_BIG_ENDIAN
+typedef union _PDMA_INT_MASK{
+ struct {
+ UINT32 rsv1:4;
+ UINT32 TxDelayINT:1;
+ UINT32 RxDelayINT:1;
+ UINT32 rsv2:1;
+ UINT32 GPTimer:1;
+ UINT32 AutoWakeup:1;
+ UINT32 TXFifoStatusInt:1;
+ UINT32 PreTBTT:1;
+ UINT32 tbttInt:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 trCoherent:1;
+ UINT32 txCoherent:1;
+ UINT32 rxCoherent:1;
+ UINT32 rsv3:2;
+ UINT32 TxDone9:1;
+ UINT32 TxDone8:1;
+ UINT32 TxDone7:1;
+ UINT32 TxDone6:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 rsv4:2;
+ UINT32 RxDone1:1;
+ UINT32 RxDone:1;
+ }field;
+ UINT32 word;
+}PMDA_INT_MASK;
+#else
+typedef union _PDMA_INT_MASK{
+ struct {
+ UINT32 RxDone:1;
+ UINT32 RxDone1:1;
+ UINT32 rsv4:2;
+ UINT32 Ac0DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 TxDone6:1;
+ UINT32 TxDone7:1;
+ UINT32 TxDone8:1;
+ UINT32 TxDone9:1;
+ UINT32 rsv3:2;
+ UINT32 rxCoherent:1;
+ UINT32 txCoherent:1;
+ UINT32 trCoherent:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 tbttInt:1;
+ UINT32 PreTBTT:1;
+ UINT32 TXFifoStatusInt:1;
+ UINT32 AutoWakeup:1;
+ UINT32 GPTimer:1;
+ UINT32 rsv2:1;
+ UINT32 RxDelayINT:1;
+ UINT32 TxDelayINT:1;
+ UINT32 rsv1:4;
+ }field;
+ UINT32 word;
+}PMDA_INT_MASK;
+#endif /* RT_BIG_ENDIAN */
+
+
+/*
+ Tx Ring Layout and assignments
+
+ Totally we have 10 Tx Rings and assigned as following usage:
+ 1. RT85592
+ TxRing 0~3: for TxQ Channel 1 with AC_BK/BE/VI/VO
+ TxRing 4 : for TxQ CTRL
+ TxRing 5 : for TxQ MGMT
+ TxRing 6~9: for TxQ Channel 2 with AC_BK/BE/VI/VO
+
+ 2. MT7650
+ TxRing 0~3: for TxQ Channel 1 with AC_BK/BE/VI/VO
+ TxRing 4~7: for TxQ Channel 2 with AC_BK/BE/VI/VO
+ TxRing 8 : for TxQ CTRL
+ TxRing 9 : for TxQ MGMT
+
+ For each TxRing, we have four register to control it
+ TX_RINGn_CTRL0 (0x0): base address of this ring(4-DWORD aligned address)
+ TX_RINGn_CTRL1 (0x4): maximum number of TxD count in this ring
+ TX_RINGn_CTRL2 (0x8): Point to the next TxD CPU wants to use
+ TX_RINGn_CTRL3 (0xc): Point to the next TxD DMA wants to use
+
+*/
+#define RINGREG_DIFF 0x10
+#define TX_RING_BASE 0x0300
+#define TX_RING_NUM 10
+#define TX_RING_PTR 0x0300
+#define TX_RING_CNT 0x0304
+#define TX_RING_CIDX 0x0308
+#define TX_RING_DIDX 0x030c
+
+#ifdef RT8592
+#define TX_MGMT_BASE (TX_RING_BASE + RINGREG_DIFF * 5)
+#else
+/* Mgmt Tx Ring registers */
+#define TX_MGMT_BASE (TX_RING_BASE + RINGREG_DIFF * 9)
+#endif /* RT8592 */
+#define TX_MGMT_CNT (TX_MGMT_BASE + 0x04)
+#define TX_MGMT_CIDX (TX_MGMT_BASE + 0x08)
+#define TX_MGMT_DIDX (TX_MGMT_BASE + 0x0c)
+
+#ifdef RT8592
+#define TX_CTRL_BASE (TX_RING_BASE + RINGREG_DIFF * 4)
+#else
+/* Mgmt Tx Ring registers */
+#define TX_CTRL_BASE (TX_RING_BASE + RINGREG_DIFF * 8)
+#endif /* RT8592 */
+#define TX_CTRL_CNT (TX_CTRL_BASE + 0x04)
+#define TX_CTRL_CIDX (TX_CTRL_BASE + 0x08)
+#define TX_CTRL_DIDX (TX_CTRL_BASE + 0x0c)
+
+
+#define TX_CHAN_BASE_1 (TX_RING_BASE + RINGREG_DIFF * 0)
+#define TX_CHAN_BASE_2 (TX_RING_BASE + RINGREG_DIFF * 6)
+
+/* following address is base on TX_CHAN_BASE_X */
+#define TX_RING_BK_BASE 0x0
+#define TX_RING_BK_CNT (TX_RING_BK_BASE + 0x04)
+#define TX_RING_BK_CIDX (TX_RING_BK_BASE + 0x08)
+#define TX_RING_BK_DIDX (TX_RING_BK_BASE + 0x0c)
+
+#define TX_RING_BE_BASE (TX_RING_BK_BASE + RINGREG_DIFF)
+#define TX_RING_BE_CNT (TX_RING_BE_BASE + 0x04)
+#define TX_RING_BE_CIDX (TX_RING_BE_BASE + 0x08)
+#define TX_RING_BE_DIDX (TX_RING_BE_BASE + 0x0c)
+
+#define TX_RING_VI_BASE (TX_RING_BE_BASE + RINGREG_DIFF)
+#define TX_RING_VI_CNT (TX_RING_VI_BASE + 0x04)
+#define TX_RING_VI_CIDX (TX_RING_VI_BASE + 0x08)
+#define TX_RING_VI_DIDX (TX_RING_VI_BASE + 0x0c)
+
+#define TX_RING_VO_BASE (TX_RING_VI_BASE + RINGREG_DIFF)
+#define TX_RING_VO_CNT (TX_RING_VO_BASE + 0x04)
+#define TX_RING_VO_CIDX (TX_RING_VO_BASE + 0x08)
+#define TX_RING_VO_DIDX (TX_RING_VO_BASE + 0x0c)
+
+
+/*
+ Rx Ring Layput and assignments
+
+ Totally we have 2 Rx Rings and assigned as following usage:
+ RxRing 0: for all received data packets
+ RxRing 1: for internal ctrl/info packets generated by on-chip CPU.
+
+ For each TxRing, we have four register to control it
+ RX_RING_CTRL0 (0x0): base address of this ring(4-DWORD aligned address)
+ RX_RING_CTRL1 (0x4): maximum number of RxD count in this ring
+ RX_RING_CTRL2 (0x8): Point to the next RxD CPU wants to use
+ RX_RING_CTRL3 (0xc): Point to the next RxD DMA wants to use
+*/
+#define RX_RING_BASE 0x03c0
+#define RX_RING_NUM 2
+#define RX_RING_PTR RX_RING_BASE
+#define RX_RING_CNT (RX_RING_BASE + 0x04)
+#define RX_RING_CIDX (RX_RING_BASE + 0x08)
+#define RX_RING_DIDX (RX_RING_BASE + 0x0c)
+#define RX_CTRL_BASE (RX_RING_BASE + RINGREG_DIFF)
+#define RX_CTRL_PTR RX_CTRL_BASE
+#define RX_CTRL_CNT (RX_CTRL_BASE + 0x04)
+#define RX_CTRL_CIDX (RX_CTRL_BASE + 0x08)
+#define RX_CTRL_DIDX (RX_CTRL_BASE + 0x0c)
+
+#endif /*__RAL_NMAC_PCI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_rxwi.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_rxwi.h
new file mode 100644
index 0000000000..9d1c62887a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_rxwi.h
@@ -0,0 +1,117 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_nmac_rxwi.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_NMAC_RXWI_H__
+#define __RAL_NMAC_RXWI_H__
+
+#include "rtmp_type.h"
+
+/*
+ RXWI wireless information format.
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXWI_NMAC{
+ /* Word 0 */
+ UINT32 eof:1;
+ UINT32 rsv:1;
+ UINT32 MPDUtotalByteCnt:14;
+ UINT32 udf:3;
+ UINT32 bss_idx:3;
+ UINT32 key_idx:2;
+ UINT32 wcid:8;
+
+ /* Word 1 */
+ UINT32 phy_mode:3;
+ UINT32 i_txbf:1;
+ UINT32 e_txbf:1;
+ UINT32 stbc:1;
+ UINT32 sgi:1;
+ UINT32 bw:2;
+ UINT32 mcs:7;
+ UINT32 sn:12;
+ UINT32 tid:4;
+
+ /* Word 2 */
+ UINT8 rssi[4];
+
+ /* Word 3~6 */
+ UINT8 bbp_rxinfo[16];
+} RXWI_NMAC;
+#else
+typedef struct GNU_PACKED _RXWI_NMAC {
+ /* Word 0 */
+ UINT32 wcid:8;
+ UINT32 key_idx:2;
+ UINT32 bss_idx:3;
+ UINT32 udf:3;
+ UINT32 MPDUtotalByteCnt:14;
+ UINT32 rsv:1;
+ UINT32 eof:1;
+
+ /* Word 1 */
+ UINT32 tid:4;
+ UINT32 sn:12;
+ UINT32 mcs:7;
+ UINT32 bw:2;
+ UINT32 sgi:1;
+ UINT32 stbc:1;
+ UINT32 e_txbf:1;
+ UINT32 i_txbf:1;
+ UINT32 phy_mode:3;
+
+ /* Word 2 */
+ UINT8 rssi[4];
+
+ /* Word 3~6 */
+ UINT8 bbp_rxinfo[16];
+} RXWI_NMAC;
+#endif /* RT_BIG_ENDIAN */
+
+
+#define RxWIMPDUByteCnt RXWI_N.MPDUtotalByteCnt
+#define RxWIWirelessCliID RXWI_N.wcid
+#define RxWIKeyIndex RXWI_N.key_idx
+#define RxWIMCS RXWI_N.mcs
+#define RxWIBW RXWI_N.bw
+#define RxWIBSSID RXWI_N.bss_idx
+#define RxWISGI RXWI_N.sgi
+#define RxWIPhyMode RXWI_N.phy_mode
+#define RxWISTBC RXWI_N.stbc
+#define RxWITID RXWI_N.tid
+#define RxWIRSSI0 RXWI_N.rssi[0]
+#define RxWIRSSI1 RXWI_N.rssi[1]
+#define RxWIRSSI2 RXWI_N.rssi[2]
+#define RxWISNR0 RXWI_N.bbp_rxinfo[0]
+#define RxWISNR1 RXWI_N.bbp_rxinfo[1]
+#define RxWISNR2 RXWI_N.bbp_rxinfo[2]
+#define RxWIFOFFSET RXWI_N.bbp_rxinfo[3]
+
+
+
+#endif /* __RAL_NMAC_RXWI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_txwi.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_txwi.h
new file mode 100644
index 0000000000..cb07fdf280
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_txwi.h
@@ -0,0 +1,249 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_nmac_txwi.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_NMAC_TXWI_H__
+#define __RAL_NMAC_TXWI_H__
+
+#include "rtmp_type.h"
+
+
+
+#ifdef RT65xx
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _TXWI_NMAC {
+ /* Word 0 */
+ UINT32 PHYMODE:3;
+ UINT32 iTxBF:1;
+ UINT32 eTxBF:1;
+ UINT32 STBC:1;
+ UINT32 ShortGI:1;
+ UINT32 BW:2; /* channel bandwidth 20/40/80 MHz */
+ UINT32 MCS:7;
+
+ UINT32 rsv0:2;
+ UINT32 Sounding:1;
+ UINT32 NDPSndBW:1; /* NDP sounding BW */
+ UINT32 NDPSndRate:2; /* 0 : MCS0, 1: MCS8, 2: MCS16, 3: reserved */
+ UINT32 txop:2;
+
+ 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 Rsv1:2;
+ UINT32 MPDUtotalByteCnt:14;
+ UINT32 wcid:8;
+ UINT32 BAWinSize:6;
+ UINT32 NSEQ:1;
+ UINT32 ACK:1;
+
+ /* Word 2 */
+ UINT32 IV;
+ /* Word 3 */
+ UINT32 EIV;
+
+ /* Word 4 */
+ UINT32 TxPktId:8;
+ UINT32 Rsv4:4;
+ UINT32 TxPwrAdj:4;
+ UINT32 TxStreamMode:8;
+ UINT32 TxEAPId:8;
+} TXWI_NMAC, *PTXWI_NMAC;
+#else
+typedef struct GNU_PACKED _TXWI_NMAC {
+ /* 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;
+ UINT32 NDPSndRate:2; /* 0 : MCS0, 1: MCS8, 2: MCS16, 3: reserved */
+ UINT32 NDPSndBW:1; /* NDP sounding BW */
+ UINT32 Sounding:1;
+ UINT32 rsv0:2;
+
+ UINT32 MCS:7;
+ UINT32 BW:2; /*channel bandwidth 20/40/80 MHz */
+ UINT32 ShortGI:1;
+ UINT32 STBC:1;
+ UINT32 eTxBF:1;
+ UINT32 iTxBF:1;
+ UINT32 PHYMODE:3;
+
+ /* Word1 */
+ /* ex: 1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCnt = 0x38 */
+ UINT32 ACK:1;
+ UINT32 NSEQ:1;
+ UINT32 BAWinSize:6;
+ UINT32 wcid:8;
+ UINT32 MPDUtotalByteCnt:14;
+ UINT32 Rsv1:2;
+
+ /*Word2 */
+ UINT32 IV;
+
+ /*Word3 */
+ UINT32 EIV;
+
+ /* Word 4 */
+ UINT32 TxEAPId:8;
+ UINT32 TxStreamMode:8;
+ UINT32 TxPwrAdj:4;
+ UINT32 Rsv4:4;
+ UINT32 TxPktId:8;
+} TXWI_NMAC, *PTXWI_NMAC;
+#endif /* RT_BIG_ENDIAN */
+#else
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _TXWI_NMAC {
+ /* Word 0 */
+ UINT32 PHYMODE:2;
+ UINT32 Rsv1:3;
+ UINT32 STBC:2;
+ UINT32 ShortGI:1;
+ UINT32 BW:1;
+ UINT32 MCS:7;
+
+ UINT32 TXLUT:1;
+ UINT32 TXRPT:1;
+ UINT32 Autofallback:1; /* TX rate auto fallback disable */
+ UINT32 CWMIN:3;
+ UINT32 txop:2;
+
+ 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 TxPktId:4;
+ UINT32 MPDUtotalByteCnt:12;
+ UINT32 wcid:8;
+ UINT32 BAWinSize:6;
+ UINT32 NSEQ:1;
+ UINT32 ACK:1;
+
+ /* Word 2 */
+ UINT32 IV;
+ /* Word 3 */
+ UINT32 EIV;
+
+ /* Word 4 */
+ UINT32 Rsv3:9;
+ UINT32 PIFS_REV:1;
+ UINT32 Rsv2:1;
+ UINT32 CCP:1; /* Channel Check Packet */
+ UINT32 TxPwrAdj:4;
+ UINT32 TxStreamMode:8;
+ UINT32 TxEAPId:8;
+} TXWI_NMAC, *PTXWI_NMAC;
+#else
+typedef struct GNU_PACKED _TXWI_NMAC {
+ /* 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;
+ UINT32 CWMIN:3;
+ UINT32 Autofallback:1; /* TX rate auto fallback disable */
+ UINT32 TXRPT:1;
+ UINT32 TXLUT:1;
+
+ UINT32 MCS:7;
+ UINT32 BW:1;
+ UINT32 ShortGI:1;
+ UINT32 STBC:2;
+ UINT32 Rsv1:3;
+ UINT32 PHYMODE:2;
+
+ /* Word1 */
+ /* ex: 1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCnt = 0x38 */
+ UINT32 ACK:1;
+ UINT32 NSEQ:1;
+ UINT32 BAWinSize:6;
+ UINT32 wcid:8;
+ UINT32 MPDUtotalByteCnt:12;
+ UINT32 TxPktId:4;
+
+ /*Word2 */
+ UINT32 IV;
+
+ /*Word3 */
+ UINT32 EIV;
+
+ /* Word 4 */
+ UINT32 TxEAPId:8;
+ UINT32 TxStreamMode:8;
+ UINT32 TxPwrAdj:4;
+ UINT32 CCP:1; /* Channel Check Packet */
+ UINT32 Rsv2:1;
+ UINT32 PIFS_REV:1;
+ UINT32 Rsv3:9;
+} TXWI_NMAC, *PTXWI_NMAC;
+#endif /* RT_BIG_ENDIAN */
+#endif /* RT65xx */
+
+#define TxWIMPDUByteCnt TXWI_N.MPDUtotalByteCnt
+#define TxWIWirelessCliID TXWI_N.wcid
+#define TxWIFRAG TXWI_N.FRAG
+#define TxWICFACK TXWI_N.CFACK
+#define TxWITS TXWI_N.TS
+#define TxWIAMPDU TXWI_N.AMPDU
+#define TxWIACK TXWI_N.ACK
+#define TxWITXOP TXWI_N.txop
+#define TxWINSEQ TXWI_N.NSEQ
+#define TxWIBAWinSize TXWI_N.BAWinSize
+#define TxWIShortGI TXWI_N.ShortGI
+#define TxWISTBC TXWI_N.STBC
+#define TxWIPacketId TXWI_N.TxPktId
+#define TxWIBW TXWI_N.BW
+#define TxWIMCS TXWI_N.MCS
+#define TxWIPHYMODE TXWI_N.PHYMODE
+#define TxWIMIMOps TXWI_N.MIMOps
+#define TxWIMpduDensity TXWI_N.MpduDensity
+#define TxWITXRPT TXWI_N.TXRPT
+#define TxWITXLUT TXWI_N.TXLUT
+
+
+#endif /* __RAL_NMAC_TXWI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_usb.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_usb.h
new file mode 100644
index 0000000000..cdaeef5241
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_usb.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ral_omac_usb.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RAL_OMAC_USB_H__
+#define __RAL_OMAC_USB_H__
+#define CMB_CTRL 0x20
+#ifdef RT_BIG_ENDIAN
+typedef union _CMB_CTRL_STRUC{
+ struct{
+ UINT32 LDO0_EN:1;
+ UINT32 LDO3_EN:1;
+ UINT32 LDO_BGSEL:2;
+ UINT32 LDO_CORE_LEVEL:4;
+ UINT32 PLL_LD:1;
+ UINT32 XTAL_RDY:1;
+ UINT32 Rsv:2;
+ UINT32 LDO25_FRC_ON:1;//4
+ UINT32 LDO25_LARGEA:1;
+ UINT32 LDO25_LEVEL:2;
+ UINT32 AUX_OPT_Bit15_Two_AntennaMode:1;
+ UINT32 AUX_OPT_Bit14_TRSW1_as_GPIO:1;
+ UINT32 AUX_OPT_Bit13_GPIO7_as_GPIO:1;
+ UINT32 AUX_OPT_Bit12_TRSW0_as_WLAN_ANT_SEL:1;
+ UINT32 AUX_OPT_Bit11_Rsv:1;
+ UINT32 AUX_OPT_Bit10_NotSwap_WL_LED_ACT_RDY:1;
+ UINT32 AUX_OPT_Bit9_GPIO3_as_GPIO:1;
+ UINT32 AUX_OPT_Bit8_AuxPower_Exists:1;
+ UINT32 AUX_OPT_Bit7_KeepInterfaceClk:1;
+ UINT32 AUX_OPT_Bit6_KeepXtal_On:1;
+ UINT32 AUX_OPT_Bit5_RemovePCIePhyClk_BTOff:1;
+ UINT32 AUX_OPT_Bit4_RemovePCIePhyClk_WLANOff:1;
+ UINT32 AUX_OPT_Bit3_PLLOn_L1:1;
+ UINT32 AUX_OPT_Bit2_PCIeCoreClkOn_L1:1;
+ UINT32 AUX_OPT_Bit1_PCIePhyClkOn_L1:1;
+ UINT32 AUX_OPT_Bit0_InterfaceClk_40Mhz:1;
+ }field;
+ UINT32 word;
+}CMB_CTRL_STRUC, *PCMB_CTRL_STRUC;
+#else
+typedef union _CMB_CTRL_STRUC{
+ struct{
+ UINT32 AUX_OPT_Bit0_InterfaceClk_40Mhz:1;
+ UINT32 AUX_OPT_Bit1_PCIePhyClkOn_L1:1;
+ UINT32 AUX_OPT_Bit2_PCIeCoreClkOn_L1:1;
+ UINT32 AUX_OPT_Bit3_PLLOn_L1:1;
+ UINT32 AUX_OPT_Bit4_RemovePCIePhyClk_WLANOff:1;
+ UINT32 AUX_OPT_Bit5_RemovePCIePhyClk_BTOff:1;
+ UINT32 AUX_OPT_Bit6_KeepXtal_On:1;
+ UINT32 AUX_OPT_Bit7_KeepInterfaceClk:1;
+ UINT32 AUX_OPT_Bit8_AuxPower_Exists:1;
+ UINT32 AUX_OPT_Bit9_GPIO3_as_GPIO:1;
+ UINT32 AUX_OPT_Bit10_NotSwap_WL_LED_ACT_RDY:1;
+ UINT32 AUX_OPT_Bit11_Rsv:1;
+ UINT32 AUX_OPT_Bit12_TRSW0_as_WLAN_ANT_SEL:1;
+ UINT32 AUX_OPT_Bit13_GPIO7_as_GPIO:1;
+ UINT32 AUX_OPT_Bit14_TRSW1_as_GPIO:1;
+ UINT32 AUX_OPT_Bit15_Two_AntennaMode:1;
+ UINT32 LDO25_LEVEL:2;
+ UINT32 LDO25_LARGEA:1;
+ UINT32 LDO25_FRC_ON:1;//4
+ UINT32 Rsv:2;
+ UINT32 XTAL_RDY:1;
+ UINT32 PLL_LD:1;
+ UINT32 LDO_CORE_LEVEL:4;
+ UINT32 LDO_BGSEL:2;
+ UINT32 LDO3_EN:1;
+ UINT32 LDO0_EN:1;
+ }field;
+ UINT32 word;
+}CMB_CTRL_STRUC, *PCMB_CTRL_STRUC;
+#endif
+
+
+
+
+#define USB_DMA_CFG 0x0238
+#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:3; /*OUT endpoint data valid. debug only */
+ UINT32 rsv3:1;
+ UINT32 UDMA_RX_WL_DROP:1; /* Drop current WL RX packets in UDMA */
+ UINT32 rsv2:1;
+ 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 rsv1: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 rsv1: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 rsv2:1;
+ UINT32 UDMA_RX_WL_DROP:1; /* Drop current WL RX packets in UDMA */
+ UINT32 rsv3:1;
+ UINT32 EpoutValid:3; /*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
+
+#endif /*__RAL_OMAC_USB_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac.h
new file mode 100644
index 0000000000..ef54a7fdc5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac.h
@@ -0,0 +1,168 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_omac.h
+
+ Abstract:
+ Ralink Wireless Chip RAL MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_OMAC_H__
+#define __RAL_OMAC_H__
+
+#include "rtmp_type.h"
+
+#include "mac_ral/omac/ral_omac_txwi.h"
+#include "mac_ral/omac/ral_omac_rxwi.h"
+
+/*
+ TXINFO
+*/
+
+/*
+ TXINFO fields defintion:
+
+ USBDMATxPktLen[b0~b14]:
+ Total bytes of all sub-frame. ONLY for USB bulk Aggregation
+ IPOffset[b15~b18]:
+ Start byte of IP packet. The base address is from TXINFO.
+ 0: header will be parsed by hardware.
+ This field is like backdoor.
+ For AMSDU, this field is useless
+
+ TCPOffset[b19~b23]:
+ Start byte of TCP packet from IP packet The base address is IP header.
+ 0: header will be parsed by hardware.
+ This field is like backdoor.
+ For AMSDU, this field is useless
+
+ WIV[b24]:
+ Wireless Info Valid.
+ 1: if Driver already fill WI
+ 0: if DMA needs to copy WI to correctposition
+
+ QSEL[b25~b26]:
+ Select on-chip FIFO ID for 2nd-stage output scheduler.
+ 0:MGMT, 1:HCCA 2:EDCA
+
+ SwUseLastRound[b27]:
+ Software used for USB-based chipset, reserved for other interfaces.
+
+ uso[b28]:
+ UDP checksum enable.
+ 1: indicate this packet needs to do UDP checksum
+
+ cso[b29]:
+ Checksum offload.
+ 1: indicate this packet needs to do checksum
+
+ USBDMANextVLD[b30]:
+ Used for USB-based chipset, reserved for other interfaces.
+ Used ONLY in USB bulk Aggregation, host driver info DMA current
+ frame is not he last frame in current Tx queue
+
+ USBDMATxburst[b31]:
+ force DMA transmit frame from current selected endpoint
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct _TXINFO_OMAC {
+ UINT32 USBDMATxburst:1;
+ UINT32 USBDMANextVLD:1;
+ UINT32 cso:1;
+ UINT32 uso:1;
+#ifdef USB_BULK_BUF_ALIGMENT
+ UINT32 bFragLasAlignmentsectiontRound:1;
+#else
+ UINT32 SwUseLastRound:1;
+#endif /* USB_BULK_BUF_ALIGMENT */
+ UINT32 QSEL:2;
+ UINT32 WIV:1;
+ UINT32 TCPOffset:5;
+ UINT32 IPOffset:4;
+ UINT32 USBDMATxPktLen:15;
+}TXINFO_OMAC;
+#else
+typedef struct _TXINFO_OMAC {
+ UINT32 USBDMATxPktLen:15;
+ UINT32 IPOffset:4;
+ UINT32 TCPOffset:5;
+ UINT32 WIV:1;
+ UINT32 QSEL:2;
+#ifdef USB_BULK_BUF_ALIGMENT
+ UINT32 bFragLasAlignmentsectiontRound:1;
+#else
+ UINT32 SwUseLastRound:1;
+#endif /* USB_BULK_BUF_ALIGMENT */
+ UINT32 uso:1;
+ UINT32 cso:1;
+ UINT32 USBDMANextVLD:1;
+ UINT32 USBDMATxburst:1;
+}TXINFO_OMAC;
+#endif /* RT_BIG_ENDIAN */
+
+
+#define TxInfoWIV txinfo_omac.WIV
+#define TxInfoQSEL txinfo_omac.QSEL
+#define TxInfoPktLen txinfo_omac.USBDMATxPktLen
+#define TxInfoSwLstRnd txinfo_omac.SwUseLastRound
+#define TxInfoUDMATxburst txinfo_omac.USBDMATxburst
+#define TxInfoUDMANextVld txinfo_omac.USBDMANextVLD
+#define TxInfoIPOffset txinfo_omac.IPOffset
+#define TxInfoTCPOffset txinfo_omac.TCPOffset
+#define TxInfoCSO txinfo_omac.cso
+#define TxInfoUSO txinfo_omac.uso
+
+
+
+
+/* ================================================================================= */
+/* Register format */
+/* ================================================================================= */
+
+#define GPIO_CTRL_CFG 0x0228
+#define MCU_CMD_CFG 0x022c
+
+
+#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 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
+
+#endif /* __RAL_OMAC_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pbf.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pbf.h
new file mode 100644
index 0000000000..46da17caa3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pbf.h
@@ -0,0 +1,104 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_omac_pbf.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_OMAC_PBF_H__
+#define __RAL_OMAC_PBF_H__
+
+
+#include "rtmp_type.h"
+
+/* ================================================================================= */
+/* Register format for PBF */
+/* ================================================================================= */
+
+
+/* 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 {
+ UINT32 Reserved5:12; /* Reserved */
+ UINT32 SHR_MSEL:1; /* Shared memory access selection */
+ UINT32 PBF_MSEL:2; /* Packet buffer memory access selection */
+ UINT32 HST_PM_SEL:1; /* The write selection of the host program RAM */
+ UINT32 Reserved4:1; /* Reserved */
+ UINT32 CAP_MODE:1; /* Packet buffer capture mode */
+ UINT32 Reserved3:1; /* Reserved */
+ UINT32 CLK_SEL:1; /* MAC/PBF clock source selection */
+ UINT32 PBF_CLK_EN:1; /* PBF clock enable */
+ UINT32 MAC_CLK_EN:1; /* MAC clock enable */
+ UINT32 DMA_CLK_EN:1; /* DMA clock enable */
+ UINT32 Reserved2:1; /* Reserved */
+ UINT32 MCU_READY:1; /* MCU ready */
+ UINT32 Reserved1:2; /* Reserved */
+ UINT32 ASY_RESET:1; /* ASYNC interface reset */
+ UINT32 PBF_RESET:1; /* PBF hardware reset */
+ UINT32 MAC_RESET:1; /* MAC hardware reset */
+ UINT32 DMA_RESET:1; /* DMA hardware reset */
+ UINT32 MCU_RESET:1; /* MCU hardware reset */
+ } field;
+ UINT32 word;
+} PBF_SYS_CTRL_STRUC;
+#else
+typedef union _PBF_SYS_CTRL_STRUC {
+ struct {
+ UINT32 MCU_RESET:1;
+ UINT32 DMA_RESET:1;
+ UINT32 MAC_RESET:1;
+ UINT32 PBF_RESET:1;
+ UINT32 ASY_RESET:1;
+ UINT32 Reserved1:2;
+ UINT32 MCU_READY:1;
+ UINT32 Reserved2:1;
+ UINT32 DMA_CLK_EN:1;
+ UINT32 MAC_CLK_EN:1;
+ UINT32 PBF_CLK_EN:1;
+ UINT32 CLK_SEL:1;
+ UINT32 Reserved3:1;
+ UINT32 CAP_MODE:1;
+ UINT32 Reserved4:1;
+ UINT32 HST_PM_SEL:1;
+ UINT32 PBF_MSEL:2;
+ UINT32 SHR_MSEL:1;
+ UINT32 Reserved5:12;
+ }field;
+ UINT32 word;
+} PBF_SYS_CTRL_STRUC;
+#endif
+
+
+#define PBF_CFG 0x0408
+#define PBF_MAX_PCNT 0x040C
+#define PBF_CAP_CTRL 0x0440
+
+#define BCN_OFFSET0 0x042C
+#define BCN_OFFSET1 0x0430
+
+#endif /* __RAL_OMAC_PBF_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pci.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pci.h
new file mode 100644
index 0000000000..bf8d9e4a3a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pci.h
@@ -0,0 +1,270 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ral_omac_pci.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RAL_OMAC_PCI_H__
+#define __RAL_OMAC_PCI_H__
+
+
+/* INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit */
+#define INT_SOURCE_CSR 0x200
+
+#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 */
+
+
+
+#define RT2860_INT_RX_DLY (1<<0) /* bit 0 */
+#define RT2860_INT_TX_DLY (1<<1) /* bit 1 */
+#define RT2860_INT_RX_DONE (1<<2) /* bit 2 */
+#define RT2860_INT_AC0_DMA_DONE (1<<3) /* bit 3 */
+#define RT2860_INT_AC1_DMA_DONE (1<<4) /* bit 4 */
+#define RT2860_INT_AC2_DMA_DONE (1<<5) /* bit 5 */
+#define RT2860_INT_AC3_DMA_DONE (1<<6) /* bit 6 */
+#define RT2860_INT_HCCA_DMA_DONE (1<<7) /* bit 7 */
+#define RT2860_INT_MGMT_DONE (1<<8) /* bit 8 */
+#ifdef CARRIER_DETECTION_SUPPORT
+#define RT2860_INT_TONE_RADAR (1<<20) /* bit 20 */
+#endif /* CARRIER_DETECTION_SUPPORT*/
+
+#define INT_RX RT2860_INT_RX_DONE
+
+#define INT_AC0_DLY (RT2860_INT_AC0_DMA_DONE) /*| RT2860_INT_TX_DLY) */
+#define INT_AC1_DLY (RT2860_INT_AC1_DMA_DONE) /*| RT2860_INT_TX_DLY) */
+#define INT_AC2_DLY (RT2860_INT_AC2_DMA_DONE) /*| RT2860_INT_TX_DLY) */
+#define INT_AC3_DLY (RT2860_INT_AC3_DMA_DONE) /*| RT2860_INT_TX_DLY) */
+#define INT_HCCA_DLY (RT2860_INT_HCCA_DMA_DONE) /*| RT2860_INT_TX_DLY) */
+#define INT_MGMT_DLY RT2860_INT_MGMT_DONE
+#ifdef CARRIER_DETECTION_SUPPORT
+#define INT_TONE_RADAR (RT2860_INT_TONE_RADAR)
+#endif /* CARRIER_DETECTION_SUPPORT*/
+
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define DELAYINTMASK 0x0013fffb
+#define INTMASK 0x0013fffb
+#define IndMask 0x0013fffc
+#define RadarInt 0x00100000
+#else
+#define DELAYINTMASK 0x0003fffb
+#define INTMASK 0x0003fffb
+#define IndMask 0x0003fffc
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _INT_SOURCE_CSR_STRUC {
+ struct {
+#ifdef CARRIER_DETECTION_SUPPORT
+ UINT32 :11;
+ UINT32 RadarINT:1;
+ UINT32 rsv:2;
+#else /* original source code */
+ UINT32 :14;
+#endif /* CARRIER_DETECTION_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;
+#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 CARRIER_DETECTION_SUPPORT
+ UINT32 rsv:2;
+ UINT32 RadarINT:1;
+ UINT32 :11;
+#else
+ UINT32 :14;
+#endif /* CARRIER_DETECTION_SUPPORT */
+ } field;
+ UINT32 word;
+} INT_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 CARRIER_DETECTION_SUPPORT
+ UINT32 :9;
+ UINT32 RadarINT:1;
+ UINT32 rsv:10;
+#else
+ UINT32 :20;
+#endif /* CARRIER_DETECTION_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 CARRIER_DETECTION_SUPPORT
+ UINT32 rsv:10;
+ UINT32 RadarINT:1;
+ UINT32 :9;
+#else
+ UINT32 :20;
+#endif /* CARRIER_DETECTION_SUPPORT */
+ UINT32 RxCoherent:1;
+ UINT32 TxCoherent:1;
+ } field;
+ UINT32 word;
+} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+#endif
+
+
+#define RINGREG_DIFF 0x10
+#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 US_CYC_CNT 0x02a4
+#ifdef BIG_ENDIAN
+typedef union _US_CYC_CNT_STRUC {
+ struct {
+ UINT32 rsv2:7;
+ UINT32 TestEn:1;
+ UINT32 TestSel:8;
+ UINT32 rsv1:7;
+ UINT32 MiscModeEn:1;
+ UINT32 UsCycCnt:8;
+ } field;
+ UINT32 word;
+} US_CYC_CNT_STRUC;
+#else
+typedef union _US_CYC_CNT_STRUC {
+ struct {
+ UINT32 UsCycCnt:8;
+ UINT32 MiscModeEn:1;
+ UINT32 rsv1:7;
+ UINT32 TestSel:8;
+ UINT32 TestEn:1;
+ UINT32 rsv2:7;
+ } field;
+ UINT32 word;
+} US_CYC_CNT_STRUC;
+#endif
+
+
+#endif /*__RAL_OMAC_PCI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rf_ctrl.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rf_ctrl.h
new file mode 100644
index 0000000000..f41740eaed
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rf_ctrl.h
@@ -0,0 +1,92 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_omac_rf_ctrl.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_OMAC_RF_CTRL_H__
+#define __RAL_OMAC_RF_CTRL_H__
+
+
+
+/* ================================================================================= */
+/* Register format for RFCTRL */
+/* ================================================================================= */
+
+#define OSC_CTRL 0x5a4
+#define PCIE_PHY_TX_ATTENUATION_CTRL 0x05C8
+#define INTERNAL_1 0x05C8
+
+#ifdef RT_BIG_ENDIAN
+typedef union _INTERNAL_1_STRUCT
+{
+ struct
+ {
+ UINT32 Reserve1:10;
+ UINT32 CSO_RX_IPV6_CHKSUM_EN:1;
+ UINT32 CSO_TX_IPV6_CHKSUM_EN:1;
+ UINT32 CSO_HW_PARSE_TCP:1;
+ UINT32 CSO_HW_PARSE_IP:1;
+ UINT32 CSO_RX_CHKSUM_EN:1;
+ UINT32 CSO_TX_CHKSUM_EN:1;
+ UINT32 CSO_TIMEOUT_VALUE:4;
+ UINT32 PCIE_PHY_TX_ATTEN_EN:1;
+ UINT32 PCIE_PHY_TX_ATTEN_VALUE:3;
+ UINT32 Reserve2:7;
+ UINT32 RF_ISOLATION_ENABLE:1;
+ } field;
+
+ UINT32 word;
+} INTERNAL_1_STRUCT, *PINTERNAL_1_STRUCT;
+#else
+typedef union _TX_ATTENUATION_CTRL_STRUC {
+ struct
+ {
+ UINT32 RF_ISOLATION_ENABLE:1;
+ UINT32 Reserve2:7;
+ UINT32 PCIE_PHY_TX_ATTEN_VALUE:3;
+ UINT32 PCIE_PHY_TX_ATTEN_EN:1;
+ UINT32 CSO_TIMEOUT_VALUE:4;
+ UINT32 CSO_TX_CHKSUM_EN:1;
+ UINT32 CSO_RX_CHKSUM_EN:1;
+ UINT32 CSO_HW_PARSE_IP:1;
+ UINT32 CSO_HW_PARSE_TCP:1;
+ UINT32 CSO_TX_IPV6_CHKSUM_EN:1;
+ UINT32 CSO_RX_IPV6_CHKSUM_EN:1;
+ UINT32 Reserve1:10;
+ } field;
+
+ UINT32 word;
+} INTERNAL_1_STRUCT, *PINTERNAL_1_STRUCT;
+#endif
+
+#define LDO_CFG0 0x05d4
+#define GPIO_SWITCH 0x05dc
+
+#define DEBUG_INDEX 0x05e8
+
+
+#endif /* __RAL_OMAC_RF_CTRL_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rxwi.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rxwi.h
new file mode 100644
index 0000000000..e320901374
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rxwi.h
@@ -0,0 +1,147 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_omac_rxwi.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_OMAC_RXWI_H__
+#define __RAL_OMAC_RXWI_H__
+
+#include "rtmp_type.h"
+
+/*
+ RXWI wireless information format, in PBF. invisible in driver.
+*/
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXWI_OMAC{
+ /* Word 0 */
+ UINT32 tid:4;
+ UINT32 MPDUtotalByteCnt:12;
+ UINT32 UDF:3;
+ UINT32 bss_idx:3;
+ UINT32 key_idx:2;
+ UINT32 wcid:8;
+
+ /* Word 1 */
+ UINT32 phy_mode:2; /* 1: this RX frame is unicast to me */
+ UINT32 iTxBF:1; /* iTxBF enable */
+ UINT32 Sounding:1; /* Sounding enable */
+ UINT32 eTxBF:1; /* eTxBF enable */
+ UINT32 stbc:2;
+ UINT32 sgi: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 FOFFSET:8;
+ UINT32 SNR2:8;
+ UINT32 SNR1:8;
+ UINT32 SNR0:8;
+
+ UINT32 rsv3;
+
+#if defined(RT5592) || defined(MT7601)
+ /* Word 5 */
+ /* For Exper Antenna */
+ UINT32 rsv4:24;
+ UINT32 EANT_ID:8;
+#endif /* RT5592 */
+} RXWI_OMAC, *PRXWI_OMAC;
+#else
+typedef struct GNU_PACKED _RXWI_OMAC{
+ /* Word 0 */
+ UINT32 wcid:8;
+ UINT32 key_idx:2;
+ UINT32 bss_idx:3;
+ UINT32 UDF:3;
+ UINT32 MPDUtotalByteCnt:12;
+ UINT32 tid:4;
+
+ /* Word 1 */
+ UINT32 FRAG:4;
+ UINT32 SEQUENCE:12;
+ UINT32 mcs:7;
+ UINT32 bw:1;
+ UINT32 sgi:1;
+ UINT32 stbc:2;
+ UINT32 eTxBF:1; /* eTxBF enable */
+ UINT32 Sounding:1; /* Sounding enable */
+ UINT32 iTxBF:1; /* iTxBF enable */
+ UINT32 phy_mode: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 SNR2:8;
+ UINT32 FOFFSET:8;
+
+ UINT32 rsv3;
+
+#if defined(RT5592) || defined(MT7601)
+ /* Word 5 */
+ /* For Exper Antenna */
+ UINT32 EANT_ID:8;
+ UINT32 rsv4:24;
+#endif /* RT5592 */
+} RXWI_OMAC, *PRXWI_OMAC;
+#endif
+
+
+#define RxWIMPDUByteCnt RXWI_O.MPDUtotalByteCnt
+#define RxWIWirelessCliID RXWI_O.wcid
+#define RxWIKeyIndex RXWI_O.key_idx
+#define RxWIMCS RXWI_O.mcs
+#define RxWIBW RXWI_O.bw
+#define RxWISGI RXWI_O.sgi
+#define RxWIBSSID RXWI_O.bss_idx
+#define RxWIPhyMode RXWI_O.phy_mode
+#define RxWISTBC RXWI_O.stbc
+#define RxWITID RXWI_O.tid
+#define RxWIRSSI0 RXWI_O.RSSI0
+#define RxWIRSSI1 RXWI_O.RSSI1
+#define RxWIRSSI2 RXWI_O.RSSI2
+#define RxWISNR0 RXWI_O.SNR0
+#define RxWISNR1 RXWI_O.SNR1
+#define RxWISNR2 RXWI_O.SNR2
+#define RxWIFOFFSET RXWI_O.FOFFSET
+
+
+
+#endif /* __RAL_OMAC_RXWI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_txwi.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_txwi.h
new file mode 100644
index 0000000000..16410348f6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_txwi.h
@@ -0,0 +1,143 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ ral_omac_txwi.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RAL_OMAC_TXWI_H__
+#define __RAL_OMAC_TXWI_H__
+
+
+#include "rtmp_type.h"
+
+
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _TXWI_OMAC {
+ /* Word 0 */
+ UINT32 PHYMODE:2;
+ UINT32 iTxBF:1; /* iTxBF enable */
+ UINT32 Sounding:1; /* Sounding enable */
+ UINT32 eTxBF:1; /* eTxBF enable */
+ 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:1;
+ UINT32 TXRPT:1;
+ UINT32 Autofallback:1; /* TX rate auto fallback disable */
+ UINT32 NDPSndBW:1; /* NDP sounding BW */
+ UINT32 NDPSndRate:2; /* 0 : MCS0, 1: MCS8, 2: MCS16, 3: reserved */
+ UINT32 txop:2;
+ 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 MPDUtotalByteCnt:12;
+ UINT32 wcid:8;
+ UINT32 BAWinSize:6;
+ UINT32 NSEQ:1;
+ UINT32 ACK:1;
+ /* Word 2 */
+ UINT32 IV;
+ /* Word 3 */
+ UINT32 EIV;
+
+ /* Word 4 */
+ /* For Expert Antenna */
+ UINT32 Reserved:11;
+ UINT32 CCP:1;
+ UINT32 TxPwrAdj:4;
+ UINT32 TxStreamMode:8;
+ UINT32 EncodedAntID:8;
+} TXWI_OMAC, *PTXWI_OMAC;
+#else
+typedef struct GNU_PACKED _TXWI_OMAC {
+ /* 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 NDPSndRate:2; /* 0 : MCS0, 1: MCS8, 2: MCS16, 3: reserved */
+ UINT32 NDPSndBW:1; /* NDP sounding BW */
+ UINT32 Autofallback:1; /* TX rate auto fallback disable */
+ UINT32 TXRPT:1;
+ UINT32 rsv:1;
+
+ 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 eTxBF:1; /* eTxBF enable */
+ UINT32 Sounding:1; /* Sounding enable */
+ UINT32 iTxBF:1; /* iTxBF enable */
+ UINT32 PHYMODE:2;
+ /* Word1 */
+ /* ex: 1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCnt = 0x38 */
+ UINT32 ACK:1;
+ UINT32 NSEQ:1;
+ UINT32 BAWinSize:6;
+ UINT32 wcid:8;
+ UINT32 MPDUtotalByteCnt:12;
+ UINT32 PacketId:4;
+ /*Word2 */
+ UINT32 IV;
+ /*Word3 */
+ UINT32 EIV;
+
+} TXWI_OMAC, *PTXWI_OMAC;
+#endif
+
+
+#define TxWIMPDUByteCnt TXWI_O.MPDUtotalByteCnt
+#define TxWIWirelessCliID TXWI_O.wcid
+#define TxWIFRAG TXWI_O.FRAG
+#define TxWICFACK TXWI_O.CFACK
+#define TxWITS TXWI_O.TS
+#define TxWIAMPDU TXWI_O.AMPDU
+#define TxWIACK TXWI_O.ACK
+#define TxWITXOP TXWI_O.txop
+#define TxWINSEQ TXWI_O.NSEQ
+#define TxWIBAWinSize TXWI_O.BAWinSize
+#define TxWIShortGI TXWI_O.ShortGI
+#define TxWISTBC TXWI_O.STBC
+#define TxWIBW TXWI_O.BW
+#define TxWIMCS TXWI_O.MCS
+#define TxWIPHYMODE TXWI_O.PHYMODE
+#define TxWIMIMOps TXWI_O.MIMOps
+#define TxWIMpduDensity TXWI_O.MpduDensity
+
+#endif /* __RAL_OMAC_TXWI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_usb.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_usb.h
new file mode 100644
index 0000000000..e9e6a157ae
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_usb.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ral_omac_usb.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RAL_OMAC_USB_H__
+#define __RAL_OMAC_USB_H__
+
+
+#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
+
+#endif /*__RAL_OMAC_USB_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/pbf.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/pbf.h
new file mode 100644
index 0000000000..b7efa3646c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/pbf.h
@@ -0,0 +1,93 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ pbf.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __PBF_H__
+#define __PBF_H__
+
+
+#ifdef RLT_MAC
+#include "mac_ral/nmac/ral_nmac_pbf.h"
+#endif /* RLT_MAC */
+
+#ifdef RTMP_MAC
+#include "mac_ral/omac/ral_omac_pbf.h"
+#endif /* RTMP_MAC */
+
+
+/* ================================================================================= */
+/* Register format for PBF */
+/* ================================================================================= */
+
+
+#define WPDMA_GLO_CFG 0x208
+#ifdef RT_BIG_ENDIAN
+typedef union _WPDMA_GLO_CFG_STRUC {
+ struct {
+ UINT32 rx_2b_offset:1;
+ UINT32 clk_gate_dis:1;
+ UINT32 rsv:14;
+ UINT32 HDR_SEG_LEN: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 HDR_SEG_LEN:8;
+ UINT32 rsv:14;
+ UINT32 clk_gate_dis:1;
+ UINT32 rx_2b_offset:1;
+ } field;
+ UINT32 word;
+} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+#endif
+
+
+#define PBF_CTRL 0x0410
+#define MCU_INT_STA 0x0414
+#define MCU_INT_ENA 0x0418
+#define TXRXQ_PCNT 0x0438
+#define PBF_DBG 0x043c
+
+
+#endif /* __PBF_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/rf_ctrl.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/rf_ctrl.h
new file mode 100644
index 0000000000..0b2e276aee
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/rf_ctrl.h
@@ -0,0 +1,146 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rf_ctrl.h
+
+ Abstract:
+ Ralink wireless chip RF related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RF_CTRL_H__
+#define __RF_CTRL_H__
+
+#ifdef RTMP_MAC
+#include "mac_ral/omac/ral_omac_rf_ctrl.h"
+#endif /* RTMP_MAC */
+
+#ifdef RLT_MAC
+
+#endif /* RLT_MAC */
+
+
+/* ================================================================================= */
+/* Register format for RFCTRL */
+/* ================================================================================= */
+
+#define RF_CSR_CFG 0x500
+
+#ifdef RLT_RF
+
+#define RF_BANK0 0
+#define RF_BANK1 1
+#define RF_BANK2 2
+#define RF_BANK3 3
+#define RF_BANK4 4
+#define RF_BANK5 5
+#define RF_BANK6 6
+#define RF_BANK7 7
+#define RF_BANK8 8
+#define RF_BANK9 9
+#define RF_BANK10 10
+#define RF_BANK11 11
+#define RF_BANK12 12
+#define RF_BANK13 13
+#define RF_BANK14 14
+#define RF_BANK15 15
+
+/* @!Release
+ RF_CSR_KICK:1
+ Write - kick RF register read/write
+ 0: do nothing
+ 1: kick read/write process
+ Read - Polling RF register read/write
+ 0: idle
+ 1: busy
+ RF_CSR_RW:1
+ 0: read 1: write
+ rsv:12
+ RF_CSR_REG_ID:10
+ RF register ID, 0 for R0, 1 for R1 and so on
+ Bits [17:15] 3 bits, indicates the bank number
+ Bits [14:08] 7 bits, indicates the register number
+
+ RF_CSR_DATA:8
+ DATA written to/read from RF
+*/
+typedef union _RLT_RF_CSR_CFG {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ UINT RF_CSR_KICK:1;
+ UINT RF_CSR_WR:1;
+ UINT rsv:12;
+#ifdef MT7601
+ UINT RF_CSR_REG_BANK:4;
+ UINT RF_CSR_REG_ID:6;
+#else
+ UINT RF_CSR_REG_BANK:3;
+ UINT RF_CSR_REG_ID:7;
+#endif /* MT7601 */
+ UINT RF_CSR_DATA:8;
+ } field;
+#else
+ struct {
+ UINT RF_CSR_DATA:8;
+#ifdef MT7601
+ UINT RF_CSR_REG_ID:6;
+ UINT RF_CSR_REG_BANK:4;
+#else
+ UINT RF_CSR_REG_ID:7;
+ UINT RF_CSR_REG_BANK:3;
+#endif /* MT7601 */
+ UINT rsv:12;
+ UINT RF_CSR_WR:1;
+ UINT RF_CSR_KICK:1;
+ } field;
+#endif /* RT_BIG_ENDIAN */
+ UINT word;
+}RLT_RF_CSR_CFG;
+#endif /* RLT_RF */
+
+
+typedef union _RF_CSR_CFG_STRUC {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ UINT32 Rsvd1:14; /* Reserved */
+ UINT32 RF_CSR_KICK:1; /* kick RF register read/write */
+ UINT32 RF_CSR_WR:1; /* 0: read 1: write */
+ UINT32 TESTCSR_RFACC_REGNUM:8; /* RF register ID */
+ UINT32 RF_CSR_DATA:8; /* DATA */
+ } field;
+#else
+ struct {
+ UINT32 RF_CSR_DATA:8;
+ UINT32 TESTCSR_RFACC_REGNUM:8;
+ UINT32 RF_CSR_WR:1;
+ UINT32 RF_CSR_KICK:1;
+ UINT32 Rsvd1:14;
+ } field;
+#endif /* RT_BIG_ENDIAN */
+ UINT32 word;
+}RF_CSR_CFG_STRUC;
+
+#define RF_BYPASS_0 0x0504
+
+#define RF_SETTING_0 0x050C
+
+#endif /* __RF_CTRL_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mac_ral/rtmp_mac.h b/cleopatre/devkit/mt7601udrv/include/mac_ral/rtmp_mac.h
new file mode 100644
index 0000000000..a4f699dc50
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mac_ral/rtmp_mac.h
@@ -0,0 +1,2379 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_mac.h
+
+ Abstract:
+ Ralink Wireless Chip MAC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_MAC_H__
+#define __RTMP_MAC_H__
+
+
+#ifdef RLT_MAC
+#include "mac_ral/nmac/ral_nmac.h"
+#endif /* RLT_MAC */
+
+#ifdef RTMP_MAC
+#include "mac_ral/omac/ral_omac.h"
+#endif /* RTMP_MAC */
+
+
+/*
+ TX / RX ring descriptor format
+
+ TX:
+ PCI/RBUS_Descriptor + TXINFO + TXWI + 802.11
+
+ Rx:
+ PCI/RBUS/USB_Descripotr + (PCI/RBUS RXFCE_INFO) + (PCI/RBUS RXINFO) + RXWI + 802.11 + (USB RXINFO)
+
+*/
+
+/* 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
+#define FIFO_EDCA2 3
+
+typedef union GNU_PACKED _TXWI_STRUC {
+#ifdef RLT_MAC
+ struct _TXWI_NMAC TXWI_N;
+#endif /* RLT_MAC */
+#ifdef RTMP_MAC
+ struct _TXWI_OMAC TXWI_O;
+#endif /* RTMP_MAC */
+ UINT32 word;
+}TXWI_STRUC;
+
+
+#define TXINFO_SIZE 4
+typedef union GNU_PACKED _TXINFO_STRUC{
+#ifdef RTMP_MAC
+ struct _TXINFO_OMAC txinfo_omac;
+#endif /* RTMP_MAC */
+#ifdef RLT_MAC
+ struct _TXINFO_NMAC_PKT txinfo_nmac_pkt;
+ struct _TXINFO_NMAC_CMD txinfo_nmac_cmd;
+#endif /* RLT_MAC */
+ UINT32 word;
+}TXINFO_STRUC;
+
+
+/*
+ RXWI wireless information format, in PBF. invisible in driver.
+*/
+typedef union GNU_PACKED _RXWI_STRUC {
+#ifdef RLT_MAC
+#ifdef MT7601
+ struct _RXWI_OMAC RXWI_O;
+#else
+ struct _RXWI_NMAC RXWI_N;
+#endif /* MT7601 */
+#endif /* RLT_MAC */
+#ifdef RTMP_MAC
+ struct _RXWI_OMAC RXWI_O;
+#endif /* RTMP_MAC */
+}RXWI_STRUC;
+
+
+#define RXINFO_SIZE 4
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _RXINFO_STRUC {
+ UINT32 ip_sum_err:1; /* IP checksum error */
+ UINT32 tcp_sum_err:1; /* TCP checksum error */
+ UINT32 ip_sum_bypass:1; /* IP checksum bypass(hw does not do checksum) */
+ UINT32 tcp_sum_bypass:1; /* TCP/UDP checksum bypass(hw does not do checksum) */
+#ifdef HDR_TRANS_SUPPORT
+ UINT32 rsv:5;
+ UINT32 pkt_80211:1;
+#else
+ UINT32 rsv:6;
+#endif /* HDR_TRANS_SUPPORT */
+ UINT32 pn_len:3;
+ UINT32 wapi_kidx:1;
+ UINT32 BssIdx3:1;
+ UINT32 Decrypted:1;
+ UINT32 AMPDU:1;
+ UINT32 L2PAD:1;
+ UINT32 RSSI:1;
+ UINT32 HTC:1;
+ UINT32 AMSDU:1; /* rx with 802.3 header, not 802.11 header. obsolete. */
+ 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;
+#else
+typedef struct GNU_PACKED _RXINFO_STRUC {
+ UINT32 BA:1;
+ UINT32 DATA:1;
+ UINT32 NULLDATA:1;
+ UINT32 FRAG:1;
+ UINT32 U2M:1;
+ UINT32 Mcast:1;
+ UINT32 Bcast:1;
+ UINT32 MyBss:1;
+ UINT32 Crc:1;
+ UINT32 CipherErr:2;
+ UINT32 AMSDU:1;
+ UINT32 HTC:1;
+ UINT32 RSSI:1;
+ UINT32 L2PAD:1;
+ UINT32 AMPDU:1;
+ UINT32 Decrypted:1;
+ UINT32 BssIdx3:1;
+ UINT32 wapi_kidx:1;
+ UINT32 pn_len:3;
+#ifdef HDR_TRANS_SUPPORT
+ UINT32 pkt_80211:1;
+ UINT32 rsv:5;
+#else
+ UINT32 rsv:6;
+#endif /* HDR_TRANS_SUPPORT */
+ UINT32 tcp_sum_bypass:1;
+ UINT32 ip_sum_bypass:1;
+ UINT32 tcp_sum_err:1;
+ UINT32 ip_sum_err:1;
+}RXINFO_STRUC, *PRXINFO_STRUC;
+#endif
+
+#define TSO_SIZE 0
+
+
+/* ================================================================================= */
+/* Register format */
+/* ================================================================================= */
+
+
+/*
+ SCH/DMA registers - base address 0x0200
+*/
+#define WMM_AIFSN_CFG 0x0214
+#ifdef RT_BIG_ENDIAN
+typedef union _AIFSN_CSR_STRUC{
+ struct {
+ UINT32 Aifsn7:4; /* for AC_VO */
+ UINT32 Aifsn6:4; /* for AC_VI */
+ UINT32 Aifsn5:4; /* for AC_BK */
+ UINT32 Aifsn4:4; /* for AC_BE */
+ 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;
+#else
+typedef union _AIFSN_CSR_STRUC {
+ struct {
+ UINT32 Aifsn0:4;
+ UINT32 Aifsn1:4;
+ UINT32 Aifsn2:4;
+ UINT32 Aifsn3:4;
+ UINT32 Aifsn4:4;
+ UINT32 Aifsn5:4;
+ UINT32 Aifsn6:4;
+ UINT32 Aifsn7:4;
+ } field;
+ UINT32 word;
+} AIFSN_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 Cwmin7:4; /* for AC_VO */
+ UINT32 Cwmin6:4; /* for AC_VI */
+ UINT32 Cwmin5:4; /* for AC_BK */
+ UINT32 Cwmin4:4; /* for AC_BE */
+ 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;
+#else
+typedef union _CWMIN_CSR_STRUC {
+ struct {
+ UINT32 Cwmin0:4;
+ UINT32 Cwmin1:4;
+ UINT32 Cwmin2:4;
+ UINT32 Cwmin3:4;
+ UINT32 Cwmin4:4;
+ UINT32 Cwmin5:4;
+ UINT32 Cwmin6:4;
+ UINT32 Cwmin7:4;
+ } field;
+ UINT32 word;
+} CWMIN_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 Cwmax7:4; /* for AC_VO */
+ UINT32 Cwmax6:4; /* for AC_VI */
+ UINT32 Cwmax5:4; /* for AC_BK */
+ UINT32 Cwmax4:4; /* for AC_BE */
+ 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;
+#else
+typedef union _CWMAX_CSR_STRUC {
+ struct {
+ UINT32 Cwmax0:4;
+ UINT32 Cwmax1:4;
+ UINT32 Cwmax2:4;
+ UINT32 Cwmax3:4;
+ UINT32 Cwmax4:4;
+ UINT32 Cwmax5:4;
+ UINT32 Cwmax6:4;
+ UINT32 Cwmax7:4;
+ } field;
+ UINT32 word;
+} CWMAX_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 {
+ UINT16 Ac1Txop; /* for AC_BE, in unit of 32us */
+ UINT16 Ac0Txop; /* for AC_BK, in unit of 32us */
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR0_STRUC;
+#else
+typedef union _AC_TXOP_CSR0_STRUC {
+ struct {
+ UINT16 Ac0Txop;
+ UINT16 Ac1Txop;
+ } field;
+ UINT32 word;
+} AC_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 {
+ UINT16 Ac3Txop; /* for AC_VO, in unit of 32us */
+ UINT16 Ac2Txop; /* for AC_VI, in unit of 32us */
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR1_STRUC;
+#else
+typedef union _AC_TXOP_CSR1_STRUC {
+ struct {
+ UINT16 Ac2Txop;
+ UINT16 Ac3Txop;
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR1_STRUC;
+#endif
+
+
+#define WMM_TXOP2_CFG 0x0228
+#define WMM_TXOP3_CFG 0x022c
+
+#define WMM_CTRL 0x0230
+
+
+
+/*================================================================================= */
+/* 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 {
+ UINT16 ASICVer; /* version */
+ UINT16 ASICRev; /* reversion */
+ } field;
+ UINT32 word;
+} ASIC_VER_ID_STRUC;
+#else
+typedef union _ASIC_VER_ID_STRUC {
+ struct {
+ UINT16 ASICRev;
+ UINT16 ASICVer;
+ } field;
+ UINT32 word;
+} ASIC_VER_ID_STRUC;
+#endif
+
+#define MAC_SYS_CTRL 0x1004
+#define MAC_ADDR_DW0 0x1008
+#define MAC_ADDR_DW1 0x100c
+
+/* MAC_CSR2: STA MAC register 0 */
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_DW0_STRUC {
+ struct {
+ UINT8 Byte3; /* MAC address byte 3 */
+ UINT8 Byte2; /* MAC address byte 2 */
+ UINT8 Byte1; /* MAC address byte 1 */
+ UINT8 Byte0; /* MAC address byte 0 */
+ } field;
+ UINT32 word;
+} MAC_DW0_STRUC;
+#else
+typedef union _MAC_DW0_STRUC {
+ struct {
+ UINT8 Byte0;
+ UINT8 Byte1;
+ UINT8 Byte2;
+ UINT8 Byte3;
+ } field;
+ UINT32 word;
+} MAC_DW0_STRUC;
+#endif
+
+
+/* MAC_CSR3: STA MAC register 1 */
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_DW1_STRUC {
+ struct {
+ UINT8 Rsvd1;
+ UINT8 U2MeMask;
+ UINT8 Byte5; /* MAC address byte 5 */
+ UINT8 Byte4; /* MAC address byte 4 */
+ } field;
+ UINT32 word;
+} MAC_DW1_STRUC;
+#else
+typedef union _MAC_DW1_STRUC {
+ struct {
+ UINT8 Byte4;
+ UINT8 Byte5;
+ UINT8 U2MeMask;
+ UINT8 Rsvd1;
+ } field;
+ UINT32 word;
+} MAC_DW1_STRUC;
+#endif
+
+#define MAC_BSSID_DW0 0x1010
+#define MAC_BSSID_DW1 0x1014
+/* MAC_CSR5: BSSID register 1 */
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_BSSID_DW1_STRUC {
+ struct {
+ UINT32 NMBssMode3:1;
+ UINT32 NMBssMode2:1;
+ UINT32 NMBssMode:1;
+ UINT32 MBssBcnNum:3;
+ UINT32 MBssMode:2; /* 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID */
+ UINT32 Byte5:8; /* BSSID byte 5 */
+ UINT32 Byte4:8; /* BSSID byte 4 */
+ } field;
+ UINT32 word;
+} MAC_BSSID_DW1_STRUC;
+#else
+typedef union _MAC_BSSID_DW1_STRUC {
+ struct {
+ UINT32 Byte4:8;
+ UINT32 Byte5:8;
+ UINT32 MBssMode:2;
+ UINT32 MBssBcnNum:3;
+ UINT32 NMBssMode:1;
+ UINT32 NMBssMode2:1;
+ UINT32 NMBssMode3:1;
+ } field;
+ UINT32 word;
+} MAC_BSSID_DW1_STRUC;
+#endif
+
+/* rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16 */
+#define MAX_LEN_CFG 0x1018
+
+
+/* BBP_CSR_CFG: BBP serial control register */
+#define BBP_CSR_CFG 0x101c
+#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;
+#else
+typedef union _BBP_CSR_CFG_STRUC {
+ struct {
+ UINT32 Value:8;
+ UINT32 RegNum:8;
+ UINT32 fRead:1;
+ UINT32 Busy:1;
+ UINT32 BBP_PAR_DUR:1;
+ UINT32 BBP_RW_MODE:1;
+ UINT32 :12;
+ } field;
+ UINT32 word;
+} BBP_CSR_CFG_STRUC;
+#endif
+
+
+/* RF_CSR_CFG: RF control register */
+#define RF_CSR_CFG0 0x1020
+#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;
+#else
+typedef union _RF_CSR_CFG0_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24;
+ UINT32 bitwidth:5;
+ UINT32 StandbyMode:1;
+ UINT32 Sel:1;
+ UINT32 Busy:1;
+ } field;
+ UINT32 word;
+} RF_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;
+#else
+typedef union _RF_CSR_CFG1_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24;
+ UINT32 RFGap:5;
+ UINT32 rsv:7;
+ } field;
+ UINT32 word;
+} RF_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;
+#else
+typedef union _RF_CSR_CFG2_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24;
+ UINT32 rsv:8;
+ } field;
+ UINT32 word;
+} RF_CSR_CFG2_STRUC;
+#endif
+
+
+#define LED_CFG 0x102c
+#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;
+#else
+typedef union _LED_CFG_STRUC {
+ struct {
+ UINT32 OnPeriod:8;
+ UINT32 OffPeriod:8;
+ UINT32 SlowBlinkPeriod:6;
+ UINT32 rsv:2;
+ UINT32 RLedMode:2;
+ UINT32 GLedMode:2;
+ UINT32 YLedMode:2;
+ UINT32 LedPolar:1;
+ UINT32 :1;
+ } field;
+ UINT32 word;
+} LED_CFG_STRUC;
+#endif
+
+
+#define AMPDU_MAX_LEN_20M1S 0x1030
+#define AMPDU_MAX_LEN_20M2S 0x1034
+#define AMPDU_MAX_LEN_40M1S 0x1038
+#define AMPDU_MAX_LEN_40M2S 0x103c
+#define AMPDU_MAX_LEN 0x1040
+
+
+/* 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 {
+ UINT8 TxChainAddr0L_Byte3; /* Destination MAC address of Tx chain0 (byte 3) */
+ UINT8 TxChainAddr0L_Byte2; /* Destination MAC address of Tx chain0 (byte 2) */
+ UINT8 TxChainAddr0L_Byte1; /* Destination MAC address of Tx chain0 (byte 1) */
+ UINT8 TxChainAddr0L_Byte0; /* Destination MAC address of Tx chain0 (byte 0) */
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR0_L_STRUC;
+#else
+typedef union _TX_CHAIN_ADDR0_L_STRUC {
+ struct {
+ UINT8 TxChainAddr0L_Byte0;
+ UINT8 TxChainAddr0L_Byte1;
+ UINT8 TxChainAddr0L_Byte2;
+ UINT8 TxChainAddr0L_Byte3;
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR0_L_STRUC;
+#endif
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_CHAIN_ADDR0_H_STRUC {
+ struct {
+ UINT16 Reserved:12; /* Reserved */
+ UINT16 TxChainSel0:4; /* Selection value of Tx chain0 */
+ UINT8 TxChainAddr0H_Byte5; /* Destination MAC address of Tx chain0 (byte 5) */
+ UINT8 TxChainAddr0H_Byte4; /* Destination MAC address of Tx chain0 (byte 4) */
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR0_H_STRUC;
+#else
+typedef union _TX_CHAIN_ADDR0_H_STRUC {
+ struct {
+ UINT8 TxChainAddr0H_Byte4; /* Destination MAC address of Tx chain0 (byte 4) */
+ UINT8 TxChainAddr0H_Byte5; /* Destination MAC address of Tx chain0 (byte 5) */
+ UINT16 TxChainSel0:4; /* Selection value of Tx chain0 */
+ UINT16 Reserved:12; /* Reserved */
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR0_H_STRUC;
+#endif
+
+
+#ifdef BIG_ENDIAN
+typedef union _TX_CHAIN_ADDR1_L_STRUC {
+ struct {
+ UINT8 TxChainAddr1L_Byte3; /* Destination MAC address of Tx chain1 (byte 3) */
+ UINT8 TxChainAddr1L_Byte2; /* Destination MAC address of Tx chain1 (byte 2) */
+ UINT8 TxChainAddr1L_Byte1; /* Destination MAC address of Tx chain1 (byte 1) */
+ UINT8 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 {
+ UINT8 TxChainAddr1L_Byte0;
+ UINT8 TxChainAddr1L_Byte1;
+ UINT8 TxChainAddr1L_Byte2;
+ UINT8 TxChainAddr1L_Byte3;
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR1_L_STRUC, *PTX_CHAIN_ADDR1_L_STRUC;
+#endif
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_CHAIN_ADDR1_H_STRUC {
+ struct {
+ UINT16 Reserved:12; /* Reserved */
+ UINT16 TxChainSel0:4; /* Selection value of Tx chain0 */
+ UINT8 TxChainAddr1H_Byte5; /* Destination MAC address of Tx chain1 (byte 5) */
+ UINT8 TxChainAddr1H_Byte4; /* Destination MAC address of Tx chain1 (byte 4) */
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR1_H_STRUC ;
+#else
+typedef union _TX_CHAIN_ADDR1_H_STRUC {
+ struct {
+ UINT8 TxChainAddr1H_Byte4;
+ UINT8 TxChainAddr1H_Byte5;
+ UINT16 TxChainSel0:4;
+ UINT16 Reserved:12;
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR1_H_STRUC ;
+#endif
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_CHAIN_ADDR2_L_STRUC {
+ struct {
+ UINT8 TxChainAddr2L_Byte3; /* Destination MAC address of Tx chain2 (byte 3) */
+ UINT8 TxChainAddr2L_Byte2; /* Destination MAC address of Tx chain2 (byte 2) */
+ UINT8 TxChainAddr2L_Byte1; /* Destination MAC address of Tx chain2 (byte 1) */
+ UINT8 TxChainAddr2L_Byte0; /* Destination MAC address of Tx chain2 (byte 0) */
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR2_L_STRUC;
+#else
+typedef union _TX_CHAIN_ADDR2_L_STRUC {
+ struct {
+ UINT8 TxChainAddr2L_Byte0;
+ UINT8 TxChainAddr2L_Byte1;
+ UINT8 TxChainAddr2L_Byte2;
+ UINT8 TxChainAddr2L_Byte3;
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR2_L_STRUC;
+#endif
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_CHAIN_ADDR2_H_STRUC {
+ struct {
+ UINT16 Reserved:12; /* Reserved */
+ UINT16 TxChainSel0:4; /* Selection value of Tx chain0 */
+ UINT8 TxChainAddr2H_Byte5; /* Destination MAC address of Tx chain2 (byte 5) */
+ UINT8 TxChainAddr2H_Byte4; /* Destination MAC address of Tx chain2 (byte 4) */
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR2_H_STRUC;
+#else
+typedef union _TX_CHAIN_ADDR2_H_STRUC {
+ struct {
+ UINT8 TxChainAddr2H_Byte4;
+ UINT8 TxChainAddr2H_Byte5;
+ UINT16 TxChainSel0:4;
+ UINT16 Reserved:12;
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR2_H_STRUC;
+#endif
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_CHAIN_ADDR3_L_STRUC {
+ struct {
+ UINT8 TxChainAddr3L_Byte3; /* Destination MAC address of Tx chain3 (byte 3) */
+ UINT8 TxChainAddr3L_Byte2; /* Destination MAC address of Tx chain3 (byte 2) */
+ UINT8 TxChainAddr3L_Byte1; /* Destination MAC address of Tx chain3 (byte 1) */
+ UINT8 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 {
+ UINT8 TxChainAddr3L_Byte0;
+ UINT8 TxChainAddr3L_Byte1;
+ UINT8 TxChainAddr3L_Byte2;
+ UINT8 TxChainAddr3L_Byte3;
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR3_L_STRUC, *PTX_CHAIN_ADDR3_L_STRUC;
+#endif
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_CHAIN_ADDR3_H_STRUC {
+ struct {
+ UINT16 Reserved:12; /* Reserved */
+ UINT16 TxChainSel0:4; /* Selection value of Tx chain0 */
+ UINT8 TxChainAddr3H_Byte5; /* Destination MAC address of Tx chain3 (byte 5) */
+ UINT8 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 {
+ UINT8 TxChainAddr3H_Byte4;
+ UINT8 TxChainAddr3H_Byte5;
+ UINT16 TxChainSel0:4;
+ UINT16 Reserved:12;
+ } field;
+ UINT32 word;
+} TX_CHAIN_ADDR3_H_STRUC;
+#endif
+
+
+
+/* 4.2 MAC TIMING configuration registers (offset:0x1100) */
+#define XIFS_TIME_CFG 0x1100
+#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;
+#else
+typedef union _IFS_SLOT_CFG_STRUC {
+ struct {
+ UINT32 CckmSifsTime:8;
+ UINT32 OfdmSifsTime:8;
+ UINT32 OfdmXifsTime:4;
+ UINT32 EIFS:9;
+ UINT32 BBRxendEnable:1;
+ UINT32 rsv:2;
+ } field;
+ UINT32 word;
+} IFS_SLOT_CFG_STRUC;
+#endif
+
+#define BKOFF_SLOT_CFG 0x1104
+#define NAV_TIME_CFG 0x1108
+#define CH_TIME_CFG 0x110C
+#define PBF_LIFE_TIMER 0x1110 /*TX/RX MPDU timestamp timer (free run)Unit: 1us */
+
+
+/* BCN_TIME_CFG : Synchronization control register */
+#define BCN_TIME_CFG 0x1114
+#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;
+#else
+typedef union _BCN_TIME_CFG_STRUC {
+ struct {
+ UINT32 BeaconInterval:16;
+ UINT32 bTsfTicking:1;
+ UINT32 TsfSyncMode:2;
+ UINT32 bTBTTEnable:1;
+ UINT32 bBeaconGen:1;
+ UINT32 :3;
+ UINT32 TxTimestampCompensate:8;
+ } field;
+ UINT32 word;
+} BCN_TIME_CFG_STRUC;
+#endif
+
+
+#define TBTT_SYNC_CFG 0x1118
+#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 */
+#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
+#define PWR_PIN_CFG 0x1204
+
+
+/* AUTO_WAKEUP_CFG: Manual power control / status register */
+#define AUTO_WAKEUP_CFG 0x1208
+#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;
+#else
+typedef union _AUTO_WAKEUP_STRUC {
+ struct {
+ UINT32 AutoLeadTime:8;
+ UINT32 NumofSleepingTbtt:7;
+ UINT32 EnableAutoWakeup:1;
+ UINT32 :16;
+ } field;
+ UINT32 word;
+} AUTO_WAKEUP_STRUC;
+#endif
+
+
+/* 4.3 MAC TX configuration registers (offset:0x1300) */
+#define EDCA_AC0_CFG 0x1300
+#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;
+#else
+typedef union _EDCA_AC_CFG_STRUC {
+ struct {
+ UINT32 AcTxop:8;
+ UINT32 Aifsn:4;
+ UINT32 Cwmin:4;
+ UINT32 Cwmax:4;
+ UINT32 :12;
+ } field;
+ UINT32 word;
+} EDCA_AC_CFG_STRUC;
+#endif
+
+#define EDCA_TID_AC_MAP 0x1310
+
+
+/* Default Tx power */
+#define DEFAULT_TX_POWER 0x6
+
+#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 {
+ UINT32 Byte3:8;
+ UINT32 Byte2:8;
+ UINT32 Byte1:8;
+ UINT32 Byte0:8;
+ } field;
+ UINT32 word;
+} TX_PWR_CFG_STRUC;
+#else
+typedef union _TX_PWR_CFG_STRUC {
+ struct {
+ UINT32 Byte0:8;
+ UINT32 Byte1:8;
+ UINT32 Byte2:8;
+ UINT32 Byte3:8;
+ } field;
+ UINT32 word;
+} TX_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;
+#else
+typedef union _TXOP_THRESHOLD_CFG_STRUC {
+ struct {
+ UINT32 RDG_OUT_THRES:8;
+ UINT32 RDG_IN_THRES:8;
+ UINT32 CF_END_THRES:8;
+ UINT32 TXOP_REM_THRES:8;
+ } field;
+ UINT32 word;
+} TXOP_THRESHOLD_CFG_STRUC;
+#endif
+
+#define TXOP_CTRL_CFG 0x1340
+
+
+#define TX_RTS_CFG 0x1344
+#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;
+#else
+typedef union _TX_RTS_CFG_STRUC {
+ struct {
+ UINT32 AutoRtsRetryLimit:8;
+ UINT32 RtsThres:16;
+ UINT32 RtsFbkEn:1;
+ UINT32 rsv:7;
+ } field;
+ UINT32 word;
+} TX_RTS_CFG_STRUC;
+#endif
+
+
+#define TX_TXBF_CFG_0 0x138c
+#define TX_TXBF_CFG_1 0x13A4
+#define TX_TXBF_CFG_2 0x13A8
+#define TX_TXBF_CFG_3 0x13AC
+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;
+
+
+#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;
+#else
+typedef union _TX_TIMEOUT_CFG_STRUC {
+ struct {
+ UINT32 rsv:4;
+ UINT32 MpduLifeTime:4;
+ UINT32 RxAckTimeout:8;
+ UINT32 TxopTimeout:8;
+ UINT32 rsv2:8;
+ } field;
+ UINT32 word;
+} TX_TIMEOUT_CFG_STRUC;
+#endif
+
+
+#define TX_RTY_CFG 0x134c
+#ifdef RT_BIG_ENDIAN
+typedef union _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;
+#else
+typedef union _TX_RTY_CFG_STRUC {
+ struct {
+ UINT32 ShortRtyLimit:8;
+ UINT32 LongRtyLimit:8;
+ UINT32 LongRtyThre:12;
+ UINT32 NonAggRtyMode:1;
+ UINT32 AggRtyMode:1;
+ UINT32 TxautoFBEnable:1;
+ UINT32 rsv:1;
+ } field;
+ UINT32 word;
+} TX_RTY_CFG_STRUC;
+#endif
+
+
+#define TX_LINK_CFG 0x1350
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_LINK_CFG_STRUC {
+ struct {
+ 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;
+#else
+typedef union _TX_LINK_CFG_STRUC {
+ struct {
+ UINT32 RemoteMFBLifeTime:8;
+ UINT32 MFBEnable:1;
+ UINT32 RemoteUMFSEnable:1;
+ UINT32 TxMRQEn:1;
+ UINT32 TxRDGEn:1;
+ UINT32 TxCFAckEn:1;
+ UINT32 rsv:3;
+ UINT32 RemotMFB:8;
+ UINT32 RemotMFS:8;
+ } field;
+ UINT32 word;
+} TX_LINK_CFG_STRUC;
+#endif
+
+
+#define HT_FBK_CFG0 0x1354
+#ifdef RT_BIG_ENDIAN
+typedef union _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;
+#else
+typedef union _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;
+#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;
+#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;
+#endif
+
+
+#define LG_FBK_CFG0 0x135c
+#ifdef RT_BIG_ENDIAN
+typedef union _LG_FBK_CFG0_STRUC {
+ struct {
+ UINT32 OFDMMCS7FBK:4;
+ UINT32 OFDMMCS6FBK:4;
+ UINT32 OFDMMCS5FBK:4
+ UINT32 OFDMMCS4FBK:4;
+ UINT32 OFDMMCS3FBK:4;
+ UINT32 OFDMMCS2FBK:4;
+ UINT32 OFDMMCS1FBK:4;
+ UINT32 OFDMMCS0FBK:4;
+ } field;
+ UINT32 word;
+} LG_FBK_CFG0_STRUC;
+#else
+typedef union _LG_FBK_CFG0_STRUC {
+ struct {
+ UINT32 OFDMMCS0FBK:4;
+ UINT32 OFDMMCS1FBK:4;
+ UINT32 OFDMMCS2FBK:4;
+ UINT32 OFDMMCS3FBK:4;
+ UINT32 OFDMMCS4FBK:4;
+ UINT32 OFDMMCS5FBK:4;
+ UINT32 OFDMMCS6FBK:4;
+ UINT32 OFDMMCS7FBK:4;
+ } field;
+ UINT32 word;
+} LG_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;
+ UINT32 CCKMCS2FBK:4;
+ UINT32 CCKMCS1FBK:4;
+ UINT32 CCKMCS0FBK:4;
+ } field;
+ UINT32 word;
+} LG_FBK_CFG1_STRUC;
+#else
+typedef union _LG_FBK_CFG1_STRUC {
+ struct {
+ UINT32 CCKMCS0FBK:4;
+ UINT32 CCKMCS1FBK:4;
+ UINT32 CCKMCS2FBK:4;
+ UINT32 CCKMCS3FBK:4;
+ UINT32 rsv:16;
+ } field;
+ UINT32 word;
+} LG_FBK_CFG1_STRUC;
+#endif
+
+
+/*======================================================= */
+/* Protection Paramater */
+/*======================================================= */
+#define ASIC_SHORTNAV 1
+#define ASIC_LONGNAV 2
+#define ASIC_RTS 1
+#define ASIC_CTS 2
+
+#define CCK_PROT_CFG 0x1364 /* CCK Protection */
+#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 */
+#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;
+#else
+typedef union _PROT_CFG_STRUC {
+ struct {
+ UINT32 ProtectRate:16;
+ UINT32 ProtectCtrl:2;
+ UINT32 ProtectNav:2;
+ UINT32 TxopAllowCck:1;
+ UINT32 TxopAllowOfdm:1;
+ UINT32 TxopAllowMM20:1;
+ UINT32 TxopAllowMM40:1;
+ UINT32 TxopAllowGF20:1;
+ UINT32 TxopAllowGF40:1;
+ UINT32 RTSThEn:1;
+ UINT32 rsv:5;
+ } field;
+ UINT32 word;
+} PROT_CFG_STRUC;
+#endif
+
+
+#define EXP_CTS_TIME 0x137C
+#define EXP_ACK_TIME 0x1380
+
+
+#define HT_FBK_TO_LEGACY 0x1384
+
+
+#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:3;
+ UINT32 HTMCS19FBK:5;
+ UINT32 rsv1:3;
+ UINT32 HTMCS18FBK:5;
+ UINT32 rsv2:3;
+ UINT32 HTMCS17FBK:5;
+ UINT32 rsv3:3;
+ UINT32 HTMCS16FBK:5;
+ } field;
+ UINT32 word;
+} TX_FBK_CFG_3S_0_STRUC;
+#else
+typedef union _TX_FBK_CFG_3S_0_STRUC {
+ struct {
+ UINT32 HTMCS16FBK:5;
+ UINT32 rsv3:3;
+ UINT32 HTMCS17FBK:5;
+ UINT32 rsv2:3;
+ UINT32 HTMCS18FBK:5;
+ UINT32 rsv1:3;
+ UINT32 HTMCS19FBK:5;
+ UINT32 rsv0:4;
+ } field;
+ UINT32 word;
+} TX_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;
+#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;
+#endif
+#endif /* DOT11N_SS3_SUPPORT */
+
+#define TX_AC_RTY_LIMIT 0x13cc
+#define TX_AC_FBK_SPEED 0x13d0
+
+
+
+/* 4.4 MAC RX configuration registers (offset:0x1400) */
+
+/* RX_FILTR_CFG: /RX configuration register */
+#define RX_FILTR_CFG 0x1400
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_FILTR_CFG_STRUC {
+ struct {
+ UINT32 rsv: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;
+#else
+typedef union _RX_FILTR_CFG_STRUC {
+ struct {
+ UINT32 DropCRCErr:1;
+ UINT32 DropPhyErr:1;
+ UINT32 DropNotToMe:1;
+ UINT32 DropNotMyBSSID:1;
+ UINT32 DropVerErr:1;
+ UINT32 DropMcast:1;
+ UINT32 DropBcast:1;
+ UINT32 DropDuplicate:1;
+ UINT32 DropCFEndAck:1;
+ UINT32 DropCFEnd:1;
+ UINT32 DropAck:1;
+ UINT32 DropCts:1;
+ UINT32 DropRts:1;
+ UINT32 DropPsPoll:1;
+ UINT32 DropBA:1;
+ UINT32 DropBAR:1;
+ UINT32 DropRsvCntlType:1;
+ UINT32 rsv:15;
+ } field;
+ UINT32 word;
+} RX_FILTR_CFG_STRUC;
+#endif
+
+
+/* AUTO_RSP_CFG: Auto-Responder */
+#define AUTO_RSP_CFG 0x1404
+#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;
+#else
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+ UINT32 AutoResponderEnable:1;
+ UINT32 BACAckPolicyEnable:1;
+ UINT32 CTS40MMode:1;
+ UINT32 CTS40MRef:1;
+ UINT32 AutoResponderPreamble:1;
+ UINT32 rsv:1;
+ UINT32 DualCTSEn:1;
+ UINT32 AckCtsPsmBit:1;
+ UINT32 :24;
+ } field;
+ UINT32 word;
+} AUTO_RSP_CFG_STRUC;
+#endif
+
+
+#define LEGACY_BASIC_RATE 0x1408
+#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) */
+/* RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count */
+#define RX_STA_CNT0 0x1700
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT0_STRUC {
+ struct {
+ UINT16 PhyErr;
+ UINT16 CrcErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT0_STRUC;
+#else
+typedef union _RX_STA_CNT0_STRUC {
+ struct {
+ UINT16 CrcErr;
+ UINT16 PhyErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT0_STRUC;
+#endif
+
+
+/* RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count */
+#define RX_STA_CNT1 0x1704
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT1_STRUC {
+ struct {
+ UINT16 PlcpErr;
+ UINT16 FalseCca;
+ } field;
+ UINT32 word;
+} RX_STA_CNT1_STRUC;
+#else
+typedef union _RX_STA_CNT1_STRUC {
+ struct {
+ UINT16 FalseCca;
+ UINT16 PlcpErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT1_STRUC;
+#endif
+
+
+/* RX_STA_CNT2_STRUC: */
+#define RX_STA_CNT2 0x1708
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT2_STRUC {
+ struct {
+ UINT16 RxFifoOverflowCount;
+ UINT16 RxDupliCount;
+ } field;
+ UINT32 word;
+} RX_STA_CNT2_STRUC;
+#else
+typedef union _RX_STA_CNT2_STRUC {
+ struct {
+ UINT16 RxDupliCount;
+ UINT16 RxFifoOverflowCount;
+ } field;
+ UINT32 word;
+} RX_STA_CNT2_STRUC;
+#endif
+
+
+/* STA_CSR3: TX Beacon count */
+#define TX_STA_CNT0 0x170C
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT0_STRUC {
+ struct {
+ UINT16 TxBeaconCount;
+ UINT16 TxFailCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT0_STRUC;
+#else
+typedef union _TX_STA_CNT0_STRUC {
+ struct {
+ UINT16 TxFailCount;
+ UINT16 TxBeaconCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT0_STRUC;
+#endif
+
+
+
+/* TX_STA_CNT1: TX tx count */
+#define TX_STA_CNT1 0x1710
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT1_STRUC {
+ struct {
+ UINT16 TxRetransmit;
+ UINT16 TxSuccess;
+ } field;
+ UINT32 word;
+} TX_STA_CNT1_STRUC;
+#else
+typedef union _TX_STA_CNT1_STRUC {
+ struct {
+ UINT16 TxSuccess;
+ UINT16 TxRetransmit;
+ } field;
+ UINT32 word;
+} TX_STA_CNT1_STRUC;
+#endif
+
+
+/* TX_STA_CNT2: TX tx count */
+#define TX_STA_CNT2 0x1714
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT2_STRUC {
+ struct {
+ UINT16 TxUnderFlowCount;
+ UINT16 TxZeroLenCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT2_STRUC;
+#else
+typedef union _TX_STA_CNT2_STRUC {
+ struct {
+ UINT16 TxZeroLenCount;
+ UINT16 TxUnderFlowCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT2_STRUC;
+#endif
+
+
+/* TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register */
+#define TX_STA_FIFO 0x1718
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_FIFO_STRUC {
+ struct {
+ UINT32 Reserve:2;
+ UINT32 iTxBF:1; /* iTxBF enable */
+ UINT32 Sounding:1; /* Sounding enable */
+ UINT32 eTxBF:1; /* eTxBF enable */
+ UINT32 SuccessRate:11; /*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;
+#else
+typedef union _TX_STA_FIFO_STRUC {
+ struct {
+ UINT32 bValid:1;
+ UINT32 PidType:4;
+ UINT32 TxSuccess:1;
+ UINT32 TxAggre:1;
+ UINT32 TxAckRequired:1;
+ UINT32 wcid:8;
+ UINT32 SuccessRate:11;
+ UINT32 eTxBF:1;
+ UINT32 Sounding:1;
+ UINT32 iTxBF:1;
+ UINT32 Reserve:2;
+ } field;
+ UINT32 word;
+} TX_STA_FIFO_STRUC;
+#endif
+
+
+/*
+ Debug counters
+*/
+#define TX_AGG_CNT 0x171c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_NAG_AGG_CNT_STRUC {
+ struct {
+ UINT16 AggTxCount;
+ UINT16 NonAggTxCount;
+ } field;
+ UINT32 word;
+} TX_NAG_AGG_CNT_STRUC;
+#else
+typedef union _TX_NAG_AGG_CNT_STRUC {
+ struct {
+ UINT16 NonAggTxCount;
+ UINT16 AggTxCount;
+ } field;
+ UINT32 word;
+} TX_NAG_AGG_CNT_STRUC;
+#endif
+
+
+#define TX_AGG_CNT0 0x1720
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT0_STRUC {
+ struct {
+ UINT16 AggSize2Count;
+ UINT16 AggSize1Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT0_STRUC;
+#else
+typedef union _TX_AGG_CNT0_STRUC {
+ struct {
+ UINT16 AggSize1Count;
+ UINT16 AggSize2Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT0_STRUC;
+#endif
+
+
+#define TX_AGG_CNT1 0x1724
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT1_STRUC {
+ struct {
+ UINT16 AggSize4Count;
+ UINT16 AggSize3Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT1_STRUC;
+#else
+typedef union _TX_AGG_CNT1_STRUC {
+ struct {
+ UINT16 AggSize3Count;
+ UINT16 AggSize4Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT1_STRUC;
+#endif
+
+
+#define TX_AGG_CNT2 0x1728
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT2_STRUC {
+ struct {
+ UINT16 AggSize6Count;
+ UINT16 AggSize5Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT2_STRUC;
+#else
+typedef union _TX_AGG_CNT2_STRUC {
+ struct {
+ UINT16 AggSize5Count;
+ UINT16 AggSize6Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT2_STRUC;
+#endif
+
+
+#define TX_AGG_CNT3 0x172c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT3_STRUC {
+ struct {
+ UINT16 AggSize8Count;
+ UINT16 AggSize7Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT3_STRUC;
+#else
+typedef union _TX_AGG_CNT3_STRUC {
+ struct {
+ UINT16 AggSize7Count;
+ UINT16 AggSize8Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT3_STRUC;
+#endif
+
+
+#define TX_AGG_CNT4 0x1730
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT4_STRUC {
+ struct {
+ UINT16 AggSize10Count;
+ UINT16 AggSize9Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT4_STRUC;
+#else
+typedef union _TX_AGG_CNT4_STRUC {
+ struct {
+ UINT16 AggSize9Count;
+ UINT16 AggSize10Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT4_STRUC;
+#endif
+
+
+#define TX_AGG_CNT5 0x1734
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT5_STRUC {
+ struct {
+ UINT16 AggSize12Count;
+ UINT16 AggSize11Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT5_STRUC;
+#else
+typedef union _TX_AGG_CNT5_STRUC {
+ struct {
+ UINT16 AggSize11Count;
+ UINT16 AggSize12Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT5_STRUC;
+#endif
+
+
+#define TX_AGG_CNT6 0x1738
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT6_STRUC {
+ struct {
+ UINT16 AggSize14Count;
+ UINT16 AggSize13Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT6_STRUC;
+#else
+typedef union _TX_AGG_CNT6_STRUC {
+ struct {
+ UINT16 AggSize13Count;
+ UINT16 AggSize14Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT6_STRUC;
+#endif
+
+
+#define TX_AGG_CNT7 0x173c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT7_STRUC {
+ struct {
+ UINT16 AggSize16Count;
+ UINT16 AggSize15Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT7_STRUC;
+#else
+typedef union _TX_AGG_CNT7_STRUC {
+ struct {
+ UINT16 AggSize15Count;
+ UINT16 AggSize16Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT7_STRUC;
+#endif
+
+
+#define TX_AGG_CNT8 0x174c /* AGG_SIZE = 17,18 */
+#define TX_AGG_CNT9 0x1750 /* AGG_SIZE = 19,20 */
+#define TX_AGG_CNT10 0x1754 /* AGG_SIZE = 21,22 */
+#define TX_AGG_CNT11 0x1758 /* AGG_SIZE = 23,24 */
+#define TX_AGG_CNT12 0x175c /* AGG_SIZE = 25,26 */
+#define TX_AGG_CNT13 0x1760 /* AGG_SIZE = 27,28 */
+#define TX_AGG_CNT14 0x1764 /* AGG_SIZE = 29,30 */
+#define TX_AGG_CNT15 0x1768 /* AGG_SIZE = 31,32 */
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT_STRUC {
+ struct {
+ UINT16 AggCnt_y; /* the count of aggregation size = x + 1 */
+ UINT16 AggCnt_x; /* the count of aggregation size = x */
+ } field;
+ UINT32 word;
+} TX_AGG_CNT_STRUC;
+#else
+typedef union _TX_AGG_CNT_STRUC {
+ struct {
+ UINT16 AggCnt_x;
+ UINT16 AggCnt_y;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT_STRUC;
+#endif
+
+typedef union _TX_AGG_CNTN_STRUC {
+ struct {
+#ifdef RT_BIG_ENDIAN
+ UINT16 AggSizeHighCount;
+ UINT16 AggSizeLowCount;
+#else
+ UINT16 AggSizeLowCount;
+ UINT16 AggSizeHighCount;
+#endif
+ } field;
+ UINT32 word;
+} TX_AGG_CNTN_STRUC;
+
+
+#define MPDU_DENSITY_CNT 0x1740
+#ifdef RT_BIG_ENDIAN
+typedef union _MPDU_DEN_CNT_STRUC {
+ struct {
+ UINT16 RXZeroDelCount; /*RX zero length delimiter count */
+ UINT16 TXZeroDelCount; /*TX zero length delimiter count */
+ } field;
+ UINT32 word;
+} MPDU_DEN_CNT_STRUC;
+#else
+typedef union _MPDU_DEN_CNT_STRUC {
+ struct {
+ UINT16 TXZeroDelCount;
+ UINT16 RXZeroDelCount;
+ } field;
+ UINT32 word;
+} MPDU_DEN_CNT_STRUC;
+#endif
+
+
+#ifdef FIFO_EXT_SUPPORT
+/* TX_STA_FIFO_EXT_STRUC: TX retry cnt for specific frame */
+#define TX_STA_FIFO_EXT 0x1798 /* Only work after RT53xx */
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_FIFO_EXT_STRUC {
+ struct {
+ UINT32 Reserve:24;
+ UINT32 txRtyCnt:8; /* frame Tx retry cnt */
+ } field;
+ UINT32 word;
+} TX_STA_FIFO_EXT_STRUC;
+#else
+typedef union _TX_STA_FIFO_EXT_STRUC {
+ struct {
+ UINT32 txRtyCnt:8;
+ UINT32 Reserve:24;
+ } field;
+ UINT32 word;
+} TX_STA_FIFO_EXT_STRUC;
+#endif
+
+
+
+#define WCID_TX_CNT_0 0x176c
+#define WCID_TX_CNT_1 0x1770
+#define WCID_TX_CNT_2 0x1774
+#define WCID_TX_CNT_3 0x1778
+#define WCID_TX_CNT_4 0x177c
+#define WCID_TX_CNT_5 0x1780
+#define WCID_TX_CNT_6 0x1784
+#define WCID_TX_CNT_7 0x1788
+#ifdef RT_BIG_ENDIAN
+typedef union _WCID_TX_CNT_STRUC {
+ struct {
+ UINT32 reTryCnt:16;
+ UINT32 succCnt:16;
+ } field;
+ UINT32 word;
+} WCID_TX_CNT_STRUC;
+#else
+typedef union _WCID_TX_CNT_STRUC {
+ struct {
+ UINT32 succCnt:16;
+ UINT32 reTryCnt:16;
+ } field;
+ UINT32 word;
+} WCID_TX_CNT_STRUC;
+#endif
+
+
+#define WCID_MAPPING_0 0x178c
+#define WCID_MAPPING_1 0x1790
+#ifdef RT_BIG_ENDIAN
+typedef union _WCID_MAPPING_STRUC {
+ struct {
+ UINT32 wcid3:8;
+ UINT32 wcid2:8;
+ UINT32 wcid1:8;
+ UINT32 wcid0:8;
+ } field;
+ UINT32 word;
+} WCID_MAPPING_STRUC;
+#else
+typedef union _WCID_MAPPING_STRUC {
+ struct {
+ UINT32 wcid0:8;
+ UINT32 wcid1:8;
+ UINT32 wcid2:8;
+ UINT32 wcid3:8;
+ } field;
+ UINT32 word;
+} WCID_MAPPINGT_STRUC;
+#endif
+#endif /* FIFO_EXT_SUPPORT */
+
+
+
+/* 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
+
+
+#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;
+#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;
+#endif
+
+
+/* 64-entry for pairwise key table, 8-byte per entry */
+typedef struct _HW_WCID_ENTRY {
+ UINT8 Address[6];
+ UINT8 Rsv[2];
+} HW_WCID_ENTRY;
+
+
+/* ================================================================================= */
+/* WCID format */
+/* ================================================================================= */
+/*7.1 WCID ENTRY format : 8bytes */
+typedef struct _WCID_ENTRY_STRUC {
+ UINT8 RXBABitmap7; /* bit0 for TID8, bit7 for TID 15 */
+ UINT8 RXBABitmap0; /* bit0 for TID0, bit7 for TID 7 */
+ UINT8 MAC[6]; /* 0 for shared key table. 1 for pairwise key table */
+} WCID_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 {
+ UINT8 Key[16];
+ UINT8 TxMic[8];
+ UINT8 RxMic[8];
+} HW_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;
+#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;
+#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;
+#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;
+#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;
+#else
+typedef union _M2H_CMD_DONE_STRUC {
+ struct {
+ UINT32 CmdToken0;
+ UINT32 CmdToken1;
+ UINT32 CmdToken2;
+ UINT32 CmdToken3;
+ } field;
+ UINT32 word;
+} M2H_CMD_DONE_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;
+#else
+typedef union _HOST_CMD_CSR_STRUC {
+ struct {
+ UINT32 HostCommand:8;
+ UINT32 Rsv:24;
+ } field;
+ UINT32 word;
+} HOST_CMD_CSR_STRUC;
+#endif
+
+
+// TODO: shiang-6590, Need to check following definitions are useful or not!!!
+/* 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;
+#else
+typedef union _E2PROM_CSR_STRUC {
+ struct {
+ UINT32 Reload:1;
+ UINT32 EepromSK:1;
+ UINT32 EepromCS:1;
+ UINT32 EepromDI:1;
+ UINT32 EepromDO:1;
+ UINT32 Type:1;
+ UINT32 LoadStatus:1;
+ UINT32 Rsvd:25;
+ } field;
+ UINT32 word;
+} E2PROM_CSR_STRUC;
+#endif
+
+
+/* QOS_CSR0: TXOP holder address0 register */
+#ifdef RT_BIG_ENDIAN
+typedef union _QOS_CSR0_STRUC {
+ struct {
+ UINT8 Byte3; /* MAC address byte 3 */
+ UINT8 Byte2; /* MAC address byte 2 */
+ UINT8 Byte1; /* MAC address byte 1 */
+ UINT8 Byte0; /* MAC address byte 0 */
+ } field;
+ UINT32 word;
+} QOS_CSR0_STRUC;
+#else
+typedef union _QOS_CSR0_STRUC {
+ struct {
+ UINT8 Byte0;
+ UINT8 Byte1;
+ UINT8 Byte2;
+ UINT8 Byte3;
+ } field;
+ UINT32 word;
+} QOS_CSR0_STRUC;
+#endif
+
+
+/* QOS_CSR1: TXOP holder address1 register */
+#ifdef RT_BIG_ENDIAN
+typedef union _QOS_CSR1_STRUC {
+ struct {
+ UINT8 Rsvd1;
+ UINT8 Rsvd0;
+ UINT8 Byte5; /* MAC address byte 5 */
+ UINT8 Byte4; /* MAC address byte 4 */
+ } field;
+ UINT32 word;
+} QOS_CSR1_STRUC;
+#else
+typedef union _QOS_CSR1_STRUC {
+ struct {
+ UINT8 Byte4; /* MAC address byte 4 */
+ UINT8 Byte5; /* MAC address byte 5 */
+ UINT8 Rsvd0;
+ UINT8 Rsvd1;
+ } field;
+ UINT32 word;
+} QOS_CSR1_STRUC;
+#endif
+
+// TODO: shiang-6590, check upper definitions are useful or not!
+
+
+
+/* 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 */
+
+#ifdef WOW_SUPPORT
+/* WOW - NullFrame buffer */
+#define HW_NULL2_BASE 0x7780
+#define GPIO_HOLDTIME_OFFSET 0x7020 /* Target is 0x7023 */
+#endif /* WOW_SUPPORT */
+
+/*
+ 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_CTRL 9
+#define QID_MGMT 13
+#define QID_RX 14
+#define QID_OTHER 15
+
+
+
+
+
+#define RTMP_MAC_SHR_MSEL_PROTECT_LOCK(__pAd, __IrqFlags) __IrqFlags = __IrqFlags;
+#define RTMP_MAC_SHR_MSEL_PROTECT_UNLOCK(__pAd, __IrqFlags) __IrqFlags = __IrqFlags;
+
+
+#ifdef RTMP_MAC_USB
+#ifdef DFS_SUPPORT
+#define BBPR127TABLE_OWNERID 0x4CA0
+#define BBPR127TABLE_OFFSET 0x4D00
+#endif /* DFS_SUPPORT */
+#endif /* RTMP_MAC_USB */
+
+
+struct _RTMP_ADAPTER;
+
+INT get_pkt_phymode_by_rxwi(RXWI_STRUC *rxwi);
+INT get_pkt_rssi_by_rxwi(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *rxwi, INT size, CHAR *rssi);
+INT get_pkt_snr_by_rxwi(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *rxwi, INT size, UCHAR *snr);
+
+INT rtmp_mac_set_band(struct _RTMP_ADAPTER *pAd, int band);
+INT rtmp_mac_set_ctrlch(struct _RTMP_ADAPTER *pAd, INT extch);
+INT rtmp_mac_set_mmps(struct _RTMP_ADAPTER *pAd, INT ReduceCorePower);
+
+#endif /* __RTMP_MAC_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mat.h b/cleopatre/devkit/mt7601udrv/include/mat.h
new file mode 100644
index 0000000000..f299d8c088
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mat.h
@@ -0,0 +1,208 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ mat.h
+
+ Abstract:
+ Support AP-Client function.
+
+ Revision History:
+ Who When What
+ -------------- ---------- ----------------------------------------------
+ Shiang 02-26-2007 created
+*/
+
+#ifndef _MAT_H_
+#define _MAT_H_
+
+
+
+
+/*#if defined(LINUX) || defined (VXWORKS) */
+
+/*#else */
+/*Currently support upper layer protocols */
+#ifndef ETH_P_IP
+#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+#endif
+#ifndef ETH_P_ARP
+#define ETH_P_ARP 0x0806 /* Address Resolution packet */
+#endif
+#ifndef ETH_P_PPP_DISC
+#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
+#endif
+#ifndef ETH_P_PPP_SES
+#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
+#endif
+
+/* ARP protocol HARDWARE identifiers. */
+#ifndef ARPHRD_ETHER
+#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
+#endif
+
+/* ARP protocol opcodes. */
+#ifndef ARPOP_REQUEST
+#define ARPOP_REQUEST 1 /* ARP request */
+#endif
+#ifndef ARPOP_REPLY
+#define ARPOP_REPLY 2 /* ARP reply */
+#endif
+
+typedef struct _NET_PRO_ARP_HDR{
+ unsigned short ar_hrd; /* format of hardware address */
+ unsigned short ar_pro; /* format of protocol address */
+ unsigned char ar_hln; /* length of hardware address */
+ unsigned char ar_pln; /* length of protocol address */
+ unsigned short ar_op; /* ARP opcode (command) */
+} NET_PRO_ARP_HDR;
+
+typedef struct _NET_PRO_IP_HDR{
+#ifndef RT_BIG_ENDIAN
+ UCHAR ihl:4,
+ version:4;
+#else
+ UCHAR version:4,
+ ihl:4;
+#endif
+ UCHAR tos;
+ UINT16 tot_len;
+ UINT16 id;
+ UINT16 frag_off;
+ UCHAR ttl;
+ UCHAR protocol;
+ UINT16 check;
+ UINT16 saddr;
+ UINT32 daddr;
+} NET_PRO_IP_HDR;
+/*#endif //endif of __LINUX__ */
+
+#ifndef MAT_SUPPORT
+#error "You should define MAT_SUPPORT if you want to compile MAT related functions!"
+#endif
+
+
+/* MAT relate definition */
+#define MAT_MAX_HASH_ENTRY_SUPPORT 64
+#define MAT_TB_ENTRY_AGEOUT_TIME (5 * 60 * OS_HZ) /* 30000, 5min. MAT convert table entry age-out time interval. now set it as 5min. */
+
+
+/* 802.3 Ethernet related definition */
+#define MAT_ETHER_HDR_LEN 14 /* dstMac(6) + srcMac(6) + protoType(2) */
+#define MAT_VLAN_ETH_HDR_LEN (MAT_ETHER_HDR_LEN + 4) /* 4 for h_vlan_TCI and h_vlan_encapsulated_proto */
+
+#define MAT_MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define MAT_MAC_ADDR_HASH_INDEX(Addr) (MAT_MAC_ADDR_HASH(Addr) % MAT_MAX_HASH_ENTRY_SUPPORT)
+
+#define isMcastEtherAddr(addr) (addr[0] & 0x1)
+#define isBcastEtherAddr(addr) ((addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5])== 0xff)
+#define isZeroEtherAddr(addr) (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
+
+#define IS_GROUP_MAC(Addr) ((Addr[0]) & 0x01)
+#define IS_UCAST_MAC(addr) (!(isMcastEtherAddr(addr) || isZeroEtherAddr(addr))) /* isUcastMac = !(00:00:00:00:00:00 || mcastMac); */
+#define IS_EQUAL_MAC(a, b) (((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | (a[4] ^ b[4]) | (a[5] ^ b[5])) == 0)
+
+#define IS_VLAN_PACKET(pkt) ((((pkt)[12] << 8) | (pkt)[13]) == 0x8100)
+
+/* IPv4 related definition */
+#define IPMAC_TB_HASH_ENTRY_NUM (MAT_MAX_HASH_ENTRY_SUPPORT+1) /* One entry for broadcast address */
+#define IPMAC_TB_HASH_INDEX_OF_BCAST MAT_MAX_HASH_ENTRY_SUPPORT /* cause hash index start from 0. */
+
+#define MAT_IP_ADDR_HASH(Addr) (((Addr>>24)&0xff)^((Addr>>16) & 0xff) ^((Addr>>8) & 0xff) ^ (Addr & 0xff))
+#define MAT_IP_ADDR_HASH_INDEX(Addr) (MAT_IP_ADDR_HASH(Addr) % MAT_MAX_HASH_ENTRY_SUPPORT)
+
+#define IS_GOOD_IP(IP) (IP!= 0)
+#define IS_MULTICAST_IP(IP) (((UINT32)(IP) & 0xf0000000) == 0xe0000000)
+
+/* IPv6 related definition */
+#define IPV6MAC_TB_HASH_ENTRY_NUM (MAT_MAX_HASH_ENTRY_SUPPORT+1) /* One entry for broadcast address */
+#define IPV6MAC_TB_HASH_INDEX_OF_BCAST MAT_MAX_HASH_ENTRY_SUPPORT /* cause hash index start from 0. */
+
+/*We just use byte 10,13,14,15 to calculate the IPv6 hash, because the byte 11,12 usually are 0xff, 0xfe for link-local address. */
+#define MAT_IPV6_ADDR_HASH(Addr) ((Addr[10]&0xff) ^ (Addr[13] & 0xff) ^(Addr[14] & 0xff) ^ (Addr[15] & 0xff))
+#define MAT_IPV6_ADDR_HASH_INDEX(Addr) (MAT_IPV6_ADDR_HASH(Addr) % MAT_MAX_HASH_ENTRY_SUPPORT)
+
+#define IS_UNSPECIFIED_IPV6_ADDR(_addr) \
+ (!((_addr).ipv6_addr32[0] | (_addr).ipv6_addr32[1] | (_addr).ipv6_addr32[2] | (_addr).ipv6_addr32[3]))
+
+#define IS_LOOPBACK_IPV6_ADDR(_addr) \
+ (NdisEqualMemory((UCHAR *)(&((_addr).ipv6_addr[0])), &IPV6_LOOPBACKADDR[0], IPV6_ADDR_LEN))
+#define IS_MULTICAST_IPV6_ADDR(_addr) \
+ (((_addr).ipv6_addr[0] & 0xff) == 0xff)
+
+/* The MAT_TABLE used for MacAddress <-> UpperLayer Address Translation. */
+typedef struct _MAT_TABLE_
+{
+ VOID *IPMacTable; /* IPv4 Address, Used for IP, ARP protocol */
+ VOID *IPv6MacTable; /* IPv6 Address, Used for IPv6 related protocols */
+ VOID *SesMacTable; /* PPPoE Session */
+ VOID *UidMacTable; /* PPPoE Discovery */
+}MAT_TABLE, *PMAT_TABLE;
+
+
+typedef enum _MAT_ENGINE_STATUS_
+{
+ MAT_ENGINE_STAT_UNKNOWN = 0,
+ MAT_ENGINE_STAT_INITED = 1,
+ MAT_ENGINE_STAT_EXITED = 2,
+}MAT_ENGINE_STATUS;
+
+
+typedef struct _MAT_STRUCT_
+{
+ MAT_ENGINE_STATUS status;
+ NDIS_SPIN_LOCK MATDBLock;
+ MAT_TABLE MatTableSet;
+#ifdef KMALLOC_BATCH
+ UCHAR *pMATNodeEntryPoll;
+#endif
+ UINT32 nodeCount; /* the number of nodes which connect to Internet via us. */
+ VOID *pPriv;
+}MAT_STRUCT;
+
+
+typedef struct _MATProtoOps
+{
+ NDIS_STATUS (*init)(MAT_STRUCT *pMatCfg);
+ PUCHAR (*tx)(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
+ PUCHAR (*rx)(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
+ NDIS_STATUS (*exit)(MAT_STRUCT *pMatCfg);
+}MATProtoOps, *PMATProtoOps;
+
+
+typedef struct _MATProtoTable
+{
+ USHORT protocol;
+ MATProtoOps *pHandle;
+}MATProtoTable, *PMATProtoTable;
+
+
+VOID dumpPkt(PUCHAR pHeader, int len);
+
+/*#define KMALLOC_BATCH */
+
+PUCHAR MATDBEntryAlloc(
+ IN MAT_STRUCT *pMatStruct,
+ IN UINT32 size);
+
+NDIS_STATUS MATDBEntryFree(
+ IN MAT_STRUCT *pMatStruct,
+ IN PUCHAR NodeEntry);
+
+
+#endif /* _MAT_H_ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mcu/MT7601_firmware.h b/cleopatre/devkit/mt7601udrv/include/mcu/MT7601_firmware.h
new file mode 100644
index 0000000000..cbe033924a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mcu/MT7601_firmware.h
@@ -0,0 +1,2844 @@
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+UCHAR MT7601_FirmwareImage[] = {
+0x44, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x76, 0x00, 0x01, 0x41, 0x76, 0x06, 0x02,
+0x32, 0x30, 0x31, 0x33, 0x30, 0x32, 0x30, 0x35, 0x32, 0x31, 0x34, 0x36, 0x5f, 0x5f, 0x5f, 0x5f,
+0x48, 0x00, 0x00, 0x52, 0x48, 0x00, 0x00, 0x1e, 0x48, 0x00, 0x00, 0x1c, 0x48, 0x00, 0x00, 0x1a,
+0x48, 0x00, 0x00, 0x18, 0x48, 0x00, 0x00, 0x16, 0x48, 0x00, 0x00, 0x14, 0x48, 0x00, 0x00, 0x12,
+0x48, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x0e, 0x48, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x0a,
+0x48, 0x00, 0x00, 0x08, 0x48, 0x00, 0x00, 0x06, 0x48, 0x00, 0x00, 0x04, 0x48, 0x00, 0x00, 0x02,
+0x92, 0x00, 0x48, 0x00, 0x00, 0x00, 0x92, 0x00, 0x3a, 0x0f, 0xab, 0xbc, 0x3a, 0xff, 0xbc, 0x3c,
+0x64, 0x62, 0x04, 0x02, 0x64, 0x72, 0xa4, 0x02, 0x64, 0x82, 0x00, 0x02, 0x3a, 0x6f, 0xa0, 0x3c,
+0x46, 0x00, 0x00, 0x0e, 0x58, 0x00, 0x01, 0x54, 0xb4, 0x00, 0x15, 0xf0, 0x00, 0x00, 0x46, 0x10,
+0x00, 0x05, 0x58, 0x10, 0x89, 0xf0, 0xdd, 0x21, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00, 0x01, 0x54,
+0xb4, 0x00, 0x05, 0xf0, 0x00, 0x00, 0x3a, 0x6f, 0xa0, 0x04, 0x64, 0x62, 0x04, 0x03, 0x64, 0x72,
+0xa4, 0x03, 0x64, 0x82, 0x00, 0x03, 0x3a, 0xff, 0xbc, 0x04, 0x3a, 0x0f, 0xab, 0x84, 0x64, 0x00,
+0x00, 0x04, 0x92, 0x00, 0x84, 0x0a, 0x64, 0x02, 0x00, 0x03, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00,
+0x02, 0x00, 0x44, 0x10, 0x04, 0x01, 0xa8, 0x41, 0x84, 0x00, 0x64, 0x02, 0x24, 0x03, 0x46, 0x0c,
+0x00, 0x00, 0x58, 0x00, 0x00, 0x02, 0x64, 0x03, 0x00, 0x03, 0x47, 0xf0, 0x00, 0x0f, 0x59, 0xff,
+0x8f, 0x00, 0x46, 0x00, 0x00, 0x0a, 0x58, 0x00, 0x06, 0xe0, 0x46, 0x10, 0x00, 0x0a, 0x58, 0x10,
+0x8e, 0xe0, 0x84, 0x40, 0xd5, 0x02, 0xaa, 0x81, 0x4c, 0x10, 0x7f, 0xff, 0x46, 0x00, 0x00, 0x0b,
+0x58, 0x00, 0x01, 0x50, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x81, 0x94, 0x84, 0x40, 0xd5, 0x02,
+0xaa, 0x81, 0x4c, 0x10, 0x7f, 0xff, 0x48, 0x00, 0x2b, 0xf3, 0x92, 0x00, 0x84, 0x80, 0xa8, 0xc5,
+0xa9, 0x01, 0xa8, 0x46, 0xa8, 0x84, 0xb6, 0x80, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0xb4, 0x20, 0xc1, 0x17, 0xa1, 0x41, 0x84, 0x80, 0xa9, 0x49, 0xb6, 0x25, 0xb6, 0x80,
+0xa9, 0x01, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x40, 0xa0, 0xc2, 0xb4, 0x20, 0x9e, 0x99,
+0xa8, 0x82, 0x4c, 0x10, 0x40, 0x08, 0xa0, 0x0b, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x90,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x27, 0x83, 0x93, 0x80, 0xe0, 0xc2, 0x11, 0x80, 0x02,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x90, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07,
+0x83, 0x93, 0x80, 0x27, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x80, 0x18, 0xdd, 0x2f, 0xec, 0x04,
+0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x8f, 0x30, 0xdd, 0x2f, 0x46, 0x17, 0xff, 0xff, 0x58, 0x10, 0x8f, 0xff,
+0x46, 0x20, 0x00, 0x0d, 0x58, 0x21, 0x0e, 0x40, 0x81, 0x00, 0x40, 0xa0, 0x04, 0x00, 0x44, 0x00,
+0xea, 0x60, 0x14, 0xa1, 0x00, 0x04, 0x80, 0xe2, 0xb4, 0xc2, 0x41, 0xc4, 0x00, 0x00, 0xd5, 0x2e,
+0xa0, 0x32, 0x40, 0x34, 0x00, 0x01, 0x4e, 0x35, 0x00, 0x21, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x81, 0x1c, 0xdd, 0x2f, 0xa4, 0x36, 0xc0, 0x10, 0x9e, 0x01, 0xac, 0x36, 0x15, 0xc3,
+0x00, 0x02, 0x05, 0xe3, 0x80, 0x01, 0xa9, 0xb9, 0xb6, 0xe6, 0x15, 0xe3, 0x00, 0x01, 0xb6, 0xde,
+0xa1, 0x7a, 0x9d, 0x29, 0xa9, 0x3a, 0xd5, 0x06, 0xa0, 0xb6, 0xc2, 0x04, 0xa0, 0x75, 0xa0, 0x34,
+0xdd, 0x22, 0x14, 0xa3, 0x80, 0x04, 0xd5, 0x09, 0xa0, 0xbc, 0x40, 0x90, 0x08, 0x01, 0x4e, 0x95,
+0x00, 0x03, 0xd5, 0x02, 0xa8, 0x3c, 0x81, 0x26, 0xb4, 0xc9, 0x46, 0x90, 0x00, 0x0d, 0x58, 0x94,
+0x8e, 0x40, 0x4c, 0x64, 0xff, 0xcf, 0xb4, 0xa6, 0xd6, 0x09, 0xa0, 0xf4, 0x40, 0x01, 0xa0, 0x01,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x81, 0x5c, 0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x80, 0xe1, 0x44, 0x10, 0xea, 0x60,
+0x80, 0xc0, 0xe2, 0x27, 0xe8, 0x0e, 0x40, 0x03, 0x84, 0x57, 0x44, 0x2f, 0x15, 0xa0, 0x96, 0x01,
+0x42, 0x70, 0x08, 0x73, 0xac, 0x36, 0xcf, 0x07, 0x9e, 0xc1, 0xac, 0xf6, 0x80, 0xe1, 0xd5, 0x03,
+0x84, 0x20, 0xac, 0x46, 0x46, 0x80, 0x00, 0x0d, 0x58, 0x84, 0x0e, 0x40, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x8f, 0x30, 0xdd, 0x2f, 0xb4, 0x88, 0x40, 0x90, 0x1c, 0x00, 0x4c, 0x44, 0x00, 0x08,
+0x05, 0xe4, 0x00, 0x04, 0x40, 0x54, 0xf8, 0x01, 0x4e, 0x54, 0x00, 0x0c, 0x46, 0xf0, 0x00, 0x0d,
+0x14, 0x97, 0x83, 0x94, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x81, 0x5c, 0xdd, 0x2f,
+0xb4, 0x06, 0x14, 0x93, 0x00, 0x02, 0xc8, 0x0f, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x47, 0x83, 0x91,
+0x14, 0x64, 0x00, 0x01, 0xb7, 0x06, 0xa9, 0x31, 0xb6, 0xc4, 0x04, 0x14, 0x00, 0x02, 0x9c, 0xc9,
+0x14, 0x34, 0x00, 0x02, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc,
+0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0e, 0x40, 0xa0, 0x33, 0x84, 0x20, 0xa8, 0x72, 0xb6, 0xc6,
+0xa9, 0xb1, 0xc8, 0x08, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0x20, 0xdd, 0x2f, 0xa8, 0x33,
+0xd5, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x90, 0xdd, 0x2f, 0x3a, 0x6f, 0x98, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x80, 0xc0, 0x50, 0x0f, 0x80, 0x04,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70, 0xdd, 0x2f, 0xa0, 0x32, 0xc8, 0x02, 0xd5, 0x09,
+0x9e, 0x01, 0xa8, 0x32, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0xf8, 0xdd, 0x2f,
+0x80, 0xc0, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84, 0xdd, 0x2f, 0x80, 0x06,
+0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xf4, 0x80, 0xc0,
+0x50, 0x0f, 0x80, 0x04, 0x80, 0xe1, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70, 0xdd, 0x2f,
+0xa0, 0xb2, 0x80, 0x06, 0x9c, 0x51, 0xa8, 0x72, 0x80, 0x27, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8b, 0xec, 0xdd, 0x2f, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84, 0xdd, 0x2f,
+0xec, 0x0c, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0x00, 0x00, 0x0d,
+0x58, 0x00, 0x0e, 0x54, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0xe4, 0xdd, 0x2f, 0x46, 0x70,
+0x00, 0x0b, 0x58, 0x73, 0x81, 0x70, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0b, 0xa0, 0x46, 0x80,
+0x00, 0x00, 0x58, 0x84, 0x03, 0x68, 0xa9, 0xf2, 0x80, 0x26, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00,
+0x0e, 0x54, 0x4b, 0xe0, 0x20, 0x01, 0x50, 0x73, 0x86, 0x40, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52,
+0x86, 0xf0, 0x8c, 0xd8, 0xdf, 0xf1, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x64, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8b, 0xe4, 0xdd, 0x2f, 0x46, 0x70, 0x00, 0x0d, 0x58, 0x73, 0x86, 0xf0,
+0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0c, 0x30, 0x46, 0x80, 0x00, 0x00, 0x58, 0x84, 0x03, 0x68,
+0xa9, 0xf2, 0x80, 0x26, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x64, 0x4b, 0xe0, 0x20, 0x01,
+0x50, 0x73, 0x80, 0xc8, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8b, 0xa0, 0x8c, 0xd8, 0xdf, 0xf1,
+0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x30, 0x04, 0x00,
+0xb4, 0x43, 0x44, 0x50, 0x76, 0x10, 0x40, 0x01, 0x40, 0x09, 0xd8, 0x07, 0x83, 0xc3, 0x04, 0x5f,
+0x00, 0x41, 0x42, 0x42, 0xd0, 0x0b, 0xc4, 0x0f, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8f, 0x9c,
+0xdd, 0x2f, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x07, 0x81, 0x64, 0x46, 0xf0, 0x00, 0x0b,
+0x10, 0x07, 0x81, 0x63, 0x46, 0x60, 0x00, 0x03, 0x58, 0x63, 0x01, 0xf8, 0x44, 0x00, 0x00, 0x10,
+0x46, 0x10, 0x00, 0x03, 0x58, 0x10, 0x84, 0x38, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x11, 0x46, 0x10,
+0x00, 0x03, 0x58, 0x10, 0x84, 0x48, 0xdd, 0x26, 0x84, 0x00, 0x46, 0x10, 0x00, 0x03, 0x58, 0x10,
+0x84, 0x58, 0xdd, 0x26, 0x84, 0x01, 0x46, 0x10, 0x00, 0x03, 0x58, 0x10, 0x84, 0x68, 0xdd, 0x26,
+0x44, 0x00, 0x00, 0x19, 0x46, 0x10, 0x00, 0x03, 0x58, 0x10, 0x84, 0x78, 0xdd, 0x26, 0x46, 0x10,
+0x00, 0x03, 0x58, 0x10, 0x85, 0x74, 0x44, 0x00, 0x00, 0x18, 0xdd, 0x26, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x83, 0xa8, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x83, 0x44, 0xdd, 0x2f, 0x84, 0xc0, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x8c, 0xb0, 0xdd, 0x2f, 0x46, 0x30, 0x00, 0x0d, 0x58, 0x31, 0x8e, 0x74, 0x84, 0x80, 0x10, 0x41,
+0x82, 0xa8, 0x14, 0x61, 0x80, 0x2d, 0x50, 0x01, 0x82, 0xaa, 0x80, 0x26, 0x84, 0x48, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x46, 0x30, 0x04, 0x10, 0x58, 0x31, 0x88, 0x00,
+0xa9, 0x9c, 0x46, 0x00, 0x30, 0x00, 0xa1, 0x5b, 0x40, 0x42, 0x80, 0x04, 0xa9, 0x1b, 0x3a, 0x6f,
+0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x9c, 0x3c, 0x96, 0x00, 0x96, 0x48, 0x95, 0x82, 0x99, 0x71,
+0x44, 0x32, 0x0d, 0x60, 0x99, 0x2b, 0x00, 0x31, 0x00, 0x40, 0x95, 0x25, 0x84, 0xa0, 0x38, 0x71,
+0x14, 0x00, 0x99, 0xac, 0xaf, 0xf0, 0x9d, 0x69, 0x44, 0x70, 0x00, 0x10, 0xdf, 0xf9, 0x9b, 0x94,
+0x50, 0x52, 0x00, 0x18, 0x50, 0x22, 0x00, 0x10, 0x38, 0x73, 0x08, 0x00, 0x18, 0x71, 0x00, 0x01,
+0xda, 0xfc, 0x50, 0x42, 0x00, 0x20, 0x38, 0x23, 0x14, 0x00, 0x18, 0x22, 0x80, 0x01, 0xdc, 0xfc,
+0x46, 0x40, 0x01, 0x06, 0x40, 0x20, 0x04, 0x09, 0x58, 0x42, 0x0c, 0x00, 0x99, 0x54, 0x94, 0xaa,
+0x97, 0x04, 0xb4, 0x02, 0xcc, 0x1d, 0xc9, 0x05, 0x54, 0x31, 0x80, 0x0f, 0x84, 0xd0, 0xd5, 0x39,
+0x84, 0xa1, 0xd9, 0x07, 0x54, 0x11, 0x80, 0x0f, 0x94, 0xcc, 0x44, 0x6f, 0xff, 0x0f, 0xd5, 0x31,
+0x84, 0x82, 0x54, 0x31, 0x80, 0x0f, 0x4c, 0x12, 0x40, 0x07, 0x40, 0x31, 0xa0, 0x08, 0x44, 0x6f,
+0xf0, 0xff, 0xd5, 0x27, 0x40, 0x31, 0xb0, 0x08, 0x44, 0x1f, 0x0f, 0xff, 0xd5, 0x2b, 0xc9, 0x0c,
+0x46, 0x5f, 0xff, 0x0f, 0x54, 0x31, 0x80, 0x0f, 0x58, 0x52, 0x8f, 0xff, 0x40, 0x31, 0xc0, 0x08,
+0x40, 0x00, 0x14, 0x02, 0xd5, 0x21, 0x84, 0xa1, 0xd9, 0x0a, 0x54, 0x11, 0x80, 0x0f, 0x40, 0x30,
+0xd0, 0x08, 0x46, 0x1f, 0xf0, 0xff, 0x58, 0x10, 0x8f, 0xff, 0xd5, 0x14, 0x84, 0xa2, 0xd9, 0x0c,
+0x54, 0x61, 0x80, 0x0f, 0x40, 0x33, 0x60, 0x08, 0x46, 0x6f, 0x0f, 0xff, 0x58, 0x63, 0x0f, 0xff,
+0x40, 0x00, 0x18, 0x02, 0xd5, 0x09, 0x46, 0x10, 0xff, 0xff, 0x40, 0x31, 0xf0, 0x08, 0x58, 0x10,
+0x8f, 0xff, 0x40, 0x00, 0x04, 0x02, 0x40, 0x00, 0x0c, 0x04, 0xb6, 0x02, 0x3a, 0x6f, 0x9c, 0x04,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xfc, 0x02, 0x10, 0x00, 0x0a, 0xa1, 0x84,
+0x5c, 0xf0, 0x80, 0x66, 0xe9, 0x2a, 0x51, 0xc0, 0xff, 0x9a, 0x84, 0xe0, 0x46, 0xa0, 0x01, 0x02,
+0x58, 0xa5, 0x06, 0xd4, 0x80, 0x06, 0x46, 0x10, 0x00, 0x0b, 0x58, 0x10, 0x80, 0x14, 0x84, 0x46,
+0x4b, 0xe0, 0x28, 0x01, 0xc8, 0x15, 0x81, 0x20, 0x50, 0x83, 0x00, 0x06, 0x80, 0x08, 0x46, 0x10,
+0x00, 0x0e, 0x58, 0x10, 0x81, 0x28, 0x84, 0x46, 0x8d, 0x21, 0x4b, 0xe0, 0x28, 0x01, 0xc8, 0x09,
+0x44, 0x50, 0x00, 0x10, 0x8d, 0x06, 0x4c, 0x92, 0xff, 0xf3, 0x84, 0x01, 0xd5, 0x07, 0x9d, 0xb1,
+0x9d, 0xf9, 0x40, 0xfe, 0x1c, 0x06, 0xe8, 0xdf, 0x84, 0x00, 0xec, 0x04, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x44, 0x30, 0x01, 0x0c, 0x54, 0xa0,
+0x80, 0xff, 0x42, 0x65, 0x0c, 0x24, 0x54, 0x91, 0x00, 0xff, 0x44, 0x20, 0x00, 0x43, 0x42, 0x64,
+0x88, 0x73, 0x97, 0xc0, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0f, 0xa4, 0x99, 0xb0, 0x84, 0x20,
+0x97, 0x20, 0x80, 0x06, 0x81, 0x05, 0xf4, 0x81, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08,
+0xdd, 0x2f, 0x84, 0x24, 0x4c, 0x70, 0xc0, 0x04, 0x84, 0x03, 0xd5, 0x09, 0x84, 0x46, 0x4c, 0x71,
+0x40, 0x04, 0x84, 0x04, 0xd5, 0x04, 0x84, 0xab, 0xdf, 0x04, 0x84, 0x02, 0x10, 0x03, 0x00, 0x40,
+0x41, 0xe0, 0x88, 0x08, 0x11, 0xe3, 0x00, 0x41, 0x80, 0x28, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73,
+0x86, 0xa4, 0x80, 0x06, 0x80, 0x5e, 0xdd, 0x27, 0x01, 0xc3, 0x00, 0x40, 0x84, 0x23, 0x4d, 0xc0,
+0xc0, 0x1b, 0xf4, 0x01, 0x50, 0x54, 0x00, 0x18, 0x50, 0x33, 0x00, 0x10, 0x8d, 0x10, 0x51, 0xc3,
+0x00, 0x18, 0xc4, 0x09, 0xb6, 0xbf, 0x80, 0x03, 0x80, 0x28, 0x84, 0x48, 0xdd, 0x27, 0xb4, 0x3f,
+0x80, 0x1c, 0xd5, 0x07, 0x80, 0x25, 0x80, 0x03, 0x84, 0x48, 0xdd, 0x27, 0x80, 0x1c, 0x80, 0x28,
+0x84, 0x48, 0xdd, 0x27, 0x80, 0x0a, 0x80, 0x29, 0x80, 0x46, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7,
+0x85, 0x44, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc,
+0x44, 0x30, 0x01, 0x0c, 0x97, 0x00, 0x42, 0x62, 0x0c, 0x24, 0x46, 0x20, 0x00, 0x0d, 0x58, 0x21,
+0x0f, 0xa4, 0x99, 0xb2, 0x81, 0x01, 0x80, 0x06, 0x84, 0x20, 0x44, 0x20, 0x00, 0x43, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x07, 0x80, 0xb1,
+0x84, 0xa4, 0xd8, 0x03, 0x84, 0x03, 0xd5, 0x04, 0x84, 0xa6, 0xd8, 0x24, 0x84, 0x04, 0x45, 0xe0,
+0x00, 0x10, 0x10, 0x03, 0x00, 0x40, 0x11, 0xe3, 0x00, 0x41, 0x50, 0x14, 0x00, 0x20, 0x46, 0x70,
+0x01, 0x02, 0x58, 0x73, 0x86, 0xa4, 0x80, 0x06, 0x80, 0x5e, 0x4b, 0xe0, 0x1c, 0x01, 0x00, 0x03,
+0x00, 0x40, 0x84, 0xa3, 0xd8, 0x0f, 0x50, 0x14, 0x00, 0x38, 0x84, 0x48, 0x50, 0x03, 0x00, 0x10,
+0x4b, 0xe0, 0x1c, 0x01, 0x50, 0x03, 0x00, 0x18, 0x50, 0x14, 0x00, 0x30, 0x84, 0x48, 0x4b, 0xe0,
+0x1c, 0x01, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xdc, 0x97, 0x20,
+0x55, 0xc0, 0x80, 0xff, 0x54, 0x91, 0x00, 0xff, 0x96, 0xd8, 0xc4, 0x44, 0x84, 0x23, 0x4c, 0x30,
+0x80, 0x05, 0x84, 0x45, 0x4c, 0x31, 0x40, 0x70, 0x85, 0x40, 0x80, 0xe0, 0x81, 0x2a, 0x81, 0x0a,
+0x80, 0xdf, 0xd5, 0x30, 0xa6, 0x38, 0x44, 0x30, 0x00, 0xdd, 0x4c, 0x01, 0xc0, 0x26, 0x9c, 0x3a,
+0x46, 0x10, 0x00, 0x0a, 0x58, 0x10, 0x8f, 0xf0, 0x84, 0x43, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x86, 0xd4, 0xdd, 0x2f, 0xc8, 0x19, 0xa7, 0x7d, 0x87, 0xc1, 0x4c, 0x5f, 0x40, 0x16, 0xa7, 0x39,
+0x00, 0x93, 0x80, 0x06, 0x50, 0x82, 0x7f, 0xfa, 0x54, 0x84, 0x00, 0xff, 0x50, 0x13, 0x80, 0x08,
+0x80, 0x1f, 0x80, 0x48, 0x54, 0x94, 0x80, 0x03, 0xe7, 0x10, 0xe9, 0x40, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xa6, 0xb9, 0x9c, 0x52, 0x89, 0x41, 0x99, 0xf9, 0x54, 0xa5,
+0x00, 0xff, 0xa7, 0x79, 0x9c, 0xea, 0x40, 0x01, 0xa8, 0x00, 0x40, 0xfe, 0x00, 0x07, 0xe8, 0xcb,
+0xd5, 0x0f, 0x84, 0xc5, 0x4c, 0x33, 0x40, 0x30, 0x80, 0x20, 0x80, 0x5c, 0x80, 0x1f, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xe7, 0x24, 0xe8, 0x20, 0x81, 0x1c, 0x46, 0x60,
+0x00, 0x0d, 0x58, 0x63, 0x0e, 0x74, 0x80, 0x48, 0x80, 0x3f, 0x50, 0x03, 0x01, 0x10, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x84, 0x20, 0x00, 0x03, 0x02, 0x3e, 0x10, 0x93,
+0x02, 0x3c, 0x80, 0x49, 0x50, 0x53, 0x01, 0x10, 0x80, 0x61, 0x80, 0x81, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x86, 0xb4, 0xdd, 0x2f, 0x84, 0x01, 0xd5, 0x02, 0x84, 0x00, 0xec, 0x24, 0x3a, 0x6f,
+0xaa, 0x84, 0xdd, 0x9e, 0x85, 0x20, 0x81, 0x09, 0xd5, 0xdb, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0x94, 0x85, 0x40, 0x80, 0xc2, 0x55, 0xc0, 0x00, 0xff, 0x44, 0x00, 0x02, 0x00, 0x81, 0x21,
+0x14, 0xaf, 0x80, 0x19, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8c, 0x14, 0xdd, 0x2f, 0xa7, 0x32,
+0xa6, 0x73, 0x40, 0x32, 0x20, 0x08, 0x40, 0x21, 0x84, 0x04, 0x9c, 0x94, 0x50, 0x1f, 0x80, 0x64,
+0x80, 0x66, 0x84, 0x9f, 0x50, 0x8f, 0x80, 0x54, 0x80, 0xe0, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x8a, 0xd0, 0xdd, 0x2f, 0x80, 0x2a, 0x80, 0x08, 0x44, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x84, 0x02, 0x4d, 0xc0, 0x40, 0x1a, 0x50, 0xaf, 0x80, 0x04,
+0xf3, 0x19, 0x80, 0x09, 0x80, 0x47, 0x80, 0x8a, 0x44, 0x50, 0x00, 0x14, 0x9e, 0x6c, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x82, 0x70, 0xdd, 0x2f, 0x80, 0x08, 0x80, 0x2a, 0x44, 0x20, 0x00, 0x10,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xd5, 0x0d, 0x44, 0x10, 0x00, 0x10,
+0xf3, 0x19, 0x80, 0x09, 0x80, 0x88, 0x80, 0x47, 0x80, 0xa1, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x81, 0x2c, 0xdd, 0x2f, 0x50, 0x1f, 0x80, 0x54, 0x44, 0x20, 0x00, 0x10, 0x50, 0x03, 0x00, 0x51,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8c, 0x28, 0xdd, 0x2f, 0xec, 0x6c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x87, 0x80, 0xb3, 0xf6, 0x0c,
+0x84, 0xe3, 0x85, 0x21, 0x84, 0xa0, 0x44, 0x00, 0x00, 0x5f, 0xaf, 0xf1, 0x10, 0x93, 0x00, 0x00,
+0xaf, 0x72, 0xae, 0x33, 0x83, 0x83, 0xf4, 0x81, 0x97, 0xc8, 0x96, 0x90, 0x4e, 0x82, 0x00, 0x04,
+0x84, 0x02, 0xd5, 0x02, 0x84, 0x1e, 0xae, 0x34, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x17, 0x80, 0xb4,
+0xc1, 0x03, 0x85, 0x23, 0xd5, 0x0d, 0x46, 0xf0, 0x00, 0x0e, 0x01, 0xe7, 0x80, 0xb1, 0x84, 0x81,
+0x56, 0x3f, 0x00, 0x06, 0x85, 0x42, 0x40, 0x95, 0x0c, 0x1a, 0x40, 0x92, 0x0c, 0x1b, 0xa7, 0x76,
+0x40, 0x02, 0x8c, 0x09, 0x94, 0x03, 0x40, 0x00, 0x24, 0x04, 0xae, 0x36, 0xe6, 0xe5, 0xe9, 0x04,
+0x42, 0x00, 0x0c, 0x09, 0xd5, 0x03, 0x58, 0x00, 0x00, 0x08, 0xae, 0x36, 0x4e, 0x83, 0x00, 0x14,
+0xe6, 0xe5, 0xe9, 0x11, 0xa7, 0x76, 0x54, 0x11, 0x00, 0x03, 0x44, 0x3f, 0xff, 0xcf, 0x94, 0x0c,
+0x41, 0xe2, 0x8c, 0x02, 0x40, 0xaf, 0x00, 0x04, 0x84, 0x43, 0x10, 0xa3, 0x00, 0x06, 0x4c, 0x71,
+0x40, 0x0f, 0xd5, 0x0f, 0x84, 0x83, 0x4c, 0x72, 0x40, 0x08, 0x00, 0xa3, 0x00, 0x06, 0x58, 0x25,
+0x00, 0x40, 0xae, 0xb6, 0xd5, 0x06, 0x87, 0xc1, 0x4c, 0x7f, 0x00, 0x04, 0x84, 0xa5, 0xdf, 0x09,
+0xa7, 0x36, 0x44, 0x1f, 0xff, 0x80, 0x40, 0x32, 0x04, 0x04, 0x84, 0xa1, 0xae, 0xf6, 0xd7, 0x06,
+0x00, 0xa3, 0x00, 0x05, 0x58, 0x25, 0x00, 0x01, 0xae, 0xb5, 0x4e, 0x82, 0x00, 0x05, 0xe6, 0xe3,
+0xe8, 0x04, 0xd5, 0x0c, 0xe6, 0xe5, 0xe9, 0x17, 0xa6, 0x35, 0x59, 0xe0, 0x00, 0x02, 0x11, 0xe3,
+0x00, 0x05, 0x4e, 0x82, 0x00, 0x11, 0x84, 0xa3, 0xd7, 0x03, 0x84, 0xa5, 0xdf, 0x05, 0xa6, 0x75,
+0x58, 0x40, 0x80, 0x10, 0xaf, 0x35, 0x4e, 0x82, 0x00, 0x07, 0x84, 0x41, 0x4c, 0x71, 0x00, 0x04,
+0x84, 0xa3, 0xdf, 0x10, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x47, 0x80, 0xb1, 0x44, 0x00, 0x00, 0x10,
+0x56, 0x32, 0x00, 0x04, 0x95, 0x41, 0x41, 0xe2, 0x8c, 0x1a, 0x41, 0xe0, 0x0c, 0x1b, 0x11, 0xe3,
+0x00, 0x08, 0x50, 0x03, 0x00, 0x09, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8f, 0x3c, 0x84, 0x48,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0xe6, 0xe4, 0xe9, 0x05, 0x4e, 0x83,
+0x00, 0x26, 0x84, 0xa5, 0xdf, 0x23, 0x46, 0xa0, 0x01, 0x02, 0x58, 0xa5, 0x06, 0xa4, 0x50, 0x03,
+0x00, 0x11, 0x80, 0x3c, 0x44, 0x20, 0x00, 0x20, 0x4b, 0xe0, 0x28, 0x01, 0x4e, 0x83, 0x00, 0x12,
+0x84, 0xa5, 0xdf, 0x0f, 0x50, 0x1e, 0x00, 0x10, 0x50, 0x03, 0x00, 0x31, 0x44, 0x20, 0x00, 0x10,
+0x4b, 0xe0, 0x28, 0x01, 0x00, 0x53, 0x00, 0x40, 0x9c, 0x2a, 0x10, 0x03, 0x00, 0x40, 0xd5, 0x08,
+0x84, 0xa3, 0xdf, 0x04, 0x4e, 0x83, 0x00, 0x05, 0xd5, 0x0c, 0x84, 0xa5, 0xdf, 0x0a, 0xf1, 0x01,
+0x50, 0x03, 0x00, 0x41, 0x84, 0x46, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f,
+0x84, 0x20, 0x50, 0x03, 0x00, 0x51, 0x44, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x87, 0x08, 0xdd, 0x2f, 0x84, 0xa1, 0xd7, 0x0c, 0x80, 0x09, 0x80, 0x46, 0x46, 0x10, 0x00, 0x0d,
+0x58, 0x10, 0x8f, 0x44, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x89, 0x0c, 0xdd, 0x2f, 0xec, 0x0c,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xee, 0x84, 0x46, 0x80,
+0x01, 0x02, 0x58, 0x84, 0x07, 0x08, 0x50, 0x60, 0x00, 0x5b, 0x84, 0x20, 0x97, 0xd0, 0x50, 0x0f,
+0x81, 0x60, 0x44, 0x20, 0x00, 0x10, 0xdd, 0x28, 0x84, 0x20, 0x44, 0x20, 0x00, 0x50, 0x50, 0x0f,
+0x81, 0x00, 0xdd, 0x28, 0x50, 0x9f, 0x81, 0x74, 0x84, 0x20, 0x44, 0x20, 0x00, 0xff, 0x80, 0x1f,
+0xdd, 0x28, 0x84, 0x20, 0x84, 0x42, 0x80, 0x09, 0xdd, 0x28, 0x50, 0x13, 0x7f, 0xaa, 0x80, 0x09,
+0x84, 0x42, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x84, 0x01, 0x46, 0xf0,
+0x00, 0x0e, 0x00, 0x87, 0x80, 0xb3, 0x4c, 0x70, 0x00, 0x08, 0x84, 0x43, 0x4c, 0x71, 0x00, 0x05,
+0x84, 0x65, 0x4c, 0x71, 0xc0, 0x26, 0x51, 0xcf, 0x81, 0x50, 0x84, 0x20, 0x84, 0x48, 0x80, 0x1c,
+0x50, 0xa3, 0x7f, 0xae, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x46, 0x90,
+0x00, 0x02, 0x58, 0x94, 0x88, 0xd8, 0x80, 0x0a, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8f, 0x3c,
+0x84, 0x48, 0x4b, 0xe0, 0x24, 0x01, 0x84, 0x81, 0x4c, 0x02, 0x00, 0x09, 0x80, 0x0a, 0x80, 0x3c,
+0x84, 0x48, 0x4b, 0xe0, 0x24, 0x01, 0x4e, 0x03, 0x00, 0xcc, 0x84, 0xa1, 0xd7, 0x6a, 0x00, 0xa3,
+0x7f, 0xa7, 0x00, 0x93, 0x7f, 0xa8, 0x41, 0xe5, 0x20, 0x08, 0x50, 0xa3, 0x7f, 0xf6, 0x41, 0xcf,
+0x24, 0x04, 0x80, 0x2a, 0x44, 0x20, 0x00, 0x10, 0x46, 0x90, 0x01, 0x02, 0x58, 0x94, 0x86, 0xa4,
+0x50, 0x0f, 0x81, 0x50, 0x4b, 0xe0, 0x24, 0x01, 0x84, 0x20, 0x80, 0x0a, 0x44, 0x20, 0x00, 0x10,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x00, 0x0f, 0x81, 0x75, 0x84, 0x21,
+0x54, 0x00, 0x00, 0x07, 0x51, 0xce, 0x00, 0x04, 0x4c, 0x00, 0xc0, 0x18, 0x46, 0x90, 0x00, 0x0d,
+0x58, 0x94, 0x8e, 0x74, 0x85, 0x44, 0x8c, 0x2f, 0x10, 0xa4, 0x82, 0x3d, 0x50, 0x04, 0x80, 0xd0,
+0x80, 0x7c, 0x50, 0x23, 0x7f, 0xa5, 0x50, 0x4f, 0x81, 0x60, 0x80, 0xa1, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x81, 0x2c, 0xdd, 0x2f, 0xd5, 0x21, 0x84, 0x42, 0x4c, 0x01, 0x40, 0x1f, 0x46, 0xa0,
+0x00, 0x0d, 0x58, 0xa5, 0x0e, 0x74, 0x80, 0x7c, 0x87, 0x86, 0x11, 0xc5, 0x02, 0x3d, 0x50, 0x05,
+0x00, 0xd0, 0x8c, 0x2f, 0x50, 0x23, 0x7f, 0xa5, 0x50, 0x4f, 0x81, 0x00, 0x9d, 0x4c, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x82, 0x70, 0xdd, 0x2f, 0x50, 0x1f, 0x81, 0x00, 0x50, 0x0f, 0x81, 0x60,
+0x44, 0x20, 0x00, 0x10, 0x4b, 0xe0, 0x24, 0x01, 0x50, 0x0f, 0x81, 0x50, 0x50, 0x1f, 0x81, 0x60,
+0x44, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xd4, 0xdd, 0x2f, 0xc8, 0x60,
+0xa7, 0x76, 0xa7, 0x37, 0x40, 0x32, 0xa0, 0x08, 0x40, 0x31, 0x90, 0x04, 0x4e, 0x36, 0x00, 0x04,
+0x84, 0x01, 0xd5, 0x57, 0x84, 0x23, 0x4c, 0x70, 0xc0, 0x05, 0x4e, 0x83, 0x00, 0x06, 0xd5, 0x42,
+0x84, 0x05, 0x4c, 0x70, 0x40, 0x40, 0x00, 0x5f, 0x81, 0x75, 0x84, 0x42, 0x55, 0xe2, 0x80, 0x07,
+0x80, 0x9f, 0x50, 0x03, 0x00, 0x08, 0x4d, 0xe1, 0x40, 0x1e, 0xa6, 0x76, 0x01, 0xe3, 0x00, 0x07,
+0x40, 0x90, 0xa0, 0x08, 0x40, 0x14, 0xf8, 0x04, 0x94, 0xd3, 0x46, 0x20, 0x00, 0x0d, 0x58, 0x21,
+0x0f, 0x54, 0x50, 0x5f, 0x81, 0x70, 0x85, 0x20, 0x14, 0x9f, 0x80, 0x5c, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x8f, 0xb4, 0xdd, 0x2f, 0xf3, 0x5c, 0x00, 0x4f, 0x81, 0x71, 0xae, 0xf7, 0xaf, 0x36,
+0xd5, 0x0d, 0x80, 0x40, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0f, 0x54, 0x50, 0x13, 0x7f, 0xd6,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x8c, 0xdd, 0x2f, 0x4e, 0x83, 0x00, 0x0c, 0x84, 0x05,
+0x4c, 0x70, 0x40, 0x09, 0x00, 0x5f, 0x81, 0x75, 0x40, 0x22, 0x90, 0x09, 0x54, 0x21, 0x00, 0x03,
+0xd5, 0x02, 0x84, 0x40, 0xa6, 0x77, 0x80, 0x67, 0x80, 0x88, 0x80, 0x1f, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x88, 0x08, 0xdd, 0x2f, 0x84, 0x60, 0x40, 0x01, 0x80, 0x06, 0xd5, 0x02, 0x84, 0x00,
+0xed, 0x7c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xd4, 0x46, 0x90,
+0x00, 0x0d, 0x58, 0x94, 0x8e, 0x74, 0x80, 0xc1, 0x00, 0x34, 0x82, 0x3d, 0x80, 0xe0, 0x80, 0x22,
+0x80, 0x06, 0x84, 0x45, 0xf3, 0x85, 0x01, 0xc4, 0x82, 0x3c, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7,
+0x8b, 0xc8, 0xdd, 0x2f, 0xc8, 0x0a, 0x46, 0x02, 0x00, 0x00, 0x80, 0x27, 0x46, 0xf0, 0x00, 0x02,
+0x58, 0xf7, 0x8e, 0xbc, 0xdd, 0x2f, 0xd5, 0x69, 0x50, 0x13, 0x00, 0x09, 0x84, 0x48, 0x46, 0x80,
+0x01, 0x02, 0x58, 0x84, 0x06, 0xa4, 0x50, 0x04, 0x80, 0xc8, 0xdd, 0x28, 0x46, 0xf0, 0x00, 0x0a,
+0x58, 0xf7, 0x84, 0x94, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x54, 0x46, 0xf0,
+0x00, 0x00, 0x58, 0xf7, 0x83, 0x24, 0xdd, 0x2f, 0x81, 0x40, 0xc0, 0x4f, 0xa1, 0xc2, 0xc7, 0x4d,
+0x84, 0xc0, 0x80, 0x26, 0x44, 0x20, 0x04, 0x00, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x87, 0x08, 0xdd, 0x2f, 0xf0, 0x05, 0x80, 0x66, 0x80, 0x86, 0x80, 0xa6, 0x80, 0x5c, 0x84, 0x26,
+0x51, 0xc3, 0x80, 0x0e, 0xb6, 0xdf, 0xf6, 0x81, 0x15, 0xcf, 0x80, 0x02, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x89, 0xe0, 0xdd, 0x2f, 0x50, 0x14, 0x82, 0x41, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x18,
+0xdd, 0x28, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x81, 0x28, 0x84, 0x46, 0x50, 0x0f, 0x80, 0x1e,
+0xdd, 0x28, 0x46, 0x10, 0x00, 0x0b, 0x58, 0x10, 0x80, 0x08, 0x84, 0x42, 0x50, 0x0f, 0x80, 0x24,
+0xdd, 0x28, 0x00, 0x2e, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x03, 0x40, 0x81, 0x20, 0x08, 0x40, 0x84,
+0x00, 0x04, 0x50, 0x1f, 0x80, 0x18, 0x84, 0x4e, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x86, 0xf0, 0xdd, 0x2f, 0x50, 0x14, 0x00, 0x12, 0x80, 0x0a, 0x96, 0x49, 0x80, 0x46, 0x46, 0xf0,
+0x00, 0x02, 0x58, 0xf7, 0x84, 0xbc, 0xdd, 0x2f, 0xec, 0x2c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x50, 0x6f, 0x80, 0x04, 0x80, 0xe1, 0x81, 0x00, 0x84, 0x20,
+0x81, 0x22, 0x80, 0x06, 0x84, 0x42, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f,
+0x80, 0x06, 0x9c, 0x7d, 0x84, 0x42, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f,
+0xa6, 0xf1, 0x54, 0x01, 0x80, 0x80, 0xc0, 0x23, 0xa7, 0x30, 0x54, 0x12, 0x00, 0x0e, 0xc9, 0x0f,
+0x54, 0x21, 0x80, 0x08, 0xc2, 0x0c, 0x97, 0x24, 0xcc, 0x1a, 0x46, 0x04, 0x00, 0x00, 0x80, 0x28,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8e, 0xbc, 0xdd, 0x2f, 0xd5, 0x11, 0x55, 0xe2, 0x00, 0x0f,
+0x84, 0xa3, 0x4d, 0xe2, 0xc0, 0x0d, 0x54, 0x31, 0x80, 0x08, 0xcb, 0x09, 0x80, 0x08, 0x80, 0x27,
+0x80, 0x49, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x8e, 0x18, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f,
+0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x9c, 0x80, 0xc0, 0x44, 0x00, 0x00, 0x10,
+0xf3, 0x83, 0xf2, 0x88, 0xf4, 0x89, 0xf5, 0x8a, 0x4c, 0x30, 0x00, 0x0d, 0x44, 0x20, 0x00, 0x18,
+0x4c, 0x31, 0x00, 0x09, 0x41, 0xe0, 0x04, 0x08, 0x4c, 0x3f, 0x00, 0x05, 0x84, 0x1f, 0x48, 0x00,
+0x00, 0xa2, 0x8e, 0x28, 0x80, 0x01, 0x84, 0xe0, 0xf1, 0x81, 0xf7, 0x97, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8c, 0x14, 0xdd, 0x2f, 0xf0, 0x82, 0xc8, 0x04, 0x84, 0x1e, 0x48, 0x00, 0x00, 0x93,
+0x50, 0x0f, 0x80, 0x54, 0x46, 0xa0, 0x01, 0x02, 0x58, 0xa5, 0x06, 0xa4, 0x80, 0x26, 0x84, 0x48,
+0x4b, 0xe0, 0x28, 0x01, 0xf2, 0x01, 0xf0, 0x02, 0x40, 0x91, 0x0c, 0x09, 0x50, 0x13, 0x00, 0x08,
+0x4b, 0xe0, 0x28, 0x01, 0x84, 0xe5, 0x54, 0x04, 0x80, 0xff, 0x80, 0x89, 0x42, 0x40, 0x1c, 0x73,
+0x40, 0x24, 0x8c, 0x08, 0x05, 0xef, 0x80, 0x02, 0x50, 0x31, 0x7f, 0xf8, 0x52, 0x50, 0x00, 0x00,
+0x54, 0x82, 0x80, 0xff, 0x55, 0xc2, 0x00, 0xff, 0x40, 0xaf, 0x0c, 0x00, 0x50, 0x64, 0xff, 0xff,
+0x14, 0x8f, 0x80, 0x07, 0x15, 0xcf, 0x80, 0x04, 0xf7, 0x85, 0x14, 0xaf, 0x80, 0x0b, 0xf6, 0x86,
+0xf6, 0x06, 0x04, 0xaf, 0x80, 0x0b, 0x05, 0xcf, 0x80, 0x04, 0x46, 0x90, 0x01, 0x02, 0x58, 0x94,
+0x86, 0xa4, 0x50, 0x8f, 0x80, 0x5c, 0x50, 0x7f, 0x80, 0x4c, 0xd5, 0x2f, 0xa7, 0x0f, 0x9f, 0xb1,
+0x40, 0x3e, 0x10, 0x03, 0xae, 0xcf, 0xdd, 0x29, 0x80, 0x2a, 0x84, 0x48, 0x50, 0x0f, 0x80, 0x3c,
+0xdd, 0x29, 0xf3, 0x03, 0x46, 0xf0, 0x00, 0x0a, 0x04, 0x17, 0x83, 0xb8, 0xf2, 0x08, 0x45, 0xe0,
+0x00, 0x10, 0x50, 0x4f, 0x80, 0x44, 0x80, 0xa8, 0x50, 0x0f, 0x80, 0x34, 0x15, 0xef, 0x80, 0x17,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x88, 0xac, 0xdd, 0x2f, 0x50, 0x1f, 0x80, 0x44, 0x84, 0x48,
+0x50, 0x0f, 0x80, 0x54, 0xdd, 0x29, 0x80, 0x0a, 0x80, 0x27, 0x84, 0x48, 0xdd, 0x29, 0x50, 0x1e,
+0x7f, 0xff, 0x55, 0xc0, 0x80, 0xff, 0x8f, 0x48, 0x84, 0x48, 0x50, 0x0f, 0x80, 0x34, 0x50, 0x1f,
+0x80, 0x54, 0x4e, 0x64, 0xff, 0xcd, 0x05, 0xef, 0x80, 0x04, 0xf4, 0x07, 0xf1, 0x05, 0x40, 0x3f,
+0x10, 0x00, 0x9e, 0x89, 0x96, 0x18, 0x84, 0xbf, 0xf2, 0x85, 0xf0, 0x84, 0xda, 0xb2, 0xf2, 0x01,
+0xf5, 0x0a, 0xb6, 0x45, 0xf2, 0x01, 0xf1, 0x02, 0xf0, 0x09, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x86, 0xa4, 0xdd, 0x2f, 0xf0, 0x02, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8c, 0x28, 0xdd, 0x2f,
+0x84, 0x00, 0xec, 0x64, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xee, 0xe4, 0xb6, 0x5f, 0xf3, 0x81, 0x80, 0xc1, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x87, 0x08,
+0x84, 0x20, 0x44, 0x20, 0x00, 0x60, 0x83, 0x80, 0x50, 0x0f, 0x80, 0x68, 0x81, 0x44, 0x81, 0x25,
+0x50, 0x8f, 0x80, 0xc8, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x20, 0x44, 0x20, 0x00, 0x60, 0x50, 0x0f,
+0x80, 0x08, 0x4b, 0xe0, 0x1c, 0x01, 0x80, 0x08, 0x84, 0x20, 0x44, 0x20, 0x00, 0x40, 0x4b, 0xe0,
+0x1c, 0x01, 0x5c, 0xf3, 0x00, 0x41, 0xe8, 0x0f, 0x80, 0x08, 0x80, 0x3c, 0x80, 0x46, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x50, 0x6f, 0x80, 0xc8, 0x51, 0xcf, 0x81, 0x08,
+0x80, 0xe6, 0xd5, 0x0a, 0x80, 0x1c, 0x80, 0x26, 0x80, 0x48, 0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7,
+0x8e, 0x98, 0xdd, 0x2f, 0xd5, 0xf2, 0xa6, 0x78, 0x56, 0x00, 0x80, 0x36, 0x18, 0x03, 0x80, 0x01,
+0x4c, 0x7e, 0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x68, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7,
+0x8e, 0x54, 0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03, 0x58, 0x84, 0x0d, 0xc0, 0x80, 0x07, 0x50, 0x1f,
+0x80, 0xc8, 0x44, 0x20, 0x00, 0x40, 0x4b, 0xe0, 0x20, 0x01, 0xb4, 0x3f, 0xf2, 0x01, 0x80, 0x07,
+0x4b, 0xe0, 0x20, 0x01, 0x80, 0x07, 0x50, 0x1f, 0x81, 0x08, 0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7,
+0x8d, 0x48, 0xdd, 0x2f, 0xa6, 0xf0, 0x56, 0x21, 0x80, 0x6a, 0x18, 0x23, 0x00, 0x01, 0x4c, 0x6e,
+0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x08, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x03, 0x58, 0xf7, 0x8e, 0x54,
+0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03, 0x58, 0x84, 0x0d, 0xc0, 0x80, 0x07, 0x50, 0x1f, 0x80, 0xc8,
+0x44, 0x20, 0x00, 0x40, 0x50, 0x6f, 0x81, 0x08, 0x4b, 0xe0, 0x20, 0x01, 0x44, 0x20, 0x00, 0x10,
+0x80, 0x07, 0x80, 0x26, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x07, 0x80, 0x26, 0x46, 0xf0, 0x01, 0x03,
+0x58, 0xf7, 0x8d, 0x48, 0xdd, 0x2f, 0x46, 0x30, 0x01, 0x02, 0x58, 0x31, 0x86, 0xa4, 0xe7, 0x31,
+0xe9, 0x06, 0x80, 0x0a, 0x80, 0x26, 0x44, 0x20, 0x00, 0x10, 0xd5, 0x04, 0x80, 0x0a, 0x80, 0x26,
+0x80, 0x49, 0x4b, 0xe0, 0x0c, 0x01, 0xed, 0x1c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xee, 0xcc, 0xb6, 0x5f, 0xf3, 0x81, 0x80, 0xc1, 0x46, 0x70, 0x01, 0x02,
+0x58, 0x73, 0x87, 0x08, 0x84, 0x20, 0x44, 0x20, 0x00, 0x68, 0x83, 0x80, 0x50, 0x0f, 0x80, 0x70,
+0x81, 0x44, 0x81, 0x25, 0x50, 0x8f, 0x80, 0xdc, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x68, 0x50, 0x0f, 0x80, 0x08, 0x4b, 0xe0, 0x1c, 0x01, 0x80, 0x08, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x40, 0x4b, 0xe0, 0x1c, 0x01, 0x5c, 0xf3, 0x00, 0x41, 0xe8, 0x0f, 0x80, 0x08, 0x80, 0x3c,
+0x80, 0x46, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xa4, 0xdd, 0x2f, 0x50, 0x6f, 0x80, 0xdc,
+0x51, 0xcf, 0x81, 0x1c, 0x80, 0xe6, 0xd5, 0x0a, 0x80, 0x1c, 0x80, 0x26, 0x80, 0x48, 0x46, 0xf0,
+0x01, 0x03, 0x58, 0xf7, 0x81, 0xbc, 0xdd, 0x2f, 0xd5, 0xf2, 0xa6, 0x78, 0x56, 0x00, 0x80, 0x36,
+0x18, 0x03, 0x80, 0x01, 0x4c, 0x7e, 0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x70, 0x80, 0x07, 0x46, 0xf0,
+0x01, 0x03, 0x58, 0xf7, 0x81, 0x78, 0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03, 0x58, 0x84, 0x00, 0xe4,
+0x80, 0x07, 0x50, 0x1f, 0x80, 0xdc, 0x44, 0x20, 0x00, 0x40, 0x4b, 0xe0, 0x20, 0x01, 0xb4, 0x3f,
+0xf2, 0x01, 0x80, 0x07, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x07, 0x50, 0x1f, 0x81, 0x1c, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x8f, 0xd8, 0xdd, 0x2f, 0xa6, 0xf0, 0x56, 0x21, 0x80, 0x6a, 0x18, 0x23,
+0x00, 0x01, 0x4c, 0x6e, 0x7f, 0xfb, 0x50, 0x7f, 0x80, 0x08, 0x80, 0x07, 0x46, 0xf0, 0x01, 0x03,
+0x58, 0xf7, 0x81, 0x78, 0xdd, 0x2f, 0x46, 0x80, 0x01, 0x03, 0x58, 0x84, 0x00, 0xe4, 0x80, 0x07,
+0x50, 0x1f, 0x80, 0xdc, 0x44, 0x20, 0x00, 0x40, 0x50, 0x6f, 0x81, 0x1c, 0x4b, 0xe0, 0x20, 0x01,
+0x44, 0x20, 0x00, 0x14, 0x80, 0x07, 0x80, 0x26, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x07, 0x80, 0x26,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x8f, 0xd8, 0xdd, 0x2f, 0x46, 0x30, 0x01, 0x02, 0x58, 0x31,
+0x86, 0xa4, 0xe7, 0x35, 0xe9, 0x06, 0x80, 0x0a, 0x80, 0x26, 0x44, 0x20, 0x00, 0x14, 0xd5, 0x04,
+0x80, 0x0a, 0x80, 0x26, 0x80, 0x49, 0x4b, 0xe0, 0x0c, 0x01, 0xed, 0x34, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x20, 0x00, 0x80, 0x58, 0x21, 0x00, 0x50, 0x46, 0x50, 0x04, 0x00,
+0x98, 0xc2, 0x58, 0x52, 0x82, 0x7c, 0x94, 0x03, 0x84, 0x40, 0x99, 0x05, 0x94, 0xdb, 0xb6, 0x44,
+0xb6, 0x43, 0x50, 0x22, 0xff, 0xf4, 0x44, 0x30, 0x00, 0xff, 0x40, 0x51, 0x80, 0x0c, 0xb4, 0x82,
+0x40, 0x32, 0x94, 0x05, 0x40, 0x51, 0x90, 0x02, 0x96, 0x48, 0x84, 0x61, 0xb6, 0xa2, 0x4c, 0x11,
+0xc0, 0x06, 0xb4, 0x22, 0x44, 0x30, 0x00, 0x82, 0xd5, 0x03, 0xb4, 0x22, 0x94, 0xdf, 0x40, 0x41,
+0x80, 0x0c, 0x40, 0x02, 0x04, 0x04, 0xb6, 0x02, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x50, 0x00, 0x80,
+0x58, 0x52, 0x80, 0x50, 0x46, 0x40, 0x04, 0x00, 0x98, 0x85, 0x58, 0x42, 0x02, 0x7c, 0x94, 0x03,
+0x99, 0x44, 0x94, 0x93, 0x44, 0x31, 0x00, 0x00, 0x84, 0x80, 0xb6, 0x65, 0xb6, 0x82, 0x46, 0x20,
+0x04, 0x00, 0x58, 0x21, 0x02, 0x70, 0x44, 0x30, 0x00, 0xff, 0x40, 0x51, 0x80, 0x0c, 0xb4, 0x82,
+0x40, 0x32, 0x94, 0x05, 0x40, 0x51, 0x90, 0x02, 0x96, 0x48, 0x84, 0x61, 0xb6, 0xa2, 0x4c, 0x11,
+0xc0, 0x06, 0xb4, 0x22, 0x44, 0x30, 0x00, 0x82, 0xd5, 0x03, 0xb4, 0x22, 0x94, 0xdf, 0x40, 0x41,
+0x80, 0x0c, 0x40, 0x02, 0x04, 0x04, 0xb6, 0x02, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x40, 0x04, 0x00,
+0x46, 0x20, 0x30, 0x70, 0x80, 0xa4, 0x58, 0x21, 0x03, 0x07, 0x14, 0x22, 0x00, 0x9d, 0x14, 0x22,
+0x80, 0x9e, 0x46, 0x20, 0x04, 0x00, 0x58, 0x21, 0x02, 0x70, 0x44, 0x30, 0x00, 0xff, 0x94, 0x03,
+0x40, 0x51, 0x80, 0x0c, 0xb4, 0x82, 0x40, 0x32, 0x94, 0x05, 0x40, 0x51, 0x90, 0x02, 0x96, 0x48,
+0x84, 0x61, 0xb6, 0xa2, 0x4c, 0x11, 0xc0, 0x06, 0xb4, 0x22, 0x44, 0x30, 0x00, 0x86, 0xd5, 0x04,
+0xb4, 0x22, 0x44, 0x30, 0x00, 0x84, 0x40, 0x51, 0x80, 0x0c, 0x40, 0x02, 0x84, 0x04, 0xb6, 0x02,
+0xdd, 0x9e, 0x92, 0x00, 0x40, 0x31, 0xe0, 0x08, 0x40, 0x41, 0x90, 0x04, 0x40, 0x21, 0x40, 0x08,
+0x46, 0x50, 0x00, 0x80, 0x40, 0x22, 0x08, 0x04, 0x58, 0x52, 0x80, 0x50, 0x46, 0x40, 0x04, 0x00,
+0x98, 0xc5, 0x58, 0x42, 0x02, 0x7c, 0x94, 0x03, 0x99, 0x44, 0xb6, 0x45, 0x94, 0xdb, 0x84, 0x40,
+0xb6, 0x43, 0x50, 0x22, 0x7f, 0xf4, 0x44, 0x50, 0x00, 0xff, 0x40, 0x32, 0x80, 0x0c, 0xb4, 0x82,
+0x40, 0x51, 0x8c, 0x05, 0x40, 0x32, 0x90, 0x02, 0x96, 0x48, 0x84, 0xa1, 0xb6, 0x62, 0xd9, 0x05,
+0xb4, 0x22, 0x44, 0x30, 0x00, 0x82, 0xd5, 0x03, 0xb4, 0x22, 0x94, 0xef, 0x40, 0x41, 0x80, 0x0c,
+0x40, 0x02, 0x04, 0x04, 0xb6, 0x02, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x44, 0x20,
+0x00, 0x19, 0x96, 0x48, 0x80, 0x62, 0x84, 0x81, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x84, 0xc4,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x44, 0x20, 0x00, 0x32, 0x96, 0x48, 0x84, 0x6a, 0x84, 0x81, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x84, 0xc4, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0x10, 0x04, 0x00, 0x04, 0x00, 0x80, 0x20, 0x54, 0x00,
+0x01, 0x00, 0xc0, 0x09, 0x84, 0x00, 0x80, 0x20, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x84, 0x0c,
+0xdd, 0x2f, 0xd5, 0x07, 0x80, 0x20, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x83, 0xb4, 0xdd, 0x2f,
+0x46, 0x20, 0x04, 0x00, 0x58, 0x21, 0x00, 0x20, 0xb4, 0x22, 0x59, 0xe0, 0x88, 0x00, 0x15, 0xe1,
+0x00, 0x00, 0x84, 0x01, 0xb4, 0xa2, 0x84, 0x20, 0x42, 0x32, 0xc4, 0x09, 0xb6, 0x62, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x84, 0x6c, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x84, 0x48, 0x96, 0x49, 0x4c, 0x11, 0x40, 0x04, 0x84, 0x81,
+0xd5, 0x07, 0x95, 0x51, 0xd1, 0x04, 0x84, 0x01, 0x48, 0x00, 0x00, 0xc4, 0x84, 0x82, 0x46, 0xa0,
+0x10, 0x00, 0x58, 0xa5, 0x00, 0x01, 0x85, 0x20, 0x47, 0xc1, 0x11, 0x10, 0x46, 0x70, 0x04, 0x00,
+0xb6, 0x9f, 0x14, 0xaf, 0x80, 0x01, 0x59, 0xce, 0x01, 0x90, 0x81, 0x49, 0x58, 0x73, 0x82, 0x70,
+0x46, 0x80, 0x00, 0x01, 0x58, 0x84, 0x04, 0x0c, 0x81, 0x20, 0x80, 0x29, 0xa3, 0x89, 0xb4, 0x21,
+0xe6, 0xc4, 0x4e, 0xf2, 0x00, 0xa0, 0x84, 0xa4, 0xd1, 0x34, 0xe6, 0x25, 0xe8, 0x0a, 0x84, 0xa1,
+0xd1, 0x1d, 0xc1, 0x17, 0x84, 0xa2, 0xd1, 0x21, 0x84, 0xa3, 0x4c, 0x12, 0xc0, 0x94, 0xd5, 0x25,
+0x8c, 0xac, 0xd1, 0x42, 0xe6, 0x31, 0xe8, 0x07, 0x84, 0xa5, 0xd1, 0x2a, 0x84, 0xa6, 0x4c, 0x12,
+0xc0, 0x8a, 0xd5, 0x32, 0x9d, 0x69, 0xd1, 0x59, 0x9d, 0x69, 0x4c, 0x12, 0xc0, 0x84, 0xd5, 0x64,
+0x80, 0x06, 0x84, 0x21, 0x4b, 0xe0, 0x20, 0x01, 0xd5, 0x7d, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x83, 0xb4, 0xdd, 0x2f, 0xd5, 0x76, 0x80, 0x06, 0x84, 0x20, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x84, 0x6c, 0xdd, 0x2f, 0xd5, 0x6e, 0x84, 0x21, 0x44, 0x20, 0x00, 0x32, 0xd5, 0x0b,
+0x80, 0x06, 0x84, 0x21, 0x46, 0x20, 0x00, 0x01, 0x58, 0x21, 0x05, 0x28, 0xd5, 0x62, 0x84, 0x21,
+0x44, 0x20, 0x00, 0x11, 0x80, 0x06, 0x80, 0x62, 0x80, 0x81, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x84, 0xc4, 0xdd, 0x2f, 0xd5, 0x57, 0x80, 0x06, 0x84, 0x21, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x85, 0x4c, 0xdd, 0x2f, 0xd5, 0x4f, 0x46, 0x50, 0x00, 0x80, 0x58, 0x52, 0x80, 0x50, 0x46, 0x20,
+0x04, 0x00, 0x98, 0xf5, 0x58, 0x21, 0x02, 0x7c, 0x95, 0x73, 0x98, 0x6a, 0x15, 0xc0, 0x80, 0x00,
+0x41, 0xe1, 0x8c, 0x08, 0xf4, 0x01, 0xb6, 0x9e, 0x44, 0x00, 0x00, 0x82, 0xb4, 0x47, 0x40, 0x60,
+0x14, 0x0c, 0x41, 0xe1, 0x20, 0x09, 0x41, 0xef, 0x20, 0x08, 0x15, 0xe3, 0x80, 0x00, 0xb4, 0x27,
+0x40, 0x63, 0x04, 0x04, 0xb6, 0xc7, 0xd5, 0x2e, 0x80, 0x06, 0x84, 0x21, 0x4b, 0xe0, 0x20, 0x01,
+0x80, 0x46, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0c, 0xc0, 0x46, 0x10, 0x00, 0x01, 0x58, 0x10,
+0x87, 0x78, 0x84, 0x61, 0xd5, 0x0f, 0x80, 0x06, 0x84, 0x21, 0x4b, 0xe0, 0x20, 0x01, 0x80, 0x46,
+0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0c, 0xc0, 0x46, 0x10, 0x00, 0x01, 0x58, 0x10, 0x87, 0x78,
+0x84, 0x63, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x81, 0x0c, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0d,
+0x58, 0x00, 0x0c, 0xc0, 0x44, 0x10, 0x13, 0x88, 0x46, 0x20, 0x00, 0x00, 0x58, 0x21, 0x02, 0x54,
+0xdd, 0x22, 0xb4, 0x1f, 0x8d, 0x41, 0x8d, 0x28, 0xe3, 0x40, 0x4e, 0xf3, 0xff, 0x58, 0x84, 0x00,
+0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0x84, 0xa2, 0x80, 0xc0,
+0xd1, 0x25, 0x84, 0xa3, 0xd1, 0x2a, 0x84, 0xa1, 0xd9, 0x2e, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x83, 0xb4, 0xdd, 0x2f, 0x80, 0x46, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0c, 0xc0, 0x46, 0x10,
+0x00, 0x01, 0x58, 0x10, 0x87, 0x78, 0x84, 0x62, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x81, 0x0c,
+0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0c, 0xc0, 0x44, 0x10, 0x0b, 0xb8, 0x46, 0xf0,
+0x00, 0x00, 0x58, 0xf7, 0x82, 0x54, 0xdd, 0x2f, 0xd5, 0x0e, 0x84, 0x20, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x84, 0x6c, 0xdd, 0x2f, 0xd5, 0x07, 0x84, 0x21, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x83, 0xb4, 0xdd, 0x2f, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0xef, 0xf8, 0x46, 0x10, 0x04, 0x00, 0x04, 0x60, 0x80, 0x97, 0x96, 0x34, 0xc0, 0x15, 0x80, 0x61,
+0x04, 0x21, 0x80, 0x20, 0x54, 0x01, 0x01, 0x00, 0xc0, 0x09, 0x84, 0x00, 0x80, 0x20, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x84, 0x0c, 0xdd, 0x2f, 0xd5, 0x07, 0x80, 0x20, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x83, 0xb4, 0xdd, 0x2f, 0x40, 0x43, 0x40, 0x08, 0x92, 0x9f, 0xc4, 0x06, 0x46, 0xf0,
+0x00, 0x04, 0x58, 0xf7, 0x8d, 0x20, 0xdd, 0x2f, 0x55, 0xe3, 0x10, 0x00, 0x4f, 0xe2, 0x00, 0x07,
+0x84, 0x21, 0x46, 0xf0, 0x00, 0x0d, 0x10, 0x17, 0x8e, 0x38, 0x46, 0x30, 0x04, 0x00, 0x14, 0x61,
+0x80, 0x97, 0x04, 0x21, 0x80, 0x97, 0xf2, 0x81, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e,
+0x96, 0x49, 0x54, 0x20, 0x80, 0x03, 0x40, 0x30, 0x88, 0x09, 0xca, 0x10, 0x5c, 0xf0, 0x80, 0xc8,
+0xe8, 0x0d, 0x80, 0x20, 0xb4, 0x40, 0x84, 0x01, 0xd5, 0x04, 0xb4, 0x81, 0x9c, 0x01, 0xab, 0x11,
+0x9c, 0x4c, 0xe2, 0x03, 0xe9, 0xfb, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0x3c, 0xa4, 0x88, 0x5c, 0xf1, 0x00, 0xc8, 0xe8, 0x16, 0x80, 0x60, 0xa2, 0x99,
+0xb4, 0xa3, 0x5c, 0xf2, 0x80, 0x40, 0xe8, 0x10, 0x84, 0x60, 0xd5, 0x04, 0xa3, 0x91, 0x80, 0x64,
+0xb6, 0xc0, 0x40, 0x21, 0x20, 0x08, 0x92, 0x48, 0x9c, 0x04, 0x9d, 0x19, 0xdb, 0xf8, 0x94, 0x22,
+0xac, 0x08, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0x3a, 0x6f, 0x98, 0x04, 0xdd, 0x9e, 0x92, 0x00,
+0x96, 0x49, 0xe6, 0x28, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x29, 0x80, 0x40, 0xa2, 0xd1, 0x8c, 0x08,
+0xb4, 0x22, 0xb4, 0x40, 0xc3, 0x02, 0xd5, 0x21, 0x46, 0x44, 0x00, 0x04, 0x46, 0x10, 0x04, 0x00,
+0x58, 0x10, 0x80, 0xdc, 0x40, 0x51, 0x10, 0x04, 0xb6, 0xa1, 0x80, 0x03, 0xd5, 0x09, 0x92, 0x00,
+0x84, 0x67, 0x9c, 0x49, 0x4c, 0x11, 0xff, 0xfd, 0x9c, 0x01, 0x84, 0xaa, 0xd0, 0x03, 0x84, 0x20,
+0xd5, 0xf7, 0x46, 0x1b, 0xff, 0xfb, 0x46, 0x00, 0x04, 0x00, 0x58, 0x10, 0x8f, 0xff, 0x40, 0x21,
+0x04, 0x02, 0x58, 0x00, 0x00, 0xdc, 0xb6, 0x40, 0x84, 0x00, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xf4, 0x80, 0xe4, 0x81, 0x42, 0x81, 0x03, 0x81, 0x25, 0x55, 0xc0, 0x00, 0xff, 0x97, 0x08,
+0x5c, 0xf3, 0x80, 0xc1, 0xe8, 0x4e, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x64, 0xf4, 0x81,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x83, 0x24, 0xdd, 0x2f, 0x80, 0xc0, 0xf4, 0x01, 0xc0, 0x41,
+0x46, 0xf0, 0x00, 0x0d, 0x00, 0x37, 0x8c, 0xdc, 0x54, 0x22, 0x00, 0x0f, 0x54, 0x5e, 0x00, 0x0f,
+0x41, 0xe1, 0x40, 0x08, 0x40, 0x02, 0xd0, 0x08, 0x46, 0x25, 0x80, 0x00, 0xa1, 0x72, 0x40, 0x4f,
+0x00, 0x04, 0x54, 0x11, 0x80, 0x03, 0x41, 0xe2, 0x08, 0x04, 0x14, 0x82, 0x80, 0x01, 0x40, 0x00,
+0xe4, 0x08, 0xb7, 0x45, 0x50, 0x83, 0x80, 0x08, 0x40, 0x3f, 0x00, 0x04, 0x80, 0x47, 0x54, 0x84,
+0x3f, 0xff, 0x80, 0x29, 0x50, 0x02, 0x80, 0x08, 0x40, 0x71, 0xa0, 0x04, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x86, 0xf0, 0xdd, 0x2f, 0x84, 0x21, 0x84, 0x00, 0x10, 0x13, 0x00, 0x0f, 0x10, 0x03,
+0x00, 0x14, 0x12, 0x83, 0x00, 0x06, 0xa9, 0xf4, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74,
+0x80, 0x26, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0xa0, 0xdd, 0x2f, 0x84, 0x00, 0xd5, 0x02,
+0x84, 0x01, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xfc, 0x97, 0x09, 0x97, 0xd8, 0xe6, 0x84, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x1f, 0xb4, 0x00,
+0x84, 0x21, 0x4c, 0x00, 0x80, 0x03, 0xd5, 0x19, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0e, 0x74,
+0x04, 0x33, 0x00, 0xa9, 0xb6, 0x62, 0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7, 0x84, 0x3c, 0xdd, 0x2f,
+0x84, 0x40, 0x80, 0x27, 0x50, 0x53, 0x02, 0xa4, 0x84, 0x05, 0x80, 0x62, 0x84, 0x84, 0x46, 0xf0,
+0x00, 0x01, 0x58, 0xf7, 0x89, 0x2c, 0xdd, 0x2f, 0x84, 0x05, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xfc, 0x97, 0x82, 0x46, 0x00, 0x00, 0x0d,
+0x58, 0x00, 0x0e, 0x64, 0x97, 0xc8, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x83, 0x24, 0xdd, 0x2f,
+0xc8, 0x03, 0x84, 0x01, 0xd5, 0x2b, 0x46, 0xf0, 0x00, 0x0d, 0x01, 0xe7, 0x8c, 0xdc, 0x54, 0x53,
+0x80, 0x0f, 0x54, 0x4f, 0x00, 0x03, 0x40, 0x32, 0xc0, 0x08, 0x40, 0x12, 0x64, 0x08, 0x46, 0x25,
+0x88, 0x08, 0x41, 0xe1, 0x84, 0x04, 0xa1, 0x42, 0x58, 0x21, 0x00, 0x08, 0x40, 0x1f, 0x08, 0x04,
+0x84, 0x88, 0x84, 0x61, 0x84, 0x40, 0xb6, 0xc5, 0xa8, 0x44, 0xad, 0x06, 0x10, 0x30, 0x00, 0x0f,
+0x10, 0x20, 0x00, 0x14, 0x80, 0x20, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x87, 0xa0, 0xdd, 0x2f, 0x84, 0x00, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0xf0, 0x00, 0x0d, 0x20, 0x27, 0x8c, 0xde,
+0x84, 0xa1, 0xda, 0x58, 0x46, 0x60, 0x04, 0x10, 0x04, 0x53, 0x01, 0x0e, 0x40, 0x82, 0xc0, 0x09,
+0x46, 0xf0, 0x00, 0x0b, 0x00, 0x37, 0x80, 0x1d, 0x54, 0x84, 0x00, 0xff, 0xe3, 0x03, 0xe9, 0x22,
+0x46, 0x70, 0x00, 0x0d, 0x20, 0x63, 0x8c, 0xe1, 0xce, 0x1d, 0x46, 0xf0, 0x00, 0x0d, 0x10, 0x67,
+0x8c, 0xe0, 0x10, 0x23, 0x8c, 0xe1, 0x80, 0x02, 0x80, 0x26, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x8a, 0x44, 0xdd, 0x2f, 0xc0, 0x03, 0x10, 0x63, 0x8c, 0xe1, 0x84, 0x01, 0x80, 0x20, 0x46, 0x60,
+0x00, 0x01, 0x58, 0x63, 0x0a, 0x44, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x01, 0x84, 0x22, 0x4b, 0xe0,
+0x18, 0x01, 0x46, 0xf0, 0x00, 0x0d, 0x00, 0x27, 0x8c, 0xdf, 0xe2, 0x48, 0xe9, 0x23, 0x46, 0x70,
+0x00, 0x0d, 0x20, 0x63, 0x8c, 0xe0, 0xce, 0x1e, 0x84, 0x61, 0x46, 0xf0, 0x00, 0x0d, 0x10, 0x67,
+0x8c, 0xe1, 0x10, 0x33, 0x8c, 0xe0, 0x80, 0x06, 0x80, 0x26, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x8a, 0x44, 0xdd, 0x2f, 0xc0, 0x03, 0x10, 0x63, 0x8c, 0xe0, 0x84, 0x21, 0x46, 0x60, 0x00, 0x01,
+0x58, 0x63, 0x0a, 0x44, 0x84, 0x00, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x00, 0x84, 0x22, 0x4b, 0xe0,
+0x18, 0x01, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0xa2, 0x41, 0x84, 0x41,
+0xb4, 0x00, 0x4c, 0x11, 0x40, 0x07, 0x46, 0xf0, 0x00, 0x0e, 0x10, 0x07, 0x80, 0xc8, 0xd5, 0x4b,
+0x84, 0xa3, 0xd9, 0x3e, 0x96, 0x00, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0e, 0x74, 0x10, 0x03,
+0x02, 0xa8, 0x46, 0x10, 0x04, 0x10, 0x04, 0x40, 0x82, 0x03, 0x42, 0x22, 0x60, 0x09, 0x42, 0x21,
+0x64, 0x09, 0xc8, 0x0f, 0x46, 0x30, 0x30, 0x00, 0x41, 0xe1, 0x0c, 0x04, 0x15, 0xe0, 0x82, 0x03,
+0x50, 0x03, 0x02, 0x68, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x81, 0x1c, 0xdd, 0x2f, 0xd5, 0x2b,
+0x42, 0x01, 0x60, 0x08, 0x84, 0x40, 0x14, 0x00, 0x82, 0x03, 0x10, 0x23, 0x02, 0x64, 0x14, 0x23,
+0x00, 0xa9, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8b, 0x34, 0xdd, 0x2f, 0x84, 0x01, 0x80, 0x20,
+0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x85, 0x28, 0xdd, 0x2f, 0x50, 0x03, 0x02, 0x68, 0x44, 0x10,
+0x27, 0x10, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x54, 0xdd, 0x2f, 0xd5, 0x0c, 0x84, 0xa4,
+0xd9, 0x0a, 0x5c, 0x50, 0x00, 0x03, 0x84, 0x80, 0x40, 0x02, 0x14, 0x1a, 0x46, 0xf0, 0x00, 0x0e,
+0x10, 0x07, 0x80, 0xd9, 0x84, 0x00, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0x94, 0x80, 0xc0, 0xb4, 0x00, 0x84, 0x21, 0x4c, 0x00, 0xc0, 0x24, 0x9c, 0xb4, 0xb4, 0x22,
+0x50, 0x33, 0x00, 0x0c, 0x97, 0x0c, 0x8c, 0xc8, 0xb4, 0x46, 0xb4, 0x63, 0xc4, 0x05, 0x46, 0xf0,
+0x00, 0x0e, 0x10, 0x07, 0x80, 0xc9, 0x54, 0x00, 0x80, 0x02, 0xc0, 0x0a, 0x85, 0x01, 0x46, 0xf0,
+0x00, 0x0e, 0x10, 0x87, 0x80, 0xcb, 0x46, 0xf0, 0x00, 0x0e, 0x10, 0x87, 0x80, 0xca, 0x46, 0xf0,
+0x00, 0x0e, 0x14, 0x37, 0x80, 0x35, 0x46, 0xf0, 0x00, 0x0e, 0x14, 0x27, 0x80, 0x34, 0xd5, 0x4e,
+0x84, 0xa2, 0xd8, 0x4e, 0x01, 0xe3, 0x00, 0x50, 0x00, 0x43, 0x00, 0x51, 0x00, 0x33, 0x00, 0x53,
+0x51, 0xc3, 0x00, 0x04, 0xb5, 0x3c, 0x01, 0xc3, 0x00, 0x52, 0x15, 0xef, 0x80, 0x01, 0xf3, 0x83,
+0xf4, 0x82, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x06, 0xf0, 0x50, 0x13, 0x00, 0x08, 0x94, 0xad,
+0x50, 0xaf, 0x80, 0x50, 0x50, 0x0f, 0x80, 0x10, 0x46, 0x70, 0x00, 0x0d, 0x58, 0x73, 0x8e, 0x74,
+0xdd, 0x28, 0x50, 0x13, 0x00, 0x48, 0x84, 0x48, 0x42, 0x64, 0x84, 0x0b, 0x80, 0x0a, 0x54, 0x94,
+0x80, 0x01, 0xdd, 0x28, 0x10, 0x93, 0x82, 0x3f, 0x10, 0x63, 0x82, 0x40, 0x50, 0x1f, 0x80, 0x10,
+0xf5, 0x01, 0x44, 0x20, 0x00, 0x40, 0x10, 0x53, 0x82, 0x3c, 0x50, 0x03, 0x80, 0xd0, 0xf3, 0x02,
+0x10, 0x33, 0x82, 0x3d, 0xf4, 0x03, 0x13, 0xc3, 0x81, 0x26, 0x10, 0x43, 0x82, 0x3e, 0xdd, 0x28,
+0x80, 0x2a, 0x84, 0x48, 0x50, 0x03, 0x80, 0xc8, 0xdd, 0x28, 0x50, 0x13, 0x80, 0xd0, 0x84, 0x00,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x87, 0x7c, 0xdd, 0x2f, 0x84, 0x00, 0xd5, 0x2a, 0x84, 0xa3,
+0xd0, 0x02, 0xd5, 0x26, 0x50, 0x9f, 0x80, 0x60, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xf0,
+0x9c, 0x74, 0x84, 0x46, 0x50, 0x8f, 0x80, 0x58, 0x80, 0x09, 0xdd, 0x27, 0x50, 0x13, 0x00, 0x0a,
+0x84, 0x46, 0x80, 0x08, 0xdd, 0x27, 0x80, 0x29, 0x84, 0x46, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00,
+0x01, 0x28, 0xdd, 0x27, 0x8c, 0xd0, 0x84, 0x46, 0x80, 0x28, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00,
+0x00, 0xb5, 0xdd, 0x27, 0xb4, 0x06, 0x46, 0xf0, 0x00, 0x0e, 0x14, 0x07, 0x80, 0x45, 0x84, 0x01,
+0xec, 0x6c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa8, 0xbc, 0x96, 0x49, 0x54, 0x70,
+0x80, 0x07, 0x40, 0xa0, 0x88, 0x09, 0xcf, 0x2e, 0x9d, 0x84, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94,
+0x8e, 0xf8, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x0d, 0xb8, 0xd5, 0x1f, 0xb4, 0x20, 0x40, 0x00,
+0xa0, 0x08, 0x92, 0x08, 0x40, 0x20, 0xf8, 0x09, 0x4e, 0x14, 0x00, 0x0a, 0x40, 0x00, 0xc0, 0x09,
+0x84, 0x40, 0x96, 0x48, 0x96, 0x00, 0x4b, 0xe0, 0x20, 0x01, 0xd5, 0x0a, 0x84, 0xa1, 0xda, 0x09,
+0x40, 0x40, 0xc0, 0x09, 0x96, 0x20, 0x96, 0x48, 0x84, 0x40, 0x4b, 0xe0, 0x24, 0x01, 0xc8, 0x0a,
+0xb4, 0xa0, 0x9d, 0xfa, 0xb6, 0xa6, 0x8c, 0xc8, 0x9e, 0x34, 0xe2, 0xea, 0xe9, 0xe0, 0x84, 0x00,
+0xd5, 0x02, 0x84, 0x01, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xfc, 0x96, 0x49, 0x54, 0x70, 0x80, 0x07, 0x41, 0xc0, 0x88, 0x09, 0xcf, 0x35, 0x9d, 0x84,
+0x46, 0xa0, 0x00, 0x05, 0x58, 0xa5, 0x0f, 0x6c, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x8e, 0x70,
+0xd5, 0x26, 0xb4, 0x20, 0x9d, 0xfa, 0x40, 0x00, 0xa0, 0x08, 0x92, 0x08, 0x40, 0x80, 0xf8, 0x09,
+0x4e, 0x14, 0x00, 0x0c, 0x40, 0x00, 0xc0, 0x09, 0xb4, 0x46, 0x96, 0x00, 0x96, 0x48, 0x4b, 0xe0,
+0x24, 0x01, 0x84, 0xa1, 0xd0, 0x13, 0xd5, 0x18, 0x84, 0xa1, 0x4c, 0x82, 0xc0, 0x0c, 0x40, 0x50,
+0xc0, 0x09, 0xb4, 0x46, 0x96, 0x28, 0x96, 0x48, 0x4b, 0xe0, 0x28, 0x01, 0x4c, 0x04, 0x00, 0x07,
+0xd5, 0x0b, 0x05, 0xe3, 0x00, 0x00, 0x15, 0xe0, 0x00, 0x00, 0x8c, 0xc8, 0x9e, 0x34, 0xe2, 0xfc,
+0xe9, 0xd9, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xec, 0x04, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x85, 0x0c, 0x96, 0xc9, 0x40, 0x21, 0xa1, 0x17, 0x40, 0x11,
+0x88, 0x09, 0xf1, 0x81, 0x4e, 0x83, 0x00, 0x6a, 0x50, 0x70, 0x00, 0x08, 0x9d, 0x84, 0x47, 0xc0,
+0x00, 0x05, 0x59, 0xce, 0x0e, 0x70, 0xd5, 0x5a, 0xb4, 0x20, 0x40, 0x00, 0xa0, 0x08, 0x92, 0x08,
+0x8d, 0x03, 0x40, 0x20, 0xf8, 0x09, 0x4e, 0x14, 0x00, 0x20, 0x40, 0x90, 0xc0, 0x09, 0x54, 0x94,
+0x80, 0xff, 0x54, 0xa0, 0x80, 0xff, 0x80, 0x2a, 0x84, 0x40, 0x80, 0x09, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0x80, 0x40, 0x80, 0x2a, 0x80, 0x09, 0xca, 0x46, 0xb4, 0x66,
+0xb4, 0x82, 0x05, 0xe3, 0x80, 0x00, 0x40, 0x21, 0x8c, 0x05, 0x40, 0x51, 0x10, 0x02, 0x40, 0x22,
+0xf8, 0x04, 0xdd, 0x3c, 0xd5, 0x23, 0x84, 0xa1, 0xda, 0x24, 0x40, 0x00, 0xc0, 0x09, 0x54, 0x90,
+0x00, 0xff, 0x54, 0xa0, 0x80, 0xff, 0x80, 0x2a, 0x84, 0x40, 0x80, 0x09, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x80, 0x40, 0x80, 0x2a, 0x80, 0x09, 0xca, 0x26, 0xb4, 0xa6,
+0xb4, 0x82, 0xb4, 0x67, 0x40, 0x22, 0x94, 0x05, 0x41, 0xe1, 0x10, 0x02, 0x40, 0x2f, 0x0c, 0x04,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8f, 0x6c, 0xdd, 0x2f, 0x84, 0xa1, 0xd0, 0x0d, 0xd5, 0x15,
+0xb4, 0x60, 0xb4, 0x26, 0xb4, 0x47, 0x40, 0x50, 0x84, 0x05, 0x40, 0x41, 0x94, 0x02, 0x41, 0xe2,
+0x08, 0x04, 0x15, 0xe0, 0x00, 0x00, 0x8c, 0xcc, 0x8c, 0xec, 0x05, 0xef, 0x80, 0x01, 0x9e, 0x34,
+0xe3, 0x1e, 0xe9, 0xa3, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x96, 0x49, 0xe6, 0x24, 0xe8, 0x03,
+0x84, 0x01, 0xd5, 0x5b, 0xb4, 0x20, 0x84, 0xa4, 0xd1, 0x2a, 0xe6, 0x25, 0xe8, 0x06, 0x84, 0xa1,
+0xd1, 0x09, 0x84, 0xa3, 0xd9, 0x51, 0xd5, 0x12, 0x84, 0xa5, 0xd1, 0x31, 0x84, 0xa6, 0xd9, 0x4c,
+0xd5, 0x38, 0x9c, 0x04, 0xb4, 0x40, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0c, 0xdc, 0x96, 0x50,
+0xae, 0x40, 0xe6, 0x22, 0xe9, 0x41, 0x84, 0x20, 0xd5, 0x20, 0x9d, 0x04, 0xb4, 0x64, 0x46, 0x10,
+0x00, 0x0b, 0x58, 0x10, 0x80, 0x1c, 0x54, 0x01, 0x80, 0x0f, 0xae, 0x08, 0xe6, 0x04, 0xe9, 0x03,
+0x84, 0x05, 0xd5, 0x31, 0xc8, 0x31, 0x84, 0xa1, 0xaf, 0x48, 0xd5, 0x2f, 0x9c, 0x84, 0xb4, 0x22,
+0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0c, 0xdd, 0x55, 0xe0, 0x80, 0x0f, 0x11, 0xe0, 0x00, 0x00,
+0x5c, 0xff, 0x00, 0x04, 0xe9, 0x21, 0x84, 0x23, 0xae, 0x40, 0xd5, 0x1e, 0x9c, 0xc4, 0xb4, 0x03,
+0x54, 0x00, 0x00, 0x0f, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x88, 0x64, 0xdd, 0x2f, 0xd5, 0x14,
+0x9c, 0x84, 0xb4, 0x02, 0x40, 0x50, 0x40, 0x09, 0x40, 0x10, 0x7c, 0x09, 0x46, 0xf0, 0x00, 0x0b,
+0x10, 0x57, 0x80, 0x1d, 0x46, 0xf0, 0x00, 0x0d, 0x10, 0x17, 0x8c, 0xde, 0x46, 0x10, 0x00, 0x0d,
+0x58, 0x10, 0x8c, 0xdf, 0xae, 0x08, 0x84, 0x00, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x04, 0x80, 0x80, 0x04, 0x80, 0xc1, 0x40, 0x14, 0x50, 0x09,
+0x81, 0x20, 0x54, 0x10, 0x80, 0x7f, 0x44, 0x00, 0x00, 0x10, 0x84, 0xe4, 0x4c, 0x10, 0x00, 0x60,
+0xe4, 0x31, 0xe8, 0x18, 0x84, 0xa9, 0xd1, 0x35, 0xe4, 0x2a, 0xe8, 0x0b, 0x84, 0xa2, 0x4c, 0x12,
+0x80, 0x9d, 0x84, 0xa8, 0xd1, 0x26, 0x84, 0xa1, 0x4c, 0x12, 0xc0, 0xf4, 0x48, 0x00, 0x00, 0x8e,
+0x84, 0x0b, 0x4c, 0x10, 0x00, 0x41, 0xe0, 0x20, 0xe9, 0x2c, 0x84, 0xac, 0x4c, 0x12, 0xc0, 0xea,
+0xd5, 0x32, 0x44, 0x50, 0x00, 0x18, 0xd1, 0x5b, 0xe4, 0x39, 0xe8, 0x09, 0x9d, 0x45, 0xd1, 0x4f,
+0x9d, 0x46, 0xd1, 0x0d, 0x9d, 0x44, 0x4c, 0x12, 0xc0, 0xdd, 0xd5, 0x41, 0x9d, 0x6e, 0xd1, 0x65,
+0x9d, 0x69, 0xd1, 0x6b, 0x9f, 0x6e, 0x4c, 0x12, 0xc0, 0xd5, 0xd5, 0x51, 0x84, 0x01, 0xd5, 0x7c,
+0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x88, 0x60, 0xdd, 0x2f, 0xd5, 0x74,
+0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8e, 0x80, 0xdd, 0x2f, 0xd5, 0x6c,
+0xa0, 0x32, 0xa4, 0x76, 0x54, 0x74, 0x3f, 0xff, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8d, 0x88,
+0xdd, 0x2f, 0xd5, 0x62, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8d, 0xfc,
+0xdd, 0x2f, 0xd5, 0x5a, 0xa0, 0x32, 0x50, 0x13, 0x00, 0x0c, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7,
+0x88, 0x90, 0xdd, 0x2f, 0xa5, 0xf6, 0x54, 0x73, 0xbf, 0xff, 0xd5, 0x4e, 0xa0, 0x32, 0xa4, 0x76,
+0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x85, 0xd0, 0xdd, 0x2f, 0xd5, 0x46, 0xa0, 0x32, 0xa4, 0x76,
+0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7, 0x83, 0x2c, 0xdd, 0x2f, 0xd5, 0x3e, 0xa0, 0x32, 0xa4, 0x76,
+0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8c, 0x3c, 0xdd, 0x2f, 0xd5, 0x36, 0xa0, 0x32, 0xa4, 0x76,
+0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x8b, 0x88, 0xdd, 0x2f, 0xd5, 0x2e, 0x40, 0x24, 0x40, 0x09,
+0xa4, 0x76, 0xa0, 0x32, 0x54, 0x31, 0x00, 0x0f, 0x50, 0x2f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x89, 0xec, 0xdd, 0x2f, 0xd5, 0x75, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x08,
+0x58, 0xf7, 0x82, 0x20, 0xdd, 0x2f, 0xd5, 0x18, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x09,
+0x58, 0xf7, 0x8b, 0xfc, 0xdd, 0x2f, 0xd5, 0x10, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x8f, 0x74, 0xdd, 0x2f, 0xd5, 0x08, 0xa0, 0x32, 0xa4, 0x76, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x88, 0xd0, 0xdd, 0x2f, 0x93, 0x10, 0x54, 0x84, 0x00, 0x0f, 0x4e, 0x82, 0x00, 0x52,
+0x46, 0x3f, 0xff, 0x0f, 0x58, 0x31, 0x8f, 0xff, 0x40, 0x73, 0x8c, 0x02, 0x40, 0x84, 0x40, 0x08,
+0x41, 0xe3, 0xa0, 0x04, 0x42, 0x5f, 0x78, 0x09, 0x42, 0x52, 0xfc, 0x09, 0x46, 0x4f, 0xf0, 0xff,
+0x42, 0x32, 0xf8, 0x08, 0x54, 0x10, 0x00, 0x0f, 0x58, 0x42, 0x0f, 0xff, 0x40, 0x71, 0x90, 0x02,
+0x40, 0x00, 0xd0, 0x08, 0x47, 0xec, 0x6f, 0xff, 0x40, 0x53, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x0d,
+0x00, 0x37, 0x8c, 0xdc, 0x59, 0xef, 0x0f, 0xff, 0x46, 0x11, 0x80, 0x00, 0x40, 0x42, 0xf8, 0x02,
+0x40, 0x72, 0x04, 0x04, 0x54, 0x01, 0x80, 0x03, 0x42, 0x53, 0xe4, 0x09, 0x42, 0x52, 0xe8, 0x09,
+0x41, 0xe0, 0x64, 0x08, 0x40, 0x32, 0xf8, 0x04, 0x42, 0x71, 0xbc, 0x09, 0x54, 0x13, 0xbf, 0xff,
+0xe4, 0x28, 0xe8, 0x07, 0x40, 0x03, 0xb8, 0x09, 0x40, 0x00, 0x38, 0x08, 0x58, 0x70, 0x00, 0x08,
+0x54, 0x53, 0xbf, 0xff, 0x84, 0x21, 0x10, 0x13, 0x00, 0x0f, 0xad, 0x76, 0xa9, 0xf4, 0x80, 0x09,
+0x80, 0x26, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x87, 0xa0, 0xdd, 0x2f, 0x84, 0x01, 0xd5, 0x02,
+0x84, 0x00, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xfc, 0x44, 0x20, 0x00, 0x14, 0x80, 0xc0, 0x80, 0xe1, 0x84, 0x20, 0x46, 0xf0, 0x01, 0x02,
+0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xa6, 0x70, 0xa6, 0xb4, 0xa6, 0x31, 0x84, 0x7e, 0x40, 0x40,
+0x8c, 0x02, 0x92, 0x02, 0x94, 0x02, 0x40, 0x51, 0x0c, 0x02, 0xaf, 0x30, 0xaf, 0x74, 0xae, 0x31,
+0xa7, 0x37, 0x00, 0x33, 0x80, 0x9d, 0x54, 0x21, 0x00, 0x02, 0xae, 0xf5, 0xa6, 0xf3, 0xa1, 0x7b,
+0x00, 0x03, 0x80, 0x9e, 0x54, 0x31, 0x80, 0x38, 0x98, 0x28, 0x96, 0x01, 0x40, 0x70, 0x20, 0x09,
+0x54, 0x53, 0x80, 0x0f, 0x92, 0x84, 0x95, 0x24, 0x40, 0x42, 0x14, 0x04, 0x58, 0x21, 0x00, 0x1c,
+0x54, 0x50, 0x80, 0x08, 0x58, 0x31, 0x80, 0x40, 0x84, 0x20, 0xaf, 0x70, 0xaf, 0x37, 0xae, 0xb4,
+0xae, 0x72, 0xae, 0xf3, 0xae, 0x36, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xfc, 0x44, 0x20, 0x00, 0x14, 0x80, 0xc0, 0x80, 0xe1, 0x84, 0x20,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xa6, 0x70, 0xa6, 0xb4, 0xa6, 0x31,
+0x84, 0x7e, 0x40, 0x40, 0x8c, 0x02, 0x92, 0x02, 0x94, 0x02, 0x40, 0x51, 0x0c, 0x02, 0xaf, 0x30,
+0xaf, 0x74, 0xae, 0x31, 0xa7, 0x37, 0x00, 0x33, 0x80, 0x9d, 0x54, 0x21, 0x00, 0x02, 0xae, 0xf5,
+0xa6, 0xf3, 0xa1, 0x7b, 0x00, 0x03, 0x80, 0x9e, 0x58, 0x21, 0x00, 0x1c, 0x98, 0x28, 0x96, 0x01,
+0x40, 0x70, 0x20, 0x09, 0x54, 0x53, 0x80, 0x0f, 0x92, 0x84, 0x95, 0x24, 0x40, 0x42, 0x14, 0x04,
+0x54, 0x31, 0x80, 0x38, 0x54, 0x50, 0x80, 0x08, 0x84, 0x20, 0xaf, 0x70, 0xaf, 0x37, 0xae, 0xb4,
+0xae, 0x72, 0xae, 0xf3, 0xae, 0x36, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa0, 0xbc, 0x44, 0x60, 0x00, 0x18, 0x10, 0x60, 0x00, 0x9e, 0x50, 0x60, 0x00, 0x24,
+0x80, 0xe0, 0x84, 0x20, 0x44, 0x20, 0x00, 0x18, 0x80, 0x06, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7,
+0x87, 0x08, 0xdd, 0x2f, 0xa6, 0xf0, 0x00, 0x83, 0x00, 0x01, 0x44, 0x0f, 0xff, 0xd8, 0x40, 0x44,
+0x00, 0x02, 0x54, 0x51, 0x80, 0x03, 0x58, 0x22, 0x80, 0x08, 0x58, 0x12, 0x00, 0x01, 0x84, 0x60,
+0x10, 0x33, 0x00, 0x16, 0x10, 0x33, 0x00, 0x17, 0xae, 0xb0, 0xae, 0x71, 0x46, 0x80, 0x01, 0x02,
+0x58, 0x84, 0x06, 0xf0, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x80, 0xb5, 0x84, 0x46, 0x50, 0x03,
+0x80, 0x28, 0x4b, 0xe0, 0x20, 0x01, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x81, 0x28, 0x84, 0x46,
+0x50, 0x03, 0x80, 0x2e, 0x4b, 0xe0, 0x20, 0x01, 0xa0, 0x79, 0x50, 0x03, 0x80, 0x34, 0x84, 0x46,
+0x4b, 0xe0, 0x20, 0x01, 0x00, 0x03, 0x80, 0x94, 0xc0, 0x06, 0xa6, 0x71, 0x59, 0xe0, 0x80, 0x40,
+0x11, 0xe3, 0x00, 0x01, 0xa7, 0x31, 0x42, 0x22, 0x10, 0x09, 0xae, 0xb1, 0x3a, 0x6f, 0xa0, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x80, 0x20, 0x46, 0x00, 0x00, 0x0d,
+0x58, 0x00, 0x0e, 0x74, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x86, 0x7c, 0xdd, 0x2f, 0x84, 0x00,
+0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa8, 0xbc, 0xef, 0x60, 0x81, 0x01,
+0x80, 0xe2, 0x50, 0x9f, 0x80, 0x24, 0x84, 0x20, 0x44, 0x20, 0x00, 0xa0, 0x80, 0x1f, 0x81, 0x43,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0x84, 0x80, 0x80, 0x28, 0x80, 0x47,
+0x84, 0x7f, 0x80, 0x09, 0xf4, 0x83, 0x10, 0x3f, 0x80, 0x9d, 0xf4, 0x82, 0xb7, 0x5f, 0x14, 0x8f,
+0x80, 0x01, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xf0, 0xdd, 0x2f, 0x96, 0xb8, 0x40, 0x04,
+0x88, 0x00, 0x9d, 0x43, 0x40, 0x42, 0x88, 0x09, 0x95, 0x22, 0x9a, 0xe0, 0x80, 0x3f, 0x50, 0x0f,
+0x80, 0x10, 0x10, 0x3f, 0x80, 0x9f, 0x10, 0x2f, 0x80, 0x9e, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x82, 0xf0, 0xdd, 0x2f, 0x80, 0x1f, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x84, 0x14, 0xdd, 0x2f,
+0x80, 0xdf, 0x84, 0x01, 0xec, 0xa0, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc,
+0xef, 0x5c, 0x81, 0x00, 0x97, 0x90, 0x40, 0x90, 0x80, 0x13, 0x80, 0x1f, 0x84, 0x20, 0x44, 0x20,
+0x00, 0xa0, 0x04, 0x74, 0x00, 0x02, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f,
+0xce, 0x10, 0x46, 0x40, 0x00, 0x0d, 0x58, 0x42, 0x0e, 0x74, 0x00, 0x32, 0x01, 0x70, 0xcb, 0x02,
+0xd5, 0x09, 0x00, 0x02, 0x01, 0x71, 0xc0, 0x05, 0x50, 0x42, 0x01, 0x30, 0x80, 0x46, 0xd5, 0x05,
+0x84, 0x60, 0x80, 0x83, 0x44, 0x20, 0x00, 0xff, 0x87, 0xc1, 0x50, 0x53, 0x80, 0x0e, 0x50, 0x14,
+0xff, 0xf2, 0x80, 0x1f, 0x11, 0xef, 0x80, 0x9d, 0x10, 0x3f, 0x80, 0x94, 0xb7, 0x1f, 0xf5, 0x82,
+0xf1, 0x83, 0xf4, 0xa6, 0x10, 0x2f, 0x80, 0x9c, 0xf7, 0x81, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7,
+0x83, 0x70, 0xdd, 0x2f, 0x00, 0x0f, 0x80, 0x9e, 0x50, 0x2f, 0x80, 0x24, 0x99, 0x50, 0x9d, 0xeb,
+0x92, 0xe2, 0x95, 0xfa, 0x9b, 0x3d, 0x10, 0x4f, 0x80, 0x9f, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84,
+0x06, 0xf0, 0x46, 0x10, 0x00, 0x0a, 0x58, 0x10, 0x8f, 0xf4, 0x84, 0x46, 0x80, 0x07, 0x4b, 0xe0,
+0x20, 0x01, 0xf1, 0x01, 0x9c, 0x3e, 0x8c, 0x2c, 0x84, 0x42, 0x4b, 0xe0, 0x20, 0x01, 0x00, 0x3f,
+0x80, 0x9e, 0x80, 0x3f, 0x50, 0x21, 0x80, 0x08, 0x50, 0x0f, 0x80, 0x10, 0x10, 0x2f, 0x80, 0x9e,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x82, 0x6c, 0xdd, 0x2f, 0x80, 0x1f, 0x46, 0xf0, 0x00, 0x02,
+0x58, 0xf7, 0x84, 0x14, 0xdd, 0x2f, 0x80, 0xdf, 0x84, 0x00, 0xec, 0xa4, 0x3a, 0x6f, 0xa4, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf0, 0xb4, 0x60, 0xa6, 0x98, 0x54, 0x11,
+0x00, 0x80, 0x4e, 0x12, 0x00, 0x9a, 0x05, 0xe0, 0x00, 0x02, 0x44, 0x50, 0x00, 0x80, 0x00, 0x6f,
+0x00, 0x00, 0x54, 0x43, 0x00, 0xf0, 0x4c, 0x42, 0xc0, 0x90, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x37,
+0x83, 0x5a, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x17, 0x81, 0x88, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63,
+0x0e, 0x74, 0x84, 0x41, 0x14, 0x33, 0x00, 0x92, 0x4c, 0x11, 0x40, 0x31, 0x02, 0x10, 0x00, 0x0a,
+0xa0, 0x04, 0x80, 0x5f, 0x50, 0x3f, 0x80, 0x08, 0x50, 0x4f, 0x80, 0x0e, 0x46, 0xf0, 0x00, 0x02,
+0x58, 0xf7, 0x89, 0x84, 0xdd, 0x2f, 0x02, 0x03, 0x01, 0x28, 0xc0, 0x0f, 0x01, 0xe3, 0x02, 0xa8,
+0x84, 0xa1, 0x4d, 0xe2, 0xc0, 0x0b, 0x00, 0x23, 0x02, 0x51, 0xc2, 0x07, 0x84, 0x00, 0x46, 0xf0,
+0x00, 0x02, 0x58, 0xf7, 0x8d, 0xb4, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x07, 0x80, 0xc4,
+0x46, 0xf0, 0x00, 0x0e, 0x00, 0x47, 0x80, 0xc5, 0x46, 0x30, 0x00, 0x0e, 0x58, 0x31, 0x81, 0x88,
+0x87, 0xc0, 0x11, 0xe1, 0x80, 0x03, 0xae, 0x19, 0xaf, 0x1a, 0x46, 0xf0, 0x00, 0x0e, 0x04, 0x27,
+0x80, 0x62, 0x40, 0x21, 0x20, 0x08, 0x92, 0x48, 0x84, 0xa1, 0xda, 0x46, 0x46, 0xf0, 0x00, 0x0e,
+0x00, 0x17, 0x81, 0x8c, 0x4c, 0x11, 0x00, 0x3f, 0x84, 0xa2, 0xd9, 0x04, 0x44, 0x00, 0x00, 0xc8,
+0xd5, 0x12, 0x84, 0xa3, 0xd1, 0x0e, 0x84, 0x04, 0x4c, 0x10, 0x00, 0x0c, 0x56, 0x30, 0x80, 0x05,
+0x45, 0xe0, 0x15, 0x7c, 0x84, 0x40, 0x40, 0x01, 0x0c, 0x1b, 0x40, 0x0f, 0x0c, 0x1a, 0xd5, 0x03,
+0x44, 0x00, 0x07, 0xd0, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x37, 0x80, 0xc2, 0xcb, 0x05, 0x46, 0xf0,
+0x00, 0x0e, 0x00, 0x37, 0x80, 0xc3, 0x46, 0x20, 0x04, 0x11, 0x05, 0xe1, 0x00, 0x49, 0x46, 0xf0,
+0x00, 0x0e, 0x04, 0x57, 0x80, 0x64, 0x40, 0x2f, 0x18, 0x08, 0x44, 0x40, 0x03, 0xe8, 0x42, 0x42,
+0x90, 0x24, 0x51, 0xe1, 0x51, 0x20, 0x40, 0x2f, 0x00, 0x01, 0x9f, 0x59, 0x42, 0x22, 0x14, 0x73,
+0x4e, 0x27, 0x00, 0x0b, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7, 0x82, 0x9c, 0xdd, 0x2f,
+0xd5, 0x03, 0x84, 0x02, 0xd5, 0xd8, 0xec, 0x10, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x17, 0x80, 0xc8, 0x80, 0xc0, 0xc1, 0x06,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8f, 0x5c, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x07,
+0x80, 0xd8, 0x84, 0xa1, 0x4c, 0x02, 0x80, 0x8a, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x57, 0x81, 0x88,
+0x4e, 0x52, 0x00, 0x84, 0xb4, 0x26, 0xa6, 0x48, 0x55, 0xe0, 0x80, 0x60, 0x4f, 0xe3, 0x00, 0x0f,
+0x54, 0x20, 0x80, 0x10, 0xc2, 0x0b, 0xa1, 0x32, 0xa6, 0xe1, 0x54, 0x61, 0x80, 0x20, 0x96, 0x70,
+0xc9, 0x05, 0x46, 0xf0, 0x00, 0x0e, 0x10, 0x17, 0x81, 0x8a, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x07,
+0x80, 0xc5, 0xc0, 0x0d, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00, 0x01, 0x88, 0x01, 0xe0, 0x00, 0x02,
+0x4f, 0xe2, 0x00, 0x06, 0xa6, 0x41, 0xc1, 0x03, 0x84, 0x20, 0xd5, 0x06, 0x84, 0x21, 0x46, 0x00,
+0x00, 0x0e, 0x58, 0x00, 0x01, 0x88, 0xae, 0x43, 0x46, 0xf0, 0x00, 0x0e, 0x04, 0x47, 0x80, 0x62,
+0x46, 0x0f, 0xf0, 0x00, 0x58, 0x00, 0x00, 0xff, 0x46, 0x30, 0x10, 0x00, 0x40, 0x52, 0x00, 0x02,
+0x58, 0x31, 0x80, 0x01, 0xdb, 0x4a, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8d, 0xb4,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x17, 0x81, 0x8c, 0x84, 0xa1, 0xd1, 0x3c, 0x84, 0xa2,
+0xd9, 0x04, 0x44, 0x00, 0x00, 0xc8, 0xd5, 0x11, 0x84, 0xa3, 0xd1, 0x0d, 0x84, 0xa4, 0xd1, 0x0b,
+0x56, 0x40, 0x80, 0x05, 0x44, 0x50, 0x15, 0x7c, 0x87, 0xc0, 0x40, 0x0f, 0x10, 0x1b, 0x40, 0x02,
+0x90, 0x1a, 0xd5, 0x03, 0x44, 0x00, 0x07, 0xd0, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x37, 0x80, 0xc2,
+0xcb, 0x05, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x37, 0x80, 0xc3, 0x46, 0x20, 0x04, 0x11, 0x05, 0xe1,
+0x00, 0x49, 0x46, 0xf0, 0x00, 0x0e, 0x04, 0x57, 0x80, 0x64, 0x40, 0x2f, 0x18, 0x08, 0x44, 0x40,
+0x03, 0xe8, 0x43, 0xe2, 0x90, 0x24, 0x50, 0x21, 0x51, 0x20, 0x9a, 0x90, 0x9e, 0x19, 0x42, 0x2f,
+0x00, 0x73, 0x4e, 0x27, 0x00, 0x0b, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7, 0x82, 0x9c,
+0xdd, 0x2f, 0xd5, 0x03, 0x84, 0x02, 0xd5, 0xd9, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xe0, 0x80, 0x60, 0xa4, 0x06, 0x5c, 0xf0, 0x00, 0x35, 0xe9, 0x2e,
+0xa0, 0x5a, 0x9c, 0x8c, 0xa7, 0x97, 0x40, 0x43, 0x18, 0x09, 0x46, 0xf0, 0x00, 0x0e, 0x10, 0x47,
+0x81, 0x1d, 0xc1, 0x24, 0xa7, 0x89, 0x55, 0xe3, 0x00, 0x01, 0x4f, 0xe3, 0x00, 0x20, 0x54, 0x63,
+0x00, 0x06, 0xce, 0x1c, 0xd5, 0x20, 0x12, 0x20, 0x00, 0x0a, 0x12, 0x60, 0x00, 0x0b, 0xa6, 0xa0,
+0x40, 0x11, 0x08, 0x09, 0x54, 0x10, 0x80, 0x03, 0xc1, 0x0b, 0x84, 0xa2, 0xd1, 0x02, 0xd5, 0x06,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x86, 0xf0, 0xdd, 0x2f, 0x84, 0x01, 0xd5, 0x08, 0x46, 0xf0,
+0x00, 0x02, 0x58, 0xf7, 0x85, 0xa4, 0xdd, 0x2f, 0xd5, 0xf9, 0x84, 0x00, 0xec, 0x20, 0x3a, 0x6f,
+0x98, 0x84, 0xdd, 0x9e, 0x50, 0x0f, 0x80, 0x04, 0x50, 0x40, 0x80, 0x1c, 0xb6, 0x20, 0xa8, 0x81,
+0xa8, 0xc3, 0xa9, 0x02, 0xa9, 0x04, 0x46, 0xf0, 0x00, 0x0e, 0x01, 0xe7, 0x80, 0xd8, 0xa7, 0x53,
+0xa6, 0xd2, 0x54, 0x22, 0x80, 0x0f, 0x40, 0x11, 0x20, 0x08, 0x84, 0xa1, 0x40, 0x20, 0x8c, 0x04,
+0x4d, 0xe2, 0xff, 0xcb, 0xd5, 0xe3, 0x92, 0x00, 0x84, 0x60, 0xd5, 0x0e, 0x38, 0x50, 0x0c, 0x00,
+0x38, 0x40, 0x8c, 0x00, 0x9c, 0xd9, 0xe2, 0x85, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x08, 0xe2, 0xa4,
+0xe8, 0x03, 0x84, 0x02, 0xd5, 0x04, 0xe2, 0x62, 0xe9, 0xf2, 0x84, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0x3c, 0x9c, 0x01, 0x08, 0x60, 0x00, 0x01, 0x96, 0x49, 0xaf, 0x90, 0x08, 0x60,
+0x00, 0x01, 0xaf, 0xa0, 0x08, 0x60, 0x00, 0x01, 0xaf, 0xa8, 0xa7, 0xa0, 0xa7, 0x40, 0xf4, 0x01,
+0xce, 0x05, 0x97, 0xac, 0xc6, 0x03, 0x84, 0xc1, 0xd5, 0x02, 0x84, 0xc0, 0xaf, 0x98, 0x54, 0x32,
+0x80, 0xfe, 0x95, 0x5b, 0xa6, 0x90, 0xe0, 0x25, 0xe9, 0x08, 0x9e, 0x94, 0x99, 0x5a, 0x96, 0xa8,
+0x9d, 0x51, 0x94, 0xab, 0xe0, 0x22, 0xe9, 0x03, 0x84, 0x00, 0xd5, 0x16, 0x40, 0x50, 0x8c, 0x09,
+0x9a, 0xeb, 0x96, 0x98, 0x98, 0x02, 0x96, 0xd4, 0x84, 0xa8, 0x40, 0x21, 0x8c, 0x1a, 0x40, 0x22,
+0x8c, 0x1b, 0x20, 0x00, 0x00, 0x01, 0x54, 0x50, 0x80, 0x0f, 0x9a, 0xea, 0x40, 0x10, 0x0c, 0x0e,
+0x96, 0x4c, 0xc1, 0x04, 0x84, 0x01, 0xae, 0x20, 0xd5, 0x02, 0xae, 0x60, 0x84, 0x01, 0x3a, 0x6f,
+0x98, 0x04, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xdc, 0x85, 0x20, 0xf4, 0x83, 0x12, 0x92,
+0x00, 0x00, 0x80, 0xa0, 0x08, 0x42, 0x80, 0x0a, 0xf3, 0x82, 0x40, 0x82, 0x10, 0x09, 0xf1, 0x85,
+0x14, 0x8f, 0x80, 0x04, 0x80, 0xc0, 0x80, 0x25, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xf0,
+0x80, 0x02, 0x84, 0x46, 0x4b, 0xe0, 0x1c, 0x01, 0xf0, 0x02, 0x50, 0x13, 0x00, 0x10, 0x84, 0x46,
+0x47, 0xc0, 0x00, 0x0d, 0x59, 0xce, 0x0e, 0x74, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0xa0, 0x00, 0x24,
+0x50, 0x73, 0x00, 0x24, 0x50, 0x9e, 0x02, 0x51, 0x50, 0x6f, 0x80, 0x1f, 0x46, 0x80, 0x00, 0x02,
+0x58, 0x84, 0x09, 0x00, 0xd5, 0x2c, 0xf0, 0x03, 0xa4, 0x80, 0x98, 0x51, 0x5e, 0xf0, 0x81, 0x7e,
+0xe8, 0x2f, 0x01, 0xe3, 0x80, 0x00, 0x84, 0x65, 0x4d, 0xe1, 0xc0, 0x1e, 0xf4, 0x04, 0x84, 0xa8,
+0xdc, 0x1a, 0xf0, 0x02, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x80, 0xb5, 0x84, 0x46, 0x46, 0xf0,
+0x01, 0x02, 0x58, 0xf7, 0x86, 0xd4, 0xdd, 0x2f, 0xc8, 0x0e, 0x02, 0x1e, 0x01, 0x26, 0xb7, 0x3f,
+0x80, 0x07, 0x80, 0x46, 0x50, 0x34, 0xff, 0xff, 0x50, 0x44, 0xff, 0xfd, 0x50, 0x54, 0xff, 0xfe,
+0x4b, 0xe0, 0x20, 0x01, 0xa6, 0xb9, 0x9c, 0x52, 0x99, 0xf9, 0x89, 0x41, 0xa6, 0x79, 0x05, 0xef,
+0x80, 0x05, 0x9c, 0xca, 0x40, 0x01, 0xa8, 0x00, 0x40, 0xff, 0x00, 0x06, 0xe8, 0xcd, 0x84, 0x01,
+0xec, 0x24, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa8, 0xbc, 0x80, 0xc0, 0x54, 0xa0,
+0x80, 0xff, 0x54, 0x91, 0x00, 0xff, 0x84, 0x20, 0x44, 0x20, 0x00, 0x18, 0x80, 0xe3, 0x81, 0x04,
+0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xa7, 0x30, 0xa6, 0x31, 0x54, 0x32,
+0x00, 0x03, 0x40, 0x55, 0x10, 0x08, 0x42, 0x40, 0x00, 0x09, 0x54, 0x24, 0x80, 0x01, 0x40, 0x02,
+0x08, 0x04, 0x40, 0x11, 0x94, 0x04, 0xae, 0x70, 0xae, 0x31, 0x80, 0x27, 0x84, 0x46, 0x46, 0x70,
+0x01, 0x02, 0x58, 0x73, 0x86, 0xf0, 0x9c, 0x34, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x10, 0x00, 0x0e,
+0x58, 0x10, 0x81, 0x28, 0x84, 0x46, 0x50, 0x03, 0x00, 0x0a, 0x4b, 0xe0, 0x1c, 0x01, 0x50, 0x03,
+0x00, 0x10, 0x80, 0x28, 0x84, 0x46, 0x4b, 0xe0, 0x1c, 0x01, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e,
+0x3a, 0x2f, 0x94, 0x3c, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x81, 0x20, 0x50, 0x0f, 0x80, 0x20,
+0xf0, 0x81, 0x80, 0xe1, 0x84, 0xc0, 0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x06, 0xa4, 0xf2, 0x01,
+0x84, 0xbf, 0x9d, 0x14, 0xf4, 0x81, 0x40, 0x04, 0x98, 0x00, 0xb4, 0x62, 0x9c, 0x64, 0x80, 0x43,
+0xd3, 0x07, 0xf1, 0x81, 0x99, 0xb3, 0xb4, 0x24, 0x4b, 0xe0, 0x20, 0x01, 0xd5, 0xf1, 0x80, 0x06,
+0xb6, 0xc7, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84, 0xec, 0x10, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x74, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff,
+0xfc, 0x84, 0xdd, 0x9e, 0x46, 0x00, 0x04, 0x11, 0xa0, 0x81, 0x58, 0x11, 0x00, 0x0c, 0xa8, 0x41,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0x3c, 0x46, 0x40, 0x04, 0x10, 0x46, 0x30, 0x04, 0x10,
+0x46, 0x20, 0x04, 0x10, 0x58, 0x42, 0x04, 0x38, 0x58, 0x31, 0x8a, 0x30, 0x58, 0x21, 0x0a, 0x34,
+0x84, 0x20, 0xb4, 0xc4, 0xb4, 0xa3, 0x5c, 0x63, 0x00, 0x01, 0x96, 0x28, 0xc0, 0x02, 0x84, 0xc0,
+0xb4, 0xa2, 0x46, 0x7f, 0xf0, 0x0f, 0x58, 0x73, 0x8f, 0x00, 0x40, 0x02, 0x9c, 0x02, 0x9c, 0x49,
+0xc8, 0x02, 0xce, 0x08, 0x84, 0x1f, 0x4c, 0x50, 0x00, 0x92, 0x44, 0x50, 0x07, 0xd0, 0xd9, 0xea,
+0xd5, 0x6b, 0x46, 0x10, 0x04, 0x11, 0x58, 0x10, 0x82, 0x00, 0xb4, 0x81, 0x96, 0xa4, 0xc2, 0x17,
+0x84, 0x40, 0xd5, 0x0b, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0xd9, 0x4c, 0x33, 0x7f, 0xfd, 0x9c, 0x91,
+0x44, 0x70, 0x00, 0x32, 0x4c, 0x23, 0x80, 0x04, 0x84, 0x60, 0xd5, 0xf5, 0x84, 0x7f, 0x4c, 0x41,
+0x80, 0x76, 0x9c, 0x01, 0x44, 0x40, 0x07, 0xd0, 0x4c, 0x02, 0x7f, 0xe9, 0x46, 0x60, 0x04, 0x11,
+0x58, 0x63, 0x00, 0x04, 0xb4, 0x06, 0x84, 0xb7, 0x40, 0x10, 0x14, 0x02, 0x46, 0x40, 0x04, 0x10,
+0x46, 0x30, 0x04, 0x10, 0x46, 0x20, 0x04, 0x10, 0xb6, 0x26, 0x58, 0x42, 0x04, 0x38, 0x58, 0x31,
+0x8a, 0x30, 0x58, 0x21, 0x0a, 0x34, 0x84, 0x20, 0xb4, 0xa4, 0x46, 0x60, 0x0f, 0xf0, 0xb4, 0x03,
+0x40, 0x52, 0x98, 0x02, 0xc0, 0x03, 0x84, 0xa0, 0xd5, 0x03, 0x5c, 0x52, 0x80, 0x01, 0xb4, 0x02,
+0x9c, 0x49, 0xc8, 0x03, 0xc5, 0x05, 0xd5, 0x09, 0x84, 0xff, 0x4c, 0x03, 0x80, 0x48, 0x44, 0x00,
+0x07, 0xd0, 0x4c, 0x10, 0x7f, 0xeb, 0xd5, 0x31, 0x46, 0x10, 0x04, 0x11, 0x58, 0x10, 0x82, 0x00,
+0xb4, 0x81, 0x54, 0x22, 0x00, 0x02, 0xc2, 0x3a, 0x84, 0x40, 0xd5, 0x0b, 0x92, 0x00, 0x84, 0xe7,
+0x9c, 0xd9, 0x4c, 0x33, 0xff, 0xfd, 0x9c, 0x91, 0x44, 0x60, 0x00, 0x32, 0x4c, 0x23, 0x00, 0x04,
+0x84, 0x60, 0xd5, 0xf5, 0x84, 0xff, 0x4c, 0x43, 0x80, 0x2a, 0x9c, 0x01, 0x44, 0x30, 0x07, 0xd0,
+0x4c, 0x01, 0xff, 0xe8, 0xd5, 0x23, 0x46, 0x10, 0x04, 0x10, 0x46, 0x60, 0x04, 0x10, 0x46, 0x40,
+0x04, 0x10, 0x58, 0x10, 0x8a, 0x30, 0x58, 0x63, 0x0a, 0x34, 0x58, 0x42, 0x04, 0x38, 0xb4, 0x41,
+0xb4, 0x26, 0xb4, 0x04, 0x84, 0x00, 0xd5, 0x86, 0x46, 0x20, 0x04, 0x10, 0x46, 0x00, 0x04, 0x10,
+0x46, 0x50, 0x04, 0x10, 0x58, 0x00, 0x0a, 0x34, 0x58, 0x21, 0x0a, 0x30, 0x58, 0x52, 0x84, 0x38,
+0xb4, 0x42, 0xb4, 0x20, 0xb4, 0x05, 0x84, 0x00, 0xd5, 0xc0, 0x3a, 0x6f, 0x9c, 0x04, 0xdd, 0x9e,
+0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xfc, 0x46, 0x60, 0x00, 0x0e, 0x58, 0x63, 0x00, 0xc8, 0x46, 0x70,
+0x01, 0x02, 0x58, 0x73, 0x87, 0x08, 0x84, 0x20, 0x44, 0x20, 0x00, 0x10, 0x80, 0x06, 0x4b, 0xe0,
+0x1c, 0x01, 0x84, 0x20, 0x44, 0x20, 0x01, 0x8c, 0x50, 0x03, 0x7e, 0x74, 0x4b, 0xe0, 0x1c, 0x01,
+0x84, 0x20, 0x84, 0x46, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00, 0x01, 0x28, 0x4b, 0xe0, 0x1c, 0x01,
+0x84, 0x40, 0x80, 0x62, 0x46, 0x70, 0x00, 0x00, 0x58, 0x73, 0x81, 0x0c, 0x50, 0x03, 0x00, 0x14,
+0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x8e, 0x78, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x40, 0x50, 0x03,
+0x00, 0x30, 0x80, 0x62, 0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x8d, 0x48, 0x4b, 0xe0, 0x1c, 0x01,
+0x84, 0x00, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8e, 0x74, 0x46, 0xf0, 0x00, 0x0e, 0x10, 0x07,
+0x81, 0x88, 0x10, 0x00, 0x82, 0x65, 0x10, 0x00, 0x82, 0x66, 0x10, 0x00, 0x82, 0x64, 0xec, 0x04,
+0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0x00,
+0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74, 0x04, 0x20, 0x00, 0xa8, 0x96, 0x54, 0xc1, 0x1c, 0x04, 0x50,
+0x00, 0x92, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x47, 0x83, 0x5a, 0x50, 0x32, 0x83, 0xe8, 0x46, 0x10,
+0x00, 0x0d, 0x58, 0x10, 0x8c, 0xe4, 0xe2, 0x64, 0xe8, 0x0c, 0xb4, 0x81, 0x9c, 0xa1, 0xb6, 0x41,
+0xe4, 0x4a, 0xe9, 0x09, 0x04, 0x50, 0x00, 0xa9, 0x42, 0x32, 0xf0, 0x08, 0x14, 0x30, 0x00, 0xa9,
+0x84, 0x00, 0xb6, 0x01, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00, 0x00, 0xf8, 0x44, 0x10, 0x03, 0xe8,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x54, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0xbc, 0x81, 0x00, 0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7,
+0x84, 0x94, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x54, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x83, 0x24, 0xdd, 0x2f, 0x80, 0xe0, 0xc0, 0x4c, 0xa1, 0x82, 0x46, 0x30, 0x00, 0x0e,
+0x58, 0x31, 0x80, 0xb5, 0x80, 0x83, 0x80, 0x06, 0x84, 0x24, 0x84, 0x41, 0x46, 0xf0, 0x00, 0x02,
+0x58, 0xf7, 0x8a, 0x58, 0xdd, 0x2f, 0x84, 0x40, 0xae, 0xb2, 0xae, 0xb3, 0x46, 0x10, 0x00, 0x0d,
+0x58, 0x10, 0x8e, 0x74, 0x00, 0x30, 0x82, 0x66, 0xa7, 0x30, 0x00, 0x53, 0x00, 0x16, 0xa6, 0x31,
+0x85, 0x53, 0x54, 0x91, 0x80, 0x0f, 0x40, 0x42, 0x28, 0x02, 0x54, 0x84, 0x00, 0x01, 0x40, 0x94,
+0x90, 0x08, 0x54, 0x52, 0x80, 0x0f, 0x40, 0x84, 0x10, 0x08, 0x42, 0x00, 0x10, 0x09, 0x40, 0x00,
+0x20, 0x04, 0x92, 0x64, 0x58, 0x42, 0x00, 0x08, 0x40, 0x52, 0xa4, 0x04, 0x10, 0x33, 0x00, 0x17,
+0xaf, 0x30, 0x10, 0x53, 0x00, 0x16, 0xae, 0x31, 0x44, 0x30, 0x00, 0xff, 0x00, 0x00, 0x82, 0x66,
+0x9d, 0x01, 0x10, 0x40, 0x82, 0x66, 0x4c, 0x01, 0xc0, 0x04, 0x10, 0x20, 0x82, 0x66, 0x80, 0x26,
+0x80, 0x67, 0x84, 0x00, 0x8c, 0x58, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x84, 0x38, 0xdd, 0x2f,
+0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x0e, 0x00, 0x07, 0x81, 0x88, 0x84, 0x41, 0x46, 0x10, 0x00, 0x02, 0x58, 0x10, 0x8d, 0xb4,
+0x4c, 0x01, 0x40, 0x03, 0xd5, 0x02, 0x84, 0x00, 0x4b, 0xe0, 0x04, 0x01, 0x46, 0x00, 0x00, 0x0e,
+0x58, 0x00, 0x00, 0xdc, 0x44, 0x10, 0x27, 0x10, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x82, 0x54,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0x84, 0x20, 0x80, 0xc0, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x84, 0x6c, 0xdd, 0x2f,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8b, 0x44, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10,
+0x8e, 0x74, 0x00, 0x20, 0x82, 0x65, 0x84, 0x01, 0x14, 0x60, 0x80, 0xa9, 0x10, 0x00, 0x82, 0x64,
+0xca, 0x14, 0x46, 0x40, 0x04, 0x00, 0x05, 0xe2, 0x00, 0x19, 0x42, 0x5f, 0x00, 0x09, 0x14, 0x52,
+0x00, 0x19, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x34, 0xb4, 0x60, 0x96, 0x99, 0xb6, 0x40,
+0x46, 0x31, 0x23, 0x40, 0xb4, 0x20, 0xd5, 0x15, 0x84, 0xa1, 0xda, 0x16, 0x46, 0x40, 0x04, 0x00,
+0x05, 0xe2, 0x00, 0x20, 0x46, 0x00, 0x04, 0x00, 0x58, 0x5f, 0x00, 0x80, 0x14, 0x52, 0x00, 0x20,
+0x58, 0x00, 0x02, 0x34, 0xb4, 0x60, 0x96, 0x99, 0xb6, 0x40, 0x46, 0x35, 0x67, 0x80, 0xb4, 0x20,
+0x40, 0x10, 0x8c, 0x04, 0xd5, 0x08, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x80, 0xb4, 0x20,
+0x42, 0x10, 0xc0, 0x08, 0xb6, 0x20, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc,
+0xef, 0xf4, 0xa0, 0x82, 0x80, 0xc0, 0xa6, 0xd0, 0x40, 0x11, 0x90, 0x09, 0x54, 0x00, 0x80, 0x04,
+0x4e, 0x03, 0x01, 0x06, 0xb4, 0x26, 0xa6, 0x08, 0x54, 0x40, 0x00, 0x60, 0xc4, 0x05, 0x54, 0x50,
+0x00, 0x80, 0x4e, 0x52, 0x00, 0xfd, 0xa7, 0xd1, 0x54, 0x23, 0x80, 0x40, 0xc2, 0x07, 0x00, 0x90,
+0x80, 0x02, 0x54, 0x84, 0x80, 0x01, 0x4e, 0x82, 0x00, 0xf3, 0x55, 0xe0, 0x00, 0x40, 0x4f, 0xe2,
+0x00, 0x04, 0x84, 0xe3, 0xd5, 0x0e, 0x54, 0x10, 0x00, 0x10, 0xc1, 0x03, 0x84, 0xe1, 0xd5, 0x09,
+0x54, 0x40, 0x00, 0x20, 0x96, 0x20, 0x84, 0x62, 0x40, 0x70, 0x00, 0x1a, 0x40, 0x71, 0x80, 0x1b,
+0xa0, 0xb4, 0x02, 0x13, 0x00, 0x0a, 0x8c, 0x58, 0x51, 0xe0, 0xff, 0xe8, 0x13, 0xe3, 0x00, 0x0a,
+0xa8, 0xb4, 0x04, 0x93, 0x00, 0x02, 0x00, 0x84, 0x80, 0x00, 0x40, 0x54, 0x10, 0x09, 0x54, 0x02,
+0x80, 0x08, 0xc0, 0x1d, 0x02, 0x43, 0x00, 0x0b, 0x58, 0x02, 0x00, 0x40, 0x96, 0x41, 0x12, 0x13,
+0x00, 0x0b, 0xa6, 0x10, 0x96, 0xc2, 0x4e, 0x34, 0x00, 0x06, 0x58, 0x50, 0x80, 0x02, 0x12, 0x53,
+0x00, 0x0b, 0xa0, 0x74, 0x03, 0xe3, 0x00, 0x0a, 0x50, 0x90, 0x80, 0x02, 0x50, 0x8f, 0x7f, 0xfe,
+0x14, 0x93, 0x00, 0x04, 0x12, 0x83, 0x00, 0x0a, 0x54, 0x00, 0x00, 0x0f, 0x10, 0x03, 0x00, 0x18,
+0xb4, 0x06, 0xa6, 0xc1, 0x54, 0x21, 0x80, 0x10, 0xc2, 0x12, 0x02, 0x13, 0x00, 0x0b, 0x05, 0xe3,
+0x00, 0x04, 0x02, 0x93, 0x00, 0x0a, 0x58, 0x80, 0x80, 0x08, 0x50, 0x5f, 0x00, 0x04, 0x50, 0x44,
+0xff, 0xfc, 0x12, 0x83, 0x00, 0x0b, 0xa9, 0x74, 0x12, 0x43, 0x00, 0x0a, 0xb4, 0x06, 0xa6, 0xc1,
+0x54, 0x21, 0x80, 0x40, 0xc2, 0x0c, 0x02, 0x93, 0x00, 0x0b, 0x04, 0x83, 0x00, 0x04, 0x58, 0x54,
+0x80, 0x10, 0x50, 0x44, 0x00, 0x02, 0x12, 0x53, 0x00, 0x0b, 0xa9, 0x34, 0xa0, 0x34, 0x46, 0x80,
+0x01, 0x02, 0x58, 0x84, 0x06, 0xd4, 0x46, 0x10, 0x00, 0x0a, 0x58, 0x10, 0x8f, 0xf4, 0x84, 0x46,
+0x4b, 0xe0, 0x20, 0x01, 0xc0, 0x0a, 0xa0, 0x34, 0x46, 0x10, 0x00, 0x0a, 0x58, 0x10, 0x8f, 0xfc,
+0x84, 0x46, 0x4b, 0xe0, 0x20, 0x01, 0xc8, 0x73, 0x04, 0x93, 0x00, 0x04, 0x02, 0x53, 0x00, 0x0a,
+0x50, 0x14, 0x80, 0x06, 0x51, 0xe2, 0xff, 0xfa, 0xa8, 0x74, 0x13, 0xe3, 0x00, 0x0a, 0x84, 0x42,
+0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x86, 0xf0, 0xdd, 0x2f, 0xa1, 0x34,
+0x02, 0x03, 0x00, 0x0a, 0x9c, 0xe2, 0x9e, 0x82, 0x84, 0xa2, 0xa8, 0xf4, 0x12, 0x23, 0x00, 0x0a,
+0xd7, 0x16, 0x46, 0xf0, 0x00, 0x0e, 0x04, 0x27, 0x80, 0x34, 0x96, 0x54, 0xc1, 0x10, 0x80, 0x06,
+0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x86, 0x44, 0xdd, 0x2f, 0x84, 0xa1, 0xd8, 0x08, 0x80, 0x26,
+0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8e, 0xbc, 0xdd, 0x2f, 0xd5, 0x41, 0x50, 0x9f, 0x80, 0x04,
+0x46, 0x80, 0x01, 0x02, 0x58, 0x84, 0x06, 0xd4, 0x80, 0x09, 0x46, 0x10, 0x00, 0x0b, 0x58, 0x10,
+0x80, 0x04, 0x84, 0x42, 0x4b, 0xe0, 0x20, 0x01, 0xc0, 0x32, 0x80, 0x09, 0x46, 0x10, 0x00, 0x0b,
+0x58, 0x10, 0x80, 0x0c, 0x84, 0x42, 0x4b, 0xe0, 0x20, 0x01, 0xc8, 0x03, 0x84, 0xa2, 0xdf, 0x27,
+0x50, 0x8f, 0x80, 0x04, 0x46, 0x70, 0x01, 0x02, 0x58, 0x73, 0x86, 0xd4, 0x80, 0x08, 0x46, 0x10,
+0x00, 0x0b, 0x58, 0x10, 0x80, 0x10, 0x84, 0x42, 0x4b, 0xe0, 0x1c, 0x01, 0xc0, 0x18, 0x80, 0x08,
+0x46, 0x10, 0x00, 0x0b, 0x58, 0x10, 0x80, 0x08, 0x84, 0x42, 0x4b, 0xe0, 0x1c, 0x01, 0xc8, 0x0f,
+0xa0, 0x74, 0x84, 0xa3, 0x01, 0xe0, 0x80, 0x01, 0x4d, 0xe2, 0xc0, 0x0a, 0x02, 0x23, 0x00, 0x0a,
+0x80, 0x06, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x8f, 0x30, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f,
+0xa4, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10,
+0x81, 0x94, 0x46, 0xf0, 0x00, 0x0b, 0x14, 0x17, 0x80, 0x54, 0x46, 0x40, 0x04, 0x00, 0x05, 0xe2,
+0x00, 0x08, 0x42, 0x5f, 0x40, 0x09, 0x14, 0x52, 0x00, 0x08, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x8e, 0xcc, 0xdd, 0x2f, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x38, 0xb4, 0x60, 0xb6, 0x60,
+0xa0, 0x81, 0xa8, 0x81, 0xa0, 0x42, 0xa8, 0x42, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x18,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x3c, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x82, 0xec, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x01, 0x58, 0xf7, 0x85, 0x70, 0xdd, 0x2f,
+0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x46, 0x40, 0x00, 0x0d, 0x58, 0x42, 0x0c, 0xe8,
+0x38, 0x12, 0x02, 0x0a, 0x46, 0x10, 0x04, 0x10, 0x58, 0x10, 0x88, 0x00, 0x04, 0x50, 0x80, 0x78,
+0x84, 0x41, 0x40, 0x41, 0x00, 0x0c, 0x40, 0x32, 0x14, 0x04, 0x14, 0x30, 0x80, 0x78, 0x04, 0x20,
+0x80, 0x7a, 0x40, 0x02, 0x08, 0x04, 0x14, 0x00, 0x80, 0x7a, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xf4, 0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x78, 0x96, 0x40,
+0x96, 0x8c, 0xc2, 0x07, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x3a, 0x84, 0x01, 0xd5, 0x68,
+0x54, 0x10, 0x80, 0x02, 0xc1, 0x07, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x3b, 0x84, 0x02,
+0xd5, 0x5f, 0x41, 0xe0, 0x40, 0x09, 0x54, 0x1f, 0x00, 0xff, 0x54, 0x50, 0x80, 0x02, 0xc5, 0x08,
+0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x4b, 0x44, 0x02, 0x00, 0x00, 0xd5, 0x51, 0x96, 0xcc,
+0xc3, 0x08, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x4a, 0x44, 0x01, 0x00, 0x00, 0xd5, 0x48,
+0x40, 0x10, 0x60, 0x09, 0x97, 0x0c, 0xc4, 0x08, 0x46, 0x00, 0x10, 0x00, 0x46, 0xf0, 0x00, 0x0d,
+0x04, 0x17, 0x83, 0x52, 0xd5, 0x3d, 0x54, 0x50, 0x80, 0x02, 0xc5, 0x08, 0x46, 0x00, 0x20, 0x00,
+0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x53, 0xd5, 0x33, 0x54, 0x20, 0x80, 0x04, 0xc2, 0x08,
+0x46, 0x00, 0x40, 0x00, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x54, 0xd5, 0x29, 0x54, 0x40,
+0x80, 0x10, 0xc4, 0x08, 0x46, 0x01, 0x00, 0x00, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x56,
+0xd5, 0x1f, 0x54, 0x50, 0x80, 0x20, 0xc5, 0x08, 0x46, 0x02, 0x00, 0x00, 0x46, 0xf0, 0x00, 0x0d,
+0x04, 0x17, 0x83, 0x57, 0xd5, 0x15, 0x54, 0x20, 0x80, 0x40, 0xc2, 0x08, 0x46, 0x04, 0x00, 0x00,
+0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x58, 0xd5, 0x0b, 0x54, 0x40, 0x80, 0x80, 0x96, 0x60,
+0xc1, 0x07, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0x59, 0x46, 0x08, 0x00, 0x00, 0x47, 0xe0,
+0x04, 0x10, 0x59, 0xef, 0x08, 0x00, 0x14, 0x0f, 0x00, 0x78, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00,
+0x0e, 0x74, 0x04, 0x5f, 0x00, 0x78, 0xf5, 0x81, 0xdd, 0x21, 0xec, 0x0c, 0x3b, 0xff, 0xfc, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x44, 0x40, 0x00, 0x40, 0x84, 0xa0,
+0xf5, 0x81, 0x46, 0x10, 0x04, 0x10, 0x10, 0x4f, 0x80, 0x04, 0x10, 0x4f, 0x80, 0x07, 0x58, 0x10,
+0x88, 0x00, 0xb4, 0x61, 0x50, 0x60, 0x00, 0x9c, 0x58, 0x01, 0x80, 0x02, 0xb6, 0x01, 0x80, 0x01,
+0xf2, 0x01, 0x14, 0x20, 0x80, 0x71, 0x04, 0x70, 0x00, 0x71, 0x42, 0x93, 0x8c, 0x0b, 0xf7, 0x81,
+0x81, 0x01, 0x4e, 0x93, 0xff, 0xfa, 0x42, 0x73, 0x84, 0x0b, 0xcf, 0xf6, 0x46, 0x90, 0x00, 0x03,
+0x58, 0x94, 0x8b, 0x34, 0x50, 0x13, 0x7f, 0x64, 0x50, 0x23, 0x7f, 0xe4, 0x50, 0x04, 0x01, 0xa0,
+0x84, 0x62, 0x4b, 0xe0, 0x24, 0x01, 0x46, 0x00, 0x04, 0x10, 0x50, 0x13, 0x7f, 0x84, 0x50, 0x23,
+0x7f, 0xec, 0x58, 0x00, 0x09, 0xb0, 0x84, 0x62, 0x4b, 0xe0, 0x24, 0x01, 0x46, 0x00, 0x04, 0x10,
+0x46, 0x90, 0x00, 0x03, 0x58, 0x94, 0x8a, 0xe8, 0x50, 0x13, 0x7f, 0xa4, 0x50, 0x23, 0x7f, 0xf4,
+0x58, 0x00, 0x09, 0x80, 0x84, 0x62, 0x4b, 0xe0, 0x24, 0x01, 0x46, 0x00, 0x04, 0x10, 0x50, 0x13,
+0x7f, 0xc4, 0x9e, 0xb4, 0x58, 0x00, 0x09, 0x90, 0x84, 0x62, 0x4b, 0xe0, 0x24, 0x01, 0x84, 0x61,
+0xaf, 0xf5, 0xaf, 0xf4, 0x10, 0x34, 0x01, 0xa8, 0x10, 0x34, 0x01, 0xb8, 0x14, 0x73, 0x00, 0x09,
+0xaf, 0xf7, 0xaf, 0xf6, 0xa9, 0xf4, 0xa9, 0xf5, 0xa9, 0xf2, 0xa9, 0xf3, 0x50, 0x03, 0x00, 0x1c,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0xe4, 0xdd, 0x2f, 0x04, 0x04, 0x00, 0x71, 0x58, 0x20,
+0x00, 0x05, 0xf0, 0x81, 0x10, 0x2f, 0x80, 0x04, 0xf1, 0x01, 0x14, 0x14, 0x00, 0x71, 0xec, 0x0c,
+0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x42, 0x11, 0x40, 0x08,
+0x14, 0x10, 0x00, 0x2d, 0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x42, 0x11, 0x44, 0x08,
+0x14, 0x10, 0x00, 0x2d, 0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x58, 0x11, 0x00, 0x01,
+0x14, 0x10, 0x00, 0x2d, 0xdd, 0x9e, 0x92, 0x00, 0x04, 0x20, 0x00, 0x2d, 0x58, 0x11, 0x00, 0x02,
+0x14, 0x10, 0x00, 0x2d, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0x3c, 0xef, 0xf4, 0x46, 0x00,
+0x04, 0x10, 0x58, 0x00, 0x08, 0x00, 0x50, 0x10, 0x00, 0x80, 0x85, 0x20, 0x04, 0x40, 0x00, 0x43,
+0x40, 0x32, 0x40, 0x09, 0x54, 0x31, 0x80, 0x0f, 0x80, 0x40, 0xc3, 0x64, 0x84, 0x40, 0x97, 0x5c,
+0xc5, 0x5c, 0x54, 0x61, 0x00, 0x03, 0x14, 0x60, 0x00, 0x43, 0x84, 0xc0, 0x04, 0x80, 0x00, 0x43,
+0x40, 0x44, 0x20, 0x09, 0x54, 0x42, 0x00, 0x7f, 0x40, 0x72, 0x20, 0x08, 0x40, 0x53, 0x90, 0x04,
+0x14, 0x50, 0x00, 0x1d, 0x44, 0x7f, 0xff, 0xc7, 0x04, 0xa0, 0x80, 0x02, 0xb5, 0x01, 0x14, 0xaf,
+0x80, 0x01, 0x8d, 0x04, 0x00, 0xaf, 0x80, 0x07, 0x80, 0xa4, 0x40, 0xa5, 0x1c, 0x02, 0x58, 0xa5,
+0x00, 0x20, 0x10, 0xaf, 0x80, 0x07, 0x54, 0x74, 0x00, 0x7f, 0x40, 0xa4, 0x1c, 0x09, 0x40, 0x74,
+0x9c, 0x06, 0x04, 0x8f, 0x80, 0x01, 0x88, 0xea, 0x14, 0x80, 0x80, 0x02, 0x50, 0x83, 0xff, 0xff,
+0xd5, 0x08, 0x14, 0xa0, 0x00, 0x1b, 0x9d, 0xb1, 0x04, 0xa0, 0x00, 0x1b, 0x54, 0x55, 0x00, 0x7f,
+0x40, 0xa2, 0xa0, 0x08, 0xe2, 0xc8, 0xe9, 0xf6, 0x54, 0x63, 0x80, 0x7f, 0x40, 0x63, 0x20, 0x08,
+0x40, 0x52, 0xc0, 0x08, 0x58, 0x73, 0x00, 0x02, 0x58, 0x63, 0x00, 0x18, 0x40, 0x73, 0x94, 0x04,
+0x40, 0x53, 0x14, 0x04, 0x46, 0x68, 0x0f, 0xff, 0x58, 0x63, 0x0f, 0xff, 0x40, 0x42, 0x60, 0x08,
+0x40, 0x52, 0x98, 0x02, 0x40, 0x73, 0x98, 0x02, 0x40, 0x73, 0x90, 0x04, 0x40, 0x42, 0x90, 0x04,
+0x14, 0x40, 0x00, 0x44, 0x14, 0x70, 0x00, 0x45, 0x9c, 0x91, 0x84, 0xa4, 0xd2, 0x98, 0x92, 0x61,
+0xd5, 0x9f, 0x46, 0x00, 0x20, 0x00, 0x14, 0x01, 0x00, 0x78, 0xec, 0x0c, 0x3a, 0x6f, 0xa8, 0x04,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0x3c, 0xef, 0xf4, 0x46, 0x00, 0x04, 0x10, 0x58, 0x00,
+0x08, 0x00, 0x50, 0x10, 0x00, 0x80, 0x85, 0x20, 0x04, 0x40, 0x00, 0x40, 0x40, 0x32, 0x40, 0x09,
+0x54, 0x31, 0x80, 0x0f, 0x80, 0x40, 0xc3, 0x6a, 0x84, 0x40, 0x97, 0x5c, 0xc5, 0x62, 0x54, 0x61,
+0x00, 0x03, 0x14, 0x60, 0x00, 0x40, 0x84, 0xc0, 0x04, 0x80, 0x00, 0x40, 0x40, 0x44, 0x20, 0x09,
+0x54, 0x42, 0x00, 0x7f, 0x40, 0x72, 0x20, 0x08, 0x40, 0x53, 0x90, 0x04, 0x14, 0x50, 0x00, 0x1d,
+0x44, 0x7f, 0xff, 0xc7, 0x04, 0xa0, 0x80, 0x02, 0xb5, 0x01, 0x14, 0xaf, 0x80, 0x01, 0x8d, 0x04,
+0x00, 0xaf, 0x80, 0x07, 0x80, 0xa4, 0x40, 0xa5, 0x1c, 0x02, 0x58, 0xa5, 0x00, 0x28, 0x10, 0xaf,
+0x80, 0x07, 0x54, 0x74, 0x00, 0x7f, 0x40, 0xa4, 0x1c, 0x09, 0x40, 0x74, 0x9c, 0x06, 0x04, 0x8f,
+0x80, 0x01, 0x88, 0xea, 0x14, 0x80, 0x80, 0x02, 0x50, 0x83, 0xff, 0xff, 0xd5, 0x08, 0x14, 0xa0,
+0x00, 0x1b, 0x9d, 0xb1, 0x04, 0xa0, 0x00, 0x1b, 0x54, 0x55, 0x00, 0x7f, 0x40, 0xa2, 0xa0, 0x08,
+0xe2, 0xc8, 0xe9, 0xf6, 0x00, 0x8f, 0x80, 0x07, 0x54, 0x63, 0x80, 0x7f, 0x40, 0x74, 0x04, 0x09,
+0x40, 0x63, 0x20, 0x08, 0x54, 0x73, 0x80, 0x03, 0x40, 0x82, 0xc0, 0x08, 0x40, 0x73, 0x98, 0x04,
+0x40, 0x53, 0xa0, 0x04, 0x58, 0x63, 0x00, 0x02, 0x46, 0x78, 0x0f, 0xff, 0x40, 0x63, 0x20, 0x04,
+0x58, 0x73, 0x8f, 0xff, 0x40, 0x82, 0x60, 0x08, 0x40, 0x52, 0x9c, 0x02, 0x40, 0x63, 0x1c, 0x02,
+0x40, 0x63, 0x20, 0x04, 0x40, 0x42, 0xa0, 0x04, 0x14, 0x40, 0x00, 0x41, 0x14, 0x60, 0x00, 0x42,
+0x9c, 0x91, 0x84, 0xa4, 0xd2, 0x92, 0x92, 0x61, 0xd5, 0x99, 0x46, 0x00, 0x10, 0x00, 0x14, 0x01,
+0x00, 0x78, 0xec, 0x0c, 0x3a, 0x6f, 0xa8, 0x04, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0x3c,
+0x04, 0x50, 0x00, 0x29, 0x04, 0x30, 0x00, 0x2a, 0x9d, 0x2a, 0x9a, 0xa3, 0xe4, 0x42, 0x4e, 0xf3,
+0x00, 0x85, 0x00, 0x30, 0x00, 0xa2, 0x9c, 0x9c, 0x40, 0x81, 0x10, 0x08, 0x40, 0x20, 0x20, 0x00,
+0xa7, 0xd7, 0x54, 0x63, 0x80, 0x80, 0xc6, 0x79, 0xb5, 0x01, 0x50, 0x41, 0x80, 0x24, 0x38, 0x80,
+0x12, 0x0a, 0x00, 0x70, 0x80, 0x9f, 0x00, 0x50, 0x80, 0x9e, 0xa1, 0x0b, 0x99, 0xbd, 0x50, 0x73,
+0x00, 0x14, 0x50, 0x50, 0x80, 0x10, 0x02, 0x81, 0x00, 0x03, 0x95, 0x9c, 0xc4, 0x22, 0x93, 0x0e,
+0x40, 0x84, 0x38, 0x08, 0x40, 0x74, 0x1c, 0x04, 0xad, 0xd3, 0xb6, 0xa2, 0xa7, 0x17, 0x42, 0x42,
+0x18, 0x09, 0xaf, 0x17, 0x99, 0x86, 0xa1, 0x4a, 0x14, 0x53, 0x00, 0x12, 0xa1, 0x0b, 0xa4, 0x52,
+0x54, 0x42, 0x3f, 0xff, 0x92, 0x2e, 0x40, 0x10, 0xb8, 0x08, 0x40, 0x50, 0x90, 0x04, 0xad, 0x52,
+0xa7, 0x17, 0xa6, 0x55, 0x54, 0x52, 0x00, 0x7f, 0x58, 0x10, 0x80, 0x40, 0xaf, 0x57, 0xd5, 0x1b,
+0x93, 0x0e, 0x40, 0x84, 0x38, 0x08, 0x40, 0x74, 0x1c, 0x04, 0xad, 0xd3, 0x99, 0x86, 0xa6, 0x57,
+0xb6, 0xa2, 0x58, 0x10, 0x80, 0x40, 0xae, 0x57, 0x14, 0x43, 0x00, 0x12, 0xa4, 0x52, 0xa7, 0x17,
+0x92, 0x2e, 0x40, 0x10, 0xb8, 0x08, 0xac, 0x52, 0x54, 0x42, 0x00, 0x7f, 0xa6, 0x55, 0xaf, 0x17,
+0x42, 0x10, 0x98, 0x09, 0x95, 0x1c, 0xae, 0x55, 0x98, 0x44, 0x50, 0x10, 0x80, 0x48, 0xa6, 0x8e,
+0x44, 0x5f, 0xff, 0xcf, 0x40, 0x41, 0x14, 0x02, 0x58, 0x22, 0x00, 0x08, 0x9c, 0xdc, 0x84, 0x84,
+0xaf, 0x0f, 0xae, 0x8e, 0x40, 0x51, 0x90, 0x0c, 0x99, 0x05, 0xa4, 0xa3, 0xb4, 0x61, 0x54, 0x51,
+0x3f, 0xff, 0x99, 0x1d, 0xad, 0x0a, 0x46, 0x40, 0x04, 0x10, 0x00, 0x20, 0x00, 0xa2, 0x04, 0x50,
+0x00, 0x2a, 0x9c, 0x51, 0x96, 0x8c, 0x9c, 0xe9, 0x58, 0x42, 0x08, 0x00, 0x14, 0x30, 0x00, 0x2a,
+0x10, 0x20, 0x00, 0xa2, 0x10, 0x22, 0x01, 0x88, 0x3a, 0x6f, 0xa0, 0x04, 0xdd, 0x9e, 0x92, 0x00,
+0x04, 0x50, 0x00, 0x2b, 0x04, 0x30, 0x00, 0x2c, 0x9d, 0x2a, 0x9a, 0xa3, 0xe4, 0x42, 0xe9, 0x3e,
+0x00, 0x30, 0x00, 0xa3, 0x9d, 0x1e, 0x94, 0xa4, 0x98, 0x82, 0xa7, 0x57, 0x54, 0x42, 0x80, 0x80,
+0xc4, 0x35, 0x50, 0x51, 0x80, 0x26, 0x38, 0x10, 0x16, 0x0a, 0x94, 0xdc, 0xa1, 0x0a, 0x98, 0xc3,
+0xb6, 0x82, 0xa1, 0x4c, 0x14, 0x51, 0x80, 0x1b, 0xa5, 0x0e, 0xa4, 0xd3, 0x54, 0x42, 0x3f, 0xff,
+0x92, 0x6e, 0x40, 0x31, 0xb8, 0x08, 0x40, 0x51, 0x90, 0x04, 0xad, 0x53, 0xa7, 0x55, 0x00, 0x40,
+0x80, 0x0f, 0xa6, 0xd7, 0x96, 0x64, 0x95, 0x0e, 0x54, 0x11, 0x80, 0x3f, 0x40, 0x30, 0x90, 0x04,
+0x54, 0x12, 0x80, 0x7f, 0xae, 0xd7, 0xae, 0x55, 0x46, 0x10, 0x04, 0x10, 0x00, 0x50, 0x00, 0xa3,
+0x04, 0x40, 0x00, 0x2c, 0x9c, 0xa9, 0x97, 0x54, 0x9c, 0xe1, 0x58, 0x10, 0x88, 0x00, 0x14, 0x30,
+0x00, 0x2c, 0x10, 0x50, 0x00, 0xa3, 0x10, 0x50, 0x81, 0x98, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc,
+0xef, 0xfc, 0x85, 0x20, 0x80, 0xc0, 0x46, 0x80, 0x00, 0x00, 0x58, 0x84, 0x03, 0x68, 0xd5, 0x22,
+0xa7, 0x1f, 0x54, 0x22, 0x00, 0x80, 0xc2, 0x30, 0x38, 0x23, 0x06, 0x02, 0x38, 0x93, 0x06, 0x0a,
+0x80, 0x22, 0x00, 0x31, 0x00, 0x14, 0xcb, 0x02, 0xd5, 0x05, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00,
+0x0e, 0x54, 0x4b, 0xe0, 0x20, 0x01, 0x9c, 0x3e, 0x94, 0xc4, 0x99, 0xf3, 0xa6, 0xbf, 0x44, 0x4f,
+0xff, 0xc0, 0x40, 0x51, 0x10, 0x04, 0xaf, 0x7f, 0x04, 0x13, 0x00, 0x2b, 0x9c, 0x09, 0x14, 0x03,
+0x00, 0x2b, 0x04, 0x23, 0x00, 0x2b, 0x04, 0x53, 0x00, 0x2c, 0x97, 0xd4, 0x9c, 0x7e, 0x95, 0x0c,
+0x41, 0xe2, 0x88, 0x01, 0x50, 0x13, 0x80, 0x26, 0x98, 0xf4, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00,
+0x0e, 0x64, 0x4f, 0xe6, 0xff, 0xcf, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x85, 0x20, 0x80, 0xc0, 0x46, 0x80, 0x00, 0x00, 0x58, 0x84,
+0x03, 0x68, 0xd5, 0x1a, 0xa6, 0xff, 0x54, 0x11, 0x80, 0x80, 0xc1, 0x28, 0x38, 0x13, 0x0a, 0x02,
+0x38, 0x93, 0x0a, 0x0a, 0x4b, 0xe0, 0x20, 0x01, 0xa6, 0x7f, 0xa6, 0xfd, 0x44, 0x0f, 0xff, 0xc0,
+0x40, 0x50, 0x80, 0x04, 0x58, 0x41, 0x80, 0x40, 0xaf, 0x7f, 0xaf, 0x3d, 0x04, 0x23, 0x00, 0x29,
+0x9c, 0x11, 0x14, 0x03, 0x00, 0x29, 0x04, 0x43, 0x00, 0x29, 0x04, 0x53, 0x00, 0x2a, 0x96, 0x64,
+0x9c, 0xcc, 0x95, 0xdc, 0x41, 0xe2, 0x90, 0x01, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x54,
+0x50, 0x20, 0x80, 0x24, 0x99, 0xf7, 0x4f, 0xe6, 0xff, 0xd7, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x83, 0x80, 0x50, 0x00, 0x00, 0xb8,
+0x46, 0x40, 0x04, 0x10, 0xf0, 0x81, 0x58, 0x42, 0x08, 0x00, 0x00, 0x7e, 0x00, 0xa1, 0x00, 0x12,
+0x01, 0xbc, 0x9d, 0x7a, 0x94, 0xac, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x54, 0x50, 0xa3,
+0x80, 0x22, 0x40, 0x6e, 0x08, 0x00, 0x4c, 0x70, 0x80, 0x55, 0xa6, 0x77, 0x55, 0xe0, 0x80, 0x80,
+0x4f, 0xe2, 0x00, 0x50, 0x02, 0x83, 0x00, 0x03, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7,
+0x83, 0x24, 0xdd, 0x2f, 0x54, 0x94, 0x3f, 0xff, 0x95, 0x3c, 0x81, 0x00, 0x40, 0x3e, 0x10, 0x00,
+0xf0, 0x01, 0xb4, 0x9f, 0x4e, 0x83, 0x00, 0x07, 0xbb, 0x2d, 0x42, 0x01, 0xc4, 0x08, 0xb8, 0xad,
+0xd5, 0x38, 0x39, 0xee, 0x2a, 0x02, 0x84, 0x41, 0x12, 0x9f, 0x00, 0x06, 0x80, 0x3e, 0x04, 0x51,
+0x80, 0x0b, 0x10, 0x2f, 0x00, 0x14, 0x14, 0x5f, 0x00, 0x04, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x83, 0x68, 0xdd, 0x2f, 0x38, 0x8e, 0x2a, 0x0a, 0x80, 0x06, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xa6, 0xf7, 0x04, 0x84,
+0x00, 0x02, 0x58, 0x01, 0x80, 0x40, 0xae, 0x37, 0xa4, 0x73, 0xb7, 0x06, 0x40, 0x50, 0xb8, 0x09,
+0x40, 0x52, 0xb8, 0x08, 0x58, 0x22, 0x86, 0x40, 0xac, 0xb3, 0xb4, 0x9f, 0x10, 0x72, 0x01, 0xb8,
+0x00, 0xae, 0x00, 0xa1, 0x50, 0x75, 0x00, 0x01, 0x97, 0xbc, 0x10, 0x6e, 0x00, 0xa1, 0xd5, 0x9e,
+0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x83, 0x80,
+0x50, 0x00, 0x00, 0xb8, 0x46, 0x40, 0x04, 0x10, 0xf0, 0x81, 0x58, 0x42, 0x08, 0x00, 0x00, 0x7e,
+0x00, 0xa0, 0x00, 0x52, 0x01, 0xac, 0x94, 0xbc, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x64,
+0x50, 0xa3, 0x80, 0x20, 0x40, 0x6e, 0x08, 0x00, 0xd7, 0x54, 0x01, 0xe3, 0x00, 0x07, 0x54, 0x5f,
+0x00, 0x80, 0xc5, 0x4f, 0x02, 0x83, 0x00, 0x03, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7,
+0x83, 0x24, 0xdd, 0x2f, 0x98, 0x7f, 0x54, 0x94, 0x3f, 0xff, 0x81, 0x00, 0x9c, 0x09, 0x95, 0x03,
+0x40, 0x3e, 0x10, 0x00, 0xf0, 0x01, 0xb4, 0x9f, 0x4e, 0x83, 0x00, 0x06, 0x44, 0x31, 0x00, 0x00,
+0xbb, 0xad, 0xd5, 0x37, 0x39, 0xee, 0x2a, 0x02, 0x84, 0x40, 0x12, 0x9f, 0x00, 0x06, 0x80, 0x3e,
+0xa1, 0x59, 0x10, 0x2f, 0x00, 0x14, 0x14, 0x5f, 0x00, 0x04, 0xb6, 0x9f, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x83, 0x68, 0xdd, 0x2f, 0x38, 0x8e, 0x2a, 0x0a, 0x80, 0x06, 0x84, 0x20, 0x44, 0x20,
+0x00, 0x10, 0x46, 0xf0, 0x01, 0x02, 0x58, 0xf7, 0x87, 0x08, 0xdd, 0x2f, 0xa6, 0xf7, 0x04, 0x84,
+0x00, 0x02, 0x58, 0x11, 0x80, 0x40, 0xae, 0x77, 0xa5, 0x33, 0xb7, 0x06, 0x40, 0x52, 0x38, 0x09,
+0x40, 0x52, 0xb8, 0x08, 0x58, 0x22, 0x80, 0xc8, 0xac, 0xb3, 0xb4, 0x9f, 0x10, 0x72, 0x01, 0xa8,
+0x00, 0xae, 0x00, 0xa0, 0x50, 0x75, 0x00, 0x01, 0x97, 0xbc, 0x10, 0x6e, 0x00, 0xa0, 0xd5, 0xa0,
+0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xfc, 0xb6, 0x20,
+0xa8, 0xc1, 0x80, 0xc1, 0xa0, 0x43, 0x84, 0xe0, 0x81, 0x23, 0x81, 0x02, 0xa8, 0x42, 0x47, 0xc0,
+0x01, 0x02, 0x59, 0xce, 0x07, 0x08, 0x81, 0x47, 0xd5, 0x0c, 0xdd, 0x3c, 0xa6, 0xb7, 0x44, 0x3f,
+0xff, 0xc0, 0x40, 0x01, 0x0c, 0x04, 0xae, 0x37, 0x1c, 0xa4, 0x00, 0x01, 0x9d, 0xf9, 0x8c, 0xd0,
+0x80, 0x06, 0x84, 0x20, 0x44, 0x20, 0x00, 0x10, 0xe2, 0xe9, 0xe9, 0xf0, 0xec, 0x04, 0x3a, 0x6f,
+0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xec, 0xb6, 0x20, 0xa8, 0xc1, 0x46, 0x80,
+0x04, 0x10, 0x04, 0x90, 0x00, 0x03, 0x58, 0x84, 0x09, 0xb0, 0x14, 0x90, 0x00, 0x02, 0x44, 0x70,
+0x06, 0x40, 0x83, 0x83, 0x80, 0xc1, 0x46, 0x30, 0x00, 0x0d, 0x58, 0x31, 0x8e, 0x54, 0x40, 0x10,
+0x20, 0x03, 0x44, 0x50, 0x00, 0xc8, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x64, 0x40, 0x41,
+0x84, 0x1a, 0x40, 0x40, 0x04, 0x1b, 0x40, 0x82, 0x84, 0x1b, 0x40, 0x83, 0x84, 0x1a, 0x84, 0xe0,
+0xf4, 0x83, 0x81, 0x42, 0x46, 0x40, 0x01, 0x02, 0x58, 0x42, 0x07, 0x08, 0x81, 0x27, 0x54, 0x34,
+0x3f, 0xff, 0xd5, 0x26, 0xf3, 0x81, 0xf4, 0x82, 0xdd, 0x24, 0xf0, 0x03, 0x46, 0xf0, 0x00, 0x00,
+0x58, 0xf7, 0x83, 0x24, 0xdd, 0x2f, 0xf3, 0x01, 0xf4, 0x02, 0xc0, 0x20, 0x12, 0x80, 0x00, 0x06,
+0x10, 0x90, 0x00, 0x0e, 0x10, 0x90, 0x00, 0x0f, 0xa6, 0x77, 0x9d, 0xf9, 0x55, 0xe0, 0x80, 0x3f,
+0x11, 0xe3, 0x00, 0x07, 0xa5, 0x73, 0x40, 0x12, 0xb8, 0x09, 0x40, 0x10, 0xb8, 0x08, 0x41, 0xe0,
+0x8c, 0x04, 0x13, 0xe3, 0x00, 0x03, 0xa0, 0x82, 0xaa, 0xb4, 0x1c, 0x05, 0x00, 0x01, 0x80, 0x06,
+0x84, 0x20, 0x44, 0x20, 0x00, 0x10, 0xe2, 0xfc, 0xe9, 0xd6, 0xec, 0x14, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x83, 0x1c, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07, 0x81, 0x69, 0x84, 0xa1,
+0xd8, 0x0b, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x04, 0xb4, 0x80, 0x54, 0x32, 0x01, 0xfd,
+0x58, 0x11, 0x80, 0x02, 0xd5, 0x08, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x04, 0xb4, 0xa0,
+0x54, 0x12, 0x81, 0xfd, 0xb6, 0x20, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x1c,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc,
+0xef, 0xfc, 0x46, 0x60, 0x04, 0x00, 0x58, 0x63, 0x00, 0x04, 0x84, 0xe0, 0x85, 0x08, 0x46, 0x90,
+0x00, 0x04, 0x58, 0x94, 0x83, 0x1c, 0x84, 0x01, 0x4b, 0xe0, 0x24, 0x01, 0xb4, 0x46, 0x99, 0xff,
+0x54, 0x11, 0x00, 0x08, 0x84, 0x01, 0x97, 0xf8, 0xc1, 0x03, 0x40, 0x73, 0x80, 0x04, 0x05, 0xe3,
+0x00, 0x00, 0x8f, 0x01, 0x54, 0x5f, 0x01, 0xfe, 0x58, 0x42, 0x80, 0x01, 0xb6, 0x86, 0x54, 0x84,
+0x00, 0xff, 0x4b, 0xe0, 0x24, 0x01, 0xb4, 0x66, 0x54, 0x01, 0x81, 0xfe, 0xb6, 0x06, 0x4e, 0x83,
+0xff, 0xe4, 0x84, 0x08, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x1c, 0xdd, 0x2f, 0x80, 0x07,
+0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x46, 0x60,
+0x04, 0x00, 0x97, 0xc0, 0x58, 0x63, 0x00, 0x04, 0x85, 0x28, 0x46, 0x80, 0x00, 0x04, 0x58, 0x84,
+0x03, 0x1c, 0xb4, 0x46, 0x40, 0x33, 0x9c, 0x09, 0x94, 0x5a, 0x55, 0xe1, 0x01, 0xfb, 0x40, 0x00,
+0xf8, 0x04, 0xb6, 0x06, 0x84, 0x01, 0x4b, 0xe0, 0x20, 0x01, 0xb4, 0xa6, 0x84, 0x01, 0x54, 0x42,
+0x81, 0xfe, 0x40, 0x32, 0x00, 0x04, 0xb6, 0x66, 0x8f, 0x21, 0x4b, 0xe0, 0x20, 0x01, 0xb4, 0x46,
+0x84, 0x01, 0x54, 0x11, 0x01, 0xfe, 0xb6, 0x26, 0x99, 0xff, 0x54, 0x94, 0x80, 0xff, 0x4b, 0xe0,
+0x20, 0x01, 0x97, 0xf8, 0x4e, 0x93, 0xff, 0xdf, 0x84, 0x0a, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x83, 0x1c, 0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc,
+0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07, 0x81, 0x69, 0x84, 0xa1, 0xd8, 0x16, 0x46, 0x60, 0x04, 0x00,
+0x58, 0x63, 0x00, 0x04, 0x05, 0xe3, 0x00, 0x00, 0x54, 0x5f, 0x01, 0xfd, 0x58, 0x42, 0x80, 0x02,
+0xb6, 0x86, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x1c, 0xdd, 0x2f, 0xb4, 0x66, 0x54, 0x21,
+0x81, 0xfd, 0xb6, 0x46, 0xd5, 0x09, 0x46, 0x60, 0x04, 0x00, 0xa0, 0xb1, 0x54, 0x01, 0x01, 0xfd,
+0x58, 0x10, 0x00, 0x02, 0xa8, 0x71, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x1c,
+0xdd, 0x2f, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x8d, 0x2c, 0xdd, 0x2f, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8c, 0xb8,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8c, 0x4c, 0xdd, 0x2f, 0x80, 0xc0, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x8b, 0xf4, 0xdd, 0x2f, 0x96, 0x34, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xfc, 0x97, 0x81, 0x97, 0xca, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x8d, 0x2c, 0xdd, 0x2f, 0x84, 0x03, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8c, 0xb8, 0xdd, 0x2f,
+0xcf, 0x05, 0x44, 0x00, 0xfc, 0x00, 0x40, 0x63, 0x00, 0x04, 0x46, 0x70, 0x00, 0x03, 0x58, 0x73,
+0x8c, 0xb8, 0x40, 0x03, 0x20, 0x09, 0x4b, 0xe0, 0x1c, 0x01, 0x96, 0x30, 0x4b, 0xe0, 0x1c, 0x01,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8c, 0x4c, 0xdd, 0x2f, 0x80, 0xc0, 0x46, 0xf0, 0x00, 0x03,
+0x58, 0xf7, 0x8b, 0xf4, 0xdd, 0x2f, 0x80, 0x06, 0xec, 0x04, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0x60, 0x00, 0x03, 0x58, 0x63, 0x0c, 0xb8, 0x54, 0x80, 0x80, 0xff,
+0x97, 0xc1, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8d, 0x2c, 0xdd, 0x2f, 0x84, 0x02, 0xdd, 0x26,
+0x40, 0x03, 0xa0, 0x09, 0xdd, 0x26, 0x96, 0x38, 0xdd, 0x26, 0x80, 0x08, 0xdd, 0x26, 0x46, 0x60,
+0x00, 0x03, 0x58, 0x63, 0x0d, 0x88, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8b, 0xf4, 0xdd, 0x2f,
+0x4b, 0xe0, 0x18, 0x01, 0xc8, 0xfe, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8d, 0x2c, 0xdd, 0x2f, 0x84, 0x04, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x8c, 0xb8, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8b, 0xf4,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8d, 0x2c, 0xdd, 0x2f, 0x84, 0x06, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x8c, 0xb8, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8b, 0xf4,
+0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x04, 0x00,
+0x80, 0x01, 0x84, 0x48, 0x14, 0x20, 0x81, 0x06, 0x14, 0x20, 0x01, 0x0a, 0xdd, 0x9e, 0x92, 0x00,
+0xef, 0xf8, 0x46, 0x10, 0x00, 0x0d, 0x04, 0x40, 0x83, 0x5a, 0x46, 0x30, 0x04, 0x00, 0x9c, 0xa1,
+0x14, 0x20, 0x83, 0x5a, 0x58, 0x31, 0x84, 0x00, 0xb4, 0x03, 0x46, 0x10, 0x04, 0x00, 0x58, 0x50,
+0x00, 0x11, 0xb6, 0xa3, 0x04, 0x40, 0x81, 0x06, 0x58, 0x22, 0x00, 0x80, 0x14, 0x20, 0x81, 0x06,
+0xb4, 0x03, 0xf0, 0x81, 0xec, 0x08, 0xdd, 0x9e, 0x46, 0x30, 0x04, 0x00, 0x80, 0x03, 0x44, 0x20,
+0x00, 0x4e, 0x44, 0x10, 0x00, 0xa8, 0x14, 0x21, 0x81, 0x04, 0x14, 0x10, 0x01, 0x06, 0xdd, 0x9e,
+0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x5a, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x00, 0x0e,
+0x58, 0x00, 0x01, 0x44, 0x84, 0x80, 0xb6, 0x80, 0x84, 0x21, 0xb4, 0x60, 0xa8, 0xc1, 0xa8, 0x42,
+0xb4, 0x40, 0xa1, 0x42, 0x9f, 0x29, 0x40, 0x32, 0x08, 0x02, 0x9c, 0x5a, 0x95, 0x4a, 0x98, 0xc5,
+0x46, 0x40, 0x00, 0x0e, 0x58, 0x42, 0x01, 0x30, 0xa9, 0x19, 0xb4, 0x40, 0x9c, 0x51, 0xb6, 0x20,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8d, 0x68, 0xb4, 0x41, 0x98, 0x02,
+0xd5, 0x03, 0x64, 0x00, 0x00, 0x00, 0xb4, 0x81, 0x9a, 0xe0, 0x4e, 0x35, 0xff, 0xfc, 0xdd, 0x9e,
+0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x80, 0xc0, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8a, 0x70, 0xdd, 0x2f, 0xa0, 0x32, 0xc0, 0x2d, 0x84, 0xa2, 0xd0, 0x2b, 0x84, 0xa3,
+0xd8, 0x02, 0xd5, 0x28, 0xa0, 0x33, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x57, 0x83, 0x5b, 0xd0, 0x07,
+0xa0, 0x41, 0x05, 0xe3, 0x00, 0x01, 0x40, 0x50, 0xf8, 0x00, 0xa9, 0x41, 0xa0, 0x73, 0x46, 0x00,
+0x00, 0x0d, 0x58, 0x00, 0x0d, 0x6c, 0x4c, 0x13, 0x40, 0x05, 0x84, 0x40, 0xb6, 0x40, 0xd5, 0x0d,
+0x05, 0xe3, 0x00, 0x04, 0x14, 0x1f, 0x00, 0x03, 0xa1, 0x33, 0xa1, 0x74, 0xa9, 0x64, 0xb4, 0x60,
+0x4c, 0x33, 0x40, 0x04, 0xa0, 0x73, 0xb6, 0x20, 0x84, 0x00, 0x84, 0x43, 0xa8, 0x34, 0xa8, 0xb2,
+0xa8, 0x33, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84, 0xdd, 0x2f, 0xec, 0x08,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xf4, 0x80, 0xe1,
+0x80, 0xc0, 0xc1, 0x7a, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70,
+0xdd, 0x2f, 0x84, 0x01, 0xa8, 0x32, 0x46, 0x30, 0x00, 0x0d, 0x04, 0x21, 0x83, 0x5b, 0x46, 0x00,
+0x00, 0x0d, 0x58, 0x00, 0x0d, 0x74, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8d, 0x68, 0xca, 0x0b,
+0xa9, 0xb3, 0xa9, 0xb4, 0x14, 0x61, 0x83, 0x5b, 0x46, 0xf0, 0x00, 0x0d, 0x14, 0x77, 0x83, 0x5c,
+0xa9, 0xf1, 0xd5, 0x39, 0xb4, 0x21, 0xb4, 0x00, 0xe2, 0x20, 0xe8, 0x03, 0x9a, 0x01, 0xd5, 0x02,
+0x9a, 0x08, 0x44, 0x10, 0x00, 0x21, 0x40, 0x00, 0x04, 0x37, 0xa0, 0x51, 0xe2, 0x01, 0xe8, 0x03,
+0x9a, 0x08, 0xd5, 0x02, 0x84, 0x00, 0xa8, 0x11, 0xa0, 0xd1, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17,
+0x83, 0x5b, 0x46, 0xf0, 0x00, 0x0d, 0x14, 0x37, 0x83, 0x5c, 0xa0, 0x11, 0xe2, 0xe0, 0xe8, 0x0b,
+0x9a, 0x07, 0xa8, 0x11, 0x46, 0x00, 0x00, 0x0d, 0x04, 0x50, 0x03, 0x5b, 0xda, 0x20, 0x14, 0x60,
+0x03, 0x5b, 0xd5, 0x1d, 0xa0, 0x93, 0x9b, 0xf8, 0x4c, 0x20, 0xff, 0xf1, 0xd5, 0x18, 0x14, 0x00,
+0x83, 0x5c, 0xc0, 0x0c, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8d, 0x68, 0x46, 0x00, 0x00, 0x0d,
+0x58, 0x00, 0x0d, 0x74, 0xb4, 0x41, 0xb6, 0x40, 0xd5, 0x03, 0x84, 0x22, 0xa8, 0x72, 0xf0, 0x01,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84, 0xdd, 0x2f, 0xd5, 0x16, 0xa8, 0xb3, 0xa0, 0x14,
+0x46, 0x10, 0x00, 0x0d, 0xa8, 0x34, 0x05, 0xe1, 0x00, 0x04, 0x14, 0x6f, 0x00, 0x03, 0xa9, 0x94,
+0xa9, 0xf1, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x37, 0x83, 0x5b, 0x04, 0x40, 0x83, 0x5c, 0xa0, 0x19,
+0xe2, 0x80, 0xe8, 0xd6, 0xd5, 0xe5, 0xec, 0x0c, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8a, 0x70, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x81, 0x44, 0xa0, 0xc9, 0xa1, 0x4a,
+0xf0, 0x01, 0x9f, 0x29, 0x40, 0x22, 0x0c, 0x02, 0x9d, 0x92, 0x95, 0x72, 0x99, 0x0d, 0xa1, 0xa1,
+0xa0, 0xc9, 0x9c, 0x99, 0xa8, 0x89, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84, 0xdd, 0x2f,
+0x84, 0x00, 0xa8, 0x34, 0xb6, 0x06, 0xa8, 0x31, 0xa8, 0x32, 0xa8, 0x33, 0x80, 0x06, 0xec, 0x08,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x0d, 0x04, 0x17, 0x83, 0x5a, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x27, 0x83, 0x94, 0x9a, 0x0a,
+0x4e, 0x05, 0x00, 0x07, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7, 0x81, 0x98, 0xdd, 0x2f, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x04, 0x01, 0x84, 0x21, 0xa8, 0x42,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x04, 0x01, 0x84, 0x20, 0xb6, 0x20, 0xdd, 0x9e, 0x92, 0x00,
+0x46, 0x10, 0x04, 0x01, 0x96, 0x00, 0xa8, 0x09, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x04, 0x01,
+0x84, 0x22, 0xa8, 0x42, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x04, 0x01, 0x04, 0x00, 0x81, 0x8a,
+0x96, 0x04, 0xc0, 0x04, 0x84, 0x41, 0x14, 0x20, 0x81, 0x8a, 0xdd, 0x9e, 0x46, 0x20, 0x04, 0x01,
+0xa0, 0x52, 0x56, 0x00, 0x80, 0x04, 0x42, 0x00, 0x08, 0x0b, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc,
+0x46, 0x50, 0x04, 0x00, 0x46, 0x60, 0x04, 0x01, 0x58, 0x63, 0x06, 0x8c, 0x04, 0x82, 0x80, 0x80,
+0xb4, 0x86, 0x46, 0x70, 0x00, 0x04, 0x58, 0x73, 0x83, 0x28, 0x58, 0x02, 0x00, 0x40, 0xb6, 0x06,
+0x44, 0x00, 0x00, 0xff, 0xdd, 0x27, 0x44, 0x00, 0x00, 0xff, 0xdd, 0x27, 0x44, 0x00, 0x00, 0xff,
+0xdd, 0x27, 0x44, 0x00, 0x00, 0xff, 0xdd, 0x27, 0xb4, 0x66, 0x42, 0x11, 0x98, 0x09, 0x54, 0x04,
+0x00, 0x03, 0xb6, 0x26, 0xc8, 0x14, 0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x04, 0xb4, 0x80,
+0x46, 0x3f, 0xf0, 0xff, 0x58, 0x22, 0x00, 0x01, 0xb6, 0x40, 0x05, 0xe0, 0x00, 0x00, 0x58, 0x31,
+0x8f, 0xff, 0x50, 0x10, 0x00, 0x08, 0x40, 0x2f, 0x0c, 0x02, 0xd5, 0x19, 0x84, 0xa1, 0xd8, 0x1c,
+0x46, 0x00, 0x04, 0x00, 0x58, 0x00, 0x02, 0x04, 0xb4, 0xa0, 0x42, 0x42, 0x80, 0x09, 0xb6, 0x80,
+0x46, 0x3f, 0xf0, 0xff, 0xb4, 0x40, 0x58, 0x31, 0x8f, 0xff, 0x41, 0xe1, 0x0c, 0x02, 0x15, 0xe0,
+0x00, 0x00, 0xb4, 0xa0, 0x50, 0x10, 0x00, 0x08, 0x42, 0x22, 0xd0, 0x08, 0xb6, 0x40, 0xb4, 0x41,
+0x58, 0x01, 0x03, 0x00, 0xb6, 0x01, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x9c, 0x3c,
+0x96, 0xd8, 0x96, 0x90, 0xcb, 0x15, 0x54, 0x21, 0x00, 0xfc, 0xd5, 0x0f, 0x38, 0x41, 0x84, 0x02,
+0x9c, 0xdc, 0x40, 0x52, 0x60, 0x09, 0x40, 0x72, 0x20, 0x09, 0x40, 0x62, 0x40, 0x09, 0xa9, 0xc1,
+0xa9, 0x82, 0xa9, 0x43, 0xb6, 0x80, 0x8c, 0x10, 0x4c, 0x31, 0x7f, 0xf2, 0xd5, 0x0c, 0x84, 0xa1,
+0xdb, 0x0a, 0x84, 0x60, 0xd5, 0x05, 0xa3, 0xc9, 0x38, 0x71, 0x80, 0x08, 0x9c, 0xd9, 0x97, 0x18,
+0xe2, 0x82, 0xe9, 0xfa, 0x3a, 0x6f, 0x9c, 0x04, 0xdd, 0x9e, 0x92, 0x00, 0x96, 0x01, 0x96, 0x89,
+0xe2, 0x02, 0xe8, 0x02, 0x80, 0x20, 0x96, 0x09, 0xdd, 0x9e, 0x92, 0x00, 0x96, 0x00, 0x96, 0x88,
+0xe2, 0x02, 0xe8, 0x02, 0x80, 0x20, 0x96, 0x08, 0xdd, 0x9e, 0x92, 0x00, 0xd5, 0x03, 0x92, 0x00,
+0x9e, 0x01, 0x96, 0x00, 0xc8, 0xfd, 0xdd, 0x9e, 0xd5, 0x08, 0x44, 0x10, 0x00, 0xff, 0x92, 0x00,
+0x9e, 0x49, 0x96, 0x48, 0xc9, 0xfd, 0x9e, 0x01, 0x96, 0x00, 0xc8, 0xf8, 0xdd, 0x9e, 0x92, 0x00,
+0x46, 0x20, 0x00, 0x0d, 0x58, 0x21, 0x0d, 0x78, 0xb4, 0x22, 0xc1, 0x08, 0xd5, 0x09, 0x84, 0x2a,
+0x92, 0x00, 0x9e, 0xc9, 0x96, 0x58, 0xc9, 0xfd, 0x9e, 0x01, 0xc8, 0xfa, 0xd5, 0x0b, 0x8c, 0x1f,
+0x92, 0x05, 0xd5, 0x07, 0x84, 0x28, 0x92, 0x00, 0x9f, 0x09, 0x96, 0x60, 0xc9, 0xfd, 0x9e, 0x01,
+0xc8, 0xfa, 0xdd, 0x9e, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0xbc, 0x96, 0x00, 0x54, 0xa0,
+0x80, 0xff, 0x46, 0x10, 0x00, 0x0b, 0x58, 0x10, 0x80, 0x20, 0x97, 0xd1, 0x40, 0x80, 0x04, 0x00,
+0x84, 0xc0, 0x46, 0x90, 0x00, 0x03, 0x58, 0x94, 0x8d, 0xc0, 0xd5, 0x09, 0x4b, 0xe0, 0x24, 0x01,
+0x9d, 0xb1, 0x9d, 0xf9, 0x18, 0x04, 0x00, 0x01, 0x97, 0xb0, 0x97, 0xf9, 0x80, 0x07, 0x84, 0x20,
+0xe2, 0xca, 0xe9, 0xf5, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0x46, 0x00, 0x04, 0x00, 0x04, 0x10, 0x00, 0x09, 0x4e, 0x14, 0x00, 0x04, 0x84, 0x21, 0xd5, 0x02,
+0x84, 0x20, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x17, 0x81, 0x69, 0x44, 0x00, 0x00, 0x11, 0x84, 0x20,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8d, 0xc0, 0xdd, 0x2f, 0x54, 0x30, 0x00, 0x0f, 0x84, 0xa2,
+0xdb, 0x0e, 0x54, 0x40, 0x00, 0x10, 0xc4, 0x09, 0x46, 0x50, 0x04, 0x00, 0x05, 0xe2, 0x80, 0x08,
+0x42, 0x6f, 0x2c, 0x09, 0x14, 0x62, 0x80, 0x08, 0x84, 0x20, 0xd5, 0x02, 0x84, 0x21, 0x46, 0xf0,
+0x00, 0x0b, 0x10, 0x17, 0x81, 0x68, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07, 0x81, 0x68, 0xc8, 0x47,
+0x46, 0x60, 0x00, 0x04, 0x58, 0x63, 0x03, 0x78, 0x84, 0x02, 0x84, 0x21, 0x94, 0x83, 0xdd, 0x26,
+0x84, 0x08, 0x84, 0x26, 0x44, 0x20, 0x00, 0x12, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x24, 0x84, 0x22,
+0x9e, 0x82, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x2a, 0x84, 0x23, 0x94, 0x8b, 0xdd, 0x26, 0x44, 0x00,
+0x00, 0x2e, 0x84, 0x23, 0x44, 0x20, 0x00, 0x1b, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x35, 0x84, 0x21,
+0x44, 0x20, 0x00, 0x1e, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x39, 0x84, 0x21, 0x44, 0x20, 0x00, 0x1f,
+0xdd, 0x26, 0x44, 0x00, 0x00, 0x76, 0x84, 0x21, 0x94, 0x8d, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x7a,
+0x84, 0x21, 0x44, 0x20, 0x00, 0x21, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x78, 0x84, 0x21, 0x44, 0x20,
+0x00, 0x26, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x96, 0x84, 0x21, 0x44, 0x20, 0x00, 0x24, 0xdd, 0x26,
+0x44, 0x00, 0x00, 0x9d, 0x84, 0x21, 0x44, 0x20, 0x00, 0x25, 0xdd, 0x26, 0x3a, 0x6f, 0x98, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xec, 0x46, 0x80, 0x04, 0x01, 0x97, 0x81,
+0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x00, 0x20, 0x97, 0x08, 0x96, 0x92, 0x96, 0xda, 0x58, 0x84,
+0x04, 0x00, 0x40, 0x93, 0x00, 0x00, 0x84, 0xe0, 0x47, 0xc0, 0x00, 0x03, 0x59, 0xce, 0x0d, 0xc0,
+0x85, 0x47, 0xd5, 0x1a, 0xc3, 0x0b, 0xf2, 0x82, 0xf3, 0x81, 0xf4, 0x83, 0x80, 0x06, 0x84, 0x20,
+0xdd, 0x3c, 0xf2, 0x02, 0xf3, 0x01, 0xf4, 0x03, 0xd5, 0x03, 0x00, 0x04, 0x80, 0x00, 0x9c, 0x79,
+0x9d, 0xb1, 0x56, 0x73, 0x80, 0x01, 0xc2, 0x03, 0x40, 0x05, 0x1c, 0x1a, 0x1c, 0x04, 0x00, 0x01,
+0x97, 0xc8, 0x97, 0xb1, 0x8d, 0x21, 0xe2, 0xe4, 0xe9, 0xe6, 0xec, 0x14, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x81, 0xcc, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0b, 0x02, 0x07, 0x80, 0xae, 0xc8, 0x02, 0xd5, 0x03, 0x84, 0xa1,
+0xd8, 0x0b, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x07, 0x81, 0x62, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x81, 0xcc, 0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xa8, 0xdd, 0x2f,
+0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x0b, 0x00, 0x07, 0x81, 0x65, 0xc8, 0x1c, 0x46, 0xf0, 0x00, 0x0b, 0x02, 0x07, 0x80, 0xae,
+0x84, 0xa1, 0xd8, 0x13, 0x46, 0x40, 0x04, 0x01, 0x04, 0x12, 0x01, 0xa3, 0x46, 0x00, 0x04, 0x10,
+0x59, 0xe0, 0x80, 0x08, 0x54, 0x5f, 0x00, 0xff, 0x14, 0x52, 0x01, 0xa3, 0x58, 0x00, 0x02, 0x38,
+0xb4, 0x60, 0x42, 0x11, 0xc4, 0x08, 0xd5, 0x36, 0x84, 0xa2, 0xd8, 0x50, 0xd5, 0x49, 0x84, 0xa2,
+0xd8, 0x4d, 0x46, 0xf0, 0x00, 0x0b, 0x02, 0x07, 0x80, 0xae, 0xc8, 0x48, 0x46, 0xf0, 0x00, 0x0b,
+0x02, 0x07, 0x80, 0xaf, 0x44, 0x50, 0x00, 0x81, 0xd0, 0x1d, 0x5c, 0xf0, 0x00, 0x82, 0xe8, 0x08,
+0xe6, 0x0a, 0xe8, 0x03, 0xc8, 0x0f, 0xd5, 0x34, 0x9f, 0x69, 0xd8, 0x38, 0xd5, 0x31, 0x9c, 0x6a,
+0x4c, 0x00, 0x80, 0x20, 0xe2, 0x01, 0xe9, 0x18, 0x9d, 0x49, 0xd0, 0x20, 0x9d, 0x4a, 0xd8, 0x2e,
+0xd5, 0x22, 0x97, 0x40, 0x46, 0x40, 0x04, 0x01, 0x94, 0x2d, 0x58, 0x42, 0x00, 0x08, 0x98, 0x04,
+0xd5, 0x05, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x38, 0x05, 0xe0, 0x00, 0x00, 0x58, 0x1f,
+0x00, 0x40, 0xb6, 0x20, 0xd5, 0x15, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x58, 0xd5, 0xf6,
+0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x78, 0xd5, 0xf1, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00,
+0x00, 0x98, 0xd5, 0xec, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0xb8, 0xd5, 0xe7, 0x46, 0xf0,
+0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc, 0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x81, 0xa8, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07, 0x81, 0x65, 0xc0, 0x05, 0x84, 0xa2, 0x4c, 0x02,
+0xc0, 0xa3, 0xd5, 0x1a, 0x46, 0xf0, 0x00, 0x0b, 0x02, 0x37, 0x80, 0xae, 0x84, 0xa1, 0x4c, 0x32,
+0xc0, 0x9b, 0x46, 0x30, 0x04, 0x01, 0x04, 0x41, 0x81, 0xa3, 0x46, 0x50, 0x04, 0x10, 0x54, 0x22,
+0x00, 0xf7, 0x14, 0x21, 0x81, 0xa3, 0x04, 0x02, 0x80, 0x8e, 0x43, 0xe0, 0x44, 0x09, 0x15, 0xe2,
+0x80, 0x8e, 0x48, 0x00, 0x00, 0x83, 0x46, 0xf0, 0x00, 0x0b, 0x02, 0x57, 0x80, 0xae, 0x4e, 0x53,
+0x00, 0x83, 0x46, 0x20, 0x00, 0x0b, 0x02, 0x01, 0x00, 0xaf, 0x44, 0x50, 0x00, 0x82, 0xd0, 0x3b,
+0x5c, 0xf0, 0x00, 0x83, 0xe8, 0x07, 0xc0, 0x71, 0xe6, 0x0a, 0xe9, 0x0c, 0x9f, 0x69, 0xd8, 0x6d,
+0xd5, 0x25, 0x9c, 0x6a, 0x4c, 0x00, 0x80, 0x4a, 0xe2, 0x01, 0xe9, 0x3a, 0x9d, 0x49, 0xd8, 0x65,
+0xd5, 0x51, 0x55, 0xe0, 0x00, 0xff, 0x46, 0x50, 0x04, 0x01, 0x58, 0x52, 0x86, 0x88, 0x58, 0x3f,
+0x00, 0x60, 0x15, 0xe2, 0x80, 0x00, 0x40, 0x0f, 0x14, 0x08, 0xb6, 0x65, 0x50, 0x12, 0xf9, 0x80,
+0x41, 0xe0, 0x04, 0x00, 0xb4, 0x7e, 0x42, 0x11, 0x98, 0x09, 0xb6, 0x3e, 0x00, 0x01, 0x01, 0x5e,
+0x58, 0x40, 0x00, 0x60, 0xb6, 0x05, 0xb6, 0x85, 0xd5, 0x48, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00,
+0x06, 0x88, 0x44, 0x30, 0x00, 0x11, 0x44, 0x20, 0x00, 0x71, 0xb6, 0x60, 0x50, 0x10, 0x79, 0xb0,
+0xb6, 0x40, 0xd5, 0x34, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x06, 0x88, 0x44, 0x30, 0x00, 0x12,
+0x44, 0x20, 0x00, 0x72, 0xb6, 0x60, 0x50, 0x10, 0x79, 0xd0, 0xb6, 0x40, 0xd5, 0x27, 0x46, 0x00,
+0x04, 0x01, 0x58, 0x00, 0x06, 0x88, 0x44, 0x30, 0x00, 0x13, 0x44, 0x20, 0x00, 0x73, 0xb6, 0x60,
+0x50, 0x10, 0x79, 0xf0, 0xb6, 0x40, 0xd5, 0x1a, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x06, 0x88,
+0x44, 0x30, 0x00, 0x14, 0x44, 0x20, 0x00, 0x74, 0xb6, 0x60, 0x50, 0x10, 0x7a, 0x10, 0xb6, 0x40,
+0xd5, 0x0d, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x06, 0x88, 0x44, 0x30, 0x00, 0x15, 0x44, 0x20,
+0x00, 0x75, 0xb6, 0x60, 0xb6, 0x40, 0x50, 0x10, 0x7a, 0x30, 0x05, 0xe0, 0x80, 0x00, 0x42, 0x4f,
+0x18, 0x09, 0xb6, 0x81, 0xb6, 0x60, 0xb6, 0x40, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc,
+0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xa8, 0xdd, 0x2f, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x96, 0x92,
+0x97, 0xc1, 0x97, 0x8b, 0xf2, 0x81, 0x47, 0xc0, 0x00, 0x04, 0x59, 0xce, 0x04, 0xb4, 0x46, 0xa0,
+0x00, 0x04, 0x58, 0xa5, 0x01, 0xc0, 0x46, 0x90, 0x00, 0x04, 0x58, 0x94, 0x81, 0xcc, 0xd5, 0x20,
+0x96, 0x30, 0x44, 0x10, 0x00, 0x40, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x0c, 0xdd, 0x2f,
+0x81, 0x00, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xec, 0xdd, 0x2f, 0xc0, 0xfb, 0xf3, 0x01,
+0x80, 0x28, 0x84, 0x40, 0x80, 0x07, 0xdd, 0x3c, 0x50, 0x63, 0x7f, 0xc0, 0x80, 0x08, 0x50, 0x73,
+0x80, 0x40, 0x4b, 0xe0, 0x28, 0x01, 0x97, 0xb3, 0x4b, 0xe0, 0x24, 0x01, 0x97, 0xf9, 0x4e, 0x64,
+0xff, 0xe1, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0xbc,
+0x46, 0xf0, 0x00, 0x0b, 0x00, 0x57, 0x81, 0x64, 0x40, 0x80, 0x00, 0x10, 0x4c, 0x54, 0x40, 0x31,
+0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x00, 0x20, 0x44, 0x40, 0x00, 0x40, 0x84, 0x60, 0x10, 0x30,
+0x00, 0x8e, 0x10, 0x40, 0x00, 0x8d, 0x10, 0x40, 0x00, 0x3e, 0x10, 0x30, 0x00, 0x3f, 0x10, 0x40,
+0x00, 0x45, 0x10, 0x30, 0x00, 0x46, 0x10, 0x40, 0x00, 0x4c, 0x10, 0x30, 0x00, 0x4d, 0x10, 0x40,
+0x00, 0x53, 0x10, 0x30, 0x00, 0x54, 0x10, 0x40, 0x00, 0x5a, 0x10, 0x30, 0x00, 0x5b, 0x10, 0x40,
+0x00, 0x61, 0x10, 0x30, 0x00, 0x62, 0x10, 0x40, 0x00, 0x68, 0x10, 0x30, 0x00, 0x69, 0x10, 0x40,
+0x00, 0x6f, 0x10, 0x30, 0x00, 0x70, 0x10, 0x40, 0x00, 0x86, 0x10, 0x30, 0x00, 0x87, 0x46, 0x60,
+0x00, 0x0b, 0x00, 0x03, 0x01, 0x60, 0x44, 0x10, 0x00, 0x40, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x83, 0x0c, 0xdd, 0x2f, 0x80, 0x20, 0x80, 0x48, 0x84, 0x60, 0x80, 0xe0, 0x44, 0x00, 0x00, 0x28,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x84, 0xb4, 0xdd, 0x2f, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x81, 0xc0, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc, 0xdd, 0x2f,
+0x00, 0x53, 0x01, 0x60, 0x5c, 0xf2, 0x80, 0x41, 0xe9, 0x37, 0x46, 0x60, 0x00, 0x04, 0x58, 0x63,
+0x01, 0xec, 0x4b, 0xe0, 0x18, 0x01, 0xc0, 0xfe, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x67, 0x80, 0x4c,
+0x84, 0xa1, 0x46, 0x00, 0x00, 0x0b, 0x46, 0x20, 0x00, 0x04, 0x58, 0x21, 0x03, 0x0c, 0xde, 0x05,
+0x00, 0x00, 0x01, 0x60, 0x84, 0x2a, 0xd5, 0x05, 0x00, 0x00, 0x01, 0x60, 0x44, 0x10, 0x00, 0x36,
+0x50, 0x00, 0x7f, 0xc0, 0x96, 0x00, 0x4b, 0xe0, 0x08, 0x01, 0x84, 0x40, 0x80, 0x20, 0x80, 0xc0,
+0x80, 0x62, 0x44, 0x00, 0x00, 0x68, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x84, 0xb4, 0xdd, 0x2f,
+0x80, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xc0, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x81, 0xcc, 0xdd, 0x2f, 0x46, 0x30, 0x00, 0x0b, 0x58, 0x31, 0x80, 0x20, 0x84, 0x40,
+0x84, 0x82, 0x10, 0x41, 0x80, 0x8e, 0x10, 0x21, 0x80, 0x8d, 0x10, 0x21, 0x80, 0x3e, 0x10, 0x41,
+0x80, 0x3f, 0x10, 0x21, 0x80, 0x45, 0x10, 0x41, 0x80, 0x46, 0x10, 0x21, 0x80, 0x4c, 0x10, 0x41,
+0x80, 0x4d, 0x10, 0x21, 0x80, 0x53, 0x10, 0x41, 0x80, 0x54, 0x10, 0x21, 0x80, 0x5a, 0x10, 0x41,
+0x80, 0x5b, 0x10, 0x21, 0x80, 0x61, 0x10, 0x41, 0x80, 0x62, 0x10, 0x21, 0x80, 0x68, 0x10, 0x41,
+0x80, 0x69, 0x10, 0x21, 0x80, 0x6f, 0x10, 0x41, 0x80, 0x70, 0x10, 0x21, 0x80, 0x86, 0x10, 0x41,
+0x80, 0x87, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x46, 0x80,
+0x00, 0x0b, 0x02, 0x04, 0x00, 0xae, 0x84, 0xa3, 0x40, 0x10, 0x20, 0x09, 0xd1, 0x45, 0xe6, 0x24,
+0xe8, 0x07, 0x84, 0xa1, 0xd1, 0x0d, 0x84, 0xa2, 0x4c, 0x12, 0xc0, 0x98, 0xd5, 0x34, 0x84, 0xa7,
+0xd1, 0x34, 0x84, 0xaf, 0xd1, 0x14, 0x84, 0xa6, 0x4c, 0x12, 0xc0, 0x90, 0xd5, 0x1e, 0x46, 0xf0,
+0x00, 0x0b, 0x00, 0x07, 0x81, 0x60, 0x44, 0x10, 0x00, 0x12, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x83, 0x0c, 0xdd, 0x2f, 0x80, 0x20, 0x84, 0x00, 0x80, 0x40, 0xd5, 0x79, 0x46, 0xf0, 0x00, 0x0b,
+0x00, 0x07, 0x81, 0x60, 0x84, 0x2c, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x0c, 0xdd, 0x2f,
+0x80, 0x20, 0x44, 0x00, 0x00, 0x1c, 0xd5, 0x51, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07, 0x81, 0x60,
+0x84, 0x2a, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x0c, 0xdd, 0x2f, 0x80, 0x20, 0x44, 0x00,
+0x00, 0x12, 0xd5, 0x43, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x88, 0x4c, 0xdd, 0x2f, 0xd5, 0x5f, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x67, 0x81, 0x68, 0xce, 0x03,
+0x96, 0x00, 0xc8, 0x05, 0x44, 0x00, 0x00, 0x9e, 0x84, 0x24, 0xd5, 0x2f, 0x46, 0x70, 0x00, 0x03,
+0x58, 0x73, 0x8d, 0xc0, 0x80, 0x26, 0x50, 0x00, 0x00, 0x27, 0x4b, 0xe0, 0x1c, 0x01, 0x81, 0x20,
+0x80, 0x26, 0x44, 0x00, 0x00, 0x27, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x50, 0x00, 0xff, 0x80, 0x20,
+0xd0, 0x05, 0x00, 0x04, 0x01, 0x5c, 0xe6, 0x0d, 0xe9, 0x1a, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07,
+0x81, 0x5c, 0x84, 0xa1, 0xd8, 0x06, 0x44, 0x00, 0x00, 0xa2, 0x44, 0x10, 0x00, 0x12, 0xd5, 0x0d,
+0x84, 0xa2, 0xd8, 0x06, 0x44, 0x00, 0x00, 0xb4, 0x44, 0x10, 0x00, 0x1c, 0xd5, 0x06, 0x84, 0xa3,
+0xd8, 0x24, 0x44, 0x00, 0x00, 0xd0, 0x84, 0x28, 0x84, 0x40, 0xd5, 0x19, 0x40, 0x00, 0xa0, 0x08,
+0x55, 0xe4, 0x80, 0xff, 0x40, 0x8f, 0x00, 0x04, 0x40, 0x84, 0x00, 0x13, 0x80, 0x26, 0x80, 0x08,
+0x4b, 0xe0, 0x1c, 0x01, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x17, 0x81, 0x60, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x83, 0x0c, 0xdd, 0x2f, 0x80, 0x20, 0x84, 0x41, 0x80, 0x08, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x87, 0xd8, 0xdd, 0x2f, 0xd5, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xa8,
+0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x46, 0x40, 0x04, 0x01, 0x80, 0x64, 0x96, 0x48, 0x96, 0x00, 0x14, 0x02, 0x01, 0x00,
+0x14, 0x11, 0x81, 0x01, 0x96, 0x10, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xc0, 0xdd, 0x2f,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x84, 0x00, 0x80, 0x20, 0x84, 0x41,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8b, 0x3c, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07,
+0x81, 0x62, 0x84, 0x20, 0x84, 0x41, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8b, 0x3c, 0xdd, 0x2f,
+0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0,
+0x00, 0x0b, 0x00, 0x07, 0x81, 0x65, 0x44, 0x50, 0x00, 0x81, 0xd0, 0x50, 0x9d, 0x69, 0xd0, 0x0b,
+0x9f, 0x6a, 0xd8, 0x44, 0x47, 0xe0, 0x04, 0x01, 0x04, 0x5f, 0x01, 0xa3, 0x54, 0x42, 0x80, 0x08,
+0xcc, 0x43, 0xd5, 0x44, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07, 0x81, 0x5e, 0x9f, 0x69, 0xd0, 0x12,
+0x5c, 0xf0, 0x00, 0x82, 0xe8, 0x05, 0xc0, 0x3a, 0xe6, 0x0a, 0xe8, 0x30, 0xd5, 0x24, 0x9c, 0x6a,
+0x4c, 0x00, 0x80, 0x13, 0xe2, 0x01, 0xe9, 0x0b, 0x9d, 0x49, 0xd0, 0x13, 0x9d, 0x4a, 0xd8, 0x26,
+0xd5, 0x15, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x38, 0xd5, 0x1b, 0x46, 0x00, 0x04, 0x01,
+0x58, 0x00, 0x00, 0x58, 0xd5, 0x16, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x78, 0xd5, 0x11,
+0x46, 0x00, 0x04, 0x01, 0x58, 0x00, 0x00, 0x98, 0xd5, 0x0c, 0x46, 0x00, 0x04, 0x01, 0x58, 0x00,
+0x00, 0xb8, 0xd5, 0x07, 0x46, 0x50, 0x04, 0x01, 0x95, 0x05, 0x58, 0x52, 0x80, 0x08, 0x98, 0x25,
+0x05, 0xe0, 0x00, 0x00, 0x42, 0x0f, 0x18, 0x0b, 0xd5, 0x0a, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x81, 0xa8, 0xdd, 0x2f, 0xd5, 0x0b, 0x84, 0x02, 0xd5, 0x02, 0x84, 0x00, 0x84, 0x20, 0x84, 0x42,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8b, 0x3c, 0xdd, 0x2f, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x30, 0x04, 0x01, 0x04, 0x51, 0x81, 0x80, 0x46, 0xf0, 0x00, 0x0b,
+0x10, 0x57, 0x81, 0x65, 0x80, 0x83, 0x04, 0x12, 0x01, 0x81, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x17,
+0x81, 0x66, 0x80, 0xa3, 0x04, 0x21, 0x81, 0x82, 0x04, 0x42, 0x81, 0x83, 0x96, 0x10, 0x96, 0x60,
+0x40, 0x30, 0xa0, 0x08, 0x40, 0x51, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x0b, 0x12, 0x57, 0x80, 0xae,
+0x46, 0x20, 0x04, 0x01, 0x80, 0x02, 0x04, 0x11, 0x01, 0x84, 0x04, 0x30, 0x01, 0x85, 0x97, 0x08,
+0x97, 0x58, 0x40, 0x22, 0xa0, 0x08, 0x40, 0x51, 0x10, 0x04, 0x46, 0xf0, 0x00, 0x0b, 0x12, 0x57,
+0x80, 0xaf, 0x80, 0x20, 0x04, 0x40, 0x81, 0x86, 0x04, 0x30, 0x01, 0x87, 0x96, 0x60, 0x96, 0x18,
+0x40, 0x40, 0x20, 0x08, 0x40, 0x32, 0x04, 0x04, 0x46, 0x00, 0x04, 0x01, 0x46, 0xf0, 0x00, 0x0b,
+0x12, 0x37, 0x80, 0xb0, 0x84, 0x41, 0x84, 0x21, 0x46, 0xf0, 0x00, 0x0b, 0x14, 0x57, 0x80, 0x55,
+0x46, 0xf0, 0x00, 0x0b, 0x10, 0x27, 0x81, 0x63, 0x14, 0x10, 0x01, 0x8c, 0xdd, 0x9e, 0x92, 0x00,
+0x84, 0x20, 0x46, 0xf0, 0x00, 0x0d, 0x10, 0x17, 0x8d, 0x7c, 0xdd, 0x9e, 0x46, 0x30, 0x04, 0x01,
+0x44, 0x50, 0x00, 0xff, 0x80, 0x43, 0x14, 0x51, 0x81, 0x8a, 0x44, 0x30, 0x00, 0x39, 0x46, 0x10,
+0x04, 0x01, 0x14, 0x31, 0x01, 0x98, 0x58, 0x10, 0x86, 0x88, 0x84, 0x80, 0x44, 0x50, 0x00, 0x10,
+0x44, 0x30, 0x00, 0x70, 0x44, 0x20, 0x00, 0x60, 0xb6, 0xa1, 0x50, 0x00, 0x80, 0x18, 0xb6, 0x61,
+0xb6, 0x81, 0xb6, 0x41, 0x44, 0x10, 0x00, 0x31, 0xb6, 0x20, 0x9d, 0x49, 0x9c, 0x4c, 0x9e, 0xca,
+0x9e, 0x89, 0xb6, 0xa0, 0xb6, 0x60, 0xb6, 0x40, 0xb6, 0x20, 0x80, 0x24, 0x50, 0x20, 0x80, 0x21,
+0x84, 0xa9, 0x9c, 0x49, 0xb6, 0x40, 0xd9, 0xfb, 0x46, 0x00, 0x04, 0x01, 0x44, 0x10, 0x00, 0x3f,
+0x14, 0x10, 0x01, 0x8c, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xe4, 0x84, 0x41,
+0x46, 0xf0, 0x00, 0x0b, 0x10, 0x27, 0x81, 0x64, 0x47, 0xe0, 0x04, 0x01, 0x04, 0x1f, 0x01, 0xa3,
+0x46, 0x40, 0x04, 0x00, 0x58, 0x50, 0x80, 0x01, 0x14, 0x5f, 0x01, 0xa3, 0x83, 0x9e, 0x81, 0x5c,
+0x81, 0x2a, 0x04, 0x02, 0x00, 0x8f, 0x15, 0xcf, 0x80, 0x00, 0x14, 0xaf, 0x80, 0x01, 0x14, 0x9f,
+0x80, 0x02, 0xb4, 0x7f, 0xf2, 0x01, 0xf1, 0x02, 0x81, 0x09, 0x80, 0xe8, 0x80, 0xc7, 0x14, 0x8f,
+0x80, 0x03, 0xf7, 0x84, 0xf6, 0x85, 0x58, 0x31, 0x80, 0x38, 0x58, 0x21, 0x00, 0x58, 0x58, 0x10,
+0x80, 0x78, 0xb6, 0x7f, 0xf2, 0x81, 0xf1, 0x82, 0xf3, 0x03, 0xf2, 0x04, 0xf1, 0x05, 0x58, 0x00,
+0x02, 0x00, 0x58, 0x31, 0x80, 0x98, 0x58, 0x21, 0x00, 0xb8, 0x58, 0x10, 0x80, 0x48, 0xf3, 0x83,
+0xf2, 0x84, 0xf1, 0x85, 0x14, 0x02, 0x00, 0x8f, 0x44, 0x00, 0x00, 0x8c, 0xb4, 0x9f, 0x9e, 0x84,
+0xb6, 0x04, 0x9e, 0xd4, 0xf4, 0x01, 0x9e, 0x43, 0xb6, 0x44, 0x83, 0xc6, 0xf0, 0x02, 0x83, 0x86,
+0xb6, 0x60, 0x81, 0x46, 0xf4, 0x03, 0x81, 0x26, 0xb6, 0x24, 0x81, 0x06, 0xf0, 0x04, 0x80, 0xe6,
+0xb6, 0x40, 0xf4, 0x05, 0x80, 0xa6, 0x44, 0x00, 0x00, 0x20, 0xb6, 0x44, 0x14, 0x3f, 0x00, 0x1a,
+0xb9, 0xa2, 0x14, 0x15, 0x00, 0x2a, 0x14, 0x14, 0x80, 0x32, 0x14, 0x14, 0x00, 0x3a, 0x14, 0x23,
+0x80, 0x42, 0x14, 0x13, 0x00, 0x4a, 0x14, 0x02, 0x81, 0x8c, 0xec, 0x1c, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x46, 0x10, 0x04, 0x01, 0x04, 0x60,
+0x81, 0x8c, 0x96, 0x34, 0xc0, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8c, 0x84, 0xdd, 0x2f,
+0x54, 0x23, 0x00, 0x08, 0xc2, 0x17, 0x46, 0x40, 0x04, 0x01, 0x80, 0x64, 0x84, 0x48, 0x84, 0x20,
+0x84, 0x01, 0x14, 0x22, 0x01, 0x8c, 0x14, 0x11, 0x81, 0xa7, 0x46, 0xf0, 0x00, 0x0d, 0x10, 0x07,
+0x8d, 0x7c, 0x46, 0x30, 0x04, 0x00, 0x04, 0x51, 0x80, 0x96, 0x42, 0x42, 0xfc, 0x08, 0x14, 0x41,
+0x80, 0x96, 0x54, 0x53, 0x00, 0x10, 0xc5, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8d, 0x2c,
+0xdd, 0x2f, 0x54, 0x63, 0x00, 0x20, 0xc6, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x8d, 0x98,
+0xdd, 0x2f, 0x46, 0x00, 0x04, 0x01, 0x05, 0xe0, 0x01, 0x8c, 0x15, 0xef, 0x80, 0x01, 0xec, 0x08,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x50, 0x0f,
+0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x01,
+0x44, 0x50, 0x00, 0x80, 0x14, 0x52, 0x01, 0xa8, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x07, 0x81, 0x65,
+0x46, 0x60, 0x00, 0x0b, 0x84, 0x40, 0x54, 0x00, 0x00, 0x60, 0x44, 0x10, 0x00, 0x20, 0x10, 0x23,
+0x01, 0x63, 0x4c, 0x00, 0x80, 0x20, 0x95, 0x49, 0xd0, 0x14, 0xc8, 0x1c, 0x46, 0xf0, 0x00, 0x0b,
+0x00, 0x07, 0x81, 0x66, 0x84, 0x2c, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x0c, 0xdd, 0x2f,
+0x46, 0x10, 0x00, 0x0a, 0x58, 0x10, 0x8e, 0xe8, 0x38, 0x20, 0x82, 0x02, 0xdd, 0x22, 0xd5, 0x0f,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x83, 0xc4, 0xdd, 0x2f, 0x96, 0xc0, 0x10, 0x33, 0x01, 0x63,
+0xd5, 0x06, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xa8, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x01,
+0x84, 0xa0, 0x14, 0x52, 0x01, 0xa8, 0xf0, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84,
+0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xf4, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0xbc, 0xdd, 0x2f, 0x46, 0x50, 0x04, 0x01,
+0x04, 0x02, 0x81, 0xa3, 0x54, 0x00, 0x00, 0x02, 0xc8, 0x66, 0x80, 0xe5, 0xb6, 0xff, 0x80, 0xc5,
+0xb4, 0x3f, 0xf6, 0x81, 0x58, 0x10, 0x80, 0xb8, 0xb6, 0x3f, 0xf1, 0x01, 0x80, 0x45, 0x58, 0x10,
+0x80, 0x88, 0xf1, 0x81, 0x44, 0x10, 0x00, 0x8b, 0x14, 0x11, 0x00, 0x26, 0x83, 0xc2, 0xb4, 0x5f,
+0x83, 0x85, 0xb6, 0x22, 0x81, 0x45, 0xf2, 0x01, 0x81, 0x25, 0x81, 0x05, 0x80, 0xe5, 0xb6, 0x22,
+0x80, 0xc5, 0x44, 0x20, 0x00, 0xff, 0x46, 0x40, 0x04, 0x01, 0x14, 0x1f, 0x00, 0x2a, 0x58, 0x42,
+0x06, 0x88, 0xb9, 0xb2, 0x14, 0x15, 0x00, 0x3a, 0x14, 0x14, 0x80, 0x42, 0x14, 0x14, 0x00, 0x4a,
+0x14, 0x23, 0x81, 0x8a, 0x44, 0x10, 0x00, 0x39, 0x44, 0x20, 0x00, 0x10, 0x14, 0x13, 0x01, 0x98,
+0xb6, 0x44, 0x44, 0x10, 0x00, 0x70, 0x44, 0x20, 0x00, 0x60, 0xb6, 0x24, 0x50, 0x32, 0x00, 0x18,
+0xb6, 0x04, 0x84, 0x22, 0xb6, 0x44, 0x44, 0x20, 0x00, 0x31, 0x14, 0x12, 0x81, 0xa3, 0x9d, 0x12,
+0xb6, 0x43, 0x9c, 0x53, 0x9f, 0x4a, 0x9c, 0x89, 0xb6, 0xa3, 0xb6, 0x83, 0xb6, 0x23, 0xb6, 0x43,
+0x80, 0x23, 0x50, 0x50, 0x00, 0x21, 0x84, 0x69, 0x9c, 0x01, 0xb6, 0xa1, 0x4c, 0x01, 0xff, 0xfb,
+0x80, 0xa6, 0x44, 0x00, 0x00, 0x3f, 0x84, 0x20, 0x14, 0x02, 0x81, 0x8c, 0x46, 0xf0, 0x00, 0x0b,
+0x10, 0x17, 0x81, 0x64, 0x80, 0x05, 0x04, 0x20, 0x01, 0xa3, 0x54, 0x41, 0x00, 0xfe, 0x14, 0x40,
+0x01, 0xa3, 0xd5, 0x38, 0x46, 0x40, 0x04, 0x00, 0x04, 0x32, 0x00, 0x85, 0x80, 0xe5, 0x46, 0x00,
+0x04, 0x01, 0x58, 0x00, 0x06, 0xa0, 0x58, 0x21, 0x80, 0x04, 0x44, 0x60, 0x00, 0x39, 0x45, 0xe0,
+0x00, 0x31, 0x45, 0xc0, 0x00, 0x32, 0x44, 0xa0, 0x00, 0x33, 0x44, 0x90, 0x00, 0x34, 0x44, 0x80,
+0x00, 0x35, 0x14, 0x22, 0x00, 0x85, 0x14, 0x63, 0x81, 0x98, 0x15, 0xe0, 0x00, 0x00, 0x15, 0xc0,
+0x00, 0x00, 0xb7, 0x40, 0xb7, 0x20, 0xb7, 0x00, 0x84, 0x20, 0x50, 0x80, 0x80, 0x21, 0x84, 0xa9,
+0x9c, 0x49, 0xb7, 0x00, 0xd9, 0xfb, 0x81, 0x27, 0x8d, 0x4c, 0x14, 0xa4, 0x81, 0x8c, 0x80, 0x07,
+0x04, 0x10, 0x01, 0xa3, 0x96, 0x4c, 0xc1, 0x02, 0x84, 0x21, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x17,
+0x81, 0x64, 0x46, 0x00, 0x04, 0x01, 0x84, 0xa0, 0x84, 0x40, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x27,
+0x81, 0x6a, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x27, 0x81, 0x63, 0x46, 0xf0, 0x00, 0x0b, 0x14, 0x57,
+0x80, 0x56, 0x14, 0x50, 0x01, 0xa8, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x37, 0x81, 0x64, 0x46, 0xf0,
+0x00, 0x0b, 0x00, 0x07, 0x81, 0x68, 0x46, 0xf0, 0x00, 0x0b, 0x00, 0x47, 0x81, 0x69, 0x40, 0x11,
+0xa4, 0x08, 0x40, 0x00, 0x28, 0x08, 0x40, 0x30, 0x80, 0x04, 0x58, 0x01, 0x80, 0x02, 0x40, 0x12,
+0x2c, 0x08, 0x46, 0x40, 0x04, 0x00, 0x40, 0x20, 0x04, 0x04, 0x46, 0xf0, 0x00, 0x0b, 0x10, 0x57,
+0x81, 0x67, 0x14, 0x22, 0x00, 0x8f, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x60, 0x00, 0x04, 0x58, 0x63, 0x01, 0xd8, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x81, 0xb4, 0xdd, 0x2f, 0x4b, 0xe0, 0x18, 0x01, 0xc0, 0xfe, 0x46, 0x00, 0x04, 0x01,
+0xb4, 0x40, 0x46, 0x00, 0x04, 0x01, 0x96, 0x90, 0x58, 0x00, 0x05, 0x00, 0x84, 0x20, 0xd5, 0x05,
+0xa3, 0x01, 0x96, 0xe0, 0x18, 0x30, 0x80, 0x01, 0xe0, 0x22, 0xe9, 0xfb, 0x47, 0xe0, 0x00, 0x0b,
+0x02, 0x3f, 0x00, 0xb0, 0x84, 0x20, 0x9a, 0x1a, 0x97, 0x41, 0x40, 0x00, 0x94, 0x06, 0x12, 0x5f,
+0x00, 0xb0, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x60, 0x00, 0x04,
+0x58, 0x63, 0x01, 0xd8, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xb4, 0xdd, 0x2f, 0x4b, 0xe0,
+0x18, 0x01, 0xc0, 0xfe, 0x47, 0xe0, 0x04, 0x01, 0xb4, 0xde, 0x97, 0xb0, 0x46, 0xf0, 0x00, 0x0b,
+0x04, 0x07, 0x80, 0x55, 0x46, 0x10, 0x04, 0x01, 0x80, 0x46, 0x58, 0x10, 0x85, 0x00, 0x84, 0x61,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x82, 0xac, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x0b, 0x02, 0x40,
+0x80, 0xb0, 0x84, 0x00, 0x9a, 0xe6, 0x96, 0x99, 0x40, 0x00, 0x08, 0x06, 0x12, 0x20, 0x80, 0xb0,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa0, 0xbc, 0x46, 0x60, 0x00, 0x0b,
+0x58, 0x63, 0x01, 0x60, 0xa4, 0x30, 0x44, 0x10, 0x00, 0x40, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x82, 0xfc, 0xdd, 0x2f, 0x46, 0x80, 0x00, 0x0b, 0x58, 0x84, 0x01, 0x54, 0x97, 0xc0, 0xb4, 0x28,
+0x46, 0x00, 0x04, 0x01, 0x80, 0x47, 0x58, 0x00, 0x04, 0x00, 0x84, 0x60, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x82, 0xac, 0xdd, 0x2f, 0xb4, 0x68, 0x80, 0x07, 0x98, 0xbb, 0xb6, 0x48, 0x46, 0xf0,
+0x00, 0x04, 0x58, 0xf7, 0x81, 0xc0, 0xdd, 0x2f, 0xa4, 0x70, 0x84, 0x00, 0x9b, 0xcf, 0x97, 0xf9,
+0x40, 0x00, 0x1c, 0x06, 0xad, 0xf0, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xf4, 0x96, 0x02, 0xf0, 0x81, 0x84, 0xc0, 0x46, 0xa0, 0x00, 0x04, 0x58, 0xa5, 0x02, 0xfc,
+0x46, 0x70, 0x00, 0x0b, 0x58, 0x73, 0x81, 0x54, 0x46, 0x90, 0x00, 0x03, 0x58, 0x94, 0x8d, 0xc0,
+0xd5, 0x12, 0x00, 0x83, 0x80, 0x01, 0xa7, 0x78, 0x40, 0x44, 0x20, 0x08, 0x40, 0x02, 0x14, 0x04,
+0xb6, 0x7f, 0x4b, 0xe0, 0x24, 0x01, 0xb4, 0x7f, 0x9d, 0xb1, 0xb6, 0x03, 0x97, 0xb0, 0xb4, 0x47,
+0x9c, 0x51, 0xb6, 0x27, 0x46, 0xf0, 0x00, 0x0b, 0x02, 0x07, 0x80, 0xb0, 0x44, 0x10, 0x00, 0x40,
+0x4b, 0xe0, 0x28, 0x01, 0x46, 0x10, 0x01, 0x00, 0x58, 0x10, 0x85, 0x00, 0x98, 0xb1, 0x46, 0x80,
+0x00, 0x0b, 0xf1, 0x01, 0x94, 0xd2, 0xe2, 0xc0, 0xe9, 0xdd, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x04,
+0x58, 0xf7, 0x81, 0xc0, 0xdd, 0x2f, 0x02, 0x34, 0x00, 0xb0, 0x84, 0x00, 0x9b, 0x9e, 0x97, 0xb1,
+0x40, 0x00, 0x18, 0x06, 0x12, 0x64, 0x00, 0xb0, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xf4, 0x46, 0x70, 0x00, 0x04, 0x58, 0x73, 0x81, 0xd8, 0x97, 0x82,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xb4, 0xdd, 0x2f, 0x4b, 0xe0, 0x1c, 0x01, 0xc0, 0xfe,
+0x46, 0x20, 0x04, 0x01, 0xb5, 0x22, 0x85, 0x00, 0x44, 0x10, 0x00, 0xfc, 0x40, 0x04, 0x18, 0x1b,
+0x40, 0x00, 0x98, 0x1a, 0x46, 0x70, 0x04, 0x01, 0xf0, 0x81, 0x54, 0x94, 0x80, 0xff, 0x58, 0x73,
+0x85, 0x00, 0x47, 0xc0, 0x00, 0x03, 0x59, 0xce, 0x0e, 0x9c, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63,
+0x01, 0x54, 0x46, 0xa0, 0x00, 0x03, 0x58, 0xa5, 0x0e, 0x20, 0xd5, 0x15, 0xdd, 0x3c, 0xa7, 0x31,
+0xf2, 0x01, 0xa6, 0x70, 0x40, 0x31, 0x10, 0x04, 0xa3, 0x79, 0x40, 0x01, 0xa0, 0x08, 0x40, 0x00,
+0x04, 0x04, 0x96, 0x68, 0x4b, 0xe0, 0x28, 0x01, 0xb4, 0x86, 0x8d, 0x01, 0x9c, 0xe1, 0xb6, 0x66,
+0x54, 0x84, 0x00, 0xff, 0xe3, 0x09, 0xe9, 0xeb, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8e, 0x6c,
+0xdd, 0x2f, 0x46, 0x30, 0x00, 0x0b, 0x02, 0x41, 0x80, 0xb0, 0x84, 0x20, 0x40, 0x02, 0x24, 0x01,
+0x97, 0x41, 0x40, 0x00, 0x94, 0x06, 0x12, 0x51, 0x80, 0xb0, 0xec, 0x0c, 0x3a, 0x6f, 0xaa, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x66,
+0xa6, 0x00, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63, 0x01, 0x6a, 0x84, 0x40, 0x44, 0x10, 0x00, 0x26,
+0xae, 0xb0, 0x4c, 0x00, 0x81, 0xde, 0x5c, 0xf0, 0x00, 0x27, 0xe8, 0x35, 0x84, 0x68, 0x4c, 0x01,
+0x82, 0x45, 0xe6, 0x09, 0xe8, 0x15, 0x84, 0x83, 0x4c, 0x02, 0x01, 0x7b, 0xe6, 0x04, 0xe8, 0x08,
+0x84, 0xa1, 0xd0, 0x6e, 0x87, 0xc2, 0x4c, 0x0f, 0x42, 0x5f, 0x48, 0x00, 0x01, 0x5c, 0x84, 0x26,
+0x4c, 0x00, 0x81, 0x67, 0x84, 0x47, 0x4c, 0x01, 0x42, 0x57, 0x48, 0x00, 0x01, 0x6a, 0x84, 0x6b,
+0x4c, 0x01, 0x82, 0x35, 0xe6, 0x0c, 0xe8, 0x09, 0x84, 0x89, 0x4c, 0x02, 0x02, 0x30, 0x84, 0xaa,
+0x4c, 0x02, 0xc2, 0x4a, 0x48, 0x00, 0x02, 0x24, 0x45, 0xe0, 0x00, 0x22, 0x4c, 0x0f, 0x01, 0xa1,
+0x44, 0x10, 0x00, 0x23, 0x4c, 0x00, 0x81, 0xb8, 0x44, 0x20, 0x00, 0x20, 0x4c, 0x01, 0x42, 0x3c,
+0x48, 0x00, 0x01, 0x89, 0x44, 0x30, 0x00, 0x43, 0x4c, 0x01, 0x81, 0x79, 0x5c, 0xf0, 0x00, 0x44,
+0xe8, 0x20, 0x44, 0x40, 0x00, 0x33, 0x4c, 0x02, 0x01, 0xcc, 0x5c, 0xf0, 0x00, 0x34, 0xe8, 0x0b,
+0x44, 0x50, 0x00, 0x27, 0x4c, 0x02, 0x81, 0xa0, 0x45, 0xe0, 0x00, 0x32, 0x4c, 0x0f, 0x42, 0x24,
+0x48, 0x00, 0x01, 0xaa, 0x44, 0x10, 0x00, 0x37, 0x4c, 0x00, 0x81, 0xbb, 0x44, 0x20, 0x00, 0x42,
+0x4c, 0x01, 0x01, 0x3c, 0x44, 0x30, 0x00, 0x36, 0x4c, 0x01, 0xc2, 0x16, 0x48, 0x00, 0x01, 0xa9,
+0x44, 0x40, 0x00, 0x52, 0x4c, 0x02, 0x01, 0xb9, 0x5c, 0xf0, 0x00, 0x53, 0xe8, 0x0b, 0x44, 0x50,
+0x00, 0x46, 0x4c, 0x02, 0x81, 0x3c, 0x45, 0xe0, 0x00, 0x47, 0x4c, 0x0f, 0x42, 0x05, 0x48, 0x00,
+0x01, 0x46, 0x44, 0x10, 0x00, 0x56, 0x4c, 0x00, 0x81, 0xb6, 0x44, 0x20, 0x00, 0x57, 0x4c, 0x01,
+0x01, 0xbb, 0x44, 0x30, 0x00, 0x53, 0x4c, 0x01, 0xc1, 0xf7, 0x48, 0x00, 0x01, 0xb5, 0x46, 0x00,
+0x00, 0x0b, 0x58, 0x00, 0x01, 0x5c, 0xa6, 0x00, 0x84, 0x88, 0x4c, 0x02, 0x00, 0x8b, 0xe6, 0x09,
+0xe8, 0x07, 0x84, 0xa1, 0xd0, 0x0f, 0x87, 0xc2, 0x4c, 0x0f, 0x41, 0xec, 0xd5, 0x76, 0x44, 0x10,
+0x00, 0x10, 0x4c, 0x00, 0x80, 0x89, 0x44, 0x20, 0x00, 0x12, 0x4c, 0x01, 0x41, 0xe3, 0x48, 0x00,
+0x00, 0xa3, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x00,
+0x58, 0x42, 0x02, 0x0c, 0xb4, 0x44, 0x84, 0x20, 0x58, 0x31, 0x00, 0x10, 0xb6, 0x64, 0x92, 0x00,
+0x84, 0x07, 0x9c, 0x49, 0x4c, 0x10, 0x7f, 0xfd, 0x44, 0x1f, 0xff, 0xef, 0x46, 0x00, 0x04, 0x00,
+0x40, 0x21, 0x04, 0x02, 0x58, 0x00, 0x02, 0x0c, 0xb6, 0x40, 0x47, 0xe0, 0x04, 0x00, 0x59, 0xef,
+0x02, 0x00, 0xb4, 0xbe, 0x54, 0x12, 0x80, 0x03, 0xc9, 0x12, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10,
+0x82, 0x04, 0x05, 0xe0, 0x80, 0x00, 0x46, 0x3f, 0xf0, 0xff, 0x58, 0x5f, 0x00, 0x01, 0xb6, 0xa1,
+0x58, 0x31, 0x8f, 0xff, 0xb4, 0x81, 0x40, 0x22, 0x0c, 0x02, 0xd5, 0x31, 0x84, 0x41, 0x4c, 0x11,
+0x40, 0x18, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x04, 0xb4, 0x41, 0x84, 0x9e, 0x41, 0xe1,
+0x10, 0x02, 0x15, 0xe0, 0x80, 0x00, 0x46, 0x3f, 0xf0, 0xff, 0xb4, 0xa1, 0x58, 0x31, 0x8f, 0xff,
+0x40, 0x42, 0x8c, 0x02, 0xb6, 0x81, 0x46, 0x30, 0x01, 0x00, 0xb4, 0x41, 0xd5, 0x16, 0x46, 0x10,
+0x04, 0x00, 0x58, 0x10, 0x82, 0x04, 0xb4, 0x81, 0x84, 0xbe, 0x40, 0x22, 0x14, 0x02, 0xb6, 0x41,
+0x46, 0x3f, 0xf0, 0xff, 0x05, 0xe0, 0x80, 0x00, 0x58, 0x31, 0x8f, 0xff, 0x40, 0x5f, 0x0c, 0x02,
+0xb6, 0xa1, 0x46, 0x30, 0x05, 0x00, 0xb4, 0x41, 0x40, 0x21, 0x0c, 0x04, 0xb6, 0x41, 0xb4, 0x20,
+0x58, 0x10, 0x83, 0x00, 0x48, 0x00, 0x00, 0xca, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xfc, 0xdd, 0x2f, 0x48, 0x00, 0x01, 0x6a,
+0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x04, 0x00, 0x05, 0xe0, 0x00, 0x00, 0x58, 0x1f, 0x0c, 0x00,
+0x48, 0x00, 0x00, 0xb4, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xec, 0xdd, 0x2f, 0xc8, 0x09,
+0x84, 0x61, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x6a, 0xae, 0xc0, 0x48, 0x00, 0x01, 0x52,
+0x46, 0x50, 0x00, 0x0a, 0x58, 0x52, 0x8e, 0xe4, 0xa7, 0x28, 0x46, 0x20, 0x04, 0x01, 0x58, 0x21,
+0x04, 0x00, 0xb6, 0x82, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xc0, 0xdd, 0x2f,
+0x48, 0x00, 0x01, 0x40, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc, 0xdd, 0x2f, 0x46, 0x40,
+0x04, 0x01, 0x58, 0x42, 0x06, 0x60, 0x84, 0xa0, 0xb6, 0xa4, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x81, 0x60, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x0b, 0x58, 0x10, 0x81, 0x6a, 0xae, 0x08, 0x46, 0x40,
+0x04, 0x00, 0x58, 0x42, 0x02, 0x04, 0xb4, 0x44, 0x44, 0x3f, 0x00, 0xff, 0x40, 0x01, 0x0c, 0x02,
+0x58, 0x50, 0x44, 0x00, 0xb6, 0xa4, 0x46, 0x0f, 0xf0, 0xff, 0xb4, 0x44, 0x58, 0x00, 0x0f, 0xff,
+0x58, 0x31, 0x00, 0x01, 0xb6, 0x64, 0x46, 0x10, 0x04, 0x00, 0xb4, 0xa4, 0x58, 0x10, 0x82, 0x0c,
+0x40, 0x22, 0x80, 0x02, 0xb6, 0x44, 0xb4, 0x61, 0x58, 0x01, 0x83, 0x00, 0xb6, 0x01, 0x48, 0x00,
+0x01, 0x09, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x47, 0xe0, 0x00, 0x0b, 0x59, 0xef,
+0x01, 0x5c, 0x46, 0x30, 0x04, 0x10, 0xb4, 0x20, 0x02, 0x2f, 0x00, 0x00, 0xd5, 0x22, 0x46, 0x00,
+0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x20, 0x04, 0x10, 0xb4, 0x20, 0xd5, 0x26, 0x46, 0x00,
+0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x30, 0x04, 0x10, 0xb4, 0x20, 0x46, 0x60, 0x00, 0x0b,
+0x58, 0x63, 0x01, 0x6a, 0x48, 0x00, 0x00, 0xab, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54,
+0x46, 0x20, 0x00, 0x0b, 0x58, 0x21, 0x01, 0x5c, 0x46, 0x30, 0x04, 0x00, 0xb4, 0x20, 0xa4, 0x90,
+0x98, 0x4b, 0xb6, 0x20, 0xac, 0x88, 0x48, 0x00, 0x00, 0xd5, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00,
+0x01, 0x54, 0x46, 0x20, 0x04, 0x00, 0xb4, 0x20, 0x98, 0xca, 0xb6, 0x60, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x81, 0xb8, 0xdd, 0x2f, 0x48, 0x00, 0x00, 0xbd, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00,
+0x01, 0x54, 0x46, 0x30, 0x04, 0x00, 0xb4, 0x20, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63, 0x01, 0x6a,
+0xd5, 0x7d, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0xb4, 0x80, 0x46, 0x00, 0x00, 0x0b,
+0x58, 0x00, 0x01, 0x58, 0x40, 0x12, 0x40, 0x08, 0xb6, 0x20, 0x48, 0x00, 0x00, 0xab, 0x46, 0x00,
+0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x47, 0xe0, 0x00, 0x0b, 0x59, 0xef, 0x01, 0x58, 0x46, 0x50,
+0x00, 0x0b, 0x58, 0x52, 0x81, 0x5c, 0xb4, 0x3e, 0xb4, 0x60, 0xa4, 0xa8, 0xd5, 0xc2, 0x46, 0x20,
+0x00, 0x0b, 0x58, 0x21, 0x01, 0x58, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0xb4, 0x22,
+0xb4, 0x40, 0xd5, 0xc3, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63, 0x01, 0x58, 0x46, 0x00, 0x00, 0x0b,
+0x58, 0x00, 0x01, 0x54, 0xb4, 0x26, 0xb4, 0x60, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63, 0x01, 0x6a,
+0x98, 0x4b, 0xd5, 0x45, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x40, 0x00, 0x0b,
+0x58, 0x42, 0x01, 0x5c, 0x46, 0x30, 0x04, 0x20, 0xb4, 0x20, 0xa4, 0xa0, 0xd5, 0x9a, 0x46, 0x00,
+0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x20, 0x04, 0x20, 0xb4, 0x20, 0xd5, 0x9e, 0x46, 0x00,
+0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x30, 0x04, 0x20, 0xb4, 0x20, 0x46, 0x60, 0x00, 0x0b,
+0x58, 0x63, 0x01, 0x6a, 0xd5, 0x23, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x50,
+0x00, 0x0b, 0x58, 0x52, 0x81, 0x5c, 0x46, 0x30, 0x05, 0x00, 0xb4, 0x20, 0xa4, 0xa8, 0x48, 0xff,
+0xff, 0x79, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x20, 0x05, 0x00, 0xb4, 0x20,
+0x48, 0xff, 0xff, 0x7c, 0x46, 0x00, 0x00, 0x0b, 0x58, 0x00, 0x01, 0x54, 0x46, 0x30, 0x05, 0x00,
+0xb4, 0x20, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63, 0x01, 0x6a, 0x98, 0x4b, 0xb6, 0x20, 0x46, 0xf0,
+0x00, 0x04, 0x58, 0xf7, 0x81, 0xec, 0xdd, 0x2f, 0xc8, 0x02, 0xd5, 0x1a, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x82, 0x18, 0xdd, 0x2f, 0xd5, 0x25, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x83, 0x10, 0xdd, 0x2f, 0xd5, 0x1c, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x81, 0xec, 0xdd, 0x2f, 0x46, 0x60, 0x00, 0x0b, 0x58, 0x63, 0x01, 0x6a, 0xc8, 0x03, 0x84, 0x01,
+0xd5, 0x10, 0x46, 0x20, 0x00, 0x0b, 0x58, 0x21, 0x01, 0x66, 0x01, 0xe1, 0x00, 0x00, 0x56, 0x0f,
+0x00, 0x0b, 0x5c, 0x00, 0x00, 0x01, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x82, 0x7c, 0xdd, 0x2f,
+0xae, 0x30, 0xd5, 0x07, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xa8, 0xdd, 0x2f, 0xd5, 0x06,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0xcc, 0xdd, 0x2f, 0x46, 0x10, 0x00, 0x0b, 0x58, 0x10,
+0x81, 0x6a, 0x20, 0x00, 0x80, 0x00, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x81, 0x84, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x00, 0x58, 0xf7,
+0x84, 0x48, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x10, 0x04, 0x62, 0x02, 0x01, 0x40, 0x53, 0x20, 0x08,
+0x92, 0xa8, 0x14, 0x52, 0x02, 0x01, 0x84, 0x0a, 0x46, 0x10, 0x00, 0x05, 0x58, 0x10, 0x8c, 0x60,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x08, 0xdd, 0x2f, 0x46, 0x30, 0x04, 0x00, 0xb4, 0x43,
+0x44, 0x50, 0x76, 0x10, 0x40, 0x01, 0x40, 0x09, 0xd8, 0x07, 0x04, 0x01, 0x80, 0x41, 0x43, 0xe0,
+0x50, 0x0b, 0x4f, 0xe2, 0x00, 0x0c, 0x84, 0x02, 0x46, 0x10, 0x00, 0x04, 0x58, 0x10, 0x8e, 0x74,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8c, 0x3c, 0xdd, 0x2f, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x0c, 0x3c, 0x84, 0x01, 0x46, 0x10, 0x00, 0x03, 0x58, 0x10, 0x82, 0x2c, 0x4b, 0xe0, 0x18, 0x01,
+0x84, 0x0c, 0x46, 0x10, 0x00, 0x03, 0x58, 0x10, 0x8e, 0xe0, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x10,
+0x00, 0x01, 0x58, 0x10, 0x87, 0xec, 0x84, 0x0f, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x00, 0x00, 0x0e,
+0x58, 0x00, 0x01, 0x78, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0xe4, 0xdd, 0x2f, 0x84, 0x20,
+0x80, 0x81, 0x46, 0x20, 0x00, 0x0a, 0x58, 0x21, 0x06, 0xe0, 0x44, 0x30, 0x08, 0x00, 0x46, 0x00,
+0x00, 0x05, 0x58, 0x00, 0x0a, 0x9c, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0x98, 0xdd, 0x2f,
+0x84, 0x00, 0x46, 0x10, 0x00, 0x0a, 0x58, 0x10, 0x85, 0x7c, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8b, 0x5c, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x00, 0x84, 0xa1, 0x14, 0x52, 0x00, 0x8c, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8a, 0x58, 0xdd, 0x2f, 0x84, 0x00, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0xf0, 0x00, 0x0b, 0x04, 0x07, 0x80, 0x48, 0xdd, 0x20,
+0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x46, 0x20, 0x00, 0x0b, 0x58, 0x21, 0x00, 0xf8,
+0x94, 0xc2, 0x98, 0x1a, 0xb6, 0x20, 0xdd, 0x9e, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00,
+0xdd, 0x9e, 0x92, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00, 0x01, 0x54,
+0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x81, 0x5c, 0xb6, 0x20, 0x48, 0xff, 0xd3, 0x07, 0xdd, 0x9e,
+0x64, 0x12, 0x00, 0x02, 0x96, 0x4c, 0x64, 0x02, 0x00, 0x43, 0x64, 0x00, 0x00, 0x08, 0xb6, 0x20,
+0xdd, 0x9e, 0x92, 0x00, 0x64, 0x12, 0x00, 0x02, 0x42, 0x10, 0x80, 0x09, 0x40, 0x10, 0x80, 0x04,
+0x64, 0x12, 0x00, 0x03, 0x64, 0x00, 0x00, 0x08, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0x64, 0x12, 0x00, 0x43, 0x64, 0x00, 0x00, 0x08, 0x46, 0x60, 0x00, 0x0e, 0x58, 0x63, 0x01, 0x54,
+0x04, 0x03, 0x00, 0x0b, 0xc0, 0x02, 0xdd, 0x20, 0x04, 0x03, 0x00, 0x0c, 0xc0, 0x02, 0xdd, 0x20,
+0x04, 0x23, 0x00, 0x08, 0x44, 0x10, 0x03, 0x00, 0x54, 0x01, 0x03, 0x00, 0x4c, 0x00, 0xff, 0xf2,
+0x64, 0x00, 0x00, 0x00, 0xd5, 0xee, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x80, 0xc0,
+0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70, 0xdd, 0x2f, 0x46, 0xf0,
+0x00, 0x0e, 0x04, 0x37, 0x80, 0x5d, 0x40, 0x43, 0x18, 0x05, 0x40, 0x22, 0x0c, 0x02, 0xf0, 0x01,
+0x46, 0xf0, 0x00, 0x0e, 0x14, 0x27, 0x80, 0x5d, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84,
+0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0xef, 0xf8, 0x80, 0xc0, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70,
+0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0e, 0x04, 0x37, 0x80, 0x5d, 0xf0, 0x01, 0x40, 0x23, 0x0c, 0x04,
+0x46, 0xf0, 0x00, 0x0e, 0x14, 0x27, 0x80, 0x5d, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84,
+0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0x80, 0xc1, 0x46, 0xf0, 0x00, 0x0e, 0x14, 0x07, 0x80, 0x60, 0x46, 0xf0, 0x00, 0x0e, 0x14, 0x67,
+0x80, 0x61, 0xc8, 0x08, 0x44, 0x00, 0x01, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0x1c,
+0xdd, 0x2f, 0xce, 0x08, 0x44, 0x00, 0x02, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0x1c,
+0xdd, 0x2f, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa8, 0xbc, 0x44, 0x50, 0x00, 0x14,
+0x46, 0x60, 0x00, 0x0e, 0x58, 0x63, 0x01, 0x5c, 0x42, 0x60, 0x94, 0x73, 0x80, 0xe0, 0x81, 0x43,
+0x50, 0x03, 0x00, 0x0c, 0xa8, 0x71, 0x84, 0x20, 0x81, 0x22, 0x81, 0x04, 0xa8, 0x72, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8b, 0xe4, 0xdd, 0x2f, 0x50, 0x35, 0x7f, 0xb8, 0x40, 0x24, 0x8c, 0x00,
+0x58, 0x44, 0x00, 0x08, 0x84, 0x0a, 0xb6, 0x46, 0xa9, 0xd1, 0xb6, 0x82, 0xa8, 0x12, 0x3a, 0x6f,
+0xa8, 0x84, 0xdd, 0x9e, 0xa8, 0x01, 0xb6, 0x00, 0xdd, 0x9e, 0x92, 0x00, 0xa0, 0x81, 0xb6, 0x01,
+0xa8, 0x89, 0xb6, 0x22, 0xa8, 0x41, 0xdd, 0x9e, 0xb4, 0x20, 0x4c, 0x10, 0x40, 0x04, 0x84, 0x20,
+0xd5, 0x07, 0xa0, 0xc9, 0xb4, 0x81, 0xb6, 0x83, 0xb4, 0x01, 0xa0, 0x89, 0xa8, 0x81, 0x80, 0x01,
+0xdd, 0x9e, 0x92, 0x00, 0x46, 0x20, 0x00, 0x0b, 0x04, 0x11, 0x00, 0x54, 0x98, 0x01, 0x14, 0x01,
+0x00, 0x54, 0x80, 0x01, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x10, 0x00, 0x0e, 0x58, 0x10, 0x81, 0x94,
+0x46, 0xf0, 0x00, 0x0b, 0x14, 0x17, 0x80, 0x54, 0xdd, 0x9e, 0x92, 0x00, 0x46, 0x50, 0x00, 0x0d,
+0x58, 0x52, 0x8d, 0x80, 0x38, 0x12, 0x82, 0x0a, 0x46, 0x10, 0x04, 0x00, 0x58, 0x10, 0x82, 0x00,
+0xa0, 0x8d, 0x84, 0x61, 0x40, 0x41, 0x80, 0x0c, 0x40, 0x02, 0x08, 0x04, 0xa8, 0x0d, 0xdd, 0x9e,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x46, 0x30, 0x04, 0x00, 0x58, 0x31, 0x82, 0x00, 0xa0, 0x5c,
+0x46, 0xf0, 0x00, 0x0d, 0x00, 0x07, 0x8e, 0x3a, 0xc0, 0x0e, 0x47, 0xe0, 0x04, 0x00, 0x46, 0x08,
+0x00, 0x00, 0x58, 0x00, 0x03, 0xe8, 0x84, 0xa1, 0x14, 0x0f, 0x00, 0x22, 0x46, 0xf0, 0x00, 0x0d,
+0x10, 0x57, 0x8e, 0x3b, 0x96, 0x08, 0x54, 0x20, 0x00, 0x08, 0xc2, 0x07, 0x46, 0xf0, 0x00, 0x0d,
+0x04, 0x07, 0x83, 0x63, 0x48, 0x00, 0x00, 0x84, 0x54, 0x30, 0x00, 0x10, 0xc3, 0x06, 0x46, 0xf0,
+0x00, 0x0d, 0x04, 0x07, 0x83, 0x64, 0xd5, 0x7b, 0x54, 0x50, 0x00, 0x20, 0xc5, 0x06, 0x46, 0xf0,
+0x00, 0x0d, 0x04, 0x07, 0x83, 0x65, 0xd5, 0x73, 0x54, 0x20, 0x00, 0x02, 0xc2, 0x06, 0x46, 0xf0,
+0x00, 0x0d, 0x04, 0x07, 0x83, 0x61, 0xd5, 0x6b, 0x96, 0xc4, 0xc3, 0x06, 0x46, 0xf0, 0x00, 0x0d,
+0x04, 0x07, 0x83, 0x60, 0xd5, 0x64, 0x54, 0x40, 0x00, 0x04, 0xc4, 0x06, 0x46, 0xf0, 0x00, 0x0d,
+0x04, 0x07, 0x83, 0x62, 0xd5, 0x5c, 0x40, 0x20, 0xa0, 0x09, 0x96, 0x10, 0x55, 0xe0, 0x00, 0x01,
+0x4f, 0xe2, 0x00, 0x07, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x68, 0xd5, 0x50, 0x54, 0x30,
+0x00, 0x02, 0xc3, 0x06, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x69, 0xd5, 0x48, 0x54, 0x40,
+0x00, 0x04, 0xc4, 0x06, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x6a, 0xd5, 0x40, 0x55, 0xe0,
+0x00, 0x08, 0x4f, 0xe2, 0x00, 0x07, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x6b, 0xd5, 0x37,
+0x54, 0x30, 0x00, 0x10, 0xc3, 0x06, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x6c, 0xd5, 0x2f,
+0x54, 0x40, 0x00, 0x20, 0xc4, 0x06, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x6d, 0xd5, 0x27,
+0x54, 0x50, 0x00, 0x40, 0xc5, 0x06, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x6e, 0xd5, 0x1f,
+0x54, 0x20, 0x00, 0x80, 0xc2, 0x06, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x6f, 0xd5, 0x17,
+0x40, 0x40, 0xc0, 0x09, 0x96, 0x60, 0x96, 0x0c, 0xc0, 0x02, 0xd5, 0x04, 0x54, 0x10, 0x80, 0x02,
+0xc1, 0x06, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x70, 0xd5, 0x09, 0x47, 0xe0, 0x04, 0x00,
+0x04, 0x3f, 0x00, 0x8d, 0x9c, 0x99, 0x14, 0x2f, 0x00, 0x8d, 0xd5, 0x02, 0xdd, 0x20, 0xec, 0x04,
+0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa8, 0x3c, 0xef, 0xf4, 0x46, 0x30,
+0x04, 0x10, 0x54, 0x80, 0x00, 0x0f, 0x58, 0x31, 0x85, 0x00, 0x40, 0x84, 0x38, 0x08, 0x84, 0x80,
+0x54, 0x70, 0x80, 0x3f, 0xb4, 0xa3, 0xf5, 0x81, 0x00, 0x5f, 0x80, 0x07, 0x54, 0x52, 0x80, 0x80,
+0x97, 0x68, 0xcd, 0x3c, 0xf5, 0x81, 0x00, 0x9f, 0x80, 0x07, 0x42, 0x94, 0x98, 0x09, 0x00, 0x6f,
+0x80, 0x05, 0x92, 0xc6, 0x95, 0xb6, 0x44, 0xaf, 0xff, 0x80, 0x40, 0x94, 0xa8, 0x04, 0x40, 0x63,
+0x1c, 0x04, 0x10, 0x9f, 0x80, 0x07, 0x10, 0x6f, 0x80, 0x05, 0x44, 0x9c, 0x3f, 0xff, 0xf6, 0x01,
+0x40, 0x63, 0x24, 0x02, 0x40, 0x63, 0x20, 0x04, 0xf6, 0x81, 0xb6, 0xc3, 0xb4, 0xc3, 0x9d, 0x69,
+0xf6, 0x81, 0x00, 0x6f, 0x80, 0x07, 0x54, 0x63, 0x00, 0x80, 0xc6, 0x05, 0x44, 0xa0, 0x00, 0x64,
+0x4c, 0x55, 0x7f, 0xf6, 0x00, 0x5f, 0x80, 0x07, 0x54, 0x52, 0x80, 0x80, 0xcd, 0x0f, 0x00, 0x5f,
+0x80, 0x05, 0x54, 0x52, 0x80, 0x3f, 0xd9, 0x0a, 0xf5, 0x01, 0x92, 0xae, 0x54, 0x52, 0x80, 0x0f,
+0xd8, 0x05, 0x00, 0x0f, 0x80, 0x04, 0xb6, 0x02, 0xd5, 0x05, 0x9d, 0x21, 0x44, 0x50, 0x00, 0x64,
+0xdc, 0xba, 0xf1, 0x01, 0x40, 0x00, 0xfc, 0x09, 0xec, 0x0c, 0x3a, 0x6f, 0xa8, 0x04, 0xdd, 0x9e,
+0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x46, 0x30, 0x04, 0x10, 0x84, 0x80, 0x05, 0xe1, 0x81, 0x40,
+0x9d, 0x21, 0x15, 0xef, 0x80, 0x01, 0x00, 0x6f, 0x80, 0x07, 0x54, 0x53, 0x00, 0x80, 0xc5, 0x04,
+0x44, 0x50, 0x00, 0x64, 0xdc, 0xf4, 0x00, 0x5f, 0x80, 0x07, 0x44, 0x3f, 0xff, 0xc0, 0x41, 0xe2,
+0x8c, 0x04, 0x11, 0xef, 0x80, 0x07, 0x54, 0x40, 0x00, 0x0f, 0xf3, 0x01, 0x44, 0x6c, 0x3f, 0xff,
+0x40, 0x52, 0x38, 0x08, 0x41, 0xe1, 0x98, 0x02, 0x40, 0x3f, 0x14, 0x04, 0xf3, 0x81, 0x01, 0xef,
+0x80, 0x05, 0x54, 0x40, 0x80, 0x3f, 0x40, 0x6f, 0x18, 0x09, 0x95, 0xb6, 0x40, 0x33, 0x10, 0x04,
+0x10, 0x2f, 0x80, 0x04, 0x10, 0x3f, 0x80, 0x05, 0x46, 0x20, 0x04, 0x10, 0xf6, 0x01, 0x14, 0x61,
+0x01, 0x40, 0x80, 0x5f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0x84, 0x01,
+0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0xef, 0xf8, 0x46, 0x00, 0x04, 0x11, 0x58, 0x00,
+0x00, 0x1c, 0x84, 0x60, 0xb4, 0x80, 0xf4, 0x81, 0x00, 0x5f, 0x80, 0x06, 0x54, 0x42, 0x80, 0x02,
+0x97, 0x20, 0xcc, 0x23, 0xf4, 0x81, 0x10, 0x1f, 0x80, 0x05, 0x00, 0x5f, 0x80, 0x06, 0x58, 0x52,
+0x80, 0x03, 0x10, 0x5f, 0x80, 0x06, 0xf5, 0x01, 0xb6, 0xa0, 0xb4, 0xa0, 0x9d, 0x21, 0xf5, 0x81,
+0x00, 0x5f, 0x80, 0x06, 0x54, 0x52, 0x80, 0x02, 0xc5, 0x04, 0x44, 0x50, 0x00, 0x64, 0xdc, 0xf6,
+0x00, 0x5f, 0x80, 0x06, 0x54, 0x42, 0x80, 0x02, 0xcc, 0x08, 0x00, 0x5f, 0x80, 0x05, 0xd9, 0x05,
+0x00, 0x0f, 0x80, 0x04, 0xb6, 0x02, 0xd5, 0x05, 0x9c, 0xd9, 0x44, 0x50, 0x00, 0x64, 0xdb, 0xd3,
+0xf1, 0x01, 0x42, 0x00, 0xc4, 0x0b, 0xec, 0x08, 0xdd, 0x9e, 0x92, 0x00, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xf4, 0x46, 0x30, 0x04, 0x11, 0x84, 0x80, 0xa1, 0x5f, 0x9d, 0x21, 0xf5, 0x81, 0x01, 0xef,
+0x80, 0x06, 0x54, 0x5f, 0x00, 0x02, 0xc5, 0x04, 0x44, 0x50, 0x00, 0x64, 0xdc, 0xf6, 0x84, 0xa0,
+0x84, 0x82, 0xf5, 0x81, 0x10, 0x2f, 0x80, 0x04, 0x10, 0x4f, 0x80, 0x06, 0x10, 0x1f, 0x80, 0x05,
+0x80, 0x43, 0xf3, 0x01, 0xa8, 0xd7, 0x80, 0x5f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8,
+0xdd, 0x2f, 0x84, 0x01, 0xec, 0x0c, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa8, 0xbc,
+0xef, 0xf8, 0x46, 0x10, 0x04, 0x10, 0x46, 0x00, 0x04, 0x10, 0x46, 0x20, 0x00, 0xff, 0x58, 0x10,
+0x85, 0x0c, 0x58, 0x00, 0x05, 0x04, 0x44, 0x40, 0xe0, 0x10, 0x58, 0x21, 0x0f, 0xf8, 0xb5, 0x21,
+0xb5, 0x00, 0xb6, 0x81, 0xb6, 0x40, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0d, 0xb8, 0x84, 0x21,
+0x50, 0x2f, 0x80, 0x04, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x64, 0x80, 0x43, 0x84, 0x05, 0x84, 0x21,
+0xb6, 0x7f, 0x81, 0x46, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0x80, 0xdf,
+0xd5, 0x0a, 0x84, 0x00, 0x92, 0x00, 0x84, 0xa7, 0x9c, 0x01, 0xd8, 0xfd, 0x84, 0x05, 0x84, 0x21,
+0x80, 0x5f, 0xdd, 0x2a, 0xb4, 0xff, 0x54, 0x73, 0x80, 0x04, 0xcf, 0xf4, 0xf2, 0x01, 0x84, 0x21,
+0x84, 0x05, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0x46, 0x30, 0x04, 0x10,
+0x46, 0x00, 0x04, 0x10, 0x58, 0x31, 0x85, 0x04, 0x58, 0x00, 0x05, 0x0c, 0xb6, 0xe3, 0xb7, 0x20,
+0xb7, 0x03, 0xec, 0x08, 0x3a, 0x6f, 0xa8, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x84, 0x21, 0x80, 0x40,
+0x44, 0x00, 0x02, 0x58, 0x40, 0x51, 0x00, 0x97, 0x9c, 0x49, 0x96, 0x48, 0x84, 0x6b, 0x98, 0x28,
+0x92, 0x01, 0x4c, 0x11, 0xff, 0xf9, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xf4, 0x46, 0x20,
+0x04, 0x11, 0x80, 0x80, 0x84, 0x60, 0x05, 0xe1, 0x00, 0x07, 0x9c, 0xd9, 0x15, 0xef, 0x80, 0x01,
+0x00, 0x5f, 0x80, 0x06, 0x54, 0x02, 0x80, 0x02, 0xc0, 0x04, 0x44, 0x50, 0x00, 0x64, 0xdb, 0xf4,
+0x84, 0x62, 0x84, 0x00, 0xf0, 0x81, 0x10, 0x3f, 0x80, 0x06, 0x10, 0x1f, 0x80, 0x04, 0x10, 0x4f,
+0x80, 0x05, 0xf1, 0x01, 0xa8, 0x57, 0x80, 0x24, 0x80, 0x5f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0xf8, 0xdd, 0x2f, 0x84, 0x01, 0xec, 0x0c, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xa4, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8d, 0xb8, 0x84, 0x22,
+0x50, 0x2f, 0x80, 0x50, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x1c, 0x50, 0x2f, 0x80, 0x4c,
+0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x1d, 0x50, 0x2f, 0x80, 0x48, 0x84, 0x04, 0xdd, 0x27,
+0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x44, 0x84, 0x04, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x11,
+0x50, 0x2f, 0x80, 0x40, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f, 0x80, 0x3c,
+0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x38, 0x84, 0x05, 0xdd, 0x27,
+0x44, 0x10, 0x00, 0x14, 0x50, 0x2f, 0x80, 0x34, 0x84, 0x05, 0xdd, 0x27, 0x46, 0x00, 0x04, 0x10,
+0x58, 0x00, 0x00, 0x80, 0xb4, 0x80, 0x46, 0x10, 0x04, 0x10, 0xf4, 0x87, 0x58, 0x10, 0x84, 0x00,
+0xb4, 0x41, 0x46, 0xa0, 0x04, 0x11, 0xf2, 0x86, 0x58, 0xa5, 0x02, 0x04, 0xb4, 0x6a, 0x46, 0x90,
+0x04, 0x10, 0xf3, 0x85, 0x58, 0x94, 0x85, 0x0c, 0xb4, 0xa9, 0x46, 0x60, 0x04, 0x10, 0xf5, 0x84,
+0x58, 0x63, 0x05, 0x04, 0xb4, 0x86, 0x47, 0xcf, 0xf0, 0x00, 0x46, 0x80, 0x00, 0x80, 0x84, 0x43,
+0x59, 0xce, 0x00, 0x03, 0x58, 0x84, 0x0c, 0x00, 0xf4, 0x83, 0x15, 0xc0, 0x00, 0x00, 0xb7, 0x01,
+0xb6, 0x4a, 0x47, 0xc0, 0x00, 0x03, 0x59, 0xce, 0x0f, 0x74, 0x84, 0x01, 0xdd, 0x3c, 0x46, 0x50,
+0x18, 0xca, 0x44, 0x30, 0x00, 0x1f, 0x58, 0x52, 0x80, 0x0f, 0x84, 0x9f, 0x44, 0xa0, 0x00, 0x17,
+0xb7, 0x49, 0xb6, 0x66, 0xb6, 0xa9, 0xb6, 0x86, 0x44, 0x10, 0x00, 0x11, 0x50, 0x2f, 0x80, 0x30,
+0x84, 0x00, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f, 0x80, 0x2c, 0x84, 0x00, 0xdd, 0x27,
+0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x28, 0x84, 0x00, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x14,
+0x50, 0x2f, 0x80, 0x24, 0x84, 0x00, 0xdd, 0x27, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x20, 0x84, 0x00,
+0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x0e, 0x70, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20,
+0x00, 0x99, 0x84, 0x00, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0x99, 0x84, 0x00,
+0xdd, 0x28, 0x44, 0x10, 0x00, 0x13, 0x84, 0x49, 0x84, 0x00, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x14,
+0x44, 0x20, 0x00, 0x51, 0x84, 0x00, 0xdd, 0x28, 0x84, 0x24, 0x44, 0x20, 0x00, 0x8e, 0x84, 0x00,
+0xdd, 0x28, 0x84, 0x21, 0x80, 0x41, 0x84, 0x05, 0xdd, 0x28, 0x84, 0x01, 0xdd, 0x3c, 0x46, 0x06,
+0x00, 0x42, 0x58, 0x00, 0x00, 0x3f, 0xb6, 0x09, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0x27,
+0x84, 0x04, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x28,
+0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xf1, 0x84, 0x05, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x13,
+0x44, 0x20, 0x00, 0xa1, 0x84, 0x05, 0xdd, 0x28, 0x84, 0x41, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05,
+0xdd, 0x28, 0x46, 0x10, 0x00, 0x82, 0x58, 0x10, 0x80, 0x3f, 0xb6, 0x29, 0x46, 0x60, 0x00, 0x06,
+0x58, 0x63, 0x00, 0x78, 0x80, 0x0a, 0x84, 0x24, 0xdd, 0x26, 0x84, 0x2a, 0x44, 0x00, 0x00, 0xf1,
+0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0xf2, 0xdd, 0x26, 0x84, 0x20, 0x84, 0x04, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x31, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x26, 0x46, 0x20, 0x04, 0x10, 0xf2, 0x82,
+0x84, 0x01, 0x84, 0x24, 0xdd, 0x26, 0xf3, 0x02, 0x85, 0x40, 0x58, 0x31, 0x80, 0x7c, 0xf3, 0x82,
+0x14, 0xaf, 0x80, 0x01, 0x83, 0x8a, 0x50, 0x9f, 0x80, 0x54, 0x05, 0xef, 0x80, 0x01, 0x54, 0x75,
+0x00, 0x07, 0x41, 0xe3, 0x9c, 0x1a, 0x54, 0x85, 0x00, 0xff, 0x15, 0xef, 0x80, 0x01, 0x41, 0xc3,
+0x9c, 0x1a, 0xe7, 0x08, 0xe8, 0x19, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2b, 0x84, 0x04, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf0, 0x15, 0x44, 0x10, 0x00, 0x2b, 0x54, 0x50,
+0x00, 0xf8, 0x40, 0x25, 0x14, 0x04, 0x84, 0x04, 0xf5, 0x95, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0x70, 0xdd, 0x2f, 0xd5, 0x19, 0x44, 0x10, 0x00, 0x11, 0x80, 0x49, 0x84, 0x04, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf2, 0x15, 0x94, 0x7b, 0x54, 0x31, 0x00, 0xc7,
+0x40, 0x20, 0x8c, 0x04, 0x84, 0x04, 0x44, 0x10, 0x00, 0x11, 0xf3, 0x95, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0x84, 0x21, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x9b, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x84, 0x20, 0xd5, 0x0b, 0x92, 0x00, 0x84, 0x87,
+0x9c, 0x01, 0x4c, 0x02, 0x7f, 0xfd, 0x9c, 0x49, 0x45, 0xe0, 0x01, 0x2c, 0x4c, 0x1f, 0x00, 0x04,
+0x84, 0x00, 0xd5, 0xf5, 0x84, 0x21, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x26, 0x84, 0x20, 0xd5, 0x09,
+0x92, 0x00, 0x84, 0xa7, 0x9c, 0x01, 0xd8, 0xfd, 0x9c, 0x49, 0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04,
+0x84, 0x00, 0xd5, 0xf7, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xba,
+0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x10, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26,
+0xf3, 0x02, 0xb4, 0x23, 0x40, 0x00, 0xc0, 0x09, 0x4e, 0x14, 0x00, 0x05, 0x44, 0x2f, 0x00, 0x00,
+0x98, 0x02, 0x45, 0xe0, 0x80, 0x00, 0x40, 0x40, 0xf8, 0x02, 0x96, 0x49, 0xc4, 0x04, 0x44, 0x5f,
+0x00, 0x00, 0x98, 0x4d, 0x42, 0x00, 0x00, 0x24, 0x42, 0x00, 0x84, 0x73, 0xf1, 0x01, 0xe2, 0x20,
+0xe8, 0x04, 0xf0, 0x81, 0x55, 0xc4, 0x00, 0x07, 0x84, 0x07, 0x4c, 0x70, 0x40, 0x6a, 0x4c, 0x83,
+0xc0, 0x4b, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2b, 0x84, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8d, 0xb8, 0xdd, 0x2f, 0xf5, 0x15, 0x44, 0x10, 0x00, 0x2b, 0x54, 0x22, 0x80, 0xf8, 0x40, 0x4e,
+0x08, 0x04, 0x80, 0x44, 0x84, 0x04, 0xf4, 0x95, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70,
+0xdd, 0x2f, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2c, 0x84, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8d, 0xb8, 0xdd, 0x2f, 0xf3, 0x15, 0x44, 0x10, 0x00, 0x2c, 0x54, 0x01, 0x80, 0xf8, 0x40, 0x5e,
+0x00, 0x04, 0x80, 0x45, 0x84, 0x04, 0xf5, 0x95, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70,
+0xdd, 0x2f, 0x80, 0x49, 0x44, 0x10, 0x00, 0x2d, 0x84, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8d, 0xb8, 0xdd, 0x2f, 0xf4, 0x15, 0x44, 0x10, 0x00, 0x2d, 0x54, 0x22, 0x00, 0xf8, 0x40, 0x3e,
+0x08, 0x04, 0x80, 0x43, 0x84, 0x04, 0xf3, 0x95, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70,
+0xdd, 0x2f, 0xd5, 0x1e, 0x87, 0xcf, 0x4c, 0x8f, 0x40, 0x1c, 0x44, 0x10, 0x00, 0x11, 0x80, 0x49,
+0x84, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf4, 0x15, 0x40, 0x1e,
+0x0c, 0x08, 0x54, 0x02, 0x00, 0xc7, 0x40, 0x30, 0x80, 0x04, 0x80, 0x43, 0x84, 0x04, 0x44, 0x10,
+0x00, 0x11, 0xf3, 0x95, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0x8d, 0x41,
+0x44, 0x20, 0x00, 0x10, 0x4c, 0xa1, 0x7e, 0xfb, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78,
+0x84, 0x20, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0x84, 0x20, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x15, 0x84, 0x21, 0xdd, 0x26,
+0x84, 0x00, 0xd5, 0x09, 0x92, 0x00, 0x84, 0xa7, 0x9c, 0x49, 0xd9, 0xfd, 0x9c, 0x01, 0x87, 0xca,
+0x4c, 0x0f, 0x00, 0x04, 0x84, 0x20, 0xd5, 0xf7, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xf2, 0x0c, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x0e, 0x70, 0x44, 0x10, 0x00, 0x11, 0x84, 0x00, 0xdd, 0x26, 0xf2, 0x0b, 0x44, 0x10, 0x00, 0x12,
+0x84, 0x00, 0xdd, 0x26, 0xf2, 0x0a, 0x44, 0x10, 0x00, 0x13, 0x84, 0x00, 0xdd, 0x26, 0xf2, 0x09,
+0x44, 0x10, 0x00, 0x14, 0x84, 0x00, 0xdd, 0x26, 0xf2, 0x08, 0x84, 0x24, 0x84, 0x00, 0xdd, 0x26,
+0xf2, 0x11, 0x44, 0x10, 0x00, 0x13, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x10, 0x44, 0x10, 0x00, 0x11,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0f, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0e,
+0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0d, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05,
+0xdd, 0x26, 0xf5, 0x07, 0x46, 0x40, 0x04, 0x10, 0x58, 0x42, 0x00, 0x80, 0xb6, 0xa4, 0x46, 0x30,
+0x04, 0x10, 0xf4, 0x06, 0x58, 0x31, 0x84, 0x00, 0xb6, 0x83, 0x46, 0x20, 0x04, 0x11, 0xf5, 0x05,
+0x58, 0x21, 0x02, 0x04, 0xb6, 0xa2, 0x46, 0x10, 0x04, 0x10, 0xf4, 0x03, 0x58, 0x10, 0x85, 0x04,
+0xb6, 0x81, 0x46, 0x00, 0x04, 0x10, 0xf3, 0x04, 0x58, 0x00, 0x05, 0x0c, 0xb6, 0x60, 0xec, 0x5c,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xc4, 0x46, 0x40,
+0x04, 0x11, 0x58, 0x42, 0x00, 0x04, 0xb4, 0xa4, 0x84, 0xc0, 0xf5, 0x81, 0x46, 0x20, 0x04, 0x10,
+0xb6, 0xc4, 0x44, 0x30, 0x18, 0x30, 0x58, 0x21, 0x05, 0x04, 0x05, 0xc1, 0x00, 0x00, 0x46, 0x00,
+0x04, 0x10, 0xb6, 0x62, 0x58, 0x00, 0x05, 0x0c, 0x44, 0x10, 0x20, 0x00, 0xb5, 0x40, 0xb6, 0x20,
+0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x0d, 0xb8, 0x50, 0x2f, 0x80, 0x34, 0x84, 0x24, 0x84, 0x05,
+0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8e, 0x70, 0xdd, 0x28, 0x84, 0x24, 0x44, 0x20, 0x00, 0x27,
+0x84, 0x05, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x30, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x28,
+0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x2c,
+0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0x83,
+0x84, 0x05, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x28, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x28,
+0x50, 0x2f, 0x80, 0x24, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x28, 0x80, 0x46, 0x44, 0x10,
+0x00, 0x13, 0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x14, 0x44, 0x20, 0x00, 0x20, 0x84, 0x05,
+0xdd, 0x27, 0x50, 0x2f, 0x80, 0x20, 0x80, 0x06, 0x84, 0x21, 0xdd, 0x28, 0x80, 0x46, 0x80, 0x06,
+0x84, 0x21, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x1c, 0x80, 0x06, 0x44, 0x10, 0x00, 0x22, 0xdd, 0x28,
+0x80, 0x06, 0x44, 0x10, 0x00, 0x22, 0x44, 0x20, 0x00, 0x13, 0xdd, 0x27, 0x50, 0x2f, 0x80, 0x18,
+0x80, 0x06, 0x44, 0x10, 0x00, 0x23, 0xdd, 0x28, 0x80, 0x46, 0x80, 0x06, 0x44, 0x10, 0x00, 0x23,
+0xdd, 0x27, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x8e, 0xf8, 0x50, 0x2f, 0x80, 0x14, 0x44, 0x10,
+0x00, 0x2f, 0x80, 0x06, 0x4b, 0xe0, 0x24, 0x01, 0x46, 0x80, 0x00, 0x06, 0x58, 0x84, 0x00, 0x78,
+0x84, 0x24, 0x44, 0x00, 0x00, 0x2f, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x16,
+0xdd, 0x28, 0x84, 0x01, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x74, 0xdd, 0x2f, 0x50, 0x2f,
+0x80, 0x10, 0x80, 0x06, 0x44, 0x10, 0x00, 0x31, 0x4b, 0xe0, 0x24, 0x01, 0x80, 0x26, 0x44, 0x00,
+0x00, 0x16, 0x04, 0x9f, 0x80, 0x04, 0xdd, 0x28, 0x80, 0x06, 0x44, 0x10, 0x00, 0x23, 0x84, 0x41,
+0xdd, 0x27, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x16, 0xdd, 0x28, 0xd5, 0x0b, 0x92, 0x00,
+0x87, 0xc7, 0x9c, 0x49, 0x4c, 0x1f, 0x7f, 0xfd, 0x9d, 0xb1, 0x44, 0x70, 0x00, 0x3c, 0x4c, 0x63,
+0x80, 0x04, 0x84, 0x20, 0xd5, 0xf5, 0x44, 0x10, 0x00, 0x31, 0x50, 0x2f, 0x80, 0x10, 0x84, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x20, 0x7f, 0x80, 0x10, 0x40, 0x54,
+0x80, 0x10, 0x9a, 0xfd, 0x44, 0x40, 0x03, 0xe8, 0x42, 0x01, 0x90, 0x24, 0x44, 0x20, 0x00, 0x2b,
+0x40, 0x00, 0x08, 0x36, 0x84, 0x2a, 0x40, 0x20, 0x04, 0xd6, 0xe4, 0xc5, 0xe9, 0x02, 0x8c, 0x0a,
+0x87, 0xca, 0x40, 0x20, 0x78, 0x16, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0x70, 0x84, 0x27,
+0x84, 0x00, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x78, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x16, 0xdd, 0x27, 0x84, 0x21, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x27, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x15, 0xdd, 0x27, 0xf2, 0x0d, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0c, 0x44, 0x10,
+0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x0b, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26,
+0xf2, 0x0a, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x09, 0x44, 0x10, 0x00, 0x14,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x08, 0x84, 0x21, 0x84, 0x00, 0xdd, 0x26, 0xf2, 0x07, 0x44, 0x10,
+0x00, 0x22, 0x84, 0x00, 0xdd, 0x26, 0xf2, 0x06, 0x44, 0x10, 0x00, 0x23, 0x84, 0x00, 0xdd, 0x26,
+0xf1, 0x05, 0x44, 0x00, 0x00, 0x2f, 0xdd, 0x27, 0xf3, 0x01, 0x46, 0x20, 0x04, 0x11, 0x46, 0x10,
+0x04, 0x10, 0x46, 0x00, 0x04, 0x10, 0x58, 0x21, 0x00, 0x04, 0x58, 0x10, 0x85, 0x04, 0x58, 0x00,
+0x05, 0x0c, 0xb6, 0x62, 0x15, 0xc0, 0x80, 0x00, 0xb7, 0x40, 0x84, 0x27, 0x50, 0x2f, 0x80, 0x0c,
+0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xec, 0x3c, 0x3a, 0x6f,
+0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc, 0xef, 0xf8, 0x84, 0x21, 0x96, 0x00, 0x50, 0x2f,
+0x80, 0x04, 0x46, 0x30, 0x00, 0x05, 0x58, 0x31, 0x8d, 0xb8, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x0e, 0x70, 0x4c, 0x00, 0xc0, 0x10, 0x84, 0x23, 0x84, 0x05, 0x4b, 0xe0, 0x0c, 0x01, 0xf2, 0x01,
+0x40, 0x31, 0x14, 0x09, 0x94, 0xdd, 0x58, 0x31, 0x80, 0x11, 0x84, 0x23, 0x80, 0x43, 0x84, 0x05,
+0xd5, 0x0e, 0x84, 0x23, 0x84, 0x05, 0x4b, 0xe0, 0x0c, 0x01, 0xf7, 0x01, 0x40, 0x53, 0x94, 0x09,
+0x95, 0x6d, 0x58, 0x32, 0x80, 0x08, 0x84, 0x05, 0x80, 0x43, 0x84, 0x23, 0xf3, 0x81, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x8e, 0xf8, 0x4b, 0xe0, 0x18, 0x01, 0x80, 0x5f, 0x44, 0x10, 0x00, 0x2f,
+0x84, 0x00, 0x4b, 0xe0, 0x1c, 0x01, 0xb4, 0x5f, 0x44, 0x0f, 0xff, 0x9f, 0x40, 0x31, 0x00, 0x02,
+0x58, 0x51, 0x80, 0x40, 0xb6, 0xbf, 0x80, 0x25, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78,
+0x44, 0x00, 0x00, 0x2f, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x20, 0x44, 0x00, 0x00, 0x3a, 0x4b, 0xe0,
+0x18, 0x01, 0x80, 0x5f, 0x44, 0x10, 0x00, 0x2f, 0x84, 0x00, 0x4b, 0xe0, 0x1c, 0x01, 0xb4, 0x9f,
+0x40, 0x22, 0x1c, 0x09, 0x94, 0x97, 0x58, 0x31, 0x00, 0x50, 0xb6, 0x7f, 0x80, 0x23, 0x44, 0x00,
+0x00, 0x2f, 0x81, 0x1f, 0x4b, 0xe0, 0x18, 0x01, 0xec, 0x08, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x84, 0x80, 0x84, 0x24, 0x40, 0x2f, 0x84, 0x00, 0x97, 0x80,
+0x80, 0x04, 0xf4, 0x81, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf0, 0x01,
+0x44, 0x3f, 0xff, 0xe7, 0x84, 0x41, 0x40, 0x10, 0x0c, 0x02, 0x4c, 0x61, 0x00, 0x06, 0xc6, 0x09,
+0x84, 0xa3, 0xde, 0x07, 0xd5, 0x04, 0x58, 0x10, 0x80, 0x10, 0xd5, 0x03, 0x58, 0x10, 0x80, 0x08,
+0x4c, 0x10, 0x00, 0x08, 0x84, 0x04, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0x84, 0x01, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xec, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x10, 0x00, 0x10, 0x81, 0x20,
+0x84, 0x04, 0xdd, 0x26, 0x44, 0x00, 0x00, 0xba, 0x84, 0x21, 0xdd, 0x26, 0x84, 0xe0, 0x80, 0x66,
+0x50, 0xaf, 0x80, 0x0c, 0x84, 0xc3, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce, 0x0e, 0xf8, 0xf3, 0x81,
+0x80, 0x26, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x23, 0x44, 0x10, 0x00, 0xbc, 0x84, 0x00, 0x80, 0x4a,
+0xdd, 0x3c, 0xf1, 0x03, 0x9d, 0xb4, 0x44, 0x50, 0x00, 0x2f, 0x99, 0xf9, 0x46, 0x80, 0x00, 0x06,
+0x58, 0x84, 0x00, 0x78, 0xf3, 0x01, 0xde, 0xec, 0x9e, 0x6c, 0x44, 0x00, 0x00, 0xbb, 0x4b, 0xe0,
+0x20, 0x01, 0x80, 0x4a, 0x44, 0x10, 0x00, 0xbc, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0xf8, 0xdd, 0x2f, 0xf6, 0x03, 0x84, 0x20, 0x84, 0x04, 0x4b, 0xe0, 0x20, 0x01, 0x44, 0x50,
+0x00, 0x37, 0x42, 0x33, 0x14, 0x24, 0x84, 0x96, 0x40, 0x21, 0x90, 0x36, 0x99, 0xfa, 0xe1, 0x27,
+0xe8, 0x03, 0x84, 0x00, 0xd5, 0x05, 0x5e, 0x73, 0xff, 0xf6, 0x56, 0x03, 0x80, 0x01, 0xec, 0x14,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x2c, 0x46, 0x40,
+0x00, 0x0a, 0x58, 0x42, 0x0f, 0xa8, 0xf0, 0x81, 0x3a, 0x02, 0x0c, 0x04, 0x50, 0x8f, 0x80, 0x80,
+0x84, 0xc0, 0x47, 0xc0, 0x04, 0x11, 0x3a, 0x04, 0x0c, 0x24, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73,
+0x80, 0x78, 0x80, 0x26, 0x44, 0x00, 0x00, 0xba, 0xb4, 0x64, 0x40, 0x91, 0xc0, 0x09, 0x12, 0x34,
+0x00, 0x00, 0x10, 0x9f, 0x80, 0x92, 0xf6, 0xb2, 0x81, 0x5c, 0x05, 0xee, 0x00, 0x01, 0x15, 0xef,
+0x80, 0x0f, 0x50, 0x8f, 0x80, 0xcc, 0xdd, 0x27, 0x80, 0x26, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x27,
+0x80, 0x26, 0x44, 0x00, 0x00, 0xbc, 0xdd, 0x27, 0x04, 0x55, 0x00, 0xca, 0x80, 0x26, 0xf5, 0x8e,
+0x44, 0x00, 0x00, 0x1b, 0xdd, 0x27, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x8e, 0xf8, 0x80, 0x48,
+0x44, 0x10, 0x00, 0x41, 0x80, 0x06, 0xdd, 0x29, 0xf4, 0x33, 0x80, 0x48, 0xf4, 0x8d, 0x44, 0x10,
+0x00, 0x42, 0x80, 0x06, 0xdd, 0x29, 0xf3, 0x33, 0x44, 0x10, 0x00, 0x8c, 0xf3, 0x8c, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x27, 0x80, 0x48, 0x44, 0x10, 0x00, 0x9f, 0x80, 0x06, 0xdd, 0x29, 0xf2, 0x33,
+0x84, 0x23, 0xf2, 0x8b, 0x44, 0x00, 0x00, 0x9e, 0x47, 0xc0, 0x04, 0x10, 0xdd, 0x27, 0x80, 0x48,
+0x44, 0x10, 0x00, 0x9f, 0x80, 0x06, 0xdd, 0x29, 0x04, 0xae, 0x01, 0x41, 0x46, 0x90, 0x04, 0x10,
+0x14, 0xaf, 0x80, 0x0a, 0x04, 0x84, 0x81, 0x43, 0x46, 0x58, 0x1f, 0xff, 0x58, 0x52, 0x8e, 0x7f,
+0x46, 0x30, 0xa0, 0x00, 0x46, 0x00, 0x80, 0x00, 0x40, 0x74, 0x14, 0x02, 0xf4, 0x33, 0x40, 0x13,
+0x8c, 0x04, 0x40, 0x23, 0x80, 0x04, 0x14, 0x8f, 0x80, 0x06, 0xf6, 0x83, 0xf7, 0x84, 0xf4, 0x89,
+0xf6, 0x85, 0xf6, 0x82, 0xf1, 0x87, 0xf2, 0x88, 0x44, 0x00, 0x00, 0x9f, 0x44, 0x10, 0x00, 0x60,
+0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0x46, 0x50, 0x04, 0x10, 0x04, 0xa2,
+0x81, 0x41, 0x47, 0xc0, 0x00, 0xc0, 0x59, 0xce, 0x00, 0x80, 0x40, 0x65, 0x70, 0x04, 0x14, 0x62,
+0x81, 0x41, 0xf0, 0x02, 0xc8, 0x13, 0x05, 0xef, 0x80, 0x01, 0x5e, 0xff, 0x01, 0x5f, 0xe9, 0x03,
+0xf3, 0x07, 0xd5, 0x1d, 0x04, 0x9f, 0x80, 0x01, 0x5e, 0xf4, 0xff, 0x06, 0xe8, 0x05, 0xf2, 0x04,
+0x42, 0x31, 0x68, 0x08, 0xd5, 0x14, 0xf3, 0x08, 0xd5, 0x12, 0xf3, 0x01, 0x5e, 0xf1, 0x81, 0x5f,
+0xe9, 0x07, 0xf4, 0x04, 0x46, 0x80, 0xc0, 0x00, 0x40, 0x32, 0x20, 0x04, 0xd5, 0x08, 0xf0, 0x01,
+0xf3, 0x08, 0xf7, 0x07, 0x5e, 0x10, 0x7f, 0x06, 0x40, 0x33, 0x84, 0x1a, 0x80, 0x85, 0x46, 0x20,
+0x04, 0x11, 0x51, 0xee, 0x7f, 0xa0, 0x14, 0x32, 0x01, 0x43, 0x15, 0xe1, 0x00, 0xca, 0x46, 0x90,
+0x00, 0x05, 0x58, 0x94, 0x8d, 0xb8, 0x84, 0x21, 0x50, 0x2f, 0x80, 0xc4, 0x84, 0x05, 0xdd, 0x29,
+0x84, 0x21, 0x50, 0x2f, 0x80, 0xc0, 0x84, 0x00, 0xdd, 0x29, 0x84, 0x20, 0x50, 0x2f, 0x80, 0xbc,
+0x84, 0x04, 0xdd, 0x29, 0x84, 0x2b, 0x50, 0x2f, 0x80, 0xb8, 0x84, 0x04, 0xdd, 0x29, 0x84, 0x2d,
+0x50, 0x2f, 0x80, 0xb4, 0x84, 0x04, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0xb0,
+0x84, 0x04, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0xac, 0x84, 0x04, 0xdd, 0x29,
+0x44, 0x10, 0x00, 0x16, 0x50, 0x2f, 0x80, 0xa8, 0x84, 0x04, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x11,
+0x50, 0x2f, 0x80, 0xa4, 0x84, 0x05, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f, 0x80, 0xa0,
+0x84, 0x05, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x9c, 0x84, 0x05, 0xdd, 0x29,
+0x44, 0x10, 0x00, 0x14, 0x50, 0x2f, 0x80, 0x98, 0x84, 0x05, 0xdd, 0x29, 0x84, 0x21, 0x47, 0xc0,
+0x00, 0x05, 0x59, 0xce, 0x0e, 0x70, 0x80, 0x41, 0x84, 0x05, 0xdd, 0x3c, 0x84, 0x21, 0x44, 0x20,
+0x00, 0xe1, 0x84, 0x00, 0xdd, 0x3c, 0x84, 0x20, 0x44, 0x20, 0x00, 0x83, 0x84, 0x04, 0xdd, 0x3c,
+0x84, 0x2b, 0x44, 0x20, 0x00, 0x51, 0x84, 0x04, 0xdd, 0x3c, 0x84, 0x2d, 0x44, 0x20, 0x00, 0x3c,
+0x84, 0x04, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0x24, 0x84, 0x04, 0xdd, 0x3c,
+0x44, 0x10, 0x00, 0x15, 0x9e, 0x8b, 0x84, 0x04, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x16, 0x44, 0x20,
+0x00, 0xa1, 0x84, 0x04, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05,
+0xdd, 0x3c, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xf1, 0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10,
+0x00, 0x13, 0x44, 0x20, 0x00, 0xa1, 0x84, 0x05, 0xdd, 0x3c, 0x84, 0x41, 0x44, 0x10, 0x00, 0x14,
+0x84, 0x05, 0xdd, 0x3c, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x10, 0x00, 0x10,
+0x9c, 0x0f, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x6d, 0xdd, 0x26, 0x46, 0xa0, 0x04, 0x11,
+0x84, 0x20, 0x44, 0x00, 0x00, 0x6e, 0xdd, 0x26, 0x84, 0xa8, 0x14, 0x55, 0x00, 0x01, 0x44, 0x10,
+0x00, 0x8c, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x40, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x1b, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x39, 0x44, 0x00,
+0x00, 0x41, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0x8c, 0xdd, 0x26, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x8e, 0xf8, 0x84, 0xc0, 0x84, 0x00, 0x44, 0x10, 0x00, 0x8c, 0x50, 0x2f,
+0x80, 0xcc, 0x4b, 0xe0, 0x1c, 0x01, 0xf3, 0x33, 0x9d, 0xb1, 0xc3, 0x05, 0x44, 0x80, 0x00, 0x64,
+0x4c, 0x64, 0x7f, 0xf4, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x84, 0x20, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x22, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26, 0x84, 0x2a, 0x44, 0x00,
+0x00, 0xbc, 0xdd, 0x26, 0x84, 0x23, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x41,
+0x44, 0x00, 0x00, 0xbc, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x00, 0x00, 0xf1, 0xdd, 0x26, 0x84, 0x20,
+0x44, 0x00, 0x00, 0xf2, 0xdd, 0x26, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8e, 0xf8, 0x84, 0x00,
+0x84, 0x24, 0x50, 0x2f, 0x80, 0xc8, 0x4b, 0xe0, 0x1c, 0x01, 0x81, 0x06, 0x85, 0x40, 0x85, 0x25,
+0x87, 0x88, 0x50, 0x7f, 0x80, 0x94, 0x84, 0x20, 0x44, 0x00, 0x00, 0x1b, 0xdd, 0x28, 0x50, 0x5f,
+0x80, 0x80, 0x38, 0x12, 0xa4, 0x00, 0x44, 0x00, 0x00, 0x42, 0xdd, 0x28, 0xf1, 0x32, 0x54, 0x00,
+0x80, 0x10, 0xc8, 0x05, 0x58, 0x10, 0x80, 0x10, 0x84, 0x04, 0xdd, 0x28, 0x44, 0x10, 0x00, 0x11,
+0x44, 0x00, 0x00, 0xf4, 0xdd, 0x28, 0x84, 0x21, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x28, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x15, 0xdd, 0x28, 0x84, 0x20, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x28, 0x84, 0x21,
+0x44, 0x00, 0x00, 0xbb, 0xdd, 0x28, 0xf1, 0x02, 0xc9, 0x06, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00,
+0x00, 0xbc, 0xd5, 0x05, 0x44, 0x00, 0x00, 0xbc, 0x44, 0x10, 0x00, 0x81, 0xdd, 0x28, 0x84, 0x01,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x8f, 0x74, 0xdd, 0x2f, 0x84, 0xc0, 0x50, 0x2f, 0x80, 0xcc,
+0x84, 0x00, 0x44, 0x10, 0x00, 0xbc, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f,
+0xf4, 0x33, 0x9d, 0xb1, 0x54, 0x22, 0x00, 0x80, 0xc2, 0x04, 0x44, 0x50, 0x00, 0x64, 0xde, 0xef,
+0xf1, 0x32, 0x84, 0x04, 0xdd, 0x28, 0x84, 0x20, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x28, 0x84, 0x21,
+0x44, 0x00, 0x00, 0x15, 0xdd, 0x28, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0xdd, 0x28, 0x84, 0x21,
+0x44, 0x00, 0x00, 0xba, 0xdd, 0x28, 0x44, 0x10, 0x00, 0xff, 0x44, 0x00, 0x00, 0xbb, 0xdd, 0x28,
+0x44, 0x10, 0x00, 0xbc, 0x84, 0x00, 0x80, 0x47, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8,
+0xdd, 0x2f, 0xf1, 0x25, 0x5c, 0xf0, 0x80, 0xb4, 0xe8, 0x05, 0x8d, 0x21, 0xe5, 0x33, 0xe9, 0x8c,
+0xd5, 0x1f, 0x5c, 0xf0, 0x80, 0xf6, 0xe9, 0x05, 0x8f, 0x21, 0x4e, 0x94, 0xff, 0x86, 0xd5, 0x18,
+0x84, 0x05, 0x40, 0x25, 0x00, 0xd6, 0x84, 0xa4, 0xde, 0x03, 0x51, 0xce, 0x00, 0x0a, 0x84, 0xa5,
+0x4c, 0xa2, 0x80, 0x0f, 0x80, 0x1c, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x89, 0x8c, 0xdd, 0x2f,
+0x84, 0xa1, 0xd8, 0x03, 0x85, 0x00, 0xd5, 0x05, 0x8d, 0x41, 0x48, 0xff, 0xff, 0x6e, 0x85, 0x01,
+0xf3, 0x32, 0x54, 0x71, 0x80, 0x10, 0xcf, 0x09, 0x58, 0x11, 0x80, 0x10, 0x84, 0x04, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78,
+0x84, 0x24, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26,
+0x84, 0x2f, 0x44, 0x00, 0x00, 0xbd, 0xdd, 0x26, 0x84, 0x25, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26,
+0x84, 0x25, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x2f, 0x44, 0x00, 0x00, 0xbd, 0xdd, 0x26,
+0x84, 0x26, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x26, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26,
+0x84, 0x2f, 0x44, 0x00, 0x00, 0xbd, 0xdd, 0x26, 0x84, 0x27, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26,
+0x84, 0x27, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x44, 0x00, 0x00, 0xbd, 0x84, 0x2f, 0xdd, 0x26,
+0xf2, 0x02, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8e, 0xf8, 0xca, 0x30, 0x84, 0x22, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x84, 0x22, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0xf0, 0x02, 0x50, 0x2f,
+0x80, 0xcc, 0x44, 0x10, 0x00, 0xbd, 0x4b, 0xe0, 0x1c, 0x01, 0xf3, 0x33, 0xf4, 0x01, 0x40, 0x21,
+0x98, 0x09, 0x94, 0x96, 0x5e, 0xf2, 0x01, 0x5f, 0xe9, 0x04, 0x58, 0x21, 0x00, 0x14, 0xd5, 0x0b,
+0x05, 0xef, 0x80, 0x01, 0x5e, 0xff, 0x7f, 0x06, 0xe8, 0x04, 0x58, 0x21, 0x00, 0x08, 0xd5, 0x03,
+0x58, 0x21, 0x00, 0x10, 0xf2, 0xb3, 0x84, 0x22, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78,
+0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x22, 0xd5, 0x2e, 0x84, 0x23, 0x44, 0x00, 0x00, 0xba,
+0xdd, 0x26, 0x84, 0x23, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x44, 0x10, 0x00, 0xbd, 0x50, 0x2f,
+0x80, 0xcc, 0x84, 0x00, 0x4b, 0xe0, 0x1c, 0x01, 0xf5, 0x33, 0xf0, 0x01, 0x40, 0x22, 0x98, 0x09,
+0x94, 0x96, 0x5e, 0xf0, 0x01, 0x5f, 0xe9, 0x04, 0x58, 0x21, 0x00, 0x18, 0xd5, 0x0a, 0xf7, 0x01,
+0x5e, 0xf3, 0xff, 0x06, 0xe8, 0x04, 0x58, 0x21, 0x00, 0x10, 0xd5, 0x03, 0x58, 0x21, 0x00, 0x14,
+0xf2, 0xb3, 0x84, 0x23, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x00, 0x00, 0xba,
+0xdd, 0x26, 0x84, 0x23, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0xf1, 0x33, 0x44, 0x00, 0x00, 0xbd,
+0xdd, 0x26, 0x84, 0xa1, 0x4c, 0x82, 0xc0, 0x27, 0xf4, 0x02, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63,
+0x00, 0x78, 0xcc, 0x11, 0x84, 0x22, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x22, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x44, 0x00, 0x00, 0xbd, 0x84, 0x2f, 0xdd, 0x26, 0x14, 0x8f, 0x80, 0x05,
+0x48, 0x00, 0x00, 0x90, 0x84, 0x23, 0x44, 0x00, 0x00, 0xba, 0xdd, 0x26, 0x84, 0x23, 0x44, 0x00,
+0x00, 0xba, 0xdd, 0x26, 0x44, 0x00, 0x00, 0xbd, 0x84, 0x2f, 0xdd, 0x26, 0x14, 0x8f, 0x80, 0x03,
+0xd5, 0x03, 0xf3, 0x02, 0xc3, 0x7e, 0xf7, 0x05, 0x84, 0xa1, 0xdf, 0x03, 0xf5, 0x03, 0xd7, 0x79,
+0x46, 0xa0, 0x00, 0x0a, 0x58, 0xa5, 0x0f, 0x68, 0x81, 0x0a, 0x3a, 0x04, 0x0c, 0x04, 0x50, 0x9f,
+0x80, 0x40, 0x85, 0x40, 0x47, 0xc0, 0x00, 0x06, 0x59, 0xce, 0x00, 0x78, 0x3a, 0x04, 0x8c, 0x24,
+0x3a, 0x04, 0x0c, 0x04, 0x3a, 0x04, 0x8c, 0x24, 0x3a, 0x04, 0x0c, 0x04, 0x3a, 0x04, 0x8c, 0x24,
+0x3a, 0x04, 0x0c, 0x00, 0x3a, 0x04, 0x8c, 0x20, 0x44, 0x00, 0x00, 0xba, 0x50, 0x15, 0x00, 0x02,
+0xdd, 0x3c, 0x50, 0x7f, 0x80, 0x40, 0x84, 0xc3, 0x85, 0x0a, 0x80, 0x26, 0x44, 0x00, 0x00, 0xbb,
+0xdd, 0x3c, 0x44, 0x10, 0x00, 0xbc, 0x50, 0x2f, 0x80, 0xcc, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf0, 0x33, 0x50, 0x00, 0x7f, 0x80, 0x4e, 0x06, 0x00, 0x05,
+0x44, 0x10, 0x00, 0x80, 0xd5, 0x08, 0xa6, 0xb8, 0x42, 0x10, 0x08, 0x24, 0x40, 0x40, 0xa0, 0x56,
+0x50, 0x12, 0x00, 0x80, 0x44, 0x00, 0x00, 0xbc, 0xdd, 0x3c, 0x9d, 0xb4, 0x44, 0x50, 0x01, 0x03,
+0x9d, 0xf9, 0x46, 0x90, 0x00, 0x06, 0x58, 0x94, 0x80, 0x78, 0xde, 0xd8, 0x8d, 0x41, 0x84, 0xa2,
+0x4c, 0xa2, 0xff, 0xcc, 0x84, 0x20, 0x44, 0x00, 0x00, 0xba, 0x4b, 0xe0, 0x24, 0x01, 0x44, 0x00,
+0x00, 0xbb, 0x84, 0x24, 0x4b, 0xe0, 0x24, 0x01, 0xf6, 0x01, 0x5e, 0xf3, 0x7f, 0x06, 0xe8, 0x05,
+0x84, 0x2e, 0x44, 0x00, 0x00, 0xbc, 0xd5, 0x05, 0x44, 0x00, 0x00, 0xbc, 0x44, 0x10, 0x00, 0x1c,
+0x4b, 0xe0, 0x24, 0x01, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x78, 0x84, 0x20, 0x44, 0x00,
+0x00, 0xbb, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x00, 0x00, 0xbc, 0x9c, 0x44, 0x4b, 0xe0, 0x1c, 0x01,
+0xf6, 0x0e, 0x47, 0xe0, 0x04, 0x11, 0x14, 0x6f, 0x00, 0xca, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73,
+0x80, 0x78, 0xf1, 0x32, 0x84, 0x04, 0xdd, 0x27, 0x84, 0x20, 0x44, 0x00, 0x00, 0x1b, 0xdd, 0x27,
+0xf1, 0x0d, 0x44, 0x00, 0x00, 0x41, 0xdd, 0x27, 0xf1, 0x0c, 0x44, 0x00, 0x00, 0x42, 0xdd, 0x27,
+0x44, 0x10, 0x00, 0x8c, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x27, 0xf1, 0x0b, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x27, 0xf2, 0x31, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0x70, 0x84, 0x21, 0x84, 0x05,
+0xdd, 0x26, 0xf2, 0x30, 0x84, 0x21, 0x84, 0x00, 0xdd, 0x26, 0xf2, 0x2f, 0x84, 0x20, 0x84, 0x04,
+0xdd, 0x26, 0xf2, 0x2e, 0x84, 0x2b, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x2d, 0x84, 0x2d, 0x84, 0x04,
+0xdd, 0x26, 0xf2, 0x2c, 0x44, 0x10, 0x00, 0x13, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x2b, 0x44, 0x10,
+0x00, 0x15, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x2a, 0x44, 0x10, 0x00, 0x16, 0x84, 0x04, 0xdd, 0x26,
+0xf2, 0x29, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x28, 0x44, 0x10, 0x00, 0x12,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x27, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x26,
+0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26, 0xf3, 0x0f, 0x46, 0x20, 0x04, 0x11, 0xa8, 0xd1,
+0x84, 0x23, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x27, 0xf1, 0x09, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27,
+0xf4, 0x0a, 0x46, 0x10, 0x04, 0x10, 0x14, 0x40, 0x81, 0x41, 0x80, 0xa1, 0xf0, 0x06, 0x14, 0x02,
+0x81, 0x43, 0xf7, 0x02, 0xcf, 0x06, 0x87, 0x81, 0x15, 0xcf, 0x80, 0x02, 0x48, 0xff, 0xfc, 0x66,
+0xec, 0xd4, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x8c, 0x96, 0x48,
+0x97, 0xd0, 0x54, 0xa0, 0x00, 0xff, 0xf1, 0x83, 0x4e, 0x73, 0x05, 0x5a, 0x84, 0x24, 0x50, 0x2f,
+0x80, 0x40, 0x80, 0x07, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0d, 0xb8, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x64, 0x84, 0x05, 0xdd, 0x26,
+0x84, 0x24, 0x50, 0x2f, 0x80, 0x60, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0x80, 0x20, 0x50, 0x2f,
+0x80, 0x5c, 0xdd, 0x26, 0x80, 0x27, 0x50, 0x2f, 0x80, 0x58, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x26,
+0x50, 0x2f, 0x80, 0x54, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0x84, 0x27, 0x50, 0x2f, 0x80, 0x50,
+0xdd, 0x26, 0x81, 0x26, 0x44, 0x80, 0x00, 0x25, 0x50, 0x6f, 0x80, 0x18, 0x80, 0x28, 0x80, 0x46,
+0x84, 0x05, 0xdd, 0x29, 0x8d, 0x01, 0x44, 0x00, 0x00, 0x2f, 0x9d, 0xb4, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x8d, 0xb8, 0x4c, 0x80, 0x7f, 0xf4, 0x44, 0x10, 0x00, 0x3a, 0x50, 0x2f, 0x80, 0x48,
+0x84, 0x05, 0xdd, 0x27, 0x44, 0x10, 0x00, 0x3b, 0x50, 0x2f, 0x80, 0x44, 0x84, 0x05, 0xdd, 0x27,
+0x50, 0x9f, 0x80, 0x6c, 0x44, 0x10, 0x00, 0x17, 0x50, 0x2f, 0x80, 0x4c, 0x84, 0x00, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x84, 0x20, 0x80, 0x49, 0x84, 0x05, 0xdd, 0x27,
+0xf4, 0x1b, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x0e, 0x70, 0x58, 0x22, 0x00, 0x03, 0x84, 0x20,
+0x84, 0x05, 0x4b, 0xe0, 0x20, 0x01, 0x84, 0x21, 0x80, 0x49, 0x84, 0x05, 0xdd, 0x27, 0xf3, 0x1b,
+0x84, 0x05, 0x58, 0x21, 0x80, 0x01, 0x84, 0x21, 0x4b, 0xe0, 0x20, 0x01, 0x84, 0xc0, 0x81, 0x09,
+0x84, 0x00, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0x47, 0x9c, 0x49, 0x4c, 0x11, 0x7f, 0xfd, 0x9c, 0x01,
+0x44, 0x50, 0x00, 0x64, 0xd0, 0x03, 0x84, 0x20, 0xd5, 0xf6, 0x84, 0x21, 0x84, 0x05, 0x80, 0x48,
+0xdd, 0x27, 0xf1, 0x1b, 0x9d, 0xb1, 0x96, 0x0c, 0x45, 0xc0, 0x00, 0x28, 0xf0, 0x9b, 0x4c, 0x6e,
+0x00, 0x03, 0xc8, 0xe7, 0x51, 0xef, 0x80, 0x6c, 0x80, 0x5e, 0x84, 0x20, 0x84, 0x05, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf0, 0x1b, 0x85, 0x1c, 0x40, 0x60, 0x20, 0x02,
+0x58, 0x23, 0x00, 0x01, 0x84, 0x20, 0x50, 0x7f, 0x80, 0x68, 0x84, 0x05, 0xf6, 0x9b, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0x80, 0x47, 0x44, 0x10, 0x00, 0x17, 0x84, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf5, 0x1a, 0x45, 0xcf, 0xff, 0xe0,
+0x40, 0x92, 0xf0, 0x02, 0x58, 0x14, 0x80, 0x10, 0x44, 0x00, 0x00, 0x17, 0x14, 0x9f, 0x80, 0x1a,
+0x85, 0x09, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0x44, 0x30, 0x00, 0x31,
+0x84, 0x82, 0x44, 0x00, 0x00, 0x27, 0x40, 0x64, 0x28, 0x1b, 0x40, 0x60, 0x28, 0x1a, 0x40, 0x22,
+0x28, 0x1b, 0x40, 0x21, 0xa8, 0x1a, 0x85, 0x20, 0xf2, 0x84, 0xf6, 0x85, 0x81, 0x09, 0x83, 0x89,
+0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8d, 0xb8, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0x70,
+0x4e, 0x93, 0x00, 0x56, 0x84, 0x28, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01,
+0xf3, 0x1b, 0x84, 0x28, 0x54, 0x21, 0x80, 0xfb, 0x84, 0x05, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10,
+0x00, 0x15, 0x50, 0x2f, 0x80, 0x68, 0x80, 0x09, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8,
+0xdd, 0x2f, 0xf2, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x58, 0x11, 0x00, 0x01, 0x46, 0xf0, 0x00, 0x06,
+0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xf1, 0x05, 0xf1, 0x82, 0x80, 0x29, 0xd5, 0x09, 0x92, 0x00,
+0x84, 0x87, 0x9c, 0x01, 0x4c, 0x02, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0xaa, 0xd1, 0x03, 0x84, 0x00,
+0xd5, 0xf7, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0xf8, 0xdd, 0x2f, 0xf7, 0x1a, 0x84, 0x04, 0x54, 0x13, 0x80, 0xe7, 0x46, 0xf0, 0x00, 0x06,
+0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01,
+0x4c, 0x03, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6,
+0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0xd5, 0x58, 0x84, 0x28, 0x50, 0x2f,
+0x80, 0x6c, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0xf3, 0x1b, 0x84, 0x28, 0x58, 0x21, 0x80, 0x04,
+0x84, 0x05, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf2, 0x1a, 0x44, 0x00, 0x00, 0x15,
+0x58, 0x11, 0x00, 0x01, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xf1, 0x04,
+0xf1, 0x82, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd,
+0x9c, 0x49, 0x84, 0x8a, 0x4c, 0x12, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x84, 0x24, 0x50, 0x2f,
+0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf7, 0x1a,
+0x84, 0x04, 0x54, 0x53, 0x80, 0xe7, 0x58, 0x12, 0x80, 0x10, 0xf5, 0x9a, 0x46, 0xf0, 0x00, 0x06,
+0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01,
+0x4c, 0x03, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6,
+0x44, 0x10, 0x00, 0x15, 0x84, 0x00, 0x50, 0x2f, 0x80, 0x68, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0xf8, 0xdd, 0x2f, 0xf1, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x54, 0x10, 0x80, 0xfe, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8d, 0xb8,
+0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0x70, 0x4e, 0xa2, 0x00, 0x7a, 0x46, 0x20, 0x04, 0x10,
+0x47, 0xe0, 0x04, 0x10, 0x59, 0xef, 0x05, 0x04, 0x44, 0x30, 0x00, 0x10, 0x58, 0x21, 0x05, 0x0c,
+0x44, 0x10, 0x00, 0x18, 0xb6, 0x62, 0xb6, 0x3e, 0x50, 0x2f, 0x80, 0x6c, 0x44, 0x10, 0x00, 0x11,
+0x84, 0x05, 0xdd, 0x27, 0x05, 0xcf, 0x80, 0x1b, 0x44, 0x10, 0x00, 0x11, 0x58, 0x2e, 0x00, 0x80,
+0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xc1, 0x84, 0x05, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0x20, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x14,
+0x84, 0x42, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27,
+0xf0, 0x1b, 0x44, 0x5f, 0xff, 0xc0, 0x40, 0x40, 0x14, 0x02, 0xf4, 0x9b, 0x58, 0x22, 0x00, 0x3f,
+0x84, 0x23, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27,
+0xf2, 0x1b, 0x44, 0x3f, 0xff, 0xc0, 0x41, 0xc1, 0x0c, 0x02, 0x15, 0xcf, 0x80, 0x1b, 0x58, 0x2e,
+0x00, 0x3f, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0x80, 0x20, 0x44, 0x20, 0x00, 0x31,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x3a, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27, 0xf0, 0x1b,
+0x44, 0x5f, 0xff, 0x80, 0x40, 0x40, 0x14, 0x02, 0xf4, 0x9b, 0x80, 0x44, 0x44, 0x10, 0x00, 0x3a,
+0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x3b, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27,
+0xf2, 0x1b, 0x44, 0x3f, 0xff, 0x80, 0x41, 0xc1, 0x0c, 0x02, 0x15, 0xcf, 0x80, 0x1b, 0x80, 0x5c,
+0x84, 0x05, 0x44, 0x10, 0x00, 0x3b, 0xdd, 0x26, 0x87, 0x80, 0xd5, 0x6c, 0x46, 0x10, 0x04, 0x10,
+0x47, 0xe0, 0x04, 0x10, 0x59, 0xef, 0x05, 0x04, 0x84, 0x88, 0x44, 0x80, 0x00, 0x18, 0x58, 0x10,
+0x85, 0x0c, 0xb6, 0x81, 0xb7, 0x1e, 0x44, 0x10, 0x00, 0x11, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05,
+0xdd, 0x27, 0xf3, 0x1b, 0x44, 0x10, 0x00, 0x11, 0x58, 0x21, 0x80, 0x80, 0x84, 0x05, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xf1, 0x84, 0x05, 0xdd, 0x26, 0x80, 0x48, 0x44, 0x10,
+0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x14, 0x44, 0x20, 0x00, 0xc2, 0x84, 0x05,
+0xdd, 0x26, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27, 0xf2, 0x1b, 0x44, 0x0f,
+0xff, 0xc0, 0x40, 0x51, 0x00, 0x02, 0xf5, 0x9b, 0x58, 0x22, 0x80, 0x34, 0x84, 0x23, 0x84, 0x05,
+0xdd, 0x26, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27, 0xf4, 0x1b, 0x44, 0x8f,
+0xff, 0xc0, 0x40, 0x32, 0x20, 0x02, 0xf3, 0x9b, 0x58, 0x21, 0x80, 0x34, 0x84, 0x24, 0x84, 0x05,
+0xdd, 0x26, 0x84, 0x26, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27, 0xf2, 0x1b, 0x44, 0x0f,
+0xff, 0x80, 0x40, 0x51, 0x00, 0x02, 0xf5, 0x9b, 0x80, 0x45, 0x84, 0x26, 0x84, 0x05, 0xdd, 0x26,
+0x84, 0x27, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0xdd, 0x27, 0xf7, 0x1b, 0x44, 0x4f, 0xff, 0x80,
+0x40, 0x83, 0x90, 0x02, 0x14, 0x8f, 0x80, 0x1b, 0x80, 0x48, 0x84, 0x05, 0x84, 0x27, 0xdd, 0x26,
+0x81, 0x0a, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01, 0x4c, 0x03, 0x7f, 0xfd,
+0x9c, 0x49, 0x84, 0xea, 0x4c, 0x13, 0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x46, 0x60, 0x00, 0x06,
+0x58, 0x63, 0x00, 0x78, 0x84, 0x22, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x70,
+0x00, 0x05, 0x58, 0x73, 0x8e, 0xf8, 0x50, 0x2f, 0x80, 0x68, 0x44, 0x10, 0x00, 0x9f, 0x84, 0x00,
+0x4b, 0xe0, 0x1c, 0x01, 0xf3, 0x1a, 0x84, 0x59, 0x40, 0x11, 0x88, 0x02, 0x44, 0x00, 0x00, 0x9f,
+0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x4b, 0xe0,
+0x1c, 0x01, 0xf5, 0x1a, 0x44, 0x00, 0x00, 0x15, 0x58, 0x12, 0x80, 0x01, 0x4b, 0xe0, 0x18, 0x01,
+0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd, 0x9c, 0x49,
+0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f,
+0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf1, 0x1a,
+0x44, 0x00, 0x00, 0x15, 0x54, 0x10, 0x80, 0xfe, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78,
+0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0x87, 0x9c, 0x01, 0x4c, 0x02, 0x7f, 0xfd,
+0x9c, 0x49, 0x84, 0xca, 0x4c, 0x13, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x46, 0x70, 0x00, 0x06,
+0x58, 0x73, 0x80, 0x78, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x00,
+0x00, 0x9f, 0x44, 0x10, 0x00, 0x82, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0xc0, 0x46, 0x70, 0x00, 0x05,
+0x58, 0x73, 0x8e, 0xf8, 0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0xa7, 0x9c, 0x01, 0xd8, 0xfd,
+0x9c, 0x49, 0x44, 0x30, 0x00, 0x64, 0x4c, 0x11, 0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x50, 0x2f,
+0x80, 0x68, 0x84, 0x00, 0x44, 0x10, 0x00, 0x9f, 0x4b, 0xe0, 0x1c, 0x01, 0xf2, 0x1a, 0x84, 0x02,
+0x4c, 0x20, 0x00, 0x08, 0x45, 0xe0, 0x00, 0x14, 0x4c, 0x6f, 0x00, 0x04, 0x9d, 0xb1, 0xd5, 0xe3,
+0x44, 0x10, 0x00, 0x39, 0x44, 0x00, 0x00, 0x9e, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78,
+0xdd, 0x2f, 0x44, 0x10, 0x00, 0x9f, 0x84, 0x00, 0x50, 0x2f, 0x80, 0x68, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x00, 0x1f, 0x80, 0x68, 0x54, 0x10, 0x80, 0x7f, 0xf1, 0x81,
+0x5e, 0xf0, 0x80, 0x40, 0xe9, 0x06, 0x44, 0x6f, 0xff, 0x80, 0x40, 0x40, 0x98, 0x04, 0xf4, 0x81,
+0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x78, 0x84, 0x22, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0,
+0x1c, 0x01, 0x46, 0x30, 0x00, 0x05, 0x58, 0x31, 0x8e, 0xf8, 0x44, 0x10, 0x00, 0x9f, 0x50, 0x2f,
+0x80, 0x68, 0x84, 0x00, 0x4b, 0xe0, 0x0c, 0x01, 0xf5, 0x1a, 0x44, 0x00, 0x00, 0x9f, 0x58, 0x12,
+0x80, 0x06, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8e, 0x70, 0x4e, 0xa2,
+0x00, 0x2a, 0x50, 0x2f, 0x80, 0x6c, 0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf0, 0x1b, 0x44, 0x10, 0x00, 0x3a, 0x54, 0x40, 0x00, 0x80,
+0xf4, 0x9b, 0x40, 0x2e, 0x10, 0x00, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0x50, 0x2f, 0x80, 0x6c,
+0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f,
+0xf2, 0x1b, 0x44, 0x10, 0x00, 0x3b, 0x54, 0x31, 0x00, 0x80, 0x40, 0x2e, 0x0c, 0x00, 0x84, 0x00,
+0xd5, 0x24, 0x84, 0x26, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8d, 0xb8, 0xdd, 0x2f, 0xf5, 0x1b, 0x84, 0x26, 0x54, 0x62, 0x80, 0x80, 0xf6, 0x9b, 0x40, 0x24,
+0x18, 0x00, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x27, 0x50, 0x2f, 0x80, 0x6c, 0x84, 0x05,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf1, 0x1b, 0x84, 0x05, 0x54, 0x30,
+0x80, 0x80, 0x40, 0x24, 0x0c, 0x00, 0x84, 0x27, 0xf3, 0x9b, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x20,
+0xd5, 0x0a, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd, 0x9c, 0x49, 0x84, 0x6a,
+0x4c, 0x11, 0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x68,
+0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf2, 0x1a, 0x44, 0x00,
+0x00, 0x15, 0x58, 0x11, 0x00, 0x01, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0x87, 0x9c, 0x01, 0x4c, 0x02, 0x7f, 0xfd, 0x9c, 0x49,
+0x84, 0x0a, 0x4c, 0x10, 0x00, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f,
+0x80, 0x68, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf1, 0x1a,
+0x44, 0x00, 0x00, 0x15, 0x54, 0x10, 0x80, 0xfe, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78,
+0xdd, 0x2f, 0x84, 0x20, 0xd5, 0x09, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01, 0x4c, 0x03, 0x7f, 0xfd,
+0x9c, 0x49, 0x84, 0xaa, 0xd1, 0x03, 0x84, 0x00, 0xd5, 0xf7, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63,
+0x00, 0x78, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x00, 0x00, 0x9f,
+0x44, 0x10, 0x00, 0x82, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0xc0, 0x84, 0x20, 0xd5, 0x0b, 0x92, 0x00,
+0x87, 0xc7, 0x9c, 0x01, 0x4c, 0x0f, 0x7f, 0xfd, 0x9c, 0x49, 0x44, 0x30, 0x00, 0x64, 0x4c, 0x11,
+0x80, 0x04, 0x84, 0x00, 0xd5, 0xf5, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x00, 0x44, 0x10, 0x00, 0x9f,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf2, 0x1a, 0x84, 0x82, 0x4c, 0x22,
+0x00, 0x08, 0x44, 0x00, 0x00, 0x14, 0x4c, 0x60, 0x00, 0x04, 0x9d, 0xb1, 0xd5, 0xdf, 0x44, 0x10,
+0x00, 0x39, 0x44, 0x00, 0x00, 0x9e, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0x44, 0x10, 0x00, 0x9f, 0x84, 0x00, 0x50, 0x2f, 0x80, 0x68, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0xf8, 0xdd, 0x2f, 0x00, 0x1f, 0x80, 0x68, 0x54, 0x10, 0x80, 0x7f, 0x5e, 0xf0, 0x80, 0x40,
+0xe9, 0x05, 0x44, 0x5f, 0xff, 0x80, 0x40, 0x10, 0x94, 0x04, 0x05, 0xef, 0x80, 0x01, 0xf6, 0x02,
+0x40, 0x1f, 0x04, 0x01, 0x40, 0x2e, 0x28, 0x1b, 0x40, 0x24, 0x28, 0x1a, 0xe0, 0xc1, 0xe8, 0x22,
+0xca, 0x2d, 0x4e, 0x93, 0x00, 0x12, 0x4e, 0xa2, 0x00, 0x09, 0x46, 0x70, 0x00, 0x0d, 0x58, 0x73,
+0x8e, 0x1d, 0x10, 0x93, 0x80, 0x00, 0xd5, 0x4e, 0x46, 0x90, 0x00, 0x0d, 0x58, 0x94, 0x8e, 0x1c,
+0x10, 0xa4, 0x80, 0x00, 0xd5, 0x47, 0x4e, 0xa2, 0x00, 0x07, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10,
+0x8e, 0x1f, 0xd5, 0x4a, 0x46, 0x30, 0x00, 0x0d, 0x58, 0x31, 0x8e, 0x1e, 0x10, 0xa1, 0x80, 0x00,
+0xd5, 0x4b, 0x5e, 0xf1, 0x00, 0x3f, 0xe8, 0x0a, 0x4e, 0xa2, 0x00, 0x06, 0x51, 0xce, 0x00, 0x01,
+0x48, 0xff, 0xfe, 0xdf, 0x8d, 0x01, 0x48, 0xff, 0xfe, 0xdc, 0xf4, 0x02, 0xe0, 0x24, 0xe8, 0x19,
+0x44, 0x00, 0x00, 0x3f, 0x4c, 0x20, 0x40, 0x16, 0x4e, 0x93, 0x00, 0x0b, 0x4e, 0xa2, 0x00, 0x1d,
+0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8e, 0x1d, 0x11, 0xc0, 0x80, 0x00, 0xd5, 0x1b, 0x4e, 0xa2,
+0x00, 0x26, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8e, 0x1f, 0x11, 0xc2, 0x80, 0x00, 0xd5, 0x24,
+0x4e, 0x93, 0x00, 0x14, 0x4e, 0xa2, 0x00, 0x09, 0x47, 0xe0, 0x00, 0x0d, 0x59, 0xef, 0x0e, 0x1d,
+0x11, 0xcf, 0x00, 0x00, 0xd5, 0x07, 0x46, 0x90, 0x00, 0x0d, 0x58, 0x94, 0x8e, 0x1c, 0x10, 0x84,
+0x80, 0x00, 0x85, 0x21, 0x48, 0xff, 0xfc, 0x26, 0x4e, 0xa2, 0x00, 0x09, 0x46, 0x10, 0x00, 0x0d,
+0x58, 0x10, 0x8e, 0x1f, 0x80, 0x5c, 0xae, 0x88, 0xd5, 0x07, 0x46, 0x30, 0x00, 0x0d, 0x58, 0x31,
+0x8e, 0x1e, 0x10, 0x81, 0x80, 0x00, 0x8d, 0x21, 0x84, 0x82, 0x4c, 0x92, 0x7c, 0x13, 0x46, 0x20,
+0x04, 0x10, 0x46, 0x10, 0x04, 0x10, 0x85, 0x00, 0x58, 0x21, 0x05, 0x0c, 0x58, 0x10, 0x85, 0x04,
+0xb7, 0x02, 0xb7, 0x01, 0x50, 0x2f, 0x80, 0x6c, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0x46, 0xf0,
+0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf0, 0x1b, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63,
+0x0e, 0x70, 0x54, 0x20, 0x00, 0x7f, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x12, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x13, 0x80, 0x48, 0x84, 0x05,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x14, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x19, 0x84, 0x23,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x18, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0xf2, 0x17,
+0x80, 0x20, 0xdd, 0x26, 0xf2, 0x16, 0x80, 0x28, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x15, 0x84, 0x26,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x14, 0x84, 0x05, 0x84, 0x27, 0xdd, 0x26, 0x50, 0x9f, 0x80, 0x18,
+0x44, 0x70, 0x00, 0x25, 0x0c, 0x24, 0x80, 0x01, 0x80, 0x27, 0x84, 0x05, 0xdd, 0x26, 0x9d, 0xf9,
+0x44, 0x50, 0x00, 0x2f, 0x46, 0x80, 0x00, 0x05, 0x58, 0x84, 0x0e, 0x70, 0xdf, 0xf4, 0xf2, 0x12,
+0x44, 0x10, 0x00, 0x3a, 0x84, 0x05, 0x4b, 0xe0, 0x20, 0x01, 0xf2, 0x11, 0x44, 0x10, 0x00, 0x3b,
+0x84, 0x05, 0x4b, 0xe0, 0x20, 0x01, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x50, 0x8f,
+0x80, 0x68, 0x84, 0x22, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94,
+0x8e, 0xf8, 0x80, 0x48, 0x44, 0x10, 0x00, 0x9f, 0x84, 0x00, 0x4b, 0xe0, 0x24, 0x01, 0xf3, 0x1a,
+0x44, 0x00, 0x00, 0x9f, 0x54, 0x11, 0x80, 0xf9, 0xdd, 0x26, 0x80, 0x48, 0x84, 0x24, 0x84, 0x00,
+0x4b, 0xe0, 0x24, 0x01, 0xf7, 0x1a, 0x84, 0x04, 0x54, 0x13, 0x80, 0xf3, 0xdd, 0x26, 0xf1, 0x13,
+0x44, 0x00, 0x00, 0x17, 0xdd, 0x26, 0xf1, 0x10, 0x84, 0x04, 0xdd, 0x26, 0x05, 0xef, 0x80, 0x03,
+0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8d, 0xb8, 0x50, 0x8f, 0x80, 0x6c, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x0e, 0x70, 0x4f, 0xe3, 0x00, 0x4c, 0x80, 0x48, 0x84, 0x26, 0x84, 0x05, 0xdd, 0x27,
+0xf4, 0x1b, 0x46, 0x90, 0x00, 0x0d, 0x58, 0x94, 0x8e, 0x1c, 0x54, 0x52, 0x00, 0xc0, 0x00, 0x14,
+0x80, 0x00, 0xf5, 0x9b, 0x98, 0x8d, 0x84, 0x05, 0x84, 0x26, 0xdd, 0x26, 0x80, 0x48, 0x84, 0x27,
+0x84, 0x05, 0xdd, 0x27, 0xf3, 0x1b, 0x00, 0x04, 0x80, 0x00, 0x54, 0x91, 0x80, 0xc0, 0x14, 0x9f,
+0x80, 0x1b, 0x40, 0x20, 0x24, 0x00, 0x84, 0x27, 0x84, 0x05, 0xdd, 0x26, 0x80, 0x48, 0x44, 0x10,
+0x00, 0x3a, 0x84, 0x05, 0xdd, 0x27, 0xf2, 0x1b, 0x46, 0x90, 0x00, 0x0d, 0x58, 0x94, 0x8e, 0x1d,
+0x54, 0x51, 0x00, 0xc0, 0x00, 0x44, 0x80, 0x00, 0xf5, 0x9b, 0x98, 0xa5, 0x44, 0x10, 0x00, 0x3a,
+0x84, 0x05, 0xdd, 0x26, 0x80, 0x48, 0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x27, 0xf1, 0x1b,
+0x00, 0x04, 0x80, 0x00, 0x54, 0x40, 0x80, 0xc0, 0xf4, 0x9b, 0x98, 0x84, 0x44, 0x10, 0x00, 0x3b,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x03, 0x84, 0x28, 0x84, 0x05, 0xd5, 0x49, 0x84, 0x26, 0x80, 0x48,
+0x84, 0x05, 0xdd, 0x27, 0xf1, 0x1b, 0x46, 0x90, 0x00, 0x0d, 0x58, 0x94, 0x8e, 0x1e, 0x54, 0x50,
+0x80, 0xc0, 0x00, 0x04, 0x80, 0x00, 0xf5, 0x9b, 0x98, 0x85, 0x84, 0x26, 0x84, 0x05, 0xdd, 0x26,
+0x84, 0x27, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x27, 0xf3, 0x1b, 0x00, 0x24, 0x80, 0x00, 0x54, 0x91,
+0x80, 0xc0, 0x14, 0x9f, 0x80, 0x1b, 0x88, 0x49, 0x84, 0x27, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x3a, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x27, 0xf4, 0x1b, 0x46, 0x90, 0x00, 0x0d, 0x58, 0x94,
+0x8e, 0x1f, 0x54, 0x52, 0x00, 0xc0, 0x00, 0x14, 0x80, 0x00, 0xf5, 0x9b, 0x98, 0x8d, 0x84, 0x05,
+0x44, 0x10, 0x00, 0x3a, 0xdd, 0x26, 0x80, 0x48, 0x44, 0x10, 0x00, 0x3b, 0x84, 0x05, 0xdd, 0x27,
+0xf0, 0x1b, 0x00, 0x24, 0x80, 0x00, 0x54, 0x30, 0x00, 0xc0, 0xf3, 0x9b, 0x98, 0x93, 0x44, 0x10,
+0x00, 0x3b, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x05, 0x84, 0x28, 0x84, 0x44, 0xdd, 0x26, 0xec, 0x74,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x84, 0x40,
+0xf2, 0x81, 0x46, 0xf0, 0x00, 0x0d, 0x00, 0x97, 0x8e, 0x28, 0x54, 0x80, 0x00, 0xff, 0x46, 0x60,
+0x00, 0x0a, 0x58, 0x63, 0x0f, 0x20, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8e, 0x70, 0xa7, 0x70,
+0x4c, 0x54, 0x40, 0x16, 0xa6, 0xb1, 0x44, 0x10, 0x00, 0x11, 0x84, 0x00, 0xdd, 0x27, 0xa6, 0xb2,
+0x44, 0x10, 0x00, 0x12, 0x84, 0x00, 0xdd, 0x27, 0xa6, 0xb3, 0x44, 0x10, 0x00, 0x13, 0x84, 0x00,
+0xdd, 0x27, 0xa6, 0xb4, 0x84, 0x00, 0x44, 0x10, 0x00, 0x14, 0xdd, 0x27, 0x9d, 0xb5, 0x46, 0x50,
+0x00, 0x0a, 0x58, 0x52, 0x8f, 0x66, 0xde, 0xe4, 0x46, 0x50, 0x04, 0x11, 0x05, 0xe2, 0x80, 0xec,
+0x44, 0x1f, 0xc0, 0xc0, 0x54, 0x74, 0x80, 0x3f, 0x40, 0x6f, 0x04, 0x02, 0x40, 0x43, 0x98, 0x04,
+0x14, 0x42, 0x80, 0xec, 0xe7, 0x0f, 0xe8, 0x1a, 0x46, 0xf0, 0x00, 0x0d, 0x04, 0x27, 0x83, 0x8b,
+0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x52, 0x71, 0x00, 0x37, 0x80, 0x27, 0x44, 0x00,
+0x00, 0x3e, 0x4b, 0xe0, 0x18, 0x01, 0x80, 0x27, 0x44, 0x00, 0x00, 0x3f, 0x4b, 0xe0, 0x18, 0x01,
+0x80, 0x27, 0x44, 0x00, 0x00, 0x40, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x24, 0x40, 0x2f, 0x84, 0x00,
+0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8d, 0xb8, 0xdd, 0x2f, 0xf1, 0x01, 0x84, 0x00,
+0x58, 0x50, 0x80, 0x80, 0x80, 0x45, 0x84, 0x24, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0e, 0x20,
+0xf5, 0x81, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0xa7, 0x32, 0x40, 0x32,
+0x04, 0x09, 0x54, 0x71, 0x80, 0x07, 0x80, 0x07, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x89, 0x30,
+0xdd, 0x2f, 0xc7, 0x06, 0x84, 0xa1, 0x4c, 0x72, 0xc1, 0x3a, 0x48, 0x00, 0x00, 0x86, 0x00, 0x83,
+0x00, 0x01, 0x84, 0xa4, 0x54, 0x84, 0x00, 0x0e, 0x4c, 0x82, 0xc0, 0x07, 0x46, 0x60, 0x00, 0x06,
+0x58, 0x63, 0x00, 0x78, 0xd5, 0x4a, 0x84, 0xa2, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78,
+0x4c, 0x82, 0xc0, 0x44, 0x44, 0x10, 0x00, 0x12, 0x44, 0x00, 0x00, 0x45, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x5e, 0x44, 0x00, 0x00, 0x4b, 0xdd, 0x26, 0x84, 0x27, 0x44, 0x00, 0x00, 0x5b, 0xdd, 0x26,
+0x80, 0x28, 0x44, 0x00, 0x00, 0x5c, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x23, 0x44, 0x00, 0x00, 0xc3,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x17, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x24,
+0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x84, 0x26, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x81, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x00, 0x00, 0xc4,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x83, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x17,
+0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x88, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x5e, 0x48, 0x00, 0x00, 0xb0, 0x44, 0x10, 0x00, 0x12, 0x44, 0x00, 0x00, 0x45,
+0xdd, 0x26, 0x84, 0x27, 0x44, 0x00, 0x00, 0x5b, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x23, 0x44, 0x00,
+0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x17, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x24, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x84, 0x26, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x81, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x00,
+0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x83, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x17, 0x48, 0x00, 0x00, 0x81, 0xa6, 0xf1, 0x84, 0x04, 0x54, 0x81, 0x80, 0x0e, 0x4c, 0x80,
+0x40, 0x34, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x10, 0x00, 0x15, 0x44, 0x00,
+0x00, 0x45, 0xdd, 0x26, 0x80, 0x28, 0x44, 0x00, 0x00, 0x5b, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x23,
+0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x24, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x84, 0x28, 0x44, 0x00, 0x00, 0xc4,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x81, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x15,
+0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x83, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x16, 0xd5, 0x48, 0x84, 0xa2, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78,
+0x4c, 0x82, 0xc0, 0x45, 0x44, 0x10, 0x00, 0x15, 0x44, 0x00, 0x00, 0x45, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x5c, 0x44, 0x00, 0x00, 0x4b, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x00, 0x00, 0x5b, 0xdd, 0x26,
+0x84, 0x23, 0x44, 0x00, 0x00, 0x5c, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x23, 0x44, 0x00, 0x00, 0xc3,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x10, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x24,
+0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x84, 0x28, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10,
+0x00, 0x81, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x15, 0x44, 0x00, 0x00, 0xc4,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x83, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x16,
+0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x88, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x5b, 0x44, 0x00, 0x00, 0xc4, 0xd5, 0x30, 0x44, 0x10, 0x00, 0x15, 0x44, 0x00,
+0x00, 0x45, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x00, 0x00, 0x5b, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x23,
+0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x24, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x84, 0x28, 0x44, 0x00, 0x00, 0xc4,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x81, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x15,
+0x44, 0x00, 0x00, 0xc4, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x83, 0x44, 0x00, 0x00, 0xc3, 0xdd, 0x26,
+0x44, 0x00, 0x00, 0xc4, 0x44, 0x10, 0x00, 0x16, 0xdd, 0x26, 0x84, 0x01, 0x80, 0x40, 0x80, 0x27,
+0x46, 0x60, 0x00, 0x07, 0x58, 0x63, 0x02, 0x78, 0x4b, 0xe0, 0x18, 0x01, 0x80, 0x27, 0x84, 0x00,
+0x84, 0x41, 0x4b, 0xe0, 0x18, 0x01, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00,
+0x3b, 0xff, 0xfc, 0xbc, 0xef, 0xfc, 0x96, 0x49, 0xe6, 0x38, 0xe9, 0x36, 0x80, 0x60, 0xa2, 0x59,
+0x47, 0xe0, 0x00, 0x0d, 0x14, 0x1f, 0x03, 0x88, 0xb4, 0xa3, 0x50, 0x20, 0x00, 0x08, 0x46, 0xf0,
+0x00, 0x0d, 0x14, 0x57, 0x83, 0x89, 0xb4, 0x62, 0x50, 0x20, 0x00, 0x0c, 0x46, 0xf0, 0x00, 0x0d,
+0x14, 0x37, 0x83, 0x8a, 0xb4, 0xa2, 0x50, 0x20, 0x00, 0x10, 0x46, 0xf0, 0x00, 0x0d, 0x14, 0x57,
+0x83, 0x8b, 0x50, 0x50, 0x00, 0x14, 0xb4, 0x82, 0x46, 0xf0, 0x00, 0x0d, 0x14, 0x47, 0x83, 0x8c,
+0x00, 0x0f, 0x0e, 0x20, 0xb4, 0x65, 0x46, 0xf0, 0x00, 0x0d, 0x14, 0x37, 0x83, 0x8d, 0x5c, 0xf0,
+0x00, 0x37, 0xe8, 0x0a, 0x42, 0x10, 0xa0, 0x0b, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7, 0x8e, 0x88,
+0xdd, 0x2f, 0x84, 0x00, 0xd5, 0x02, 0x84, 0x01, 0xec, 0x04, 0x3b, 0xff, 0xfc, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xfc, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x54, 0x90,
+0x00, 0xff, 0x54, 0x80, 0x80, 0xff, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0xb0, 0x97, 0xd0,
+0x4b, 0xe0, 0x18, 0x01, 0x80, 0x29, 0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0, 0x18, 0x01, 0x4e, 0x83,
+0x00, 0x07, 0x44, 0x10, 0x00, 0xb1, 0x44, 0x00, 0x00, 0x9e, 0xd5, 0x05, 0x44, 0x00, 0x00, 0x9e,
+0x44, 0x10, 0x00, 0xb2, 0x4b, 0xe0, 0x18, 0x01, 0x80, 0x27, 0x44, 0x00, 0x00, 0x9f, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xec, 0x04, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e,
+0x3a, 0x6f, 0xa4, 0xbc, 0xef, 0xf4, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x54, 0x90,
+0x00, 0xff, 0x97, 0xc8, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0xb0, 0x81, 0x02, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x30, 0x00, 0xb2, 0x44, 0x40,
+0x00, 0xb1, 0x40, 0x12, 0x24, 0x1a, 0x40, 0x11, 0xa4, 0x1b, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0x80, 0x27, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x15, 0x84, 0x21, 0xdd, 0x26,
+0x84, 0x00, 0x92, 0x00, 0x84, 0x27, 0x9c, 0x01, 0x4c, 0x00, 0xff, 0xfd, 0x46, 0x60, 0x00, 0x06,
+0x58, 0x63, 0x00, 0x78, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x00, 0x00, 0x9f, 0x44, 0x10, 0x00, 0x9b,
+0x4b, 0xe0, 0x18, 0x01, 0x44, 0x00, 0x00, 0x9b, 0xf0, 0x81, 0x84, 0xe0, 0x50, 0x6f, 0x80, 0x04,
+0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x8e, 0xf8, 0xd5, 0x27, 0x44, 0x20, 0x00, 0x65, 0x4c, 0x71,
+0x00, 0x04, 0x84, 0x00, 0xd5, 0x18, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x84, 0x20,
+0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0,
+0x18, 0x01, 0xd5, 0x17, 0x92, 0x00, 0x84, 0xa7, 0x9c, 0x49, 0xd9, 0xfd, 0x9c, 0x01, 0x87, 0xca,
+0x4c, 0x0f, 0x00, 0x04, 0x84, 0x20, 0xd5, 0xf7, 0x84, 0x00, 0x44, 0x10, 0x00, 0x9f, 0x80, 0x46,
+0x9d, 0xf9, 0x4b, 0xe0, 0x24, 0x01, 0xf4, 0x01, 0x44, 0x30, 0x00, 0x9b, 0x4c, 0x41, 0xbf, 0xd7,
+0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x10, 0x00, 0xba, 0x44, 0x00, 0x00, 0x9e,
+0x4b, 0xe0, 0x18, 0x01, 0x84, 0x2a, 0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x10,
+0x04, 0x10, 0x58, 0x10, 0x80, 0x7c, 0xb4, 0x01, 0x40, 0x10, 0x40, 0x09, 0x4e, 0x04, 0x00, 0x05,
+0x44, 0x2f, 0x00, 0x00, 0x98, 0x4a, 0x45, 0xe0, 0x80, 0x00, 0x40, 0x50, 0x78, 0x02, 0x96, 0x01,
+0xc5, 0x04, 0x44, 0x4f, 0x00, 0x00, 0x98, 0x04, 0x42, 0x30, 0x84, 0x24, 0x42, 0x30, 0x00, 0x73,
+0xb6, 0x68, 0xec, 0x0c, 0x3a, 0x6f, 0xa4, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0x6c, 0x96, 0x00, 0xf0, 0x82, 0xc0, 0x08, 0x84, 0x20, 0xf1, 0x84, 0xf1, 0x89, 0xf1, 0x8a,
+0xf1, 0x8b, 0x48, 0x00, 0x02, 0x7f, 0x46, 0x30, 0x04, 0x11, 0x58, 0x31, 0x80, 0x04, 0xb5, 0x23,
+0x47, 0xe0, 0x04, 0x11, 0x14, 0x9f, 0x80, 0x0b, 0x59, 0xef, 0x03, 0xb8, 0xb4, 0x5e, 0x46, 0x70,
+0x04, 0x10, 0xf2, 0x8a, 0x58, 0x73, 0x85, 0x04, 0xb4, 0x87, 0x46, 0x80, 0x04, 0x10, 0xf4, 0x89,
+0x58, 0x84, 0x05, 0x0c, 0xb4, 0x28, 0xf0, 0x02, 0x44, 0xa0, 0x00, 0x10, 0xf1, 0x84, 0xb6, 0x03,
+0xb7, 0x5e, 0x50, 0x2f, 0x80, 0x48, 0xf0, 0x02, 0x84, 0x24, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0xf8, 0xdd, 0x2f, 0xf5, 0x12, 0x46, 0x90, 0x00, 0x06, 0x58, 0x94, 0x80, 0x78, 0x54, 0x12,
+0x80, 0xe7, 0x84, 0x04, 0x4b, 0xe0, 0x24, 0x01, 0xf0, 0x02, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce,
+0x0d, 0xb8, 0x84, 0x21, 0x50, 0x2f, 0x80, 0x7c, 0xdd, 0x3c, 0xf0, 0x02, 0x84, 0x22, 0x50, 0x2f,
+0x80, 0x78, 0xdd, 0x3c, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x23, 0x50, 0x2f, 0x80, 0x74, 0xdd, 0x3c,
+0xf0, 0x02, 0x44, 0x10, 0x00, 0x2a, 0x50, 0x2f, 0x80, 0x70, 0xdd, 0x3c, 0xf1, 0x02, 0x50, 0x2f,
+0x80, 0x6c, 0x84, 0x04, 0xdd, 0x3c, 0x84, 0x22, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x04, 0xdd, 0x3c,
+0x44, 0x10, 0x00, 0x22, 0x50, 0x2f, 0x80, 0x64, 0x84, 0x04, 0xdd, 0x3c, 0x84, 0x23, 0x50, 0x2f,
+0x80, 0x60, 0x84, 0x05, 0xdd, 0x3c, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x5c, 0x84, 0x05, 0xdd, 0x3c,
+0x44, 0x10, 0x00, 0x11, 0x50, 0x2f, 0x80, 0x58, 0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x12,
+0x50, 0x2f, 0x80, 0x54, 0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x50,
+0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x14, 0x50, 0x2f, 0x80, 0x4c, 0x84, 0x05, 0xdd, 0x3c,
+0xf0, 0x02, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0x70, 0x84, 0x21, 0x44, 0x20, 0x00, 0x21,
+0xdd, 0x26, 0xf0, 0x02, 0x80, 0x4a, 0x84, 0x22, 0xdd, 0x26, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x23,
+0x80, 0x40, 0xdd, 0x26, 0xf0, 0x02, 0x44, 0x10, 0x00, 0x2a, 0x44, 0x20, 0x00, 0x1b, 0xdd, 0x26,
+0xf1, 0x02, 0x44, 0x20, 0x00, 0x81, 0x84, 0x04, 0xdd, 0x26, 0x84, 0x22, 0x44, 0x20, 0x00, 0x81,
+0x84, 0x04, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x22, 0x44, 0x20, 0x00, 0xee, 0x84, 0x04, 0xdd, 0x26,
+0x84, 0x23, 0x44, 0x20, 0x00, 0x30, 0x84, 0x05, 0xdd, 0x26, 0x84, 0x24, 0x44, 0x20, 0x00, 0x30,
+0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xd7, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x13,
+0x44, 0x20, 0x00, 0xa2, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x20, 0x00, 0x20, 0x44, 0x10, 0x00, 0x14,
+0x84, 0x05, 0xdd, 0x26, 0xf1, 0x02, 0x44, 0x00, 0x00, 0x17, 0x4b, 0xe0, 0x24, 0x01, 0xf2, 0x02,
+0x46, 0x30, 0x00, 0xcf, 0x58, 0x31, 0x88, 0xb0, 0x44, 0x45, 0x20, 0x00, 0xb6, 0x47, 0xb6, 0x88,
+0xb6, 0x67, 0xf3, 0x02, 0x92, 0x00, 0x84, 0xe7, 0x9c, 0xd9, 0x4c, 0x33, 0xff, 0xfd, 0x46, 0x80,
+0x04, 0x10, 0x58, 0x84, 0x05, 0x0c, 0x44, 0x65, 0x20, 0x1e, 0xb6, 0xc8, 0x84, 0x60, 0x92, 0x00,
+0x85, 0x47, 0x9c, 0xd9, 0x4c, 0x35, 0x7f, 0xfd, 0x47, 0xc0, 0x04, 0x10, 0x59, 0xce, 0x05, 0x0c,
+0x44, 0x55, 0x20, 0x3e, 0xb6, 0xbc, 0x84, 0x60, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0xd9, 0x4c, 0x3f,
+0x7f, 0xfd, 0x46, 0x90, 0x00, 0x06, 0x58, 0x94, 0x80, 0x78, 0x84, 0x20, 0x44, 0x00, 0x00, 0x17,
+0xdd, 0x29, 0x44, 0x10, 0x00, 0xaa, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x9f, 0xdd, 0x29, 0x44, 0x10, 0x00, 0xab, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x84, 0x2a,
+0x44, 0x00, 0x00, 0x9f, 0xdd, 0x29, 0x44, 0x10, 0x00, 0xac, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29,
+0x44, 0x10, 0x00, 0x3f, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x29, 0x44, 0x10, 0x00, 0xad, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x3f, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x29, 0x44, 0x10,
+0x00, 0x40, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x29, 0x50, 0x2f, 0x80, 0x88, 0x44, 0x10, 0x00, 0x1f,
+0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf7, 0x22, 0x44, 0x00,
+0x00, 0x1f, 0x58, 0x23, 0x80, 0x60, 0xf2, 0xa2, 0x80, 0x22, 0xdd, 0x29, 0x84, 0x25, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x29, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x29, 0x46, 0x40, 0x00, 0x0d,
+0x58, 0x42, 0x0e, 0x00, 0x22, 0x12, 0x00, 0x00, 0x46, 0x30, 0x00, 0x0d, 0x58, 0x31, 0x8e, 0x10,
+0x84, 0x00, 0xf1, 0x88, 0xf3, 0x86, 0xf0, 0x83, 0x46, 0x80, 0x00, 0x0a, 0x58, 0x84, 0x0f, 0xd8,
+0x3a, 0x04, 0x04, 0x00, 0x46, 0x70, 0x00, 0x0a, 0x58, 0x73, 0x8f, 0xd0, 0xf0, 0x90, 0x12, 0x1f,
+0x80, 0x22, 0xf1, 0x03, 0x50, 0x0f, 0x80, 0x40, 0x38, 0x20, 0x04, 0x00, 0x44, 0x31, 0x20, 0x3e,
+0x40, 0x91, 0x64, 0x08, 0x3a, 0x03, 0x84, 0x00, 0x46, 0x40, 0x04, 0x10, 0x41, 0xe4, 0x8c, 0x04,
+0x58, 0x42, 0x05, 0x0c, 0x51, 0xcf, 0x80, 0x38, 0xb6, 0x1c, 0x12, 0x1f, 0x80, 0x1e, 0x15, 0xe2,
+0x00, 0x00, 0x46, 0xa0, 0x00, 0x06, 0x58, 0xa5, 0x00, 0x78, 0xf5, 0x03, 0x44, 0x00, 0x00, 0x17,
+0x38, 0x1e, 0x14, 0x00, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0xb0, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x2a,
+0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0xb2, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x2a, 0x44, 0x00, 0x00, 0x9f, 0x84, 0x20, 0xdd, 0x2a, 0xf6, 0x03, 0x54, 0x83,
+0x00, 0xff, 0x4e, 0x83, 0x00, 0x3b, 0x46, 0x80, 0x2e, 0xba, 0x58, 0x84, 0x0e, 0x3f, 0x44, 0x70,
+0x00, 0x12, 0x47, 0xc0, 0x00, 0x0a, 0x59, 0xce, 0x0f, 0xbc, 0x46, 0xa0, 0x00, 0x05, 0x58, 0xa5,
+0x0e, 0x70, 0x46, 0x90, 0x00, 0x08, 0x58, 0x94, 0x83, 0x00, 0xd5, 0x22, 0xf5, 0x08, 0x9f, 0xfa,
+0x38, 0x6e, 0x14, 0x00, 0x80, 0x46, 0x4b, 0xe0, 0x28, 0x01, 0x80, 0x46, 0x84, 0x24, 0x84, 0x05,
+0x4b, 0xe0, 0x28, 0x01, 0x84, 0x00, 0x80, 0x20, 0x50, 0x2f, 0x80, 0x84, 0x4b, 0xe0, 0x24, 0x01,
+0x84, 0x00, 0x44, 0x10, 0x00, 0x21, 0x50, 0x2f, 0x80, 0x80, 0x4b, 0xe0, 0x24, 0x01, 0xf6, 0x21,
+0xe3, 0x06, 0xe9, 0x05, 0x05, 0xef, 0x80, 0x20, 0xe3, 0x1e, 0xe8, 0x07, 0x97, 0xf9, 0x97, 0x3b,
+0x84, 0x23, 0x84, 0x05, 0xf4, 0x88, 0xcf, 0xdb, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x78,
+0x44, 0x10, 0x00, 0xb1, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x00, 0x00, 0x9f,
+0x84, 0x20, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x90, 0x00, 0x20, 0x84, 0x60, 0x85, 0x40, 0x87, 0x85,
+0x14, 0x9f, 0x80, 0x05, 0x10, 0x3f, 0x80, 0x8d, 0x10, 0x3f, 0x80, 0x8c, 0x15, 0xcf, 0x80, 0x07,
+0x81, 0x2a, 0xd5, 0x63, 0x81, 0x49, 0xf1, 0x05, 0xa7, 0x98, 0x44, 0x80, 0x00, 0x20, 0x9a, 0xb1,
+0x54, 0x71, 0x00, 0x3f, 0x80, 0x1c, 0x80, 0x27, 0x50, 0x2f, 0x80, 0x84, 0x4c, 0x64, 0x40, 0x06,
+0x14, 0x9f, 0x80, 0x21, 0x80, 0xe6, 0xd5, 0x08, 0xf3, 0x81, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7,
+0x83, 0x00, 0xdd, 0x2f, 0xf3, 0x01, 0x05, 0xef, 0x80, 0x0c, 0x80, 0x1c, 0x40, 0x5f, 0x18, 0x00,
+0x54, 0x82, 0x80, 0x3f, 0x80, 0x28, 0x50, 0x2f, 0x80, 0x80, 0xf3, 0x81, 0x46, 0xf0, 0x00, 0x08,
+0x58, 0xf7, 0x83, 0x00, 0xdd, 0x2f, 0x04, 0x9f, 0x80, 0x21, 0xf5, 0x20, 0x40, 0x04, 0xa8, 0x06,
+0xf1, 0x0d, 0x56, 0x20, 0x00, 0x01, 0x40, 0x31, 0x04, 0x02, 0x40, 0x45, 0x14, 0x06, 0x40, 0x01,
+0x90, 0x02, 0xf3, 0x01, 0xc0, 0x04, 0xaf, 0x98, 0x81, 0x2a, 0xd5, 0x08, 0xe3, 0x25, 0xe8, 0x03,
+0xaf, 0xd8, 0xd5, 0x04, 0x10, 0x81, 0x80, 0x00, 0x81, 0x25, 0x08, 0x21, 0x80, 0x01, 0x80, 0x3c,
+0x84, 0x00, 0x51, 0xce, 0x00, 0x01, 0x84, 0xc2, 0xf3, 0x81, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7,
+0x82, 0xa0, 0xdd, 0x2f, 0xf3, 0x01, 0x4d, 0xc3, 0x7f, 0xaf, 0xf3, 0x07, 0x84, 0xff, 0x50, 0x81,
+0xff, 0xff, 0x40, 0xa4, 0x00, 0x10, 0x14, 0xaf, 0x80, 0x07, 0x4c, 0xa3, 0x80, 0x18, 0xf4, 0x05,
+0x41, 0xc2, 0x04, 0x09, 0x15, 0xcf, 0x80, 0x05, 0xf6, 0x07, 0x87, 0x80, 0xf0, 0x05, 0x56, 0x23,
+0x00, 0x05, 0x87, 0xc0, 0x80, 0x3c, 0x40, 0x5f, 0x08, 0x06, 0x40, 0x10, 0x08, 0x1b, 0xf5, 0x8d,
+0x50, 0x3f, 0x80, 0x8c, 0x81, 0x49, 0xf1, 0x8c, 0xd5, 0x8f, 0x04, 0x8f, 0x80, 0x06, 0xf1, 0x03,
+0x00, 0x4f, 0x80, 0x8c, 0x00, 0x3f, 0x80, 0x8d, 0x50, 0x90, 0x80, 0x01, 0x50, 0x74, 0x00, 0x02,
+0x85, 0x43, 0x14, 0x9f, 0x80, 0x03, 0x10, 0x44, 0x00, 0x00, 0x10, 0x34, 0x00, 0x01, 0xf7, 0x86,
+0x4c, 0x95, 0x7e, 0xdc, 0xf2, 0x08, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x00, 0xac, 0x80,
+0x85, 0x20, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x78, 0xd5, 0x37, 0x44, 0x10, 0x00, 0xb0,
+0x44, 0x00, 0x00, 0x9e, 0xdd, 0x27, 0x80, 0x2a, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27, 0x00, 0x24,
+0x00, 0x00, 0x44, 0x10, 0x00, 0xb1, 0x54, 0x41, 0x00, 0x3f, 0xf4, 0xa2, 0x44, 0x00, 0x00, 0x9e,
+0xdd, 0x27, 0xf1, 0x22, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27, 0x00, 0x34, 0x00, 0x01, 0x44, 0x10,
+0x00, 0xb2, 0x54, 0x61, 0x80, 0x3f, 0xf6, 0xa2, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x27, 0xf1, 0x22,
+0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27, 0x8d, 0x02, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8e, 0x16,
+0x8d, 0x41, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x4c, 0x82, 0xff, 0xd1, 0x8d, 0x24,
+0x45, 0xe0, 0x00, 0x10, 0x4c, 0x9f, 0x00, 0x08, 0x46, 0x80, 0x00, 0x0d, 0x58, 0x84, 0x0e, 0x10,
+0x81, 0x49, 0xd5, 0xc5, 0xf1, 0x02, 0x4e, 0x13, 0x00, 0x95, 0xf3, 0x0b, 0x46, 0x40, 0x04, 0x11,
+0x58, 0x42, 0x00, 0x04, 0xb6, 0x64, 0x46, 0x50, 0x04, 0x11, 0xf0, 0x0a, 0x58, 0x52, 0x83, 0xb8,
+0xb6, 0x05, 0x44, 0x00, 0x00, 0xf4, 0xf1, 0x02, 0xdd, 0x26, 0xf0, 0x02, 0x50, 0x2f, 0x80, 0x88,
+0x44, 0x10, 0x00, 0x1f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x04, 0x8f,
+0x80, 0x22, 0x44, 0x00, 0x00, 0x1f, 0x54, 0x74, 0x00, 0x9f, 0xf7, 0xa2, 0x80, 0x27, 0xdd, 0x26,
+0x84, 0x28, 0x44, 0x00, 0x00, 0x1f, 0xdd, 0x26, 0xf1, 0x02, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0xf1, 0x02, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x44, 0x00, 0x00, 0x15, 0x84, 0x21, 0xdd, 0x26,
+0xf0, 0x02, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01, 0x4c, 0x03, 0x7f, 0xfd, 0x84, 0x20, 0x46, 0x80,
+0x00, 0x06, 0x58, 0x84, 0x00, 0x78, 0x44, 0x00, 0x00, 0x15, 0x4b, 0xe0, 0x20, 0x01, 0x46, 0x20,
+0x04, 0x10, 0x84, 0xe0, 0x58, 0x21, 0x05, 0x04, 0xb6, 0xe2, 0x46, 0x00, 0x04, 0x10, 0xf5, 0x04,
+0x58, 0x00, 0x05, 0x0c, 0xb6, 0xa0, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0x70, 0xf1, 0x09,
+0x80, 0x07, 0xb6, 0x22, 0x84, 0x21, 0xf2, 0x1f, 0xdd, 0x26, 0xf2, 0x1e, 0x84, 0x22, 0x80, 0x07,
+0xdd, 0x26, 0xf2, 0x1d, 0x44, 0x10, 0x00, 0x23, 0x80, 0x07, 0xdd, 0x26, 0xf2, 0x1c, 0x44, 0x10,
+0x00, 0x2a, 0x80, 0x07, 0xdd, 0x26, 0xf2, 0x1b, 0x80, 0x27, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x1a,
+0x84, 0x22, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x19, 0x44, 0x10, 0x00, 0x22, 0x84, 0x04, 0xdd, 0x26,
+0xf2, 0x18, 0x84, 0x23, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x17, 0x84, 0x24, 0x84, 0x05, 0xdd, 0x26,
+0xf2, 0x16, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x15, 0x44, 0x10, 0x00, 0x12,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x14, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x13,
+0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26, 0xf1, 0x12, 0x84, 0x04, 0x4b, 0xe0, 0x20, 0x01,
+0xec, 0x94, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc, 0xef, 0xf8, 0x84, 0x21,
+0x80, 0xe0, 0x44, 0x00, 0x00, 0x15, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0x84, 0x20, 0xd5, 0x0a, 0x92, 0x00, 0x84, 0x07, 0x9c, 0x91, 0x4c, 0x20, 0x7f, 0xfd, 0x9c, 0x49,
+0x84, 0x6a, 0x4c, 0x11, 0x80, 0x04, 0x84, 0x40, 0xd5, 0xf6, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63,
+0x00, 0x78, 0x84, 0x20, 0x44, 0x00, 0x00, 0x15, 0x4b, 0xe0, 0x18, 0x01, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x9b, 0x44, 0x00, 0x00, 0x9f, 0x4b, 0xe0,
+0x18, 0x01, 0x44, 0x10, 0x00, 0x9b, 0xf1, 0x81, 0x50, 0x6f, 0x80, 0x04, 0x46, 0x80, 0x00, 0x05,
+0x58, 0x84, 0x0e, 0xf8, 0xd5, 0x12, 0x92, 0x00, 0x84, 0x87, 0x9c, 0x91, 0x4c, 0x22, 0x7f, 0xfd,
+0x9c, 0x49, 0x84, 0x4a, 0x4c, 0x11, 0x00, 0x04, 0x84, 0x40, 0xd5, 0xf6, 0x84, 0x00, 0x44, 0x10,
+0x00, 0x9f, 0x80, 0x46, 0x4b, 0xe0, 0x20, 0x01, 0xf5, 0x01, 0x45, 0xe0, 0x00, 0x9b, 0x4c, 0x5f,
+0x40, 0x04, 0x84, 0x20, 0xd5, 0xf2, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x10,
+0x00, 0xba, 0x44, 0x00, 0x00, 0x9e, 0x4b, 0xe0, 0x18, 0x01, 0x44, 0x10, 0x00, 0x14, 0x44, 0x00,
+0x00, 0x9f, 0x4b, 0xe0, 0x18, 0x01, 0x46, 0x00, 0x04, 0x10, 0x58, 0x00, 0x00, 0x7c, 0xb4, 0x20,
+0x40, 0x20, 0xc0, 0x09, 0x4e, 0x14, 0x00, 0x05, 0x44, 0x3f, 0x00, 0x00, 0x98, 0x93, 0x44, 0x50,
+0x80, 0x00, 0x40, 0x40, 0x94, 0x02, 0x96, 0x49, 0xc4, 0x04, 0x45, 0xef, 0x00, 0x00, 0x88, 0x3e,
+0x42, 0x21, 0x08, 0x24, 0x42, 0x20, 0x84, 0x73, 0xb6, 0x47, 0xec, 0x08, 0x3a, 0x6f, 0xa0, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0x7c, 0x96, 0x00, 0xf0, 0x83, 0xc0, 0x08,
+0x84, 0x20, 0xf1, 0x87, 0xf1, 0x8a, 0xf1, 0x8b, 0xf1, 0x8c, 0x48, 0x00, 0x03, 0x9d, 0x46, 0x40,
+0x04, 0x11, 0x58, 0x42, 0x00, 0x04, 0xb5, 0x24, 0x46, 0x30, 0x04, 0x11, 0x14, 0x9f, 0x80, 0x0a,
+0x58, 0x31, 0x83, 0xb8, 0xb4, 0x43, 0x46, 0x70, 0x04, 0x10, 0xf2, 0x87, 0x58, 0x73, 0x85, 0x04,
+0xb4, 0x27, 0x46, 0x80, 0x04, 0x10, 0xf1, 0x8c, 0x58, 0x84, 0x05, 0x0c, 0x05, 0xef, 0x80, 0x03,
+0xb4, 0x08, 0x44, 0xa0, 0x00, 0x10, 0xf0, 0x8b, 0x15, 0xe2, 0x00, 0x00, 0xb7, 0x43, 0x50, 0x2f,
+0x80, 0x44, 0xf0, 0x03, 0x84, 0x24, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f,
+0xf5, 0x11, 0x46, 0x90, 0x00, 0x06, 0x58, 0x94, 0x80, 0x78, 0x54, 0x12, 0x80, 0xe7, 0x84, 0x04,
+0x4b, 0xe0, 0x24, 0x01, 0xf0, 0x03, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce, 0x0d, 0xb8, 0x84, 0x21,
+0x50, 0x2f, 0x80, 0x78, 0xdd, 0x3c, 0xf0, 0x03, 0x84, 0x22, 0x50, 0x2f, 0x80, 0x74, 0xdd, 0x3c,
+0xf0, 0x03, 0x44, 0x10, 0x00, 0x23, 0x50, 0x2f, 0x80, 0x70, 0xdd, 0x3c, 0xf0, 0x03, 0x44, 0x10,
+0x00, 0x2a, 0x50, 0x2f, 0x80, 0x6c, 0xdd, 0x3c, 0xf1, 0x03, 0x50, 0x2f, 0x80, 0x68, 0x84, 0x04,
+0xdd, 0x3c, 0x84, 0x22, 0x50, 0x2f, 0x80, 0x64, 0x84, 0x04, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x22,
+0x50, 0x2f, 0x80, 0x60, 0x84, 0x04, 0xdd, 0x3c, 0x84, 0x23, 0x50, 0x2f, 0x80, 0x5c, 0x84, 0x05,
+0xdd, 0x3c, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x58, 0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x11,
+0x50, 0x2f, 0x80, 0x54, 0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f, 0x80, 0x50,
+0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x4c, 0x84, 0x05, 0xdd, 0x3c,
+0x44, 0x10, 0x00, 0x14, 0x50, 0x2f, 0x80, 0x48, 0x84, 0x05, 0xdd, 0x3c, 0xf0, 0x03, 0x46, 0x60,
+0x00, 0x05, 0x58, 0x63, 0x0e, 0x70, 0x84, 0x21, 0x44, 0x20, 0x00, 0x21, 0xdd, 0x26, 0xf0, 0x03,
+0x80, 0x4a, 0x84, 0x22, 0xdd, 0x26, 0xf0, 0x03, 0x44, 0x10, 0x00, 0x23, 0x80, 0x40, 0xdd, 0x26,
+0xf0, 0x03, 0x44, 0x10, 0x00, 0x2a, 0x44, 0x20, 0x00, 0x1b, 0xdd, 0x26, 0xf1, 0x03, 0x44, 0x20,
+0x00, 0x81, 0x84, 0x04, 0xdd, 0x26, 0x84, 0x22, 0x44, 0x20, 0x00, 0x81, 0x84, 0x04, 0xdd, 0x26,
+0x44, 0x10, 0x00, 0x22, 0x44, 0x20, 0x00, 0xee, 0x84, 0x04, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x11,
+0x44, 0x20, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x12, 0x44, 0x20, 0x00, 0xd7,
+0x84, 0x05, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0xa2, 0x84, 0x05, 0xdd, 0x26,
+0x44, 0x20, 0x00, 0x20, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26, 0xf1, 0x03, 0x44, 0x00,
+0x00, 0x17, 0x4b, 0xe0, 0x24, 0x01, 0xf2, 0x03, 0x46, 0x30, 0x00, 0xcf, 0x58, 0x31, 0x88, 0xb0,
+0x44, 0x45, 0x20, 0x00, 0xb6, 0x47, 0xb6, 0x88, 0xb6, 0x67, 0xf3, 0x03, 0x92, 0x00, 0x84, 0xe7,
+0x9c, 0xd9, 0x4c, 0x33, 0xff, 0xfd, 0x46, 0x80, 0x04, 0x10, 0x58, 0x84, 0x05, 0x0c, 0x44, 0x65,
+0x20, 0x1e, 0xb6, 0xc8, 0x84, 0x60, 0x92, 0x00, 0x85, 0x47, 0x9c, 0xd9, 0x4c, 0x35, 0x7f, 0xfd,
+0x47, 0xc0, 0x04, 0x10, 0x59, 0xce, 0x05, 0x0c, 0x44, 0x55, 0x20, 0x3e, 0xb6, 0xbc, 0x84, 0x60,
+0x92, 0x00, 0x84, 0x87, 0x9c, 0xd9, 0x4c, 0x32, 0x7f, 0xfd, 0x46, 0x90, 0x00, 0x06, 0x58, 0x94,
+0x80, 0x78, 0x84, 0x24, 0x44, 0x00, 0x00, 0x17, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x14, 0x44, 0x00,
+0x00, 0xf1, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0xf2, 0xdd, 0x29, 0x44, 0x10,
+0x00, 0x31, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x29, 0x44, 0x10, 0x00, 0xb0, 0x44, 0x00, 0x00, 0x9e,
+0xdd, 0x29, 0x44, 0x10, 0x00, 0x80, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x29, 0x46, 0x80, 0x00, 0x05,
+0x58, 0x84, 0x0e, 0xf8, 0x50, 0x2f, 0x80, 0x40, 0x44, 0x10, 0x00, 0x1f, 0x84, 0x00, 0x4b, 0xe0,
+0x20, 0x01, 0xf1, 0x10, 0x44, 0x00, 0x00, 0x1f, 0x58, 0x20, 0x80, 0x60, 0xf2, 0x9f, 0x80, 0x22,
+0xdd, 0x29, 0x84, 0x25, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x84, 0x24, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x29, 0x84, 0x23, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x50, 0x2f, 0x80, 0x7c, 0x44, 0x10,
+0x00, 0x9f, 0x84, 0x00, 0x4b, 0xe0, 0x20, 0x01, 0xf3, 0x1f, 0x44, 0x00, 0x00, 0x9f, 0x58, 0x11,
+0x80, 0x60, 0xdd, 0x29, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8e, 0x70, 0x84, 0x23, 0x44, 0x20,
+0x00, 0x3c, 0x84, 0x05, 0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x20, 0x00, 0x3c, 0x84, 0x24, 0x84, 0x05,
+0x4b, 0xe0, 0x1c, 0x01, 0x44, 0x10, 0x00, 0x28, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x44, 0x00,
+0x00, 0x9f, 0x84, 0x20, 0xdd, 0x29, 0x46, 0x30, 0x00, 0x0d, 0x58, 0x31, 0x8e, 0x00, 0x22, 0x41,
+0x80, 0x00, 0x4e, 0x44, 0x00, 0x04, 0x84, 0x80, 0xd5, 0x05, 0xe4, 0x93, 0xe9, 0x42, 0x44, 0x40,
+0x00, 0x12, 0xad, 0x18, 0xd5, 0x3e, 0x46, 0x40, 0x00, 0x0a, 0x58, 0x42, 0x0f, 0xbc, 0x38, 0x22,
+0x08, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0x22, 0x54, 0x00, 0x00,
+0x47, 0xe0, 0x00, 0x0a, 0x59, 0xef, 0x0f, 0xbc, 0x38, 0x2f, 0x14, 0x00, 0x84, 0x24, 0x84, 0x05,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0x70, 0xdd, 0x2f, 0x44, 0x10, 0x00, 0x29, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x21, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x29, 0x80, 0x07,
+0xdd, 0x3c, 0x44, 0x10, 0x00, 0x29, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x9f, 0xdd, 0x29, 0x80, 0x06, 0xdd, 0x3c, 0xf0, 0x0f, 0xe3, 0x40, 0xe9, 0x24, 0xf3, 0x0e,
+0xe3, 0x43, 0xe9, 0x21, 0x02, 0x14, 0x00, 0x00, 0x9c, 0x8a, 0x12, 0x24, 0x00, 0x00, 0xd5, 0x15,
+0x46, 0xa0, 0x05, 0xf5, 0x58, 0xa5, 0x0e, 0x10, 0x46, 0x80, 0x00, 0x0d, 0x58, 0x84, 0x0e, 0x00,
+0x46, 0x90, 0x00, 0x06, 0x58, 0x94, 0x80, 0x78, 0x50, 0x7f, 0x80, 0x3c, 0x47, 0xc0, 0x00, 0x08,
+0x59, 0xce, 0x0b, 0x18, 0x50, 0x6f, 0x80, 0x38, 0x22, 0x24, 0x00, 0x00, 0x84, 0x23, 0x84, 0x05,
+0xe4, 0x53, 0xe9, 0xaa, 0x85, 0x40, 0x85, 0x25, 0x45, 0xc0, 0x00, 0x20, 0x84, 0x00, 0x46, 0x70,
+0x00, 0x0d, 0x58, 0x73, 0x8e, 0x0c, 0x14, 0x9f, 0x80, 0x05, 0x15, 0xcf, 0x80, 0x06, 0x14, 0xaf,
+0x80, 0x04, 0xae, 0x38, 0x50, 0x2f, 0x80, 0x38, 0x50, 0x5f, 0x80, 0x3c, 0x81, 0x2a, 0x83, 0x8a,
+0x48, 0x00, 0x00, 0xf4, 0x14, 0x9f, 0x80, 0x04, 0x84, 0x61, 0x4c, 0xa1, 0x80, 0x17, 0x05, 0xef,
+0x80, 0x05, 0x5e, 0xff, 0x00, 0x04, 0x4e, 0xf2, 0x00, 0xd7, 0x46, 0x80, 0x00, 0x0d, 0x58, 0x84,
+0x0e, 0x0c, 0x00, 0x94, 0x00, 0x00, 0x04, 0x8f, 0x80, 0x09, 0x54, 0x14, 0x80, 0x0f, 0x56, 0x40,
+0x80, 0x08, 0x40, 0x02, 0x0c, 0x06, 0xd5, 0x09, 0x54, 0x64, 0x80, 0x3f, 0x56, 0x33, 0x00, 0x20,
+0x04, 0x8f, 0x80, 0x08, 0x5c, 0x01, 0x80, 0x01, 0xc0, 0x05, 0x15, 0xcf, 0x80, 0x0f, 0x80, 0xe9,
+0xd5, 0x39, 0xf0, 0x06, 0x40, 0x74, 0x80, 0x01, 0x96, 0xf8, 0x4e, 0xa3, 0x00, 0x12, 0x44, 0x10,
+0x00, 0x28, 0x44, 0x00, 0x00, 0x9e, 0xf2, 0x81, 0xb6, 0xbf, 0x54, 0x71, 0x80, 0x0f, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xf2, 0x01, 0xb4, 0xbf, 0xd5, 0x10, 0x44, 0x00,
+0x00, 0x9e, 0x44, 0x10, 0x00, 0x29, 0xf2, 0x81, 0xb6, 0xbf, 0x54, 0x71, 0x80, 0x3f, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xb4, 0xbf, 0xf2, 0x01, 0x80, 0x27, 0x44, 0x00,
+0x00, 0x9f, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0xb4, 0xbf, 0x80, 0x05, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x8b, 0x18, 0xdd, 0x2f, 0xb4, 0xbf,
+0xf2, 0x01, 0xf1, 0x06, 0x84, 0x80, 0x40, 0x40, 0xa0, 0x1a, 0x41, 0xe2, 0x24, 0x00, 0x54, 0x3f,
+0x00, 0xff, 0x4e, 0xa3, 0x00, 0x12, 0x44, 0x10, 0x00, 0x28, 0x44, 0x00, 0x00, 0x9e, 0xf2, 0x81,
+0xb6, 0xbf, 0x54, 0x61, 0x80, 0x0f, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0xf2, 0x01, 0xb4, 0xbf, 0xd5, 0x10, 0x44, 0x00, 0x00, 0x9e, 0x44, 0x10, 0x00, 0x29, 0xf2, 0x81,
+0xb6, 0xbf, 0x54, 0x61, 0x80, 0x3f, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0xb4, 0xbf, 0xf2, 0x01, 0x80, 0x26, 0x44, 0x00, 0x00, 0x9f, 0xb6, 0xbf, 0xf2, 0x81, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xf2, 0x01, 0x80, 0x02, 0x46, 0xf0, 0x00, 0x08,
+0x58, 0xf7, 0x8b, 0x18, 0xdd, 0x2f, 0xf2, 0x01, 0xb4, 0xbf, 0x4e, 0x83, 0x00, 0x09, 0xf3, 0x0f,
+0xe2, 0x7c, 0xe9, 0x05, 0xf0, 0x0e, 0x40, 0xfe, 0x00, 0x06, 0xe9, 0x0a, 0xf3, 0x0f, 0x05, 0xcf,
+0x80, 0x0e, 0xe2, 0x7c, 0xe8, 0x04, 0x83, 0x83, 0x81, 0x27, 0xd5, 0x02, 0x81, 0x26, 0x4e, 0xa3,
+0x00, 0x10, 0x44, 0x10, 0x00, 0x28, 0x44, 0x00, 0x00, 0x9e, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xf2, 0x01, 0xb4, 0xbf, 0xd5, 0x0e, 0x44, 0x00,
+0x00, 0x9e, 0x44, 0x10, 0x00, 0x29, 0xf2, 0x81, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7,
+0x80, 0x78, 0xdd, 0x2f, 0xb4, 0xbf, 0xf2, 0x01, 0x44, 0x00, 0x00, 0x9f, 0x80, 0x29, 0xf2, 0x81,
+0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0xf2, 0x01, 0xb4, 0xbf,
+0x4e, 0xa3, 0x00, 0x0a, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0e, 0x0c, 0x10, 0x93, 0x00, 0x00,
+0x04, 0x9f, 0x80, 0x04, 0x8d, 0x41, 0x54, 0xa5, 0x00, 0xff, 0x84, 0xe2, 0x4c, 0xa3, 0xff, 0x1c,
+0xf1, 0x05, 0x9f, 0x09, 0x41, 0xe2, 0x00, 0x10, 0x15, 0xef, 0x80, 0x05, 0x4f, 0xe2, 0x00, 0x18,
+0xf0, 0x06, 0x40, 0x30, 0x04, 0x09, 0xf3, 0x86, 0x05, 0xef, 0x80, 0x05, 0x14, 0x9f, 0x80, 0x04,
+0x56, 0x4f, 0x00, 0x05, 0x56, 0x7f, 0x00, 0x03, 0x5c, 0xa2, 0x00, 0x01, 0x5c, 0x63, 0x80, 0x01,
+0x14, 0xaf, 0x80, 0x08, 0xf6, 0x89, 0x85, 0x40, 0x48, 0xff, 0xff, 0x00, 0x44, 0x00, 0x00, 0x17,
+0x84, 0x27, 0x14, 0x9f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0x46, 0x20, 0x00, 0x0d, 0x58, 0x21, 0x0e, 0x0c, 0xa7, 0x50, 0x80, 0xdc, 0x55, 0xc2, 0x80, 0x08,
+0x54, 0x32, 0x80, 0x0f, 0x4f, 0xc2, 0x00, 0x05, 0x50, 0x11, 0xff, 0xf0, 0x96, 0xca, 0x84, 0x04,
+0x42, 0x31, 0x80, 0x01, 0x5e, 0xf1, 0xff, 0xf9, 0xe8, 0x04, 0x84, 0x78, 0xf3, 0x86, 0xd5, 0x04,
+0x9f, 0x19, 0x97, 0xe2, 0xf7, 0x86, 0x05, 0xcf, 0x80, 0x04, 0x55, 0xee, 0x00, 0x20, 0x54, 0x3e,
+0x00, 0x3f, 0x4f, 0xe2, 0x00, 0x05, 0x50, 0x51, 0xff, 0xc0, 0x96, 0xea, 0x44, 0x20, 0x00, 0x1c,
+0x42, 0x31, 0x88, 0x01, 0x5e, 0xf1, 0xff, 0xe1, 0xe8, 0x04, 0x44, 0x3f, 0xff, 0xe0, 0xd5, 0x03,
+0x9e, 0x59, 0x96, 0xca, 0xf3, 0x85, 0xf3, 0x06, 0xf7, 0x05, 0x87, 0xc0, 0x9d, 0x1b, 0x9c, 0x3b,
+0x15, 0xef, 0x80, 0x08, 0xf4, 0x89, 0xf0, 0x8d, 0x50, 0x2f, 0x80, 0x3c, 0x83, 0x83, 0xd5, 0x5f,
+0xf2, 0x81, 0xf4, 0x82, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0x80, 0x2a, 0x44, 0x00, 0x00, 0x9f, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f,
+0x44, 0x10, 0x00, 0x29, 0x44, 0x00, 0x00, 0x9e, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78,
+0xdd, 0x2f, 0x80, 0x26, 0x44, 0x00, 0x00, 0x9f, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0x78,
+0xdd, 0x2f, 0xf5, 0x01, 0x80, 0x05, 0x46, 0xf0, 0x00, 0x08, 0x58, 0xf7, 0x8b, 0x18, 0xdd, 0x2f,
+0xb4, 0xbf, 0xf1, 0x06, 0xf2, 0x01, 0xf4, 0x02, 0xd9, 0x09, 0xf3, 0x05, 0x4c, 0x81, 0xc0, 0x07,
+0x10, 0xa2, 0x00, 0x00, 0xf6, 0x84, 0xf0, 0x0f, 0xd5, 0x0c, 0xf0, 0x0f, 0xe2, 0x09, 0xe9, 0x03,
+0x80, 0x09, 0xd5, 0x07, 0x54, 0x93, 0x80, 0x3f, 0x10, 0xa2, 0x00, 0x00, 0x14, 0x9f, 0x80, 0x04,
+0x8d, 0x01, 0x40, 0x84, 0x00, 0x10, 0x51, 0xce, 0x00, 0x01, 0x81, 0x20, 0x05, 0xef, 0x80, 0x05,
+0x54, 0x74, 0x00, 0xff, 0x40, 0x3e, 0x78, 0x00, 0x05, 0xef, 0x80, 0x0d, 0x44, 0x10, 0x00, 0x28,
+0x44, 0x00, 0x00, 0x9e, 0x54, 0x63, 0x80, 0x3f, 0x40, 0xff, 0x0c, 0x07, 0xe8, 0xaa, 0xf7, 0x08,
+0x9d, 0x29, 0x9c, 0x39, 0xf0, 0x88, 0x80, 0xc9, 0x41, 0xc2, 0x00, 0x10, 0x05, 0xef, 0x80, 0x08,
+0xf3, 0x06, 0xf1, 0x09, 0x40, 0x5f, 0x0c, 0x00, 0xe0, 0x25, 0xe9, 0x0f, 0x54, 0x9e, 0x00, 0x0f,
+0x85, 0x40, 0x80, 0xbc, 0x04, 0x8f, 0x80, 0x05, 0x83, 0x8a, 0x46, 0x40, 0x00, 0x0d, 0x58, 0x42,
+0x0e, 0x0c, 0x81, 0x49, 0x81, 0x26, 0xd5, 0xd3, 0xf6, 0x04, 0x46, 0x20, 0x00, 0x0d, 0x58, 0x21,
+0x0e, 0x0d, 0xaf, 0x90, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x10, 0x00, 0x28,
+0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8e, 0x0c, 0xa7, 0x28,
+0x44, 0x00, 0x00, 0x9f, 0x54, 0x12, 0x00, 0x0f, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x29, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x26, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x0d, 0xa7, 0xc0, 0x44, 0x00,
+0x00, 0x9f, 0x54, 0x13, 0x80, 0x3f, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26,
+0x84, 0x20, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0xf4, 0xdd, 0x26,
+0x44, 0x00, 0x00, 0x15, 0x84, 0x21, 0xdd, 0x26, 0x84, 0x60, 0x92, 0x00, 0x84, 0x27, 0x9c, 0xd9,
+0x4c, 0x30, 0xff, 0xfd, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x78, 0x44, 0x00, 0x00, 0x15,
+0x84, 0x20, 0xdd, 0x27, 0xf3, 0x03, 0xcb, 0x6e, 0x05, 0xef, 0x80, 0x0a, 0x46, 0x30, 0x04, 0x11,
+0x58, 0x31, 0x80, 0x04, 0x15, 0xe1, 0x80, 0x00, 0x46, 0x50, 0x04, 0x11, 0xf1, 0x07, 0x58, 0x52,
+0x83, 0xb8, 0xb6, 0x25, 0x46, 0x20, 0x04, 0x10, 0xf0, 0x03, 0x58, 0x21, 0x05, 0x04, 0xb6, 0x02,
+0x46, 0x40, 0x04, 0x10, 0xf6, 0x0b, 0x58, 0x42, 0x05, 0x0c, 0xb6, 0xc4, 0x44, 0x10, 0x00, 0xb0,
+0x05, 0xef, 0x80, 0x0c, 0x44, 0x00, 0x00, 0x9e, 0x15, 0xe1, 0x00, 0x00, 0x46, 0x60, 0x00, 0x05,
+0x58, 0x63, 0x0e, 0x70, 0xdd, 0x27, 0xf1, 0x03, 0x44, 0x00, 0x00, 0x9f, 0xdd, 0x27, 0xf1, 0x10,
+0x44, 0x00, 0x00, 0x1f, 0xdd, 0x27, 0xf2, 0x1e, 0xf0, 0x03, 0x84, 0x21, 0xdd, 0x26, 0xf2, 0x1d,
+0xf0, 0x03, 0x84, 0x22, 0xdd, 0x26, 0xf2, 0x1c, 0xf0, 0x03, 0x44, 0x10, 0x00, 0x23, 0xdd, 0x26,
+0xf2, 0x1b, 0xf0, 0x03, 0x44, 0x10, 0x00, 0x2a, 0xdd, 0x26, 0xf2, 0x1a, 0xf1, 0x03, 0x84, 0x04,
+0xdd, 0x26, 0xf2, 0x19, 0x84, 0x22, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x18, 0x44, 0x10, 0x00, 0x22,
+0x84, 0x04, 0xdd, 0x26, 0xf2, 0x17, 0x84, 0x23, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x16, 0x84, 0x24,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x15, 0x44, 0x10, 0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x14,
+0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x13, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05,
+0xdd, 0x26, 0xf2, 0x12, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x26, 0xf1, 0x11, 0x84, 0x04,
+0xdd, 0x27, 0xec, 0x84, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0x94, 0x46, 0x60, 0x00, 0x0a, 0x58, 0x63, 0x0f, 0xe0, 0x96, 0x40, 0xf1, 0x82, 0x3a, 0x03,
+0x08, 0x00, 0x50, 0x5f, 0x80, 0x2c, 0x80, 0x65, 0x3a, 0x01, 0x84, 0x24, 0x40, 0x41, 0x40, 0x09,
+0xf0, 0x02, 0xac, 0x98, 0x10, 0x4f, 0x80, 0x36, 0xc0, 0x06, 0x84, 0x40, 0xf2, 0x87, 0xf2, 0x89,
+0x48, 0x00, 0x02, 0x9d, 0x46, 0x70, 0x04, 0x10, 0x58, 0x73, 0x85, 0x0c, 0xb4, 0x87, 0x46, 0x80,
+0x04, 0x10, 0xf4, 0x89, 0x58, 0x84, 0x05, 0x04, 0x05, 0xe4, 0x00, 0x00, 0xf1, 0x02, 0x15, 0xef,
+0x80, 0x07, 0x47, 0xc0, 0x00, 0x05, 0x59, 0xce, 0x0d, 0xb8, 0x50, 0x2f, 0x80, 0x64, 0x84, 0x04,
+0xdd, 0x3c, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x60, 0x84, 0x04, 0xdd, 0x3c, 0x44, 0x10,
+0x00, 0x11, 0x50, 0x2f, 0x80, 0x5c, 0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x12, 0x50, 0x2f,
+0x80, 0x58, 0x84, 0x05, 0xdd, 0x3c, 0x44, 0x10, 0x00, 0x13, 0x50, 0x2f, 0x80, 0x54, 0x84, 0x05,
+0xdd, 0x3c, 0x44, 0x10, 0x00, 0x14, 0x50, 0x2f, 0x80, 0x50, 0x84, 0x05, 0xdd, 0x3c, 0x84, 0x23,
+0x50, 0x2f, 0x80, 0x4c, 0x84, 0x05, 0xdd, 0x3c, 0x84, 0x24, 0x50, 0x2f, 0x80, 0x48, 0x84, 0x05,
+0xdd, 0x3c, 0xf1, 0x02, 0x46, 0xa0, 0x00, 0x05, 0x58, 0xa5, 0x0e, 0x70, 0x44, 0x20, 0x00, 0x87,
+0x84, 0x04, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0x24, 0x84, 0x04, 0xdd, 0x2a,
+0x44, 0x10, 0x00, 0x11, 0x44, 0x20, 0x00, 0x80, 0x84, 0x05, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x12,
+0x44, 0x20, 0x00, 0xc1, 0x84, 0x05, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x13, 0x44, 0x20, 0x00, 0x60,
+0x84, 0x05, 0xdd, 0x2a, 0xf2, 0x02, 0x44, 0x10, 0x00, 0x14, 0x84, 0x05, 0xdd, 0x2a, 0x84, 0x23,
+0x44, 0x20, 0x00, 0x3c, 0x84, 0x05, 0xdd, 0x2a, 0x84, 0x24, 0x44, 0x20, 0x00, 0x3c, 0x84, 0x05,
+0xdd, 0x2a, 0xf0, 0x02, 0x46, 0x90, 0x00, 0x05, 0x58, 0x94, 0x8e, 0xf8, 0x44, 0x10, 0x00, 0x17,
+0x50, 0x2f, 0x80, 0x40, 0x4b, 0xe0, 0x24, 0x01, 0xf0, 0x02, 0x50, 0x2f, 0x80, 0x44, 0x84, 0x24,
+0x4b, 0xe0, 0x24, 0x01, 0xf1, 0x02, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x84, 0x04,
+0x4b, 0xe0, 0x18, 0x01, 0xf1, 0x02, 0x44, 0x00, 0x00, 0x17, 0x4b, 0xe0, 0x18, 0x01, 0x47, 0xc0,
+0x00, 0x92, 0xf0, 0x02, 0x46, 0xa0, 0x00, 0xdf, 0x46, 0x90, 0x00, 0x92, 0x58, 0xa5, 0x08, 0x38,
+0x58, 0x94, 0x80, 0x10, 0xb6, 0x08, 0x15, 0xc3, 0x80, 0x00, 0xb7, 0x48, 0xb7, 0x27, 0xf3, 0x02,
+0x92, 0x00, 0x84, 0xa7, 0x9c, 0xd9, 0xdb, 0xfd, 0x46, 0x30, 0x04, 0x10, 0x46, 0x10, 0x00, 0x92,
+0x58, 0x31, 0x85, 0x0c, 0x58, 0x10, 0x80, 0x30, 0xb6, 0x23, 0x84, 0x60, 0x92, 0x00, 0x84, 0x47,
+0x9c, 0xd9, 0x4c, 0x31, 0x7f, 0xfd, 0x46, 0x70, 0x04, 0x10, 0x46, 0x80, 0x00, 0x92, 0x58, 0x73,
+0x85, 0x0c, 0x58, 0x84, 0x00, 0x38, 0xb7, 0x07, 0x84, 0x60, 0x92, 0x00, 0x84, 0x07, 0x9c, 0xd9,
+0x4c, 0x30, 0x7f, 0xfd, 0x46, 0x90, 0x00, 0x06, 0x58, 0x94, 0x80, 0x78, 0x84, 0x22, 0x44, 0x00,
+0x00, 0x17, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x14, 0x44, 0x00, 0x00, 0xf1, 0xdd, 0x29, 0x44, 0x10,
+0x00, 0x80, 0x44, 0x00, 0x00, 0xf2, 0xdd, 0x29, 0x44, 0x10, 0x00, 0x31, 0x44, 0x00, 0x00, 0xf4,
+0xdd, 0x29, 0x84, 0x25, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9f,
+0xdd, 0x29, 0x85, 0x40, 0x84, 0x23, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x29, 0x14, 0xaf, 0x80, 0x03,
+0x44, 0x00, 0x00, 0x9f, 0x44, 0x10, 0x00, 0x60, 0xdd, 0x29, 0xf6, 0x03, 0x50, 0x5f, 0x80, 0x38,
+0xf6, 0x88, 0xf6, 0x86, 0xf6, 0x85, 0xf6, 0x84, 0x81, 0x26, 0x51, 0xef, 0x80, 0x2c, 0x38, 0x8f,
+0x24, 0x00, 0x84, 0x23, 0x80, 0x48, 0x84, 0x05, 0xb6, 0xbf, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0x70, 0xdd, 0x2f, 0x80, 0x48, 0x84, 0x24, 0x84, 0x05, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8e, 0x70, 0xdd, 0x2f, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x78, 0x84, 0x20, 0x44, 0x00,
+0x00, 0x9e, 0x4b, 0xe0, 0x1c, 0x01, 0x45, 0xc0, 0x00, 0x93, 0x44, 0x00, 0x00, 0x9f, 0x44, 0x10,
+0x00, 0x93, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0xf8, 0x15, 0xcf,
+0x80, 0x0f, 0xd5, 0x14, 0x92, 0x00, 0x84, 0x87, 0x9c, 0x01, 0x4c, 0x02, 0x7f, 0xfd, 0x9c, 0x49,
+0x84, 0x6a, 0x4c, 0x11, 0x80, 0x04, 0x84, 0x00, 0xd5, 0xf6, 0xb6, 0xbf, 0x84, 0x00, 0x44, 0x10,
+0x00, 0x9f, 0x50, 0x2f, 0x80, 0x3c, 0x4b, 0xe0, 0x18, 0x01, 0xf2, 0x0f, 0x44, 0x10, 0x00, 0x93,
+0xb4, 0xbf, 0x4c, 0x20, 0xc0, 0x04, 0x84, 0x20, 0xd5, 0xef, 0x87, 0x80, 0x46, 0xa0, 0x00, 0x06,
+0x58, 0xa5, 0x00, 0x78, 0x44, 0x40, 0x10, 0x00, 0x87, 0xc0, 0x15, 0xef, 0x80, 0x0e, 0xb6, 0xbf,
+0xf4, 0x81, 0x44, 0x10, 0x00, 0x1e, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x2a, 0x80, 0x3c, 0x44, 0x00,
+0x00, 0x9f, 0xdd, 0x2a, 0x44, 0x10, 0x00, 0x22, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x2a, 0xb5, 0x1f,
+0x46, 0x20, 0x00, 0x0a, 0x58, 0x21, 0x0f, 0x1c, 0xb4, 0x02, 0x44, 0x10, 0x00, 0x9f, 0x80, 0x48,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf3, 0x0e, 0x44, 0x10, 0x00, 0x21,
+0x44, 0x00, 0x00, 0x9e, 0x40, 0x81, 0xe0, 0x08, 0xdd, 0x2a, 0x46, 0x40, 0x00, 0x0a, 0x58, 0x42,
+0x0f, 0x1c, 0xb4, 0xff, 0xb4, 0x04, 0x80, 0x47, 0x44, 0x10, 0x00, 0x9f, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x44, 0x10, 0x00, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xf6, 0x0e,
+0xdd, 0x2a, 0x46, 0x50, 0x00, 0x0a, 0x58, 0x52, 0x8f, 0x1c, 0xb4, 0x3f, 0xb4, 0x05, 0x80, 0x41,
+0x44, 0x10, 0x00, 0x9f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf2, 0x0e,
+0x44, 0x10, 0x00, 0x1f, 0x44, 0x00, 0x00, 0x9e, 0x40, 0x73, 0x40, 0x08, 0x40, 0x61, 0x20, 0x08,
+0xdd, 0x2a, 0x46, 0x30, 0x00, 0x0a, 0x58, 0x31, 0x8f, 0x1c, 0xb4, 0x9f, 0xb4, 0x03, 0x80, 0x44,
+0x44, 0x10, 0x00, 0x9f, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0x40, 0x04,
+0x1c, 0x00, 0x04, 0x8f, 0x80, 0x0e, 0x54, 0x3e, 0x00, 0xff, 0x40, 0x50, 0x20, 0x00, 0x98, 0xae,
+0xf4, 0x01, 0xb4, 0xbf, 0xe6, 0x62, 0xe8, 0x10, 0x46, 0x10, 0x08, 0x00, 0x40, 0x01, 0x04, 0x02,
+0xc0, 0x10, 0x46, 0x80, 0x0f, 0xff, 0x58, 0x84, 0x0f, 0xff, 0x46, 0x7f, 0xf0, 0x00, 0x40, 0x61,
+0x20, 0x02, 0x98, 0x37, 0xd5, 0x07, 0x87, 0xc4, 0x4c, 0x3f, 0x40, 0x04, 0x80, 0x02, 0xd5, 0x1d,
+0x80, 0x02, 0xcb, 0x05, 0x40, 0x30, 0x10, 0x16, 0xf3, 0x84, 0xd5, 0x1b, 0x84, 0x21, 0x4c, 0x30,
+0xc0, 0x06, 0x40, 0x20, 0x10, 0x16, 0xf2, 0x85, 0xd5, 0x14, 0x84, 0xc2, 0x4c, 0x33, 0x40, 0x06,
+0x40, 0x01, 0x30, 0x09, 0xf0, 0x86, 0xd5, 0x0d, 0x84, 0xe3, 0x4c, 0x33, 0xc0, 0x07, 0x40, 0x81,
+0x30, 0x09, 0x14, 0x8f, 0x80, 0x08, 0xd5, 0x05, 0x41, 0xe0, 0x10, 0x16, 0x15, 0xef, 0x80, 0x03,
+0x51, 0xce, 0x00, 0x01, 0x84, 0x65, 0x4d, 0xc1, 0xff, 0x59, 0xf1, 0x06, 0xf4, 0x04, 0x42, 0x12,
+0x10, 0x75, 0xf1, 0x8f, 0x5c, 0xf0, 0xa7, 0x10, 0xe8, 0x38, 0x5c, 0xf0, 0x80, 0x65, 0xe8, 0x04,
+0x50, 0x04, 0x80, 0x09, 0xd5, 0x2d, 0x5c, 0xf0, 0x80, 0x9f, 0xe8, 0x04, 0x50, 0x04, 0x80, 0x08,
+0xd5, 0x27, 0x5c, 0xf0, 0x80, 0xfc, 0xe8, 0x04, 0x50, 0x04, 0x80, 0x07, 0xd5, 0x21, 0x5c, 0xf0,
+0x81, 0x8f, 0xe8, 0x04, 0x50, 0x04, 0x80, 0x06, 0xd5, 0x1b, 0x5c, 0xf0, 0x82, 0x77, 0xe8, 0x04,
+0x50, 0x04, 0x80, 0x05, 0xd5, 0x15, 0x5c, 0xf0, 0x83, 0xe9, 0xe8, 0x04, 0x50, 0x04, 0x80, 0x04,
+0xd5, 0x0f, 0x5c, 0xf0, 0x86, 0x31, 0xe8, 0x04, 0x50, 0x04, 0x80, 0x03, 0xd5, 0x09, 0x5c, 0xf0,
+0x89, 0xd0, 0xe8, 0x04, 0x50, 0x04, 0x80, 0x02, 0xd5, 0x03, 0x50, 0x04, 0x80, 0x01, 0x54, 0x90,
+0x00, 0xff, 0xe7, 0x2b, 0x4e, 0xf3, 0xfe, 0xcb, 0xf0, 0x04, 0xf6, 0x06, 0x44, 0x80, 0x00, 0x64,
+0x42, 0x60, 0x00, 0x75, 0x46, 0x70, 0x00, 0x06, 0x58, 0x73, 0x80, 0x5c, 0x42, 0x03, 0x20, 0x24,
+0x4b, 0xe0, 0x1c, 0x01, 0xf1, 0x08, 0xf2, 0x05, 0x80, 0xc0, 0x42, 0x11, 0x08, 0x75, 0x42, 0x00,
+0xa0, 0x24, 0x4b, 0xe0, 0x1c, 0x01, 0x50, 0x53, 0x7c, 0x18, 0x80, 0x60, 0x5c, 0xf2, 0x81, 0x91,
+0xe8, 0x48, 0x9b, 0x30, 0x5e, 0xf2, 0x00, 0x71, 0xe8, 0x44, 0x5e, 0xf2, 0x7f, 0x90, 0xe9, 0x41,
+0xf0, 0x04, 0x51, 0xe0, 0x00, 0x20, 0x5c, 0xff, 0x00, 0x41, 0xe8, 0x3b, 0xf1, 0x05, 0x50, 0x40,
+0x80, 0x20, 0x5c, 0xf2, 0x00, 0x41, 0xe8, 0x35, 0x44, 0x70, 0x03, 0xe8, 0x42, 0x21, 0x9c, 0x24,
+0x04, 0x8f, 0x80, 0x03, 0x44, 0x50, 0x59, 0x88, 0x42, 0x80, 0x80, 0x75, 0x40, 0x01, 0x18, 0x96,
+0x42, 0x84, 0x14, 0x24, 0x42, 0x41, 0x98, 0x24, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8e, 0x08,
+0x46, 0x30, 0x00, 0x0d, 0x58, 0x31, 0x8e, 0x04, 0x51, 0xe0, 0x7c, 0x18, 0x40, 0x24, 0x10, 0xd6,
+0x50, 0x70, 0x03, 0xe8, 0x40, 0x6f, 0x20, 0x08, 0x40, 0x43, 0x1c, 0xf6, 0x50, 0x11, 0x00, 0x0c,
+0xb6, 0x45, 0xb6, 0x83, 0xe6, 0x39, 0xe9, 0x03, 0x84, 0x20, 0xb6, 0x25, 0x9c, 0xe7, 0xe6, 0x6f,
+0xe9, 0x15, 0x84, 0x00, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0e, 0x04, 0xb6, 0x06, 0xd5, 0x0e,
+0x87, 0xc0, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8e, 0x08, 0x46, 0x40, 0x00, 0x0d, 0x58, 0x42,
+0x0e, 0x04, 0x15, 0xe2, 0x80, 0x00, 0x15, 0xe2, 0x00, 0x00, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63,
+0x00, 0x78, 0x84, 0x23, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x50, 0x2f, 0x80, 0x3c, 0x44, 0x10,
+0x00, 0x9f, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf5, 0x0f,
+0x44, 0x00, 0x00, 0x9f, 0x58, 0x12, 0x80, 0x07, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x37, 0x44, 0x00,
+0x00, 0x9e, 0xdd, 0x26, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x04, 0xb4, 0x80, 0x44, 0x00,
+0x00, 0x9f, 0x54, 0x12, 0x00, 0x3f, 0xdd, 0x26, 0x44, 0x10, 0x00, 0x35, 0x44, 0x00, 0x00, 0x9e,
+0xdd, 0x26, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8e, 0x08, 0xb4, 0x61, 0x44, 0x00, 0x00, 0x9f,
+0x54, 0x11, 0x80, 0x3f, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0x9e, 0xdd, 0x26, 0x44, 0x00,
+0x00, 0x9f, 0x84, 0x20, 0xdd, 0x26, 0xf2, 0x02, 0x4e, 0x23, 0x00, 0x9e, 0x46, 0x60, 0x04, 0x10,
+0x47, 0xe0, 0x00, 0x92, 0x58, 0x63, 0x05, 0x0c, 0x59, 0xef, 0x00, 0x18, 0x15, 0xe3, 0x00, 0x00,
+0xf1, 0x02, 0x92, 0x00, 0x84, 0x47, 0x9c, 0x49, 0x4c, 0x11, 0x7f, 0xfd, 0x46, 0x30, 0x04, 0x10,
+0x46, 0x10, 0x00, 0x92, 0x58, 0x31, 0x85, 0x0c, 0x58, 0x10, 0x80, 0x08, 0xb6, 0x23, 0x84, 0x00,
+0x92, 0x00, 0x84, 0x87, 0x9c, 0x01, 0x4c, 0x02, 0x7f, 0xfd, 0x46, 0x00, 0x04, 0x10, 0x46, 0x50,
+0x00, 0x92, 0x58, 0x00, 0x05, 0x0c, 0xb6, 0xa0, 0x84, 0x00, 0x92, 0x00, 0x84, 0xc7, 0x9c, 0x01,
+0x4c, 0x03, 0x7f, 0xfd, 0xf1, 0x10, 0x46, 0x60, 0x00, 0x06, 0x58, 0x63, 0x00, 0x78, 0x44, 0x00,
+0x00, 0x17, 0xdd, 0x26, 0xf1, 0x11, 0x84, 0x04, 0xdd, 0x26, 0x84, 0x20, 0x44, 0x00, 0x00, 0xf4,
+0xdd, 0x26, 0x44, 0x10, 0x00, 0x15, 0x50, 0x2f, 0x80, 0x3c, 0x84, 0x00, 0x46, 0xf0, 0x00, 0x05,
+0x58, 0xf7, 0x8e, 0xf8, 0xdd, 0x2f, 0xf3, 0x0f, 0x44, 0x00, 0x00, 0x15, 0x58, 0x21, 0x80, 0x01,
+0xf2, 0x8f, 0x80, 0x22, 0xdd, 0x26, 0x84, 0x00, 0xd5, 0x0a, 0x92, 0x00, 0x87, 0xc7, 0x9c, 0x49,
+0x4c, 0x1f, 0x7f, 0xfd, 0x9c, 0x01, 0x84, 0x2a, 0x4c, 0x00, 0x80, 0x04, 0x84, 0x20, 0xd5, 0xf6,
+0xf3, 0x0f, 0x44, 0x00, 0x00, 0x15, 0x54, 0x21, 0x80, 0xfe, 0x80, 0x22, 0xf2, 0x8f, 0x46, 0xf0,
+0x00, 0x06, 0x58, 0xf7, 0x80, 0x78, 0xdd, 0x2f, 0x46, 0x40, 0x04, 0x10, 0x58, 0x42, 0x05, 0x04,
+0x84, 0x20, 0xb6, 0x24, 0x46, 0x50, 0x04, 0x10, 0xf6, 0x09, 0x58, 0x52, 0x85, 0x0c, 0xb6, 0xc5,
+0x46, 0x60, 0x00, 0x05, 0x58, 0x63, 0x0e, 0x70, 0xf0, 0x07, 0xb6, 0x04, 0x84, 0x04, 0xf2, 0x19,
+0xdd, 0x26, 0xf2, 0x18, 0x44, 0x10, 0x00, 0x13, 0x84, 0x04, 0xdd, 0x26, 0xf2, 0x17, 0x44, 0x10,
+0x00, 0x11, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x16, 0x44, 0x10, 0x00, 0x12, 0x84, 0x05, 0xdd, 0x26,
+0xf2, 0x15, 0x44, 0x10, 0x00, 0x13, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x14, 0x44, 0x10, 0x00, 0x14,
+0x84, 0x05, 0xdd, 0x26, 0xf2, 0x13, 0x84, 0x23, 0x84, 0x05, 0xdd, 0x26, 0xf2, 0x12, 0x84, 0x05,
+0x84, 0x24, 0xdd, 0x26, 0xec, 0x6c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3b, 0xff, 0xfc, 0xbc,
+0xef, 0xfc, 0x96, 0x49, 0xe6, 0x24, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x61, 0xb4, 0x20, 0x84, 0xa5,
+0xd1, 0x2c, 0xe4, 0x26, 0xe8, 0x09, 0x84, 0xa3, 0xd1, 0x17, 0xe4, 0x24, 0xe8, 0x1b, 0x84, 0x01,
+0x4c, 0x10, 0x40, 0x55, 0xd5, 0x0b, 0x84, 0x47, 0x4c, 0x11, 0x00, 0x3b, 0xe0, 0x22, 0xe9, 0x26,
+0x84, 0xa8, 0xd1, 0x3e, 0x84, 0xa9, 0xd1, 0x45, 0xd5, 0x49, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7,
+0x85, 0xe8, 0xdd, 0x2f, 0xd5, 0x43, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x80, 0xd0, 0xdd, 0x2f,
+0xd5, 0x3d, 0x9c, 0x44, 0x05, 0xe0, 0x80, 0x00, 0x54, 0x0f, 0x00, 0x01, 0x46, 0xf0, 0x00, 0x08,
+0x58, 0xf7, 0x84, 0x4c, 0xdd, 0x2f, 0xd5, 0x32, 0x9c, 0xc4, 0xb4, 0x43, 0x96, 0x14, 0x46, 0xf0,
+0x00, 0x08, 0x58, 0xf7, 0x8c, 0x14, 0xdd, 0x2f, 0xd5, 0x29, 0x9c, 0x04, 0x05, 0xe0, 0x00, 0x00,
+0xb4, 0x20, 0xb4, 0x80, 0x40, 0x50, 0xa0, 0x09, 0x54, 0x0f, 0x00, 0xff, 0x96, 0x68, 0x42, 0x22,
+0x40, 0x0b, 0x46, 0xf0, 0x00, 0x07, 0x58, 0xf7, 0x82, 0x78, 0xdd, 0x2f, 0xd5, 0x17, 0x9c, 0x84,
+0xb4, 0x02, 0x46, 0xf0, 0x00, 0x06, 0x58, 0xf7, 0x8a, 0x38, 0xdd, 0x2f, 0xd5, 0x0f, 0x9d, 0x04,
+0xb4, 0x64, 0x96, 0x1c, 0x46, 0xf0, 0x00, 0x09, 0x58, 0xf7, 0x84, 0xcc, 0xdd, 0x2f, 0xd5, 0x06,
+0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8f, 0xbc, 0xdd, 0x2f, 0x84, 0x00, 0xec, 0x04, 0x3b, 0xff,
+0xfc, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc, 0xef, 0xc4, 0x84, 0xa1, 0x46, 0x40, 0x00, 0x0d,
+0x58, 0x42, 0x0e, 0x3a, 0x84, 0x60, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x3b, 0xaf, 0x60,
+0x46, 0x60, 0x04, 0x00, 0xae, 0xc0, 0x58, 0x63, 0x02, 0x14, 0x05, 0xc3, 0x00, 0x00, 0x45, 0xef,
+0xef, 0xff, 0x40, 0xae, 0x78, 0x02, 0xb7, 0x46, 0x46, 0x70, 0x04, 0x00, 0x58, 0x73, 0x84, 0x18,
+0xb5, 0x27, 0x44, 0x6f, 0xff, 0x7f, 0x40, 0x84, 0x98, 0x02, 0xb7, 0x07, 0x46, 0x30, 0x04, 0x00,
+0x58, 0x31, 0x82, 0x58, 0xb4, 0xa3, 0x46, 0x7f, 0x0f, 0xff, 0x58, 0x73, 0x8f, 0xff, 0x47, 0xe0,
+0xa0, 0x00, 0x54, 0xa0, 0x80, 0xff, 0x40, 0x12, 0x9c, 0x02, 0x40, 0x40, 0xf8, 0x04, 0x84, 0x05,
+0xb6, 0x83, 0x4c, 0xa0, 0x41, 0x64, 0x47, 0xc0, 0x04, 0x10, 0x15, 0xcf, 0x80, 0x04, 0x47, 0xe0,
+0x0c, 0x2d, 0x15, 0xef, 0x80, 0x01, 0x05, 0xef, 0x80, 0x04, 0x46, 0x00, 0x04, 0x10, 0x59, 0xef,
+0x07, 0x20, 0x15, 0xef, 0x80, 0x04, 0x05, 0xef, 0x80, 0x01, 0x58, 0x00, 0x00, 0x80, 0x59, 0xef,
+0x0f, 0xc0, 0x15, 0xef, 0x80, 0x01, 0x46, 0x10, 0x04, 0x10, 0x05, 0xe0, 0x00, 0x00, 0x58, 0x10,
+0x80, 0xc0, 0x15, 0xef, 0x80, 0x0b, 0x46, 0x50, 0x04, 0x10, 0x05, 0xe0, 0x80, 0x00, 0x58, 0x52,
+0x80, 0x04, 0x15, 0xef, 0x80, 0x0a, 0x46, 0x60, 0x04, 0x10, 0x05, 0xe2, 0x80, 0x00, 0x58, 0x63,
+0x07, 0x08, 0x15, 0xef, 0x80, 0x09, 0x46, 0x90, 0x04, 0x10, 0x05, 0xe3, 0x00, 0x00, 0x58, 0x94,
+0x80, 0x20, 0x15, 0xef, 0x80, 0x08, 0x46, 0x30, 0x04, 0x10, 0x05, 0xe4, 0x80, 0x00, 0x58, 0x31,
+0x80, 0x78, 0x15, 0xef, 0x80, 0x07, 0x46, 0x4f, 0x02, 0x10, 0x05, 0xe1, 0x80, 0x00, 0x15, 0xef,
+0x80, 0x06, 0x05, 0xef, 0x80, 0x04, 0x46, 0x7f, 0xf0, 0x00, 0x05, 0xef, 0x00, 0x00, 0x46, 0x80,
+0x04, 0x10, 0x47, 0xc0, 0x18, 0x00, 0x15, 0xef, 0x80, 0x05, 0x58, 0x84, 0x00, 0x3c, 0xb6, 0x80,
+0x44, 0x40, 0x00, 0x10, 0x44, 0x00, 0x00, 0xc8, 0x59, 0xce, 0x00, 0x80, 0xb6, 0xe1, 0xb6, 0x85,
+0xb6, 0x06, 0x15, 0xc4, 0x00, 0x00, 0x47, 0xe0, 0x00, 0x0d, 0x59, 0xef, 0x0d, 0x78, 0xf7, 0x01,
+0x84, 0xc1, 0xb6, 0xe9, 0xb6, 0xde, 0xf2, 0x82, 0xf3, 0x83, 0x46, 0x70, 0x00, 0x04, 0x58, 0x73,
+0x83, 0x40, 0x80, 0x0a, 0xdd, 0x27, 0x46, 0x10, 0x0c, 0x2d, 0x58, 0x10, 0x8f, 0x80, 0xb6, 0x29,
+0x46, 0x28, 0x00, 0x00, 0xf5, 0x03, 0xb6, 0x45, 0x46, 0x00, 0x19, 0xc0, 0xf3, 0x04, 0x84, 0x84,
+0x58, 0x00, 0x00, 0x80, 0xb6, 0x83, 0x46, 0x60, 0x19, 0xc0, 0xb6, 0x08, 0x58, 0x63, 0x00, 0x90,
+0x80, 0x0a, 0xdd, 0x27, 0xb6, 0xc8, 0x84, 0x0a, 0xdd, 0x27, 0x46, 0x10, 0x19, 0x40, 0x58, 0x10,
+0x80, 0x90, 0xb6, 0x28, 0x84, 0x0a, 0xdd, 0x27, 0x46, 0x20, 0x18, 0x40, 0x58, 0x21, 0x00, 0x90,
+0xb6, 0x48, 0x84, 0x0a, 0xdd, 0x27, 0x46, 0x00, 0x04, 0x00, 0xf2, 0x02, 0x58, 0x00, 0x00, 0x88,
+0xb4, 0x20, 0xc2, 0x09, 0x46, 0x3f, 0xf0, 0x00, 0x40, 0x60, 0x8c, 0x02, 0x98, 0x96, 0x42, 0x81,
+0x7c, 0x08, 0xb7, 0x00, 0x64, 0x00, 0x00, 0x00, 0x84, 0x00, 0x46, 0x40, 0x00, 0x0d, 0x58, 0x42,
+0x0e, 0x3a, 0x46, 0x80, 0x00, 0x0d, 0x58, 0x84, 0x0e, 0x3b, 0xae, 0x20, 0x46, 0x30, 0x04, 0x00,
+0x10, 0x04, 0x00, 0x00, 0x58, 0x31, 0x82, 0x14, 0xb4, 0x23, 0x47, 0xe0, 0x04, 0x00, 0x58, 0x50,
+0x90, 0x00, 0xb6, 0xa3, 0x59, 0xef, 0x04, 0x18, 0xb4, 0xde, 0x46, 0x80, 0x04, 0x10, 0x46, 0x70,
+0x19, 0x40, 0x58, 0x84, 0x00, 0x3c, 0x58, 0x23, 0x00, 0x80, 0x58, 0x73, 0x80, 0x90, 0xb6, 0x5e,
+0xb6, 0xe8, 0x44, 0x00, 0x08, 0x98, 0x46, 0x70, 0x00, 0x04, 0x58, 0x73, 0x83, 0x40, 0x4b, 0xe0,
+0x1c, 0x01, 0x46, 0x40, 0x19, 0xc0, 0x58, 0x42, 0x00, 0x90, 0xb6, 0x88, 0x84, 0x0a, 0x4b, 0xe0,
+0x1c, 0x01, 0x46, 0x00, 0x19, 0x80, 0x46, 0x50, 0x04, 0x10, 0x46, 0x10, 0x0c, 0x0d, 0x58, 0x00,
+0x00, 0x90, 0x58, 0x52, 0x80, 0x20, 0x58, 0x10, 0x8f, 0xc0, 0xb6, 0x08, 0x46, 0x80, 0x04, 0x00,
+0xb6, 0x25, 0x58, 0x84, 0x00, 0x20, 0x84, 0xc0, 0xb4, 0xa8, 0x46, 0x30, 0x04, 0x00, 0xf5, 0x8d,
+0xf2, 0x0d, 0x84, 0x04, 0x41, 0xe1, 0x0c, 0x02, 0x4f, 0xe3, 0x00, 0x0a, 0x4b, 0xe0, 0x1c, 0x01,
+0x44, 0x10, 0x07, 0xd1, 0x4c, 0x60, 0x80, 0x04, 0x9d, 0xb1, 0xd5, 0xef, 0x46, 0x70, 0x04, 0x10,
+0x46, 0x60, 0x0c, 0x0d, 0x58, 0x73, 0x80, 0x20, 0x58, 0x63, 0x0f, 0xc8, 0xb6, 0xc7, 0x46, 0x70,
+0x04, 0x00, 0x58, 0x73, 0x80, 0x20, 0x84, 0xc0, 0x46, 0x80, 0x00, 0x04, 0x58, 0x84, 0x03, 0x40,
+0xb4, 0x67, 0x46, 0x20, 0x08, 0x00, 0xf3, 0x8d, 0x05, 0xef, 0x80, 0x0d, 0x84, 0x04, 0x40, 0x4f,
+0x08, 0x02, 0xcc, 0x09, 0x4b, 0xe0, 0x20, 0x01, 0x44, 0x00, 0x0b, 0xb9, 0x4c, 0x60, 0x00, 0x04,
+0x9d, 0xb1, 0xd5, 0xef, 0x46, 0x70, 0x04, 0x10, 0x58, 0x73, 0x80, 0x3c, 0x84, 0x20, 0xb6, 0x27,
+0x46, 0x80, 0x04, 0x10, 0x05, 0xef, 0x80, 0x0b, 0x58, 0x84, 0x00, 0x80, 0x15, 0xe4, 0x00, 0x00,
+0x46, 0x60, 0x04, 0x10, 0xf7, 0x0a, 0x58, 0x63, 0x00, 0xc0, 0xb6, 0xe6, 0x46, 0x50, 0x04, 0x10,
+0xf6, 0x09, 0x58, 0x52, 0x80, 0x04, 0xb6, 0xc5, 0x46, 0x40, 0x04, 0x10, 0xf7, 0x08, 0x58, 0x42,
+0x07, 0x08, 0xb6, 0xe4, 0x46, 0x30, 0x04, 0x10, 0x05, 0xef, 0x80, 0x07, 0x58, 0x31, 0x80, 0x20,
+0x15, 0xe1, 0x80, 0x00, 0x46, 0x20, 0x04, 0x10, 0xf3, 0x06, 0x58, 0x21, 0x00, 0x78, 0xb6, 0x62,
+0x46, 0x00, 0x04, 0x10, 0xf4, 0x05, 0x58, 0x00, 0x07, 0x20, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52,
+0x8d, 0x78, 0xb6, 0x80, 0xb6, 0x25, 0x48, 0x00, 0x01, 0x34, 0x51, 0xc5, 0x7f, 0xff, 0x54, 0x9e,
+0x00, 0xff, 0xe7, 0x24, 0x4e, 0xf2, 0x01, 0x2d, 0x46, 0x40, 0x04, 0x00, 0x58, 0x42, 0x00, 0x64,
+0x46, 0x60, 0x04, 0x00, 0xb4, 0xa4, 0x58, 0x63, 0x00, 0x38, 0x46, 0x31, 0x00, 0x00, 0xb4, 0x26,
+0x44, 0x0f, 0xe0, 0x00, 0x40, 0x82, 0x8c, 0x02, 0x40, 0x40, 0x80, 0x02, 0x4e, 0x82, 0x00, 0x05,
+0x58, 0x42, 0x00, 0x13, 0xd5, 0x03, 0x58, 0x42, 0x00, 0x27, 0x46, 0x80, 0x04, 0x00, 0x58, 0x84,
+0x00, 0x38, 0xb6, 0x88, 0x46, 0x70, 0x04, 0x00, 0x58, 0x73, 0x82, 0x08, 0xb5, 0x07, 0x05, 0xc3,
+0x80, 0x00, 0x45, 0xef, 0xef, 0x37, 0x40, 0x9e, 0x78, 0x02, 0xb7, 0x27, 0xe7, 0x43, 0xe9, 0x13,
+0x46, 0x50, 0x04, 0x00, 0x58, 0x52, 0x80, 0x80, 0xb4, 0xc5, 0x44, 0x1f, 0xff, 0xef, 0x40, 0x33,
+0x04, 0x02, 0xb6, 0x65, 0x84, 0x05, 0xf2, 0x82, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x83, 0x40,
+0xdd, 0x2f, 0xf2, 0x02, 0x47, 0xc0, 0x04, 0x00, 0x46, 0x60, 0x04, 0x00, 0x59, 0xce, 0x00, 0xc0,
+0x58, 0x63, 0x00, 0x80, 0xb5, 0x3c, 0xb4, 0xe6, 0x84, 0x3d, 0x40, 0x43, 0x84, 0x02, 0xb6, 0x86,
+0x84, 0x05, 0xb4, 0xbc, 0x41, 0xe2, 0x84, 0x02, 0x15, 0xee, 0x00, 0x00, 0xf2, 0x82, 0x46, 0xf0,
+0x00, 0x04, 0x58, 0xf7, 0x83, 0x40, 0xdd, 0x2f, 0xb4, 0x46, 0x87, 0xde, 0x40, 0x31, 0x78, 0x02,
+0xb6, 0x66, 0x46, 0x10, 0x04, 0x00, 0xb4, 0xfc, 0x58, 0x10, 0x82, 0x14, 0x40, 0x73, 0xf8, 0x02,
+0xb6, 0xfc, 0x46, 0x20, 0x04, 0x00, 0xb4, 0x81, 0x58, 0x21, 0x02, 0x58, 0x42, 0x02, 0x3c, 0x08,
+0xb6, 0x01, 0x46, 0x6f, 0x0f, 0xff, 0xb4, 0xa2, 0x58, 0x63, 0x0f, 0xff, 0x47, 0xc0, 0xa0, 0x00,
+0x40, 0x42, 0x98, 0x02, 0x40, 0x02, 0x70, 0x04, 0xb6, 0x02, 0x46, 0x30, 0x04, 0x00, 0xf2, 0x02,
+0x58, 0x31, 0x80, 0x88, 0xb4, 0x83, 0xc2, 0x0c, 0x46, 0x7f, 0xf0, 0x00, 0x40, 0x62, 0x1c, 0x02,
+0x47, 0xe8, 0x00, 0x00, 0x41, 0xc1, 0x18, 0x00, 0x40, 0x0e, 0x78, 0x04, 0xb6, 0x03, 0x47, 0xc0,
+0x04, 0x00, 0x59, 0xce, 0x00, 0x80, 0xb4, 0x3c, 0x46, 0x50, 0x04, 0x00, 0x58, 0x30, 0x80, 0x40,
+0xb6, 0x7c, 0x58, 0x52, 0x80, 0x04, 0xb4, 0xc5, 0x84, 0x1b, 0x40, 0x43, 0x00, 0x02, 0xb6, 0x85,
+0x46, 0x30, 0x04, 0x00, 0x58, 0x31, 0x80, 0x20, 0xb4, 0x23, 0x46, 0x00, 0x04, 0x00, 0x58, 0x50,
+0x90, 0x00, 0xb6, 0xa3, 0x58, 0x00, 0x00, 0x3c, 0xb4, 0xdc, 0x46, 0x1f, 0x00, 0x00, 0x58, 0x43,
+0x00, 0x20, 0xb6, 0x9c, 0xb4, 0x60, 0x84, 0xa3, 0x40, 0x31, 0x84, 0x02, 0x4c, 0xa2, 0x80, 0x0d,
+0x87, 0x84, 0x4c, 0xae, 0x00, 0x06, 0x84, 0xa2, 0x4c, 0xa2, 0xc0, 0x0f, 0xd5, 0x09, 0x44, 0x70,
+0xef, 0x01, 0x98, 0xdf, 0xd5, 0x0c, 0x45, 0xe0, 0xe3, 0x01, 0x88, 0x7e, 0xd5, 0x08, 0x44, 0x40,
+0xc0, 0x01, 0x98, 0xdc, 0xd5, 0x04, 0x44, 0x60, 0x80, 0x01, 0x98, 0xde, 0x46, 0x10, 0x04, 0x00,
+0x58, 0x10, 0x80, 0x3c, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8e, 0x38, 0x84, 0x00, 0xb6, 0x61,
+0xae, 0x28, 0xa6, 0xe8, 0xcb, 0x04, 0x64, 0x00, 0x00, 0x20, 0xd5, 0xfc, 0x44, 0x60, 0x03, 0xe8,
+0x40, 0x21, 0x18, 0x77, 0x46, 0x50, 0x00, 0x0d, 0x58, 0x52, 0x8d, 0x68, 0xb4, 0xc5, 0x46, 0x40,
+0x04, 0x00, 0x58, 0x42, 0x02, 0x14, 0x47, 0xc0, 0x04, 0x00, 0x59, 0xce, 0x04, 0x18, 0x98, 0xd6,
+0xb6, 0x65, 0xb4, 0x24, 0x58, 0x00, 0x90, 0x00, 0xb6, 0x04, 0xb4, 0xbc, 0x58, 0x22, 0x80, 0x80,
+0xb6, 0x5c, 0xe7, 0x43, 0xe9, 0x09, 0x47, 0xc0, 0x04, 0x00, 0x59, 0xce, 0x00, 0x80, 0xb4, 0x9c,
+0x58, 0x02, 0x00, 0x10, 0xb6, 0x1c, 0x47, 0xc0, 0x04, 0x00, 0x59, 0xce, 0x00, 0x80, 0xb4, 0x1c,
+0x46, 0x20, 0x04, 0x00, 0x58, 0x10, 0x00, 0x02, 0xb6, 0x3c, 0x58, 0x21, 0x00, 0xc0, 0xb4, 0x7c,
+0x46, 0x10, 0x04, 0x00, 0x58, 0x51, 0x80, 0x01, 0xb6, 0xbc, 0xb7, 0x22, 0x58, 0x10, 0x80, 0x20,
+0xb4, 0x01, 0x44, 0x4f, 0xef, 0xff, 0x40, 0x30, 0x10, 0x02, 0xb6, 0x61, 0x46, 0x20, 0x04, 0x00,
+0xb4, 0x9c, 0x46, 0x10, 0x04, 0x00, 0x44, 0x5f, 0xff, 0xdf, 0x58, 0x21, 0x00, 0x3c, 0x40, 0x02,
+0x14, 0x02, 0x58, 0x10, 0x82, 0x08, 0x84, 0x60, 0xb6, 0x1c, 0xb6, 0x62, 0xb7, 0x01, 0x84, 0x60,
+0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x3a, 0x46, 0x10, 0x00, 0x0d, 0x58, 0x10, 0x8e, 0x3b,
+0xae, 0xc0, 0x46, 0x40, 0x04, 0x00, 0xae, 0xc8, 0x58, 0x42, 0x00, 0x20, 0xb4, 0xa4, 0x58, 0x22,
+0x80, 0x40, 0xb6, 0x44, 0xec, 0x3c, 0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xa0, 0xbc,
+0xef, 0xf8, 0x46, 0x70, 0x04, 0x00, 0x58, 0x73, 0x82, 0x14, 0x84, 0xc0, 0x44, 0x30, 0x80, 0x06,
+0xb5, 0x07, 0xb6, 0xc7, 0xb6, 0x67, 0x96, 0x48, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x09, 0x58, 0xf7,
+0x8c, 0xd4, 0xdd, 0x2f, 0xb7, 0x07, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x07, 0x81, 0x88, 0x84, 0xa1,
+0xd8, 0x29, 0xf6, 0x81, 0x46, 0x70, 0x00, 0x05, 0x58, 0x73, 0x8e, 0x70, 0x84, 0x24, 0x84, 0x4a,
+0x80, 0x06, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x25, 0x44, 0x20, 0x00, 0x20, 0x80, 0x06, 0x4b, 0xe0,
+0x1c, 0x01, 0x84, 0x24, 0x40, 0x2f, 0x84, 0x00, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8d, 0xb8, 0xdd, 0x2f, 0xf5, 0x01, 0x80, 0x06, 0x58, 0x42, 0x80, 0x80, 0xf4, 0x81, 0x80, 0x44,
+0x84, 0x24, 0x4b, 0xe0, 0x1c, 0x01, 0x84, 0x02, 0x46, 0xf0, 0x00, 0x02, 0x58, 0xf7, 0x8b, 0x1c,
+0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0xa0, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x98, 0xbc,
+0x96, 0x49, 0xe6, 0x28, 0xe8, 0x03, 0x84, 0x01, 0xd5, 0x7c, 0x80, 0x60, 0xa2, 0x99, 0x44, 0x40,
+0x00, 0x30, 0xb4, 0x23, 0x4c, 0x22, 0x40, 0x06, 0x80, 0x02, 0x96, 0x48, 0x84, 0x40, 0xd5, 0x3d,
+0x44, 0x50, 0x00, 0x32, 0xda, 0x40, 0x87, 0xc1, 0x46, 0xf0, 0x00, 0x0d, 0x11, 0xe7, 0x8e, 0x39,
+0x50, 0x30, 0x00, 0x08, 0x50, 0x20, 0x00, 0x0c, 0x84, 0x01, 0xb4, 0x83, 0xb4, 0x62, 0x4c, 0x10,
+0x00, 0x64, 0x84, 0xa2, 0xd9, 0x04, 0x44, 0x00, 0x00, 0xc8, 0xd5, 0x12, 0x84, 0x03, 0x4c, 0x10,
+0x00, 0x0e, 0x84, 0xa4, 0xd1, 0x0b, 0x56, 0x60, 0x80, 0x05, 0x45, 0xe0, 0x15, 0x7c, 0x84, 0xa0,
+0x40, 0x02, 0x98, 0x1b, 0x40, 0x0f, 0x18, 0x1a, 0xd5, 0x03, 0x44, 0x00, 0x07, 0xd0, 0x47, 0xe0,
+0x04, 0x11, 0x04, 0x2f, 0x00, 0x49, 0x44, 0x50, 0x03, 0xe8, 0x43, 0xe1, 0x94, 0x24, 0x95, 0x56,
+0x50, 0x22, 0xd1, 0x20, 0x50, 0x3f, 0x7c, 0x18, 0x42, 0x21, 0x90, 0x73, 0x9a, 0x90, 0x4e, 0x27,
+0x00, 0x38, 0x96, 0x48, 0x44, 0x00, 0x00, 0x32, 0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7, 0x82, 0x9c,
+0xdd, 0x2f, 0xd5, 0x2e, 0x44, 0x10, 0x00, 0x33, 0x4c, 0x20, 0xc0, 0x08, 0x84, 0x20, 0x46, 0x00,
+0x00, 0x0d, 0x58, 0x00, 0x0e, 0x39, 0xd5, 0x23, 0x44, 0x50, 0x00, 0x34, 0xda, 0x18, 0x50, 0x40,
+0x00, 0x08, 0xb4, 0x43, 0x51, 0xe0, 0x00, 0x10, 0xb4, 0x64, 0x50, 0x10, 0x00, 0x0c, 0xb4, 0x01,
+0x46, 0x50, 0x00, 0x0e, 0x58, 0x52, 0x81, 0x88, 0xb4, 0x1e, 0x84, 0x01, 0xa8, 0xea, 0xae, 0x28,
+0xae, 0xac, 0x46, 0x60, 0x04, 0x11, 0x04, 0x03, 0x00, 0x49, 0xd5, 0x0a, 0x9d, 0x4a, 0xd2, 0x02,
+0xd5, 0x07, 0x84, 0x20, 0x46, 0x00, 0x00, 0x0e, 0x58, 0x00, 0x01, 0x88, 0xae, 0x40, 0x84, 0x00,
+0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x84, 0x02, 0xd5, 0xb3, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc,
+0xef, 0xf4, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70, 0xdd, 0x2f,
+0x46, 0xf0, 0x00, 0x0d, 0x04, 0x17, 0x83, 0xca, 0x54, 0x70, 0x80, 0x02, 0xc7, 0x04, 0x42, 0x10,
+0x80, 0x09, 0x84, 0xe1, 0xf0, 0x01, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63, 0x0e, 0x74, 0x14, 0x13,
+0x00, 0x2d, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84, 0xdd, 0x2f, 0xc7, 0x07, 0x80, 0x06,
+0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0x2c, 0xdd, 0x2f, 0xec, 0x0c, 0x3a, 0x6f, 0x9c, 0x84,
+0xdd, 0x9e, 0x92, 0x00, 0x3a, 0x6f, 0x9c, 0xbc, 0xef, 0xf4, 0x46, 0x60, 0x00, 0x0d, 0x58, 0x63,
+0x0e, 0x74, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x70, 0xdd, 0x2f,
+0x04, 0x73, 0x00, 0x2d, 0xf0, 0x01, 0x97, 0xfc, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84,
+0xdd, 0x2f, 0xc7, 0x07, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xb0, 0xdd, 0x2f,
+0xec, 0x0c, 0x3a, 0x6f, 0x9c, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0x98, 0xbc, 0xef, 0xf8, 0x46, 0x60,
+0x00, 0x0d, 0x58, 0x63, 0x0e, 0x74, 0x50, 0x0f, 0x80, 0x04, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7,
+0x8a, 0x70, 0xdd, 0x2f, 0x04, 0x33, 0x00, 0x2d, 0xf0, 0x01, 0x84, 0x40, 0xb6, 0x7f, 0x14, 0x23,
+0x00, 0x2d, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0x84, 0xdd, 0x2f, 0xb4, 0x3f, 0x96, 0x0c,
+0xc0, 0x07, 0x80, 0x06, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7, 0x88, 0xb0, 0xdd, 0x2f, 0xb4, 0xbf,
+0x54, 0x42, 0x80, 0x02, 0xc4, 0x0a, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x88, 0x2c, 0xdd, 0x2f, 0xb4, 0x1f, 0x41, 0xe0, 0x3c, 0x08, 0x41, 0xef,
+0x7c, 0x09, 0x4f, 0xe2, 0x00, 0x0b, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74, 0x46, 0xf0,
+0x00, 0x03, 0x58, 0xf7, 0x8a, 0x08, 0xdd, 0x2f, 0xb4, 0x7f, 0x40, 0x21, 0xb8, 0x08, 0x92, 0x5f,
+0xc2, 0x0a, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74, 0x46, 0xf0, 0x00, 0x03, 0x58, 0xf7,
+0x89, 0x24, 0xdd, 0x2f, 0xec, 0x08, 0x3a, 0x6f, 0x98, 0x84, 0xdd, 0x9e, 0x3a, 0x6f, 0xaa, 0xbc,
+0xef, 0xfc, 0x44, 0x00, 0x02, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8a, 0xd8, 0xdd, 0x2f,
+0x46, 0x30, 0x04, 0x00, 0xb4, 0x43, 0x44, 0x50, 0x76, 0x10, 0x40, 0x01, 0x40, 0x09, 0xd8, 0x07,
+0x80, 0xe3, 0x04, 0x53, 0x80, 0x41, 0x42, 0x42, 0xd0, 0x0b, 0xc4, 0x23, 0x46, 0xf0, 0x00, 0x0b,
+0x00, 0x87, 0x81, 0x63, 0x84, 0xa1, 0x4c, 0x82, 0xc0, 0x07, 0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7,
+0x8e, 0xf8, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0e, 0x00, 0x07, 0x80, 0xc8, 0xc8, 0x12, 0x46, 0xf0,
+0x00, 0x0d, 0x01, 0xe7, 0x8d, 0x7c, 0x84, 0xa1, 0x4d, 0xe2, 0xc0, 0x0c, 0x46, 0xf0, 0x00, 0x0b,
+0x00, 0x17, 0x80, 0x1c, 0x80, 0x40, 0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7, 0x82, 0x9c, 0xdd, 0x2f,
+0x46, 0xf0, 0x00, 0x04, 0x58, 0xf7, 0x81, 0x78, 0xdd, 0x2f, 0x46, 0xf0, 0x00, 0x0a, 0x58, 0xf7,
+0x84, 0xd8, 0xdd, 0x2f, 0x46, 0xa0, 0x00, 0x00, 0x58, 0xa5, 0x03, 0x24, 0x46, 0xf0, 0x00, 0x01,
+0x58, 0xf7, 0x8a, 0xc4, 0xdd, 0x2f, 0x46, 0x90, 0x00, 0x02, 0x58, 0x94, 0x88, 0x30, 0x46, 0x70,
+0x00, 0x00, 0x58, 0x73, 0x83, 0x68, 0x46, 0x80, 0x00, 0x02, 0x58, 0x84, 0x00, 0x40, 0xd5, 0x20,
+0x4b, 0xe0, 0x28, 0x01, 0x00, 0x10, 0x00, 0x14, 0x80, 0xc0, 0xc9, 0x0f, 0x80, 0x20, 0x46, 0x00,
+0x00, 0x0d, 0x58, 0x00, 0x0e, 0x74, 0x4b, 0xe0, 0x20, 0x01, 0xc8, 0x12, 0x80, 0x26, 0x46, 0x00,
+0x00, 0x0d, 0x58, 0x00, 0x0e, 0x64, 0xd5, 0x0a, 0x84, 0xa1, 0xd9, 0x0a, 0x4b, 0xe0, 0x24, 0x01,
+0x80, 0x26, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0e, 0x54, 0x4b, 0xe0, 0x1c, 0x01, 0x46, 0xf0,
+0x00, 0x0d, 0x04, 0x57, 0x83, 0xcd, 0x46, 0x00, 0x00, 0x0d, 0x58, 0x00, 0x0f, 0x2c, 0xcd, 0xd9,
+0x46, 0xf0, 0x00, 0x0d, 0x04, 0x07, 0x83, 0x8f, 0x44, 0x20, 0x03, 0xe8, 0x40, 0x20, 0x0b, 0xd6,
+0x4f, 0xe3, 0x00, 0x07, 0x46, 0x10, 0x04, 0x00, 0x9c, 0xd1, 0x14, 0x30, 0x80, 0x8e, 0x46, 0x10,
+0x00, 0x0d, 0x9d, 0x01, 0x14, 0x40, 0x83, 0x8f, 0x5e, 0xf0, 0x13, 0x89, 0xe9, 0x04, 0x84, 0xa0,
+0x14, 0x50, 0x83, 0x8f, 0x46, 0xf0, 0x00, 0x0d, 0x05, 0xe7, 0x83, 0xca, 0x4f, 0xe3, 0x00, 0x09,
+0x44, 0x00, 0x02, 0x00, 0x46, 0xf0, 0x00, 0x05, 0x58, 0xf7, 0x8b, 0x1c, 0xdd, 0x2f, 0xec, 0x04,
+0x3a, 0x6f, 0xaa, 0x84, 0xdd, 0x9e, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb8, 0x4b, 0x00, 0x00, 0x6c, 0x46, 0x00, 0x00,
+0xa8, 0x41, 0x00, 0x00, 0x78, 0x45, 0x00, 0x00, 0xa8, 0x41, 0x00, 0x00, 0x74, 0x43, 0x00, 0x00,
+0xd8, 0x49, 0x00, 0x00, 0xa8, 0x41, 0x00, 0x00, 0x94, 0x4b, 0x00, 0x00, 0x3c, 0x45, 0x00, 0x00,
+0x74, 0x4b, 0x00, 0x00, 0x24, 0x45, 0x00, 0x00, 0xa8, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x99, 0x99, 0x09, 0x50, 0x02, 0x46, 0x44, 0x0a, 0x50, 0x03, 0xec, 0xee, 0x0a, 0x50, 0x04,
+0x99, 0x99, 0x0b, 0x50, 0x05, 0x46, 0x44, 0x08, 0x51, 0x06, 0xec, 0xee, 0x08, 0x51, 0x07, 0x99,
+0x99, 0x09, 0x51, 0x08, 0x46, 0x44, 0x0a, 0x51, 0x09, 0xec, 0xee, 0x0a, 0x51, 0x0a, 0x99, 0x99,
+0x0b, 0x51, 0x0b, 0x46, 0x44, 0x08, 0x52, 0x0c, 0xec, 0xee, 0x08, 0x52, 0x0d, 0x99, 0x99, 0x09,
+0x52, 0x0e, 0x33, 0x33, 0x0b, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x30, 0x34, 0x38,
+0x3c, 0x40, 0x44, 0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x00, 0x24, 0x25, 0x26, 0x27,
+0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00,
+0x16, 0x14, 0x12, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x14, 0x18, 0x1c, 0x00, 0x00,
+0x20, 0x21, 0x22, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0f, 0xac, 0x00, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x03, 0x00,
+0x00, 0xf8, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x88, 0x8e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x86, 0xdd, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x05, 0xff, 0x00, 0x00,
+0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x8f, 0x14, 0x01, 0x76, 0x01, 0x00, 0x01, 0x02,
+0x03, 0x01, 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x05, 0x0f, 0x0c, 0x00,
+0x01, 0x07, 0x10, 0x02, 0x02, 0x00, 0x00, 0x00, 0x09, 0x02, 0x4a, 0x00, 0x01, 0x01, 0x00, 0xa0,
+0x50, 0x09, 0x04, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x84, 0x02, 0x00, 0x02,
+0x00, 0x07, 0x05, 0x85, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x08, 0x02, 0x00, 0x02, 0x00, 0x07,
+0x05, 0x04, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x05, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x06,
+0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x07, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x09, 0x02, 0x00,
+0x02, 0x00, 0x09, 0x04, 0x01, 0x00, 0x05, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x81, 0x03, 0x40,
+0x00, 0x00, 0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00,
+0x07, 0x05, 0x83, 0x01, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x01, 0x40, 0x00, 0x00, 0x04, 0x03,
+0x09, 0x04, 0x12, 0x03, 0x4d, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x61, 0x00, 0x54, 0x00,
+0x65, 0x00, 0x6b, 0x00, 0x1c, 0x03, 0x38, 0x00, 0x30, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00,
+0x31, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x57, 0x00, 0x4c, 0x00, 0x41, 0x00, 0x4e, 0x00,
+0x08, 0x03, 0x31, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x18, 0x5a, 0x00, 0x00, 0x1c, 0x5a, 0x00, 0x00,
+0x20, 0x5a, 0x00, 0x00, 0x24, 0x5a, 0x00, 0x00, 0x28, 0x5a, 0x00, 0x00, 0x2c, 0x5a, 0x00, 0x00,
+0x30, 0x5a, 0x00, 0x00, 0x34, 0x5a, 0x00, 0x00, 0x38, 0x5a, 0x00, 0x00, 0x3c, 0x5a, 0x00, 0x00,
+0x40, 0x5a, 0x00, 0x00, 0x44, 0x5a, 0x00, 0x00, 0x48, 0x5a, 0x00, 0x00, 0x4c, 0x5a, 0x00, 0x00,
+0x50, 0x5a, 0x00, 0x00, 0x54, 0x5a, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0xb1, 0x00, 0x00, 0x00,
+0x40, 0x76, 0x00, 0x01, } ;
diff --git a/cleopatre/devkit/mt7601udrv/include/misc.h b/cleopatre/devkit/mt7601udrv/include/misc.h
new file mode 100644
index 0000000000..2248bd3e84
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/misc.h
@@ -0,0 +1,32 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2009, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ misc.h
+
+ Abstract:
+
+ Handling Misc Problem
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sean Wang 2009-08-12 Create
+ John Li 2009-12-23 Modified
+*/
+
+
diff --git a/cleopatre/devkit/mt7601udrv/include/misc_cmm.h b/cleopatre/devkit/mt7601udrv/include/misc_cmm.h
new file mode 100644
index 0000000000..aa91c80561
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/misc_cmm.h
@@ -0,0 +1,32 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2009, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ misc_cmm.h
+
+ Abstract:
+
+ Handling Misc Problem
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sean Wang 2009-08-12 Create
+ John Li 2009-12-23 Modified
+*/
+
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mlme.h b/cleopatre/devkit/mt7601udrv/include/mlme.h
new file mode 100644
index 0000000000..076c5ebd2b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mlme.h
@@ -0,0 +1,1515 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ mlme.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2003-08-28 Created
+ John Chang 2004-09-06 modified for RT2600
+
+*/
+#ifndef __MLME_H__
+#define __MLME_H__
+
+#include "rtmp_dot11.h"
+
+#include "wpa_cmm.h"
+
+
+/* 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*/ /* */
+#ifdef RT3290
+#define LEAD_TIME 7
+#else
+#define LEAD_TIME 5
+#endif /* RT3290 */
+
+#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
+#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_AP_SUPPORT
+#define CW_MAX_IN_BITS 6 /* actual CwMax = 2^CW_MAX_IN_BITS - 1 */
+#endif /* CONFIG_AP_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 BSS_NOT_FOUND 0xFFFFFFFF
+
+#ifdef CONFIG_AP_SUPPORT
+#define MAX_LEN_OF_MLME_QUEUE 20 /*10 */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+enum SCAN_MODE{
+ /* Active scan, send probe request, and wait beacon and probe response */
+ SCAN_ACTIVE = 0x00, /* all channels */
+ SCAN_CISCO_ACTIVE = 0x1, /* single channel only */
+ FAST_SCAN_ACTIVE = 0x2,
+#ifdef WSC_INCLUDED
+ SCAN_WSC_ACTIVE = 0x3,
+#endif /* WSC_INCLUDED */
+#ifdef DOT11N_DRAFT3
+ SCAN_2040_BSS_COEXIST = 0x4,
+#endif /* DOT11N_DRAFT3 */
+ SCAN_ACTIVE_MAX,
+
+ /* Passive scan, no probe request, only wait beacon and probe response */
+ SCAN_PASSIVE = 0x80, /* all channels */
+ SCAN_CISCO_PASSIVE = 0x81, /* single channel only */
+ SCAN_CISCO_NOISE = 0x82, /* single channel only, for noise histogram collection */
+ SCAN_CISCO_CHANNEL_LOAD = 0x83, /* single channel only, for channel load collection */
+ SCAN_PASSIVE_MAX,
+};
+
+#define SCAN_MASK 0x80
+#define SCAN_MODE_ACT(_x) (((_x) & SCAN_MASK) == 0)
+#define SCAN_MODE_PSV(_x) (((_x) & SCAN_MASK) == SCAN_MASK)
+#define SCAN_MODE_VALID(_x) ((SCAN_MODE_ACT(_x) && ((_x) < SCAN_ACTIVE_MAX)) ||\
+ (SCAN_MODE_PSV(_x) && ((_x) < SCAN_PASSIVE_MAX)))
+
+/*#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))
+
+
+/* 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 */
+#ifdef FIFO_EXT_SUPPORT
+#define RESET_ONE_SEC_TX_CNT(__pEntry) \
+if (((__pEntry)) != NULL) \
+{ \
+ (__pEntry)->OneSecTxRetryOkCount = 0; \
+ (__pEntry)->OneSecTxFailCount = 0; \
+ (__pEntry)->OneSecTxNoRetryOkCount = 0; \
+ (__pEntry)->OneSecRxLGICount = 0; \
+ (__pEntry)->OneSecRxSGICount = 0; \
+ (__pEntry)->fifoTxSucCnt = 0;\
+ (__pEntry)->fifoTxRtyCnt = 0;\
+}
+#else
+#define RESET_ONE_SEC_TX_CNT(__pEntry) \
+if (((__pEntry)) != NULL) \
+{ \
+ (__pEntry)->OneSecTxRetryOkCount = 0; \
+ (__pEntry)->OneSecTxFailCount = 0; \
+ (__pEntry)->OneSecTxNoRetryOkCount = 0; \
+ (__pEntry)->OneSecRxLGICount = 0; \
+ (__pEntry)->OneSecRxSGICount = 0; \
+}
+#endif /* FIFO_EXT_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;
+ USHORT RxSTBC:2;
+ USHORT TxSTBC:1;
+ USHORT ShortGIfor40:1;
+ USHORT ShortGIfor20:1;
+ USHORT GF:1;
+ USHORT MimoPs:2;
+ USHORT ChannelWidth:1;
+ USHORT AdvCoding:1;
+#else
+ USHORT AdvCoding:1;
+ USHORT ChannelWidth:1;
+ USHORT MimoPs:2; /* mimo power safe */
+ USHORT GF:1; /* green field */
+ USHORT ShortGIfor20:1;
+ USHORT ShortGIfor40:1; /* for40MHz */
+ USHORT TxSTBC:1; /* 0:not supported, 1:if supported */
+ USHORT RxSTBC:2;
+ USHORT DelayedBA:1;
+ 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 _HT_CAP_PARM{
+#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;
+
+
+typedef struct GNU_PACKED _HT_MCS_SET_TX_SUBFIELD{
+#ifdef RT_BIG_ENDIAN
+ UCHAR TxMCSSetDefined:1;
+ UCHAR TxRxNotEqual:1;
+ UCHAR TxMaxStream:2;
+ UCHAR TxUnqualModulation:1;
+ UCHAR rsv:3;
+#else
+ UCHAR rsv:3;
+ UCHAR TxUnqualModulation:1;
+ UCHAR TxMaxStream:2;
+ UCHAR TxRxNotEqual:1;
+ UCHAR TxMCSSetDefined:1;
+#endif /* RT_BIG_ENDIAN */
+}HT_MCS_SET_TX_SUBFIELD, *PHT_MCS_SET_TX_SUBFIELD;
+
+
+/* HT Capability INFO field in HT Cap IE . */
+typedef struct GNU_PACKED _HT_MCS_SET{
+ 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 _EXT_HT_CAP_INFO{
+#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 Explicit Beamforming Feedback Capable */
+#define HT_ExBF_FB_CAP_NONE 0
+#define HT_ExBF_FB_CAP_DELAYED 1
+#define HT_ExBF_FB_CAP_IMMEDIATE 2
+#define HT_ExBF_FB_CAP_BOTH 3
+
+/* 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
+ // TODO: shiang-6590, check the data structure format if this IE
+ UINT32 rsv7:1;
+ UINT32 TDLSChSwitchSupport:1; /* bit30: TDLS Channel Switching */
+ UINT32 TDLSPeerPSMSupport:1; /* bit29: TDLS Peer PSM Support */
+ UINT32 UAPSDBufSTASupport:1; /* bit28: Peer U-APSD Buffer STA Support */
+ UINT32 rsv6:1;
+ UINT32 DMSSupport:1;
+ UINT32 rsv5:6;
+ UINT32 BssTransitionManmt:1;
+ UINT32 rsv4:1;
+ UINT32 WNMSleepSupport:1;/*bit 17*/
+ UINT32 TFSSupport:1;/*bit 16*/
+ UINT32 rsv3:4;
+ UINT32 FMSSupport:1;/*bit 11*/
+ UINT32 rsv2:8;
+ UINT32 ExtendChannelSwitch:1;
+ UINT32 rsv:1;
+ UINT32 BssCoexistMgmtSupport:1;
+#else
+ UINT32 BssCoexistMgmtSupport:1;
+ UINT32 rsv:1;
+ UINT32 ExtendChannelSwitch:1;
+ UINT32 rsv2:8;
+ UINT32 FMSSupport:1;/*bit 11*/
+ UINT32 rsv3:4;
+ UINT32 TFSSupport:1;/*bit 16*/
+ UINT32 WNMSleepSupport:1;/*bit 17*/
+ UINT32 rsv4:1;
+ UINT32 BssTransitionManmt:1;
+ UINT32 rsv5:6;
+ UINT32 DMSSupport:1;
+ UINT32 rsv6:1;
+ UINT32 UAPSDBufSTASupport:1; /* bit28: Peer U-APSD Buffer STA Support */
+ UINT32 TDLSPeerPSMSupport:1; /* bit29: TDLS Peer PSM Support */
+ UINT32 TDLSChSwitchSupport:1; /* bit30: TDLS Channel Switching */
+ UINT32 rsv7:1;
+#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 and RT_VHT_CAP */
+typedef struct _RT_PHY_INFO{
+ BOOLEAN bHtEnable; /* If we should use ht rate. */
+ BOOLEAN bPreNHt; /* If we should use ht rate. */
+ /*Substract from HT Capability IE */
+ UCHAR MCSSet[16];
+#ifdef DOT11_VHT_AC
+ BOOLEAN bVhtEnable;
+ UCHAR vht_bw;
+ VHT_MCS_SET vht_mcs_set;
+#endif /* DOT11_VHT_AC */
+} RT_PHY_INFO;
+
+
+#ifdef DOT11_VHT_AC
+typedef struct _RT_VHT_CAP{
+ UINT32 vht_bw:2;
+ UINT32 vht_txstbc:1;
+ UINT32 vht_rxstbc:3;
+ UINT32 sgi_80m:1;
+ UINT32 vht_htc:1;
+
+ UINT32 vht_mcs_ss1:2;
+ UINT32 vht_mcs_ss2:2;
+ UINT32 vht_rx_rate:2;
+ UINT32 vht_tx_rate:2;
+
+ UINT32 rsv:16;
+}RT_VHT_CAP;
+#endif /* DOT11_VHT_AC */
+
+
+/*
+ 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;
+ 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; /*for 40MHz */
+ USHORT TxSTBC:1; /* 0:not supported, 1:if supported */
+ 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 _ADD_HTINFO{
+#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 _ADD_HTINFO2{
+#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 _ADD_HTINFO3{
+#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 _ADD_HT_INFO_IE{
+ 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 _NEW_EXT_CHAN_IE{
+ 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 _DELBA_PARM{
+#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 _BA_PARM{
+#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 _BASEQ_CONTROL{
+ 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 _BA_CONTROL{
+#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 _BAR_CONTROL{
+#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 _MTBAR_CONTROL{
+#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 _PER_TID_INFO{
+#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 _HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE{
+ 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 _CF_PARM{
+ 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 _QBSS_STA_INFO_PARM{
+#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 _QBSS_AP_INFO_PARM{
+#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;
+
+
+
+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;
+
+#ifdef DOT11_VHT_AC
+ UCHAR vht_cap_len;
+ UCHAR vht_op_len;
+ VHT_CAP_IE vht_cap_ie;
+ VHT_OP_IE vht_op_ie;
+#endif /* DOT11_VHT_AC */
+
+
+ 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 */
+#ifdef WAPI_SUPPORT
+ CIPHER_SUITE WAPI; /* AP announced WAPI cipher suite */
+#endif /* WAPI_SUPPORT */
+
+ /* 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 WSC_INCLUDED
+ UCHAR WpsAP; /* 0x00: not support WPS, 0x01: support normal WPS, 0x02: support Ralink auto WPS, 0x04: support WAC AP */
+ USHORT WscDPIDFromWpsAP;
+#endif /* WSC_INCLUDED */
+
+
+
+ UCHAR MacAddr[MAC_ADDR_LEN];
+ ULONG ClientStatusFlags;
+} 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 AntSel;
+ 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 *pAd, MLME_QUEUE_ELEM *Elem);
+
+typedef struct _STATE_MACHINE {
+ ULONG Base;
+ ULONG NrState;
+ ULONG NrMsg;
+ ULONG CurrState;
+ STATE_MACHINE_FUNC *TransFunc;
+} STATE_MACHINE, *PSTATE_MACHINE;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+typedef VOID (*APCLI_STATE_MACHINE_FUNC)(VOID *pAd, MLME_QUEUE_ELEM *Elem, PULONG pCurrState, USHORT ifIndex);
+
+typedef struct _STA_STATE_MACHINE {
+ ULONG Base;
+ ULONG NrState;
+ ULONG NrMsg;
+ ULONG CurrState;
+ APCLI_STATE_MACHINE_FUNC *TransFunc;
+} APCLI_STATE_MACHINE, *PSTA_STATE_MACHINE;
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+/* 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; */
+
+#ifdef DOT11_VHT_AC
+ UCHAR vht_cap_len;
+ UCHAR vht_op_len;
+ VHT_CAP_IE vht_cap;
+ VHT_OP_IE vht_op;
+#endif /* DOT11_VHT_AC */
+
+ /* 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_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ USHORT VarIELen; /* Length of next VIE include EID & Length */
+ UCHAR VarIEs[MAX_VIE_LEN];
+ LONG Rssi; /* Record the rssi value when receive Probe Rsp. */
+ RALINK_TIMER_STRUCT ProbeTimer, ApCliAssocTimer, ApCliAuthTimer;
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_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;
+
+
+typedef struct GNU_PACKED _EID_STRUCT{
+ UCHAR Eid;
+ UCHAR Len;
+ UCHAR Octet[1];
+} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
+
+
+/* ========================== 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;
+
+
+typedef struct _IE_lists {
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR ApAddr[MAC_ADDR_LEN];
+ USHORT CapabilityInfo;
+ USHORT ListenInterval;
+ UCHAR SsidLen;
+ UCHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SupportedRatesLen;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE];
+ UCHAR RSNIE_Len;
+ BOOLEAN bWmmCapable;
+#ifdef WSC_AP_SUPPORT
+ BOOLEAN bWscCapable;
+#endif /* WSC_AP_SUPPORT */
+ ULONG RalinkIe;
+ EXT_CAP_INFO_ELEMENT ExtCapInfo;
+ UCHAR ht_cap_len;
+ HT_CAPABILITY_IE HTCapability;
+#ifdef DOT11_VHT_AC
+ VHT_CAP_IE vht_cap;
+ VHT_OP_IE vht_op;
+ UCHAR vht_cap_len;
+ UCHAR vht_op_len;
+#endif /* DOT11_VHT_AC */
+}IE_LISTS;
+
+
+typedef struct _bcn_ie_list {
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR Bssid[MAC_ADDR_LEN];
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+ UCHAR BssType;
+ USHORT BeaconPeriod;
+ UCHAR Channel;
+ UCHAR NewChannel;
+ USHORT AtimWin;
+ USHORT CapabilityInfo;
+ UCHAR Erp;
+ UCHAR DtimCount;
+ UCHAR DtimPeriod;
+ UCHAR BcastFlag;
+ UCHAR MessageToMe;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRateLen;
+ UCHAR CkipFlag;
+ UCHAR AironetCellPowerLimit;
+ LARGE_INTEGER TimeStamp;
+ CF_PARM CfParm;
+ EDCA_PARM EdcaParm;
+ QBSS_LOAD_PARM QbssLoad;
+ QOS_CAPABILITY_PARM QosCapability;
+ ULONG RalinkIe;
+ EXT_CAP_INFO_ELEMENT ExtCapInfo;
+ UCHAR HtCapabilityLen;
+ UCHAR PreNHtCapabilityLen;
+ HT_CAPABILITY_IE HtCapability;
+ UCHAR AddHtInfoLen;
+ ADD_HT_INFO_IE AddHtInfo;
+ UCHAR NewExtChannelOffset;
+#ifdef DOT11_VHT_AC
+ VHT_CAP_IE vht_cap_ie;
+ VHT_OP_IE vht_op_ie;
+ UCHAR vht_cap_len;
+ UCHAR vht_op_len;
+#endif /* DOT11_VHT_AC */
+}BCN_IE_LIST;
+
+#endif /* MLME_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/mlme_sys.h b/cleopatre/devkit/mt7601udrv/include/mlme_sys.h
new file mode 100644
index 0000000000..f36fabaaf0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/mlme_sys.h
@@ -0,0 +1,9 @@
+/*
+
+*/
+
+
+#include "rtmp_type.h"
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/include/netif_block.h b/cleopatre/devkit/mt7601udrv/include/netif_block.h
new file mode 100644
index 0000000000..3714bf0695
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/netif_block.h
@@ -0,0 +1,31 @@
+
+#ifndef __NET_IF_BLOCK_H__
+#define __NET_IF_BLOCK_H__
+
+#include "link_list.h"
+#include "rtmp.h"
+
+#define FREE_NETIF_POOL_SIZE 32
+
+typedef struct _NETIF_ENTRY
+{
+ struct _NETIF_ENTRY *pNext;
+ PNET_DEV pNetDev;
+} NETIF_ENTRY, *PNETIF_ENTRY;
+
+void initblockQueueTab(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN blockNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+ IN PNET_DEV pNetDev);
+
+VOID releaseNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry);
+
+VOID StopNetIfQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+#endif /* __NET_IF_BLOCK_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/oid.h b/cleopatre/devkit/mt7601udrv/include/oid.h
new file mode 100644
index 0000000000..6152987c99
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/oid.h
@@ -0,0 +1,1320 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ oid.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#ifndef _OID_H_
+#define _OID_H_
+
+/*#include <linux/wireless.h> */
+
+
+
+/* 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_80 2
+#define BAND_WIDTH_BOTH 3
+#define BAND_WIDTH_10 4 /* 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 */
+#define RT_OID_802_11_RSSI_1 0x0109 /* rt2860 only */
+#define RT_OID_802_11_RSSI_2 0x010A /* rt2860 only */
+#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 RT_OID_802_11_QUERY_PID 0x051A
+#define RT_OID_802_11_QUERY_VID 0x051B
+#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
+#define OID_802_11_ACL_LIST 0x052A
+
+/* 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
+#define RT_OID_802_11_PER_BSS_STATISTICS 0x067D
+
+#ifdef TXBF_SUPPORT
+#define RT_OID_802_11_QUERY_TXBF_TABLE 0x067C
+#endif
+
+
+#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)
+
+#ifdef WAPI_SUPPORT
+#define OID_802_11_WAPI_PID 0x06A0
+#define OID_802_11_PORT_SECURE_STATE 0x06A1
+#define OID_802_11_UCAST_KEY_INFO 0x06A2
+#define OID_802_11_MCAST_TXIV 0x06A3
+#define OID_802_11_MCAST_KEY_INFO 0x06A4
+#define OID_802_11_WAPI_CONFIGURATION 0x06A5
+#define OID_802_11_WAPI_IE 0x06A6
+
+#define RT_OID_802_11_WAPI_PID (OID_GET_SET_TOGGLE | OID_802_11_WAPI_PID)
+#define RT_OID_802_11_PORT_SECURE_STATE (OID_GET_SET_TOGGLE | OID_802_11_PORT_SECURE_STATE)
+#define RT_OID_802_11_UCAST_KEY_INFO (OID_GET_SET_TOGGLE | OID_802_11_UCAST_KEY_INFO)
+#define RT_OID_802_11_MCAST_TXIV (OID_GET_SET_TOGGLE | OID_802_11_MCAST_TXIV)
+#define RT_OID_802_11_MCAST_KEY_INFO (OID_GET_SET_TOGGLE | OID_802_11_MCAST_KEY_INFO)
+#define RT_OID_802_11_WAPI_CONFIGURATION (OID_GET_SET_TOGGLE | OID_802_11_WAPI_CONFIGURATION)
+#define RT_OID_802_11_WAPI_IE (OID_GET_SET_TOGGLE | OID_802_11_WAPI_IE)
+#endif /* WAPI_SUPPORT */
+
+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 TransmittedFrameCount;
+ LARGE_INTEGER WEPUndecryptableCount;
+ 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 struct _MBSS_STATISTICS {
+ LONG TxCount;
+ ULONG RxCount;
+ ULONG ReceivedByteCount;
+ ULONG TransmittedByteCount;
+ ULONG RxErrorCount;
+ ULONG RxDropCount;
+ ULONG TxErrorCount;
+ ULONG TxDropCount;
+ ULONG ucPktsTx;
+ ULONG ucPktsRx;
+ ULONG mcPktsTx;
+ ULONG mcPktsRx;
+ ULONG bcPktsTx;
+ ULONG bcPktsRx;
+} MBSS_STATISTICS, *PMBSS_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_AP_SUPPORT
+typedef struct _NDIS_AP_802_11_KEY {
+ UINT Length; /* Length of this structure */
+ UCHAR addr[6];
+ UINT KeyIndex;
+ UINT KeyLength; /* length of key in bytes */
+ UCHAR KeyMaterial[1]; /* variable length depending on above field */
+} NDIS_AP_802_11_KEY, *PNDIS_AP_802_11_KEY;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+typedef struct _NDIS_APCLI_802_11_KEY
+{
+ UINT Length;
+ UINT KeyIndex;
+ UINT KeyLength;
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ NDIS_802_11_KEY_RSC KeyRSC;
+ UCHAR KeyMaterial[1];
+} NDIS_APCLI_802_11_KEY, *PNDIS_APCLI_802_11_KEY;
+#endif/* APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif /* APCLI_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,
+#ifdef WAPI_SUPPORT
+ Ndis802_11AuthModeWAICERT, /* WAI certificate authentication */
+ Ndis802_11AuthModeWAIPSK, /* WAI pre-shared key */
+#endif /* WAPI_SUPPORT */
+ 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,
+#ifdef WAPI_SUPPORT
+ Ndis802_11EncryptionSMS4Enabled, /* WPI SMS4 support */
+#endif /* WAPI_SUPPORT */
+} 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];
+
+#if defined(CONFIG_STA_SUPPORT) || defined(APCLI_WPA_SUPPLICANT_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 /* defined(CONFIG_STA_SUPPORT) || defined(APCLI_WPA_SUPPLICANT_SUPPORT) */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+typedef struct _NDIS_APCLI_802_11_PMKID
+{
+ UINT Length;
+ UINT BSSIDInfoCount;
+ BSSID_INFO BSSIDInfo[1];
+} NDIS_APCLI_802_11_PMKID, *PNDIS_APCLI_802_11_PMKID;
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+typedef struct _AP_BSSID_INFO {
+ NDIS_802_11_MAC_ADDRESS MAC;
+ NDIS_802_11_PMKID_VALUE PMKID;
+ UCHAR PMK[32];
+ ULONG RefreshTime;
+ BOOLEAN Valid;
+} AP_BSSID_INFO, *PAP_BSSID_INFO;
+
+#define MAX_PMKID_COUNT 8
+typedef struct _NDIS_AP_802_11_PMKID {
+ AP_BSSID_INFO BSSIDInfo[MAX_PMKID_COUNT];
+} NDIS_AP_802_11_PMKID, *PNDIS_AP_802_11_PMKID;
+#endif /* CONFIG_AP_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 , 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 WSC_INCLUDED
+#define RT_OID_WAC_REQ 0x0736
+#define RT_OID_WSC_AUTO_PROVISION_WITH_BSSID 0x0737
+#define RT_OID_WSC_AUTO_PROVISION 0x0738
+#ifdef WSC_LED_SUPPORT
+/*WPS LED MODE 10 for Dlink WPS LED */
+#define RT_OID_LED_WPS_MODE10 0x0739
+#endif /* WSC_LED_SUPPORT */
+#endif /* WSC_INCLUDED */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+#define RT_OID_APCLI_WSC_PIN_CODE 0x074A
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_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
+#ifdef CONFIG_AP_SUPPORT
+#define RT_OID_GET_LLTD_ASSO_TABLE 0x762
+#ifdef APCLI_SUPPORT
+#define RT_OID_GET_REPEATER_AP_LINEAGE 0x763
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* LLTD_SUPPORT */
+
+
+
+
+/* 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!!! */
+#ifdef RT65xx
+typedef union _HTTRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ USHORT MODE:3; /* Use definition MODE_xxx. */
+ USHORT iTxBF:1;
+ USHORT eTxBF:1;
+ USHORT STBC:1; /* only support in HT/VHT mode with MCS0~7 */
+ USHORT ShortGI:1;
+ USHORT BW:2; /* channel bandwidth 20MHz/40/80 MHz */
+ USHORT MCS:7; /* MCS */
+ } field;
+#else
+ struct {
+ USHORT MCS:7;
+ USHORT BW:2;
+ USHORT ShortGI:1;
+ USHORT STBC:1;
+ USHORT eTxBF:1;
+ USHORT iTxBF:1;
+ USHORT MODE:3;
+ } field;
+#endif
+ USHORT word;
+} HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
+#else
+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;
+#endif /* RT65xx */
+
+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 = 1,
+ PHY_11A = 2,
+ PHY_11ABG_MIXED = 3,
+ PHY_11G = 4,
+#ifdef DOT11_N_SUPPORT
+ PHY_11ABGN_MIXED = 5, /* both band 5 */
+ PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
+ PHY_11GN_MIXED = 7, /* 2.4G band 7 */
+ PHY_11AN_MIXED = 8, /* 5G band 8 */
+ PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
+ PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
+ PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
+#endif /* DOT11_N_SUPPORT */
+#ifdef DOT11_VHT_AC
+ PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
+ PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
+ PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
+ PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
+#endif /* DOT11_VHT_AC */
+ PHY_MODE_MAX,
+} RT_802_11_PHY_MODE;
+
+#ifdef DOT11_VHT_AC
+#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) ||\
+ (__Mode == PHY_11VHT_N_MIXED) ||\
+ (__Mode == PHY_11VHT_N_A_MIXED))
+#elif defined(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 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 WSC_INCLUDED
+#define RT_WSC_UPNP_EVENT_FLAG 0x109
+#endif /* WSC_INCLUDED */
+
+
+
+/*#define MAX_CUSTOM_LEN 128 */
+
+
+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;
+
+#ifdef WAPI_SUPPORT
+typedef enum _WAPI_PORT_SECURE_STATE {
+ WAPI_PORT_NOT_SECURED,
+ WAPI_PORT_SECURED,
+} WAPI_PORT_SECURE_STATE, *PWAPI_PORT_SECURE_STATE;
+
+typedef struct _WAPI_PORT_SECURE_STRUCT {
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ USHORT state;
+} WAPI_PORT_SECURE_STRUCT, *PWAPI_PORT_SECURE_STRUCT;
+
+typedef struct _WAPI_UCAST_KEY_STRUCT {
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ USHORT key_id;
+ UCHAR PTK[64]; /* unicast and additional key */
+} WAPI_UCAST_KEY_STRUCT, *PWAPI_UCAST_KEY_STRUCT;
+
+typedef struct _WAPI_MCAST_KEY_STRUCT {
+ UINT32 key_id;
+ UCHAR m_tx_iv[16];
+ UCHAR key_announce[16];
+ UCHAR NMK[16]; /* notify master key */
+} WAPI_MCAST_KEY_STRUCT, *PWAPI_MCAST_KEY_STRUCT;
+
+typedef struct _WAPI_WIE_STRUCT {
+ UCHAR addr[6];
+ UINT32 wie_len;
+ UCHAR wie[90]; /* wapi information element */
+} WAPI_WIE_STRUCT, *PWAPI_WIE_STRUCT;
+
+#endif /* WAPI_SUPPORT */
+
+
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_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 /* APCLI_WPA_SUPPLICANT_SUPPORT */
+#endif /* APCLI_SUPPORT */
+
+
+
+
+
+
+#ifdef RTMP_MAC_USB
+#define RT_OID_USB_WOW_SUSPEND 0x0920
+#define RT_OID_USB_WOW_RESUME 0x0921
+#endif /* RTMP_MAC_USB */
+
+#endif /* _OID_H_ */
diff --git a/cleopatre/devkit/mt7601udrv/include/os/rt_drv.h b/cleopatre/devkit/mt7601udrv/include/os/rt_drv.h
new file mode 100644
index 0000000000..290e68a0fe
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/os/rt_drv.h
@@ -0,0 +1,1061 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt_drv.h
+
+ Abstract:
+ Put all virtual OS related definition/structure/MACRO here except
+ standard ANSI C function.
+
+ Note:
+ No any OS related definition/MACRO is defined here.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+*/
+
+/* same as rt_linux.h to warn users the two files can not be used simultaneously */
+#ifndef __RT_LINUX_H__
+#define __RT_LINUX_H__
+
+#include "os/rt_linux_cmm.h"
+#include <linux/string.h>
+#include <linux/ctype.h>
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_AP_SUPPORT
+#define AP_WSC_INCLUDED
+#endif /* WSC_AP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#if defined(WSC_AP_SUPPORT) || defined(WSC_STA_SUPPORT)
+#define WSC_INCLUDED
+#endif
+
+/*#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_AP_SUPPORT
+#ifdef RTMP_MAC_USB
+#ifdef INF_AMAZON_SE
+#define AP_PROFILE_PATH "/ramdisk/etc/Wireless/RT2870AP/RT2870AP.dat"
+#define AP_RTMP_FIRMWARE_FILE_NAME "/ramdisk/etc/Wireless/RT2870AP/RT2870AP.bin"
+#else
+#define AP_PROFILE_PATH "/etc/Wireless/RT2870AP/RT2870AP.dat"
+#define AP_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2870AP/RT2870AP.bin"
+#endif
+#define AP_NIC_DEVICE_NAME "RT2870AP"
+#define AP_DRIVER_VERSION "3.0.0.1"
+#ifdef MULTIPLE_CARD_SUPPORT
+#define CARD_INFO_PATH "/etc/Wireless/RT2870AP/RT2870APCard.dat"
+#endif /* MULTIPLE_CARD_SUPPORT */
+#endif /* RTMP_MAC_USB */
+
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+#ifdef SINGLE_SKU_V2
+#define SINGLE_SKU_TABLE_FILE_NAME "/etc/Wireless/RT2870STA/SingleSKU.dat"
+#endif /* SINGLE_SKU_V2 */
+
+/***********************************************************************************
+ * 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_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
+
+#define NET_DEVICE_REAL_IDX_MASK 0x0f /* for each operation mode, we maximum support 15 entities. */
+
+
+
+
+/***********************************************************************************
+ * 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;
+
+#endif /* RTMP_MAC_USB */
+
+#ifdef WORKQUEUE_BH
+ UINT32 pAd_va;
+#endif /* WORKQUEUE_BH */
+
+ RTMP_NET_TASK_STRUCT rx_done_task;
+ RTMP_NET_TASK_STRUCT cmd_rsp_event_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;
+
+
+#ifdef UAPSD_SUPPORT
+ RTMP_NET_TASK_STRUCT uapsd_eosp_sent_task;
+#endif /* UAPSD_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DFS_SUPPORT
+#ifdef DFS_SOFTWARE_SUPPORT
+ RTMP_NET_TASK_STRUCT pulse_radar_detect_task;
+ RTMP_NET_TASK_STRUCT width_radar_detect_task;
+#endif /* DFS_SOFTWARE_SUPPORT */
+#endif /* DFS_SUPPORT */
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ RTMP_NET_TASK_STRUCT carrier_sense_task;
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#ifdef DFS_SUPPORT
+ RTMP_NET_TASK_STRUCT dfs_task;
+#endif /* DFS_SUPPORT */
+
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef RTMP_MAC_USB
+ RTMP_NET_TASK_STRUCT null_frame_complete_task;
+ RTMP_NET_TASK_STRUCT pspoll_frame_complete_task;
+#endif /* RTMP_MAC_USB */
+
+#ifdef CONFIG_MULTI_CHANNEL
+ RTMP_NET_TASK_STRUCT hcca_null_frame_complete_task;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ RTMP_OS_PID apd_pid; /*802.1x daemon pid */
+ unsigned long apd_pid_nr;
+#ifdef CONFIG_AP_SUPPORT
+#ifdef IAPP_SUPPORT
+/* RT_SIGNAL_STRUC RTSignal; */
+ RTMP_OS_PID IappPid; /*IAPP daemon pid */
+ unsigned long IappPid_nr;
+#endif /* IAPP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+#ifdef WAPI_SUPPORT
+ RTMP_OS_PID wapi_pid; /*wapi daemon pid */
+ unsigned long wapi_pid_nr;
+#endif /* WAPI_SUPPORT */
+ 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;
+extern ULONG RTDebugFunc;
+
+#define DBGPRINT_RAW(Level, Fmt) \
+do{ \
+ ULONG __gLevel = (Level) & 0xff;\
+ ULONG __fLevel = ((Level)>>8) & 0xffffff;\
+ if (__gLevel <= RTDebugLevel) \
+ { \
+ if ((RTDebugFunc == 0) || \
+ ((RTDebugFunc != 0) && (((__fLevel & RTDebugFunc)!= 0) || (__gLevel <= RT_DEBUG_ERROR))))\
+ 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(phy_addr) (phy_addr)
+
+/*
+ * ULONG
+ * RTMP_GetPhysicalAddressHigh(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressHigh(phy_addr) (0)
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressLow(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ * IN ULONG Value);
+ */
+#define RTMP_SetPhysicalAddressLow(phy_addr, Value) \
+ phy_addr = Value;
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressHigh(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ * IN ULONG Value);
+ */
+#define RTMP_SetPhysicalAddressHigh(phy_addr, 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_FORCE_WRITE32(_A, _R, _V) \
+ do{\
+ /* if ((_R) != 0x404)*/ /* TODO:shiang-6590, depends on sw porting guide, don't acccess it now */\
+ RTUSBWriteMACRegister((_A), (_R), (UINT32) (_V), FALSE); \
+ }while(0)
+
+#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), FALSE)
+
+#define RTMP_IO_WRITE8(_A, _R, _V) \
+{ \
+ USHORT _Val = _V; \
+ RTUSBSingleWrite((_A), (_R), (USHORT) (_Val), FALSE); \
+}
+
+
+#define RTMP_IO_WRITE16(_A, _R, _V) \
+{ \
+ RTUSBSingleWrite((_A), (_R), (USHORT) (_V), FALSE); \
+}
+
+#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_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))
+
+
+
+#ifdef UAPSD_SUPPORT
+/* if we queue a U-APSD packet to any software queue, we will set the U-APSD
+ flag and its physical queue ID for it */
+#define RTMP_SET_PACKET_UAPSD(_p, _flg_uapsd, _que_id) \
+ (PACKET_CB(_p, 9) = ((_flg_uapsd<<7) | _que_id))
+
+#define RTMP_SET_PACKET_QOS_NULL(_p) (PACKET_CB(_p, 9) = 0xff)
+#define RTMP_GET_PACKET_QOS_NULL(_p) (PACKET_CB(_p, 9))
+#define RTMP_SET_PACKET_NON_QOS_NULL(_p) (PACKET_CB(_p, 9) = 0x00)
+#define RTMP_GET_PACKET_UAPSD_Flag(_p) ((PACKET_CB(_p, 9) & 0x80) >> 7)
+#define RTMP_GET_PACKET_UAPSD_QUE_ID(_p) (PACKET_CB(_p, 9) & 0x7f)
+
+#define RTMP_SET_PACKET_EOSP(_p, _flg) (PACKET_CB(_p, 10) = _flg)
+#define RTMP_GET_PACKET_EOSP(_p) (PACKET_CB(_p, 10))
+#endif /* UAPSD_SUPPORT */
+
+
+/* */
+/* 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
+#define RTMP_PACKET_SPECIFIC_TDLS 0x40
+
+/*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)
+
+/* TDLS */
+#define RTMP_SET_PACKET_TDLS(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_TDLS); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_TDLS); \
+ }while(0)
+
+#define RTMP_GET_PACKET_TDLS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_TDLS)
+
+/* 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))
+
+
+#ifdef DOT11_VHT_AC
+#define MAX_PACKETS_IN_QUEUE 1024 /*(512)*/
+#else
+#define MAX_PACKETS_IN_QUEUE (512)
+#endif /* DOT11_VHT_AC */
+
+
+/* use bit3 of cb[CB_OFF+16] */
+#define RTMP_SET_PACKET_MGMT_PKT(_p, _flg) \
+ PACKET_CB(_p, 16) = (PACKET_CB(_p, 16) & 0xF7) | ((_flg & 0x01) << 3);
+#define RTMP_GET_PACKET_MGMT_PKT(_p) \
+ ((PACKET_CB(_p, 16) & 0x08) >> 3)
+
+/* use bit0 of cb[CB_OFF+20] */
+#define RTMP_SET_PACKET_MGMT_PKT_DATA_QUE(_p, _flg) \
+ PACKET_CB(_p, 20) = (PACKET_CB(_p, 20) & 0xFE) | (_flg & 0x01);
+#define RTMP_GET_PACKET_MGMT_PKT_DATA_QUE(_p) \
+ (PACKET_CB(_p, 20) & 0x01)
+
+#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] */
+
+
+
+
+#if defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_SUPPORT)
+#define RTMP_SET_TCP_CHKSUM_FAIL(_p, _flg) (PACKET_CB(_p, 30) = _flg);
+#define RTMP_GET_TCP_CHKSUM_FAIL(_p) (PACKET_CB(_p, 30))
+#endif /* defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_SUPPORT) */
+
+
+
+/***********************************************************************************
+ * 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
+#ifdef CONFIG_MULTI_CHANNEL
+#define RtmpUsbBulkOutHCCANullFrameComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutHCCANullFrameComplete
+#endif /* CONFIG_MULTI_CHANNEL */
+
+#define RtmpUsbBulkOutRTSFrameComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutRTSFrameComplete
+#define RtmpUsbBulkOutPsPollComplete pRtmpDrvNetOps->RtmpNetUsbBulkOutPsPollComplete
+#define RtmpUsbBulkRxComplete pRtmpDrvNetOps->RtmpNetUsbBulkRxComplete
+#define RtmpUsbBulkCmdRspEventComplete pRtmpDrvNetOps->RtmpNetUsbBulkCmdRspEventComplete
+
+#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)
+#define RTUSBBulkCmdRspEventComplete(Status, pURB, pt_regs) RTUSBBulkCmdRspEventComplete(pURB)
+#define USBUploadFWComplete(Status, pURB, pt_regs) USBUploadFWComplete(pURB)
+#define USBKickOutCmdComplete(Status, pURB, pt_regs) USBKickOutCmdComplete(pURB)
+#ifdef CONFIG_MULTI_CHANNEL
+#define RTUSBBulkOutHCCANullFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutHCCANullFrameComplete(pURB)
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+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);
+USBHST_STATUS RTUSBBulkCmdRspEventComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs);
+#ifdef CONFIG_MULTI_CHANNEL
+USBHST_STATUS RTUSBBulkOutHCCANullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+#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_AP_SUPPORT
+#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870AP/e2p.bin"
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* RTMP_MAC_USB */
+
+#endif /* RALINK_ATE */
+
+
+/* OS definition re-declaration */
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef ETH_P_IPV6
+#define ETH_P_IPV6 0x86DD
+#endif
+
+#ifndef ETH_P_IP
+#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+#endif
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#undef KERN_EMERG
+#define KERN_EMERG
+#undef KERN_WARNING
+#define KERN_WARNING
+
+#undef copy_from_user
+#undef copy_to_user
+
+#define RTMP_OS_MAX_SCAN_DATA_GET RtmpOsMaxScanDataGet
+#define vmalloc RtmpOsVmalloc
+#define vfree RtmpOsVfree
+#define copy_from_user RtmpOsCopyFromUser
+#define copy_to_user RtmpOsCopyToUser
+#define simple_strtol RtmpOsSimpleStrtol
+
+#undef atomic_read
+#undef atomic_dec
+#undef InterlockedExchange
+#define atomic_read RtmpOsAtomicRead
+#define atomic_dec RtmpOsAtomicDec
+#define InterlockedExchange RtmpOsAtomicInterlockedExchange
+
+extern int sprintf(char * buf, const char * fmt, ...);
+extern int sscanf(const char *, const char *, ...);
+
+#define printk pRaOsOps->ra_printk
+#define snprintf pRaOsOps->ra_snprintf
+
+#endif /* __RT_LINUX_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/os/rt_linux.h b/cleopatre/devkit/mt7601udrv/include/os/rt_linux.h
new file mode 100644
index 0000000000..af57cd58b5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/os/rt_linux.h
@@ -0,0 +1,1575 @@
+/****************************************************************************
+
+ Module Name:
+ rt_linux.h
+
+ Abstract:
+ Any OS related definition/MACRO is defined here.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#ifndef __RT_LINUX_H__
+#define __RT_LINUX_H__
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/if_arp.h>
+#include <linux/ctype.h>
+#include <linux/vmalloc.h>
+#ifdef RTMP_USB_SUPPORT
+#include <linux/usb.h>
+#endif /* RTMP_USB_SUPPORT */
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+#ifdef INF_PPA_SUPPORT
+#include <net/ifx_ppa_api.h>
+#include <net/ifx_ppa_hook.h>
+#endif /* INF_PPA_SUPPORT */
+
+/* load firmware */
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/unaligned.h> /* for get_unaligned() */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/pid.h>
+#endif
+
+#ifdef RT_CFG80211_SUPPORT
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
+#include <net/mac80211.h>
+#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 */
+
+#ifdef MAT_SUPPORT
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/ip.h>
+#endif /* MAT_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 <linux/err.h>
+#include <linux/kthread.h>
+#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_AP_SUPPORT
+#ifdef WSC_AP_SUPPORT
+#define AP_WSC_INCLUDED
+#endif /* WSC_AP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#if defined(WSC_AP_SUPPORT) || defined(WSC_STA_SUPPORT)
+#define WSC_INCLUDED
+#endif
+
+#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_AP_SUPPORT
+#ifdef RTMP_MAC_USB
+#ifdef INF_AMAZON_SE
+#define AP_PROFILE_PATH "/ramdisk/etc/Wireless/RT2870AP/RT2870AP.dat"
+#define AP_RTMP_FIRMWARE_FILE_NAME "/ramdisk/etc/Wireless/RT2870AP/RT2870AP.bin"
+#else
+#define AP_PROFILE_PATH "/etc/Wireless/RT2870AP/RT2870AP.dat"
+#define AP_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2870AP/RT2870AP.bin"
+#endif
+#define AP_NIC_DEVICE_NAME "RT2870AP"
+#define AP_DRIVER_VERSION "3.0.0.1"
+#ifdef MULTIPLE_CARD_SUPPORT
+#define CARD_INFO_PATH "/etc/Wireless/RT2870AP/RT2870APCard.dat"
+#endif /* MULTIPLE_CARD_SUPPORT */
+#endif /* RTMP_MAC_USB */
+
+
+#ifdef SINGLE_SKU_V2
+#define SINGLE_SKU_TABLE_FILE_NAME "/etc/Wireless/RT2860STA/SingleSKU.dat"
+#endif /* SINGLE_SKU_V2 */
+
+#endif /* CONFIG_AP_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_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
+
+#define NET_DEVICE_REAL_IDX_MASK 0x0f /* for each operation mode, we maximum support 15 entities. */
+
+
+
+
+/***********************************************************************************
+ * 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);
+
+#ifdef WORKQUEUE_BH
+typedef struct work_struct OS_NET_TASK_STRUCT;
+typedef struct work_struct *POS_NET_TASK_STRUCT;
+#else
+typedef struct tasklet_struct OS_NET_TASK_STRUCT;
+typedef struct tasklet_struct *POS_NET_TASK_STRUCT;
+#endif /* WORKQUEUE_BH */
+
+/***********************************************************************************
+ * 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;
+#endif /* RTMP_MAC_USB */
+
+#ifdef WORKQUEUE_BH
+ UINT32 pAd_va;
+#endif /* WORKQUEUE_BH */
+
+ RTMP_NET_TASK_STRUCT rx_done_task;
+ RTMP_NET_TASK_STRUCT cmd_rsp_event_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;
+
+
+#ifdef UAPSD_SUPPORT
+ RTMP_NET_TASK_STRUCT uapsd_eosp_sent_task;
+#endif /* UAPSD_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef DFS_SUPPORT
+#ifdef DFS_SOFTWARE_SUPPORT
+ RTMP_NET_TASK_STRUCT pulse_radar_detect_task;
+ RTMP_NET_TASK_STRUCT width_radar_detect_task;
+#endif /* DFS_SOFTWARE_SUPPORT */
+#endif /* DFS_SUPPORT */
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ RTMP_NET_TASK_STRUCT carrier_sense_task;
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#ifdef DFS_SUPPORT
+ struct tasklet_struct dfs_task;
+#endif /* DFS_SUPPORT */
+
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef RTMP_MAC_USB
+ RTMP_NET_TASK_STRUCT null_frame_complete_task;
+ RTMP_NET_TASK_STRUCT pspoll_frame_complete_task;
+#endif /* RTMP_MAC_USB */
+
+#ifdef CONFIG_MULTI_CHANNEL
+ RTMP_NET_TASK_STRUCT hcca_null_frame_complete_task;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ RTMP_OS_PID apd_pid; /*802.1x daemon pid */
+ unsigned long apd_pid_nr;
+#ifdef CONFIG_AP_SUPPORT
+#ifdef IAPP_SUPPORT
+/* RT_SIGNAL_STRUC RTSignal; */
+ RTMP_OS_PID IappPid; /*IAPP daemon pid */
+ unsigned long IappPid_nr;
+#endif /* IAPP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+#ifdef WAPI_SUPPORT
+ RTMP_OS_PID wapi_pid; /*wapi daemon pid */
+ unsigned long wapi_pid_nr;
+#endif /* WAPI_SUPPORT */
+ 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;
+extern ULONG RTDebugFunc;
+
+#define DBGPRINT_RAW(Level, Fmt) \
+do{ \
+ ULONG __gLevel = (Level) & 0xff;\
+ ULONG __fLevel = ((Level)>>8) & 0xffffff;\
+ if (__gLevel <= RTDebugLevel) \
+ { \
+ if ((RTDebugFunc == 0) || \
+ ((RTDebugFunc != 0) && (((__fLevel & RTDebugFunc)!= 0) || (__gLevel <= RT_DEBUG_ERROR))))\
+ 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_FORCE_WRITE32(_A, _R, _V) \
+ do{\
+ /*if ((_R) != 0x404)*/ /* TODO:shiang-6590, depends on sw porting guide, don't acccess it now */\
+ RTUSBWriteMACRegister((_A), (_R), (UINT32) (_V), FALSE); \
+ }while(0)
+
+#define RTMP_IO_READ8(_A, _R, _pV) \
+{ \
+}
+
+#define RTMP_IO_WRITE32(_A, _R, _V) \
+ RTUSBWriteMACRegister((_A), (_R), (UINT32) (_V), FALSE)
+
+#define RTMP_IO_WRITE8(_A, _R, _V) \
+{ \
+ USHORT _Val = _V; \
+ RTUSBSingleWrite((_A), (_R), (USHORT) (_Val), FALSE); \
+}
+
+
+#define RTMP_IO_WRITE16(_A, _R, _V) \
+{ \
+ RTUSBSingleWrite((_A), (_R), (USHORT) (_V), FALSE); \
+}
+
+#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])
+
+
+
+#ifdef UAPSD_SUPPORT
+/* if we queue a U-APSD packet to any software queue, we will set the U-APSD
+ flag and its physical queue ID for it */
+#define RTMP_SET_PACKET_UAPSD(_p, _flg_uapsd, _que_id) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9] = ((_flg_uapsd<<7) | _que_id))
+
+#define RTMP_SET_PACKET_QOS_NULL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9] = 0xff)
+#define RTMP_GET_PACKET_QOS_NULL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9])
+#define RTMP_SET_PACKET_NON_QOS_NULL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9] = 0x00)
+#define RTMP_GET_PACKET_UAPSD_Flag(_p) (((RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9]) & 0x80) >> 7)
+#define RTMP_GET_PACKET_UAPSD_QUE_ID(_p) ((RTPKT_TO_OSPKT(_p)->cb[CB_OFF+9]) & 0x7f)
+
+#define RTMP_SET_PACKET_EOSP(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+10] = _flg)
+#define RTMP_GET_PACKET_EOSP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+10])
+#endif /* UAPSD_SUPPORT */
+
+/* */
+/* 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
+#define RTMP_PACKET_SPECIFIC_TDLS 0x40
+
+/*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)
+
+// TDLS
+#define RTMP_SET_PACKET_TDLS(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_TDLS); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (~RTMP_PACKET_SPECIFIC_TDLS); \
+ }while(0)
+
+#define RTMP_GET_PACKET_TDLS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_TDLS)
+
+/* 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])
+
+
+#ifdef DOT11_VHT_AC
+#define MAX_PACKETS_IN_QUEUE 1024 /*(512)*/
+#else
+#define MAX_PACKETS_IN_QUEUE (512)
+#endif /* DOT11_VHT_AC */
+
+
+/* use bit3 of cb[CB_OFF+16] */
+#define RTMP_SET_PACKET_MGMT_PKT(_p, _flg) \
+ RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] = (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0xF7) | ((_flg & 0x01) << 3);
+#define RTMP_GET_PACKET_MGMT_PKT(_p) \
+ ((RTPKT_TO_OSPKT(_p)->cb[CB_OFF+16] & 0x08) >> 3)
+
+/* use bit0 of cb[CB_OFF+20] */
+#define RTMP_SET_PACKET_MGMT_PKT_DATA_QUE(_p, _flg) \
+ RTPKT_TO_OSPKT(_p)->cb[CB_OFF+20] = (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+20] & 0xFE) | (_flg & 0x01);
+#define RTMP_GET_PACKET_MGMT_PKT_DATA_QUE(_p) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+20] & 0x01)
+
+#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 */
+
+
+
+#if defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_SUPPORT)
+#define RTMP_SET_TCP_CHKSUM_FAIL(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+30] = _flg);
+#define RTMP_GET_TCP_CHKSUM_FAIL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+30])
+#endif /* defined(CONFIG_CSO_SUPPORT) || defined(CONFIG_RX_CSO_SUPPORT) */
+
+
+/* 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
+
+#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev) \
+ _pAd = RTMP_OS_NETDEV_GET_PRIV(_net_dev);
+
+/*#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
+#ifdef CONFIG_MULTI_CHANNEL
+#define RtmpUsbBulkOutHCCANullFrameComplete RTUSBBulkOutHCCANullFrameComplete
+#endif /* CONFIG_MULTI_CHANNEL */
+#define RtmpUsbBulkOutRTSFrameComplete RTUSBBulkOutRTSFrameComplete
+#define RtmpUsbBulkOutPsPollComplete RTUSBBulkOutPsPollComplete
+#define RtmpUsbBulkRxComplete RTUSBBulkRxComplete
+#define RTUSBBulkCmdRspEventComplete(Status, pURB, pt_regs) RTUSBBulkCmdRspEventComplete(pURB)
+
+#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)
+#ifdef CONFIG_MULTI_CHANNEL
+#define RTUSBBulkOutHCCANullFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutHCCANullFrameComplete(pURB)
+#endif /* CONFIG_MULTI_CHANNEL */
+#define RTUSBBulkOutRTSFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutRTSFrameComplete(pURB)
+#define RTUSBBulkOutPsPollComplete(Status, pURB, pt_regs) RTUSBBulkOutPsPollComplete(pURB)
+#define RTUSBBulkRxComplete(Status, pURB, pt_regs) RTUSBBulkRxComplete(pURB)
+#define RTUSBBulkCmdRspEventComplete(Status, pURB, pt_regs) RTUSBBulkCmdRspEventComplete(pURB)
+#define USBUploadFWComplete(Status, pURB, pt_regs) USBUploadFWComplete(pURB)
+#define USBKickOutCmdComplete(Status, pURB, pt_regs) USBKickOutCmdComplete(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)
+#ifdef CONFIG_MULTI_CHANNEL
+#define RTUSBBulkOutHCCANullFrameComplete(Status, pURB, pt_regs) RTUSBBulkOutHCCANullFrameComplete(pURB, pt_regs)
+#endif /* CONFIG_MULTI_CHANNEL */
+#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)
+#define RTUSBBulkCmdRspEventComplete(Status, pURB, pt_regs) RTUSBBulkCmdRspEventComplete(pURB, pt_regs)
+#define USBUploadFWComplete(Status, pURB, pt_regs) USBUploadFWComplete(pURB, pt_regs)
+#define USBKickOutCmdComplete(Status, pURB, pt_regs) USBKickOutCmdComplete(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);
+#ifdef CONFIG_MULTI_CHANNEL
+USBHST_STATUS RTUSBBulkOutHCCANullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs);
+#endif /* CONFIG_MULTI_CHANNEL */
+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);
+USBHST_STATUS RTUSBBulkCmdRspEventComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs);
+USBHST_STATUS USBUploadFWComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs);
+USBHST_STATUS USBKickOutCmdComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs);
+
+
+/* Fill Bulk URB Macro */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RTUSB_FILL_TX_BULK_URB(pUrb, \
+ pUsb_Dev, \
+ uEndpointAddress, \
+ pTransferBuf, \
+ BufSize, \
+ Complete, \
+ pContext, \
+ TransferDma) \
+ do{ \
+ usb_fill_bulk_urb(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \
+ pTransferBuf, BufSize, Complete, pContext); \
+ pUrb->transfer_dma = TransferDma; \
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; \
+ }while(0)
+#else
+#define RTUSB_FILL_TX_BULK_URB(pUrb, \
+ pUsb_Dev, \
+ uEndpointAddress, \
+ pTransferBuf, \
+ BufSize, \
+ Complete, \
+ pContext, \
+ TransferDma) \
+ do{ \
+ FILL_BULK_URB(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \
+ pTransferBuf, BufSize, Complete, pContext); \
+ }while(0)
+
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RTUSB_FILL_HTTX_BULK_URB(pUrb, \
+ pUsb_Dev, \
+ uEndpointAddress, \
+ pTransferBuf, \
+ BufSize, \
+ Complete, \
+ pContext, \
+ TransferDma) \
+ do{ \
+ usb_fill_bulk_urb(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \
+ pTransferBuf, BufSize, Complete, pContext); \
+ pUrb->transfer_dma = TransferDma; \
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; \
+ }while(0)
+#else
+#define RTUSB_FILL_HTTX_BULK_URB(pUrb, \
+ pUsb_Dev, \
+ uEndpointAddress, \
+ pTransferBuf, \
+ BufSize, \
+ Complete, \
+ pContext, \
+ TransferDma) \
+ do{ \
+ FILL_BULK_URB(pUrb, pUsb_Dev, usb_sndbulkpipe(pUsb_Dev, uEndpointAddress), \
+ pTransferBuf, BufSize, Complete, pContext); \
+ }while(0)
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RTUSB_FILL_RX_BULK_URB(pUrb, \
+ pUsb_Dev, \
+ uEndpointAddress, \
+ pTransferBuf, \
+ BufSize, \
+ Complete, \
+ pContext, \
+ TransferDma) \
+ do{ \
+ usb_fill_bulk_urb(pUrb, pUsb_Dev, usb_rcvbulkpipe(pUsb_Dev, uEndpointAddress), \
+ pTransferBuf, BufSize, Complete, pContext); \
+ pUrb->transfer_dma = TransferDma; \
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; \
+ }while(0)
+/* pRxContext->data_dma + pAd->NextRxBulkInPosition; */
+#else
+#define RTUSB_FILL_RX_BULK_URB(pUrb, \
+ pUsb_Dev, \
+ uEndpointAddress, \
+ pTransferBuf, \
+ BufSize, \
+ Complete, \
+ pContext, \
+ TransferDma) \
+ do{ \
+ FILL_BULK_URB(pUrb, pUsb_Dev, usb_rcvbulkpipe(pUsb_Dev, uEndpointAddress), \
+ pTransferBuf, BufSize, Complete, pContext); \
+ }while(0)
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RTUSB_URB_DMA_MAPPING(pUrb) \
+ { \
+ pUrb->transfer_dma = 0; \
+ pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP); \
+ }
+#else
+#define RTUSB_URB_DMA_MAPPING(pUrb)
+#endif
+
+#define RTUSB_CONTROL_MSG(pUsb_Dev, uEndpointAddress, Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, timeout, ret) \
+ do{ \
+ if (RequestType == DEVICE_VENDOR_REQUEST_OUT) \
+ ret = USB_CONTROL_MSG(pUsb_Dev, usb_sndctrlpipe(pUsb_Dev, uEndpointAddress), Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, timeout); \
+ else if (RequestType == DEVICE_VENDOR_REQUEST_IN) \
+ ret = USB_CONTROL_MSG(pUsb_Dev, usb_rcvctrlpipe(pUsb_Dev, uEndpointAddress), Request, RequestType, Value, Index, tmpBuf, TransferBufferLength, timeout); \
+ else \
+ { \
+ DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n")); \
+ ret = -1; \
+ } \
+ }while(0)
+
+#define rtusb_urb_context context
+#define rtusb_urb_status status
+
+#define RTMP_OS_USB_CONTEXT_GET(__pURB) __pURB->rtusb_urb_context
+#define RTMP_OS_USB_STATUS_GET(__pURB) __pURB->rtusb_urb_status
+
+#ifndef OS_ABL_SUPPORT
+#define USB_CONTROL_MSG usb_control_msg
+
+#else
+
+#define USB_CONTROL_MSG rausb_control_msg
+
+/*extern int rausb_register(struct usb_driver * new_driver); */
+/*extern void rausb_deregister(struct usb_driver * driver); */
+
+extern struct urb *rausb_alloc_urb(int iso_packets);
+extern void rausb_free_urb(VOID *urb);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+extern void rausb_put_dev(VOID *dev);
+extern struct usb_device *rausb_get_dev(VOID *dev);
+#endif /* LINUX_VERSION_CODE */
+
+extern int rausb_submit_urb(VOID *urb);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#ifndef gfp_t
+#define gfp_t INT32
+#endif /* gfp_t */
+
+extern void *rausb_buffer_alloc(VOID *dev,
+ size_t size,
+ ra_dma_addr_t *dma);
+extern void rausb_buffer_free(VOID *dev,
+ size_t size,
+ void *addr,
+ ra_dma_addr_t dma);
+#endif /* LINUX_VERSION_CODE */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7)
+extern void rausb_kill_urb(VOID *urb);
+#endif /* LINUX_VERSION_CODE */
+
+extern int rausb_control_msg(VOID *dev,
+ unsigned int pipe,
+ __u8 request,
+ __u8 requesttype,
+ __u16 value,
+ __u16 index,
+ void *data,
+ __u16 size,
+ int timeout);
+
+#endif /* OS_ABL_SUPPORT */
+
+/*#endif // RTMP_USB_SUPPORT */
+
+#ifdef RALINK_ATE
+/******************************************************************************
+
+ ATE related definitions
+
+******************************************************************************/
+#define ate_print printk
+#define ATEDBGPRINT DBGPRINT
+
+#ifdef RTMP_MAC_USB
+#ifdef CONFIG_AP_SUPPORT
+#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870AP/e2p.bin"
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* RTMP_MAC_USB */
+
+#ifdef RTMP_USB_SUPPORT
+
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 51)) || (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)))
+/* Prototypes of completion funuc. */
+#define ATE_RTUSBBulkOutDataPacketComplete(Status, pURB, pt_regs) ATE_RTUSBBulkOutDataPacketComplete(pURB)
+#else
+#define ATE_RTUSBBulkOutDataPacketComplete(Status, pURB, pt_regs) ATE_RTUSBBulkOutDataPacketComplete(pURB, pt_regs)
+#endif /* LINUX_VERSION_CODE */
+
+USBHST_STATUS ATE_RTUSBBulkOutDataPacketComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs);
+
+#endif /* RTMP_USB_SUPPORT */
+
+#endif /* RALINK_ATE */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
+INT RtmpOSNetDevOpsAlloc(
+ IN PVOID *pNetDevOps);
+#endif
+
+#define RTMP_OS_MAX_SCAN_DATA_GET() IW_SCAN_MAX_DATA
+
+#include "os/rt_os.h"
+
+#endif /* __RT_LINUX_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/os/rt_linux_cmm.h b/cleopatre/devkit/mt7601udrv/include/os/rt_linux_cmm.h
new file mode 100644
index 0000000000..6d0d0cc38b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/os/rt_linux_cmm.h
@@ -0,0 +1,412 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt_linux_cmm.h
+
+ Abstract:
+ Common OS structure/definition in LINUX whatever OS ABL.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+
+#ifndef __RT_LINUX_CMM_H__
+#define __RT_LINUX_CMM_H__
+
+
+typedef struct _OS_RSTRUC {
+ UCHAR *pContent; /* pointer to real structure content */
+} OS_RSTRUC;
+
+
+/* declare new chipset function here */
+#ifdef OS_ABL_FUNC_SUPPORT
+
+#define RTMP_DECLARE_DRV_OPS_FUNCTION(_func) \
+ void Rtmp_Drv_Ops_##_func(VOID *__pDrvOps, VOID *__pNetOps, \
+ VOID *__pPciConfig, VOID *__pUsbConfig)
+
+#define RTMP_BUILD_DRV_OPS_FUNCTION(_func) \
+void Rtmp_Drv_Ops_##_func(VOID *__pDrvOps, VOID *__pNetOps, \
+ VOID *__pPciConfig, VOID *__pUsbConfig) \
+{ \
+ RtmpDrvOpsInit(__pDrvOps, __pNetOps, __pPciConfig, __pUsbConfig);\
+}
+
+#define RTMP_GET_DRV_OPS_FUNCTION(_func) \
+ (PVOID)Rtmp_Drv_Ops_##_func
+
+#define RTMP_DRV_OPS_FUNCTION_BODY(_func) \
+ Rtmp_Drv_Ops_##_func
+
+
+#define xdef_to_str(s) def_to_str(s)
+#define def_to_str(s) #s
+
+
+#ifdef RTMP_MAC_USB
+#define RTMP_DRV_NAME "rtusb" xdef_to_str(RT28xx_MODE)
+RTMP_DECLARE_DRV_OPS_FUNCTION(usb);
+#define RTMP_DRV_OPS_FUNCTION RTMP_DRV_OPS_FUNCTION_BODY(usb)
+#define RTMP_BUILD_DRV_OPS_FUNCTION_BODY RTMP_BUILD_DRV_OPS_FUNCTION(usb)
+#endif /* RTMP_MAC_USB */
+
+#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)
+#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)
+
+#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_OS_ATMOIC_DESTROY(__pAtomic)
+#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_OS_ATMOIC_DESTROY RtmpOsAtomicDestroy
+#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, __Data) \
+ INIT_WORK((struct work_struct *)__pTasklet, (work_func_t)__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.
+*/
+/*
+ In big-endian & 32-bit DMA address platform, if you use long long to
+ record DMA address, when you call kernel function to set DMA address,
+ the address will be 0 because you need to do swap I think.
+ So if you sure your DMA address is 32-bit, do not use RTMP_DMA_ADDR_64.
+*/
+#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)
+
+
+#define RTMP_OS_NETDEV_SET_PRIV RtmpOsSetNetDevPriv
+#define RTMP_OS_NETDEV_GET_PRIV RtmpOsGetNetDevPriv
+#define RT_DEV_PRIV_FLAGS_GET RtmpDevPrivFlagsGet
+#define RT_DEV_PRIV_FLAGS_SET RtmpDevPrivFlagsSet
+
+#endif /* __RT_LINUX_CMM_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/os/rt_os.h b/cleopatre/devkit/mt7601udrv/include/os/rt_os.h
new file mode 100644
index 0000000000..3f3b8fc741
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/os/rt_os.h
@@ -0,0 +1,83 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_os.h
+
+ Abstract:
+ Put all OS related definition/structure/MACRO here.
+
+ Note:
+ Used in UTIL/NETIF module.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifndef _RT_OS_H_
+#define _RT_OS_H_
+
+
+#ifdef LINUX
+#if WIRELESS_EXT <= 11
+#ifndef SIOCDEVPRIVATE
+#define SIOCDEVPRIVATE 0x8BE0
+#endif
+#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
+#endif
+#endif /* LINUX */
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+/* Ralink defined OIDs */
+#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x01)
+#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02)
+#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x0E) /* Sync. with RT61 (for wpa_supplicant) */
+#ifdef DBG
+#define RTPRIV_IOCTL_BBP (SIOCIWFIRSTPRIV + 0x03)
+#define RTPRIV_IOCTL_MAC (SIOCIWFIRSTPRIV + 0x05)
+
+#define RTPRIV_IOCTL_RF (SIOCIWFIRSTPRIV + 0x13)
+
+#endif /* DBG */
+#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07)
+
+#define RTPRIV_IOCTL_ATE (SIOCIWFIRSTPRIV + 0x08)
+
+#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 RTPRIV_IOCTL_ADD_WPA_KEY (SIOCIWFIRSTPRIV + 0x0E)
+#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_STATIC_WEP_COPY (SIOCIWFIRSTPRIV + 0x10)
+
+#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11)
+#define RTPRIV_IOCTL_WSC_PROFILE (SIOCIWFIRSTPRIV + 0x12)
+#define RTPRIV_IOCTL_QUERY_BATABLE (SIOCIWFIRSTPRIV + 0x16)
+#ifdef INF_AR9
+#define RTPRIV_IOCTL_GET_AR9_SHOW (SIOCIWFIRSTPRIV + 0x17)
+#endif/* INF_AR9 */
+#define RTPRIV_IOCTL_SET_WSCOOB (SIOCIWFIRSTPRIV + 0x19)
+#define RTPRIV_IOCTL_WSC_CALLBACK (SIOCIWFIRSTPRIV + 0x1A)
+#endif /* CONFIG_AP_SUPPORT */
+
+#endif /* _RT_OS_H_ */
diff --git a/cleopatre/devkit/mt7601udrv/include/phy/rlt_phy.h b/cleopatre/devkit/mt7601udrv/include/phy/rlt_phy.h
new file mode 100644
index 0000000000..df418d71bf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/phy/rlt_phy.h
@@ -0,0 +1,275 @@
+
+/*
+
+*/
+
+
+#ifndef __RLT_PHY_H__
+#define __RLT_PHY_H_
+
+
+#define BBP_CORE 0x2000
+#define BBP_IBI 0x2100
+#define BBP_AGC1 0x2300
+#define BBP_TXC 0x2400
+#define BBP_RXC 0x2500
+#define BBP_TXO 0x2600
+#define BBP_TXBE 0x2700
+#define BBP_RXFE 0x2800
+#define BBP_RXO 0x2900
+#define BBP_DFS 0x2a00
+#define BBP_TR 0x2b00
+#define BBP_CAL 0x2c00
+#define BBP_DSC 0x2d00
+#define BBP_PFMU 0x2f00
+
+
+/* 0x2000 ~ */
+#define CORE_R0 (BBP_CORE + 0x00)
+#define CORE_R1 (BBP_CORE + 0x04)
+#define CORE_R4 (BBP_CORE + 0x10)
+#define CORE_R24 (BBP_CORE + 0x60)
+#define CORE_R32 (BBP_CORE + 0x80)
+#define CORE_R35 (BBP_CORE + 0x8c)
+#define CORE_R42 (BBP_CORE + 0xa8)
+#define CORE_R44 (BBP_CORE + 0xb0)
+
+/* 0x2100 ~ */
+#define IBI_R0 (BBP_IBI + 0x00)
+#define IBI_R1 (BBP_IBI + 0x04)
+#define IBI_R2 (BBP_IBI + 0x08)
+#define IBI_R3 (BBP_IBI + 0x0c)
+#define IBI_R4 (BBP_IBI + 0x10)
+#define IBI_R5 (BBP_IBI + 0x14)
+#define IBI_R6 (BBP_IBI + 0x18)
+#define IBI_R7 (BBP_IBI + 0x1c)
+#define IBI_R9 (BBP_IBI + 0x24)
+#define IBI_R11 (BBP_IBI + 0x2c)
+
+/* 0x2300 ~ */
+#define AGC1_R0 (BBP_AGC1 + 0x00)
+#define AGC1_R1 (BBP_AGC1 + 0x04)
+#define AGC1_R2 (BBP_AGC1 + 0x08)
+#define AGC1_R4 (BBP_AGC1 + 0x10)
+#define AGC1_R5 (BBP_AGC1 + 0x14)
+#define AGC1_R8 (BBP_AGC1 + 0x20)
+#define AGC1_R9 (BBP_AGC1 + 0x24)
+#define AGC1_R12 (BBP_AGC1 + 0x30)
+#define AGC1_R13 (BBP_AGC1 + 0x34)
+#define AGC1_R14 (BBP_AGC1 + 0x38)
+#define AGC1_R16 (BBP_AGC1 + 0x40)
+#define AGC1_R18 (BBP_AGC1 + 0x48)
+#define AGC1_R19 (BBP_AGC1 + 0x4c)
+#define AGC1_R20 (BBP_AGC1 + 0x50)
+#define AGC1_R21 (BBP_AGC1 + 0x54)
+#define AGC1_R22 (BBP_AGC1 + 0x58)
+#define AGC1_R23 (BBP_AGC1 + 0x5c)
+#define AGC1_R24 (BBP_AGC1 + 0x60)
+#define AGC1_R25 (BBP_AGC1 + 0x64)
+#define AGC1_R26 (BBP_AGC1 + 0x68)
+#define AGC1_R27 (BBP_AGC1 + 0x6c)
+#define AGC1_R28 (BBP_AGC1 + 0x70)
+#define AGC1_R30 (BBP_AGC1 + 0x78)
+#define AGC1_R31 (BBP_AGC1 + 0x7c)
+#define AGC1_R32 (BBP_AGC1 + 0x80)
+#define AGC1_R33 (BBP_AGC1 + 0x84)
+#define AGC1_R34 (BBP_AGC1 + 0x88)
+#define AGC1_R35 (BBP_AGC1 + 0x8c)
+#define AGC1_R37 (BBP_AGC1 + 0x94)
+#define AGC1_R39 (BBP_AGC1 + 0x9c)
+#define AGC1_R41 (BBP_AGC1 + 0xa4)
+#define AGC1_R43 (BBP_AGC1 + 0xac)
+#define AGC1_R45 (BBP_AGC1 + 0xb4)
+#define AGC1_R47 (BBP_AGC1 + 0xbc)
+#define AGC1_R49 (BBP_AGC1 + 0xc4)
+#define AGC1_R51 (BBP_AGC1 + 0xcc)
+#define AGC1_R53 (BBP_AGC1 + 0xd4)
+#define AGC1_R55 (BBP_AGC1 + 0xdc)
+#define AGC1_R57 (BBP_AGC1 + 0xe4)
+#define AGC1_R58 (BBP_AGC1 + 0xe8)
+#define AGC1_R59 (BBP_AGC1 + 0xec)
+#define AGC1_R60 (BBP_AGC1 + 0xf0)
+#define AGC1_R61 (BBP_AGC1 + 0xf4)
+#define AGC1_R62 (BBP_AGC1 + 0xf8)
+#define AGC1_R63 (BBP_AGC1 + 0xfc)
+
+/* 0x2400 ~ */
+#define TXC_R0 (BBP_TXC + 0x00)
+#define TXC_R1 (BBP_TXC + 0x04)
+
+/* 0x2500 ~ */
+#define RXC_R0 (BBP_RXC + 0x00)
+#define RXC_R1 (BBP_RXC + 0x04)
+#define RXC_R2 (BBP_RXC + 0x08)
+#define RXC_R3 (BBP_RXC + 0x0c)
+#define RXC_R4 (BBP_RXC + 0x10)
+
+/* 0x2600 ~ */
+#define TXO_R0 (BBP_TXO + 0x00)
+#define TXO_R1 (BBP_TXO + 0x04)
+#define TXO_R2 (BBP_TXO + 0x08)
+#define TXO_R3 (BBP_TXO + 0x0c)
+#define TXO_R4 (BBP_TXO + 0x10)
+#define TXO_R5 (BBP_TXO + 0x14)
+#define TXO_R6 (BBP_TXO + 0x18)
+#define TXO_R7 (BBP_TXO + 0x1c)
+#define TXO_R8 (BBP_TXO + 0x20)
+
+/* 0x2700 ~ */
+#define TXBE_R0 (BBP_TXBE + 0x00)
+#define TXBE_R1 (BBP_TXBE + 0x04)
+#define TXBE_R2 (BBP_TXBE + 0x08)
+#define TXBE_R3 (BBP_TXBE + 0x0c)
+#define TXBE_R4 (BBP_TXBE + 0x10)
+#define TXBE_R5 (BBP_TXBE + 0x14)
+#define TXBE_R6 (BBP_TXBE + 0x18)
+#define TXBE_R8 (BBP_TXBE + 0x20)
+#define TXBE_R9 (BBP_TXBE + 0x24)
+#define TXBE_R10 (BBP_TXBE + 0x28)
+#define TXBE_R12 (BBP_TXBE + 0x30)
+#define TXBE_R13 (BBP_TXBE + 0x34)
+#define TXBE_R14 (BBP_TXBE + 0x38)
+#define TXBE_R15 (BBP_TXBE + 0x3c)
+#define TXBE_R16 (BBP_TXBE + 0x40)
+#define TXBE_R17 (BBP_TXBE + 0x44)
+
+/* 0x2800 ~ */
+#define RXFE_R0 (BBP_RXFE + 0x00)
+#define RXFE_R2 (BBP_RXFE + 0x08)
+#define RXFE_R3 (BBP_RXFE + 0x0c)
+#define RXFE_R4 (BBP_RXFE + 0x10)
+
+/* 0x2900 ~ */
+#define RXO_R9 (BBP_RXO + 0x24)
+#define RXO_R13 (BBP_RXO + 0x34)
+#define RXO_R14 (BBP_RXO + 0x38)
+#define RXO_R15 (BBP_RXO + 0x3c)
+#define RXO_R16 (BBP_RXO + 0x40)
+#define RXO_R17 (BBP_RXO + 0x44)
+#define RXO_R21 (BBP_RXO + 0x54)
+#define RXO_R24 (BBP_RXO + 0x60)
+#define RXO_R28 (BBP_RXO + 0x70)
+#define RXO_R29 (BBP_RXO + 0x74)
+
+/* 0x2a00 ~ */
+#define DFS_R0 (BBP_DFS + 0x00)
+#define DFS_R1 (BBP_DFS + 0x04)
+#define DFS_R2 (BBP_DFS + 0x08)
+#define DFS_R3 (BBP_DFS + 0x0c)
+#define DFS_R4 (BBP_DFS + 0x10)
+#define DFS_R5 (BBP_DFS + 0x14)
+#define DFS_R7 (BBP_DFS + 0x1c)
+#define DFS_R9 (BBP_DFS + 0x24)
+#define DFS_R11 (BBP_DFS + 0x2c)
+#define DFS_R13 (BBP_DFS + 0x34)
+#define DFS_R14 (BBP_DFS + 0x38)
+#define DFS_R15 (BBP_DFS + 0x3c)
+#define DFS_R17 (BBP_DFS + 0x44)
+#define DFS_R19 (BBP_DFS + 0x4c)
+#define DFS_R20 (BBP_DFS + 0x50)
+#define DFS_R22 (BBP_DFS + 0x58)
+#define DFS_R23 (BBP_DFS + 0x5c)
+#define DFS_R25 (BBP_DFS + 0x64)
+#define DFS_R26 (BBP_DFS + 0x68)
+#define DFS_R28 (BBP_DFS + 0x70)
+#define DFS_R30 (BBP_DFS + 0x78)
+#define DFS_R31 (BBP_DFS + 0x7c)
+
+/* 0x2c00 ~ */
+#define CAL_R0 (BBP_CAL + 0x00)
+#define CAL_R1 (BBP_CAL + 0x04)
+#define CAL_R2 (BBP_CAL + 0x08)
+#define CAL_R3 (BBP_CAL + 0x0c)
+#define CAL_R4 (BBP_CAL + 0x10)
+#define CAL_R5 (BBP_CAL + 0x14)
+#define CAL_R6 (BBP_CAL + 0x18)
+#define CAL_R7 (BBP_CAL + 0x1C)
+#define CAL_R8 (BBP_CAL + 0x20)
+#define CAL_R9 (BBP_CAL + 0x24)
+#define CAL_R10 (BBP_CAL + 0x28)
+#define CAL_R11 (BBP_CAL + 0x2C)
+#define CAL_R12 (BBP_CAL + 0x30)
+#define CAL_R13 (BBP_CAL + 0x34)
+#define CAL_R14 (BBP_CAL + 0x38)
+#define CAL_R15 (BBP_CAL + 0x3C)
+#define CAL_R16 (BBP_CAL + 0x40)
+#define CAL_R17 (BBP_CAL + 0x44)
+#define CAL_R18 (BBP_CAL + 0x48)
+#define CAL_R19 (BBP_CAL + 0x4C)
+#define CAL_R20 (BBP_CAL + 0x50)
+#define CAL_R21 (BBP_CAL + 0x54)
+#define CAL_R22 (BBP_CAL + 0x58)
+#define CAL_R23 (BBP_CAL + 0x5C)
+#define CAL_R24 (BBP_CAL + 0x60)
+#define CAL_R25 (BBP_CAL + 0x64)
+#define CAL_R26 (BBP_CAL + 0x68)
+#define CAL_R27 (BBP_CAL + 0x6C)
+#define CAL_R28 (BBP_CAL + 0x70)
+#define CAL_R29 (BBP_CAL + 0x74)
+#define CAL_R30 (BBP_CAL + 0x78)
+#define CAL_R31 (BBP_CAL + 0x7C)
+#define CAL_R32 (BBP_CAL + 0x80)
+#define CAL_R33 (BBP_CAL + 0x84)
+#define CAL_R34 (BBP_CAL + 0x88)
+#define CAL_R35 (BBP_CAL + 0x8C)
+#define CAL_R36 (BBP_CAL + 0x90)
+#define CAL_R37 (BBP_CAL + 0x94)
+#define CAL_R38 (BBP_CAL + 0x98)
+#define CAL_R39 (BBP_CAL + 0x9C)
+#define CAL_R40 (BBP_CAL + 0xA0)
+#define CAL_R41 (BBP_CAL + 0xA4)
+#define CAL_R42 (BBP_CAL + 0xA8)
+#define CAL_R43 (BBP_CAL + 0xAC)
+#define CAL_R44 (BBP_CAL + 0xB0)
+#define CAL_R45 (BBP_CAL + 0xB4)
+#define CAL_R46 (BBP_CAL + 0xB8)
+#define CAL_R47 (BBP_CAL + 0xBC)
+#define CAL_R48 (BBP_CAL + 0xC0)
+#define CAL_R49 (BBP_CAL + 0xC4)
+#define CAL_R50 (BBP_CAL + 0xC8)
+#define CAL_R51 (BBP_CAL + 0xCC)
+#define CAL_R52 (BBP_CAL + 0xD0)
+#define CAL_R53 (BBP_CAL + 0xD4)
+#define CAL_R54 (BBP_CAL + 0xD8)
+#define CAL_R55 (BBP_CAL + 0xDC)
+#define CAL_R56 (BBP_CAL + 0xE0)
+#define CAL_R57 (BBP_CAL + 0xE4)
+#define CAL_R58 (BBP_CAL + 0xE8)
+#define CAL_R59 (BBP_CAL + 0xEC)
+#define CAL_R60 (BBP_CAL + 0xF0)
+#define CAL_R61 (BBP_CAL + 0xF4)
+#define CAL_R62 (BBP_CAL + 0xF8)
+#define CAL_R63 (BBP_CAL + 0xFC)
+#define CAL_R64 (BBP_CAL + 0x100)
+#define CAL_R65 (BBP_CAL + 0x104)
+#define CAL_R66 (BBP_CAL + 0x108)
+#define CAL_R67 (BBP_CAL + 0x10C)
+#define CAL_R68 (BBP_CAL + 0x110)
+#define CAL_R69 (BBP_CAL + 0x114)
+#define CAL_R70 (BBP_CAL + 0x118)
+
+
+#define RTMP_BBP_IO_READ32(_p, _i, _pV) RTMP_IO_READ32(_p, _i, _pV)
+#define RTMP_BBP_IO_WRITE32(_p, _i, _v) RTMP_IO_WRITE32(_p, _i, _v)
+
+#define RF_BANK0 0
+#define RF_BANK1 1
+#define RF_BANK2 2
+#define RF_BANK3 3
+#define RF_BANK4 4
+#define RF_BANK5 5
+#define RF_BANK6 6
+#define RF_BANK7 7
+#define RF_BANK8 8
+#define RF_BANK9 9
+#define RF_BANK10 10
+#define RF_BANK11 11
+#define RF_BANK12 12
+#define RF_BANK13 13
+#define RF_BANK14 14
+#define RF_BANK15 15
+
+INT rlt_bbp_is_ready(struct _RTMP_ADAPTER *pAd);
+
+#endif /* __RLT_PHY_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/radar.h b/cleopatre/devkit/mt7601udrv/include/radar.h
new file mode 100644
index 0000000000..ce3f27f2d3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/radar.h
@@ -0,0 +1,89 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ radar.h
+
+ Abstract:
+ CS/DFS common functions.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+#ifndef __RADAR_H__
+#define __RADAR_H__
+
+/* RESTRICTION_BAND_1: 5600MHz ~ 5650MHz */
+#define RESTRICTION_BAND_1(_pAd) \
+ _pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40 ? \
+ ((_pAd->CommonCfg.Channel >= 116) && (_pAd->CommonCfg.Channel <= 128)) : \
+ ((_pAd->CommonCfg.Channel >= 120) && (_pAd->CommonCfg.Channel <= 128))
+
+/* 802.11H */
+typedef struct _DOT11_H {
+ /* 802.11H and DFS related params */
+ UCHAR CSCount; /*Channel switch counter */
+ UCHAR CSPeriod; /*Channel switch period (beacon count) */
+ USHORT RDCount; /*Radar detection counter, if RDCount > ChMovingTime, start to send beacons*/
+ UCHAR RDMode; /*Radar Detection mode */
+ USHORT ChMovingTime;
+ BOOLEAN bDFSIndoor;
+ ULONG InServiceMonitorCount; /* unit: sec */
+} DOT11_H, *PDOT11_H;
+
+BOOLEAN RadarChannelCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ch);
+
+ULONG JapRadarType(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef CONFIG_AP_SUPPORT
+VOID ChannelSwitchingCountDownProc(
+ IN PRTMP_ADAPTER pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID RadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd);
+
+INT Set_CSPeriod_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_ChMovingTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_BlockChReset_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#if defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT)
+INT Set_RadarShow_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+VOID CckMrcStatusCtrl(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RadarGLRTCompensate(
+ IN PRTMP_ADAPTER pAd);
+
+#endif /*defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT)*/
+
+#endif /* __RADAR_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rt_config.h b/cleopatre/devkit/mt7601udrv/include/rt_config.h
new file mode 100644
index 0000000000..d1b382b357
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rt_config.h
@@ -0,0 +1,211 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_config.h
+
+ Abstract:
+ Central header file to maintain all include files for all NDIS
+ miniport driver routines.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+
+*/
+#ifndef __RT_CONFIG_H__
+#define __RT_CONFIG_H__
+
+/* #define WDS_VLAN_SUPPORT */
+
+#include "rtmp_comm.h"
+/*#include "rtmp_type.h" */
+/*#include "rtmp_os.h" */
+
+#include "rtmp_def.h"
+#include "rtmp_chip.h"
+#include "rtmp_timer.h"
+
+
+#ifdef LINUX
+#ifdef RT_CFG80211_SUPPORT
+#include "cfg80211extr.h"
+#endif /* RT_CFG80211_SUPPORT */
+#endif /* LINUX */
+
+#ifdef AGS_SUPPORT
+#include "ags.h"
+#endif /* AGS_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 "chlist.h"
+#include "spectrum.h"
+#ifdef CONFIG_AP_SUPPORT
+#include "ap_autoChSel.h"
+#endif /* CONFIG_AP_SUPPORT */
+#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 UAPSD_SUPPORT
+#include "uapsd.h"
+#endif /* UAPSD_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+#include "ap_mbss.h"
+#endif /* MBSS_SUPPORT */
+
+#ifdef WDS_SUPPORT
+#include "ap_wds.h"
+#endif /* WDS_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+#include "ap_apcli.h"
+#endif /* APCLI_SUPPORT */
+
+#ifdef WSC_AP_SUPPORT
+#define AP_WSC_INCLUDED
+#endif /* WSC_AP_SUPPORT */
+
+#include "ap_ids.h"
+#include "ap_cfg.h"
+
+#ifdef CLIENT_WDS
+#include "client_wds.h"
+#endif /* CLIENT_WDS */
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef MAT_SUPPORT
+#include "mat.h"
+#endif /* MAT_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
+#include "rt_qa.h"
+#endif /* RALINK_QA */
+
+#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 */
+
+
+
+#ifdef WAPI_SUPPORT
+#include "wapi.h"
+#endif /* WAPI_SUPPORT */
+
+
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+//#ifdef CONFIG_AP_SUPPORT
+//#ifdef WDS_SUPPORT
+#define RALINK_PASSPHRASE "Ralink"
+//#endif /* WDS_SUPPORT */
+//#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+#ifndef APCLI_SUPPORT
+#error "Build Apcli for being controlled by NetworkManager or wext, please set HAS_APCLI_SUPPORT=y and HAS_APCLI_WPA_SUPPLICANT=y"
+#endif /* APCLI_SUPPORT */
+#endif /* APCLI_WPA_SUPPLICANT_SUPPORT */
+
+
+
+#ifdef WSC_INCLUDED
+#include "crypt_biginteger.h"
+#include "crypt_dh.h"
+#include "wsc_tlv.h"
+#endif /* WSC_INCLUDED */
+
+
+#ifdef IKANOS_VX_1X0
+#include "vr_ikans.h"
+#endif /* IKANOS_VX_1X0 */
+
+
+
+
+
+#ifdef WAPI_SUPPORT
+#include "wapi.h"
+#endif /* WAPI_SUPPORT */
+
+
+#ifdef WFD_SUPPORT
+#include "wfd.h"
+#endif /* WFD_SUPPORT */
+
+#ifdef DOT11_VHT_AC
+#include "vht.h"
+#endif /* DOT11_VHT_AC */
+
+
+
+
+#ifdef WORKQUEUE_BH
+#include <linux/workqueue.h>
+#endif /* WORKQUEUE_BH / */
+
+
+#ifdef TXBF_SUPPORT
+#include "rt_txbf.h"
+#endif /* TXBF_SUPPORT */
+
+
+#include "mac_ral/fce.h"
+
+#endif /* __RT_CONFIG_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/rt_os_net.h b/cleopatre/devkit/mt7601udrv/include/rt_os_net.h
new file mode 100644
index 0000000000..b4a69b44e4
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rt_os_net.h
@@ -0,0 +1,583 @@
+/****************************************************************************
+
+ Module Name:
+ rt_os_net.h
+
+ Abstract:
+ All function prototypes are defined in NETIF modules.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#ifndef __RT_OS_NET_H__
+#define __RT_OS_NET_H__
+
+#include "chip/chip_id.h"
+
+typedef VOID *(*RTMP_NET_ETH_CONVERT_DEV_SEARCH)(VOID *net_dev, UCHAR *pData);
+typedef int (*RTMP_NET_PACKET_TRANSMIT)(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)(PVOID handle, VOID **ppAdapter);
+VOID (*RTMPFreeAdapter)(VOID *pAd);
+BOOLEAN (*RtmpRaDevCtrlExit)(VOID *pAd);
+INT (*RtmpRaDevCtrlInit)(VOID *pAd, RTMP_INF_TYPE infType);
+VOID (*RTMPHandleInterrupt)(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)(VOID *pAd);
+
+VOID (*RTMPDrvClose)(VOID *pAd, VOID *net_dev);
+
+VOID (*RTMPInfClose)(VOID *pAd);
+
+int (*rt28xx_init)(VOID *pAd, PSTRING pDefaultMac, 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)(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;
+
+#ifdef CONFIG_MULTI_CHANNEL
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutHCCANullFrameComplete;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutRTSFrameComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkOutPsPollComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkRxComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpNetUsbBulkCmdRspEventComplete;
+
+/* drv complete handlers */
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutDataPacketComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutMLMEPacketComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutNullFrameComplete;
+
+#ifdef CONFIG_MULTI_CHANNEL
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutHCCANullFrameComplete;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutRTSFrameComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutPsPollComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkRxComplete;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkCmdRspEventComplete;
+
+#endif /* RTMP_USB_SUPPORT */
+
+} RTMP_NET_ABL_OPS;
+
+extern RTMP_NET_ABL_OPS *pRtmpDrvNetOps;
+
+VOID RtmpNetOpsInit(VOID *pNetOpsOrg);
+VOID RtmpNetOpsSet(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(PVOID handle, VOID **ppAdapter);
+VOID RTMPFreeAdapter(VOID *pAd);
+BOOLEAN RtmpRaDevCtrlExit(VOID *pAd);
+INT RtmpRaDevCtrlInit(VOID *pAd, RTMP_INF_TYPE infType);
+VOID RTMPHandleInterrupt(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_AP_SUPPORT
+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);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+VOID RTMPDrvOpen(VOID *pAd);
+VOID RTMPDrvClose(VOID *pAd, VOID *net_dev);
+VOID RTMPInfClose(VOID *pAd);
+
+int rt28xx_init(
+ IN VOID *pAd,
+ IN PSTRING pDefaultMac,
+ IN PSTRING pHostName);
+
+PNET_DEV RtmpPhyNetDevMainCreate(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_AP_SUPPORT
+INT rt28xx_ap_ioctl(
+ IN PNET_DEV net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd);
+#endif /* CONFIG_AP_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)
+
+#define RTMP_DRIVER_MCU_SLEEP_CLEAR(__pAd) \
+ RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_MCU_SLEEP_CLEAR, 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 */
+
+#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)
+
+#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_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, __SetCmd) \
+ RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_SANITY_CHECK, 0, __SetCmd, 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)
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+#define RTMP_DRIVER_SET_PRECONFIG_VALUE(__pAd) \
+ RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_SET_PRECONFIG_VALUE, 0, NULL, 0)
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+/* 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)
+#define RTMP_DRIVER_80211_SURVEY_GET(__pAd, __pSurveyInfo) \
+ RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_80211_SURVEY_GET, 0, __pSurveyInfo, 0)
+#define RTMP_DRIVER_80211_PMKID_CTRL(__pAd, __pPmkidInfo) \
+ RTMP_STA_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_STA_SIOCSIWPMKSA, 0, __pPmkidInfo, 0, 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)
+
+#define RTMP_DRIVER_ADAPTER_CSO_SUPPORT_TEST(__pAd, __flag) \
+ RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_CSO_SUPPORT_TEST, 0, __flag, 0)
+
+#define RTMP_DRIVER_ADAPTER_TSO_SUPPORT_TEST(__pAd, __flag) \
+ RTMP_COM_IoctlHandle(__pAd, NULL, CMD_RTPRIV_IOCTL_ADAPTER_TSO_SUPPORT_TEST, 0, __flag, 0)
+
+#endif /* __RT_OS_NET_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/rt_os_util.h b/cleopatre/devkit/mt7601udrv/include/rt_os_util.h
new file mode 100644
index 0000000000..cecc103ecf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rt_os_util.h
@@ -0,0 +1,1003 @@
+/****************************************************************************
+
+ Module Name:
+ rt_os_util.h
+
+ Abstract:
+ All function prototypes are provided from UTIL modules.
+
+ Note:
+ But can not use any OS key word and compile option here.
+ All functions are provided from UTIL modules.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#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 RtmpOsUsDelay(ULONG value);
+
+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);
+
+#ifdef HDR_TRANS_SUPPORT
+VOID RtmpOsSetPacket(
+ IN PNET_DEV pNetDev,
+ IN PNDIS_PACKET pRxPacket,
+ IN UCHAR *pData,
+ IN ULONG DataSize);
+#endif /* HDR_TRANS_SUPPORT */
+
+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);
+
+void RtmpOSNetDevProtect(
+ IN BOOLEAN lock_it);
+
+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);
+
+USHORT RtmpDevPrivFlagsGet(
+ IN VOID *pDev);
+
+VOID RtmpDevPrivFlagsSet(
+ IN VOID *pDev,
+ IN USHORT PrivFlags);
+
+VOID RtmpOsSetNetDevType(VOID *pDev, USHORT Type);
+
+VOID RtmpOsSetNetDevTypeMonitor(VOID *pDev);
+
+
+/* OS Semaphore */
+VOID RtmpOsCmdUp(RTMP_OS_TASK *pCmdQTask);
+BOOLEAN RtmpOsSemaInitLocked(RTMP_OS_SEM *pSemOrg, LIST_HEADER *pSemList);
+BOOLEAN RtmpOsSemaInit(RTMP_OS_SEM *pSemOrg, LIST_HEADER *pSemList);
+BOOLEAN RtmpOsSemaDestory(RTMP_OS_SEM *pSemOrg);
+INT RtmpOsSemaWaitInterruptible(RTMP_OS_SEM *pSemOrg);
+VOID RtmpOsSemaWakeUp(RTMP_OS_SEM *pSemOrg);
+VOID RtmpOsMlmeUp(RTMP_OS_TASK *pMlmeQTask);
+
+/* OS Task */
+BOOLEAN RtmpOsTaskletSche(RTMP_NET_TASK_STRUCT *pTasklet);
+
+BOOLEAN RtmpOsTaskletInit(
+ RTMP_NET_TASK_STRUCT *pTasklet,
+ VOID (*pFunc)(unsigned long data),
+ ULONG Data,
+ LIST_HEADER *pTaskletList);
+
+BOOLEAN RtmpOsTaskletKill(RTMP_NET_TASK_STRUCT *pTasklet);
+
+VOID RtmpOsTaskletDataAssign(
+ RTMP_NET_TASK_STRUCT *pTasklet,
+ ULONG Data);
+
+VOID RtmpOsTaskWakeUp(RTMP_OS_TASK *pTaskOrg);
+
+INT32 RtmpOsTaskIsKilled(RTMP_OS_TASK *pTaskOrg);
+
+BOOLEAN RtmpOsCheckTaskLegality(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(RTMP_OS_TASK *pTaskOrg);
+
+INT32 RtmpThreadPidKill(RTMP_OS_PID PID);
+
+/* OS Cache */
+VOID RtmpOsDCacheFlush(ULONG AddrStart, ULONG Size);
+
+/* 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(NDIS_SPIN_LOCK *pLockOrg);
+VOID RtmpOsIntLock(NDIS_SPIN_LOCK *pLockOrg, ULONG *pIrqFlags);
+VOID RtmpOsIntUnLock(NDIS_SPIN_LOCK *pLockOrg, ULONG IrqFlags);
+
+/* OS PID */
+VOID RtmpOsGetPid(ULONG *pDst, ULONG PID);
+VOID RtmpOsTaskPidInit(RTMP_OS_PID *pPid);
+
+/* OS I/O */
+VOID RTMP_PCI_Writel(ULONG Value, VOID *pAddr);
+VOID RTMP_PCI_Writew(ULONG Value, VOID *pAddr);
+VOID RTMP_PCI_Writeb(ULONG Value, VOID *pAddr);
+ULONG RTMP_PCI_Readl(VOID *pAddr);
+ULONG RTMP_PCI_Readw(VOID *pAddr);
+ULONG RTMP_PCI_Readb(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(VOID *pPciDevSrc);
+
+int RtmpOsPciMsiEnable(VOID *pDev);
+VOID RtmpOsPciMsiDisable(VOID *pDev);
+
+/* OS Wireless */
+ULONG RtmpOsMaxScanDataGet(VOID);
+
+/* OS Interrutp */
+INT32 RtmpOsIsInInterrupt(VOID);
+
+/* OS USB */
+VOID *RtmpOsUsbUrbDataGet(VOID *pUrb);
+NTSTATUS RtmpOsUsbUrbStatusGet(VOID *pUrb);
+ULONG RtmpOsUsbUrbLenGet(VOID *pUrb);
+
+/* OS Atomic */
+BOOLEAN RtmpOsAtomicInit(RTMP_OS_ATOMIC *pAtomic, LIST_HEADER *pAtomicList);
+VOID RtmpOsAtomicDestroy(RTMP_OS_ATOMIC *pAtomic);
+LONG RtmpOsAtomicRead(RTMP_OS_ATOMIC *pAtomic);
+VOID RtmpOsAtomicDec(RTMP_OS_ATOMIC *pAtomic);
+VOID RtmpOsAtomicInterlockedExchange(RTMP_OS_ATOMIC *pAtomicSrc, 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);
+
+#ifdef CONFIG_AP_SUPPORT
+void SendSignalToDaemon(
+ IN INT sig,
+ IN RTMP_OS_PID pid,
+ IN unsigned long pid_no);
+#endif /* CONFIG_AP_SUPPORT */
+
+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);
+
+VOID RtmpDrvAllRFPrint(
+ IN VOID *pReserved,
+ IN UINT32 *pBuf,
+ IN UINT32 BufLen);
+
+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(UINT16 *pWord);
+
+UINT32 RtmpOsGetUnaligned32(UINT32 *pWord);
+
+ULONG RtmpOsGetUnalignedlong(ULONG *pWord);
+
+long RtmpOsSimpleStrtol(
+ IN const char *cp,
+ IN char **endp,
+ IN unsigned int base);
+
+VOID RtmpOsOpsInit(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(USHORT authFlag);
+
+PSTRING WscGetEncryTypeStr(USHORT encryFlag);
+
+USHORT WscGetAuthTypeFromStr(PSTRING arg);
+
+USHORT WscGetEncrypTypeFromStr(PSTRING arg);
+
+VOID RtmpMeshDown(
+ IN VOID *pDrvCtrlBK,
+ IN BOOLEAN WaitFlag,
+ IN BOOLEAN (*RtmpMeshLinkCheck)(IN VOID *pAd));
+
+USHORT RtmpOsNetPrivGet(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);
+
+PVOID RtmpInitCompletion(VOID);
+
+ULONG RtmpWaitForCompletionTimeout(VOID *Completion, ULONG Expire);
+
+VOID RtmpComplete(VOID *Completion);
+
+ULONG RtmpMsecsToJiffies(UINT32 msecs);
+/* ============================ rt_rbus_pci_util.c ========================== */
+void RtmpAllocDescBuf(
+ IN PPCI_DEV pPciDev,
+ IN UINT Index,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT VOID **VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RtmpFreeDescBuf(
+ IN PPCI_DEV pPciDev,
+ IN ULONG Length,
+ IN VOID *VirtualAddress,
+ IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateFirstTxBuffer(
+ IN PPCI_DEV pPciDev,
+ IN UINT Index,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT VOID **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);
+
+
+int rausb_autopm_put_interface (
+ IN VOID *intfsrc);
+
+int rausb_autopm_get_interface (
+ IN VOID *intfsrc);
+
+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 *pPendingRx);
+
+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 */
+
+#if defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT)
+void RtmpFlashRead(
+ UCHAR * p,
+ ULONG a,
+ ULONG b);
+
+void RtmpFlashWrite(
+ UCHAR * p,
+ ULONG a,
+ ULONG b);
+#endif /* defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT) */
+
+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);
+
+BOOLEAN CFG80211OS_ChanInfoInit(
+ IN VOID *pCB,
+ IN UINT32 InfoIndex,
+ IN UCHAR ChanId,
+ IN UCHAR MaxTxPwr,
+ IN BOOLEAN FlgIsNMode,
+ IN BOOLEAN FlgIsBW20M);
+
+VOID CFG80211OS_Scaning(
+ IN VOID *pCB,
+ 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 */
+
+
+
+
+/* ================================ MACRO =================================== */
+#define RTMP_UTIL_DCACHE_FLUSH(__AddrStart, __Size)
+
+/* ================================ EXTERN ================================== */
+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;
+
+#ifdef PLATFORM_UBM_IPX8
+#include "vrut_ubm.h"
+#endif /* PLATFORM_UBM_IPX8 */
+
+INT32 RtPrivIoctlSetVal(VOID);
+
+#endif /* __RT_OS_UTIL_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rt_txbf.h b/cleopatre/devkit/mt7601udrv/include/rt_txbf.h
new file mode 100644
index 0000000000..33d5b3a115
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rt_txbf.h
@@ -0,0 +1,215 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2009, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_txbf.c
+
+ Abstract:
+ Tx Beamforming related constants and data structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Shiang 2010/06/29
+*/
+
+
+#ifndef _RT_TXBF_H_
+#define _RT_TXBF_H_
+
+#ifdef TXBF_SUPPORT
+
+//#define MRQ_FORCE_TX //Force MRQ regardless the capability of the station
+
+
+// TxSndgPkt Sounding type definitions
+#define SNDG_TYPE_DISABLE 0
+#define SNDG_TYPE_SOUNDING 1
+#define SNDG_TYPE_NDP 2
+
+// Explicit TxBF feedback mechanism
+#define ETXBF_FB_DISABLE 0
+#define ETXBF_FB_CSI 1
+#define ETXBF_FB_NONCOMP 2
+#define ETXBF_FB_COMP 4
+
+
+//#define MRQ_FORCE_TX //Force MRQ regardless the capability of the station
+
+/*
+ eTxBfEnCond values:
+ 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)
+*/
+
+// Defines to include optional code.
+// NOTE: Do not define these options. ETxBfEnCond==3 and
+// MCS Feedback are not fully implemented
+//#define ETXBF_EN_COND3_SUPPORT // Include ETxBfEnCond==3 code
+//#define MFB_SUPPORT // Include MCS Feedback code
+
+// MCS FB definitions
+#define MSI_TOGGLE_BF 6
+#define TOGGLE_BF_PKTS 5// the number of packets with inverted BF status
+
+// TXBF State definitions
+#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()
+
+
+// ------------ BEAMFORMING PROFILE HANDLING ------------
+
+#define IMP_MAX_BYTES 14 // Implicit: 14 bytes per subcarrier
+#define IMP_MAX_BYTES_ONE_COL 7 // Implicit: 7 bytes per subcarrier, when reading first column
+#define EXP_MAX_BYTES 18 // Explicit: 18 bytes per subcarrier
+#define IMP_COEFF_SIZE 9 // 9 bits/coeff
+#define IMP_COEFF_MASK 0x1FF
+
+#define PROFILE_MAX_CARRIERS_20 56 // Number of subcarriers in 20 MHz mode
+#define PROFILE_MAX_CARRIERS_40 114 // Number of subcarriers in 40 MHz mode
+
+// Indices of valid rows in Implicit and Explicit profiles for 20 and 40 MHz
+typedef struct {
+ int lwb1, upb1;
+ int lwb2, upb2;
+} SC_TABLE_ENTRY;
+
+
+typedef struct {
+ BOOLEAN impProfile;
+ BOOLEAN fortyMHz;
+ int rows, columns;
+ int grouping;
+ UCHAR tag[EXP_MAX_BYTES];
+ UCHAR data[PROFILE_MAX_CARRIERS_40][EXP_MAX_BYTES];
+} PROFILE_DATA;
+
+extern PROFILE_DATA profData;
+
+
+typedef
+struct {
+ UCHAR gBeg[2];
+ UCHAR gEnd[2];
+ UCHAR aLowBeg[2];
+ UCHAR aLowEnd[2];
+ UCHAR aMidBeg[2];
+ UCHAR aMidEnd[2];
+ UCHAR aHighBeg[2];
+ UCHAR aHighEnd[2];
+} ITXBF_PHASE_PARAMS; // ITxBF BBP reg phase calibration parameters
+
+typedef
+struct {
+ UCHAR gBeg[2];
+ UCHAR gEnd[2];
+ UCHAR aLowBeg[2];
+ UCHAR aLowEnd[2];
+ UCHAR aMidBeg[2];
+ UCHAR aMidEnd[2];
+ UCHAR aHighBeg[2];
+ UCHAR aHighEnd[2];
+} ITXBF_LNA_PARAMS; // ITxBF BBP reg LNA calibration parameters
+
+typedef
+struct {
+ UCHAR gBeg[2];
+ UCHAR gEnd[2];
+ UCHAR aLow[2];
+ UCHAR aMid[2];
+ UCHAR aHigh[2];
+} ITXBF_DIV_PARAMS; // ITxBF Divider Calibration parameters
+
+void ITxBFGetEEPROM(
+ IN RTMP_ADAPTER *pAd,
+ IN ITXBF_PHASE_PARAMS *phaseParams,
+ IN ITXBF_LNA_PARAMS *lnaParams,
+ IN ITXBF_DIV_PARAMS *divParams);
+
+INT ITxBFDividerCalibration(
+ IN RTMP_ADAPTER *pAd,
+ IN int calFunction,
+ IN int calMethod,
+ OUT UCHAR *divPhase);
+
+VOID ITxBFLoadLNAComp(
+ IN RTMP_ADAPTER *pAd);
+
+int ITxBFLNACalibration(
+ IN RTMP_ADAPTER *pAd,
+ IN int calFunction,
+ IN int calMethod,
+ IN BOOLEAN gBand);
+
+void Read_TxBfProfile(
+ IN RTMP_ADAPTER *pAd,
+ IN PROFILE_DATA *prof,
+ IN int profileNum,
+ IN BOOLEAN implicitProfile);
+
+void Write_TxBfProfile(
+ IN RTMP_ADAPTER *pAd,
+ IN PROFILE_DATA *prof,
+ IN int profileNum);
+
+void Read_TagField(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *row,
+ IN int profileNum);
+
+// Write_TagField - write a profile tagfield
+void Write_TagField(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR *row,
+ IN int profileNum);
+
+// displayTagfield - display one tagfield
+void displayTagfield(
+ IN RTMP_ADAPTER *pAd,
+ IN int profileNum,
+ IN BOOLEAN implicitProfile);
+
+// Unpack an ITxBF matrix element from a row of bytes
+int Unpack_IBFValue(
+ IN UCHAR *row,
+ IN int elemNum);
+
+int iCalcCalibration(
+ IN RTMP_ADAPTER *pAd,
+ IN int calParams[2],
+ IN int profileNum);
+
+void ITxBFSetEEPROM(
+ IN RTMP_ADAPTER *pAd,
+ IN ITXBF_PHASE_PARAMS *phaseParams,
+ IN ITXBF_LNA_PARAMS *lnaParams,
+ IN ITXBF_DIV_PARAMS *divParams);
+
+#endif // TXBF_SUPPORT //
+
+#endif // _RT_TXBF_H_
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp.h b/cleopatre/devkit/mt7601udrv/include/rtmp.h
new file mode 100644
index 0000000000..bdaa571b82
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp.h
@@ -0,0 +1,9018 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp.h
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 2002-08-01 created
+ James Tan 2002-09-06 modified (Revise NTCRegTable)
+ John Chang 2004-09-06 modified for RT2600
+*/
+#ifndef __RTMP_H__
+#define __RTMP_H__
+
+#include "link_list.h"
+#include "spectrum_def.h"
+
+#include "rtmp_dot11.h"
+#include "wpa_cmm.h"
+
+#ifdef CONFIG_AP_SUPPORT
+#include "ap_autoChSel_cmm.h"
+#endif /* CONFIG_AP_SUPPORT */
+
+#include "wsc.h"
+#ifdef MAT_SUPPORT
+#include "mat.h"
+#endif /* MAT_SUPPORT */
+
+
+#ifdef WAPI_SUPPORT
+#include "wapi_def.h"
+#endif /* WAPI_SUPPORT */
+
+
+
+
+
+#ifdef CLIENT_WDS
+#include "client_wds_cmm.h"
+#endif /* CLIENT_WDS */
+
+
+
+
+#ifdef WFD_SUPPORT
+#include "wfd_cmm.h"
+#endif /* WFD_SUPPORT */
+
+#include "drs_extr.h"
+
+struct _RTMP_RA_LEGACY_TB;
+
+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;
+
+typedef struct _UAPSD_INFO {
+ BOOLEAN bAPSDCapable;
+} UAPSD_INFO;
+
+#include "rtmp_mcu.h"
+
+#include "rtmp_M51.h"
+
+#ifdef CONFIG_ANDES_SUPPORT
+#include "rtmp_and.h"
+#endif
+
+#include "rtmp_chip.h"
+
+#include "radar.h"
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#include "cs.h"
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#ifdef DFS_SUPPORT
+#include "dfs.h"
+#endif /* DFS_SUPPORT */
+
+#ifdef LED_CONTROL_SUPPORT
+#include "rt_led.h"
+#endif /* LED_CONTROL_SUPPORT */
+
+
+#ifdef RALINK_ATE
+#include "rt_ate.h"
+#endif /* RALINK_ATE */
+
+
+/*#define DBG 1 */
+
+BOOLEAN RtmpPktPmBitCheck(
+ IN PRTMP_ADAPTER pAd);
+
+/*#define DBG_DIAGNOSE 1 */
+
+
+/*+++Used for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */
+#define MAX_DATAMM_RETRY 3
+#define MGMT_USE_QUEUE_FLAG 0x80
+/*---Used 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 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[];
+
+typedef union _CAPTURE_MODE_PACKET_BUFFER {
+ struct
+ {
+ UINT32 BYTE0:8;
+ UINT32 BYTE1:8;
+ UINT32 BYTE2:8;
+ UINT32 BYTE3:8;
+ } field;
+ UINT32 Value;
+}CAPTURE_MODE_PACKET_BUFFER, *PCAPTURE_MODE_PACKET_BUFFER;
+
+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++; \
+}
+void DisplayTxAgg (RTMP_ADAPTER *pAd);
+
+
+/* */
+/* 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))
+
+#define SET_ASIC_CAP(_pAd, _caps) ((_pAd)->chipCap.asic_caps |= (_caps))
+#define IS_ASIC_CAP(_pAd, _caps) (((_pAd)->chipCap.asic_caps & (_caps)) != 0)
+#define CLR_ASIC_CAP(_pAd, _caps) ((_pAd)->chipCap.asic_caps &= ~(_caps))
+
+
+
+#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 */
+
+#ifdef DOT11_VHT_AC
+#define COPY_VHT_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
+{ \
+}
+#endif /* DOT11_VHT_AC */
+
+
+/*
+ Common fragment list structure - Identical to the scatter gather frag list structure
+*/
+#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, _AntSel, _OpMode) \
+{ \
+ UINT32 High32TSF=0, Low32TSF=0; \
+ MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2 ,_AntSel, _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)))
+
+
+
+/* */
+/* 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 */
+#ifdef CACHE_LINE_32B
+ RXD_STRUC LastBDInfo;
+#endif /* CACHE_LINE_32B */
+} 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;
+
+typedef struct _RTMP_CTRL_RING {
+ RTMP_DMACB Cell[16];
+ UINT32 TxCpuIdx;
+ UINT32 TxDmaIdx;
+ UINT32 TxSwFreeIdx; /* software next free tx index */
+} RTMP_CTRL_RING, *PRTMP_CTRL_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;
+ LARGE_INTEGER TransmittedFrameCount;
+ LARGE_INTEGER WEPUndecryptableCount;
+ LARGE_INTEGER TransmitCountFrmOs;
+} COUNTER_802_11, *PCOUNTER_802_11;
+
+
+#ifdef RT3290
+typedef struct _ANT_DIVERSITY
+{
+ BOOLEAN RateUp;
+ ULONG TrainCounter;
+ ULONG AntennaDiversityState; // 0->Stable state 1->training state
+ ULONG AntennaDiversityPER[2]; // 0 ->main 1->aux
+ ULONG AntennaDiversityTxPacketCount[2]; // 0 ->main 1->aux
+ ULONG AntennaDiversityRxPacketCount[2];
+ CHAR Rssi[2];
+ ULONG AntennaDiversityCount;
+ ULONG AntennaDiversityTrigger;
+}ANT_DIVERSITY, *PANT_DIVERSITY;
+#endif /* RT3290 */
+
+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 */
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ UINT16 FalseCCACnt_100MS[MLME_TASK_EXEC_MULTIPLE]; /* one handred millisecond false CCA Count */
+ UINT16 PLCPErrCnt_100MS[MLME_TASK_EXEC_MULTIPLE]; /* one handred millisecond PLCP Error Count */
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ ULONG TransmittedByteCount; /* both successful and failure, used to calculate TX throughput */
+ ULONG ReceivedByteCount; /* both CRC okay and CRC error, used to calculate RX throughput */
+#ifdef RT3290
+ // TODO: shiang, check the purpose of following parameter
+ ULONG OneSecRxOkCnt2; /* RX without error */
+#endif /* RT3290 */
+ ULONG BadCQIAutoRecoveryCount;
+ ULONG PoorCQIRoamingCount;
+ ULONG MgmtRingFullCount;
+ ULONG RxCountSinceLastNULL;
+ ULONG RxCount;
+ ULONG KickTxCount;
+ LARGE_INTEGER RealFcsErrCount;
+ ULONG PendingNdisPacketCount;
+ ULONG FalseCCACnt; /* CCA error count */
+
+ 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_TX_RATE_INDEX+1];
+ UCHAR PER[MAX_TX_RATE_INDEX+1];
+ 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 /* TXBF_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef STREAM_MODE_SUPPORT
+typedef struct _STREAM_MODE_ENTRY_{
+#define STREAM_MODE_STATIC 1
+ USHORT flag;
+ UCHAR macAddr[MAC_ADDR_LEN];
+}STREAM_MODE_ENTRY;
+#endif /* STREAM_MODE_SUPPORT */
+
+/* for Microwave oven */
+#ifdef MICROWAVE_OVEN_SUPPORT
+typedef struct _MO_CFG_STRUCT {
+ BOOLEAN bEnable;
+ UINT8 nPeriod_Cnt; /* measurement period 100ms, mitigate the interference period 900 ms */
+ UINT16 nFalseCCACnt;
+ UINT16 nFalseCCATh; /* default is 100 */
+#ifdef MT7601
+ UINT32 Stored_BBP_R65;
+ UCHAR Stored_RF_B5_R6;
+ UCHAR Stored_RF_B5_R7;
+#endif /* MT7601 */
+} MO_CFG_STRUCT, *PMO_CFG_STRUCT;
+#endif /* MICROWAVE_OVEN_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.
+ CHANNEL_40M_CAP: 40 BW channel group
+ */
+#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
+#define CHANNEL_40M_CAP 0x40
+
+ UCHAR Flags;
+
+} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
+
+/* Channel list subset */
+typedef struct _CHANNEL_LIST_SUB {
+ UCHAR Channel;
+ UCHAR IdxMap; /* Index mapping to original channel list */
+} CHANNEL_LIST_SUB, *PCHANNEL_LIST_SUB;
+
+
+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 */
+ SHORT Pair1LastAvgRssi; /* */
+ SHORT Pair2LastAvgRssi; /* */
+ ULONG RcvPktNumWhenEvaluate;
+ BOOLEAN FirstPktArrivedWhenEvaluate;
+#ifdef CONFIG_AP_SUPPORT
+ LONG Pair1AvgRssiGroup1[2];
+ LONG Pair1AvgRssiGroup2[2];
+ ULONG RcvPktNum[2];
+#endif /* CONFIG_AP_SUPPORT */
+} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
+
+typedef enum _ABGBAND_STATE_ {
+ UNKNOWN_BAND,
+ BG_BAND,
+ A_BAND,
+} ABGBAND_STATE;
+
+/***************************************************************************
+ * structure for MLME state machine
+ **************************************************************************/
+typedef struct _MLME_STRUCT {
+ STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
+ /* Action */
+ STATE_MACHINE ActMachine;
+
+#ifdef WSC_INCLUDED
+ STATE_MACHINE WscMachine;
+ STATE_MACHINE_FUNC WscFunc[WSC_FUNC_SIZE];
+
+#endif /* WSC_INCLUDED */
+
+#ifdef QOS_DLS_SUPPORT
+ STATE_MACHINE DlsMachine;
+ STATE_MACHINE_FUNC DlsFunc[DLS_FUNC_SIZE];
+#endif /* QOS_DLS_SUPPORT */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ /* AP state machines */
+ STATE_MACHINE ApAssocMachine;
+ STATE_MACHINE ApAuthMachine;
+ STATE_MACHINE ApSyncMachine;
+ STATE_MACHINE_FUNC ApAssocFunc[AP_ASSOC_FUNC_SIZE];
+/* STATE_MACHINE_FUNC ApDlsFunc[DLS_FUNC_SIZE]; */
+ STATE_MACHINE_FUNC ApAuthFunc[AP_AUTH_FUNC_SIZE];
+ STATE_MACHINE_FUNC ApSyncFunc[AP_SYNC_FUNC_SIZE];
+#ifdef APCLI_SUPPORT
+ STATE_MACHINE ApCliAuthMachine;
+ STATE_MACHINE ApCliAssocMachine;
+ STATE_MACHINE ApCliCtrlMachine;
+ STATE_MACHINE ApCliSyncMachine;
+ STATE_MACHINE ApCliWpaPskMachine;
+
+ STATE_MACHINE_FUNC ApCliAuthFunc[APCLI_AUTH_FUNC_SIZE];
+ STATE_MACHINE_FUNC ApCliAssocFunc[APCLI_ASSOC_FUNC_SIZE];
+ STATE_MACHINE_FUNC ApCliCtrlFunc[APCLI_CTRL_FUNC_SIZE];
+ STATE_MACHINE_FUNC ApCliSyncFunc[APCLI_SYNC_FUNC_SIZE];
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_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 RTMP_MAC_USB
+ RALINK_TIMER_STRUCT AutoWakeupTimer;
+ BOOLEAN AutoWakeupTimerRunning;
+#endif /* RTMP_MAC_USB */
+
+
+#ifdef CONFIG_MULTI_CHANNEL
+ RALINK_TIMER_STRUCT MCCTimer;
+
+ RALINK_TIMER_STRUCT ConcurrentP2PConnectTimer;
+ UINT32 HCCAToEDCATimerValue;
+ UINT32 EDCAToHCCATimerValue;
+ BOOLEAN ConcurrentP2PConnectTimerRunning;
+ UINT32 StaStayTick;
+ UINT32 P2pStayTick;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+} 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<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize */
+ UCHAR rsv;
+ UCHAR BufSize[8];
+ REC_BLOCKACK_STATUS REC_BA_Status[8];
+} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
+
+/*For QureyBATableOID use; */
+typedef struct GNU_PACKED _OID_BA_ORI_ENTRY {
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR BaBitmap; /* if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status */
+ UCHAR rsv;
+ UCHAR BufSize[8];
+ ORI_BLOCKACK_STATUS ORI_BA_Status[8];
+} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
+
+typedef struct _QUERYBA_TABLE {
+ OID_BA_ORI_ENTRY BAOriEntry[32];
+ OID_BA_REC_ENTRY BARecEntry[32];
+ UCHAR OriNum; /* Number of below BAOriEntry */
+ UCHAR RecNum; /* Number of below BARecEntry */
+} QUERYBA_TABLE, *PQUERYBA_TABLE;
+
+typedef union _BACAP_STRUC {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ UINT32:4;
+ UINT32 b2040CoexistScanSup:1; /*As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz. */
+ UINT32 bHtAdhoc:1; /* adhoc can use ht rate. */
+ UINT32 MMPSmode:2; /* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */
+ UINT32 AmsduSize:1; /* 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935}; */
+ UINT32 AmsduEnable:1; /*Enable AMSDU transmisstion */
+ UINT32 MpduDensity:3;
+ UINT32 Policy:2; /* 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use */
+ UINT32 AutoBA:1; /* automatically BA */
+ UINT32 TxBAWinLimit:8;
+ UINT32 RxBAWinLimit:8;
+ } field;
+#else
+ struct {
+ UINT32 RxBAWinLimit:8;
+ UINT32 TxBAWinLimit:8;
+ UINT32 AutoBA:1; /* automatically BA */
+ UINT32 Policy:2; /* 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use */
+ UINT32 MpduDensity:3;
+ UINT32 AmsduEnable:1; /*Enable AMSDU transmisstion */
+ UINT32 AmsduSize:1; /* 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935}; */
+ UINT32 MMPSmode:2; /* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */
+ UINT32 bHtAdhoc:1; /* adhoc can use ht rate. */
+ UINT32 b2040CoexistScanSup:1; /*As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz. */
+ UINT32:4;
+ } field;
+#endif
+ UINT32 word;
+} BACAP_STRUC, *PBACAP_STRUC;
+
+typedef struct {
+ BOOLEAN IsRecipient;
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR TID;
+ UCHAR nMSDU;
+ USHORT TimeOut;
+ BOOLEAN bAllTid; /* If True, delete all TID for BA sessions with this MACaddr. */
+} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
+
+#ifdef DOT11N_DRAFT3
+typedef enum _BSS2040COEXIST_FLAG {
+ BSS_2040_COEXIST_DISABLE = 0,
+ BSS_2040_COEXIST_TIMER_FIRED = 1,
+ BSS_2040_COEXIST_INFO_SYNC = 2,
+ BSS_2040_COEXIST_INFO_NOTIFY = 4,
+} BSS2040COEXIST_FLAG;
+
+typedef struct _BssCoexChRange_ {
+ UCHAR primaryCh;
+ UCHAR secondaryCh;
+ UCHAR effectChStart;
+ UCHAR effectChEnd;
+} BSS_COEX_CH_RANGE;
+#endif /* DOT11N_DRAFT3 */
+
+#define IS_HT_STA(_pMacEntry) \
+ (_pMacEntry->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;
+} 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;
+
+
+struct hw_setting{
+ UCHAR prim_ch;
+ UCHAR cent_ch;
+ UCHAR bbp_bw;
+ UCHAR rf_band;
+};
+
+
+struct wifi_dev{
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
+ WPA_MIX_PAIR_CIPHER WpaMixPairCipher;
+
+ RT_PHY_INFO DesiredHtPhyInfo;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; /* Desired transmit setting. this is for reading registry setting only. not useful. */
+ BOOLEAN bAutoTxRateSwitch;
+
+ BOOLEAN bWmmCapable; /* 0:disable WMM, 1:enable WMM */
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+};
+
+
+#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];
+ 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]; }
+
+
+#ifdef CONFIG_AP_SUPPORT
+typedef struct _MULTISSID_STRUCT {
+
+ struct wifi_dev wdev;
+
+#ifdef HOSTAPD_SUPPORT
+ BOOLEAN Hostapd;
+ BOOLEAN HostapdWPS;
+#endif
+
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ USHORT CapabilityInfo;
+
+ UCHAR MaxStaNum; /* Limit the STA connection number per BSS */
+ UCHAR StaCount;
+
+ PNET_DEV MSSIDDev;
+
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
+ WPA_MIX_PAIR_CIPHER WpaMixPairCipher;
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode; /* For transmit phy setting in TXWI. */
+ RT_PHY_INFO DesiredHtPhyInfo;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; /* Desired transmit setting. this is for reading registry setting only. not useful. */
+ BOOLEAN bAutoTxRateSwitch;
+
+ /*MBSS_STATISTICS MbssStat;*/
+ ULONG TxCount;
+ ULONG RxCount;
+ ULONG ReceivedByteCount;
+ ULONG TransmittedByteCount;
+ ULONG RxErrorCount;
+ ULONG RxDropCount;
+
+ ULONG TxErrorCount;
+ ULONG TxDropCount;
+ ULONG ucPktsTx;
+ ULONG ucPktsRx;
+ ULONG mcPktsTx;
+ ULONG mcPktsRx;
+ ULONG bcPktsTx;
+ ULONG bcPktsRx;
+
+ /*CIPHER_KEY SharedKey[SHARE_KEY_NUM]; // ref pAd->SharedKey[BSS][4] */
+ UCHAR DefaultKeyId;
+
+ UCHAR TxRate; /* RATE_1, RATE_2, RATE_5_5, RATE_11, ... */
+ UCHAR DesiredRates[MAX_LEN_OF_SUPPORTED_RATES]; /* OID_802_11_DESIRED_RATES */
+ UCHAR DesiredRatesIndex;
+ UCHAR MaxTxRate; /* RATE_1, RATE_2, RATE_5_5, RATE_11 */
+
+/* ULONG TimBitmap; // bit0 for broadcast, 1 for AID1, 2 for AID2, ...so on */
+/* ULONG TimBitmap2; // b0 for AID32, b1 for AID33, ... and so on */
+ UCHAR TimBitmaps[WLAN_MAX_NUM_OF_TIM];
+
+ /* WPA */
+ UCHAR GMK[32];
+ UCHAR PMK[32];
+ UCHAR GTK[32];
+#ifdef DOT1X_SUPPORT
+ BOOLEAN IEEE8021X;
+ BOOLEAN PreAuth;
+#endif /* DOT1X_SUPPORT */
+ UCHAR GNonce[32];
+ UCHAR PortSecured;
+ NDIS_802_11_PRIVACY_FILTER PrivacyFilter;
+ UCHAR BANClass3Data;
+ ULONG IsolateInterStaTraffic;
+
+ UCHAR RSNIE_Len[2];
+ UCHAR RSN_IE[2][MAX_LEN_OF_RSNIE];
+
+ /* for Group Rekey */
+ RT_WPA_REKEY WPAREKEY;
+ ULONG REKEYCOUNTER;
+ RALINK_TIMER_STRUCT REKEYTimer;
+ UCHAR REKEYTimerRunning;
+ UINT8 RekeyCountDown;
+
+#ifdef WAPI_SUPPORT
+ UCHAR WAPIPassPhrase[64]; /* WAPI PSK pass phrase */
+ UINT WAPIPassPhraseLen; /* the length of WAPI PSK pass phrase */
+ UINT WapiPskType; /* 0 - Hex, 1 - ASCII */
+ UCHAR WAPI_BK[16]; /* WAPI base key */
+
+ UCHAR NMK[LEN_WAPI_NMK];
+ UCHAR key_announce_flag[LEN_WAPI_TSC];
+ BOOLEAN sw_wpi_encrypt; /* WPI data encrypt by SW */
+#endif /* WAPI_SUPPORT */
+
+ UCHAR TimIELocationInBeacon;
+ UCHAR CapabilityInfoLocationInBeacon;
+
+ /* For PMK Cache using */
+ ULONG PMKCachePeriod; /* unit : jiffies */
+ NDIS_AP_802_11_PMKID PMKIDCache;
+
+ /* outgoing BEACON frame buffer and corresponding TXWI */
+ /* TXWI_STRUC *BeaconTxWI; */
+ CHAR BeaconBuf[MAX_BEACON_SIZE]; /* NOTE: BeaconBuf should be 4-byte aligned */
+
+ BOOLEAN bHideSsid;
+ UINT16 StationKeepAliveTime; /* unit: second */
+
+ /* VLAN related */
+ BOOLEAN bVLAN_Tag;
+ USHORT VLAN_VID;
+ USHORT VLAN_Priority;
+
+ RT_802_11_ACL AccessControlList;
+
+ /* EDCA Qos */
+ BOOLEAN bWmmCapable; /* 0:disable WMM, 1:enable WMM */
+ BOOLEAN bDLSCapable; /* 0:disable DLS, 1:enable DLS */
+
+ /*
+ Why need the parameter: 2009/09/22
+
+ 1. iwpriv ra0 set WmmCapable=0
+ 2. iwpriv ra0 set WirelessMode=9
+ 3. iwpriv ra0 set WirelessMode=0
+ 4. iwpriv ra0 set SSID=SampleAP
+
+ After the 4 commands, WMM is still enabled.
+ So we need the parameter to recover WMM Capable flag.
+
+ No the problem in station mode.
+ */
+ BOOLEAN bWmmCapableOrg; /* origin Wmm Capable in non-11n mode */
+
+#ifdef QOS_DLS_SUPPORT
+ UCHAR DlsPTK[64]; /* Due to windows dirver count on meetinghouse to handle 4-way shake */
+#endif /* QOS_DLS_SUPPORT */
+
+#ifdef DOT1X_SUPPORT
+ /* For 802.1x daemon setting per BSS */
+ UINT8 radius_srv_num;
+ RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
+ UINT8 NasId[IFNAMSIZ];
+ UINT8 NasIdLen;
+#endif /* DOT1X_SUPPORT */
+
+#ifdef RTL865X_SOC
+ unsigned int mylinkid;
+#endif
+
+#ifdef CONFIG_AP_SUPPORT
+ WSC_LV_INFO WscIEBeacon;
+ WSC_LV_INFO WscIEProbeResp;
+#ifdef WSC_AP_SUPPORT
+ WSC_CTRL WscControl;
+ WSC_SECURITY_MODE WscSecurityMode;
+#endif /* WSC_AP_SUPPORT */
+
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef IDS_SUPPORT
+ UINT32 RcvdConflictSsidCount;
+ UINT32 RcvdSpoofedAssocRespCount;
+ UINT32 RcvdSpoofedReassocRespCount;
+ UINT32 RcvdSpoofedProbeRespCount;
+ UINT32 RcvdSpoofedBeaconCount;
+ UINT32 RcvdSpoofedDisassocCount;
+ UINT32 RcvdSpoofedAuthCount;
+ UINT32 RcvdSpoofedDeauthCount;
+ UINT32 RcvdSpoofedUnknownMgmtCount;
+ UINT32 RcvdReplayAttackCount;
+
+ CHAR RssiOfRcvdConflictSsid;
+ CHAR RssiOfRcvdSpoofedAssocResp;
+ CHAR RssiOfRcvdSpoofedReassocResp;
+ CHAR RssiOfRcvdSpoofedProbeResp;
+ CHAR RssiOfRcvdSpoofedBeacon;
+ CHAR RssiOfRcvdSpoofedDisassoc;
+ CHAR RssiOfRcvdSpoofedAuth;
+ CHAR RssiOfRcvdSpoofedDeauth;
+ CHAR RssiOfRcvdSpoofedUnknownMgmt;
+ CHAR RssiOfRcvdReplayAttack;
+#endif /* IDS_SUPPORT */
+
+ /* used in if beacon send or stop */
+ BOOLEAN bBcnSntReq;
+ UCHAR BcnBufIdx;
+
+
+
+
+
+ UCHAR PhyMode;
+
+
+ /* UAPSD information: such as enable or disable, do not remove */
+ UAPSD_INFO UapsdInfo;
+
+} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+/* 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;
+ UCHAR DfsType;
+ PUCHAR pChDesp;
+#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;
+ UCHAR cfg_wmode;
+ 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 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 */
+ UCHAR MaxSPLength;
+
+ BOOLEAN bNeedSendTriggerFrame;
+ BOOLEAN bAPSDForcePowerSave; /* Force power save mode, should only use in APSD-STAUT */
+ ULONG TriggerTimerCount;
+ UCHAR BBPCurrentBW; /* BW_10, BW_20, BW_40, BW_80 */
+ REG_TRANSMIT_SETTING RegTransmitSetting; /*registry transmit setting. this is for reading registry setting only. not useful. */
+ 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 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 */
+
+#ifdef DOT11_VHT_AC
+ BOOLEAN force_vht;
+ UCHAR vht_bw;
+ UCHAR vht_cent_ch;
+ UCHAR vht_cent_ch2;
+#endif /* DOT11_VHT_AC */
+
+ 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. */
+ UCHAR RDDurRegion; /* Region of radar detection */
+ 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 */
+ /* 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. */
+
+#ifdef DFS_SUPPORT
+ /* IEEE802.11H--DFS. */
+ RADAR_DETECT_STRUCT RadarDetect;
+#endif /* DFS_SUPPORT */
+#ifdef CARRIER_DETECTION_SUPPORT
+ CARRIER_DETECTION_STRUCT CarrierDetect;
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ /* HT */
+ 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;
+ UCHAR Bss2040NeedFallBack; /* 1: Need Fall back to 20MHz */
+
+ /*This IE is used for 20/40 BSS Coexistence. */
+ BSS_2040_COEXIST_IE BSS2040CoexistInfo;
+
+ 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;
+
+ 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;
+
+ BOOLEAN bRalinkBurstMode;
+ UINT32 RestoreBurstMode;
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_VHT_AC
+ UINT32 cfg_vht;
+ VHT_CAP_INFO vht_info;
+#endif /* DOT11_VHT_AC */
+
+#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 */
+
+#ifdef WSC_INCLUDED
+ /* WSC hardware push button function 0811 */
+ UINT8 WscHdrPshBtnCheckCount;
+#endif /* WSC_INCLUDED */
+
+
+ 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;
+ UINT16 ModuleTxpower;
+#endif /* SINGLE_SKU */
+
+#ifdef WAPI_SUPPORT
+ COMMON_WAPI_INFO comm_wapi_info;
+
+ /* rekey related parameter */
+ /* USK update parameter */
+ UINT8 wapi_usk_rekey_method; /* 0:disable , 1:time, 2:packet */
+ UINT32 wapi_usk_rekey_threshold; /* the rekey threshold */
+
+ /* MSK update parameter */
+ UINT8 wapi_msk_rekey_method; /* 0:disable , 1:time, 2:packet */
+ UINT32 wapi_msk_rekey_threshold; /* the rekey threshold */
+
+ UINT32 wapi_msk_rekey_cnt;
+ RALINK_TIMER_STRUCT WapiMskRekeyTimer;
+ UCHAR WapiMskRekeyTimerRunning;
+#endif /* WAPI_SUPPORT */
+
+
+ BOOLEAN HT_DisallowTKIP; /* Restrict the encryption type in 11n HT mode */
+
+ BOOLEAN HT_Disable; /* 1: disable HT function; 0: enable HT function */
+
+
+#ifdef PRE_ANT_SWITCH
+ BOOLEAN PreAntSwitch; /* Preamble Antenna Switch */
+ SHORT PreAntSwitchRSSI; /* Preamble Antenna Switch RSSI threshold */
+ SHORT PreAntSwitchTimeout; /* Preamble Antenna Switch timeout in seconds */
+#endif /* PRE_ANT_SWITCH */
+
+#ifdef CFO_TRACK
+ SHORT CFOTrack; /* CFO Tracking. 0=>use default, 1=>track, 2-7=> track 8-n times, 8=>done tracking */
+#endif /* CFO_TRACK */
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ USHORT lowTrafficThrd; /* Threshold for reverting to default MCS when traffic is low */
+ BOOLEAN TrainUpRule; /* QuickDRS train up criterion: 0=>Throughput, 1=>PER, 2=> Throughput & PER */
+ SHORT TrainUpRuleRSSI; /* If TrainUpRule=2 then use Hybrid rule when RSSI < TrainUpRuleRSSI */
+ USHORT TrainUpLowThrd; /* QuickDRS Hybrid train up low threshold */
+ USHORT TrainUpHighThrd; /* QuickDRS Hybrid train up high threshold */
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef STREAM_MODE_SUPPORT
+#define STREAM_MODE_STA_NUM 4
+
+ UCHAR StreamMode; /* 0=disabled, 1=enable for 1SS, 2=enable for 2SS, 3=enable for 1,2SS */
+ UCHAR StreamModeMac[STREAM_MODE_STA_NUM][MAC_ADDR_LEN];
+ UINT16 StreamModeMCS; /* Bit map for enabling Stream Mode based on MCS */
+#endif /* STREAM_MODE_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+#ifdef TXBF_SUPPORT
+ ULONG ITxBfTimeout;
+ ULONG ETxBfTimeout;
+ ULONG ETxBfEnCond; /* Enable sending of sounding and beamforming */
+ BOOLEAN ETxBfNoncompress; /* Force non-compressed Sounding Response */
+ BOOLEAN ETxBfIncapable; /* Report Incapable of BF in TX BF Capabilities */
+#endif /* TXBF_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DBG_CTRL_SUPPORT
+ ULONG DebugFlags; /* Temporary debug flags */
+#endif /* DBG_CTRL_SUPPORT */
+
+
+#ifdef WSC_INCLUDED
+ BOOLEAN WscPBCOverlap;
+ WSC_STA_PBC_PROBE_INFO WscStaPbcProbeInfo;
+#endif /* WSC_INCLUDED */
+
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ MO_CFG_STRUCT MO_Cfg; /* data structure for mitigating microwave interference */
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+
+} COMMON_CONFIG, *PCOMMON_CONFIG;
+
+#ifdef DBG_CTRL_SUPPORT
+/* DebugFlag definitions */
+#define DBF_NO_BF_AWARE_RA 0x0001 /* Revert to older Rate Adaptation that is not BF aware */
+#define DBF_SHOW_BF_STATS 0x0002 /* Display BF statistics in AP "iwpriv stat" display */
+#define DBF_NO_TXBF_3SS 0x0004 /* Disable TXBF for MCS > 20 */
+#define DBF_UNUSED0008 0x0008 /* Unused */
+#define DBF_DBQ_RA_LOG 0x0010 /* Log RA information in DBQ */
+#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_FORCE_QUICK_DRS 0x0080 /* Force Quick DRS even if rate didn't change */
+#define DBF_FORCE_SGI 0x0100 /* Force Short GI */
+#define DBF_DBQ_NO_BCN 0x0200 /* Disable logging of RX Beacon frames */
+#define DBF_LOG_VCO_CAL 0x0400 /* Log VCO cal */
+#define DBF_DISABLE_CAL 0x0800 /* Disable Divider Calibration at channel change */
+#ifdef INCLUDE_DEBUG_QUEUE
+#define DBF_DBQ_TXFIFO 0x1000 /* Enable logging of TX information from FIFO */
+#define DBF_DBQ_TXFRAME 0x2000 /* Enable logging of Frames queued for TX */
+#define DBF_DBQ_RXWI_FULL 0x4000 /* Enable logging of full RXWI */
+#define DBF_DBQ_RXWI 0x8000 /* Enable logging of partial RXWI */
+#endif /* INCLUDE_DEBUG_QUEUE */
+
+#define DBF_SHOW_RA_LOG 0x010000 /* Display concise Rate Adaptation information */
+#define DBF_SHOW_ZERO_RA_LOG 0x020000 /* Include RA Log entries when TxCount is 0 */
+#define DBF_FORCE_20MHZ 0x040000 /* Force 20 MHz TX */
+#define DBF_FORCE_40MHZ 0x080000 /* Force 40 MHz Tx */
+#define DBF_DISABLE_CCK 0x100000 /* Disable CCK */
+#define DBF_UNUSED200000 0x200000 /* Unused */
+#define DBF_ENABLE_HT_DUP 0x400000 /* Allow HT Duplicate mode in TX rate table */
+#define DBF_ENABLE_CCK_5G 0x800000 /* Enable CCK rates in 5G band */
+#define DBF_UNUSED0100000 0x0100000 /* Unused */
+#define DBF_ENABLE_20MHZ_MCS8 0x02000000 /* Substitute 20MHz MCS8 for 40MHz MCS8 */
+#define DBF_DISABLE_20MHZ_MCS0 0x04000000 /* Disable substitution of 20MHz MCS0 for 40MHz MCS32 */
+#define DBF_DISABLE_20MHZ_MCS1 0x08000000 /* Disable substitution of 20MHz MCS1 for 40MHz MCS0 */
+#endif /* DBG_CTRL_SUPPORT */
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+/***************************************************************************
+ * AP related data structures
+ **************************************************************************/
+/* AUTH-RSP State Machine Aux data structure */
+typedef struct _AP_MLME_AUX {
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Alg;
+ CHAR Challenge[CIPHER_TEXT_LEN];
+} AP_MLME_AUX, *PAP_MLME_AUX;
+
+typedef enum _MAC_ENTRY_OP_MODE_ {
+ ENTRY_OP_MODE_ERROR = 0x00,
+ ENTRY_OP_MODE_CLI = 0x01, /* Sta mode, set this TRUE after Linkup,too. */
+ ENTRY_OP_MODE_WDS = 0x02, /* This is WDS Entry. only for AP mode. */
+ ENTRY_OP_MODE_APCLI = 0x04, /* This is a AP-Client entry, only for AP mode which enable AP-Client functions. */
+ ENTRY_OP_MODE_MESH = 0x08, /* Peer conect with us via mesh. */
+ ENTRY_OP_MODE_DLS = 0x10, /* This is DLS Entry. only for STA mode. */
+ ENTRY_OP_MODE_MAX = 0x20
+} MAC_ENTRY_OP_MODE;
+#endif /* CONFIG_AP_SUPPORT */
+
+/* Values of LastSecTxRateChangeAction */
+#define RATE_NO_CHANGE 0 /* No change in rate */
+#define RATE_UP 1 /* Trying higher rate or same rate with different BF */
+#define RATE_DOWN 2 /* Trying lower rate */
+
+
+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;
+#ifdef TXBF_SUPPORT
+ RALINK_TIMER_STRUCT eTxBfProbeTimer;
+#endif /* TXBF_SUPPORT */
+ 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 */
+
+#ifdef WAPI_SUPPORT
+ UCHAR usk_id; /* unicast key index for WPI */
+#endif /* WAPI_SUPPORT */
+
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR HdrAddr1[MAC_ADDR_LEN];
+ UCHAR HdrAddr2[MAC_ADDR_LEN];
+ UCHAR HdrAddr3[MAC_ADDR_LEN];
+ UCHAR PsMode;
+ UCHAR FlgPsModeIsWakeForAWhile; /* wake up for a while until a condition */
+ UCHAR VirtualTimeout; /* peer power save virtual timeout */
+ 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 UAPSD_SUPPORT
+ /* these UAPSD states are used on the fly */
+ /* 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO */
+ BOOLEAN bAPSDCapablePerAC[4]; /* for trigger-enabled */
+ BOOLEAN bAPSDDeliverEnabledPerAC[4]; /* for delivery-enabled */
+
+
+ UCHAR MaxSPLength;
+
+ BOOLEAN bAPSDAllAC; /* 1: all AC are delivery-enabled U-APSD */
+
+ QUEUE_HEADER UAPSDQueue[WMM_NUM_OF_AC]; /* queue for each U-APSD */
+ USHORT UAPSDQIdleCount; /* U-APSD queue timeout */
+
+ PQUEUE_ENTRY pUAPSDEOSPFrame; /* the last U-APSD frame */
+ USHORT UAPSDTxNum; /* total U-APSD frame number */
+ BOOLEAN bAPSDFlagEOSPOK; /* 1: EOSP frame is tx by ASIC */
+ BOOLEAN bAPSDFlagSPStart; /* 1: SP is started */
+
+ /* need to use unsigned long, because time parameters in OS is defined as
+ unsigned long */
+ unsigned long UAPSDTimeStampLast; /* unit: 1000000/OS_HZ */
+ BOOLEAN bAPSDFlagSpRoughUse; /* 1: use rough SP (default: accurate) */
+
+ /* we will set the flag when PS-poll frame is received and
+ clear it when statistics handle.
+ if the flag is set when PS-poll frame is received then calling
+ statistics handler to clear it. */
+ BOOLEAN bAPSDFlagLegacySent; /* 1: Legacy PS sent but
+ yet statistics handle */
+
+#ifdef RTMP_MAC_USB
+ UINT32 UAPSDTagOffset[WMM_NUM_OF_AC];
+#endif /* RTMP_MAC_USB */
+#endif /* UAPSD_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN bSendBAR;
+ USHORT NoBADataCountDown;
+
+ UINT32 CachedBuf[16]; /* UINT (4 bytes) for alignment */
+
+#ifdef TXBF_SUPPORT
+ COUNTER_TXBF TxBFCounters; /* TxBF Statistics */
+ UINT LastETxCount; /* Used to compute %BF statistics */
+ UINT LastITxCount;
+ UINT LastTxCount;
+#endif /* TXBF_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef STREAM_MODE_SUPPORT
+ UINT32 StreamModeMACReg; /* MAC reg used to control stream mode for this client. 0=>No stream mode */
+#endif // STREAM_MODE_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;
+ UCHAR lastRateIdx;
+ UCHAR *pTable; /* Pointer to this entry's Tx Rate Table */
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ UCHAR lowTrafficCount;
+ UCHAR fewPktsCnt;
+ BOOLEAN perThrdAdj;
+ UCHAR mcsGroup;/*the mcs group to be tried */
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ enum RATE_ADAPT_ALG rateAlg;
+
+#ifdef MFB_SUPPORT
+ 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 */
+ struct _RTMP_RA_LEGACY_TB *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;
+ UCHAR mfb0, mfb1;
+#endif /* MFB_SUPPORT */
+#ifdef TXBF_SUPPORT
+ UCHAR TxSndgType;
+ NDIS_SPIN_LOCK TxSndgLock;
+
+/* ETxBF */
+ UCHAR bfState;
+ UCHAR sndgMcs;
+ UCHAR sndgBW;
+ INT sndg0Snr0, sndg0Snr1, sndg0Snr2;
+ UCHAR sndg0Mcs;
+#ifdef ETXBF_EN_COND3_SUPPORT
+ UCHAR bestMethod;
+ UCHAR sndgRateIdx;
+ UCHAR bf0Mcs, sndg0RateIdx, bf0RateIdx;
+ UCHAR sndg1Mcs, bf1Mcs, sndg1RateIdx, bf1RateIdx;
+ INT sndg1Snr0, sndg1Snr1, sndg1Snr2;
+#endif /* ETXBF_EN_COND3_SUPPORT */
+ UCHAR noSndgCnt;
+ UCHAR eTxBfEnCond;
+ UCHAR noSndgCntThrd, ndpSndgStreams;
+ UCHAR iTxBfEn;
+
+ BOOLEAN phyETxBf; /* True=>Set ETxBF bit in PHY rate */
+ BOOLEAN phyITxBf; /* True=>Set ITxBF bit in PHY rate */
+ UCHAR lastNonBfRate; /* Last good non-BF rate */
+ BOOLEAN lastRatePhyTxBf; /* For Quick Check. True if last rate was BF */
+ USHORT BfTxQuality[MAX_TX_RATE_INDEX + 1]; /* Beamformed TX Quality */
+#endif /* TXBF_SUPPORT */
+
+ /* to record the each TX rate's quality. 0 is best, the bigger the worse. */
+ USHORT TxQuality[MAX_TX_RATE_INDEX + 1];
+ UINT32 OneSecTxNoRetryOkCount;
+ UINT32 OneSecTxRetryOkCount;
+ UINT32 OneSecTxFailCount;
+ UINT32 OneSecRxLGICount; /* unicast-to-me Long GI count */
+ UINT32 OneSecRxSGICount; /* unicast-to-me Short GI count */
+
+#ifdef FIFO_EXT_SUPPORT
+ UINT32 fifoTxSucCnt;
+ UINT32 fifoTxRtyCnt;
+#endif /* FIFO_EXT_SUPPORT */
+
+
+ BOOLEAN fLastSecAccordingRSSI;
+ UCHAR LastSecTxRateChangeAction; /* 0: no change, 1:rate UP, 2:rate down */
+ CHAR LastTimeTxRateChangeAction; /*Keep last time value of LastSecTxRateChangeAction */
+ ULONG LastTxOkCount; /* TxSuccess count in last Rate Adaptation interval */
+ UCHAR LastTxPER; /* Tx PER in last Rate Adaptation interval */
+ UCHAR PER[MAX_TX_RATE_INDEX + 1];
+
+ UINT32 ContinueTxFailCnt;
+ UINT32 CurrTxRateStableTime; /* # of second in current TX rate */
+ UCHAR TxRateUpPenalty; /* extra # of second penalty due to last unstable condition */
+#ifdef WDS_SUPPORT
+ BOOLEAN LockEntryTx; /* TRUE = block to WDS Entry traffic, FALSE = not. */
+#endif /* WDS_SUPPORT */
+ ULONG TimeStamp_toTxRing;
+
+/*==================================================== */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ UINT MatchAPCLITabIdx; /* indicate the index in ApCfg.ApCliTab. */
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_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
+ 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 */
+
+#ifdef DOT11_VHT_AC
+ VHT_CAP_IE vht_cap_ie;
+#endif /* DOT11_VHT_AC */
+
+#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;
+ SHORT freqOffset; /* Last RXWI FOFFSET */
+ SHORT freqOffsetValid; /* Set when freqOffset field has been updated */
+
+
+ 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 WAPI_SUPPORT
+ BOOLEAN WapiUskRekeyTimerRunning;
+ RALINK_TIMER_STRUCT WapiUskRekeyTimer;
+ UINT32 wapi_usk_rekey_cnt;
+#endif /* WAPI_SUPPORT */
+
+
+ ULONG AssocDeadLine;
+
+
+
+
+ ULONG ChannelQuality; /* 0..100, Channel Quality Indication for Roaming */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ MULTISSID_STRUCT *pMbss;
+#endif /* CONFIG_AP_SUPPORT */
+#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 */
+
+#ifdef CONFIG_AP_SUPPORT
+ LARGE_INTEGER TxPackets;
+ LARGE_INTEGER RxPackets;
+ ULONG TxBytes;
+ ULONG RxBytes;
+#endif /* CONFIG_AP_SUPPORT */
+#ifdef WFD_SUPPORT
+ BOOLEAN bWfdClient;
+#endif /* WFD_SUPPORT */
+
+UCHAR SupportRateMode; /* 1: CCK 2:OFDM 4: HT, 8:VHT */
+BOOLEAN SupportCCKMCS[MAX_LEN_OF_CCK_RATES];
+BOOLEAN SupportOFDMMCS[MAX_LEN_OF_OFDM_RATES];
+BOOLEAN SupportHTMCS[MAX_LEN_OF_HT_RATES];
+
+
+#ifdef DOT11_VHT_AC
+BOOLEAN SupportVHTMCS[MAX_LEN_OF_VHT_RATES];
+#endif /* DOT11_VHT_AC */
+#ifdef CONFIG_MULTI_CHANNEL
+ BOOLEAN bDoRateTune;
+#endif /* CONFIG_MULTI_CHANNEL */
+} 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! */
+ BOOLEAN fAllStationGainGoodMCS; /* Check if all stations more than MCS threshold */
+
+#ifdef CONFIG_AP_SUPPORT
+ BOOLEAN fAnyStationIsHT; /* Check if there is 11n STA. Force turn off AP MIMO PS */
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+ USHORT MsduLifeTime; /* life time for PS packet */
+
+#ifdef WAPI_SUPPORT
+ BOOLEAN fAnyWapiStation;
+#endif /* WAPI_SUPPORT */
+} MAC_TABLE, *PMAC_TABLE;
+
+
+/***************************************************************************
+ * AP WDS related data structures
+ **************************************************************************/
+//#ifdef WDS_SUPPORT
+typedef struct _WDS_COUNTER {
+ LARGE_INTEGER ReceivedFragmentCount;
+ LARGE_INTEGER TransmittedFragmentCount;
+ ULONG ReceivedByteCount;
+ ULONG TransmittedByteCount;
+ ULONG RxErrors;
+ ULONG TxErrors;
+ LARGE_INTEGER MulticastReceivedFrameCount;
+ ULONG OneCollision;
+ ULONG MoreCollisions;
+ ULONG RxNoBuffer;
+ ULONG RcvAlignmentErrors;
+} WDS_COUNTER, *PWDS_COUNTER;
+
+typedef struct _WDS_ENTRY {
+ BOOLEAN Valid;
+ UCHAR Addr[MAC_ADDR_LEN];
+ ULONG NoDataIdleCount;
+ struct _WDS_ENTRY *pNext;
+} WDS_ENTRY, *PWDS_ENTRY;
+
+typedef struct _WDS_TABLE_ENTRY {
+ USHORT Size;
+ UCHAR WdsAddr[MAC_ADDR_LEN];
+ WDS_ENTRY *Hash[HASH_TABLE_SIZE];
+ WDS_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
+ UCHAR MaxSupportedRate;
+ UCHAR CurrTxRate;
+ USHORT TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
+ USHORT OneSecTxOkCount;
+ USHORT OneSecTxRetryOkCount;
+ USHORT OneSecTxFailCount;
+ ULONG CurrTxRateStableTime; /* # of second in current TX rate */
+ UCHAR TxRateUpPenalty; /* extra # of second penalty due to last unstable condition */
+} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
+
+typedef struct _RT_802_11_WDS_ENTRY {
+ struct wifi_dev wdev;
+ PNET_DEV dev;
+ UCHAR Valid;
+ UCHAR PhyMode;
+ UCHAR PeerWdsAddr[MAC_ADDR_LEN];
+ UCHAR MacTabMatchWCID; /* ASIC */
+ NDIS_802_11_WEP_STATUS WepStatus;
+ UCHAR KeyIdx;
+ CIPHER_KEY WdsKey;
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+ RT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; /* Desired transmit setting. */
+ WDS_COUNTER WdsCounter;
+
+#ifdef WDS_VLAN_SUPPORT
+ /* VLAN */
+ USHORT VLAN_VID;
+ USHORT VLAN_Priority;
+#endif /* WDS_VLAN_SUPPORT */
+} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
+
+typedef struct _WDS_TABLE {
+ UCHAR Mode;
+ ULONG Size;
+ RT_802_11_WDS_ENTRY WdsEntry[MAX_WDS_ENTRY];
+} WDS_TABLE, *PWDS_TABLE;
+//#endif /* WDS_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+/***************************************************************************
+ * AP APCLI related data structures
+ **************************************************************************/
+typedef struct _APCLI_STRUCT {
+ struct wifi_dev wdev;
+
+ PNET_DEV dev;
+#ifdef RTL865X_SOC
+ unsigned int mylinkid;
+#endif
+ BOOLEAN Enable; /* Set it as 1 if the apcli interface was configured to "1" or by iwpriv cmd "ApCliEnable" */
+ BOOLEAN Valid; /* Set it as 1 if the apcli interface associated success to remote AP. */
+ UCHAR MacTabWCID; /*WCID value, which point to the entry of ASIC Mac table. */
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+
+ UCHAR CfgSsidLen;
+ CHAR CfgSsid[MAX_LEN_OF_SSID];
+ UCHAR CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
+ UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
+
+ ULONG ApCliRcvBeaconTime;
+ ULONG ApCliLinkUpTime;
+ USHORT ApCliBeaconPeriod;
+
+ ULONG CtrlCurrState;
+ ULONG SyncCurrState;
+ ULONG AuthCurrState;
+ ULONG AssocCurrState;
+ ULONG WpaPskCurrState;
+
+ USHORT AuthReqCnt;
+ USHORT AssocReqCnt;
+
+ ULONG ClientStatusFlags;
+ UCHAR MpduDensity;
+
+ 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;
+
+ UCHAR PSK[100]; /* reserve PSK key material */
+ UCHAR PSKLen;
+ UCHAR PMK[32]; /* WPA PSK mode PMK */
+ /*UCHAR PTK[64]; // WPA PSK mode PTK */
+ UCHAR GTK[32]; /* GTK from authenticator */
+
+ /*CIPHER_KEY PairwiseKey; */
+ CIPHER_KEY SharedKey[SHARE_KEY_NUM];
+ UCHAR DefaultKeyId;
+
+ /* WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED */
+ /*UCHAR PortSecured; */
+
+ /* store RSN_IE built by driver */
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; /* The content saved here should be convert to little-endian format. */
+ UCHAR RSNIE_Len;
+
+ /* 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 */
+ /*WPA_STATE WpaState; // Default is SS_NOTUSE */
+ /*UCHAR ReplayCounter[8]; */
+ /*UCHAR ANonce[32]; // ANonce for WPA-PSK from authenticator */
+ UCHAR SNonce[32]; /* SNonce for WPA-PSK */
+ UCHAR GNonce[32]; /* GNonce for WPA-PSK from authenticator */
+
+#ifdef WSC_AP_SUPPORT
+ WSC_CTRL WscControl;
+#endif /* WSC_AP_SUPPORT */
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+ RT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; /* Desired transmit setting. */
+ UCHAR RxMcsSet[16];
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+ BOOLEAN IEEE8021X;
+ BOOLEAN IEEE8021x_required_keys;
+ CIPHER_KEY DesireSharedKey[4]; // Record user desired WEP keys
+ UCHAR DesireSharedKeyId;
+ UCHAR WpaSupplicantUP;
+ UCHAR WpaSupplicantScanCount;
+ BOOLEAN bRSN_IE_FromWpaSupplicant;
+ BOOLEAN bLostAp;
+ UCHAR *pWpsProbeReqIe;
+ UINT WpsProbeReqIeLen;
+ UCHAR *pWpaAssocIe;
+ UINT WpaAssocIeLen;
+ BOOLEAN bScanReqIsFromWebUI;
+ BSSID_INFO SavedPMK[PMKID_NO];
+ UINT SavedPMKNum; // Saved PMKID number
+ BOOLEAN bConfigChanged;
+ 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 LastSsidLen; // the actual ssid length in used
+ CHAR LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
+ UCHAR LastBssid[MAC_ADDR_LEN];
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+
+
+ PSPOLL_FRAME PsPollFrame;
+ HEADER_802_11 NullFrame;
+
+ UAPSD_INFO UapsdInfo;
+} APCLI_STRUCT, *PAPCLI_STRUCT;
+
+typedef struct _AP_ADMIN_CONFIG {
+ USHORT CapabilityInfo;
+ /* Multiple SSID */
+ UCHAR BssidNum;
+ UCHAR MacMask;
+ MULTISSID_STRUCT MBSSID[HW_BEACON_MAX_NUM];
+ ULONG IsolateInterStaTrafficBTNBSSID;
+
+#ifdef APCLI_SUPPORT
+ UCHAR ApCliInfRunned; /* Number of ApClient interface which was running. value from 0 to MAX_APCLI_INTERFACE */
+ BOOLEAN FlgApCliIsUapsdInfoUpdated;
+ APCLI_STRUCT ApCliTab[MAX_APCLI_NUM]; /*AP-client */
+#endif /* APCLI_SUPPORT */
+
+ /* for wpa */
+ RALINK_TIMER_STRUCT CounterMeasureTimer;
+
+ UCHAR CMTimerRunning;
+ UCHAR BANClass3Data;
+ LARGE_INTEGER aMICFailTime;
+ LARGE_INTEGER PrevaMICFailTime;
+ ULONG MICFailureCounter;
+
+ RSSI_SAMPLE RssiSample;
+ ULONG NumOfAvgRssiSample;
+
+ BOOLEAN bAutoChannelAtBootup; /* 0: disable, 1: enable */
+ ChannelSel_Alg AutoChannelAlg; /* Alg for selecting Channel */
+ BOOLEAN bAvoidDfsChannel; /* 0: disable, 1: enable */
+ BOOLEAN bIsolateInterStaTraffic;
+ BOOLEAN bHideSsid;
+
+ /* temporary latch for Auto channel selection */
+ ULONG ApCnt; /* max RSSI during Auto Channel Selection period */
+ UCHAR AutoChannel_Channel; /* channel number during Auto Channel Selection */
+ UCHAR current_channel_index; /* current index of channel list */
+ UCHAR AutoChannelSkipListNum; /* number of rejected channel list */
+ UCHAR AutoChannelSkipList[10];
+ UCHAR DtimCount; /* 0.. DtimPeriod-1 */
+ UCHAR DtimPeriod; /* default = 3 */
+ UCHAR ErpIeContent;
+ ULONG LastOLBCDetectTime;
+ ULONG LastNoneHTOLBCDetectTime;
+ ULONG LastScanTime; /* Record last scan time for issue BSSID_SCAN_LIST */
+
+ 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 2nd antenna */
+#endif /* DOT11N_SS3_SUPPORT */
+
+#ifdef DOT1X_SUPPORT
+ /* dot1x related parameter */
+ UINT32 own_ip_addr;
+ UINT32 retry_interval;
+ UINT32 session_timeout_interval;
+ UINT32 quiet_interval;
+ UCHAR EAPifname[HW_BEACON_MAX_NUM][IFNAMSIZ]; /* indicate as the binding interface for EAP negotiation. */
+ UCHAR EAPifname_len[HW_BEACON_MAX_NUM];
+ UCHAR PreAuthifname[HW_BEACON_MAX_NUM][IFNAMSIZ]; /* indicate as the binding interface for WPA2 Pre-authentication. */
+ UCHAR PreAuthifname_len[HW_BEACON_MAX_NUM];
+#endif /* DOT1X_SUPPORT */
+
+ /* EDCA parameters to be announced to its local BSS */
+ EDCA_PARM BssEdcaParm;
+
+ RALINK_TIMER_STRUCT ApQuickResponeForRateUpTimer;
+ BOOLEAN ApQuickResponeForRateUpTimerRunning;
+
+#ifdef IDS_SUPPORT
+ /* intrusion detection parameter */
+ BOOLEAN IdsEnable;
+ UINT32 AuthFloodThreshold; /* Authentication frame flood threshold */
+ UINT32 AssocReqFloodThreshold; /* Association request frame flood threshold */
+ UINT32 ReassocReqFloodThreshold; /* Re-association request frame flood threshold */
+ UINT32 ProbeReqFloodThreshold; /* Probe request frame flood threshold */
+ UINT32 DisassocFloodThreshold; /* Disassociation frame flood threshold */
+ UINT32 DeauthFloodThreshold; /* Deauthentication frame flood threshold */
+ UINT32 EapReqFloodThreshold; /* EAP request frame flood threshold */
+
+ UINT32 RcvdAuthCount;
+ UINT32 RcvdAssocReqCount;
+ UINT32 RcvdReassocReqCount;
+ UINT32 RcvdProbeReqCount;
+ UINT32 RcvdDisassocCount;
+ UINT32 RcvdDeauthCount;
+ UINT32 RcvdEapReqCount;
+
+ RALINK_TIMER_STRUCT IDSTimer;
+ BOOLEAN IDSTimerRunning;
+#endif /* IDS_SUPPORT */
+
+ /* Indicate the maximum idle timeout */
+ UINT32 StaIdleTimeout;
+
+ ULONG EntryLifeCheck;
+
+#ifdef IGMP_SNOOP_SUPPORT
+ BOOLEAN IgmpSnoopEnable; /* 0: disable, 1: enable. */
+#endif /* IGMP_SNOOP_SUPPORT */
+
+
+#ifdef CLIENT_WDS
+ NDIS_SPIN_LOCK CliWdsTabLock;
+ PCLIWDS_PROXY_ENTRY pCliWdsEntryPool;
+ LIST_HEADER CliWdsEntryFreeList;
+ LIST_HEADER CliWdsProxyTab[CLIWDS_HASH_TAB_SIZE];
+#endif /* CLIENT_WDS */
+
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+ UCHAR GreenAPLevel;
+ BOOLEAN bGreenAPEnable;
+ BOOLEAN bGreenAPActive;
+#endif /* GREENAP_SUPPORT */
+
+ ULONG MAX_PSDU_LEN; /* Maximum PSDU length */
+#endif /* DOT11_N_SUPPORT */
+
+ UCHAR EntryClientCount;
+} AP_ADMIN_CONFIG, *PAP_ADMIN_CONFIG;
+
+#ifdef IGMP_SNOOP_SUPPORT
+typedef enum _IGMP_GROUP_TYPE {
+ MODE_IS_INCLUDE = 1,
+ MODE_IS_EXCLUDE,
+ CHANGE_TO_INCLUDE_MODE,
+ CHANGE_TO_EXCLUDE_MODE,
+ ALLOW_NEW_SOURCES,
+ BLOCK_OLD_SOURCES
+} IgmpGroupType;
+
+typedef enum _MULTICAST_FILTER_ENTRY_TYPE {
+ MCAT_FILTER_STATIC = 0,
+ MCAT_FILTER_DYNAMIC,
+} MulticastFilterEntryType;
+
+typedef struct _MEMBER_ENTRY {
+ struct _MEMBER_ENTRY *pNext;
+ UCHAR Addr[MAC_ADDR_LEN];
+/* USHORT Aid; */
+} MEMBER_ENTRY, *PMEMBER_ENTRY;
+
+typedef struct _MULTICAST_FILTER_TABLE_ENTRY {
+ BOOLEAN Valid;
+ MulticastFilterEntryType type; /* 0: static, 1: dynamic. */
+ UINT lastTime;
+ PNET_DEV net_dev;
+ UCHAR Addr[MAC_ADDR_LEN];
+ LIST_HEADER MemberList;
+ struct _MULTICAST_FILTER_TABLE_ENTRY *pNext;
+} MULTICAST_FILTER_TABLE_ENTRY, *PMULTICAST_FILTER_TABLE_ENTRY;
+
+typedef struct _MULTICAST_FILTER_TABLE {
+ UCHAR Size;
+ PMULTICAST_FILTER_TABLE_ENTRY
+ Hash[MAX_LEN_OF_MULTICAST_FILTER_HASH_TABLE];
+ MULTICAST_FILTER_TABLE_ENTRY Content[MAX_LEN_OF_MULTICAST_FILTER_TABLE];
+ NDIS_SPIN_LOCK MulticastFilterTabLock;
+ NDIS_SPIN_LOCK FreeMemberPoolTabLock;
+ MEMBER_ENTRY freeMemberPool[FREE_MEMBER_POOL_SIZE];
+ LIST_HEADER freeEntryList;
+} MULTICAST_FILTER_TABLE, *PMULTICAST_FILTER_TABLE;
+#endif /* IGMP_SNOOP_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+typedef enum _RT_GREEN_AP_LEVEL {
+ GREENAP_11BGN_STAS = 0,
+ GREENAP_ONLY_11BG_STAS,
+ GREENAP_WITHOUT_ANY_STAS_CONNECT
+} RT_GREEN_AP_LEVEL;
+#endif /* DOT11_N_SUPPORT */
+#endif /* GREENAP_SUPPORT */
+
+/* ----------- end of AP ---------------------------- */
+#endif /* CONFIG_AP_SUPPORT */
+
+#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 */
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+/*
+ 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 */
+ 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 */
+ CHAR idxTxPowerTable; /* The index of the Tx power table for ant0 */
+ CHAR idxTxPowerTable2; /* The index of the Tx power table for ant1 */
+ CHAR RF_TX_ALC; /* 3390: RF R12[4:0]: Tx0 ALC, 3352: RF R47[4:0]: Tx0 ALC, 5390: RF R49[5:0]: Tx0 ALC */
+ CHAR MAC_PowerDelta; /* Tx power control over MAC 0x1314~0x1324 */
+ CHAR MAC_PowerDelta2; /* Tx power control for Tx1 */
+ CHAR TotalDeltaPower2; /* Tx power control for Tx1 */
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+ INT LookupTable[IEEE80211_BAND_NUMS][33];
+ INT RefTemp[IEEE80211_BAND_NUMS];
+ UCHAR TssiGain[IEEE80211_BAND_NUMS];
+ /* Index offset, -7....25. */
+ INT LookupTableIndex;
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+} TX_POWER_CONTROL, *PTX_POWER_CONTROL;
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+
+/* */
+/* 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;
+
+/* For Wake on Wireless LAN */
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+typedef struct _WOW_CFG_STRUCT {
+ BOOLEAN bEnable; /* Enable WOW function*/
+ BOOLEAN bWOWFirmware; /* Enable WOW function, trigger to reload WOW-support firmware */
+ BOOLEAN bInBand; /* use in-band signal to wakeup system */
+ UINT8 nSelectedGPIO; /* Side band signal to wake up system */
+ UINT8 nDelay; /* Delay number is multiple of 3 secs, and it used to postpone the WOW function */
+ UINT8 nHoldTime; /* GPIO puls hold time, unit: 10ms */
+} WOW_CFG_STRUCT, *PWOW_CFG_STRUCT;
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+#ifdef NEW_WOW_SUPPORT
+typedef enum {
+ WOW_PKT_TO_HOST,
+ WOW_PKT_TO_ANDES
+} WOW_PKT_FLOW_T;
+
+typedef enum {
+ WOW_WAKEUP_BY_PCIE,
+ WOW_WAKEUP_BY_USB,
+ WOW_WAKEUP_BY_GPIO
+} WOW_WAKEUP_METHOD_T;
+
+typedef enum {
+ WOW_ENABLE = 1,
+ WOW_TRAFFIC = 3,
+ WOW_WAKEUP = 4
+} WOW_FEATURE_T;
+
+typedef enum {
+ WOW_MASK_CFG = 1,
+ WOW_SEC_CFG,
+ WOW_INFRA_CFG,
+ WOW_P2P_CFG,
+} WOW_CONFIG_T;
+
+enum {
+ WOW_MAGIC_PKT,
+ WOW_BITMAP,
+ WOW_IPV4_TCP_SYNC,
+ WOW_IPV6_TCP_SYNC
+};
+
+typedef struct NEW_WOW_MASK_CFG_STRUCT {
+ UINT32 Config_Type;
+ UINT32 Function_Enable;
+ UINT32 Detect_Mask;
+ UINT32 Event_Mask;
+} NEW_WOW_MASK_CFG_STRUCT, PNEW_WOW_MASK_CFG_STRUCT;
+
+typedef struct NEW_WOW_SEC_CFG_STRUCT {
+ UINT32 Config_Type;
+ UINT32 WPA_Ver;
+ UCHAR PTK[64];
+ UCHAR R_COUNTER[8];
+ UCHAR Key_Id;
+ UCHAR Cipher_Alg;
+ UCHAR WCID;
+ UCHAR Group_Cipher;
+} NEW_WOW_SEC_CFG_STRUCT, PNEW_WOW_SEC_CFG_STRUCT;
+
+typedef struct NEW_WOW_INFRA_CFG_STRUCT {
+ UINT32 Config_Type;
+ UCHAR STA_MAC[6];
+ UCHAR AP_MAC[6];
+ UINT32 AP_Status;
+} NEW_WOW_INFRA_CFG_STRUCT, PNEW_WOW_INFRA_CFG_STRUCT;
+
+typedef struct _NEW_WOW_P2P_CFG_STRUCT {
+ UINT32 Config_Type;
+ UCHAR GO_MAC[6];
+ UCHAR CLI_MAC[6];
+ UINT32 P2P_Status;
+} NEW_WOW_P2P_CFG_STRUCT, *PNEW_WOW_P2P_CFG_STRUCT;
+
+typedef struct _NEW_WOW_PARAM_STRUCT {
+ UINT32 Parameter;
+ UINT32 Value;
+} NEW_WOW_PARAM_STRUCT, *PNEW_WOW_PARAM_STRUCT;
+#endif /* NEW_WOW_SUPPORT */
+
+/*
+ Packet drop reason code
+*/
+typedef enum{
+ PKT_ATE_ON = 1 << 8,
+ PKT_RADAR_ON = 2 << 8,
+ PKT_RRM_QUIET = 3 << 8,
+ PKT_TX_STOP = 4 <<8,
+ PKT_TX_JAM = 5 << 8,
+
+ PKT_NETDEV_DOWN = 6 < 8,
+ PKT_NETDEV_NO_MATCH = 7 << 8,
+ PKT_NOT_ALLOW_SEND = 8 << 8,
+
+ PKT_INVALID_DST = 9<< 8,
+ PKT_INVALID_SRC = 10 << 8,
+ PKT_INVALID_PKT_DATA = 11 << 8,
+ PKT_INVALID_PKT_LEN = 12 << 8,
+ PKT_INVALID_ETH_TYPE = 13 << 8,
+ PKT_INVALID_TXBLK_INFO = 14 << 8,
+ PKT_INVALID_SW_ENCRYPT = 15 << 8,
+ PKT_INVALID_PKT_TYPE = 16 << 8,
+ PKT_INVALID_PKT_MIC = 17 << 8,
+
+ PKT_PORT_NOT_SECURE = 18 << 8,
+ PKT_TSPEC_NO_MATCH = 19 << 8,
+ PKT_NO_ASSOCED_STA = 20 << 8,
+ PKT_INVALID_MAC_ENTRY = 21 << 8,
+
+ PKT_TX_QUE_FULL = 22 << 8,
+ PKT_TX_QUE_ADJUST = 23<<8,
+
+ PKT_PS_QUE_TIMEOUT = 24 <<8,
+ PKT_PS_QUE_CLEAN = 25 << 8,
+ PKT_MCAST_PS_QUE_FULL = 26 << 8,
+ PKT_UCAST_PS_QUE_FULL = 27 << 8,
+
+ PKT_RX_EAPOL_SANITY_FAIL = 28 <<8,
+ PKT_RX_NOT_TO_KERNEL = 29 << 8,
+ PKT_RX_MESH_SIG_FAIL = 30 << 8,
+ PKT_APCLI_FAIL = 31 << 8,
+ PKT_ZERO_DATA = 32 <<8,
+ PKT_SW_DECRYPT_FAIL = 33 << 8,
+ PKT_TX_SW_ENC_FAIL = 34 << 8,
+
+ PKT_ACM_FAIL = 35 << 8,
+ PKT_IGMP_GRP_FAIL = 36 << 8,
+ PKT_MGMT_FAIL = 37 << 8,
+ PKT_AMPDU_OUT_ORDER = 38 << 8,
+ PKT_UAPSD_EOSP = 39 << 8,
+ PKT_UAPSD_Q_FULL = 40 << 8,
+
+ PKT_DRO_REASON_MAX = 41,
+}PKT_DROP_REASON;
+
+/* Packet drop Direction code */
+typedef enum{
+ PKT_TX = 0,
+ PKT_RX = 1 << 31,
+}PKT_DROP_DIECTION;
+
+
+
+
+typedef struct _BBP_RESET_CTL
+{
+#define BBP_RECORD_NUM 47
+ REG_PAIR BBPRegDB[BBP_RECORD_NUM];
+ BOOLEAN AsicCheckEn;
+} BBP_RESET_CTL, *PBBP_RESET_CTL;
+
+
+/* */
+/* The miniport adapter structure */
+/* */
+struct _RTMP_ADAPTER {
+ PVOID OS_Cookie; /* save specific structure relative to OS */
+ PNET_DEV net_dev;
+ ULONG VirtualIfCnt;
+
+ RTMP_CHIP_OP chipOps;
+ RTMP_CHIP_CAP chipCap;
+
+
+#ifdef 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 NumberOfPipes;
+ USHORT BulkOutMaxPacketSize;
+ USHORT BulkInMaxPacketSize;
+ UINT8 BulkOutEpAddr[6];
+ UINT8 BulkInEpAddr[2];
+
+ /*======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 reg_atomic;
+ RTMP_OS_SEM hw_atomic;
+ PVOID UsbVendorReqBuf;
+ BOOLEAN VendorResetFlag;
+/* 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 */
+
+
+#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 */
+
+ /* Maximum allowed tx software Queue length */
+ UINT32 TxSwQMaxLen;
+
+ 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 */
+ NDIS_SPIN_LOCK CmdRspLock;
+ 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 */
+
+ CMD_RSP_CONTEXT CmdRspEventContext;
+#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];
+#ifdef TXBF_SUPPORT
+ USHORT EEPROMITxBFCalParams[6];
+#endif /* TXBF_SUPPORT */
+ UCHAR EEPROMAddressNum; /* 93c46=6 93c66=8 */
+ BOOLEAN EepromAccess;
+ UCHAR EFuseTag;
+
+ /* --------------------------- */
+ /* BBP Control */
+ /* --------------------------- */
+ 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;
+#if defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290)
+ EEPROM_NIC_CONFIG3_STRUC NicConfig3;
+#endif /* defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290) */
+
+ /* 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 DOT11_VHT_AC
+ ULONG Tx80MPwrCfgABand[MAX_TXPOWER_ARRAY_SIZE]; // Per-rate Tx power control for VHT BW80 (5GHz only)
+#endif /* DOT11_VHT_AC */
+
+
+#ifdef MT7601
+ UINT32 TxCCKPwrCfg;
+#endif /* MT7601 */
+
+ 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)) */
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+ TX_POWER_CONTROL TxPowerCtrl; /* The Tx power control using the internal ALC */
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+
+
+ signed char BGRssiOffset[3]; /* Store B/G RSSI #0/1/2 Offset value on EEPROM 0x46h */
+ signed char ARssiOffset[3]; /* Store A RSSI 0/1/2 Offset value on EEPROM 0x4Ah */
+
+ 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 LED_CONTROL_SUPPORT
+ /* LED control */
+ LED_CONTROL LedCntl;
+#endif /* LED_CONTROL_SUPPORT */
+
+ /* ---------------------------- */
+ /* MAC control */
+ /* ---------------------------- */
+
+#ifdef RT8592
+// TODO: shiang-6590, temporary get from windows and need to revise it!!
+ /* IQ Calibration */
+ UCHAR IQGainTx[3][4];
+ UCHAR IQPhaseTx[3][4];
+ USHORT IQControl;
+#endif /* RT8592 */
+
+#if defined(RT3290) || defined(RT65xx) || defined(MT7601)
+
+ WLAN_FUN_CTRL_STRUC WlanFunCtrl;
+#endif /* defined(RT3290) || defined(RT65xx) || defined(MT7601) */
+
+#ifdef RT3290
+ // TODO: shiang, check about the purpose of this parameter
+ CMB_CTRL_STRUC CmbCtrl;
+ WLAN_FUN_INFO_STRUC WlanFunInfo;
+ BT_FUN_CTRL_STRUC BtFunCtrl;
+ WLAN_BT_COEX_SETTING WlanBTCoexInfo;
+ BOOLEAN RateUp;
+ ULONG AntennaDiversityState;/* 0->Stable state 1->training state */
+ ULONG AntennaDiversityPER[2]; // 0 ->main 1->aux
+ ULONG AntennaDiversityTxPacketCount[2]; // 0 ->main 1->aux
+ ULONG AntennaDiversityRxPacketCount[2];
+ ULONG AntennaDiversityTrigger;
+ ULONG AntennaDiversityCount;
+ ULONG TrainCounter;
+ ANT_DIVERSITY AntennaDiversityInfo;
+#endif /* RT3290 */
+
+ struct hw_setting hw_cfg;
+
+/*****************************************************************************************/
+/* 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. */
+ HEADER_802_11 NullFrame;
+
+#ifdef RTMP_MAC_USB
+ TX_CONTEXT NullContext[2];
+ TX_CONTEXT PsPollContext;
+#endif /* RTMP_MAC_USB */
+
+
+#ifdef UAPSD_SUPPORT
+ NDIS_SPIN_LOCK UAPSDEOSPLock; /* EOSP frame access lock use */
+ BOOLEAN bAPSDFlagSPSuspend; /* 1: SP is suspended; 0: SP is not */
+#endif /* UAPSD_SUPPORT */
+
+/*=========AP=========== */
+#ifdef CONFIG_AP_SUPPORT
+ /* ----------------------------------------------- */
+ /* AP specific configuration & operation status */
+ /* used only when pAd->OpMode == OPMODE_AP */
+ /* ----------------------------------------------- */
+ AP_ADMIN_CONFIG ApCfg; /* user configuration when in AP mode */
+ AP_MLME_AUX ApMlmeAux;
+#ifdef APCLI_SUPPORT
+ MLME_AUX ApCliMlmeAux; /* temporary settings used during MLME state machine */
+#endif /* APCLI_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ WDS_TABLE WdsTab; /* WDS table when working as an AP */
+ NDIS_SPIN_LOCK WdsTabLock;
+#endif /* WDS_SUPPORT */
+
+#ifdef MBSS_SUPPORT
+ BOOLEAN FlgMbssInit;
+#endif /* MBSS_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ BOOLEAN flg_wds_init;
+#endif /* WDS_SUPPORT */
+
+#ifdef APCLI_SUPPORT
+ BOOLEAN flg_apcli_init;
+#endif /* APCLI_SUPPORT */
+
+/*#ifdef AUTO_CH_SELECT_ENHANCE */
+ PBSSINFO pBssInfoTab;
+ PCHANNELINFO pChannelInfo;
+/*#endif // AUTO_CH_SELECT_ENHANCE */
+
+
+#endif /* CONFIG_AP_SUPPORT */
+
+ WDS_TABLE MulTestTab;
+/*=======STA=========== */
+
+/*=======Common=========== */
+ /* OP mode: either AP or STA */
+ UCHAR OpMode; /* OPMODE_STA, OPMODE_AP */
+
+ enum RATE_ADAPT_ALG rateAlg; /* Rate adaptation algorithm */
+
+ NDIS_MEDIA_STATE IndicateMediaState; /* Base on Indication state, default is NdisMediaStateDisConnected */
+#ifdef CONFIG_MULTI_CHANNEL
+ BOOLEAN Multi_Channel_Enable;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+#ifdef PROFILE_STORE
+ RTMP_OS_TASK WriteDatTask;
+ BOOLEAN bWriteDat;
+#endif /* PROFILE_STORE */
+
+#ifdef CREDENTIAL_STORE
+ STA_CONNECT_INFO StaCtIf;
+#endif /* CREDENTIAL_STORE */
+
+#ifdef WSC_INCLUDED
+ RTMP_OS_TASK wscTask;
+ UCHAR WriteWscCfgToDatFile;
+ BOOLEAN WriteWscCfgToAr9DatFile;
+ NDIS_SPIN_LOCK WscElmeLock;
+ MLME_QUEUE_ELEM *pWscElme;
+
+ /* WSC hardware push button function 0811 */
+ BOOLEAN WscHdrPshBtnFlag; /* 1: support, read from EEPROM */
+#ifdef CONFIG_AP_SUPPORT
+ BOOLEAN bWscDriverAutoUpdateCfg;
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* WSC_INCLUDED */
+
+
+ /* MAT related parameters */
+#ifdef MAT_SUPPORT
+ MAT_STRUCT MatCfg;
+#endif /* MAT_SUPPORT */
+
+
+ /*
+ Frequency setting for rate adaptation
+ @ra_interval: for baseline time interval
+ @ra_fast_interval: for quick response time interval
+ */
+ UINT32 ra_interval;
+ UINT32 ra_fast_interval;
+
+ /* 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 */
+
+ /* DOT11_H */
+ DOT11_H Dot11_H;
+
+ /* 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 */
+ /* ---------------------------- */
+
+ /* ---------------------------- */
+ /* 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 CONFIG_AP_SUPPORT
+#ifdef IGMP_SNOOP_SUPPORT
+ PMULTICAST_FILTER_TABLE pMulticastFilterTable;
+ UCHAR IgmpGroupTxRate;
+#endif /* IGMP_SNOOP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#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 */
+
+#ifdef CONFIG_AP_SUPPORT
+ RALINK_TIMER_STRUCT PeriodicTimer;
+
+#ifdef AP_QLOAD_SUPPORT
+ UINT8 FlgQloadEnable; /* 1: any BSS WMM is enabled */
+ ULONG QloadUpTimeLast; /* last up time */
+ UINT8 QloadChanUtil; /* last QBSS Load, unit: us */
+ UINT32 QloadChanUtilTotal; /* current QBSS Load Total */
+ UINT8 QloadChanUtilBeaconCnt; /* 1~100, default: 50 */
+ UINT8 QloadChanUtilBeaconInt; /* 1~100, default: 50 */
+ UINT32 QloadLatestChannelBusyTimePri;
+ UINT32 QloadLatestChannelBusyTimeSec;
+
+ /*
+ ex: For 100ms beacon interval,
+ if the busy time in last TBTT is smaller than 5ms, QloadBusyCount[0] ++;
+ if the busy time in last TBTT is between 5 and 10ms, QloadBusyCount[1] ++;
+ ......
+ if the busy time in last TBTT is larger than 95ms, QloadBusyCount[19] ++;
+
+ Command: "iwpriv ra0 qload show".
+ */
+
+/* provide busy time statistics for every TBTT */
+#define QLOAD_FUNC_BUSY_TIME_STATS
+
+/* provide busy time alarm mechanism */
+/* use the function to avoid to locate in some noise environments */
+#define QLOAD_FUNC_BUSY_TIME_ALARM
+
+#ifdef QLOAD_FUNC_BUSY_TIME_STATS
+#define QLOAD_BUSY_INTERVALS 20 /* partition TBTT to QLOAD_BUSY_INTERVALS */
+ /* for primary channel & secondary channel */
+ UINT32 QloadBusyCountPri[QLOAD_BUSY_INTERVALS];
+ UINT32 QloadBusyCountSec[QLOAD_BUSY_INTERVALS];
+#endif /* QLOAD_FUNC_BUSY_TIME_STATS */
+
+#ifdef QLOAD_FUNC_BUSY_TIME_ALARM
+#define QLOAD_DOES_ALARM_OCCUR(pAd) (pAd->FlgQloadAlarmIsSuspended == TRUE)
+#define QLOAD_ALARM_EVER_OCCUR(pAd) (pAd->QloadAlarmNumber > 0)
+ BOOLEAN FlgQloadAlarmIsSuspended; /* 1: suspend */
+
+ UINT8 QloadAlarmBusyTimeThreshold; /* unit: 1/100 */
+ UINT8 QloadAlarmBusyNumThreshold; /* unit: 1 */
+ UINT8 QloadAlarmBusyNum;
+ UINT8 QloadAlarmDuration; /* unit: TBTT */
+
+ UINT32 QloadAlarmNumber; /* total alarm times */
+ BOOLEAN FlgQloadAlarm; /* 1: alarm occurs */
+
+ /* speed up use */
+ UINT32 QloadTimePeriodLast;
+ UINT32 QloadBusyTimeThreshold;
+#else
+
+#define QLOAD_DOES_ALARM_OCCUR(pAd) 0
+#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */
+
+#endif /* AP_QLOAD_SUPPORT */
+#endif /* CONFIG_AP_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 WSC_INCLUDED
+ /* for multiple card */
+ UCHAR *pHmacData;
+#endif /* WSC_INCLUDED */
+
+#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 RTMP_EFUSE_SUPPORT
+ BOOLEAN bUseEfuse;
+ BOOLEAN bEEPROMFile;
+ BOOLEAN bFroceEEPROMBuffer;
+ BOOLEAN bCalFreeIC;
+ UCHAR EEPROMImage[1024];
+#endif /* RTMP_EFUSE_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
+#ifdef MAT_SUPPORT
+ /* used in OS_ABL */
+ BOOLEAN (*MATPktRxNeedConvert) (RTMP_ADAPTER *pAd, PNET_DEV net_dev);
+
+ PUCHAR (*MATEngineRxHandle)(RTMP_ADAPTER *pAd, PNDIS_PACKET pPkt, UINT infIdx);
+#endif /* MAT_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 */
+
+
+
+
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ WOW_CFG_STRUCT WOW_Cfg; /* data structure for wake on wireless */
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+#ifdef WLAN_SKB_RECYCLE
+ struct sk_buff_head rx0_recycle;
+#endif /* WLAN_SKB_RECYCLE */
+
+#ifdef FPGA_MODE
+ INT tx_kick_cnt;
+ INT phy_rates;
+ INT data_phy;
+ UCHAR data_bw;
+ UCHAR data_mcs;
+ UCHAR data_gi;
+ UCHAR data_basize;
+ BOOLEAN fpga_on;
+#endif /* FPGA_MODE */
+#ifdef WFA_VHT_PF
+ BOOLEAN force_amsdu;
+#endif /* WFA_VHT_PF */
+
+ UCHAR bloopBackTest;
+ BOOLEAN bHwTxLookupRate;
+ TXWI_STRUC NullTxWI;
+ BOOLEAN TestMulMac;
+
+ struct MCU_CTRL MCUCtrl;
+
+#ifdef CONFIG_MULTI_CHANNEL
+ USHORT NullBufOffset[2];
+ CHAR NullFrBuf[100];
+ UINT32 NullFrLen;
+ UINT32 MultiChannelFlowCtl;
+ RTMP_OS_TASK MultiChannelTask;
+ UCHAR MultiChannelAction;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+#ifdef SINGLE_SKU_V2
+ LIST_HEADER SingleSkuPwrList;
+ UCHAR DefaultTargetPwr;
+ CHAR SingleSkuRatePwrDiff[18];
+#endif /* SINGLE_SKU_V2 */
+
+};
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+/* 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 in G band */
+#define UPPERBOUND_TX_POWER_TUNING_ENTRY(__pAd) ((__pAd)->chipCap.TxAlcTxPowerUpperBound_2G)
+
+#ifdef A_BAND_SUPPORT
+/* The upper-bound of the Tx power tuning entry in A band */
+#define UPPERBOUND_TX_POWER_TUNING_ENTRY_5G(__pAd) ((__pAd)->chipCap.TxAlcTxPowerUpperBound_5G)
+#endif /* A_BAND_SUPPORT */
+
+/* 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 struct _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;
+
+typedef struct _TSSI_INFO_{
+ UCHAR tssi_info_0;
+ union {
+ CCK_TSSI_INFO cck_tssi_info;
+ OFDM_TSSI_INFO ofdm_tssi_info;
+ HT_TSSI_INFO ht_tssi_info_1;
+ UCHAR byte;
+ }tssi_info_1;
+ HT_TSSI_INFO ht_tssi_info_2;
+}TSSI_INFO;
+
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+
+
+/***************************************************************************
+ * Rx Path software control block related data structures
+ **************************************************************************/
+typedef struct _RX_BLK_
+{
+ UCHAR hw_rx_info[RXD_SIZE]; /* include "RXD_STRUC RxD" and "RXINFO_STRUC rx_info " */
+ RXINFO_STRUC *pRxInfo;
+#ifdef RLT_MAC
+ RXFCE_INFO *pRxFceInfo;
+#endif /* RLT_MAC */
+ RXWI_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 */
+ UCHAR wcid; /* copy of pRxWI->RxWIWirelessCliID */
+ UCHAR mcs;
+ UCHAR U2M;
+#ifdef HDR_TRANS_SUPPORT
+ BOOLEAN bHdrRxTrans; /* this packet's header is translated to 802.3 by HW */
+ BOOLEAN bHdrVlanTaged; /* VLAN tag is added to this header */
+ UCHAR *pTransData;
+ USHORT TransDataSize;
+#endif /* HDR_TRANS_SUPPORT */
+} 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 + TSO_INFO + 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 */
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ UINT ApCliIfidx;
+ PAPCLI_STRUCT pApCliEntry;
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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. */
+
+#ifdef CONFIG_AP_SUPPORT
+ MULTISSID_STRUCT *pMbss;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ UCHAR TxSndgPkt; /* 1: sounding 2: NDP sounding */
+ UCHAR TxNDPSndgBW;
+ UCHAR TxNDPSndgMcs;
+#endif /* TXBF_SUPPORT */
+
+#ifdef TX_PKT_SG
+ PACKET_INFO pkt_info;
+#endif /* TX_PKT_SG */
+ UCHAR OpMode;
+
+#ifdef HDR_TRANS_SUPPORT
+ BOOLEAN NeedTrans; /* indicate the packet needs to do hw header translate */
+#endif /* HDR_TRANS_SUPPORT */
+} 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_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+#define fTX_bApCliPacket 0x0200
+#endif /* APCLI_SUPPORT */
+
+#ifdef WDS_SUPPORT
+#define fTX_bWDSEntry 0x1000 /* Used when WDS_SUPPORT */
+#endif /* WDS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef UAPSD_SUPPORT
+#define fTX_bWMM_UAPSD_EOSP 0x0800 /* Used when UAPSD_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+
+
+#ifdef WAPI_SUPPORT
+#define fTX_bWPIDataFrame 0x8000 /* indicate this packet is an WPI data frame, it need to be encrypted by software */
+#endif /* WAPI_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 PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DescriptorType)
+{
+ int size;
+ int i;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ UINT8 RXWISize = pAd->chipCap.RXWISize;
+
+ size = ((DescriptorType == TYPE_TXWI) ? TXWISize : RXWISize);
+
+ 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(UCHAR *pData, ULONG DescType)
+{
+ *((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 *get_phymode_str(int phy_mode);
+char *get_bw_str(int bandwidth);
+
+
+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 WSC_INCLUDED
+VOID rtmp_read_wsc_user_parms_from_file(
+ IN PRTMP_ADAPTER pAd,
+ IN char *tmpbuf,
+ IN char *buffer);
+#endif/*WSC_INCLUDED*/
+
+VOID rtmp_read_multest_from_file(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING tmpbuf,
+ IN PSTRING buffer);
+
+#ifdef SINGLE_SKU_V2
+NDIS_STATUS RTMPSetSingleSKUParameters(
+ IN RTMP_ADAPTER *pAd);
+
+VOID InitSkuRateDiffTable(
+ IN PRTMP_ADAPTER pAd );
+
+UCHAR GetSkuChannelBasePwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel);
+
+UCHAR GetSkuRatePwr(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR phymode,
+ IN UCHAR channel,
+ IN UCHAR bw);
+
+VOID UpdateSkuRatePwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel,
+ IN UCHAR bw,
+ IN CHAR base_pwr);
+#endif /* SINGLE_SKU_V2 */
+
+VOID AP_WDS_KeyNameMakeUp(
+ IN STRING *pKey,
+ IN UINT32 KeyMaxSize,
+ IN INT KeyId);
+
+VOID AsicUpdateMulTestRxWCIDTable(
+ IN PRTMP_ADAPTER pAd);
+
+MAC_TABLE_ENTRY *MulTestTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount);
+
+VOID AsicUpdateMulTestEncryption(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid);
+
+MAC_TABLE_ENTRY *MacTableInsertMulTestEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ UINT WdsTabIdx);
+
+
+
+#ifdef RLT_RF
+NDIS_STATUS rlt_rf_write(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR bank,
+ IN UCHAR regID,
+ IN UCHAR value);
+
+NDIS_STATUS rlt_rf_read(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR bank,
+ IN UCHAR regID,
+ IN UCHAR *pValue);
+#endif /* RLT_RF */
+
+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);
+
+VOID NICUpdateFifoStaCounters(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICUpdateRawCounters(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+VOID NICUpdateRxStatusCnt1(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Idx);
+
+UINT32 NICSumFalseCCACnt(
+IN PRTMP_ADAPTER pAd);
+
+UINT32 NICSumPLCPErrCnt(
+IN PRTMP_ADAPTER pAd);
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+#ifdef FIFO_EXT_SUPPORT
+BOOLEAN NicGetMacFifoTxCnt(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID AsicFifoExtSet(
+ IN RTMP_ADAPTER *pAd);
+
+VOID AsicFifoExtEntryClean(
+ IN RTMP_ADAPTER * pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+#endif /* FIFO_EXT_SUPPORT */
+
+VOID NicResetRawCounters(RTMP_ADAPTER *pAd);
+
+VOID NicGetTxRawCounters(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_STA_CNT0_STRUC *pStaTxCnt0,
+ IN TX_STA_CNT1_STRUC *pStaTxCnt1);
+
+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 RTMP_AllTimerListRelease(
+ 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);
+
+#ifdef CONFIG_AP_SUPPORT
+VOID SendBeaconRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid);
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID PeerRMAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+
+#ifdef CONFIG_AP_SUPPORT
+VOID ApPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif /* CONFIG_AP_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 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 */
+
+VOID AsicEnableRalinkBurstMode(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicDisableRalinkBurstMode(
+ IN PRTMP_ADAPTER pAd);
+#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 UINT32 int_reg);
+
+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);
+
+#ifdef CONFIG_AP_SUPPORT
+VOID RTMPHandleMcuInterrupt(
+ IN PRTMP_ADAPTER pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+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 RTMP_ADAPTER *pAd,
+ IN BOOLEAN bIntContext,
+ IN UCHAR QueIdx,
+ IN INT 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 RTMP_ADAPTER *pAd,
+ IN UCHAR Rate,
+ IN ULONG Size);
+
+VOID RTMPWriteTxWI(
+ IN RTMP_ADAPTER *pAd,
+ IN TXWI_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 RTMP_ADAPTER *pAd,
+ INOUT TXWI_STRUC *pTxWI,
+ IN TX_BLK *pTxBlk);
+
+
+VOID RTMPWriteTxWI_Cache(
+ IN RTMP_ADAPTER *pAd,
+ INOUT TXWI_STRUC *pTxWI,
+ IN TX_BLK *pTxBlk);
+
+VOID RTMPSuspendMsduTransmission(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RTMPResumeMsduTransmission(
+ IN RTMP_ADAPTER *pAd);
+
+NDIS_STATUS MiniportMMRequest(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR *pData,
+ IN UINT Length);
+
+VOID RTMPSendNullFrame(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull,
+ IN USHORT PwrMgmt);
+
+#ifdef CONFIG_MULTI_CHANNEL
+VOID RTMPP2PSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull,
+ IN USHORT PwrMgmt);
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+
+
+
+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 AsicGetTxPowerOffset(
+ IN PRTMP_ADAPTER pAd,
+ IN PULONG TxPwr);
+
+VOID AsicGetAutoAgcOffsetForExternalTxAlc(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1);
+
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+VOID AsicGetAutoAgcOffsetForTemperatureSensor(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1);
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+#ifdef SINGLE_SKU
+VOID GetSingleSkuDeltaPower(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pTotalDeltaPower,
+ INOUT PULONG pSingleSKUTotalDeltaPwr,
+ INOUT PUCHAR pSingleSKUBbpR1Offset);
+#endif /* SINGLE_SKU*/
+
+VOID AsicPercentageDeltaPower(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ INOUT PCHAR pDeltaPwr,
+ INOUT PCHAR pDeltaPowerByBbpR1);
+
+VOID AsicCompensatePowerViaBBP(
+ IN PRTMP_ADAPTER pAd,
+ INOUT PCHAR pTotalDeltaPower);
+
+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);
+
+INT AsicSetChannel(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR ch,
+ IN UCHAR bw,
+ IN UCHAR ext_ch,
+ 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);
+
+
+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);
+
+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,
+ IN BOOLEAN in_atomic);
+
+BOOLEAN AsicSendCommandToMcuBBP(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1,
+ IN BOOLEAN FlgIsNeedLocked);
+
+
+
+#ifdef WAPI_SUPPORT
+VOID AsicUpdateWAPIPN(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG pn_low,
+ IN ULONG pn_high);
+#endif /* WAPI_SUPPORT */
+
+#ifdef VCORECAL_SUPPORT
+VOID AsicVCORecalibration(
+ IN PRTMP_ADAPTER pAd);
+#endif /* VCORECAL_SUPPORT */
+
+#ifdef STREAM_MODE_SUPPORT
+UINT32 StreamModeRegVal(
+ IN RTMP_ADAPTER *pAd);
+
+VOID AsicSetStreamMode(
+ IN RTMP_ADAPTER *pAd,
+ IN PUCHAR pMacAddr,
+ IN INT chainIdx,
+ IN BOOLEAN bEnabled);
+
+VOID RtmpStreamModeInit(
+ IN RTMP_ADAPTER *pAd);
+
+/*
+ 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);
+
+INT Set_StreamMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_StreamModeMac_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_StreamModeMCS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* STREAM_MODE_SUPPORT */
+
+#ifdef WOW_SUPPORT
+#ifdef RTMP_MAC_USB
+/* For WOW, 8051 MUC send full frame */
+VOID AsicWOWSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull);
+
+VOID AsicLoadWOWFirmware(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN WOW);
+#endif /* RTMP_MAC_USB */
+#endif /* WOW_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);
+
+ULONG BssTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *Tab,
+ IN BCN_IE_LIST *ie_list,
+ IN CHAR Rssi,
+ 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 UCHAR AntSel,
+ IN ULONG MsgLen,
+ IN PVOID Msg,
+ IN UCHAR Signal,
+ IN UCHAR OpMode);
+
+#ifdef WSC_INCLUDED
+BOOLEAN MlmeEnqueueForWsc(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG eventID,
+ IN LONG senderID,
+ IN ULONG Machine,
+ IN ULONG MsgType,
+ IN ULONG MsgLen,
+ IN VOID *Msg);
+#endif /* WSC_INCLUDED */
+
+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 IE_LISTS *ie_list,
+ 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_AP_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+VOID APDLSStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APPeerDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerDlsRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif /* QOS_DLS_SUPPORT */
+#endif /* CONFIG_AP_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 MlmeForceJoinReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeForceScanReqAction(
+ 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);
+
+
+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_Old(
+ 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,
+ 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);
+
+
+BOOLEAN PeerBeaconAndProbeRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgChannel,
+ OUT BCN_IE_LIST *ie_list,
+ 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,
+ OUT IE_LISTS *ie_list);
+
+BOOLEAN PeerDisassocSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerDeauthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr1,
+ OUT PUCHAR pAddr2,
+ OUT PUCHAR pAddr3,
+ OUT USHORT *Reason);
+
+BOOLEAN GetTimBit(
+ IN CHAR *Ptr,
+ IN USHORT Aid,
+ OUT UCHAR *TimLen,
+ OUT UCHAR *BcastFlag,
+ OUT UCHAR *DtimCount,
+ OUT UCHAR *DtimPeriod,
+ OUT UCHAR *MessageToMe);
+
+UCHAR ChannelSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel);
+
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
+ IN PBSS_ENTRY pBss);
+
+BOOLEAN MlmeDelBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen);
+
+BOOLEAN MlmeAddBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2);
+
+ULONG MakeOutgoingFrame(
+ OUT UCHAR *Buffer,
+ OUT ULONG *Length, ...);
+
+UCHAR RandomByte(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR RandomByte2(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateAutoFallBackTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pTxRate);
+
+
+
+VOID MlmePeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LinkDownExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LinkUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID STAMlmePeriodicExec(
+ PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoScan(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoReconnectLastSSID(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeValidateSSID(
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen);
+
+VOID MlmeCheckForRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32);
+
+BOOLEAN MlmeCheckForFastRoaming(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef TXBF_SUPPORT
+BOOLEAN MlmeTxBfAllowed(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN struct _RTMP_RA_LEGACY_TB *pTxRate);
+#endif /* TXBF_SUPPORT */
+
+#ifdef AGS_SUPPORT
+INT Show_AGS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+#ifdef CONFIG_AP_SUPPORT
+VOID ApMlmeDynamicTxRateSwitchingAGS(
+ IN RTMP_ADAPTER *pAd,
+ IN INT idx);
+
+VOID ApQuickResponeForRateUpExecAGS(
+ IN RTMP_ADAPTER *pAd,
+ IN INT idx);
+
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* AGS_SUPPORT */
+
+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);
+
+
+BOOLEAN RTMPCheckHt(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Wcid,
+ INOUT HT_CAPABILITY_IE *pHtCapability,
+ INOUT ADD_HT_INFO_IE *pAddHtInfo);
+
+#ifdef DOT11_VHT_AC
+BOOLEAN RTMPCheckVht(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Wcid,
+ IN VHT_CAP_IE *vht_cap,
+ IN VHT_OP_IE *vht_op);
+#endif /* DOT11_VHT_AC */
+
+VOID RTMPUpdateMlmeRate(
+ IN PRTMP_ADAPTER pAd);
+
+CHAR RTMPMaxRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2);
+
+CHAR RTMPAvgRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN RSSI_SAMPLE *pRssi);
+
+
+CHAR RTMPMinSnr(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Snr0,
+ IN CHAR Snr1);
+
+VOID AsicSetRxAnt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ant);
+
+#ifdef RTMP_EFUSE_SUPPORT
+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 */
+#endif /* RTMP_EFUSE_SUPPORT */
+
+
+
+
+
+VOID AsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicRxAntEvalTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID APSDPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+UCHAR RTMPStaFixedTxMode(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID RTMPUpdateLegacyTxSetting(
+ UCHAR fixed_tx_mode,
+ PMAC_TABLE_ENTRY pEntry);
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS MlmeInit(
+ IN PRTMP_ADAPTER pAd);
+
+
+
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+VOID InitLookupTable(
+ IN PRTMP_ADAPTER pAd);
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+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);
+
+UCHAR cfgmode_2_wmode(UCHAR cfg_mode);
+UCHAR wmode_2_cfgmode(UCHAR wmode);
+UCHAR *wmode_2_str(UCHAR wmode);
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef MBSS_SUPPORT
+INT RT_CfgSetMbssWirelessMode(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+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 INT keyStringLen,
+ 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);
+
+#ifdef WSC_INCLUDED
+INT RT_CfgSetWscPinCode(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING pPinCodeStr,
+ OUT PWSC_CTRL pWscControl);
+#endif /* WSC_INCLUDED */
+
+INT Set_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+INT Set_MO_FalseCCATh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+/* */
+/* 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);
+
+UCHAR get_cent_ch_by_htinfo(
+ RTMP_ADAPTER *pAd,
+ ADD_HT_INFO_IE *ht_op,
+ HT_CAPABILITY_IE *ht_cap);
+
+INT get_ht_cent_ch(RTMP_ADAPTER *pAd, UCHAR *rf_bw, UCHAR *ext_ch);
+INT ht_mode_adjust(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, HT_CAPABILITY_IE *peer, RT_HT_CAPABILITY *my);
+INT set_ht_fixed_mcs(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, UCHAR fixed_mcs, UCHAR mcs_bound);
+INT get_ht_max_mcs(RTMP_ADAPTER *pAd, UCHAR *desire_mcs, UCHAR *cap_mcs);
+#endif /* DOT11_N_SUPPORT */
+
+VOID RTMPDisableDesiredHtInfo(
+ IN PRTMP_ADAPTER pAd);
+
+#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,
+ IN UCHAR AntSel,
+ IN UCHAR BW);
+
+CHAR ConvertToSnr(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Snr);
+
+#ifdef DOT11N_DRAFT3
+VOID BuildEffectedChannelList(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID DeleteEffectedChannelList(
+ IN PRTMP_ADAPTER pAd);
+
+VOID CntlChannelWidth(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PrimaryChannel,
+ IN UCHAR CentralChannel,
+ IN UCHAR ChannelWidth,
+ IN UCHAR SecondaryChannelOffset);
+
+#endif /* DOT11N_DRAFT3 */
+
+
+VOID APAsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID APAsicRxAntEvalTimeout(
+ IN PRTMP_ADAPTER pAd);
+
+
+/* */
+/* function prototype in ap_wpa.c */
+/* */
+VOID RTMPGetTxTscFromAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx,
+ OUT PUCHAR pTxTsc);
+
+MAC_TABLE_ENTRY *PACInquiry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid);
+
+UINT APValidateRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR pRsnIe,
+ IN UCHAR rsnie_len);
+
+VOID HandleCounterMeasure(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID WPAStart4WayHS(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN ULONG TimeInterval);
+
+VOID WPAStart2WayGroupHS(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID PeerPairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerGroupMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerGroupMsg2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN VOID *Msg,
+ IN UINT MsgLen);
+
+VOID CMTimerExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WPARetryExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+#ifdef TXBF_SUPPORT
+VOID eTxBfProbeTimerExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif /* TXBF_SUPPORT */
+
+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 */
+
+#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 WSC_INCLUDED
+INT Set_WscGenPinCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WscVendorPinCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef WSC_AP_SUPPORT
+VOID RTMPIoctlSetWSCOOB(IN PRTMP_ADAPTER pAd);
+#endif
+
+#ifdef WSC_STA_SUPPORT
+VOID CntlWscIterate(
+ IN PRTMP_ADAPTER pAd);
+
+USHORT WscGetAuthTypeFromStr(
+ IN PSTRING arg);
+
+USHORT WscGetEncrypTypeFromStr(
+ IN PSTRING arg);
+#endif /* WSC_STA_SUPPORT */
+/* */
+/* prototype in wsc.c */
+/* */
+BOOLEAN WscMsgTypeSubst(
+ IN UCHAR EAPType,
+ IN UCHAR EAPCode,
+ OUT INT *MsgType);
+
+VOID WscStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+
+VOID WscEAPOLStartAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WscEAPAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WscEapEnrolleeAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl);
+
+#ifdef CONFIG_AP_SUPPORT
+VOID WscEapApProxyAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl);
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID WscEapRegistrarAction(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MLME_QUEUE_ELEM *Elem,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscEAPOLTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID Wsc2MinsTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+UCHAR WscRxMsgType(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PMLME_QUEUE_ELEM pElem);
+
+VOID WscInitRegistrarPair(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN UCHAR apidx);
+
+VOID WscSendEapReqId(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR CurOpMode);
+
+VOID WscSendEapolStart(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid,
+ IN UCHAR CurOpMode);
+
+VOID WscSendEapRspId(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 Hdr,
+ IN PUCHAR pAddr1,
+ IN PUCHAR pBSSID,
+ IN BOOLEAN bFromApCli);
+
+VOID WscSendMessage(
+ IN PRTMP_ADAPTER pAdapter,
+ IN UCHAR OpCode,
+ IN PUCHAR pData,
+ IN INT Len,
+ IN PWSC_CTRL pWscControl,
+ IN UCHAR OpMode, /* 0: AP Mode, 1: AP Client Mode, 2: STA Mode */
+ IN UCHAR EapType);
+
+VOID WscSendEapReqAck(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID WscSendEapReqDone(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PMLME_QUEUE_ELEM pElem);
+
+VOID WscSendEapFail(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN BOOLEAN bSendDeAuth);
+
+VOID WscM2DTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WscUPnPMsgTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+int WscSendUPnPConfReqMsg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apIdx,
+ IN PUCHAR ssidStr,
+ IN PUCHAR macAddr,
+ IN INT Status,
+ IN UINT eventID,
+ IN UCHAR CurOpMode);
+
+
+int WscSendUPnPMessage(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apIdx,
+ IN USHORT msgType,
+ IN USHORT msgSubType,
+ IN PUCHAR pData,
+ IN INT dataLen,
+ IN UINT eventID,
+ IN UINT toIPAddr,
+ IN PUCHAR pMACAddr,
+ IN UCHAR CurOpMode);
+
+VOID WscUPnPErrHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN UINT eventID);
+
+VOID WscBuildBeaconIE(
+ IN PRTMP_ADAPTER pAdapter,
+ IN UCHAR b_configured,
+ IN BOOLEAN b_selRegistrar,
+ IN USHORT devPwdId,
+ IN USHORT selRegCfgMethods,
+ IN UCHAR apidx,
+ IN UCHAR *pAuthorizedMACs,
+ IN UCHAR AuthorizedMACsLen,
+ IN UCHAR CurOpMode);
+
+VOID WscBuildProbeRespIE(
+ IN PRTMP_ADAPTER pAdapter,
+ IN UCHAR respType,
+ IN UCHAR scState,
+ IN BOOLEAN b_selRegistrar,
+ IN USHORT devPwdId,
+ IN USHORT selRegCfgMethods,
+ IN UCHAR apidx,
+ IN UCHAR *pAuthorizedMACs,
+ IN INT AuthorizedMACsLen,
+ IN UCHAR CurOpMode);
+
+
+#ifdef CONFIG_AP_SUPPORT
+VOID WscBuildAssocRespIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ApIdx,
+ IN UCHAR Reason,
+ OUT PUCHAR pOutBuf,
+ OUT PUCHAR pIeLen);
+
+VOID WscSelectedRegistrar(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR RegInfo,
+ IN UINT length,
+ IN UCHAR apidx);
+
+VOID WscInformFromWPA(
+ IN PMAC_TABLE_ENTRY pEntry);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+VOID WscProfileRetryTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WscPBCTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WscScanTimeOutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+
+INT WscGenerateUUID(
+ RTMP_ADAPTER *pAd,
+ UCHAR *uuidHexStr,
+ UCHAR *uuidAscStr,
+ int apIdx,
+ BOOLEAN bUseCurrentTime);
+
+VOID WscStop(
+ IN PRTMP_ADAPTER pAd,
+#ifdef CONFIG_AP_SUPPORT
+ IN BOOLEAN bFromApcli,
+#endif /* CONFIG_AP_SUPPORT */
+ IN PWSC_CTRL pWscControl);
+
+VOID WscInit(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromApcli,
+ IN UCHAR BssIndex);
+
+BOOLEAN ValidateChecksum(
+ IN UINT PIN);
+
+UINT WscRandomGen4digitPinCode(
+ IN PRTMP_ADAPTER pAd);
+
+UINT WscRandomGeneratePinCode(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx);
+
+int BuildMessageM1(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM2(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM2D(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM3(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM4(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM5(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM6(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM7(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageM8(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageDONE(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageACK(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int BuildMessageNACK(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ OUT VOID *pbuf);
+
+int ProcessMessageM1(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM2(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ IN UCHAR apidx,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM2D(
+ IN PRTMP_ADAPTER pAdapter,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM3(
+ IN PRTMP_ADAPTER pAdapter,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM4(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM5(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM6(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM7(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN VOID *precv,
+ IN INT Length,
+ OUT PWSC_REG_DATA pReg);
+
+int ProcessMessageM8(
+ IN PRTMP_ADAPTER pAdapter,
+ IN VOID *precv,
+ IN INT Length,
+ IN PWSC_CTRL pWscControl);
+
+USHORT WscGetAuthType(
+ IN NDIS_802_11_AUTHENTICATION_MODE authType);
+
+USHORT WscGetEncryType(
+ IN NDIS_802_11_WEP_STATUS encryType);
+
+NDIS_STATUS WscThreadInit(
+ IN RTMP_ADAPTER *pAd);
+
+BOOLEAN WscThreadExit(
+ IN RTMP_ADAPTER *pAd);
+
+int AppendWSCTLV(
+ IN USHORT index,
+ OUT UCHAR * obuf,
+ IN UCHAR * ibuf,
+ IN USHORT varlen);
+
+VOID WscGetRegDataPIN(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT PinCode,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscPushPBCAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscScanExec(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl);
+
+BOOLEAN WscPBCExec(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromM2,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscPBCBssTableSort(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscGenRandomKey(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ INOUT PUCHAR pKey,
+ INOUT PUSHORT pKeyLen);
+
+VOID WscCreateProfileFromCfg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR OpMode, /* 0: AP Mode, 1: AP Client Mode, 2: STA Mode */
+ IN PWSC_CTRL pWscControl,
+ OUT PWSC_PROFILE pWscProfile);
+
+void WscWriteConfToPortCfg(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN PWSC_CREDENTIAL pCredential,
+ IN BOOLEAN bEnrollee);
+
+#ifdef APCLI_SUPPORT
+void WscWriteConfToApCliCfg(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN PWSC_CREDENTIAL pCredential,
+ IN BOOLEAN bEnrollee);
+#endif /* APCLI_SUPPORT */
+
+VOID WpsSmProcess(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WscPBCSessionOverlapCheck(
+ IN PRTMP_ADAPTER pAd);
+
+VOID WscPBC_DPID_FromSTA(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pMacAddr);
+
+#ifdef CONFIG_AP_SUPPORT
+INT WscGetConfWithoutTrigger(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl,
+ IN BOOLEAN bFromUPnP);
+
+BOOLEAN WscReadProfileFromUfdFile(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ApIdx,
+ IN PSTRING pUfdFileName);
+
+BOOLEAN WscWriteProfileToUfdFile(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ApIdx,
+ IN PSTRING pUfdFileName);
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID WscCheckWpsIeFromWpsAP(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT pEid,
+ OUT PUSHORT pDPIDFromAP);
+
+
+/* WSC hardware push button function 0811 */
+VOID WSC_HDR_BTN_Init(
+ IN PRTMP_ADAPTER pAd);
+
+VOID WSC_HDR_BTN_Stop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID WSC_HDR_BTN_CheckHandler(
+ IN PRTMP_ADAPTER pAd);
+#ifdef WSC_LED_SUPPORT
+BOOLEAN WscSupportWPSLEDMode(
+ IN PRTMP_ADAPTER pAdapter);
+
+BOOLEAN WscSupportWPSLEDMode10(
+ IN PRTMP_ADAPTER pAdapter);
+
+BOOLEAN WscAPHasSecuritySetting(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl);
+
+VOID WscLEDTimer(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WscSkipTurnOffLEDTimer(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif /* WSC_LED_SUPPORT */
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+VOID WscUpdatePortCfgTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif /* CONFIG_AP_SUPPORT */
+
+VOID WscCheckPeerDPID(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 Fr,
+ IN PUCHAR eid_data,
+ IN INT eid_len);
+
+VOID WscClearPeerList(
+ IN PLIST_HEADER pWscEnList);
+
+PWSC_PEER_ENTRY WscFindPeerEntry(
+ IN PLIST_HEADER pWscEnList,
+ IN PUCHAR pMacAddr);
+
+VOID WscDelListEntryByMAC(
+ PLIST_HEADER pWscEnList,
+ IN PUCHAR pMacAddr);;
+
+VOID WscInsertPeerEntryByMAC(
+ IN PLIST_HEADER pWscEnList,
+ IN PUCHAR pMacAddr);
+
+#ifdef CONFIG_AP_SUPPORT
+INT WscApShowPeerList(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+VOID WscMaintainPeerList(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWpsCtrl);
+
+VOID WscAssignEntryMAC(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWpsCtrl);
+
+#ifdef WSC_V2_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+VOID WscOnOff(
+ IN PRTMP_ADAPTER pAd,
+ IN INT ApIdx,
+ IN BOOLEAN bOff);
+
+VOID WscAddEntryToAclList(
+ IN PRTMP_ADAPTER pAd,
+ IN INT ApIdx,
+ IN PUCHAR pMacAddr);
+
+VOID WscSetupLockTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WscCheckPinAttackCount(
+ IN PRTMP_ADAPTER pAd,
+ IN PWSC_CTRL pWscControl);
+#endif /* CONFIG_AP_SUPPORT */
+
+BOOLEAN WscGenV2Msg(
+ IN PWSC_CTRL pWpsCtrl,
+ IN BOOLEAN bSelRegistrar,
+ IN PUCHAR pAuthorizedMACs,
+ IN INT AuthorizedMACsLen,
+ OUT UCHAR **pOutBuf,
+ OUT INT *pOutBufLen);
+
+BOOLEAN WscParseV2SubItem(
+ IN UCHAR SubID,
+ IN PUCHAR pData,
+ IN USHORT DataLen,
+ OUT PUCHAR pOutBuf,
+ OUT PUCHAR pOutBufLen);
+
+VOID WscSendEapFragAck(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID WscSendEapFragData(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PWSC_CTRL pWscControl,
+ IN PMAC_TABLE_ENTRY pEntry);
+#endif /* WSC_V2_SUPPORT */
+
+BOOLEAN WscGetDataFromPeerByTag(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pIeData,
+ IN INT IeDataLen,
+ IN USHORT WscTag,
+ OUT PUCHAR pWscBuf,
+ OUT PUSHORT pWscBufLen);
+
+#endif /* WSC_INCLUDED */
+
+
+
+
+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 EXT_BUILD_CHANNEL_LIST
+INT Set_ExtCountryCode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+INT Set_ExtDfsType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ChannelListAdd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ChannelListShow_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+INT Set_ChannelListDel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+#ifdef DBG
+INT Set_Debug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_DebugFunc_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+#endif
+
+#ifdef TXBF_SUPPORT
+INT Set_ReadITxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ReadETxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WriteITxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WriteETxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_StatITxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_StatETxBf_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TxBfTag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ITxBfTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ETxBfTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_InvTxBfTag_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ITxBfCal_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ITxBfDivCal_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ITxBfLnaCal_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ETxBfEnCond_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ETxBfCodebook_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ETxBfCoefficient_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ETxBfGrouping_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ETxBfNoncompress_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ETxBfIncapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_NoSndgCntThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_NdpSndgStreams_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_Trigger_Sounding_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ITxBfEn_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#endif /* TXBF_SUPPORT */
+
+INT Set_RateAdaptInterval(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+
+#ifdef PRE_ANT_SWITCH
+INT Set_PreAntSwitch_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PreAntSwitchRSSI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PreAntSwitchTimeout_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#endif /* PRE_ANT_SWITCH */
+
+
+#ifdef CFO_TRACK
+INT Set_CFOTrack_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef CFO_TRACK
+#ifdef CONFIG_AP_SUPPORT
+INT rtmp_cfo_track(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, INT lastClient);
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* CFO_TRACK */
+
+#endif // CFO_TRACK //
+
+#ifdef DBG_CTRL_SUPPORT
+INT Set_DebugFlags_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef INCLUDE_DEBUG_QUEUE
+INT Set_DebugQueue_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+void dbQueueEnqueue(
+ IN UCHAR type,
+ IN UCHAR *data);
+
+void dbQueueEnqueueTxFrame(
+ IN UCHAR *pTxWI,
+ IN UCHAR *pHeader_802_11);
+
+void dbQueueEnqueueRxFrame(
+ IN UCHAR *pRxWI,
+ IN UCHAR *pHeader_802_11,
+ IN ULONG flags);
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+
+INT Show_DescInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Show_MacTable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT show_devinfo_proc(RTMP_ADAPTER *pAd, 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 */
+
+
+#ifdef CONFIG_AP_SUPPORT
+INT Set_HtTxStream_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_HtRxStream_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#ifdef DOT11_N_SUPPORT
+#ifdef GREENAP_SUPPORT
+INT Set_GreenAP_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* GREENAP_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+INT Set_ForceShortGI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ForceGF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT SetCommonHT(RTMP_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);
+
+INT Set_BurstMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef DOT11_VHT_AC
+INT Set_VhtBw_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_VhtStbc_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+#endif /* DOT11_VHT_AC */
+
+
+#ifdef APCLI_SUPPORT
+INT RTMPIoctlConnStatus(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PSTRING arg);
+
+#endif /*APCLI_SUPPORT*/
+
+
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+VOID detect_wmm_traffic(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR up,
+ IN UCHAR bOutput);
+
+VOID dynamic_tune_be_tx_op(
+ IN RTMP_ADAPTER *pAd,
+ IN ULONG nonBEpackets);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef DOT11_N_SUPPORT
+VOID Handle_BSS_Width_Trigger_Events(RTMP_ADAPTER *pAd);
+
+void build_ext_channel_switch_ie(
+ IN RTMP_ADAPTER *pAd,
+ IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
+
+void assoc_ht_info_debugshow(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR ht_cap_len,
+ IN HT_CAPABILITY_IE *pHTCapability);
+#endif /* DOT11_N_SUPPORT */
+
+BOOLEAN APRxDoneInterruptHandle(RTMP_ADAPTER *pAd);
+BOOLEAN STARxDoneInterruptHandle(RTMP_ADAPTER *pAd, BOOLEAN argc);
+BOOLEAN RxDoneInterruptHandle(RTMP_ADAPTER *pAd);
+
+NTSTATUS StopDmaRx(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Level);
+NTSTATUS StopDmaTx(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Level);
+
+#ifdef DOT11_N_SUPPORT
+/* AMPDU packet indication */
+VOID Indicate_AMPDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+#ifdef HDR_TRANS_SUPPORT
+VOID Indicate_AMPDU_Packet_Hdr_Trns(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+#endif /* HDR_TRANS_SUPPORT */
+
+/* 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);
+
+#ifdef HDR_TRANS_SUPPORT
+VOID Indicate_Legacy_Packet_Hdr_Trns(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+#endif /* HDR_TRANS_SUPPORT */
+
+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 TXBF_SUPPORT
+BOOLEAN clientSupportsETxBF(RTMP_ADAPTER *pAd, HT_BF_CAP *pTxBFCap);
+void setETxBFCap(RTMP_ADAPTER *pAd, HT_BF_CAP *pTxBFCap);
+
+#ifdef ETXBF_EN_COND3_SUPPORT
+VOID txSndgSameMcs(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY * pEnt, UCHAR smoothMfb);
+VOID txSndgOtherGroup(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry);
+VOID txMrqInvTxBF(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry);
+VOID chooseBestMethod(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, UCHAR mfb);
+VOID rxBestSndg(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry);
+#endif /* ETXBF_EN_COND3_SUPPORT */
+
+VOID handleBfFb(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk);
+
+VOID TxBFInit(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN BOOLEAN supportsETxBF);
+
+VOID eTxBFProbing(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID Trigger_Sounding_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR SndgType,
+ IN UCHAR SndgBW,
+ IN UCHAR SndgMcs,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID rtmp_asic_set_bf(
+ IN RTMP_ADAPTER *pAd);
+
+BOOLEAN rtmp_chk_itxbf_calibration(
+ IN RTMP_ADAPTER *pAd);
+
+#endif /* TXBF_SUPPORT */
+
+BOOLEAN CmdRspEventCallbackHandle(PRTMP_ADAPTER pAd, PUCHAR pRspBuffer);
+
+#ifdef CONFIG_AP_SUPPORT
+/* remove LLC and get 802_3 Header */
+#define RTMP_AP_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_APCLI)) \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr1; \
+ _pSA = _pRxBlk->pHeader->Addr3; \
+ } \
+ else \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr3; \
+ _pSA = _pRxBlk->pHeader->Addr2; \
+ } \
+ \
+ CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \
+ _pRxBlk->DataSize, _pRemovedLLCSNAP); \
+}
+#endif /* CONFIG_AP_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_AP_SUPPORT
+#define AP_ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
+ Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+
+/* Normal, AMPDU or AMSDU */
+VOID CmmRxnonRalinkFrameIndicate(
+ IN RTMP_ADAPTER *pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+#ifdef HDR_TRANS_SUPPORT
+VOID CmmRxnonRalinkFrameIndicate_Hdr_Trns(
+ IN RTMP_ADAPTER *pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+#endif /* HDR_TRANS_SUPPORT */
+
+VOID CmmRxRalinkFrameIndicate(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+VOID Update_Rssi_Sample(
+ IN RTMP_ADAPTER *pAd,
+ IN RSSI_SAMPLE *pRssi,
+ IN RXWI_STRUC *pRxWI);
+
+PNDIS_PACKET GetPacketFromRxRing(
+ IN RTMP_ADAPTER *pAd,
+ OUT RX_BLK *pRxBlk,
+ OUT BOOLEAN *pbReschedule,
+ INOUT UINT32 *pRxPending);
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+ IN RTMP_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 CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+INT Set_ApCli_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_ApCli_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef MAT_SUPPORT
+
+VOID getIPv6MacTbInfo(MAT_STRUCT *, char *, ULONG);
+
+VOID getIPMacTbInfo(
+ IN MAT_STRUCT *pMatCfg,
+ IN char *pOutBuf,
+ IN ULONG BufLen);
+
+NDIS_STATUS MATEngineInit(
+ IN RTMP_ADAPTER *pAd);
+
+NDIS_STATUS MATEngineExit(
+ IN RTMP_ADAPTER *pAd);
+
+PUCHAR MATEngineRxHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPkt,
+ IN UINT infIdx);
+
+
+PUCHAR MATEngineTxHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPkt,
+ IN UINT infIdx,
+ IN UCHAR OpMode);
+
+BOOLEAN MATPktRxNeedConvert(
+ IN PRTMP_ADAPTER pAd,
+ IN PNET_DEV net_dev);
+
+#endif /* MAT_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+typedef struct CountryCodeToCountryRegion {
+ USHORT CountryNum;
+ UCHAR IsoName[3];
+ /*UCHAR CountryName[40]; */
+ PSTRING pCountryName;
+ BOOLEAN SupportABand;
+ /*ULONG RegDomainNum11A; */
+ UCHAR RegDomainNum11A;
+ BOOLEAN SupportGBand;
+ /*ULONG RegDomainNum11G; */
+ UCHAR RegDomainNum11G;
+} COUNTRY_CODE_TO_COUNTRY_REGION;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef SNMP_SUPPORT
+/*for snmp */
+typedef struct _DefaultKeyIdxValue
+{
+ UCHAR KeyIdx;
+ UCHAR Value[16];
+} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
+#endif
+
+
+
+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);
+
+void tbtt_tasklet(unsigned long data);
+
+
+
+
+
+
+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,
+ IN BOOLEAN bWriteHigh);
+
+NTSTATUS RTUSBMultiWrite_nBytes(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length,
+ IN USHORT batchLen);
+
+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,
+ IN BOOLEAN bWriteHigh);
+
+NTSTATUS RTUSBReadMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUINT32 pValue);
+
+NTSTATUS RTUSBSingleWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN USHORT Value,
+ IN BOOLEAN bWriteHigh);
+
+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 RTMP_ADAPTER *pAd);
+
+VOID MlmeSetPsm(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT psm);
+
+NDIS_STATUS RTMPWPAAddKeyProc(
+ IN RTMP_ADAPTER *pAd,
+ IN VOID *pBuf);
+
+VOID AsicRxAntEvalAction(
+ IN RTMP_ADAPTER *pAd);
+
+void append_pkt(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR *pHeader802_3,
+ IN UINT HdrLen,
+ IN UCHAR *pData,
+ IN ULONG DataSize,
+ OUT PNDIS_PACKET *ppPacket);
+
+
+VOID RTUSBMlmeHardTransmit(
+ IN RTMP_ADAPTER *pAd,
+ IN MGMT_STRUC *pMgmt);
+
+INT MlmeThread(ULONG Context);
+
+
+/*
+ Function Prototype in rtusb_data.c
+*/
+NDIS_STATUS RTUSBFreeDescRequest(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UINT32 req_cnt);
+
+
+BOOLEAN RTUSBNeedQueueBackForAgg(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId);
+
+
+/* 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);
+
+VOID RT28xxUsbAsicWOWEnable(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT28xxUsbAsicWOWDisable(
+ IN PRTMP_ADAPTER pAd);
+
+#endif /* RTMP_MAC_USB */
+
+#ifdef NEW_WOW_SUPPORT
+VOID RT28xxAndesWOWEnable(
+ IN PRTMP_ADAPTER pAd);
+VOID RT28xxAndesWOWDisable(
+ IN PRTMP_ADAPTER pAd);
+#endif /* NEW_WOW_SUPPORT */
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+VOID RT28xxAsicWOWEnable(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT28xxAsicWOWDisable(
+ IN PRTMP_ADAPTER pAd);
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+NDIS_STATUS RTMPCheckRxError(
+ IN RTMP_ADAPTER *pAd,
+ IN PHEADER_802_11 pHeader,
+ IN RXWI_STRUC *pRxWI,
+ IN RXINFO_STRUC *pRxInfo);
+
+
+/*////////////////////////////////////*/
+
+#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);
+/*//////////////////////////////////*/
+
+
+
+VOID ReSyncBeaconTime(RTMP_ADAPTER *pAd);
+VOID RTMPSetAGCInitValue(RTMP_ADAPTER *pAd, UCHAR BandWidth);
+
+#ifdef TXBF_SUPPORT
+VOID handleHtcField(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk);
+#endif /* TXBF_SUPPORT */
+
+#ifdef MFB_SUPPORT
+VOID MFB_PerPareMRQ(
+ IN PRTMP_ADAPTER pAd,
+ OUT VOID* pBuf,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID MFB_PerPareMFB(
+ IN PRTMP_ADAPTER pAd,
+ OUT VOID* pBuf,
+ IN PMAC_TABLE_ENTRY pEntry);
+#endif /* MFB_SUPPORT */
+
+#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
+ */
+
+#ifdef INF_AMAZON_SE
+VOID SoftwareFlowControl(
+ IN PRTMP_ADAPTER pAd) ;
+#endif /* INF_AMAZON_SE */
+
+
+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 RTUSBBulkCmdRspEventReceive(
+ 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 */
+
+
+INT AsicGetMacVersion(
+ IN RTMP_ADAPTER *pAd);
+
+INT WaitForAsicReady(
+ IN RTMP_ADAPTER *pAd);
+
+BOOLEAN CHAN_PropertyCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 ChanNum,
+ IN UCHAR Property);
+
+
+void getRate(
+ IN HTTRANSMIT_SETTING HTSetting,
+ OUT ULONG* fLastTxRxRate);
+
+
+#ifdef APCLI_SUPPORT
+#ifdef APCLI_WPA_SUPPLICANT_SUPPORT
+VOID ApcliSendAssocIEsToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT ifIndex);
+
+INT ApcliWpaCheckEapCode(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFrame,
+ IN USHORT FrameLen,
+ IN USHORT OffSet);
+
+VOID ApcliWpaSendEapolStart(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid,
+ IN PMAC_TABLE_ENTRY pMacEntry,
+ IN PAPCLI_STRUCT pApCliEntry);
+
+
+VOID ApCliRTMPSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull,
+ IN PMAC_TABLE_ENTRY pMacEntry);
+
+#endif/*APCLI_WPA_SUPPLICANT_SUPPORT*/
+#endif/*APCLI_SUPPORT*/
+
+
+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 RTMP_ADAPTER *pAd,
+ IN OUT RTMP_IOCTL_INPUT_STRUCT *rq,
+ IN INT cmd);
+
+INT RTMPQueryInformation(
+ IN RTMP_ADAPTER *pAd,
+ INOUT RTMP_IOCTL_INPUT_STRUCT *rq,
+ IN INT cmd);
+
+VOID RTMPIoctlShow(
+ IN RTMP_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);
+
+#ifdef CONFIG_AP_SUPPORT
+INT RTMP_AP_IoctlPrepare(
+ IN RTMP_ADAPTER *pAd,
+ IN VOID *pCB);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+INT Set_VcoPeriod_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+INT Set_RateAlg_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+
+#ifdef SINGLE_SKU
+INT Set_ModuleTxpower_Proc(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING arg);
+#endif /* SINGLE_SKU */
+
+VOID RtmpEnqueueNullFrame(
+ 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);
+
+VOID RtmpCleanupPsQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_HEADER pQueue);
+
+#ifdef CONFIG_MULTI_CHANNEL
+VOID RtmpPrepareHwNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN BOOLEAN bQosNull,
+ IN BOOLEAN bEOSP,
+ IN UCHAR OldUP,
+ IN UCHAR OpMode,
+ IN UCHAR PwrMgmt,
+ IN BOOLEAN bWaitACK,
+ IN CHAR Index);
+
+VOID RTMPHwSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull,
+ IN USHORT PwrMgmt,
+ IN CHAR Index);
+
+VOID RtmpEnqueueLastNullFrame(
+ 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,
+ IN UCHAR PwrMgmt,
+ IN UCHAR OpMode);
+
+VOID RtmpPrepareHwNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN BOOLEAN bQosNull,
+ IN BOOLEAN bEOSP,
+ IN UCHAR OldUP,
+ IN UCHAR OpMode,
+ IN UCHAR PwrMgmt,
+ IN BOOLEAN bWaitACK,
+ IN CHAR Index);
+
+VOID MCC_ChangeAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID ConcurrentP2PConnectTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+NDIS_STATUS MultiChannelThreadInit(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MultiChannelThreadExit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MultiChannelTimerStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MultiChannelTimerStart(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID MultiChannelSwitchToRa(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MultiChannelSwitchToP2P(
+ IN PRTMP_ADAPTER pAd);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+UCHAR dot11_2_ra_rate(UCHAR MaxSupportedRateIn500Kbps);
+UCHAR dot11_max_sup_rate(INT SupRateLen, UCHAR *SupRate, INT ExtRateLen, UCHAR *ExtRate);
+
+VOID set_entry_phy_cfg(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry);
+VOID MacTableReset(RTMP_ADAPTER *pAd);
+MAC_TABLE_ENTRY *MacTableLookup(RTMP_ADAPTER *pAd, UCHAR *pAddr);
+BOOLEAN MacTableDeleteEntry(RTMP_ADAPTER *pAd, USHORT wcid, UCHAR *pAddr);
+MAC_TABLE_ENTRY *MacTableInsertEntry(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR *pAddr,
+ IN UCHAR apidx,
+ IN UCHAR OpMode,
+ IN BOOLEAN CleanAll);
+
+
+
+VOID dumpTxWI(RTMP_ADAPTER *pAd, TXWI_STRUC *pTxWI);
+VOID dump_rxwi(RTMP_ADAPTER *pAd, RXWI_STRUC *pRxWI);
+VOID dump_txinfo(RTMP_ADAPTER *pAd, TXINFO_STRUC *pTxInfo);
+VOID dump_rxinfo(RTMP_ADAPTER *pAd, RXINFO_STRUC *pRxInfo);
+#if defined(RT65xx) || defined(MT7601)
+VOID dumpRxFCEInfo(RTMP_ADAPTER *pAd, RXFCE_INFO *pRxFceInfo);
+#endif /* defined(RT65xx) || defined(MT7601) */
+
+
+
+#ifdef FPGA_MODE
+INT set_tx_kickcnt(RTMP_ADAPTER *pAd, PSTRING arg);
+INT set_data_phy_mode(RTMP_ADAPTER *pAd, PSTRING arg);
+INT set_data_bw(RTMP_ADAPTER *pAd, PSTRING arg);
+INT set_data_mcs(RTMP_ADAPTER *pAd, PSTRING arg);
+INT set_data_gi(RTMP_ADAPTER *pAd, PSTRING arg);
+INT set_data_basize(RTMP_ADAPTER *pAd, PSTRING arg);
+INT set_fpga_mode(RTMP_ADAPTER *pAd, PSTRING arg);
+#endif /* FPGA_MODE */
+
+#ifdef WFA_VHT_PF
+INT set_force_amsdu(RTMP_ADAPTER *pAd, PSTRING arg);
+#endif /* WFA_VHT_PF */
+
+
+
+#ifdef RLT_RF
+INT set_rf(RTMP_ADAPTER *pAd, PSTRING arg);
+#endif /* RLT_RF */
+
+BOOLEAN CmdRspEventHandle(RTMP_ADAPTER *pAd);
+
+
+
+#endif /* __RTMP_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_M51.h b/cleopatre/devkit/mt7601udrv/include/rtmp_M51.h
new file mode 100644
index 0000000000..410005e2cc
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_M51.h
@@ -0,0 +1,53 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_M51.h
+
+ Abstract:
+ Miniport header file for mcu related information
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_M51_H__
+#define __RTMP_M51_H__
+
+struct _RTMP_ADAPTER;
+
+INT RtmpAsicEraseFirmware(
+ struct _RTMP_ADAPTER *pAd);
+
+NDIS_STATUS RtmpAsicLoadFirmware(
+ struct _RTMP_ADAPTER *pAd);
+
+NDIS_STATUS isMCUnotReady(
+ struct _RTMP_ADAPTER *pAd);
+
+NDIS_STATUS isMCUNeedToLoadFIrmware(
+ struct _RTMP_ADAPTER *pAd);
+
+INT RtmpAsicSendCommandToMcu(
+ struct _RTMP_ADAPTER *pAd,
+ UCHAR Command,
+ UCHAR Token,
+ UCHAR Arg0,
+ UCHAR Arg1,
+ BOOLEAN FlgIsNeedLocked);
+#endif
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_and.h b/cleopatre/devkit/mt7601udrv/include/rtmp_and.h
new file mode 100644
index 0000000000..396dd67938
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_and.h
@@ -0,0 +1,137 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_and.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_AND_H__
+#define __RTMP_AND_H__
+
+/*
+ * Power opration
+ */
+enum PWR_OP {
+ RADIO_OFF = 0x30,
+ RADIO_ON,
+ RADIO_OFF_AUTO_WAKEUP,
+ RADIO_OFF_ADVANCE,
+ RADIO_ON_ADVANCE,
+};
+
+
+/*
+ * Calibration ID
+ */
+enum CALIBRATION_ID {
+ R_CALIBRATION = 1,
+ DCOC_CALIBRATION,
+};
+
+/*
+ * Function set ID
+ */
+enum FUN_ID {
+ Q_SELECT = 1,
+ ATOMIC_TSSI_SETTING = 5,
+};
+
+/*
+ * Command response RX Ring selection
+ */
+enum RX_RING_ID {
+ RX_RING0,
+ RX_RING1,
+};
+
+/*
+ * Command type table
+ */
+enum CMD_TYPE {
+ CMD_FUN_SET_OP = 1,
+ CMD_BURST_WRITE = 8,
+ CMD_READ_MODIFY_WRITE,
+ CMD_RANDOM_READ,
+ CMD_BURST_READ,
+ CMD_RANDOM_WRITE = 12,
+ CMD_LED_MODE_OP = 16,
+ CMD_POWER_SAVING_OP = 20,
+ CMD_WOW_CONFIG,
+ CMD_WOW_QUERY,
+ CMD_WOW_FEATURE = 24,
+ CMD_CARRIER_DETECT_OP = 28,
+ CMD_RADOR_DETECT_OP,
+ CMD_SWITCH_CHANNEL_OP,
+ CMD_CALIBRATION_OP,
+ CMD_BEACON_OP,
+ CMD_ANTENNA_OP
+};
+
+/*
+ * Event type table
+ */
+enum EVENT_TYPE {
+ CMD_DONE,
+ CMD_ERROR,
+ CMD_RETRY,
+ EVENT_PWR_RSP,
+ EVENT_WOW_RSP,
+ EVENT_CARRIER_DETECT_RSP,
+ EVENT_DFS_DETECT_RSP,
+};
+
+#define ANDES_CALIBRATION_R 1
+#define ANDES_CALIBRATION_LC 3
+#define ANDES_CALIBRATION_LOFT 4
+#define ANDES_CALIBRATION_TXIQ 5
+#define ANDES_CALIBRATION_BW 6
+#define ANDES_CALIBRATION_DPD 7
+#define ANDES_CALIBRATION_RXIQ 8
+#define ANDES_CALIBRATION_TXDCOC 9
+
+INT AsicSendCommandToAndes(PRTMP_ADAPTER pAd, struct CMD_UNIT CmdUnit);
+NDIS_STATUS USBLoadFirmwareToAndes(RTMP_ADAPTER *pAd);
+NDIS_STATUS PCILoadFirmwareToAndes(RTMP_ADAPTER *pAd);
+INT AsicSendCmdToAndes(PRTMP_ADAPTER pAd, struct CMD_UNIT *CmdUnit);
+INT AndesBurstWrite(PRTMP_ADAPTER pAd, UINT32 Offset, UINT32 *Data, UINT32 Count);
+INT AndesBurstRead(PRTMP_ADAPTER pAd, UINT32 Offset, UINT32 Cnt, UINT32 *Data);
+INT AndesRandomRead(PRTMP_ADAPTER pAd, RTMP_REG_PAIR *RegPair, UINT32 Num);
+INT AndesRFRandomRead(PRTMP_ADAPTER pAd, BANK_RF_REG_PAIR *RegPair, UINT32 Num);
+INT AndesReadModifyWrite(PRTMP_ADAPTER pAd, R_M_W_REG *RegPair, UINT32 Num);
+INT AndesRFReadModifyWrite(PRTMP_ADAPTER pAd, RF_R_M_W_REG *RegPair, UINT32 Num);
+INT AndesRandomWritePair(PRTMP_ADAPTER pAd, RTMP_REG_PAIR *RegPair, UINT32 Num);
+INT AndesRFRandomWritePair(PRTMP_ADAPTER pAd, BANK_RF_REG_PAIR *RegPair, UINT32 Num);
+INT AndesRandomWrite(PRTMP_ADAPTER pAd, UINT32 Num, ...);
+INT AndesRFRandomWrite(PRTMP_ADAPTER pAd, UINT32 Num, ...);
+#ifdef MT7601
+INT AndesBBPRandomWritePair(PRTMP_ADAPTER pAd, RTMP_REG_PAIR *RegPair, UINT32 Num);
+INT AndesBBPRandomWrite(PRTMP_ADAPTER pAd, UINT32 Num, ...);
+#endif /* MT7601 */
+INT AndesFunSetOP(PRTMP_ADAPTER pAd, UINT32 FunID, UINT32 Param);
+INT AndesPwrSavingOP(PRTMP_ADAPTER pAd, UINT32 PwrOP, UINT32 PwrLevel,
+ UINT32 ListenInterval, UINT32 PreTBTTLeadTime,
+ UINT8 TIMByteOffset, UINT8 TIMBytePattern);
+INT AndesCalibrationOP(PRTMP_ADAPTER, UINT32 CalibrationID, UINT32 Param);
+BOOLEAN IsInBandCmdProcessing(PRTMP_ADAPTER pAd);
+UCHAR GetCmdRspNum(PRTMP_ADAPTER pAd);
+#endif
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_chip.h b/cleopatre/devkit/mt7601udrv/include/rtmp_chip.h
new file mode 100644
index 0000000000..26104131ba
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_chip.h
@@ -0,0 +1,1095 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_chip.h
+
+ Abstract:
+ Ralink Wireless Chip related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_CHIP_H__
+#define __RTMP_CHIP_H__
+
+#include "rtmp_type.h"
+
+struct _RTMP_ADAPTER;
+struct _RSSI_SAMPLE;
+
+#include "mac_ral/pbf.h"
+
+#include "eeprom.h"
+
+
+#ifdef RTMP_MAC_USB
+#include "mac_ral/rtmp_mac.h"
+#include "mac_ral/mac_usb.h"
+#endif /* RTMP_MAC_USB */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef RT3290
+#include "chip/rt3290.h"
+#endif /* RT3290 */
+
+#ifdef RT65xx
+#include "chip/rt6590.h"
+#endif /* RT65xx */
+
+#ifdef RT8592
+#include "chip/rt6590.h"
+#endif /* RT8592 */
+
+#include "rtmp_mcu.h"
+
+#ifdef MT7601
+#include "chip/mt7601.h"
+#endif /* MT7601 */
+
+#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_RT2880(_pAd) (IS_RT2860(_pAd) && IS_RBUS_INF(_pAd))
+
+#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd)||IS_RT3390(_pAd))
+
+#define IS_RT3052B(_pAd) (((_pAd)->CommonCfg.CID == 0x102) && (((_pAd)->CommonCfg.CN >> 16) == 0x3033))
+#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)
+#define IS_RT305x(_pAd) (IS_RT3050(_pAd) || IS_RT3052(_pAd) || IS_RT3350(_pAd) || IS_RT3352(_pAd) || IS_RT5350(_pAd))
+#define IS_RT3050_3052_3350(_pAd) (\
+ ((_pAd)->MACVersion == 0x28720200) && \
+ ((((_pAd)->CommonCfg.CN >> 16) == 0x3333) || (((_pAd)->CommonCfg.CN >> 16) == 0x3033)) \
+)
+
+
+/* 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 RT3593_DEVICE_ID_CHECK(__DevId) \
+ (0)
+
+#define RT3592_DEVICE_ID_CHECK(__DevId) \
+ (__DevId == NIC3592_PCIe_DEVICE_ID)
+
+#define IS_RT2883(_pAd) (0)
+
+#define IS_RT3883(_pAd) (0)
+
+#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)))
+
+#define IS_RT3290(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x32900000)
+#define IS_RT3290LE(_pAd) ((((_pAd)->MACVersion & 0xffffffff) >= 0x32900011))
+
+/* 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_RT5390H(_pAd)) /* Include RT5390, RT5370 and RT5360 */
+
+/* RT5390F */
+#define IS_RT5390F(_pAd) ((IS_RT5390(_pAd)) && (((_pAd)->MACVersion & 0x0000FFFF) >= 0x0502))
+
+/* 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)
+
+/* RT5390H */
+#define IS_RT5390H(_pAd) (((_pAd->MACVersion & 0xFFFF0000) == 0x53910000) && (((_pAd)->MACVersion & 0x0000FFFF) >= 0x1500))
+
+/* 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 */
+
+#define IS_RT5592(_pAd) (((_pAd)->MACVersion & 0xFFFF0000) == 0x55920000)
+#define REV_RT5592C 0x0221
+
+#define IS_RT65XX(_pAd) ((((_pAd)->MACVersion & 0xFFFF0000) == 0x65900000) ||\
+ (((_pAd)->MACVersion & 0xfffff000) == 0x85592000) || \
+ (((_pAd)->MACVersion & 0xfffff000) == 0x65900000) || \
+ (((_pAd)->MACVersion & 0xffff0000) == 0x76500000))
+
+#define IS_RT6570(_pAd) (((((_pAd)->MACVersion & 0xffff0000) == 0x76500000) || \
+ (((_pAd)->MACVersion & 0xffff0000) == 0x65900000)) && \
+ ((_pAd)->infType == RTMP_DEV_INF_USB))
+#define IS_RT6590(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x65900000) || \
+ (((_pAd)->MACVersion & 0xffff0000) == 0x76500000))
+#define IS_MT7650(_pAd) (((_pAd)->chipCap.ChipID && 0xffff0000) == 0x76500000)
+
+#define IS_MT76x2(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x76620000)
+#define IS_MT7662(_pAd) (((_pAd)->chipCap.ChipID && 0xffff0000) == 0x76620000)
+
+#define IS_MT76xx(_pAd) (IS_MT76x0(_pAd) || IS_MT76x2(_pAd))
+
+#define IS_RT8592(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x85590000)
+
+#define IS_RT8592(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x85590000)
+
+#define IS_MT7601(_pAd) ((((_pAd)->MACVersion & 0xFFFF0000) == 0x76010000))
+
+/* RT3592BC8 (WiFi + BT) */
+
+#define IS_USB_INF(_pAd) ((_pAd)->infType == RTMP_DEV_INF_USB)
+#define IS_PCIE_INF(_pAd) ((_pAd)->infType == RTMP_DEV_INF_PCIE)
+#define IS_PCI_INF(_pAd) (((_pAd)->infType == RTMP_DEV_INF_PCI) || IS_PCIE_INF(_pAd))
+#define IS_PCI_ONLY_INF(_pAd) ((_pAd)->infType == RTMP_DEV_INF_PCI)
+#define IS_RBUS_INF(_pAd) ((_pAd)->infType == RTMP_DEV_INF_RBUS)
+
+#define RT_REV_LT(_pAd, _chip, _rev)\
+ IS_##_chip(_pAd) && (((_pAd)->MACVersion & 0x0000FFFF) < (_rev))
+
+#define RT_REV_GTE(_pAd, _chip, _rev)\
+ IS_##_chip(_pAd) && (((_pAd)->MACVersion & 0x0000FFFF) >= (_rev))
+
+/* 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
+#if defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290)
+#define EEPROM_NIC3_OFFSET 0x42
+#endif /* defined(BT_COEXISTENCE_SUPPORT) || defined(RT3290) */
+
+#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
+
+#ifdef MT7601
+#define EEPROM_TX0_TSSI_SLOPE 0x6e
+#define EEPROM_TX0_TSSI_OFFSET_GROUP1 0x70
+#define EEPROM_TX0_TSSI_OFFSET 0x76
+#define EEPROM_G_TARGET_POWER 0xD0
+#define EEPROM_FREQ_OFFSET_COMPERSATION 0xDA
+#endif /* MT7601 */
+
+
+#define EEPROM_A_TX_PWR_OFFSET 0x78
+#define EEPROM_A_TX2_PWR_OFFSET 0xa6
+
+#define MBSSID_MODE0 0
+#define MBSSID_MODE1 1
+
+enum FREQ_CAL_INIT_MODE {
+ FREQ_CAL_INIT_MODE0,
+ FREQ_CAL_INIT_MODE1,
+ FREQ_CAL_INIT_MODE2,
+ FREQ_CAL_INIT_UNKNOW,
+};
+
+enum FREQ_CAL_MODE {
+ FREQ_CAL_MODE0,
+ FREQ_CAL_MODE1,
+ FREQ_CAL_MODE2,
+};
+
+enum RXWI_FRQ_OFFSET_FIELD {
+ RXWI_FRQ_OFFSET_FIELD0, /* SNR1 */
+ RXWI_FRQ_OFFSET_FIELD1, /* Frequency Offset */
+};
+
+
+#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
+
+/* ITxBF calibration values EEPROM locations 0x1a0 to 0x1ab */
+#define EEPROM_ITXBF_CAL 0x1a0
+
+#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
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+/* */
+/* 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
+#define EEPROM_TSSI_STEP_OVER_5DOT5G 0xDD
+#define TSSI_READ_SAMPLE_NUM 3
+
+/* */
+/* 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
+
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+
+
+#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, 3: 3T */
+ 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, 3: 3T */
+ 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
+
+
+/*
+ * 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))
+
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+/* The Tx power tuning entry */
+typedef struct _TX_POWER_TUNING_ENTRY_STRUCT {
+ CHAR RF_TX_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_TUNING_ENTRY_STRUCT, *PTX_POWER_TUNING_ENTRY_STRUCT;
+#endif /* defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION) */
+
+/*
+ 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_ {
+ UINT32 ChipID;
+ /* 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;
+
+ /* VCO calibration mode */
+ UINT8 VcoPeriod; /* default 10s */
+#define VCO_CAL_DISABLE 0 /* not support */
+#define VCO_CAL_MODE_1 1 /* toggle RF7[0] */
+#define VCO_CAL_MODE_2 2 /* toggle RF3[7] */
+#define VCO_CAL_MODE_3 3 /* toggle RF4[7] */
+ UINT8 FlgIsVcoReCalMode;
+
+ BOOLEAN FlgIsHwAntennaDiversitySup;
+ BOOLEAN FlgSwBasedPPAD;
+#ifdef STREAM_MODE_SUPPORT
+ BOOLEAN FlgHwStreamMode;
+#endif /* STREAM_MODE_SUPPORT */
+#ifdef TXBF_SUPPORT
+ BOOLEAN FlgHwTxBfCap;
+#endif /* TXBF_SUPPORT */
+#ifdef FIFO_EXT_SUPPORT
+ BOOLEAN FlgHwFifoExtCap;
+#endif /* FIFO_EXT_SUPPORT */
+
+
+ enum ASIC_CAP asic_caps;
+ enum PHY_CAP phy_caps;
+
+#ifdef TXRX_SW_ANTDIV_SUPPORT
+ BOOLEAN bTxRxSwAntDiv;
+#endif /* TXRX_SW_ANTDIV_SUPPORT */
+
+ /* ---------------------------- 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;
+
+ UINT8 MaxNss; /* maximum Nss, 3 for 3883 or 3593 */
+
+ BOOLEAN bTempCompTxALC;
+
+ BOOLEAN bLimitPowerRange; /* TSSI compensation range limit */
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+ UINT8 TxAlcTxPowerUpperBound_2G;
+ const TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable_2G;
+#ifdef A_BAND_SUPPORT
+ UINT8 TxAlcTxPowerUpperBound_5G;
+ const TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable_5G;
+#endif /* A_BAND_SUPPORT */
+
+#ifdef MT7601
+ MT7601_TX_ALC_DATA TxALCData;
+#endif /* MT7601 */
+#endif /* defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION) */
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(SINGLE_SKU_V2)
+ INT16 PAModeCCK[4];
+ INT16 PAModeOFDM[8];
+ INT16 PAModeHT[16];
+#endif /* defined(RTMP_INTERNAL_TX_ALC) || defined(SINGLE_SKU_V2) */
+
+#ifdef MT7601
+ CHAR TemperatureRef25C;
+ UCHAR TemperatureMode;
+ BOOLEAN bPllLockProtect;
+ CHAR CurrentTemperBbpR49;
+ INT32 TemperatureDPD; // temperature when do DPD calibration
+ INT32 CurrentTemperature; // (BBP_R49 - Ref25C) * offset
+#endif /* MT7601 */
+ /* ---------------------------- packet ---------------------------------- */
+ UINT8 TXWISize;
+ UINT8 RXWISize;
+
+ /* ---------------------------- others ---------------------------------- */
+#ifdef RTMP_EFUSE_SUPPORT
+ UINT16 EFUSE_USAGE_MAP_START;
+ UINT16 EFUSE_USAGE_MAP_END;
+ UINT8 EFUSE_USAGE_MAP_SIZE;
+ UCHAR *EFUSE_DEFAULT_BIN;
+ UINT16 EFUSE_DEFAULT_BIN_SIZE;
+#endif /* RTMP_EFUSE_SUPPORT */
+
+#ifdef RTMP_FLASH_SUPPORT
+ UCHAR *eebuf;
+#endif /* RTMP_FLASH_SUPPORT */
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ UCHAR carrier_func;
+#endif /* CARRIER_DETECTION_SUPPORT */
+#ifdef DFS_SUPPORT
+ UINT8 DfsEngineNum;
+#endif /* DFS_SUPPORT */
+
+ /*
+ Define the burst size of WPDMA of PCI
+ 0 : 4 DWORD (16bytes)
+ 1 : 8 DWORD (32 bytes)
+ 2 : 16 DWORD (64 bytes)
+ 3 : 32 DWORD (128 bytes)
+ */
+ UINT8 WPDMABurstSIZE;
+
+ /*
+ * 0: MBSSID_MODE0
+ * (The multiple MAC_ADDR/BSSID are distinguished by [bit2:bit0] of byte5)
+ * 1: MBSSID_MODE1
+ * (The multiple MAC_ADDR/BSSID are distinguished by [bit4:bit2] of byte0)
+ */
+ UINT8 MBSSIDMode;
+
+
+
+#ifdef RT5592EP_SUPPORT
+ UINT32 Priv; /* Flag for RT5592 EP */
+#endif /* RT5592EP_SUPPORT */
+
+#ifdef CONFIG_ANDES_SUPPORT
+ UINT32 WlanMemmapOffset;
+ UINT32 InbandPacketMaxLen;
+ UINT8 CmdRspRxRing;
+ BOOLEAN IsComboChip;
+#endif
+
+#ifdef SINGLE_SKU_V2
+ CHAR Apwrdelta;
+ CHAR Gpwrdelta;
+#endif /* SINGLE_SKU_V2 */
+
+#ifdef RTMP_USB_SUPPORT
+ UINT8 DataBulkInAddr;
+ UINT8 CommandRspBulkInAddr;
+ UINT8 WMM0ACBulkOutAddr[4];
+ UINT8 WMM1ACBulkOutAddr;
+ UINT8 CommandBulkOutAddr;
+#endif
+
+ enum MCU_TYPE MCUType;
+ UCHAR *FWImageName;
+};
+
+typedef VOID (*CHIP_SPEC_FUNC)(VOID *pAd, VOID *pData, ULONG Data);
+
+/* The chip specific function ID */
+typedef enum _CHIP_SPEC_ID
+{
+ CHIP_SPEC_RESV_FUNC
+} CHIP_SPEC_ID;
+
+#define CHIP_SPEC_ID_NUM CHIP_SPEC_RESV_FUNC
+
+
+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); */
+#ifdef CONFIG_ANDES_SUPPORT
+ int (*sendCommandToAndesMcu)(struct _RTMP_ADAPTER *pAd, UCHAR QueIdx, UCHAR cmd, UCHAR *pData, USHORT DataLen, BOOLEAN FlgIsNeedLocked);
+#endif /* CONFIG_ANDES_SUPPORT */
+
+ 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);
+
+ /* 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 (*BeaconUpdate)(struct _RTMP_ADAPTER *pAd, USHORT Offset, UINT32 Value, UINT8 Unit);
+
+ /* BBP adjust */
+ VOID (*ChipBBPAdjust)(IN struct _RTMP_ADAPTER *pAd);
+
+ /* AGC */
+ VOID (*ChipAGCInit)(struct _RTMP_ADAPTER *pAd, UCHAR bw);
+ UCHAR (*ChipAGCAdjust)(struct _RTMP_ADAPTER *pAd, CHAR Rssi, UCHAR OrigR66Value);
+
+ /* Channel */
+ VOID (*ChipSwitchChannel)(struct _RTMP_ADAPTER *pAd, UCHAR ch, BOOLEAN bScan);
+
+ /* IQ Calibration */
+ VOID (*ChipIQCalibration)(struct _RTMP_ADAPTER *pAd, UCHAR Channel);
+
+ /* TX ALC */
+ UINT32 (*TSSIRatio)(INT32 delta_power);
+ VOID (*InitDesiredTSSITable)(IN struct _RTMP_ADAPTER *pAd);
+ int (*ATETssiCalibration)(struct _RTMP_ADAPTER *pAd, PSTRING arg);
+ int (*ATETssiCalibrationExtend)(struct _RTMP_ADAPTER *pAd, PSTRING arg);
+ int (*ATEReadExternalTSSI)(struct _RTMP_ADAPTER *pAd, PSTRING arg);
+
+ VOID (*AsicTxAlcGetAutoAgcOffset)(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1);
+
+
+
+ VOID (*AsicGetTxPowerOffset)(struct _RTMP_ADAPTER *pAd, ULONG *TxPwr);
+ VOID (*AsicExtraPowerOverMAC)(struct _RTMP_ADAPTER *pAd);
+
+ /* Antenna */
+ VOID (*AsicAntennaDefaultReset)(struct _RTMP_ADAPTER *pAd, union _EEPROM_ANTENNA_STRUC *pAntenna);
+ VOID (*SetRxAnt)(struct _RTMP_ADAPTER *pAd, UCHAR Ant);
+
+ /* EEPROM */
+ VOID (*NICInitAsicFromEEPROM)(IN struct _RTMP_ADAPTER *pAd);
+
+ /* Temperature Compensation */
+ VOID (*InitTemperCompensation)(IN struct _RTMP_ADAPTER *pAd);
+ VOID (*TemperCompensation)(IN struct _RTMP_ADAPTER *pAd);
+
+ /* high power tuning */
+ VOID (*HighPowerTuning)(struct _RTMP_ADAPTER *pAd, struct _RSSI_SAMPLE *pRssi);
+
+ /* Others */
+ VOID (*NetDevNickNameInit)(IN struct _RTMP_ADAPTER *pAd);
+
+ /* The chip specific function list */
+ CHIP_SPEC_FUNC ChipSpecFunc[CHIP_SPEC_ID_NUM];
+
+ VOID (*AsicResetBbpAgent)(IN struct _RTMP_ADAPTER *pAd);
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ VOID (*ToneRadarProgram)(struct _RTMP_ADAPTER *pAd, ULONG threshold);
+#endif /* CARRIER_DETECTION_SUPPORT */
+ VOID (*CckMrcStatusCtrl)(struct _RTMP_ADAPTER *pAd);
+ VOID (*RadarGLRTCompensate)(struct _RTMP_ADAPTER *pAd);
+
+ VOID (*Calibration)(struct _RTMP_ADAPTER *pAd, UINT32 CalibrationID, UINT32 Parameter);
+
+ INT (*BurstWrite)(struct _RTMP_ADAPTER *pAd, UINT32 Offset, UINT32 *Data, UINT32 Cnt);
+
+ INT (*BurstRead)(struct _RTMP_ADAPTER *pAd, UINT32 Offset, UINT32 Cnt, UINT32 *Data);
+
+ INT (*RandomRead)(struct _RTMP_ADAPTER *pAd, RTMP_REG_PAIR *RegPair, UINT32 Num);
+
+ INT (*RFRandomRead)(struct _RTMP_ADAPTER *pAd, BANK_RF_REG_PAIR *RegPair, UINT32 Num);
+
+ INT (*ReadModifyWrite)(struct _RTMP_ADAPTER *pAd, R_M_W_REG *RegPair, UINT32 Num);
+
+ INT (*RFReadModifyWrite)(struct _RTMP_ADAPTER *pAd, RF_R_M_W_REG *RegPair, UINT32 Num);
+
+ INT (*RandomWrite)(struct _RTMP_ADAPTER *pAd, RTMP_REG_PAIR *RegPair, UINT32 Num);
+
+ INT (*RFRandomWrite)(struct _RTMP_ADAPTER *pAd, BANK_RF_REG_PAIR *RegPair, UINT32 Num);
+
+ VOID (*DisableTxRx)(struct _RTMP_ADAPTER *pAd, UCHAR Level);
+
+ VOID (*AsicRadioOn)(struct _RTMP_ADAPTER *pAd, UCHAR Stage);
+
+ VOID (*AsicRadioOff)(struct _RTMP_ADAPTER *pAd, UCHAR Stage);
+
+ INT (*PwrSavingOP)(struct _RTMP_ADAPTER *pAd, UINT32 PwrOP, UINT32 PwrLevel,
+ UINT32 ListenInterval, UINT32 PreTBTTLeadTime,
+ UINT8 TIMByteOffset, UINT8 TIMBytePattern);
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+ VOID (*AsicMeasureFalseCCA)(IN struct _RTMP_ADAPTER *pAd);
+
+ VOID (*AsicMitigateMicrowave)(IN struct _RTMP_ADAPTER *pAd);
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ VOID (*AsicWOWEnable)(
+ IN struct _RTMP_ADAPTER *pAd);
+ VOID (*AsicWOWDisable)(
+ IN struct _RTMP_ADAPTER *pAd);
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+};
+
+#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 PWR_SAVING_OP(__pAd, __PwrOP, __PwrLevel, __ListenInterval, \
+ __PreTBTTLeadTime, __TIMByteOffset, __TIMBytePattern) \
+do { \
+ if (__pAd->chipOps.PwrSavingOP != NULL) \
+ __pAd->chipOps.PwrSavingOP(__pAd, __PwrOP, __PwrLevel, \
+ __ListenInterval,__PreTBTTLeadTime, \
+ __TIMByteOffset, __TIMBytePattern); \
+} while (0)
+
+#define RTMP_CHIP_RX_SENSITIVITY_TUNING(__pAd) \
+ if (__pAd->chipOps.RxSensitivityTuning != NULL) \
+ __pAd->chipOps.RxSensitivityTuning(__pAd)
+
+#define RTMP_CHIP_ASIC_AGC_ADJUST(__pAd, __Rssi, __R66) \
+ if (__pAd->chipOps.ChipAGCAdjust != NULL) \
+ __R66 = __pAd->chipOps.ChipAGCAdjust(__pAd, __Rssi, __R66)
+
+#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_TX_POWER_OFFSET_GET(__pAd, __pCfgOfTxPwrCtrlOverMAC) \
+ if (__pAd->chipOps.AsicGetTxPowerOffset != NULL) \
+ __pAd->chipOps.AsicGetTxPowerOffset(__pAd, __pCfgOfTxPwrCtrlOverMAC)
+
+#define RTMP_CHIP_ASIC_AUTO_AGC_OFFSET_GET( \
+ __pAd, __pDeltaPwr, __pTotalDeltaPwr, __pAgcCompensate, __pDeltaPowerByBbpR1) \
+ if (__pAd->chipOps.AsicTxAlcGetAutoAgcOffset != NULL) \
+ __pAd->chipOps.AsicTxAlcGetAutoAgcOffset( \
+ __pAd, __pDeltaPwr, __pTotalDeltaPwr, __pAgcCompensate, __pDeltaPowerByBbpR1)
+
+#define RTMP_CHIP_ASIC_EXTRA_POWER_OVER_MAC(__pAd) \
+ if (__pAd->chipOps.AsicExtraPowerOverMAC != NULL) \
+ __pAd->chipOps.AsicExtraPowerOverMAC(__pAd)
+
+#define RTMP_CHIP_ASIC_GET_TSSI_RATIO(__pAd, __DeltaPwr) \
+ __pAd->chipOps.TSSIRatio(__DeltaPwr)
+
+#define RTMP_CHIP_ASIC_FREQ_CAL_STOP(__pAd) \
+ if (__pAd->chipOps.AsicFreqCalStop != NULL) \
+ __pAd->chipOps.AsicFreqCalStop(__pAd)
+
+#define RTMP_CHIP_IQ_CAL(__pAd, __pChannel) \
+ if (__pAd->chipOps.ChipIQCalibration != NULL) \
+ __pAd->chipOps.ChipIQCalibration(__pAd, __pChannel)
+
+#define RTMP_CHIP_HIGH_POWER_TUNING(__pAd, __pRssi) \
+ if (__pAd->chipOps.HighPowerTuning != NULL) \
+ __pAd->chipOps.HighPowerTuning(__pAd, __pRssi)
+
+#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_ASIC_INIT_TEMPERATURE_COMPENSATION(__pAd) \
+ if (__pAd->chipOps.InitTemperCompensation != NULL) \
+ __pAd->chipOps.InitTemperCompensation(__pAd)
+
+#define RTMP_CHIP_ASIC_TEMPERATURE_COMPENSATION(__pAd) \
+ if (__pAd->chipOps.TemperCompensation != NULL) \
+ __pAd->chipOps.TemperCompensation(__pAd)
+
+#define RTMP_CHIP_SPECIFIC(__pAd, __FuncId, __pData, __Data) \
+ if ((__FuncId >= 0) && (__FuncId < CHIP_SPEC_RESV_FUNC)) \
+ { \
+ if (__pAd->chipOps.ChipSpecFunc[__FuncId] != NULL) \
+ __pAd->chipOps.ChipSpecFunc[__FuncId](__pAd, __pData, __Data); \
+ }
+
+#define RTMP_CHIP_ASIC_RESET_BBP_AGENT(__pAd) \
+ if (__pAd->chipOps.AsicResetBbpAgent != NULL) \
+ __pAd->chipOps.AsicResetBbpAgent(__pAd)
+
+#define RTMP_CHIP_UPDATE_BEACON(__pAd, Offset, Value, Unit) \
+ if (__pAd->chipOps.BeaconUpdate != NULL) \
+ __pAd->chipOps.BeaconUpdate(__pAd, Offset, Value, Unit)
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define RTMP_CHIP_CARRIER_PROGRAM(__pAd, threshold) \
+ if(__pAd->chipOps.ToneRadarProgram != NULL) \
+ __pAd->chipOps.ToneRadarProgram(__pAd, threshold)
+#endif /* CARRIER_DETECTION_SUPPORT */
+
+#define RTMP_CHIP_CCK_MRC_STATUS_CTRL(__pAd) \
+ if(__pAd->chipOps.CckMrcStatusCtrl != NULL) \
+ __pAd->chipOps.CckMrcStatusCtrl(__pAd)
+
+#define RTMP_CHIP_RADAR_GLRT_COMPENSATE(__pAd) \
+ if(__pAd->chipOps.RadarGLRTCompensate != NULL) \
+ __pAd->chipOps.RadarGLRTCompensate(__pAd)
+
+
+#define RTMP_CHIP_CALIBRATION(__pAd, __CalibrationID, __parameter) \
+do { \
+ if(__pAd->chipOps.Calibration != NULL) \
+ __pAd->chipOps.Calibration(__pAd, __CalibrationID, __parameter); \
+} while (0)
+
+#define BURST_WRITE(_pAd, _Offset, _pData, _Cnt) \
+do { \
+ if (_pAd->chipOps.BurstWrite != NULL) \
+ _pAd->chipOps.BurstWrite(_pAd, _Offset, _pData, _Cnt);\
+} while (0)
+
+#define BURST_READ(_pAd, _Offset, _Cnt, _pData) \
+do { \
+ if (_pAd->chipOps.BurstRead != NULL) \
+ _pAd->chipOps.BurstRead(_pAd, _Offset, _Cnt, _pData); \
+} while (0)
+
+#define RANDOM_READ(_pAd, _RegPair, _Num) \
+do { \
+ if (_pAd->chipOps.RandomRead != NULL) \
+ _pAd->chipOps.RandomRead(_pAd, _RegPair, _Num); \
+} while (0)
+
+#define RF_RANDOM_READ(_pAd, _RegPair, _Num) \
+do { \
+ if (_pAd->chipOps.RFRandomRead != NULL) \
+ _pAd->chipOps.RFRandomRead(_pAd, _RegPair, _Num); \
+} while (0)
+
+#define READ_MODIFY_WRITE(_pAd, _RegPair, _Num) \
+do { \
+ if (_pAd->chipOps.ReadModifyWrite != NULL) \
+ _pAd->chipOps.ReadModifyWrite(_pAd, _RegPair, _Num); \
+} while (0)
+
+#define RF_READ_MODIFY_WRITE(_pAd, _RegPair, _Num) \
+do { \
+ if (_pAd->chipOps.RFReadModifyWrite != NULL) \
+ _pAd->chipOps.RFReadModifyWrite(_pAd, _RegPair, _Num); \
+} while (0)
+
+#define RANDOM_WRITE(_pAd, _RegPair, _Num) \
+do { \
+ if (_pAd->chipOps.RandomWrite != NULL) \
+ _pAd->chipOps.RandomWrite(_pAd, _RegPair, _Num); \
+} while (0)
+
+#define RF_RANDOM_WRITE(_pAd, _RegPair, _Num) \
+do { \
+ if (_pAd->chipOps.RFRandomWrite != NULL) \
+ _pAd->chipOps.RFRandomWrite(_pAd, _RegPair, _Num); \
+} while (0)
+
+#define DISABLE_TX_RX(_pAd, _Level) \
+do { \
+ if (_pAd->chipOps.DisableTxRx != NULL) \
+ _pAd->chipOps.DisableTxRx(_pAd, _Level); \
+} while (0)
+
+#define ASIC_RADIO_ON(_pAd, _Stage) \
+do { \
+ if (_pAd->chipOps.AsicRadioOn != NULL) \
+ _pAd->chipOps.AsicRadioOn(_pAd, _Stage); \
+} while (0)
+
+#define ASIC_RADIO_OFF(_pAd, _Stage) \
+do { \
+ if (_pAd->chipOps.AsicRadioOff != NULL) \
+ _pAd->chipOps.AsicRadioOff(_pAd, _Stage); \
+} while (0)
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+#define ASIC_MEASURE_FALSE_CCA(_pAd) \
+do { \
+ if (_pAd->chipOps.AsicMeasureFalseCCA != NULL) \
+ _pAd->chipOps.AsicMeasureFalseCCA(_pAd); \
+} while (0)
+
+#define ASIC_MITIGATE_MICROWAVE(_pAd) \
+do { \
+ if (_pAd->chipOps.AsicMitigateMicrowave != NULL) \
+ _pAd->chipOps.AsicMitigateMicrowave(_pAd); \
+} while (0)
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+#define ASIC_WOW_ENABLE(_pAd) \
+do { \
+ if (_pAd->chipOps.AsicWOWEnable != NULL) \
+ _pAd->chipOps.AsicWOWEnable(_pAd); \
+} while (0)
+
+#define ASIC_WOW_DISABLE(_pAd) \
+do { \
+ if (_pAd->chipOps.AsicWOWDisable != NULL) \
+ _pAd->chipOps.AsicWOWDisable(_pAd); \
+} while(0)
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+/* function prototype */
+VOID RtmpChipOpsHook(VOID *pCB);
+
+VOID RtmpChipBcnInit(struct _RTMP_ADAPTER *pAd);
+VOID RtmpChipBcnSpecInit(struct _RTMP_ADAPTER *pAd);
+#ifdef RLT_MAC
+VOID rlt_bcn_buf_init(struct _RTMP_ADAPTER *pAd);
+#endif /* RLT_MAC */
+
+VOID RtmpChipWriteHighMemory(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN UINT32 Value,
+ IN UINT8 Unit);
+
+VOID RtmpChipWriteMemory(
+ IN struct _RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN UINT32 Value,
+ IN UINT8 Unit);
+
+VOID RTMPReadChannelPwr(struct _RTMP_ADAPTER *pAd);
+VOID RTMPReadTxPwrPerRate(struct _RTMP_ADAPTER *pAd);
+
+
+VOID NetDevNickNameInit(IN struct _RTMP_ADAPTER *pAd);
+
+
+
+#ifdef GREENAP_SUPPORT
+VOID EnableAPMIMOPSv2(struct _RTMP_ADAPTER *pAd, BOOLEAN ReduceCorePower);
+VOID DisableAPMIMOPSv2(struct _RTMP_ADAPTER *pAd);
+VOID EnableAPMIMOPSv1(struct _RTMP_ADAPTER *pAd, BOOLEAN ReduceCorePower);
+VOID DisableAPMIMOPSv1(struct _RTMP_ADAPTER *pAd);
+#endif /* GREENAP_SUPPORT */
+
+
+/* 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;
+
+BOOLEAN AsicWaitPDMAIdle(struct _RTMP_ADAPTER *pAd, INT round, INT wait_us);
+INT AsicSetPreTbttInt(struct _RTMP_ADAPTER *pAd, BOOLEAN enable);
+INT AsicReadAggCnt(struct _RTMP_ADAPTER *pAd, ULONG *aggCnt, int cnt_len);
+
+#endif /* __RTMP_CHIP_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_cmd.h b/cleopatre/devkit/mt7601udrv/include/rtmp_cmd.h
new file mode 100644
index 0000000000..98839563c2
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_cmd.h
@@ -0,0 +1,683 @@
+#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 {
+#ifdef MAT_SUPPORT
+ SHOW_IPV4_MAT_INFO = 1,
+ SHOW_IPV6_MAT_INFO = 2,
+ SHOW_ETH_CLONE_MAC = 3,
+#endif /* MAT_SUPPORT */
+ 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,
+ SHOW_DEV_INFO = 26,
+ SHOW_STA_INFO = 27,
+};
+
+
+/* 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,
+ CMD_RTPRIV_IOCTL_MCU_SLEEP_CLEAR,
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ CMD_RTPRIV_IOCTL_MAX_IN_BIT,
+#endif /* CONFIG_APSTA_MIXED_SUPPORT */
+ CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_SET,
+ CMD_RTPRIV_IOCTL_ADAPTER_SUSPEND_CLEAR,
+ CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_OFF,
+ CMD_RTPRIV_IOCTL_ADAPTER_RT28XX_USB_ASICRADIO_ON,
+ CMD_RTPRIV_IOCTL_SANITY_CHECK,
+ CMD_RTPRIV_IOCTL_SANITY_CHECK_ON_SET_CMD,
+#ifdef EXT_BUILD_CHANNEL_LIST
+ CMD_RTPRIV_SET_PRECONFIG_VALUE,
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+
+ /* 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 */
+ /* Note: All cfg commands must be continue. */
+ CMD_RTPRIV_IOCTL_80211_START,
+ 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,
+ CMD_RTPRIV_IOCTL_80211_SURVEY_GET,
+ CMD_RTPRIV_IOCTL_80211_EXTRA_IES_SET,
+ CMD_RTPRIV_IOCTL_80211_REMAIN_ON_CHAN_SET,
+ CMD_RTPRIV_IOCTL_80211_MGMT_FRAME_REG,
+ CMD_RTPRIV_IOCTL_80211_CHANNEL_LOCK,
+ CMD_RTPRIV_IOCTL_80211_MGMT_FRAME_SEND,
+ CMD_RTPRIV_IOCTL_80211_REMAIN_ON_CHAN_DUR_TIMER_INIT,
+ CMD_RTPRIV_IOCTL_80211_CHANNEL_LIST_SET,
+ CMD_RTPRIV_IOCTL_80211_ACTION_FRAME_REG,
+ CMD_RTPRIV_IOCTL_80211_BEACON_ADD,
+ CMD_RTPRIV_IOCTL_80211_BEACON_SET,
+ CMD_RTPRIV_IOCTL_80211_BEACON_DEL,
+ CMD_RTPRIV_IOCTL_80211_AP_KEY_ADD,
+ CMD_RTPRIV_IOCTL_80211_CHANGE_BSS_PARM,
+ CMD_RTPRIV_IOCTL_80211_AP_KEY_DEL,
+ CMD_RTPRIV_IOCTL_80211_AP_PROBE_RSP,
+ CMD_RTPRIV_IOCTL_80211_PORT_SECURED,
+ CMD_RTPRIV_IOCTL_80211_AP_STA_DEL,
+ CMD_RTPRIV_IOCTL_80211_CANCEL_REMAIN_ON_CHAN_SET,
+ CMD_RTPRIV_IOCTL_80211_BITRATE_SET,
+#ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT
+ CMD_RTPRIV_IOCTL_80211_SEND_WIRELESS_EVENT,
+#endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */
+ CMD_RTPRIV_IOCTL_80211_END,
+#endif /* RT_CFG80211_SUPPORT */
+
+ CMD_RTPRIV_IOCTL_ADAPTER_CSO_SUPPORT_TEST,
+ CMD_RTPRIV_IOCTL_ADAPTER_TSO_SUPPORT_TEST,
+
+ /* can not exceed 0xa000 */
+ CMD_RTPRIV_IOCTL_80211_COM_LATEST_ONE,
+} 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;
+
+typedef struct __CMD_RTPRIV_IOCTL_80211_SURVEY {
+
+ VOID *pCfg80211;
+/* UINT64 ChannelTime; */ /* idle + busy, not support */
+ UINT64 ChannelTimeBusy;
+ UINT64 ChannelTimeExtBusy;
+} CMD_RTPRIV_IOCTL_80211_SURVEY;
+
+#endif /* RT_CFG80211_SUPPORT */
+
+/* station commands */
+
+/* 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 UINT8 BulkInEpAddr[2];
+ IN USHORT BulkInMaxPacketSize;
+ IN UINT8 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
+
+#define RT_CMD_STA_IOCTL_WPA_AUTH_COUNTERMEASURES 0xA0
+
+ IN UINT32 flags;
+ IN UINT32 value;
+} RT_CMD_STA_IOCTL_SECURITY_ADV;
+
+typedef struct __RT_CMD_STA_IOCTL_RSN_IE {
+ INOUT UINT32 length;
+ INOUT UCHAR *pRsnIe;
+} RT_CMD_STA_IOCTL_RSN_IE;
+
+typedef struct __RT_CMD_STA_IOCTL_PMA_SA {
+#define RT_CMD_STA_IOCTL_PMA_SA_FLUSH 0x01
+#define RT_CMD_STA_IOCTL_PMA_SA_REMOVE 0x02
+#define RT_CMD_STA_IOCTL_PMA_SA_ADD 0x03
+ IN UINT32 Cmd;
+ IN UCHAR *pBssid;
+ IN UCHAR *pPmkid;
+} RT_CMD_STA_IOCTL_PMA_SA;
+
+#endif /* __RTMP_CMD_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_comm.h b/cleopatre/devkit/mt7601udrv/include/rtmp_comm.h
new file mode 100644
index 0000000000..79fb12f241
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_comm.h
@@ -0,0 +1,502 @@
+/****************************************************************************
+
+ Module Name:
+ rtmp_comm.h
+
+ Abstract:
+ All common definitions and macros for UTIL/DRIVER/NETIF.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#ifndef __RT_COMM_H__
+#define __RT_COMM_H__
+
+#define VENDOR_FEATURE1_SUPPORT
+/*#define VENDOR_FEATURE3_SUPPORT */
+
+
+/*#define MONITOR_FLAG_11N_SNIFFER_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 */
+
+
+#ifdef CONFIG_AP_SUPPORT
+
+#ifndef VENDOR_FEATURE3_SUPPORT
+#define AP_QLOAD_SUPPORT
+#endif /* VENDOR_FEATURE3_SUPPORT */
+
+#endif /* CONFIG_AP_SUPPORT */
+
+
+/* ======================== Before include files ============================ */
+/*
+ 14 channels @2.4G + 12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination
+ Refer to CH_HZ_ID_MAP[] in rt_channel.c
+
+*/
+#ifdef DOT11_VHT_AC
+#define MAX_NUM_OF_CHS (54 + 5) /* 5 channels for central channel of VHT 80MHz */
+#else
+#define MAX_NUM_OF_CHS 54
+#endif /* DOT11_VHT_AC*/
+/* 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */
+#define MAX_NUM_OF_CHANNELS MAX_NUM_OF_CHS
+
+
+#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
+
+typedef enum{
+ DBG_FUNC_RA = 0x100, /* debug flag for rate adaptation */
+ DBG_FUNC_SA = 0x200, /* debug flag for smart antenna */
+}RT_DEBUG_FUNC;
+
+
+/* ======================== 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 */
+#define MODE_VHT 4
+
+#ifdef NO_CONSISTENT_MEM_SUPPORT
+/* current support RXD_SIZE = 16B and cache line = 16 or 32B */
+#define RTMP_DCACHE_FLUSH(__AddrStart, __Size) \
+ RtmpOsDCacheFlush((ULONG)(__AddrStart), (ULONG)(__Size))
+#else
+#define RTMP_DCACHE_FLUSH(__AddrStart, __Size)
+#endif /* NO_CONSISTENT_MEM_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
+
+/* associated with device interface */
+typedef struct _DEV_PRIV_INFO {
+ VOID *pPriv; /* pAd */
+ UINT32 priv_flags;
+} DEV_PRIV_INFO;
+
+
+
+
+/***********************************************************************************
+ * 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 */
+
+
+#ifdef TX_PKT_SG
+#ifndef MAX_SKB_FRAGS
+#define MAX_SKB_FRAGS (65536/(1UL << 12) + 2)
+#endif
+typedef struct _PTK_SG_T{
+ VOID *data;
+ INT len;
+}PKT_SG_T;
+#endif /* TX_PKT_SG */
+/*
+ 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 */
+#ifdef TX_PKT_SG
+ PKT_SG_T sg_list[MAX_SKB_FRAGS];
+#endif /* TX_PKT_SG */
+} 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__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_def.h b/cleopatre/devkit/mt7601udrv/include/rtmp_def.h
new file mode 100644
index 0000000000..0b254f09fa
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_def.h
@@ -0,0 +1,1948 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_def.h
+
+ Abstract:
+ Miniport related definition header
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+ John Chang 08-05-2003 add definition for 11g & other drafts
+*/
+#ifndef __RTMP_DEF_H__
+#define __RTMP_DEF_H__
+
+#include "oid.h"
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_AP_SUPPORT
+#define AP_WSC_INCLUDED
+#endif /* WSC_AP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+#define BAND_5G 1
+#define BAND_24G 2
+#define BAND_BOTH (BAND_5G | BAND_24G)
+
+
+#ifdef SNMP_SUPPORT
+/* for snmp, to get manufacturer OUI, 2008_0220 */
+#define ManufacturerOUI_LEN 3
+#define ManufacturerNAME ("Ralink Technology Company.")
+#define ResourceTypeIdName ("Ralink_ID")
+#endif
+
+#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
+
+
+#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 /* TXD_SIZE = TxD + TxInfo */
+#define RXD_SIZE 16
+
+#define RXINFO_OFFSET 12
+
+/* 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)
+
+#ifdef WLAN_SKB_RECYCLE
+#define NUM_RX_DESC 128
+#endif /* WLAN_SKB_RECYCLE */
+
+/*
+ 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 CONFIG_AP_SUPPORT
+#ifdef IGMP_SNOOP_SUPPORT
+#ifdef MEMORY_OPTIMIZATION
+#define MAX_LEN_OF_MULTICAST_FILTER_TABLE 16
+#else
+#define MAX_LEN_OF_MULTICAST_FILTER_TABLE 64
+#endif
+/* Size of hash tab must be power of 2. */
+#define MAX_LEN_OF_MULTICAST_FILTER_HASH_TABLE ((MAX_LEN_OF_MULTICAST_FILTER_TABLE) * 2)
+#define FREE_MEMBER_POOL_SIZE 64
+#endif /* IGMP_SNOOP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+#define MAX_AGG_3SS_BALIMIT 31
+
+/* RxFilter */
+#define STANORMAL 0x17f97
+#define APNORMAL 0x15f97
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+#define MAX_PRECONFIG_DESP_ENTRY_SIZE 11
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+
+/*
+ RTMP_ADAPTER flags
+*/
+#ifdef CONFIG_MULTI_CHANNEL
+#define fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET 0x00000001
+#else
+#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001
+#endif /*CONFIG_MULTI_CHANNEL*/
+#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002
+#define fRTMP_HW_ERR 0x00000004
+#define fRTMP_SG 0x00000008 /* Scatter and Gather */
+#define fRTMP_PKT_TX_ERR 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_RALINK_BURST_MODE 0x00400000
+#define fRTMP_ADAPTER_SUSPEND 0x00800000
+#define fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD 0x01000000
+#define fRTMP_ADAPTER_CMD_RADIO_OFF 0x02000000
+#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_POLL_IDLE 0x80000000
+
+enum ASIC_CAP{
+ fASIC_CAP_CSO = 0x1,
+ fASIC_CAP_TSO = 0x2,
+
+ fASIC_CAP_PMF_ENC = 0x10,
+};
+#define fRTMP_ADAPTER_WSC_PBC_PIN0 0x00000004
+#define fRTMP_ADAPTER_DISABLE_DOT_11N 0x00000008
+
+enum PHY_CAP{
+ fPHY_CAP_24G = 0x1,
+ fPHY_CAP_5G = 0x2,
+
+ fPHY_CAP_HT = 0x10,
+ fPHY_CAP_VHT = 0x20,
+
+ fPHY_CAP_TXBF = 0x100,
+};
+
+#define PHY_CAP_2G(_x) (((_x) & fPHY_CAP_24G) == fPHY_CAP_24G)
+#define PHY_CAP_5G(_x) (((_x) & fPHY_CAP_5G) == fPHY_CAP_5G)
+
+enum WIFI_MODE{
+ WMODE_INVALID = 0,
+ WMODE_A = 1 << 0,
+ WMODE_B = 1 << 1,
+ WMODE_G = 1 << 2,
+ WMODE_GN = 1 << 3,
+ WMODE_AN = 1 << 4,
+ WMODE_AC = 1 << 5,
+ WMODE_COMP = 6, /* total types of supported wireless mode, add this value once yow add new type */
+};
+
+#define WMODE_CAP_5G(_x) (((_x) & (WMODE_A | WMODE_AN | WMODE_AC)) != 0)
+#define WMODE_CAP_2G(_x) (((_x) & (WMODE_B | WMODE_G | WMODE_GN)) != 0)
+#define WMODE_CAP_N(_x) (((_x) & (WMODE_GN | WMODE_AN)) != 0)
+#define WMODE_CAP_AC(_x) (((_x) & (WMODE_AC)) != 0)
+#define WMODE_CAP(_x, _mode) (((_x) & (_mode)) != 0)
+
+#define WMODE_EQUAL(_x, _mode) ((_x) == (_mode))
+
+#define WMODE_5G_ONLY(_x) (((_x) & (WMODE_B | WMODE_G | WMODE_GN)) == 0)
+#define WMODE_2G_ONLY(_x) (((_x) & (WMODE_A | WMODE_AN | WMODE_AC)) == 0)
+#define WMODE_HT_ONLY(_x) (((_x) & (~(WMODE_GN | WMODE_AN | WMODE_AC))) == 0)
+#define WMODE_VHT_ONLY(_x) (((_x) & (~(WMODE_AC))) == 0)
+
+
+/*
+ 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 */
+#define fRTMP_PS_MCU_SLEEP 0x00800000
+
+
+#define WAKE_MCU_CMD 0x31
+#define SLEEP_MCU_CMD 0x30
+#define RFOFF_MCU_CMD 0x35
+
+#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 */
+
+#ifdef DOT11_VHT_AC
+#define fCLIENT_STATUS_SGI80_CAPABLE 0x00010000
+#define fCLIENT_STATUS_SGI160_CAPABLE 0x00020000
+#define fCLIENT_STATUS_VHT_TXSTBC_CAPABLE 0x00040000
+#define fCLIENT_STATUS_VHT_RXSTBC_CAPABLE 0x00080000
+#endif /* DOT11_VHT_AC */
+
+#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 VALID_MBSS(_pAd, _apidx) ((_apidx < MAX_MBSSID_NUM(_pAd)) && (_apidx < HW_BEACON_MAX_NUM))
+
+#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 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
+
+#define MAX_LEN_OF_CCK_RATES 4
+#define MAX_LEN_OF_OFDM_RATES 8
+#define MAX_LEN_OF_HT_RATES 24
+#ifdef DOT11_VHT_AC
+#define MAX_LEN_OF_VHT_RATES 16
+#endif /* DOT11_VHT_AC */
+#define SUPPORT_CCK_MODE 1
+#define SUPPORT_OFDM_MODE 2
+#define SUPPORT_HT_MODE 4
+#define SUPPORT_VHT_MODE 8
+
+/*============================================================ */
+/* 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 128 /* 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 */
+
+#define PS_LEVEL_NONE 0
+#define PS_LEVEL_NORMAL 1
+#define PS_LEVEL_MAX 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_INVALID_SECURITY_POLICY 46 /* Cipher suite rejected because of security policy */
+#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_TIMEOUT_INTERVAL 56 /* 802.11w */
+#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_TIME_ZONE 98 /* 802.11V */
+#define IE_INTERWORKING 107 /* 802.11u */
+#define IE_ADVERTISEMENT_PROTO 108 /* 802.11u */
+#define IE_QOS_MAP_SET 110 /* 802.11u */
+#define IE_ROAMING_CONSORTIUM 111 /* 802.11u */
+#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
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+#define APCLI_AUTH_STATE_MACHINE 19
+#define APCLI_ASSOC_STATE_MACHINE 20
+#define APCLI_SYNC_STATE_MACHINE 21
+#define APCLI_CTRL_STATE_MACHINE 22
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+#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
+#define CNTL_WAIT_SCAN_FOR_CONNECT 10
+
+
+#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
+
+
+/* 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_GAS_INITIAL_REQ 10 /* 11U */
+#define ACTION_GAS_INITIAL_RSP 11 /* 11U */
+#define ACTION_GAS_COMEBACK_REQ 12 /* 11U */
+#define ACTION_GAS_COMEBACK_RSP 13 /* 11U */
+#define ACTION_TDLS_DISCOVERY_RSP 14 /* 11z D13.0 */
+#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 /* non-compressed beamforming report */
+#define MIMO_BEACONFORM 6 /* compressed beamforming report */
+#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 MT2_MLME_FORCE_JOIN_REQ 10
+#define MT2_MLME_FORCE_SCAN_REQ 11
+#define MAX_SYNC_MSG 12
+
+#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 #
+*/
+#ifdef WSC_INCLUDED
+/*Messages for the WSC State machine */
+#define WSC_IDLE 0
+#define MAX_WSC_STATE 1
+#define WSC_FUNC_SIZE (MAX_WSC_STATE * MAX_WSC_MSG)
+
+#endif /* WSC_INCLUDED */
+
+/*
+ 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 #
+*/
+#ifdef CONFIG_MULTI_CHANNEL
+#define AP_SYNC_IDLE 0
+#ifdef AP_SCAN_SUPPORT
+#define AP_SCAN_LISTEN 1
+#define AP_SCAN_PENDING 2
+#define AP_MAX_SYNC_STATE 3
+#else
+#define AP_SCAN_PENDING 1
+#define AP_MAX_SYNC_STATE 2
+#endif
+#else
+#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
+#endif /*CONFIG_MULTI_CHANNEL*/
+
+#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 */
+
+
+/* ============================================================================= */
+
+
+/* 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
+#define FIXED_TXMODE_VHT 3
+
+/* BW */
+#define BW_20 BAND_WIDTH_20
+#define BW_40 BAND_WIDTH_40
+#define BW_80 BAND_WIDTH_80
+#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. */
+
+
+
+#define RF_BW_20 1
+#define RF_BW_40 2
+#define RF_BW_10 4
+#define RF_BW_80 8
+
+#define RF_MODE_CCK 1
+#define RF_MODE_OFDM 2
+
+#ifdef DOT11_N_SUPPORT
+#define HT_BW_20 0
+#define HT_BW_40 1
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef DOT11_VHT_AC
+#define VHT_BW_2040 0
+#define VHT_BW_80 1
+#define VHT_BW_160 2
+#define VHT_BW_8080 3
+#endif /* DOT11_VHT_AC */
+
+#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
+
+
+
+/* Rate Adaptation timing */
+#define RA_RATE 5 /* RA every fifth 100msec period */
+#define RA_INTERVAL (RA_RATE*100) /* RA Interval in msec */
+
+/* Rate Adaptation simpling interval setting */
+#define DEF_QUICK_RA_TIME_INTERVAL 100
+
+#define DEF_RA_TIME_INTRVAL 500
+
+/*definition of DRS */
+#define MAX_TX_RATE_INDEX 33 /* Maximum Tx Rate Table Index value */
+
+/* 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 CONFIG_AP_SUPPORT
+#define MAX_BARECI_SESSION 16
+#endif /* CONFIG_AP_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_PKT_OPMODE_AP(_x) ((_x)->OpMode = OPMODE_AP)
+#define SET_PKT_OPMODE_STA(_x) ((_x)->OpMode = OPMODE_STA)
+#define IS_PKT_OPMODE_AP(_x) ((_x)->OpMode == OPMODE_AP)
+#define IS_PKT_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)
+
+#ifdef ANDROID_SUPPORT
+#define INF_MAIN_DEV_NAME "wlan"
+#define INF_MBSSID_DEV_NAME "wlan"
+#else
+#define INF_MAIN_DEV_NAME "ra"
+#define INF_MBSSID_DEV_NAME "ra"
+#endif /* ANDROID_SUPPORT */
+#define INF_WDS_DEV_NAME "wds"
+#define INF_APCLI_DEV_NAME "apcli"
+#define INF_MESH_DEV_NAME "mesh"
+#define INF_P2P_DEV_NAME "p2p"
+
+/* 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 */
+
+#ifdef WSC_INCLUDED
+/* For WSC wireless event - start */
+#define IW_WSC_EVENT_FLAG_START 0x0500
+#define IW_WSC_PBC_SESSION_OVERLAP 0x0500
+#define IW_WSC_REGISTRAR_SUPPORT_PBC 0x0501
+#define IW_WSC_REGISTRAR_SUPPORT_PIN 0x0502
+#define IW_WSC_STATUS_SUCCESS 0x0503
+#define IW_WSC_STATUS_FAIL 0x0504
+#define IW_WSC_2MINS_TIMEOUT 0x0505
+#define IW_WSC_SEND_EAPOL_START 0x0506
+#define IW_WSC_SEND_WSC_START 0x0507
+#define IW_WSC_SEND_M1 0x0508
+#define IW_WSC_SEND_M2 0x0509
+#define IW_WSC_SEND_M3 0x050a
+#define IW_WSC_SEND_M4 0x050b
+#define IW_WSC_SEND_M5 0x050c
+#define IW_WSC_SEND_M6 0x050d
+#define IW_WSC_SEND_M7 0x050e
+#define IW_WSC_SEND_M8 0x050f
+#define IW_WSC_SEND_DONE 0x0510
+#define IW_WSC_SEND_ACK 0x0511
+#define IW_WSC_SEND_NACK 0x0512
+#define IW_WSC_RECEIVE_WSC_START 0x0513
+#define IW_WSC_RECEIVE_M1 0x0514
+#define IW_WSC_RECEIVE_M2 0x0515
+#define IW_WSC_RECEIVE_M3 0x0516
+#define IW_WSC_RECEIVE_M4 0x0517
+#define IW_WSC_RECEIVE_M5 0x0518
+#define IW_WSC_RECEIVE_M6 0x0519
+#define IW_WSC_RECEIVE_M7 0x051a
+#define IW_WSC_RECEIVE_M8 0x051b
+#define IW_WSC_RECEIVE_DONE 0x051c
+#define IW_WSC_RECEIVE_ACK 0x051d
+#define IW_WSC_RECEIVE_NACK 0x051e
+#define IW_WSC_MANY_CANDIDATE 0x051f
+#define IW_WSC_NEXT_CANDIDATE 0x0520
+#define IW_WSC_T1_TIMER_TIMEOUT 0x0521
+#define IW_WSC_T2_TIMER_TIMEOUT 0x0522
+#define IW_WSC_EVENT_FLAG_END 0x0522
+#define IW_WSC_EVENT_TYPE_NUM (IW_WSC_EVENT_FLAG_END - IW_WSC_EVENT_FLAG_START + 1)
+/* For WSC wireless event - end */
+#endif /* WSC_INCLUDED */
+/* End - WIRELESS EVENTS definition */
+
+
+#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
+#ifdef RT3290
+#define FROM_TX 4
+#endif /* RT3290 */
+/* -- */
+
+/* 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
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+/* definition for mitigating microwave interference */
+#define MO_FALSE_CCA_TH 50
+#define MO_MEAS_PERIOD 0 /* 0 ~ 100 ms */
+#define MO_IDLE_PERIOD 1 /* 100 ~ 1000 ms */
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+/* 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;
+
+enum IEEE80211_BAND {
+ IEEE80211_BAND_2G,
+ IEEE80211_BAND_5G,
+ IEEE80211_BAND_NUMS
+};
+
+enum {
+ RESUME_RADIO_ON,
+ SUSPEND_RADIO_OFF,
+ MLME_RADIO_ON,
+ MLME_RADIO_OFF,
+ DOT11_RADIO_ON,
+ DOT11_RADIO_OFF,
+};
+
+#ifdef CONFIG_MULTI_CHANNEL
+
+enum {
+ EDCA_AC0_DEQUEUE_DISABLE = (1 << 0),
+ EDCA_AC1_DEQUEUE_DISABLE = (1 << 1),
+ EDCA_AC2_DEQUEUE_DISABLE = (1 << 2),
+ EDCA_AC3_DEQUEUE_DISBALE = (1 << 3),
+ HCCA_DEQUEUE_DISABLE = (1 << 4)
+};
+
+enum {
+ HCCA_TO_EDCA,
+ EDCA_TO_HCCA = 0x55
+};
+
+#define MUL_CHANNEL_ENABLE 0x77
+#define HCCA_TIMEOUT 100
+#define EDCA_TIMEOUT 100
+#define MCC_ACTION 400
+
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+/* Advertismenet Protocol ID definitions */
+enum DOT11U_ADVERTISMENT_PROTOCOL_ID {
+ ACCESS_NETWORK_QUERY_PROTOCOL = 0,
+ MIH_INFORMATION_SERVICE = 1,
+ MIH_COMMAND_AND_EVENT_SERVICES_CAPBILITY_DISCOVERY = 2,
+ EMERGENCY_ALERT_SYSTEM = 3,
+ VENDOR_SPECIFIC = 221
+};
+
+#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x))
+
+#define A2Dec(_X, _p) \
+{ \
+ UCHAR *p; \
+ _X = 0; \
+ p = _p; \
+ while (((*p >= '0') && (*p <= '9'))) \
+ { \
+ if ((*p >= '0') && (*p <= '9')) \
+ _X = _X * 10 + *p - 48; \
+ p++; \
+ } \
+}
+
+#define A2Hex(_X, _p) \
+do{ \
+ char *__p; \
+ (_X) = 0; \
+ __p = (char *)(_p); \
+ while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9'))) \
+ { \
+ if ((*__p >= 'a') && (*__p <= 'f')) \
+ (_X) = (_X) * 16 + *__p - 87; \
+ else if ((*__p >= 'A') && (*__p <= 'F')) \
+ (_X) = (_X) * 16 + *__p - 55; \
+ else if ((*__p >= '0') && (*__p <= '9')) \
+ (_X) = (_X) * 16 + *__p - 48; \
+ __p++; \
+ } \
+}while(0)
+
+/* ========================================================================== */
+/*
+ The full range (1-4,095) of VLAN IDs must be supported by the 802.1Q
+ implementation.
+ VLAN ID 0 is reserved.
+*/
+
+#define RT_VLAN_8023_HEADER_COPY(__pAd, __VLAN_VID, __VLAN_Priority, \
+ __pHeader8023, __HdrLen, __pData, \
+ __FromWhichBSSID, __TPID) \
+{ \
+ VLAN_8023_Header_Copy(__VLAN_VID, __VLAN_Priority, \
+ __pHeader8023, __HdrLen, __pData, \
+ __FromWhichBSSID, __TPID); \
+}
+
+
+#define RT_VLAN_PKT_DUPLICATE(__pPacket, __pAd, __VLAN_VID, __VLAN_Priority,\
+ __pHeader8023, __HdrLen, __pData, \
+ __DataSize, __FromWhichBSSID, __TPID) \
+{ \
+ __pPacket = duplicate_pkt_with_VLAN( \
+ get_netdev_from_bssid(__pAd, __FromWhichBSSID), \
+ __VLAN_VID, \
+ __VLAN_Priority, \
+ __pHeader8023, __HdrLen, __pData, __DataSize, \
+ __FromWhichBSSID, __TPID); \
+}
+
+
+#define RT_80211_TO_8023_PACKET(__pAd, __VLAN_VID, __VLAN_Priority, \
+ __pRxBlk, __pHeader802_3, \
+ __FromWhichBSSID, __TPID) \
+{ \
+ wlan_802_11_to_802_3_packet( \
+ get_netdev_from_bssid(__pAd, __FromWhichBSSID), \
+ __pRxBlk->OpMode, \
+ __VLAN_VID, __VLAN_Priority, \
+ __pRxBlk->pRxPacket, __pRxBlk->pData, __pRxBlk->DataSize, \
+ __pHeader802_3, __FromWhichBSSID, __TPID); \
+}
+
+#define RTMP_L2_FRAME_TX_ACTION(__pAd, __ApIdx, __FrameBuf, __FrameLen) \
+ RTMPL2FrameTxAction(__pAd, get_netdev_from_bssid(__pAd, __ApIdx), \
+ announce_802_3_packet, __ApIdx, __FrameBuf, __FrameLen, __pAd->OpMode)
+
+#define RTMP_DUPLICATE_PACKET(__pAd, __pPacket, __FromWhichBSSID) \
+ DuplicatePacket(get_netdev_from_bssid(__pAd, __FromWhichBSSID), \
+ __pPacket, __FromWhichBSSID)
+
+#define RTMP_UPDATE_OS_PACKET_INFO(__pAd, __pRxBlk, __FromWhichBSSID) \
+ RtmpOsPktInit(__pRxBlk->pRxPacket, \
+ get_netdev_from_bssid(__pAd, __FromWhichBSSID), \
+ __pRxBlk->pData, __pRxBlk->DataSize);
+
+#ifdef SYSTEM_LOG_SUPPORT
+/*
+ RTMPSendWirelessEvent --> RtmpOsSendWirelessEvent --> RtmpDrvSendWirelessEvent
+*/
+#define RTMPSendWirelessEvent(__pAd, __Event_flag, __pAddr, __BssIdx, __Rssi) \
+ RtmpOsSendWirelessEvent(__pAd, __Event_flag, __pAddr, __BssIdx, __Rssi, \
+ RtmpDrvSendWirelessEvent);
+#else
+#define RTMPSendWirelessEvent(__pAd, __Event_flag, __pAddr, __BssIdx, __Rssi)
+#endif /* SYSTEM_LOG_SUPPORT */
+
+#define RTMP_OS_TASK_INIT(__pTask, __pTaskName, __pAd) \
+ RtmpOSTaskInit(__pTask, __pTaskName, __pAd, &(__pAd)->RscTaskMemList, &(__pAd)->RscSemMemList);
+
+#endif /* __RTMP_DEF_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_dot11.h b/cleopatre/devkit/mt7601udrv/include/rtmp_dot11.h
new file mode 100644
index 0000000000..a71a2ebd18
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_dot11.h
@@ -0,0 +1,98 @@
+/*
+
+*/
+
+#ifndef __DOT11_BASE_H__
+#define __DOT11_BASE_H__
+
+#include "rtmp_type.h"
+
+#ifdef DOT11_VHT_AC
+#include "dot11ac_vht.h"
+#endif /* DOT11_VHT_AC */
+
+#ifdef TXBF_SUPPORT
+/* CSI/Steering values */
+#define DOT11N_BF_FB_NONE 0
+#define DOT11N_BF_FB_CSI 1
+#define DOT11N_BF_FB_NOCOMP 2
+#define DOT11N_BF_FB_COMP 3
+#endif /* TXBF_SUPPORT */
+
+/* 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1. */
+typedef struct GNU_PACKED _HT_CONTROL{
+#ifdef RT_BIG_ENDIAN
+ UINT32 RDG:1;
+ UINT32 ACConstraint:1;
+ UINT32 rsv2:5;
+ UINT32 NDPAnnounce:1;
+ UINT32 CSISTEERING:2;
+ UINT32 rsv1:2;
+ UINT32 CalSeq:2;
+ UINT32 CalPos:2;
+ UINT32 MFBorASC:7;
+ UINT32 MFSI:3;
+ UINT32 MSI:3;
+ UINT32 MRQ:1;
+ UINT32 TRQ:1;
+ UINT32 vht:1;
+#else
+ UINT32 vht:1; /* indicate for VHT variant or HT variant */
+ 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 NDPAnnounce: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 _QOS_CONTROL{
+#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 _AC_PARAM_RECORD{
+ UINT8 aci_aifsn;
+ UINT8 ecw_max:4;
+ UINT8 ecw_min: 4;
+ UINT16 txop_limit;
+}AC_PARAM_RECORD;
+
+
+typedef struct GNU_PACKED _PSPOLL_FRAME {
+ FRAME_CONTROL FC;
+ USHORT Aid;
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR Ta[MAC_ADDR_LEN];
+} PSPOLL_FRAME, *PPSPOLL_FRAME;
+
+
+typedef struct GNU_PACKED _RTS_FRAME {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+} RTS_FRAME, *PRTS_FRAME;
+
+#endif /* __DOT11_BASE_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_iface.h b/cleopatre/devkit/mt7601udrv/include/rtmp_iface.h
new file mode 100644
index 0000000000..adf8456ade
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_iface.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt_iface.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RTMP_IFACE_H__
+#define __RTMP_IFACE_H__
+
+
+
+#ifdef RTMP_USB_SUPPORT
+#include "iface/rtmp_usb.h"
+#endif /* RTMP_USB_SUPPORT */
+
+typedef struct _INF_PCI_CONFIG_ {
+ unsigned long CSRBaseAddress; /* PCI MMIO Base Address, all access will use */
+ unsigned int irq_num;
+} INF_PCI_CONFIG;
+
+typedef struct _INF_USB_CONFIG_ {
+ unsigned char BulkInEpAddr; /* bulk-in endpoint address */
+ unsigned char BulkOutEpAddr[6]; /* bulk-out endpoint address */
+} INF_USB_CONFIG;
+
+typedef struct _INF_RBUS_CONFIG_ {
+ unsigned long csr_addr;
+ unsigned int irq;
+} INF_RBUS_CONFIG;
+
+
+typedef union _RTMP_INF_CONFIG_ {
+ struct _INF_PCI_CONFIG_ pciConfig;
+ struct _INF_USB_CONFIG_ usbConfig;
+ struct _INF_RBUS_CONFIG_ rbusConfig;
+} RTMP_INF_CONFIG;
+
+#endif /* __RTMP_IFACE_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_mcu.h b/cleopatre/devkit/mt7601udrv/include/rtmp_mcu.h
new file mode 100644
index 0000000000..f3510762f3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_mcu.h
@@ -0,0 +1,90 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_mcu.h
+
+ Abstract:
+ Miniport header file for mcu related information
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __RTMP_MCU_H__
+#define __RTMP_MCU_H__
+
+enum MCU_TYPE {
+ SWMCU,
+ M8051,
+ ANDES,
+};
+
+
+struct _RTMP_ADAPTER;
+
+typedef void (*CMD_RSP_HANDLER)(struct _RTMP_ADAPTER *pAd, UCHAR *Data);
+
+/*
+ * CMD Unit (8051, Andes, ...,and etc)
+ */
+struct CMD_UNIT {
+ union {
+ struct {
+ UCHAR Command;
+ UCHAR Token;
+ UCHAR Arg0;
+ UCHAR Arg1;
+ } MCU51;
+ struct {
+ UINT8 Type;
+ USHORT CmdPayloadLen;
+ PUCHAR CmdPayload;
+ USHORT RspPayloadLen;
+ PUCHAR RspPayload;
+ ULONG Timeout;
+ BOOLEAN NeedRsp;
+ BOOLEAN NeedWait;
+ CMD_RSP_HANDLER CmdRspHdler;
+ } ANDES;
+ } u;
+};
+
+
+struct MCU_CTRL {
+ UCHAR CmdSeq;
+ NDIS_SPIN_LOCK CmdRspEventListLock;
+ DL_LIST CmdRspEventList;
+};
+
+
+struct CMD_RSP_EVENT {
+ DL_LIST List;
+ UCHAR CmdSeq;
+ UINT32 Timeout;
+ BOOLEAN NeedWait;
+ PVOID AckDone;
+ UCHAR **RspPayload;
+ USHORT *RspPayloadLen;
+};
+
+VOID ChipOpsMCUHook(struct _RTMP_ADAPTER *pAd, enum MCU_TYPE MCUType);
+VOID MCUCtrlInit(struct _RTMP_ADAPTER *pAd);
+VOID MCUCtrlExit(struct _RTMP_ADAPTER *pAd);
+
+#endif
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_os.h b/cleopatre/devkit/mt7601udrv/include/rtmp_os.h
new file mode 100644
index 0000000000..335d3b957e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_os.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rtmp_os.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#ifndef __RTMP_OS_H__
+#define __RTMP_OS_H__
+
+/* Driver Operators */
+typedef int (*RTMP_PRINTK)(const char *ftm, ...);
+typedef int (*RTMP_SNPRINTF)(char *, ULONG, const char *ftm, ...);
+
+typedef struct _RTMP_OS_ABL_OPS {
+ int (*ra_printk)(const char *ftm, ...);
+ int (*ra_snprintf)(char *, ULONG, const char *ftm, ...);
+} RTMP_OS_ABL_OPS;
+
+extern RTMP_OS_ABL_OPS *pRaOsOps;
+
+#ifdef LINUX
+#ifndef OS_ABL_FUNC_SUPPORT
+#include "os/rt_linux.h"
+
+#else
+
+#ifdef RTMP_MODULE_OS
+/* for util/netif */
+#include "os/rt_linux.h"
+#else
+/* for core */
+#include "os/rt_drv.h"
+#endif /* RTMP_MODULE_OS */
+#endif /* OS_ABL_FUNC_SUPPORT */
+#endif /* LINUX */
+
+
+
+
+
+/*
+ This data structure mainly strip some callback function defined in
+ "struct net_device" in kernel source "include/linux/netdevice.h".
+
+ The definition of this data structure may various depends on different
+ OS. Use it carefully.
+*/
+typedef struct _RTMP_OS_NETDEV_OP_HOOK_ {
+ void *open;
+ void *stop;
+ void *xmit;
+ void *ioctl;
+ void *get_stats;
+ void *priv;
+ void *get_wstats;
+ void *iw_handler;
+ int priv_flags;
+ unsigned char devAddr[6];
+ unsigned char devName[16];
+ unsigned char needProtcted;
+} RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK;
+
+
+typedef enum _RTMP_TASK_STATUS_ {
+ RTMP_TASK_STAT_UNKNOWN = 0,
+ RTMP_TASK_STAT_INITED = 1,
+ RTMP_TASK_STAT_RUNNING = 2,
+ RTMP_TASK_STAT_STOPED = 4,
+} RTMP_TASK_STATUS;
+#define RTMP_TASK_CAN_DO_INSERT (RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING)
+
+#define RTMP_OS_TASK_NAME_LEN 16
+
+#if defined(RTMP_MODULE_OS) || !defined(OS_ABL_FUNC_SUPPORT)
+/* used in UTIL/NETIF module */
+typedef struct _RTMP_OS_TASK_ {
+ char taskName[RTMP_OS_TASK_NAME_LEN];
+ void *priv;
+ /*unsigned long taskFlags; */
+ RTMP_TASK_STATUS taskStatus;
+#ifndef KTHREAD_SUPPORT
+ RTMP_OS_SEM taskSema;
+ RTMP_OS_PID taskPID;
+ struct completion taskComplete;
+#endif
+ unsigned char task_killed;
+#ifdef KTHREAD_SUPPORT
+ struct task_struct *kthread_task;
+ wait_queue_head_t kthread_q;
+ BOOLEAN kthread_running;
+#endif
+} OS_TASK;
+#endif /* RTMP_MODULE_OS || ! OS_ABL_FUNC_SUPPORT */
+
+int RtmpOSIRQRequest(
+ IN PNET_DEV pNetDev);
+/*int RtmpOSIRQRelease(IN PNET_DEV pNetDev); */
+
+#ifndef OS_ABL_SUPPORT
+#define RTMP_MATOpsInit(__pAd)
+#define RTMP_MATPktRxNeedConvert(__pAd, __pDev) \
+ MATPktRxNeedConvert(__pAd, __pDev)
+#define RTMP_MATEngineRxHandle(__pAd, __pPkt, __InfIdx) \
+ MATEngineRxHandle(__pAd, __pPkt, __InfIdx)
+#else
+
+#define RTMP_MATOpsInit(__pAd) \
+ (__pAd)->MATPktRxNeedConvert = MATPktRxNeedConvert; \
+ (__pAd)->MATEngineRxHandle = MATEngineRxHandle;
+#define RTMP_MATPktRxNeedConvert(__pAd, __pDev) \
+ ((__pAd)->MATPktRxNeedConvert(__pAd, __pDev))
+#define RTMP_MATEngineRxHandle(__pAd, __pPkt, __InfIdx) \
+ ((__pAd)->MATEngineRxHandle(__pAd, __pPkt, __InfIdx))
+#endif /* OS_ABL_SUPPORT */
+
+#endif /* __RMTP_OS_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_osabl.h b/cleopatre/devkit/mt7601udrv/include/rtmp_osabl.h
new file mode 100644
index 0000000000..cf96daeefe
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_osabl.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+
+ Module Name:
+ OS/rtmp_osabl.h
+
+ Abstract:
+ Some structure/definitions for OS ABL function.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#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 <linux/usb.h>
+
+#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
+#ifndef CONFIG_AP_SUPPORT
+#define CONFIG_AP_SUPPORT
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* OS_ABL_OS_AP_SUPPORT */
+
+#ifdef OS_ABL_OS_STA_SUPPORT
+#define 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__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_timer.h b/cleopatre/devkit/mt7601udrv/include/rtmp_timer.h
new file mode 100644
index 0000000000..547a867eb5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_timer.h
@@ -0,0 +1,182 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2008, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_timer.h
+
+ Abstract:
+ Ralink Wireless Driver timer related data structures and delcarations
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Shiang Tu Aug-28-2008 init version
+
+*/
+
+#ifndef __RTMP_TIMER_H__
+#define __RTMP_TIMER_H__
+
+#include "rtmp_os.h"
+
+#define DECLARE_TIMER_FUNCTION(_func) \
+ void rtmp_timer_##_func(unsigned long data)
+
+#define GET_TIMER_FUNCTION(_func) \
+ (PVOID)rtmp_timer_##_func
+
+/* ----------------- Timer Related MARCO ---------------*/
+/* In some os or chipset, we have a lot of timer functions and will read/write register, */
+/* it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */
+/* submit to ctrl pipe). So we need a wrapper function to take care it. */
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+typedef VOID(
+ *RTMP_TIMER_TASK_HANDLE) (
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif /* RTMP_TIMER_TASK_SUPPORT */
+
+typedef struct _RALINK_TIMER_STRUCT {
+ RTMP_OS_TIMER TimerObj; /* Ndis Timer object */
+ BOOLEAN Valid; /* Set to True when call RTMPInitTimer */
+ BOOLEAN State; /* True if timer cancelled */
+ BOOLEAN PeriodicType; /* True if timer is periodic timer */
+ BOOLEAN Repeat; /* True if periodic timer */
+ ULONG TimerValue; /* Timer value in milliseconds */
+ ULONG cookie; /* os specific object */
+ void *pAd;
+#ifdef RTMP_TIMER_TASK_SUPPORT
+ RTMP_TIMER_TASK_HANDLE handle;
+#endif /* RTMP_TIMER_TASK_SUPPORT */
+} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
+
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+typedef struct _RTMP_TIMER_TASK_ENTRY_ {
+ RALINK_TIMER_STRUCT *pRaTimer;
+ struct _RTMP_TIMER_TASK_ENTRY_ *pNext;
+} RTMP_TIMER_TASK_ENTRY;
+
+#define TIMER_QUEUE_SIZE_MAX 128
+typedef struct _RTMP_TIMER_TASK_QUEUE_ {
+ unsigned int status;
+ unsigned char *pTimerQPoll;
+ RTMP_TIMER_TASK_ENTRY *pQPollFreeList;
+ RTMP_TIMER_TASK_ENTRY *pQHead;
+ RTMP_TIMER_TASK_ENTRY *pQTail;
+} RTMP_TIMER_TASK_QUEUE;
+
+#define BUILD_TIMER_FUNCTION(_func) \
+void rtmp_timer_##_func(unsigned long data) \
+{ \
+ PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \
+ RTMP_TIMER_TASK_ENTRY *_pQNode; \
+ RTMP_ADAPTER *_pAd; \
+ \
+ _pTimer->handle = _func; \
+ _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \
+ _pQNode = RtmpTimerQInsert(_pAd, _pTimer); \
+ if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)) \
+ RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ); \
+}
+#else /* !RTMP_TIMER_TASK_SUPPORT */
+#define BUILD_TIMER_FUNCTION(_func) \
+void rtmp_timer_##_func(unsigned long data) \
+{ \
+ PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) data; \
+ \
+ _func(NULL, (PVOID) pTimer->cookie, NULL, pTimer); \
+ if (pTimer->Repeat) \
+ RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \
+}
+#endif /* RTMP_TIMER_TASK_SUPPORT */
+
+DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
+DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
+DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
+DECLARE_TIMER_FUNCTION(EnqueueStartForPSKExec);
+
+
+#ifdef RTMP_MAC_USB
+DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
+#endif /* RTMP_MAC_USB */
+
+#ifdef CONFIG_MULTI_CHANNEL
+DECLARE_TIMER_FUNCTION(MCC_ChangeAction);
+
+DECLARE_TIMER_FUNCTION(ConcurrentP2PConnectTimeout);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+#ifdef CONFIG_AP_SUPPORT
+DECLARE_TIMER_FUNCTION(APDetectOverlappingExec);
+
+#ifdef DOT11N_DRAFT3
+DECLARE_TIMER_FUNCTION(Bss2040CoexistTimeOut);
+#endif /* DOT11N_DRAFT3 */
+
+DECLARE_TIMER_FUNCTION(GREKEYPeriodicExec);
+DECLARE_TIMER_FUNCTION(CMTimerExec);
+DECLARE_TIMER_FUNCTION(WPARetryExec);
+#ifdef AP_SCAN_SUPPORT
+DECLARE_TIMER_FUNCTION(APScanTimeout);
+#endif /* AP_SCAN_SUPPORT */
+DECLARE_TIMER_FUNCTION(APQuickResponeForRateUpExec);
+
+#ifdef IDS_SUPPORT
+DECLARE_TIMER_FUNCTION(RTMPIdsPeriodicExec);
+#endif /* IDS_SUPPORT */
+
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#ifdef TXBF_SUPPORT
+DECLARE_TIMER_FUNCTION(eTxBfProbeTimerExec);
+#endif // TXBF_SUPPORT //
+
+#ifdef WSC_INCLUDED
+DECLARE_TIMER_FUNCTION(WscEAPOLTimeOutAction);
+DECLARE_TIMER_FUNCTION(Wsc2MinsTimeOutAction);
+DECLARE_TIMER_FUNCTION(WscUPnPMsgTimeOutAction);
+DECLARE_TIMER_FUNCTION(WscM2DTimeOutAction);
+DECLARE_TIMER_FUNCTION(WscPBCTimeOutAction);
+DECLARE_TIMER_FUNCTION(WscScanTimeOutAction);
+DECLARE_TIMER_FUNCTION(WscProfileRetryTimeout);
+#ifdef WSC_LED_SUPPORT
+DECLARE_TIMER_FUNCTION(WscLEDTimer);
+DECLARE_TIMER_FUNCTION(WscSkipTurnOffLEDTimer);
+#endif /* WSC_LED_SUPPORT */
+#ifdef CONFIG_AP_SUPPORT
+DECLARE_TIMER_FUNCTION(WscUpdatePortCfgTimeout);
+#ifdef WSC_V2_SUPPORT
+DECLARE_TIMER_FUNCTION(WscSetupLockTimeout);
+#endif /* WSC_V2_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* WSC_INCLUDED */
+
+
+
+
+#ifdef RALINK_ATE
+DECLARE_TIMER_FUNCTION(ATEPeriodicExec);
+#endif /* RALINK_ATE */
+
+#endif /* __RTMP_TIMER_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtmp_type.h b/cleopatre/devkit/mt7601udrv/include/rtmp_type.h
new file mode 100644
index 0000000000..4c80ee0f9c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtmp_type.h
@@ -0,0 +1,192 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_type.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 1-2-2004
+*/
+
+#ifndef __RTMP_TYPE_H__
+#define __RTMP_TYPE_H__
+
+
+
+#ifndef GNU_PACKED
+#define GNU_PACKED __attribute__ ((packed))
+#endif /* GNU_PACKED */
+
+
+#ifdef LINUX
+/* Put platform dependent declaration here */
+/* For example, linux type definition */
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef unsigned long long UINT64;
+typedef short INT16;
+typedef int INT32;
+typedef long long INT64;
+
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+#endif /* LINUX */
+
+typedef unsigned char *PUINT8;
+typedef unsigned short *PUINT16;
+typedef unsigned int *PUINT32;
+typedef unsigned long long *PUINT64;
+typedef int *PINT32;
+typedef long long *PINT64;
+
+/* modified for fixing compile warning on Sigma 8634 platform */
+typedef char STRING;
+
+typedef signed char CHAR;
+
+typedef signed short SHORT;
+typedef signed int INT;
+typedef signed long LONG;
+typedef signed long long LONGLONG;
+
+typedef unsigned long long ULONGLONG;
+
+typedef unsigned char BOOLEAN;
+#ifdef LINUX
+typedef void VOID;
+#endif /* LINUX */
+
+typedef char *PSTRING;
+typedef VOID *PVOID;
+typedef CHAR *PCHAR;
+typedef UCHAR *PUCHAR;
+typedef USHORT *PUSHORT;
+typedef LONG *PLONG;
+typedef ULONG *PULONG;
+typedef UINT *PUINT;
+
+typedef unsigned int NDIS_MEDIA_STATE;
+
+typedef union _LARGE_INTEGER {
+ struct {
+#ifdef RT_BIG_ENDIAN
+ INT32 HighPart;
+ UINT LowPart;
+#else
+ UINT LowPart;
+ INT32 HighPart;
+#endif
+ } u;
+ INT64 QuadPart;
+} LARGE_INTEGER;
+
+
+/* Register set pair for initialzation register set definition */
+typedef struct _RTMP_REG_PAIR {
+ UINT32 Register;
+ UINT32 Value;
+} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
+
+typedef struct _REG_PAIR {
+ UCHAR Register;
+ UCHAR Value;
+} REG_PAIR, *PREG_PAIR;
+
+typedef struct _REG_PAIR_CHANNEL {
+ UCHAR Register;
+ UCHAR FirstChannel;
+ UCHAR LastChannel;
+ UCHAR Value;
+} REG_PAIR_CHANNEL, *PREG_PAIR_CHANNEL;
+
+typedef struct _REG_PAIR_BW {
+ UCHAR Register;
+ UCHAR BW;
+ UCHAR Value;
+} REG_PAIR_BW, *PREG_PAIR_BW;
+
+
+typedef struct _REG_PAIR_PHY{
+ UCHAR reg;
+ UCHAR s_ch;
+ UCHAR e_ch;
+ UCHAR phy; /* RF_MODE_XXX */
+ UCHAR bw; /* RF_BW_XX */
+ UCHAR val;
+}REG_PAIR_PHY;
+
+
+/* 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;
+
+typedef struct _BANK_RF_REG_PAIR {
+ UCHAR Bank;
+ UCHAR Register;
+ UCHAR Value;
+} BANK_RF_REG_PAIR, *PBANK_RF_REG_PAIR;
+
+typedef struct _R_M_W_REG{
+ UINT32 Register;
+ UINT32 ClearBitMask;
+ UINT32 Value;
+} R_M_W_REG, *PR_M_W_REG;
+
+typedef struct _RF_R_M_W_REG{
+ UCHAR Bank;
+ UCHAR Register;
+ UCHAR ClearBitMask;
+ UCHAR Value;
+} RF_R_M_W_REG, *PRF_R_M_W_REG;
+
+#endif /* __RTMP_TYPE_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/rtusb_io.h b/cleopatre/devkit/mt7601udrv/include/rtusb_io.h
new file mode 100644
index 0000000000..a249a8b9b3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/rtusb_io.h
@@ -0,0 +1,195 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2009, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtusb_io.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifndef __RTUSB_IO_H__
+#define __RTUSB_IO_H__
+
+#include "wpa_cmm.h"
+#include "rtmp_type.h"
+
+/* First RTUSB IO command number */
+#define CMDTHREAD_FIRST_CMD_ID 0x0D730101
+
+#define CMDTHREAD_RESET_BULK_OUT 0x0D730101
+#define CMDTHREAD_RESET_BULK_IN 0x0D730102
+#define CMDTHREAD_CHECK_GPIO 0x0D730103
+#define CMDTHREAD_SET_ASIC_WCID 0x0D730104
+#define CMDTHREAD_DEL_ASIC_WCID 0x0D730105
+#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D730106
+
+
+#ifdef CONFIG_AP_SUPPORT
+#define CMDTHREAD_AP_UPDATE_CAPABILITY_AND_ERPIE 0x0D73010B
+#define CMDTHREAD_AP_ENABLE_TX_BURST 0x0D73010C
+#define CMDTHREAD_AP_DISABLE_TX_BURST 0x0D73010D
+#define CMDTHREAD_AP_ADJUST_EXP_ACK_TIME 0x0D73010E
+#define CMDTHREAD_AP_RECOVER_EXP_ACK_TIME 0x0D73010F
+#define CMDTHREAD_CHAN_RESCAN 0x0D730110
+#endif /* CONFIG_AP_SUPPORT */
+
+#define CMDTHREAD_SET_LED_STATUS 0x0D730111 /* Set WPS LED status (LED_WPS_XXX). */
+#ifdef WSC_INCLUDED
+#ifdef WSC_LED_SUPPORT
+#define CMDTHREAD_LED_WPS_MODE10 0x0D730112
+#endif /* WSC_LED_SUPPORT */
+#endif /* WSC_INCLUDED */
+
+/* Security related */
+#define CMDTHREAD_SET_WCID_SEC_INFO 0x0D730113
+#define CMDTHREAD_SET_ASIC_WCID_IVEIV 0x0D730114
+#define CMDTHREAD_SET_ASIC_WCID_ATTR 0x0D730115
+#define CMDTHREAD_SET_ASIC_SHARED_KEY 0x0D730116
+#define CMDTHREAD_SET_ASIC_PAIRWISE_KEY 0x0D730117
+#define CMDTHREAD_REMOVE_PAIRWISE_KEY 0x0D730118
+
+#ifdef CONFIG_AP_SUPPORT
+#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D73011A
+#endif /* CONFIG_AP_SUPPORT */
+
+/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
+#define CMDTHREAD_UPDATE_PROTECT 0x0D73011B
+/* end johnli */
+
+#ifdef LINUX
+#ifdef RT_CFG80211_SUPPORT
+#define CMDTHREAD_REG_HINT 0x0D73011C
+#define CMDTHREAD_REG_HINT_11D 0x0D73011D
+#define CMDTHREAD_SCAN_END 0x0D73011E
+#define CMDTHREAD_CONNECT_RESULT_INFORM 0x0D73011F
+#endif /* RT_CFG80211_SUPPORT */
+#endif /* LINUX */
+
+
+
+
+#define CMDTHREAD_RESPONSE_EVENT_CALLBACK 0x0D730123
+
+
+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;
+
+typedef struct _RT_ASIC_PROTECT_INFO {
+ USHORT OperationMode;
+ UCHAR SetMask;
+ BOOLEAN bDisableBGProtect;
+ BOOLEAN bNonGFExist;
+} RT_ASIC_PROTECT_INFO, *PRT_ASIC_PROTECT_INFO;
+
+/******************************************************************************
+
+ 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; \
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_DEL_ASIC_WCID, \
+ &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); }
+
+/* Set MAC register value according operation mode */
+#ifdef CONFIG_AP_SUPPORT
+#define RTMP_AP_UPDATE_CAPABILITY_AND_ERPIE(pAd) \
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_AP_UPDATE_CAPABILITY_AND_ERPIE, NULL, 0);
+#endif /* CONFIG_AP_SUPPORT */
+
+/* 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)
+
+#define RTMP_UPDATE_PROTECT(_pAd, _OperationMode, _SetMask, _bDisableBGProtect, _bNonGFExist) \
+ do {\
+ RT_ASIC_PROTECT_INFO AsicProtectInfo;\
+ AsicProtectInfo.OperationMode = (_OperationMode);\
+ AsicProtectInfo.SetMask = (_SetMask);\
+ AsicProtectInfo.bDisableBGProtect = (_bDisableBGProtect);\
+ AsicProtectInfo.bNonGFExist = (_bNonGFExist);\
+ RTEnqueueInternalCmd((_pAd), CMDTHREAD_UPDATE_PROTECT, &AsicProtectInfo, sizeof(RT_ASIC_PROTECT_INFO));\
+ } while(0)
+
+#endif /* __RTUSB_IO_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/spectrum.h b/cleopatre/devkit/mt7601udrv/include/spectrum.h
new file mode 100644
index 0000000000..6a2c1bda19
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/spectrum.h
@@ -0,0 +1,215 @@
+
+#ifndef __SPECTRUM_H__
+#define __SPECTRUM_H__
+
+#include "rtmp_type.h"
+#include "spectrum_def.h"
+
+
+UINT8 GetRegulatoryMaxTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 channel);
+
+CHAR RTMP_GetTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN HTTRANSMIT_SETTING HTTxMode);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID MakeMeasurementReqFrame(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pOutBuffer,
+ OUT PULONG pFrameLen,
+ IN UINT8 TotalLen,
+ IN UINT8 Category,
+ IN UINT8 Action,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT16 NumOfRepetitions);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 ReportInfoLen,
+ IN PUINT8 pReportInfo);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UCHAR DialogToken);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin);
+
+#ifdef WDS_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Prepare Channel Switch Announcement action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+ 2. Channel switch announcement mode.
+ 2. a New selected channel.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueChSwAnn(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewCh);
+#endif /* WDS_SUPPORT */
+
+/*
+ ==========================================================================
+ Description:
+ Spectrun action frames Handler such as channel switch annoucement,
+ measurement report, measurement request actions frames.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+VOID PeerSpectrumAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+/*
+ ==========================================================================
+ Description:
+
+ Parametrs:
+
+ Return : None.
+ ==========================================================================
+ */
+INT Set_MeasureReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_TpcReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PwrConstraint(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+
+NDIS_STATUS MeasureReqTabInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MeasureReqTabExit(
+ IN PRTMP_ADAPTER pAd);
+
+PMEASURE_REQ_ENTRY MeasureReqLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken);
+
+PMEASURE_REQ_ENTRY MeasureReqInsert(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken);
+
+VOID MeasureReqDelete(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken);
+
+VOID InsertChannelRepIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PSTRING pCountry,
+ IN UINT8 RegulatoryClass);
+
+VOID InsertTpcReportIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin);
+
+VOID InsertDialogToken(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 DialogToken);
+
+NDIS_STATUS TpcReqTabInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID TpcReqTabExit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NotifyChSwAnnToPeerAPs(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRA,
+ IN PUCHAR pTA,
+ IN UINT8 ChSwMode,
+ IN UINT8 Channel);
+
+VOID RguClass_BuildBcnChList(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf,
+ OUT PULONG pBufLen);
+#endif /* __SPECTRUM_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/spectrum_def.h b/cleopatre/devkit/mt7601udrv/include/spectrum_def.h
new file mode 100644
index 0000000000..316956c132
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/spectrum_def.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ spectrum_def.h
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Fonchi Wu 2008 created for 802.11h
+ */
+
+#ifndef __SPECTRUM_DEF_H__
+#define __SPECTRUM_DEF_H__
+
+
+#define MAX_MEASURE_REQ_TAB_SIZE 32
+/* Size of hash tab must be power of 2. */
+#define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE
+
+#define MAX_TPC_REQ_TAB_SIZE 32
+/* Size of hash tab must be power of 2. */
+#define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE
+
+#define MIN_RCV_PWR 100 /* Negative value ((dBm) */
+
+#define TPC_REQ_AGE_OUT 500 /* ms */
+#define MQ_REQ_AGE_OUT 500 /* ms */
+
+#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) & (MAX_HASH_TPC_REQ_TAB_SIZE - 1))
+#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) & (MAX_MEASURE_REQ_TAB_SIZE - 1))
+
+typedef struct _MEASURE_REQ_ENTRY
+{
+ struct _MEASURE_REQ_ENTRY *pNext;
+ ULONG lastTime;
+ BOOLEAN Valid;
+ UINT8 DialogToken;
+ UINT8 MeasureDialogToken[3]; /* 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure. */
+} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
+
+typedef struct _MEASURE_REQ_TAB
+{
+ UCHAR Size;
+ PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
+ MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
+} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
+
+typedef struct _TPC_REQ_ENTRY
+{
+ struct _TPC_REQ_ENTRY *pNext;
+ ULONG lastTime;
+ BOOLEAN Valid;
+ UINT8 DialogToken;
+} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
+
+typedef struct _TPC_REQ_TAB
+{
+ UCHAR Size;
+ PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
+ TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
+} TPC_REQ_TAB, *PTPC_REQ_TAB;
+
+
+/* The regulatory information */
+typedef struct _DOT11_CHANNEL_SET
+{
+ UCHAR NumberOfChannels;
+ UINT8 MaxTxPwr;
+ UCHAR ChannelList[16];
+} DOT11_CHANNEL_SET, *PDOT11_CHANNEL_SET;
+
+typedef struct _DOT11_REGULATORY_INFORMATION
+{
+ UCHAR RegulatoryClass;
+ DOT11_CHANNEL_SET ChannelSet;
+} DOT11_REGULATORY_INFORMATION, *PDOT11_REGULATORY_INFORMATION;
+
+
+
+#define RM_TPC_REQ 0
+#define RM_MEASURE_REQ 1
+
+#define RM_BASIC 0
+#define RM_CCA 1
+#define RM_RPI_HISTOGRAM 2
+#define RM_CH_LOAD 3
+#define RM_NOISE_HISTOGRAM 4
+
+
+typedef struct GNU_PACKED _TPC_REPORT_INFO
+{
+ UINT8 TxPwr;
+ UINT8 LinkMargin;
+} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
+
+typedef struct GNU_PACKED _CH_SW_ANN_INFO
+{
+ UINT8 ChSwMode;
+ UINT8 Channel;
+ UINT8 ChSwCnt;
+} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
+
+typedef union GNU_PACKED _MEASURE_REQ_MODE
+{
+#ifdef RT_BIG_ENDIAN
+ struct GNU_PACKED
+ {
+
+ UINT8 :3;
+ UINT8 DurationMandatory:1;
+ UINT8 Report:1;
+ UINT8 Request:1;
+ UINT8 Enable:1;
+ UINT8 Parallel:1;
+ } field;
+#else
+ struct GNU_PACKED
+ {
+ UINT8 Parallel:1;
+ UINT8 Enable:1;
+ UINT8 Request:1;
+ UINT8 Report:1;
+ UINT8 DurationMandatory:1;
+ UINT8 :3;
+ } field;
+#endif /* RT_BIG_ENDIAN */
+ UINT8 word;
+} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
+
+typedef struct GNU_PACKED _MEASURE_REQ
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+} MEASURE_REQ, *PMEASURE_REQ;
+
+typedef struct GNU_PACKED _MEASURE_REQ_INFO
+{
+ UINT8 Token;
+ MEASURE_REQ_MODE ReqMode;
+ UINT8 ReqType;
+ UINT8 Oct[0];
+} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
+
+typedef union GNU_PACKED _MEASURE_BASIC_REPORT_MAP
+{
+#ifdef RT_BIG_ENDIAN
+ struct GNU_PACKED
+ {
+ UINT8 Rev:3;
+
+ UINT8 Unmeasure:1;
+ UINT8 Radar:1;
+ UINT8 UnidentifiedSignal:1;
+ UINT8 OfdmPreamble:1;
+ UINT8 BSS:1;
+ } field;
+#else
+ struct GNU_PACKED
+ {
+ UINT8 BSS:1;
+
+ UINT8 OfdmPreamble:1;
+ UINT8 UnidentifiedSignal:1;
+ UINT8 Radar:1;
+ UINT8 Unmeasure:1;
+ UINT8 Rev:3;
+ } field;
+#endif /* RT_BIG_ENDIAN */
+ UINT8 word;
+} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
+
+typedef struct GNU_PACKED _MEASURE_BASIC_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ MEASURE_BASIC_REPORT_MAP Map;
+} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
+
+typedef struct GNU_PACKED _MEASURE_CCA_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ UINT8 CCA_Busy_Fraction;
+} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
+
+typedef struct GNU_PACKED _MEASURE_RPI_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ UINT8 RPI_Density[8];
+} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
+
+typedef union GNU_PACKED _MEASURE_REPORT_MODE
+{
+ struct GNU_PACKED
+ {
+#ifdef RT_BIG_ENDIAN
+ UINT8 Rev:5;
+ UINT8 Refused:1;
+ UINT8 Incapable:1;
+ UINT8 Late:1;
+#else
+ UINT8 Late:1;
+ UINT8 Incapable:1;
+ UINT8 Refused:1;
+ UINT8 Rev:5;
+#endif /* RT_BIG_ENDIAN */
+ } field;
+ UINT8 word;
+} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
+
+typedef struct GNU_PACKED _MEASURE_REPORT_INFO
+{
+ UINT8 Token;
+ UINT8 ReportMode;
+ UINT8 ReportType;
+ UINT8 Octect[0];
+} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
+
+typedef struct GNU_PACKED _QUIET_INFO
+{
+ UINT8 QuietCnt;
+ UINT8 QuietPeriod;
+ UINT16 QuietDuration;
+ UINT16 QuietOffset;
+} QUIET_INFO, *PQUIET_INFO;
+
+#endif /* __SPECTRUM_DEF_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/sta_cfg.h b/cleopatre/devkit/mt7601udrv/include/sta_cfg.h
new file mode 100644
index 0000000000..5537384353
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/sta_cfg.h
@@ -0,0 +1,72 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2009, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ sta_cfg.h
+
+ Abstract:
+
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+
+*/
+
+#ifndef __STA_CFG_H__
+#define __STA_CFG_H__
+
+INT RTMPSTAPrivIoctlSet(
+ IN RTMP_ADAPTER *pAd,
+ IN PSTRING SetProcName,
+ IN PSTRING ProcArg);
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+/* set WOW enable */
+INT Set_WOW_Enable(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+/* set GPIO pin for wake-up signal */
+INT Set_WOW_GPIO(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+/* set delay time for WOW really enable */
+INT Set_WOW_Delay(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+/* set wake up hold time */
+INT Set_WOW_Hold(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+/* set wakeup signal type */
+INT Set_WOW_InBand(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+#ifdef RTMP_MAC_USB
+/* Sets the FW into WOW Suspend mode */
+INT Set_UsbWOWSuspend(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+/* Resume the FW to Normal mode */
+INT Set_UsbWOWResume(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* RTMP_MAC_USB */
+
+#endif /* __STA_CFG_H__ */
diff --git a/cleopatre/devkit/mt7601udrv/include/uapsd.h b/cleopatre/devkit/mt7601udrv/include/uapsd.h
new file mode 100644
index 0000000000..3c7fbb975a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/uapsd.h
@@ -0,0 +1,725 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related WMM UAPSD definitions & function prototype.
+
+***************************************************************************/
+
+
+/* only for UAPSD_TIMING_RECORD */
+
+
+#define UAPSD_TIMING_RECORD_MAX 1000
+#define UAPSD_TIMING_RECORD_DISPLAY_TIMES 10
+
+#define UAPSD_QUEUE_TIMEOUT 5 /* unit: seconds */
+
+#define UAPSD_TIMING_RECORD_ISR 1
+#define UAPSD_TIMING_RECORD_TASKLET 2
+#define UAPSD_TIMING_RECORD_TRG_RCV 3
+#define UAPSD_TIMING_RECORD_MOVE2TX 4
+#define UAPSD_TIMING_RECORD_TX2AIR 5
+
+#define UAPSD_TIMING_CTRL_STOP 0
+#define UAPSD_TIMING_CTRL_START 1
+#define UAPSD_TIMING_CTRL_SUSPEND 2
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+#define UAPSD_TIMING_RECORD_START() \
+ UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_START);
+#define UAPSD_TIMING_RECORD_STOP() \
+ UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_STOP);
+#define UAPSD_TIMING_RECORD(__pAd, __Type) \
+ UAPSD_TimingRecord(__pAd, __Type);
+#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex) \
+ UAPSD_TimeingRecordLoopIndex(__LoopIndex);
+#else
+
+#define UAPSD_TIMING_RECORD_START()
+#define UAPSD_TIMING_RECORD_STOP()
+#define UAPSD_TIMING_RECORD(__pAd, __type)
+#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex)
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+
+
+/* timing */
+#define UAPSD_TIMESTAMP_GET(__pAd, __TimeStamp) \
+ { \
+ UINT32 __CSR=0; UINT64 __Value64; \
+ RTMP_IO_READ32((__pAd), TSF_TIMER_DW0, &__CSR); \
+ __TimeStamp = (UINT64)__CSR; \
+ RTMP_IO_READ32((__pAd), TSF_TIMER_DW1, &__CSR); \
+ __Value64 = (UINT64)__CSR; \
+ __TimeStamp |= (__Value64 << 32); \
+ }
+
+
+#define UAPSD_TIME_GET(__pAd, __Time) \
+ { \
+ NdisGetSystemUpTime(&__Time); \
+ }
+
+/* uapsd packet */
+#ifdef VENDOR_FEATURE3_SUPPORT
+#define UAPSD_INSERT_QUEUE_AC UAPSD_InsertTailQueueAc
+#else
+#define UAPSD_INSERT_QUEUE_AC InsertTailQueueAc
+#endif /* VENDOR_FEATURE3_SUPPORT */
+
+/* uapsd initialization */
+#define UAPSD_INFO_INIT(__pInfo) \
+{ \
+ (__pInfo)->bAPSDCapable = FALSE; \
+}
+
+#define UAPSD_SP_START(__pAd, __pEntry) \
+ __pEntry->bAPSDFlagSPStart = 1;
+
+/* for AP, we maybe sleep until all SPs are closed */
+#define UAPSD_SP_END(__pAd, __pEntry) \
+ __pEntry->bAPSDFlagSPStart = 0;
+
+
+
+/* recover the peer power save mode virtually */
+#define RTMP_PS_VIRTUAL_SLEEP(__pMacEntry) \
+{ \
+ __pMacEntry->FlgPsModeIsWakeForAWhile = FALSE; \
+ __pMacEntry->VirtualTimeout = 0; \
+ DBGPRINT(RT_DEBUG_TRACE, \
+ ("%02x:%02x:%02x:%02x:%02x:%02x can sleep (ps mode = %d)!\n", \
+ __pMacEntry->Addr[0], __pMacEntry->Addr[1], __pMacEntry->Addr[2], \
+ __pMacEntry->Addr[3], __pMacEntry->Addr[4], __pMacEntry->Addr[5], \
+ __pMacEntry->PsMode)); \
+}
+
+/* check if the peer virtual ps mode timeout */
+#define RTMP_PS_VIRTUAL_TIMEOUT_HANDLE(__pMacEntry) \
+{ \
+ if (__pMacEntry->VirtualTimeout > 0) \
+ { \
+ __pMacEntry->VirtualTimeout --; \
+ if (__pMacEntry->VirtualTimeout == 0) \
+ { \
+ DBGPRINT(RT_DEBUG_TRACE, \
+ ("tdls uapsd> virtual ps timeout!\n")); \
+ RTMP_PS_VIRTUAL_SLEEP(__pMacEntry); \
+ } \
+ } \
+}
+
+/* extern MACRO & function */
+#ifndef MODULE_WMM_UAPSD
+
+#define UAPSD_EXTERN extern
+
+/* Public Marco list */
+
+/*
+ Init some parameters in packet structure for QoS Null frame;
+ purpose: is for management frame tx done use
+*/
+#define UAPSD_MR_QOS_NULL_HANDLE(__pAd, __pData, __pPacket) \
+ { \
+ PHEADER_802_11 __pHeader = (PHEADER_802_11)(__pData); \
+ MAC_TABLE_ENTRY *__pEntry; \
+ if (__pHeader->FC.SubType == SUBTYPE_QOS_NULL) \
+ { \
+ RTMP_SET_PACKET_QOS_NULL((__pPacket)); \
+ __pEntry = MacTableLookup((__pAd), __pHeader->Addr1); \
+ if (__pEntry != NULL) \
+ { \
+ RTMP_SET_PACKET_WCID((__pPacket), __pEntry->Aid); \
+ } \
+ } \
+ else \
+ { \
+ RTMP_SET_PACKET_NON_QOS_NULL((__pPacket)); \
+ } \
+ }
+
+/*
+ Init MAC entry UAPSD parameters;
+ purpose: initialize UAPSD PS queue and control parameters
+*/
+#define UAPSD_MR_ENTRY_INIT(__pEntry) \
+ { \
+ UINT16 __IdAc; \
+ for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \
+ InitializeQueueHeader(&(__pEntry)->UAPSDQueue[__IdAc]); \
+ (__pEntry)->UAPSDTxNum = 0; \
+ (__pEntry)->pUAPSDEOSPFrame = NULL; \
+ (__pEntry)->bAPSDFlagSPStart = 0; \
+ (__pEntry)->bAPSDFlagEOSPOK = 0; \
+ (__pEntry)->MaxSPLength = 0; \
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> MaxSPLength = 0!\n")); \
+ }
+
+/*
+ Reset MAC entry UAPSD parameters;
+ purpose: clean all UAPSD PS queue; release the EOSP frame if exists;
+ reset control parameters
+*/
+#define UAPSD_MR_ENTRY_RESET(__pAd, __pEntry) \
+ { \
+ MAC_TABLE_ENTRY *__pSta; \
+ UINT32 __IdAc; \
+ __pSta = (__pEntry); \
+ /* clear all U-APSD queues */ \
+ for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \
+ RtmpCleanupPsQueue((__pAd), &__pSta->UAPSDQueue[__IdAc]); \
+ /* clear EOSP frame */ \
+ __pSta->UAPSDTxNum = 0; \
+ if (__pSta->pUAPSDEOSPFrame != NULL) { \
+ RELEASE_NDIS_PACKET((__pAd), \
+ QUEUE_ENTRY_TO_PACKET(__pSta->pUAPSDEOSPFrame), \
+ NDIS_STATUS_FAILURE); \
+ __pSta->pUAPSDEOSPFrame = NULL; } \
+ __pSta->bAPSDFlagSPStart = 0; \
+ __pSta->bAPSDFlagEOSPOK = 0; \
+ UAPSD_SP_END(__pAd, __pSta); \
+ DBGPRINT(RT_DEBUG_TRACE, ("uapsd> clear UAPSD queues!\n")); }
+
+/*
+ * we can not use bMoreData bit to get EOSP bit because
+ * maybe bMoreData = 1 & EOSP = 1 when Max SP Length != 0
+ */
+#define UAPSD_MR_EOSP_SET(__pQosCtrl, __pTxBlk) \
+ if (CLIENT_STATUS_TEST_FLAG((__pTxBlk)->pMacEntry, \
+ fCLIENT_STATUS_APSD_CAPABLE)) { \
+ if (TX_BLK_TEST_FLAG((__pTxBlk), fTX_bWMM_UAPSD_EOSP)) \
+ *(__pQosCtrl) |= (1 << 4); \
+ }
+
+/*
+ Enable or disable UAPSD flag in WMM element in beacon frame;
+ purpose: set UAPSD enable/disable bit
+*/
+#define UAPSD_MR_IE_FILL(__QosCtrlField, __pUapsdInfo) \
+ (__QosCtrlField) |= ((__pUapsdInfo)->bAPSDCapable) ? 0x80 : 0x00;
+
+/*
+ Check if we do NOT need to control TIM bit for the station;
+ note: we control TIM bit only when all AC are UAPSD AC
+*/
+#define UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(__pMacEntry, __QueIdx) \
+ (CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
+ (!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VO] || \
+ !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VI] || \
+ !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BE] || \
+ !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BK]) && \
+ (__pMacEntry)->bAPSDDeliverEnabledPerAC[__QueIdx])
+
+/* check if the AC is UAPSD delivery-enabled AC */
+#define UAPSD_MR_IS_UAPSD_AC(__pMacEntry, __AcId) \
+ (CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
+ ((0 <= (__AcId)) && ((__AcId) < WMM_NUM_OF_AC)) && /* 0 ~ 3 */ \
+ (__pMacEntry)->bAPSDDeliverEnabledPerAC[(__AcId)])
+
+/* check if all AC are UAPSD delivery-enabled AC */
+#define UAPSD_MR_IS_ALL_AC_UAPSD(__FlgIsActive, __pMacEntry) \
+ (((__FlgIsActive) == FALSE) && ((__pMacEntry)->bAPSDAllAC == 1))
+
+/* suspend SP */
+#define UAPSD_MR_SP_SUSPEND(__pAd) \
+ (__pAd)->bAPSDFlagSPSuspend = 1;
+
+/* resume SP */
+#define UAPSD_MR_SP_RESUME(__pAd) \
+ (__pAd)->bAPSDFlagSPSuspend = 0;
+
+/* mark PS poll frame sent in mix mode */
+
+#ifdef RTMP_MAC_USB
+#define UAPSD_MR_MIX_PS_POLL_RCV(__pAd, __pMacEntry)
+#endif /* RTMP_MAC_USB */
+
+#else
+
+#define UAPSD_EXTERN
+#define UAPSD_QOS_NULL_QUE_ID 0x7f
+
+
+#define UAPSD_EPT_SP_INT (100000/(1000000/OS_HZ)) /* 100ms */
+
+#endif /* MODULE_WMM_UAPSD */
+
+
+/* max UAPSD buffer queue size */
+#define MAX_PACKETS_IN_UAPSD_QUEUE 16 /* for each AC = 16*4 = 64 */
+
+
+/* Public function list */
+/*
+========================================================================
+Routine Description:
+ UAPSD Module Init.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_Init(
+ IN PRTMP_ADAPTER pAd);
+
+
+/*
+========================================================================
+Routine Description:
+ UAPSD Module Release.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_Release(
+ IN PRTMP_ADAPTER pAd);
+
+
+/*
+========================================================================
+Routine Description:
+ Check if ASIC can enter sleep mode. Not software sleep.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID RtmpAsicSleepHandle(
+ IN PRTMP_ADAPTER pAd);
+
+/*
+========================================================================
+Routine Description:
+ Close current Service Period.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry Close the SP of the entry
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_Close(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+/*
+========================================================================
+Routine Description:
+ Check if the SP for entry is closed.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry the peer entry
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN BOOLEAN UAPSD_SP_IsClosed(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+/*
+========================================================================
+Routine Description:
+ Deliver all queued packets.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+
+Return Value:
+ None
+
+Note:
+ SMP protection by caller for packet enqueue.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_AllPacketDeliver(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+
+/*
+========================================================================
+Routine Description:
+ Parse the UAPSD field in WMM element in (re)association request frame.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+ *pElm QoS information field
+ FlgApsdCapable TRUE: Support UAPSD
+
+Return Value:
+ None
+
+Note:
+ No protection is needed.
+
+ 1. Association -> TSPEC:
+ use static UAPSD settings in Association
+ update UAPSD settings in TSPEC
+
+ 2. Association -> TSPEC(11r) -> Reassociation:
+ update UAPSD settings in TSPEC
+ backup static UAPSD settings in Reassociation
+
+ 3. Association -> Reassociation:
+ update UAPSD settings in TSPEC
+ backup static UAPSD settings in Reassociation
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_AssocParse(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR *pElm,
+ IN BOOLEAN FlgApsdCapable);
+
+
+/*
+========================================================================
+Routine Description:
+ Enqueue a UAPSD packet.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+ pPacket UAPSD dnlink packet
+ IdAc UAPSD AC ID (0 ~ 3)
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_PacketEnqueue(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PNDIS_PACKET pPacket,
+ IN UINT32 IdAc);
+
+
+/*
+========================================================================
+Routine Description:
+ Handle QoS Null Frame Tx Done or Management Tx Done interrupt.
+
+Arguments:
+ pAd Pointer to our adapter
+ pPacket Completed TX packet
+ pDstMac Destinated MAC address
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_QoSNullTxMgmtTxDoneHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR *pDstMac);
+
+
+/*
+========================================================================
+Routine Description:
+ Maintenance our UAPSD PS queue. Release all queued packet if timeout.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry STATION
+
+Return Value:
+ None
+
+Note:
+ If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance()
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_QueueMaintenance(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+
+/*
+========================================================================
+Routine Description:
+ Close SP in Tx Done, not Tx DMA Done.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry destination entry
+ FlgSuccess 0:tx success, 1:tx fail
+
+Return Value:
+ None
+
+Note:
+ For RT28xx series, for packetID=0 or multicast frame, no statistics
+ count can be got, ex: ARP response or DHCP packets, we will use
+ low rate to set (CCK, MCS=0=packetID).
+ So SP will not be close until UAPSD_EPT_SP_INT timeout.
+
+ So if the tx rate is 1Mbps for a entry, we will use DMA done, not
+ use UAPSD_SP_AUE_Handle().
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_AUE_Handle(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR FlgSuccess);
+
+
+/*
+========================================================================
+Routine Description:
+ Close current Service Period.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ None
+
+Note:
+ When we receive EOSP frame tx done interrupt and a uplink packet
+ from the station simultaneously, we will regard it as a new trigger
+ frame because the packet is received when EOSP frame tx done interrupt.
+
+ We can not sure the uplink packet is sent after old SP or in the old SP.
+ So we must close the old SP in receive done ISR to avoid the problem.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_CloseInRVDone(
+ IN PRTMP_ADAPTER pAd);
+
+
+/*
+========================================================================
+Routine Description:
+ Check if we need to close current SP.
+
+Arguments:
+ pAd Pointer to our adapter
+ pPacket Completed TX packet
+ pDstMac Destinated MAC address
+
+Return Value:
+ None
+
+Note:
+ 1. We need to call the function in TxDone ISR.
+ 2. SMP protection by caller for packet enqueue.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_PacketCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR *pDstMac);
+
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+/*
+========================================================================
+Routine Description:
+ Enable/Disable Timing Record Function.
+
+Arguments:
+ pAd Pointer to our adapter
+ Flag 1 (Enable) or 0 (Disable)
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TimingRecordCtrl(
+ IN UINT32 Flag);
+
+/*
+========================================================================
+Routine Description:
+ Record some timings.
+
+Arguments:
+ pAd Pointer to our adapter
+ Type The timing is for what type
+
+Return Value:
+ None
+
+Note:
+ UAPSD_TIMING_RECORD_ISR
+ UAPSD_TIMING_RECORD_TASKLET
+ UAPSD_TIMING_RECORD_TRG_RCV
+ UAPSD_TIMING_RECORD_MOVE2TX
+ UAPSD_TIMING_RECORD_TX2AIR
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TimingRecord(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 Type);
+
+/*
+========================================================================
+Routine Description:
+ Record the loop index for received packet handle.
+
+Arguments:
+ pAd Pointer to our adapter
+ LoopIndex The RxProcessed in APRxDoneInterruptHandle()
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TimeingRecordLoopIndex(
+ IN UINT32 LoopIndex);
+#endif /* UAPSD_TIMING_RECORD_FUNC */
+
+
+/*
+========================================================================
+Routine Description:
+ Get the queue status for delivery-enabled AC.
+
+Arguments:
+ pAd Pointer to our adapter
+ pEntry the peer entry
+ pFlgIsAnyPktForBK TRUE: At lease a BK packet is queued
+ pFlgIsAnyPktForBE TRUE: At lease a BE packet is queued
+ pFlgIsAnyPktForVI TRUE: At lease a VI packet is queued
+ pFlgIsAnyPktForVO TRUE: At lease a VO packet is queued
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID UAPSD_QueueStatusGet(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ OUT BOOLEAN *pFlgIsAnyPktForBK,
+ OUT BOOLEAN *pFlgIsAnyPktForBE,
+ OUT BOOLEAN *pFlgIsAnyPktForVI,
+ OUT BOOLEAN *pFlgIsAnyPktForVO);
+
+
+/*
+========================================================================
+Routine Description:
+ Handle UAPSD Trigger Frame.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pEntry the source STATION
+ UpOfFrame the UP of the trigger frame
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TriggerFrameHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR UpOfFrame);
+
+
+#ifdef RTMP_MAC_USB
+/*
+========================================================================
+Routine Description:
+ Tag current offset of the AC in USB URB tx buffer.
+
+Arguments:
+ pAd Pointer to our adapter
+ *pPkt the tx packet
+ Wcid destination entry id
+ PktOffset USB tx buffer offset
+
+Return Value:
+ None
+
+Note:
+ Only for RT2870.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TagFrame(
+ IN RTMP_ADAPTER *pAd,
+ IN NDIS_PACKET *pPkt,
+ IN UCHAR Wcid,
+ IN UINT32 PktOffset);
+
+
+/*
+========================================================================
+Routine Description:
+ Check if UAPSD packets are tx ok.
+
+Arguments:
+ pAd Pointer to our adapter
+ AcQueId TX completion for the AC (0 ~ 3)
+ bulkStartPos
+ bulkEnPos
+
+Return Value:
+ None
+
+Note:
+ Only for RT2870.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_UnTagFrame(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR AcQueId,
+ IN UINT32 bulkStartPos,
+ IN UINT32 bulkEnPos);
+#endif /* RTMP_MAC_USB */
+
+/* End of ap_uapsd.h */
diff --git a/cleopatre/devkit/mt7601udrv/include/vht.h b/cleopatre/devkit/mt7601udrv/include/vht.h
new file mode 100644
index 0000000000..3725ea086a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/vht.h
@@ -0,0 +1,28 @@
+/*
+
+*/
+
+#include "dot11ac_vht.h"
+
+
+struct _RTMP_ADAPTER;
+struct _RT_PHY_INFO;
+
+
+VOID dump_vht_cap(struct _RTMP_ADAPTER *pAd, VHT_CAP_IE *vht_ie);
+VOID dump_vht_op(struct _RTMP_ADAPTER *pAd, VHT_OP_IE *vht_ie);
+
+INT build_vht_ies(struct _RTMP_ADAPTER *pAd, UCHAR *buf, UCHAR frm);
+INT build_vht_cap_ie(RTMP_ADAPTER *pAd, UCHAR *buf);
+
+UCHAR vht_cent_ch_freq(struct _RTMP_ADAPTER *pAd, UCHAR prim_ch);
+INT vht_mode_adjust(struct _RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, VHT_CAP_IE *cap, VHT_OP_IE *op);
+INT SetCommonVHT(struct _RTMP_ADAPTER *pAd);
+VOID rtmp_set_vht(struct _RTMP_ADAPTER *pAd, struct _RT_PHY_INFO *phy_info);
+
+void assoc_vht_info_debugshow(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN VHT_CAP_IE *vht_cap,
+ IN VHT_OP_IE *vht_op);
+
diff --git a/cleopatre/devkit/mt7601udrv/include/video.h b/cleopatre/devkit/mt7601udrv/include/video.h
new file mode 100644
index 0000000000..54ec5e6901
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/video.h
@@ -0,0 +1,12 @@
+#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 */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/vr_ikans.h b/cleopatre/devkit/mt7601udrv/include/vr_ikans.h
new file mode 100644
index 0000000000..c5694cb858
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/vr_ikans.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ vr_ikans.h
+
+ Abstract:
+ Only for IKANOS Vx160 or Vx180 platform.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sample Lin 01-28-2008 Created
+
+ */
+
+#ifndef __VR_IKANS_H__
+#define __VR_IKANS_H__
+
+#ifndef MODULE_IKANOS
+#define IKANOS_EXTERN extern
+#else
+#define IKANOS_EXTERN
+#endif /* MODULE_IKANOS */
+
+#ifdef IKANOS_VX_1X0
+ typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
+
+ struct IKANOS_TX_INFO
+ {
+ struct net_device *netdev;
+ IkanosWlanTxCbFuncP *fp;
+ };
+#endif /* IKANOS_VX_1X0 */
+
+
+IKANOS_EXTERN void VR_IKANOS_FP_Init(UINT8 BssNum, UINT8 *pApMac);
+
+IKANOS_EXTERN INT32 IKANOS_DataFramesTx(struct sk_buff *pSkb,
+ struct net_device *pNetDev);
+
+IKANOS_EXTERN void IKANOS_DataFrameRx(PRTMP_ADAPTER pAd,
+ struct sk_buff *pSkb);
+
+#endif /* __VR_IKANS_H__ */
+
+/* End of vr_ikans.h */
diff --git a/cleopatre/devkit/mt7601udrv/include/vrut_ubm.h b/cleopatre/devkit/mt7601udrv/include/vrut_ubm.h
new file mode 100644
index 0000000000..fab13c4ea6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/vrut_ubm.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All Related Structure & Definition for UBICOM platform.
+
+ Only used in UTIL module.
+
+***************************************************************************/
+
+#ifndef __VR_UBICOM_H__
+#define __VR_UBICOM_H__
+
+#ifdef PLATFORM_UBM_IPX8
+
+#include <asm/cachectl.h>
+
+#undef RTMP_UTIL_DCACHE_FLUSH
+#define RTMP_UTIL_DCACHE_FLUSH(__AddrStart, __Size) \
+ flush_dcache_range((ULONG)(__AddrStart), \
+ (ULONG)(((UCHAR *)(__AddrStart)) + __Size - 1))
+
+#endif /* PLATFORM_UBM_IPX8 */
+
+#endif /* __VR_UBICOM_H__ */
+
+/* End of vrut_ubm.h */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/wapi.h b/cleopatre/devkit/mt7601udrv/include/wapi.h
new file mode 100644
index 0000000000..4a98cac493
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wapi.h
@@ -0,0 +1,183 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2005, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attempt
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wapi.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Albert 2008-4-3 Supoort WAPI protocol
+*/
+
+#ifndef __WAPI_H__
+#define __WAPI_H__
+
+#include "wpa_cmm.h"
+
+/* Increase TxIV value for next transmission */
+/* Todo - When overflow occurred, do re-key mechanism */
+#define INC_TX_IV(_V, NUM) \
+{ \
+ UCHAR cnt = LEN_WAPI_TSC; \
+ do \
+ { \
+ cnt--; \
+ _V[cnt] = _V[cnt] + NUM; \
+ if (cnt == 0) \
+ { \
+ DBGPRINT(RT_DEBUG_TRACE, ("PN overflow!!!!\n")); \
+ break; \
+ } \
+ }while (_V[cnt] == 0); \
+}
+
+#define IS_WAPI_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWAICERT) && ((a) <= Ndis802_11AuthModeWAIPSK))
+
+/* The underlying chip supports hardware-based WPI-SMS4 encryption and de-encryption. */
+#define IS_HW_WAPI_SUPPORT(__pAd) (__pAd->chipCap.FlgIsHwWapiSup)
+/*
+ =====================================
+ function prototype in wapi_crypt.c
+ =====================================
+*/
+int wpi_cbc_mac_engine(
+ unsigned char * maciv_in,
+ unsigned char * in_data1,
+ unsigned int in_data1_len,
+ unsigned char * in_data2,
+ unsigned int in_data2_len,
+ unsigned char * pkey,
+ unsigned char * mac_out);
+
+int wpi_sms4_ofb_engine(
+ unsigned char * pofbiv_in,
+ unsigned char * pbw_in,
+ unsigned int plbw_in,
+ unsigned char * pkey,
+ unsigned char * pcw_out);
+
+VOID RTMPInsertWapiIe(
+ IN UINT AuthMode,
+ IN UINT WepStatus,
+ OUT PUCHAR pWIe,
+ OUT UCHAR *w_len);
+
+BOOLEAN RTMPCheckWAIframe(
+ IN PUCHAR pData,
+ IN ULONG DataByteCount);
+
+VOID RTMPConstructWPIIVHdr(
+ IN UCHAR key_id,
+ IN UCHAR *tx_iv,
+ OUT UCHAR *iv_hdr);
+
+extern INT RTMPSoftEncryptSMS4(
+ IN PUCHAR pHeader,
+ IN PUCHAR pData,
+ IN UINT32 data_len,
+ IN UCHAR key_id,
+ IN PUCHAR pKey,
+ IN PUCHAR pIv);
+extern INT RTMPSoftDecryptSMS4(
+ IN PUCHAR pHdr,
+ IN BOOLEAN bSanityIV,
+ IN PCIPHER_KEY pKey,
+ INOUT PUCHAR pData,
+ INOUT UINT16 *DataByteCnt);
+
+VOID RTMPDeriveWapiGTK(
+ IN PUCHAR nmk,
+ OUT PUCHAR gtk_ptr);
+
+VOID RT_SMS4_TEST(
+ IN UINT8 test);
+
+INT SMS4_TEST(void);
+
+/*
+ =====================================
+ function prototype in wapi.c
+ =====================================
+*/
+
+BOOLEAN RTMPIsWapiCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx);
+
+VOID RTMPIoctlQueryWapiConf(
+ IN PRTMP_ADAPTER pAd,
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq);
+
+void rtmp_read_wapi_parms_from_file(
+ IN PRTMP_ADAPTER pAd,
+ char *tmpbuf,
+ char *buffer);
+
+VOID RTMPWapiUskRekeyPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID RTMPWapiMskRekeyPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID RTMPInitWapiRekeyTimerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID RTMPStartWapiRekeyTimerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID RTMPCancelWapiRekeyTimerAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID RTMPGetWapiTxTscFromAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT Wcid,
+ OUT UCHAR *tx_tsc);
+
+VOID WAPIInstallPairwiseKey(
+ PRTMP_ADAPTER pAd,
+ PMAC_TABLE_ENTRY pEntry,
+ BOOLEAN bAE);
+
+VOID WAPIInstallSharedKey(
+ PRTMP_ADAPTER pAd,
+ UINT8 GroupCipher,
+ UINT8 BssIdx,
+ UINT8 KeyIdx,
+ UINT8 Wcid,
+ PUINT8 pGtk);
+
+BOOLEAN WAPI_InternalCmdAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AuthMode,
+ IN UCHAR apidx,
+ IN PUCHAR pAddr,
+ IN UCHAR flag);
+
+#endif /* __WAPI_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/wapi_def.h b/cleopatre/devkit/mt7601udrv/include/wapi_def.h
new file mode 100644
index 0000000000..774bdae1ca
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wapi_def.h
@@ -0,0 +1,179 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2005, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attempt
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wapi_def.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#ifndef __WAPI_DEF_H__
+#define __WAPI_DEF_H__
+
+#ifndef IN
+#define IN
+#endif
+#ifndef OUT
+#define OUT
+#endif
+#ifndef INOUT
+#define INOUT
+#endif
+#ifndef MAC_ADDR_LEN
+#define MAC_ADDR_LEN 6
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define WAPI_IFNAMSIZ 16
+#define MAX_WAPI_MBSSID_NUM 8
+#define MAX_ID_NO 10
+
+#define LENGTH_WAI_H 12
+#define LEN_WAPI_TSC 16
+#define LEN_WPI_MIC 16
+#define LEN_WPI_IV_HDR 18
+#define LEN_WAPI_NMK 16
+#define LEN_WAPI_GTK 32
+
+/* trigger message from driver */
+#define WAI_MLME_CERT_AUTH_START 1
+#define WAI_MLME_KEY_HS_START 2
+#define WAI_MLME_UPDATE_BK 3
+#define WAI_MLME_UPDATE_USK 4
+#define WAI_MLME_UPDATE_MSK 5
+#define WAI_MLME_DISCONNECT 0xff
+
+#define WAPI_KEY_UPDATE_EXEC_INTV 1000 /* 1 sec */
+
+/* WAPI rekey method */
+#define REKEY_METHOD_DISABLE 0
+#define REKEY_METHOD_TIME 1
+#define REKEY_METHOD_PKT 2
+/*#define REKEY_METHOD_TIME_PKT 3 */
+
+#define STATUS_WAPI_KEY_INVALID 1
+#define STATUS_WAPI_IV_MISMATCH 2
+#define STATUS_WAPI_MIC_DIFF 3
+
+extern UCHAR AE_BCAST_PN[LEN_WAPI_TSC];
+extern UCHAR ASUE_UCAST_PN[LEN_WAPI_TSC];
+extern UCHAR AE_UCAST_PN[LEN_WAPI_TSC];
+
+/* WAPI authentication mode */
+typedef enum _WAPI_AUTH_MODE
+{
+ WAPI_AUTH_DISABLE,
+ WAPI_AUTH_PSK,
+ WAPI_AUTH_CERT,
+} WAPI_AUTH_MODE, *PWAPI_AUTH_MODE;
+
+/* WAPI authentication mode */
+typedef enum _KEY_TYPE_MODE
+{
+ HEX_MODE,
+ ASCII_MODE
+} KEY_TYPE_MODE, *PKEY_TYPE_MODE;
+
+/* the defintion of WAI header */
+typedef struct GNU_PACKED _HEADER_WAI {
+ USHORT version;
+ UCHAR type;
+ UCHAR sub_type;
+ USHORT reserved;
+ USHORT length;
+ USHORT pkt_seq;
+ UCHAR frag_seq;
+ UCHAR flag;
+} HEADER_WAI, *PHEADER_WAI;
+
+/* For WAPI */
+typedef struct GNU_PACKED _WAPIIE {
+ USHORT version;
+ USHORT acount;
+ struct GNU_PACKED {
+ UCHAR oui[4];
+ }auth[1];
+} WAPIIE, *PWAPIIE;
+
+/* unicast key suite */
+typedef struct GNU_PACKED _WAPIIE_UCAST {
+ USHORT ucount;
+ struct GNU_PACKED {
+ UCHAR oui[4];
+ }ucast[1];
+} WAPIIE_UCAST,*PWAPIIE_UCAST;
+
+/* multi-cast key suite and capability */
+typedef struct GNU_PACKED _WAPIIE_MCAST {
+ UCHAR mcast[4];
+ USHORT capability;
+} WAPIIE_MCAST,*PWAPIIE_MCAST;
+
+/* the relative to wapi daemon */
+typedef struct GNU_PACKED _COMMON_WAPI_INFO
+{
+ UINT8 wapi_ifname[WAPI_IFNAMSIZ]; /* wai negotiation */
+ UINT8 wapi_ifname_len;
+ UINT8 preauth_ifname[WAPI_IFNAMSIZ]; /* pre-authentication */
+ UINT8 preauth_ifname_len;
+ UINT8 as_cert_no;
+ UINT8 as_cert_path[MAX_ID_NO][128]; /* the path of as certification */
+ UINT8 as_cert_path_len[MAX_ID_NO];
+ UINT8 ca_cert_path[128]; /* the path of ca certification */
+ UINT8 ca_cert_path_len;
+ UINT8 user_cert_path[128]; /* the path of local user certification */
+ UINT8 user_cert_path_len;
+ UINT32 wapi_as_ip; /* the ip address of authentication server */
+ UINT32 wapi_as_port; /* the port of authentication server */
+} COMMON_WAPI_INFO, *PCOMMON_WAPI_INFO;
+
+typedef struct GNU_PACKED _MBSS_WAPI_INFO
+{
+ UINT8 ifname[WAPI_IFNAMSIZ];
+ UINT8 ifname_len;
+ UINT8 auth_mode;
+ UINT8 psk[64];
+ UINT8 psk_len;
+ UINT8 wie[128];
+ UINT8 wie_len;
+} MBSS_WAPI_INFO, *PMBSS_WAPI_INFO;
+
+/* It's used by wapi daemon to require relative configuration */
+typedef struct GNU_PACKED _WAPI_CONF
+{
+ UINT8 mbss_num; /* indicate multiple BSS number */
+ COMMON_WAPI_INFO comm_wapi_info;
+ MBSS_WAPI_INFO mbss_wapi_info[MAX_WAPI_MBSSID_NUM];
+} WAPI_CONF, *PWAPI_CONF;
+
+#ifdef LINUX
+#define WapiMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
+#define WapiZeroMemory(Destination, Length) memset(Destination, 0, Length)
+#define WapiEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
+#endif /* LINUX */
+
+#endif /* __WAPI_DEF_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/wapi_sms4.h b/cleopatre/devkit/mt7601udrv/include/wapi_sms4.h
new file mode 100644
index 0000000000..ef90f2a465
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wapi_sms4.h
@@ -0,0 +1,12 @@
+
+
+/* SMS4 encryption/decryption definition */
+/* Parameter : */
+/* Input - the incoming message packet */
+/* Ouput - the result ouput */
+/* rk - key */
+void SMS4Crypt(unsigned char *Input, unsigned char *Output, unsigned int *rk);
+
+/* SMS4 key extend algorithm */
+void SMS4KeyExt(unsigned char *Key, unsigned int *rk, unsigned int CryptFlag);
+
diff --git a/cleopatre/devkit/mt7601udrv/include/wfd.h b/cleopatre/devkit/mt7601udrv/include/wfd.h
new file mode 100644
index 0000000000..beb88fa47f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wfd.h
@@ -0,0 +1,149 @@
+/*
+
+ This file is provided under a dual BSD/GPLv2 license. When using or
+ redistributing this file, you may do so under either license.
+
+ GPL LICENSE SUMMARY
+
+ Copyright(c) 2005-2011 Ralink Technology Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ The full GNU General Public License is included in this distribution
+ in the file called LICENSE.GPL.
+
+ Contact Information:
+ Ralink Technology Corporation
+ 5F, No.5, Tai-Yuen 1st St., Jhubei City,
+ HsinChu Hsien 30265, Taiwan, R.O.C.
+
+
+ BSD LICENSE
+
+ Copyright(c) 2005-2011 Ralink Technology Corporation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+/*
+ Module Name:
+ wfd.h
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+
+*/
+
+
+#ifndef __WFD_H__
+#define __WFD_H__
+
+#ifdef WFD_SUPPORT
+
+#include "rtmp_type.h"
+
+INT Set_WfdEnable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+#ifdef RT_CFG80211_SUPPORT
+INT Set_WfdInsertIe_Proc
+(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+#endif /* RT_CFG80211_SUPPORT */
+
+INT Set_WfdDeviceType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WfdCouple_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WfdSessionAvailable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WfdCP_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WfdRtspPort_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WfdMaxThroughput_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_WfdLocalIp_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+INT Set_PeerRtspPort_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg);
+
+VOID WfdMakeWfdIE(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG WfdIeBitmap,
+ OUT PUCHAR pOutBuf,
+ OUT PULONG pIeLen);
+
+ULONG InsertWfdSubelmtTlv(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR SubId,
+ IN PUCHAR pInBuffer,
+ IN PUCHAR pOutBuffer,
+ IN UINT Action);
+
+VOID WfdParseSubElmt(
+ IN PRTMP_ADAPTER pAd,
+ IN PWFD_ENTRY_INFO pWfdEntryInfo,
+ IN VOID *Msg,
+ IN ULONG MsgLen);
+
+VOID WfdCfgInit(
+ IN PRTMP_ADAPTER pAd);
+
+#endif /* WFD_SUPPORT */
+#endif /* __WFD_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/wfd_cmm.h b/cleopatre/devkit/mt7601udrv/include/wfd_cmm.h
new file mode 100644
index 0000000000..4d58fc5415
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wfd_cmm.h
@@ -0,0 +1,293 @@
+/*
+
+ This file is provided under a dual BSD/GPLv2 license. When using or
+ redistributing this file, you may do so under either license.
+
+ GPL LICENSE SUMMARY
+
+ Copyright(c) 2005-2011 Ralink Technology Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ The full GNU General Public License is included in this distribution
+ in the file called LICENSE.GPL.
+
+ Contact Information:
+ Ralink Technology Corporation
+ 5F, No.5, Tai-Yuen 1st St., Jhubei City,
+ HsinChu Hsien 30265, Taiwan, R.O.C.
+
+
+ BSD LICENSE
+
+ Copyright(c) 2005-2011 Ralink Technology Corporation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+/*
+ Module Name:
+ wfd.h
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+
+*/
+
+
+#ifndef __WFD_CMM_H__
+#define __WFD_CMM_H__
+
+#ifdef WFD_SUPPORT
+
+#include "rtmp_type.h"
+
+#define WFD_OUI 0x506F9A
+
+/* Subelement ID Definitions */
+#define SUBID_WFD_DEVICE_INFO 0
+#define SUBID_WFD_ASSOCIATED_BSSID 1
+#define SUBID_WFD_AUDIO_FORMATS 2
+#define SUBID_WFD_VIDEO_FORMATS 3
+#define SUBID_WFD_3D_VIDEO_FORMATS 4
+#define SUBID_WFD_CONTENT_PROTECTION 5
+#define SUBID_WFD_COUPLED_SINK_INFO 6
+#define SUBID_WFD_EXTENDED_CAP 7
+#define SUBID_WFD_LOCAL_IP_ADDR 8
+#define SUBID_WFD_SESSION_INFO 9
+#define SUBID_WFD_ALTERNATE_MAC_ADDR 10
+#define SUBID_WFD_END 11
+
+/* Subelement ID Definitions */
+#define SUBID_WFD_DEVICE_INFO_LEN 6
+#define SUBID_WFD_ASSOCIATED_BSSID_LEN 6
+#define SUBID_WFD_AUDIO_FORMATS_LEN 15
+#define SUBID_WFD_VIDEO_FORMATS_LEN 21
+#define SUBID_WFD_3D_VIDEO_FORMATS_LEN 13
+#define SUBID_WFD_CONTENT_PROTECTION_LEN 1
+#define SUBID_WFD_COUPLED_SINK_INFO_LEN 1
+#define SUBID_WFD_EXTENDED_CAP_LEN 2
+#define SUBID_WFD_LOCAL_IP_ADDR_LEN 5
+#define SUBID_WFD_ALTERNATE_MAC_ADDR_LEN 6
+#define WFD_SOURCE 0x0
+#define WFD_PRIMARY_SINK 0x1
+#define WFD_SECONDARY_SINK 0x2
+#define WFD_SOURCE_PRIMARY_SINK 0x3
+#define WFD_DEVICE_TYPE_END 0x4
+
+#define WFD_COUPLED_NOT_SUPPORT 0x0
+#define WFD_COUPLED_SUPPORT 0x1
+
+#define WFD_SESSION_NOT_AVAILABLE 0x0
+#define WFD_SESSION_AVAILABLE 0x1
+
+#define WFD_WSD_NOT_SUPPORT 0x0
+#define WFD_WSD_SUPPORT 0x1
+
+#define WFD_PC_P2P 0x0
+#define WFD_PC_TDLS 0x1
+
+#define WFD_CP_NOT_SUPPORT 0x0
+#define WFD_CP_HDCP20 0x1
+
+#define WFD_TIME_SYNC_NOT_SUPPORT 0x0
+#define WFD_TIME_SYNC_SUPPORT 0x1 /* Time Synchronization using 802.1AS */
+
+#define WFD_TDLS_WEAK_SECURITY 0x0
+#define WFD_TDLS_STRONG_SECURITY 0x1
+
+/* Coupled Sink Status Bitmap */
+#define WFD_AVAILABLE_FOR_COUPLING 0x0
+#define WFD_COUPLED_SUCCESS 0x1
+#define WFD_TEARDOWN_COUPLING 0x2
+
+/* WFD RTSP Default Port */
+#define WFD_RTSP_DEFAULT_PORT 7236
+
+/* Version of Local IP Address Subelement */
+#define WFD_LOCAL_IP_ADDR_VERSION_IPV4 1
+
+/* Default max throughput */
+#define WFD_MAX_THROUGHPUT_DEFAULT 150
+
+/* Default content protection bit */
+#define WFD_CONTENT_PROTECT_DEFAULT WFD_CP_NOT_SUPPORT
+
+typedef struct GNU_PACKED _WFD_DEVICE_INFO
+{
+#ifndef RT_BIG_ENDIAN
+ USHORT DeviceType:2;
+ USHORT SourceCoupled:1;
+ USHORT SinkCoupled:1;
+ USHORT SessionAvail:2;
+ USHORT WSD:1;
+ USHORT PC:1; /* Preferred Connectivity */
+ USHORT CP:1;
+ USHORT TimeSync:1;
+ USHORT Rsvd:6;
+#else
+ USHORT Rsvd:6;
+ USHORT TimeSync:1; /* 802.1AS Support */
+ USHORT CP:1; /* Content Protection */
+ USHORT PC:1; /* Preferred Connectivity */
+ USHORT WSD:1; /* WFD Service Discovery */
+ USHORT SessionAvail:2;
+ USHORT SinkCoupled:1;
+ USHORT SourceCoupled:1;
+ USHORT DeviceType:2;
+#endif
+} WFD_DEVICE_INFO, *PWFD_DEVICE_INFO;
+
+
+typedef struct GNU_PACKED _WFD_COUPLED_SINK_INFO
+{
+#ifndef RT_BIG_ENDIAN
+ UCHAR CoupledStat:2;
+ UCHAR Rsvd:6;
+#else
+ UCHAR Rsvd:6;
+ UCHAR CoupledStat:2;
+#endif
+} WFD_COUPLED_SINK_INFO, *PWFD_COUPLED_SINK_INFO;
+
+
+typedef struct GNU_PACKED _WFD_SESSION_INFO
+{
+#ifndef RT_BIG_ENDIAN
+ UCHAR Length;
+ UCHAR DeviceAddr[MAC_ADDR_LEN];
+ UCHAR Bssid[MAC_ADDR_LEN];
+ WFD_DEVICE_INFO WfdDevInfo;
+ USHORT MaxThroughput;
+ WFD_COUPLED_SINK_INFO CoupledSinkInfo;
+ UCHAR CoupledPeerAddr[MAC_ADDR_LEN];
+#else
+ UCHAR CoupledPeerAddr[MAC_ADDR_LEN];
+ WFD_COUPLED_SINK_INFO CoupledSinkInfo;
+ USHORT MaxThroughput;
+ WFD_DEVICE_INFO WfdDevInfo;
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR DeviceAddr[MAC_ADDR_LEN];
+ UCHAR Length;
+#endif
+} WFD_SESSION_INFO, *PWFD_SESSION_INFO;
+
+typedef struct _WFD_SERV_DISC_QUERY_INFO
+{
+ BOOLEAN bWfd_device_info_ie;
+ UCHAR wfd_device_info_ie[SUBID_WFD_DEVICE_INFO_LEN];
+ BOOLEAN bWfd_associate_bssid_ie;
+ UCHAR wfd_associate_bssid_ie[SUBID_WFD_ASSOCIATED_BSSID_LEN];
+ BOOLEAN bWfd_audio_format_ie;
+ UCHAR wfd_audio_format_ie[SUBID_WFD_AUDIO_FORMATS_LEN];
+ BOOLEAN bWfd_video_format_ie;
+ UCHAR wfd_video_format_ie[SUBID_WFD_VIDEO_FORMATS_LEN];
+ BOOLEAN bWfd_3d_video_format_ie;
+ UCHAR wfd_3d_video_format_ie[SUBID_WFD_3D_VIDEO_FORMATS_LEN];
+ BOOLEAN bWfd_content_proctection;
+ UCHAR wfd_content_proctection[SUBID_WFD_CONTENT_PROTECTION_LEN];
+ BOOLEAN bWfd_couple_sink_info_ie;
+ UCHAR wfd_couple_sink_info_ie[SUBID_WFD_COUPLED_SINK_INFO_LEN];
+ BOOLEAN bWfd_extent_capability_ie;
+ UCHAR wfd_extent_capability_ie[SUBID_WFD_EXTENDED_CAP_LEN];
+ BOOLEAN bWfd_local_ip_ie;
+ UCHAR wfd_local_ip_ie[SUBID_WFD_LOCAL_IP_ADDR_LEN];
+ BOOLEAN bWfd_session_info_ie;
+ UCHAR wfd_session_info_ie[120];
+ BOOLEAN bWfd_alternate_mac_addr_ie;
+ UCHAR wfd_alternate_mac_addr_ie[SUBID_WFD_ALTERNATE_MAC_ADDR_LEN];
+} WFD_SERV_DISC_QUERY_INFO, *PWFD_SERV_DISC_QUERY_INFO;
+
+/* Store for WFD Entry Configuration */
+typedef struct _WFD_ENTRY_INFO
+{
+ UCHAR bWfdClient;
+ UCHAR wfd_devive_type;
+ UCHAR source_coupled;
+ UCHAR sink_coupled;
+ UCHAR session_avail;
+ UCHAR wfd_service_discovery;
+ UCHAR wfd_PC;
+ UCHAR wfd_CP;
+ UCHAR wfd_time_sync;
+ UCHAR sink_audio_unsupport;
+ UCHAR source_audio_only;
+ UCHAR tdls_persistent_group;
+ USHORT rtsp_port;
+ USHORT max_throughput;
+ UCHAR assoc_addr[MAC_ADDR_LEN];
+ WFD_COUPLED_SINK_INFO coupled_sink_status;
+ UCHAR coupled_peer_addr[MAC_ADDR_LEN];
+ /* Service Discovery */
+ WFD_SERV_DISC_QUERY_INFO wfd_serv_disc_query_info;
+} WFD_ENTRY_INFO, *PWFD_ENTRY_INFO;
+
+/* Store for WFD Configuration */
+typedef struct _RT_WFD_CONFIG
+{
+ BOOLEAN bWfdEnable;
+#ifdef RT_CFG80211_SUPPORT
+ BOOLEAN bSuppInsertWfdIe; /* Insert WFD IE to management frames from wpa_supplicant */
+ BOOLEAN bSuppGoOn; /* wpa_supplicant P2P GO is on */
+#endif /* RT_CFG80211_SUPPORT */
+ UCHAR DeviceType;
+ UCHAR SourceCoupled;
+ UCHAR SinkCoupled;
+ UCHAR SessionAvail;
+ UCHAR WSD;
+ UCHAR PC;
+ UCHAR CP; /* WFD Content Protection capability */
+ UCHAR TimeSync;
+ USHORT RtspPort; /* Deafult WFD_RTSP_DEFAULT_PORT */
+ USHORT MaxThroughput; /* Maximum average throughput capability */
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR IPv4Addr[4];
+ UCHAR TdlsSecurity;
+ UCHAR PeerSessionAvail;
+ UCHAR PeerPC;
+ WFD_COUPLED_SINK_INFO CoupledSinkStatus;
+ /* Service Discovery */
+ UINT32 WfdSerDiscCapable;
+ WFD_SERV_DISC_QUERY_INFO wfd_serv_disc_query_info;
+} RT_WFD_CONFIG, *PRT_WFD_CONFIG;
+
+#endif /* WFD_SUPPORT */
+#endif /* __WFD_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/wpa.h b/cleopatre/devkit/mt7601udrv/include/wpa.h
new file mode 100644
index 0000000000..3dcd838404
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wpa.h
@@ -0,0 +1,506 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wpa.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifndef __WPA_H__
+#define __WPA_H__
+
+#ifndef ROUND_UP
+#define ROUND_UP(__x, __y) \
+ (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
+#endif
+
+#define SET_UINT16_TO_ARRARY(_V, _LEN) \
+{ \
+ _V[0] = ((UINT16)_LEN) >> 8; \
+ _V[1] = ((UINT16)_LEN & 0xFF); \
+}
+
+#define INC_UINT16_TO_ARRARY(_V, _LEN) \
+{ \
+ UINT16 var_len; \
+ \
+ var_len = (_V[0]<<8) | (_V[1]); \
+ var_len += _LEN; \
+ \
+ _V[0] = (var_len & 0xFF00) >> 8; \
+ _V[1] = (var_len & 0xFF); \
+}
+
+#define CONV_ARRARY_TO_UINT16(_V) ((_V[0]<<8) | (_V[1]))
+
+#define ADD_ONE_To_64BIT_VAR(_V) \
+{ \
+ UCHAR cnt = LEN_KEY_DESC_REPLAY; \
+ do \
+ { \
+ cnt--; \
+ _V[cnt]++; \
+ if (cnt == 0) \
+ break; \
+ }while (_V[cnt] == 0); \
+}
+
+#define INC_TX_TSC(_tsc, _cnt) \
+{ \
+ INT i=0; \
+ while (++_tsc[i] == 0x0) \
+ { \
+ i++; \
+ if (i == (_cnt)) \
+ break; \
+ } \
+}
+
+#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+
+/*
+ WFA recommend to restrict the encryption type in 11n-HT mode.
+ So, the WEP and TKIP shall not be allowed to use HT rate.
+ */
+#define IS_INVALID_HT_SECURITY(_mode) \
+ (((_mode) == Ndis802_11Encryption1Enabled) || \
+ ((_mode) == Ndis802_11Encryption2Enabled))
+
+#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0)
+#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0)
+#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0)
+#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0)
+
+/* Some definition are different between Keneral mode and Daemon mode */
+#ifdef WPA_DAEMON_MODE
+/* The definition for Daemon mode */
+#define WPA_GET_BSS_NUM(_pAd) (_pAd)->mbss_num
+
+#define WPA_GET_PMK(_pAd, _pEntry, _pmk) \
+{ \
+ _pmk = _pAd->MBSS[_pEntry->apidx].PMK; \
+}
+
+#define WPA_GET_GTK(_pAd, _pEntry, _gtk) \
+{ \
+ _gtk = _pAd->MBSS[_pEntry->apidx].GTK; \
+}
+
+#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \
+{ \
+ _cipher = (_pAd)->MBSS[_pEntry->apidx].GroupEncrypType; \
+}
+
+#define WPA_GET_DEFAULT_KEY_ID(_pAd, _pEntry, _idx) \
+{ \
+ _idx = (_pAd)->MBSS[_pEntry->apidx].DefaultKeyId; \
+}
+
+#define WPA_GET_BMCST_TSC(_pAd, _pEntry, _tsc) \
+{ \
+ _tsc = 1; \
+}
+
+#define WPA_BSSID(_pAd, _apidx) (_pAd)->MBSS[_apidx].wlan_addr
+
+#define WPA_OS_MALLOC(_p, _s) \
+{ \
+ _p = os_malloc(_s); \
+}
+
+#define WPA_OS_FREE(_p) \
+{ \
+ os_free(_p); \
+}
+
+#define WPA_GET_CURRENT_TIME(_time) \
+{ \
+ struct timeval tv; \
+ gettimeofday(&tv, NULL); \
+ *(_time) = tv.tv_sec; \
+}
+
+#else
+/* The definition for Driver mode */
+
+#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
+#define WPA_GET_BSS_NUM(_pAd) (((_pAd)->OpMode == OPMODE_AP) ? (_pAd)->ApCfg.BssidNum : 1)
+#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \
+ { \
+ _cipher = Ndis802_11WEPDisabled; \
+ if ((_pAd)->OpMode == OPMODE_AP) \
+ { \
+ if (IS_ENTRY_APCLI(_pEntry) && \
+ ((_pEntry)->MatchAPCLITabIdx < MAX_APCLI_NUM)) \
+ _cipher = (_pAd)->ApCfg.ApCliTab[(_pEntry)->MatchAPCLITabIdx].GroupCipher; \
+ else if ((_pEntry)->apidx < (_pAd)->ApCfg.BssidNum) \
+ _cipher = (_pAd)->ApCfg.MBSSID[_pEntry->apidx].GroupKeyWepStatus;\
+ } \
+ else \
+ _cipher = (_pAd)->StaCfg.GroupCipher; \
+ }
+
+#define WPA_BSSID(_pAd, _apidx) (((_pAd)->OpMode == OPMODE_AP) ?\
+ (_pAd)->ApCfg.MBSSID[_apidx].Bssid :\
+ (_pAd)->CommonCfg.Bssid)
+#elif defined(CONFIG_AP_SUPPORT)
+#define WPA_GET_BSS_NUM(_pAd) (_pAd)->ApCfg.BssidNum
+#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \
+ { \
+ _cipher = Ndis802_11WEPDisabled; \
+ if (IS_ENTRY_APCLI(_pEntry) && \
+ ((_pEntry)->MatchAPCLITabIdx < MAX_APCLI_NUM)) \
+ _cipher = (_pAd)->ApCfg.ApCliTab[(_pEntry)->MatchAPCLITabIdx].GroupCipher; \
+ else if ((_pEntry)->apidx < (_pAd)->ApCfg.BssidNum) \
+ _cipher = (_pAd)->ApCfg.MBSSID[_pEntry->apidx].GroupKeyWepStatus;\
+ }
+
+#define WPA_BSSID(_pAd, _apidx) (_pAd)->ApCfg.MBSSID[_apidx].Bssid
+
+#elif defined(CONFIG_STA_SUPPORT)
+#define WPA_GET_BSS_NUM(_pAd) 1
+#define WPA_GET_GROUP_CIPHER(_pAd, _pEntry, _cipher) \
+ { \
+ _cipher = (_pAd)->StaCfg.GroupCipher; \
+ }
+#define WPA_BSSID(_pAd, _apidx) (_pAd)->CommonCfg.Bssid
+#endif /* defined(CONFIG_STA_SUPPORT) */
+
+#define WPA_OS_MALLOC(_p, _s) \
+{ \
+ os_alloc_mem(NULL, (PUCHAR *)&_p, _s); \
+}
+
+#define WPA_OS_FREE(_p) \
+{ \
+ os_free_mem(NULL, _p); \
+}
+
+#define WPA_GET_CURRENT_TIME(_time) NdisGetSystemUpTime(_time);
+
+#endif /* End of Driver Mode */
+
+#ifdef CONFIG_AP_SUPPORT
+/*========================================
+ The prototype is defined in ap_wpa.c
+ ========================================*/
+VOID WPA_APSetGroupRekeyAction(
+ IN PRTMP_ADAPTER pAd);
+
+#endif /* CONFIG_AP_SUPPORT */
+
+/*========================================
+ 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);
+
+#ifdef HDR_TRANS_SUPPORT
+BOOLEAN RTMPCheckWPAframe_Hdr_Trns(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR pData,
+ IN ULONG DataByteCount,
+ IN UCHAR FromWhichBSSID);
+#endif /* HDR_TRANS_SUPPORT */
+
+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);
+
+
+/*
+ =====================================
+ function prototype in cmm_wep.c
+ =====================================
+*/
+UINT RTMP_CALC_FCS32(
+ IN UINT Fcs,
+ IN PUCHAR Cp,
+ IN INT Len);
+
+VOID RTMPConstructWEPIVHdr(
+ IN UINT8 key_idx,
+ IN UCHAR *pn,
+ OUT UCHAR *iv_hdr);
+
+BOOLEAN RTMPSoftEncryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pIvHdr,
+ IN PCIPHER_KEY pKey,
+ INOUT PUCHAR pData,
+ IN ULONG DataByteCnt);
+
+BOOLEAN RTMPSoftDecryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PCIPHER_KEY pKey,
+ INOUT PUCHAR pData,
+ INOUT UINT16 *DataByteCnt);
+
+/*
+ =====================================
+ function prototype in cmm_tkip.c
+ =====================================
+*/
+BOOLEAN RTMPSoftDecryptTKIP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHdr,
+ IN UCHAR UserPriority,
+ IN PCIPHER_KEY pKey,
+ INOUT PUCHAR pData,
+ IN UINT16 *DataByteCnt);
+
+VOID TKIP_GTK_KEY_WRAP(
+ IN UCHAR *key,
+ IN UCHAR *iv,
+ IN UCHAR *input_text,
+ IN UINT32 input_len,
+ OUT UCHAR *output_text);
+
+VOID TKIP_GTK_KEY_UNWRAP(
+ IN UCHAR *key,
+ IN UCHAR *iv,
+ IN UCHAR *input_text,
+ IN UINT32 input_len,
+ OUT UCHAR *output_text);
+
+/*
+ =====================================
+ function prototype in cmm_aes.c
+ =====================================
+*/
+BOOLEAN RTMPSoftDecryptAES(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pWpaKey);
+
+VOID RTMPConstructCCMPHdr(
+ IN UINT8 key_idx,
+ IN UCHAR *pn,
+ OUT UCHAR *ccmp_hdr);
+
+BOOLEAN RTMPSoftEncryptCCMP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHdr,
+ IN PUCHAR pIV,
+ IN PUCHAR pKey,
+ INOUT PUCHAR pData,
+ IN UINT32 DataLen);
+
+BOOLEAN RTMPSoftDecryptCCMP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHdr,
+ IN PCIPHER_KEY pKey,
+ INOUT PUCHAR pData,
+ INOUT UINT16 *DataLen);
+
+VOID CCMP_test_vector(
+ IN PRTMP_ADAPTER pAd,
+ IN INT input);
+
+#endif
diff --git a/cleopatre/devkit/mt7601udrv/include/wpa_cmm.h b/cleopatre/devkit/mt7601udrv/include/wpa_cmm.h
new file mode 100644
index 0000000000..feccc6c8ce
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wpa_cmm.h
@@ -0,0 +1,211 @@
+
+#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 */
+ UCHAR Type; /* Indicate Pairwise/Group when reporting MIC error */
+} CIPHER_KEY, *PCIPHER_KEY;
+
+#endif /* WPA_CMM_H */
diff --git a/cleopatre/devkit/mt7601udrv/include/wsc.h b/cleopatre/devkit/mt7601udrv/include/wsc.h
new file mode 100644
index 0000000000..1c1b61ea45
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wsc.h
@@ -0,0 +1,820 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wsc.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-08-08 Initial
+*/
+
+#ifndef __WSC_H__
+#define __WSC_H__
+
+/* WSC OUI SMI */
+#define WSC_OUI 0x0050f204
+#define WSC_SMI 0x00372A
+#define WSC_VENDOR_TYPE 0x00000001
+
+/* EAP code */
+#define EAP_CODE_REQ 0x01
+#define EAP_CODE_RSP 0x02
+#define EAP_CODE_FAIL 0x04
+#define EAP_TYPE_ID 0x01
+#define EAP_TYPE_NOTIFY 0x02
+#define EAP_TYPE_WSC 0xfe
+
+/* structure to store Simple Config Attributes Info */
+typedef struct GNU_PACKED _WSC_LV_INFO {
+ USHORT ValueLen;
+ UCHAR Value[512];
+} WSC_LV_INFO;
+
+typedef struct GNU_PACKED _WSC_IE_HEADER {
+ UCHAR elemId;
+ UCHAR length;
+ UCHAR oui[4];
+} WSC_IE_HEADER;
+
+/* WSC IE structure */
+typedef struct GNU_PACKED _WSC_IE
+{
+ USHORT Type;
+ USHORT Length;
+ UCHAR Data[1]; /* variable length data */
+} WSC_IE, *PWSC_IE;
+
+/* WSC fixed information within EAP */
+typedef struct GNU_PACKED _WSC_FRAME
+{
+ UCHAR SMI[3];
+ UINT VendorType;
+ UCHAR OpCode;
+ UCHAR Flags;
+} WSC_FRAME, *PWSC_FRAME;
+
+/* EAP frame format */
+typedef struct GNU_PACKED _EAP_FRAME {
+ UCHAR Code; /* 1 = Request, 2 = Response */
+ UCHAR Id;
+ USHORT Length;
+ UCHAR Type; /* 1 = Identity, 0xfe = reserved, used by WSC */
+} EAP_FRAME, *PEAP_FRAME;
+
+static inline BOOLEAN WscCheckWSCHeader(
+ IN PUCHAR pData)
+{
+ PWSC_FRAME pWsc;
+
+ pWsc = (PWSC_FRAME) pData;
+
+ /* Verify SMI first */
+ if (((pWsc->SMI[0] * 256 + pWsc->SMI[1]) * 256 + pWsc->SMI[2]) != WSC_SMI)
+ {
+ /* Wrong WSC SMI Vendor ID, Update WSC status */
+ return FALSE;
+ }
+
+ /* Verify Vendor Type */
+ if (cpu2be32(get_unaligned32(&pWsc->VendorType)) != WSC_VENDOR_TYPE)
+ {
+ /* Wrong WSC Vendor Type, Update WSC status */
+ return FALSE;
+ }
+ return TRUE;
+}
+#ifdef WSC_INCLUDED
+
+
+/* WSC HDR PSH BTN FUNC */
+/* WSC hardware push button function 0811 */
+#define WSC_HDR_BTN_CHECK_PERIOD MLME_TASK_EXEC_INTV /* unit: ms, check pin every 100ms */
+#define WSC_HDR_BTN_PRESS_TIME 2000 /* unit: ms, press button for 2s */
+#define WSC_HDR_BTN_CONT_TIMES (WSC_HDR_BTN_PRESS_TIME/WSC_HDR_BTN_CHECK_PERIOD)
+#define WSC_HDR_BTN_GPIO_0 ((UINT32)0x00000001) /* bit 0 for RT2860/RT2870 */
+#define WSC_HDR_BTN_GPIO_3 ((UINT32)0x00000008) /* bit 3 for RT2860/RT2870 */
+
+/* bit7: WPS PBC (0:off, 1:on) */
+#define WSC_HDR_BTN_MR_HDR_SUPPORT_SET(__pAd, __FlgIsSup) \
+ (__pAd)->WscHdrPshBtnFlag = __FlgIsSup;
+
+/* check if hardware push button is supported */
+#define WSC_HDR_BTN_MR_IS_HDR_SUPPORT(__pAd) \
+ ((__pAd)->WscHdrPshBtnFlag)
+
+/* run hardware push button handler */
+#define WSC_HDR_BTN_MR_HANDLE(__pAd) \
+ if ((__pAd)->WscHdrPshBtnFlag) WSC_HDR_BTN_CheckHandler(__pAd);
+
+/* bit3: WPS PBC function is controlled through GPIO[3] */
+/* currently only for RT2860 & RT2870 */
+#define WSC_HDR_BTN_MR_PRESS_FLG_GET(__pAd, __FlgIsPressed) \
+ { \
+ UINT32 __gpio_value, mask; \
+ RTMP_IO_READ32(__pAd, GPIO_CTRL_CFG, (&__gpio_value)); \
+ if (RTMP_TEST_MORE_FLAG(__pAd, fRTMP_ADAPTER_WSC_PBC_PIN0)) \
+ mask = WSC_HDR_BTN_GPIO_0; \
+ else \
+ mask = WSC_HDR_BTN_GPIO_3; \
+ if (__gpio_value & mask) \
+ __FlgIsPressed = 0; \
+ else \
+ __FlgIsPressed = 1; \
+ }
+/* WSC HDR PSH BTN FUNC */
+
+
+#define WSC_TIMER_INIT(_pAd, _pData, _time_var, _time_flg, _time_fn) \
+ do{ \
+ RTMPInitTimer((_pAd), (_time_var), GET_TIMER_FUNCTION(_time_fn), (_pData), FALSE); \
+ (_time_flg) = FALSE; \
+ }while(0)
+
+
+/*Messages for the WSC state machine, */
+#define WSC_MACHINE_BASE 34
+#define WSC_EAPOL_PACKET_MSG 34
+#define WSC_EAPOL_START_MSG 35
+#define WSC_EAPOL_UPNP_MSG 36
+
+#define MAX_WSC_MSG 3
+
+/* WSC Opcode */
+#define WSC_OPCODE_START 0x01
+#define WSC_OPCODE_ACK 0x02
+#define WSC_OPCODE_NACK 0x03
+#define WSC_OPCODE_MSG 0x04
+#define WSC_OPCODE_DONE 0x05
+#define WSC_OPCODE_FRAG_ACK 0x06
+
+/* Flags */
+#define WSC_MSG_FLAG_MF 0x01 /* More fragments */
+#define WSC_MSG_FLAG_LF 0x02 /* Length field */
+
+#define WSC_OPCODE_UPNP_MASK 0x10
+#define WSC_OPCODE_UPNP_DATA 0x11
+#define WSC_OPCODE_UPNP_MGMT 0x12
+#define WSC_OPCODE_UPNP_CTRL 0x13
+
+#define WSC_UPNP_MGMT_SUB_PROBE_REQ 0x01
+#define WSC_UPNP_MGMT_SUB_CONFIG_REQ 0x02
+#define WSC_UPNP_MGMT_SUB_REG_SELECT 0x03
+
+
+/*patch for Atheros External registrar */
+#define WSC_UPNP_DATA_SUB_INCLUDE_MAC 0x0100
+
+#define WSC_UPNP_DATA_SUB_NORMAL 0x00
+#define WSC_UPNP_DATA_SUB_TO_ALL 0x01
+#define WSC_UPNP_DATA_SUB_TO_ONE 0x02
+#define WSC_UPNP_DATA_SUB_ACK 0x03
+#define WSC_UPNP_DATA_SUB_M1 0x04
+#define WSC_UPNP_DATA_SUB_M2 0x05
+#define WSC_UPNP_DATA_SUB_M2D 0x06
+#define WSC_UPNP_DATA_SUB_M3 0x07
+#define WSC_UPNP_DATA_SUB_M4 0x08
+#define WSC_UPNP_DATA_SUB_M5 0x09
+#define WSC_UPNP_DATA_SUB_M6 0x0A
+#define WSC_UPNP_DATA_SUB_M7 0x0B
+#define WSC_UPNP_DATA_SUB_M8 0x0C
+#define WSC_UPNP_DATA_SUB_WSC_ACK 0x0D
+#define WSC_UPNP_DATA_SUB_WSC_NACK 0x0E
+#define WSC_UPNP_DATA_SUB_WSC_DONE 0x0F
+#define WSC_UPNP_DATA_SUB_WSC_UNKNOWN 0xff
+
+
+/* Wsc EAP Messges type */
+#define WSC_MSG_EAP_RSP_ID 0x21
+#define WSC_MSG_EAP_REG_RSP_ID 0x22
+#define WSC_MSG_EAP_ENR_RSP_ID 0x23
+#define WSC_MSG_EAP_UPNP_RSP_ID 0x24
+#define WSC_MSG_EAP_REQ_ID 0x25
+#define WSC_MSG_EAP_REQ_START 0x26
+#define WSC_MSG_EAP_FAIL 0x27
+#define WSC_MSG_EAP_FRAG_ACK 0x28
+#define WSC_MSG_PROB_RSP 0x01
+#define WSC_MSG_EAPOL_START 0x02
+#define WSC_MSG_M1 0x04
+#define WSC_MSG_M2 0x05
+#define WSC_MSG_M2D 0x06
+#define WSC_MSG_M3 0x07
+#define WSC_MSG_M4 0x08
+#define WSC_MSG_M5 0x09
+#define WSC_MSG_M6 0x0A
+#define WSC_MSG_M7 0x0B
+#define WSC_MSG_M8 0x0C
+#define WSC_MSG_WSC_ACK 0x0D
+#define WSC_MSG_WSC_NACK 0x0E
+#define WSC_MSG_WSC_DONE 0x0F
+#define WSC_MSG_UNKNOWN 0xff
+
+/* WSC connection mode */
+#define WSC_PIN_MODE 1
+#define WSC_PBC_MODE 2
+#define WSC_SMPBC_MODE 3
+
+/* Value of WSC_IE_DEV_PASS_ID 0x1012 */
+#define DEV_PASS_ID_PIN 0x0000
+#define DEV_PASS_ID_USER 0x0001
+#define DEV_PASS_ID_MACHINE 0x0002
+#define DEV_PASS_ID_REKEY 0x0003
+#define DEV_PASS_ID_PBC 0x0004
+#define DEV_PASS_ID_REG 0x0005
+#define DEV_PASS_ID_SMPBC 0x0006
+#define DEV_PASS_ID_NOSPEC 0xffff
+
+
+/* Common definition */
+#define WSC_VERSION 0x10
+#define WSC_CONFIG_METHODS 0x008C
+
+/* Wsc status code */
+#define STATUS_WSC_NOTUSED 0
+#define STATUS_WSC_IDLE 1
+#define STATUS_WSC_FAIL 2 /* WSC Process Fail */
+#define STATUS_WSC_LINK_UP 3 /* Start WSC Process */
+#define STATUS_WSC_EAPOL_START_RECEIVED 4 /* Received EAPOL-Start */
+#define STATUS_WSC_EAP_REQ_ID_SENT 5 /* Sending EAP-Req(ID) */
+#define STATUS_WSC_EAP_RSP_ID_RECEIVED 6 /* Receive EAP-Rsp(ID) */
+#define STATUS_WSC_EAP_RSP_WRONG_SMI 7 /* Receive EAP-Req with wrong WSC SMI Vendor Id */
+#define STATUS_WSC_EAP_RSP_WRONG_VENDOR_TYPE 8 /* Receive EAPReq with wrong WSC Vendor Type */
+#define STATUS_WSC_EAP_REQ_WSC_START 9 /* Sending EAP-Req(WSC_START) */
+#define STATUS_WSC_EAP_M1_SENT 10 /* Send M1 */
+#define STATUS_WSC_EAP_M1_RECEIVED 11 /* Received M1 */
+#define STATUS_WSC_EAP_M2_SENT 12 /* Send M2 */
+#define STATUS_WSC_EAP_M2_RECEIVED 13 /* Received M2 */
+#define STATUS_WSC_EAP_M2D_RECEIVED 14 /* Received M2D */
+#define STATUS_WSC_EAP_M3_SENT 15 /* Send M3 */
+#define STATUS_WSC_EAP_M3_RECEIVED 16 /* Received M3 */
+#define STATUS_WSC_EAP_M4_SENT 17 /* Send M4 */
+#define STATUS_WSC_EAP_M4_RECEIVED 18 /* Received M4 */
+#define STATUS_WSC_EAP_M5_SENT 19 /* Send M5 */
+#define STATUS_WSC_EAP_M5_RECEIVED 20 /* Received M5 */
+#define STATUS_WSC_EAP_M6_SENT 21 /* Send M6 */
+#define STATUS_WSC_EAP_M6_RECEIVED 22 /* Received M6 */
+#define STATUS_WSC_EAP_M7_SENT 23 /* Send M7 */
+#define STATUS_WSC_EAP_M7_RECEIVED 24 /* Received M7 */
+#define STATUS_WSC_EAP_M8_SENT 25 /* Send M8 */
+#define STATUS_WSC_EAP_M8_RECEIVED 26 /* Received M8 */
+#define STATUS_WSC_EAP_RAP_RSP_ACK 27 /* Processing EAP Response (ACK) */
+#define STATUS_WSC_EAP_RAP_REQ_DONE_SENT 28 /* Processing EAP Request (Done) */
+#define STATUS_WSC_EAP_RAP_RSP_DONE_SENT 29 /* Processing EAP Response (Done) */
+#define STATUS_WSC_EAP_FAIL_SENT 30 /* Sending EAP-Fail */
+#define STATUS_WSC_ERROR_HASH_FAIL 31 /* WSC_ERROR_HASH_FAIL */
+#define STATUS_WSC_ERROR_HMAC_FAIL 32 /* WSC_ERROR_HMAC_FAIL */
+#define STATUS_WSC_ERROR_DEV_PWD_AUTH_FAIL 33 /* WSC_ERROR_DEV_PWD_AUTH_FAIL */
+#define STATUS_WSC_CONFIGURED 34
+#define STATUS_WSC_SCAN_AP 35 /* Scanning AP */
+#define STATUS_WSC_EAPOL_START_SENT 36
+#define STATUS_WSC_EAP_RSP_DONE_SENT 37
+#define STATUS_WSC_WAIT_PIN_CODE 38
+#define STATUS_WSC_START_ASSOC 39
+#define STATUS_WSC_IBSS_WAIT_NEXT_SMPBC_ENROLLEE 40
+#define STATUS_WSC_IBSS_NEW_RANDOM_PIN 41
+#define STATUS_WSC_IBSS_FIXED_PIN 42
+
+/* All error message dtarting from 0x0100 */
+#define STATUS_WSC_PBC_TOO_MANY_AP 0x0101 /* Too many PBC AP avaliable */
+#define STATUS_WSC_PBC_NO_AP 0x0102 /* No PBC AP avaliable */
+#define STATUS_WSC_EAP_FAIL_RECEIVED 0x0103 /* Received EAP-FAIL */
+#define STATUS_WSC_EAP_NONCE_MISMATCH 0x0104 /* Receive EAP with wrong NONCE */
+#define STATUS_WSC_EAP_INVALID_DATA 0x0105 /* Receive EAP without integrity (Hmac mismatch) */
+#define STATUS_WSC_PASSWORD_MISMATCH 0x0106 /* Error PIN Code (R-Hash mismatch) */
+#define STATUS_WSC_EAP_REQ_WRONG_SMI 0x0107 /* Receive EAP-Req with wrong WPS SMI Vendor Id */
+#define STATUS_WSC_EAP_REQ_WRONG_VENDOR_TYPE 0x0108 /* Receive EAPReq with wrong WPS Vendor Type */
+#define STATUS_WSC_PBC_SESSION_OVERLAP 0x0109 /* AP PBC session overlap */
+#define STATUS_WSC_SMPBC_TOO_MANY_REGISTRAR 0x010a /* Too many SMPBC Registrars avaliable */
+#define STATUS_WSC_EMPTY_IPV4_SUBMASK_LIST 0x010b /* Empty available IPv4 Submask list */
+#define STATUS_WSC_SMPBC_NO_AP 0x010c /* No SMPBC AP avaliable */
+
+#define WSC_DISABLE 0x0
+#define WSC_ENROLLEE 0x1
+#define WSC_PROXY 0x2
+#define WSC_REGISTRAR 0x4
+#define WSC_ENROLLEE_PROXY (WSC_ENROLLEE | WSC_PROXY)
+#define WSC_ENROLLEE_REGISTRAR (WSC_ENROLLEE | WSC_REGISTRAR)
+#define WSC_PROXY_REGISTRAR (WSC_PROXY | WSC_REGISTRAR)
+#define WSC_ENROLLEE_PROXY_REGISTRAR (WSC_ENROLLEE | WSC_PROXY | WSC_REGISTRAR)
+
+/* Device request/response type */
+#define WSC_MSGTYPE_ENROLLEE_INFO_ONLY 0x00
+#define WSC_MSGTYPE_ENROLLEE_OPEN_8021X 0x01
+#define WSC_MSGTYPE_REGISTRAR 0x02
+#define WSC_MSGTYPE_AP_WLAN_MGR 0x03
+
+/* RF Band */
+#define WSC_RFBAND_24GHZ 0x01
+#define WSC_RFBAND_50GHZ 0x02
+
+/* Simple Config state */
+#define WSC_SCSTATE_UNCONFIGURED 0x01
+#define WSC_SCSTATE_CONFIGURED 0x02
+
+/* Common definition */
+#define WSC_MANUFACTURE "Ralink Technology, Corp."
+#ifdef CONFIG_AP_SUPPORT
+#define AP_WSC_MODEL_NAME "Ralink Wireless Access Point"
+#define AP_WSC_DEVICE_NAME "RalinkAPS"
+#endif /* CONFIG_AP_SUPPORT */
+#define WSC_MODEL_NUMBER "RT2860"
+#define WSC_MODEL_SERIAL "12345678"
+
+/* Time-Out, param for timer func, count by micro-sec, not ticks */
+#define WSC_EAPOL_START_TIME_OUT 2000
+#define WSC_EAP_ID_TIME_OUT 5000
+#define WSC_EAP_MSG_TIME_OUT 5000
+#define WSC_EAP_MSG_ACK_TIME_OUT 1000
+#define WSC_EAP_EAP_FAIL_TIME_OUT 1000
+#define WSC_TWO_MINS_TIME_OUT 120000
+#define WSC_UPNP_M2D_TIME_OUT 15000
+#define WSC_UPNP_MSG_TIME_OUT 15000
+#define WSC_PROFILE_RETRY_TIME_OUT 10000
+#ifdef WSC_LED_SUPPORT
+#define WSC_SUCCESSFUL_LED_PATTERN_TIMEOUT 300000 /* 300 seconds */
+#define WSC_WPS_FAIL_LED_PATTERN_TIMEOUT 15000 /* 15 seconds. */
+#define WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT 2500 /* 2.5 seconds. */
+#define WSC_WPS_TURN_OFF_LED_TIMEOUT 1000 /* 1 second. */
+#endif /* WSC_LED_SUPPORT */
+
+#ifdef WSC_V2_SUPPORT
+#define WSC_WPS_AP_SETUP_LOCK_TIME 60 /* 60 mins */
+#define WSC_WPS_AP_MAX_PIN_ATTACK 3
+#define WSC_LOCK_FOREVER_PIN_ATTACK 10
+#endif /* WSC_V2_SUPPORT */
+
+#define WSC_INIT_ENTRY_APIDX 0xFF
+#define WSC_MAX_DATA_LEN 1024
+
+#define WSC_ENTRY_GET_EAPOL_START 0x1
+#define WSC_ENTRY_GET_EAP_RSP_ID 0x2
+
+/* Pack struct to align at byte */
+/*#pragma pack(1) */
+
+/* General used field */
+
+/* UUID related definition */
+#define UUID_LEN_HEX 16 /* 128 bits => 16 bytes */
+#define UUID_LEN_STR 37 /* hex to string, plus 4 dash, plus 1 '\0' */
+#define UUID_VERSION 1 /* We currently just support version 1 */
+
+/* user define length add by woody */
+#define WSC_MANUFACTURE_LEN 64
+#define WSC_MODELNAME_LEN 32
+#define WSC_MODELNUNBER_LEN 32
+#define WSC_DEVICENAME_LEN 32
+#define WSC_SERIALNUNBER_LEN 32
+#define MAX_2ND_DEV_TYPE_LIST 2
+#define MAX_2ND_DEV_TYPE_LIST_BUFFER (1+(8*MAX_2ND_DEV_TYPE_LIST))
+
+typedef struct _WSC_UUID_T{
+ UINT32 timeLow;
+ UINT16 timeMid;
+ UINT16 timeHi_Version;
+ UCHAR clockSeqHi_Var;
+ UCHAR clockSeqLow;
+ UCHAR node[6];
+}WSC_UUID_T;
+
+/* For WSC state machine states. */
+/* We simplified it */
+typedef enum _WscState
+{
+ WSC_STATE_OFF,
+ WSC_STATE_INIT,
+ WSC_STATE_START,
+ WSC_STATE_FAIL,
+ WSC_STATE_CONFIGURED,
+ WSC_STATE_LINK_UP,
+ WSC_STATE_SEND_EAPOL_START,
+ WSC_STATE_WAIT_EAPOL_START,
+ WSC_STATE_WAIT_UPNP_START,
+ WSC_STATE_WAIT_REQ_ID,
+ WSC_STATE_WAIT_RESP_ID,
+ WSC_STATE_WAIT_WSC_START,
+ WSC_STATE_WAIT_M1,
+ WSC_STATE_SENT_M1,
+ WSC_STATE_SENT_M2D,
+ WSC_STATE_WAIT_M2,
+ WSC_STATE_RX_M2D,
+ WSC_STATE_WAIT_PIN,
+ WSC_STATE_WAIT_M3,
+ WSC_STATE_WAIT_M4,
+ WSC_STATE_WAIT_M5,
+ WSC_STATE_WAIT_M6,
+ WSC_STATE_WAIT_M7,
+ WSC_STATE_WAIT_M8,
+ WSC_STATE_WAIT_DONE,
+ WSC_STATE_WAIT_ACK,
+ WSC_STATE_WAIT_EAPFAIL,
+ WSC_STATE_WAIT_DISCONN
+} WSC_STATE;
+
+/* WSC saved message */
+typedef struct _WSC_MESSAGE
+{
+ INT Length; /* Length of saved message */
+ UCHAR Data[2048]; /* Contents */
+} WSC_MESSAGE, *PWSC_MESSAGE;
+
+
+/* Data structure to hold Enrollee and Registrar information */
+typedef struct _WSC_DEV_INFO
+{
+ UCHAR Version;
+ UCHAR Version2;
+ UCHAR Uuid[16];
+ UCHAR MacAddr[6];
+ UCHAR DeviceName[32];
+ UCHAR PriDeviceType[8];
+ UCHAR SecDevTypList[MAX_2ND_DEV_TYPE_LIST_BUFFER]; /* 2nd Device Type List, ref. P2P Spec. v1.1 Table 29*/
+ USHORT AuthTypeFlags;
+ USHORT EncrTypeFlags;
+ UCHAR ConnTypeFlags;
+ USHORT ConfigMethods;
+ UCHAR ScState;
+ UCHAR Manufacturer[64];
+ UCHAR ModelName[32];
+ UCHAR ModelNumber[32];
+ UCHAR SerialNumber[32];
+ UCHAR RfBand;
+ UINT OsVersion;
+ UINT FeatureId;
+ USHORT AssocState;
+ USHORT DevPwdId;
+ USHORT ConfigError;
+ UCHAR Ssid[32];
+ UCHAR NewKey[64 + 1]; /* not sure sprintf would add '\0' or not, add one byte for \0' */
+ INT NewKeyLen;
+ UCHAR NewKeyIndex;
+} WSC_DEV_INFO, *PWSC_DEV_INFO;
+
+/* data structure to store info of the instance of Registration protocol */
+typedef struct _WSC_REG_DATA
+{
+ /* filled in by device self */
+ WSC_DEV_INFO SelfInfo;
+ /* filled in by wps peer */
+ WSC_DEV_INFO PeerInfo;
+
+ /*Diffie Hellman parameters */
+/* BIGNUM *DH_PubKey_Peer; //peer's pub key stored in bignum format */
+/* DH *DHSecret; //local key pair in bignum format */
+ UCHAR EnrolleeRandom[192]; /* Saved random byte for public key generation */
+
+ UCHAR ReComputePke;
+ UCHAR Pke[192]; /*enrollee's raw pub key */
+ UCHAR Pkr[192]; /*registrar's raw pub key */
+
+ UCHAR SecretKey[192]; /* Secret key calculated by enrollee */
+
+ UCHAR StaEncrSettings[128]; /* to be sent in M2/M8 by reg & M7 by enrollee */
+ UCHAR ApEncrSettings[1024];
+
+ /* Saved Message content for authenticator calculation */
+ WSC_MESSAGE LastTx;
+ WSC_MESSAGE LastRx;
+
+ /* Device password */
+ UCHAR PIN[8];
+ UCHAR PinCodeLen;
+
+ /* From KDF Key */
+ UCHAR AuthKey[32];
+ UCHAR KeyWrapKey[16];
+ UCHAR Emsk[32];
+
+ USHORT EnrolleePwdId;
+ UCHAR EnrolleeNonce[16]; /*N1, from enrollee */
+ UCHAR RegistrarNonce[16]; /*N2, from registrar */
+ UCHAR SelfNonce[16];
+
+ UCHAR Psk1[16];
+ UCHAR Psk2[16];
+
+ UCHAR EHash1[32];
+ UCHAR EHash2[32];
+ UCHAR Es1[16];
+ UCHAR Es2[16];
+
+ UCHAR RHash1[32];
+ UCHAR RHash2[32];
+ UCHAR Rs1[16];
+ UCHAR Rs2[16];
+} WSC_REG_DATA, *PWSC_REG_DATA;
+
+
+/* WSC UPnP node info. */
+typedef struct _WSC_UPNP_NODE_INFO{
+ BOOLEAN bUPnPInProgress;
+ BOOLEAN bUPnPMsgTimerRunning;
+ BOOLEAN bUPnPMsgTimerPending;
+ UINT registrarID;
+ RALINK_TIMER_STRUCT UPnPMsgTimer;
+}WSC_UPNP_NODE_INFO, *PWSC_UPNP_NODE_INFO;
+
+#define MAX_PBC_STA_TABLE_SIZE 4
+typedef struct _WSC_STA_PBC_PROBE_INFO {
+ ULONG ReciveTime[MAX_PBC_STA_TABLE_SIZE];
+ UCHAR WscPBCStaProbeCount;
+ UCHAR StaMacAddr[MAX_PBC_STA_TABLE_SIZE][MAC_ADDR_LEN];
+ UCHAR Valid[MAX_PBC_STA_TABLE_SIZE];
+} WSC_STA_PBC_PROBE_INFO, *PWSC_STA_PBC_PROBE_INFO;
+
+
+
+typedef struct GNU_PACKED _WSC_PEER_DEV_INFO {
+ UCHAR WscPeerDeviceName[32];
+ UCHAR WscPeerManufacturer[64];
+ UCHAR WscPeerModelName[32];
+ UCHAR WscPeerModelNumber[32];
+ UCHAR WscPeerSerialNumber[32];
+ UCHAR WscPeerMAC[6];
+} WSC_PEER_DEV_INFO, *PWSC_PEER_DEV_INFO;
+
+#ifdef WSC_V2_SUPPORT
+#define WSC_PIN_ATTACK_CHECK 600
+#define WSC_V2_VERSION 0x20
+#define TLV_ASCII 0
+#define TLV_HEX 1
+
+typedef struct _WSC_TLV {
+ USHORT TlvTag;
+ USHORT TlvLen;
+ PUCHAR pTlvData;
+ UCHAR TlvType; /* 0: ASCII, 1: Hex */
+} WSC_TLV, *PWSC_TLV;
+
+typedef struct _WSC_V2_INFO {
+ WSC_TLV ExtraTlv;
+ BOOLEAN bWpsEnable; /* FALSE: disable WSC , TRUE: enable WSC */
+ BOOLEAN bEnableWpsV2; /* FALSE: not support WSC 2.0, TRUE: support WSC 2.0 */
+} WSC_V2_INFO, *PWSC_V2_INFO;
+#endif /* WSC_V2_SUPPORT */
+
+/* WSC control block */
+typedef struct _WSC_CTRL
+{
+ INT WscConfMode; /* 0 Wsc not enable; 1 un-configure AP ; 3 un-configure AP with Proxy ; */
+ /* 5 un-configure AP with Registrar ; 7 un-configure AP with proxy and Registrar */
+ INT WscMode; /* 1 PIN ;2 PBC set from UI dynamically */
+ UCHAR WscConfStatus; /* 1 un-configured; 2 configured; need to update to .dat */
+ USHORT WscConfigMethods; /* Registrar support list. The List is bitwise. PBC:0x0080 Lable:0x0004 Display:0x0008 */
+ INT WscStatus; /* for user to monitor the status */
+ INT WscState; /* WSC Protocl State: M1 to M8 */
+ UINT WscPinCode; /* record the UI's PIN code input when we are registrar */
+ UCHAR WscPinCodeLen; /* record the UI's PIN code input length when we are registrar */
+ BOOLEAN WscEnrollee4digitPinCode; /* flag to use 4 or 8 digit Device own PIN code. */
+ UINT WscEnrolleePinCode; /* recored Device own PIN code. */
+ UCHAR WscEnrolleePinCodeLen; /* recored Device own PIN code length */
+ INT WscSelReg; /* record the UI's PIN code input when we are registrar */
+ NDIS_802_11_SSID WscSsid; /* select a desired ssid to connect for PIN mode */
+ UCHAR WscPBCBssCount; /* Count of PBC activated APs. */
+ UCHAR WscBssid[MAC_ADDR_LEN]; /* select a desired bssid to connect */
+ WSC_REG_DATA RegData; /* Registrar pair data */
+ UCHAR lastId;
+ UCHAR WscUseUPnP;
+ BOOLEAN EapMsgRunning; /* already recived Eap-Rsp(Identity) and sent M1 or Eap-Req(Start) */
+ UCHAR WscRetryCount;
+ UCHAR EntryIfIdx;
+ UCHAR EntryAddr[MAC_ADDR_LEN];
+ BOOLEAN Wsc2MinsTimerRunning;
+ RALINK_TIMER_STRUCT Wsc2MinsTimer;
+ WSC_PROFILE WscProfile; /* Saved WSC profile after M8 */
+ WSC_UPNP_NODE_INFO WscUPnPNodeInfo; /*Use to save UPnP node related info. */
+
+ BOOLEAN EapolTimerRunning;
+ BOOLEAN EapolTimerPending;
+ RALINK_TIMER_STRUCT EapolTimer;
+
+ BOOLEAN WscPBCTimerRunning;
+ RALINK_TIMER_STRUCT WscPBCTimer;
+ BOOLEAN WscScanTimerRunning;
+ RALINK_TIMER_STRUCT WscScanTimer;
+ BOOLEAN WscProfileRetryTimerRunning;
+ RALINK_TIMER_STRUCT WscProfileRetryTimer;
+#ifdef WSC_LED_SUPPORT
+ ULONG WscLEDMode; /* WPS LED mode: LED_WPS_XXX definitions. */
+ ULONG WscLastWarningLEDMode; /* LED_WPS_ERROR or LED_WPS_SESSION_OVERLAP_DETECTED */
+ BOOLEAN bSkipWPSTurnOffLED; /* Skip the WPS turn off LED command. */
+ BOOLEAN WscLEDTimerRunning;
+ RALINK_TIMER_STRUCT WscLEDTimer;
+ BOOLEAN WscSkipTurnOffLEDTimerRunning;
+ RALINK_TIMER_STRUCT WscSkipTurnOffLEDTimer;
+ /* This variable is TRUE after the 120 seconds WPS walk time expiration. */
+ /* Note that in the case of LED mode 9, the error LED should be turned on only after WPS walk time expiration */
+ /* if the NIC cannot find any WPS PBC-enabled APs in the last scanning result. */
+ BOOLEAN bWPSWalkTimeExpiration;
+#endif /* WSC_LED_SUPPORT */
+ UCHAR WpaPsk[64];
+ INT WpaPskLen;
+ BOOLEAN bWscTrigger; /* TRUE: AP-Enrollee & AP-Registrar work, FALSE: AP-Enrollee & AP-Registrar stop working */
+ PVOID pAd;
+ UINT WscLastPinFromEnrollee;
+ BOOLEAN WscRejectSamePinFromEnrollee;
+#ifdef CONFIG_AP_SUPPORT
+ NDIS_802_11_SSID WscDefaultSsid; /* Default WPS SSID after WPS process complete with Enrollee when AP is un-configured Registrar. */
+ BOOLEAN bWCNTest;
+#endif /* CONFIG_AP_SUPPORT */
+ INT WscKeyASCII; /*WscKeyASCII (0:Hex, 1:ASCII(random length), others: ASCII length(8~63, default 8)) */
+ INT WscActionMode;
+ UCHAR Wsc_Uuid_E[UUID_LEN_HEX];
+ UCHAR Wsc_Uuid_Str[UUID_LEN_STR];
+
+ UCHAR WpsApBand; /* Preferred WPS AP PHY type. Ref: PREFERRED_WPS_AP_PHY_TYPE */
+/*add by woody */
+ UCHAR Flags;
+
+ WSC_PEER_DEV_INFO WscPeerInfo;
+ BOOLEAN bCheckMultiByte;
+#ifdef WSC_V2_SUPPORT
+ WSC_V2_INFO WscV2Info;
+#endif /* WSC_V2_SUPPORT */
+ RALINK_TIMER_STRUCT WscUpdatePortCfgTimer;
+ BOOLEAN WscUpdatePortCfgTimerRunning;
+#ifdef CONFIG_AP_SUPPORT
+ RALINK_TIMER_STRUCT WscSetupLockTimer;
+ BOOLEAN WscSetupLockTimerRunning;
+ RALINK_TIMER_STRUCT WscPinAttackCountCheckTimer;
+ BOOLEAN WscPinAttackCountCheckTimerRunning;
+ BOOLEAN bSetupLock;
+ UCHAR PinAttackCount;
+ UCHAR MaxPinAttack;
+ UINT SetupLockTime; /* unit: minute */
+#endif /* CONFIG_AP_SUPPORT */
+ BOOLEAN bWscAutoTigeer;
+ BOOLEAN bWscFragment;
+ PUCHAR pWscRxBuf;
+ INT WscRxBufLen;
+ USHORT WscFragSize;
+ INT WscTxBufLen;
+ PUCHAR pWscTxBuf;
+ BOOLEAN bWscLastOne;
+ BOOLEAN bWscFirstOne;
+ PUCHAR pWscCurBufIdx;
+ NDIS_SPIN_LOCK WscPeerListSemLock;
+ LIST_HEADER WscPeerList;
+ RALINK_TIMER_STRUCT M2DTimer;
+ BOOLEAN bM2DTimerRunning;
+ INT M2DACKBalance;
+} WSC_CTRL, *PWSC_CTRL;
+
+typedef struct GNU_PACKED _WSC_CONFIGURED_VALUE {
+ USHORT WscConfigured; /* 1 un-configured; 2 configured */
+ UCHAR WscSsid[32 + 1];
+ USHORT WscAuthMode; /* mandatory, 0x01: open, 0x02: wpa-psk, 0x04: shared, 0x08:wpa, 0x10: wpa2, 0x20: wpa2-psk */
+ USHORT WscEncrypType; /* 0x01: none, 0x02: wep, 0x04: tkip, 0x08: aes */
+ UCHAR DefaultKeyIdx;
+ UCHAR WscWPAKey[64 + 1];
+} WSC_CONFIGURED_VALUE;
+
+/*
+ Following definitions are used for UPnP module to communicate msg.
+*/
+
+/* Ralink specific message header for Linux specific NETLINK socket. */
+#define RTMP_WSC_NLMSG_HDR_LEN 30 /*signature(8) + envID(4) + ackID(4) + msgLen(4) + Flag(2) + segLen(2) + devAddr(6) */
+typedef struct GNU_PACKED _RTMP_WSC_NLMSG_HDR{
+ UCHAR signature[8]; /* Signature used to identify that this's a Ralink specific NETLINK message.
+ MUST be "RAWSCMSG" currently.
+ */
+ UINT envID; /* Unique event Identification assigned by sender. */
+ UINT ackID; /* Notify that this message is a repsone for the message whose event identifier is "ackID". */
+ UINT msgLen; /* Totally length for this message. This message may seperate in serveral packets. */
+ USHORT flags;
+ USHORT segLen; /* The "segLen" means the actual data length in this one msg packet.
+ Because the NETLINK socket just support 256bytes for "IWCUSTOM" typed message, so we may
+ need to do fragement for our msg. If one message was fragemented as serveral pieces, the
+ user space receiver need to re-assemble it.
+ */
+ UCHAR devAddr[MAC_ADDR_LEN]; /* MAC address of the net device which send this netlink msg. */
+}RTMP_WSC_NLMSG_HDR;
+
+
+/*
+ Ralink specific WSC Mesage Header definition.
+*/
+#define RTMP_WSC_MSG_HDR_LEN 12 /*msgType(2) + msgSubType(2) + ipAddr(4) + len(4) */
+typedef struct GNU_PACKED _RTMP_WSC_MSG_HDR{
+ USHORT msgType;
+ USHORT msgSubType;
+ UINT ipAddr;
+ UINT msgLen; /*Not include this header. */
+}RTMP_WSC_MSG_HDR;
+
+#define WSC_MSG_TYPE_ENROLLEE 0x1
+#define WSC_MSG_TYPE_PROXY 0x2
+#define WSC_MSG_TYPE_REGISTRAR 0x3
+#define WSC_MSG_TYPE_CTRL 0x4
+#define WSC_MSG_TYPE_MGMT 0x5
+
+PSTRING WscGetAuthTypeStr(
+ IN USHORT authFlag);
+
+PSTRING WscGetEncryTypeStr(
+ IN USHORT encryFlag);
+
+#define IWEVCUSTOM_MSG_MAX_LEN 255 /*refer to kernel definition. <linux/wireless.h> */
+#define IWEVCUSTOM_PAYLOD_MAX_LEN (IWEVCUSTOM_MSG_MAX_LEN - RTMP_WSC_NLMSG_HDR_LEN)
+
+
+#define WSC_U2KMSG_HDR_LEN 41
+typedef struct GNU_PACKED _RTMP_WSC_U2KMSG_HDR{
+ UINT envID; /*Event ID. */
+ UCHAR Addr1[MAC_ADDR_LEN]; /*RA, should be the MAC address of the AP. */
+ UCHAR Addr2[MAC_ADDR_LEN]; /*TA, should be the ipAddress of remote UPnP Device/CotrnolPoint. */
+ UCHAR Addr3[MAC_ADDR_LEN]; /*DA, Not used now. */
+ UCHAR rsvWLHdr[2]; /*Reserved space for remained 802.11 hdr content. */
+ UCHAR rsv1HHdr[LENGTH_802_1_H];/*Reserved space for 802.1h header */
+ IEEE8021X_FRAME IEEE8021XHdr; /*802.1X header */
+ EAP_FRAME EAPHdr; /*EAP frame header. */
+}RTMP_WSC_U2KMSG_HDR;
+/*--- Used for UPnP module to communicate msg. */
+
+/* define OpMode for WscSendMessage */
+#undef AP_MODE
+#undef AP_CLIENT_MODE
+#undef STA_MODE
+
+#define AP_MODE 0x00
+#define AP_CLIENT_MODE 0x01
+#define STA_MODE 0x02
+#define REGISTRAR_ACTION 0x40
+#define ENROLLEE_ACTION 0x80
+
+/* Definition for Config Methods */
+#define WPS_CONFIG_METHODS_USBA 0x0001
+#define WPS_CONFIG_METHODS_ETHERNET 0x0002
+#define WPS_CONFIG_METHODS_LABEL 0x0004
+#define WPS_CONFIG_METHODS_DISPLAY 0x0008
+#define WPS_CONFIG_METHODS_ENT 0x0010 /* External NFC Token */
+#define WPS_CONFIG_METHODS_INT 0x0020 /* Integrated NFC Token */
+#define WPS_CONFIG_METHODS_NFCI 0x0040 /* NFC Interface */
+#define WPS_CONFIG_METHODS_PBC 0x0080
+#define WPS_CONFIG_METHODS_KEYPAD 0x0100
+
+typedef struct _UUID_BSSID_CH_INFO {
+ UCHAR Uuid[16];
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR Channel;
+ UCHAR Band;
+ UCHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+ UCHAR MacAddr[MAC_ADDR_LEN];
+} UUID_BSSID_CH_INFO, *PUUID_BSSID_CH_INFO;
+
+/*
+ Preferred WPS AP type.
+
+ a) PREFERRED_WPS_AP_PHY_TYPE_2DOT4_G_FIRST
+ Select 2.4G WPS AP first. Otherwise select 5G WPS AP.
+ b) PREFERRED_WPS_AP_PHY_TYPE_5_G_FIRST
+ Select the 5G WPS AP first. Otherwise select the 2.4G WPS AP.
+ c) PREFERRED_WPS_AP_PHY_TYPE_AUTO_SELECTION
+ Automactically select WPS AP.
+*/
+typedef enum _PREFERRED_WPS_AP_PHY_TYPE
+{
+ PREFERRED_WPS_AP_PHY_TYPE_2DOT4_G_FIRST = 0,
+ PREFERRED_WPS_AP_PHY_TYPE_5_G_FIRST,
+ PREFERRED_WPS_AP_PHY_TYPE_AUTO_SELECTION,
+ PREFERRED_WPS_AP_PHY_TYPE_MAXIMUM,
+} PREFERRED_WPS_AP_PHY_TYPE;
+
+typedef enum _WscSecurityMode{
+ WPA2PSKAES,
+ WPA2PSKTKIP,
+ WPAPSKAES,
+ WPAPSKTKIP,
+}WSC_SECURITY_MODE;
+
+typedef struct _WSC_PEER_ENTRY {
+ struct _WSC_PEER_ENTRY *pNext;
+ ULONG receive_time;
+ UCHAR mac_addr[MAC_ADDR_LEN];
+} WSC_PEER_ENTRY, *PWSC_PEER_ENTRY;
+
+
+#endif /* WSC_INCLUDED */
+
+#endif /* __WSC_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/include/wsc_tlv.h b/cleopatre/devkit/mt7601udrv/include/wsc_tlv.h
new file mode 100644
index 0000000000..43eb906642
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/include/wsc_tlv.h
@@ -0,0 +1,280 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ wsc_tlv.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ JuemingChen 06-09-11 Initial
+*/
+
+#ifndef __WSC_TLV_H__
+#define __WSC_TLV_H__
+
+/* Data Element Definitions */
+#define WSC_ID_AP_CHANNEL 0x1001
+#define WSC_ID_ASSOC_STATE 0x1002
+#define WSC_ID_AUTH_TYPE 0x1003
+#define WSC_ID_AUTH_TYPE_FLAGS 0x1004
+#define WSC_ID_AUTHENTICATOR 0x1005
+#define WSC_ID_CONFIG_METHODS 0x1008
+#define WSC_ID_CONFIG_ERROR 0x1009
+#define WSC_ID_CONF_URL4 0x100A
+#define WSC_ID_CONF_URL6 0x100B
+#define WSC_ID_CONN_TYPE 0x100C
+#define WSC_ID_CONN_TYPE_FLAGS 0x100D
+#define WSC_ID_CREDENTIAL 0x100E
+#define WSC_ID_ENCR_TYPE 0x100F
+#define WSC_ID_ENCR_TYPE_FLAGS 0x1010
+#define WSC_ID_DEVICE_NAME 0x1011
+#define WSC_ID_DEVICE_PWD_ID 0x1012
+#define WSC_ID_E_HASH1 0x1014
+#define WSC_ID_E_HASH2 0x1015
+#define WSC_ID_E_SNONCE1 0x1016
+#define WSC_ID_E_SNONCE2 0x1017
+#define WSC_ID_ENCR_SETTINGS 0x1018
+#define WSC_ID_ENROLLEE_NONCE 0x101A
+#define WSC_ID_FEATURE_ID 0x101B
+#define WSC_ID_IDENTITY 0x101C
+#define WSC_ID_IDENTITY_PROOF 0x101D
+#define WSC_ID_KEY_WRAP_AUTH 0x101E
+#define WSC_ID_KEY_IDENTIFIER 0x101F
+#define WSC_ID_MAC_ADDR 0x1020
+#define WSC_ID_MANUFACTURER 0x1021
+#define WSC_ID_MSG_TYPE 0x1022
+#define WSC_ID_MODEL_NAME 0x1023
+#define WSC_ID_MODEL_NUMBER 0x1024
+#define WSC_ID_NW_INDEX 0x1026
+#define WSC_ID_NW_KEY 0x1027
+#define WSC_ID_NW_KEY_INDEX 0x1028
+#define WSC_ID_NEW_DEVICE_NAME 0x1029
+#define WSC_ID_NEW_PWD 0x102A
+#define WSC_ID_OOB_DEV_PWD 0x102C
+#define WSC_ID_OS_VERSION 0x102D
+#define WSC_ID_POWER_LEVEL 0x102F
+#define WSC_ID_PSK_CURRENT 0x1030
+#define WSC_ID_PSK_MAX 0x1031
+#define WSC_ID_PUBLIC_KEY 0x1032
+#define WSC_ID_RADIO_ENABLED 0x1033
+#define WSC_ID_REBOOT 0x1034
+#define WSC_ID_REGISTRAR_CURRENT 0x1035
+#define WSC_ID_REGISTRAR_ESTBLSHD 0x1036
+#define WSC_ID_REGISTRAR_LIST 0x1037
+#define WSC_ID_REGISTRAR_MAX 0x1038
+#define WSC_ID_REGISTRAR_NONCE 0x1039
+#define WSC_ID_REQ_TYPE 0x103A
+#define WSC_ID_RESP_TYPE 0x103B
+#define WSC_ID_RF_BAND 0x103C
+#define WSC_ID_R_HASH1 0x103D
+#define WSC_ID_R_HASH2 0x103E
+#define WSC_ID_R_SNONCE1 0x103F
+#define WSC_ID_R_SNONCE2 0x1040
+#define WSC_ID_SEL_REGISTRAR 0x1041
+#define WSC_ID_SERIAL_NUM 0x1042
+#define WSC_ID_SC_STATE 0x1044
+#define WSC_ID_SSID 0x1045
+#define WSC_ID_TOT_NETWORKS 0x1046
+#define WSC_ID_UUID_E 0x1047
+#define WSC_ID_UUID_R 0x1048
+#define WSC_ID_VENDOR_EXT 0x1049
+#define WSC_ID_VERSION 0x104A
+#define WSC_ID_X509_CERT_REQ 0x104B
+#define WSC_ID_X509_CERT 0x104C
+#define WSC_ID_EAP_IDENTITY 0x104D
+#define WSC_ID_MSG_COUNTER 0x104E
+#define WSC_ID_PUBKEY_HASH 0x104F
+#define WSC_ID_REKEY_KEY 0x1050
+#define WSC_ID_KEY_LIFETIME 0x1051
+#define WSC_ID_PERM_CFG_METHODS 0x1052
+#define WSC_ID_SEL_REG_CFG_METHODS 0x1053
+#define WSC_ID_PRIM_DEV_TYPE 0x1054
+#define WSC_ID_SEC_DEV_TYPE_LIST 0x1055
+#define WSC_ID_PORTABLE_DEVICE 0x1056
+#define WSC_ID_AP_SETUP_LOCKED 0x1057
+#define WSC_ID_APP_LIST 0x1058
+#define WSC_ID_EAP_TYPE 0x1059
+#define WSC_ID_INIT_VECTOR 0x1060
+#define WSC_ID_KEY_PROVIDED_AUTO 0x1061
+#define WSC_ID_8021X_ENABLED 0x1062
+#define WSC_ID_APPSESSIONKEY 0x1063
+#define WSC_ID_WEPTRANSMITKEY 0x1064
+
+/* WFA Vendor Extension Subelements */
+#define WFA_EXT_ID_VERSION2 0x00
+#define WFA_EXT_ID_AUTHORIZEDMACS 0x01
+#define WFA_EXT_ID_NW_KEY_SHAREABLE 0x02
+#define WFA_EXT_ID_REQ_TO_ENROLL 0x03
+#define WFA_EXT_ID_SETTINGS_DELAY_TIME 0x04
+
+/* Association states */
+#define WSC_ASSOC_NOT_ASSOCIATED 0
+#define WSC_ASSOC_CONN_SUCCESS 1
+#define WSC_ASSOC_CONFIG_FAIL 2
+#define WSC_ASSOC_ASSOC_FAIL 3
+#define WSC_ASSOC_IP_FAIL 4
+
+/* Authentication types */
+#define WSC_AUTHTYPE_OPEN 0x0001
+#define WSC_AUTHTYPE_WPAPSK 0x0002
+#define WSC_AUTHTYPE_SHARED 0x0004
+#define WSC_AUTHTYPE_WPA 0x0008
+#define WSC_AUTHTYPE_WPA2 0x0010
+#define WSC_AUTHTYPE_WPA2PSK 0x0020
+#define WSC_AUTHTYPE_WPANONE 0x0080
+
+/* Config methods */
+#define WSC_CONFMET_USBA 0x0001
+#define WSC_CONFMET_ETHERNET 0x0002
+#define WSC_CONFMET_LABEL 0x0004
+#define WSC_CONFMET_DISPLAY 0x0008
+#define WSC_CONFMET_EXT_NFC_TOK 0x0010
+#define WSC_CONFMET_INT_NFC_TOK 0x0020
+#define WSC_CONFMET_NFC_INTF 0x0040
+#define WSC_CONFMET_PBC 0x0080
+#define WSC_CONFMET_KEYPAD 0x0100
+
+/* WSC error messages */
+#define WSC_ERROR_NO_ERROR 0
+#define WSC_ERROR_OOB_INT_READ_ERR 1
+#define WSC_ERROR_DECRYPT_CRC_FAIL 2
+#define WSC_ERROR_CHAN24_NOT_SUPP 3
+#define WSC_ERROR_CHAN50_NOT_SUPP 4
+#define WSC_ERROR_SIGNAL_WEAK 5
+#define WSC_ERROR_NW_AUTH_FAIL 6
+#define WSC_ERROR_NW_ASSOC_FAIL 7
+#define WSC_ERROR_NO_DHCP_RESP 8
+#define WSC_ERROR_FAILED_DHCP_CONF 9
+#define WSC_ERROR_IP_ADDR_CONFLICT 10
+#define WSC_ERROR_FAIL_CONN_REGISTRAR 11
+#define WSC_ERROR_MULTI_PBC_DETECTED 12
+#define WSC_ERROR_ROGUE_SUSPECTED 13
+#define WSC_ERROR_DEVICE_BUSY 14
+#define WSC_ERROR_SETUP_LOCKED 15
+#define WSC_ERROR_MSG_TIMEOUT 16
+#define WSC_ERROR_REG_SESSION_TIMEOUT 17
+#define WSC_ERROR_DEV_PWD_AUTH_FAIL 18
+#define WSC_ERROR_DO_MULTI_PBC_DETECTION 251
+#define WSC_ERROR_CAN_NOT_ALLOCMEM 252
+#define WSC_ERROR_WANTING_FIELD 253
+#define WSC_ERROR_HASH_FAIL 254
+#define WSC_ERROR_HMAC_FAIL 255
+
+/* Connection types */
+#define WSC_CONNTYPE_ESS 0x01
+#define WSC_CONNTYPE_IBSS 0x02
+
+/* Device password ID */
+#define WSC_DEVICEPWDID_DEFAULT 0x0000
+#define WSC_DEVICEPWDID_USER_SPEC 0x0001
+#define WSC_DEVICEPWDID_MACHINE_SPEC 0x0002
+#define WSC_DEVICEPWDID_REKEY 0x0003
+#define WSC_DEVICEPWDID_PUSH_BTN 0x0004
+#define WSC_DEVICEPWDID_REG_SPEC 0x0005
+
+/* Device type */
+#define WSC_DEVICETYPE_COMPUTER "Computer"
+#define WSC_DEVICETYPE_AP "Access_Point"
+#define WSC_DEVICETYPE_ROUTER_AP "Router_AP"
+#define WSC_DEVICETYPE_PRINTER "Printer"
+#define WSC_DEVICETYPE_PRINTER_BRIDGE "Printer_Brigde"
+#define WSC_DEVICETYPE_ELECT_PIC_FRAME "Electronic_Picture_Frame"
+#define WSC_DEVICETYPE_DIG_AUDIO_RECV "Digital_Audio_Receiver"
+#define WSC_DEVICETYPE_WIN_MCE "Windows_Media_Center_Extender"
+#define WSC_DEVICETYPE_WIN_MOBILE "Windows_Mobile"
+#define WSC_DEVICETYPE_PVR "Personal_Video_Recorder"
+#define WSC_DEVICETYPE_VIDEO_STB "Video_STB"
+#define WSC_DEVICETYPE_PROJECTOR "Projector"
+#define WSC_DEVICETYPE_IP_TV "IP_TV"
+#define WSC_DEVICETYPE_DIG_STILL_CAM "Digital_Still_Camera"
+#define WSC_DEVICETYPE_PHONE "Phone"
+#define WSC_DEVICETYPE_VOID_PHONE "VoIP_Phone"
+#define WSC_DEVICETYPE_GAME_CONSOLE "Game_console"
+#define WSC_DEVICETYPE_OTHER "Other"
+
+/* Encryption type */
+#define WSC_ENCRTYPE_NONE 0x0001
+#define WSC_ENCRTYPE_WEP 0x0002
+#define WSC_ENCRTYPE_TKIP 0x0004
+#define WSC_ENCRTYPE_AES 0x0008
+
+/* WSC Message Types */
+#define WSC_ID_BEACON 0x01
+#define WSC_ID_PROBE_REQ 0x02
+#define WSC_ID_PROBE_RESP 0x03
+#define WSC_ID_MESSAGE_M1 0x04
+#define WSC_ID_MESSAGE_M2 0x05
+#define WSC_ID_MESSAGE_M2D 0x06
+#define WSC_ID_MESSAGE_M3 0x07
+#define WSC_ID_MESSAGE_M4 0x08
+#define WSC_ID_MESSAGE_M5 0x09
+#define WSC_ID_MESSAGE_M6 0x0A
+#define WSC_ID_MESSAGE_M7 0x0B
+#define WSC_ID_MESSAGE_M8 0x0C
+#define WSC_ID_MESSAGE_ACK 0x0D
+#define WSC_ID_MESSAGE_NACK 0x0E
+#define WSC_ID_MESSAGE_DONE 0x0F
+#define WSC_ID_MESSAGE_EAP_REQ_ID 0x21
+#define WSC_ID_MESSAGE_EAP_REQ_START 0x22
+#define WSC_ID_MESSAGE_EAP_FAIL 0x23
+#define WSC_ID_MESSAGE_UNKNOWN 0xFF
+
+/* Device Type categories for primary and secondary device types */
+#define WSC_DEVICE_TYPE_CAT_COMPUTER 1
+#define WSC_DEVICE_TYPE_CAT_INPUT_DEVICE 2
+#define WSC_DEVICE_TYPE_CAT_PRINTER 3
+#define WSC_DEVICE_TYPE_CAT_CAMERA 4
+#define WSC_DEVICE_TYPE_CAT_STORAGE 5
+#define WSC_DEVICE_TYPE_CAT_NW_INFRA 6
+#define WSC_DEVICE_TYPE_CAT_DISPLAYS 7
+#define WSC_DEVICE_TYPE_CAT_MM_DEVICES 8
+#define WSC_DEVICE_TYPE_CAT_GAME_DEVICES 9
+#define WSC_DEVICE_TYPE_CAT_TELEPHONE 10
+
+/* Device Type sub categories for primary and secondary device types */
+#define WSC_DEVICE_TYPE_SUB_CAT_COMP_PC 1
+#define WSC_DEVICE_TYPE_SUB_CAT_COMP_SERVER 2
+#define WSC_DEVICE_TYPE_SUB_CAT_COMP_MEDIA_CTR 3
+#define WSC_DEVICE_TYPE_SUB_CAT_PRTR_PRINTER 1
+#define WSC_DEVICE_TYPE_SUB_CAT_PRTR_SCANNER 2
+#define WSC_DEVICE_TYPE_SUB_CAT_CAM_DGTL_STILL 1
+#define WSC_DEVICE_TYPE_SUB_CAT_STOR_NAS 1
+#define WSC_DEVICE_TYPE_SUB_CAT_NW_AP 1
+#define WSC_DEVICE_TYPE_SUB_CAT_NW_ROUTER 2
+#define WSC_DEVICE_TYPE_SUB_CAT_NW_SWITCH 3
+#define WSC_DEVICE_TYPE_SUB_CAT_DISP_TV 1
+#define WSC_DEVICE_TYPE_SUB_CAT_DISP_PIC_FRAME 2
+#define WSC_DEVICE_TYPE_SUB_CAT_DISP_PROJECTOR 3
+#define WSC_DEVICE_TYPE_SUB_CAT_MM_DAR 1
+#define WSC_DEVICE_TYPE_SUB_CAT_MM_PVR 2
+#define WSC_DEVICE_TYPE_SUB_CAT_MM_MCX 3
+#define WSC_DEVICE_TYPE_SUB_CAT_GAM_XBOX 1
+#define WSC_DEVICE_TYPE_SUB_CAT_GAM_XBOX_360 2
+#define WSC_DEVICE_TYPE_SUB_CAT_GAM_PS 3
+#define WSC_DEVICE_TYPE_SUB_CAT_PHONE_WM 1
+
+typedef struct _WSC_TLV_0B {
+ /*USHORT tag;*/
+ USHORT len;
+} WSC_TLV_0B, *PWSC_TLV_0B;
+
+#endif /* __WSC_TLV_H__ */
+
diff --git a/cleopatre/devkit/mt7601udrv/load b/cleopatre/devkit/mt7601udrv/load
new file mode 100644
index 0000000000..8faa4fb4e8
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/load
@@ -0,0 +1,3 @@
+dmesg -c
+insmod os/linux/mt7601Uap.ko
+ifconfig ra0 10.10.10.100
diff --git a/cleopatre/devkit/mt7601udrv/mac/ral_nmac.c b/cleopatre/devkit/mt7601udrv/mac/ral_nmac.c
new file mode 100644
index 0000000000..80fdf42481
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mac/ral_nmac.c
@@ -0,0 +1,31 @@
+/*
+
+*/
+
+
+#include "rt_config.h"
+
+
+INT get_pkt_phymode_by_rxwi(RXWI_STRUC *rxwi)
+{
+ return rxwi->RXWI_N.phy_mode;
+}
+
+INT get_pkt_rssi_by_rxwi(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *rxwi, INT size, CHAR *rssi)
+{
+ if (size < sizeof(rxwi->RXWI_N.rssi)/ sizeof(UINT8))
+ NdisMoveMemory(rssi, &rxwi->RXWI_N.rssi[0], size);
+
+ return 0;
+}
+
+
+INT get_pkt_snr_by_rxwi(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *rxwi, INT size, UCHAR *snr)
+{
+ // TODO: shiang-6590, fix me for SNR info of RXWI!!
+ if (size < 3)
+ NdisMoveMemory(snr, &rxwi->RXWI_N.bbp_rxinfo[0], size);
+
+ return 0;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mac/ral_omac.c b/cleopatre/devkit/mt7601udrv/mac/ral_omac.c
new file mode 100644
index 0000000000..59369adcea
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mac/ral_omac.c
@@ -0,0 +1,67 @@
+/*
+
+*/
+
+
+#include "rt_config.h"
+
+
+INT get_pkt_phymode_by_rxwi(RXWI_STRUC *rxwi)
+{
+ return rxwi->RXWI_O.phy_mode;
+}
+
+INT get_pkt_rssi_by_rxwi(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *rxwi, INT size, CHAR *rssi)
+{
+ switch (size) {
+ case 3:
+ rssi[2] = rxwi->RxWIRSSI2;
+ case 2:
+ rssi[1] = rxwi->RxWIRSSI1;
+ case 1:
+ default:
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ rssi[0] = rxwi->RxWISNR2;
+ else
+#endif /* MT7601 */
+ rssi[0] = rxwi->RxWIRSSI0;
+ break;
+ }
+
+ return 0;
+}
+
+
+INT get_pkt_snr_by_rxwi(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *rxwi, INT size, UCHAR *snr)
+{
+
+#ifdef MT7601
+ /*
+ snr[2] = Gain Report
+ snr[1] = Antenna report
+ */
+
+ if ( IS_MT7601(pAd) )
+ {
+ snr[0] = rxwi->RxWISNR0;
+ snr[1] = 0;
+ snr[2] = 0;
+ return 0;
+ }
+#endif /* MT7601 */
+
+ switch (size) {
+ case 3:
+ snr[2] = rxwi->RxWISNR2;
+ case 2:
+ snr[1] = rxwi->RxWISNR1;
+ case 1:
+ default:
+ snr[0] = rxwi->RxWISNR0;
+ break;
+ }
+
+ return 0;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mac/rtmp_mac.c b/cleopatre/devkit/mt7601udrv/mac/rtmp_mac.c
new file mode 100644
index 0000000000..aca5b02c1f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mac/rtmp_mac.c
@@ -0,0 +1,607 @@
+/*
+
+*/
+
+
+#include "rt_config.h"
+
+
+/*
+ ========================================================================
+
+ 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
+
+ See also : BASmartHardTransmit() !!!
+
+ ========================================================================
+*/
+VOID RTMPWriteTxWI(
+ IN RTMP_ADAPTER *pAd,
+ IN TXWI_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;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+ 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, TXWISize);
+ pTxWI = &TxWI;
+ pTxWI->TxWIFRAG= FRAG;
+ pTxWI->TxWICFACK = CFACK;
+ pTxWI->TxWITS= InsTimestamp;
+ pTxWI->TxWIAMPDU = AMPDU;
+ pTxWI->TxWIACK = Ack;
+ pTxWI->TxWITXOP= Txopmode;
+
+ pTxWI->TxWINSEQ = NSeq;
+ /* John tune the performace with Intel Client in 20 MHz performance*/
+#ifdef DOT11_N_SUPPORT
+ BASize = pAd->CommonCfg.TxBASize;
+#ifdef RT65xx
+ if (IS_RT65XX(pAd))
+ {
+ if (BASize > 31)
+ BASize =31;
+ }
+ else
+#endif /* RT65xx */
+#ifdef MT7601
+ if (IS_MT7601(pAd))
+ {
+ if (BASize > 15)
+ BASize =15;
+ }
+ else
+#endif /* MT7601 */
+ if (pAd->MACVersion == 0x28720200)
+ {
+ if (BASize > 13)
+ BASize =13;
+ }
+ else
+ {
+ if( BASize >7 )
+ BASize =7;
+ }
+
+ pTxWI->TxWIBAWinSize = BASize;
+ pTxWI->TxWIShortGI = pTransmit->field.ShortGI;
+ pTxWI->TxWISTBC = pTransmit->field.STBC;
+
+#ifdef TXBF_SUPPORT
+ if (pMac && pAd->chipCap.FlgHwTxBfCap)
+ {
+ if (pMac->TxSndgType == SNDG_TYPE_NDP || pMac->TxSndgType == SNDG_TYPE_SOUNDING || pTxWI->eTxBF)
+ pTxWI->TxWISTBC = 0;
+ }
+#endif /* TXBF_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+ pTxWI->TxWIWirelessCliID = WCID;
+ pTxWI->TxWIMPDUByteCnt = Length;
+#ifdef RLT_MAC
+ pTxWI->TxWIPacketId = PID;
+#endif /* RLT_MAC */
+
+ /* If CCK or OFDM, BW must be 20*/
+ pTxWI->TxWIBW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->TxWIBW)
+ pTxWI->TxWIBW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif /* DOT11N_DRAFT3 */
+#endif /* DOT11_N_SUPPORT */
+
+ pTxWI->TxWIMCS = pTransmit->field.MCS;
+ pTxWI->TxWIPHYMODE = pTransmit->field.MODE;
+ pTxWI->TxWICFACK = 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->TxWIMIMOps = 1;
+ }
+ else if (pMac->MmpsMode == MMPS_STATIC)
+ {
+ /* Static MIMO Power Save Mode*/
+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+ {
+ pTxWI->TxWIMCS = 7;
+ pTxWI->TxWIMIMOps = 0;
+ }
+ }
+ }
+ /*pTxWI->TxWIMIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;*/
+ {
+ pTxWI->TxWIMpduDensity = pMac->MpduDensity;
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+
+
+#ifdef RLT_MAC
+ pTxWI->TxWIPacketId = pTxWI->TxWIMCS;
+#endif /* RLT_MAC */
+ NdisMoveMemory(pOutTxWI, &TxWI, TXWISize);
+//+++Add by shiang for debug
+if (0){
+ hex_dump("TxWI", (UCHAR *)pOutTxWI, TXWISize);
+}
+//---Add by shiang for debug
+}
+
+
+VOID RTMPWriteTxWI_Data(RTMP_ADAPTER *pAd, TXWI_STRUC *pTxWI, TX_BLK *pTxBlk)
+{
+ HTTRANSMIT_SETTING *pTransmit;
+ MAC_TABLE_ENTRY *pMacEntry;
+#ifdef DOT11_N_SUPPORT
+ UCHAR BASize;
+#endif /* DOT11_N_SUPPORT */
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+#ifdef WFA_VHT_PF
+ BOOLEAN amsdu_in_ampdu = FALSE;
+#endif /* WFA_VHT_PF */
+
+ 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, TXWISize);
+
+ pTxWI->TxWIFRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
+ pTxWI->TxWIACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
+ pTxWI->TxWITXOP = pTxBlk->FrameGap;
+
+ pTxWI->TxWIWirelessCliID = pTxBlk->Wcid;
+
+#ifdef HDR_TRANS_SUPPORT
+ if (pTxBlk->NeedTrans )
+ pTxWI->TxWIMPDUByteCnt = pTxBlk->SrcBufLen;
+ else
+#endif /* HDR_TRANS_SUPPORT */
+ pTxWI->TxWIMPDUByteCnt = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+ pTxWI->TxWICFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
+
+ /* If CCK or OFDM, BW must be 20 */
+ pTxWI->TxWIBW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->TxWIBW)
+ pTxWI->TxWIBW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif /* DOT11N_DRAFT3 */
+
+#ifdef WFA_VHT_PF
+ if ((pAd->force_amsdu == TRUE) && (pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
+ (pTxWI->TxWIWirelessCliID != MCAST_WCID) && pMacEntry)
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("%s():f_amsdu=%d, pTxBlk->TxFrameType=%d, pMacEntry->TXBAbitmap=0x%x, pTxBlk->UserPriority=%d, cond_match=%d!\n",
+ __FUNCTION__, pAd->force_amsdu, pTxBlk->TxFrameType, pMacEntry->TXBAbitmap,
+ pTxBlk->UserPriority, ((pMacEntry->TXBAbitmap & (1<<pTxBlk->UserPriority)) != 0) ? TRUE : FALSE));
+
+
+ if ((pAd->force_amsdu == TRUE) && (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+ && (pMacEntry && ((pMacEntry->TXBAbitmap & (1<<pTxBlk->UserPriority)) != 0)))
+ amsdu_in_ampdu = TRUE;
+ }
+#endif /* WFA_VHT_PF */
+
+#ifdef WFA_VHT_PF
+ if (amsdu_in_ampdu)
+ pTxWI->TxWIAMPDU = TRUE;
+ else
+#endif /* WFA_VHT_PF */
+ pTxWI->TxWIAMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
+
+#ifdef TXBF_SUPPORT
+ if(pTxBlk->TxSndgPkt > SNDG_TYPE_DISABLE)
+ pTxWI->TxWIAMPDU = FALSE;
+#endif /* TXBF_SUPPORT */
+
+ BASize = pAd->CommonCfg.TxBASize;
+ if((pTxBlk->TxFrameType == TX_AMPDU_FRAME
+#ifdef WFA_VHT_PF
+ || amsdu_in_ampdu == TRUE
+#endif /* WFA_VHT_PF */
+ ) && (pMacEntry))
+ {
+ UCHAR RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
+
+ BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
+ }
+
+#ifdef TXBF_SUPPORT
+ if (pTxBlk->TxSndgPkt == SNDG_TYPE_SOUNDING)
+ {
+ pTxWI->Sounding = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("ETxBF in RTMPWriteTxWI_Data(): sending normal sounding, eTxBF=%d\n", pTxWI->eTxBF));
+ pTxWI->iTxBF = 0;
+ }
+ else if (pTxBlk->TxSndgPkt == SNDG_TYPE_NDP)
+ {
+ if (pTxBlk->TxNDPSndgMcs >= 16)
+ pTxWI->NDPSndRate = 2;
+ else if (pTxBlk->TxNDPSndgMcs >= 8)
+ pTxWI->NDPSndRate = 1;
+ else
+ pTxWI->NDPSndRate = 0;
+
+ pTxWI->NDPSndBW = pTransmit->field.BW;
+ pTxWI->iTxBF = 0;
+ }
+ else
+ {
+#ifdef MFB_SUPPORT
+ if (pMacEntry && (pMacEntry->mrqCnt >0) && (pMacEntry->toTxMrq == TRUE))
+ pTxWI->eTxBF = ~(pTransmit->field.eTxBF);
+ else
+#endif /* MFB_SUPPORT */
+ pTxWI->eTxBF = pTransmit->field.eTxBF;
+ pTxWI->iTxBF = pTransmit->field.iTxBF;
+ }
+#endif /* TXBF_SUPPORT */
+
+ pTxWI->TxWIBAWinSize = BASize;
+ pTxWI->TxWIShortGI = pTransmit->field.ShortGI;
+ pTxWI->TxWISTBC = pTransmit->field.STBC;
+#ifdef TXBF_SUPPORT
+ if (pTxBlk->TxSndgPkt == SNDG_TYPE_NDP || pTxBlk->TxSndgPkt == SNDG_TYPE_SOUNDING || pTxWI->eTxBF)
+ pTxWI->TxWISTBC = 0;
+#endif /* TXBF_SUPPORT */
+
+#endif /* DOT11_N_SUPPORT */
+
+ pTxWI->TxWIMCS = pTransmit->field.MCS;
+ pTxWI->TxWIPHYMODE = pTransmit->field.MODE;
+
+
+#ifdef DOT11_N_SUPPORT
+ if (pMacEntry)
+ {
+ if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+ {
+ /* Dynamic MIMO Power Save Mode*/
+ pTxWI->TxWIMIMOps = 1;
+ }
+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
+ {
+ /* Static MIMO Power Save Mode*/
+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+ {
+ pTxWI->TxWIMCS = 7;
+ pTxWI->TxWIMIMOps = 0;
+ }
+ }
+
+ pTxWI->TxWIMpduDensity = pMacEntry->MpduDensity;
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ if (pTxBlk->TxSndgPkt > SNDG_TYPE_DISABLE)
+ {
+ pTxWI->TxWIMCS = 0;
+ pTxWI->TxWIAMPDU = FALSE;
+ }
+#endif /* TXBF_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 */
+
+#ifdef RLT_MAC
+ /* for rate adapation*/
+ pTxWI->TxWIPacketId = pTxWI->TxWIMCS;
+#endif /* RLT_MAC */
+
+
+#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->TxWIPHYMODE == MODE_CCK)
+ pTxWI->TxWIPacketId = 6;
+ }
+#endif /* INF_AMAZON_SE */
+
+
+#ifdef FPGA_MODE
+ if (pAd->fpga_on & 0x2)
+ {
+ pTxWI->TxWIPHYMODE = pAd->data_phy;
+ pTxWI->TxWIMCS = pAd->data_mcs;
+ pTxWI->TxWIBW = pAd->data_bw;
+ pTxWI->TxWIShortGI = pAd->data_gi;
+ if (pAd->data_basize)
+ pTxWI->TxWIBAWinSize = pAd->data_basize;
+ }
+#endif /* FPGA_MODE */
+
+
+}
+
+
+VOID RTMPWriteTxWI_Cache(
+ IN RTMP_ADAPTER *pAd,
+ INOUT TXWI_STRUC *pTxWI,
+ IN TX_BLK *pTxBlk)
+{
+ HTTRANSMIT_SETTING *pTransmit;
+ MAC_TABLE_ENTRY *pMacEntry;
+#ifdef DOT11_N_SUPPORT
+#endif /* DOT11_N_SUPPORT */
+
+
+ /* update TXWI */
+ pMacEntry = pTxBlk->pMacEntry;
+ pTransmit = pTxBlk->pTransmit;
+
+ if (pMacEntry->bAutoTxRateSwitch)
+ {
+ pTxWI->TxWITXOP = IFS_HTTXOP;
+
+ /* If CCK or OFDM, BW must be 20*/
+ pTxWI->TxWIBW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+ pTxWI->TxWIShortGI = pTransmit->field.ShortGI;
+ pTxWI->TxWISTBC = pTransmit->field.STBC;
+
+#ifdef TXBF_SUPPORT
+ if (pTxBlk->TxSndgPkt == SNDG_TYPE_NDP || pTxBlk->TxSndgPkt == SNDG_TYPE_SOUNDING || pTxWI->eTxBF)
+ pTxWI->TxWISTBC = 0;
+#endif /* TXBF_SUPPORT */
+
+ pTxWI->TxWIMCS = pTransmit->field.MCS;
+ pTxWI->TxWIPHYMODE = pTransmit->field.MODE;
+
+#ifdef RLT_MAC
+ /* set PID for TxRateSwitching*/
+ pTxWI->TxWIPacketId = pTransmit->field.MCS;
+#endif /* RLT_MAC */
+
+ }
+
+#ifdef DOT11_N_SUPPORT
+ pTxWI->TxWIAMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
+#ifdef TXBF_SUPPORT
+ if(pTxBlk->TxSndgPkt > SNDG_TYPE_DISABLE)
+ pTxWI->TxWIAMPDU = FALSE;
+#endif /* TXBF_SUPPORT */
+
+ pTxWI->TxWIMIMOps = 0;
+
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->TxWIBW)
+ pTxWI->TxWIBW = (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->TxWIMIMOps = 1;
+ }
+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
+ {
+ /* Static MIMO Power Save Mode*/
+ if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
+ {
+ pTxWI->TxWIMCS = 7;
+ pTxWI->TxWIMIMOps = 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 */
+
+#ifdef TXBF_SUPPORT
+ if (pTxBlk->TxSndgPkt == SNDG_TYPE_SOUNDING)
+ {
+ pTxWI->Sounding = 1;
+ pTxWI->eTxBF = 0;
+ pTxWI->iTxBF = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("ETxBF in RTMPWriteTxWI_Cache(): sending normal sounding, eTxBF=%d\n", pTxWI->eTxBF));
+ }
+ else if (pTxBlk->TxSndgPkt == SNDG_TYPE_NDP)
+ {
+ if (pTxBlk->TxNDPSndgMcs>=16)
+ pTxWI->NDPSndRate = 2;
+ else if (pTxBlk->TxNDPSndgMcs>=8)
+ pTxWI->NDPSndRate = 1;
+ else
+ pTxWI->NDPSndRate = 0;
+ pTxWI->Sounding = 0;
+ pTxWI->eTxBF = 0;
+ pTxWI->iTxBF = 0;
+
+ pTxWI->NDPSndBW = pTransmit->field.BW;
+
+/*
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("%s():ETxBF, sending ndp sounding(BW=%d, Rate=%d, eTxBF=%d)\n",
+ __FUNCTION__, pTxWI->NDPSndBW, pTxWI->NDPSndRate, pTxWI->eTxBF));
+*/
+ }
+ else
+ {
+ pTxWI->Sounding = 0;
+#ifdef MFB_SUPPORT
+ if (pMacEntry && pMacEntry->mrqCnt >0 && pMacEntry->toTxMrq == 1)
+ {
+ pTxWI->eTxBF = ~(pTransmit->field.eTxBF);
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("ETxBF in AP_AMPDU_Frame_Tx(): invert eTxBF\n"));
+ }
+ else
+#endif /* MFB_SUPPORT */
+ pTxWI->eTxBF = pTransmit->field.eTxBF;
+
+ pTxWI->iTxBF = pTransmit->field.iTxBF;
+
+ if (pTxWI->eTxBF || pTxWI->iTxBF)
+ pTxWI->TxWISTBC = 0;
+ }
+
+ if (pTxBlk->TxSndgPkt > SNDG_TYPE_DISABLE)
+ {
+ pTxWI->TxWIMCS = 0;
+ pTxWI->TxWIAMPDU = FALSE;
+ }
+#endif /* TXBF_SUPPORT */
+
+#ifdef HDR_TRANS_SUPPORT
+ if (pTxBlk->NeedTrans )
+ pTxWI->TxWIMPDUByteCnt = pTxBlk->SrcBufLen;
+ else
+#endif /* HDR_TRANS_SUPPORT */
+ pTxWI->TxWIMPDUByteCnt = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+
+#ifdef FPGA_MODE
+ if (pAd->fpga_on & 0x2)
+ {
+ pTxWI->TxWIPHYMODE = pAd->data_phy;
+ pTxWI->TxWIMCS = pAd->data_mcs;
+ pTxWI->TxWIBW = pAd->data_bw;
+ pTxWI->TxWIShortGI = pAd->data_gi;
+ if (pAd->data_basize)
+ pTxWI->TxWIBAWinSize = pAd->data_basize;
+ }
+#endif /* FPGA_MODE */
+
+
+}
+
+
+INT rtmp_mac_set_band(RTMP_ADAPTER *pAd, int band)
+{
+ UINT32 val, band_cfg;
+
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &band_cfg);
+ val = band_cfg & (~0x6);
+ switch (band)
+ {
+ case BAND_5G:
+ val |= 0x02;
+ break;
+ case BAND_24G:
+ default:
+ val |= 0x4;
+ break;
+ }
+
+ if (val != band_cfg)
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, val);
+
+ return TRUE;
+}
+
+
+INT rtmp_mac_set_ctrlch(RTMP_ADAPTER *pAd, INT extch)
+{
+ UINT32 val, band_cfg;
+
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &band_cfg);
+ val = band_cfg & (~0x1);
+ switch (extch)
+ {
+ case EXTCHA_ABOVE:
+ val &= (~0x1);
+ break;
+ case EXTCHA_BELOW:
+ val |= (0x1);
+ break;
+ case EXTCHA_NONE:
+ val &= (~0x1);
+ break;
+ }
+
+ if (val != band_cfg)
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, val);
+
+ return TRUE;
+}
+
+
+INT rtmp_mac_set_mmps(RTMP_ADAPTER *pAd, INT ReduceCorePower)
+{
+ UINT32 mac_val, org_val;
+
+ RTMP_IO_READ32(pAd, 0x1210, &org_val);
+ mac_val = org_val;
+ if (ReduceCorePower)
+ mac_val |= 0x09;
+ else
+ mac_val &= ~0x09;
+
+ if (mac_val != org_val)
+ RTMP_IO_WRITE32(pAd, 0x1210, mac_val);
+
+ return TRUE;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601.bin b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601.bin
new file mode 100644
index 0000000000..62b3894310
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601.bin
Binary files differ
diff --git a/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5.bin b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5.bin
new file mode 100644
index 0000000000..62b3894310
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5.bin
Binary files differ
diff --git a/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5_Debug.bin b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5_Debug.bin
new file mode 100644
index 0000000000..ac487d1aec
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5_Debug.bin
Binary files differ
diff --git a/cleopatre/devkit/mt7601udrv/mcu/rtmp_M51.c b/cleopatre/devkit/mt7601udrv/mcu/rtmp_M51.c
new file mode 100644
index 0000000000..e1972add58
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mcu/rtmp_M51.c
@@ -0,0 +1,710 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_M51.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
+#include "rt_config.h"
+#include "firmware.h"
+
+
+#ifdef RTMP_MAC_USB
+
+/* RT2870 Firmware Spec only used 1 oct for version expression*/
+
+#define FIRMWARE_MINOR_VERSION 7
+#endif /* RTMP_MAC_USB */
+
+/* New 8k byte firmware size for RT3071/RT3072*/
+#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
+#ifdef WOW_SUPPORT
+#define FIRMWAREIMAGE_WOW_LENGTH 0x3000 /* WOW support firmware(12KB) */
+#endif/*WOW_SUPPORT*/
+#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
+#define FIRMWARE_MAJOR_VERSION 0
+
+#define FIRMWAREIMAGEV1_LENGTH 0x1000
+#define FIRMWAREIMAGEV2_LENGTH 0x1000
+#ifdef WOW_SUPPORT
+#define FIRMWAREIMAGEV3_LENGTH 0x2000 /* WOW support firmware */
+#endif/*WOW_SUPPORT*/
+
+
+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)
+{
+ UINT32 i;
+
+ for(i = 0; i < MAX_FIRMWARE_IMAGE_SIZE; i += 4)
+ RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
+
+ return 0;
+}
+
+NDIS_STATUS isMCUNeedToLoadFIrmware(
+ 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 & 0x100) /* check bit 8*/
+ break;
+
+ RTMPusecDelay(1000);
+ } while (Index++ < 100);
+
+ if (Index >= 100)
+ Status = NDIS_STATUS_FAILURE;
+
+ return Status;
+}
+
+NDIS_STATUS isMCUnotReady(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ ULONG Index;
+ UINT32 MacReg;
+
+#ifdef RT65xx
+ // TODO: shiang-6590, fix me, currently firmware is not ready yet, so ignore it!
+ if (IS_RT65XX(pAd)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): Ignore for MCU status check for 6590 now!\n", __FUNCTION__));
+ return Status;
+ }
+#endif /* RT65xx */
+
+#ifdef MT7601
+ if (IS_MT7601(pAd)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): Ignore for MCU status check for MT7601 now!\n", __FUNCTION__));
+ return Status;
+ }
+#endif /* MT7601 */
+
+ 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);
+ }
+
+
+ /* 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);
+
+ 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;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
+ }
+ 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)
+ os_free_mem(NULL, pFirmwareImage);
+
+ /* use default *.bin array */
+ pFirmwareImage = FirmwareImage;
+ FileLength = sizeof(FirmwareImage);
+ }
+
+ /* enable Host program ram write selection */
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
+
+ for(i=0; i<FileLength; i+=4)
+ {
+ firm = pFirmwareImage[i] +
+ (pFirmwareImage[i+3] << 24) +
+ (pFirmwareImage[i+2] << 16) +
+ (pFirmwareImage[i+1] << 8);
+
+ RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
+ }
+
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
+
+ /* initialize BBP R/W access agent */
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+
+ if (flg_default_firm_use == FALSE)
+ {
+ /* use file firmware, free allocated buffer */
+ if (pFirmwareImage != NULL)
+ os_free_mem(NULL, pFirmwareImage);
+ }
+
+ RtmpOSFSInfoChange(&osFSInfo, FALSE);
+#else
+
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PUCHAR pFirmwareImage;
+ ULONG FileLength;
+ UINT32 Version = (pAd->MACVersion >> 16);
+#ifdef RTMP_MAC_USB
+ BOOLEAN Equal = TRUE;
+ UINT32 MacReg1 = 0;
+ UCHAR FVer;
+ UINT16 FCS;
+#endif
+
+
+ pFirmwareImage = FirmwareImage;
+ FileLength = sizeof(FirmwareImage);
+
+#ifdef RTMP_MAC_USB
+ /* check firmware version and checksum in RAM and firmware.h */
+ /* if they are equal, then will skip firmware load procedure */
+ if (isMCUNeedToLoadFIrmware(pAd) == NDIS_STATUS_SUCCESS)
+ {
+ RTMP_IO_READ32(pAd, 0x3FFC, &MacReg1);
+ FVer = (MacReg1 >> 8) & 0x00FF;
+ FCS = (MacReg1 >> 16) & 0xFFFF;
+
+
+#ifdef WOW_SUPPORT
+ if (pAd->WOW_Cfg.bWOWFirmware == TRUE)
+ {
+ UCHAR ver = FirmwareImage[FIRMWAREIMAGEV3_LENGTH+0xFFD];
+ UINT16 sum ;
+
+ NdisCopyMemory(&sum, &FirmwareImage[FIRMWAREIMAGEV3_LENGTH+0xFFE], 2);
+ printk("%s: ver %x/%x, sum %x/%x, mac %x\n", __FUNCTION__, FVer, ver, FCS, sum, MacReg1);
+ if ( FVer != ver || FCS != sum )
+ Equal = FALSE;
+ }
+ else
+#endif /* WOW_SUPPORT */
+ {
+ UCHAR ver = FirmwareImage[FIRMWAREIMAGEV2_LENGTH+0xFFD];
+ UINT16 sum ;
+
+ NdisCopyMemory(&sum, &FirmwareImage[FIRMWAREIMAGEV2_LENGTH+0xFFE], 2);
+ printk("%s: ver %x/%x, sum %x/%x, mac %x\n", __FUNCTION__, FVer, ver, FCS, sum, MacReg1);
+ if ( FVer != ver || FCS != sum )
+ Equal = FALSE;
+ }
+
+ /* do not need to load firmware */
+ if (Equal == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("%s: WOW stops to go into 4K ram codes ...\n", __FUNCTION__));
+
+#ifdef WOW_SUPPORT
+ /* Disable MAC TX/RX */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacReg1);
+ MacReg1 &= ~0xC;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacReg1);
+
+ /* Disable USB TX/RX DMA */
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &MacReg1);
+ MacReg1 &= ~0xC00000;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, MacReg1);
+
+ /* Clear Firmware(bit 8) ready bit to force firmware download*/
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg1);
+ MacReg1 &= ~0x100;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacReg1);
+
+#endif /* WOW_SUPPORT */
+
+ /* prevent CPU to run in 4K ram codes */
+ /* only allow USB vendor request */
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x14,
+ 0x0,
+ 0,
+ NULL,
+ 0);
+
+ /* disable external functions */
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x12,
+ 0x0,
+ 0,
+ NULL,
+ 0);
+ }
+ }
+
+#endif /* RTMP_MAC_USB */
+
+ /* 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
+ {
+#if defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)
+ /* WOW firmware is 12KB */
+ if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
+ {
+ if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_WOW_LENGTH) /* size 0x3000 */
+ {
+ if (pAd->WOW_Cfg.bWOWFirmware == TRUE)
+ {
+ pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV3_LENGTH]; /* WOW offset: 0x2000 */
+ FileLength = FIRMWAREIMAGEV1_LENGTH; /* 0x1000 */
+ DBGPRINT(RT_DEBUG_OFF, ("%s: Load WOW firmware!!\n", __FUNCTION__));
+ }
+ else
+ {
+ pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV2_LENGTH]; /* normal offset: 0x1000 */
+ FileLength = FIRMWAREIMAGEV1_LENGTH; /* 0x1000 */
+ DBGPRINT(RT_DEBUG_OFF, ("%s: Load normal firmware!!\n", __FUNCTION__));
+ }
+
+ }
+ }
+ else
+#endif /* defined(WOW_SUPPORT) && defined(RTMP_MAC_USB) */
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ }
+
+#ifdef RTMP_MAC_USB
+ /* firmware is never loaded or the loadable firmware is different with the firmware in the RAM */
+ if (isMCUNeedToLoadFIrmware(pAd) || Equal == FALSE )
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: We need to load firmware\n"));
+ RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength); /* FirmwareRun VndReq 0x1/0x8 --> initDone = 1 */
+ }
+ else {
+ DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: firmware loaded already\n"));
+ RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x8,
+ 0,
+ NULL,
+ 0);
+ }
+#else
+ RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+#endif /* RTMP_MAC_USB */
+
+#endif
+
+ if (isMCUnotReady(pAd))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s(): MCU is not ready!\n\n\n", __FUNCTION__));
+ Status = NDIS_STATUS_FAILURE;
+ }
+#ifdef RTMP_USB_SUPPORT
+ else
+ {
+ RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, 0, FALSE); /* initialize BBP R/W access agent. */
+ RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0, FALSE);
+ RTUSBWriteMACRegister(pAd, H2M_INT_SRC, 0, FALSE);
+ AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00, FALSE); /* reset rf by MCU supported by new firmware */
+ }
+#ifdef WOW_SUPPORT
+ if (pAd->WOW_Cfg.bEnable == TRUE)
+ {
+ /* Enable MAC TX/RX */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacReg1);
+ MacReg1 |= 0xC;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacReg1);
+
+ /* Enble USB TX/RX DMA */
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &MacReg1);
+ MacReg1 |= 0xC00000;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, MacReg1);
+
+ /* Set Firmware ready bit(bit8) */
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg1);
+ MacReg1 |= 0x100;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacReg1);
+
+ /* need to reset, because interface-up will be normal firmware */
+ pAd->WOW_Cfg.bWOWFirmware = FALSE;
+
+ }
+#endif /* WOW_SUPPORT */
+
+ if (Equal == FALSE)
+ {
+ /* allow all requests (USB vendor request, sleep, wake up, led) */
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x13,
+ 0x0,
+ 0,
+ NULL,
+ 0);
+ }
+
+#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;
+ INT i = 0;
+ int ret;
+
+
+
+
+
+ {
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd) && (!FlgIsNeedLocked))
+ {
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
+ if (ret != 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ return FALSE;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ ret = FALSE;
+ 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))
+ {
+ goto done;
+ }
+ RTMPusecDelay(2);
+ } while(i++ < 100);
+
+ if (i >= 100)
+ {
+ {
+ DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+ }
+ goto done;
+ }
+
+ H2MMailbox.field.Owner = 1; /* pass ownership to MCU*/
+ H2MMailbox.field.CmdToken = Token;
+ H2MMailbox.field.HighByte = Arg1;
+ H2MMailbox.field.LowByte = Arg0;
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+ H2MCmd.word = 0;
+ H2MCmd.field.HostCommand = Command;
+ RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+}
+
+
+ if (Command == WAKE_MCU_CMD)
+ pAd->LastMCUCmd = Command;
+
+ ret = TRUE;
+
+done:
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd) && (!FlgIsNeedLocked))
+ {
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+ return ret;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mcu/rtmp_and.c b/cleopatre/devkit/mt7601udrv/mcu/rtmp_and.c
new file mode 100644
index 0000000000..4f81e1940b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mcu/rtmp_and.c
@@ -0,0 +1,2071 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_and.c
+
+ Abstract:
+ on-chip CPU related codes
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#include "rt_config.h"
+
+
+#ifdef RT_BIG_ENDIAN
+typedef struct GNU_PACKED _TXINFO_NMAC_CMD_PKT{
+ UINT32 info_type:2;
+ UINT32 d_port:3;
+ UINT32 cmd_type:7;
+ UINT32 cmd_seq:4;
+ UINT32 pkt_len:16;
+}TXINFO_NMAC_CMD_PKT;
+#else
+typedef struct GNU_PACKED _TXINFO_NMAC_CMD_PKT {
+ UINT32 pkt_len:16;
+ UINT32 cmd_seq:4;
+ UINT32 cmd_type:7;
+ UINT32 d_port:3;
+ UINT32 info_type:2;
+}TXINFO_NMAC_CMD_PKT;
+#endif /* RT_BIG_ENDIAN */
+
+
+
+
+#ifdef RTMP_USB_SUPPORT
+
+USBHST_STATUS USBUploadFWComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
+{
+ VOID *SentToMCUDone = RTMP_OS_USB_CONTEXT_GET(pURB);
+
+ RtmpComplete(SentToMCUDone);
+}
+
+
+static NDIS_STATUS USBLoadIVB(RTMP_ADAPTER *pAd)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UINT32 i;
+ USHORT Value;
+ USHORT Index;
+ USHORT Temp;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x12,
+ 0x00,
+ pChipCap->FWImageName + 32,
+ 64);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Upload IVB Fail\n"));
+ return Status;
+ }
+
+ return Status;
+}
+
+
+NDIS_STATUS USBLoadFirmwareToAndes(RTMP_ADAPTER *pAd)
+{
+ PURB pURB;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ ra_dma_addr_t DataDMA;
+ PUCHAR DataBuffer;
+ TXINFO_NMAC_CMD *TxInfoCmd;
+ INT32 SentLen;
+ UINT32 CurLen;
+ UINT32 MACValue, Loop = 0;
+ USHORT Value;
+ INT Ret;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ USB_DMA_CFG_STRUC UsbCfg;
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+ //struct completion SentToMCUDone;
+ VOID *SentToMCUDone;
+ UINT32 ILMLen, DLMLen;
+ USHORT FWVersion, BuildVersion;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
+
+ if (pChipCap->IsComboChip)
+ {
+loadfw_protect:
+ RTUSBReadMACRegister(pAd, SEMAPHORE_00, &MACValue);
+ Loop++;
+
+ if (((MACValue & 0x01) == 0) && (Loop < 10000))
+ goto loadfw_protect;
+ }
+
+ /* Enable USB_DMA_CFG */
+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, 0xC00000, FALSE);
+
+ /* Check MCU if ready */
+ RTUSBReadMACRegister(pAd, COM_REG0, &MACValue);
+
+ if (MACValue == 0x01)
+ goto error0;
+
+ RTUSBVenderReset(pAd);
+ //mdelay(5);
+ RtmpOsMsDelay(5);
+
+ ILMLen = (*(pChipCap->FWImageName + 3) << 24) | (*(pChipCap->FWImageName + 2) << 16) |
+ (*(pChipCap->FWImageName + 1) << 8) | (*pChipCap->FWImageName);
+
+ DLMLen = (*(pChipCap->FWImageName + 7) << 24) | (*(pChipCap->FWImageName + 6) << 16) |
+ (*(pChipCap->FWImageName + 5) << 8) | (*(pChipCap->FWImageName + 4));
+
+ FWVersion = (*(pChipCap->FWImageName + 11) << 8) | (*(pChipCap->FWImageName + 10));
+
+ BuildVersion = (*(pChipCap->FWImageName + 9) << 8) | (*(pChipCap->FWImageName + 8));
+
+ DBGPRINT(RT_DEBUG_OFF, ("FW Version:%d.%d.%02d ", (FWVersion & 0xf000) >> 8,
+ (FWVersion & 0x0f00) >> 8, FWVersion & 0x00ff));
+ DBGPRINT(RT_DEBUG_OFF, ("Build:%x\n", BuildVersion));
+ DBGPRINT(RT_DEBUG_OFF, ("Build Time:"));
+
+ for (Loop = 0; Loop < 16; Loop++)
+ DBGPRINT(RT_DEBUG_OFF, ("%c", *(pChipCap->FWImageName + 16 + Loop)));
+
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+
+ DBGPRINT(RT_DEBUG_OFF, ("ILM Length = %d(bytes)\n", ILMLen));
+ DBGPRINT(RT_DEBUG_OFF, ("DLM Length = %d(bytes)\n", DLMLen));
+
+ RTMP_IO_WRITE32(pAd, 0xa44, 0x0);
+
+ RTMP_IO_WRITE32(pAd, 0x230, 0x84210);
+ //RTMP_IO_WRITE32(pAd, 0x230, 0x41210);
+
+ RTMP_IO_WRITE32(pAd, 0x400, 0x80c00);
+
+ RTMP_IO_WRITE32(pAd, 0x800, 0x01);
+
+ RTMP_IO_READ32(pAd, 0x0404, &MACValue);
+ MACValue |= 0xF;
+ RTMP_IO_WRITE32(pAd, 0x0404, MACValue);
+
+ /* Enable FCE */
+ RTMP_IO_WRITE32(pAd, FCE_PSE_CTRL, 0x01);
+
+ /* Enable USB_DMA_CFG */
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0xC00000);
+
+#ifdef MT7601
+ if ( IS_MT7601(pAd) )
+ {
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word);
+ UsbCfg.field.TxClear = 1;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word);
+ UsbCfg.field.TxClear = 0;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word);
+ }
+#endif /* MT7601 */
+
+ /* FCE tx_fs_base_ptr */
+ RTMP_IO_WRITE32(pAd, TX_CPU_PORT_FROM_FCE_BASE_PTR, 0x400230);
+
+ /* FCE tx_fs_max_cnt */
+ RTMP_IO_WRITE32(pAd, TX_CPU_PORT_FROM_FCE_MAX_COUNT, 0x01);
+
+ /* FCE pdma enable */
+ RTMP_IO_WRITE32(pAd, FCE_PDMA_GLOBAL_CONF, 0x44);
+
+ /* FCE skip_fs_en */
+ RTMP_IO_WRITE32(pAd, FCE_SKIP_FS, 0x03);
+
+ /* Allocate URB */
+ pURB = RTUSB_ALLOC_URB(0);
+
+ if (!pURB)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Can not allocate URB\n"));
+ Status = NDIS_STATUS_RESOURCES;
+ goto error0;
+ }
+
+ /* Allocate TransferBuffer */
+ DataBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, 14592, &DataDMA);
+
+ if (!DataBuffer)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ goto error1;
+ }
+
+
+ DBGPRINT(RT_DEBUG_OFF, ("Loading FW"));
+
+ //init_completion(&SentToMCUDone);
+ SentToMCUDone = RtmpInitCompletion();
+
+ CurLen = 0x40;
+
+ /* Loading ILM */
+ while (1)
+ {
+/* ++ dump firmware ++ */
+/* ++ dump firmware ++ */
+
+ SentLen = (ILMLen - CurLen) >= 14336 ? 14336 : (ILMLen - CurLen);
+
+ if (SentLen > 0)
+ {
+ TxInfoCmd = (TXINFO_NMAC_CMD *)DataBuffer;
+ TxInfoCmd->info_type = CMD_PACKET;
+ TxInfoCmd->pkt_len = SentLen;
+ TxInfoCmd->d_port = CPU_TX_PORT;
+
+/* ++ dump firmware ++ */
+/* ++ dump firmware ++ */
+
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)TxInfoCmd, TYPE_TXINFO);
+#endif
+ NdisMoveMemory(DataBuffer + sizeof(*TxInfoCmd), pChipCap->FWImageName + 32 + CurLen, SentLen);
+
+ NdisZeroMemory(DataBuffer + sizeof(*TxInfoCmd) + SentLen, 4);
+
+ Value = CurLen & 0xFFFF;
+
+ /* Set FCE DMA descriptor */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x230,
+ NULL,
+ 0);
+
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA descriptor fail\n"));
+ goto error2;
+ }
+
+ Value = ((CurLen & 0xFFFF0000) >> 16);
+
+ /* Set FCE DMA descriptor */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x232,
+ NULL,
+ 0);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA descriptor fail\n"));
+ goto error2;
+ }
+
+
+
+ CurLen += SentLen;
+
+ while ((SentLen % 4) != 0)
+ SentLen++;
+
+ Value = ((SentLen << 16) & 0xFFFF);
+
+ /* Set FCE DMA length */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x234,
+ NULL,
+ 0);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA length fail\n"));
+ goto error2;
+ }
+
+ Value = (((SentLen << 16) & 0xFFFF0000) >> 16);
+
+ /* Set FCE DMA length */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x236,
+ NULL,
+ 0);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA length fail\n"));
+ goto error2;
+ }
+
+ /* Initialize URB descriptor */
+ RTUSB_FILL_HTTX_BULK_URB(pURB,
+ pObj->pUsb_Dev,
+ pChipCap->CommandBulkOutAddr,
+ DataBuffer,
+ SentLen + sizeof(*TxInfoCmd) + 4,
+ USBUploadFWComplete,
+ //&SentToMCUDone,
+ SentToMCUDone,
+ DataDMA);
+
+ Status = RTUSB_SUBMIT_URB(pURB);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("SUBMIT URB fail\n"));
+ goto error2;
+ }
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: submit URB, SentLen = %d, ILMLen = %d, CurLen = %d\n", __FUNCTION__, SentLen, ILMLen, CurLen));
+
+ //if (!wait_for_completion_timeout(&SentToMCUDone, msecs_to_jiffies(1000)))
+ if (!RtmpWaitForCompletionTimeout(SentToMCUDone, RtmpMsecsToJiffies(1000)))
+ {
+ RTUSB_UNLINK_URB(pURB);
+ Ret = NDIS_STATUS_FAILURE;
+ DBGPRINT(RT_DEBUG_ERROR, ("Upload FW timeout\n"));
+ goto error2;
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("."));
+
+ RTMP_IO_READ32(pAd, TX_CPU_PORT_FROM_FCE_CPU_DESC_INDEX, &MACValue);
+ MACValue++;
+ RTMP_IO_WRITE32(pAd, TX_CPU_PORT_FROM_FCE_CPU_DESC_INDEX, MACValue);
+
+/* ++ dump firmware ++ */
+/* ++ dump firmware ++ */
+
+ }
+ else
+ {
+ break;
+ }
+
+ /* Check if DMA done */
+ Loop = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, COM_REG1, &MACValue);
+ if (MACValue & 0x80000000) // DDONE 0x400234, bit[31]
+ break;
+ Loop++;
+ RtmpOsMsDelay(5);
+ } while (Loop <= 100);
+
+ }
+
+ os_free_mem(NULL, SentToMCUDone);
+
+ //init_completion(&SentToMCUDone);
+ SentToMCUDone = RtmpInitCompletion();
+ CurLen = 0x00;
+
+ /* Loading DLM */
+ while (1)
+ {
+ SentLen = (DLMLen - CurLen) >= 14336 ? 14336 : (DLMLen - CurLen);
+
+ if (SentLen > 0)
+ {
+ TxInfoCmd = (TXINFO_NMAC_CMD *)DataBuffer;
+ TxInfoCmd->info_type = CMD_PACKET;
+ TxInfoCmd->pkt_len = SentLen;
+ TxInfoCmd->d_port = CPU_TX_PORT;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)TxInfoCmd, TYPE_TXINFO);
+#endif
+ NdisMoveMemory(DataBuffer + sizeof(*TxInfoCmd), pChipCap->FWImageName + 32 + ILMLen + CurLen, SentLen);
+
+ NdisZeroMemory(DataBuffer + sizeof(*TxInfoCmd) + SentLen + 4, 4);
+
+ Value = ((CurLen + 0x80000) & 0xFFFF);
+
+ /* Set FCE DMA descriptor */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x230,
+ NULL,
+ 0);
+
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA descriptor fail\n"));
+ goto error2;
+ }
+
+ Value = (((CurLen + 0x80000) & 0xFFFF0000) >> 16);
+
+ /* Set FCE DMA descriptor */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x232,
+ NULL,
+ 0);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA descriptor fail\n"));
+ goto error2;
+ }
+
+
+
+ CurLen += SentLen;
+
+ while ((SentLen % 4) != 0)
+ SentLen++;
+
+ Value = ((SentLen << 16) & 0xFFFF);
+
+ /* Set FCE DMA length */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x234,
+ NULL,
+ 0);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA length fail\n"));
+ goto error2;
+ }
+
+ Value = (((SentLen << 16) & 0xFFFF0000) >> 16);
+
+ /* Set FCE DMA length */
+ Status = RTUSB_VendorRequest(pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x42,
+ Value,
+ 0x236,
+ NULL,
+ 0);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set FCE DMA length fail\n"));
+ goto error2;
+ }
+
+ /* Initialize URB descriptor */
+ RTUSB_FILL_HTTX_BULK_URB(pURB,
+ pObj->pUsb_Dev,
+ pChipCap->CommandBulkOutAddr,
+ DataBuffer,
+ SentLen + sizeof(*TxInfoCmd) + 4,
+ USBUploadFWComplete,
+ //&SentToMCUDone,
+ SentToMCUDone,
+ DataDMA);
+
+ Status = RTUSB_SUBMIT_URB(pURB);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("SUBMIT URB fail\n"));
+ goto error2;
+ }
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: submit URB, SentLen = %d, DLMLen = %d, CurLen = %d\n", __FUNCTION__, SentLen, DLMLen, CurLen));
+
+ //if (!wait_for_completion_timeout(&SentToMCUDone, msecs_to_jiffies(1000)))
+ if (!RtmpWaitForCompletionTimeout(SentToMCUDone, RtmpMsecsToJiffies(1000)))
+ {
+ RTUSB_UNLINK_URB(pURB);
+ Ret = NDIS_STATUS_FAILURE;
+ DBGPRINT(RT_DEBUG_ERROR, ("Upload FW timeout\n"));
+ goto error2;
+ }
+ DBGPRINT(RT_DEBUG_OFF, ("."));
+
+ RTUSBReadMACRegister(pAd, TX_CPU_PORT_FROM_FCE_CPU_DESC_INDEX, &MACValue);
+ MACValue++;
+ RTUSBWriteMACRegister(pAd, TX_CPU_PORT_FROM_FCE_CPU_DESC_INDEX, MACValue, FALSE);
+ }
+ else
+ {
+ break;
+ }
+
+ //mdelay(5);
+ RtmpOsMsDelay(5);
+ }
+
+ os_free_mem(NULL, SentToMCUDone);
+
+ /* Upload new 64 bytes interrupt vector */
+ DBGPRINT(RT_DEBUG_OFF, ("\n"));
+ Status = USBLoadIVB(pAd);
+
+ /* Check MCU if ready */
+ Loop = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, COM_REG0, &MACValue);
+ if (MACValue == 0x1)
+ break;
+ RtmpOsMsDelay(10);
+ Loop++;
+ } while (Loop <= 100);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: COM_REG0(0x%x) = 0x%x\n", __FUNCTION__, COM_REG0, MACValue));
+
+ if (MACValue != 0x1)
+ Status = NDIS_STATUS_FAILURE;
+
+error2:
+ /* Free TransferBuffer */
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, 14592,
+ DataBuffer, DataDMA);
+
+error1:
+ /* Free URB */
+ RTUSB_FREE_URB(pURB);
+
+error0:
+ if (pChipCap->IsComboChip)
+ RTUSBWriteMACRegister(pAd, SEMAPHORE_00, 0x1, FALSE);
+ return Status;
+}
+#endif /* RTMP_USB_SUPPORT */
+
+
+VOID MCUCtrlInit(PRTMP_ADAPTER pAd)
+{
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_POLL_IDLE);
+ NdisZeroMemory(MCtrl, sizeof(*MCtrl));
+ MCtrl->CmdSeq = 0;
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
+ NdisAllocateSpinLock(pAd, &MCtrl->CmdRspEventListLock);
+ DlListInit(&MCtrl->CmdRspEventList);
+}
+
+
+VOID MCUCtrlExit(PRTMP_ADAPTER pAd)
+{
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+ struct CMD_RSP_EVENT *CmdRspEvent, *CmdRspEventTmp;
+ INT32 Ret;
+ unsigned long IrqFlags;
+
+ RtmpOsMsDelay(30);
+
+ RTMP_IRQ_LOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+ DlListForEachSafe(CmdRspEvent, CmdRspEventTmp, &MCtrl->CmdRspEventList, struct CMD_RSP_EVENT, List)
+ {
+ if (!CmdRspEvent->NeedWait)
+ {
+ DlListDel(&CmdRspEvent->List);
+ os_free_mem(NULL, CmdRspEvent);
+ }
+ }
+ RTMP_IRQ_UNLOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+
+ NdisFreeSpinLock(&MCtrl->CmdRspEventListLock);
+ NdisZeroMemory(MCtrl, sizeof(*MCtrl));
+}
+
+
+BOOLEAN IsInBandCmdProcessing(PRTMP_ADAPTER pAd)
+{
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+ unsigned long IrqFlags;
+ BOOLEAN Ret;
+
+ RTMP_IRQ_LOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+
+ if (DlListEmpty(&MCtrl->CmdRspEventList))
+ Ret = FALSE;
+ else
+ Ret = TRUE;
+
+ RTMP_IRQ_UNLOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+
+ return Ret;
+}
+
+
+UCHAR GetCmdRspNum(PRTMP_ADAPTER pAd)
+{
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+ unsigned long IrqFlags;
+ UCHAR Num = 0;
+ Num = DlListLen(&MCtrl->CmdRspEventList);
+
+ return Num;
+}
+
+
+static inline UCHAR GetCmdSeq(PRTMP_ADAPTER pAd)
+{
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+ struct CMD_RSP_EVENT *CmdRspEvent, *CmdRspEventTmp;
+ unsigned long IrqFlags;
+ UCHAR TryCount = 0;
+
+ RTMP_IRQ_LOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+get_seq:
+ MCtrl->CmdSeq >= 0xf ? MCtrl->CmdSeq = 1 : MCtrl->CmdSeq++;
+ TryCount++;
+ DlListForEachSafe(CmdRspEvent, CmdRspEventTmp, &MCtrl->CmdRspEventList, struct CMD_RSP_EVENT, List)
+ {
+ if (CmdRspEvent->CmdSeq == MCtrl->CmdSeq)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Command(seq: %d) is still running\n", MCtrl->CmdSeq));
+
+ if (TryCount > 128)
+ {
+ break;
+ }
+ else
+ {
+ printk("CmdRspNum = %d\n", GetCmdRspNum(pAd));
+ goto get_seq;
+ }
+ }
+ }
+ RTMP_IRQ_UNLOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+
+ return MCtrl->CmdSeq;
+}
+
+
+#ifdef RTMP_MAC_USB
+
+
+USBHST_STATUS USBKickOutCmdComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
+{
+ //struct completion *SentToMCUDone = (struct completion *)RTMP_OS_USB_CONTEXT_GET(pURB);
+
+ //complete(SentToMCUDone);
+
+ VOID *SentToMCUDone = RTMP_OS_USB_CONTEXT_GET(pURB);
+
+ RtmpComplete(SentToMCUDone);
+}
+
+
+INT USBKickOutCmd(PRTMP_ADAPTER pAd, UCHAR *Buf, UINT32 Len)
+{
+ PURB pURB;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ PCHAR DataBuffer;
+ ra_dma_addr_t DataDMA;
+ INT Ret;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ //struct completion SentToMCUDone;
+ VOID *SentToMCUDone;
+
+ //if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ //return NDIS_STATUS_FAILURE;
+
+ /* Allocate URB */
+ pURB = RTUSB_ALLOC_URB(0);
+
+ if (!pURB)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Can not allocate URB\n"));
+ Status = NDIS_STATUS_RESOURCES;
+ goto error0;
+ }
+
+ /* Allocate TransferBuffer */
+ DataBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, 512, &DataDMA);
+
+ if (!DataBuffer)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ goto error1;
+ }
+
+ NdisMoveMemory(DataBuffer, Buf, Len);
+
+ NdisZeroMemory(DataBuffer + Len, 4);
+
+
+ //init_completion(&SentToMCUDone);
+ SentToMCUDone = RtmpInitCompletion();
+
+ /* Initialize URB descriptor */
+ RTUSB_FILL_HTTX_BULK_URB(pURB,
+ pObj->pUsb_Dev,
+ pChipCap->CommandBulkOutAddr,
+ DataBuffer,
+ Len + 4,
+ USBKickOutCmdComplete,
+ //&SentToMCUDone,
+ SentToMCUDone,
+ DataDMA);
+
+ Status = RTUSB_SUBMIT_URB(pURB);
+
+ if (Status)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("SUBMIT URB fail\n"));
+ goto error2;
+ }
+
+ //if (!wait_for_completion_timeout(&SentToMCUDone, msecs_to_jiffies(500)))
+ if (!RtmpWaitForCompletionTimeout(SentToMCUDone, RtmpMsecsToJiffies(500)))
+ {
+ RTUSB_UNLINK_URB(pURB);
+ Ret = NDIS_STATUS_FAILURE;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Timeout\n", __FUNCTION__));
+ hex_dump("CmdBuffer", (char *)DataBuffer, Len + 4);
+ }
+
+error2:
+ /* Free TransferBuffer */
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, 512,
+ DataBuffer, DataDMA);
+
+ os_free_mem(NULL, SentToMCUDone);
+
+
+error1:
+ /* Free URB */
+ RTUSB_FREE_URB(pURB);
+
+error0:
+ return Status;
+}
+#endif /* RTMP_MAC_USB */
+
+
+INT AsicSendCmdToAndes(PRTMP_ADAPTER pAd, struct CMD_UNIT *CmdUnit)
+{
+ UINT32 VarLen;
+ UCHAR *Pos, *Buf;
+ TXINFO_NMAC_CMD *TxInfoCmd;
+ INT32 Ret = NDIS_STATUS_SUCCESS;
+ struct MCU_CTRL *MCtrl = &pAd->MCUCtrl;
+ struct CMD_RSP_EVENT *CmdRspEvent;
+ ULONG Expire;
+ unsigned long IrqFlags;
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: !fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD && fRTMP_ADAPTER_IDLE_RADIO_OFF\n", __FUNCTION__));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ if (pAd->PM_FlgSuspend)
+ return NDIS_STATUS_FAILURE;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_IDLE_RADIO_OFF | fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ return NDIS_STATUS_FAILURE;
+
+ VarLen = sizeof(*TxInfoCmd) + CmdUnit->u.ANDES.CmdPayloadLen;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ NdisZeroMemory(Buf, VarLen);
+
+ Pos = Buf;
+ TxInfoCmd = (TXINFO_NMAC_CMD *)Pos;
+ TxInfoCmd->info_type = CMD_PACKET;
+ TxInfoCmd->d_port = CPU_TX_PORT;
+ TxInfoCmd->cmd_type = CmdUnit->u.ANDES.Type;
+
+ if (CmdUnit->u.ANDES.NeedRsp)
+ {
+ TxInfoCmd->cmd_seq = GetCmdSeq(pAd);
+
+ //printk("cmd seq = %d\n", TxInfoCmd->cmd_seq);
+
+ os_alloc_mem(NULL, (UCHAR **)&CmdRspEvent, sizeof(*CmdRspEvent));
+
+ if (!CmdRspEvent)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Not available memory\n", __FUNCTION__));
+ Ret = NDIS_STATUS_RESOURCES;
+ goto error;
+ }
+
+ NdisZeroMemory(CmdRspEvent, sizeof(*CmdRspEvent));
+
+ CmdRspEvent->CmdSeq = TxInfoCmd->cmd_seq;
+ CmdRspEvent->Timeout = CmdUnit->u.ANDES.Timeout;
+ CmdRspEvent->RspPayload = &CmdUnit->u.ANDES.RspPayload;
+ CmdRspEvent->RspPayloadLen = &CmdUnit->u.ANDES.RspPayloadLen;
+
+ if (CmdUnit->u.ANDES.NeedWait)
+ {
+ CmdRspEvent->NeedWait = TRUE;
+ CmdRspEvent->AckDone = RtmpInitCompletion();
+ }
+
+ RTMP_IRQ_LOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+ DlListAddTail(&MCtrl->CmdRspEventList, &CmdRspEvent->List);
+ RTMP_IRQ_UNLOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+ }
+ else
+ {
+ TxInfoCmd->cmd_seq = 0;
+ }
+
+ TxInfoCmd->pkt_len = CmdUnit->u.ANDES.CmdPayloadLen;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)TxInfoCmd, TYPE_TXINFO);
+#endif
+
+ Pos += sizeof(*TxInfoCmd);
+
+ NdisMoveMemory(Pos, CmdUnit->u.ANDES.CmdPayload, CmdUnit->u.ANDES.CmdPayloadLen);
+
+#ifdef RTMP_USB_SUPPORT
+ USBKickOutCmd(pAd, Buf, VarLen);
+#endif
+
+
+ /* Wait for Command Rsp */
+ if (CmdUnit->u.ANDES.NeedWait) {
+ ULONG Timeout = CmdUnit->u.ANDES.Timeout;
+ Expire = Timeout ? RtmpMsecsToJiffies(Timeout) : RtmpMsecsToJiffies(300);
+ if (!RtmpWaitForCompletionTimeout(CmdRspEvent->AckDone, Expire))
+ {
+ Ret = NDIS_STATUS_FAILURE;
+ DBGPRINT(RT_DEBUG_ERROR, ("Wait for command response timeout(300ms)\n"));
+ }
+
+ RTMP_IRQ_LOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+ DlListDel(&CmdRspEvent->List);
+ os_free_mem(NULL, CmdRspEvent->AckDone);
+ os_free_mem(NULL, CmdRspEvent);
+ RTMP_IRQ_UNLOCK(&MCtrl->CmdRspEventListLock, IrqFlags);
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+
+ return Ret;
+}
+
+static VOID CmdDoneHandler(PRTMP_ADAPTER pAd, UCHAR *Data)
+{
+
+
+}
+
+
+static VOID CmdErrorHandler(PRTMP_ADAPTER pAd, UCHAR *Data)
+{
+
+
+}
+
+
+static VOID CmdRetryHandler(PRTMP_ADAPTER pAd, UCHAR *Data)
+{
+
+
+}
+
+
+static VOID PwrRspEventHandler(PRTMP_ADAPTER pAd, UCHAR *Data)
+{
+
+
+}
+
+
+static VOID WowRspEventHandler(PRTMP_ADAPTER pAd, UCHAR *Data)
+{
+
+
+}
+
+
+static VOID CarrierDetectRspEventHandler(PRTMP_ADAPTER pAd, UCHAR *Data)
+{
+
+
+
+}
+
+
+static VOID DFSDetectRspEventHandler(PRTMP_ADAPTER pAd, UCHAR *Data)
+{
+
+
+
+}
+
+
+CMD_RSP_HANDLER CmdRspHandlerTable[] =
+{
+ CmdDoneHandler,
+ CmdErrorHandler,
+ CmdRetryHandler,
+ PwrRspEventHandler,
+ WowRspEventHandler,
+ CarrierDetectRspEventHandler,
+ DFSDetectRspEventHandler,
+};
+
+
+INT AndesBurstWrite(PRTMP_ADAPTER pAd, UINT32 Offset, UINT32 *Data, UINT32 Cnt)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen, OffsetNum, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ BOOLEAN LastPacket = FALSE;
+
+ OffsetNum = Cnt / ((pChipCap->InbandPacketMaxLen - sizeof(Offset)) / 4);
+
+ if (Cnt % ((pChipCap->InbandPacketMaxLen - sizeof(Offset)) / 4))
+ VarLen = sizeof(Offset) * (OffsetNum + 1) + 4 * Cnt;
+ else
+ VarLen = sizeof(Offset) * OffsetNum + 4 * Cnt;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ Value = cpu2le32(Offset + pChipCap->WlanMemmapOffset + CurIndex * 4);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ for (i = 0; i < ((SentLen - 4) / 4); i++)
+ {
+ Value = cpu2le32(Data[i + CurIndex]);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ };
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_BURST_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket && (Cnt > 1))
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += ((SentLen - 4) / 4);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesBurstRead(PRTMP_ADAPTER pAd, UINT32 Offset, UINT32 Cnt, UINT32 *Data)
+{
+ struct CMD_UNIT CmdUnit;
+ UINT32 CurLen = 0, CmdLen, RspLen, OffsetNum, ReceiveLen;
+ CHAR *Pos, *Pos1, *CmdBuf, *RspBuf, *CurCmdHeader, *CurRspHeader;
+ UINT32 i, Value, Status = NDIS_STATUS_SUCCESS, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+
+ OffsetNum = Cnt / ((pChipCap->InbandPacketMaxLen - sizeof(Offset)) / 4);
+
+ if (Cnt % ((pChipCap->InbandPacketMaxLen - sizeof(Offset)) / 4))
+ {
+ CmdLen = 8 * (OffsetNum + 1);
+ RspLen = sizeof(Offset) * (OffsetNum + 1) + 4 * Cnt;
+ }
+ else
+ {
+ CmdLen = 8 * OffsetNum;
+ RspLen = sizeof(Offset) * OffsetNum + 4 * Cnt;
+ }
+
+ os_alloc_mem(pAd, (UCHAR **)&CmdBuf, CmdLen);
+ os_alloc_mem(pAd, (UCHAR **)&RspBuf, RspLen);
+
+ Pos = CmdBuf;
+ Pos1 = RspBuf;
+
+ while (CurLen < RspLen)
+ {
+ ReceiveLen = (RspLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen
+ : (RspLen - CurLen);
+
+ CurCmdHeader = Pos;
+ CurRspHeader = Pos1;
+
+ Value = cpu2le32(Offset + pChipCap->WlanMemmapOffset + CurIndex * 4);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ Value = cpu2le32((ReceiveLen - 4) / 4);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+ CmdUnit.u.ANDES.Type = CMD_BURST_READ;
+ CmdUnit.u.ANDES.CmdPayloadLen = 8;
+ CmdUnit.u.ANDES.CmdPayload = CurCmdHeader;
+ CmdUnit.u.ANDES.RspPayload = CurRspHeader;
+ CmdUnit.u.ANDES.RspPayloadLen = ReceiveLen;
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ if (CmdUnit.u.ANDES.RspPayloadLen == ReceiveLen)
+ {
+ NdisMoveMemory(&Data[CurIndex], CmdUnit.u.ANDES.RspPayload + 4, CmdUnit.u.ANDES.RspPayloadLen - 4);
+ Pos1 += ReceiveLen;
+
+ for (i = 0; i < (ReceiveLen - 4) / 4; i++)
+ {
+ Data[i + CurIndex] = le2cpu32(Data[i + CurIndex]);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Rsp len(%d) != Expect len (%d)\n",
+ __FUNCTION__, CmdUnit.u.ANDES.RspPayloadLen, ReceiveLen));
+
+ Status = NDIS_STATUS_FAILURE;
+
+ goto error;
+ }
+
+ CurIndex += ((ReceiveLen - 4) / 4);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+
+ os_free_mem(NULL, CmdBuf);
+ os_free_mem(NULL, RspBuf);
+
+ return Status;
+}
+
+
+INT AndesRandomRead(PRTMP_ADAPTER pAd, RTMP_REG_PAIR *RegPair, UINT32 Num)
+{
+ struct CMD_UNIT CmdUnit;
+ UINT32 VarLen = Num * 8, CurLen = 0, ReceiveLen;
+ CHAR *Pos, *Pos1, *CmdBuf, *RspBuf, *CurCmdHeader, *CurRspHeader;
+ UINT32 i, Value, Status = NDIS_STATUS_SUCCESS, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+
+ os_alloc_mem(pAd, (UCHAR **)&CmdBuf, VarLen);
+ os_alloc_mem(pAd, (UCHAR **)&RspBuf, VarLen);
+
+ NdisZeroMemory(CmdBuf, VarLen);
+
+ Pos = CmdBuf;
+ Pos1 = RspBuf;
+
+ while (CurLen < VarLen)
+ {
+ ReceiveLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen
+ : (VarLen - CurLen);
+
+ CurCmdHeader = Pos;
+ CurRspHeader = Pos1;
+
+ for (i = 0; i < ReceiveLen / 8; i++)
+ {
+ Value = cpu2le32(RegPair[i + CurIndex].Register + pChipCap->WlanMemmapOffset);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 8;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_READ;
+ CmdUnit.u.ANDES.CmdPayloadLen = ReceiveLen;
+ CmdUnit.u.ANDES.CmdPayload = CurCmdHeader;
+ CmdUnit.u.ANDES.RspPayload = CurRspHeader;
+ CmdUnit.u.ANDES.RspPayloadLen = ReceiveLen;
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ if (CmdUnit.u.ANDES.RspPayloadLen == ReceiveLen)
+ {
+ for (i = 0; i < ReceiveLen / 8; i++)
+ {
+ NdisMoveMemory(&RegPair[i + CurIndex].Value, CmdUnit.u.ANDES.RspPayload + 8 * i + 4, 4);
+ RegPair[i + CurIndex].Value = le2cpu32(RegPair[i + CurIndex].Value);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Rsp len(%d) != Expect len (%d)\n",
+ __FUNCTION__, CmdUnit.u.ANDES.RspPayloadLen, ReceiveLen));
+
+ Status = NDIS_STATUS_FAILURE;
+
+ goto error;
+ }
+
+ CurIndex += ReceiveLen / 8;
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, CmdBuf);
+ os_free_mem(NULL, RspBuf);
+
+ return Status;
+}
+
+
+INT AndesRFRandomRead(PRTMP_ADAPTER pAd, BANK_RF_REG_PAIR *RegPair, UINT32 Num)
+{
+ struct CMD_UNIT CmdUnit;
+ UINT32 VarLen = Num * 8, CurLen = 0, ReceiveLen;
+ CHAR *Pos, *Pos1, *CmdBuf, *RspBuf, *CurCmdHeader, *CurRspHeader;
+ UINT32 i, Value, Status = NDIS_STATUS_SUCCESS, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+
+ os_alloc_mem(pAd, (UCHAR **)&CmdBuf, VarLen);
+ os_alloc_mem(pAd, (UCHAR **)&RspBuf, VarLen);
+
+ NdisZeroMemory(CmdBuf, VarLen);
+ Pos = CmdBuf;
+ Pos1 = RspBuf;
+
+ while (CurLen < VarLen)
+ {
+ ReceiveLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen
+ : (VarLen - CurLen);
+
+ CurCmdHeader = Pos;
+ CurRspHeader = Pos1;
+
+ for (i = 0; i < ReceiveLen / 8; i++)
+ {
+ Value = 0;
+
+ /* RF selection */
+ Value = (Value & ~0x80000000) | 0x80000000;
+
+ /* RF bank */
+ Value = (Value & ~0x00ff0000) | (RegPair[i + CurIndex].Bank << 16);
+
+ /* RF Index */
+ Value = (Value & ~0x0000ffff) | RegPair[i + CurIndex].Register;
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 8;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_READ;
+ CmdUnit.u.ANDES.CmdPayloadLen = ReceiveLen;
+ CmdUnit.u.ANDES.CmdPayload = CurCmdHeader;
+ CmdUnit.u.ANDES.RspPayload = CurRspHeader;
+ CmdUnit.u.ANDES.RspPayloadLen = ReceiveLen;
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+
+ if (CmdUnit.u.ANDES.RspPayloadLen == ReceiveLen)
+ {
+ for (i = 0; i < ReceiveLen / 8; i++)
+ {
+ NdisMoveMemory(&RegPair[i + CurIndex].Value, CmdUnit.u.ANDES.RspPayload + 8 * i + 4, 1);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Rsp len(%d) != Expect len (%d)\n",
+ __FUNCTION__, CmdUnit.u.ANDES.RspPayloadLen, ReceiveLen));
+
+ Status = NDIS_STATUS_FAILURE;
+
+ goto error;
+ }
+
+ CurIndex += ReceiveLen / 8;
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, CmdBuf);
+ os_free_mem(NULL, RspBuf);
+
+ return Status;
+}
+
+
+INT AndesReadModifyWrite(PRTMP_ADAPTER pAd, R_M_W_REG *RegPair, UINT32 Num)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 12, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ BOOLEAN LastPacket = FALSE;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < (SentLen / 12); i++)
+ {
+ /* Address */
+ Value = cpu2le32(RegPair[i + CurIndex].Register + pChipCap->WlanMemmapOffset);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ /* ClearBitMask */
+ Value = cpu2le32(RegPair[i + CurIndex].ClearBitMask);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ /* UpdateData */
+ Value = cpu2le32(RegPair[i + CurIndex].Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_READ_MODIFY_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 12);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesRFReadModifyWrite(PRTMP_ADAPTER pAd, RF_R_M_W_REG *RegPair, UINT32 Num)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 12, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ BOOLEAN LastPacket = FALSE;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < SentLen / 12; i++)
+ {
+ Value = 0;
+ /* RF selection */
+ Value = (Value & ~0x80000000) | 0x80000000;
+
+ /* RF bank */
+ Value = (Value & ~0x00ff0000) | (RegPair[i + CurIndex].Bank << 16);
+
+ /* RF Index */
+ Value = (Value & ~0x000000ff) | RegPair[i + CurIndex].Register;
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ Value = 0;
+ /* ClearBitMask */
+ Value = (Value & ~0x000000ff) | RegPair[i + CurIndex].ClearBitMask;
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ Value = 0;
+ /* UpdateData */
+ Value = (Value & ~0x000000ff) | RegPair[i + CurIndex].Value;
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_READ_MODIFY_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 12);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesRandomWritePair(PRTMP_ADAPTER pAd, RTMP_REG_PAIR *RegPair, UINT32 Num)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 8, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ BOOLEAN LastPacket = FALSE;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < (SentLen / 8); i++)
+ {
+ /* Address */
+ Value = cpu2le32(RegPair[i + CurIndex].Register + pChipCap->WlanMemmapOffset);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ /* UpdateData */
+ Value = cpu2le32(RegPair[i + CurIndex].Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ };
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 8);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesRandomWrite(PRTMP_ADAPTER pAd, UINT32 Num, ...)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 8, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ va_list argptr;
+ BOOLEAN LastPacket = FALSE;
+
+ va_start(argptr, Num);
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < (SentLen / 8); i++)
+ {
+ /* Address */
+ Value = cpu2le32( va_arg(argptr, UINT32) +pChipCap->WlanMemmapOffset);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ /* UpdateData */
+ Value = cpu2le32(va_arg(argptr, UINT32));
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ };
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 8);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+ va_end(argptr);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesRFRandomWritePair(PRTMP_ADAPTER pAd, BANK_RF_REG_PAIR *RegPair, UINT32 Num)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 8, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ BOOLEAN LastPacket = FALSE;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < (SentLen / 8); i++)
+ {
+ Value = 0;
+ /* RF selection */
+ Value = (Value & ~0x80000000) | 0x80000000;
+
+ /* RF bank */
+ Value = (Value & ~0x00ff0000) | (RegPair[i + CurIndex].Bank << 16);
+
+ /* RF Index */
+ Value = (Value & ~0x000000ff) | RegPair[i + CurIndex].Register;
+
+ //printk("Value = %x RF Bank = %d and Index = %d\n", Value, RegPair[i + CurIndex].Bank, RegPair[i + CurIndex].Register);
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ Value = 0;
+ /* UpdateData */
+ Value = (Value & ~0x000000ff) | RegPair[i + CurIndex].Value;
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 8);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+
+error:
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesRFRandomWrite(PRTMP_ADAPTER pAd, UINT32 Num, ...)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 8, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ va_list argptr;
+ BOOLEAN LastPacket = FALSE;
+
+ va_start(argptr, Num);
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < (SentLen / 8); i++)
+ {
+ Value = 0;
+ /* RF selection */
+ Value = (Value & ~0x80000000) | 0x80000000;
+
+ /* RF bank */
+ Value = (Value & ~0x00ff0000) | (va_arg(argptr, UINT) << 16);
+
+ /* RF Index */
+ Value = (Value & ~0x000000ff) | va_arg(argptr, UINT);
+
+ //printk("Value = %x RF Bank = %d and Index = %d\n", Value, RegPair[i + CurIndex].Bank, RegPair[i + CurIndex].Register);
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ Value = 0;
+ /* UpdateData */
+ Value = (Value & ~0x000000ff) | va_arg(argptr, UINT);
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 8);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+
+error:
+ os_free_mem(NULL, Buf);
+ va_end(argptr);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef MT7601
+INT AndesBBPRandomWritePair(PRTMP_ADAPTER pAd, RTMP_REG_PAIR *RegPair, UINT32 Num)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 8, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ BOOLEAN LastPacket = FALSE;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < (SentLen / 8); i++)
+ {
+ Value = 0;
+ /* BBP selection */
+ Value = (Value & ~0x40000000) | 0x40000000;
+
+ /* BBP Index */
+ Value = (Value & ~0x000000ff) | RegPair[i + CurIndex].Register;
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ Value = 0;
+ /* UpdateData */
+ Value = (Value & ~0x000000ff) | RegPair[i + CurIndex].Value;
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 8);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesBBPRandomWrite(PRTMP_ADAPTER pAd, UINT32 Num, ...)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf, *CurHeader;
+ UINT32 VarLen = Num * 8, CurLen = 0, SentLen;
+ UINT32 Value, i, CurIndex = 0;
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ INT32 Ret;
+ va_list argptr;
+ BOOLEAN LastPacket = FALSE;
+
+ va_start(argptr, Num);
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ while (CurLen < VarLen)
+ {
+ SentLen = (VarLen - CurLen) > pChipCap->InbandPacketMaxLen
+ ? pChipCap->InbandPacketMaxLen : (VarLen - CurLen);
+
+ if ((SentLen < pChipCap->InbandPacketMaxLen) || (CurLen + pChipCap->InbandPacketMaxLen) == VarLen)
+ LastPacket = TRUE;
+
+ CurHeader = Pos;
+
+ for (i = 0; i < (SentLen / 8); i++)
+ {
+ Value = 0;
+ /* BBP selection */
+ Value = (Value & ~0x40000000) | 0x40000000;
+
+ /* BBP Index */
+ Value = (Value & ~0x000000ff) | va_arg(argptr, UINT);
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ Value = 0;
+ /* UpdateData */
+ Value = (Value & ~0x000000ff) | va_arg(argptr, UINT);
+
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_RANDOM_WRITE;
+ CmdUnit.u.ANDES.CmdPayloadLen = SentLen;
+ CmdUnit.u.ANDES.CmdPayload = CurHeader;
+
+ if (LastPacket)
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ if (Ret != NDIS_STATUS_SUCCESS)
+ goto error;
+
+ CurIndex += (SentLen / 8);
+ CurLen += pChipCap->InbandPacketMaxLen;
+ }
+
+error:
+ os_free_mem(NULL, Buf);
+ va_end(argptr);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+#endif
+
+
+INT AndesPwrSavingOP(PRTMP_ADAPTER pAd, UINT32 PwrOP, UINT32 PwrLevel,
+ UINT32 ListenInterval, UINT32 PreTBTTLeadTime,
+ UINT8 TIMByteOffset, UINT8 TIMBytePattern)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf;
+ UINT32 VarLen;
+ UINT32 Value;
+ INT32 Ret;
+
+ /* Power operation and Power Level */
+ VarLen = 8;
+
+ if (PwrOP == RADIO_OFF_ADVANCE)
+ {
+ /* Listen interval, Pre-TBTT, TIM info */
+ VarLen += 12;
+ }
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ /* Power operation */
+ Value = cpu2le32(PwrOP);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ /* Power Level */
+ Value = cpu2le32(PwrLevel);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ if ( (PwrOP == RADIO_OFF_ADVANCE) || (PwrOP == RADIO_OFF_AUTO_WAKEUP))
+ {
+ /* Listen interval */
+ Value = cpu2le32(ListenInterval);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+
+ /* Pre TBTT lead time */
+ Value = cpu2le32(PreTBTTLeadTime);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ if (PwrOP == RADIO_OFF_ADVANCE)
+ {
+ /* TIM Info */
+ Value = (Value & ~0x000000ff) | TIMBytePattern;
+ Value = (Value & ~0x0000ff00) | (TIMByteOffset << 8);
+ Value = cpu2le32(Value);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+ }
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_POWER_SAVING_OP;
+ CmdUnit.u.ANDES.CmdPayloadLen = VarLen;
+ CmdUnit.u.ANDES.CmdPayload = Buf;
+
+ CmdUnit.u.ANDES.NeedRsp = FALSE;
+ CmdUnit.u.ANDES.NeedWait = FALSE;
+
+ CmdUnit.u.ANDES.Timeout = 0;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesFunSetOP(PRTMP_ADAPTER pAd, UINT32 FunID, UINT32 Param)
+{
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf;
+ UINT32 VarLen;
+ UINT32 Value;
+ INT32 Ret;
+
+ /* Function ID and Parameter */
+ VarLen = 8;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ /* Function ID */
+ Value = cpu2le32(FunID);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ /* Parameter */
+ Value = cpu2le32(Param);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_FUN_SET_OP;
+ CmdUnit.u.ANDES.CmdPayloadLen = VarLen;
+ CmdUnit.u.ANDES.CmdPayload = Buf;
+
+ if ( FunID == 5 )
+ {
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+ }
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT AndesCalibrationOP(PRTMP_ADAPTER pAd, UINT32 CalibrationID, UINT32 Param)
+{
+
+ struct CMD_UNIT CmdUnit;
+ CHAR *Pos, *Buf;
+ UINT32 VarLen;
+ UINT32 Value;
+ INT32 Ret;
+
+ /* Calibration ID and Parameter */
+ VarLen = 8;
+
+ os_alloc_mem(pAd, (UCHAR **)&Buf, VarLen);
+
+ Pos = Buf;
+
+ /* Calibration ID */
+ Value = cpu2le32(CalibrationID);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ /* Parameter */
+ Value = cpu2le32(Param);
+ NdisMoveMemory(Pos, &Value, 4);
+ Pos += 4;
+
+ NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
+
+ CmdUnit.u.ANDES.Type = CMD_CALIBRATION_OP;
+ CmdUnit.u.ANDES.CmdPayloadLen = VarLen;
+ CmdUnit.u.ANDES.CmdPayload = Buf;
+
+ CmdUnit.u.ANDES.NeedRsp = TRUE;
+ CmdUnit.u.ANDES.NeedWait = TRUE;
+ CmdUnit.u.ANDES.Timeout = 0;
+
+ Ret = AsicSendCmdToAndes(pAd, &CmdUnit);
+
+ os_free_mem(NULL, Buf);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mcu/rtmp_mcu.c b/cleopatre/devkit/mt7601udrv/mcu/rtmp_mcu.c
new file mode 100644
index 0000000000..4359bc312c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mcu/rtmp_mcu.c
@@ -0,0 +1,77 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtmp_mcu.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
+#include "rt_config.h"
+
+INT MCUBurstWrite(PRTMP_ADAPTER pAd, UINT32 Offset, UINT32 *Data, UINT32 Cnt)
+{
+ RTUSBMultiWrite_nBytes(pAd, Offset, Data, Cnt * 4, 64);
+}
+
+INT MCURandomWrite(PRTMP_ADAPTER pAd, RTMP_REG_PAIR *RegPair, UINT32 Num)
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < Num; Index++)
+ RTMP_IO_WRITE32(pAd, RegPair->Register, RegPair->Value);
+}
+
+VOID ChipOpsMCUHook(PRTMP_ADAPTER pAd, enum MCU_TYPE MCUType)
+{
+
+ RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
+
+ if (MCUType == M8051)
+ {
+ pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
+ pChipOps->BurstWrite = MCUBurstWrite;
+ pChipOps->RandomWrite = MCURandomWrite;
+ }
+
+#ifdef CONFIG_ANDES_SUPPORT
+ if (MCUType == ANDES)
+ {
+
+#ifdef RTMP_USB_SUPPORT
+ pChipOps->loadFirmware = USBLoadFirmwareToAndes;
+#endif
+ //pChipOps->sendCommandToMcu = AsicSendCmdToAndes;
+ pChipOps->Calibration = AndesCalibrationOP;
+ pChipOps->BurstWrite = AndesBurstWrite;
+ pChipOps->BurstRead = AndesBurstRead;
+ pChipOps->RandomRead = AndesRandomRead;
+ pChipOps->RFRandomRead = AndesRFRandomRead;
+ pChipOps->ReadModifyWrite = AndesReadModifyWrite;
+ pChipOps->RFReadModifyWrite = AndesRFReadModifyWrite;
+ pChipOps->RandomWrite = AndesRandomWrite;
+ pChipOps->RFRandomWrite = AndesRFRandomWrite;
+ pChipOps->PwrSavingOP = AndesPwrSavingOP;
+ }
+#endif
+}
diff --git a/cleopatre/devkit/mt7601udrv/mgmt/mgmt_dev.c b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_dev.c
new file mode 100644
index 0000000000..c44474f6cf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_dev.c
@@ -0,0 +1,58 @@
+/*
+
+*/
+
+#include "rt_config.h"
+
+
+struct wifi_dev *get_wdev_by_idx(RTMP_ADAPTER *pAd, INT idx)
+{
+ struct wifi_dev *wdev = NULL;
+
+ do
+ {
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (idx >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ idx -= MIN_NET_DEVICE_FOR_APCLI;
+ if (idx < MAX_APCLI_NUM)
+ {
+ wdev = &pAd->ApCfg.ApCliTab[idx].wdev;
+ break;
+ }
+ }
+#endif /* APCLI_SUPPORT */
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+
+#ifdef WDS_SUPPORT
+ if (idx >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ idx -= MIN_NET_DEVICE_FOR_WDS;
+ if (idx < MAX_WDS_ENTRY)
+ {
+ wdev = &&pAd->WdsTab.WdsEntry[idx].wdev;
+ break;
+ }
+ }
+#endif /* WDS_SUPPORT */
+ if ((idx < pAd->ApCfg.BssidNum) && (idx < MAX_MBSSID_NUM(pAd)) && (idx < HW_BEACON_MAX_NUM))
+ wdev = &pAd->ApCfg.MBSSID[idx].wdev;
+
+ break;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ } while (FALSE);
+
+ if (wdev == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid idx(%d)\n", idx));
+ }
+
+ return wdev;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mgmt/mgmt_entrytb.c b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_entrytb.c
new file mode 100644
index 0000000000..a6f2b2ef44
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_entrytb.c
@@ -0,0 +1,729 @@
+/*
+
+*/
+
+#include <rt_config.h>
+
+
+VOID set_entry_phy_cfg(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry)
+{
+
+ 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];
+ }
+}
+
+
+
+/*
+ ==========================================================================
+ 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;
+
+
+ /* 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_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ SET_ENTRY_APCLI(pEntry);
+ pEntry->isCached = FALSE;
+ break;
+ }
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ SET_ENTRY_WDS(pEntry);
+ pEntry->isCached = FALSE;
+ break;
+ }
+#endif /* WDS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ { /* be a regular-entry*/
+ if ((apidx < pAd->ApCfg.BssidNum) &&
+ (apidx < MAX_MBSSID_NUM(pAd)) &&
+ ((apidx < HW_BEACON_MAX_NUM)) &&
+ (pAd->ApCfg.MBSSID[apidx].MaxStaNum != 0) &&
+ (pAd->ApCfg.MBSSID[apidx].StaCount >= pAd->ApCfg.MBSSID[apidx].MaxStaNum))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s: The connection table is full in ra%d.\n", __FUNCTION__, apidx));
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ return NULL;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ SET_ENTRY_CLIENT(pEntry);
+
+ } while (FALSE);
+
+ pEntry->bIAmBadAtheros = FALSE;
+
+ RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE);
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (IS_ENTRY_CLIENT(pEntry)) /* Only Clent entry need the retry timer.*/
+ {
+ RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE);
+
+ /* RTMP_OS_Init_Timer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pAd);*/
+ }
+#ifdef APCLI_SUPPORT
+ else if (IS_ENTRY_APCLI(pEntry))
+ {
+ RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE);
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ RTMPInitTimer(pAd, &pEntry->eTxBfProbeTimer, GET_TIMER_FUNCTION(eTxBfProbeTimerExec), pEntry, FALSE);
+#endif /* TXBF_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);
+ else
+ pEntry->apidx = apidx;
+
+#ifdef CONFIG_AP_SUPPORT
+ if ((apidx < pAd->ApCfg.BssidNum) &&
+ (apidx < MAX_MBSSID_NUM(pAd)) &&
+ (apidx < HW_BEACON_MAX_NUM))
+ pEntry->pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx];
+ else
+ pEntry->pMbss = NULL;
+#endif /* CONFIG_AP_SUPPORT */
+
+ do
+ {
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ pEntry->AuthMode = pAd->ApCfg.ApCliTab[pEntry->apidx].AuthMode;
+ pEntry->WepStatus = pAd->ApCfg.ApCliTab[pEntry->apidx].WepStatus;
+
+ if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
+ {
+ pEntry->WpaState = AS_NOTUSE;
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ }
+ else
+ {
+ pEntry->WpaState = AS_PTKSTART;
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ }
+ pEntry->MatchAPCLITabIdx = pEntry->apidx;
+ break;
+ }
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(pEntry))
+ {
+ pEntry->AuthMode = Ndis802_11AuthModeOpen;
+ pEntry->WepStatus = Ndis802_11EncryptionDisabled;
+
+ pEntry->MatchWDSTabIdx = pEntry->apidx;
+ break;
+ }
+#endif /* WDS_SUPPORT */
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ MBSS_MR_APIDX_SANITY_CHECK(pAd, apidx);
+ pEntry->AuthMode = pAd->ApCfg.MBSSID[apidx].AuthMode;
+ pEntry->WepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus;
+ pEntry->GroupKeyWepStatus = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus;
+
+ if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
+ pEntry->WpaState = AS_NOTUSE;
+ else
+ pEntry->WpaState = AS_INITIALIZE;
+
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ pEntry->StaIdleTimeout = pAd->ApCfg.StaIdleTimeout;
+ pAd->ApCfg.MBSSID[apidx].StaCount++;
+ pAd->ApCfg.EntryClientCount++;
+ break;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ } while (FALSE);
+
+ pEntry->GTKState = REKEY_NEGOTIATING;
+ pEntry->PairwiseKey.KeyLen = 0;
+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+ pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
+ COPY_MAC_ADDR(pEntry->Addr, pAddr);
+ COPY_MAC_ADDR(pEntry->HdrAddr1, pAddr);
+
+ do
+ {
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ {
+ COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.ApCliTab[pEntry->apidx].CurrentAddress);
+ COPY_MAC_ADDR(pEntry->HdrAddr3, pAddr);
+ break;
+ }
+#endif // APCLI_SUPPORT //
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(pEntry))
+ {
+ COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid);
+ COPY_MAC_ADDR(pEntry->HdrAddr3, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid);
+ break;
+ }
+#endif // WDS_SUPPORT //
+#ifdef CONFIG_AP_SUPPORT
+ if (OpMode == OPMODE_AP)
+ {
+ COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.MBSSID[apidx].Bssid);
+ COPY_MAC_ADDR(pEntry->HdrAddr3, pAd->ApCfg.MBSSID[apidx].Bssid);
+ break;
+ }
+#endif // CONFIG_AP_SUPPORT //
+ } while (FALSE);
+
+ pEntry->Sst = SST_NOT_AUTH;
+ pEntry->AuthState = AS_NOT_AUTH;
+ pEntry->Aid = (USHORT)i; /*0;*/
+ pEntry->CapabilityInfo = 0;
+ pEntry->PsMode = PWR_ACTIVE;
+ pEntry->PsQIdleCount = 0;
+ pEntry->NoDataIdleCount = 0;
+ pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
+ pEntry->ContinueTxFailCnt = 0;
+#ifdef WDS_SUPPORT
+ pEntry->LockEntryTx = FALSE;
+#endif /* WDS_SUPPORT */
+ pEntry->TimeStamp_toTxRing = 0;
+ InitializeQueueHeader(&pEntry->PsQueue);
+
+#ifdef STREAM_MODE_SUPPORT
+ /* Enable Stream mode for first three entries in MAC table */
+
+#endif /* STREAM_MODE_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef UAPSD_SUPPORT
+ if (IS_ENTRY_CLIENT(pEntry)) /* Ralink WDS doesn't support any power saving.*/
+ {
+ /* init U-APSD enhancement related parameters */
+ UAPSD_MR_ENTRY_INIT(pEntry);
+ }
+#endif /* UAPSD_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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);
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef WSC_AP_SUPPORT
+ pEntry->bWscCapable = FALSE;
+ pEntry->Receive_EapolStart_EapRspId = 0;
+#endif /* WSC_AP_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ NdisAllocateSpinLock(pAd, &pEntry->TxSndgLock);
+#endif /* TXBF_SUPPORT */
+
+ 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;
+ }
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+
+#ifdef WSC_AP_SUPPORT
+ if (IS_ENTRY_CLIENT(pEntry) &&
+ (pEntry->apidx < pAd->ApCfg.BssidNum) &&
+ MAC_ADDR_EQUAL(pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr))
+ {
+ NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, MAC_ADDR_LEN);
+ }
+#endif /* WSC_AP_SUPPORT */
+
+
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ }
+
+ 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 TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ RTMPReleaseTimer(&pEntry->eTxBfProbeTimer, &Cancelled);
+#endif /* TXBF_SUPPORT */
+
+#ifdef STREAM_MODE_SUPPORT
+ /* Clear Stream Mode register for this client */
+ if (pEntry->StreamModeMACReg != 0)
+ RTMP_IO_WRITE32(pAd, pEntry->StreamModeMACReg+4, 0);
+#endif // STREAM_MODE_SUPPORT //
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (IS_ENTRY_CLIENT(pEntry)
+ )
+ {
+#ifdef DOT1X_SUPPORT
+ INT PmkCacheIdx = -1;
+#endif /* DOT1X_SUPPORT */
+
+ RTMPReleaseTimer(&pEntry->RetryTimer, &Cancelled);
+
+#ifdef DOT1X_SUPPORT
+ /* Notify 802.1x daemon to clear this sta info*/
+ if (pEntry->AuthMode == Ndis802_11AuthModeWPA ||
+ pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+ pAd->ApCfg.MBSSID[pEntry->apidx].IEEE8021X)
+ DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY);
+
+ /* Delete the PMK cache for this entry if it exists.*/
+ if ((PmkCacheIdx = RTMPSearchPMKIDCache(pAd, pEntry->apidx, pEntry->Addr)) != -1)
+ {
+ RTMPDeletePMKIDCache(pAd, pEntry->apidx, PmkCacheIdx);
+ }
+#endif /* DOT1X_SUPPORT */
+
+#ifdef WAPI_SUPPORT
+ RTMPCancelWapiRekeyTimerAction(pAd, pEntry);
+#endif /* WAPI_SUPPORT */
+
+#ifdef IGMP_SNOOP_SUPPORT
+ IgmpGroupDelMembers(pAd, (PUCHAR)pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].MSSIDDev);
+#endif /* IGMP_SNOOP_SUPPORT */
+ pAd->ApCfg.MBSSID[pEntry->apidx].StaCount--;
+ pAd->ApCfg.EntryClientCount--;
+
+#ifdef HOSTAPD_SUPPORT
+ if(pEntry && pAd->ApCfg.MBSSID[pEntry->apidx].Hostapd == TRUE )
+ {
+ RtmpOSWrielessEventSendExt(pAd->net_dev, RT_WLAN_EVENT_EXPIRED, -1, pEntry->Addr,
+ NULL, 0,pEntry->apidx);
+ }
+#endif
+
+ }
+#ifdef APCLI_SUPPORT
+ else if (IS_ENTRY_APCLI(pEntry))
+ {
+ RTMPReleaseTimer(&pEntry->RetryTimer, &Cancelled);
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_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);
+
+#ifdef CONFIG_AP_SUPPORT
+ APCleanupPsQueue(pAd, &pEntry->PsQueue); /* return all NDIS packet in PSQ*/
+#endif /* CONFIG_AP_SUPPORT */
+ /*RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, wcid);*/
+
+#ifdef UAPSD_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+ UAPSD_MR_ENTRY_RESET(pAd, pEntry);
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+ if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
+ {
+ RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+ }
+ RTMPReleaseTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WSC_AP_SUPPORT
+ if (IS_ENTRY_CLIENT(pEntry))
+ {
+ PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[pEntry->apidx].WscControl;
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pWscControl->EntryAddr))
+ {
+ /*
+ Some WPS Client will send dis-assoc close to WSC_DONE.
+ If AP misses WSC_DONE, WPS Client still sends dis-assoc to AP.
+ Do not cancel timer if WscState is WSC_STATE_WAIT_DONE.
+ */
+ if ((pWscControl->EapolTimerRunning == TRUE) &&
+ (pWscControl->WscState != WSC_STATE_WAIT_DONE))
+ {
+ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled);
+ pWscControl->EapolTimerRunning = FALSE;
+ pWscControl->EapMsgRunning = FALSE;
+ NdisZeroMemory(&(pWscControl->EntryAddr[0]), MAC_ADDR_LEN);
+ }
+ }
+ pEntry->Receive_EapolStart_EapRspId = 0;
+ pEntry->bWscCapable = FALSE;
+ }
+#endif /* WSC_AP_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+// NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+ NdisZeroMemory(pEntry->Addr, MAC_ADDR_LEN);
+ /* invalidate the entry */
+ SET_ENTRY_NONE(pEntry);
+ pAd->MacTab.Size --;
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ NdisFreeSpinLock(&pEntry->TxSndgLock);
+#endif /* TXBF_SUPPORT */
+ 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, 0, ALLN_SETPROTECT, TRUE, 0);
+ }
+#ifdef CONFIG_AP_SUPPORT
+ /*APUpdateCapabilityAndErpIe(pAd);*/
+ RTMP_AP_UPDATE_CAPABILITY_AND_ERPIE(pAd); /* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet*/
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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;
+#ifdef CONFIG_AP_SUPPORT
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ HEADER_802_11 DeAuthHdr;
+ USHORT Reason;
+ UCHAR apidx = MAIN_MBSSID;
+#endif /* CONFIG_AP_SUPPORT */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
+ /*NdisAcquireSpinLock(&pAd->MacTabLock);*/
+
+
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]))
+ {
+ /* Delete a entry via WCID */
+
+ /*MacTableDeleteEntry(pAd, i, pAd->MacTab.Content[i].Addr);*/
+ RTMPReleaseTimer(&pAd->MacTab.Content[i].EnqueueStartForPSKTimer, &Cancelled);
+ pAd->MacTab.Content[i].EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* Before reset MacTable, send disassociation packet to client.*/
+ if (pAd->MacTab.Content[i].Sst == SST_ASSOC)
+ {
+ /* send out a De-authentication request frame*/
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n"));
+ /*NdisReleaseSpinLock(&pAd->MacTabLock);*/
+ return;
+ }
+
+ Reason = REASON_NO_LONGER_VALID;
+ DBGPRINT(RT_DEBUG_WARN, ("Send DEAUTH - Reason = %d frame tO %02x:%02x:%02x:%02x:%02x:%02x \n",Reason, PRINT_MAC(pAd->MacTab.Content[i].Addr)));
+ MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pAd->MacTab.Content[i].Addr,
+ pAd->ApCfg.MBSSID[pAd->MacTab.Content[i].apidx].Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DeAuthHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ RTMPusecDelay(5000);
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* 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);
+ }
+ }
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (apidx = MAIN_MBSSID; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+#ifdef WSC_AP_SUPPORT
+ BOOLEAN Cancelled;
+
+ RTMPCancelTimer(&pAd->ApCfg.MBSSID[apidx].WscControl.EapolTimer, &Cancelled);
+ pAd->ApCfg.MBSSID[apidx].WscControl.EapolTimerRunning = FALSE;
+ NdisZeroMemory(pAd->ApCfg.MBSSID[apidx].WscControl.EntryAddr, MAC_ADDR_LEN);
+ pAd->ApCfg.MBSSID[apidx].WscControl.EapMsgRunning = FALSE;
+#endif /* WSC_AP_SUPPORT */
+ pAd->ApCfg.MBSSID[apidx].StaCount = 0;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("McastPsQueue.Number %ld...\n",pAd->MacTab.McastPsQueue.Number));
+ if (pAd->MacTab.McastPsQueue.Number > 0)
+ APCleanupPsQueue(pAd, &pAd->MacTab.McastPsQueue);
+ DBGPRINT(RT_DEBUG_TRACE, ("2McastPsQueue.Number %ld...\n",pAd->MacTab.McastPsQueue.Number));
+
+ /* ENTRY PREEMPTION: Zero Mac Table but entry's content */
+/* NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));*/
+ NdisZeroMemory(&pAd->MacTab.Size,
+ sizeof(MAC_TABLE)-
+ sizeof(pAd->MacTab.Hash)-
+ sizeof(pAd->MacTab.Content));
+
+ InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
+ /*NdisReleaseSpinLock(&pAd->MacTabLock);*/
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ return;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mgmt/mgmt_ht.c b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_ht.c
new file mode 100644
index 0000000000..5b3b5a01b5
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_ht.c
@@ -0,0 +1,747 @@
+/*
+
+
+*/
+
+
+#include "rt_config.h"
+
+
+#ifdef DOT11_N_SUPPORT
+
+
+INT ht_mode_adjust(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, HT_CAPABILITY_IE *peer, RT_HT_CAPABILITY *my)
+{
+ if ((peer->HtCapInfo.GF) && (my->GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ }
+
+ if ((peer->HtCapInfo.ChannelWidth) && (my->ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((my->ShortGIfor40) & (peer->HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((my->ShortGIfor20) & (peer->HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+INT set_ht_fixed_mcs(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, UCHAR fixed_mcs, UCHAR mcs_bound)
+{
+ if (fixed_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 > mcs_bound)
+ {
+ /* STA supports fixed MCS */
+ pEntry->MaxHTPhyMode.field.MCS = mcs_bound;
+ }
+
+ return TRUE;
+}
+
+
+INT get_ht_max_mcs(RTMP_ADAPTER *pAd, UCHAR *desire_mcs, UCHAR *cap_mcs)
+{
+ INT i, j;
+ UCHAR bitmask;
+
+
+ for (i=23; i>=0; i--)
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+ if ((desire_mcs[j] & bitmask) && (cap_mcs[j] & bitmask))
+ {
+ /*pEntry->MaxHTPhyMode.field.MCS = i; */
+ /* find it !!*/
+ break;
+ }
+ if (i==0)
+ break;
+ }
+
+ return i;
+}
+
+
+INT get_ht_cent_ch(RTMP_ADAPTER *pAd, UCHAR *rf_bw, UCHAR *ext_ch)
+{
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ )
+ {
+ *rf_bw = BW_40;
+ *ext_ch = EXTCHA_ABOVE;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ }
+ else if ((pAd->CommonCfg.Channel > 2) &&
+ (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW))
+ {
+ *rf_bw = BW_40;
+ *ext_ch = EXTCHA_BELOW;
+ if (pAd->CommonCfg.Channel == 14)
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
+ else
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ } else {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+UCHAR get_cent_ch_by_htinfo(
+ RTMP_ADAPTER *pAd,
+ ADD_HT_INFO_IE *ht_op,
+ HT_CAPABILITY_IE *ht_cap)
+{
+ UCHAR cent_ch;
+
+ if ((ht_op->ControlChan > 2)&&
+ (ht_op->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) &&
+ (ht_cap->HtCapInfo.ChannelWidth == BW_40))
+ cent_ch = ht_op->ControlChan - 2;
+ else if ((ht_op->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) &&
+ (ht_cap->HtCapInfo.ChannelWidth == BW_40))
+ cent_ch = ht_op->ControlChan + 2;
+ else
+ cent_ch = ht_op->ControlChan;
+
+ return cent_ch;
+}
+
+
+/*
+ ========================================================================
+ 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 RTMP_ADAPTER *pAd,
+ IN OID_SET_HT_PHYMODE *pHTPhyMode)
+{
+ UCHAR RxStream = pAd->CommonCfg.RxStream;
+#ifdef CONFIG_AP_SUPPORT
+ INT apidx;
+#endif /* CONFIG_AP_SUPPORT */
+ INT bw;
+ RT_HT_CAPABILITY *rt_ht_cap = &pAd->CommonCfg.DesiredHtPhy;
+ HT_CAPABILITY_IE *ht_cap= &pAd->CommonCfg.HtCapability;
+
+#ifdef CONFIG_AP_SUPPORT
+ /* sanity check for extention channel */
+ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel,
+ CHANNEL_NO_FAT_BELOW | CHANNEL_NO_FAT_ABOVE) == TRUE)
+ {
+ /* only 20MHz is allowed */
+ pHTPhyMode->BW = 0;
+ }
+ else if (pHTPhyMode->ExtOffset == EXTCHA_BELOW)
+ {
+ /* extension channel below this channel is not allowed */
+ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel,
+ CHANNEL_NO_FAT_BELOW) == TRUE)
+ {
+ pHTPhyMode->ExtOffset = EXTCHA_ABOVE;
+ }
+ }
+ else if (pHTPhyMode->ExtOffset == EXTCHA_ABOVE)
+ {
+ /* extension channel above this channel is not allowed */
+ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel,
+ CHANNEL_NO_FAT_ABOVE) == TRUE)
+ {
+ pHTPhyMode->ExtOffset = EXTCHA_BELOW;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ 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(ht_cap, sizeof(HT_CAPABILITY_IE));
+ RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+ RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
+ RTMPZeroMemory(rt_ht_cap, sizeof(RT_HT_CAPABILITY));
+
+ if (pAd->CommonCfg.bRdg)
+ {
+ ht_cap->ExtHtCapInfo.PlusHTC = 1;
+ ht_cap->ExtHtCapInfo.RDGSupport = 1;
+ }
+ else
+ {
+ ht_cap->ExtHtCapInfo.PlusHTC = 0;
+ ht_cap->ExtHtCapInfo.RDGSupport = 0;
+ }
+
+
+ if (RxStream == 1)
+ {
+ ht_cap->HtCapParm.MaxRAmpduFactor = 2;
+ rt_ht_cap->MaxRAmpduFactor = 2;
+ }
+ else
+ {
+ ht_cap->HtCapParm.MaxRAmpduFactor = 3;
+ rt_ht_cap->MaxRAmpduFactor = 3;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+
+ /* Mimo power save, A-MSDU size, */
+ rt_ht_cap->AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
+ rt_ht_cap->AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
+ rt_ht_cap->MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
+ rt_ht_cap->MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+ ht_cap->HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+ ht_cap->HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+ ht_cap->HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
+ rt_ht_cap->AmsduSize,
+ rt_ht_cap->MimoPs,
+ rt_ht_cap->MpduDensity,
+ rt_ht_cap->MaxRAmpduFactor));
+
+ if(pHTPhyMode->HtMode == HTMODE_GF)
+ {
+ ht_cap->HtCapInfo.GF = 1;
+ rt_ht_cap->GF = 1;
+ }
+ else
+ rt_ht_cap->GF = 0;
+
+ /* Decide Rx MCSSet*/
+ switch (RxStream)
+ {
+ case 3:
+ ht_cap->MCSSet[2] = 0xff;
+ case 2:
+ ht_cap->MCSSet[1] = 0xff;
+ case 1:
+ default:
+ ht_cap->MCSSet[0] = 0xff;
+ break;
+ }
+
+ if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pHTPhyMode->BW == BW_40))
+ {
+ pHTPhyMode->BW = BW_20;
+ ht_cap->HtCapInfo.Forty_Mhz_Intolerant = 1;
+ }
+
+ // TODO: shiang-6590, how about the "bw" when channel 14 for JP region???
+ bw = BW_20;
+ if(pHTPhyMode->BW == BW_40)
+ {
+ ht_cap->MCSSet[4] = 0x1; /* MCS 32*/
+ ht_cap->HtCapInfo.ChannelWidth = 1;
+ if (pAd->CommonCfg.Channel <= 14)
+ ht_cap->HtCapInfo.CCKmodein40 = 1;
+
+ rt_ht_cap->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_mac_set_ctrlch(pAd, pHTPhyMode->ExtOffset);
+
+ /* 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_set_ctrlch(pAd, pHTPhyMode->ExtOffset);
+#ifdef GREENAP_SUPPORT
+ if (pAd->ApCfg.bGreenAPActive == 1)
+ bw = BW_20;
+ else
+#endif /* GREENAP_SUPPORT */
+ bw = BW_40;
+ }
+ }
+ else
+ {
+ ht_cap->HtCapInfo.ChannelWidth = 0;
+ rt_ht_cap->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.*/
+ bw = BW_20;
+ }
+
+#ifdef DOT11_VHT_AC
+ if (pHTPhyMode->BW == BW_40 &&
+ pAd->CommonCfg.vht_bw == VHT_BW_80 &&
+ pAd->CommonCfg.vht_cent_ch)
+ bw = BW_80;
+#endif /* DOT11_VHT_AC */
+ rtmp_bbp_set_bw(pAd, bw);
+
+
+ if(pHTPhyMode->STBC == STBC_USE)
+ {
+ if (pAd->Antenna.field.TxPath >= 2)
+ {
+ ht_cap->HtCapInfo.TxSTBC = 1;
+ rt_ht_cap->TxSTBC = 1;
+ }
+ else
+ {
+ ht_cap->HtCapInfo.TxSTBC = 0;
+ rt_ht_cap->TxSTBC = 0;
+ }
+
+ /*
+ RxSTBC
+ 0: not support,
+ 1: support for 1SS
+ 2: support for 1SS, 2SS
+ 3: support for 1SS, 2SS, 3SS
+ */
+ if (pAd->Antenna.field.RxPath >= 1)
+ {
+ ht_cap->HtCapInfo.RxSTBC = 1;
+ rt_ht_cap->RxSTBC = 1;
+ }
+ else
+ {
+ ht_cap->HtCapInfo.RxSTBC = 0;
+ rt_ht_cap->RxSTBC = 0;
+ }
+ }
+ else
+ {
+ rt_ht_cap->TxSTBC = 0;
+ rt_ht_cap->RxSTBC = 0;
+ }
+
+ if(pHTPhyMode->SHORTGI == GI_400)
+ {
+ ht_cap->HtCapInfo.ShortGIfor20 = 1;
+ ht_cap->HtCapInfo.ShortGIfor40 = 1;
+ rt_ht_cap->ShortGIfor20 = 1;
+ rt_ht_cap->ShortGIfor40 = 1;
+ }
+ else
+ {
+ ht_cap->HtCapInfo.ShortGIfor20 = 0;
+ ht_cap->HtCapInfo.ShortGIfor40 = 0;
+ rt_ht_cap->ShortGIfor20 = 0;
+ rt_ht_cap->ShortGIfor40 = 0;
+ }
+
+ /* We support link adaptation for unsolicit MCS feedback, set to 2.*/
+ 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 TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ {
+ /* Set ETxBF */
+ setETxBFCap(pAd, &ht_cap->TxBFCap);
+
+ /* Check ITxBF */
+ pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn &= rtmp_chk_itxbf_calibration(pAd);
+
+ /* Apply to ASIC */
+ rtmp_asic_set_bf(pAd);
+ }
+#endif /* TXBF_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ RTMPSetIndividualHT(pAd, apidx);
+#ifdef WDS_SUPPORT
+ for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++)
+ RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_WDS);
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++)
+ RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_APCLI);
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_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 RTMP_ADAPTER *pAd,
+ IN UCHAR apidx)
+{
+ RT_PHY_INFO *pDesired_ht_phy = NULL;
+ UCHAR TxStream = pAd->CommonCfg.TxStream;
+ UCHAR DesiredMcs = MCS_AUTO;
+ UCHAR encrypt_mode = Ndis802_11EncryptionDisabled;
+
+ do
+ {
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ UCHAR idx = apidx - MIN_NET_DEVICE_FOR_APCLI;
+
+ if (idx < MAX_APCLI_NUM)
+ {
+ pDesired_ht_phy = &pAd->ApCfg.ApCliTab[idx].DesiredHtPhyInfo;
+ DesiredMcs = pAd->ApCfg.ApCliTab[idx].DesiredTransmitSetting.field.MCS;
+ encrypt_mode = pAd->ApCfg.ApCliTab[idx].WepStatus;
+ pAd->ApCfg.ApCliTab[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid idx(%d)\n", idx));
+ return;
+ }
+ }
+#endif /* APCLI_SUPPORT */
+
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef WDS_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ UCHAR idx = apidx - MIN_NET_DEVICE_FOR_WDS;
+
+ if (idx < MAX_WDS_ENTRY)
+ {
+ pDesired_ht_phy = &pAd->WdsTab.WdsEntry[idx].DesiredHtPhyInfo;
+ DesiredMcs = pAd->WdsTab.WdsEntry[idx].DesiredTransmitSetting.field.MCS;
+ /*encrypt_mode = pAd->WdsTab.WdsEntry[idx].WepStatus;*/
+ pAd->WdsTab.WdsEntry[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
+ return;
+ }
+ }
+#endif /* WDS_SUPPORT */
+ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM))
+ {
+ pDesired_ht_phy = &pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo;
+ DesiredMcs = pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.MCS;
+ encrypt_mode = pAd->ApCfg.MBSSID[apidx].WepStatus;
+ pAd->ApCfg.MBSSID[apidx].bWmmCapable = TRUE;
+ pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
+ break;
+ }
+
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
+ return;
+ }
+#endif /* CONFIG_AP_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_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;
+ }
+
+ /*
+ 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)
+ {
+ 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;
+ else if (DesiredMcs <= MCS_7)
+ pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
+ 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:
+ 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);
+
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) {
+ pDesired_ht_phy->bVhtEnable = TRUE;
+ rtmp_set_vht(pAd, pDesired_ht_phy);
+ }
+#endif /* DOT11_VHT_AC */
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Clear the desire HT info per interface
+
+ Arguments:
+
+ ========================================================================
+*/
+VOID RTMPDisableDesiredHtInfo(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef CONFIG_AP_SUPPORT
+ UINT8 apidx = 0;
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++)
+ {
+ RTMPZeroMemory(&pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo, sizeof(RT_PHY_INFO));
+ }
+#ifdef WDS_SUPPORT
+ for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++)
+ {
+ RTMPZeroMemory(&pAd->WdsTab.WdsEntry[apidx].DesiredHtPhyInfo, sizeof(RT_PHY_INFO));
+ }
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++)
+ {
+ RTMPZeroMemory(&pAd->ApCfg.ApCliTab[apidx].DesiredHtPhyInfo, sizeof(RT_PHY_INFO));
+ }
+#endif /* APCLI_SUPPORT */
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+}
+
+
+INT SetCommonHT(RTMP_ADAPTER *pAd)
+{
+ OID_SET_HT_PHYMODE SetHT;
+
+ if (!WMODE_CAP_N(pAd->CommonCfg.PhyMode))
+ {
+ /* Clear previous HT information */
+ RTMPDisableDesiredHtInfo(pAd);
+ return FALSE;
+ }
+
+#ifdef DOT11_VHT_AC
+ SetCommonVHT(pAd);
+#endif /* DOT11_VHT_AC */
+
+ 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);
+
+#ifdef DOT11N_DRAFT3
+ if(pAd->CommonCfg.bBssCoexEnable && pAd->CommonCfg.Bss2040NeedFallBack)
+ {
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
+ pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq = 1;
+ pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC;
+ pAd->CommonCfg.Bss2040NeedFallBack = 1;
+ }
+#endif /* DOT11N_DRAFT3 */
+
+ 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 */
+
diff --git a/cleopatre/devkit/mt7601udrv/mgmt/mgmt_hw.c b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_hw.c
new file mode 100644
index 0000000000..7f7b3afb87
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_hw.c
@@ -0,0 +1,37 @@
+/*
+
+
+*/
+
+
+#include <rt_config.h>
+
+
+INT dev_adjust_radio(RTMP_ADAPTER *pAd)
+{
+ struct hw_setting *hw_cfg = &pAd->hw_cfg, new_cfg;
+
+
+ NdisZeroMemory(&new_cfg, sizeof(struct hw_setting));
+
+
+ /* For all wdev, find the maximum inter-set */
+
+
+ if (hw_cfg->bbp_bw != new_cfg.bbp_bw)
+ {
+ rtmp_bbp_set_bw(pAd, new_cfg.bbp_bw);
+ hw_cfg->bbp_bw = new_cfg.bbp_bw;
+ }
+
+ if (hw_cfg->cent_ch != new_cfg.cent_ch)
+ {
+ UCHAR ext_ch = EXTCHA_NONE;
+
+ rtmp_bbp_set_ctrlch(pAd, ext_ch);
+ rtmp_mac_set_ctrlch(pAd, ext_ch);
+ }
+
+ return TRUE;
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/mgmt/mgmt_vht.c b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_vht.c
new file mode 100644
index 0000000000..68fd646487
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/mgmt/mgmt_vht.c
@@ -0,0 +1,39 @@
+/*
+
+*/
+
+#include "rt_config.h"
+
+
+#ifdef DOT11_VHT_AC
+
+VOID rtmp_set_vht(RTMP_ADAPTER *pAd, RT_PHY_INFO *phy_info)
+{
+ if (!phy_info)
+ return;
+
+ if (phy_info->bVhtEnable)
+ phy_info->vht_bw = VHT_BW_80;
+
+}
+
+
+INT SetCommonVHT(RTMP_ADAPTER *pAd)
+{
+ UCHAR cent_ch = 0;
+
+ if (!WMODE_CAP_AC(pAd->CommonCfg.PhyMode))
+ {
+ /* Clear previous VHT information */
+ return FALSE;
+ }
+
+
+ pAd->CommonCfg.vht_cent_ch = vht_cent_ch_freq(pAd, pAd->CommonCfg.Channel);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): Config VHT parameters!cent_ch=%d!vht_cent_ch = %d, vht_cent_ch2 = %d\n",
+ __FUNCTION__, cent_ch, pAd->CommonCfg.vht_cent_ch, pAd->CommonCfg.vht_cent_ch2));
+ return TRUE;
+}
+
+#endif /* DOT11_VHT_AC */
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.soc b/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.soc
new file mode 100644
index 0000000000..7e4a982b2c
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.soc
@@ -0,0 +1,159 @@
+config RT2860V2_AP
+ tristate "Ralink RT2860 802.11n AP support"
+ depends on NET_RADIO
+
+config RT2860V2_AP_V24_DATA_STRUCTURE
+ bool
+ depends on RT2860V2_AP
+ default y
+
+config RT2860V2_AP_LED
+ bool "LED Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_WSC
+ bool "WSC (WiFi Simple Config)"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_LLTD
+ bool "LLTD (Link Layer Topology Discovery Protocol)"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_WDS
+ bool "WDS"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_NINTENDO
+ bool "Nintendo"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_WMM_ACM
+ bool "WMM ACM"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_MBSS
+ bool "MBSSID"
+ depends on RT2860V2_AP
+
+config NEW_MBSSID_MODE
+ bool "New MBSSID MODE"
+ depends on RT2860V2_AP
+ depends on RT2860V2_AP_MBSS
+ depends on RALINK_RT3883 || RALINK_RT3352 || RALINK_RT5350
+ default n
+
+config RT2860V2_AP_APCLI
+ bool "AP-CLient Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_IGMP_SNOOP
+ bool "IGMP snooping"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_NETIF_BLOCK
+ bool "NETIF Block"
+ depends on RT2860V2_AP
+ help
+ Support Net interface block while Tx-Sw queue full
+
+config RT2860V2_AP_DFS
+ bool "DFS"
+ depends on RT2860V2_AP
+ select RALINK_TIMER_DFS
+
+config RT2860V2_AP_CARRIER
+ bool "Carrier Detect"
+ depends on RT2860V2_AP
+ select RALINK_TIMER_DFS
+
+config RT2860V2_AP_DLS
+ bool "DLS ((Direct-Link Setup) Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_IDS
+ bool "IDS (Intrusion Detection System) Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_MESH
+ bool "MESH Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_HW_ANTENNA_DIVERSITY
+ bool "Antenna Diversity Support"
+ depends on RT2860V2_AP
+ depends on RALINK_RT5350
+
+config RT2860V2_RT3XXX_AP_ANTENNA_DIVERSITY
+ bool "Antenna Diversity Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_WAPI
+ bool "WAPI Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_COC
+ bool "CoC Support"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_MEMORY_OPTIMIZATION
+ bool "Memory Optimization"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_VIDEO_TURBINE
+ bool "Video Turbine support"
+ depends on RT2860V2_AP
+
+config RA_CLASSIFIER
+ tristate "Ralink Flow Classifier"
+ depends on RT2860V2_AP_VIDEO_TURBINE
+ default n
+
+config RT2860V2_80211N_DRAFT3
+ bool "802.11n Draft3"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_INTELLIGENT_RATE_ADAPTION
+ bool "Intelligent Rate Adaption"
+ depends on RT2860V2_AP
+
+config RT2860V2_AP_TXBF
+ bool "Tx Beam Forming"
+ depends on RT2860V2_AP
+ depends on RALINK_RT3883
+
+config RT2860V2_AP_RTMP_INTERNAL_TX_ALC
+ bool "TSSI Compensation"
+ depends on RT2860V2_AP
+ depends on RALINK_RT3350 || RALINK_RT3352 || RALINK_RT5350
+
+#config RT2860V2_EXT_CHANNEL_LIST
+# bool "Extension Channel List"
+# depends on RT2860V2_AP
+
+#config RT2860V2_KTHREAD
+# bool "Kernel Thread"
+# depends on RT2860V2_AP
+
+#config RT2860V2_AUTO_CH_SELECT_ENHANCE
+# bool "Auto Channel Selection Enhancement"
+# depends on RT2860V2_AP
+
+#config RT2860V2_80211R_FT
+# bool "802.11r Fast BSS Transition"
+# depends on RT2860V2_AP
+
+#config RT2860V2_80211R_RR
+# bool "802.11k Radio Resource Management"
+# depends on RT2860V2_AP
+
+#config RT2860V2_SINGLE_SKU
+# bool "Single SKU"
+# depends on RT2860V2_AP
+
+#config RT2860V2_MCAST_RATE_SPECIFIC
+# bool "User specific tx rate of mcast pkt"
+# depends on RT2860V2_AP
+
+#config RT2860V2_SNMP
+# bool "Net-SNMP Support"
+# depends on RT2860V2_AP
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.usb b/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.usb
new file mode 100644
index 0000000000..902fab93d3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.usb
@@ -0,0 +1,111 @@
+config RTUSB_AP
+ tristate "Ralink WiFi USB combo driver AP module"
+ depends on m
+ default m
+
+config RTUSB_AP_WSC
+ bool "WPS support including WPS2.0"
+ depends on RTUSB_AP
+ default y
+
+config RTUSB_AP_MBSS
+ bool "MBSS support"
+ depends on RTUSB_AP
+ default y
+
+config RTUSB_AP_NEW_MBSS_MODE
+ bool "New MBSS support"
+ depends on RTUSB_AP_MBSS
+
+config RTUSB_WDS
+ bool "WDS support"
+ depends on RTUSB_AP
+
+config RTUSB_APCLI
+ bool "APClient support"
+ depends on RTUSB_AP
+
+config RTUSB_DFS
+ bool "DFS support"
+ depends on RTUSB_AP
+
+config RTUSB_CS
+ bool "CS support"
+ depends on RTUSB_AP
+
+config RTUSB_IGMP_SNOOP
+ bool "IGMP snoop support"
+ depends on RTUSB_AP
+
+config RTUSB_NETIF_BLOCK
+ bool "NETIF block support"
+ depends on RTUSB_AP
+
+config RTUSB_DLS
+ bool "DLS support"
+ depends on RTUSB_AP
+
+config RTUSB_IDS
+ bool "IDS support"
+ depends on RTUSB_AP
+
+config RTUSB_AP_FLASH_SUPPORT
+ bool "FLASH support"
+ depends on RTUSB_AP
+
+config RTUSB_AP_80211N_DRAFT3
+ bool "802.11n Draft3 support"
+ depends on RTUSB_AP
+ default y
+
+# Chip related
+config RT2870_AP
+ bool "RT2870 support"
+ depends on RTUSB_AP
+
+config RT3572_AP
+ bool "RT3572 support"
+ depends on RTUSB_AP
+
+config RT3573_AP
+ bool "RT3573 support"
+ depends on RTUSB_AP
+
+config RT5572_AP
+ bool "RT5572 support"
+ depends on RTUSB_AP
+ default y
+
+# ATE
+config RTUSB_AP_ATE
+ bool "ATE support"
+ depends on RTUSB_AP
+
+config RT2870_AP_ATE
+ bool "RT2870 ATE support"
+ depends on RTUSB_AP_ATE && RT2870_AP
+
+config RT3572_AP_ATE
+ bool "RT3572 ATE support"
+ depends on RTUSB_AP_ATE && RT3572_AP
+
+config RT5572_AP_ATE
+ bool "RT5572 ATE support"
+ depends on RTUSB_AP_ATE && RT5572_AP
+ default y
+
+# QA
+config RTUSB_AP_QA
+ bool "QA tool support"
+ depends on RTUSB_AP_ATE
+ default y
+
+config RTUSB_AP_WAPI
+ bool "WAPI support"
+ depends on RTUSB_AP
+
+# Platform specific
+config RT5572_AP_WDS
+ bool
+ depends on RTUSB_WDS
+ default y
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.sta.soc b/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.sta.soc
new file mode 100644
index 0000000000..18027ef829
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Kconfig.sta.soc
@@ -0,0 +1,89 @@
+config RT2860V2_STA
+ tristate "Ralink RT2860 802.11n STA support"
+ depends on NET_RADIO
+
+config RT2860V2_STA_WPA_SUPPLICANT
+ bool "WPA Supplicant"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_ETH_CONVERT
+ bool "Ethernet Convert Support"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_DPB
+ bool
+ depends on RT2860V2_STA_ETH_CONVERT
+ default y
+
+config RT2860V2_STA_WMM_ACM
+ bool "WMM ACM Support"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_LED
+ bool "LED Support"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_IDS
+ bool "IDS (Intrusion Detection System) Support"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_WSC
+ bool "WSC (WiFi Simple Config)"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_CARRIER
+ bool "Carrier Sense Support"
+ depends on RT2860V2_STA
+ select RALINK_TIMER
+ select RALINK_TIMER_DFS
+
+config RT2860V2_STA_DLS
+ bool "DLS ((Direct-Link Setup) Support"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_MESH
+ bool "MESH Support"
+ depends on RT2860V2_STA
+
+config RT2860V2_RT3XXX_STA_ANTENNA_DIVERSITY
+ bool "Antenna Diversity Support"
+ depends on RT2860V2_STA
+
+config RT2860V2_HW_STA_ANTENNA_DIVERSITY
+ bool "Antenna Diversity Support"
+ depends on RT2860V2_STA
+ depends on RALINK_RT5350
+
+#config RT2860V2_STA_WAPI
+# bool "WAPI Support"
+# depends on RT2860V2_STA
+
+config RT2860V2_STA_VIDEO_TURBINE
+ bool "Video Turbine support"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_INTELLIGENT_RATE_ADAPTION
+ bool "Intelligent Rate Adaption"
+ depends on RT2860V2_STA
+
+config RT2860V2_STA_TXBF
+ bool "Tx Bean Forming Support (Only 3883)"
+ depends on RT2860V2_STA
+ depends on RALINK_RT3883
+
+config RT2860V2_STA_RTMP_INTERNAL_TX_ALC
+ bool "TSSI Compensation"
+ depends on RT2860V2_STA
+ depends on RALINK_RT3350 || RALINK_RT3352 || RALINK_RT5350
+
+config RT2860V2_STA_80211N_DRAFT3
+ bool "802.11n Draft3"
+ depends on RT2860V2_STA
+
+#config RT2860V2_EXT_CHANNEL_LIST
+# bool "Extension Channel List"
+# depends on RT2860V2_STA
+
+#config RT2860V2_SNMP
+# bool "Net-SNMP Support"
+# depends on RT2860V2_STA
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4 b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4
new file mode 100644
index 0000000000..93be7f888d
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4
@@ -0,0 +1,291 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+MOD_NAME = rt$(MODULE)ap
+DAT_PATH = /etc/Wireless/RT$(MODULE_DAT)AP
+DAT_FILE_NAME = RT$(MODULE_DAT)AP.dat
+endif
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+#ifdef WAPI_SUPPORT
+ifeq ($(HAS_WAPI_SUPPORT),y)
+OBJ := -DEXPORT_SYMTAB
+endif
+#endif // WAPI_SUPPORT //
+
+OBJ := $(MOD_NAME).o
+
+#ifdef CONFIG_AP_SUPPORT
+RT28XX_AP_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)/rate_ctrl/ra_ctrl.o\
+ $(RT28xx_DIR)/rate_ctrl/alg_legacy.o\
+ $(RT28xx_DIR)/os/linux/rt_profile.o\
+ $(RT28xx_DIR)/ap/ap_mbss.o\
+ $(RT28xx_DIR)/chips/rtmp_chip.o\
+ $(RT28xx_DIR)/ap/ap.o\
+ $(RT28xx_DIR)/ap/ap_assoc.o\
+ $(RT28xx_DIR)/ap/ap_auth.o\
+ $(RT28xx_DIR)/ap/ap_connect.o\
+ $(RT28xx_DIR)/ap/ap_mlme.o\
+ $(RT28xx_DIR)/ap/ap_sanity.o\
+ $(RT28xx_DIR)/ap/ap_sync.o\
+ $(RT28xx_DIR)/ap/ap_wpa.o\
+ $(RT28xx_DIR)/ap/ap_data.o\
+ $(RT28xx_DIR)/common/uapsd.o\
+ $(RT28xx_DIR)/ap/ap_autoChSel.o\
+ $(RT28xx_DIR)/ap/ap_qload.o\
+ $(RT28xx_DIR)/ap/ap_cfg.o
+
+ifeq ($(OSABL),NO)
+RT28XX_AP_OBJ := \
+ $(RT28xx_DIR)/ap/ap_mbss_inf.o\
+ $(RT28xx_DIR)/common/rt_os_util.o\
+ $(RT28xx_DIR)/os/linux/ap_ioctl.o\
+ $(RT28xx_DIR)/os/linux/rt_linux.o\
+ $(RT28xx_DIR)/os/linux/rt_main_dev.o
+else
+RT28XX_AP_OBJ := \
+ $(RT28xx_DIR)/os/linux/rt_symb.o
+endif
+
+ifeq ($(HAS_NEW_RATE_ADAPT_SUPPORT),y)
+RT28XX_AP_OBJS += $(RT28xx_DIR)/rate_ctrl/alg_grp.o
+endif
+
+#ifdef DOT11_N_SUPPORT
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/common/ba_action.o
+
+#ifdef TXBF_SUPPORT
+ifeq ($(HAS_TXBF_SUPPORT),y)
+rt$(MODULE)ap-objs += \
+ $(RT28xx_DIR)/common/cmm_txbf.o\
+ $(RT28xx_DIR)/common/cmm_txbf_cal.o
+endif
+#endif // TXBF_SUPPORT //
+endif
+#endif // DOT11_N_SUPPORT //
+
+#ifdef BG_FT_SUPPORT
+ifeq ($(OSABL),NO)
+ifeq ($(HAS_BGFP_SUPPORT),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/os/linux/br_ftph.o
+endif
+endif
+#endif // BG_FT_SUPPORT //
+
+#ifdef LED_CONTROL_SUPPORT
+ifeq ($(HAS_LED_CONTROL_SUPPORT),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/common/rt_led.o
+endif
+#endif // LED_CONTROL_SUPPORT //
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ifeq ($(HAS_RT2880_RT2860_COEXIST),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/os/linux/rt_pci_rbus.o\
+ $(RT28xx_DIR)/os/linux/rt_rbus_pci_util.o\
+ $(RT28xx_DIR)/os/linux/pci_main_dev.o\
+ $(RT28xx_DIR)/common/dfs.o
+endif
+
+ifeq ($(HAS_ATE),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/ate/common/rt_ate.o
+endif
+
+ifeq ($(HAS_QA_SUPPORT),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/ate/common/rt_qa.o
+endif
+
+#ifdef WSC_INCLUDED
+ifeq ($(HAS_WSC),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/common/wsc.o\
+ $(RT28xx_DIR)/common/wsc_tlv.o\
+ $(RT28xx_DIR)/common/wsc_ufd.o\
+ $(RT28xx_DIR)/common/crypt_biginteger.o\
+ $(RT28xx_DIR)/common/crypt_dh.o
+endif
+ifeq ($(HAS_WSC_V2),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/common/wsc_v2.o
+endif
+#endif // WSC_INCLUDED //
+
+
+
+ifeq ($(HAS_WDS),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/ap/ap_wds.o
+
+ifeq ($(OSABL),NO)
+RT28XX_AP_OBJ += \
+ ../../ap/ap_wds_inf.o
+endif
+endif
+
+#ifdef APCLI_SUPPORT
+ifeq ($(HAS_APCLI),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/ap/ap_apcli.o \
+ $(RT28xx_DIR)/ap/apcli_ctrl.o \
+ $(RT28xx_DIR)/ap/apcli_sync.o \
+ $(RT28xx_DIR)/ap/apcli_auth.o \
+ $(RT28xx_DIR)/ap/apcli_assoc.o \
+ $(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
+
+ifeq ($(OSABL),NO)
+RT28XX_AP_OBJ += \
+ ../../ap/ap_apcli_inf.o
+endif
+endif
+#endif // APCLI_SUPPORT //
+
+ifeq ($(HAS_BLOCK_NET_IF),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/common/netif_block.o
+endif
+
+ifeq ($(HAS_IGMP_SNOOP_SUPPORT),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/common/igmp_snoop.o
+endif
+
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/ap/ap_dls.o
+endif
+
+ifeq ($(HAS_IDS_SUPPORT),y)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/ap/ap_ids.o
+endif
+
+ifeq ($(PLATFORM),IKANOS_V160)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/os/linux/vr_ikans.o
+endif
+
+ifeq ($(PLATFORM),IKANOS_V180)
+RT28XX_AP_OBJ += $(RT28xx_DIR)/os/linux/vr_ikans.o
+endif
+
+
+#ifdef WAPI_SUPPORT
+ifeq ($(HAS_WAPI_SUPPORT),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/common/wapi.o
+endif
+#endif // WAPI_SUPPORT //
+
+
+
+
+ifeq ($(HAS_CLIENT_WDS_SUPPORT),y)
+RT28XX_AP_OBJ += \
+ $(RT28xx_DIR)/common/client_wds.o
+endif
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+PHONY := all release clean install uninstall
+
+all:$(OBJ)
+
+rt$(MODULE)sta.o: $(RT28XX_STA_OBJ)
+ $(LD) -r $^ -o $@
+
+rt$(MODULE)ap.o: $(RT28XX_AP_OBJ)
+ $(LD) -r $^ -o $@
+
+rt$(MODULE)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)
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.netif b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.netif
new file mode 100644
index 0000000000..dcc5b7f9e0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.netif
@@ -0,0 +1,103 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+MOD_NAME = rtnet$(MODULE)ap
+endif
+#endif // CONFIG_AP_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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+PHONY := all clean
+
+all:$(OBJ)
+
+rtnet$(MODULE)sta.o: $(RT28XX_STA_OBJ)
+ $(LD) -r $^ -o $@
+
+rtnet$(MODULE)ap.o: $(RT28XX_AP_OBJ)
+ $(LD) -r $^ -o $@
+
+rtnet$(MODULE)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)
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.util b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.util
new file mode 100644
index 0000000000..dc26a243a9
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.util
@@ -0,0 +1,82 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+MOD_NAME = rtutil$(MODULE)ap
+endif
+#endif // CONFIG_AP_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 //
+
+
+
+
+
+PHONY := all clean
+
+all:$(OBJ)
+
+rtutil$(MODULE)sta.o: $(RT28XX_STA_OBJ)
+ $(LD) -r $^ -o $@
+
+rtutil$(MODULE)ap.o: $(RT28XX_AP_OBJ)
+ $(LD) -r $^ -o $@
+
+rtutil$(MODULE)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)
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6 b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6
new file mode 100644
index 0000000000..921c3eaa0f
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6
@@ -0,0 +1,652 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+obj_wsc :=
+obj_vht :=
+obj_cmm := \
+ ../../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/cmm_radar.o\
+ ../../common/spectrum.o\
+ ../../common/rtmp_timer.o\
+ ../../common/rt_channel.o\
+ ../../common/cmm_profile.o\
+ ../../common/cmm_asic.o\
+ ../../common/scan.o\
+ ../../common/cmm_cmd.o\
+ ../../common/uapsd.o\
+ ../../common/ps.o\
+ ../../rate_ctrl/ra_ctrl.o\
+ ../../rate_ctrl/alg_legacy.o\
+ ../../rate_ctrl/alg_ags.o\
+ ../../chips/rtmp_chip.o\
+ ../../common/txpower.o\
+ ../../mac/rtmp_mac.o\
+ ../../mgmt/mgmt_hw.o\
+ ../../mgmt/mgmt_entrytb.o\
+ ../../phy/rtmp_phy.o\
+ ../../phy/rlt_phy.o\
+ ../../phy/rlt_rf.o
+
+ifeq ($(HAS_BLOCK_NET_IF),y)
+obj_cmm += ../../common/netif_block.o
+endif
+
+ifeq ($(HAS_NEW_RATE_ADAPT_SUPPORT),y)
+obj_cmm += ../../rate_ctrl/alg_grp.o
+endif
+
+ifeq ($(HAS_RATE_ADAPT_AGS_SUPPORT),y)
+obj_cmm += ../../rate_ctrl/alg_ags.o
+endif
+
+ifeq ($(HAS_DFS_SUPPORT),y)
+obj_cmm += ../../common/cmm_dfs.o
+endif
+
+ifeq ($(HAS_CS_SUPPORT),y)
+obj_cmm += ../../common/cmm_cs.o
+endif
+
+#ifdef DOT11_N_SUPPORT
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+obj_cmm += \
+ ../../common/ba_action.o\
+ ../../mgmt/mgmt_ht.o
+
+#ifdef TXBF_SUPPORT
+ifeq ($(HAS_TXBF_SUPPORT),y)
+obj_cmm += \
+ ../../common/cmm_txbf.o\
+ ../../common/cmm_txbf_cal.o
+endif
+#endif // TXBF_SUPPORT //
+endif
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DOT11_VHT_SUPPORT
+ifeq ($(HAS_DOT11_VHT_SUPPORT),y)
+obj_vht += ../../mgmt/mgmt_vht.o\
+ ../../common/vht.o
+endif
+#endif // DOT11_VHT_SUPPORT //
+
+#ifdef WSC_INCLUDED
+ifeq ($(HAS_WSC),y)
+obj_wsc += \
+ ../../common/wsc.o\
+ ../../common/wsc_tlv.o\
+ ../../common/crypt_biginteger.o\
+ ../../common/crypt_dh.o
+endif
+ifeq ($(HAS_WSC_V2),y)
+obj_wsc += ../../common/wsc_v2.o
+endif
+#endif // WSC_INCLUDED //
+
+
+#ifdef ANDES_FIRMWARE_SUPPORT
+ifeq ($(HAS_ANDES_FIRMWARE_SUPPORT),y)
+obj_cmm += ../../mcu/rtmp_and.o
+endif
+#endif /* ANDES_FIRMWARE_SUPPORT */
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+ifneq ($(findstring 7601,$(CHIPSET)),)
+MOD_NAME = mt$(MODULE)ap
+else
+MOD_NAME = rt$(MODULE)ap
+endif
+DAT_PATH = /etc/Wireless/RT$(CHIPSET_DAT)AP
+DAT_FILE_NAME = RT$(CHIPSET_DAT)AP.dat
+endif
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+obj-m := $(MOD_NAME).o
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+$(MOD_NAME)-objs := \
+ ../../os/linux/rt_profile.o\
+ ../../ap/ap_mbss.o\
+ ../../ap/ap.o\
+ ../../ap/ap_assoc.o\
+ ../../ap/ap_auth.o\
+ ../../ap/ap_connect.o\
+ ../../ap/ap_mlme.o\
+ ../../ap/ap_sanity.o\
+ ../../ap/ap_sync.o\
+ ../../ap/ap_wpa.o\
+ ../../ap/ap_data.o\
+ ../../ap/ap_autoChSel.o\
+ ../../ap/ap_qload.o\
+ ../../ap/ap_cfg.o\
+ $(obj_vht)\
+ $(obj_cmm)\
+ $(obj_wsc)
+
+#ifdef WSC_INCLUDED
+ifeq ($(HAS_WSC),y)
+$(MOD_NAME)-objs += \
+ ../../common/wsc_ufd.o
+endif
+#endif // WSC_INCLUDE //
+
+ifeq ($(HAS_ATE),y)
+$(MOD_NAME)-objs += ../../ate/common/rt_ate.o
+endif
+
+ifeq ($(HAS_QA_SUPPORT),y)
+$(MOD_NAME)-objs += ../../ate/common/rt_qa.o
+endif
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../ap/ap_mbss_inf.o\
+ ../../common/rt_os_util.o\
+ ../../os/linux/ap_ioctl.o\
+ ../../os/linux/rt_linux.o\
+ ../../os/linux/rt_main_dev.o
+else
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_symb.o
+endif
+
+#ifdef BG_FT_SUPPORT
+ifeq ($(OSABL),NO)
+ifeq ($(HAS_BGFP_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../os/linux/br_ftph.o
+endif
+endif
+#endif // BG_FT_SUPPORT //
+
+
+#ifdef CRDA_SUPPORT
+ifeq ($(OSABL),NO)
+ifeq ($(HAS_CFG80211_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../os/linux/cfg80211.o\
+ ../../os/linux/cfg80211drv.o
+endif
+endif
+
+ifeq ($(OSABL),YES)
+ifeq ($(HAS_CFG80211_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../os/linux/cfg80211drv.o
+endif
+endif
+#endif // CRDA_SUPPORT //
+
+#ifdef LED_CONTROL_SUPPORT
+ifeq ($(HAS_LED_CONTROL_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/rt_led.o
+endif
+#endif // LED_CONTROL_SUPPORT //
+
+
+ifeq ($(HAS_RT2880_RT2860_COEXIST),y)
+RT28XX_AP_OBJ += \
+ ../../os/linux/rt_pci_rbus.o\
+ ../../os/linux/rt_rbus_pci_util.o\
+ ../../os/linux/pci_main_dev.o\
+ ../../common/dfs.o
+endif
+
+
+
+ifeq ($(HAS_WDS),y)
+$(MOD_NAME)-objs += ../../ap/ap_wds.o
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../ap/ap_wds_inf.o
+endif
+endif
+
+#ifdef APCLI_SUPPORT
+ifeq ($(HAS_APCLI),y)
+$(MOD_NAME)-objs += \
+ ../../ap/ap_apcli.o \
+ ../../ap/apcli_ctrl.o \
+ ../../ap/apcli_sync.o \
+ ../../ap/apcli_auth.o \
+ ../../ap/apcli_assoc.o \
+ ../../common/cmm_mat.o \
+ ../../common/cmm_mat_iparp.o \
+ ../../common/cmm_mat_pppoe.o \
+ ../../common/cmm_mat_ipv6.o
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../ap/ap_apcli_inf.o
+endif
+endif
+#endif // APCLI_SUPPORT //
+
+ifeq ($(HAS_IGMP_SNOOP_SUPPORT),y)
+$(MOD_NAME)-objs += ../../common/igmp_snoop.o
+endif
+
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+$(MOD_NAME)-objs += ../../ap/ap_dls.o
+endif
+
+ifeq ($(HAS_IDS_SUPPORT),y)
+$(MOD_NAME)-objs += ../../ap/ap_ids.o
+endif
+
+ifeq ($(PLATFORM),IKANOS_V160)
+$(MOD_NAME)-objs += ../../os/linux/vr_ikans.o
+endif
+
+ifeq ($(PLATFORM),IKANOS_V180)
+$(MOD_NAME)-objs += ../../os/linux/vr_ikans.o
+endif
+
+ifeq ($(PLATFORM),BL2348)
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += ../../os/linux/vr_bdlt.o
+endif
+endif
+#ifdef PLATFORM_BL23570
+ifeq ($(PLATFORM),BL23570)
+rt$(CHIPSET)ap-objs += \
+ ../../os/linux/vr_bdlt.o
+endif
+#endif // PLATFORM_BL23570 //
+
+
+#ifdef WAPI_SUPPORT
+ifeq ($(HAS_WAPI_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/wapi.o
+endif
+#endif // WAPI_SUPPORT //
+
+
+
+
+
+ifeq ($(HAS_CLIENT_WDS_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/client_wds.o
+endif
+
+ifeq ($(HAS_EASY_CONFIG_SETUP_SUPPORT),y)
+ifeq ($(PLATFORM),RALINK_3052)
+$(MOD_NAME)-objs += lib.a
+endif
+endif
+
+endif
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+
+#chip releated
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef RT3290
+ifneq ($(findstring 3290,$(CHIPSET)),)
+$(MOD_NAME)-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/rt30xx.o\
+ ../../chips/rt3290.o
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_pci_rbus.o\
+ ../../os/linux/rt_rbus_pci_util.o\
+ ../../os/linux/pci_main_dev.o
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+$(MOD_NAME)-objs += \
+ ../../common/frq_cal.o
+endif
+
+endif
+#endif // RT3290 //
+
+#ifdef RT6592
+ifneq ($(findstring 6592,$(CHIPSET)),)
+$(MOD_NAME)-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/rt6592.o
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_pci_rbus.o\
+ ../../os/linux/rt_rbus_pci_util.o\
+ ../../os/linux/pci_main_dev.o
+endif
+endif
+#endif // RT6592 //
+
+
+
+
+
+#ifdef RT6590
+ifneq ($(findstring 6590,$(CHIPSET)),)
+$(MOD_NAME)-objs += \
+ ../../common/cmm_mac_pci.o\
+ ../../common/cmm_data_pci.o\
+ ../../os/linux/rt_rbus_pci_drv.o\
+ ../../common/ee_efuse.o\
+ ../../common/ee_prom.o\
+ ../../common/rt_rf.o\
+ ../../chips/rt30xx.o\
+ ../../chips/rt65xx.o\
+ ../../chips/rt6590.o\
+ ../../mac/ral_nmac.o\
+ ../../mcu/rtmp_and.o
+
+ifeq ($(HAS_RTMP_FLASH_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/ee_flash.o
+endif
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_pci_rbus.o\
+ ../../os/linux/rt_rbus_pci_util.o\
+ ../../os/linux/pci_main_dev.o
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+$(MOD_NAME)-objs += \
+ ../../common/frq_cal.o
+endif
+
+endif
+#endif // RT6590 //
+
+
+#ifdef RT6570
+ifneq ($(findstring 6570,$(CHIPSET)),)
+$(MOD_NAME)-objs += \
+ ../../common/cmm_mac_usb.o\
+ ../../common/cmm_data_usb.o\
+ ../../common/rtusb_io.o\
+ ../../common/rtusb_data.o\
+ ../../common/rtusb_bulk.o\
+ ../../os/linux/rt_usb.o\
+ ../../common/ee_prom.o\
+ ../../common/ee_efuse.o\
+ ../../common/rtmp_mcu.o\
+ ../../common/rt_rf.o\
+ ../../chips/rt30xx.o\
+ ../../chips/rt65xx.o\
+ ../../chips/rt6590.o\
+ ../../mac/ral_nmac.o\
+ ../../mcu/rtmp_and.o
+
+ifeq ($(HAS_RTMP_FLASH_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/ee_flash.o
+endif
+
+ifeq ($(HAS_TSO_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../naf/net_acc.o\
+ ../../naf/tso.o\
+ ../../naf/cso.o
+endif
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_usb.o\
+ ../../os/linux/rt_usb_util.o\
+ ../../os/linux/usb_main_dev.o\
+ ../../common/rtusb_dev_id.o
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+$(MOD_NAME)-objs += \
+ ../../common/frq_cal.o
+endif
+
+endif
+#endif // RT6570 //
+
+
+#ifdef RT8592
+ifneq ($(findstring 8592,$(CHIPSET)),)
+$(MOD_NAME)-objs += \
+ ../../common/cmm_mac_pci.o\
+ ../../common/cmm_data_pci.o\
+ ../../os/linux/rt_rbus_pci_drv.o\
+ ../../common/ee_prom.o\
+ ../../common/ee_efuse.o\
+ ../../common/rtmp_mcu.o\
+ ../../common/rt_rf.o\
+ ../../chips/rt30xx.o\
+ ../../chips/rt65xx.o\
+ ../../chips/rt6592.o\
+ ../../chips/rt85592.o\
+ ../../mac/ral_nmac.o\
+ ../../mcu/rtmp_and.o
+
+ifeq ($(HAS_RTMP_FLASH_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/ee_flash.o
+endif
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_pci_rbus.o\
+ ../../os/linux/rt_rbus_pci_util.o\
+ ../../os/linux/pci_main_dev.o
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+$(MOD_NAME)-objs += \
+ ../../common/frq_cal.o
+endif
+
+endif
+#endif // RT8592 //
+
+
+#ifdef MT7601E
+ifneq ($(findstring 7601E,$(CHIPSET)),)
+$(MOD_NAME)-objs += \
+ ../../common/cmm_mac_pci.o\
+ ../../common/cmm_data_pci.o\
+ ../../os/linux/rt_rbus_pci_drv.o\
+ ../../common/ee_prom.o\
+ ../../common/ee_efuse.o\
+ ../../mcu/rtmp_and.o\
+ ../../mcu/rtmp_mcu.o\
+ ../../mcu/rtmp_M51.o\
+ ../../common/rt_rf.o\
+ ../../chips/rt30xx.o\
+ ../../chips/mt7601.o\
+ ../../mac/ral_omac.o
+
+ifeq ($(HAS_RTMP_FLASH_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/ee_flash.o
+endif
+
+ifeq ($(HAS_ATE),y)
+$(MOD_NAME)-objs += \
+ ../../ate/chips/mt7601_ate.o\
+ ../../ate/common/ate_usb.o
+endif
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_pci_rbus.o\
+ ../../os/linux/rt_rbus_pci_util.o\
+ ../../os/linux/pci_main_dev.o
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+$(MOD_NAME)-objs += \
+ ../../common/frq_cal.o
+endif
+
+endif
+#endif // MT7601E //
+
+
+#ifdef MT7601U
+ifneq ($(findstring 7601U,$(CHIPSET)),)
+$(MOD_NAME)-objs += \
+ ../../common/cmm_mac_usb.o\
+ ../../common/cmm_data_usb.o\
+ ../../common/rtusb_io.o\
+ ../../common/rtusb_data.o\
+ ../../common/rtusb_bulk.o\
+ ../../os/linux/rt_usb.o\
+ ../../common/ee_prom.o\
+ ../../common/ee_efuse.o\
+ ../../mcu/rtmp_and.o\
+ ../../mcu/rtmp_mcu.o\
+ ../../mcu/rtmp_M51.o\
+ ../../common/rt_rf.o\
+ ../../chips/mt7601.o\
+ ../../mac/ral_omac.o
+
+ifeq ($(HAS_RTMP_FLASH_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/ee_flash.o
+endif
+
+ifeq ($(HAS_ATE),y)
+$(MOD_NAME)-objs += \
+ ../../ate/chips/mt7601_ate.o\
+ ../../ate/common/ate_usb.o
+endif
+
+ifeq ($(HAS_TSO_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../naf/net_acc.o\
+ ../../naf/tso.o\
+ ../../naf/cso.o
+endif
+
+ifeq ($(OSABL),NO)
+$(MOD_NAME)-objs += \
+ ../../os/linux/rt_usb.o\
+ ../../os/linux/rt_usb_util.o\
+ ../../os/linux/usb_main_dev.o\
+ ../../common/rtusb_dev_id.o
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+$(MOD_NAME)-objs += \
+ ../../common/frq_cal.o
+endif
+
+endif
+#endif // MT7601U //
+
+
+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)
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.netif b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.netif
new file mode 100644
index 0000000000..36911c7f12
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.netif
@@ -0,0 +1,99 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+MOD_NAME = rtnet$(MODULE)ap
+endif
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+obj-m := $(MOD_NAME).o
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+$(MOD_NAME)-objs := \
+ ../../ap/ap_mbss_inf.o\
+ ../../os/linux/ap_ioctl.o\
+ ../../os/linux/rt_main_dev.o
+
+ifeq ($(HAS_CFG80211_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../os/linux/cfg80211.o
+endif
+
+ifeq ($(HAS_WDS),y)
+$(MOD_NAME)-objs += \
+ ../../ap/ap_wds_inf.o
+endif
+
+ifeq ($(HAS_APCLI),y)
+$(MOD_NAME)-objs += \
+ ../../ap/ap_apcli_inf.o
+endif
+
+ifeq ($(HAS_MESH_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../common/mesh_inf.o
+endif
+
+endif
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+#chip related
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef MT7601
+ifneq ($(findstring 7601,$(CHIPSET)),)
+$(MOD_NAME)-objs += \
+ ../../common/rtusb_dev_id.o\
+ ../../os/linux/usb_main_dev.o
+endif
+#endif // MT7601 //
+
+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}
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.util b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.util
new file mode 100644
index 0000000000..d237ab53a2
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.util
@@ -0,0 +1,72 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+MOD_NAME = rtutil$(MODULE)ap
+endif
+#endif // CONFIG_AP_SUPPORT //
+
+
+
+obj-m := $(MOD_NAME).o
+
+#ifdef CONFIG_AP_SUPPORT
+ifeq ($(RT28xx_MODE),AP)
+$(MOD_NAME)-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)
+$(MOD_NAME)-objs += \
+ ../../os/linux/vr_bdlt.o
+endif
+
+ifeq ($(PLATFORM),BLUBB)
+$(MOD_NAME)-objs += \
+ ../../os/linux/vr_bdlt.o
+endif
+
+ifeq ($(HAS_BGFP_SUPPORT),y)
+$(MOD_NAME)-objs += \
+ ../../os/linux/br_ftph.o
+endif
+endif
+#endif // CONFIG_AP_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}
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.soc b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.soc
new file mode 100644
index 0000000000..1e781a3e22
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.soc
@@ -0,0 +1,394 @@
+EXTRA_CFLAGS = -Idrivers/net/wireless/rt2860v2/include -Idrivers/net/wireless/rt2860v2/ate/include
+
+obj-$(CONFIG_RT2860V2_AP) += rt2860v2_ap.o
+
+rt2860v2_ap-objs += ../rt2860v2/common/crypt_md5.o
+rt2860v2_ap-objs += ../rt2860v2/common/crypt_sha2.o
+rt2860v2_ap-objs += ../rt2860v2/common/crypt_hmac.o
+rt2860v2_ap-objs += ../rt2860v2/common/crypt_aes.o
+rt2860v2_ap-objs += ../rt2860v2/common/crypt_arc4.o
+rt2860v2_ap-objs += ../rt2860v2/common/mlme.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_wep.o
+rt2860v2_ap-objs += ../rt2860v2/common/action.o
+rt2860v2_ap-objs += ../rt2860v2/common/ba_action.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_data.o
+rt2860v2_ap-objs += ../rt2860v2/common/rtmp_init.o
+rt2860v2_ap-objs += ../rt2860v2/common/rtmp_init_inf.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_tkip.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_aes.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_sync.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_sanity.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_info.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_cfg.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_wpa.o
+rt2860v2_ap-objs += ../rt2860v2/common/dfs.o
+rt2860v2_ap-objs += ../rt2860v2/common/dfs_mcu.o
+rt2860v2_ap-objs += ../rt2860v2/common/spectrum.o
+rt2860v2_ap-objs += ../rt2860v2/common/rtmp_timer.o
+rt2860v2_ap-objs += ../rt2860v2/common/rt_channel.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_profile.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_asic.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_cmd.o
+rt2860v2_ap-objs += ../rt2860v2/common/rtmp_swmcu.o
+rt2860v2_ap-objs += ../rt2860v2/common/rt_os_util.o
+rt2860v2_ap-objs += ../rt2860v2/common/eeprom.o
+rt2860v2_ap-objs += ../rt2860v2/common/ee_flash.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_mac_pci.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_data_pci.o
+
+rt2860v2_ap-objs += ../rt2860v2/chips/rtmp_chip.o
+
+rt2860v2_ap-objs += ../rt2860v2/ap/ap.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_assoc.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_auth.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_connect.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_mlme.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_sanity.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_sync.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_wpa.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_data.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_uapsd.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_autoChSel.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_qload.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_cfg.o
+
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rt_proc.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rt_linux.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rt_profile.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rt_main_dev.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/ap_ioctl.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rt_pci_rbus.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rt_rbus_pci_util.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rt_rbus_pci_drv.o
+rt2860v2_ap-objs += ../rt2860v2/os/linux/rbus_main_dev.o
+rt2860v2_ap-objs += ../rt2860v2/common/rt_ate.o
+
+ifeq ($(CONFIG_RT2860V2_AP_WMM_ACM),y)
+rt2860v2_ap-objs += ../rt2860v2/common/acm_edca.o
+rt2860v2_ap-objs += ../rt2860v2/common/acm_comm.o
+rt2860v2_ap-objs += ../rt2860v2/common/acm_iocl.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_LED),y)
+rt2860v2_ap-objs += ../rt2860v2/common/rt_led.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_WSC),y)
+rt2860v2_ap-objs += ../rt2860v2/common/wsc.o
+rt2860v2_ap-objs += ../rt2860v2/common/wsc_tlv.o
+rt2860v2_ap-objs += ../rt2860v2/common/crypt_dh.o
+rt2860v2_ap-objs += ../rt2860v2/common/crypt_biginteger.o
+rt2860v2_ap-objs += ../rt2860v2/common/wsc_ufd.o
+rt2860v2_ap-objs += ../rt2860v2/common/wsc_v2.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_NINTENDO),y)
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_nintendo.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_WDS),y)
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_wds.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_wds_inf.o
+rt2860v2_ap-objs += ../rt2860v2/common/client_wds.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_MBSS),y)
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_mbss.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_mbss_inf.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_APCLI),y)
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_apcli.o
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_apcli_inf.o
+rt2860v2_ap-objs += ../rt2860v2/ap/apcli_assoc.o
+rt2860v2_ap-objs += ../rt2860v2/ap/apcli_auth.o
+rt2860v2_ap-objs += ../rt2860v2/ap/apcli_ctrl.o
+rt2860v2_ap-objs += ../rt2860v2/ap/apcli_sync.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_mat.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_mat_iparp.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_mat_pppoe.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_mat_ipv6.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_IGMP_SNOOP),y)
+rt2860v2_ap-objs += ../rt2860v2/common/igmp_snoop.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_NETIF_BLOCK),y)
+rt2860v2_ap-objs += ../rt2860v2/common/netif_block.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_DLS),y)
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_dls.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_IDS),y)
+rt2860v2_ap-objs += ../rt2860v2/ap/ap_ids.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_MESH),y)
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_bmpkt.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_ctrl.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_link_mng.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_sanity.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_tlv.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_inf.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_forwarding.o
+rt2860v2_ap-objs += ../rt2860v2/common/mesh_path_mng.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_RT3XXX_AP_ANTENNA_DIVERSITY),y)
+rt2860v2_ap-objs += ../rt2860v2/os/linux/ap_diversity.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_WAPI),y)
+rt2860v2_ap-objs += ../rt2860v2/common/wapi.o
+rt2860v2_ap-objs += ../rt2860v2/common/wapi_crypt.o
+rt2860v2_ap-objs += ../rt2860v2/common/wapi_sms4.o
+endif
+
+#ifeq ($(CONFIG_RT2860V2_80211R_FT),y)
+#rt2860v2_ap-objs += ../rt2860v2/common/ft.o
+#rt2860v2_ap-objs += ../rt2860v2/common/ft_tlv.o
+#rt2860v2_ap-objs += ../rt2860v2/common/ft_ioctl.o
+#rt2860v2_ap-objs += ../rt2860v2/common/ft_rc.o
+#rt2860v2_ap-objs += ../rt2860v2/ap/ap_ftkd.o
+#endif
+
+#ifeq ($(CONFIG_RT2860V2_80211K_RR),y)
+#rt2860v2_ap-objs += ../rt2860v2/common/rrm_tlv.o
+#rt2860v2_ap-objs += ../rt2860v2/common/rrm_sanity.o
+#rt2860v2_ap-objs += ../rt2860v2/common/rrm.o
+#endif
+
+ifeq ($(CONFIG_RT2860V2_AP_VIDEO_TURBINE),y)
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_video.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT2880),y)
+rt2860v2_ap-objs += ../rt2860v2/chips/rt2880.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT3052),y)
+rt2860v2_ap-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt305x.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT3352),y)
+rt2860v2_ap-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt305x.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt3352.o
+endif
+
+ifeq ($(CONFIG_RT3x52),y)
+rt2860v2_ap-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt305x.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt3352.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT5350),y)
+rt2860v2_ap-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt305x.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt5350.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT3883),y)
+rt2860v2_ap-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt3883.o
+ifeq ($(CONFIG_RT2860V2_AP_TXBF),y)
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_txbf.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_txbf_cal.o
+endif
+endif
+
+###################
+# CFLAGS
+##################
+EXTRA_CFLAGS += -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -DLINUX \
+ -Wall -Wstrict-prototypes -Wno-trigraphs
+
+EXTRA_CFLAGS += -DCONFIG_AP_SUPPORT -DAP_SCAN_SUPPORT -DUAPSD_AP_SUPPORT -DRTMP_RBUS_SUPPORT -DRTMP_MAC_PCI
+EXTRA_CFLAGS += -DDOT11_N_SUPPORT -DSTATS_COUNT_SUPPORT -DRELASE_EXCLUDE -DIAPP_SUPPORT -DDOT1X_SUPPORT
+EXTRA_CFLAGS += -DRALINK_ATE -DRALINK_QA -DCONFIG_RT2880_ATE_CMD_NEW -DNEW_TXCONT -DNEW_TXCARRSUPP
+EXTRA_CFLAGS += -DCONFIG_RA_NAT_NONE
+
+#provide busy time statistics for every TBTT */
+#EXTRA_CFLAGS += -DQLOAD_FUNC_BUSY_TIME_STATS
+
+# provide busy time alarm mechanism
+# use the function to avoid to locate in some noise environments
+#EXTRA_CFLAGS += -DQLOAD_FUNC_BUSY_TIME_ALARM
+
+ifeq ($(CONFIG_RALINK_RT2880),y)
+EXTRA_CFLAGS += -DRT2880
+endif
+
+ifeq ($(CONFIG_RALINK_RT3052),y)
+ifeq ($(CONFIG_RALINK_RT3350),y)
+EXTRA_CFLAGS += -DRT3350 -DRT305x -DRTMP_RF_RW_SUPPORT
+else
+EXTRA_CFLAGS += -DRT3052 -DRT305x -DRTMP_RF_RW_SUPPORT
+endif
+endif
+
+ifeq ($(CONFIG_RALINK_RT3352),y)
+EXTRA_CFLAGS += -DRT3352 -DRT305x -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT3x52),y)
+EXTRA_CFLAGS += -DRT3052 -DRT3352 -DRT305x -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT
+endif
+
+ifeq ($(CONFIG_RALINK_RT5350),y)
+EXTRA_CFLAGS += -DRT5350 -DRT305x -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT
+endif
+
+ifeq ($(CONFIG_RALINK_RT3883),y)
+EXTRA_CFLAGS += -DRT3883 -DDOT11N_SS3_SUPPORT -DA_BAND_SUPPORT -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT
+ifeq ($(CONFIG_RT2860V2_AP_TXBF),y)
+EXTRA_CFLAGS += -DTXBF_SUPPORT
+endif
+EXTRA_CFLAGS += -DSTREAM_MODE_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_DLS),y)
+EXTRA_CFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_IDS),y)
+EXTRA_CFLAGS += -DIDS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_DFS),y)
+EXTRA_CFLAGS += -DDFS_SUPPORT
+EXTRA_CFLAGS += -DNEW_DFS
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_CARRIER),y)
+EXTRA_CFLAGS += -DCARRIER_DETECTION_SUPPORT
+ifeq ($(CONFIG_RALINK_RT3052),y)
+EXTRA_CFLAGS += -DTONE_RADAR_DETECT_SUPPORT
+endif
+endif
+
+ifeq ($(CONFIG_RT2860V2_AUTO_CH_SELECT_ENCANCE),y)
+EXTRA_CFLAGS += -DAUTO_CH_SELECT_ENHANCE
+endif
+
+ifeq ($(CONFIG_RT2860V2_80211N_DRAFT3),y)
+EXTRA_CFLAGS += -DDOT11N_DRAFT3
+endif
+
+ifeq ($(CONFIG_SINGLE_SKU),y)
+EXTRA_CFLAGS += -DSINGLE_SKU
+endif
+
+ifeq ($(CONFIG_RT2860V2_SNMP),y)
+EXTRA_CFLAGS += -DSNMP_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_MCAST_RATE_SPECIFIC),y)
+EXTRA_CFLAGS += -DMCAST_RATE_SPECIFIC
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_WMM_ACM),y)
+EXTRA_CFLAGS += -DWMM_ACM_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_LED),y)
+EXTRA_CFLAGS += -DLED_CONTROL_SUPPORT -DCONFIG_SWMCU_SUPPORT
+ifeq ($(CONFIG_RT2860V2_AP_WSC),y)
+EXTRA_CFLAGS += -DWSC_LED_SUPPORT
+endif
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_NINTENDO),y)
+EXTRA_CFLAGS += -DNINTENDO_AP
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_WSC),y)
+EXTRA_CFLAGS += -DWSC_AP_SUPPORT -DWSC_V2_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_LLTD),y)
+EXTRA_CFLAGS += -DLLTD_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_WDS),y)
+EXTRA_CFLAGS += -DWDS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_MBSS),y)
+EXTRA_CFLAGS += -DMBSS_SUPPORT
+endif
+
+ifeq ($(CONFIG_NEW_MBSSID_MODE),y)
+EXTRA_CFLAGS += -DNEW_MBSSID_MODE
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_APCLI),y)
+EXTRA_CFLAGS += -DAPCLI_SUPPORT
+EXTRA_CFLAGS += -DMAT_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_IGMP_SNOOP),y)
+EXTRA_CFLAGS += -DIGMP_SNOOP_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_NETIF_BLOCK),y)
+EXTRA_CFLAGS += -DBLOCK_NET_IF
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_MESH),y)
+EXTRA_CFLAGS += -DMESH_SUPPORT -DINTEL_CMPC
+endif
+
+ifeq ($(CONFIG_RT2860V2_RT3XXX_AP_ANTENNA_DIVERSITY),y)
+EXTRA_CFLAGS += -DRT3XXX_ANTENNA_DIVERSITY_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_HW_ANTENNA_DIVERSITY),y)
+EXTRA_CFLAGS += -DHW_ANTENNA_DIVERSITY_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_WAPI),y)
+EXTRA_CFLAGS += -DWAPI_SUPPORT
+ifeq ($(CONFIG_RALINK_RT3052),y)
+EXTRA_CFLAGS += -DSOFT_ENCRYPT
+endif
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_COC),y)
+EXTRA_CFLAGS += -DCOC_SUPPORT -DGREENAP_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_EXT_CHANNEL_LIST),y)
+EXTRA_CFLAGS += -DEXT_BUILD_CHANNEL_LIST
+endif
+
+ifeq ($(CONFIG_KTHREAD),y)
+EXTRA_CFLAGS += -DKTHREAD_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_MEMORY_OPTIMIZATION),y)
+EXTRA_CFLAGS += -DMEMORY_OPTIMIZATION
+else
+EXTRA_CFLAGS += -DDBG
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_VIDEO_TURBINE),y)
+EXTRA_CFLAGS += -DVIDEO_TURBINE_SUPPORT
+endif
+
+ifeq ($(CONFIG_RA_NETWORK_WORKQUEUE_BH),y)
+EXTRA_CFLAGS += -DWORKQUEUE_BH
+endif
+
+ifeq ($(CONFIG_RT2860V2_AP_RTMP_INTERNAL_TX_ALC),y)
+EXTRA_CFLAGS += -DRTMP_INTERNAL_TX_ALC
+endif
+
+#ifeq ($(CONFIG_RT2860V2_AP_INTELLIGENT_RATE_ADAPTION),y)
+#EXTRA_CFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+#endif
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.usb b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.usb
new file mode 100644
index 0000000000..7adec8c6d4
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.usb
@@ -0,0 +1,334 @@
+# In-Tree Makefile for USB combo
+EXTRA_CFLAGS += -Idrivers/net/wireless/RT5572_ap/MODULE/include
+EXTRA_CFLAGS += -Idrivers/net/wireless/RT5572_ap/UTIL/include
+EXTRA_CFLAGS += -Idrivers/net/wireless/RT5572_ap/NETIF/include
+EXTRA_CFLAGS += -Idrivers/net/wireless/RT5572_ap/MODULE/ate/include
+
+# UTIL module
+obj-$(CONFIG_RTUSB_AP) += RT5572_ap_util.o
+RT5572_ap_util-y += UTIL/common/rt_os_util.o
+RT5572_ap_util-y += UTIL/os/linux/rt_linux_symb.o
+RT5572_ap_util-y += UTIL/os/linux/rt_rbus_pci_util.o
+RT5572_ap_util-y += UTIL/os/linux/rt_usb_util.o
+RT5572_ap_util-y += UTIL/os/linux/rt_linux.o
+
+# MODULE module
+obj-$(CONFIG_RTUSB_AP) += RT5572_ap.o
+RT5572_ap-y += MODULE/common/crypt_md5.o
+RT5572_ap-y += MODULE/common/crypt_sha2.o
+RT5572_ap-y += MODULE/common/crypt_hmac.o
+RT5572_ap-y += MODULE/common/crypt_aes.o
+RT5572_ap-y += MODULE/common/crypt_arc4.o
+RT5572_ap-y += MODULE/common/mlme.o
+RT5572_ap-y += MODULE/common/cmm_wep.o
+RT5572_ap-y += MODULE/common/action.o
+RT5572_ap-y += MODULE/common/cmm_data.o
+RT5572_ap-y += MODULE/common/rtmp_init.o
+RT5572_ap-y += MODULE/common/rtmp_init_inf.o
+RT5572_ap-y += MODULE/common/cmm_tkip.o
+RT5572_ap-y += MODULE/common/cmm_aes.o
+RT5572_ap-y += MODULE/common/cmm_sync.o
+RT5572_ap-y += MODULE/common/eeprom.o
+RT5572_ap-y += MODULE/common/cmm_sanity.o
+RT5572_ap-y += MODULE/common/cmm_info.o
+RT5572_ap-y += MODULE/common/cmm_cfg.o
+RT5572_ap-y += MODULE/common/cmm_wpa.o
+RT5572_ap-y += MODULE/common/cmm_radar.o
+RT5572_ap-y += MODULE/common/spectrum.o
+RT5572_ap-y += MODULE/common/rtmp_timer.o
+RT5572_ap-y += MODULE/common/rt_channel.o
+RT5572_ap-y += MODULE/common/cmm_profile.o
+RT5572_ap-y += MODULE/common/cmm_asic.o
+RT5572_ap-y += MODULE/common/cmm_cmd.o
+RT5572_ap-y += MODULE/rate_ctrl/ra_ctrl.o
+RT5572_ap-y += MODULE/rate_ctrl/alg_legacy.o
+RT5572_ap-y += MODULE/rate_ctrl/alg_ags.o
+RT5572_ap-y += MODULE/os/linux/rt_profile.o
+RT5572_ap-y += MODULE/chips/rtmp_chip.o
+RT5572_ap-y += MODULE/ap/ap.o
+RT5572_ap-y += MODULE/ap/ap_assoc.o
+RT5572_ap-y += MODULE/ap/ap_auth.o
+RT5572_ap-y += MODULE/ap/ap_connect.o
+RT5572_ap-y += MODULE/ap/ap_mlme.o
+RT5572_ap-y += MODULE/ap/ap_sanity.o
+RT5572_ap-y += MODULE/ap/ap_sync.o
+RT5572_ap-y += MODULE/ap/ap_wpa.o
+RT5572_ap-y += MODULE/ap/ap_data.o
+RT5572_ap-y += MODULE/common/uapsd.o
+RT5572_ap-y += MODULE/ap/ap_autoChSel.o
+RT5572_ap-y += MODULE/ap/ap_qload.o
+RT5572_ap-y += MODULE/ap/ap_cfg.o
+RT5572_ap-y += MODULE/common/ba_action.o
+RT5572_ap-y += MODULE/common/cmm_mac_usb.o
+RT5572_ap-y += MODULE/common/rtusb_io.o
+RT5572_ap-y += MODULE/common/rtusb_data.o
+RT5572_ap-y += MODULE/common/cmm_data_usb.o
+RT5572_ap-y += MODULE/common/rtmp_mcu.o
+RT5572_ap-y += MODULE/common/rtusb_bulk.o
+RT5572_ap-y += MODULE/os/linux/rt_usb.o
+RT5572_ap-y += MODULE/common/ee_prom.o
+RT5572_ap-y += MODULE/common/cmm_dfs.o
+RT5572_ap-y += MODULE/common/cmm_cs.o
+RT5572_ap-y += MODULE/common/ee_prom.o
+RT5572_ap-y += MODULE/common/ee_efuse.o
+RT5572_ap-y += MODULE/common/rt_rf.o
+RT5572_ap-y += MODULE/os/linux/rt_symb.o
+RT5572_ap-y += MODULE/common/rt_led.o
+
+# NET module
+obj-$(CONFIG_RTUSB_AP) += RT5572_ap_net.o
+RT5572_ap_net-y += NETIF/common/rtusb_dev_id.o
+RT5572_ap_net-y += NETIF/os/linux/ap_ioctl.o
+RT5572_ap_net-y += NETIF/os/linux/rt_main_dev.o
+RT5572_ap_net-y += NETIF/os/linux/usb_main_dev.o
+
+# By feature
+ifeq ($(CONFIG_RTUSB_AP_WSC),y)
+RT5572_ap-y += MODULE/common/wsc.o
+RT5572_ap-y += MODULE/common/wsc_tlv.o
+RT5572_ap-y += MODULE/common/wsc_ufd.o
+RT5572_ap-y += MODULE/common/crypt_biginteger.o
+RT5572_ap-y += MODULE/common/crypt_dh.o
+RT5572_ap-y += MODULE/common/wsc_v2.o
+endif
+
+ifeq ($(CONFIG_RTUSB_WDS),y)
+RT5572_ap-y += MODULE/ap/ap_wds.o
+RT5572_ap-y += MODULE/common/client_wds.o
+RT5572_ap_net-y += NETIF/ap/ap_wds_inf.o
+endif
+
+ifeq ($(CONFIG_RTUSB_AP_MBSS),y)
+RT5572_ap-y += MODULE/ap/ap_mbss.o
+RT5572_ap_net-y += NETIF/ap/ap_mbss_inf.o
+endif
+
+ifeq ($(CONFIG_RTUSB_APCLI),y)
+RT5572_ap-y += MODULE/ap/ap_apcli.o
+RT5572_ap-y += MODULE/ap/apcli_ctrl.o
+RT5572_ap-y += MODULE/ap/apcli_sync.o
+RT5572_ap-y += MODULE/ap/apcli_auth.o
+RT5572_ap-y += MODULE/ap/apcli_assoc.o
+RT5572_ap-y += MODULE/common/cmm_mat.o
+RT5572_ap-y += MODULE/common/cmm_mat_iparp.o
+RT5572_ap-y += MODULE/common/cmm_mat_pppoe.o
+RT5572_ap-y += MODULE/common/cmm_mat_ipv6.o
+RT5572_ap_net-y += NETIF/ap/ap_apcli_inf.o
+endif
+
+ifeq ($(CONFIG_RTUSB_DFS),y)
+RT5572_ap-y += MODULE/common/cmm_dfs.o
+endif
+
+ifeq ($(CONFIG_RTUSB_CS),y)
+RT5572_ap-y += MODULE/common/cmm_cs.o
+endif
+
+ifeq ($(CONFIG_RTUSB_IGMP_SNOOP),y)
+RT5572_ap-y += MODULE/common/igmp_snoop.o
+endif
+
+ifeq ($(CONFIG_RTUSB_NETIF_BLOCK),y)
+RT5572_ap-y += MODULE/common/netif_block.o
+endif
+
+ifeq ($(CONFIG_RTUSB_DLS),y)
+RT5572_ap-y += MODULE/ap/ap_dls.o
+endif
+
+ifeq ($(CONFIG_RTUSB_IDS),y)
+RT5572_ap-y += MODULE/ap/ap_ids.o
+endif
+
+ifeq ($(CONFIG_RTUSB_AP_FLASH_SUPPORT),y)
+RT5572_ap-y += MODULE/common/ee_flash.o
+endif
+
+# WAPI
+ifeq ($(CONFIG_RTUSB_AP_WAPI),y)
+RT5572_ap-y += MODULE/common/wapi.o
+RT5572_ap-y += MODULE/common/wapi_sms4.o
+RT5572_ap-y += MODULE/common/wapi_crypt.o
+endif
+
+# Chip related
+ifeq ($(CONFIG_RT2870_AP),y)
+RT5572_ap-y += MODULE/chips/rt28xx.o
+endif
+
+ifeq ($(CONFIG_RT3572_AP),y)
+RT5572_ap-y += MODULE/chips/rt28xx.o
+RT5572_ap-y += MODULE/chips/rt30xx.o
+RT5572_ap-y += MODULE/chips/rt35xx.o
+endif
+
+ifeq ($(CONFIG_RT3573_AP),y)
+RT5572_ap-y += MODULE/chips/rt28xx.o
+RT5572_ap-y += MODULE/chips/rt30xx.o
+RT5572_ap-y += MODULE/chips/rt35xx.o
+RT5572_ap-y += MODULE/chips/rt3593.o
+endif
+
+ifeq ($(CONFIG_RT5572_AP),y)
+RT5572_ap-y += MODULE/chips/rt30xx.o
+RT5572_ap-y += MODULE/chips/rt5592.o
+endif
+
+# ATE
+ifeq ($(CONFIG_RTUSB_AP_ATE),y)
+RT5572_ap-y += MODULE/ate/common/rt_ate.o
+RT5572_ap-y += MODULE/ate/common/ate_usb.o
+endif
+
+ifeq ($(CONFIG_RT2870_AP_ATE),y)
+RT5572_ap-y += MODULE/ate/chips/rt28xx_ate.o
+endif
+
+ifeq ($(CONFIG_RT3572_AP_ATE),y)
+RT5572_ap-y += MODULE/ate/chips/rt28xx_ate.o
+RT5572_ap-y += MODULE/ate/chips/rt35xx_ate.o
+endif
+
+ifeq ($(CONFIG_RT5572_AP_ATE),y)
+RT5572_ap-y += MODULE/ate/chips/rt5592_ate.o
+endif
+
+# QA tool
+ifeq ($(CONFIG_RTUSB_AP_QA),y)
+RT5572_ap-y += MODULE/ate/common/rt_qa.o
+endif
+###################
+# CFLAGS
+###################
+EXTRA_CFLAGS += -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -DLINUX\
+ -Wall -Wstrict-prototypes -Wno-trigraphs
+EXTRA_CFLAGS += -DSYSTEM_LOG_SUPPORT -DKTHREAD_SUPPORT
+EXTRA_CFLAGS += -DCONFIG_AP_SUPPORT -DUAPSD_SUPPORT -DIAPP_SUPPORT -DDBG\
+ -DDOT1X_SUPPORT -DAP_SCAN_SUPPORT
+EXTRA_CFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT
+EXTRA_CFLAGS += -DSTATS_COUNT_SUPPORT -DDOT11_N_SUPPORT -DRTDEV_SUPPORT
+
+
+ifeq ($(CONFIG_RTUSB_AP),m)
+EXTRA_CFLAGS += -DOS_ABL_SUPPORT
+EXTRA_CFLAGS += -DOS_ABL_FUNC_SUPPORT
+EXTRA_CFLAGS += -DOS_ABL_OS_PCI_SUPPORT
+EXTRA_CFLAGS += -DOS_ABL_OS_USB_SUPPORT
+EXTRA_CFLAGS += -DOS_ABL_OS_AP_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_AP_WSC),y)
+EXTRA_CFLAGS += -DWSC_AP_SUPPORT -DWSC_INCLUDED -DWSC_V2_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_WDS),y)
+EXTRA_CFLAGS += -DWDS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_MBSS),y)
+EXTRA_CFLAGS += -DMBSS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_APCLI),y)
+EXTRA_CFLAGS += -DAPCLI_SUPPORT
+EXTRA_CFLAGS += -DMAT_SUPPORT
+EXTRA_CFLAGS += -DAP_SCAN_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_AP_DLS),y)
+EXTRA_CFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_IDS),y)
+EXTRA_CFLAGS += -DIDS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_AP_FLASH_SUPPORT), y)
+EXTRA_CFLAGS += -DRTMP_FLASH_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_AP_80211N_DRAFT3),y)
+EXTRA_CFLAGS += -DDOT11N_DRAFT3
+endif
+
+ifeq ($(CONFIG_RTUSB_LLTD),y)
+EXTRA_CFLAGS += -DLLTD_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_IGMP_SNOOP),y)
+EXTRA_CFLAGS += -DIGMP_SNOOP_SUPPORT
+endif
+
+ifeq ($(CONFIG_RTUSB_NETIF_BLOCK),y)
+EXTRA_CFLAGS += -DBLOCK_NET_IF
+endif
+
+# Chip related
+ifeq ($(CONFIG_RT2870_AP), y)
+EXTRA_CFLAGS += -DRT2870 -DRT28xx -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT
+
+ifeq ($(CONFIG_RTUSB_DFS), y)
+EXTRA_CFLAGS += -DDFS_SOFTWARE_SUPPORT
+endif
+
+endif
+
+ifeq ($(CONFIG_RT3572_AP), y)
+EXTRA_CFLAGS += -DRT2870 -DRT28xx -DRT30xx -DRT35xx -DRT3572 -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT
+
+ifeq ($(CONFIG_RTUSB_DFS), y)
+EXTRA_CFLAGS += -DDFS_DEBUG
+endif
+
+ifeq ($(CONFIG_RTUSB_CS_SUPPORT), y)
+EXTRA_CFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+
+endif
+
+ifeq ($(CONFIG_RT3573_AP), y)
+EXTRA_CFLAGS += -DRT30xx -DRT35xx -DRT3593 -DRT3573 -DA_BAND_SUPPORT -DDOT11N_SS3_SUPPORT -DVCORECAL_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT5572_AP), y)
+EXTRA_CFLAGS += -DRT30xx -DRT5572 -DRT5592 -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT -DIQ_CAL_SUPPORT -DVCORECAL_SUPPORT -DRTMP_TEMPERATURE_COMPENSATION
+
+ifeq ($(CONFIG_RTUSB_DFS), y)
+EXTRA_CFLAGS += -DDFS_SOFTWARE_SUPPORT -DDFS_HARDWARE_SUPPORT -DDFS_DEBUG
+endif
+
+ifeq ($(CONFIG_RTUSB_CS_SUPPORT), y)
+EXTRA_CFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+
+endif
+
+# ATE
+ifeq ($(CONFIG_RTUSB_AP_ATE), y)
+EXTRA_CFLAGS += -DRALINK_ATE -DCONFIG_RT2880_ATE_CMD_NEW
+endif
+
+# QA
+ifeq ($(CONFIG_RTUSB_AP_QA), y)
+EXTRA_CFLAGS += -DRALINK_QA
+endif
+
+# WAPI
+ifeq ($(CONFIG_RTUSB_AP_WAPI), y)
+EXTRA_CFLAGS += -DWAPI_SUPPORT -DSOFT_ENCRYPT -DEXPORT_SYMTAB
+endif
+
+# NEW MBSS
+ifeq ($(CONFIG_RTUSB_AP_NEW_MBSS_MODE), y)
+EXTRA_CFLAGS += -DNEW_MBSSID_MODE
+endif
+
+clean:
+ @rm -f common/*.o
+ @rm -f ap/*.o
+ @rm -f sta/*.o
+ @rm -f os/linux/*.o
+ @rm -f chips/*.o
+ @rm -f `find ./ -name *.o.cmd`
+ @rm -f *.ko
+ @rm -f *.o
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.clean b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.clean
new file mode 100644
index 0000000000..495fd2bed1
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.clean
@@ -0,0 +1,58 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+PHONY := clean install uninstall
+
+clean:
+ rm -f ../../common/*.o
+ rm -f ../../common/.*.cmd .*.flags .*.d
+ rm -f ../../os/linux/*.o *.ko *.mod.o *.mod.c
+ rm -f ../../os/linux/.*.cmd .*.flags .*.d
+ rm -fr ../../os/linux/.tmp_versions
+#Must clean Module.symvers; or you will suffer symbol version not match
+#when OS_ABL = YES.
+ rm -f ../../os/linux/Module.symvers
+ rm -f ../../os/linux/Modules.symvers
+ rm -f ../../os/linux/Module.markers
+ rm -f ../../os/linux/modules.order
+ rm -f ../../chips/*.o
+ rm -f ../../chips/.*.cmd .*.flags .*.d
+ rm -f ../../rate_ctrl/*.o
+ rm -f ../../rate_ctrl/.*.cmd .*.flags .*.d
+ rm -f ../../ate/common/*.o
+ rm -f ../../ate/common/.*.cmd .*.flags .*.d
+ rm -f ../../ate/chips/*.o
+ rm -f ../../ate/chips/.*.cmd .*.flags .*.d
+ rm -f ../../phy/*.o
+ rm -f ../../phy/.*.cmd .*.flags .*.d
+ rm -f ../../mac/*.o
+ rm -f ../../mac/.*.cmd .*.flags .*.d
+ rm -f ../../mcu/*.o
+ rm -f ../../mcu/.*.cmd .*.flags .*.d
+ rm -f ../../mgmt/*.o
+ rm -f ../../mgmt/.*.cmd .*.flags .*.d
+ rm -f ../../naf/*.o
+ rm -f ../../naf/.*.cmd .*.flags .*.d
+ifeq ($(RT28xx_MODE),AP)
+ rm -f ../../ap/*.o
+ rm -f ../../ap/.*.cmd .*.flags .*.d
+else
+ifeq ($(RT28xx_MODE),STA)
+ rm -f ../../sta/*.o
+ rm -f ../../sta/.*.cmd .*.flags .*.d
+ifeq ($(HAS_P2P_SUPPORT),y)
+ rm -f ../../ap/*.o
+ rm -f ../../ap/.*.cmd .*.flags .*.d
+endif
+else
+ifeq ($(RT28xx_MODE),APSTA)
+ rm -f ../../ap/*.o
+ rm -f ../../ap/.*.cmd .*.flags .*.d
+ rm -f ../../sta/*.o
+ rm -f ../../sta/.*.cmd .*.flags .*.d
+endif
+endif
+endif
+
+# Declare the contents of the .PHONY variable as phony. We keep that
+# information in a variable so we can use it in if_changed and friends.
+.PHONY: $(PHONY)
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libautoprovision.6 b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libautoprovision.6
new file mode 100644
index 0000000000..e285006206
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libautoprovision.6
@@ -0,0 +1,9 @@
+include $(RT28xx_DIR)/os/linux/config.mk
+
+#ifdef CONFIG_AP_SUPPORT
+
+ifeq ($(HAS_SAMSUNG_EASY_CONFIG_SUPPORT),y)
+lib-y := ../../common/auto_provision.o
+endif
+
+#endif // CONFIG_AP_SUPPORT //
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.4 b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.4
new file mode 100644
index 0000000000..51c5f958e0
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.4
@@ -0,0 +1,23 @@
+#
+# Release file for AP Mode
+#
+include $(RT28xx_DIR)/os/linux/config.mk
+
+MOD_NAME = wapi_module
+
+OBJ := $(MOD_NAME).o
+
+WAPI_M_OBJ := \
+ $(RT28xx_DIR)/common/wapi_sms4.o\
+ $(RT28xx_DIR)/common/wapi_crypt.o
+
+PHONY := all
+
+all:$(OBJ)
+
+$(MOD_NAME).o: $(WAPI_M_OBJ)
+ $(LD) -r $^ -o $@
+
+# 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) \ No newline at end of file
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.6 b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.6
new file mode 100644
index 0000000000..8ce3d92b80
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.6
@@ -0,0 +1,11 @@
+#
+# Release file for AP Mode
+#
+include $(RT28xx_DIR)/os/linux/config.mk
+
+obj-m := wapi_module.o
+
+wapi_module-objs := \
+ ../../common/wapi_sms4.o\
+ ../../common/wapi_crypt.o
+ \ No newline at end of file
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/Makefile.sta.soc b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.sta.soc
new file mode 100644
index 0000000000..74d8eb8e66
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/Makefile.sta.soc
@@ -0,0 +1,275 @@
+EXTRA_CFLAGS = -Idrivers/net/wireless/rt2860v2/include -Idrivers/net/wireless/rt2860v2/ate/include
+
+obj-$(CONFIG_RT2860V2_STA) += rt2860v2_sta.o
+
+rt2860v2_sta-objs += ../rt2860v2/common/crypt_md5.o
+rt2860v2_sta-objs += ../rt2860v2/common/crypt_sha2.o
+rt2860v2_sta-objs += ../rt2860v2/common/crypt_hmac.o
+rt2860v2_sta-objs += ../rt2860v2/common/mlme.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_wep.o
+rt2860v2_sta-objs += ../rt2860v2/common/action.o
+rt2860v2_sta-objs += ../rt2860v2/common/ba_action.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_data.o
+rt2860v2_sta-objs += ../rt2860v2/common/rtmp_init.o
+rt2860v2_sta-objs += ../rt2860v2/common/rtmp_init_inf.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_tkip.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_aes.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_sync.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_sanity.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_info.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_wpa.o
+rt2860v2_sta-objs += ../rt2860v2/common/dfs.o
+#rt2860v2_sta-objs += ../rt2860v2/common/dfs_mcu.o
+rt2860v2_sta-objs += ../rt2860v2/common/spectrum.o
+rt2860v2_sta-objs += ../rt2860v2/common/rt_os_util.o
+
+rt2860v2_sta-objs += ../rt2860v2/common/rtmp_timer.o
+rt2860v2_sta-objs += ../rt2860v2/common/rt_channel.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_profile.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_asic.o
+rt2860v2_sta-objs += ../rt2860v2/common/rtmp_swmcu.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_cfg.o
+rt2860v2_sta-objs += ../rt2860v2/common/eeprom.o
+rt2860v2_sta-objs += ../rt2860v2/common/ee_flash.o
+#rt2860v2_sta-objs += ../rt2860v2/common/rtmp_mcu.o
+
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_mac_pci.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_data_pci.o
+rt2860v2_sta-objs += ../rt2860v2/common/crypt_aes.o
+rt2860v2_sta-objs += ../rt2860v2/common/crypt_arc4.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_cmd.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_wpa_adhoc.o
+
+rt2860v2_sta-objs += ../rt2860v2/sta/assoc.o
+rt2860v2_sta-objs += ../rt2860v2/sta/auth.o
+rt2860v2_sta-objs += ../rt2860v2/sta/auth_rsp.o
+rt2860v2_sta-objs += ../rt2860v2/sta/sync.o
+rt2860v2_sta-objs += ../rt2860v2/sta/sanity.o
+rt2860v2_sta-objs += ../rt2860v2/sta/rtmp_data.o
+rt2860v2_sta-objs += ../rt2860v2/sta/connect.o
+rt2860v2_sta-objs += ../rt2860v2/sta/wpa.o
+rt2860v2_sta-objs += ../rt2860v2/sta/sta_cfg.o
+
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rt_proc.o
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rt_linux.o
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rt_profile.o
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rt_main_dev.o
+rt2860v2_sta-objs += ../rt2860v2/os/linux/sta_ioctl.o
+rt2860v2_sta-objs += ../rt2860v2/common/rt_ate.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rtmp_chip.o
+
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rbus_main_dev.o
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rt_pci_rbus.o
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rt_rbus_pci_util.o
+rt2860v2_sta-objs += ../rt2860v2/os/linux/rt_rbus_pci_drv.o
+
+ifeq ($(CONFIG_RALINK_RT2880),y)
+rt2860v2_sta-objs += ../rt2860v2/chips/rt2880.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT3052),y)
+rt2860v2_sta-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rt305x.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT3352),y)
+rt2860v2_sta-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rt305x.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rt3352.o
+endif
+
+ifeq ($(CONFIG_RT3x52),y)
+rt2860v2_sta-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rt305x.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rt3352.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT5350),y)
+rt2860v2_sta-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rt305x.o
+rt2860v2_sta-objs += ../rt2860v2/chips/rt5350.o
+endif
+
+ifeq ($(CONFIG_RALINK_RT3883),y)
+rt2860v2_ap-objs += ../rt2860v2/common/rt_rf.o
+rt2860v2_ap-objs += ../rt2860v2/chips/rt3883.o
+ifeq ($(CONFIG_RT2860V2_STA_TXBF),y)
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_txbf.o
+rt2860v2_ap-objs += ../rt2860v2/common/cmm_txbf_cal.o
+endif
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_LED),y)
+rt2860v2_sta-objs += ../rt2860v2/common/rt_led.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_WMM_ACM),y)
+rt2860v2_sta-objs += ../rt2860v2/common/acm_edca.o
+rt2860v2_sta-objs += ../rt2860v2/common/acm_comm.o
+rt2860v2_sta-objs += ../rt2860v2/common/acm_iocl.o
+endif
+
+#ifeq ($(CONFIG_RT2860V2_STA_WAPI),y)
+#rt2860v2_sta-objs += wapi.obj
+#rt2860v2_sta-objs += wapi_sms4.obj
+#rt2860v2_sta-objs += wapi_crypt.obj
+#endif
+
+#ifeq ($(CONFIG_RT2860V2_RT3XXX_STA_ANTENNA_DIVERSITY),y)
+#rt2860v2_sta-objs += ../rt2860v2/os/linux/ap_diversity.o
+#endif
+
+ifeq ($(CONFIG_RT2860V2_STA_MESH),y)
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_bmpkt.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_ctrl.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_link_mng.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_sanity.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_tlv.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_inf.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_forwarding.o
+rt2860v2_sta-objs += ../rt2860v2/common/mesh_path_mng.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_DLS),y)
+rt2860v2_sta-objs += ../rt2860v2/sta/dls.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_WSC),y)
+rt2860v2_sta-objs += ../rt2860v2/common/wsc.o
+rt2860v2_sta-objs += ../rt2860v2/common/wsc_tlv.o
+rt2860v2_sta-objs += ../rt2860v2/common/crypt_biginteger.o
+rt2860v2_sta-objs += ../rt2860v2/common/crypt_dh.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_ETH_CONVERT),y)
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_mat.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_mat_iparp.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_mat_pppoe.o
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_mat_ipv6.o
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_VIDEO_TURBINE),y)
+rt2860v2_sta-objs += ../rt2860v2/common/cmm_video.o
+endif
+
+###################
+# CFLAGS
+##################
+EXTRA_CFLAGS += -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -DLINUX \
+ -Wall -Wstrict-prototypes -Wno-trigraphs
+
+EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT -DDBG -DRTMP_RBUS_SUPPORT -DRTMP_MAC_PCI
+EXTRA_CFLAGS += -DDOT11_N_SUPPORT -DSTATS_COUNT_SUPPORT -DRELASE_EXCLUDE
+EXTRA_CFLAGS += -DRALINK_ATE -DRALINK_QA -DNEW_TXCONT -DNEW_TXCARRSUPP -DCONFIG_RT2880_ATE_CMD_NEW
+
+ifeq ($(CONFIG_RALINK_RT2880),y)
+EXTRA_CFLAGS += -DRT2880
+endif
+
+ifeq ($(CONFIG_RALINK_RT3052),y)
+ifeq ($(CONFIG_RALINK_RT3350),y)
+EXTRA_CFLAGS += -DRT3350 -DRT305x -DRTMP_RF_RW_SUPPORT
+else
+EXTRA_CFLAGS += -DRT3052 -DRT305x -DRTMP_RF_RW_SUPPORT
+endif
+endif
+
+ifeq ($(CONFIG_RALINK_RT3352),y)
+EXTRA_CFLAGS += -DRT3352 -DRT305x -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT3x52),y)
+EXTRA_CFLAGS += -DRT3052 -DRT3352 -DRT305x -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT
+endif
+
+ifeq ($(CONFIG_RALINK_RT5350),y)
+EXTRA_CFLAGS += -DRT5350 -DRT305x -DRTMP_RF_RW_SUPPORT -DVCORECAL_SUPPORT
+endif
+
+ifeq ($(CONFIG_RALINK_RT3883),y)
+EXTRA_CFLAGS += -DRT3883 -DDOT11N_SS3_SUPPORT -DA_BAND_SUPPORT -DRTMP_RF_RW_SUPPORT -DSPECIFIC_BCN_BUF_SUPPORT -DVCORECAL_SUPPORT
+ifeq ($(CONFIG_RT2860V2_AP_TXBF),y)
+EXTRA_CFLAGS += -DTXBF_SUPPORT
+endif
+EXTRA_CFLAGS += -DSTREAM_MODE_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_WPA_SUPPLICANT),y)
+EXTRA_CFLAGS += -DWPA_SUPPLICANT_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_WMM_ACM),y)
+EXTRA_CFLAGS += -DWMM_ACM_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_LED),y)
+EXTRA_CFLAGS += -DLED_CONTROL_SUPPORT -DCONFIG_SWMCU_SUPPORT
+ifeq ($(CONFIG_RT2860V2_STA_WSC),y)
+EXTRA_CFLAGS += -DWSC_LED_SUPPORT
+endif
+endif
+
+ifeq ($(CONFIG_RT2860V2_SNMP),y)
+EXTRA_CFLAGS += -DSNMP_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_CARRIER),y)
+EXTRA_CFLAGS += -DCARRIER_DETECTION_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_EXT_CHANNEL_LIST),y)
+EXTRA_CFLAGS += -DEXT_BUILD_CHANNEL_LIST
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_IDS),y)
+EXTRA_CFLAGS += -DIDS_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_DLS),y)
+EXTRA_CFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+#ifeq ($(CONFIG_RT2860V2_STA_WAPI),y)
+#EXTRA_CFLAGS += -DWAPI_SUPPORT
+#ifeq ($(CONFIG_RALINK_RT3052),y)
+#EXTRA_CFLAGS += -DWAPI_SUPPORT -DSOFT_ENCRYPT
+#endif
+#endif
+
+ifeq ($(CONFIG_RT2860V2_STA_MESH),y)
+EXTRA_CFLAGS += -DMESH_SUPPORT -DINTEL_CMPC
+endif
+
+ifeq ($(CONFIG_RT2860V2_RT3XXX_STA_ANTENNA_DIVERSITY),y)
+EXTRA_CFLAGS += -DRT3XXX_ANTENNA_DIVERSITY_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_HW_STA_ANTENNA_DIVERSITY),y)
+EXTRA_CFLAGS += -DHW_ANTENNA_DIVERSITY_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_WSC),y)
+EXTRA_CFLAGS += -DWSC_STA_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_ETH_CONVERT),y)
+EXTRA_CFLAGS += -DETH_CONVERT_SUPPORT -DMAT_SUPPORT
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_VIDEO_TURBINE),y)
+EXTRA_CFLAGS += -DVIDEO_TURBINE_SUPPORT
+endif
+
+ifeq ($(CONFIG_RA_NETWORK_WORKQUEUE_BH),y)
+EXTRA_CFLAGS += -DWORKQUEUE_BH
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_RTMP_INTERNAL_TX_ALC),y)
+EXTRA_CFLAGS += -DRTMP_INTERNAL_TX_ALC
+endif
+
+ifeq ($(CONFIG_RT2860V2_STA_80211N_DRAFT3),y)
+EXTRA_CFLAGS += -DDOT11N_DRAFT3
+endif
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/ap_ioctl.c b/cleopatre/devkit/mt7601udrv/os/linux/ap_ioctl.c
new file mode 100644
index 0000000000..b2aad0d8bb
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/ap_ioctl.c
@@ -0,0 +1,441 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ ap_ioctl.c
+
+ Abstract:
+ IOCTL related subroutines
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+*/
+#define RTMP_MODULE_OS
+
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rt_os_net.h"
+#include <linux/wireless.h>
+
+struct iw_priv_args ap_privtab[] = {
+{ RTPRIV_IOCTL_SET,
+/* 1024 --> 1024 + 512 */
+/* larger size specific to allow 64 ACL MAC addresses to be set up all at once. */
+ IW_PRIV_TYPE_CHAR | 1536, 0,
+ "set"},
+{ RTPRIV_IOCTL_SHOW,
+ IW_PRIV_TYPE_CHAR | 1024, 0,
+ "show"},
+{ RTPRIV_IOCTL_GSITESURVEY,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 ,
+ "get_site_survey"},
+#ifdef INF_AR9
+ { RTPRIV_IOCTL_GET_AR9_SHOW,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 ,
+ "ar9_show"},
+#endif
+ { RTPRIV_IOCTL_SET_WSCOOB,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 ,
+ "set_wsc_oob"},
+{ RTPRIV_IOCTL_GET_MAC_TABLE,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 ,
+ "get_mac_table"},
+{ RTPRIV_IOCTL_E2P,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "e2p"},
+#ifdef DBG
+{ RTPRIV_IOCTL_BBP,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "bbp"},
+{ RTPRIV_IOCTL_MAC,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "mac"},
+{ RTPRIV_IOCTL_RF,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "rf"},
+#endif /* DBG */
+
+#ifdef WSC_AP_SUPPORT
+{ RTPRIV_IOCTL_WSC_PROFILE,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 ,
+ "get_wsc_profile"},
+#endif /* WSC_AP_SUPPORT */
+{ RTPRIV_IOCTL_QUERY_BATABLE,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 ,
+ "get_ba_table"},
+{ RTPRIV_IOCTL_STATISTICS,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "stat"}
+};
+
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+const struct iw_handler_def rt28xx_ap_iw_handler_def =
+{
+#define N(a) (sizeof (a) / sizeof (a[0]))
+ .private_args = (struct iw_priv_args *) ap_privtab,
+ .num_private_args = N(ap_privtab),
+#if IW_HANDLER_VERSION >= 7
+ .get_wireless_stats = rt28xx_get_wireless_stats,
+#endif
+};
+#endif /* CONFIG_APSTA_MIXED_SUPPORT */
+
+
+INT rt28xx_ap_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ VOID *pAd = NULL;
+ struct iwreq *wrqin = (struct iwreq *) rq;
+ RTMP_IOCTL_INPUT_STRUCT rt_wrq, *wrq = &rt_wrq;
+ INT Status = NDIS_STATUS_SUCCESS;
+ USHORT subcmd; /*, index; */
+/* POS_COOKIE pObj; */
+ INT apidx=0;
+ UINT32 org_len;
+ RT_CMD_AP_IOCTL_CONFIG IoctlConfig, *pIoctlConfig = &IoctlConfig;
+
+ GET_PAD_FROM_NET_DEV(pAd, net_dev);
+/* pObj = (POS_COOKIE) pAd->OS_Cookie; */
+
+ 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;
+
+ pIoctlConfig->Status = 0;
+ pIoctlConfig->net_dev = net_dev;
+ pIoctlConfig->priv_flags = RT_DEV_PRIV_FLAGS_GET(net_dev);
+ pIoctlConfig->pCmdData = wrqin->u.data.pointer;
+ pIoctlConfig->CmdId_RTPRIV_IOCTL_SET = RTPRIV_IOCTL_SET;
+ pIoctlConfig->name = net_dev->name;
+ pIoctlConfig->apidx = 0;
+
+ if ((cmd != SIOCGIWPRIV) &&
+ RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_PREPARE, 0,
+ pIoctlConfig, 0) != NDIS_STATUS_SUCCESS)
+ {
+ /* prepare error */
+ Status = pIoctlConfig->Status;
+ goto LabelExit;
+ }
+
+ apidx = pIoctlConfig->apidx;
+
+ /*+ patch for SnapGear Request even the interface is down */
+ if(cmd== SIOCGIWNAME){
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWNAME\n"));
+
+ RTMP_COM_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_SIOCGIWNAME, 0, wrqin->u.name, 0);
+
+ return Status;
+ }/*- patch for SnapGear */
+
+
+ switch(cmd)
+ {
+ case RTPRIV_IOCTL_ATE:
+ {
+ RTMP_COM_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_ATE, 0, wrqin->ifr_name, 0);
+ }
+ break;
+
+ case SIOCGIFHWADDR:
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTLIOCTLIOCTL::SIOCGIFHWADDR\n"));
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_AP_SIOCGIFHWADDR, 0, NULL, 0);
+/* if (pObj->ioctl_if < MAX_MBSSID_NUM(pAd)) */
+/* strcpy((PSTRING) wrq->u.name, (PSTRING) pAd->ApCfg.MBSSID[pObj->ioctl_if].Bssid); */
+ break;
+ case SIOCSIWESSID: /*Set ESSID */
+ break;
+ case SIOCGIWESSID: /*Get ESSID */
+ {
+ RT_CMD_AP_IOCTL_SSID IoctlSSID, *pIoctlSSID = &IoctlSSID;
+ struct iw_point *erq = &wrqin->u.essid;
+ PCHAR pSsidStr = NULL;
+
+ erq->flags=1;
+ /*erq->length = pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen; */
+
+ pIoctlSSID->priv_flags = RT_DEV_PRIV_FLAGS_GET(net_dev);
+ pIoctlSSID->apidx = apidx;
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_AP_SIOCGIWESSID, 0, pIoctlSSID, 0);
+
+ pSsidStr = (PCHAR)pIoctlSSID->pSsidStr;
+ erq->length = pIoctlSSID->length;
+
+
+ if((erq->pointer) && (pSsidStr != NULL))
+ {
+ /*if(copy_to_user(erq->pointer, pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid, erq->length)) */
+ if(copy_to_user(erq->pointer, pSsidStr, erq->length))
+ {
+ Status = RTMP_IO_EFAULT;
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWESSID (Len=%d, ssid=%s...)\n", erq->length, (char *)erq->pointer));
+ }
+ break;
+ case SIOCGIWNWID: /* get network id */
+ case SIOCSIWNWID: /* set network id (the cell) */
+ Status = RTMP_IO_EOPNOTSUPP;
+ break;
+ case SIOCGIWFREQ: /* get channel/frequency (Hz) */
+ {
+ ULONG Channel;
+ RTMP_DRIVER_CHANNEL_GET(pAd, &Channel);
+ wrqin->u.freq.m = Channel; /*pAd->CommonCfg.Channel; */
+ wrqin->u.freq.e = 0;
+ wrqin->u.freq.i = 0;
+ }
+ break;
+ case SIOCSIWFREQ: /*set channel/frequency (Hz) */
+ Status = RTMP_IO_EOPNOTSUPP;
+ break;
+ case SIOCGIWNICKN:
+ case SIOCSIWNICKN: /*set node name/nickname */
+ Status = RTMP_IO_EOPNOTSUPP;
+ break;
+ case SIOCGIWRATE: /*get default bit rate (bps) */
+ {
+ RT_CMD_IOCTL_RATE IoctlRate, *pIoctlRate = &IoctlRate;
+
+ pIoctlRate->priv_flags = RT_DEV_PRIV_FLAGS_GET(net_dev);
+ RTMP_DRIVER_BITRATE_GET(pAd, pIoctlRate);
+
+
+ wrqin->u.bitrate.value = pIoctlRate->BitRate;
+ wrqin->u.bitrate.disabled = 0;
+ }
+ break;
+ case SIOCSIWRATE: /*set default bit rate (bps) */
+ case SIOCGIWRTS: /* get RTS/CTS threshold (bytes) */
+ case SIOCSIWRTS: /*set RTS/CTS threshold (bytes) */
+ case SIOCGIWFRAG: /*get fragmentation thr (bytes) */
+ case SIOCSIWFRAG: /*set fragmentation thr (bytes) */
+ case SIOCGIWENCODE: /*get encoding token & mode */
+ case SIOCSIWENCODE: /*set encoding token & mode */
+ Status = RTMP_IO_EOPNOTSUPP;
+ break;
+ case SIOCGIWAP: /*get access point MAC addresses */
+ {
+/* PCHAR pBssidStr; */
+
+ wrqin->u.ap_addr.sa_family = ARPHRD_ETHER;
+ /*memcpy(wrqin->u.ap_addr.sa_data, &pAd->ApCfg.MBSSID[pObj->ioctl_if].Bssid, ETH_ALEN); */
+
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_AP_SIOCGIWAP, 0,
+ wrqin->u.ap_addr.sa_data, RT_DEV_PRIV_FLAGS_GET(net_dev));
+ }
+ break;
+ case SIOCGIWMODE: /*get operation mode */
+ wrqin->u.mode = IW_MODE_INFRA; /*SoftAP always on INFRA mode. */
+ break;
+ case SIOCSIWAP: /*set access point MAC addresses */
+ case SIOCSIWMODE: /*set operation mode */
+ 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 = RTMP_IO_EOPNOTSUPP;
+ break;
+ case SIOCGIWRANGE: /*Get range of parameters */
+ {
+/* struct iw_range range; */
+ struct iw_range *prange = NULL;
+ UINT32 len;
+
+ /* allocate memory */
+ os_alloc_mem(NULL, (UCHAR **)&prange, sizeof(struct iw_range));
+ if (prange == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ break;
+ }
+
+ memset(prange, 0, sizeof(struct iw_range));
+ prange->we_version_compiled = WIRELESS_EXT;
+ prange->we_version_source = 14;
+
+ /*
+ what is correct max? This was not
+ documented exactly. At least
+ 69 has been observed.
+ */
+ prange->max_qual.qual = 100;
+ prange->max_qual.level = 0; /* dB */
+ prange->max_qual.noise = 0; /* dB */
+ len = copy_to_user(wrq->u.data.pointer, prange, sizeof(struct iw_range));
+ os_free_mem(NULL, prange);
+ }
+ break;
+
+ case RT_PRIV_IOCTL:
+ case RT_PRIV_IOCTL_EXT:
+ {
+ subcmd = wrqin->u.data.flags;
+
+ Status = RTMP_AP_IoctlHandle(pAd, wrq, CMD_RT_PRIV_IOCTL, subcmd, wrqin->u.data.pointer, 0);
+ }
+ break;
+
+#ifdef HOSTAPD_SUPPORT
+ case SIOCSIWGENIE:
+ DBGPRINT(RT_DEBUG_TRACE,("ioctl SIOCSIWGENIE apidx=%d\n",apidx));
+ DBGPRINT(RT_DEBUG_TRACE,("ioctl SIOCSIWGENIE length=%d, pointer=%x\n", wrqin->u.data.length, wrqin->u.data.pointer));
+
+
+ RTMP_AP_IoctlHandle(pAd, wrqin, CMD_RTPRIV_IOCTL_AP_SIOCSIWGENIE, 0, NULL, 0);
+ break;
+#endif /* HOSTAPD_SUPPORT */
+
+ case SIOCGIWPRIV:
+ if (wrqin->u.data.pointer)
+ {
+ if ( access_ok(VERIFY_WRITE, wrqin->u.data.pointer, sizeof(ap_privtab)) != TRUE)
+ break;
+ if ((sizeof(ap_privtab) / sizeof(ap_privtab[0])) <= wrq->u.data.length)
+ {
+ wrqin->u.data.length = sizeof(ap_privtab) / sizeof(ap_privtab[0]);
+ if (copy_to_user(wrqin->u.data.pointer, ap_privtab, sizeof(ap_privtab)))
+ Status = RTMP_IO_EFAULT;
+ }
+ else
+ Status = RTMP_IO_E2BIG;
+ }
+ break;
+ case RTPRIV_IOCTL_SET:
+ {
+ if( access_ok(VERIFY_READ, wrqin->u.data.pointer, wrqin->u.data.length) == TRUE)
+ Status = RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_SET, 0, NULL, 0);
+ }
+ break;
+
+ case RTPRIV_IOCTL_SHOW:
+ {
+ if( access_ok(VERIFY_READ, wrqin->u.data.pointer, wrqin->u.data.length) == TRUE)
+ Status = RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_SHOW, 0, NULL, 0);
+ }
+ break;
+
+#ifdef INF_AR9
+#ifdef AR9_MAPI_SUPPORT
+ case RTPRIV_IOCTL_GET_AR9_SHOW:
+ {
+ if( access_ok(VERIFY_READ, wrqin->u.data.pointer, wrqin->u.data.length) == TRUE)
+ Status = RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_GET_AR9_SHOW, 0, NULL, 0);
+ }
+ break;
+#endif /*AR9_MAPI_SUPPORT*/
+#endif /* INF_AR9 */
+
+#ifdef WSC_AP_SUPPORT
+ case RTPRIV_IOCTL_SET_WSCOOB:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_SET_WSCOOB, 0, NULL, 0);
+ break;
+#endif/*WSC_AP_SUPPORT*/
+
+/* modified by Red@Ralink, 2009/09/30 */
+ case RTPRIV_IOCTL_GET_MAC_TABLE:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_GET_MAC_TABLE, 0, NULL, 0);
+ break;
+
+ case RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT, 0, NULL, 0);
+ break;
+/* end of modification */
+
+#ifdef AP_SCAN_SUPPORT
+ case RTPRIV_IOCTL_GSITESURVEY:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_GSITESURVEY, 0, NULL, 0);
+ break;
+#endif /* AP_SCAN_SUPPORT */
+
+ case RTPRIV_IOCTL_STATISTICS:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_STATISTICS, 0, NULL, 0);
+ break;
+
+#ifdef WSC_AP_SUPPORT
+ case RTPRIV_IOCTL_WSC_PROFILE:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_WSC_PROFILE, 0, NULL, 0);
+ break;
+#endif /* WSC_AP_SUPPORT */
+#ifdef DOT11_N_SUPPORT
+ case RTPRIV_IOCTL_QUERY_BATABLE:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_QUERY_BATABLE, 0, NULL, 0);
+ break;
+#endif /* DOT11_N_SUPPORT */
+ case RTPRIV_IOCTL_E2P:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_E2P, 0, NULL, 0);
+ break;
+
+#ifdef DBG
+ case RTPRIV_IOCTL_BBP:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_BBP, 0, NULL, 0);
+ break;
+
+ case RTPRIV_IOCTL_MAC:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_MAC, 0, NULL, 0);
+ break;
+
+ case RTPRIV_IOCTL_RF:
+ RTMP_AP_IoctlHandle(pAd, wrq, CMD_RTPRIV_IOCTL_RF, 0, NULL, 0);
+ break;
+#endif /* DBG */
+
+ default:
+/* DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd)); */
+ Status = RTMP_IO_EOPNOTSUPP;
+ break;
+ }
+
+LabelExit:
+ if (Status != 0)
+ {
+ RT_CMD_STATUS_TRANSLATE(Status);
+ }
+ else
+ {
+ /*
+ If wrq length is modified, we reset the lenght of origin wrq;
+
+ Or we can not modify it because the address of wrq->u.data.length
+ maybe same as other union field, ex: iw_range, etc.
+
+ if the length is not changed but we change it, the value for other
+ union will also be changed, this is not correct.
+ */
+ if (wrq->u.data.length != org_len)
+ wrqin->u.data.length = wrq->u.data.length;
+ }
+
+ return Status;
+}
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/br_ftph.c b/cleopatre/devkit/mt7601udrv/os/linux/br_ftph.c
new file mode 100644
index 0000000000..6e5eb6e55d
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/br_ftph.c
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ bg_ftph.c
+
+ Abstract:
+ Provide fast path between LAN and WLAN.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sample Lin 01-22-2008 Created
+
+ */
+
+#include "rt_config.h"
+
+#ifdef BG_FT_SUPPORT
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+#include <linux/netfilter_bridge.h>
+#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;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Remove bridge fast path module.
+
+Arguments:
+ None
+
+Return Value:
+ None
+
+Note:
+ Used in module remove.
+========================================================================
+*/
+VOID BG_FTPH_Remove(VOID)
+{
+ RALINK_FP_Handle = NULL;
+} /* End of BG_FTPH_Init */
+
+
+
+
+/*
+========================================================================
+Routine Description:
+ Forward the received packet.
+
+Arguments:
+ pPacket - the received packet
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UINT32 BG_FTPH_PacketFromApHandle(
+ IN PNDIS_PACKET pPacket)
+{
+ struct net_device *pNetDev;
+ struct sk_buff *pRxPkt;
+ struct net_bridge_fdb_entry *pSrcFdbEntry, *pDstFdbEntry;
+
+
+ /* init */
+ pRxPkt = RTPKT_TO_OSPKT(pPacket);
+ pNetDev = pRxPkt->dev;
+
+ /* if pNetDev is promisc mode ??? */
+ DBGPRINT(RT_DEBUG_INFO, ("ft bg> BG_FTPH_PacketFromApHandle\n"));
+
+ if (pNetDev != NULL)
+ {
+ if (pNetDev->br_port != NULL)
+ {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
+ pDstFdbEntry = br_fdb_get_hook(pNetDev->br_port->br, pRxPkt->data);
+ pSrcFdbEntry = br_fdb_get_hook(pNetDev->br_port->br, pRxPkt->data + 6);
+#else
+ /* br_fdb_get is not exported symbol, need exported in net/bridge/br.c */
+ pDstFdbEntry = br_fdb_get(pNetDev->br_port->br, pRxPkt->data);
+ pSrcFdbEntry = br_fdb_get(pNetDev->br_port->br, pRxPkt->data + 6);
+#endif
+
+ /* check destination address in bridge forwarding table */
+ if ((pSrcFdbEntry == NULL) ||
+ (pDstFdbEntry == NULL) ||
+ (pDstFdbEntry->is_local) ||
+ (pDstFdbEntry->dst == NULL) ||
+ (pDstFdbEntry->dst->dev == NULL) ||
+ (pDstFdbEntry->dst->dev == pNetDev) ||
+ (pNetDev->br_port->state != BR_STATE_FORWARDING) ||
+ ((pSrcFdbEntry->dst != NULL) &&
+ (pSrcFdbEntry->dst->dev != NULL) &&
+ (pSrcFdbEntry->dst->dev != pNetDev)))
+ {
+
+ goto LabelPassToUpperLayer;
+ } /* End of if */
+
+ if ((!pDstFdbEntry->is_local) &&
+ (pDstFdbEntry->dst != NULL) &&
+ (pDstFdbEntry->dst->dev != NULL))
+ {
+ pRxPkt->dev = pDstFdbEntry->dst->dev;
+ pDstFdbEntry->dst->dev->hard_start_xmit(pRxPkt, pDstFdbEntry->dst->dev);
+ return 0;
+ } /* End of if */
+ } /* End of if */
+ } /* End of if */
+
+LabelPassToUpperLayer:
+ DBGPRINT(RT_DEBUG_TRACE, ("ft bg> Pass packet to bridge module.\n"));
+ return 1;
+} /* End of BG_FTPH_PacketFromApHandle */
+
+
+#endif /* CONFIG_BRIDGE || CONFIG_BRIDGE_MODULE */
+#endif /* BG_FT_SUPPORT */
+
+/* End of bg_ftph.c */
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/cfg80211.c b/cleopatre/devkit/mt7601udrv/os/linux/cfg80211.c
new file mode 100644
index 0000000000..00fd0e22d8
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/cfg80211.c
@@ -0,0 +1,1576 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2009, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related CFG80211 function body.
+
+ History:
+ 1. 2009/09/17 Sample Lin
+ (1) Init version.
+ 2. 2009/10/27 Sample Lin
+ (1) Do not use ieee80211_register_hw() to create virtual interface.
+ Use wiphy_register() to register nl80211 command handlers.
+ (2) Support iw utility.
+ 3. 2009/11/03 Sample Lin
+ (1) Change name MAC80211 to CFG80211.
+ (2) Modify CFG80211_OpsChannelSet().
+ (3) Move CFG80211_Register()/CFG80211_UnRegister() to open/close.
+ 4. 2009/12/16 Sample Lin
+ (1) Patch for Linux 2.6.32.
+ (2) Add more supported functions in CFG80211_Ops.
+ 5. 2010/12/10 Sample Lin
+ (1) Modify for OS_ABL.
+ 6. 2011/04/19 Sample Lin
+ (1) Add more supported functions in CFG80211_Ops v33 ~ 38.
+
+ Note:
+ The feature is supported only in "LINUX" 2.6.28 ~ 2.6.38.
+
+***************************************************************************/
+
+
+/* #include "rt_config.h" */
+#define RTMP_MODULE_OS
+
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rt_os_net.h"
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
+#ifdef RT_CFG80211_SUPPORT
+
+/* 36 ~ 64, 100 ~ 136, 140 ~ 161 */
+#define CFG80211_NUM_OF_CHAN_5GHZ \
+ (sizeof(Cfg80211_Chan)-CFG80211_NUM_OF_CHAN_2GHZ)
+
+#ifdef OS_ABL_FUNC_SUPPORT
+/*
+ Array of bitrates the hardware can operate with
+ in this band. Must be sorted to give a valid "supported
+ rates" IE, i.e. CCK rates first, then OFDM.
+
+ For HT, assign MCS in another structure, ieee80211_sta_ht_cap.
+*/
+const struct ieee80211_rate Cfg80211_SupRate[12] = {
+ {
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE,
+ .bitrate = 10,
+ .hw_value = 0,
+ .hw_value_short = 0,
+ },
+ {
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE,
+ .bitrate = 20,
+ .hw_value = 1,
+ .hw_value_short = 1,
+ },
+ {
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE,
+ .bitrate = 55,
+ .hw_value = 2,
+ .hw_value_short = 2,
+ },
+ {
+ .flags = IEEE80211_RATE_SHORT_PREAMBLE,
+ .bitrate = 110,
+ .hw_value = 3,
+ .hw_value_short = 3,
+ },
+ {
+ .flags = 0,
+ .bitrate = 60,
+ .hw_value = 4,
+ .hw_value_short = 4,
+ },
+ {
+ .flags = 0,
+ .bitrate = 90,
+ .hw_value = 5,
+ .hw_value_short = 5,
+ },
+ {
+ .flags = 0,
+ .bitrate = 120,
+ .hw_value = 6,
+ .hw_value_short = 6,
+ },
+ {
+ .flags = 0,
+ .bitrate = 180,
+ .hw_value = 7,
+ .hw_value_short = 7,
+ },
+ {
+ .flags = 0,
+ .bitrate = 240,
+ .hw_value = 8,
+ .hw_value_short = 8,
+ },
+ {
+ .flags = 0,
+ .bitrate = 360,
+ .hw_value = 9,
+ .hw_value_short = 9,
+ },
+ {
+ .flags = 0,
+ .bitrate = 480,
+ .hw_value = 10,
+ .hw_value_short = 10,
+ },
+ {
+ .flags = 0,
+ .bitrate = 540,
+ .hw_value = 11,
+ .hw_value_short = 11,
+ },
+};
+#endif /* OS_ABL_FUNC_SUPPORT */
+
+/* all available channels */
+static const UCHAR Cfg80211_Chan[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+
+ /* 802.11 UNI / HyperLan 2 */
+ 36, 38, 40, 44, 46, 48, 52, 54, 56, 60, 62, 64,
+
+ /* 802.11 HyperLan 2 */
+ 100, 104, 108, 112, 116, 118, 120, 124, 126, 128, 132, 134, 136,
+
+ /* 802.11 UNII */
+ 140, 149, 151, 153, 157, 159, 161, 165, 167, 169, 171, 173,
+
+ /* Japan */
+ 184, 188, 192, 196, 208, 212, 216,
+};
+
+
+static const UINT32 CipherSuites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+};
+
+
+
+/*
+ The driver's regulatory notification callback.
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
+static INT32 CFG80211_RegNotifier(
+ IN struct wiphy *pWiphy,
+ IN struct regulatory_request *pRequest);
+#else
+static INT32 CFG80211_RegNotifier(
+ IN struct wiphy *pWiphy,
+ IN enum reg_set_by Request);
+#endif /* LINUX_VERSION_CODE */
+
+
+
+
+/* =========================== Private Function ============================== */
+
+/* get RALINK pAd control block in 80211 Ops */
+#define MAC80211_PAD_GET(__pAd, __pWiphy) \
+ { \
+ ULONG *__pPriv; \
+ __pPriv = (ULONG *)(wiphy_priv(__pWiphy)); \
+ __pAd = (VOID *)(*__pPriv); \
+ if (__pAd == NULL) \
+ { \
+ DBGPRINT(RT_DEBUG_ERROR, \
+ ("80211> %s but pAd = NULL!", __FUNCTION__)); \
+ return -EINVAL; \
+ } \
+ }
+
+/*
+========================================================================
+Routine Description:
+ Set channel.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pChan - Channel information
+ ChannelType - Channel type
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+ For iw utility: set channel, set freq
+
+ enum nl80211_channel_type {
+ NL80211_CHAN_NO_HT,
+ NL80211_CHAN_HT20,
+ NL80211_CHAN_HT40MINUS,
+ NL80211_CHAN_HT40PLUS
+ };
+========================================================================
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+static int CFG80211_OpsChannelSet(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pDev,
+ IN struct ieee80211_channel *pChan,
+ IN enum nl80211_channel_type ChannelType)
+
+#else
+static int CFG80211_OpsChannelSet(
+ IN struct wiphy *pWiphy,
+ IN struct ieee80211_channel *pChan,
+ IN enum nl80211_channel_type ChannelType)
+#endif /* LINUX_VERSION_CODE */
+{
+ VOID *pAd;
+ CFG80211_CB *p80211CB;
+ CMD_RTPRIV_IOCTL_80211_CHAN ChanInfo;
+ UINT32 ChanId;
+
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ 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_OpsChannelSet */
+
+
+/*
+========================================================================
+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_OpsVirtualInfChg(
+ 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_OpsVirtualInfChg(
+ 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> %s ==>\n", __FUNCTION__));
+ MAC80211_PAD_GET(pAd, pWiphy);
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> Type = %d\n", Type));
+
+ /* sanity check */
+ {
+ 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_OpsVirtualInfChg */
+
+
+#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
+/*
+========================================================================
+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)
+{
+
+ return -EOPNOTSUPP;
+} /* End of CFG80211_OpsScan */
+#endif /* LINUX_VERSION_CODE */
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
+#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
+========================================================================
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
+static int CFG80211_OpsTxPwrSet(
+ IN struct wiphy *pWiphy,
+ IN enum nl80211_tx_power_setting Type,
+ IN int dBm)
+{
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ return -EOPNOTSUPP;
+} /* End of CFG80211_OpsTxPwrSet */
+
+#else
+static int CFG80211_OpsTxPwrSet(
+ IN struct wiphy *pWiphy,
+ IN enum tx_power_setting Type,
+ IN int dBm)
+{
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ return -EOPNOTSUPP;
+} /* End of CFG80211_OpsTxPwrSet */
+#endif /* LINUX_VERSION_CODE */
+
+
+/*
+========================================================================
+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_OpsTxPwrGet(
+ IN struct wiphy *pWiphy,
+ IN int *pdBm)
+{
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ return -EOPNOTSUPP;
+} /* End of CFG80211_OpsTxPwrGet */
+
+
+/*
+========================================================================
+Routine Description:
+ Power management.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev -
+ FlgIsEnabled -
+ Timeout -
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+========================================================================
+*/
+static int CFG80211_OpsPwrMgmt(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN bool FlgIsEnabled,
+ IN int Timeout)
+{
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ return -EOPNOTSUPP;
+} /* End of CFG80211_OpsPwrMgmt */
+
+
+/*
+========================================================================
+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_OpsStaGet(
+ 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> %s ==>\n", __FUNCTION__));
+ 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;
+
+#ifdef CONFIG_AP_SUPPORT
+ /* fill tx count */
+ pSinfo->tx_packets = StaInfo.TxPacketCnt;
+ pSinfo->filled |= STATION_INFO_TX_PACKETS;
+
+ /* fill inactive time */
+ pSinfo->inactive_time = StaInfo.InactiveTime;
+ pSinfo->filled |= STATION_INFO_INACTIVE_TIME;
+#endif /* CONFIG_AP_SUPPORT */
+
+ return 0;
+} /* End of CFG80211_OpsStaGet */
+
+
+/*
+========================================================================
+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_OpsStaDump(
+ 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> %s ==>\n", __FUNCTION__));
+ MAC80211_PAD_GET(pAd, pWiphy);
+
+
+ return -EOPNOTSUPP;
+} /* End of CFG80211_OpsStaDump */
+
+
+/*
+========================================================================
+Routine Description:
+ Notify that wiphy parameters have changed.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ Changed -
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+========================================================================
+*/
+static int CFG80211_OpsWiphyParamsSet(
+ IN struct wiphy *pWiphy,
+ IN UINT32 Changed)
+{
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ return -EOPNOTSUPP;
+} /* End of CFG80211_OpsWiphyParamsSet */
+
+
+/*
+========================================================================
+Routine Description:
+ Add a key with the given parameters.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev -
+ KeyIdx -
+ Pairwise -
+ pMacAddr -
+ pParams -
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+ pMacAddr will be NULL when adding a group key.
+========================================================================
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static int CFG80211_OpsKeyAdd(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN UINT8 KeyIdx,
+ IN bool Pairwise,
+ IN const UINT8 *pMacAddr,
+ IN struct key_params *pParams)
+#else
+
+static int CFG80211_OpsKeyAdd(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN UINT8 KeyIdx,
+ IN const UINT8 *pMacAddr,
+ IN struct key_params *pParams)
+#endif /* LINUX_VERSION_CODE */
+{
+ VOID *pAd;
+ CMD_RTPRIV_IOCTL_80211_KEY KeyInfo;
+
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ 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_AP_SUPPORT
+ return -ENOTSUPP;
+#endif /* CONFIG_AP_SUPPORT */
+} /* End of CFG80211_OpsKeyAdd */
+
+
+/*
+========================================================================
+Routine Description:
+ Get information about the key with the given parameters.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev -
+ KeyIdx -
+ Pairwise -
+ 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.
+========================================================================
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static int CFG80211_OpsKeyGet(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN UINT8 KeyIdx,
+ IN bool Pairwise,
+ IN const UINT8 *pMacAddr,
+ IN void *pCookie,
+ IN void (*pCallback)(void *cookie,
+ struct key_params *))
+#else
+
+static int CFG80211_OpsKeyGet(
+ 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 *))
+#endif /* LINUX_VERSION_CODE */
+{
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ return -ENOTSUPP;
+} /* End of CFG80211_OpsKeyGet */
+
+
+/*
+========================================================================
+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.
+========================================================================
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static int CFG80211_OpsKeyDel(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN UINT8 KeyIdx,
+ IN bool Pairwise,
+ IN const UINT8 *pMacAddr)
+#else
+
+static int CFG80211_OpsKeyDel(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN UINT8 KeyIdx,
+ IN const UINT8 *pMacAddr)
+#endif /* LINUX_VERSION_CODE */
+{
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ return -ENOTSUPP;
+} /* End of CFG80211_OpsKeyDel */
+
+
+/*
+========================================================================
+Routine Description:
+ Set the default key on an interface.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev -
+ KeyIdx -
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+========================================================================
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+static int CFG80211_OpsKeyDefaultSet(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN UINT8 KeyIdx,
+ IN bool Unicast,
+ IN bool Multicast)
+#else
+
+static int CFG80211_OpsKeyDefaultSet(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN UINT8 KeyIdx)
+#endif /* LINUX_VERSION_CODE */
+{
+ VOID *pAd;
+
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+ 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_OpsKeyDefaultSet */
+
+
+#endif /* LINUX_VERSION_CODE */
+
+
+#ifdef RFKILL_HW_SUPPORT
+static int CFG80211_OpsRFKill(
+ 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 */
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+/*
+========================================================================
+Routine Description:
+ Get site survey information.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev - Network device interface
+ Idx -
+ pSurvey -
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+ For iw utility: survey dump
+========================================================================
+*/
+static int CFG80211_OpsSurveyGet(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN int Idx,
+ IN struct survey_info *pSurvey)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ VOID *pAd;
+ CMD_RTPRIV_IOCTL_80211_SURVEY SurveyInfo;
+
+
+ if (Idx != 0)
+ return -ENOENT;
+ /* End of if */
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> %s ==>\n", __FUNCTION__));
+
+ MAC80211_PAD_GET(pAd, pWiphy);
+
+ /* get information from driver */
+ RTMP_DRIVER_80211_SURVEY_GET(pAd, &SurveyInfo);
+
+ /* return the information to upper layer */
+ pSurvey->channel = ((CFG80211_CB *)(SurveyInfo.pCfg80211))->pCfg80211_Channels;
+ pSurvey->filled = SURVEY_INFO_CHANNEL_TIME_BUSY |
+ SURVEY_INFO_CHANNEL_TIME_EXT_BUSY;
+ pSurvey->channel_time_busy = SurveyInfo.ChannelTimeBusy; /* unit: us */
+ pSurvey->channel_time_ext_busy = SurveyInfo.ChannelTimeExtBusy;
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> busy time = %ld %ld\n",
+ (ULONG)SurveyInfo.ChannelTimeBusy,
+ (ULONG)SurveyInfo.ChannelTimeExtBusy));
+ return 0;
+#else
+
+ return -ENOTSUPP;
+#endif /* LINUX_VERSION_CODE */
+} /* End of CFG80211_OpsSurveyGet */
+
+
+/*
+========================================================================
+Routine Description:
+ Cache a PMKID for a BSSID.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev - Network device interface
+ pPmksa - PMKID information
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+ This is mostly useful for fullmac devices running firmwares capable of
+ generating the (re) association RSN IE.
+ It allows for faster roaming between WPA2 BSSIDs.
+========================================================================
+*/
+static int CFG80211_OpsPmksaSet(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN struct cfg80211_pmksa *pPmksa)
+{
+
+ return 0;
+} /* End of CFG80211_OpsPmksaSet */
+
+
+/*
+========================================================================
+Routine Description:
+ Delete a cached PMKID.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev - Network device interface
+ pPmksa - PMKID information
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+========================================================================
+*/
+static int CFG80211_OpsPmksaDel(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev,
+ IN struct cfg80211_pmksa *pPmksa)
+{
+
+ return 0;
+} /* End of CFG80211_OpsPmksaDel */
+
+
+/*
+========================================================================
+Routine Description:
+ Flush a cached PMKID.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pNdev - Network device interface
+
+Return Value:
+ 0 - success
+ -x - fail
+
+Note:
+========================================================================
+*/
+static int CFG80211_OpsPmksaFlush(
+ IN struct wiphy *pWiphy,
+ IN struct net_device *pNdev)
+{
+
+ return 0;
+} /* End of CFG80211_OpsPmksaFlush */
+#endif /* LINUX_VERSION_CODE */
+
+
+
+
+struct cfg80211_ops CFG80211_Ops = {
+ /* set channel for a given wireless interface */
+ .set_channel = CFG80211_OpsChannelSet,
+ /* change type/configuration of virtual interface */
+ .change_virtual_intf = CFG80211_OpsVirtualInfChg,
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
+ /* request to do a scan */
+ /*
+ Note: must exist whatever AP or STA mode; Or your kernel will crash
+ in v2.6.38.
+ */
+ .scan = CFG80211_OpsScan,
+#endif /* LINUX_VERSION_CODE */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
+#endif /* LINUX_VERSION_CODE */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
+ /* set the transmit power according to the parameters */
+ .set_tx_power = CFG80211_OpsTxPwrSet,
+ /* store the current TX power into the dbm variable */
+ .get_tx_power = CFG80211_OpsTxPwrGet,
+ /* configure WLAN power management */
+ .set_power_mgmt = CFG80211_OpsPwrMgmt,
+ /* get station information for the station identified by @mac */
+ .get_station = CFG80211_OpsStaGet,
+ /* dump station callback */
+ .dump_station = CFG80211_OpsStaDump,
+ /* notify that wiphy parameters have changed */
+ .set_wiphy_params = CFG80211_OpsWiphyParamsSet,
+ /* add a key with the given parameters */
+ .add_key = CFG80211_OpsKeyAdd,
+ /* get information about the key with the given parameters */
+ .get_key = CFG80211_OpsKeyGet,
+ /* remove a key given the @mac_addr */
+ .del_key = CFG80211_OpsKeyDel,
+ /* set the default key on an interface */
+ .set_default_key = CFG80211_OpsKeyDefaultSet,
+#endif /* LINUX_VERSION_CODE */
+
+#ifdef RFKILL_HW_SUPPORT
+ /* polls the hw rfkill line */
+ .rfkill_poll = CFG80211_OpsRFKill,
+#endif /* RFKILL_HW_SUPPORT */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+ /* get site survey information */
+ .dump_survey = CFG80211_OpsSurveyGet,
+ /* cache a PMKID for a BSSID */
+ .set_pmksa = CFG80211_OpsPmksaSet,
+ /* delete a cached PMKID */
+ .del_pmksa = CFG80211_OpsPmksaDel,
+ /* flush all cached PMKIDs */
+ .flush_pmksa = CFG80211_OpsPmksaFlush,
+#endif /* LINUX_VERSION_CODE */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
+ /*
+ Request the driver to remain awake on the specified
+ channel for the specified duration to complete an off-channel
+ operation (e.g., public action frame exchange).
+ */
+ .remain_on_channel = NULL,
+ /* cancel an on-going remain-on-channel operation */
+ .cancel_remain_on_channel = NULL,
+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,34))
+ /* transmit an action frame */
+ .action = NULL,
+#endif /* LINUX_VERSION_CODE */
+#endif /* LINUX_VERSION_CODE */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+ /* configure connection quality monitor RSSI threshold */
+ .set_cqm_rssi_config = NULL,
+#endif /* LINUX_VERSION_CODE */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ /* notify driver that a management frame type was registered */
+ .mgmt_frame_register = NULL,
+#endif /* LINUX_VERSION_CODE */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+ /* set antenna configuration (tx_ant, rx_ant) on the device */
+ .set_antenna = NULL,
+ /* get current antenna configuration from device (tx_ant, rx_ant) */
+ .get_antenna = NULL,
+#endif /* LINUX_VERSION_CODE */
+};
+
+
+
+
+/* =========================== 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_AP_SUPPORT
+ pWdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP);
+#ifdef WDS_SUPPORT
+ pWdev->wiphy->interface_modes | = BIT(NL80211_IFTYPE_WDS);
+#endif /* WDS_SUPPORT */
+#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_AP_SUPPORT
+ /* default we are AP mode */
+ pCfg80211_CB->pCfg80211_Wdev->iftype = NL80211_IFTYPE_AP;
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ pNetDev->ieee80211_ptr = pCfg80211_CB->pCfg80211_Wdev;
+ SET_NETDEV_DEV(pNetDev, wiphy_dev(pCfg80211_CB->pCfg80211_Wdev->wiphy));
+ pCfg80211_CB->pCfg80211_Wdev->netdev = pNetDev;
+
+#ifdef RFKILL_HW_SUPPORT
+ wiphy_rfkill_start_polling(pCfg80211_CB->pCfg80211_Wdev->wiphy);
+#endif /* RFKILL_HW_SUPPORT */
+
+ RTMP_DRIVER_80211_CB_SET(pAd, pCfg80211_CB);
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_Register\n"));
+ return TRUE;
+} /* End of CFG80211_Register */
+
+
+
+
+/* =========================== Local Function =============================== */
+
+/*
+========================================================================
+Routine Description:
+ The driver's regulatory notification callback.
+
+Arguments:
+ pWiphy - Wireless hardware description
+ pRequest - Regulatory request
+
+Return Value:
+ 0
+
+Note:
+========================================================================
+*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
+static INT32 CFG80211_RegNotifier(
+ IN struct wiphy *pWiphy,
+ IN struct regulatory_request *pRequest)
+{
+ VOID *pAd;
+ ULONG *pPriv;
+
+
+ /* sanity check */
+ pPriv = (ULONG *)(wiphy_priv(pWiphy));
+ pAd = (VOID *)(*pPriv);
+
+ if (pAd == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("crda> reg notify but pAd = NULL!"));
+ return 0;
+ } /* End of if */
+
+ /*
+ Change the band settings (PASS scan, IBSS allow, or DFS) in mac80211
+ based on EEPROM.
+
+ IEEE80211_CHAN_DISABLED: This channel is disabled.
+ IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
+ on this channel.
+ IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
+ IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
+ IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel
+ is not permitted.
+ IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel
+ is not permitted.
+ */
+
+ /*
+ Change regulatory rule here.
+
+ struct ieee80211_channel {
+ enum ieee80211_band band;
+ u16 center_freq;
+ u8 max_bandwidth;
+ u16 hw_value;
+ u32 flags;
+ int max_antenna_gain;
+ int max_power;
+ bool beacon_found;
+ u32 orig_flags;
+ int orig_mag, orig_mpwr;
+ };
+
+ In mac80211 layer, it will change flags, max_antenna_gain,
+ max_bandwidth, max_power.
+ */
+
+ switch(pRequest->initiator)
+ {
+ case NL80211_REGDOM_SET_BY_CORE:
+ /*
+ Core queried CRDA for a dynamic world regulatory domain.
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by core: "));
+ break;
+
+ case NL80211_REGDOM_SET_BY_USER:
+ /*
+ User asked the wireless core to set the regulatory domain.
+ (when iw, network manager, wpa supplicant, etc.)
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by user: "));
+ break;
+
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ /*
+ A wireless drivers has hinted to the wireless core it thinks
+ its knows the regulatory domain we should be in.
+ (when driver initialization, calling regulatory_hint)
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by driver: "));
+ break;
+
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ /*
+ The wireless core has received an 802.11 country information
+ element with regulatory information it thinks we should consider.
+ (when beacon receive, calling regulatory_hint_11d)
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by country IE: "));
+ break;
+ } /* End of switch */
+
+ CFG80211DBG(RT_DEBUG_ERROR,
+ ("%c%c\n", pRequest->alpha2[0], pRequest->alpha2[1]));
+
+ /* only follow rules from user */
+ if (pRequest->initiator == NL80211_REGDOM_SET_BY_USER)
+ {
+ /* keep Alpha2 and we can re-call the function when interface is up */
+ CMD_RTPRIV_IOCTL_80211_REG_NOTIFY RegInfo;
+
+ RegInfo.Alpha2[0] = pRequest->alpha2[0];
+ RegInfo.Alpha2[1] = pRequest->alpha2[1];
+ RegInfo.pWiphy = pWiphy;
+
+ RTMP_DRIVER_80211_REG_NOTIFY(pAd, &RegInfo);
+ } /* End of if */
+
+ return 0;
+} /* End of CFG80211_RegNotifier */
+
+#else
+
+static INT32 CFG80211_RegNotifier(
+ IN struct wiphy *pWiphy,
+ IN enum reg_set_by Request)
+{
+ struct device *pDev = pWiphy->dev.parent;
+ struct net_device *pNetDev = dev_get_drvdata(pDev);
+ VOID *pAd = (VOID *)RTMP_OS_NETDEV_GET_PRIV(pNetDev);
+ UINT32 ReqType = Request;
+
+
+ /* sanity check */
+ if (pAd == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("crda> reg notify but pAd = NULL!"));
+ return 0;
+ } /* End of if */
+
+ /*
+ Change the band settings (PASS scan, IBSS allow, or DFS) in mac80211
+ based on EEPROM.
+
+ IEEE80211_CHAN_DISABLED: This channel is disabled.
+ IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
+ on this channel.
+ IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
+ IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
+ IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel
+ is not permitted.
+ IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel
+ is not permitted.
+ */
+
+ /*
+ Change regulatory rule here.
+
+ struct ieee80211_channel {
+ enum ieee80211_band band;
+ u16 center_freq;
+ u8 max_bandwidth;
+ u16 hw_value;
+ u32 flags;
+ int max_antenna_gain;
+ int max_power;
+ bool beacon_found;
+ u32 orig_flags;
+ int orig_mag, orig_mpwr;
+ };
+
+ In mac80211 layer, it will change flags, max_antenna_gain,
+ max_bandwidth, max_power.
+ */
+
+ switch(ReqType)
+ {
+ case REGDOM_SET_BY_CORE:
+ /*
+ Core queried CRDA for a dynamic world regulatory domain.
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by core: "));
+ break;
+
+ case REGDOM_SET_BY_USER:
+ /*
+ User asked the wireless core to set the regulatory domain.
+ (when iw, network manager, wpa supplicant, etc.)
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by user: "));
+ break;
+
+ case REGDOM_SET_BY_DRIVER:
+ /*
+ A wireless drivers has hinted to the wireless core it thinks
+ its knows the regulatory domain we should be in.
+ (when driver initialization, calling regulatory_hint)
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by driver: "));
+ break;
+
+ case REGDOM_SET_BY_COUNTRY_IE:
+ /*
+ The wireless core has received an 802.11 country information
+ element with regulatory information it thinks we should consider.
+ (when beacon receive, calling regulatory_hint_11d)
+ */
+ CFG80211DBG(RT_DEBUG_ERROR, ("crda> requlation requestion by country IE: "));
+ break;
+ } /* End of switch */
+
+ DBGPRINT(RT_DEBUG_ERROR, ("00\n"));
+
+ /* only follow rules from user */
+ if (ReqType == REGDOM_SET_BY_USER)
+ {
+ /* keep Alpha2 and we can re-call the function when interface is up */
+ CMD_RTPRIV_IOCTL_80211_REG_NOTIFY RegInfo;
+
+ RegInfo.Alpha2[0] = '0';
+ RegInfo.Alpha2[1] = '0';
+ RegInfo.pWiphy = pWiphy;
+
+ RTMP_DRIVER_80211_REG_NOTIFY(pAd, &RegInfo);
+ } /* End of if */
+
+ return 0;
+} /* End of CFG80211_RegNotifier */
+#endif /* LINUX_VERSION_CODE */
+
+
+#endif /* RT_CFG80211_SUPPORT */
+#endif /* LINUX_VERSION_CODE */
+
+/* End of crda.c */
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/cfg80211drv.c b/cleopatre/devkit/mt7601udrv/os/linux/cfg80211drv.c
new file mode 100644
index 0000000000..3eee8a2f00
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/cfg80211drv.c
@@ -0,0 +1,1675 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related CFG80211 function body.
+
+ History:
+
+***************************************************************************/
+
+#ifdef RT_CFG80211_SUPPORT
+
+#include "rt_config.h"
+
+#define RT_CFG80211_DEBUG /* debug use */
+#define CFG80211CB (pAd->pCfg80211_CB)
+
+#ifdef RT_CFG80211_DEBUG
+#define CFG80211DBG(__Flg, __pMsg) DBGPRINT(__Flg, __pMsg)
+#else
+#define CFG80211DBG(__Flg, __pMsg)
+#endif /* RT_CFG80211_DEBUG */
+
+
+
+
+INT CFG80211DRV_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;
+
+
+ switch(cmd)
+ {
+ case CMD_RTPRIV_IOCTL_80211_START:
+ case CMD_RTPRIV_IOCTL_80211_END:
+ /* nothing to do */
+ break;
+
+ 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:
+ 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_UNREGISTER:
+ CFG80211_UnRegister(pAd, pData);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_BANDINFO_GET:
+ {
+ CFG80211_BAND *pBandInfo = (CFG80211_BAND *)pData;
+ CFG80211_BANDINFO_FILL(pAd, pBandInfo);
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_SURVEY_GET:
+ CFG80211DRV_SurveyGet(pAd, pData);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_EXTRA_IES_SET:
+ CFG80211DRV_OpsExtraIesSet(pAd);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_REMAIN_ON_CHAN_SET:
+ CFG80211DRV_OpsRemainOnChannel(pAd, pData, Data);
+ break;
+ case CMD_RTPRIV_IOCTL_80211_CANCEL_REMAIN_ON_CHAN_SET:
+ CFG80211DRV_OpsCancelRemainOnChannel(pAd, Data);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_MGMT_FRAME_REG:
+ if (Data)
+ pAd->Cfg80211ProbeReqCount++;
+ else
+ {
+ pAd->Cfg80211ProbeReqCount--;
+ }
+
+ if (pAd->Cfg80211ProbeReqCount > 0)
+ pAd->Cfg80211RegisterProbeReqFrame = TRUE;
+ else
+ pAd->Cfg80211RegisterProbeReqFrame = FALSE;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("pAd->Cfg80211RegisterProbeReqFrame=%d[%d]\n",pAd->Cfg80211RegisterProbeReqFrame, pAd->Cfg80211ProbeReqCount));
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_ACTION_FRAME_REG:
+ if (Data)
+ pAd->Cfg80211ActionCount++;
+ else
+ pAd->Cfg80211ActionCount--;
+
+ if (pAd->Cfg80211ActionCount > 0)
+ pAd->Cfg80211RegisterActionFrame = TRUE;
+ else
+ pAd->Cfg80211RegisterActionFrame = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->Cfg80211RegisterActionFrame=%d [%d]\n",pAd->Cfg80211RegisterActionFrame, pAd->Cfg80211ActionCount));
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_CHANNEL_LOCK:
+ //pAd->CommonCfg.CentralChannel = Data;
+ //DBGPRINT(RT_DEBUG_TRACE, ("CMD_RTPRIV_IOCTL_80211_CHANNEL_LOCK %d\n", Data));
+ if (pAd->CommonCfg.Channel != Data)
+ {
+ pAd->CommonCfg.Channel= Data;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_MGMT_FRAME_SEND:
+ /* send a managment frame */
+ pAd->TxStatusInUsed = TRUE;
+ pAd->TxStatusSeq = pAd->Sequence;
+ if (pData != NULL)
+ {
+#ifdef WFD_SUPPORT
+ if (pAd->StaCfg.WfdCfg.bSuppInsertWfdIe)
+ {
+ PP2P_PUBLIC_FRAME pFrame = (PP2P_PUBLIC_FRAME)pData;
+ ULONG WfdIeLen = 0, WfdIeBitmap = 0;
+
+ switch (pFrame->p80211Header.FC.SubType)
+ {
+ case SUBTYPE_BEACON:
+ case SUBTYPE_PROBE_REQ:
+ case SUBTYPE_ASSOC_REQ:
+ case SUBTYPE_REASSOC_REQ:
+ WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
+ (0x1 << SUBID_WFD_COUPLED_SINK_INFO);
+ break;
+
+ case SUBTYPE_ASSOC_RSP:
+ case SUBTYPE_REASSOC_RSP:
+ WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
+ (0x1 << SUBID_WFD_COUPLED_SINK_INFO) | (0x1 << SUBID_WFD_SESSION_INFO);
+ break;
+
+ case SUBTYPE_PROBE_RSP:
+ WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
+ (0x1 << SUBID_WFD_COUPLED_SINK_INFO) | (0x1 << SUBID_WFD_SESSION_INFO);
+ break;
+
+ case SUBTYPE_ACTION:
+ if ((pFrame->Category == CATEGORY_PUBLIC) &&
+ (pFrame->Action == ACTION_WIFI_DIRECT))
+ {
+ switch (pFrame->Subtype)
+ {
+ case GO_NEGOCIATION_REQ:
+ case GO_NEGOCIATION_RSP:
+ case GO_NEGOCIATION_CONFIRM:
+ case P2P_PROVISION_REQ:
+ WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
+ (0x1 << SUBID_WFD_COUPLED_SINK_INFO);
+ break;
+
+ case P2P_INVITE_REQ:
+ case P2P_INVITE_RSP:
+ case P2P_PROVISION_RSP:
+ WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
+ (0x1 << SUBID_WFD_COUPLED_SINK_INFO) | (0x1 << SUBID_WFD_SESSION_INFO);
+ break;
+ }
+ }
+ break;
+ }
+
+ if (WfdIeBitmap > 0)
+ {
+ PUCHAR pOutBuffer;
+ NDIS_STATUS NStatus;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
+ else
+ {
+ memcpy(pOutBuffer, pData, Data);
+ WfdMakeWfdIE(pAd, WfdIeBitmap, pOutBuffer + Data, &WfdIeLen);
+ Data += WfdIeLen;
+
+ if (pAd->pTxStatusBuf != NULL)
+ os_free_mem(NULL, pAd->pTxStatusBuf);
+
+ os_alloc_mem(NULL, (UCHAR **)&pAd->pTxStatusBuf, Data);
+ if (pAd->pTxStatusBuf != NULL)
+ {
+ NdisCopyMemory(pAd->pTxStatusBuf, pOutBuffer, Data);
+ pAd->TxStatusBufLen = Data;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("YF_TX_STATUS: MEM ALLOC ERROR\n"));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ return NDIS_STATUS_FAILURE;
+ }
+ MiniportMMRequest(pAd, 0, pOutBuffer, Data);
+ }
+ }
+ }
+ else
+#endif /* WFD_SUPPORT */
+ {
+ if (pAd->pTxStatusBuf != NULL)
+ os_free_mem(NULL, pAd->pTxStatusBuf);
+
+ os_alloc_mem(NULL, (UCHAR **)&pAd->pTxStatusBuf, Data);
+ if (pAd->pTxStatusBuf != NULL)
+ {
+ NdisCopyMemory(pAd->pTxStatusBuf, pData, Data);
+ pAd->TxStatusBufLen = Data;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("YF_TX_STATUS: MEM ALLOC ERROR\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+ // pAd->pTxStatusBuf
+ // pAd->TxStatusBufLen = Data
+ //DBGPRINT(RT_DEBUG_TRACE, ("YF_TX_STATUS: send %d\n", pAd->TxStatusSeq));
+ MiniportMMRequest(pAd, 0, pData, Data);
+ //DBGPRINT(RT_DEBUG_TRACE, ("YF_TX_STATUS: sent %d\n", pAd->TxStatusSeq));
+ }
+ }
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_REMAIN_ON_CHAN_DUR_TIMER_INIT:
+ DBGPRINT(RT_DEBUG_TRACE, ("ROC TIMER INIT\n"));
+ RTMPInitTimer(pAd, &pAd->Cfg80211RemainOnChannelDurationTimer, GET_TIMER_FUNCTION(RemainOnChannelTimeout), pAd, FALSE);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_CHANNEL_LIST_SET:
+ DBGPRINT(RT_DEBUG_TRACE, ("CMD_RTPRIV_IOCTL_80211_CHANNEL_LIST_SET: %d\n", Data));
+ UINT32 *pChanList = (UINT32 *) pData;
+
+ if (pChanList != NULL)
+ {
+
+ if (pAd->pCfg80211ChanList != NULL)
+ os_free_mem(NULL, pAd->pCfg80211ChanList);
+
+ os_alloc_mem(NULL, (UINT32 **)&pAd->pCfg80211ChanList, sizeof(UINT32 *) * Data);
+ if (pAd->pCfg80211ChanList != NULL)
+ {
+ NdisCopyMemory(pAd->pCfg80211ChanList, pChanList, sizeof(UINT32 *) * Data);
+ pAd->Cfg80211ChanListLan = Data;
+ }
+ else
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_BEACON_SET:
+ CFG80211DRV_OpsBeaconSet(pAd, pData, 0);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_BEACON_ADD:
+ CFG80211DRV_OpsBeaconSet(pAd, pData, 1);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_BEACON_DEL:
+#ifdef WFD_SUPPORT
+ pAd->StaCfg.WfdCfg.bSuppGoOn = FALSE;
+#endif /* WFD_SUPPORT */
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_CHANGE_BSS_PARM:
+ CFG80211DRV_OpsChangeBssParm(pAd, pData);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_AP_PROBE_RSP:
+ if (pData != NULL)
+ {
+ if (pAd->pCfg80211RrobeRsp != NULL)
+ os_free_mem(NULL, pAd->pCfg80211RrobeRsp);
+
+ os_alloc_mem(NULL, (UCHAR **)&pAd->pCfg80211RrobeRsp, Data);
+ if (pAd->pCfg80211RrobeRsp != NULL)
+ {
+ NdisCopyMemory(pAd->pCfg80211RrobeRsp, pData, Data);
+ pAd->Cfg80211AssocRspLen = Data;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("YF_AP: MEM ALLOC ERROR\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ }
+ else
+ return NDIS_STATUS_FAILURE;
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_PORT_SECURED:
+ CFG80211_StaPortSecured(pAd, pData, Data);
+ break;
+
+ case CMD_RTPRIV_IOCTL_80211_AP_STA_DEL:
+ CFG80211_ApStaDel(pAd, pData);
+ break;
+ case CMD_RTPRIV_IOCTL_80211_BITRATE_SET:
+ // pAd->CommonCfg.PhyMode = PHY_11AN_MIXED;
+ // RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode);
+ //Set_WirelessMode_Proc(pAd, PHY_11AGN_MIXED);
+ break;
+#ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT
+ case CMD_RTPRIV_IOCTL_80211_SEND_WIRELESS_EVENT:
+ CFG80211_SendWirelessEvent(pAd, pData);
+ break;
+#endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */
+ default:
+ return NDIS_STATUS_FAILURE;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+static VOID CFG80211DRV_DisableApInterface(
+ VOID *pAdOrg)
+{
+ UINT32 Value;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = FALSE;
+
+ /* Disable pre-tbtt interrupt */
+ RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
+ Value &=0xe;
+ RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
+
+ if (!INFRA_ON(pAd))
+ {
+ /* Disable piggyback */
+ RTMPSetPiggyBack(pAd, FALSE);
+ AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
+
+ }
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ /*RTMP_ASIC_INTERRUPT_DISABLE(pAd); */
+ AsicDisableSync(pAd);
+
+#ifdef LED_CONTROL_SUPPORT
+ /* Set LED */
+ RTMPSetLED(pAd, LED_LINK_DOWN);
+#endif /* LED_CONTROL_SUPPORT */
+ }
+
+#ifdef RTMP_MAC_USB
+ /* For RT2870, we need to clear the beacon sync buffer. */
+ RTUSBBssBeaconExit(pAd);
+#endif /* RTMP_MAC_USB */
+
+}
+
+VOID CFG80211DRV_OpsChangeBssParm(
+ VOID *pAdOrg,
+ VOID *pData)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
+ CMD_RTPRIV_IOCTL_80211_BSS_PARM *pBssInfo;
+ BOOLEAN TxPreamble;
+
+ CFG80211DBG(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
+
+ pBssInfo = (CMD_RTPRIV_IOCTL_80211_BSS_PARM *)pData;
+
+ /* Short Preamble */
+ if (pBssInfo->use_short_preamble != -1)
+ {
+ CFG80211DBG(RT_DEBUG_TRACE, ("%s: ShortPreamble %d\n", __FUNCTION__, pBssInfo->use_short_preamble));
+ pAd->CommonCfg.TxPreamble = (pBssInfo->use_short_preamble == 0 ? Rt802_11PreambleLong : Rt802_11PreambleShort);
+ TxPreamble = (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1);
+ MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble);
+ }
+
+ /* CTS Protection */
+ if (pBssInfo->use_cts_prot != -1)
+ {
+ CFG80211DBG(RT_DEBUG_TRACE, ("%s: CTS Protection %d\n", __FUNCTION__, pBssInfo->use_cts_prot));
+ }
+
+ /* Short Slot */
+ if (pBssInfo->use_short_slot_time != -1)
+ {
+ CFG80211DBG(RT_DEBUG_TRACE, ("%s: Short Slot %d\n", __FUNCTION__, pBssInfo->use_short_slot_time));
+ }
+}
+
+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 */
+
+
+ return TRUE;
+}
+
+
+BOOLEAN CFG80211DRV_OpsChgVirtualInf(
+ VOID *pAdOrg,
+ VOID *pFlgFilter,
+ UINT8 IfType)
+{
+
+ 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;
+}
+
+/* REF: ap_connect.c ApMakeBssBeacon */
+BOOLEAN CFG80211DRV_OpsBeaconSet(
+ VOID *pAdOrg,
+ VOID *pData,
+ BOOLEAN isAdd)
+{
+ CFG80211DBG(RT_DEBUG_TRACE, ("80211> CFG80211DRV_OpsBeaconSet ==> %d\n", isAdd));
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
+ CMD_RTPRIV_IOCTL_80211_BEACON *pBeacon;
+ PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
+ HTTRANSMIT_SETTING BeaconTransmit; /* MGMT frame PHY rate setting when operatin at Ht rate. */
+ BCN_TIME_CFG_STRUC csr9;
+ UCHAR *ptr;
+ UINT i;
+ UINT32 longValue;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ UINT32 rx_filter_flag;
+ BOOLEAN TxPreamble, SpectrumMgmt = FALSE;
+ BOOLEAN bWmmCapable = FALSE;
+ UCHAR BBPR1 = 0, BBPR3 = 0;
+ INT idx;
+ ULONG offset;
+
+ CFG80211DBG(RT_DEBUG_TRACE, ("80211> CFG80211DRV_OpsBeaconSet ==> \n"));
+ pBeacon = (CMD_RTPRIV_IOCTL_80211_BEACON *)pData;
+
+#ifdef WFD_SUPPORT
+ if (pAd->StaCfg.WfdCfg.bSuppInsertWfdIe)
+ {
+ ULONG TmpLen, WfdIeBitmap;
+
+ ptr = pBeacon->beacon + pBeacon->beacon_len;
+ WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
+ (0x1 << SUBID_WFD_COUPLED_SINK_INFO);
+ WfdMakeWfdIE(pAd, WfdIeBitmap, ptr, &TmpLen);
+ pBeacon->beacon_len += TmpLen;
+ }
+#endif /* WFD_SUPPORT */
+
+ if (isAdd)
+ {
+ rx_filter_flag = APNORMAL;
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); /* enable RX of DMA block */
+
+ pAd->ApCfg.BssidNum = 1;
+ pAd->MacTab.MsduLifeTime = 20; /* default 5 seconds */
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE;
+
+#ifdef INF_AMAZON_SE
+ printk("YF DEBUG: INF_AMAZON_SE\n");
+ for (i = 0; i < NUM_OF_TX_RING; i++)
+ {
+ pAd->BulkOutDataSizeLimit[i]=24576;
+ }
+#endif /* INF_AMAZON_SE */
+
+ AsicDisableSync(pAd);
+
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ if (pAd->CommonCfg.Channel > 14)
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11AN_MIXED;
+ else
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11BGN_MIXED;
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel > 14)
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11A;
+ else
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11BG_MIXED;
+ }
+
+ TxPreamble = (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1);
+ }
+
+ PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];
+
+ const UCHAR *ssid_ie = NULL;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+ ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, pBeacon->beacon+36, pBeacon->beacon_len-36);
+#endif
+ NdisZeroMemory(pMbss->Ssid, pMbss->SsidLen);
+ if (ssid_ie == NULL)
+ {
+ printk("YF Debug: SSID Not Found In Packet\n");
+ NdisMoveMemory(pMbss->Ssid, "P2P_Linux_AP", 12);
+ pMbss->SsidLen = 12;
+ }
+ else
+ {
+ pMbss->SsidLen = ssid_ie[1];
+ NdisCopyMemory(pMbss->Ssid, ssid_ie+2, pMbss->SsidLen);
+ printk("YF Debug: SSID: %s, %d\n", pMbss->Ssid, pMbss->SsidLen);
+ }
+
+ if (isAdd)
+ {
+ //if (pMbss->bWmmCapable)
+ //{
+ bWmmCapable = FALSE;
+ pMbss->bWmmCapable = FALSE;
+ //}
+
+ pMbss->MSSIDDev = pAd->net_dev;
+ COPY_MAC_ADDR(pMbss->Bssid, pAd->CurrentAddress);
+ printk("AP BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->CurrentAddress));
+
+ /* GO always use WPA2PSK / AES */
+ pMbss->AuthMode = Ndis802_11AuthModeWPA2PSK;
+ pMbss->WepStatus = Ndis802_11Encryption3Enabled;
+ pMbss->WscSecurityMode = WPA2PSKAES;
+ pMbss->GroupKeyWepStatus = pMbss->WepStatus;
+ pMbss->CapabilityInfo =
+ CAP_GENERATE(1, 0, (pMbss->WepStatus != Ndis802_11EncryptionDisabled), TxPreamble, pAd->CommonCfg.bUseShortSlotTime, SpectrumMgmt);
+
+ RTMPMakeRSNIE(pAd, Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled, MAIN_MBSSID);
+
+#ifdef DOT11_N_SUPPORT
+ RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode);
+ SetCommonHT(pAd);
+
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->Antenna.field.TxPath == 2))
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
+ BBPR1 &= (~0x18);
+ BBPR1 |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
+ }
+ else
+#endif /* DOT11_N_SUPPORT */
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
+ BBPR1 &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
+ }
+
+ /* Receiver Antenna selection, write to BBP R3(bit4:3) */
+ 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))
+ {
+ if ((pAd->CommonCfg.PhyMode > PHY_11G) || bWmmCapable)
+ {
+ /* EDCA parameters used for AP's own transmission */
+ 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; /*96; */
+ pAd->CommonCfg.APEdcaParm.Txop[3] = 47; /*48; */
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+ /* EDCA parameters to be annouced in outgoing BEACON, used by WMM STA */
+ pAd->ApCfg.BssEdcaParm.bValid = TRUE;
+ pAd->ApCfg.BssEdcaParm.Aifsn[0] = 3;
+ pAd->ApCfg.BssEdcaParm.Aifsn[1] = 7;
+ pAd->ApCfg.BssEdcaParm.Aifsn[2] = 2;
+ pAd->ApCfg.BssEdcaParm.Aifsn[3] = 2;
+
+ pAd->ApCfg.BssEdcaParm.Cwmin[0] = 4;
+ pAd->ApCfg.BssEdcaParm.Cwmin[1] = 4;
+ pAd->ApCfg.BssEdcaParm.Cwmin[2] = 3;
+ pAd->ApCfg.BssEdcaParm.Cwmin[3] = 2;
+
+ pAd->ApCfg.BssEdcaParm.Cwmax[0] = 10;
+ pAd->ApCfg.BssEdcaParm.Cwmax[1] = 10;
+ pAd->ApCfg.BssEdcaParm.Cwmax[2] = 4;
+ pAd->ApCfg.BssEdcaParm.Cwmax[3] = 3;
+
+ pAd->ApCfg.BssEdcaParm.Txop[0] = 0;
+ pAd->ApCfg.BssEdcaParm.Txop[1] = 0;
+ pAd->ApCfg.BssEdcaParm.Txop[2] = 94; /*96; */
+ pAd->ApCfg.BssEdcaParm.Txop[3] = 47; /*48; */
+ }
+ else
+ {
+ AsicSetEdcaParm(pAd, NULL);
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
+ {
+ /* Patch UI */
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = BW_20;
+ }
+
+ /* init */
+ if (pAd->CommonCfg.bRdg)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
+ AsicEnableRDG(pAd);
+ }
+ else
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
+ AsicDisableRDG(pAd);
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ //AsicSetBssid(pAd, pAd->CurrentAddress);
+ AsicSetMcastWC(pAd);
+
+ /* In AP mode, First WCID Table in ASIC will never be used. To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */
+ /* p.s ASIC use all 0xff as termination of WCID table search. */
+ RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
+ RTMP_IO_WRITE32(pAd, MAC_WCID_BASE+4, 0x0);
+
+ /* reset WCID table */
+ for (idx=2; idx<255; idx++)
+ {
+ offset = MAC_WCID_BASE + (idx * HW_WCID_ENTRY_SIZE);
+ RTMP_IO_WRITE32(pAd, offset, 0x0);
+ RTMP_IO_WRITE32(pAd, offset+4, 0x0);
+ }
+
+ pAd->MacTab.Content[0].Addr[0] = 0x01;
+ pAd->MacTab.Content[0].HTPhyMode.field.MODE = MODE_OFDM;
+ pAd->MacTab.Content[0].HTPhyMode.field.MCS = 3;
+
+ AsicBBPAdjust(pAd);
+ //MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble);
+
+ {
+ ULONG Addr4;
+ UINT32 regValue;
+ PUCHAR pP2PBssid = &pAd->CurrentAddress[0];
+
+ Addr4 = (ULONG)(pP2PBssid[0]) |
+ (ULONG)(pP2PBssid[1] << 8) |
+ (ULONG)(pP2PBssid[2] << 16) |
+ (ULONG)(pP2PBssid[3] << 24);
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+ Addr4 = 0;
+
+ Addr4 = (ULONG)(pP2PBssid[4]) | (ULONG)(pP2PBssid[5] << 8);
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+
+ RTMP_IO_READ32(pAd, MAC_BSSID_DW1, &regValue);
+ regValue &= 0x0000FFFF;
+
+ regValue |= (1 << 16);
+
+ if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
+ regValue |= (1 << 21);
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, regValue);
+ }
+
+
+#ifdef RTMP_MAC_USB
+ printk("YF DEBUG: RTUSBBssBeaconInit\n");
+ RTUSBBssBeaconInit(pAd);
+#endif /* RTMP_MAC_USB */
+ }
+
+ UCHAR apcliIdx, apidx = MAIN_MBSSID;
+
+ //pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11BGN_MIXED;
+
+
+ printk("YF DEBUG: Beacon Len %d\n", pBeacon->beacon_len);
+ printk("YF DEBUG: Beacon Interval %d\n", pBeacon->interval);
+ BeaconTransmit.word = 0;
+
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS0Mcast_WCID,
+ pBeacon->beacon_len, PID_MGMT, 0, 0,IFS_HTTXOP, FALSE, &BeaconTransmit);
+
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(ptr, TYPE_TXWI);
+#endif
+
+ for (i=0; i<TXWISize; i+=4) /* 16-byte TXWI field */
+ {
+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[0] + i, longValue);
+ ptr += 4;
+ }
+
+ /* update BEACON frame content. start right after the 16-byte TXWI field. */
+ ptr = pBeacon->beacon;
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
+#endif
+
+ for (i= 0; i< pBeacon->beacon_len; i+=4)
+ {
+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[0] + TXWISize + i, longValue);
+ ptr += 4;
+ }
+
+ if (isAdd)
+ {
+ /* Enable Bss Sync*/
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
+ csr9.field.BeaconInterval = (pBeacon->interval) << 4; /* ASIC register in units of 1/16 TU*/
+ csr9.field.bTsfTicking = 1;
+ csr9.field.TsfSyncMode = 3;
+ csr9.field.bTBTTEnable = 1;
+ csr9.field.bBeaconGen = 1;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+
+ pAd->P2pCfg.bSentProbeRSP = TRUE;
+
+#ifdef RTMP_MAC_USB
+ /*
+ * Support multiple BulkIn IRP,
+ * the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
+ */
+
+ UCHAR num_idx;
+
+ for(num_idx=0; num_idx < pAd->CommonCfg.NumOfBulkInIRP; num_idx++)
+ {
+ RTUSBBulkReceive(pAd);
+ printk("RTUSBBulkReceive!\n" );
+ }
+
+#endif /* RTMP_MAC_USB */
+ }
+
+#ifdef WFD_SUPPORT
+ pAd->StaCfg.WfdCfg.bSuppGoOn = TRUE;
+#endif /* WFD_SUPPORT */
+
+ return TRUE;
+
+}
+
+BOOLEAN CFG80211DRV_OpsExtraIesSet(
+ VOID *pAdOrg)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
+
+ CFG80211_CB *pCfg80211_CB = pAd->pCfg80211_CB;
+ UINT ie_len = pCfg80211_CB->pCfg80211_ScanReq->ie_len;
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211DRV_OpsExtraIesSet ==> %d\n", ie_len));
+
+ if (pAd->StaCfg.pWpsProbeReqIe)
+ {
+ os_free_mem(NULL, pAd->StaCfg.pWpsProbeReqIe);
+ pAd->StaCfg.pWpsProbeReqIe = NULL;
+ }
+
+ pAd->StaCfg.WpsProbeReqIeLen = 0;
+
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> is_wpa_supplicant_up ==> %d\n", pAd->StaCfg.WpaSupplicantUP));
+ os_alloc_mem(pAd, (UCHAR **)&(pAd->StaCfg.pWpsProbeReqIe), ie_len);
+ if (pAd->StaCfg.pWpsProbeReqIe)
+ {
+ memcpy(pAd->StaCfg.pWpsProbeReqIe, pCfg80211_CB->pCfg80211_ScanReq->ie, ie_len);
+ pAd->StaCfg.WpsProbeReqIeLen = ie_len;
+ //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
+ {
+ CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211DRV_OpsExtraIesSet ==> allocate fail. \n"));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+BOOLEAN CFG80211DRV_OpsJoinIbss(
+ VOID *pAdOrg,
+ VOID *pData)
+{
+ return TRUE;
+}
+
+
+BOOLEAN CFG80211DRV_OpsLeave(
+ VOID *pAdOrg)
+{
+ 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_AP_SUPPORT
+{
+ MAC_TABLE_ENTRY *pEntry;
+ ULONG DataRate = 0;
+ UINT32 RSSI;
+
+
+ pEntry = MacTableLookup(pAd, pIbssInfo->MAC);
+ if (pEntry == NULL)
+ return FALSE;
+ /* End of if */
+
+ /* fill tx rate */
+ getRate(pEntry->HTPhyMode, &DataRate);
+
+ if ((pEntry->HTPhyMode.field.MODE == MODE_HTMIX) ||
+ (pEntry->HTPhyMode.field.MODE == MODE_HTGREENFIELD))
+ {
+ if (pEntry->HTPhyMode.field.BW)
+ pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_BW_40;
+ /* End of if */
+ if (pEntry->HTPhyMode.field.ShortGI)
+ pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_SHORT_GI;
+ /* End of if */
+
+ pIbssInfo->TxRateMCS = pEntry->HTPhyMode.field.MCS;
+ }
+ else
+ {
+ pIbssInfo->TxRateFlags = RT_CMD_80211_TXRATE_LEGACY;
+ pIbssInfo->TxRateMCS = DataRate*1000; /* unit: 100kbps */
+ } /* End of if */
+
+ /* fill signal */
+ RSSI = (pEntry->RssiSample.AvgRssi0 +
+ pEntry->RssiSample.AvgRssi1 +
+ pEntry->RssiSample.AvgRssi2) / 3;
+ pIbssInfo->Signal = RSSI;
+
+ /* fill tx count */
+ pIbssInfo->TxPacketCnt = pEntry->OneSecTxNoRetryOkCount +
+ pEntry->OneSecTxRetryOkCount +
+ pEntry->OneSecTxFailCount;
+
+ /* fill inactive time */
+ pIbssInfo->InactiveTime = pEntry->NoDataIdleCount * 1000; /* unit: ms */
+ pIbssInfo->InactiveTime *= MLME_TASK_EXEC_MULTIPLE;
+ pIbssInfo->InactiveTime /= 20;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ return TRUE;
+}
+
+
+BOOLEAN CFG80211DRV_KeyAdd(
+ VOID *pAdOrg,
+ VOID *pData)
+{
+
+ return TRUE;
+}
+
+
+BOOLEAN CFG80211DRV_Connect(
+ VOID *pAdOrg,
+ VOID *pData)
+{
+
+ 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 CFG80211DRV_SurveyGet(
+ VOID *pAdOrg,
+ VOID *pData)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
+ CMD_RTPRIV_IOCTL_80211_SURVEY *pSurveyInfo;
+
+
+ pSurveyInfo = (CMD_RTPRIV_IOCTL_80211_SURVEY *)pData;
+
+ pSurveyInfo->pCfg80211 = pAd->pCfg80211_CB;
+
+#ifdef AP_QLOAD_SUPPORT
+ pSurveyInfo->ChannelTimeBusy = pAd->QloadLatestChannelBusyTimePri;
+ pSurveyInfo->ChannelTimeExtBusy = pAd->QloadLatestChannelBusyTimeSec;
+#endif /* AP_QLOAD_SUPPORT */
+}
+
+
+VOID CFG80211_UnRegister(
+ IN VOID *pAdOrg,
+ IN VOID *pNetDev)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
+
+
+ /* 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;
+ UINT32 IdBand, IdChan, IdPwr;
+ UINT32 ChanNum, ChanId, Power, RecId, DfsType;
+ BOOLEAN FlgIsRadar;
+ ULONG IrqFlags;
+#ifdef DFS_SUPPORT
+ RADAR_DETECT_STRUCT *pRadarDetect;
+#endif /* DFS_SUPPORT */
+
+
+ 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;
+#ifdef DFS_SUPPORT
+ pRadarDetect = &pAd->CommonCfg.RadarDetect;
+#endif /* DFS_SUPPORT */
+
+ /* 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]))
+ {
+ if (pAd->CommonCfg.DfsType != MAX_RD_REGION)
+ DfsType = pAd->CommonCfg.DfsType;
+ else
+ 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; IdChan<ChanNum; IdChan++)
+ {
+ if (CFG80211OS_ChanInfoGet(CFG80211CB, pWiphy, IdBand, IdChan,
+ &ChanId, &Power, &FlgIsRadar) == FALSE)
+ {
+ /* the channel is not allowed in the regulatory domain */
+ /* get next channel information */
+ continue;
+ }
+
+ if (!WMODE_CAP_2G(pAd->CommonCfg.PhyMode))
+ {
+ /* 5G-only mode */
+ if (ChanId <= CFG80211_NUM_OF_CHAN_2GHZ)
+ continue;
+ }
+
+ if (!WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
+ {
+ /* 2.4G-only mode */
+ if (ChanId > CFG80211_NUM_OF_CHAN_2GHZ)
+ continue;
+ }
+
+ for(IdPwr=0; IdPwr<MAX_NUM_OF_CHANNELS; IdPwr++)
+ {
+ if (ChanId == pAd->TxPower[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. */
+ pAd->CommonCfg.RDDurRegion = DfsType;
+
+ 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)
+{
+} /* 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)
+{
+} /* 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 */
+
+
+INT CFG80211_StaPortSecured(
+ IN VOID *pAdCB,
+ IN UCHAR *pMac,
+ IN UINT flag)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
+ MAC_TABLE_ENTRY *pEntry;
+
+ pEntry = MacTableLookup(pAd, pMac);
+ if (!pEntry)
+ {
+ printk("Can't find pEntry in CFG80211_StaPortSecured\n");
+ }
+ else
+ {
+ if (flag)
+ {
+ printk("AID:%d, PortSecured\n", pEntry->Aid);
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ pEntry->WpaState = AS_PTKINITDONE;
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ }
+ else
+ {
+ printk("AID:%d, PortNotSecured\n", pEntry->Aid);
+ pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ }
+
+ return 0;
+}
+
+INT CFG80211_ApStaDel(
+ IN VOID *pAdCB,
+ IN UCHAR *pMac)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
+ MAC_TABLE_ENTRY *pEntry;
+
+ if (pMac == NULL)
+ {
+ MacTableReset(pAd);
+ }
+ else
+ {
+ pEntry = MacTableLookup(pAd, pMac);
+ if (pEntry)
+ {
+ // MlmeDeAuthAction(pAd, pEntry, 2, FALSE);
+ }
+ else
+ printk("Can't find pEntry in ApStaDel\n");
+ }
+}
+
+//CMD_RTPRIV_IOCTL_80211_KEY_DEFAULT_SET:
+INT CFG80211_setDefaultKey(
+ IN VOID *pAdCB,
+ IN UINT Data
+)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
+ CFG80211_CB *p80211CB = pAd->pCfg80211_CB;
+
+ if (p80211CB->pCfg80211_Wdev->iftype == RT_CMD_80211_IFTYPE_AP)
+ //if (pAd->VifNextMode == RT_CMD_80211_IFTYPE_AP)
+ {
+ printk("Set Ap Default Key: %d\n", Data);
+ pAd->ApCfg.MBSSID[MAIN_MBSSID].DefaultKeyId = Data;
+ }
+ else
+ return 0;
+
+}
+
+#ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT
+INT CFG80211_SendWirelessEvent(
+ IN VOID *pAdCB,
+ IN UCHAR *pMacAddr)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
+
+ P2pSendWirelessEvent(pAd, RT_P2P_CONNECTED, NULL, pMacAddr);
+
+ return 0;
+}
+#endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */
+
+
+#endif /* RT_CFG80211_SUPPORT */
+
+/* End of cfg80211drv.c */
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/config.mk b/cleopatre/devkit/mt7601udrv/os/linux/config.mk
new file mode 100644
index 0000000000..87b00d5cf6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/config.mk
@@ -0,0 +1,1125 @@
+# Support ATE function
+HAS_ATE=y
+
+# Support QA ATE function
+HAS_QA_SUPPORT=y
+
+HAS_RSSI_FEEDBACK=n
+
+# Support XLINK mode
+HAS_XLINK=n
+
+# Support WSC function
+HAS_WSC=y
+HAS_WSC_V2=y
+HAS_WSC_LED=n
+
+
+# Support LLTD function
+HAS_LLTD=n
+
+# Support WDS function
+HAS_WDS=n
+
+# Support AP-Client function
+HAS_APCLI=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 HE_BD_SUPPORT
+HAS_HE_BD_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 Single SKU.
+HAS_SINGLE_SKU_V2_SUPPORT=n
+
+#Support features of 802.11n
+HAS_DOT11_N_SUPPORT=y
+
+#Support for 802.11ac VHT
+HAS_DOT11_VHT_SUPPORT=n
+
+#Support for WAPI
+HAS_WAPI_SUPPORT=n
+
+
+#Support for 2860/2880 co-exist
+HAS_RT2880_RT2860_COEXIST=n
+
+HAS_KTHREAD_SUPPORT=n
+
+
+
+
+
+#Support for WiFi Display
+HAS_WFD_SUPPORT=n
+
+#Support for Auto channel select enhance
+HAS_AUTO_CH_SELECT_ENHANCE=n
+
+#Support statistics count
+HAS_STATS_COUNT=y
+
+#Support TSSI Antenna Variation
+HAS_TSSI_ANTENNA_VARIATION=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 USB load firmware by multibyte
+HAS_USB_FIRMWARE_MULTIBYTE_WRITE=n
+
+
+#Support ANDROID_SUPPORT
+HAS_ANDROID_SUPPORT=n
+
+#HAS_IFUP_IN_PROBE_SUPPORT
+HAS_IFUP_IN_PROBE_SUPPORT=n
+
+
+
+
+#Support TXRX SW Antenna Diversity
+HAS_TXRX_SW_ANTDIV_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_APCLI_WPA_SUPPLICANT=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=n
+
+
+#Support WIDI feature
+#Must enable HAS_WSC at the same time.
+
+HAS_TXBF_SUPPORT=n
+
+HAS_STREAM_MODE_SUPPORT=n
+
+HAS_NEW_RATE_ADAPT_SUPPORT=n
+
+HAS_RATE_ADAPT_AGS_SUPPORT=n
+
+
+
+
+#MT7601
+HAS_RX_CSO_SUPPORT=y
+
+
+HAS_WOW_SUPPORT=n
+HAS_WOW_IFDOWN_SUPPORT=n
+HAS_NEW_WOW_SUPPORT=n
+
+HAS_ANDES_FIRMWARE_SUPPORT=n
+
+HAS_HDR_TRANS_SUPPORT=n
+
+HAS_MULTI_CHANNEL=n
+
+HAS_MICROWAVE_OVEN_SUPPORT=n
+
+HAS_WIFI_P2P_CONCURRENT_FAST_SCAN=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=$(MODULE) -DRESOURCE_PRE_ALLOC
+#WFLAGS += -DFPGA_MODE
+WFLAGS += -I$(RT28xx_DIR)/include
+
+
+
+
+
+ifeq ($(HAS_WIFI_P2P_CONCURRENT_FAST_SCAN),y)
+WFLAGS += -DWIFI_P2P_CONCURRENT_FAST_SCAN
+endif
+
+ifeq ($(HAS_HE_BD_SUPPORT),y)
+WFLAGS += -DHE_BD_SUPPORT
+endif
+
+ifeq ($(HAS_KTHREAD_SUPPORT),y)
+WFLAGS += -DKTHREAD_SUPPORT
+endif
+
+ifeq ($(HAS_RTMP_FLASH_SUPPORT),y)
+WFLAGS += -DRTMP_FLASH_SUPPORT
+endif
+
+ifeq ($(HAS_STREAM_MODE_SUPPORT),y)
+WFLAGS += -DSTREAM_MODE_SUPPORT
+endif
+
+ifeq ($(HAS_SINGLE_SKU_SUPPORT),y)
+WFLAGS += -DSINGLE_SKU
+endif
+
+ifeq ($(HAS_SINGLE_SKU_V2_SUPPORT),y)
+WFLAGS += -DSINGLE_SKU_V2
+endif
+
+ifeq ($(HAS_DOT11_VHT_SUPPORT),y)
+WFLAGS += -DDOT11_VHT_AC
+endif
+
+ifeq ($(HAS_ANDES_FIRMWARE_SUPPORT),y)
+WFLAGS += -DANDES_FIRMWARE_SUPPORT
+endif
+
+ifeq ($(HAS_HDR_TRANS_SUPPORT),y)
+WFLAGS += -DHDR_TRANS_SUPPORT
+endif
+
+# config for AP mode
+
+ifeq ($(RT28xx_MODE),AP)
+#WFLAGS += -DCONFIG_AP_SUPPORT -DUAPSD_SUPPORT -DMBSS_SUPPORT -DIAPP_SUPPORT -DDBG -DDOT1X_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT
+WFLAGS += -DCONFIG_AP_SUPPORT -DUAPSD_SUPPORT -DMBSS_SUPPORT -DIAPP_SUPPORT -DDOT1X_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT
+
+ifeq ($(HAS_APCLI_WPA_SUPPLICANT),y)
+WFLAGS += -DApCli_WPA_SUPPLICANT_SUPPORT
+endif
+
+ifeq ($(HAS_HOSTAPD_SUPPORT),y)
+WFLAGS += -DHOSTAPD_SUPPORT
+endif
+
+ifeq ($(HAS_ATE),y)
+WFLAGS += -DRALINK_ATE
+WFLAGS += -DCONFIG_RT2880_ATE_CMD_NEW
+WFLAGS += -I$(RT28xx_DIR)/ate/include
+ifeq ($(HAS_QA_SUPPORT),y)
+WFLAGS += -DRALINK_QA
+endif
+endif
+
+ifeq ($(HAS_RSSI_FEEDBACK),y)
+WFLAGS += -DRSSI_FEEDBACK
+endif
+
+
+
+
+ifeq ($(HAS_WSC),y)
+WFLAGS += -DWSC_AP_SUPPORT
+
+ifeq ($(HAS_WSC_V2),y)
+WFLAGS += -DWSC_V2_SUPPORT
+endif
+ifeq ($(HAS_WSC_LED),y)
+WFLAGS += -DWSC_LED_SUPPORT
+endif
+endif
+
+
+ifeq ($(HAS_WDS),y)
+WFLAGS += -DWDS_SUPPORT
+endif
+
+ifeq ($(HAS_APCLI),y)
+WFLAGS += -DAPCLI_SUPPORT -DMAT_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT
+#ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
+#WFLAGS += -DETH_CONVERT_SUPPORT
+endif
+
+ifeq ($(HAS_IGMP_SNOOP_SUPPORT),y)
+WFLAGS += -DIGMP_SNOOP_SUPPORT
+endif
+
+ifeq ($(HAS_CS_SUPPORT),y)
+WFLAGS += -DCARRIER_DETECTION_SUPPORT
+endif
+
+ifeq ($(HAS_MCAST_RATE_SPECIFIC_SUPPORT), y)
+WFLAGS += -DMCAST_RATE_SPECIFIC
+endif
+
+ifneq ($(findstring 2860,$(CHIPSET)),)
+ifeq ($(HAS_MSI_SUPPORT),y)
+WFLAGS += -DPCI_MSI_SUPPORT
+endif
+endif
+
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+WFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+ifeq ($(HAS_SNMP_SUPPORT),y)
+WFLAGS += -DSNMP_SUPPORT
+endif
+
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+WFLAGS += -DDOT11_N_SUPPORT
+
+ifeq ($(HAS_DOT11N_DRAFT3_SUPPORT),y)
+WFLAGS += -DDOT11N_DRAFT3
+endif
+
+ifeq ($(HAS_TXBF_SUPPORT),y)
+WFLAGS += -DTXBF_SUPPORT
+endif
+
+ifeq ($(HAS_NEW_RATE_ADAPT_SUPPORT),y)
+WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+endif
+
+ifeq ($(HAS_RATE_ADAPT_AGS_SUPPORT),y)
+WFLAGS += -DAGS_SUPPORT
+endif
+
+ifeq ($(HAS_GREENAP_SUPPORT),y)
+WFLAGS += -DGREENAP_SUPPORT
+endif
+
+endif
+
+ifeq ($(HAS_AUTO_CH_SELECT_ENHANCE),y)
+WFLAGS += -DAUTO_CH_SELECT_ENHANCE
+endif
+
+ifeq ($(HAS_STATS_COUNT),y)
+WFLAGS += -DSTATS_COUNT_SUPPORT
+endif
+
+ifeq ($(HAS_TSSI_ANTENNA_VARIATION),y)
+WFLAGS += -DTSSI_ANTENNA_VARIATION
+endif
+
+ifeq ($(HAS_USB_BULK_BUF_ALIGMENT),y)
+WFLAGS += -DUSB_BULK_BUF_ALIGMENT
+endif
+
+
+ifeq ($(HAS_CFG80211_SUPPORT),y)
+WFLAGS += -DRT_CFG80211_SUPPORT -DEXT_BUILD_CHANNEL_LIST
+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_TXRX_SW_ANTDIV_SUPPORT),y)
+WFLAGS += -DTXRX_SW_ANTDIV_SUPPORT
+endif
+
+
+endif #// endif of RT2860_MODE == AP //
+
+#################################################
+
+
+#################################################
+
+#################################################
+
+#
+# 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_WAPI_SUPPORT),y)
+WFLAGS += -DWAPI_SUPPORT -DSOFT_ENCRYPT -DEXPORT_SYMTAB
+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
+
+
+ifeq ($(HAS_MICROWAVE_OVEN_SUPPORT),y)
+WFLAGS += -DMICROWAVE_OVEN_SUPPORT
+endif
+
+#################################################
+# ChipSet specific definitions.
+#
+ifneq ($(findstring 2860,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860 -DRT28xx -DA_BAND_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 3090,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT3090 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 2870,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRT28xx -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT
+CHIPSET_DAT = 2870
+endif
+
+ifneq ($(findstring 2070,$(CHIPSET)),)
+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
+
+ifneq ($(findstring 3070,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_USB -DRT30xx -DRT3070 -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 2880,$(CHIPSET)),)
+WFLAGS += -DRT2880 -DRT28xx -DRTMP_MAC_PCI -DCONFIG_RALINK_RT2880_MP -DRTMP_RBUS_SUPPORT -DMERGE_ARCH_TEAM -DA_BAND_SUPPORT -DCONFIG_SWMCU_SUPPORT
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+endif
+
+ifneq ($(findstring 3572,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRT28xx -DRT30xx -DRT35xx -DRT3572 -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 3573,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT30xx -DRT35xx -DRT3593 -DRT3573\
+ -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT\
+ -DA_BAND_SUPPORT -DDOT11N_SS3_SUPPORT \
+ -DVCORECAL_SUPPORT -DNEW_MBSSID_MODE
+#WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 3062,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT2860 -DRT28xx -DRT30xx -DRT35xx -DRT3062 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 3562,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT2860 -DRT28xx -DRT30xx -DRT35xx -DRT3562 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT
+
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 3593,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DDOT11N_SS3_SUPPORT -DRT3593 -DRT28xx -DRT30xx -DRT35xx -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DNEW_MBSSID_MODE -DVCORECAL_SUPPORT
+
+#WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+CHIPSET_DAT = 2860
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 3390,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT33xx -DRT3090 -DRT3390 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_INTERNAL_TX_ALC -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 8592,$(CHIPSET)),)
+WFLAGS += -DRT8592 -DRT65xx -DRLT_MAC -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DA_BAND_SUPPORT -DRX_DMA_SCATTER
+WFLAGS += -DRTMP_RF_RW_SUPPORT -DIQ_CAL_SUPPORT -DVCORECAL_SUPPORT
+#WFLAGS += -DRTMP_EFUSE_SUPPORT
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+# TODO: shiang-6590, need to ask hardware about the memory base setting first!!
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 6590,$(CHIPSET)),)
+WFLAGS += -DRT6590 -DRT65xx -DRLT_MAC -DRLT_RF -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DA_BAND_SUPPORT -DRX_DMA_SCATTER
+#-DRTMP_FREQ_CALIBRATION_SUPPORT -DVCORECAL_SUPPORT
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+CHIPSET_DAT = 2860
+endif
+
+
+ifneq ($(findstring 6570,$(CHIPSET)),)
+WFLAGS += -DRT6570 -DRT65xx -DRLT_MAC -DRLT_RF -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT -DRX_DMA_SCATTER -DRTMP_EFUSE_SUPPORT -DNEW_MBSSID_MODE
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+ifeq ($(HAS_CSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT
+endif
+
+ifeq ($(HAS_TSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT -DCONFIG_TSO_SUPPORT -DTX_PKT_SG
+endif
+
+CHIPSET_DAT = 2870
+endif
+
+ifneq ($(findstring 7601E,$(CHIPSET)),)
+WFLAGS += -DMT7601E -DMT7601 -DRLT_MAC -DRLT_RF -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRX_DMA_SCATTER -DVCORECAL_SUPPORT -DVCORECAL_SUPPORT -DRTMP_EFUSE_SUPPORT -DhNEW_MBSSID_MODE -DRTMP_INTERNAL_TX_ALC -DCONFIG_ANDES_SUPPORT
+#-DRTMP_FREQ_CALIBRATION_SUPPORT
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+CHIPSET_DAT = 2860
+endif
+
+
+ifneq ($(findstring 7601U,$(CHIPSET)),)
+WFLAGS += -DMT7601U -DMT7601 -DRLT_MAC -DRLT_RF -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DRX_DMA_SCATTER -DVCORECAL_SUPPORT -DRTMP_EFUSE_SUPPORT -DNEW_MBSSID_MODE -DRTMP_INTERNAL_TX_ALC -DCONFIG_ANDES_SUPPORT -DDPD_CALIBRATION_SUPPORT
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+ifeq ($(HAS_RX_CSO_SUPPORT), y)
+WFLAGS += -DCONFIG_RX_CSO_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+else
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+CHIPSET_DAT = 2870
+endif
+
+ifneq ($(findstring 3370,$(CHIPSET)),)
+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 -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 5390,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT33xx -DRT3090 -DRT3390 -DRT5390 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_FREQ_CALIBRATION_SUPPORT -DRTMP_INTERNAL_TX_ALC -DVCORECAL_SUPPORT -DIQ_CAL_SUPPORT -DNEW_MBSSID_MODE -DRTMP_TEMPERATURE_COMPENSATION -DRTMP_MAC
+CHIPSET_DAT = 2860
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 5370,$(CHIPSET)),)
+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 -DRTMP_FREQ_CALIBRATION_SUPPORT -DVCORECAL_SUPPORT -DIQ_CAL_SUPPORT -DNEW_MBSSID_MODE -DRTMP_TEMPERATURE_COMPENSATION -DRTMP_MAC
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 3052,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT3052 -DRT305x -DRTMP_RF_RW_SUPPORT -DCONFIG_SWMCU_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+endif
+
+ifneq ($(findstring 3352,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT3352 -DRT305x -DRTMP_RF_RW_SUPPORT -DVCORECAL_SUPPORT -DCONFIG_SWMCU_SUPPORT -DRTMP_INTERNAL_TX_ALC -DNEW_MBSSID_MODE
+CHIPSET_DAT = 2860
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 5350,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT5350 -DRT305x -DRT3050 -DRT3350 -DRTMP_RF_RW_SUPPORT -DVCORECAL_SUPPORT -DCONFIG_SWMCU_SUPPORT -DRTMP_INTERNAL_TX_ALC -DRTMP_FREQ_CALIBRATION_SUPPORT -DIQ_CAL_SUPPORT -DNEW_MBSSID_MODE
+CHIPSET_DAT = 2860
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 5592,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT30xx -DRT5592\
+ -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT\
+ -DA_BAND_SUPPORT -DIQ_CAL_SUPPORT -DRX_DMA_SCATTER -DVCORECAL_SUPPORT\
+ -DNEW_MBSSID_MODE -DRTMP_TEMPERATURE_COMPENSATION
+CHIPSET_DAT = 2860
+ifeq ($(HAS_CSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+endif
+
+ifneq ($(findstring 5572,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT30xx -DRT5572 -DRT5592\
+ -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DNEW_MBSSID_MODE\
+ -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT -DIQ_CAL_SUPPORT -DVCORECAL_SUPPORT\
+ -DRTMP_TEMPERATURE_COMPENSATION
+CHIPSET_DAT = 2870
+ifeq ($(HAS_CSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+endif
+
+ifneq ($(findstring 3290,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_FREQ_CALIBRATION_SUPPORT -DRTMP_INTERNAL_TX_ALC -DRT30xx -DRT3290 -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT -DPCIE_PS_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+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
+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
+endif
+
+
+ifeq ($(CHIPSET),RBUS)
+WFLAGS += -DMERGE_ARCH_TEAM -DCONFIG_SWMCU_SUPPORT -DCONFIG_RA_NAT_NONE -DRTMP_RBUS_SUPPORT
+#5350, 3050, 3350, 3883
+WFLAGS +=-DRTMP_MAC_PCI -DRT305x -DRT5350 -DRT3050 -DRT3350 -DRT3883 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+#WFLAGS += -DDBG_CTRL_SUPPORT
+#WFLAGS += -DINCLUDE_DEBUG_QUEUE
+#WFLAGS += -DRANGE_EXTEND -DCFO_TRACK -DPRE_ANT_SWITCH
+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),UBICOM_IPX8)
+WFLAGS += -DRT_BIG_ENDIAN -DUNALIGNMENT_SUPPORT -DPLATFORM_UBM_IPX8 -DNO_CONSISTENT_MEM_SUPPORT -DCACHE_LINE_32B
+endif
+
+ifeq ($(PLATFORM),BL2348)
+WFLAGS += -DRT_BIG_ENDIAN
+endif
+
+ifeq ($(PLATFORM),BL23570)
+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 -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 -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 -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),UBICOM_IPX8)
+EXTRA_CFLAGS += $(WFLAGS)
+export EXTRA_CFLAGS
+endif
+
+ifeq ($(PLATFORM),SIGMA)
+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 -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 -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 -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 -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 -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 -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 := $(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 := $(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 := $(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 := $(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) -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 -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 -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 -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)
+ endif
+endif
+
+ifeq ($(PLATFORM),INTELP6)
+ EXTRA_CFLAGS := $(WFLAGS)
+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 -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 -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 -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) -mbig-endian
+ export CFLAGS
+endif
+
+ifeq ($(PLATFORM),SMDK)
+ EXTRA_CFLAGS := $(WFLAGS)
+endif
+
+ifeq ($(PLATFORM),CAVM_OCTEON)
+ EXTRA_CFLAGS := $(WFLAGS) -mabi=64 $(WFLAGS)
+export CFLAGS
+endif
+
+ifeq ($(PLATFORM),DM6446)
+ CFLAGS := -nostdinc -iwithprefix include -D__KERNEL__ -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$(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),BL23570)
+EXTRA_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 -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=74kc -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS) -DSIGMA863X_PLATFORM -DEXPORT_SYMTAB -DPLATFORM_BL23570
+export EXTRA_CFLAGS
+endif
+
+ifeq ($(PLATFORM),BLUBB)
+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 -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$(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 -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) -DMT85XX
+ 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_INT16_ \
+ -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 -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)
+ endif
+endif
+
+ifeq ($(PLATFORM),MVL5)
+CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/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 -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),MT7620)
+ EXTRA_CFLAGS := $(WFLAGS)
+endif
+
+ifeq ($(PLATFORM),MSTARPLC)
+EXTRA_CFLAGS += $(WFLAGS) -I$(RT28xx_DIR)/include
+export EXTRA_CFLAGS
+endif
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/config.mk.bak b/cleopatre/devkit/mt7601udrv/os/linux/config.mk.bak
new file mode 100644
index 0000000000..d2643e27cb
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/config.mk.bak
@@ -0,0 +1,1637 @@
+# Support ATE function
+HAS_ATE=n
+
+# Support QA ATE function
+HAS_QA_SUPPORT=n
+
+#ifdef RSSI_FEEDBACK
+HAS_RSSI_FEEDBACK=n
+#endif // RSSI_FEEDBACK //
+
+#ifdef XLINK_SUPPORT
+# Support XLINK mode
+HAS_XLINK=n
+#endif // XLINK_SUPPORT //
+
+#ifdef WSC_INCLUDED
+# Support WSC function
+HAS_WSC=n
+#ifdef WSC_V2_SUPPORT
+HAS_WSC_V2=n
+#endif // WSC_V2_SUPPORT //
+HAS_WSC_LED=n
+#ifdef IWSC_SUPPORT
+HAS_IWSC_SUPPORT=n
+#endif // IWSC_SUPPORT //
+#endif // WSC_INCLUDED //
+
+#ifdef NINTENDO_AP
+HAS_NINTENDO=n
+#endif // NINTENDO_AP //
+
+# Support LLTD function
+HAS_LLTD=n
+
+#ifdef WDS_SUPPORT
+# Support WDS function
+HAS_WDS=n
+#endif // WDS_SUPPORT //
+
+#ifdef APCLI_SUPPORT
+# Support AP-Client function
+HAS_APCLI=n
+#endif // APCLI_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+# Support Wpa_Supplicant
+# i.e. wpa_supplicant -Dralink
+HAS_WPA_SUPPLICANT=n
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+# Support Native WpaSupplicant for Network Maganger
+# i.e. wpa_supplicant -Dwext
+HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#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
+
+#ifdef ETH_CONVERT_SUPPORT
+# Support for STA Ethernet Converter
+HAS_ETH_CONVERT_SUPPORT=n
+#endif // ETH_CONVERT_SUPPORT //
+
+# Support user specific transmit rate of Multicast packet.
+HAS_MCAST_RATE_SPECIFIC_SUPPORT=n
+
+#ifdef MULTI_CARD
+# Support for Multiple Cards
+HAS_MC_SUPPORT=n
+#endif // MULTI_CARD //
+
+#Support for PCI-MSI
+HAS_MSI_SUPPORT=n
+
+#ifdef WMM_ACM_SUPPORT
+# Support for WMM ACM v1.1
+HAS_WMM_ACM_SUPPORT=n
+#endif // WMM_ACM_SUPPORT //
+
+#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
+
+#ifdef MESH_SUPPORT
+#Support for MESH
+HAS_MESH_SUPPORT=n
+#endif // MESH_SUPPORT //
+
+#Support for Net-SNMP
+HAS_SNMP_SUPPORT=n
+
+#ifdef DOT11N_DRAFT3
+#Support features of 802.11n Draft3
+HAS_DOT11N_DRAFT3_SUPPORT=n
+#endif // DOT11N_DRAFT3 //
+
+#Support features of Single SKU.
+HAS_SINGLE_SKU_SUPPORT=n
+
+#ifdef DOT11_N_SUPPORT
+#Support features of 802.11n
+HAS_DOT11_N_SUPPORT=y
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DOT11_VHT_SUPPORT
+#Support for 802.11ac VHT
+HAS_DOT11_VHT_SUPPORT=y
+#endif // DOT11_VHT_SUPPORT //
+
+#ifdef WAPI_SUPPORT
+#Support for WAPI
+HAS_WAPI_SUPPORT=n
+#endif // WAPI_SUPPORT //
+
+#ifdef DOT11R_FT_SUPPORT
+#Support for dot11r FT
+HAS_DOT11R_FT_SUPPORT=n
+#endif // DOT11R_FT_SUPPORT //
+
+#Support for 2860/2880 co-exist
+HAS_RT2880_RT2860_COEXIST=n
+
+HAS_KTHREAD_SUPPORT=n
+
+#ifdef DOT11K_RRM_SUPPORT
+#Support for dot11k RRM
+HAS_DOT11K_RRM_SUPPORT=n
+#endif // DOT11K_RRM_SUPPORT //
+
+#ifdef DOT11V_WNM_SUPPORT
+#Support for dot 11v WNM
+HAS_DOT11V_WNM_SUPPORT=n
+#endif // DOT11V_WNM_SUPPORT //
+
+#ifdef DOT11Z_TDLS_SUPPORT
+#Support for dot11z TDLS
+HAS_DOT11Z_TDLS_SUPPORT=n
+#endif // DOT11Z_TDLS_SUPPORT //
+
+#ifdef P2P_SUPPORT
+#Support for WiFi-Driect(Peer to Peer)
+HAS_P2P_SUPPORT=n
+HAS_P2P_ODD_MAC_ADJUST=n
+HAS_P2P_SPECIFIC_WIRELESS_EVENT=n
+#endif // P2P_SUPPORT //
+
+#Support for Auto channel select enhance
+HAS_AUTO_CH_SELECT_ENHANCE=n
+
+#Support statistics count
+HAS_STATS_COUNT=y
+
+#Support TSSI Antenna Variation
+HAS_TSSI_ANTENNA_VARIATION=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 USB load firmware by multibyte
+HAS_USB_FIRMWARE_MULTIBYTE_WRITE=n
+
+
+#Support ANDROID_SUPPORT
+HAS_ANDROID_SUPPORT=n
+
+#HAS_IFUP_IN_PROBE_SUPPORT
+HAS_IFUP_IN_PROBE_SUPPORT=n
+
+
+#ifdef DOT11W_PMF_SUPPORT
+#Support for dot11w Protected Management Frame
+HAS_DOT11W_PMF_SUPPORT=n
+#endif // DOT11W_PMF_SUPPORT //
+
+#ifdef ANT_DIVERSITY_SUPPORT
+#Support Antenna Diversity
+HAS_ANTENNA_DIVERSITY_SUPPORT=n
+#endif // ANT_DIVERSITY_SUPPORT //
+
+#ifdef TXRX_SW_ANTDIV_SUPPORT
+#Support TXRX SW Antenna Diversity
+HAS_TXRX_SW_ANTDIV_SUPPORT=n
+#endif // TXRX_SW_ANTDIV_SUPPORT //
+
+#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
+
+#ifdef EASY_CONFIG_SETUP
+HAS_EASY_CONFIG_SETUP_SUPPORT=n
+#endif // EASY_CONFIG_SETUP //
+
+#ifdef RELEASE_EXCLUDE
+#Support GPL Cryptography
+HAS_GPL_ALGORITHM_SUPPORT=n
+
+#ifdef HW_COEXISTENCE_SUPPORT
+HAS_HW_COEXISTENCE_SUPPORT=n
+#endif // HW_COEXISTENCE_SUPPORT //
+
+#ifdef BT_COEXISTENCE_SUPPORT
+HAS_BT_COEXISTENCE_SUPPORT=n
+#endif // BT_COEXISTENCE_SUPPORT //
+#endif //RELEASE_EXCLUDE //
+
+HAS_APCLI_WPA_SUPPLICANT=n
+
+HAS_RTMP_FLASH_SUPPORT=n
+
+#ifdef OS_ABL_FUNC_SUPPORT
+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
+#endif // OS_ABL_FUNC_SUPPORT //
+
+#ifdef LED_CONTROL_SUPPORT
+HAS_LED_CONTROL_SUPPORT=y
+#endif // LED_CONTROL_SUPPORT //
+
+#ifdef CONFIG_WIFI_LED_SHARE
+HAS_WIFI_LED_SHARE=n
+#endif // CONFIG_WIFI_LED_SHARE //
+
+#Support WIDI feature
+#Must enable HAS_WSC at the same time.
+#ifdef WIDI_SUPPORT
+HAS_WIDI_SUPPORT=n
+HAS_INTEL_WFD_SUPPORT=n
+HAS_WFA_WFD_SUPPORT=n
+#endif // HAS_WIDI_SUPPORT //
+
+#ifdef TXBF_SUPPORT
+HAS_TXBF_SUPPORT=n
+#endif // TXBF_SUPPORT //
+
+#ifdef STREAM_MODE_SUPPORT
+HAS_STREAM_MODE_SUPPORT=n
+#endif // STREAM_MODE_SUPPORT //
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+HAS_NEW_RATE_ADAPT_SUPPORT=n
+#endif // NEW_RATE_ADAPT_SUPPORT //
+
+#ifdef DPA_S
+HAS_DPA_S_SUPPORT=n
+#endif
+
+#ifdef DPA_T
+HAS_DPA_T_SUPPORT=n
+#endif
+
+#ifdef CONFIG_CSO_SUPPORT
+#RT5572 RT5592
+HAS_CSO_SUPPORT=y
+#endif
+
+#ifdef CONFIG_TSO_SUPPORT
+#RT6590 RT6570
+HAS_TSO_SUPPORT=y
+#endif
+
+#ifdef WOW_SUPPORT
+HAS_WOW_SUPPORT=n
+HAS_WOW_IFDOWN_SUPPORT=n
+#endif
+
+#################################################
+
+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=$(MODULE) -DRESOURCE_PRE_ALLOC
+#WFLAGS += -DFPGA_MODE
+WFLAGS += -I$(RT28xx_DIR)/include
+
+#ifdef DPA_S
+ifeq ($(HAS_DPA_S_SUPPORT),y)
+WFLAGS += -DDPA_S
+endif
+#endif
+
+#ifdef DPA_T
+ifeq ($(HAS_DPA_T_SUPPORT),y)
+WFLAGS += -DDPA_T
+endif
+#endif
+
+#ifdef RELEASE_EXCLUDE
+#removed for building in RT3052 ApSoc SDK
+ifneq ($(PLATFORM),RALINK_3052)
+ifneq ($(PLATFORM),DM6446)
+#WFLAGS += -Wpointer-sign
+endif
+endif
+#endif // RELEASE_EXCLUDE //
+
+#ifdef RELEASE_EXCLUDE
+ifeq ($(HAS_GPL_ALGORITHM_SUPPORT),y)
+WFLAGS += -DCRYPT_GPL_ALGORITHM
+endif
+#endif // RELEASE_EXCLUDE //
+
+
+ifeq ($(HAS_KTHREAD_SUPPORT),y)
+WFLAGS += -DKTHREAD_SUPPORT
+endif
+
+ifeq ($(HAS_RTMP_FLASH_SUPPORT),y)
+WFLAGS += -DRTMP_FLASH_SUPPORT
+endif
+
+ifeq ($(HAS_STREAM_MODE_SUPPORT),y)
+WFLAGS += -DSTREAM_MODE_SUPPORT
+endif
+
+ifeq ($(HAS_SINGLE_SKU_SUPPORT),y)
+WFLAGS += -DSINGLE_SKU
+endif
+
+ifeq ($(HAS_DOT11_VHT_SUPPORT),y)
+WFLAGS += -DDOT11_VHT_SUPPORT
+endif
+
+
+#ifdef CONFIG_AP_SUPPORT
+# config for AP mode
+
+ifeq ($(RT28xx_MODE),AP)
+WFLAGS += -DCONFIG_AP_SUPPORT -DUAPSD_SUPPORT -DMBSS_SUPPORT -DIAPP_SUPPORT -DDBG -DDOT1X_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT
+
+ifeq ($(HAS_APCLI_WPA_SUPPLICANT),y)
+WFLAGS += -DApCli_WPA_SUPPLICANT_SUPPORT
+endif
+
+ifeq ($(HAS_HOSTAPD_SUPPORT),y)
+WFLAGS += -DHOSTAPD_SUPPORT
+endif
+
+ifeq ($(HAS_ATE),y)
+WFLAGS += -DRALINK_ATE
+WFLAGS += -DCONFIG_RT2880_ATE_CMD_NEW
+WFLAGS += -I$(RT28xx_DIR)/ate/include
+ifeq ($(HAS_QA_SUPPORT),y)
+WFLAGS += -DRALINK_QA
+endif
+endif
+
+#ifdef RSSI_FEEDBACK
+ifeq ($(HAS_RSSI_FEEDBACK),y)
+WFLAGS += -DRSSI_FEEDBACK
+endif
+#endif // RSSI_FEEDBACK //
+
+#ifdef GEMTEK_ATE
+ifeq ($(RELEASE), DPB)
+WFLAGS += -DGEMTEK_ATE
+endif
+#endif // GEMTEK_ATE //
+
+
+#ifdef NINTENDO_AP
+ifeq ($(HAS_NINTENDO),y)
+WFLAGS += -DNINTENDO_AP
+endif
+#endif // NINTENDO_AP //
+
+#ifdef WSC_INCLUDED
+ifeq ($(HAS_WSC),y)
+WFLAGS += -DWSC_AP_SUPPORT
+
+ifeq ($(HAS_WSC_V2),y)
+WFLAGS += -DWSC_V2_SUPPORT
+endif
+ifeq ($(HAS_WSC_LED),y)
+WFLAGS += -DWSC_LED_SUPPORT
+endif
+endif
+#endif // WSC_INCLUDED //
+
+#ifdef EASY_CONFIG_SETUP
+ifeq ($(HAS_EASY_CONFIG_SETUP_SUPPORT),y)
+WFLAGS += -DEASY_CONFIG_SETUP -DWAC_SUPPORT
+endif
+#endif // EASY_CONFIG_SETUP //
+
+#ifdef WDS_SUPPORT
+ifeq ($(HAS_WDS),y)
+WFLAGS += -DWDS_SUPPORT
+endif
+#endif // WDS_SUPPORT //
+
+#ifdef APCLI_SUPPORT
+ifeq ($(HAS_APCLI),y)
+WFLAGS += -DAPCLI_SUPPORT -DMAT_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT
+#ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
+#WFLAGS += -DETH_CONVERT_SUPPORT
+#endif
+endif
+#endif // APCLI_SUPPORT //
+
+ifeq ($(HAS_IGMP_SNOOP_SUPPORT),y)
+WFLAGS += -DIGMP_SNOOP_SUPPORT
+endif
+
+ifeq ($(HAS_CS_SUPPORT),y)
+WFLAGS += -DCARRIER_DETECTION_SUPPORT
+endif
+
+ifeq ($(HAS_MCAST_RATE_SPECIFIC_SUPPORT), y)
+WFLAGS += -DMCAST_RATE_SPECIFIC
+endif
+
+ifneq ($(findstring 2860,$(CHIPSET)),)
+ifeq ($(HAS_MSI_SUPPORT),y)
+WFLAGS += -DPCI_MSI_SUPPORT
+endif
+endif
+
+#ifdef WMM_ACM_SUPPORT
+ifeq ($(HAS_WMM_ACM_SUPPORT),y)
+WFLAGS += -DWMM_ACM_SUPPORT
+endif
+#endif // WMM_ACM_SUPPORT //
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+WFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+ifeq ($(HAS_SNMP_SUPPORT),y)
+WFLAGS += -DSNMP_SUPPORT
+endif
+
+#ifdef DOT11_N_SUPPORT
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+WFLAGS += -DDOT11_N_SUPPORT
+
+#ifdef DOT11N_DRAFT3
+ifeq ($(HAS_DOT11N_DRAFT3_SUPPORT),y)
+WFLAGS += -DDOT11N_DRAFT3
+endif
+#endif // DOT11N_DRAFT3 //
+
+#ifdef TXBF_SUPPORT
+ifeq ($(HAS_TXBF_SUPPORT),y)
+WFLAGS += -DTXBF_SUPPORT
+endif
+#endif // TXBF_SUPPORT //
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ifeq ($(HAS_NEW_RATE_ADAPT_SUPPORT),y)
+WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+endif
+#endif // NEW_RATE_ADAPT_SUPPORT //
+
+ifeq ($(HAS_GREENAP_SUPPORT),y)
+WFLAGS += -DGREENAP_SUPPORT
+endif
+
+endif
+#endif // DOT11_N_SUPPORT //
+
+ifeq ($(HAS_AUTO_CH_SELECT_ENHANCE),y)
+WFLAGS += -DAUTO_CH_SELECT_ENHANCE
+endif
+
+ifeq ($(HAS_STATS_COUNT),y)
+WFLAGS += -DSTATS_COUNT_SUPPORT
+endif
+
+ifeq ($(HAS_TSSI_ANTENNA_VARIATION),y)
+WFLAGS += -DTSSI_ANTENNA_VARIATION
+endif
+
+ifeq ($(HAS_USB_BULK_BUF_ALIGMENT),y)
+WFLAGS += -DUSB_BULK_BUF_ALIGMENT
+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
+
+#ifdef ANT_DIVERSITY_SUPPORT
+ifeq ($(HAS_ANTENNA_DIVERSITY_SUPPORT),y)
+WFLAGS += -DANT_DIVERSITY_SUPPORT
+endif
+#endif // ANT_DIVERSITY_SUPPORT //
+
+#ifdef TXRX_SW_ANTDIV_SUPPORT
+ifeq ($(HAS_TXRX_SW_ANTDIV_SUPPORT),y)
+WFLAGS += -DTXRX_SW_ANTDIV_SUPPORT
+endif
+#endif // TXRX_SW_ANTDIV_SUPPORT //
+
+#ifdef RELEASE_EXCLUDE
+#ifdef HW_COEXISTENCE_SUPPORT
+ifeq ($(HAS_HW_COEXISTENCE_SUPPORT),y)
+WFLAGS += -DHW_COEXISTENCE_SUPPORT
+endif
+#endif // HW_COEXISTENCE_SUPPORT //
+#endif //RELEASE_EXCLUDE //
+
+endif #// endif of RT2860_MODE == AP //
+#endif // CONFIG_AP_SUPPORT //
+
+#################################################
+
+#ifdef CONFIG_STA_SUPPORT
+# config for STA mode
+
+ifeq ($(RT28xx_MODE),STA)
+WFLAGS += -DCONFIG_STA_SUPPORT -DSCAN_SUPPORT -DDBG
+
+#ifdef XLINK_SUPPORT
+ifeq ($(HAS_XLINK),y)
+WFLAGS += -DXLINK_SUPPORT
+endif
+#endif // XLINK_SUPPORT //
+
+#ifdef ADHOC_WPA2PSK_SUPPORT
+WFLAGS += -DADHOC_WPA2PSK_SUPPORT
+#endif // ADHOC_WPA2PSK_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ifeq ($(HAS_WPA_SUPPLICANT),y)
+WFLAGS += -DWPA_SUPPLICANT_SUPPORT
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
+WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
+endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+endif
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef WSC_INCLUDED
+ifeq ($(HAS_WSC),y)
+WFLAGS += -DWSC_STA_SUPPORT
+ifeq ($(HAS_WSC_V2),y)
+WFLAGS += -DWSC_V2_SUPPORT
+endif
+ifeq ($(HAS_WSC_LED),y)
+WFLAGS += -DWSC_LED_SUPPORT
+endif
+ifeq ($(HAS_IWSC_SUPPORT),y)
+WFLAGS += -DIWSC_SUPPORT
+endif
+endif
+#endif // WSC_INCLUDED //
+
+#ifdef STA_EASY_CONFIG_SETUP
+ifeq ($(HAS_WSC),y)
+ifeq ($(HAS_EASY_CONFIG_SETUP_SUPPORT),y)
+WFLAGS += -DEASY_CONFIG_SETUP -DSTA_EASY_CONFIG_SETUP -DWAC_SUPPORT
+endif
+endif
+#endif // STA_EASY_CONFIG_SETUP //
+
+#ifdef ETH_CONVERT_SUPPORT
+ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
+WFLAGS += -DETH_CONVERT_SUPPORT -DMAT_SUPPORT
+endif
+#endif // ETH_CONVERT_SUPPORT //
+
+ifeq ($(HAS_ATE),y)
+WFLAGS += -DRALINK_ATE
+WFLAGS += -DCONFIG_RT2880_ATE_CMD_NEW
+WFLAGS += -I$(RT28xx_DIR)/ate/include
+ifeq ($(HAS_QA_SUPPORT),y)
+WFLAGS += -DRALINK_QA
+endif
+endif
+
+#ifdef WMM_ACM_SUPPORT
+ifeq ($(HAS_WMM_ACM_SUPPORT),y)
+WFLAGS += -DWMM_ACM_SUPPORT
+endif
+#endif // WMM_ACM_SUPPORT //
+
+ifeq ($(HAS_SNMP_SUPPORT),y)
+WFLAGS += -DSNMP_SUPPORT
+endif
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+WFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+#ifdef DOT11_N_SUPPORT
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+WFLAGS += -DDOT11_N_SUPPORT
+
+#ifdef DOT11N_DRAFT3
+ifeq ($(HAS_DOT11N_DRAFT3_SUPPORT),y)
+WFLAGS += -DDOT11N_DRAFT3
+endif
+#endif // DOT11N_DRAFT3 //
+
+#ifdef TXBF_SUPPORT
+ifeq ($(HAS_TXBF_SUPPORT),y)
+WFLAGS += -DTXBF_SUPPORT
+endif
+#endif // TXBF_SUPPORT //
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ifeq ($(HAS_NEW_RATE_ADAPT_SUPPORT),y)
+WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+endif
+#endif // NEW_RATE_ADAPT_SUPPORT //
+
+endif
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DOT11Z_TDLS_SUPPORT
+ifeq ($(HAS_DOT11Z_TDLS_SUPPORT),y)
+WFLAGS += -DDOT11Z_TDLS_SUPPORT
+endif
+#endif // DOT11Z_TDLS_SUPPORT //
+
+#ifdef P2P_SUPPORT
+ifeq ($(HAS_P2P_SUPPORT),y)
+WFLAGS += -DP2P_SUPPORT -DAPCLI_SUPPORT -DMAT_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT -DP2P_APCLI_SUPPORT -DCONFIG_AP_SUPPORT -DCONFIG_APSTA_MIXED_SUPPORT -DUAPSD_SUPPORT -DMBSS_SUPPORT -DIAPP_SUPPORT -DDOT1X_SUPPORT -DWSC_AP_SUPPORT -DWSC_STA_SUPPORT
+endif
+
+ifeq ($(HAS_P2P_ODD_MAC_ADJUST),y)
+WFLAGS += -DP2P_ODD_MAC_ADJUST
+endif
+
+ifeq ($(HAS_P2P_SPECIFIC_WIRELESS_EVENT),y)
+WFLAGS += -DRT_P2P_SPECIFIC_WIRELESS_EVENT
+endif
+#endif // P2P_SUPPORT //
+
+ifeq ($(HAS_CS_SUPPORT),y)
+WFLAGS += -DCARRIER_DETECTION_SUPPORT
+endif
+
+ifeq ($(HAS_STATS_COUNT),y)
+WFLAGS += -DSTATS_COUNT_SUPPORT
+endif
+
+ifeq ($(HAS_TSSI_ANTENNA_VARIATION),y)
+WFLAGS += -DTSSI_ANTENNA_VARIATION
+endif
+
+ifeq ($(HAS_ANDROID_SUPPORT),y)
+WFLAGS += -DANDROID_SUPPORT
+endif
+
+
+ifeq ($(HAS_IFUP_IN_PROBE_SUPPORT),y)
+WFLAGS += -DIFUP_IN_PROBE
+endif
+
+ifeq ($(HAS_USB_SUPPORT_SELECTIVE_SUSPEND),y)
+WFLAGS += -DUSB_SUPPORT_SELECTIVE_SUSPEND
+endif
+
+ifeq ($(HAS_USB_FIRMWARE_MULTIBYTE_WRITE),y)
+WFLAGS += -DUSB_FIRMWARE_MULTIBYTE_WRITE -DMULTIWRITE_BYTES=4
+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
+
+#ifdef ANT_DIVERSITY_SUPPORT
+ifeq ($(HAS_ANTENNA_DIVERSITY_SUPPORT),y)
+WFLAGS += -DANT_DIVERSITY_SUPPORT
+endif
+#endif // ANT_DIVERSITY_SUPPORT //
+
+#ifdef TXRX_SW_ANTDIV_SUPPORT
+ifeq ($(HAS_TXRX_SW_ANTDIV_SUPPORT),y)
+WFLAGS += -DTXRX_SW_ANTDIV_SUPPORT
+endif
+#endif // TXRX_SW_ANTDIV_SUPPORT //
+
+#ifdef RELEASE_EXCLUDE
+#ifdef HW_COEXISTENCE_SUPPORT
+ifeq ($(HAS_HW_COEXISTENCE_SUPPORT),y)
+WFLAGS += -DHW_COEXISTENCE_SUPPORT
+endif
+#endif // HW_COEXISTENCE_SUPPORT //
+
+#ifdef BT_COEXISTENCE_SUPPORT
+ifeq ($(HAS_BT_COEXISTENCE_SUPPORT),y)
+WFLAGS += -DHW_COEXISTENCE_SUPPORT -DBT_COEXISTENCE_SUPPORT
+endif
+#endif // BT_COEXISTENCE_SUPPORT //
+#endif //RELEASE_EXCLUDE //
+
+ifeq ($(HAS_WIDI_SUPPORT),y)
+WFLAGS += -DWIDI_SUPPORT
+
+ifeq ($(HAS_P2P_SUPPORT),y)
+ifeq ($(HAS_INTEL_WFD_SUPPORT),y)
+WFLAGS += -DINTEL_WFD_SUPPORT
+endif
+
+ifeq ($(HAS_WFA_WFD_SUPPORT),y)
+WFLAGS += -DWFA_WFD_SUPPORT
+endif
+endif
+
+endif
+
+#ifdef WOW_SUPPORT
+ifeq ($(HAS_WOW_SUPPORT),y)
+WFLAGS += -DWOW_SUPPORT
+endif
+#endif // WOW_SUPPORT //
+
+#ifdef WOW_IFDOWN_SUPPORT
+ifeq ($(HAS_WOW_IFDOWN_SUPPORT),y)
+WFLAGS += -DWOW_IFDOWN_SUPPORT
+endif
+#endif // WOW_IFDOWN_SUPPORT //
+
+endif
+# endif of ifeq ($(RT28xx_MODE),STA)
+#endif // CONFIG_STA_SUPPORT //
+
+#################################################
+
+#ifdef CONFIG_APSTA_SUPPORT
+# config for APSTA
+
+ifeq ($(RT28xx_MODE),APSTA)
+WFLAGS += -DCONFIG_AP_SUPPORT -DCONFIG_STA_SUPPORT -DCONFIG_APSTA_MIXED_SUPPORT -DUAPSD_SUPPORT -DMBSS_SUPPORT -DIAPP_SUPPORT -DDOT1X_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT -DDBG
+
+#ifdef NINTENDO_AP
+ifeq ($(HAS_NINTENDO),y)
+WFLAGS += -DNINTENDO_AP
+endif
+#endif // NINTENDO_AP //
+
+#ifdef WSC_INCLUDED
+ifeq ($(HAS_WSC),y)
+WFLAGS += -DWSC_AP_SUPPORT -DWSC_STA_SUPPORT
+endif
+#endif // WSC_INCLUDED //
+
+#ifdef WDS_SUPPORT
+ifeq ($(HAS_WDS),y)
+WFLAGS += -DWDS_SUPPORT
+endif
+#endif // WDS_SUPPORT //
+
+#ifdef APCLI_SUPPORT
+ifeq ($(HAS_APCLI),y)
+WFLAGS += -DAPCLI_SUPPORT -DMAT_SUPPORT
+endif
+#endif // APCLI_SUPPORT //
+
+ifeq ($(HAS_IGMP_SNOOP_SUPPORT),y)
+WFLAGS += -DIGMP_SNOOP_SUPPORT
+endif
+
+ifeq ($(HAS_CS_SUPPORT),y)
+WFLAGS += -DCARRIER_DETECTION_SUPPORT
+endif
+
+ifeq ($(HAS_MCAST_RATE_SPECIFIC_SUPPORT), y)
+WFLAGS += -DMCAST_RATE_SPECIFIC
+endif
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+WFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ifeq ($(HAS_WPA_SUPPLICANT),y)
+WFLAGS += -DWPA_SUPPLICANT_SUPPORT
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
+WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
+endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+endif
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef ETH_CONVERT_SUPPORT
+ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
+WFLAGS += -DETH_CONVERT_SUPPORT -DMAT_SUPPORT
+endif
+#endif // ETH_CONVERT_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+WFLAGS += -DDOT11_N_SUPPORT
+endif
+
+#ifdef TXBF_SUPPORT
+ifeq ($(HAS_TXBF_SUPPORT),y)
+WFLAGS += -DTXBF_SUPPORT
+endif
+#endif // TXBF_SUPPORT //
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ifeq ($(HAS_NEW_RATE_ADAPT_SUPPORT),y)
+WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+endif
+#endif // NEW_RATE_ADAPT_SUPPORT //
+
+#endif // DOT11_N_SUPPORT //
+
+ifeq ($(HAS_CS_SUPPORT),y)
+WFLAGS += -DCARRIER_DETECTION_SUPPORT
+endif
+
+ifeq ($(HAS_STATS_COUNT),y)
+WFLAGS += -DSTATS_COUNT_SUPPORT
+endif
+
+ifeq ($(HAS_TSSI_ANTENNA_VARIATION),y)
+WFLAGS += -DTSSI_ANTENNA_VARIATION
+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_P2P_SUPPORT),y)
+WFLAGS += -DP2P_SUPPORT
+WFLAGS += -DAPCLI_SUPPORT -DMAT_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT -DP2P_APCLI_SUPPORT
+endif
+
+endif
+# endif of ifeq ($(RT28xx_MODE),APSTA)
+#endif // CONFIG_APSTA_SUPPORT //
+#################################################
+
+#
+# Common compiler flag
+#
+
+#ifdef RELEASE_EXCLUDE
+#Remove internal debug code when offical release
+WFLAGS += -DRELEASE_EXCLUDE
+#endif // RELEASE_EXCLUDE //
+
+#ifdef MESH_SUPPORT
+ifeq ($(HAS_MESH_SUPPORT),y)
+WFLAGS += -DMESH_SUPPORT -DINTEL_CMPC -DAP_SCAN_SUPPORT -DSCAN_SUPPORT
+endif
+#endif // MESH_SUPPORT //
+
+#ifdef DOT11R_FT_SUPPORT
+ifeq ($(HAS_DOT11R_FT_SUPPORT),y)
+WFLAGS += -DDOT11R_FT_SUPPORT
+endif
+#endif // DOT11R_FT_SUPPORT //
+
+#ifdef DOT11K_RRM_SUPPORT
+ifeq ($(HAS_DOT11K_RRM_SUPPORT),y)
+WFLAGS += -DDOT11K_RRM_SUPPORT -DAP_SCAN_SUPPORT -DSCAN_SUPPORT
+endif
+#endif // DOT11K_RRM_SUPPORT //
+
+#ifdef DOT11V_WNM_SUPPORT
+ifeq ($(HAS_DOT11V_WNM_SUPPORT),y)
+WFLAGS += -DDOT11V_WNM_SUPPORT
+endif
+#endif // DOT11V_WNM_SUPPORT //
+
+ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
+WFLAGS += -DEXT_BUILD_CHANNEL_LIST
+endif
+
+ifeq ($(HAS_IDS_SUPPORT),y)
+WFLAGS += -DIDS_SUPPORT
+endif
+
+#ifdef WAPI_SUPPORT
+ifeq ($(HAS_WAPI_SUPPORT),y)
+WFLAGS += -DWAPI_SUPPORT -DSOFT_ENCRYPT -DEXPORT_SYMTAB
+endif
+#endif // WAPI_SUPPORT //
+
+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
+
+#ifdef DOT11W_PMF_SUPPORT
+ifeq ($(HAS_DOT11W_PMF_SUPPORT),y)
+WFLAGS += -DDOT11W_PMF_SUPPORT -DSOFT_ENCRYPT
+endif
+#endif // DOT11W_PMF_SUPPORT //
+
+#ifdef LED_CONTROL_SUPPORT
+ifeq ($(HAS_LED_CONTROL_SUPPORT),y)
+WFLAGS += -DLED_CONTROL_SUPPORT
+endif
+#endif // LED_CONTROL_SUPPORT //
+
+#################################################
+# ChipSet specific definitions.
+#
+ifneq ($(findstring 2860,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860 -DRT28xx -DA_BAND_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 3090,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT3090 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 2870,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRT28xx -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT
+CHIPSET_DAT = 2870
+endif
+
+ifneq ($(findstring 2070,$(CHIPSET)),)
+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
+
+ifneq ($(findstring 3070,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_USB -DRT30xx -DRT3070 -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 2880,$(CHIPSET)),)
+WFLAGS += -DRT2880 -DRT28xx -DRTMP_MAC_PCI -DCONFIG_RALINK_RT2880_MP -DRTMP_RBUS_SUPPORT -DMERGE_ARCH_TEAM -DA_BAND_SUPPORT -DCONFIG_SWMCU_SUPPORT
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+endif
+
+ifneq ($(findstring 3572,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRT28xx -DRT30xx -DRT35xx -DRT3572 -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 3573,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT30xx -DRT35xx -DRT3593 -DRT3573\
+ -DRTMP_TIMER_TASK_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT\
+ -DA_BAND_SUPPORT -DDOT11N_SS3_SUPPORT \
+ -DVCORECAL_SUPPORT -DNEW_MBSSID_MODE
+#WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 3062,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT2860 -DRT28xx -DRT30xx -DRT35xx -DRT3062 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 3562,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT2860 -DRT28xx -DRT30xx -DRT35xx -DRT3562 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT
+
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 3593,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DDOT11N_SS3_SUPPORT -DRT3593 -DRT28xx -DRT30xx -DRT35xx -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DA_BAND_SUPPORT -DNEW_MBSSID_MODE -DVCORECAL_SUPPORT
+
+#WFLAGS += -DNEW_RATE_ADAPT_SUPPORT
+CHIPSET_DAT = 2860
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 3390,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT33xx -DRT3090 -DRT3390 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_INTERNAL_TX_ALC -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 8592,$(CHIPSET)),)
+WFLAGS += -DRT8592 -DRT65xx -DRLT_MAC -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DA_BAND_SUPPORT -DRX_DMA_SCATTER
+WFLAGS += -DRTMP_EFUSE_SUPPORT -DRTMP_RF_RW_SUPPORT
+WFLAGS += -DDOT11_VHT_SUPPORT
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+CHIPSET_DAT = 2860
+endif
+
+ifneq ($(findstring 6590,$(CHIPSET)),)
+WFLAGS += -DRT6590 -DRT65xx -DRLT_MAC -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DA_BAND_SUPPORT -DRX_DMA_SCATTER
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+CHIPSET_DAT = 2860
+endif
+
+
+ifneq ($(findstring 6570,$(CHIPSET)),)
+WFLAGS += -DRT6570 -DRT65xx -DRLT_MAC -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT -DRX_DMA_SCATTER
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+ifeq ($(HAS_CSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT
+endif
+ifeq ($(HAS_TSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT -DCONFIG_TSO_SUPPORT -DTX_PKT_SG
+endif
+
+CHIPSET_DAT = 2870
+endif
+
+ifneq ($(findstring 3370,$(CHIPSET)),)
+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 -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+endif
+
+ifneq ($(findstring 5390,$(CHIPSET)),)
+WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT33xx -DRT3090 -DRT3390 -DRT5390 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_FREQ_CALIBRATION_SUPPORT -DRTMP_INTERNAL_TX_ALC -DVCORECAL_SUPPORT -DIQ_CAL_SUPPORT -DNEW_MBSSID_MODE -DRTMP_TEMPERATURE_COMPENSATION
+CHIPSET_DAT = 2860
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 5370,$(CHIPSET)),)
+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 -DRTMP_FREQ_CALIBRATION_SUPPORT -DVCORECAL_SUPPORT -DIQ_CAL_SUPPORT -DNEW_MBSSID_MODE -DRTMP_TEMPERATURE_COMPENSATION
+CHIPSET_DAT = 2870
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 3052,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT3052 -DRT305x -DRTMP_RF_RW_SUPPORT -DCONFIG_SWMCU_SUPPORT -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2870
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+endif
+
+ifneq ($(findstring 3352,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT3352 -DRT305x -DRTMP_RF_RW_SUPPORT -DVCORECAL_SUPPORT -DCONFIG_SWMCU_SUPPORT -DRTMP_INTERNAL_TX_ALC -DNEW_MBSSID_MODE
+CHIPSET_DAT = 2860
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 5350,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_RBUS_SUPPORT -DRT5350 -DRT305x -DRT3050 -DRT3350 -DRTMP_RF_RW_SUPPORT -DVCORECAL_SUPPORT -DCONFIG_SWMCU_SUPPORT -DRTMP_INTERNAL_TX_ALC -DRTMP_FREQ_CALIBRATION_SUPPORT -DIQ_CAL_SUPPORT -DNEW_MBSSID_MODE
+CHIPSET_DAT = 2860
+ifeq ($(HAS_WIFI_LED_SHARE), y)
+WFLAGS += -DCONFIG_WIFI_LED_SHARE
+endif
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+endif
+
+ifneq ($(findstring 5592,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT30xx -DRT5592\
+ -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT\
+ -DA_BAND_SUPPORT -DIQ_CAL_SUPPORT -DRX_DMA_SCATTER -DVCORECAL_SUPPORT\
+ -DNEW_MBSSID_MODE -DRTMP_TEMPERATURE_COMPENSATION
+CHIPSET_DAT = 2860
+ifeq ($(HAS_CSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+endif
+
+ifneq ($(findstring 5572,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT30xx -DRT5572 -DRT5592\
+ -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DNEW_MBSSID_MODE\
+ -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT -DIQ_CAL_SUPPORT -DVCORECAL_SUPPORT\
+ -DRTMP_TEMPERATURE_COMPENSATION
+CHIPSET_DAT = 2870
+ifeq ($(HAS_CSO_SUPPORT), y)
+WFLAGS += -DCONFIG_CSO_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+ifeq ($(HAS_CS_SUPPORT), y)
+WFLAGS += -DCARRIER_DETECTION_FIRMWARE_SUPPORT
+endif
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+
+endif
+
+ifneq ($(findstring 3290,$(CHIPSET)),)
+WFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRTMP_FREQ_CALIBRATION_SUPPORT -DRTMP_INTERNAL_TX_ALC -DRT30xx -DRT3290 -DVCORECAL_SUPPORT
+CHIPSET_DAT = 2860
+
+ifneq ($(findstring $(RT28xx_MODE),STA APSTA),)
+WFLAGS += -DRTMP_FREQ_CALIBRATION_SUPPORT -DPCIE_PS_SUPPORT
+endif
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+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
+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
+endif
+
+
+ifeq ($(CHIPSET),RBUS)
+WFLAGS += -DMERGE_ARCH_TEAM -DCONFIG_SWMCU_SUPPORT -DCONFIG_RA_NAT_NONE -DRTMP_RBUS_SUPPORT
+#5350, 3050, 3350, 3883
+WFLAGS +=-DRTMP_MAC_PCI -DRT305x -DRT5350 -DRT3050 -DRT3350 -DRT3883 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DA_BAND_SUPPORT -DVCORECAL_SUPPORT
+
+ifneq ($(findstring $(RT28xx_MODE),AP),)
+WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
+endif
+#WFLAGS += -DDBG_CTRL_SUPPORT
+#WFLAGS += -DINCLUDE_DEBUG_QUEUE
+#WFLAGS += -DRANGE_EXTEND -DCFO_TRACK -DPRE_ANT_SWITCH
+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
+
+#ifdef MULTI_CARD
+ifeq ($(HAS_MC_SUPPORT),y)
+WFLAGS += -DMULTIPLE_CARD_SUPPORT
+endif
+#endif // MULTI_CARD //
+
+ifeq ($(HAS_LLTD),y)
+WFLAGS += -DLLTD_SUPPORT
+endif
+
+ifeq ($(PLATFORM),RMI)
+WFLAGS += -DRT_BIG_ENDIAN
+endif
+
+ifeq ($(PLATFORM),UBICOM_IPX8)
+WFLAGS += -DRT_BIG_ENDIAN -DUNALIGNMENT_SUPPORT -DPLATFORM_UBM_IPX8 -DNO_CONSISTENT_MEM_SUPPORT -DCACHE_LINE_32B
+endif
+
+ifeq ($(PLATFORM),BL2348)
+WFLAGS += -DRT_BIG_ENDIAN
+endif
+
+ifeq ($(PLATFORM),BL23570)
+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 -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 -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 -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),UBICOM_IPX8)
+EXTRA_CFLAGS += $(WFLAGS)
+export EXTRA_CFLAGS
+endif
+
+ifeq ($(PLATFORM),SIGMA)
+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 -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 -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 -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 -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 -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 -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 := $(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 := $(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 := $(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 := $(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) -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 -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 -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 -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)
+ endif
+endif
+
+ifeq ($(PLATFORM),INTELP6)
+ EXTRA_CFLAGS := $(WFLAGS)
+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 -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 -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 -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) -mbig-endian
+ export CFLAGS
+endif
+
+ifeq ($(PLATFORM),SMDK)
+ EXTRA_CFLAGS := $(WFLAGS)
+endif
+
+ifeq ($(PLATFORM),CAVM_OCTEON)
+ EXTRA_CFLAGS := $(WFLAGS) -mabi=64 $(WFLAGS)
+export CFLAGS
+endif
+
+ifeq ($(PLATFORM),DM6446)
+ CFLAGS := -nostdinc -iwithprefix include -D__KERNEL__ -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$(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),BL23570)
+EXTRA_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 -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=74kc -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS) -DSIGMA863X_PLATFORM -DEXPORT_SYMTAB -DPLATFORM_BL23570
+export EXTRA_CFLAGS
+endif
+
+ifeq ($(PLATFORM),BLUBB)
+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 -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$(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 -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)
+ 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 -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)
+ endif
+endif
+
+ifeq ($(PLATFORM),MVL5)
+CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/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 -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
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/inf_ppa.c b/cleopatre/devkit/mt7601udrv/os/linux/inf_ppa.c
new file mode 100644
index 0000000000..78a9f2b9b1
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/inf_ppa.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ inf_ppa.c
+
+ Abstract:
+ Only for Infineon PPA Direct path feature.
+
+
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ carella 06-01-2010 Created
+
+ */
+
+#ifdef INF_PPA_SUPPORT
+
+#include "rt_config.h"
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+
+extern INT rt28xx_send_packets(
+ IN struct sk_buff *skb_p,
+ IN struct net_device *net_dev);
+
+int ifx_ra_start_xmit(
+ struct net_device *rx_dev,
+ struct net_device *tx_dev,
+ struct sk_buff *skb, int len)
+{
+ if(tx_dev != NULL)
+ {
+ SET_OS_PKT_NETDEV(skb, tx_dev);
+ rt28xx_send_packets(skb, tx_dev);
+ }
+ else if(rx_dev != NULL)
+ {
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ netif_rx(skb);
+ }
+ else
+ {
+ dev_kfree_skb_any(skb);
+ }
+ return 0;
+}
+#endif /* INF_PPA_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/load b/cleopatre/devkit/mt7601udrv/os/linux/load
new file mode 100644
index 0000000000..5699ee4876
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/load
@@ -0,0 +1,6 @@
+#!/bin/sh
+ifconfig ra0 down
+rmmod rt2860ap
+insmod rt2860ap.o
+ifconfig ra0 up 192.168.100.77
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_linux.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_linux.c
new file mode 100644
index 0000000000..3fa69be48b
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_linux.c
@@ -0,0 +1,5258 @@
+/****************************************************************************
+
+ Module Name:
+ UTIL/rt_linux.c
+
+ Abstract:
+ All functions provided from OS module are put here.
+
+ Note:
+ 1. Can not use sizeof() for a structure with any parameter included
+ by any compile option, such as RTMP_ADAPTER.
+
+ Because the RTMP_ADAPTER size in the UTIL module is different with
+ DRIVER/NETIF.
+
+ 2. Do not use any structure with any parameter included by PCI/USB/RBUS/
+ AP/STA.
+
+ Because the structure size in the UTIL module is different with
+ DRIVER/NETIF.
+
+ 3. Do not use any structure defined in DRIVER module, EX: pAd.
+ So we can do module partition.
+
+ Revision History:
+ Who When What
+ --------- ---------- -------------------------------------------
+
+***************************************************************************/
+
+#define RTMP_MODULE_OS
+#define RTMP_MODULE_OS_UTIL
+
+
+#include "rtmp_comm.h"
+#include "rtmp_osabl.h"
+#include "rt_os_util.h"
+#include <linux/rtnetlink.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_TRACE;
+ULONG RTDebugLevel = RT_DEBUG_ERROR;
+ULONG RTDebugFunc = 0;
+
+#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;
+
+
+BOOLEAN RTMP_OS_Alloc_RscOnly(VOID *pRscSrc, UINT32 RscLen);
+BOOLEAN RTMP_OS_Remove_Rsc(LIST_HEADER *pRscList, VOID *pRscSrc);
+
+/*
+========================================================================
+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(ULONG usec)
+{
+ ULONG i;
+
+ for (i = 0; i < (usec / 50); i++)
+ udelay(50);
+
+ if (usec % 50)
+ udelay(usec % 50);
+}
+
+
+/* Unify all delay routine by using udelay */
+VOID RtmpOsUsDelay(ULONG value)
+{
+ ULONG i;
+
+ udelay(value);
+}
+
+VOID RtmpOsMsDelay(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);
+#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(VOID *dummy, 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(VOID *dummy, ULONG len)
+{
+ struct sk_buff *pkt;
+
+ pkt = dev_alloc_skb(len);
+
+ if (pkt == NULL) {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("can't allocate frag rx %ld size packet\n", len));
+ }
+
+ 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 UCHAR *pHeader,
+ IN UINT HeaderLen,
+ IN UCHAR *pData,
+ IN UINT DataLen)
+{
+ struct sk_buff *pPacket;
+
+
+ ASSERT(pData);
+ ASSERT(DataLen);
+
+ pPacket = 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);
+
+ /* Clone the frame content and update the length of packet */
+ if (HeaderLen > 0)
+ NdisMoveMemory(pPacket->data, pHeader, HeaderLen);
+ if (DataLen > 0)
+ NdisMoveMemory(pPacket->data + HeaderLen, pData, DataLen);
+ skb_put(pPacket, HeaderLen + DataLen);
+/* printk(KERN_ERR "%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));*/
+
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+ *ppPacket = (PNDIS_PACKET)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 *info,
+ OUT UCHAR **pSrcBufVA,
+ OUT UINT *pSrcBufLen)
+{
+ info->BufferCount = 1;
+ info->pFirstBuffer = (PNDIS_BUFFER) GET_OS_PKT_DATAPTR(pPacket);
+ info->PhysicalBufferCount = 1;
+ info->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
+
+ *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+ *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
+
+#ifdef TX_PKT_SG
+ if (RTMP_GET_PKT_SG(pPacket)) {
+ struct sk_buff *skb = (struct sk_buff *)pPacket;
+ int i, nr_frags = skb_shinfo(skb)->nr_frags;
+
+ info->BufferCount = nr_frags + 1;
+ info->PhysicalBufferCount = info->BufferCount;
+ info->sg_list[0].data = (VOID *)GET_OS_PKT_DATAPTR(pPacket);
+ info->sg_list[0].len = skb_headlen(skb);
+ for (i = 0; i < nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ info->sg_list[i+1].data = ((void *) page_address(frag->page) +
+ frag->page_offset);
+ info->sg_list[i+1].len = frag->size;
+ }
+ }
+#endif /* TX_PKT_SG */
+}
+
+
+
+
+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);
+
+
+}
+
+#ifdef CONFIG_AP_SUPPORT
+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)
+{
+ struct sk_buff *skb;
+ PNDIS_PACKET pPacket = NULL;
+ UINT16 VLAN_Size;
+
+ if ((skb = __dev_alloc_skb(HdrLen + DataSize + LENGTH_802_1Q + 2,
+ MEM_ALLOC_FLAG)) != NULL) {
+ MEM_DBG_PKT_ALLOC_INC(skb);
+
+ skb_reserve(skb, 2);
+
+ /* copy header (maybe +VLAN tag) */
+ VLAN_Size = VLAN_8023_Header_Copy(VLAN_VID, VLAN_Priority,
+ pHeader802_3, HdrLen,
+ skb->tail, FromWhichBSSID,
+ TPID);
+ skb_put(skb, HdrLen + VLAN_Size);
+
+ /* copy data body */
+ 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;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+/*
+ ========================================================================
+
+ 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(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_AP_SUPPORT
+ RT_CONFIG_IF_OPMODE_ON_AP(OpMode)
+ {
+ /* maybe insert VLAN tag to the received packet */
+ UCHAR VLAN_Size = 0;
+ UCHAR *data_p;
+
+ if (VLAN_VID != 0)
+ VLAN_Size = LENGTH_802_1Q;
+
+ data_p = skb_push(pOSPkt, LENGTH_802_3 + VLAN_Size);
+
+ VLAN_8023_Header_Copy(VLAN_VID, VLAN_Priority,
+ pHeader802_3, LENGTH_802_3,
+ data_p, FromWhichBSSID, TPID);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+}
+
+
+#ifdef HDR_TRANS_SUPPORT
+VOID RtmpOsSetPacket(
+ IN PNET_DEV pNetDev,
+ IN PNDIS_PACKET pRxPacket,
+ IN UCHAR *pData,
+ IN ULONG DataSize)
+{
+
+ struct sk_buff *pOSPkt;
+
+ pOSPkt = RTPKT_TO_OSPKT(pRxPacket);
+
+ pOSPkt->dev = pNetDev;
+ pOSPkt->data = pData;
+ pOSPkt->len = DataSize;
+ pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+}
+
+#endif /* HDR_TRANS_SUPPORT */
+
+
+void hex_dump(char *str, UCHAR *pSrcBufVA, UINT 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_AP_SUPPORT
+VOID SendSignalToDaemon(
+ IN INT sig,
+ RTMP_OS_PID pid,
+ unsigned long pid_no)
+{
+}
+#endif /* CONFIG_AP_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(OS_TASK *pTask)
+{
+ int ret = NDIS_STATUS_FAILURE;
+
+#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(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(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(&current->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(&current->sigmask_lock, flags);
+ flush_signals(current);
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->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: 0x%x\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;
+ else
+ wrqu.data.length = 0;
+
+ 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;
+
+ net_dev = pNetDev;
+/* GET_PAD_FROM_NET_DEV(pAd, net_dev); */
+
+
+ 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(PNET_DEV pNetDev)
+{
+ dev_close(pNetDev);
+}
+
+void RtmpOSNetDevFree(PNET_DEV pNetDev)
+{
+ DEV_PRIV_INFO *pDevInfo = NULL;
+
+
+ ASSERT(pNetDev);
+
+ /* free assocaited private information */
+ pDevInfo = _RTMP_OS_NETDEV_GET_PRIV(pNetDev);
+ if (pDevInfo != NULL)
+ os_free_mem(NULL, pDevInfo);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ free_netdev(pNetDev);
+#else
+ kfree(pNetDev);
+#endif
+
+#ifdef VENDOR_FEATURE4_SUPPORT
+ printk("OS_NumOfMemAlloc = %ld, OS_NumOfMemFree = %ld\n",
+ OS_NumOfMemAlloc, OS_NumOfMemFree);
+#endif /* VENDOR_FEATURE4_SUPPORT */
+#ifdef VENDOR_FEATURE2_SUPPORT
+ printk("OS_NumOfPktAlloc = %ld, OS_NumOfPktFree = %ld\n",
+ OS_NumOfPktAlloc, OS_NumOfPktFree);
+#endif /* VENDOR_FEATURE2_SUPPORT */
+}
+
+INT RtmpOSNetDevAlloc(
+ IN PNET_DEV *new_dev_p,
+ IN UINT32 privDataSize)
+{
+ *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(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(VOID *pReserved, 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
+ int ret;
+
+ ret = rtnl_trylock();
+
+ unregister_netdevice(pNetDev);
+
+ if ( ret )
+ rtnl_unlock();
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
+ vfree(pNetDevOps);
+#endif
+}
+
+
+void RtmpOSNetDevProtect(BOOLEAN lock_it)
+{
+
+/*
+ if (lock_it)
+ rtnl_lock();
+ else
+ rtnl_unlock();
+*/
+}
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+static void RALINK_ET_DrvInfoGet(
+ struct net_device *pDev,
+ 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
+
+
+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; */
+ RT_DEV_PRIV_FLAGS_SET(pNetDev, 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_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;
+}
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+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)
+{
+ UINT16 TCI;
+ UCHAR VLAN_Size = 0;
+
+ if (VLAN_VID != 0) {
+ /* need to insert VLAN tag */
+ VLAN_Size = LENGTH_802_1Q;
+
+ /* make up TCI field */
+ TCI = (VLAN_VID & 0x0fff) | ((VLAN_Priority & 0x7) << 13);
+
+#ifndef RT_BIG_ENDIAN
+ TCI = SWAP16(TCI);
+#endif /* RT_BIG_ENDIAN */
+
+ /* copy dst + src MAC (12B) */
+ memcpy(pData, pHeader802_3, LENGTH_802_3_NO_TYPE);
+
+ /* copy VLAN tag (4B) */
+ /* do NOT use memcpy to speed up */
+ *(UINT16 *) (pData + LENGTH_802_3_NO_TYPE) = *(UINT16 *) TPID;
+ *(UINT16 *) (pData + LENGTH_802_3_NO_TYPE + 2) = TCI;
+
+ /* copy type/len (2B) */
+ *(UINT16 *) (pData + LENGTH_802_3_NO_TYPE + LENGTH_802_1Q) =
+ *(UINT16 *) & pHeader802_3[LENGTH_802_3 -
+ LENGTH_802_3_TYPE];
+
+ /* copy tail if exist */
+ if (HdrLen > LENGTH_802_3)
+ memcpy(pData + LENGTH_802_3 + LENGTH_802_1Q, pHeader802_3 + LENGTH_802_3, HdrLen - LENGTH_802_3);
+ }
+ else
+ {
+ /* no VLAN tag is needed to insert */
+ memcpy(pData, pHeader802_3, HdrLen);
+ }
+
+ return VLAN_Size;
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+/*
+========================================================================
+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(VOID *handle, VOID **ppAd, UINT32 SizeOfpAd)
+{
+#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); */
+ 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;
+ UINT32 macAddr = 0, macValue = 0;
+
+ os_alloc_mem(NULL, (UCHAR **)&msg, 1024);
+ if (!msg)
+ return;
+
+ 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, "%04x = %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;
+ USHORT eepAddr = 0;
+ USHORT eepValue;
+
+ os_alloc_mem(NULL, (UCHAR **)&msg, 1024);
+ if (!msg)
+ return;
+
+ 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 <= AddrEnd) {
+ 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 >> 1);
+ }
+ sprintf(msg, "\nDump all EEPROM values to %s\n",
+ fileName);
+ }
+ filp_close(file_w, NULL);
+ }
+ set_fs(orig_fs);
+ os_free_mem(NULL, msg);
+}
+
+
+VOID RtmpDrvAllRFPrint(
+ IN VOID *pReserved,
+ IN UINT32 *pBuf,
+ IN UINT32 BufLen)
+{
+ struct file *file_w;
+ PSTRING fileName = "RFDump.txt";
+ mm_segment_t orig_fs;
+ UINT32 macAddr = 0, macValue = 0;
+
+ 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;
+ /* write data to file */
+ file_w->f_op->write(file_w, pBuf, BufLen, &file_w->f_pos);
+ }
+ filp_close(file_w, NULL);
+ }
+ set_fs(orig_fs);
+}
+
+/*
+========================================================================
+Routine Description:
+ Check if the network interface is up.
+
+Arguments:
+ *pDev - Network Interface
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+BOOLEAN RtmpOSNetDevIsUp(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(RTMP_OS_TASK *pCmdQTask)
+{
+ OS_TASK *pTask = RTMP_OS_TASK_GET(pCmdQTask);
+#ifdef KTHREAD_SUPPORT
+ pTask->kthread_running = TRUE;
+ wake_up(&pTask->kthread_q);
+#else
+ CHECK_PID_LEGALITY(pTask->taskPID) {
+ RTMP_SEM_EVENT_UP(&(pTask->taskSema));
+ }
+#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_TASK *pTask = RTMP_OS_TASK_GET(pMlmeQTask);
+
+#ifdef KTHREAD_SUPPORT
+ if ((pTask != NULL) && (pTask->kthread_task)) {
+ pTask->kthread_running = TRUE;
+ wake_up(&pTask->kthread_q);
+ }
+#else
+ if (pTask != NULL) {
+ CHECK_PID_LEGALITY(pTask->taskPID) {
+ RTMP_SEM_EVENT_UP(&(pTask->taskSema));
+ }
+ }
+#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 = (struct net_device *)pNetDev;
+
+
+
+ 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(ULONG Size)
+{
+ return vmalloc(Size);
+}
+
+/*
+========================================================================
+Routine Description:
+ vfree
+
+Arguments:
+ pMem - the memory
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsVfree(VOID *pMem)
+{
+ if (pMem != NULL)
+ vfree(pMem);
+}
+
+/*
+========================================================================
+Routine Description:
+ Get network interface name.
+
+Arguments:
+ pDev - the device
+
+Return Value:
+ the name
+
+Note:
+========================================================================
+*/
+char *RtmpOsGetNetDevName(VOID *pDev)
+{
+ return ((PNET_DEV) pDev)->name;
+}
+
+/*
+========================================================================
+Routine Description:
+ Assign protocol to the packet.
+
+Arguments:
+ pPkt - the packet
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsPktProtocolAssign(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(PNDIS_PACKET pNetPkt)
+{
+ struct sk_buff *pRxPkt = RTPKT_TO_OSPKT(pNetPkt);
+
+#ifdef CONFIG_RX_CSO_SUPPORT
+
+ if (RTMP_GET_TCP_CHKSUM_FAIL(pNetPkt))
+ pRxPkt->ip_summed = CHECKSUM_NONE;
+ else
+ pRxPkt->ip_summed = CHECKSUM_UNNECESSARY;
+
+#endif
+
+ netif_rx(pRxPkt);
+}
+
+
+VOID RtmpOsTaskPidInit(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(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(PNDIS_PACKET pNetPkt)
+{
+}
+
+VOID RtmpOsPktNatNone(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);
+ kfree(pCfg80211_CB->pCfg80211_Wdev);
+
+ if (pCfg80211_CB->pCfg80211_Channels != NULL)
+ kfree(pCfg80211_CB->pCfg80211_Channels);
+
+ if (pCfg80211_CB->pCfg80211_Rates != NULL)
+ kfree(pCfg80211_CB->pCfg80211_Rates);
+
+ 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);
+ }
+
+ os_free_mem(NULL, pCfg80211_CB);
+}
+
+
+/*
+========================================================================
+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;
+
+ 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;
+
+ if (pBandInfo->FlgIsBMode == TRUE)
+ NumOfRate = 4;
+ else
+ NumOfRate = 4 + 8;
+
+ if (pChannels == NULL)
+ {
+ pChannels = kzalloc(sizeof(*pChannels) * NumOfChan, GFP_KERNEL);
+ if (!pChannels)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("80211> ieee80211_channel allocation fail!\n"));
+ return FALSE;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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; IdLoop<NumOfChan; IdLoop++)
+ {
+ pChannels[IdLoop].center_freq = \
+ ieee80211_channel_to_frequency(Cfg80211_Chan[IdLoop]);
+ pChannels[IdLoop].hw_value = IdLoop;
+
+ if (IdLoop < CFG80211_NUM_OF_CHAN_2GHZ)
+ pChannels[IdLoop].max_power = CurTxPower;
+ else
+ pChannels[IdLoop].max_power = CurTxPower;
+
+ pChannels[IdLoop].max_antenna_gain = 0xff;
+ }
+
+ /* init rate */
+ for(IdLoop=0; IdLoop<NumOfRate; IdLoop++)
+ memcpy(&pRates[IdLoop], &Cfg80211_SupRate[IdLoop], sizeof(*pRates));
+
+ pBand = &pCfg80211_CB->Cfg80211_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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ pCfg80211_CB->pCfg80211_Channels = pChannels;
+ pCfg80211_CB->pCfg80211_Rates = pRates;
+
+ return TRUE;
+}
+
+
+/*
+========================================================================
+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;
+
+
+ if ((pCfg80211_CB == NULL) || (pCfg80211_CB->pCfg80211_Wdev == NULL))
+ return FALSE;
+
+ 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;
+ }
+
+ return FALSE;
+}
+
+
+/*
+========================================================================
+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;
+ }
+
+ /* 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);
+}
+
+
+/*
+========================================================================
+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;
+ }
+
+ 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 */
+}
+
+
+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;
+
+
+ if (pWiphy == NULL)
+ {
+ if ((pCfg80211_CB != NULL) && (pCfg80211_CB->pCfg80211_Wdev != NULL))
+ pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy;
+ }
+
+ 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;
+
+
+ if (pWiphy == NULL)
+ {
+ if ((pCfg80211_CB != NULL) && (pCfg80211_CB->pCfg80211_Wdev != NULL))
+ pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy;
+ }
+
+ 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;
+
+
+ if (pWiphy == NULL)
+ {
+ if ((pCfg80211_CB != NULL) && (pCfg80211_CB->pCfg80211_Wdev != NULL))
+ pWiphy = pCfg80211_CB->pCfg80211_Wdev->wiphy;
+ }
+
+ 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:
+ Initialize a channel information used in scan inform.
+
+Arguments:
+
+Return Value:
+ TRUE - Successful
+ FALSE - Fail
+
+Note:
+========================================================================
+*/
+BOOLEAN CFG80211OS_ChanInfoInit(
+ IN VOID *pCB,
+ IN UINT32 InfoIndex,
+ IN UCHAR ChanId,
+ IN UCHAR MaxTxPwr,
+ IN BOOLEAN FlgIsNMode,
+ IN BOOLEAN FlgIsBW20M)
+{
+ CFG80211_CB *pCfg80211_CB = (CFG80211_CB *)pCB;
+ struct ieee80211_channel *pChan;
+
+
+ if (InfoIndex >= MAX_NUM_OF_CHANNELS)
+ return FALSE;
+
+ pChan = (struct ieee80211_channel *)&(pCfg80211_CB->ChanInfo[InfoIndex]);
+ memset(pChan, 0, sizeof(*pChan));
+
+ if (ChanId > 14)
+ pChan->band = IEEE80211_BAND_5GHZ;
+ else
+ pChan->band = IEEE80211_BAND_2GHZ;
+
+ pChan->center_freq = ieee80211_channel_to_frequency(ChanId);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32))
+ if (FlgIsNMode == TRUE)
+ {
+ if (FlgIsBW20M == TRUE)
+ pChan->max_bandwidth = 20; /* 20MHz */
+ else
+ pChan->max_bandwidth = 40; /* 40MHz */
+ }
+ else
+ pChan->max_bandwidth = 5; /* 5MHz for non-HT device */
+#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; */
+
+ 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 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))
+#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))
+#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;
+
+ 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);
+ }
+#endif /* LINUX_VERSION_CODE */
+}
+#endif /* RT_CFG80211_SUPPORT */
+
+
+/*
+========================================================================
+Routine Description:
+ Flush a data cache line.
+
+Arguments:
+ AddrStart - the start address
+ Size - memory size
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsDCacheFlush(
+ IN ULONG AddrStart,
+ IN ULONG Size)
+{
+ RTMP_UTIL_DCACHE_FLUSH(AddrStart, Size);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Assign private data pointer to the network interface.
+
+Arguments:
+ pDev - the device
+ pPriv - the pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsSetNetDevPriv(VOID *pDev, VOID *pPriv)
+{
+ DEV_PRIV_INFO *pDevInfo = NULL;
+
+
+ pDevInfo = (DEV_PRIV_INFO *) _RTMP_OS_NETDEV_GET_PRIV((PNET_DEV) pDev);
+ if (pDevInfo == NULL)
+ {
+ os_alloc_mem(NULL, (UCHAR **)&pDevInfo, sizeof(DEV_PRIV_INFO));
+ if (pDevInfo == NULL)
+ return;
+ }
+
+ pDevInfo->pPriv = (VOID *)pPriv;
+ pDevInfo->priv_flags = 0;
+
+ _RTMP_OS_NETDEV_SET_PRIV((PNET_DEV) pDev, pDevInfo);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Get private data pointer from the network interface.
+
+Arguments:
+ pDev - the device
+ pPriv - the pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID *RtmpOsGetNetDevPriv(VOID *pDev)
+{
+ DEV_PRIV_INFO *pDevInfo = NULL;
+
+
+ pDevInfo = (DEV_PRIV_INFO *) _RTMP_OS_NETDEV_GET_PRIV((PNET_DEV) pDev);
+ if (pDevInfo != NULL)
+ return pDevInfo->pPriv;
+ return NULL;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Get private flags from the network interface.
+
+Arguments:
+ pDev - the device
+
+Return Value:
+ pPriv - the pointer
+
+Note:
+========================================================================
+*/
+USHORT RtmpDevPrivFlagsGet(VOID *pDev)
+{
+
+ DEV_PRIV_INFO *pDevInfo = NULL;
+
+
+ pDevInfo = (DEV_PRIV_INFO *) _RTMP_OS_NETDEV_GET_PRIV((PNET_DEV) pDev);
+ if (pDevInfo != NULL)
+ return pDevInfo->priv_flags;
+ return 0;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Get private flags from the network interface.
+
+Arguments:
+ pDev - the device
+
+Return Value:
+ pPriv - the pointer
+
+Note:
+========================================================================
+*/
+VOID RtmpDevPrivFlagsSet(VOID *pDev, USHORT PrivFlags)
+{
+ DEV_PRIV_INFO *pDevInfo = NULL;
+
+
+ pDevInfo = (DEV_PRIV_INFO *) _RTMP_OS_NETDEV_GET_PRIV((PNET_DEV) pDev);
+ if (pDevInfo != NULL)
+ pDevInfo->priv_flags = PrivFlags;
+}
+
+
+
+
+#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(RTMP_OS_FS_INFO *pOSFSInfoOrg, 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(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(
+ RTMP_NET_TASK_STRUCT *pTasklet,
+ VOID (*pFunc) (unsigned long data),
+ ULONG Data,
+ LIST_HEADER *pTaskletList)
+{
+#ifdef WORKQUEUE_BH
+ if (RTMP_OS_Alloc_RscOnly(pTasklet, sizeof (struct work_struct)) == FALSE)
+ return FALSE;
+
+ INIT_WORK((struct work_struct *)(pTasklet->pContent), pFunc);
+#else
+
+ if (RTMP_OS_Alloc_RscOnly(pTasklet, sizeof (OS_NET_TASK_STRUCT)) == FALSE)
+ return FALSE;
+
+ 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(RTMP_NET_TASK_STRUCT *pTasklet)
+{
+ if (pTasklet->pContent != NULL) {
+#ifndef WORKQUEUE_BH
+ tasklet_kill((OS_NET_TASK_STRUCT *) (pTasklet->pContent));
+#endif /* WORKQUEUE_BH */
+
+ os_free_mem(NULL, pTasklet->pContent);
+ pTasklet->pContent = NULL;
+ }
+
+ return TRUE;
+}
+
+
+VOID RtmpOsTaskletDataAssign(RTMP_NET_TASK_STRUCT *pTasklet, ULONG Data)
+{
+#ifndef WORKQUEUE_BH
+ if (pTasklet->pContent != NULL)
+ ((OS_NET_TASK_STRUCT *) (pTasklet->pContent))->data = Data;
+#endif /* WORKQUEUE_BH */
+}
+
+
+INT32 RtmpOsTaskIsKilled(RTMP_OS_TASK *pTaskOrg)
+{
+ OS_TASK *pTask;
+
+ pTask = (OS_TASK *) (pTaskOrg->pContent);
+ if (pTask == NULL)
+ return 1;
+ return pTask->task_killed;
+}
+
+
+VOID RtmpOsTaskWakeUp(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(RTMP_OS_TASK *pTaskOrg)
+{
+ OS_TASK *pTask;
+
+ pTask = (OS_TASK *) (pTaskOrg->pContent);
+ if (!pTask)
+ 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(NDIS_MINIPORT_TIMER *pTimerOrg, ULONG timeout)
+{
+ OS_NDIS_MINIPORT_TIMER *pTimer;
+
+ pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent);
+ if (pTimer)
+ __RTMP_SetPeriodicTimer(pTimer, timeout);
+}
+
+
+/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
+VOID RTMP_OS_Init_Timer(
+ VOID *pReserved,
+ NDIS_MINIPORT_TIMER *pTimerOrg,
+ TIMER_FUNCTION function,
+ PVOID data,
+ LIST_HEADER *pTimerList)
+{
+ OS_NDIS_MINIPORT_TIMER *pTimer;
+
+ if (RTMP_OS_Alloc_RscOnly(pTimerOrg, sizeof (OS_NDIS_MINIPORT_TIMER)) == FALSE)
+ return;
+
+ pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent);
+ if (pTimer)
+ __RTMP_OS_Init_Timer(pReserved, pTimer, function, data);
+}
+
+
+VOID RTMP_OS_Add_Timer(NDIS_MINIPORT_TIMER *pTimerOrg, ULONG timeout)
+{
+ OS_NDIS_MINIPORT_TIMER *pTimer;
+
+ pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent);
+
+ if (pTimer) {
+ if (timer_pending(pTimer))
+ return;
+
+ __RTMP_OS_Add_Timer(pTimer, timeout);
+ }
+}
+
+
+VOID RTMP_OS_Mod_Timer(NDIS_MINIPORT_TIMER *pTimerOrg, ULONG timeout)
+{
+ OS_NDIS_MINIPORT_TIMER *pTimer;
+
+ pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent);
+ if (pTimer)
+ __RTMP_OS_Mod_Timer(pTimer, timeout);
+}
+
+
+VOID RTMP_OS_Del_Timer(NDIS_MINIPORT_TIMER *pTimerOrg, BOOLEAN *pCancelled)
+{
+ OS_NDIS_MINIPORT_TIMER *pTimer;
+
+ pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent);
+ if (pTimer)
+ __RTMP_OS_Del_Timer(pTimer, pCancelled);
+}
+
+
+VOID RTMP_OS_Release_Timer(NDIS_MINIPORT_TIMER *pTimerOrg)
+{
+ OS_NDIS_MINIPORT_TIMER *pTimer;
+
+ pTimer = (OS_NDIS_MINIPORT_TIMER *) (pTimerOrg->pContent);
+ if (pTimer) {
+ __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(
+ LIST_HEADER *pRscList,
+ VOID *pRscSrc,
+ 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:
+ 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_RscOnly(VOID *pRscSrc, 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;
+ }
+ memset(pRsc->pContent, 0, RscLen);
+ }
+
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Remove a OS resource.
+
+Arguments:
+ pAd - WLAN control block pointer
+ pRsc - the resource
+
+Return Value:
+ TRUE or FALSE
+
+Note:
+========================================================================
+*/
+BOOLEAN RTMP_OS_Remove_Rsc(
+ LIST_HEADER *pRscList,
+ VOID *pRscSrc)
+{
+ LIST_RESOURCE_OBJ_ENTRY *pObj;
+ OS_RSTRUC *pRscHead, *pRsc, *pRscRev = (OS_RSTRUC *) pRscSrc;
+ pRscHead = NULL;
+
+ OS_SEM_LOCK(&UtilSemLock);
+ while(TRUE)
+ {
+ pObj = (LIST_RESOURCE_OBJ_ENTRY *) removeHeadList(pRscList);
+ if (pRscHead == NULL)
+ pRscHead = pObj->pRscObj; /* backup first entry */
+ else if (((ULONG)pRscHead) == ((ULONG)(pObj->pRscObj)))
+ break; /* has searched all entries */
+
+ pRsc = (OS_RSTRUC *) (pObj->pRscObj);
+ if ((ULONG)pRsc == (ULONG)pRscRev)
+ break; /* find it */
+
+ /* re-insert it */
+ 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(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(RTMP_OS_TASK *pTask, LIST_HEADER *pTaskList)
+{
+ if (RTMP_OS_Alloc_RscOnly(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(RTMP_OS_TASK *pTaskOrg)
+{
+ OS_TASK *pTask;
+
+ pTask = (OS_TASK *) (pTaskOrg->pContent);
+ if (pTask != NULL) {
+ os_free_mem(NULL, pTask);
+ pTaskOrg->pContent = NULL;
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Kill a kernel task.
+
+Arguments:
+ pTaskOrg - the task
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+NDIS_STATUS RtmpOSTaskKill(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(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(RTMP_OS_TASK *pTaskOrg)
+{
+ OS_TASK *pTask;
+
+ pTask = (OS_TASK *) (pTaskOrg->pContent);
+ if (pTask)
+ __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(
+ RTMP_OS_TASK *pTaskOrg,
+ RTMP_OS_TASK_CALLBACK fn,
+ 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(
+ RTMP_OS_TASK *pTaskOrg,
+ PSTRING pTaskName,
+ VOID *pPriv,
+ LIST_HEADER *pTaskList,
+ 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(VOID *pReserved, RTMP_OS_TASK *pTaskOrg, 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(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(NDIS_SPIN_LOCK *pLock, LIST_HEADER *pLockList)
+{
+ if (RTMP_OS_Alloc_RscOnly(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(NDIS_SPIN_LOCK *pLockOrg)
+{
+ /* we will free all locks memory in RTMP_OS_FREE_LOCK() */
+ OS_NDIS_SPIN_LOCK *pLock;
+
+ pLock = (OS_NDIS_MINIPORT_TIMER *) (pLockOrg->pContent);
+ if (pLock != NULL) {
+ OS_NdisFreeSpinLock(pLock);
+
+ os_free_mem(NULL, pLock);
+ pLockOrg->pContent = NULL;
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Spin lock bh.
+
+Arguments:
+ pLockOrg - the lock
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsSpinLockBh(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(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(NDIS_SPIN_LOCK *pLockOrg, 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(NDIS_SPIN_LOCK *pLockOrg, 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(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(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(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(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(VOID *pPkt, VOID *pDev)
+{
+ SET_OS_PKT_NETDEV(pPkt, (PNET_DEV) pDev);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Assign network interface type.
+
+Arguments:
+ pDev - the device
+ Type - the type
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsSetNetDevType(VOID *pDev, 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(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(UINT32 Time)
+{
+ OS_WAIT(Time);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Check if b is smaller than a.
+
+Arguments:
+ Time - micro second
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+UINT32 RtmpOsTimerAfter(ULONG a, 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(ULONG a, 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(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(UINT16 Value)
+{
+ return OS_NTOHS(Value);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ htons
+
+Arguments:
+ Value - the value
+
+Return Value:
+ the value
+
+Note:
+========================================================================
+*/
+UINT16 RtmpOsHtons(UINT16 Value)
+{
+ return OS_HTONS(Value);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ ntohl
+
+Arguments:
+ Value - the value
+
+Return Value:
+ the value
+
+Note:
+========================================================================
+*/
+UINT32 RtmpOsNtohl(UINT32 Value)
+{
+ return OS_NTOHL(Value);
+}
+
+/*
+========================================================================
+Routine Description:
+ htonl
+
+Arguments:
+ Value - the value
+
+Return Value:
+ the value
+
+Note:
+========================================================================
+*/
+UINT32 RtmpOsHtonl(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(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(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(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(VOID *to, const void *from, 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(VOID *to, const void *from, 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(RTMP_OS_SEM *pSem, LIST_HEADER *pSemList)
+{
+ if (RTMP_OS_Alloc_RscOnly(pSem, sizeof (OS_SEM)) == FALSE) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: alloc semaphore fail!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ 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(RTMP_OS_SEM *pSem, LIST_HEADER *pSemList)
+{
+ if (RTMP_OS_Alloc_RscOnly(pSem, sizeof (OS_SEM)) == FALSE) {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("%s: alloc semaphore fail!\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ 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(RTMP_OS_SEM *pSemOrg)
+{
+ OS_SEM *pSem;
+
+ pSem = (OS_SEM *) (pSemOrg->pContent);
+ if (pSem != NULL) {
+ OS_SEM_EVENT_DESTORY(pSem);
+
+ 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(RTMP_OS_SEM *pSemOrg)
+{
+ OS_SEM *pSem;
+ INT 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(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(
+ PNET_DEV pNetDev,
+ PNDIS_PACKET pNetPkt,
+ ULONG ThisFrameLen,
+ 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(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(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(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(PNDIS_PACKET pNetPkt, 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(PNDIS_PACKET pNetPkt, 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(PNDIS_PACKET pNetPkt, 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(PNDIS_PACKET pNetPkt, 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(PNDIS_PACKET pNetPkt, 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(PNDIS_PACKET pNetPkt, UINT Len)
+{
+ return OS_PKT_HEAD_BUF_EXTEND(pNetPkt, Len);
+}
+
+
+/*
+========================================================================
+Routine Description:
+
+
+Arguments:
+ pPkt - the packet
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsPktInfPpaSend(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(RTMP_OS_PID PID)
+{
+ return KILL_THREAD_PID(PID, SIGTERM, 1);
+}
+
+
+long RtmpOsSimpleStrtol(const char *cp, char **endp, unsigned int base)
+{
+ return simple_strtol(cp, endp, base);
+}
+
+
+BOOLEAN RtmpOsPktOffsetInit(VOID)
+{
+ struct sk_buff *pPkt = NULL;
+
+ if ((RTPktOffsetData == 0) && (RTPktOffsetLen == 0)
+ && (RTPktOffsetCB == 0)) {
+ pPkt = kmalloc(sizeof (struct sk_buff), GFP_ATOMIC);
+ if (pPkt == NULL)
+ return FALSE;
+
+ RTPktOffsetData = (ULONG) (&(pPkt->data)) - (ULONG) pPkt;
+ RTPktOffsetLen = (ULONG) (&(pPkt->len)) - (ULONG) pPkt;
+ RTPktOffsetCB = (ULONG) (pPkt->cb) - (ULONG) pPkt;
+ kfree(pPkt);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("packet> data offset = %lu\n", RTPktOffsetData));
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("packet> len offset = %lu\n", RTPktOffsetLen));
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("packet> cb offset = %lu\n", RTPktOffsetCB));
+ }
+
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize the OS atomic_t.
+
+Arguments:
+ pAtomic - the atomic
+
+Return Value:
+ TRUE - allocation successfully
+ FALSE - allocation fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RtmpOsAtomicInit(RTMP_OS_ATOMIC *pAtomic, LIST_HEADER *pAtomicList)
+{
+ if (RTMP_OS_Alloc_RscOnly(pAtomic, sizeof (atomic_t)) == FALSE) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: alloc atomic fail!\n", __FUNCTION__));
+ return FALSE; /* allocate fail */
+ }
+
+ return TRUE;
+}
+
+/*
+========================================================================
+Routine Description:
+ Initialize the OS atomic_t.
+
+Arguments:
+ pAtomic - the atomic
+
+Return Value:
+ TRUE - allocation successfully
+ FALSE - allocation fail
+
+Note:
+========================================================================
+*/
+VOID RtmpOsAtomicDestroy(RTMP_OS_ATOMIC *pAtomic)
+{
+ if (pAtomic->pContent) {
+ os_free_mem(NULL, pAtomic->pContent);
+ pAtomic->pContent = NULL;
+ }
+}
+
+/*
+========================================================================
+Routine Description:
+ Atomic read a variable.
+
+Arguments:
+ pAtomic - the atomic
+
+Return Value:
+ content
+
+Note:
+========================================================================
+*/
+LONG RtmpOsAtomicRead(RTMP_OS_ATOMIC *pAtomicSrc)
+{
+ if (pAtomicSrc->pContent)
+ return atomic_read((atomic_t *) (pAtomicSrc->pContent));
+ else
+ return 0;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Atomic dec a variable.
+
+Arguments:
+ pAtomic - the atomic
+
+Return Value:
+ content
+
+Note:
+========================================================================
+*/
+VOID RtmpOsAtomicDec(RTMP_OS_ATOMIC *pAtomicSrc)
+{
+ if (pAtomicSrc->pContent)
+ atomic_dec((atomic_t *) (pAtomicSrc->pContent));
+}
+
+
+/*
+========================================================================
+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(
+ RTMP_OS_ATOMIC *pAtomicSrc,
+ LONG Value)
+{
+ if (pAtomicSrc->pContent)
+ InterlockedExchange((atomic_t *) (pAtomicSrc->pContent), Value);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize the OS utilities.
+
+Arguments:
+ pOps - Utility table
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RtmpOsOpsInit(RTMP_OS_ABL_OPS *pOps)
+{
+ pOps->ra_printk = (RTMP_PRINTK)printk;
+ pOps->ra_snprintf = (RTMP_SNPRINTF)snprintf;
+}
+
+#else /* OS_ABL_FUNC_SUPPORT */
+
+
+void RtmpOSFSInfoChange(RTMP_OS_FS_INFO *pOSFSInfoOrg, BOOLEAN bSet)
+{
+ __RtmpOSFSInfoChange(pOSFSInfoOrg, bSet);
+}
+
+
+/* timeout -- ms */
+VOID RTMP_SetPeriodicTimer(NDIS_MINIPORT_TIMER *pTimerOrg, unsigned long timeout)
+{
+ __RTMP_SetPeriodicTimer(pTimerOrg, timeout);
+}
+
+
+/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
+VOID RTMP_OS_Init_Timer(
+ VOID *pReserved,
+ NDIS_MINIPORT_TIMER *pTimerOrg,
+ TIMER_FUNCTION function,
+ PVOID data,
+ LIST_HEADER *pTimerList)
+{
+ __RTMP_OS_Init_Timer(pReserved, pTimerOrg, function, data);
+}
+
+
+VOID RTMP_OS_Add_Timer(NDIS_MINIPORT_TIMER *pTimerOrg, unsigned long timeout)
+{
+ __RTMP_OS_Add_Timer(pTimerOrg, timeout);
+}
+
+
+VOID RTMP_OS_Mod_Timer(NDIS_MINIPORT_TIMER *pTimerOrg, unsigned long timeout)
+{
+ __RTMP_OS_Mod_Timer(pTimerOrg, timeout);
+}
+
+
+VOID RTMP_OS_Del_Timer(NDIS_MINIPORT_TIMER *pTimerOrg, BOOLEAN *pCancelled)
+{
+ __RTMP_OS_Del_Timer(pTimerOrg, pCancelled);
+}
+
+
+VOID RTMP_OS_Release_Timer(NDIS_MINIPORT_TIMER *pTimerOrg)
+{
+ __RTMP_OS_Release_Timer(pTimerOrg);
+}
+
+
+NDIS_STATUS RtmpOSTaskKill(RTMP_OS_TASK *pTask)
+{
+ return __RtmpOSTaskKill(pTask);
+}
+
+
+INT RtmpOSTaskNotifyToExit(RTMP_OS_TASK *pTask)
+{
+ return __RtmpOSTaskNotifyToExit(pTask);
+}
+
+
+void RtmpOSTaskCustomize(RTMP_OS_TASK *pTask)
+{
+ __RtmpOSTaskCustomize(pTask);
+}
+
+
+NDIS_STATUS RtmpOSTaskAttach(
+ RTMP_OS_TASK *pTask,
+ RTMP_OS_TASK_CALLBACK fn,
+ ULONG arg)
+{
+ return __RtmpOSTaskAttach(pTask, fn, arg);
+}
+
+
+NDIS_STATUS RtmpOSTaskInit(
+ RTMP_OS_TASK *pTask,
+ PSTRING pTaskName,
+ VOID *pPriv,
+ LIST_HEADER *pTaskList,
+ LIST_HEADER *pSemList)
+{
+ return __RtmpOSTaskInit(pTask, pTaskName, pPriv, pSemList);
+}
+
+
+BOOLEAN RtmpOSTaskWait(VOID *pReserved, RTMP_OS_TASK * pTask, INT32 *pStatus)
+{
+ return __RtmpOSTaskWait(pReserved, pTask, pStatus);
+}
+
+
+VOID RtmpOsTaskWakeUp(RTMP_OS_TASK *pTask)
+{
+#ifdef KTHREAD_SUPPORT
+ WAKE_UP(pTask);
+#else
+ RTMP_SEM_EVENT_UP(&pTask->taskSema);
+#endif
+}
+
+#endif /* OS_ABL_FUNC_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_linux_symb.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_linux_symb.c
new file mode 100644
index 0000000000..a74ceff3b6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_linux_symb.c
@@ -0,0 +1,287 @@
+/****************************************************************************
+
+ Module Name:
+ UTIL/rt_linux_symb.c
+
+ Abstract:
+ All symbols provided from UTIL module are put here.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#define RTMP_MODULE_OS
+#define RTMP_MODULE_OS_UTIL
+
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rtmp_osabl.h"
+#include "rt_os_util.h"
+
+
+#ifdef OS_ABL_FUNC_SUPPORT
+
+EXPORT_SYMBOL(RTDebugLevel);
+EXPORT_SYMBOL(RTDebugFunc);
+
+/* 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);
+#ifdef CONFIG_AP_SUPPORT
+EXPORT_SYMBOL(VLAN_8023_Header_Copy);
+#endif /* CONFIG_AP_SUPPORT */
+EXPORT_SYMBOL(wlan_802_11_to_802_3_packet);
+EXPORT_SYMBOL(RtmpOsPktOffsetInit);
+
+#ifdef HDR_TRANS_SUPPORT
+EXPORT_SYMBOL(RtmpOsSetPacket);
+#endif /* HDR_TRANS_SUPPORT */
+
+EXPORT_SYMBOL(RtmpOSNetDevCreate);
+EXPORT_SYMBOL(RtmpOSNetDevClose);
+EXPORT_SYMBOL(RtmpOSNetDevAttach);
+EXPORT_SYMBOL(RtmpOSNetDevDetach);
+EXPORT_SYMBOL(RtmpOSNetDevProtect);
+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(RtmpDevPrivFlagsGet);
+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(RtmpOsDCacheFlush);
+
+
+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(RtmpOsAtomicDestroy);
+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_ChanInfoInit);
+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_AP_SUPPORT
+EXPORT_SYMBOL(duplicate_pkt_with_VLAN);
+#ifdef BG_FT_SUPPORT
+EXPORT_SYMBOL(BG_FTPH_Init);
+EXPORT_SYMBOL(BG_FTPH_Remove);
+#endif /* BG_FT_SUPPORT */
+#endif /* CONFIG_AP_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 or flash-capable concurrent devices */
+#if defined(RTMP_RBUS_SUPPORT) || defined (RTMP_FLASH_SUPPORT)
+EXPORT_SYMBOL(RtmpFlashRead);
+EXPORT_SYMBOL(RtmpFlashWrite);
+#endif /* defined(RTMP_RBUS_SUPPORT) || defined (RTMP_FLASH_SUPPORT) */
+
+
+EXPORT_SYMBOL(RtPrivIoctlSetVal);
+
+#ifdef RTMP_USB_SUPPORT
+EXPORT_SYMBOL(RtmpInitCompletion);
+EXPORT_SYMBOL(RtmpWaitForCompletionTimeout);
+EXPORT_SYMBOL(RtmpComplete);
+#endif /* RTMP_USB_SUPPORT */
+EXPORT_SYMBOL(RtmpMsecsToJiffies);
+
+
+EXPORT_SYMBOL(RtmpDrvAllRFPrint);
+#endif /* OS_ABL_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_main_dev.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_main_dev.c
new file mode 100644
index 0000000000..42c42cef21
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_main_dev.c
@@ -0,0 +1,840 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_main_dev.c
+
+ Abstract:
+ Create and register network interface.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+
+#define RTMP_MODULE_OS
+
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rt_os_net.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#ifndef SA_SHIRQ
+#define SA_SHIRQ IRQF_SHARED
+#endif
+#endif
+
+// TODO: shiang-6590, remove it when MP
+// TODO: End---
+
+#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);
+
+
+
+
+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);
+
+
+#ifdef IFUP_IN_PROBE
+#else
+ VIRTUAL_IF_DOWN(pAd);
+#endif /* IFUP_IN_PROBE */
+
+ 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 */
+
+#ifdef CONFIG_AP_SUPPORT
+/* pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE; */
+ RTMP_DRIVER_AP_MAIN_OPEN(pAd);
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef IFUP_IN_PROBE
+ while (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) != NDIS_STATUS_SUCCESS)
+ {
+ OS_WAIT(10);
+ DBGPRINT(RT_DEBUG_TRACE, ("Card not ready, NDIS_STATUS_SUCCESS!\n"));
+ }
+#else
+ if (VIRTUAL_IF_UP(pAd) != 0)
+ return -1;
+#endif /* IFUP_IN_PROBE */
+
+ /* 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;
+
+ 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);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
+ return 0;
+}
+
+
+/*
+========================================================================
+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;
+
+
+
+ /* 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_MCU_SLEEP_CLEAR(pAd);
+
+ RTMP_DRIVER_OP_MODE_GET(pAd, &OpMode);
+
+
+
+#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 (RT_DEV_PRIV_FLAGS_GET(net_dev) == INT_MAIN) */
+ if (RTMP_DRIVER_MAIN_INF_CHECK(pAd, RT_DEV_PRIV_FLAGS_GET(net_dev)) == 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 */
+ }
+#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 WDS_SUPPORT
+ RT28xx_WDS_Init(pAd, net_dev);
+#endif /* WDS_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:
+/*+++move from rt28xx_init() to here. */
+/* RtmpOSIRQRelease(net_dev); */
+ RTMP_DRIVER_IRQ_RELEASE(pAd);
+/*---move from rt28xx_init() to here. */
+
+ return (-1);
+}
+
+
+PNET_DEV RtmpPhyNetDevInit(
+ IN VOID *pAd,
+ IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook)
+{
+ struct net_device *net_dev = NULL;
+ 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_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 */
+
+ /* put private data structure */
+ RTMP_OS_NETDEV_SET_PRIV(net_dev, pAd);
+
+ /* double-check if pAd is associated with the net_dev */
+ if (RTMP_OS_NETDEV_GET_PRIV(net_dev) == NULL)
+ {
+ RtmpOSNetDevFree(net_dev);
+ return NULL;
+ }
+
+ 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;
+ 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)
+{
+ 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(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 = RT_DEV_PRIV_FLAGS_GET(net_dev);
+ 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,
+ INOUT 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_AP_SUPPORT
+/* IF_DEV_CONFIG_OPMODE_ON_AP(pAd) */
+ RT_CONFIG_IF_OPMODE_ON_AP(OpMode)
+ {
+ ret = rt28xx_ap_ioctl(net_dev, rq, cmd);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ return ret;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ return ethernet statistics counter
+
+ Arguments:
+ net_dev Pointer to net_device
+
+ Return Value:
+ net_device_stats*
+
+ Note:
+
+ ========================================================================
+*/
+struct net_device_stats *RT28xx_get_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;
+
+
+ //assign net device for RTMP_DRIVER_INF_STATS_GET()
+ pDrvStats->pNetDev = net_dev;
+ 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 CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ /* remove all AP-client virtual interfaces. */
+ RT28xx_ApCli_Remove(pAd);
+#endif /* APCLI_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ /* remove all WDS virtual interfaces. */
+ RT28xx_WDS_Remove(pAd);
+#endif /* WDS_SUPPORT */
+
+#ifdef MBSS_SUPPORT
+ RT28xx_MBSS_Remove(pAd);
+#endif /* MBSS_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+#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;
+
+}
+
+#ifdef WDS_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ return ethernet statistics counter
+
+ Arguments:
+ net_dev Pointer to net_device
+
+ Return Value:
+ net_device_stats*
+
+ Note:
+
+ ========================================================================
+*/
+struct net_device_stats *RT28xx_get_wds_ether_stats(
+ IN PNET_DEV net_dev)
+{
+ VOID *pAd = NULL;
+/* INT WDS_apidx = 0,index; */
+ struct net_device_stats *pStats;
+ RT_CMD_STATS WdsStats, *pWdsStats = &WdsStats;
+
+ if (net_dev) {
+ GET_PAD_FROM_NET_DEV(pAd, net_dev);
+ }
+
+/* if (RT_DEV_PRIV_FLAGS_GET(net_dev) == INT_WDS) */
+ {
+ if (pAd)
+ {
+
+ pWdsStats->pNetDev = net_dev;
+ if (RTMP_COM_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_WDS_STATS_GET,
+ 0, pWdsStats, RT_DEV_PRIV_FLAGS_GET(net_dev)) != NDIS_STATUS_SUCCESS)
+ return NULL;
+
+ pStats = (struct net_device_stats *)pWdsStats->pStats; /*pAd->stats; */
+
+ pStats->rx_packets = pWdsStats->rx_packets; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.ReceivedFragmentCount.QuadPart; */
+ pStats->tx_packets = pWdsStats->tx_packets; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TransmittedFragmentCount.QuadPart; */
+
+ pStats->rx_bytes = pWdsStats->rx_bytes; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.ReceivedByteCount; */
+ pStats->tx_bytes = pWdsStats->tx_bytes; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TransmittedByteCount; */
+
+ pStats->rx_errors = pWdsStats->rx_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxErrors; */
+ pStats->tx_errors = pWdsStats->tx_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.TxErrors; */
+
+ pStats->rx_dropped = 0;
+ pStats->tx_dropped = 0;
+
+ pStats->multicast = pWdsStats->multicast; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.MulticastReceivedFrameCount.QuadPart; // multicast packets received */
+ pStats->collisions = pWdsStats->collisions; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.OneCollision + pAd->WdsTab.WdsEntry[index].WdsCounter.MoreCollisions; // Collision packets */
+
+ pStats->rx_length_errors = 0;
+ pStats->rx_over_errors = pWdsStats->rx_over_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxNoBuffer; // receiver ring buff overflow */
+ pStats->rx_crc_errors = 0;/*pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error */
+ pStats->rx_frame_errors = pWdsStats->rx_frame_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RcvAlignmentErrors; // recv'd frame alignment error */
+ pStats->rx_fifo_errors = pWdsStats->rx_fifo_errors; /*pAd->WdsTab.WdsEntry[WDS_apidx].WdsCounter.RxNoBuffer; // recv'r fifo overrun */
+ pStats->rx_missed_errors = 0; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ pStats->tx_aborted_errors = 0;
+ pStats->tx_carrier_errors = 0;
+ pStats->tx_fifo_errors = 0;
+ pStats->tx_heartbeat_errors = 0;
+ pStats->tx_window_errors = 0;
+
+ /* for cslip etc */
+ pStats->rx_compressed = 0;
+ pStats->tx_compressed = 0;
+
+ return pStats;
+ }
+ else
+ return NULL;
+ }
+/* else */
+/* return NULL; */
+}
+#endif /* WDS_SUPPORT */
+
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_proc.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_proc.c
new file mode 100644
index 0000000000..aeebcd1ecf
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_proc.c
@@ -0,0 +1,539 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rt_proc.c
+
+ Abstract:
+ Create and register proc file system for ralink device
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+#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
+extern BOOLEAN UpdateFromGlobal;
+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_Update, *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_Update_get(char *page, char **start, off_t off, int count,
+ int *eof, void *data_unused)
+{
+ sprintf(page, "%d\n", UpdateFromGlobal);
+ *eof = 1;
+ return strlen(page);
+}
+
+ssize_t video_Update_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);
+
+ UpdateFromGlobal = val;
+ }
+ return count;
+}
+
+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 = FALSE;
+ GLOBAL_AP_VIDEO_CONFIG.ClassifierEnable = FALSE;
+ GLOBAL_AP_VIDEO_CONFIG.HighTxMode = FALSE;
+ GLOBAL_AP_VIDEO_CONFIG.TxPwr = 0;
+ GLOBAL_AP_VIDEO_CONFIG.VideoMCSEnable = FALSE;
+ GLOBAL_AP_VIDEO_CONFIG.VideoMCS = 0;
+ GLOBAL_AP_VIDEO_CONFIG.TxBASize = 0;
+ GLOBAL_AP_VIDEO_CONFIG.TxLifeTimeMode = FALSE;
+ GLOBAL_AP_VIDEO_CONFIG.TxLifeTime = 0;
+ GLOBAL_AP_VIDEO_CONFIG.TxRetryLimit = 0;
+
+ 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_Update = create_proc_entry("UpdateFromGlobal", 0, proc_ralink_wl_video);
+ if (entry_wl_video_Update) {
+ entry_wl_video_Update->read_proc = (read_proc_t*)&video_Update_get;
+ entry_wl_video_Update->write_proc = (write_proc_t*)&video_Update_set;
+ }
+
+ entry_wl_video_Enable = create_proc_entry("Enable", 0, proc_ralink_wl_video);
+ if (entry_wl_video_Enable) {
+ entry_wl_video_Enable->read_proc = (read_proc_t*)&video_Enable_get;
+ entry_wl_video_Enable->write_proc = (write_proc_t*)&video_Enable_set;
+ }
+
+ entry_wl_video_ClassifierEnable = create_proc_entry("ClassifierEnable", 0, proc_ralink_wl_video);
+ if (entry_wl_video_ClassifierEnable) {
+ entry_wl_video_ClassifierEnable->read_proc = (read_proc_t*)&video_ClassifierEnable_get;
+ entry_wl_video_ClassifierEnable->write_proc = (write_proc_t*)&video_ClassifierEnable_set;
+ }
+
+ entry_wl_video_HighTxMode = create_proc_entry("HighTxMode", 0, proc_ralink_wl_video);
+ if (entry_wl_video_HighTxMode) {
+ entry_wl_video_HighTxMode->read_proc = (read_proc_t*)&video_HighTxMode_get;
+ entry_wl_video_HighTxMode->write_proc = (write_proc_t*)&video_HighTxMode_set;
+ }
+
+ entry_wl_video_TxPwr = create_proc_entry("TxPwr", 0, proc_ralink_wl_video);
+ if (entry_wl_video_TxPwr) {
+ entry_wl_video_TxPwr->read_proc = (read_proc_t*)&video_TxPwr_get;
+ entry_wl_video_TxPwr->write_proc = (write_proc_t*)&video_TxPwr_set;
+ }
+
+ entry_wl_video_VideoMCSEnable = create_proc_entry("VideoMCSEnable", 0, proc_ralink_wl_video);
+ if (entry_wl_video_VideoMCSEnable) {
+ entry_wl_video_VideoMCSEnable->read_proc = (read_proc_t*)&video_VideoMCSEnable_get;
+ entry_wl_video_VideoMCSEnable->write_proc = (write_proc_t*)&video_VideoMCSEnable_set;
+ }
+
+ entry_wl_video_VideoMCS = create_proc_entry("VideoMCS", 0, proc_ralink_wl_video);
+ if (entry_wl_video_VideoMCS) {
+ entry_wl_video_VideoMCS->read_proc = (read_proc_t*)&video_VideoMCS_get;
+ entry_wl_video_VideoMCS->write_proc = (write_proc_t*)&video_VideoMCS_set;
+ }
+
+ entry_wl_video_TxBASize = create_proc_entry("TxBASize", 0, proc_ralink_wl_video);
+ if (entry_wl_video_TxBASize) {
+ entry_wl_video_TxBASize->read_proc = (read_proc_t*)&video_TxBASize_get;
+ entry_wl_video_TxBASize->write_proc = (write_proc_t*)&video_TxBASize_set;
+ }
+ entry_wl_video_TxLifeTimeMode = create_proc_entry("TxLifeTimeMode", 0, proc_ralink_wl_video);
+ if (entry_wl_video_TxLifeTimeMode) {
+ entry_wl_video_TxLifeTimeMode->read_proc = (read_proc_t*)&video_TxLifeTimeMode_get;
+ entry_wl_video_TxLifeTimeMode->write_proc = (write_proc_t*)&video_TxLifeTimeMode_set;
+ }
+
+ entry_wl_video_TxLifeTime = create_proc_entry("TxLifeTime", 0, proc_ralink_wl_video);
+ if (entry_wl_video_TxLifeTime) {
+ entry_wl_video_TxLifeTime->read_proc = (read_proc_t*)&video_TxLifeTime_get;
+ entry_wl_video_TxLifeTime->write_proc = (write_proc_t*)&video_TxLifeTime_set;
+ }
+
+ entry_wl_video_TxRetryLimit = create_proc_entry("TxRetryLimit", 0, proc_ralink_wl_video);
+ if (entry_wl_video_TxRetryLimit) {
+ entry_wl_video_TxRetryLimit->read_proc = (read_proc_t*)&video_TxRetryLimit_get;
+ entry_wl_video_TxRetryLimit->write_proc = (write_proc_t*)&video_TxRetryLimit_set;
+ }
+ }
+
+ return 0;
+}
+
+int wl_video_proc_exit(void)
+{
+
+ if (entry_wl_video_Enable)
+ remove_proc_entry("Enable", proc_ralink_wl_video);
+
+ if (entry_wl_video_ClassifierEnable)
+ remove_proc_entry("ClassifierEnabl", proc_ralink_wl_video);
+
+ if (entry_wl_video_HighTxMode)
+ remove_proc_entry("HighTxMode", proc_ralink_wl_video);
+
+ if (entry_wl_video_TxPwr)
+ remove_proc_entry("TxPwr", proc_ralink_wl_video);
+
+ if (entry_wl_video_VideoMCSEnable)
+ remove_proc_entry("VideoMCSEnable", proc_ralink_wl_video);
+
+ if (entry_wl_video_VideoMCS)
+ remove_proc_entry("VideoMCS", proc_ralink_wl_video);
+
+ if (entry_wl_video_TxBASize)
+ remove_proc_entry("TxBASize", proc_ralink_wl_video);
+
+ if (entry_wl_video_TxLifeTimeMode)
+ remove_proc_entry("TxLifeTimeMode", proc_ralink_wl_video);
+
+ if (entry_wl_video_TxLifeTime)
+ remove_proc_entry("TxLifeTime", proc_ralink_wl_video);
+
+ if (entry_wl_video_TxRetryLimit)
+ remove_proc_entry("TxRetryLimit", proc_ralink_wl_video);
+
+ if (proc_ralink_wl_video)
+ remove_proc_entry("Video", proc_ralink_wl);
+
+ return 0;
+}
+#endif /* VIDEO_TURBINE_SUPPORT */
+
+int wl_proc_init(void)
+{
+ if (procRegDir == NULL)
+ procRegDir = proc_mkdir(PROCREG_DIR, NULL);
+
+ if (procRegDir) {
+#ifdef VIDEO_TURBINE_SUPPORT
+ wl_video_proc_init();
+#endif /* VIDEO_TURBINE_SUPPORT */
+ }
+
+ return 0;
+}
+
+int wl_proc_exit(void)
+{
+#ifdef VIDEO_TURBINE_SUPPORT
+ if (proc_ralink_wl_video) {
+ wl_video_proc_exit();
+ remove_proc_entry("Video", proc_ralink_wl);
+ }
+ if (proc_ralink_wl)
+ remove_proc_entry("wl", procRegDir);
+#endif /* VIDEO_TURBINE_SUPPORT */
+
+
+ return 0;
+}
+#else
+int wl_proc_init(void)
+{
+ return 0;
+}
+
+int wl_proc_exit(void)
+{
+
+ return 0;
+}
+#endif /* CONFIG_PROC_FS */
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_profile.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_profile.c
new file mode 100644
index 0000000000..cadf457028
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_profile.c
@@ -0,0 +1,857 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ****************************************************************************
+
+ Module Name:
+ rt_profile.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ */
+
+#include "rt_config.h"
+
+
+
+#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 */
+
+#ifdef WSC_INCLUDED
+/* for WSC wireless event message */
+char const *pWirelessWscEventText[IW_WSC_EVENT_TYPE_NUM] = {
+ "PBC Session Overlap", /* IW_WSC_PBC_SESSION_OVERLAP */
+ "This WPS Registrar supports PBC", /* IW_WSC_REGISTRAR_SUPPORT_PBC */
+ "This WPS Registrar supports PIN", /* IW_WSC_REGISTRAR_SUPPORT_PIN */
+ "WPS status success", /* IW_WSC_STATUS_SUCCESS */
+ "WPS status fail", /* IW_WSC_STATUS_FAIL */
+ "WPS 2 mins time out!", /* IW_WSC_2MINS_TIMEOUT */
+ "WPS Send EAPOL_Start!", /* IW_WSC_SEND_EAPOL_START */
+ "WPS Send WscStart!", /* IW_WSC_SEND_WSC_START */
+ "WPS Send M1!", /* IW_WSC_SEND_M1 */
+ "WPS Send M2!", /* IW_WSC_SEND_M2 */
+ "WPS Send M3!", /* IW_WSC_SEND_M3 */
+ "WPS Send M4!", /* IW_WSC_SEND_M4 */
+ "WPS Send M5!", /* IW_WSC_SEND_M5 */
+ "WPS Send M6!", /* IW_WSC_SEND_M6 */
+ "WPS Send M7!", /* IW_WSC_SEND_M7 */
+ "WPS Send M8!", /* IW_WSC_SEND_M8 */
+ "WPS Send WscDone!", /* IW_WSC_SEND_DONE */
+ "WPS Send WscAck!", /* IW_WSC_SEND_ACK */
+ "WPS Send WscNack!", /* IW_WSC_SEND_NACK */
+ "WPS Receive WscStart!", /* IW_WSC_RECEIVE_WSC_START */
+ "WPS Receive M1!", /* IW_WSC_RECEIVE_M1 */
+ "WPS Receive M2!", /* IW_WSC_RECEIVE_M2 */
+ "WPS Receive M3!", /* IW_WSC_RECEIVE_M3 */
+ "WPS Receive M4!", /* IW_WSC_RECEIVE_M4 */
+ "WPS Receive M5!", /* IW_WSC_RECEIVE_M5 */
+ "WPS Receive M6!", /* IW_WSC_RECEIVE_M6 */
+ "WPS Receive M7!", /* IW_WSC_RECEIVE_M7 */
+ "WPS Receive M8!", /* IW_WSC_RECEIVE_M8 */
+ "WPS Receive WscDone!", /* IW_WSC_RECEIVE_DONE */
+ "WPS Receive WscAck!", /* IW_WSC_RECEIVE_ACK */
+ "WPS Receive WscNack!", /* IW_WSC_RECEIVE_NACK */
+ "Not only one candidate found" /* IW_WSC_MANY_CANDIDATE */
+ };
+#endif /* WSC_INCLUDED */
+
+#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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ src = AP_PROFILE_PATH;
+ }
+#endif /* CONFIG_AP_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 */
+
+#ifdef SINGLE_SKU_V2
+ RTMPSetSingleSKUParameters(pAd);
+#endif /* SINGLE_SKU_V2 */
+
+/* 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 */
+#ifdef WSC_INCLUDED
+ case IW_WSC_EVENT_FLAG_START:
+ event_table_len = IW_WSC_EVENT_TYPE_NUM;
+ break;
+#endif /* WSC_INCLUDED */
+ }
+
+ 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 */
+#ifdef WSC_INCLUDED
+ else if (type == IW_WSC_EVENT_FLAG_START)
+ pBufPtr += sprintf(pBufPtr, "%s", pWirelessWscEventText[event]);
+#endif /* WSC_INCLUDED */
+ 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 */
+}
+
+
+void tbtt_tasklet(unsigned long data)
+{
+#ifdef CONFIG_AP_SUPPORT
+#ifdef WORKQUEUE_BH
+ struct work_struct *work = (struct work_struct *)data;
+ POS_COOKIE pObj = container_of(work, struct os_cookie, tbtt_task);
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pObj->pAd_va;
+#else
+ PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)data;
+#endif /* WORKQUEUE_BH */
+
+
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ /* step 7 - if DTIM, then move backlogged bcast/mcast frames from PSQ to TXQ whenever DtimCount==0 */
+#ifdef RTMP_MAC_USB
+ if ((pAd->ApCfg.DtimCount + 1) == pAd->ApCfg.DtimPeriod)
+#endif /* RTMP_MAC_USB */
+ {
+ PQUEUE_ENTRY pEntry;
+ BOOLEAN bPS = FALSE;
+ UINT count = 0;
+ unsigned long IrqFlags;
+
+/* NdisAcquireSpinLock(&pAd->MacTabLock); */
+/* NdisAcquireSpinLock(&pAd->TxSwQueueLock); */
+
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ while (pAd->MacTab.McastPsQueue.Head)
+ {
+ bPS = TRUE;
+ if (pAd->TxSwQueue[QID_AC_BE].Number <= (pAd->TxSwQMaxLen + MAX_PACKETS_IN_MCAST_PS_QUEUE))
+ {
+ pEntry = RemoveHeadQueue(&pAd->MacTab.McastPsQueue);
+ /*if(pAd->MacTab.McastPsQueue.Number) */
+ if (count)
+ {
+ RTMP_SET_PACKET_MOREDATA(pEntry, TRUE);
+ }
+ InsertHeadQueue(&pAd->TxSwQueue[QID_AC_BE], pEntry);
+ count++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+
+/* NdisReleaseSpinLock(&pAd->TxSwQueueLock); */
+/* NdisReleaseSpinLock(&pAd->MacTabLock); */
+ if (pAd->MacTab.McastPsQueue.Number == 0)
+ {
+ UINT bss_index;
+
+ /* clear MCAST/BCAST backlog bit for all BSS */
+ for(bss_index=BSS0; bss_index<pAd->ApCfg.BssidNum; bss_index++)
+ WLAN_MR_TIM_BCMC_CLEAR(bss_index);
+ }
+ pAd->MacTab.PsQIdleCount = 0;
+
+ /* Dequeue outgoing framea from TxSwQueue0..3 queue and process it */
+ if (bPS == TRUE)
+ {
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, /*MAX_TX_IN_TBTT*/MAX_PACKETS_IN_MCAST_PS_QUEUE);
+ }
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+}
+
+
+void announce_802_3_packet(
+ IN VOID *pAdSrc,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR OpMode)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pAdSrc;
+ PNDIS_PACKET pRxPkt = pPacket;
+
+ ASSERT(pPacket);
+ MEM_DBG_PKT_FREE_INC(pPacket);
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef APCLI_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (RTMP_MATPktRxNeedConvert(pAd, RtmpOsPktNetDevGet(pRxPkt)))
+ RTMP_MATEngineRxHandle(pAd, pRxPkt, 0);
+ }
+#endif /* APCLI_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ /* Push up the protocol stack */
+#ifdef CONFIG_AP_SUPPORT
+#ifdef PLATFORM_BL2348
+{
+ extern int (*pToUpperLayerPktSent)(PNDIS_PACKET *pSkb);
+ RtmpOsPktProtocolAssign(pRxPkt);
+ pToUpperLayerPktSent(pRxPkt);
+ return;
+}
+#endif /* PLATFORM_BL2348 */
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef IKANOS_VX_1X0
+{
+ IKANOS_DataFrameRx(pAd, pRxPkt);
+ return;
+}
+#endif /* IKANOS_VX_1X0 */
+
+#ifdef INF_PPA_SUPPORT
+ if (ppa_hook_directpath_send_fn && pAd->PPAEnable==TRUE )
+ {
+ RtmpOsPktInfPpaSend(pRxPkt);
+ pRxPkt=NULL;
+ return;
+ }
+#endif /* INF_PPA_SUPPORT */
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef BG_FT_SUPPORT
+ if (BG_FTPH_PacketFromApHandle(pRxPkt) == 0)
+ return;
+#endif /* BG_FT_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+//+++Add by shiang for debug
+if (0) {
+ hex_dump("announce_802_3_packet", GET_OS_PKT_DATAPTR(pRxPkt), GET_OS_PKT_LEN(pRxPkt));
+}
+//---Add by shiang for debug
+
+ RtmpOsPktProtocolAssign(pRxPkt);
+ RtmpOsPktRcvHandle(pRxPkt);
+}
+
+
+
+
+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 UAPSD_SUPPORT
+ NdisFreeSpinLock(&pAd->UAPSDEOSPLock); /* OS_ABL_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+#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);
+
+#ifdef RALINK_ATE
+#ifdef RTMP_MAC_USB
+ RTMP_OS_ATMOIC_DESTROY(&pAd->BulkOutRemained);
+ RTMP_OS_ATMOIC_DESTROY(&pAd->BulkInRemained);
+#endif /* RTMP_MAC_USB */
+#endif /* RALINK_ATE */
+
+ 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);
+}
+
+
+int RTMPSendPackets(
+ IN NDIS_HANDLE dev_hnd,
+ IN PPNDIS_PACKET ppPacketArray,
+ IN UINT NumberOfPackets,
+ IN UINT32 PktTotalLen,
+ IN RTMP_NET_ETH_CONVERT_DEV_SEARCH Func)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)dev_hnd;
+ PNDIS_PACKET pPacket = ppPacketArray[0];
+
+
+ INC_COUNTER64(pAd->WlanCounters.TransmitCountFrmOs);
+
+ 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 */
+
+
+ /* 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ APSendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
+#endif /* CONFIG_AP_SUPPORT */
+
+
+done:
+ return 0;
+}
+
+
+PNET_DEV get_netdev_from_bssid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR FromWhichBSSID)
+{
+ PNET_DEV dev_p = NULL;
+#ifdef CONFIG_AP_SUPPORT
+ UCHAR infRealIdx;
+#endif /* CONFIG_AP_SUPPORT */
+
+ do
+ {
+#ifdef CONFIG_AP_SUPPORT
+ infRealIdx = FromWhichBSSID & (NET_DEVICE_REAL_IDX_MASK);
+#ifdef APCLI_SUPPORT
+ if(FromWhichBSSID >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ dev_p = (infRealIdx >= MAX_APCLI_NUM ? NULL : pAd->ApCfg.ApCliTab[infRealIdx].dev);
+ break;
+ }
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if(FromWhichBSSID >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ dev_p = ((infRealIdx >= MAX_WDS_ENTRY) ? NULL : pAd->WdsTab.WdsEntry[infRealIdx].dev);
+ break;
+ }
+#endif /* WDS_SUPPORT */
+
+ if ((FromWhichBSSID > 0) &&
+ (FromWhichBSSID < pAd->ApCfg.BssidNum) &&
+ (FromWhichBSSID < MAX_MBSSID_NUM(pAd)) &&
+ (FromWhichBSSID < HW_BEACON_MAX_NUM))
+ {
+ dev_p = pAd->ApCfg.MBSSID[FromWhichBSSID].MSSIDDev;
+ }
+ else
+#endif /* CONFIG_AP_SUPPORT */
+ {
+ dev_p = pAd->net_dev;
+ }
+
+ } while (FALSE);
+
+ ASSERT(dev_p);
+ return dev_p; /* return one of MBSS */
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Driver pre-Ioctl for AP.
+
+Arguments:
+ pAdSrc - WLAN control block pointer
+ pCB - the IOCTL parameters
+
+Return Value:
+ NDIS_STATUS_SUCCESS - IOCTL OK
+ Otherwise - IOCTL fail
+
+Note:
+========================================================================
+*/
+INT RTMP_AP_IoctlPrepare(
+ IN RTMP_ADAPTER *pAd,
+ IN VOID *pCB)
+{
+ RT_CMD_AP_IOCTL_CONFIG *pConfig = (RT_CMD_AP_IOCTL_CONFIG *)pCB;
+ POS_COOKIE pObj;
+ USHORT index;
+ INT Status = NDIS_STATUS_SUCCESS;
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ INT cmd = 0xff;
+#endif /* CONFIG_APSTA_MIXED_SUPPORT */
+
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if((pConfig->priv_flags == INT_MAIN) && !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ if (pConfig->pCmdData == NULL)
+ return Status;
+
+ if (RtPrivIoctlSetVal() == pConfig->CmdId_RTPRIV_IOCTL_SET)
+ {
+ if (TRUE
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ && (strstr(pConfig->pCmdData, "OpMode") == NULL)
+#endif /* CONFIG_APSTA_MIXED_SUPPORT */
+#ifdef SINGLE_SKU
+ && (strstr(pConfig->pCmdData, "ModuleTxpower") == NULL)
+#endif /* SINGLE_SKU */
+ )
+
+ {
+ return -ENETDOWN;
+ }
+ }
+ else
+ return -ENETDOWN;
+ }
+
+ /* determine this ioctl command is comming from which interface. */
+ if (pConfig->priv_flags == INT_MAIN)
+ {
+ pObj->ioctl_if_type = INT_MAIN;
+ pObj->ioctl_if = MAIN_MBSSID;
+/* DBGPRINT(RT_DEBUG_INFO, ("rt28xx_ioctl I/F(ra%d)(flags=%d): cmd = 0x%08x\n", pObj->ioctl_if, RT_DEV_PRIV_FLAGS_GET(net_dev), cmd)); */
+ }
+ else if (pConfig->priv_flags == INT_MBSSID)
+ {
+ pObj->ioctl_if_type = INT_MBSSID;
+/* if (!RTMPEqualMemory(net_dev->name, pAd->net_dev->name, 3)) // for multi-physical card, no MBSSID */
+ if (strcmp(pConfig->name, RtmpOsGetNetDevName(pAd->net_dev)) != 0) /* sample */
+ {
+ for (index = 1; index < pAd->ApCfg.BssidNum; index++)
+ {
+ if (pAd->ApCfg.MBSSID[index].MSSIDDev == pConfig->net_dev)
+ {
+ pObj->ioctl_if = index;
+
+/* DBGPRINT(RT_DEBUG_INFO, ("rt28xx_ioctl I/F(ra%d)(flags=%d): cmd = 0x%08x\n", index, RT_DEV_PRIV_FLAGS_GET(net_dev), cmd)); */
+ break;
+ }
+ }
+ /* Interface not found! */
+ if(index == pAd->ApCfg.BssidNum)
+ {
+/* DBGPRINT(RT_DEBUG_ERROR, ("rt28xx_ioctl can not find I/F\n")); */
+ return -ENETDOWN;
+ }
+ }
+ else /* ioctl command from I/F(ra0) */
+ {
+/* GET_PAD_FROM_NET_DEV(pAd, net_dev); */
+ pObj->ioctl_if = MAIN_MBSSID;
+/* DBGPRINT(RT_DEBUG_ERROR, ("rt28xx_ioctl can not find I/F and use default: cmd = 0x%08x\n", cmd)); */
+ }
+ MBSS_MR_APIDX_SANITY_CHECK(pAd, pObj->ioctl_if);
+ }
+#ifdef WDS_SUPPORT
+ else if (pConfig->priv_flags == INT_WDS)
+ {
+ pObj->ioctl_if_type = INT_WDS;
+ for(index = 0; index < MAX_WDS_ENTRY; index++)
+ {
+ if (pAd->WdsTab.WdsEntry[index].dev == pConfig->net_dev)
+ {
+ pObj->ioctl_if = index;
+
+ break;
+ }
+
+ if(index == MAX_WDS_ENTRY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("rt28xx_ioctl can not find wds I/F\n"));
+ return -ENETDOWN;
+ }
+ }
+ }
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ else if (pConfig->priv_flags == INT_APCLI)
+ {
+ pObj->ioctl_if_type = INT_APCLI;
+ for (index = 0; index < MAX_APCLI_NUM; index++)
+ {
+ if (pAd->ApCfg.ApCliTab[index].dev == pConfig->net_dev)
+ {
+ pObj->ioctl_if = index;
+
+ break;
+ }
+
+ if(index == MAX_APCLI_NUM)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("rt28xx_ioctl can not find Apcli I/F\n"));
+ return -ENETDOWN;
+ }
+ }
+ APCLI_MR_APIDX_SANITY_CHECK(pObj->ioctl_if);
+ }
+#endif /* APCLI_SUPPORT */
+ else
+ {
+/* DBGPRINT(RT_DEBUG_WARN, ("IOCTL is not supported in WDS interface\n")); */
+ return -EOPNOTSUPP;
+ }
+
+ pConfig->apidx = pObj->ioctl_if;
+ return Status;
+}
+
+
+VOID AP_E2PROM_IOCTL_PostCtrl(
+ IN RTMP_IOCTL_INPUT_STRUCT *wrq,
+ IN PSTRING msg)
+{
+ 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__));
+ }
+}
+
+
+VOID IAPP_L2_UpdatePostCtrl(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 *mac_p,
+ IN INT bssid)
+{
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+//#ifdef WDS_SUPPORT
+VOID AP_WDS_KeyNameMakeUp(
+ IN STRING *pKey,
+ IN UINT32 KeyMaxSize,
+ IN INT KeyId)
+{
+ snprintf(pKey, KeyMaxSize, "Wds%dKey", KeyId);
+}
+//#endif /* WDS_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_rbus_pci_drv.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_rbus_pci_drv.c
new file mode 100644
index 0000000000..9b216e3270
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_rbus_pci_drv.c
@@ -0,0 +1,16 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_symb.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_symb.c
new file mode 100644
index 0000000000..9b2b1e71f4
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_symb.c
@@ -0,0 +1,9 @@
+#ifdef OS_ABL_SUPPORT
+
+#include <linux/module.h>
+#include "rt_config.h"
+
+EXPORT_SYMBOL(RTMP_DRV_OPS_FUNCTION);
+
+#endif /* OS_ABL_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_usb.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_usb.c
new file mode 100644
index 0000000000..bbc7fefde3
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_usb.c
@@ -0,0 +1,1314 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2006, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ rtusb_bulk.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+
+*/
+
+#include "rt_config.h"
+
+
+/*
+========================================================================
+Routine Description:
+ Create kernel threads & tasklets.
+
+Arguments:
+ *net_dev Pointer to wireless net device interface
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+
+Note:
+========================================================================
+*/
+NDIS_STATUS RtmpMgmtTaskInit(
+ IN RTMP_ADAPTER *pAd)
+{
+ RTMP_OS_TASK *pTask;
+ NDIS_STATUS status;
+
+ /*
+ Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
+ */
+ RtmpTimerQInit(pAd);
+
+ pTask = &pAd->timerTask;
+ RTMP_OS_TASK_INIT(pTask, "RtmpTimerTask", pAd);
+ status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, (ULONG)pTask);
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ printk (KERN_WARNING "%s: unable to start RtmpTimerQThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ /* Creat MLME Thread */
+ pTask = &pAd->mlmeTask;
+ RTMP_OS_TASK_INIT(pTask, "RtmpMlmeTask", pAd);
+ status = RtmpOSTaskAttach(pTask, MlmeThread, (ULONG)pTask);
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ printk (KERN_WARNING "%s: unable to start MlmeThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ /* Creat Command Thread */
+ pTask = &pAd->cmdQTask;
+ RTMP_OS_TASK_INIT(pTask, "RtmpCmdQTask", pAd);
+ status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, (ULONG)pTask);
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ printk (KERN_WARNING "%s: unable to start RTUSBCmdThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifdef WSC_INCLUDED
+ /* start the crediential write task first. */
+ WscThreadInit(pAd);
+#endif /* WSC_INCLUDED */
+
+ 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"));
+ }
+
+#ifdef WSC_INCLUDED
+ WscThreadExit(pAd);
+#endif /* WSC_INCLUDED */
+
+}
+
+
+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); */
+
+#ifdef UAPSD_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ UAPSD_UnTagFrame(pAd, BulkOutPipeId, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+ }
+ 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)); */
+
+ }
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MultiChannelFlowCtl & (1 << BulkOutPipeId)) == (1 << BulkOutPipeId))
+ return;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ /* */
+ /* 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);
+#ifdef CONFIG_MULTI_CHANNEL
+ if (pAd->Multi_Channel_Enable == TRUE)
+ pAd->bulkResetPipeid = (0 | BULKOUT_MGMT_RESET_FLAG);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+ 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);
+}
+
+
+#ifdef CONFIG_MULTI_CHANNEL
+static void rtusb_hcca_null_frame_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pNullContext;
+ purbb_t pUrb;
+ NTSTATUS Status;
+ unsigned long irqFlag;
+ UCHAR BulkOutPipeId;
+
+ pUrb = (purbb_t)data;
+ pNullContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb);
+ Status = RTMP_USB_URB_STATUS_GET(pUrb);
+ pAd = pNullContext->pAd;
+ BulkOutPipeId = pNullContext->BulkOutPipeId;
+/* Status = pUrb->status; */
+
+ /* Reset Null frame context flags */
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], irqFlag);
+ pNullContext->IRPPending = FALSE;
+ pNullContext->InUse = FALSE;
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], 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 = (BulkOutPipeId | BULKOUT_MGMT_RESET_FLAG);
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], irqFlag);
+ RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], irqFlag);
+ }
+
+ /* Always call Bulk routine, even reset bulk. */
+ /* The protectioon of rest bulk should be in BulkOut routine */
+ RTUSBKickBulkOut(pAd);
+}
+
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+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);
+#ifdef CONFIG_MULTI_CHANNEL
+ if (pAd->Multi_Channel_Enable == TRUE)
+ pAd->bulkResetPipeid = (0 | BULKOUT_MGMT_RESET_FLAG);
+ else
+#endif /* CONFIG_MULTI_CHANNEL */
+ 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); */
+ if ( pAd->PendingRx > 0 )
+ 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;
+
+}
+
+
+#ifdef RLT_MAC
+static void cmd_rsp_event_tasklet(unsigned long data)
+{
+ purbb_t pUrb;
+ PCMD_RSP_CONTEXT pCmdRspEventContext;
+ PRTMP_ADAPTER pAd;
+ NTSTATUS Status;
+ unsigned int IrqFlags;
+
+ pUrb = (purbb_t)data;
+ pCmdRspEventContext = (PRX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb);
+ Status = RTMP_USB_URB_STATUS_GET(pUrb);
+ pAd = pCmdRspEventContext->pAd;
+
+ RTMP_IRQ_LOCK(&pAd->CmdRspLock, IrqFlags);
+ pCmdRspEventContext->IRPPending = FALSE;
+ pCmdRspEventContext->InUse = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMP_IRQ_LOCK(&pAd->CmdRspLock, IrqFlags);
+ pCmdRspEventContext->Readable = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+
+ }
+ else
+ {
+ RTMP_IRQ_LOCK(&pAd->CmdRspLock, IrqFlags);
+ pCmdRspEventContext->Readable = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->CmdRspLock, IrqFlags);
+ }
+
+ RTUSBBulkCmdRspEventReceive(pAd);
+}
+#endif /* RLT_MAC */
+
+
+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);
+
+
+#ifdef UAPSD_SUPPORT
+ /* Qos Null frame with EOSP shall have valid Wcid value. reference RtmpUSBMgmtKickOut() API. */
+ /* otherwise will be value of MCAST_WCID. */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ /* Qos Null frame with EOSP shall have valid Wcid value. reference RtmpUSBMgmtKickOut() API. */
+ /* otherwise will be value of MCAST_WCID. */
+ if ((pMLMEContext->Wcid != MCAST_WCID) && (pMLMEContext->Wcid < MAX_LEN_OF_MAC_TABLE))
+ {
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[pMLMEContext->Wcid];
+
+ UAPSD_SP_Close(pAd, pEntry);
+ pMLMEContext->Wcid = MCAST_WCID;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* UAPSD_SUPPORT */
+
+
+ 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);
+ }
+ }
+
+
+}
+
+
+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);
+ }
+
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MultiChannelFlowCtl & (1 << BulkOutPipeId)) == (1 << BulkOutPipeId))
+ return;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ 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);
+ }
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MultiChannelFlowCtl & (1 << BulkOutPipeId)) == (1 << BulkOutPipeId))
+ return;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ 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);
+ }
+
+#ifdef CONFIG_MULTI_CHANNEL
+ if ((pAd->MultiChannelFlowCtl & (1 << BulkOutPipeId)) == (1 << BulkOutPipeId))
+ return;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ 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)
+ {
+#ifdef RELASE_EXCLUDE
+ /*
+ 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.
+ */
+#endif /* RELASE_EXCLUDE */
+ RTMPusecDelay(10);
+ 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_INFO, ("pNullContext->pAd = 0x%lx\n", (ULONG)&pNullContext->pAd));
+ DBGPRINT(RT_DEBUG_INFO, ("pNullContext->pUrb = 0x%lx\n", (ULONG)&pNullContext->pUrb));
+ DBGPRINT(RT_DEBUG_INFO, ("pNullContext->TransferBuffer = 0x%lx\n", (ULONG)&pNullContext->TransferBuffer));
+ DBGPRINT(RT_DEBUG_INFO, ("pNullContext->BulkOutPipeId = %d\n", pNullContext->BulkOutPipeId));
+ DBGPRINT(RT_DEBUG_INFO, ("pNullContext->BulkOutSize = %ld\n", pNullContext->BulkOutSize));
+ DBGPRINT(RT_DEBUG_INFO, ("pNullContext->InUse = %d\n", (pNullContext->InUse==TRUE)));
+ DBGPRINT(RT_DEBUG_INFO, ("pNullContext->bWaitingBulkOut = %d\n", (pNullContext->bWaitingBulkOut==TRUE)));
+ DBGPRINT(RT_DEBUG_INFO, ("pNullContext->IRPPending = %d\n", (pNullContext->IRPPending==TRUE)));
+ DBGPRINT(RT_DEBUG_INFO, ("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);
+#ifdef RLT_MAC
+ RTMP_OS_TASKLET_INIT(pAd, &pObj->cmd_rsp_event_task, cmd_rsp_event_tasklet, (ULONG)pAd);
+#endif /* RLT_MAC */
+ 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);
+#ifdef CONFIG_MULTI_CHANNEL
+ RTMP_OS_TASKLET_INIT(pAd, &pObj->hcca_null_frame_complete_task, rtusb_hcca_null_frame_done_tasklet, (unsigned long)pAd);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+ 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);
+#ifdef RLT_MAC
+ RTMP_OS_TASKLET_KILL(&pObj->cmd_rsp_event_task);
+#endif /* RLT_MAC */
+ 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);
+#ifdef CONFIG_MULTI_CHANNEL
+ RTMP_OS_TASKLET_KILL(&pObj->hcca_null_frame_complete_task);
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ RTMP_OS_TASKLET_KILL(&pObj->pspoll_frame_complete_task);
+}
+
+
+/*
+========================================================================
+Routine Description:
+ MLME kernel thread.
+
+Arguments:
+ *Context the pAd, driver control block pointer
+
+Return Value:
+ 0 close the thread
+
+Note:
+========================================================================
+*/
+INT MlmeThread(
+ IN ULONG Context)
+{
+ RTMP_ADAPTER *pAd;
+ RTMP_OS_TASK *pTask;
+ int status;
+ status = 0;
+
+ pTask = (RTMP_OS_TASK *)Context;
+ pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask);
+ if (pAd == NULL)
+ goto LabelExit; /* avoid compile warning */
+
+ RtmpOSTaskCustomize(pTask);
+
+ while(!RTMP_OS_TASK_IS_KILLED(pTask))
+ {
+ if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+
+ /* lock the device pointers , need to check if required*/
+ /*down(&(pAd->usbdev_semaphore)); */
+
+ if (!pAd->PM_FlgSuspend)
+ MlmeHandler(pAd);
+ }
+
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+LabelExit:
+ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+ RtmpOSTaskNotifyToExit(pTask);
+ return 0;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ USB command kernel thread.
+
+Arguments:
+ *Context the pAd, driver control block pointer
+
+Return Value:
+ 0 close the thread
+
+Note:
+========================================================================
+*/
+INT RTUSBCmdThread(
+ IN ULONG Context)
+{
+ RTMP_ADAPTER *pAd;
+ RTMP_OS_TASK *pTask;
+ int status;
+ status = 0;
+
+ pTask = (RTMP_OS_TASK *)Context;
+ pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask);
+
+ if (pAd == NULL)
+ return 0;
+
+ RtmpOSTaskCustomize(pTask);
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ while (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING)
+ {
+ if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+
+ if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
+ break;
+
+ if (!pAd->PM_FlgSuspend)
+ CMDHandler(pAd);
+ }
+
+ if (!pAd->PM_FlgSuspend)
+ { /* Clear the CmdQElements. */
+ CmdQElmt *pCmdQElmt = NULL;
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
+ while(pAd->CmdQ.size)
+ {
+ RTThreadDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
+ if (pCmdQElmt)
+ {
+ if (pCmdQElmt->CmdFromNdis == TRUE)
+ {
+ if (pCmdQElmt->buffer != NULL)
+ os_free_mem(pAd, pCmdQElmt->buffer);
+ os_free_mem(pAd, (PUCHAR)pCmdQElmt);
+ }
+ else
+ {
+ if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
+ os_free_mem(pAd, pCmdQElmt->buffer);
+ os_free_mem(pAd, (PUCHAR)pCmdQElmt);
+ }
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+ }
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+ DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
+
+ RtmpOSTaskNotifyToExit(pTask);
+ return 0;
+
+}
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/rt_usb_util.c b/cleopatre/devkit/mt7601udrv/os/linux/rt_usb_util.c
new file mode 100644
index 0000000000..de7a785f10
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/rt_usb_util.c
@@ -0,0 +1,603 @@
+/****************************************************************************
+
+ Module Name:
+ rt_usb_util.c
+
+ Abstract:
+ Any utility is used in UTIL module for USB function.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+
+***************************************************************************/
+
+#define RTMP_MODULE_OS
+#define RTMP_MODULE_OS_UTIL
+
+#include "rtmp_comm.h"
+#include "rtmp_osabl.h"
+#include "rt_os_util.h"
+
+#ifdef RTMP_MAC_USB
+#ifdef OS_ABL_SUPPORT
+MODULE_LICENSE("GPL");
+#endif /* OS_ABL_SUPPORT */
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+/*
+========================================================================
+Routine Description:
+ Dump URB information.
+
+Arguments:
+ purb_org - the URB
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+void dump_urb(VOID *purb_org)
+{
+ struct urb *purb = (struct urb *)purb_org;
+
+ printk("urb :0x%08lx\n", (unsigned long)purb);
+ printk("\tdev :0x%08lx\n", (unsigned long)purb->dev);
+ printk("\t\tdev->state :0x%d\n", purb->dev->state);
+ printk("\tpipe :0x%08x\n", purb->pipe);
+ printk("\tstatus :%d\n", purb->status);
+ printk("\ttransfer_flags :0x%08x\n", purb->transfer_flags);
+ printk("\ttransfer_buffer :0x%08lx\n", (unsigned long)purb->transfer_buffer);
+ printk("\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length);
+ printk("\tactual_length :%d\n", purb->actual_length);
+ printk("\tsetup_packet :0x%08lx\n", (unsigned long)purb->setup_packet);
+ printk("\tstart_frame :%d\n", purb->start_frame);
+ printk("\tnumber_of_packets :%d\n", purb->number_of_packets);
+ printk("\tinterval :%d\n", purb->interval);
+ printk("\terror_count :%d\n", purb->error_count);
+ printk("\tcontext :0x%08lx\n", (unsigned long)purb->context);
+ printk("\tcomplete :0x%08lx\n\n", (unsigned long)purb->complete);
+}
+#else
+void dump_urb(VOID *purb_org)
+{
+ return;
+}
+#endif /* LINUX_VERSION_CODE */
+
+
+
+
+
+
+#ifdef OS_ABL_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Register a USB driver.
+
+Arguments:
+ new_driver - the driver
+
+Return Value:
+ 0 - successfully
+ Otherwise - fail
+
+Note:
+========================================================================
+*/
+int rausb_register(VOID * new_driver)
+{
+ return usb_register((struct usb_driver *)new_driver);
+}
+EXPORT_SYMBOL(rausb_register);
+
+
+/*
+========================================================================
+Routine Description:
+ De-Register a USB driver.
+
+Arguments:
+ new_driver - the driver
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+void rausb_deregister(VOID * driver)
+{
+ usb_deregister((struct usb_driver *)driver);
+}
+EXPORT_SYMBOL(rausb_deregister);
+
+
+/*
+========================================================================
+Routine Description:
+ Create a new urb for a USB driver to use.
+
+Arguments:
+ iso_packets - number of iso packets for this urb
+
+Return Value:
+ the URB
+
+Note:
+========================================================================
+*/
+struct urb *rausb_alloc_urb(int iso_packets)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ return usb_alloc_urb(iso_packets, GFP_ATOMIC);
+#else
+ return usb_alloc_urb(iso_packets);
+#endif /* LINUX_VERSION_CODE */
+}
+EXPORT_SYMBOL(rausb_alloc_urb);
+
+
+/*
+========================================================================
+Routine Description:
+ Free the memory used by a urb.
+
+Arguments:
+ urb - the URB
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+void rausb_free_urb(VOID *urb)
+{
+ usb_free_urb((struct urb *)urb);
+}
+EXPORT_SYMBOL(rausb_free_urb);
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+/*
+========================================================================
+Routine Description:
+ Release a use of the usb device structure.
+
+Arguments:
+ dev - the USB device
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+void rausb_put_dev(VOID *dev)
+{
+ usb_put_dev((struct usb_device *)dev);
+}
+EXPORT_SYMBOL(rausb_put_dev);
+
+
+/*
+========================================================================
+Routine Description:
+ Increments the reference count of the usb device structure.
+
+Arguments:
+ dev - the USB device
+
+Return Value:
+ the device with the incremented reference counter
+
+Note:
+========================================================================
+*/
+struct usb_device *rausb_get_dev(VOID *dev)
+{
+ return usb_get_dev((struct usb_device *)dev);
+}
+EXPORT_SYMBOL(rausb_get_dev);
+#endif /* LINUX_VERSION_CODE */
+
+
+/*
+========================================================================
+Routine Description:
+ Issue an asynchronous transfer request for an endpoint.
+
+Arguments:
+ urb - the URB
+
+Return Value:
+ 0 - successfully
+ Otherwise - fail
+
+Note:
+========================================================================
+*/
+int rausb_submit_urb(VOID *urb)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ return usb_submit_urb((struct urb *)urb, GFP_ATOMIC);
+#else
+ return usb_submit_urb((struct urb *)urb);
+#endif /* LINUX_VERSION_CODE */
+}
+EXPORT_SYMBOL(rausb_submit_urb);
+
+/*
+========================================================================
+Routine Description:
+ Allocate dma-consistent buffer.
+
+Arguments:
+ dev - the USB device
+ size - buffer size
+ dma - used to return DMA address of buffer
+
+Return Value:
+ a buffer that may be used to perform DMA to the specified device
+
+Note:
+========================================================================
+*/
+void *rausb_buffer_alloc(VOID *dev,
+ size_t size,
+ ra_dma_addr_t *dma)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ 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)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ dma_addr_t DmaAddr = (dma_addr_t)(dma);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
+ usb_free_coherent(dev, size, addr, DmaAddr);
+#else
+ usb_buffer_free(dev, size, addr, DmaAddr);
+#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 *pPendingRx)
+{
+ 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 (*pPendingRx == 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;
+ dma_addr_t DmaAddr = (dma_addr_t)(TransferDma);
+
+
+ ASSERT(pUrb);
+
+ /*Initialize a tx bulk urb */
+ RTUSB_FILL_HTTX_BULK_URB(pUrb,
+ pUsb_Dev,
+ BulkOutEpAddr,
+ pSrc,
+ BulkOutSize,
+ (usb_complete_t)Func,
+ pTxContext,
+ DmaAddr);
+}
+
+
+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;
+ dma_addr_t DmaAddr = (dma_addr_t)(TransferDma);
+
+
+ ASSERT(pUrb);
+
+ /*Initialize a rx bulk urb */
+ RTUSB_FILL_RX_BULK_URB(pUrb,
+ pUsb_Dev,
+ BulkInEpAddr,
+ pTransferBuffer,
+ BufSize,
+ (usb_complete_t)Func,
+ pRxContext,
+ DmaAddr);
+}
+
+
+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 */
+
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/unload b/cleopatre/devkit/mt7601udrv/os/linux/unload
new file mode 100644
index 0000000000..cf698b0cd6
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/unload
@@ -0,0 +1,2 @@
+ifconfig ra0 down
+rmmod rt2860ap
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/usb_main_dev.c b/cleopatre/devkit/mt7601udrv/os/linux/usb_main_dev.c
new file mode 100644
index 0000000000..401a7bd51d
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/usb_main_dev.c
@@ -0,0 +1,846 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+#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_LICENSE("GPL");
+MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
+MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
+
+
+
+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;
+ ULONG BulkInIdx;
+ 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;
+ BulkInIdx = 0;
+
+ for(i=0; i<pConfig->NumberOfPipes; i++)
+ {
+ if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
+ ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+ {
+ pConfig->BulkInEpAddr[BulkInIdx++] = 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;
+ ULONG BulkInIdx;
+ 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;
+ BulkInIdx = 0;
+
+ for (i = 0; i < pConfig->NumberOfPipes; 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))
+ {
+ if (BulkInIdx < 2)
+ {
+ pConfig->BulkInEpAddr[BulkInIdx++] = 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
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Bulk IN endpoint nums large than 2\n"));
+ }
+ }
+ 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))
+ {
+ if (BulkOutIdx < 6)
+ {
+ /* 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));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Bulk Out endpoint nums large than 6\n"));
+ }
+ }
+ }
+
+ 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);
+ }
+#ifdef IFUP_IN_PROBE
+ else
+ {
+ if (VIRTUAL_IF_UP(pAd) != 0)
+ {
+ pAd = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);
+ rt2870_disconnect(dev, pAd);
+ rv = -ENOMEM;
+ }
+ }
+#endif /* IFUP_IN_PROBE */
+ 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);
+#ifdef IFUP_IN_PROBE
+ VIRTUAL_IF_DOWN(pAd);
+#endif /* IFUP_IN_PROBE */
+ usb_set_intfdata(intf, NULL);
+
+ rt2870_disconnect(dev, pAd);
+
+#ifdef CONFIG_PM
+#ifdef USB_SUPPORT_SELECTIVE_SUSPEND
+ printk("rtusb_disconnect usb_autopm_put_interface \n");
+ usb_autopm_put_interface(intf);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+ printk(" ^^rt2870_disconnect ====> pm_usage_cnt %d \n", atomic_read(&intf->pm_usage_cnt));
+#else
+ printk(" rt2870_disconnect ====> pm_usage_cnt %d \n", intf->pm_usage_cnt);
+#endif
+#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */
+#endif /* CONFIG_PM */
+
+}
+
+
+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 */
+ .supports_autosuspend = 1,
+ };
+
+#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);
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ UCHAR Flag;
+
+ RTMP_DRIVER_ADAPTER_RT28XX_WOW_STATUS(pAd, &Flag);
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
+
+#ifdef USB_SUPPORT_SELECTIVE_SUSPEND
+ UCHAR Flag;
+ DBGPRINT(RT_DEBUG_ERROR, ("autosuspend===> rt2870_suspend()\n"));
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ if (Flag == FALSE)
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+ {
+/* if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) */
+ RTMP_DRIVER_ADAPTER_END_DISSASSOCIATE(pAd);
+ 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_SUSPEND); */
+ RTMP_DRIVER_ADAPTER_SUSPEND_SET(pAd);
+ return 0;
+#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */
+
+
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ if (Flag == TRUE)
+ RTMP_DRIVER_ADAPTER_RT28XX_WOW_ENABLE(pAd);
+ else
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+ {
+ RTMP_DRIVER_ADAPTER_RT28XX_USB_ASICRADIO_OFF(pAd);
+ RTMP_DRIVER_ADAPTER_SUSPEND_SET(pAd);
+ }
+
+
+
+ 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);
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ UCHAR Flag;
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+#ifdef USB_SUPPORT_SELECTIVE_SUSPEND
+ INT pm_usage_cnt;
+ UCHAR Flag;
+#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ RTMP_DRIVER_ADAPTER_RT28XX_WOW_STATUS(pAd, &Flag);
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+
+#ifdef USB_SUPPORT_SELECTIVE_SUSPEND
+#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 <= 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);
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ if (Flag == FALSE)
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+ /*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"));
+
+
+#if (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT)
+ if (Flag == TRUE)
+ RTMP_DRIVER_ADAPTER_RT28XX_WOW_DISABLE(pAd);
+ else
+#endif /* (defined(WOW_SUPPORT) && defined(RTMP_MAC_USB)) || defined(NEW_WOW_SUPPORT) */
+ {
+ RTMP_DRIVER_ADAPTER_SUSPEND_CLEAR(pAd);
+ RTMP_DRIVER_ADAPTER_RT28XX_USB_ASICRADIO_ON(pAd);
+ }
+
+
+
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
+ return 0;
+}
+#endif /* CONFIG_PM */
+#endif /* LINUX_VERSION_CODE */
+
+
+/* Init driver module */
+INT __init rtusb_init(void)
+{
+ printk("rtusb init %s --->\n", RTMP_DRV_NAME);
+ return usb_register(&rtusb_driver);
+}
+
+/* Deinit driver module */
+VOID __exit rtusb_exit(void)
+{
+ usb_deregister(&rtusb_driver);
+ printk("<--- rtusb exit\n");
+}
+
+module_init(rtusb_init);
+module_exit(rtusb_exit);
+
+
+
+
+/*--------------------------------------------------------------------- */
+/* function declarations */
+/*--------------------------------------------------------------------- */
+
+
+
+/*
+========================================================================
+Routine Description:
+ Release allocated resources.
+
+Arguments:
+ *dev Point to the PCI or USB device
+ pAd driver control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static void rt2870_disconnect(struct usb_device *dev, VOID *pAd)
+{
+ struct net_device *net_dev;
+
+
+ DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
+ dev->bus->bus_name, dev->devpath));
+ if (!pAd)
+ {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ while(MOD_IN_USE > 0)
+ {
+ MOD_DEC_USE_COUNT;
+ }
+#else
+ usb_put_dev(dev);
+#endif /* LINUX_VERSION_CODE */
+
+ printk("rtusb_disconnect: pAd == NULL!\n");
+ return;
+ }
+/* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); */
+ RTMP_DRIVER_NIC_NOT_EXIST_SET(pAd);
+
+ /* for debug, wait to show some messages to /proc system */
+ udelay(1);
+
+
+ RTMP_DRIVER_NET_DEV_GET(pAd, &net_dev);
+
+ RtmpPhyNetDevExit(pAd, net_dev);
+
+ /* FIXME: Shall we need following delay and flush the schedule?? */
+ udelay(1);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+#else
+ flush_scheduled_work();
+#endif /* LINUX_VERSION_CODE */
+ udelay(1);
+
+#ifdef RT_CFG80211_SUPPORT
+ RTMP_DRIVER_80211_UNREGISTER(pAd, net_dev);
+#endif /* RT_CFG80211_SUPPORT */
+
+ /* free the root net_device */
+// RtmpOSNetDevFree(net_dev);
+
+ RtmpRaDevCtrlExit(pAd);
+
+ /* free the root net_device */
+ RtmpOSNetDevFree(net_dev);
+
+ /* 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;
+
+
+ /* 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. */
+
+
+/*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 */
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ RTMP_DRIVER_SET_PRECONFIG_VALUE(pAd);
+#endif /* EXT_BUILD_CHANNEL_LIST */
+
+ 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;
+#ifdef CONFIG_MULTI_CHANNEL
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutHCCANullFrameComplete = NULL;
+#endif /* CONFIG_MULTI_CHANNEL */
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutRTSFrameComplete = NULL;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkOutPsPollComplete = NULL;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkRxComplete = NULL;
+RTMP_DRV_USB_COMPLETE_HANDLER RtmpDrvUsbBulkCmdRspEventComplete = 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);
+}
+
+#ifdef CONFIG_MULTI_CHANNEL
+USBHST_STATUS RTUSBBulkOutHCCANullFrameComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
+{
+ RtmpDrvUsbBulkOutHCCANullFrameComplete((VOID *)pURB);
+}
+#endif /* CONFIG_MULTI_CHANNEL */
+
+
+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);
+}
+
+USBHST_STATUS RTUSBBulkCmdRspEventComplete(URBCompleteStatus Status, purbb_t pURB, pregs *pt_regs)
+{
+ RtmpDrvUsbBulkCmdRspEventComplete((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;
+#ifdef CONFIG_MULTI_CHANNEL
+ pDrvNetOps->RtmpNetUsbBulkOutHCCANullFrameComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutHCCANullFrameComplete;
+#endif /* CONFIG_MULTI_CHANNEL */
+ pDrvNetOps->RtmpNetUsbBulkOutRTSFrameComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutRTSFrameComplete;
+ pDrvNetOps->RtmpNetUsbBulkOutPsPollComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkOutPsPollComplete;
+ pDrvNetOps->RtmpNetUsbBulkRxComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkRxComplete;
+ pDrvNetOps->RtmpNetUsbBulkCmdRspEventComplete = (RTMP_DRV_USB_COMPLETE_HANDLER)RTUSBBulkCmdRspEventComplete;
+}
+
+
+VOID RtmpNetOpsSet(
+ IN VOID *pDrvNetOpsSrc)
+{
+ RTMP_NET_ABL_OPS *pDrvNetOps = (RTMP_NET_ABL_OPS *)pDrvNetOpsSrc;
+
+
+ RtmpDrvUsbBulkOutDataPacketComplete = pDrvNetOps->RtmpDrvUsbBulkOutDataPacketComplete;
+ RtmpDrvUsbBulkOutMLMEPacketComplete = pDrvNetOps->RtmpDrvUsbBulkOutMLMEPacketComplete;
+ RtmpDrvUsbBulkOutNullFrameComplete = pDrvNetOps->RtmpDrvUsbBulkOutNullFrameComplete;
+#ifdef CONFIG_MULTI_CHANNEL
+ RtmpDrvUsbBulkOutHCCANullFrameComplete = pDrvNetOps->RtmpDrvUsbBulkOutHCCANullFrameComplete;
+#endif /* CONFIG_MULTI_CHANNEL */
+
+ RtmpDrvUsbBulkOutRTSFrameComplete = pDrvNetOps->RtmpDrvUsbBulkOutRTSFrameComplete;
+ RtmpDrvUsbBulkOutPsPollComplete = pDrvNetOps->RtmpDrvUsbBulkOutPsPollComplete;
+ RtmpDrvUsbBulkRxComplete = pDrvNetOps->RtmpDrvUsbBulkRxComplete;
+ RtmpDrvUsbBulkCmdRspEventComplete = pDrvNetOps->RtmpDrvUsbBulkCmdRspEventComplete;
+}
+#endif /* OS_ABL_SUPPORT */
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/vr_bdlt.c b/cleopatre/devkit/mt7601udrv/os/linux/vr_bdlt.c
new file mode 100644
index 0000000000..f802db09fe
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/vr_bdlt.c
@@ -0,0 +1,63 @@
+/****************************************************************************
+
+ Module Name:
+ vr_brlt.c
+
+ Abstract:
+ Only for BroadLight 2348 platform.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Sample Lin 01-12-2010 Created
+
+***************************************************************************/
+
+#define RTMP_MODULE_OS
+#define RTMP_MODULE_OS_UTIL
+
+#define MODULE_BDLT
+
+/*#include "rt_config.h" */
+#include "rtmp_comm.h"
+#include "rt_os_util.h"
+#include "rtmp_osabl.h"
+
+
+#if defined(PLATFORM_BL2348) || defined(PLATFORM_BL23570)
+
+/* global variables */
+int (*pToUpperLayerPktSent)(struct sk_buff *pSkb) = netif_rx ;
+
+
+
+
+/*
+========================================================================
+Routine Description:
+ Assign the briding function.
+
+Arguments:
+ xi_destination_ptr - bridging function
+
+Return Value:
+ None
+
+Note:
+ The function name must be replace_upper_layer_packet_destination.
+========================================================================
+*/
+VOID replace_upper_layer_packet_destination(VOID *pXiDestination)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("ralink broad light> replace_upper_layer_packet_destination\n"));
+ pToUpperLayerPktSent = pXiDestination ;
+} /* End of replace_upper_layer_packet_destination */
+
+
+EXPORT_SYMBOL(pToUpperLayerPktSent);
+EXPORT_SYMBOL(replace_upper_layer_packet_destination);
+
+#endif /* PLATFORM_BL2348 */
+
+
+/* End of vr_bdlt.c */
diff --git a/cleopatre/devkit/mt7601udrv/os/linux/vr_ikans.c b/cleopatre/devkit/mt7601udrv/os/linux/vr_ikans.c
new file mode 100644
index 0000000000..bc630ff545
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/os/linux/vr_ikans.c
@@ -0,0 +1,363 @@
+/****************************************************************************
+
+ Module Name:
+ vr_ikans.c
+
+ Abstract:
+ Only for IKANOS Vx160 or Vx180 platform.
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Sample Lin 01-28-2008 Created
+
+***************************************************************************/
+
+#define RTMP_MODULE_OS
+#define RTMP_MODULE_OS_UTIL
+
+#define MODULE_IKANOS
+
+#include "rt_config.h"
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <netpro/apprehdr.h>
+
+
+#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<BssNum; i++)
+ {
+ apMacAddrConfig(7, mac, 0xAD);
+ mac[5] ++;
+ } /* End of for */
+} /* End of VR_IKANOS_FP_Init */
+
+
+/*
+========================================================================
+Routine Description:
+ Ikanos LAN --> 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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if(FromWhichBSSID >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ IfIdx = MAX_MBSSID_NUM(pAd) + MAX_WDS_ENTRY;
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if(FromWhichBSSID >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ INT WdsIndex = FromWhichBSSID - MIN_NET_DEVICE_FOR_WDS;
+ IfIdx = MAX_MBSSID_NUM(pAd) + WdsIndex;
+ }
+ else
+#endif /* WDS_SUPPORT */
+ {
+ IfIdx = FromWhichBSSID;
+ }
+ }
+#endif /* CONFIG_AP_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_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef APCLI_SUPPORT
+ if(FromWhichBSSID >= MIN_NET_DEVICE_FOR_APCLI)
+ {
+ IfIdx = MAX_MBSSID_NUM(pAd) + MAX_WDS_ENTRY;
+ }
+ else
+#endif /* APCLI_SUPPORT */
+#ifdef WDS_SUPPORT
+ if(FromWhichBSSID >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ INT WdsIndex = FromWhichBSSID - MIN_NET_DEVICE_FOR_WDS;
+ IfIdx = MAX_MBSSID_NUM(pAd) + WdsIndex;
+ }
+ else
+#endif /* WDS_SUPPORT */
+ {
+ IfIdx = FromWhichBSSID;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+
+ return IfIdx; /* return one of MBSS */
+} /* End of GetSpecInfoIdxFromBssid */
+
+
+/*
+========================================================================
+Routine Description:
+ Ikanos WLAN --> LAN transmit fast path function.
+
+Arguments:
+ pFrame - the received packet (Ikanos packet format)
+
+Return Value:
+ None
+
+Note:
+ Ikanos platform supports only 8 VAPs
+========================================================================
+*/
+static void IKANOS_WlanPktFromAp(
+ IN apPreHeader_t *pFrame)
+{
+ PRTMP_ADAPTER pAd;
+ struct net_device *dev = NULL;
+ struct sk_buff *skb;
+ INT32 index;
+ apPreHeader_t *apBuf = K0_TO_K1(pFrame);
+
+
+ pAd = pIkanosAd;
+ /*index = apBuf->specInfoElement; */
+ /*dev = pAd->ApCfg.MBSSID[index].MSSIDDev; */
+ index = GetSpecInfoIdxFromBssid(pAd, apBuf->specInfoElement);
+ dev = get_netdev_from_bssid(pAd, apBuf->specInfoElement);
+ if (dev == NULL)
+ {
+ printk("ikanos> %s: ERROR null device ***************\n", __FUNCTION__);
+ return;
+ } /* End of if */
+
+ skb = (struct sk_buff *)translateApbuf2Mbuf(apBuf);
+ if (NULL == skb)
+ {
+ printk("ikanos> %s: skb is null *********************\n", __FUNCTION__);
+ return;
+ } /* End of if */
+
+ pAd->IkanosRxInfo[index].netdev = dev;
+ pAd->IkanosRxInfo[index].fp = &IKANOS_WlanDataFramesTx;
+
+ skb->dev = dev;
+ skb->apFlowData.rxApId = IKANOS_PERAP_ID;
+ /*skb->apFlowData.txHandle = &(txinforx[index]); */
+ skb->apFlowData.rxHandle = &(pAd->IkanosRxInfo[index]);
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+#ifdef IKANOS_DEBUG
+ printk("ikanos> rx no fp!\n"); /* debug use */
+#endif /* IKANOS_DEBUG */
+
+ netif_rx(skb);
+ return;
+} /* End of IKANOS_WlanPktFromAp */
+
+#endif /* IKANOS_VX_1X0 */
+
+/* End of vr_ikans.c */
diff --git a/cleopatre/devkit/mt7601udrv/phy/rlt_phy.c b/cleopatre/devkit/mt7601udrv/phy/rlt_phy.c
new file mode 100644
index 0000000000..7df9a259a4
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/phy/rlt_phy.c
@@ -0,0 +1,436 @@
+/*
+
+*/
+
+
+#include "rt_config.h"
+
+
+#ifdef RLT_MAC
+
+#ifndef MT7601
+
+NDIS_STATUS NICInitBBP(RTMP_ADAPTER *pAd)
+{
+ INT idx;
+
+ /* Read BBP register, make sure BBP is up and running before write new data*/
+ if (rlt_bbp_is_ready(pAd) == FALSE)
+ return NDIS_STATUS_FAILURE;
+
+ /* re-config specific BBP registers for individual chip */
+ if (pAd->chipCap.pBBPRegTable)
+ {
+ RTMP_REG_PAIR *reg = (RTMP_REG_PAIR *)pAd->chipCap.pBBPRegTable;
+
+ for (idx = 0; idx < pAd->chipCap.bbpRegTbSize; idx++)
+ {
+ RTMP_BBP_IO_WRITE32(pAd, reg[idx].Register, reg[idx].Value);
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP[%x]=0x%x\n",
+ reg[idx].Register, reg[idx].Value));
+ }
+ }
+
+ if (pAd->chipOps.AsicBbpInit != NULL)
+ pAd->chipOps.AsicBbpInit(pAd);
+
+ // TODO: shiang-6590, check these bbp registers if need to remap to new BBP_Registers
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
+
+INT rtmp_bbp_set_txdac(struct _RTMP_ADAPTER *pAd, INT tx_dac)
+{
+ UINT32 txbe, txbe_r5 = 0;
+
+ RTMP_BBP_IO_READ32(pAd, TXBE_R5, &txbe_r5);
+ txbe = txbe_r5 & (~0x3);
+ switch (tx_dac)
+ {
+ case 2:
+ txbe |= 0x3;
+ break;
+ case 1:
+ case 0:
+ default:
+ txbe &= (~0x3);
+ break;
+ }
+
+ if (txbe != txbe_r5)
+ RTMP_BBP_IO_WRITE32(pAd, TXBE_R5, txbe);
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_set_rxpath(struct _RTMP_ADAPTER *pAd, INT rxpath)
+{
+ UINT32 agc, agc_r0 = 0;
+
+ RTMP_BBP_IO_READ32(pAd, AGC1_R0, &agc_r0);
+ agc = agc_r0 & (~0x18);
+ if(rxpath == 2)
+ agc |= (0x8);
+ else if(rxpath == 1)
+ agc |= (0x0);
+
+ if (agc != agc_r0)
+ RTMP_BBP_IO_WRITE32(pAd, AGC1_R0, agc);
+
+//DBGPRINT(RT_DEBUG_OFF, ("%s(): rxpath=%d, Set AGC1_R0=0x%x, agc_r0=0x%x\n", __FUNCTION__, rxpath, agc, agc_r0));
+// RTMP_BBP_IO_READ32(pAd, AGC1_R0, &agc);
+//DBGPRINT(RT_DEBUG_OFF, ("%s(): rxpath=%d, After write, Get AGC1_R0=0x%x,\n", __FUNCTION__, rxpath, agc));
+
+ return TRUE;
+}
+
+
+static UCHAR vht_prim_ch_val[] = {
+ 42, 36, 0,
+ 42, 40, 1,
+ 42, 44, 2,
+ 42, 48, 3,
+ 58, 52, 0,
+ 58, 56, 1,
+ 58, 60, 2,
+ 58, 64, 3,
+ 106, 100, 0,
+ 106, 104, 1,
+ 106, 108, 2,
+ 106, 112, 3,
+ 122, 116, 0,
+ 122, 120, 1,
+ 122, 124, 2,
+ 122, 128, 3,
+ 138, 132, 0,
+ 138, 136, 1,
+ 138, 140, 2,
+ 138, 144, 3,
+ 155, 149, 0,
+ 155, 153, 1,
+ 155, 157, 2,
+ 155, 161, 3
+};
+
+
+INT rtmp_bbp_set_ctrlch(struct _RTMP_ADAPTER *pAd, INT ext_ch)
+{
+ UINT32 agc, agc_r0 = 0;
+ UINT32 be, be_r0 = 0;
+
+
+ RTMP_BBP_IO_READ32(pAd, AGC1_R0, &agc_r0);
+ agc = agc_r0 & (~0x300);
+ RTMP_BBP_IO_READ32(pAd, TXBE_R0, &be_r0);
+ be = (be_r0 & (~0x03));
+#ifdef DOT11_VHT_AC
+ if (pAd->CommonCfg.BBPCurrentBW == BW_80 &&
+ pAd->CommonCfg.Channel >= 36 &&
+ pAd->CommonCfg.vht_cent_ch)
+ {
+ if (pAd->CommonCfg.Channel < pAd->CommonCfg.vht_cent_ch)
+ {
+ switch (pAd->CommonCfg.vht_cent_ch - pAd->CommonCfg.Channel)
+ {
+ case 6:
+ be |= 0;
+ agc |=0x000;
+ break;
+ case 2:
+ be |= 1;
+ agc |=0x100;
+ break;
+
+ }
+ }
+ else if (pAd->CommonCfg.Channel > pAd->CommonCfg.vht_cent_ch)
+ {
+ switch (pAd->CommonCfg.Channel - pAd->CommonCfg.vht_cent_ch)
+ {
+ case 6:
+ be |= 0x3;
+ agc |=0x300;
+ break;
+ case 2:
+ be |= 0x2;
+ agc |=0x200;
+ break;
+ }
+ }
+ }
+ else
+#endif /* DOT11_VHT_AC */
+ {
+ switch (ext_ch)
+ {
+ case EXTCHA_BELOW:
+ agc |= 0x100;
+ be |= 0x01;
+ break;
+ case EXTCHA_ABOVE:
+ agc &= (~0x300);
+ be &= (~0x03);
+ break;
+ case EXTCHA_NONE:
+ default:
+ agc &= (~0x300);
+ be &= (~0x03);
+ break;
+ }
+ }
+ if (agc != agc_r0)
+ RTMP_BBP_IO_WRITE32(pAd, AGC1_R0, agc);
+
+ if (be != be_r0)
+ RTMP_BBP_IO_WRITE32(pAd, TXBE_R0, be);
+
+//DBGPRINT(RT_DEBUG_OFF, ("%s(): ext_ch=%d, Set AGC1_R0=0x%x, agc_r0=0x%x\n", __FUNCTION__, ext_ch, agc, agc_r0));
+// RTMP_BBP_IO_READ32(pAd, AGC1_R0, &agc);
+//DBGPRINT(RT_DEBUG_OFF, ("%s(): ext_ch=%d, After write, Get AGC1_R0=0x%x,\n", __FUNCTION__, ext_ch, agc));
+
+ return TRUE;
+}
+
+/*
+ <<Gamma2.1 Control Registers Rev1.3.pdf>>
+ BBP bandwidth (CORE_R1[4:3]) change procedure:
+ 1. Hold BBP in reset by setting CORE_R4[0] to '1'
+ 2. Wait 0.5 us to ensure BBP is in the idle State
+ 3. Change BBP bandwidth with CORE_R1[4:3]
+ CORE_R1 (Bit4:3)
+ 0: 20MHz
+ 1: 10MHz (11J)
+ 2: 40MHz
+ 3: 80MHz
+ 4. Wait 0.5 us for BBP clocks to settle
+ 5. Release BBP from reset by clearing CORE_R4[0]
+*/
+INT rtmp_bbp_set_bw(struct _RTMP_ADAPTER *pAd, INT bw)
+{
+ UINT32 core, core_r1 = 0, core_r4 = 0;
+ UINT32 agc, agc_r0 = 0;
+
+ RTMP_BBP_IO_READ32(pAd, CORE_R1, &core_r1);
+ core = (core_r1 & (~0x18));
+ RTMP_BBP_IO_READ32(pAd, AGC1_R0, &agc_r0);
+ agc = agc_r0 & (~0x7000);
+ switch (bw)
+ {
+ case BW_80:
+ core |= 0x18;
+ agc |= 0x7000;
+ break;
+ case BW_40:
+ core |= 0x10;
+ agc |= 0x3000;
+ break;
+ case BW_20:
+ core &= (~0x18);
+ agc |= 0x1000;
+ break;
+ case BW_10:
+ core |= 0x08;
+ agc |= 0x1000;
+ break;
+ }
+
+ if (core != core_r1)
+ {
+#ifdef RT65xx
+ if (IS_RT6590(pAd))
+ {
+ /*
+ Hold BBP in reset by setting CORE_R4[0]=1
+ */
+ RTMP_BBP_IO_READ32(pAd, CORE_R4, &core_r4);
+ core_r4 |= 0x00000001;
+ RTMP_BBP_IO_WRITE32(pAd, CORE_R4, core_r4);
+
+ /*
+ Wait 0.5 us to ensure BBP is in the idle state.
+ */
+ RtmpOsUsDelay(1);
+ }
+#endif /* RT65xx */
+
+
+ RTMP_BBP_IO_WRITE32(pAd, CORE_R1, core);
+
+#ifdef RT65xx
+ if (IS_RT6590(pAd))
+ {
+ /*
+ Wait 0.5 us for BBP clocks to settle.
+ */
+ RtmpOsUsDelay(1);
+
+ /*
+ Release BBP from reset by clearing CORE_R4[0].
+ */
+ RTMP_BBP_IO_READ32(pAd, CORE_R4, &core_r4);
+ core_r4 &= ~(0x00000001);
+ RTMP_BBP_IO_WRITE32(pAd, CORE_R4, core_r4);
+ }
+#endif /* RT65xx */
+ }
+
+ if (agc != agc_r0) {
+ RTMP_BBP_IO_WRITE32(pAd, AGC1_R0, agc);
+//DBGPRINT(RT_DEBUG_OFF, ("%s(): bw=%d, Set AGC1_R0=0x%x, agc_r0=0x%x\n", __FUNCTION__, bw, agc, agc_r0));
+// RTMP_BBP_IO_READ32(pAd, AGC1_R0, &agc);
+//DBGPRINT(RT_DEBUG_OFF, ("%s(): bw=%d, After write, Get AGC1_R0=0x%x,\n", __FUNCTION__, bw, agc));
+ }
+
+ pAd->CommonCfg.BBPCurrentBW = bw;
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_set_mmps(struct _RTMP_ADAPTER *pAd, BOOLEAN ReduceCorePower)
+{
+ UINT32 bbp_val, org_val;
+
+ RTMP_BBP_IO_READ32(pAd, AGC1_R0, &org_val);
+ bbp_val = org_val;
+ if (ReduceCorePower)
+ bbp_val |= 0x04;
+ else
+ bbp_val &= ~0x04;
+
+ if (bbp_val != org_val)
+ RTMP_BBP_IO_WRITE32(pAd, AGC1_R0, bbp_val);
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_get_agc(struct _RTMP_ADAPTER *pAd, CHAR *agc, RX_CHAIN_IDX chain)
+{
+ UCHAR idx, val;
+ UINT32 bbp_val, bbp_reg = AGC1_R8;
+
+
+ if (((pAd->MACVersion & 0xffff0000) < 0x28830000) ||
+ (pAd->Antenna.field.RxPath == 1))
+ {
+ chain = RX_CHAIN_0;
+ }
+
+ idx = val = 0;
+ while(chain != 0)
+ {
+ if (idx >= pAd->Antenna.field.RxPath)
+ break;
+
+ if (chain & 0x01)
+ {
+ RTMP_BBP_IO_READ32(pAd, bbp_reg, &bbp_val);
+ val = ((bbp_val & (0x0000ff00)) >> 8) & 0xff;
+ break;
+ }
+ chain >>= 1;
+ bbp_reg += 4;
+ idx++;
+ }
+
+ *agc = val;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT rtmp_bbp_set_agc(struct _RTMP_ADAPTER *pAd, UCHAR agc, RX_CHAIN_IDX chain)
+{
+ UCHAR idx = 0;
+ UINT32 bbp_val, bbp_reg = AGC1_R8;
+
+ if (((pAd->MACVersion & 0xf0000000) < 0x28830000) ||
+ (pAd->Antenna.field.RxPath == 1))
+ {
+ chain = RX_CHAIN_0;
+ }
+
+ while (chain != 0)
+ {
+ if (idx >= pAd->Antenna.field.RxPath)
+ break;
+
+ if (idx & 0x01)
+ {
+ RTMP_BBP_IO_READ32(pAd, bbp_reg, &bbp_val);
+ bbp_val = (bbp_val & 0xffff00ff) | (agc << 8);
+ RTMP_BBP_IO_WRITE32(pAd, bbp_reg, bbp_val);
+
+ DBGPRINT(RT_DEBUG_INFO,
+ ("%s(Idx):Write(R%d,val:0x%x) to Chain(0x%x, idx:%d)\n",
+ __FUNCTION__, bbp_reg, bbp_val, chain, idx));
+ }
+ chain >>= 1;
+ bbp_reg += 4;
+ idx++;
+ }
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_set_filter_coefficient_ctrl(RTMP_ADAPTER *pAd, UCHAR Channel)
+{
+ UINT32 bbp_val = 0, org_val = 0;
+
+ if (Channel == 14)
+ {
+ /* when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1 */
+ RTMP_BBP_IO_READ32(pAd, CORE_R1, &org_val);
+ bbp_val = org_val;
+ if (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+ bbp_val |= 0x20;
+ else
+ bbp_val &= (~0x20);
+
+ if (bbp_val != org_val)
+ RTMP_BBP_IO_WRITE32(pAd, CORE_R1, bbp_val);
+ }
+
+ return TRUE;
+}
+
+
+UCHAR rtmp_bbp_get_random_seed(RTMP_ADAPTER *pAd)
+{
+ UINT32 value, value2;
+ UCHAR seed;
+
+ RTMP_BBP_IO_READ32(pAd, AGC1_R16, &value);
+ seed = (UCHAR)((value & 0xff) ^ ((value & 0xff00) >> 8)^
+ ((value & 0xff0000) >> 16));
+ RTMP_BBP_IO_READ32(pAd, RXO_R9, &value2);
+
+ return (UCHAR)(seed ^ (value2 & 0xff)^ ((value2 & 0xff00) >> 8));
+}
+
+
+INT rlt_bbp_is_ready(struct _RTMP_ADAPTER *pAd)
+{
+ INT idx = 0;
+ UINT32 val;
+
+ do
+ {
+ RTMP_BBP_IO_READ32(pAd, CORE_R0, &val);
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", val));
+ } while ((++idx < 20) && ((val == 0xffffffff) || (val == 0x0)));
+
+ return (((val == 0xffffffff) || (val == 0x0)) ? FALSE : TRUE);
+}
+
+#endif /* MT7601 */
+
+#endif /* RLT_MAC */
+
diff --git a/cleopatre/devkit/mt7601udrv/phy/rlt_rf.c b/cleopatre/devkit/mt7601udrv/phy/rlt_rf.c
new file mode 100644
index 0000000000..d3ebaea5b4
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/phy/rlt_rf.c
@@ -0,0 +1,182 @@
+/*
+
+*/
+
+#ifdef RLT_RF
+
+#include "rt_config.h"
+
+
+NDIS_STATUS rlt_rf_write(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR bank,
+ IN UCHAR regID,
+ IN UCHAR value)
+{
+ RLT_RF_CSR_CFG rfcsr = { { 0 } };
+ UINT i = 0;
+ NDIS_STATUS ret;
+
+#ifdef MT7601FPGA
+ return;
+#endif /*MT7601FPGA */
+
+
+ if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
+ {
+ DBGPRINT_ERR(("rlt_rf_write. Not allow to write RF 0x%x : fail\n", regID));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
+ if (ret != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ ASSERT((regID <= pAd->chipCap.MaxNumOfRfId));
+
+ ret = STATUS_UNSUCCESSFUL;
+ do
+ {
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (!rfcsr.field.RF_CSR_KICK)
+ break;
+ i++;
+ }
+ while ((i < MAX_BUSY_COUNT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ 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"));
+ goto done;
+ }
+
+ rfcsr.field.RF_CSR_WR = 1;
+ rfcsr.field.RF_CSR_KICK = 1;
+ rfcsr.field.RF_CSR_REG_BANK = bank;
+ rfcsr.field.RF_CSR_REG_ID = regID;
+
+
+ rfcsr.field.RF_CSR_DATA = value;
+ RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+
+ ret = NDIS_STATUS_SUCCESS;
+done:
+
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+ return ret;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Read RT30xx RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS rlt_rf_read(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR bank,
+ IN UCHAR regID,
+ IN UCHAR *pValue)
+{
+ RLT_RF_CSR_CFG rfcsr = { { 0 } };
+ UINT i=0, k=0;
+ NDIS_STATUS ret = STATUS_UNSUCCESSFUL;
+
+
+ if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
+ {
+ DBGPRINT_ERR(("rlt_rf_read. Not allow to read RF 0x%x : fail\n", regID));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i);
+ if (i != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i));
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ ASSERT((regID <= pAd->chipCap.MaxNumOfRfId));
+
+ for (i=0; i<MAX_BUSY_COUNT; i++)
+ {
+ if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ goto done;
+
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (rfcsr.field.RF_CSR_KICK == BUSY)
+ continue;
+
+ rfcsr.word = 0;
+ rfcsr.field.RF_CSR_WR = 0;
+ rfcsr.field.RF_CSR_KICK = 1;
+ rfcsr.field.RF_CSR_REG_ID = regID;
+ rfcsr.field.RF_CSR_REG_BANK = bank;
+ RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+
+ for (k=0; k<MAX_BUSY_COUNT; k++)
+ {
+ if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ goto done;
+
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (rfcsr.field.RF_CSR_KICK == IDLE)
+ break;
+ }
+
+ if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
+ (rfcsr.field.RF_CSR_REG_ID == regID) &&
+ (rfcsr.field.RF_CSR_REG_BANK == bank))
+ {
+ *pValue = (UCHAR)(rfcsr.field.RF_CSR_DATA);
+ break;
+ }
+ }
+
+ if (rfcsr.field.RF_CSR_KICK == BUSY)
+ {
+ DBGPRINT_ERR(("RF read R%d=0x%X fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k));
+ goto done;
+ }
+ ret = STATUS_SUCCESS;
+
+done:
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+ return ret;
+}
+
+#endif /* RLT_RF */
+
diff --git a/cleopatre/devkit/mt7601udrv/phy/rtmp_phy.c b/cleopatre/devkit/mt7601udrv/phy/rtmp_phy.c
new file mode 100644
index 0000000000..857d7c8b27
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/phy/rtmp_phy.c
@@ -0,0 +1,629 @@
+/*
+
+*/
+
+
+#include "rt_config.h"
+
+
+//#ifdef RTMP_MAC
+#if defined(RTMP_MAC) || defined(MT7601)
+
+/* 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_R68, 0x0B}, /* improve Rx sensitivity. */
+ {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))
+
+
+NDIS_STATUS NICInitBBP(RTMP_ADAPTER *pAd)
+{
+ INT Index = 0;
+ UCHAR R0 = 0xff;
+
+ /* Read BBP register, make sure BBP is up and running before write new data*/
+ if (rtmp_bbp_is_ready(pAd)== FALSE)
+ return NDIS_STATUS_FAILURE;
+
+ Index = 0;
+
+ /* Initialize BBP register to default value*/
+ for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
+ {
+
+#ifdef MICROWAVE_OVEN_SUPPORT
+#ifdef MT7601
+ if ( BBPRegTable[Index].Register == BBP_R65)
+ {
+ /* Backup BBP_R65 and B5.R6 and B5.R7 */
+ pAd->CommonCfg.MO_Cfg.Stored_BBP_R65 = BBPRegTable[Index].Value;
+ DBGPRINT(RT_DEBUG_TRACE, ("Stored_BBP_R65=%x @%s \n", pAd->CommonCfg.MO_Cfg.Stored_BBP_R65, __FUNCTION__));
+ }
+#endif /* MT7601 */
+#endif /* MICROWAVE_OVEN_SUPPORT */
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd,
+ BBPRegTable[Index].Register,
+ BBPRegTable[Index].Value);
+ }
+
+ /* re-config specific BBP registers for individual chip */
+ 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=0x%x\n",
+ pbbpRegTb[Index].Register,
+ pbbpRegTb[Index].Value));
+ }
+ }
+
+ if (pAd->chipOps.AsicBbpInit != NULL)
+ pAd->chipOps.AsicBbpInit(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 (((pAd->MACVersion & 0xffff) != 0x0101) &&
+ !(IS_RT30xx(pAd)|| IS_RT3572(pAd) || IS_RT5390(pAd) || IS_RT5392(pAd) || IS_RT3290(pAd) || IS_MT7601(pAd)))
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
+
+
+ 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);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
+
+INT rtmp_bbp_set_txdac(struct _RTMP_ADAPTER *pAd, INT tx_dac)
+{
+ UCHAR val, old_val = 0;
+
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &old_val);
+ val = old_val & (~0x18);
+ switch (tx_dac)
+ {
+ case 2:
+ val |= 0x10;
+ break;
+ case 1:
+ val |= 0x08;
+ break;
+ case 0:
+ default:
+ break;
+ }
+
+ if (val != old_val) {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, val);
+ }
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_set_rxpath(struct _RTMP_ADAPTER *pAd, INT rxpath)
+{
+ UCHAR val = 0;
+
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &val);
+ val &= (~0x18);
+ if(rxpath == 3)
+ val |= (0x10);
+ else if(rxpath == 2)
+ val |= (0x8);
+ else if(rxpath == 1)
+ val |= (0x0);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, val);
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_set_ctrlch(struct _RTMP_ADAPTER *pAd, INT ext_ch)
+{
+ UCHAR val, old_val = 0;
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &old_val);
+ val = old_val;
+ switch (ext_ch)
+ {
+ case EXTCHA_BELOW:
+ val |= (0x20);
+ break;
+ case EXTCHA_ABOVE:
+ case EXTCHA_NONE:
+ val &= (~0x20);
+ break;
+ }
+
+ if (val != old_val)
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, val);
+
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_set_bw(struct _RTMP_ADAPTER *pAd, INT bw)
+{
+ UCHAR val, old_val = 0;
+ BOOLEAN bstop = FALSE;
+ UINT32 Data, MTxCycle, macStatus;
+
+
+ if (bw != pAd->CommonCfg.BBPCurrentBW)
+ bstop = TRUE;
+
+ if (bstop)
+ {
+ /* Disable MAC Tx/Rx */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Data);
+ Data &= (~0x0C);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Data);
+
+ /* Check MAC Tx/Rx idle */
+ for (MTxCycle = 0; MTxCycle < 10000; MTxCycle++)
+ {
+ RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &macStatus);
+ if (macStatus & 0x3)
+ RTMPusecDelay(50);
+ else
+ break;
+ }
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &old_val);
+ val = (old_val & (~0x18));
+ switch (bw)
+ {
+ case BW_20:
+ val &= (~0x18);
+ break;
+ case BW_40:
+ val |= (0x10);
+ break;
+ case BW_10:
+ val |= 0x08;
+ break;
+ }
+
+ if (val != old_val) {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, val);
+ }
+
+ if (bstop)
+ {
+ /* Enable MAC Tx/Rx */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Data);
+ Data |= 0x0C;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Data);
+ }
+
+ pAd->CommonCfg.BBPCurrentBW = bw;
+
+ return TRUE;
+}
+
+
+INT rtmp_bbp_set_mmps(struct _RTMP_ADAPTER *pAd, BOOLEAN ReduceCorePower)
+{
+ UCHAR bbp_val, org_val;
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &org_val);
+ bbp_val = org_val;
+ if (ReduceCorePower)
+ bbp_val |= 0x04;
+ else
+ bbp_val &= ~0x04;
+
+ if (bbp_val != org_val)
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbp_val);
+
+ return TRUE;
+}
+
+
+NDIS_STATUS AsicBBPWriteWithRxChain(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR bbpId,
+ IN CHAR bbpVal,
+ IN RX_CHAIN_IDX rx_ch_idx)
+{
+ UCHAR idx = 0, val = 0;
+
+ if (((pAd->MACVersion & 0xf0000000) < 0x28830000) ||
+ (pAd->Antenna.field.RxPath == 1))
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, bbpId, bbpVal);
+ return NDIS_STATUS_SUCCESS;
+ }
+
+ while (rx_ch_idx != 0)
+ {
+ if (idx >= pAd->Antenna.field.RxPath)
+ break;
+
+ if (rx_ch_idx & 0x01)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &val);
+ val = (val & (~0x60)) | (idx << 5);
+#ifdef RTMP_MAC_USB
+ if ((IS_USB_INF(pAd)) &&
+ (RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, val) == STATUS_SUCCESS))
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, bbpId, bbpVal);
+ }
+#endif /* RTMP_MAC_USB */
+
+
+ DBGPRINT(RT_DEBUG_INFO,
+ ("%s(Idx):Write(R%d,val:0x%x) to Chain(0x%x, idx:%d)\n",
+ __FUNCTION__, bbpId, bbpVal, rx_ch_idx, idx));
+ }
+ rx_ch_idx >>= 1;
+ idx++;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+NDIS_STATUS AsicBBPReadWithRxChain(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR bbpId,
+ IN CHAR *pBbpVal,
+ IN RX_CHAIN_IDX rx_ch_idx)
+{
+ UCHAR idx, val;
+
+ if (((pAd->MACVersion & 0xffff0000) < 0x28830000) ||
+ (pAd->Antenna.field.RxPath == 1))
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, pBbpVal);
+ return NDIS_STATUS_SUCCESS;
+ }
+
+ idx = 0;
+ while(rx_ch_idx != 0)
+ {
+ if (idx >= pAd->Antenna.field.RxPath)
+ break;
+
+ if (rx_ch_idx & 0x01)
+ {
+ val = 0;
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R27, &val);
+ val = (val & (~0x60)) | (idx << 5);
+#ifdef RTMP_MAC_USB
+ if ((IS_USB_INF(pAd)) &&
+ (RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R27, val) == STATUS_SUCCESS))
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, bbpId, pBbpVal);
+ }
+#endif /* RTMP_MAC_USB */
+
+ break;
+ }
+ rx_ch_idx >>= 1;
+ idx++;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+INT rtmp_bbp_get_agc(struct _RTMP_ADAPTER *pAd, CHAR *agc, RX_CHAIN_IDX idx)
+{
+ return AsicBBPReadWithRxChain(pAd, BBP_R66, agc, idx);
+}
+
+
+INT rtmp_bbp_set_agc(struct _RTMP_ADAPTER *pAd, UCHAR agc, RX_CHAIN_IDX idx)
+{
+ return AsicBBPWriteWithRxChain(pAd, BBP_R66, agc, idx);
+}
+
+
+INT rtmp_bbp_set_filter_coefficient_ctrl(RTMP_ADAPTER *pAd, UCHAR Channel)
+{
+ UCHAR bbp_val = 0, org_val = 0;
+
+ if (Channel == 14)
+ {
+ /* when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1 */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &org_val);
+ bbp_val = org_val;
+ if (WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+ bbp_val |= 0x20;
+ else
+ bbp_val &= (~0x20);
+
+ if (bbp_val != org_val)
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, bbp_val);
+ }
+
+ return TRUE;
+}
+
+
+UCHAR rtmp_bbp_get_random_seed(RTMP_ADAPTER *pAd)
+{
+ UCHAR value1, value2, value3, value4, value5;
+
+ 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 (value1^value2^value3^value4^value5);
+}
+
+
+INT rtmp_bbp_is_ready(struct _RTMP_ADAPTER *pAd)
+{
+ INT idx = 0;
+ UCHAR val;
+
+ do
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &val);
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", val));
+ } while ((++idx < 20) && ((val == 0xff) || (val == 0x00)));
+
+ return (((val == 0xff) || (val == 0x00)) ? FALSE : TRUE);
+}
+
+
+#ifdef PRE_ANT_SWITCH
+
+#endif /* PRE_ANT_SWITCH */
+
+
+#ifdef CFO_TRACK
+#ifdef CONFIG_AP_SUPPORT
+INT rtmp_cfo_track(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry, INT lastClient)
+{
+ /* CFO Tracking */
+ if (IS_RT3883(pAd))
+ {
+ if (pAd->MacTab.Size !=1 || pAd->CommonCfg.CFOTrack==0)
+ {
+ /* Set to default */
+ RT3883_AsicSetFreqOffset(pAd, pAd->RfFreqOffset);
+ }
+ else if ((lastClient < MAX_LEN_OF_MAC_TABLE) && (lastClient >=1) &&
+ pAd->CommonCfg.CFOTrack < 8 &&
+ pEntry->freqOffsetValid)
+ {
+ /* Track CFO */
+ SHORT foValue, offset = pEntry->freqOffset;
+ UCHAR RFValue;
+
+ RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)&RFValue);
+ RFValue &= 0x7F;
+
+ if (offset > 32)
+ offset = 32;
+ else if (offset < -32)
+ offset = -32;
+
+ foValue = RFValue - (offset/16);
+ if (foValue < 0)
+ foValue = 0;
+ else if (foValue > 0x5F)
+ foValue = 0x5F;
+
+ if (foValue != RFValue)
+ RT3883_AsicSetFreqOffset(pAd, foValue);
+
+ /* If CFOTrack!=1 then keep updating until CFOTrack==8 */
+ if (pAd->CommonCfg.CFOTrack != 1)
+ pAd->CommonCfg.CFOTrack++;
+
+ pEntry->freqOffsetValid = FALSE;
+ }
+ }
+
+ return TRUE;
+}
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* CFO_TRACK */
+
+
+#ifdef MT7601
+NDIS_STATUS MT7601_BBP_write(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR regID,
+ IN UCHAR value)
+{
+ BBP_CSR_CFG_STRUC BbpCsr = { { 0 } };
+ UINT i = 0;
+ NDIS_STATUS ret;
+
+#ifdef MT7601FPGA
+ return;
+#endif /*MT7601FPGA */
+
+
+ if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
+ {
+ DBGPRINT_ERR(("rlt_rf_write. Not allow to write BBP 0x%x : fail\n", regID));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, ret);
+ if (ret != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", ret));
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ ASSERT((regID <= pAd->chipCap.MaxNumOfBbpId));
+
+ ret = STATUS_UNSUCCESSFUL;
+ do
+ {
+ RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word);
+
+ if (!BbpCsr.field.Busy)
+ break;
+ i++;
+ }
+ while ((i < MAX_BUSY_COUNT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ 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"));
+ goto done;
+ }
+
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 0;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.Value = value;
+ BbpCsr.field.RegNum = regID;
+
+
+ RTMP_IO_WRITE32(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+ ret = NDIS_STATUS_SUCCESS;
+done:
+
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+ return ret;
+}
+
+
+NDIS_STATUS MT7601_BBP_read(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR regID,
+ IN UCHAR *pValue)
+{
+ BBP_CSR_CFG_STRUC BbpCsr = { { 0 } };
+ UINT i=0, k=0;
+ NDIS_STATUS ret = STATUS_UNSUCCESSFUL;
+
+
+ if (pAd->WlanFunCtrl.field.WLAN_EN == 0)
+ {
+ DBGPRINT_ERR(("MT7601_BBP_read. Not allow to read BBP 0x%x : fail\n", regID));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_WAIT(&pAd->reg_atomic, i);
+ if (i != 0) {
+ DBGPRINT(RT_DEBUG_ERROR, ("reg_atomic get failed(ret=%d)\n", i));
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+#endif /* RTMP_MAC_USB */
+
+ ASSERT((regID <= pAd->chipCap.MaxNumOfBbpId));
+
+ for (i=0; i<MAX_BUSY_COUNT; i++)
+ {
+ if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ goto done;
+
+ RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word);
+
+ if (BbpCsr.field.Busy == BUSY)
+ continue;
+
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 1;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = regID;
+
+
+ RTMP_IO_WRITE32(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+ for (k=0; k<MAX_BUSY_COUNT; k++)
+ {
+ if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ goto done;
+
+ RTMP_IO_READ32(pAd, BBP_CSR_CFG, &BbpCsr.word);
+
+ if (BbpCsr.field.Busy == IDLE)
+ break;
+ }
+
+ if ((BbpCsr.field.Busy == IDLE) &&
+ (BbpCsr.field.RegNum == regID) )
+ {
+ *pValue = (UCHAR)(BbpCsr.field.Value);
+ break;
+ }
+ }
+
+ if (BbpCsr.field.Busy == BUSY)
+ {
+ DBGPRINT_ERR(("BBP read R%d=0x%X fail, i[%d], k[%d]\n", regID, BbpCsr.word,i,k));
+ goto done;
+ }
+ ret = STATUS_SUCCESS;
+
+done:
+#ifdef RTMP_MAC_USB
+ if (IS_USB_INF(pAd)) {
+ RTMP_SEM_EVENT_UP(&pAd->reg_atomic);
+ }
+#endif /* RTMP_MAC_USB */
+
+ return ret;
+}
+
+
+#endif /* MT7601 */
+
+#endif /* RTMP_MAC */
+
diff --git a/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_ags.c b/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_ags.c
new file mode 100644
index 0000000000..bc8343f339
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_ags.c
@@ -0,0 +1,1181 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related AGS (Adaptive Group Switching) function body.
+
+***************************************************************************/
+
+#ifdef AGS_SUPPORT
+
+#include "rt_config.h"
+
+
+/*
+ HT Rate Table format
+ [Item no.] [Mode]* [Mode]** [CurrMCS] [TrainUp] [TrainDown] [downMCS] [upMCS3] [upMCS2] [upMCS1]
+
+ [Mode]*:
+ bit0: STBC -STBC_XXX
+ bit1: Short GI - GI_XXX
+ bit2~3: BW - BW_XXX
+ bit4~bit6: Mode (0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF, 4: VHT) - MODE_XXX
+ bit7: Reserved
+
+ [Mode]**
+ bit0~1: Nss - NSS_XXX (VHT only)
+ bit2~7: Reserved
+*/
+
+/* AGS: 1x1 HT-capable rate table */
+UCHAR AGS1x1HTRateTable[] = {
+ 0x09, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, /* Initial used item after association: the number of rate indexes, the initial mcs */
+ 0x00, 0x21, 0, 0, 30, 101, 0, 16, 8, 1, /* MCS 0 */
+ 0x01, 0x21, 0, 1, 20, 50, 0, 16, 9, 2, /* MCS 1 */
+ 0x02, 0x21, 0, 2, 20, 50, 1, 17, 9, 3, /* MCS 2 */
+ 0x03, 0x21, 0, 3, 15, 50, 2, 17, 10, 4, /* MCS 3 */
+ 0x04, 0x21, 0, 4, 15, 30, 3, 18, 11, 5, /* MCS 4 */
+ 0x05, 0x21, 0, 5, 10, 25, 4, 18, 12, 6, /* MCS 5 */
+ 0x06, 0x21, 0, 6, 8, 14, 5, 19, 12, 7, /* MCS 6 */
+ 0x07, 0x21, 0, 7, 8, 14, 6, 19, 12, 8, /* MCS 7 */
+ 0x08, 0x23, 0, 7, 8, 14, 7, 19, 12, 8, /* MCS 7 + Short GI */
+};
+
+
+/* AGS: 2x2 HT-capable rate table */
+UCHAR AGS2x2HTRateTable[] = {
+ 0x11, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, /* Initial used item after association: the number of rate indexes, the initial mcs */
+ 0x00, 0x21, 0, 0, 30, 101, 0, 16, 8, 1, /* MCS 0 */
+ 0x01, 0x21, 0, 1, 20, 50, 0, 16, 9, 2, /* MCS 1 */
+ 0x02, 0x21, 0, 2, 20, 50, 1, 17, 9, 3, /* MCS 2 */
+ 0x03, 0x21, 0, 3, 15, 50, 2, 17, 10, 4, /* MCS 3 */
+ 0x04, 0x21, 0, 4, 15, 30, 3, 18, 11, 5, /* MCS 4 */
+ 0x05, 0x21, 0, 5, 10, 25, 4, 18, 12, 6, /* MCS 5 */
+ 0x06, 0x21, 0, 6, 8, 14, 5, 19, 12, 7, /* MCS 6 */
+ 0x07, 0x21, 0, 7, 8, 14, 6, 19, 12, 7, /* MCS 7 */
+ 0x08, 0x20, 0, 8, 30, 50, 0, 16, 9, 2, /* MCS 8 */
+ 0x09, 0x20, 0, 9, 20, 50, 8, 17, 10, 4, /* MCS 9 */
+ 0x0A, 0x20, 0, 10, 20, 50, 9, 18, 11, 5, /* MCS 10 */
+ 0x0B, 0x20, 0, 11, 15, 30, 10, 18, 12, 6, /* MCS 11 */
+ 0x0C, 0x20, 0, 12, 15, 30, 11, 20, 13, 12, /* MCS 12 */
+ 0x0D, 0x20, 0, 13, 8, 20, 12, 20, 14, 13, /* MCS 13 */
+ 0x0E, 0x20, 0, 14, 8, 18, 13, 21, 15, 14, /* MCS 14 */
+ 0x0F, 0x20, 0, 15, 8, 25, 14, 21, 16, 15, /* MCS 15 */
+ 0x10, 0x22, 0, 15, 8, 25, 15, 21, 16, 16, /* MCS 15 + Short GI */
+};
+
+
+/* AGS: 3x3 HT-capable rate table */
+UCHAR AGS3x3HTRateTable[] = {
+ 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, 0, 30, 101, 0, 16, 8, 1, /* MCS 0 */
+ 0x01, 0x21, 0, 1, 20, 50, 0, 16, 9, 2, /* MCS 1 */
+ 0x02, 0x21, 0, 2, 20, 50, 1, 17, 9, 3, /* MCS 2 */
+ 0x03, 0x21, 0, 3, 15, 50, 2, 17, 10, 4, /* MCS 3 */
+ 0x04, 0x21, 0, 4, 15, 30, 3, 18, 11, 5, /* MCS 4 */
+ 0x05, 0x21, 0, 5, 10, 25, 4, 18, 12, 6, /* MCS 5 */
+ 0x06, 0x21, 0, 6, 8, 14, 5, 19, 12, 7, /* MCS 6 */
+ 0x07, 0x21, 0, 7, 8, 14, 6, 19, 12, 7, /* MCS 7 */
+ 0x08, 0x20, 0, 8, 30, 50, 0, 16, 9, 2, /* MCS 8 */
+ 0x09, 0x20, 0, 9, 20, 50, 8, 17, 10, 4, /* MCS 9 */
+ 0x0A, 0x20, 0, 10, 20, 50, 9, 18, 11, 5, /* MCS 10 */
+ 0x0B, 0x20, 0, 11, 15, 30, 10, 18, 12, 6, /* MCS 11 */
+ 0x0C, 0x20, 0, 12, 15, 30, 11, 20, 13, 12, /* MCS 12 */
+ 0x0D, 0x20, 0, 13, 8, 20, 12, 20, 14, 13, /* MCS 13 */
+ 0x0E, 0x20, 0, 14, 8, 18, 13, 21, 15, 14, /* MCS 14 */
+ 0x0F, 0x20, 0, 15, 8, 14, 14, 21, 15, 15, /* MCS 15 */
+ 0x10, 0x20, 0, 16, 30, 50, 8, 17, 9, 3, /* MCS 16 */
+ 0x11, 0x20, 0, 17, 20, 50, 16, 18, 11, 5, /* MCS 17 */
+ 0x12, 0x20, 0, 18, 20, 50, 17, 19, 12, 7, /* MCS 18 */
+ 0x13, 0x20, 0, 19, 15, 30, 18, 20, 13, 19, /* MCS 19 */
+ 0x14, 0x20, 0, 20, 15, 30, 19, 21, 15, 20, /* MCS 20 */
+ 0x15, 0x20, 0, 21, 8, 20, 20, 22, 21, 21, /* MCS 21 */
+ 0x16, 0x20, 0, 22, 8, 20, 21, 23, 22, 22, /* MCS 22 */
+ 0x17, 0x20, 0, 23, 6, 18, 22, 24, 23, 23, /* MCS 23 */
+ 0x18, 0x22, 0, 23, 6, 14, 23, 24, 24, 24, /* MCS 23 + Short GI */
+};
+
+
+#ifdef DOT11_VHT_AC
+
+#define NSS_1 0
+#define NSS_2 1
+/* RSSI Offset table for Ags rate tuning */
+UCHAR AgsRssiOffsetTable[3][4] =
+{
+ // [i][] MAX System spatial stream capability: 1*1, 2*2, 3*3
+ // [i][] MAX System Bandwidth: 20, 40, 80, 160
+ // ----------------------
+ {0, 2, 4, 6}, // For VHT 1*1: BW20, BW40, BW80, BW160
+ {2, 4, 6, 8}, // For VHT 2*2: BW20, BW40, BW80, BW160
+ {4, 6, 8, 10} // For VHT 3*3: BW20, BW40, BW80, BW160
+};
+
+
+/*
+ [Item no.] [Mode]* [Mode]** [CurrMCS] [TrainUp] [TrainDown] [downMCS] [upMCS3] [upMCS2] [upMCS1]
+
+ Note: downMCS, upMCS3, upMCS2 and upMCS1 are zero-based array index.
+
+ [Mode]*:
+ bit0: STBC -STBC_XXX
+ bit1: Short GI - GI_XXX
+ bit2~3: BW - BW_XXX
+ bit4~bit6: Mode (0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF, 4: VHT) - MODE_XXX
+ bit7: Reserved
+
+ [Mode]**
+ bit0~1: Nss - NSS_XXX (VHT only)
+ bit2~7: Reserved
+*/
+
+/* AGS: 1x1 VHT-capable rate table */
+UCHAR Ags1x1VhtRateTable[] =
+{
+ // Initial used item after association: the number of rate indexes, the initial MCS (index)
+ 9, 0x08, 0x00, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x41, 0x00, 0,/* VHT 1x1 MCS 0 */ 30, 101, 0, 0, 0, 1,
+ 1, 0x41, 0x00, 1,/* VHT 1x1 MCS 1 */ 20, 50, 0, 0, 0, 2,
+ 2, 0x41, 0x00, 2,/* VHT 1x1 MCS 2 */ 20, 50, 1, 0, 0, 3,
+ 3, 0x41, 0x00, 3,/* VHT 1x1 MCS 3 */ 15, 50, 2, 0, 0, 4,
+ 4, 0x41, 0x00, 4,/* VHT 1x1 MCS 4 */ 15, 30, 3, 0, 0, 5,
+ 5, 0x41, 0x00, 5,/* VHT 1x1 MCS 5 */ 10, 25, 4, 0, 0, 6,
+ 6, 0x41, 0x00, 6,/* VHT 1x1 MCS 6 */ 8, 14, 5, 0, 0, 7,
+ 7, 0x41, 0x00, 7,/* VHT 1x1 MCS 7 */ 8, 14, 6, 0, 0, 8,
+ 8, 0x43, 0x00, 7,/* VHT 1x1 MCS 7 + SGI */ 8, 14, 7, 0, 0, 8,
+};
+
+
+/* AGS: 2x2 VHT-capable rate table */
+UCHAR Ags2x2VhtRateTable[] = {
+ // row #1 is initial used item after association: the number of rate indexes, the initial MCS (index)
+ 17, 0x10, 0x00, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x41, 0x00, 0, /* VHT 1x1 MCS 0 */ 30, 101, 0, 0, 8, 1,
+ 1, 0x41, 0x00, 1, /* VHT 1x1 MCS 1 */ 20, 50, 0, 0, 9, 2,
+ 2, 0x41, 0x00, 2, /* VHT 1x1 MCS 2 */ 20, 50, 1, 0, 9, 3,
+ 3, 0x41, 0x00, 3, /* VHT 1x1 MCS 3 */ 15, 50, 2, 0, 10, 4,
+ 4, 0x41, 0x00, 4, /* VHT 1x1 MCS 4 */ 15, 30, 3, 0, 11, 5,
+ 5, 0x41, 0x00, 5, /* VHT 1x1 MCS 5 */ 10, 25, 4, 0, 12, 6,
+ 6, 0x41, 0x00, 6, /* VHT 1x1 MCS 6 */ 8, 14, 5, 0, 12, 7,
+ 7, 0x41, 0x00, 7, /* VHT 1x1 MCS 7 */ 8, 14, 6, 0, 12, 7,
+ 8, 0x40, 0x01, 0, /* VHT 2x2 MCS 0 */ 30, 50, 0, 0, 9, 2,
+ 9, 0x40, 0x01, 1, /* VHT 2x2 MCS 1 */ 20, 50, 8, 0, 10, 4,
+ 10, 0x40, 0x01, 2, /* VHT 2x2 MCS 2 */ 20, 50, 9, 0, 11, 5,
+ 11, 0x40, 0x01, 3, /* VHT 2x2 MCS 3 */ 15, 30, 10, 0, 12, 6,
+ 12, 0x40, 0x01, 4, /* VHT 2x2 MCS 4 */ 15, 30, 11, 0, 13, 12,
+ 13, 0x40, 0x01, 5, /* VHT 2x2 MCS 5 */ 8, 20, 12, 0, 14, 13,
+ 14, 0x40, 0x01, 6, /* VHT 2x2 MCS 6 */ 8, 18, 13, 0, 15, 14,
+ 15, 0x40, 0x01, 7, /* VHT 2x2 MCS 7 */ 8, 25, 14, 0, 16, 15,
+ 16, 0x42, 0x01, 7, /* VHT 2x2 MCS 7 + SGI */ 8, 25, 15, 0, 16, 16,
+};
+#endif /* DOT11_VHT_AC */
+
+
+INT Show_AGS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[1];
+ UINT32 IdQuality;
+
+
+ DBGPRINT(RT_DEBUG_OFF, ("MCS Group\t\tMCS Index\n"));
+ DBGPRINT(RT_DEBUG_OFF, ("%d\t\t\t%d\n\n", pEntry->AGSCtrl.MCSGroup, pEntry->CurrTxRateIndex));
+
+ DBGPRINT(RT_DEBUG_OFF, ("MCS Quality:\n"));
+ for(IdQuality=0; IdQuality<=23; IdQuality++)
+ DBGPRINT(RT_DEBUG_OFF, ("%02d\t\t%d\n", IdQuality, pEntry->TxQuality[IdQuality]));
+
+ return TRUE;
+}
+
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ The dynamic Tx rate switching for AGS in VHT(Adaptive Group Switching)
+
+ Parameters
+ pAd: The adapter data structure
+
+ Return Value:
+ None
+*/
+VOID ApMlmeDynamicTxRateSwitchingAGS(
+ IN RTMP_ADAPTER *pAd,
+ IN INT idx)
+{
+ UCHAR *pTable, TableSize = 0;
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[idx];
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+ RTMP_RA_AGS_TB *pCurrTxRate = NULL;
+ RTMP_RA_LEGACY_TB *pNextTxRate = NULL;
+ BOOLEAN bTxRateChanged = TRUE, bUpgradeQuality = FALSE;
+ UCHAR TrainUp = 0, TrainDown = 0, next_grp;
+ CHAR RssiOffset = 0;
+ ULONG TxTotalCnt, TxErrorRatio = 0;
+ ULONG TxSuccess, TxRetransmit, TxFailCount;
+ AGS_STATISTICS_INFO AGSStatisticsInfo = {0};
+
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("AGS: ---> %s\n", __FUNCTION__));
+
+ if (pAd->MacTab.Size == 1)
+ {
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+
+ /* Update statistic counter */
+ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ TxRetransmit = pEntry->OneSecTxRetryOkCount;
+ TxSuccess = pEntry->OneSecTxNoRetryOkCount;
+ TxFailCount = pEntry->OneSecTxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+#ifdef FIFO_EXT_SUPPORT
+ if (pEntry->Aid >= 1 && pEntry->Aid <= 8)
+ {
+ ULONG HwTxCnt, HwErrRatio;
+
+ NicGetMacFifoTxCnt(pAd, pEntry);
+ HwTxCnt = pEntry->fifoTxSucCnt + pEntry->fifoTxRtyCnt;
+ if (HwTxCnt)
+ HwErrRatio = (pEntry->fifoTxRtyCnt * 100) / HwTxCnt;
+ else
+ HwErrRatio = 0;
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,("%s():Aid:%d, MCS:%d, TxErrRatio(Hw:0x%lx-0x%lx, Sw:0x%lx-%lx)\n",
+ __FUNCTION__, pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ HwTxCnt, HwErrRatio, TxTotalCnt, TxErrorRatio));
+
+ TxSuccess = pEntry->fifoTxSucCnt;
+ TxRetransmit = pEntry->fifoTxRtyCnt;
+ TxTotalCnt = HwTxCnt;
+ TxErrorRatio = HwErrRatio;
+ }
+#endif /* FIFO_EXT_SUPPORT */
+ }
+
+ AGSStatisticsInfo.RSSI = RTMPAvgRssi(pAd, &pEntry->RssiSample);;
+ AGSStatisticsInfo.TxErrorRatio = TxErrorRatio;
+ AGSStatisticsInfo.AccuTxTotalCnt = TxTotalCnt;
+ AGSStatisticsInfo.TxTotalCnt = TxTotalCnt;
+ AGSStatisticsInfo.TxSuccess = TxSuccess;
+ AGSStatisticsInfo.TxRetransmit = TxRetransmit;
+ AGSStatisticsInfo.TxFailCount = TxFailCount;
+
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: QuickAGS: AccuTxTotalCnt = %ld, TxSuccess = %ld, TxRetransmit = %ld, TxFailCount = %ld, TxErrorRatio = %ld\n",
+ __FUNCTION__,
+ AGSStatisticsInfo.AccuTxTotalCnt,
+ AGSStatisticsInfo.TxSuccess,
+ AGSStatisticsInfo.TxRetransmit,
+ AGSStatisticsInfo.TxFailCount,
+ AGSStatisticsInfo.TxErrorRatio));
+
+ pTable = pEntry->pTable;
+ TableSize = pTable[0];
+
+ CurrRateIdx = pEntry->CurrTxRateIndex;
+
+ if (CurrRateIdx >= TableSize)
+ CurrRateIdx = TableSize - 1;
+
+
+ pCurrTxRate = (RTMP_RA_AGS_TB *)(&pTable[(CurrRateIdx + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]);
+
+ /* Select the next upgrade rate and the next downgrade rate, if any */
+ do
+ {
+ if (pTable == AGS3x3HTRateTable)
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%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 */
+ /* for 3*3, pEntry->AGSCtrl.MCSGroup = 0, 3, 3, 3, ... */
+ next_grp = pEntry->AGSCtrl.MCSGroup;
+ switch (pEntry->AGSCtrl.MCSGroup)
+ {
+ case 0: /* MCS selection in round robin policy (different MCS group) */
+ {
+ UpRateIdx = pCurrTxRate->upMcs3;
+ next_grp = 3;
+
+ /* MCS group #2 has better Tx quality */
+ if ((pEntry->TxQuality[UpRateIdx] > pEntry->TxQuality[pCurrTxRate->upMcs2]) &&
+ (pCurrTxRate->upMcs2 != pCurrTxRate->ItemNo))
+ {
+ UpRateIdx = pCurrTxRate->upMcs2;
+ next_grp = 2;
+ }
+
+ /* MCS group #1 has better Tx quality */
+ if ((pEntry->TxQuality[UpRateIdx] > pEntry->TxQuality[pCurrTxRate->upMcs1]) &&
+ (pCurrTxRate->upMcs1 != pCurrTxRate->ItemNo))
+ {
+ UpRateIdx = pCurrTxRate->upMcs1;
+ next_grp = 1;
+ }
+ }
+ break;
+
+ case 3:
+ UpRateIdx = pCurrTxRate->upMcs3;
+ break;
+
+ case 2:
+ UpRateIdx = pCurrTxRate->upMcs2;
+ break;
+
+ case 1:
+ UpRateIdx = pCurrTxRate->upMcs1;
+ break;
+
+ default:
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,
+ ("%s: AGS: Incorrect MCS group, pEntry->AGSCtrl.MCSGroup = %d\n",
+ __FUNCTION__, pEntry->AGSCtrl.MCSGroup));
+ }
+ break;
+ }
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("AGS> Current Group:%d, Select UpRateIdx=%d in group %d\n",
+ pEntry->AGSCtrl.MCSGroup, UpRateIdx, next_grp));
+
+
+ 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))))
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: ##############\n", __FUNCTION__));
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: AGS: [3x3 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 ((pTable == AGS2x2HTRateTable)
+#ifdef DOT11_VHT_AC
+ || (pTable == Ags2x2VhtRateTable)
+#endif /* DOT11_VHT_AC*/
+ )
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%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_INFO | DBG_FUNC_RA, ("%s: ###########\n", __FUNCTION__));
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%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_INFO | DBG_FUNC_RA, ("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_INFO | DBG_FUNC_RA,
+ ("ags> UpRateIdx = %d, DownRateIdx = %d\n",
+ UpRateIdx, DownRateIdx));
+
+#ifdef DOT11_N_SUPPORT
+ if ((AGSStatisticsInfo.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;
+
+
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: AGS: Rssi = %d, TxSuccess = %lu, TxRetransmit = %lu, TxFailCount = %lu, TxErrorRatio = %lu\n",
+ __FUNCTION__,
+ AGSStatisticsInfo.RSSI,
+ AGSStatisticsInfo.TxSuccess,
+ AGSStatisticsInfo.TxRetransmit,
+ AGSStatisticsInfo.TxFailCount,
+ AGSStatisticsInfo.TxErrorRatio));
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: AGS: Before - CurrTxRateIdx = %d, MCS = %d, STBC = %d, ShortGI = %d, Mode = %d, "
+ "TrainUp = %d, TrainDown = %d, NextUp = %d, NextDown = %d, "
+ "CurrMCS = %d, pEntry->AGSCtrl.MCSGroup = %d, PER = %lu%%, Retry = %lu, NoRetry = %lu\n",
+ __FUNCTION__,
+ CurrRateIdx,
+ pCurrTxRate->CurrMCS,
+ pCurrTxRate->STBC,
+ pCurrTxRate->ShortGI,
+ pCurrTxRate->Mode,
+ TrainUp,
+ TrainDown,
+ UpRateIdx,
+ DownRateIdx,
+ pEntry->HTPhyMode.field.MCS,
+ pEntry->AGSCtrl.MCSGroup,
+ AGSStatisticsInfo.TxErrorRatio,
+ AGSStatisticsInfo.TxRetransmit,
+ AGSStatisticsInfo.TxSuccess));
+
+ /* MCS selection based on the RSSI information when the Tx samples are fewer than 15. */
+ if (AGSStatisticsInfo.AccuTxTotalCnt <= 15)
+ {
+ CHAR idx = 0;
+ UCHAR TxRateIdx;
+ UCHAR MCS[24] = {0};
+ /* Check the existence and index of each needed MCS */
+
+#ifdef DOT11_VHT_AC
+ if ((pTable == Ags2x2VhtRateTable) || (pTable == Ags1x1VhtRateTable))
+ {
+ INT mcs_idx_offset;
+ while (idx < pTable[0])
+ {
+ pCurrTxRate = (RTMP_RA_AGS_TB *)(&pTable[(idx + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]);
+ if (pCurrTxRate->Mode == MODE_VHT)
+ {
+ if (pCurrTxRate->Nss == NSS_1)
+ mcs_idx_offset = 0;
+ else if ((pCurrTxRate->Nss == NSS_2) && (pTable == Ags2x2VhtRateTable))
+ mcs_idx_offset = 8;
+ else {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():Invalid Nss(%d)\n", __FUNCTION__, pCurrTxRate->Nss));
+ mcs_idx_offset = 0;
+ }
+
+ if ((pCurrTxRate->CurrMCS <= MCS_7) /* && (pCurrTxRate->CurrMCS >= MCS_0) */)
+ MCS[pCurrTxRate->CurrMCS + mcs_idx_offset] = idx;
+ }
+ idx++;
+ }
+ }
+ else
+#endif /* DOT11_VHT_AC */
+ {
+ while (idx < pTable[0])
+ {
+ pCurrTxRate = (RTMP_RA_AGS_TB *)(&pTable[(idx + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]);
+
+ if (pCurrTxRate->CurrMCS <= MCS_23 /* && pCurrTxRate->CurrMCS >= MCS_0 */)
+ MCS[pCurrTxRate->CurrMCS] = idx;
+ idx++;
+ }
+ }
+
+ /* peer device (Adhoc, DLS or AP) */
+ RssiOffset = 0;
+ if (pTable == AGS3x3HTRateTable)
+ {
+ if (MCS[23] && (AGSStatisticsInfo.RSSI > (-67 + RssiOffset)))
+ TxRateIdx = MCS[23];
+ else if (MCS[22] && (AGSStatisticsInfo.RSSI > (-69 + RssiOffset)))
+ TxRateIdx = MCS[22];
+ else if (MCS[21] && (AGSStatisticsInfo.RSSI > (-72 + RssiOffset)))
+ TxRateIdx = MCS[21];
+ else if (MCS[20] && (AGSStatisticsInfo.RSSI > (-74 + RssiOffset)))
+ TxRateIdx = MCS[20];
+ else if (MCS[19] && (AGSStatisticsInfo.RSSI > (-78 + RssiOffset)))
+ TxRateIdx = MCS[19];
+ else if (MCS[18] && (AGSStatisticsInfo.RSSI > (-80 + RssiOffset)))
+ TxRateIdx = MCS[18];
+ else if (MCS[17] && (AGSStatisticsInfo.RSSI > (-85 + RssiOffset)))
+ TxRateIdx = MCS[17];
+ else
+ TxRateIdx = MCS[16];
+
+ pEntry->AGSCtrl.MCSGroup = 3;
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("ags> Group3 RSSI = %d, TxRateIdx = %d\n",
+ AGSStatisticsInfo.RSSI, TxRateIdx));
+ }
+ else if ((pTable == AGS2x2HTRateTable)
+#ifdef DOT11_VHT_AC
+ || (pTable == Ags2x2VhtRateTable)
+#endif /* DOT11_VHT_AC */
+ )
+ {
+#ifdef DOT11_VHT_AC
+ if (pTable == Ags2x2VhtRateTable)
+ RssiOffset = AgsRssiOffsetTable[1][pAd->CommonCfg.BBPCurrentBW];
+#endif /* DOT11_VHT_AC */
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s: AGS: 2*2, RssiOffsetForAgs=%d\n", __FUNCTION__, RssiOffset));
+
+ if (MCS[15] && (AGSStatisticsInfo.RSSI > (-69 + RssiOffset)))
+ TxRateIdx = MCS[15];
+ else if (MCS[14] && (AGSStatisticsInfo.RSSI > (-71 + RssiOffset)))
+ TxRateIdx = MCS[14];
+ else if (MCS[13] && (AGSStatisticsInfo.RSSI > (-74 + RssiOffset)))
+ TxRateIdx = MCS[13];
+ else if (MCS[12] && (AGSStatisticsInfo.RSSI > (-76 + RssiOffset)))
+ TxRateIdx = MCS[12];
+ else if (MCS[11] && (AGSStatisticsInfo.RSSI > (-80 + RssiOffset)))
+ TxRateIdx = MCS[11];
+ else if (MCS[10] && (AGSStatisticsInfo.RSSI > (-82 + RssiOffset)))
+ TxRateIdx = MCS[10];
+ else if (MCS[9] && (AGSStatisticsInfo.RSSI > (-87 + RssiOffset)))
+ TxRateIdx = MCS[9];
+ else
+ TxRateIdx = MCS[8];
+
+ pEntry->AGSCtrl.MCSGroup = 2;
+ }
+ else
+ {
+#ifdef DOT11_VHT_AC
+ if (pTable == Ags1x1VhtRateTable)
+ RssiOffset = AgsRssiOffsetTable[0][pAd->CommonCfg.BBPCurrentBW];
+#endif /* DOT11_VHT_AC */
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: AGS: 1*1, RssiOffset=%d\n", __FUNCTION__, RssiOffset));
+
+ /* 1x1 peer device (Adhoc, DLS or AP) */
+ if (MCS[7] && (AGSStatisticsInfo.RSSI > (-71 + RssiOffset)))
+ TxRateIdx = MCS[7];
+ else if (MCS[6] && (AGSStatisticsInfo.RSSI > (-73 + RssiOffset)))
+ TxRateIdx = MCS[6];
+ else if (MCS[5] && (AGSStatisticsInfo.RSSI > (-76 + RssiOffset)))
+ TxRateIdx = MCS[5];
+ else if (MCS[4] && (AGSStatisticsInfo.RSSI > (-78 + RssiOffset)))
+ TxRateIdx = MCS[4];
+ else if (MCS[3] && (AGSStatisticsInfo.RSSI > (-82 + RssiOffset)))
+ TxRateIdx = MCS[3];
+ else if (MCS[2] && (AGSStatisticsInfo.RSSI > (-84 + RssiOffset)))
+ TxRateIdx = MCS[2];
+ else if (MCS[1] && (AGSStatisticsInfo.RSSI > (-89 + RssiOffset)))
+ TxRateIdx = MCS[1];
+ else
+ TxRateIdx = MCS[0];
+
+ pEntry->AGSCtrl.MCSGroup = 1;
+ }
+
+ pEntry->AGSCtrl.lastRateIdx = pEntry->CurrTxRateIndex;
+ pEntry->CurrTxRateIndex = TxRateIdx;
+
+ pNextTxRate = (RTMP_RA_LEGACY_TB *)(&pTable[(pEntry->CurrTxRateIndex + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]);
+ APMlmeSetTxRate(pAd, pEntry, pNextTxRate);
+
+ RTMPZeroMemory(pEntry->TxQuality, (sizeof(USHORT) * (MAX_TX_RATE_INDEX+1)));
+ RTMPZeroMemory(pEntry->PER, (sizeof(UCHAR) * (MAX_TX_RATE_INDEX+1)));
+
+ 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 = RATE_NO_CHANGE;
+
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: AGS: The MCS selection base on RSSI\n", __FUNCTION__));
+
+ return;
+ }
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: AGS: TrainUp:%d, TrainDown:%d\n", __FUNCTION__, TrainUp, TrainDown));
+
+ do
+ {
+ BOOLEAN bTrainUpDown = FALSE;
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: AGS: TxQuality[CurrRateIdx(%d)] = %d, UpPenalty:%d\n",
+ __FUNCTION__, CurrRateIdx,
+ pEntry->TxQuality[CurrRateIdx], pEntry->TxRateUpPenalty));
+
+ if (AGSStatisticsInfo.TxErrorRatio >= TrainDown) /* Poor quality */
+ {
+ /* error ratio too high, do rate down */
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: AGS: (DOWN) TxErrorRatio >= TrainDown\n",__FUNCTION__));
+ bTrainUpDown = TRUE;
+ pEntry->TxQuality[CurrRateIdx] = AGS_TX_QUALITY_WORST_BOUND;
+ }
+ else if (AGSStatisticsInfo.TxErrorRatio <= TrainUp) /* Good quality */
+ {
+ bTrainUpDown = TRUE;
+ bUpgradeQuality = TRUE;
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: AGS: (UP) pEntry->TxQuality[CurrRateIdx] = %d, pEntry->TxRateUpPenalty = %d\n",
+ __FUNCTION__,
+ pEntry->TxQuality[CurrRateIdx],
+ pEntry->TxRateUpPenalty));
+
+ if (pEntry->TxQuality[CurrRateIdx])
+ pEntry->TxQuality[CurrRateIdx]--; /* Good quality in the current Tx rate */
+
+ if (pEntry->TxRateUpPenalty)
+ pEntry->TxRateUpPenalty--; /* no use for the parameter */
+ 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]--;
+ }
+ }
+ else if (pEntry->AGSCtrl.MCSGroup > 0) /* even if TxErrorRatio > TrainUp */
+ {
+ /* not bad and not good */
+ if (UpRateIdx != 0)
+ {
+ bTrainUpDown = FALSE;
+
+ /* Good quality in the current Tx rate */
+ if (pEntry->TxQuality[CurrRateIdx])
+ pEntry->TxQuality[CurrRateIdx]--;
+
+ /* It may improve next train-up Tx rate's quality */
+ if (pEntry->TxQuality[UpRateIdx])
+ pEntry->TxQuality[UpRateIdx]--;
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("ags> not bad and not good\n"));
+ }
+ }
+
+ /* update error ratio for current MCS */
+ pEntry->PER[CurrRateIdx] = (UCHAR)(AGSStatisticsInfo.TxErrorRatio);
+
+ /* Update the current Tx rate */
+ if (bTrainUpDown)
+ {
+ /* need to rate up or down */
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%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 = RATE_DOWN;
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("ags> rate down!\n"));
+ }
+ else if ((CurrRateIdx != UpRateIdx) &&
+ (pEntry->TxQuality[UpRateIdx] <= 0)) /* Upgrade Tx rate */
+ {
+ pEntry->CurrTxRateIndex = UpRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("ags> rate up!\n"));
+ }
+ }
+ } while (FALSE);
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: AGS: pEntry->CurrTxRateIndex = %d, CurrRateIdx = %d, pEntry->LastSecTxRateChangeAction = %d\n",
+ __FUNCTION__,
+ pEntry->CurrTxRateIndex, CurrRateIdx,
+ pEntry->LastSecTxRateChangeAction));
+
+ /* rate up/down post handle */
+ if ((pEntry->CurrTxRateIndex != CurrRateIdx) &&
+ (pEntry->LastSecTxRateChangeAction == RATE_UP))
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: AGS: ++TX rate from %d to %d\n",
+ __FUNCTION__, CurrRateIdx, pEntry->CurrTxRateIndex));
+
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ pEntry->TxRateUpPenalty = 0;
+ RTMPZeroMemory(pEntry->PER, sizeof(UCHAR) * (MAX_TX_RATE_INDEX+1));
+ pEntry->AGSCtrl.lastRateIdx = CurrRateIdx;
+
+ bTxRateChanged = TRUE;
+ }
+ else if ((pEntry->CurrTxRateIndex != CurrRateIdx) &&
+ (pEntry->LastSecTxRateChangeAction == RATE_DOWN))
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: AGS: --TX rate from %d to %d\n",
+ __FUNCTION__, CurrRateIdx, pEntry->CurrTxRateIndex));
+
+ pEntry->LastSecTxRateChangeAction = RATE_DOWN;
+ pEntry->TxRateUpPenalty = 0; /* No penalty */
+ pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0;
+ pEntry->AGSCtrl.lastRateIdx = CurrRateIdx;
+
+ bTxRateChanged = TRUE;
+ }
+ else /* Tx rate remains unchanged. */
+ {
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE; /* Tx rate remains unchanged. */
+ bTxRateChanged = FALSE;
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("ags> no rate up/down!\n"));
+ }
+
+ /* Tx rate fast train up/down */
+ if ((bTxRateChanged == TRUE) &&
+ (!pAd->ApCfg.ApQuickResponeForRateUpTimerRunning))
+ {
+ RTMPSetTimer(&pAd->ApCfg.ApQuickResponeForRateUpTimer, pAd->ra_fast_interval);
+ pAd->ApCfg.ApQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ pEntry->LastTxOkCount = AGSStatisticsInfo.TxSuccess;
+
+ /* set new tx rate */
+ pNextTxRate = (RTMP_RA_LEGACY_TB *)(&pTable[(pEntry->CurrTxRateIndex + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]);
+
+ if ((bTxRateChanged == TRUE) && (pNextTxRate != NULL))
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("ags> set new rate MCS = %d!\n", pEntry->CurrTxRateIndex));
+ APMlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+
+ /* 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 ApQuickResponeForRateUpExecAGS(
+ IN RTMP_ADAPTER *pAd,
+ IN INT idx)
+{
+ UCHAR *pTable, TableSize = 0;
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+ RTMP_RA_AGS_TB *pCurrTxRate = NULL;
+ RTMP_RA_LEGACY_TB *pNextTxRate = NULL;
+ BOOLEAN bTxRateChanged = TRUE;
+ UCHAR TrainUp = 0, TrainDown = 0;
+ CHAR ratio = 0;
+ ULONG OneSecTxNoRetryOKRationCount = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ AGS_STATISTICS_INFO AGSStatisticsInfo = {0};
+ ULONG TxTotalCnt, TxErrorRatio = 0;
+ ULONG TxSuccess, TxRetransmit, TxFailCount;
+
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("QuickAGS: ---> %s\n", __FUNCTION__));
+ pAd->ApCfg.ApQuickResponeForRateUpTimerRunning = FALSE;
+
+ pEntry = &pAd->MacTab.Content[idx]; /* point to information of the individual station */
+ pTable = pEntry->pTable;
+ TableSize = pTable[0];
+
+ if (pAd->MacTab.Size == 1)
+ {
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+
+ /* Update statistic counter */
+ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ TxRetransmit = pEntry->OneSecTxRetryOkCount;
+ TxSuccess = pEntry->OneSecTxNoRetryOkCount;
+ TxFailCount = pEntry->OneSecTxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+#ifdef FIFO_EXT_SUPPORT
+ if (pEntry->Aid >= 1 && pEntry->Aid <= 8)
+ {
+ ULONG HwTxCnt, HwErrRatio;
+
+ NicGetMacFifoTxCnt(pAd, pEntry);
+ HwTxCnt = pEntry->fifoTxSucCnt + pEntry->fifoTxRtyCnt;
+ if (HwTxCnt)
+ HwErrRatio = (pEntry->fifoTxRtyCnt * 100) / HwTxCnt;
+ else
+ HwErrRatio = 0;
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,("%s():Aid:%d, MCS:%d, TxErrRatio(Hw:0x%lx-0x%lx, Sw:0x%lx-%lx)\n",
+ __FUNCTION__, pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ HwTxCnt, HwErrRatio, TxTotalCnt, TxErrorRatio));
+
+ TxSuccess = pEntry->fifoTxSucCnt;
+ TxRetransmit = pEntry->fifoTxRtyCnt;
+ TxTotalCnt = HwTxCnt;
+ TxErrorRatio = HwErrRatio;
+ }
+#endif /* FIFO_EXT_SUPPORT */
+ }
+
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: QuickAGS: AccuTxTotalCnt = %lu, TxSuccess = %lu, "
+ "TxRetransmit = %lu, TxFailCount = %lu, TxErrorRatio = %lu\n",
+ __FUNCTION__,
+ AGSStatisticsInfo.AccuTxTotalCnt,
+ AGSStatisticsInfo.TxSuccess,
+ AGSStatisticsInfo.TxRetransmit,
+ AGSStatisticsInfo.TxFailCount,
+ AGSStatisticsInfo.TxErrorRatio));
+
+ CurrRateIdx = pEntry->CurrTxRateIndex;
+
+ if (CurrRateIdx >= TableSize)
+ CurrRateIdx = TableSize - 1;
+
+ UpRateIdx = DownRateIdx = pEntry->AGSCtrl.lastRateIdx;
+
+ pCurrTxRate = (RTMP_RA_AGS_TB *)(&pTable[(CurrRateIdx + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]);
+
+ if ((AGSStatisticsInfo.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 (AGSStatisticsInfo.AccuTxTotalCnt <= 15)
+ {
+ RTMPZeroMemory(pEntry->TxQuality, sizeof(USHORT) * (MAX_TX_RATE_INDEX+1));
+ RTMPZeroMemory(pEntry->PER, sizeof(UCHAR) * (MAX_TX_RATE_INDEX+1));
+
+ 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_INFO | DBG_FUNC_RA,
+ ("%s: QuickAGS: AccuTxTotalCnt <= 15, train back to original rate\n",
+ __FUNCTION__));
+
+ return;
+ }
+
+ do
+ {
+ if (pEntry->LastTimeTxRateChangeAction == 0)
+ ratio = 5;
+ else
+ ratio = 4;
+
+ if (AGSStatisticsInfo.TxErrorRatio >= TrainDown) /* Poor quality */
+ pEntry->TxQuality[CurrRateIdx] = AGS_TX_QUALITY_WORST_BOUND;
+
+ pEntry->PER[CurrRateIdx] = (UCHAR)(AGSStatisticsInfo.TxErrorRatio);
+
+ OneSecTxNoRetryOKRationCount = (AGSStatisticsInfo.TxSuccess * ratio);
+
+ /* Tx rate down */
+ if ((pEntry->LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+ {
+ // Change Auto Rate tuning rule 1: Change from tx_ok to PER
+ if (AGSStatisticsInfo.TxErrorRatio > TrainDown) /* Poor quality */
+ {
+ pEntry->CurrTxRateIndex = DownRateIdx;
+ pEntry->TxQuality[CurrRateIdx] = AGS_TX_QUALITY_WORST_BOUND;
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: QuickAGS: (UP) bad Tx ok count (Current PER:%ld, NewMcs's TrainDown:%d)\n",
+ __FUNCTION__, AGSStatisticsInfo.TxErrorRatio, TrainDown));
+ }
+ else /* Good quality */
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s: QuickAGS: (UP) keep rate-up (Current PER:%ld, NewMcs's TrainDown:%d)\n",
+ __FUNCTION__, AGSStatisticsInfo.TxErrorRatio, TrainDown));
+
+ RTMPZeroMemory(pEntry->TxQuality, sizeof(USHORT) * (MAX_TX_RATE_INDEX+1));
+
+ if (pEntry->AGSCtrl.MCSGroup == 0)
+ {
+ if (pTable == AGS3x3HTRateTable)
+ pEntry->AGSCtrl.MCSGroup = 3;
+ else if ((pTable == AGS2x2HTRateTable) ||
+ (pTable == Ags2x2VhtRateTable))
+ pEntry->AGSCtrl.MCSGroup = 2;
+ else
+ pEntry->AGSCtrl.MCSGroup = 1;
+ }
+ }
+ }
+ else if ((pEntry->LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) // Tx rate up
+ {
+
+// Don't quick check within train down case
+ }
+ }while (FALSE);
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("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 = (RTMP_RA_AGS_TB *)(&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_INFO | DBG_FUNC_RA, ("%s: QuickAGS: Incorrect MCS group, pEntry->AGSCtrl.MCSGroup = %d\n",
+ __FUNCTION__,
+ pEntry->AGSCtrl.MCSGroup));
+ }
+ break;
+ }
+
+ /* Try to escape the local optima */
+ if (UpRateIdx == pEntry->CurrTxRateIndex)
+ pEntry->AGSCtrl.MCSGroup = 0;
+
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%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_INFO | DBG_FUNC_RA, ("%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_TX_RATE_INDEX+1));
+ }
+ else if ((pEntry->CurrTxRateIndex != CurrRateIdx) &&
+ (pEntry->LastSecTxRateChangeAction == 1)) /* Tx rate down */
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%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_INFO | DBG_FUNC_RA, ("%s: QuickAGS: rate is not changed\n", __FUNCTION__));
+ }
+
+ pNextTxRate = (RTMP_RA_LEGACY_TB *)(&pTable[(pEntry->CurrTxRateIndex + 1) * SIZE_OF_AGS_RATE_TABLE_ENTRY]);
+ if ((bTxRateChanged == TRUE) && (pNextTxRate != NULL))
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("ags> confirm current rate MCS = %d!\n", pEntry->CurrTxRateIndex));
+
+ APMlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("QuickAGS: <--- %s\n", __FUNCTION__));
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+#endif /* AGS_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_grp.c b/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_grp.c
new file mode 100644
index 0000000000..ebe34a2e06
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_grp.c
@@ -0,0 +1,1661 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related Dynamic Rate Switch (AP/STA) function body.
+
+ History:
+
+***************************************************************************/
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+#include "rt_config.h"
+
+
+/*
+ MlmeSetMcsGroup - set initial mcsGroup based on supported MCSs
+ On exit pEntry->mcsGroup is set to the mcsGroup
+*/
+VOID MlmeSetMcsGroup(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry)
+{
+#ifdef DOT11N_SS3_SUPPORT
+ if ((pEntry->HTCapability.MCSSet[2] == 0xff) && (pAd->CommonCfg.TxStream == 3))
+ pEntry->mcsGroup = 3;
+ else
+#endif /* DOT11N_SS3_SUPPORT */
+ 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;
+
+#ifdef DOT11_VHT_AC
+ // TODO: shiang-6590, fix me!!
+ if (pEntry->SupportRateMode & SUPPORT_VHT_MODE)
+ {
+ if ((pAd->CommonCfg.TxStream == 2) && (pEntry->SupportVHTMCS[8] == 0x1))
+ pEntry->mcsGroup = 2;
+ else
+ pEntry->mcsGroup = 1;
+ }
+#endif /* DOT11_VHT_AC */
+}
+
+
+/*
+ MlmeSelectUpRate - select UpRate based on MCS group
+ returns the UpRate index and updates the MCS group
+*/
+UCHAR MlmeSelectUpRate(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RTMP_RA_GRP_TB *pCurrTxRate)
+{
+ UCHAR UpRateIdx = 0;
+
+ while (1)
+ {
+ 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 (UpRateIdx == pCurrTxRate->ItemNo)
+ {
+ UpRateIdx = pCurrTxRate->upMcs2;
+ if (UpRateIdx == pCurrTxRate->ItemNo)
+ UpRateIdx = pCurrTxRate->upMcs1;
+ }
+
+ if (MlmeGetTxQuality(pEntry, UpRateIdx) > MlmeGetTxQuality(pEntry, pCurrTxRate->upMcs2) &&
+ pCurrTxRate->upMcs2 != pCurrTxRate->ItemNo)
+ UpRateIdx = pCurrTxRate->upMcs2;
+
+ if (MlmeGetTxQuality(pEntry, UpRateIdx) > MlmeGetTxQuality(pEntry, 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_ERROR, ("3ss:wrong mcsGroup value\n"));
+ break;
+ }
+
+ }
+ 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)))
+#ifdef DOT11_VHT_AC
+ || (pEntry->pTable == RateTableVht2S)
+#endif /* DOT11_VHT_AC */
+ )
+ {
+ switch (pEntry->mcsGroup)
+ {
+ case 0:
+ UpRateIdx = pCurrTxRate->upMcs2;
+ if (UpRateIdx == pCurrTxRate->ItemNo)
+ UpRateIdx = pCurrTxRate->upMcs1;
+
+ if (MlmeGetTxQuality(pEntry, UpRateIdx) > MlmeGetTxQuality(pEntry, 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;
+ }
+
+ }
+ 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 going up from CCK to MCS32 make sure it's allowed */
+ if (PTX_RA_GRP_ENTRY(pEntry->pTable, UpRateIdx)->CurrMCS == 32)
+ {
+ /* If not allowed then skip over it */
+ BOOLEAN mcs32Supported = 0;
+ BOOLEAN mcs0Fallback = 0;
+
+ if ((pEntry->HTCapability.MCSSet[4] & 0x1)
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_ENABLE_HT_DUP)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ mcs32Supported = 1;
+
+#ifdef DBG_CTRL_SUPPORT
+ if ((pAd->CommonCfg.DebugFlags & DBF_DISABLE_20MHZ_MCS0)==0)
+ mcs0Fallback = 1;
+#endif /* DBG_CTRL_SUPPORT */
+
+ if (pEntry->MaxHTPhyMode.field.BW != BW_40 ||
+ pAd->CommonCfg.BBPCurrentBW != BW_40 ||
+ (!mcs32Supported && !mcs0Fallback))
+ {
+ UpRateIdx = PTX_RA_GRP_ENTRY(pEntry->pTable, UpRateIdx)->upMcs1;
+ pEntry->mcsGroup = 1;
+ break;
+ }
+ }
+
+ /* If ShortGI and not allowed then mark it as bad. We'll try another group below */
+ if (PTX_RA_GRP_ENTRY(pEntry->pTable, UpRateIdx)->ShortGI &&
+ !pEntry->MaxHTPhyMode.field.ShortGI)
+ {
+ MlmeSetTxQuality(pEntry, UpRateIdx, DRS_TX_QUALITY_WORST_BOUND*2);
+ }
+
+ /* If we reached the end of the group then select the best next time */
+ if (UpRateIdx == pEntry->CurrTxRateIndex)
+ {
+ pEntry->mcsGroup = 0;
+ break;
+ }
+
+ /* If the current group has bad TxQuality then try another group */
+ if ((MlmeGetTxQuality(pEntry, UpRateIdx) > 0) && (pEntry->mcsGroup > 0))
+ pEntry->mcsGroup--;
+ else
+ break;
+ }
+
+ return UpRateIdx;
+}
+
+/*
+ MlmeSelectDownRate - select DownRate.
+ pEntry->pTable is assumed to be a pointer to an adaptive rate table with mcsGroup values
+ CurrRateIdx - current rate index
+ returns the DownRate index. Down Rate = CurrRateIdx if there is no valid Down Rate
+*/
+UCHAR MlmeSelectDownRate(
+ IN RTMP_ADAPTER *pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR CurrRateIdx)
+{
+ UCHAR DownRateIdx = PTX_RA_GRP_ENTRY(pEntry->pTable, CurrRateIdx)->downMcs;
+ RTMP_RA_GRP_TB *pDownRate;
+
+ /* Loop until a valid down rate is found */
+ while (1) {
+ pDownRate = PTX_RA_GRP_ENTRY(pEntry->pTable, DownRateIdx);
+
+ /* Break out of loop if rate is valid */
+ if (pDownRate->Mode==MODE_CCK)
+ {
+ /* CCK is valid only if in G band and if not disabled */
+ if ((pAd->LatchRfRegs.Channel<=14
+#ifdef DBG_CTRL_SUPPORT
+ || (pAd->CommonCfg.DebugFlags & DBF_ENABLE_CCK_5G)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+#ifdef DBG_CTRL_SUPPORT
+ && ((pAd->CommonCfg.DebugFlags & DBF_DISABLE_CCK)==0)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ break;
+ }
+ else if (pDownRate->CurrMCS == MCS_32)
+ {
+ BOOLEAN valid_mcs32 = FALSE;
+
+ if ((pEntry->MaxHTPhyMode.field.BW == BW_40 && pAd->CommonCfg.BBPCurrentBW == BW_40)
+#ifdef DOT11_VHT_AC
+ || (pEntry->MaxHTPhyMode.field.BW == BW_80 && pAd->CommonCfg.BBPCurrentBW == BW_80)
+#endif /* DOT11_VHT_AC */
+ )
+ valid_mcs32 = TRUE;
+
+ /* If 20MHz MCS0 fallback enabled and in 40MHz then MCS32 is valid and will be mapped to 20MHz MCS0 */
+ if (valid_mcs32
+#ifdef DBG_CTRL_SUPPORT
+ && ((pAd->CommonCfg.DebugFlags & DBF_DISABLE_20MHZ_MCS0)==0)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ break;
+
+ /* MCS32 is valid if enabled and client supports it */
+ if (valid_mcs32 && (pEntry->HTCapability.MCSSet[4] & 0x1)
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_ENABLE_HT_DUP)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ break;
+ }
+ else
+ break; /* All other rates are valid */
+
+ /* Return original rate if we reached the end without finding a valid rate */
+ if (DownRateIdx == pDownRate->downMcs)
+ return CurrRateIdx;
+
+ /* Otherwise try the next lower rate */
+ DownRateIdx = pDownRate->downMcs;
+ }
+
+ return DownRateIdx;
+}
+
+
+/*
+ MlmeGetSupportedMcsAdapt - fills in the table of supported MCSs
+ pAd - pointer to adapter
+ pEntry - MAC Table entry. pEntry->pTable is a rate table with mcsGroup values
+ mcs23GI - the MCS23 entry will have this guard interval
+ mcs - table of MCS index into the Rate Table. -1 => not supported
+*/
+VOID MlmeGetSupportedMcsAdapt(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR mcs23GI,
+ OUT CHAR mcs[])
+{
+ CHAR idx;
+ RTMP_RA_GRP_TB *pCurrTxRate;
+ UCHAR *pTable = pEntry->pTable;
+
+ for (idx=0; idx<24; idx++)
+ mcs[idx] = -1;
+
+#ifdef DOT11_VHT_AC
+ if (pEntry->pTable == RateTableVht1S || pEntry->pTable == RateTableVht2S)
+ {
+ for (idx = 0; idx < RATE_TABLE_SIZE(pTable); idx++)
+ {
+ pCurrTxRate = PTX_RA_GRP_ENTRY(pEntry->pTable, idx);
+ if (pCurrTxRate->CurrMCS == MCS_0 && pCurrTxRate->dataRate == 1)
+ mcs[0] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_1 && pCurrTxRate->dataRate == 1)
+ mcs[1] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_2 && pCurrTxRate->dataRate == 1)
+ mcs[2] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_3 && pCurrTxRate->dataRate == 1)
+ mcs[3] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_4 && pCurrTxRate->dataRate == 1)
+ mcs[4] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_5 && pCurrTxRate->dataRate == 1)
+ mcs[5] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_6 && pCurrTxRate->dataRate == 1)
+ mcs[6] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_7 && pCurrTxRate->dataRate == 1)
+ mcs[7] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_0 && pCurrTxRate->dataRate == 2)
+ mcs[8] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_1 && pCurrTxRate->dataRate == 2)
+ mcs[9] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_2 && pCurrTxRate->dataRate == 2)
+ mcs[10] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_3 && pCurrTxRate->dataRate == 2)
+ mcs[11] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_4 && pCurrTxRate->dataRate == 2)
+ mcs[12] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_5 && pCurrTxRate->dataRate == 2)
+ mcs[13] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_6 && pCurrTxRate->dataRate == 2)
+ mcs[14] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_7 && pCurrTxRate->dataRate == 2)
+ mcs[15] = idx;
+ }
+
+ return;
+ }
+#endif /* DOT11_VHT_AC */
+
+ /* check the existence and index of each needed MCS */
+ for (idx = 0; idx < RATE_TABLE_SIZE(pTable); idx++)
+ {
+ pCurrTxRate = PTX_RA_GRP_ENTRY(pEntry->pTable, idx);
+
+ if ((pCurrTxRate->CurrMCS >= 8 && pAd->CommonCfg.TxStream < 2) ||
+ (pCurrTxRate->CurrMCS >= 16 && pAd->CommonCfg.TxStream < 3))
+ continue;
+
+ /* Rate Table may contain CCK and MCS rates. Give HT/Legacy priority over CCK */
+ if (pCurrTxRate->CurrMCS==MCS_0 && (mcs[0]==-1 || pCurrTxRate->Mode!=MODE_CCK))
+ mcs[0] = idx;
+ else if (pCurrTxRate->CurrMCS==MCS_1 && (mcs[1]==-1 || pCurrTxRate->Mode!=MODE_CCK))
+ mcs[1] = idx;
+ else if (pCurrTxRate->CurrMCS==MCS_2 && (mcs[2]==-1 || pCurrTxRate->Mode!=MODE_CCK))
+ mcs[2] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_3)
+ mcs[3] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_4)
+ mcs[4] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_5)
+ mcs[5] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_6)
+ mcs[6] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))
+ mcs[7] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_8)
+ mcs[8] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_9)
+ mcs[9] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_10)
+ mcs[10] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_11)
+ mcs[11] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_12)
+ mcs[12] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_13)
+ mcs[13] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_14) && (pCurrTxRate->ShortGI == GI_800))
+ mcs[14] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))
+ mcs[15] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_16)
+ mcs[16] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_17)
+ mcs[17] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_18)
+ mcs[18] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_19)
+ mcs[19] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_20)
+ mcs[20] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_21) && (pCurrTxRate->ShortGI == GI_800))
+ mcs[21] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_22) && (pCurrTxRate->ShortGI == GI_800))
+ mcs[22] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_23) && (pCurrTxRate->ShortGI == mcs23GI))
+ mcs[23] = idx;
+ }
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug Option: Disable highest MCSs when picking initial MCS based on RSSI */
+ if (pAd->CommonCfg.DebugFlags & DBF_INIT_MCS_DIS1)
+ mcs[23] = mcs[15] = mcs[7] = mcs[22] = mcs[14] = mcs[6] = 0;
+#endif /* DBG_CTRL_SUPPORT */
+
+}
+
+
+/*
+ MlmeSelectTxRateAdapt - select the MCS based on the RSSI and the available MCSs
+ pAd - pointer to adapter
+ pEntry - pointer to MAC table entry
+ mcs - table of MCS index into the Rate Table. -1 => not supported
+ Rssi - the Rssi value
+ RssiOffset - offset to apply to the Rssi
+*/
+UCHAR MlmeSelectTxRateAdapt(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN CHAR mcs[],
+ IN CHAR Rssi,
+ IN CHAR RssiOffset)
+{
+ UCHAR TxRateIdx = 0;
+ UCHAR *pTable = pEntry->pTable;
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug option: Add 6 dB of margin */
+ if (pAd->CommonCfg.DebugFlags & DBF_INIT_MCS_MARGIN)
+ RssiOffset += 6;
+#endif /* DBG_CTRL_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11_VHT_AC
+ if ((pTable == RateTableVht1S || pTable == RateTableVht2S))
+ {
+ if (pTable == RateTableVht2S)
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: GRP: 2*2, RssiOffset=%d\n", __FUNCTION__, RssiOffset));
+
+ /* 2x2 peer device (Adhoc, DLS or AP) */
+ if (mcs[15] && (Rssi > (-69 + RssiOffset)))
+ TxRateIdx = mcs[15];
+ else if (mcs[14] && (Rssi > (-71 + RssiOffset)))
+ TxRateIdx = mcs[14];
+ else if (mcs[13] && (Rssi > (-74 + RssiOffset)))
+ TxRateIdx = mcs[13];
+ else if (mcs[12] && (Rssi > (-76 + RssiOffset)))
+ TxRateIdx = mcs[12];
+ else if (mcs[11] && (Rssi > (-80 + RssiOffset)))
+ TxRateIdx = mcs[11];
+ else if (mcs[10] && (Rssi > (-82 + RssiOffset)))
+ TxRateIdx = mcs[10];
+ else if (mcs[9] && (Rssi > (-87 + RssiOffset)))
+ TxRateIdx = mcs[9];
+ else
+ TxRateIdx = mcs[8];
+
+ pEntry->mcsGroup = 2;
+ }
+ else
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s: GRP: 1*1, RssiOffset=%d\n", __FUNCTION__, RssiOffset));
+
+ /* 1x1 peer device (Adhoc, DLS or AP) */
+ if (mcs[7] && (Rssi > (-71 + RssiOffset)))
+ TxRateIdx = mcs[7];
+ else if (mcs[6] && (Rssi > (-73 + RssiOffset)))
+ TxRateIdx = mcs[6];
+ else if (mcs[5] && (Rssi > (-76 + RssiOffset)))
+ TxRateIdx = mcs[5];
+ else if (mcs[4] && (Rssi > (-78 + RssiOffset)))
+ TxRateIdx = mcs[4];
+ else if (mcs[3] && (Rssi > (-82 + RssiOffset)))
+ TxRateIdx = mcs[3];
+ else if (mcs[2] && (Rssi > (-84 + RssiOffset)))
+ TxRateIdx = mcs[2];
+ else if (mcs[1] && (Rssi > (-89 + RssiOffset)))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+
+ pEntry->mcsGroup = 1;
+ }
+ }
+ else
+#endif /* DOT11_VHT_AC */
+ if (ADAPT_RATE_TABLE(pTable) ||
+ (pTable == RateSwitchTable11BGN3S) ||
+ (pTable == RateSwitchTable11BGN3SForABand))
+ {/* N mode with 3 stream */
+ if ((pEntry->HTCapability.MCSSet[2] == 0xff) && (pAd->CommonCfg.TxStream == 3))
+ {
+ if (mcs[23]>=0 && (Rssi > (-72+RssiOffset)))
+ TxRateIdx = mcs[23];
+ else if (mcs[22]>=0 && (Rssi > (-74+RssiOffset)))
+ TxRateIdx = mcs[22];
+ else if (mcs[21]>=0 && (Rssi > (-77+RssiOffset)))
+ TxRateIdx = mcs[21];
+ else if (mcs[20]>=0 && (Rssi > (-79+RssiOffset)))
+ TxRateIdx = mcs[20];
+ else if (mcs[11]>=0 && (Rssi > (-81+RssiOffset)))
+ TxRateIdx = mcs[11];
+ else if (mcs[10]>=0 && (Rssi > (-83+RssiOffset)))
+ TxRateIdx = mcs[10];
+ else if (mcs[2]>=0 && (Rssi > (-86+RssiOffset)))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > (-88+RssiOffset)))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+
+ 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 (mcs[15]>=0 && (Rssi > (-72+RssiOffset)))
+ TxRateIdx = mcs[15];
+ else if (mcs[14]>=0 && (Rssi > (-74+RssiOffset)))
+ TxRateIdx = mcs[14];
+ else if (mcs[13]>=0 && (Rssi > (-77+RssiOffset)))
+ TxRateIdx = mcs[13];
+ else if (mcs[12]>=0 && (Rssi > (-79+RssiOffset)))
+ TxRateIdx = mcs[12];
+ else if (mcs[11]>=0 && (Rssi > (-81+RssiOffset)))
+ TxRateIdx = mcs[11];
+ else if (mcs[10]>=0 && (Rssi > (-83+RssiOffset)))
+ TxRateIdx = mcs[10];
+ else if (mcs[2]>=0 && (Rssi > (-86+RssiOffset)))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > (-88+RssiOffset)))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+
+ pEntry->mcsGroup = 2;
+ }
+ else
+ {
+ if (mcs[7]>=0 && (Rssi > (-72+RssiOffset)))
+ TxRateIdx = mcs[7];
+ else if (mcs[6]>=0 && (Rssi > (-74+RssiOffset)))
+ TxRateIdx = mcs[6];
+ else if (mcs[5]>=0 && (Rssi > (-77+RssiOffset)))
+ TxRateIdx = mcs[5];
+ else if (mcs[4]>=0 && (Rssi > (-79+RssiOffset)))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi > (-81+RssiOffset)))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > (-83+RssiOffset)))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > (-86+RssiOffset)))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+
+ pEntry->mcsGroup = 1;
+ }
+ }
+ else if ((pTable == RateSwitchTable11BGN2S) ||
+ (pTable == RateSwitchTable11BGN2SForABand) ||
+ (pTable == RateSwitchTable11N2S) ||
+ (pTable == RateSwitchTable11N2SForABand))
+ {/* N mode with 2 stream */
+ if (mcs[15]>=0 && (Rssi >= (-70+RssiOffset)))
+ TxRateIdx = mcs[15];
+ else if (mcs[14]>=0 && (Rssi >= (-72+RssiOffset)))
+ TxRateIdx = mcs[14];
+ else if (mcs[13]>=0 && (Rssi >= (-76+RssiOffset)))
+ TxRateIdx = mcs[13];
+ else if (mcs[12]>=0 && (Rssi >= (-78+RssiOffset)))
+ TxRateIdx = mcs[12];
+ else if (mcs[4]>=0 && (Rssi >= (-82+RssiOffset)))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi >= (-84+RssiOffset)))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi >= (-86+RssiOffset)))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi >= (-88+RssiOffset)))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+ else if ((pTable == RateSwitchTable11BGN1S) ||
+ (pTable == RateSwitchTable11N1S) ||
+ (pTable == RateSwitchTable11N1SForABand))
+ {/* N mode with 1 stream */
+ if (mcs[7]>=0 && (Rssi > (-72+RssiOffset)))
+ TxRateIdx = mcs[7];
+ else if (mcs[6]>=0 && (Rssi > (-74+RssiOffset)))
+ TxRateIdx = mcs[6];
+ else if (mcs[5]>=0 && (Rssi > (-77+RssiOffset)))
+ TxRateIdx = mcs[5];
+ else if (mcs[4]>=0 && (Rssi > (-79+RssiOffset)))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi > (-81+RssiOffset)))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > (-83+RssiOffset)))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > (-86+RssiOffset)))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+ else
+#endif /* DOT11_N_SUPPORT */
+ {/* Legacy mode */
+ if (mcs[7]>=0 && (Rssi > -70))
+ TxRateIdx = mcs[7];
+ else if (mcs[6]>=0 && (Rssi > -74))
+ TxRateIdx = mcs[6];
+ else if (mcs[5]>=0 && (Rssi > -78))
+ TxRateIdx = mcs[5];
+ else if (mcs[4]>=0 && (Rssi > -82))
+ TxRateIdx = mcs[4];
+ else if (mcs[4] == -1) /* for B-only mode */
+ TxRateIdx = mcs[3];
+ else if (mcs[3]>=0 && (Rssi > -85))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > -87))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > -90))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+
+ return TxRateIdx;
+}
+
+/*
+ MlmeRAEstimateThroughput - estimate Throughput based on PER and PHY rate
+ pEntry - the MAC table entry for this STA
+ pCurrTxRate - pointer to Rate table entry for rate
+ TxErrorRatio - the PER
+*/
+static ULONG MlmeRAEstimateThroughput(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RTMP_RA_GRP_TB *pCurrTxRate,
+ IN ULONG TxErrorRatio)
+{
+ ULONG estTP = (100-TxErrorRatio)*pCurrTxRate->dataRate;
+
+ /* Adjust rates for MCS32-40MHz mapped to MCS0-20MHz and for non-CCK 40MHz */
+ if (pCurrTxRate->CurrMCS == MCS_32)
+ {
+#ifdef DBG_CTRL_SUPPORT
+ if ((pAd->CommonCfg.DebugFlags & DBF_DISABLE_20MHZ_MCS0)==0)
+ estTP /= 2;
+#endif /* DBG_CTRL_SUPPORT */
+ }
+ else if ((pCurrTxRate->Mode==MODE_HTMIX) || (pCurrTxRate->Mode==MODE_HTGREENFIELD))
+ {
+ if (pEntry->MaxHTPhyMode.field.BW==BW_40
+#ifdef DBG_CTRL_SUPPORT
+ || (pAd->CommonCfg.DebugFlags & DBF_FORCE_40MHZ)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ estTP *= 2;
+ }
+
+ return estTP;
+}
+
+/*
+ MlmeRAHybridRule - decide whether to keep the new rate or use old rate
+ pEntry - the MAC table entry for this STA
+ pCurrTxRate - pointer to Rate table entry for new up rate
+ NewTxOkCount - normalized count of Tx packets for new up rate
+ TxErrorRatio - the PER
+ returns
+ TRUE if old rate should be used
+*/
+BOOLEAN MlmeRAHybridRule(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN RTMP_RA_GRP_TB *pCurrTxRate,
+ IN ULONG NewTxOkCount,
+ IN ULONG TxErrorRatio)
+{
+ ULONG newTP, oldTP;
+
+ if (100*NewTxOkCount < pAd->CommonCfg.TrainUpLowThrd*pEntry->LastTxOkCount)
+ return TRUE;
+
+ if (100*NewTxOkCount > pAd->CommonCfg.TrainUpHighThrd*pEntry->LastTxOkCount)
+ return FALSE;
+
+ newTP = MlmeRAEstimateThroughput(pAd, pEntry, pCurrTxRate, TxErrorRatio);
+ oldTP = MlmeRAEstimateThroughput(pAd, pEntry, PTX_RA_GRP_ENTRY(pEntry->pTable, pEntry->lastRateIdx), pEntry->LastTxPER);
+
+ return (oldTP > newTP);
+}
+
+/*
+ MlmeNewRateAdapt - perform Rate Adaptation based on PER using New RA algorithm
+ pEntry - the MAC table entry for this STA
+ UpRateIdx, DownRateIdx - UpRate and DownRate index
+ TrainUp, TrainDown - TrainUp and Train Down threhsolds
+ TxErrorRatio - the PER
+
+ On exit:
+ pEntry->LastSecTxRateChangeAction = RATE_UP or RATE_DOWN if there was a change
+ pEntry->CurrTxRateIndex = new rate index
+ pEntry->TxQuality is updated
+*/
+VOID MlmeNewRateAdapt(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR UpRateIdx,
+ IN UCHAR DownRateIdx,
+ IN ULONG TrainUp,
+ IN ULONG TrainDown,
+ IN ULONG TxErrorRatio)
+{
+ USHORT phyRateLimit20 = 0;
+ BOOLEAN bTrainUp = FALSE;
+#ifdef TXBF_SUPPORT
+ BOOLEAN invertTxBf = FALSE;
+#endif /* TXBF_SUPPORT */
+ UCHAR *pTable = pEntry->pTable;
+ UCHAR CurrRateIdx = pEntry->CurrTxRateIndex;
+ RTMP_RA_GRP_TB *pCurrTxRate = PTX_RA_GRP_ENTRY(pTable, CurrRateIdx);
+
+ pEntry->CurrTxRateStableTime++;
+
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE;
+
+
+ if (TxErrorRatio >= TrainDown)
+ {
+#ifdef TXBF_SUPPORT
+ RTMP_RA_GRP_TB *pDownRate, *pLastNonBfRate;
+#endif /* TXBF_SUPPORT */
+
+ /* Downgrade TX quality if PER >= Rate-Down threshold */
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND);
+
+#ifdef TXBF_SUPPORT
+ /*
+ Need to train down. If BF and last Non-BF is no worse than the down rate then
+ go to last Non-BF rate. Otherwise just go to the down rate
+ */
+
+ pDownRate = PTX_RA_GRP_ENTRY(pTable, DownRateIdx);
+ pLastNonBfRate = PTX_RA_GRP_ENTRY(pTable, pEntry->lastNonBfRate);
+
+ if ((pEntry->phyETxBf || pEntry->phyITxBf) &&
+ (pLastNonBfRate->dataRate >= pDownRate->dataRate)
+#ifdef DBG_CTRL_SUPPORT
+ && ((pAd->CommonCfg.DebugFlags & DBF_NO_BF_AWARE_RA)==0)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ invertTxBf = TRUE;
+ pEntry->CurrTxRateIndex = pEntry->lastNonBfRate;
+ pEntry->LastSecTxRateChangeAction = RATE_DOWN;
+ }
+ else
+#endif /* TXBF_SUPPORT */
+ if (CurrRateIdx != DownRateIdx)
+ {
+ pEntry->CurrTxRateIndex = DownRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_DOWN;
+ }
+ }
+ else
+ {
+ RTMP_RA_GRP_TB *pUpRate = PTX_RA_GRP_ENTRY(pTable, UpRateIdx);
+
+ /* Upgrade TX quality if PER <= Rate-Up threshold */
+ if (TxErrorRatio <= TrainUp)
+ {
+ bTrainUp = TRUE;
+ MlmeDecTxQuality(pEntry, CurrRateIdx); /* quality very good in CurrRate */
+
+ if (pEntry->TxRateUpPenalty) /* always == 0, always go to else */
+ pEntry->TxRateUpPenalty --;
+ else
+ {
+ /*
+ Decrement the TxQuality of the UpRate and all of the MCS groups.
+ Note that UpRate may mot equal one of the MCS groups if MlmeSelectUpRate
+ skipped over a rate that is not valid for this configuration.
+ */
+ MlmeDecTxQuality(pEntry, UpRateIdx);
+
+ if (pCurrTxRate->upMcs3!=CurrRateIdx &&
+ pCurrTxRate->upMcs3!=UpRateIdx)
+ MlmeDecTxQuality(pEntry, pCurrTxRate->upMcs3);
+
+ if (pCurrTxRate->upMcs2!=CurrRateIdx &&
+ pCurrTxRate->upMcs2!=UpRateIdx &&
+ pCurrTxRate->upMcs2!=pCurrTxRate->upMcs3)
+ MlmeDecTxQuality(pEntry, pCurrTxRate->upMcs2);
+
+ if (pCurrTxRate->upMcs1!=CurrRateIdx &&
+ pCurrTxRate->upMcs1!=UpRateIdx &&
+ pCurrTxRate->upMcs1!=pCurrTxRate->upMcs3 &&
+ pCurrTxRate->upMcs1!=pCurrTxRate->upMcs2)
+ MlmeDecTxQuality(pEntry, pCurrTxRate->upMcs1);
+ }
+ }
+ else if (pEntry->mcsGroup > 0) /* even if TxErrorRatio > TrainUp */
+ {
+ /* Moderate PER but some groups are not tried */
+ bTrainUp = TRUE;
+
+ /* TxQuality[CurrRateIdx] must be decremented so that mcs won't decrease wrongly */
+ MlmeDecTxQuality(pEntry, CurrRateIdx); /* quality very good in CurrRate */
+ MlmeDecTxQuality(pEntry, UpRateIdx); /* may improve next UP rate's quality */
+ }
+
+ /* Don't try up rate if it's greater than the limit */
+ if ((phyRateLimit20 != 0) && (pUpRate->dataRate >= phyRateLimit20))
+ return;
+
+ /* If UpRate is good then train up in current BF state */
+ if ((CurrRateIdx != UpRateIdx) && (MlmeGetTxQuality(pEntry, UpRateIdx) <= 0) && bTrainUp)
+ {
+ pEntry->CurrTxRateIndex = UpRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+#ifdef TXBF_SUPPORT
+ else
+#ifdef DBG_CTRL_SUPPORT
+ if ((pAd->CommonCfg.DebugFlags & DBF_NO_BF_AWARE_RA)==0)
+#endif /* DBG_CTRL_SUPPORT */
+ {
+ /* If not at the highest rate then try inverting BF state */
+ if (pEntry->phyETxBf || pEntry->phyITxBf)
+ {
+ /* If BF then try the same MCS non-BF unless PER is good */
+ if (TxErrorRatio > TrainUp)
+ {
+ if (pEntry->TxQuality[CurrRateIdx])
+ pEntry->TxQuality[CurrRateIdx]--;
+
+ if (pEntry->TxQuality[CurrRateIdx]==0)
+ {
+ invertTxBf = TRUE;
+ pEntry->CurrTxRateIndex = CurrRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+ }
+ }
+ else if (pEntry->eTxBfEnCond>0 || pEntry->iTxBfEn)
+ {
+ /* First try Up Rate with BF */
+ if ((CurrRateIdx != UpRateIdx) &&
+ MlmeTxBfAllowed(pAd, pEntry, (RTMP_RA_LEGACY_TB *)pUpRate))
+ {
+ if (pEntry->BfTxQuality[UpRateIdx])
+ pEntry->BfTxQuality[UpRateIdx]--;
+
+ if (pEntry->BfTxQuality[UpRateIdx]==0)
+ {
+ invertTxBf = TRUE;
+ pEntry->CurrTxRateIndex = UpRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+ }
+
+ /* Try Same Rate if Up Rate failed */
+ if (pEntry->LastSecTxRateChangeAction==RATE_NO_CHANGE &&
+ MlmeTxBfAllowed(pAd, pEntry, (RTMP_RA_LEGACY_TB *)pCurrTxRate))
+ {
+ if (pEntry->BfTxQuality[CurrRateIdx])
+ pEntry->BfTxQuality[CurrRateIdx]--;
+
+ if (pEntry->BfTxQuality[CurrRateIdx]==0)
+ {
+ invertTxBf = TRUE;
+ pEntry->CurrTxRateIndex = CurrRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+ }
+ }
+ }
+#endif /* TXBF_SUPPORT */
+ }
+
+ /* Handle the rate change */
+ if ((pEntry->LastSecTxRateChangeAction != RATE_NO_CHANGE)
+#ifdef DBG_CTRL_SUPPORT
+ || (pAd->CommonCfg.DebugFlags & DBF_FORCE_QUICK_DRS)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ if (pEntry->LastSecTxRateChangeAction!=RATE_NO_CHANGE)
+ {
+ DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: %sTX rate from %d to %d \n",
+ pEntry->LastSecTxRateChangeAction==RATE_UP? "++": "--", CurrRateIdx, pEntry->CurrTxRateIndex));
+ }
+
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0;
+
+ /* Save last rate information */
+ pEntry->lastRateIdx = CurrRateIdx;
+#ifdef TXBF_SUPPORT
+ if (pEntry->eTxBfEnCond > 0)
+ {
+ pEntry->lastRatePhyTxBf = pEntry->phyETxBf;
+ pEntry->phyETxBf ^= invertTxBf;
+ }
+ else
+ {
+ pEntry->lastRatePhyTxBf = pEntry->phyITxBf;
+ pEntry->phyITxBf ^= invertTxBf;
+ }
+#endif /* TXBF_SUPPORT */
+
+ /* Update TxQuality */
+ if (pEntry->LastSecTxRateChangeAction == RATE_DOWN)
+ {
+ MlmeSetTxQuality(pEntry, pEntry->CurrTxRateIndex, 0);
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0;
+ }
+
+ /* Set timer for check in 100 msec */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (!pAd->ApCfg.ApQuickResponeForRateUpTimerRunning)
+ {
+ RTMPSetTimer(&pAd->ApCfg.ApQuickResponeForRateUpTimer, pAd->ra_fast_interval);
+ pAd->ApCfg.ApQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* Update PHY rate */
+ MlmeNewTxRate(pAd, pEntry);
+ }
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ AP 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 APQuickResponeForRateUpExecAdapt(/* actually for both up and down */
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG idx)
+{
+ PUCHAR pTable;
+ UCHAR CurrRateIdx;
+ ULONG AccuTxTotalCnt, TxTotalCnt, TxCnt;
+ ULONG TxErrorRatio = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ RTMP_RA_GRP_TB *pCurrTxRate;
+ UCHAR TrainUp, TrainDown;
+ CHAR Rssi, ratio;
+ ULONG TxSuccess, TxRetransmit, TxFailCount;
+ ULONG OneSecTxNoRetryOKRationCount;
+ BOOLEAN rateChanged;
+#ifdef TXBF_SUPPORT
+ BOOLEAN CurrPhyETxBf, CurrPhyITxBf;
+#endif /* TXBF_SUPPORT */
+
+ pEntry = &pAd->MacTab.Content[idx];
+
+
+ pTable = pEntry->pTable;
+
+ /* Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2); */
+ Rssi = RTMPAvgRssi(pAd, &pEntry->RssiSample);
+
+ if (pAd->MacTab.Size == 1)
+ {
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+
+ /* Update statistic counter */
+ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+ /* Rssi is calculated again with new formula?In rory's code, the average instead of max is used. */
+ if (pAd->Antenna.field.TxPath > 1)
+ Rssi = (pEntry->RssiSample.AvgRssi0 + pEntry->RssiSample.AvgRssi1) >> 1;
+ else
+ Rssi = pEntry->RssiSample.AvgRssi0;
+
+ TxCnt = AccuTxTotalCnt;
+ }
+ else
+ {
+ TxRetransmit = pEntry->OneSecTxRetryOkCount;
+ TxSuccess = pEntry->OneSecTxNoRetryOkCount;
+ TxFailCount = pEntry->OneSecTxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ TxCnt = TxTotalCnt;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+#ifdef FIFO_EXT_SUPPORT
+ if ((pEntry->Aid >= 1) && (pEntry->Aid <= 8))
+ {
+ ULONG HwTxCnt, HwErrRatio;
+
+ NicGetMacFifoTxCnt(pAd, pEntry);
+ HwTxCnt = pEntry->fifoTxSucCnt + pEntry->fifoTxRtyCnt;
+ if (HwTxCnt)
+ HwErrRatio = (pEntry->fifoTxRtyCnt * 100) / HwTxCnt;
+ else
+ HwErrRatio = 0;
+
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,("%s():Aid:%d, MCS:%d, TxErrRation(Hw:0x%lx-0x%lx, Sw:0x%lx-%lx)\n",
+ __FUNCTION__, pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ HwTxCnt, HwErrRatio, TxTotalCnt, TxErrorRatio));
+
+ TxSuccess = pEntry->fifoTxSucCnt;
+ TxRetransmit = pEntry->fifoTxRtyCnt;
+ TxErrorRatio = HwErrRatio;
+ TxTotalCnt = HwTxCnt;
+ TxCnt = HwTxCnt;
+ }
+#endif /* FIFO_EXT_SUPPORT */
+ }
+
+#ifdef MFB_SUPPORT
+ if (pEntry->fLastChangeAccordingMfb == TRUE)
+ {
+ pEntry->fLastChangeAccordingMfb = FALSE;
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE;
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,("DRS: MCS is according to MFB, and ignore tuning this sec \n"));
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+ return;
+ }
+#endif /* MFB_SUPPORT */
+
+ /* Remember the current rate */
+ CurrRateIdx = pEntry->CurrTxRateIndex;
+#ifdef TXBF_SUPPORT
+ CurrPhyETxBf = pEntry->phyETxBf;
+ CurrPhyITxBf = pEntry->phyITxBf;
+#endif /* TXBF_SUPPORT */
+ pCurrTxRate = PTX_RA_GRP_ENTRY(pTable, CurrRateIdx);
+
+#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;
+ }
+
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug option: Concise RA log */
+ if ((pAd->CommonCfg.DebugFlags & DBF_SHOW_RA_LOG) || (pAd->CommonCfg.DebugFlags & DBF_DBQ_RA_LOG))
+ MlmeRALog(pAd, pEntry, RAL_QUICK_DRS, TxErrorRatio, TxTotalCnt);
+#endif /* DBG_CTRL_SUPPORT */
+
+ /* Handle the low traffic case */
+ if (TxCnt <= 15)
+ {
+ /* Go back to the original rate */
+ MlmeRestoreLastRate(pEntry);
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA, (" QuickDRS: TxTotalCnt <= 15, back to original rate \n"));
+
+ MlmeNewTxRate(pAd, pEntry);
+
+
+ // TODO: should we reset all OneSecTx counters?
+ /* RESET_ONE_SEC_TX_CNT(pEntry); */
+
+ return;
+ }
+
+ /*
+ Compare throughput.
+ LastTxCount is based on a time interval of 500 msec or "500 - pAd->ra_fast_interval" ms.
+ */
+ if ((pEntry->LastTimeTxRateChangeAction == RATE_NO_CHANGE)
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_FORCE_QUICK_DRS)==0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ ratio = RA_INTERVAL / pAd->ra_fast_interval;
+ else
+ ratio = (RA_INTERVAL - pAd->ra_fast_interval) / pAd->ra_fast_interval;
+
+ if (pAd->MacTab.Size == 1)
+ OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
+ else
+ OneSecTxNoRetryOKRationCount = pEntry->OneSecTxNoRetryOkCount * ratio + (pEntry->OneSecTxNoRetryOkCount >> 1);
+
+ /* Downgrade TX quality if PER >= Rate-Down threshold */
+ /* the only situation when pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND but no rate change */
+ if (TxErrorRatio >= TrainDown)
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND);
+
+ pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+
+ /* Perform DRS - consider TxRate Down first, then rate up. */
+ if (pEntry->LastSecTxRateChangeAction == RATE_UP)
+ {
+ BOOLEAN useOldRate;
+
+ // TODO: gaa - Finalize the decision criterion
+ /*
+ 0=>Throughput. Use New Rate if New TP is better than Old TP
+ 1=>PER. Use New Rate if New PER is less than the TrainDown PER threshold
+ 2=>Hybrid. Use rate with best TP if difference > 10%. Otherwise use rate with Best Estimated TP
+ 3=>Hybrid with check that PER<TrainDown Threshold
+ */
+ if (pAd->CommonCfg.TrainUpRule == 0)
+ {
+ useOldRate = (pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount;
+ }
+ else if (pAd->CommonCfg.TrainUpRule==2 && Rssi<=pAd->CommonCfg.TrainUpRuleRSSI)
+ {
+ useOldRate = MlmeRAHybridRule(pAd, pEntry, pCurrTxRate, OneSecTxNoRetryOKRationCount, TxErrorRatio);
+ }
+ else if (pAd->CommonCfg.TrainUpRule==3 && Rssi<=pAd->CommonCfg.TrainUpRuleRSSI)
+ {
+ useOldRate = (TxErrorRatio >= TrainDown) ||
+ MlmeRAHybridRule(pAd, pEntry, pCurrTxRate, OneSecTxNoRetryOKRationCount, TxErrorRatio);
+ }
+ else
+ useOldRate = TxErrorRatio >= TrainDown;
+ if (useOldRate)
+ {
+ /* If PER>50% or TP<lastTP/2 then double the TxQuality delay */
+ if ((TxErrorRatio > 50) || (OneSecTxNoRetryOKRationCount < pEntry->LastTxOkCount/2))
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND*2);
+ else
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND);
+
+ MlmeRestoreLastRate(pEntry);
+ }
+ else
+ {
+ RTMP_RA_GRP_TB *pLastTxRate = PTX_RA_GRP_ENTRY(pTable, pEntry->lastRateIdx);
+
+ /* Clear the history if we changed the MCS and PHY Rate */
+ if ((pCurrTxRate->CurrMCS != pLastTxRate->CurrMCS) &&
+ (pCurrTxRate->dataRate != pLastTxRate->dataRate))
+ MlmeClearTxQuality(pEntry);
+
+ if (pEntry->mcsGroup == 0)
+ MlmeSetMcsGroup(pAd, pEntry);
+
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,
+ (" QuickDRS: (Up) keep rate-up (L:%ld, C:%ld)\n",
+ pEntry->LastTxOkCount, OneSecTxNoRetryOKRationCount));
+ }
+ }
+ else if (pEntry->LastSecTxRateChangeAction == RATE_DOWN)
+ {
+ if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown)) /* there will be train down again */
+ {
+ MlmeSetMcsGroup(pAd, pEntry);
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,(" QuickDRS: (Down) direct train down (TxErrorRatio >= TrainDown)\n"));
+ }
+ else if ((pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+ {
+ MlmeRestoreLastRate(pEntry);
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,(" QuickDRS: (Down) bad tx ok count (L:%ld, C:%ld)\n", pEntry->LastTxOkCount, OneSecTxNoRetryOKRationCount));
+ }
+ else
+ {
+ MlmeSetMcsGroup(pAd, pEntry);
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,(" QuickDRS: (Down) keep rate-down (L:%ld, C:%ld)\n", pEntry->LastTxOkCount, OneSecTxNoRetryOKRationCount));
+ }
+ }
+
+ /* See if we reverted to the old rate */
+#ifdef TXBF_SUPPORT
+ rateChanged = (pEntry->CurrTxRateIndex != CurrRateIdx) ||
+ (pEntry->phyETxBf!=CurrPhyETxBf) || (pEntry->phyITxBf!=CurrPhyITxBf);
+
+ /* Remember last good non-BF rate */
+ if (!pEntry->phyETxBf && !pEntry->phyITxBf)
+ pEntry->lastNonBfRate = pEntry->CurrTxRateIndex;
+#else
+ rateChanged = (pEntry->CurrTxRateIndex != CurrRateIdx);
+#endif /* TXBF_SUPPORT */
+
+
+ /* Update mcsGroup */
+ if (pEntry->LastSecTxRateChangeAction == RATE_UP)
+ {
+ UCHAR UpRateIdx;
+
+ /* If RATE_UP failed look for the next group with valid mcs */
+ if (pEntry->CurrTxRateIndex != CurrRateIdx && pEntry->mcsGroup > 0)
+ {
+ pEntry->mcsGroup--;
+ pCurrTxRate = PTX_RA_GRP_ENTRY(pTable, pEntry->lastRateIdx);
+ }
+
+ switch (pEntry->mcsGroup)
+ {
+ case 3:
+ UpRateIdx = pCurrTxRate->upMcs3;
+ break;
+ case 2:
+ UpRateIdx = pCurrTxRate->upMcs2;
+ break;
+ case 1:
+ UpRateIdx = pCurrTxRate->upMcs1;
+ break;
+ default:
+ UpRateIdx = CurrRateIdx;
+ break;
+ }
+
+ if (UpRateIdx == pEntry->CurrTxRateIndex)
+ pEntry->mcsGroup = 0;
+ }
+
+
+ /* Handle change back to old rate */
+ if (rateChanged)
+ {
+ /* Clear Old Rate's TxQuality */
+ MlmeSetTxQuality(pEntry, pEntry->CurrTxRateIndex, 0);
+
+ pEntry->TxRateUpPenalty = 0; /* redundant */
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0; /* redundant */
+
+ /* Set new Tx rate */
+ MlmeNewTxRate(pAd, pEntry);
+ }
+
+ // TODO: should we reset all OneSecTx counters?
+ /* RESET_ONE_SEC_TX_CNT(pEntry); */
+}
+
+
+
+/*
+ ==========================================================================
+ Description:
+ This routine walks through the MAC table, see if TX rate change is
+ required for each associated client.
+ Output:
+ pEntry->CurrTxRate -
+ NOTE:
+ call this routine every second
+ ==========================================================================
+ */
+VOID APMlmeDynamicTxRateSwitchingAdapt(RTMP_ADAPTER *pAd, ULONG i)
+{
+ PUCHAR pTable;
+ UCHAR UpRateIdx, DownRateIdx, CurrRateIdx, TrainUp, TrainDown;
+ ULONG TxTotalCnt, TxSuccess, TxRetransmit, TxFailCount, TxErrorRatio;
+ MAC_TABLE_ENTRY *pEntry;
+ RTMP_RA_GRP_TB *pCurrTxRate;
+ CHAR Rssi;
+
+
+ pEntry = &pAd->MacTab.Content[i]; /* point to information of the individual station */
+ pTable = pEntry->pTable;
+ TxTotalCnt = TxSuccess = TxRetransmit = TxFailCount = TxErrorRatio = 0;
+
+ if (pAd->MacTab.Size == 1)
+ {
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+
+ /* Update statistic counter */
+ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ TxRetransmit = pEntry->OneSecTxRetryOkCount;
+ TxSuccess = pEntry->OneSecTxNoRetryOkCount;
+ TxFailCount = pEntry->OneSecTxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+#ifdef FIFO_EXT_SUPPORT
+ if (pEntry->Aid >= 1 && pEntry->Aid <= 8)
+ {
+ ULONG HwTxCnt, HwErrRatio;
+
+ NicGetMacFifoTxCnt(pAd, pEntry);
+ HwTxCnt = pEntry->fifoTxSucCnt + pEntry->fifoTxRtyCnt;
+ if (HwTxCnt)
+ HwErrRatio = (pEntry->fifoTxRtyCnt * 100) / HwTxCnt;
+ else
+ HwErrRatio = 0;
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,("%s():Aid:%d, MCS:%d, TxErrRatio(Hw:0x%lx-0x%lx, Sw:0x%lx-%lx)\n",
+ __FUNCTION__, pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ HwTxCnt, HwErrRatio, TxTotalCnt, TxErrorRatio));
+
+ TxSuccess = pEntry->fifoTxSucCnt;
+ TxRetransmit = pEntry->fifoTxRtyCnt;
+ TxTotalCnt = HwTxCnt;
+ TxErrorRatio = HwErrRatio;
+ }
+#endif /* FIFO_EXT_SUPPORT */
+ }
+
+ /* Save LastTxOkCount, LastTxPER and last MCS action for APQuickResponeForRateUpExec */
+ pEntry->LastTxOkCount = TxSuccess;
+ pEntry->LastTxPER = (UCHAR)TxErrorRatio;
+ pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
+
+ /* different calculation in APQuickResponeForRateUpExec() */
+ /* Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2); */
+ Rssi = RTMPAvgRssi(pAd, &pEntry->RssiSample);
+
+ /* decide the next upgrade rate and downgrade rate, if any */
+ CurrRateIdx = pEntry->CurrTxRateIndex;
+ pCurrTxRate = PTX_RA_GRP_ENTRY(pTable, CurrRateIdx);
+ UpRateIdx = MlmeSelectUpRate(pAd, pEntry, pCurrTxRate);
+ DownRateIdx = MlmeSelectDownRate(pAd, pEntry, CurrRateIdx);
+
+#ifdef DOT11_N_SUPPORT
+ /*
+ when Rssi > -65, there is a lot of interference usually. therefore,
+ the algorithm tends to choose the mcs lower than the optimal one.
+ By increasing the thresholds, the chosen mcs will be closer to the
+ optimal mcs
+ */
+ 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;
+ }
+
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug option: Concise RA log */
+ if ((pAd->CommonCfg.DebugFlags & DBF_SHOW_RA_LOG) || (pAd->CommonCfg.DebugFlags & DBF_DBQ_RA_LOG))
+ MlmeRALog(pAd, pEntry, RAL_NEW_DRS, TxErrorRatio, TxTotalCnt);
+#endif /* DBG_CTRL_SUPPORT */
+
+#ifdef MFB_SUPPORT
+ if (pEntry->fLastChangeAccordingMfb == TRUE)
+ {
+ RTMP_RA_LEGACY_TB *pNextTxRate;
+
+ /* with this method mfb result can be applied every 500msec, instead of immediately */
+ NdisAcquireSpinLock(&pEntry->fLastChangeAccordingMfbLock);
+ pEntry->fLastChangeAccordingMfb = FALSE;
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE;
+ NdisReleaseSpinLock(&pEntry->fLastChangeAccordingMfbLock);
+ APMlmeSetTxRate(pAd, pEntry, pEntry->LegalMfbRS);
+ DBGPRINT(RT_DEBUG_INFO,("DRS: MCS is according to MFB, and ignore tuning this sec \n"));
+ MlmeClearAllTxQuality(pEntry); /* clear all history, same as train up, purpose??? */
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ pEntry->CurrTxRateIndex = (pEntry->LegalMfbRS)->ItemNo;
+ pNextTxRate = (RTMP_RA_LEGACY_TB *) &pTable[(pEntry->CurrTxRateIndex+1)*10]; /* actually = pEntry->LegalMfbRS */
+ return;
+ }
+#endif /* MFB_SUPPORT */
+
+
+ /* Handle low traffic case */
+ if (TxTotalCnt <= 15)
+ {
+ pEntry->lowTrafficCount++;
+ if (pEntry->lowTrafficCount >= pAd->CommonCfg.lowTrafficThrd)
+ {
+ UCHAR TxRateIdx;
+ CHAR mcs[24];
+ CHAR RssiOffset = 0;
+
+ pEntry->lowTrafficCount = 0;
+
+ /* Check existence and get index of each MCS */
+ MlmeGetSupportedMcsAdapt(pAd, pEntry, GI_400, mcs);
+
+ if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||
+ (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable11N2SForABand))
+ {
+ RssiOffset = 2;
+ }
+ else if (ADAPT_RATE_TABLE(pTable))
+ {
+ RssiOffset = 0;
+ }
+ else
+ {
+ RssiOffset = 5;
+ }
+
+ /* Select the Tx rate based on the RSSI */
+ TxRateIdx = MlmeSelectTxRateAdapt(pAd, pEntry, mcs, Rssi, RssiOffset);
+ pEntry->lastRateIdx = pEntry->CurrTxRateIndex;
+ MlmeSetMcsGroup(pAd, pEntry);
+
+ pEntry->CurrTxRateIndex = TxRateIdx;
+#ifdef TXBF_SUPPORT
+ pEntry->phyETxBf = pEntry->phyITxBf = FALSE;
+#endif /* TXBF_SUPPORT */
+ MlmeNewTxRate(pAd, pEntry);
+ if (!pEntry->fLastSecAccordingRSSI)
+ {
+ DBGPRINT(RT_DEBUG_INFO,("DRS: TxTotalCnt <= 15, switch to MCS%d according to RSSI (%d), RssiOffset=%d\n", pEntry->HTPhyMode.field.MCS, Rssi, RssiOffset));
+ }
+
+ MlmeClearAllTxQuality(pEntry); /* clear all history */
+ pEntry->fLastSecAccordingRSSI = TRUE;
+ }
+
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+#ifdef TXBF_SUPPORT
+#ifdef DBG_CTRL_SUPPORT
+ /* In Unaware mode always try to send sounding */
+ if (pAd->CommonCfg.DebugFlags & DBF_NO_BF_AWARE_RA)
+ eTxBFProbing(pAd, pEntry);
+#endif /* DBG_CTRL_SUPPORT */
+#endif /* TXBF_SUPPORT */
+
+ return;
+ }
+
+ pEntry->lowTrafficCount = 0;
+
+ /*
+ After pEntry->fLastSecAccordingRSSI = TRUE; the for loop
+ continue. this condition is true when RateSwitching() is run
+ next time.
+ so the next rate adaptation is skipped. This mechanism is
+ deliberately designed by rory.
+ */
+ if (pEntry->fLastSecAccordingRSSI == TRUE)
+ {
+ pEntry->fLastSecAccordingRSSI = FALSE;
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE;
+ /* DBGPRINT(RT_DEBUG_INFO,("DRS: MCS is according to RSSI, and ignore tuning this sec \n")); */
+
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ eTxBFProbing(pAd, pEntry);
+#endif /* TXBF_SUPPORT */
+
+ return;
+ }
+
+ pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+ /* Select rate based on PER */
+ MlmeNewRateAdapt(pAd, pEntry, UpRateIdx, DownRateIdx, TrainUp, TrainDown, TxErrorRatio);
+
+#ifdef DOT11N_SS3_SUPPORT
+ /* Turn off RDG when 3s and rx count > tx count*5 */
+ MlmeCheckRDG(pAd, pEntry);
+#endif /* DOT11N_SS3_SUPPORT */
+
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ eTxBFProbing(pAd, pEntry);
+#endif /* TXBF_SUPPORT */
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+/*
+ Set_RateTable_Proc - Display or replace byte for item in RateSwitchTableAdapt11N3S
+ usage: iwpriv ra0 set RateTable=<item>[:<offset>:<value>]
+*/
+INT Set_RateTable_Proc(RTMP_ADAPTER *pAd, PSTRING arg)
+{
+ UCHAR *pTable, TableSize, InitTxRateIdx;
+ int i;
+ MAC_TABLE_ENTRY *pEntry;
+ int itemNo, rtIndex, value;
+ UCHAR *pRateEntry;
+
+ /* Find first Associated STA in MAC table */
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (IS_ENTRY_CLIENT(pEntry) && pEntry->Sst==SST_ASSOC)
+ break;
+ }
+
+ if (i==MAX_LEN_OF_MAC_TABLE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_RateTable_Proc: Empty MAC Table\n"));
+ return FALSE;
+ }
+
+ /* Get peer's rate table */
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+
+ /* Get rate index */
+ itemNo = simple_strtol(arg, &arg, 10);
+ if (itemNo<0 || itemNo>=RATE_TABLE_SIZE(pTable))
+ return FALSE;
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (ADAPT_RATE_TABLE(pTable))
+ pRateEntry = (UCHAR *)PTX_RA_GRP_ENTRY(pTable, itemNo);
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ pRateEntry = (UCHAR *)PTX_RA_LEGACY_ENTRY(pTable, itemNo);
+
+ /* If no addtional parameters then print the entry */
+ if (*arg != ':') {
+ DBGPRINT(RT_DEBUG_OFF, ("Set_RateTable_Proc::%d\n", itemNo));
+ }
+ else {
+ /* Otherwise get the offset and the replace byte */
+ while (*arg<'0' || *arg>'9')
+ arg++;
+ rtIndex = simple_strtol(arg, &arg, 10);
+ if (rtIndex<0 || rtIndex>9)
+ return FALSE;
+
+ if (*arg!=':')
+ return FALSE;
+ while (*arg<'0' || *arg>'9')
+ arg++;
+ value = simple_strtol(arg, &arg, 10);
+ pRateEntry[rtIndex] = value;
+ DBGPRINT(RT_DEBUG_OFF, ("Set_RateTable_Proc::%d:%d:%d\n", itemNo, rtIndex, value));
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("%d, 0x%02x, %d, %d, %d, %d, %d, %d, %d, %d\n",
+ pRateEntry[0], pRateEntry[1], pRateEntry[2], pRateEntry[3], pRateEntry[4],
+ pRateEntry[5], pRateEntry[6], pRateEntry[7], pRateEntry[8], pRateEntry[9]));
+
+ return TRUE;
+}
+
+
+INT Set_PerThrdAdj_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UCHAR i;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++){
+ pAd->MacTab.Content[i].perThrdAdj = simple_strtol(arg, 0, 10);
+ }
+ return TRUE;
+}
+
+/* Set_LowTrafficThrd_Proc - set threshold for reverting to default MCS based on RSSI */
+INT Set_LowTrafficThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.lowTrafficThrd = simple_strtol(arg, 0, 10);
+
+ return TRUE;
+}
+
+/* Set_TrainUpRule_Proc - set rule for Quick DRS train up */
+INT Set_TrainUpRule_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.TrainUpRule = simple_strtol(arg, 0, 10);
+
+ return TRUE;
+}
+
+/* Set_TrainUpRuleRSSI_Proc - set RSSI threshold for Quick DRS Hybrid train up */
+INT Set_TrainUpRuleRSSI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.TrainUpRuleRSSI = simple_strtol(arg, 0, 10);
+
+ return TRUE;
+}
+
+/* Set_TrainUpLowThrd_Proc - set low threshold for Quick DRS Hybrid train up */
+INT Set_TrainUpLowThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.TrainUpLowThrd = simple_strtol(arg, 0, 10);
+
+ return TRUE;
+}
+
+/* Set_TrainUpHighThrd_Proc - set high threshold for Quick DRS Hybrid train up */
+INT Set_TrainUpHighThrd_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ pAd->CommonCfg.TrainUpHighThrd = simple_strtol(arg, 0, 10);
+
+ return TRUE;
+}
+
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
diff --git a/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_legacy.c b/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_legacy.c
new file mode 100644
index 0000000000..dfda83c0ad
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/rate_ctrl/alg_legacy.c
@@ -0,0 +1,907 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+/****************************************************************************
+
+ Abstract:
+
+ All related Dynamic Rate Switch (AP/STA) function body.
+
+ History:
+
+***************************************************************************/
+
+#include "rt_config.h"
+
+
+#ifdef CONFIG_AP_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ This routine walks through the MAC table, see if TX rate change is
+ required for each associated client.
+ Output:
+ pEntry->CurrTxRate -
+ NOTE:
+ call this routine every second
+ ==========================================================================
+ */
+VOID APMlmeDynamicTxRateSwitching(RTMP_ADAPTER *pAd)
+{
+ INT i;
+ PUCHAR pTable;
+ UCHAR TableSize = 0, InitTxRateIdx, TrainUp, TrainDown;
+ UCHAR UpRateIdx, DownRateIdx, CurrRateIdx;
+ MAC_TABLE_ENTRY *pEntry;
+ RTMP_RA_LEGACY_TB *pCurrTxRate, *pTmpTxRate = NULL;
+ CHAR Rssi, TmpIdx = 0;
+ ULONG TxTotalCnt, TxErrorRatio = 0, TxSuccess, TxRetransmit, TxFailCount;
+
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ return;
+ }
+#endif /* RALINK_ATE */
+
+ /* 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++)
+ {
+ /* point to information of the individual station */
+ pEntry = &pAd->MacTab.Content[i];
+
+ if (IS_ENTRY_NONE(pEntry))
+ continue;
+
+ if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst != SST_ASSOC))
+ continue;
+
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry) && (pEntry->Sst != SST_ASSOC))
+ continue;
+#endif /* APCLI_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(pEntry) && !WDS_IF_UP_CHECK(pAd, pEntry->MatchWDSTabIdx))
+ continue;
+#endif /* WDS_SUPPORT */
+
+
+ /* check if this entry need to switch rate automatically */
+ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+ continue;
+
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+ pEntry->pTable = pTable;
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (ADAPT_RATE_TABLE(pTable))
+ {
+ APMlmeDynamicTxRateSwitchingAdapt(pAd, i);
+
+ continue;
+ }
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef AGS_SUPPORT
+ if (SUPPORT_AGS(pAd) && AGS_IS_USING(pAd, pTable))
+ {
+ ApMlmeDynamicTxRateSwitchingAGS(pAd, i);
+ continue;
+ }
+#endif /* AGS_SUPPORT */
+
+ /* NICUpdateFifoStaCounters(pAd); */
+
+ if (pAd->MacTab.Size == 1)
+ {
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+
+ /* Update statistic counter */
+ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ TxRetransmit = pEntry->OneSecTxRetryOkCount;
+ TxSuccess = pEntry->OneSecTxNoRetryOkCount;
+ TxFailCount = pEntry->OneSecTxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+#ifdef FIFO_EXT_SUPPORT
+ if (pEntry->Aid >= 1 && pEntry->Aid <= 8)
+ {
+ ULONG HwTxCnt, HwErrRatio;
+
+ NicGetMacFifoTxCnt(pAd, pEntry);
+ HwTxCnt = pEntry->fifoTxSucCnt + pEntry->fifoTxRtyCnt;
+ if (HwTxCnt)
+ HwErrRatio = (pEntry->fifoTxRtyCnt * 100) / HwTxCnt;
+ else
+ HwErrRatio = 0;
+
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,
+ ("%s():Aid:%d, MCS:%d, CuTxRaIdx=%d,TxErrRatio(Hw:%ld-%ld%%, Sw:%ld-%ld%%)\n",
+ __FUNCTION__, pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ pEntry->CurrTxRateIndex,
+ HwTxCnt, HwErrRatio, TxTotalCnt, TxErrorRatio));
+
+ TxSuccess = pEntry->fifoTxSucCnt;
+ TxRetransmit = pEntry->fifoTxRtyCnt;
+ TxTotalCnt = HwTxCnt;
+ TxErrorRatio = HwErrRatio;
+ }
+#endif /* FIFO_EXT_SUPPORT */
+ }
+
+ /* Save LastTxOkCount, LastTxPER and last MCS action for APQuickResponeForRateUpExec */
+ pEntry->LastTxOkCount = TxSuccess;
+ pEntry->LastTxPER = (TxTotalCnt == 0 ? 0 : (UCHAR)TxErrorRatio);
+ pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
+
+ /* different calculation in APQuickResponeForRateUpExec() */
+ /* Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2); */
+ Rssi = RTMPAvgRssi(pAd, &pEntry->RssiSample);
+
+ CurrRateIdx = UpRateIdx = DownRateIdx = pEntry->CurrTxRateIndex;
+
+ /* decide the next upgrade rate and downgrade rate, if any */
+ pCurrTxRate = PTX_RA_LEGACY_ENTRY(pTable, CurrRateIdx);
+
+ if ((pCurrTxRate->Mode <= MODE_CCK) && (pEntry->SupportRateMode <= SUPPORT_CCK_MODE))
+ {
+ TmpIdx = CurrRateIdx + 1;
+ while(TmpIdx < TableSize)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportCCKMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ UpRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx++;
+ }
+
+ TmpIdx = CurrRateIdx - 1;
+ while(TmpIdx >= 0)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportCCKMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ DownRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx--;
+ }
+ }
+ else if ((pCurrTxRate->Mode <= MODE_OFDM) && (pEntry->SupportRateMode < SUPPORT_HT_MODE))
+ {
+ TmpIdx = CurrRateIdx + 1;
+ while(TmpIdx < TableSize)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportOFDMMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ UpRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx++;
+ }
+
+ TmpIdx = CurrRateIdx - 1;
+ while(TmpIdx >= 0)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportOFDMMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ DownRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx--;
+ }
+ }
+ else
+ {
+ /* decide the next upgrade rate and downgrade rate, if any*/
+ if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
+ {
+ TmpIdx = CurrRateIdx + 1;
+ while(TmpIdx < TableSize)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportHTMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ UpRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx++;
+ }
+
+ TmpIdx = CurrRateIdx - 1;
+ while(TmpIdx >= 0)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportHTMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ DownRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx--;
+ }
+ }
+ else if (CurrRateIdx == 0)
+ {
+ TmpIdx = CurrRateIdx + 1;
+ while(TmpIdx < TableSize)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportHTMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ UpRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx++;
+ }
+
+ DownRateIdx = CurrRateIdx;
+ }
+ else if (CurrRateIdx == (TableSize - 1))
+ {
+ UpRateIdx = CurrRateIdx;
+
+ TmpIdx = CurrRateIdx - 1;
+ while(TmpIdx >= 0)
+ {
+ pTmpTxRate = PTX_RA_LEGACY_ENTRY(pTable, TmpIdx);
+ if (pEntry->SupportHTMCS[pTmpTxRate->CurrMCS] == TRUE)
+ {
+ DownRateIdx = TmpIdx;
+ break;
+ }
+ TmpIdx--;
+ }
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ /*
+ when Rssi > -65, there is a lot of interference usually. therefore, the algorithm
+ tends to choose the mcs lower than the optimal one.
+ by increasing the thresholds, the chosen mcs will be closer to the optimal mcs
+ */
+ 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;
+ }
+
+
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug option: Concise RA log */
+ if (pAd->CommonCfg.DebugFlags & DBF_SHOW_RA_LOG)
+ MlmeRALog(pAd, pEntry, RAL_OLD_DRS, TxErrorRatio, TxTotalCnt);
+#endif /* DBG_CTRL_SUPPORT */
+
+
+ /* Check for low traffic case */
+ if (TxTotalCnt <= 15)
+ {
+ UCHAR TxRateIdx;
+ CHAR mcs[24];
+
+ /* Check existence and get the index of each MCS */
+ MlmeGetSupportedMcs(pAd, pTable, mcs);
+
+ /* Select the Tx rate based on the RSSI */
+ TxRateIdx = MlmeSelectTxRate(pAd, pEntry, mcs, Rssi, 0);
+
+
+ if (TxRateIdx != pEntry->CurrTxRateIndex
+#ifdef TXBF_SUPPORT
+ || pEntry->phyETxBf || pEntry->phyITxBf
+#endif /* TXBF_SUPPORT */
+ )
+ {
+ pEntry->CurrTxRateIndex = TxRateIdx;
+#ifdef TXBF_SUPPORT
+ pEntry->phyETxBf = pEntry->phyITxBf = FALSE;
+#endif /* TXBF_SUPPORT */
+ MlmeNewTxRate(pAd, pEntry);
+ if (!pEntry->fLastSecAccordingRSSI)
+ DBGPRINT(RT_DEBUG_INFO,("DRS: TxTotalCnt <= 15, switch MCS according to RSSI (%d)\n", Rssi));
+ }
+
+ MlmeClearAllTxQuality(pEntry);
+ pEntry->fLastSecAccordingRSSI = TRUE;
+
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+
+#ifdef TXBF_SUPPORT
+#ifdef DBG_CTRL_SUPPORT
+ /* In Unaware mode always try to send sounding */
+ if (pAd->CommonCfg.DebugFlags & DBF_NO_BF_AWARE_RA)
+ eTxBFProbing(pAd, pEntry);
+#endif /* DBG_CTRL_SUPPORT */
+#endif /* TXBF_SUPPORT */
+ continue;
+ }
+
+ if (pEntry->fLastSecAccordingRSSI == TRUE)
+ {
+ pEntry->fLastSecAccordingRSSI = FALSE;
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE;
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ eTxBFProbing(pAd, pEntry);
+#endif /* TXBF_SUPPORT */
+
+ continue;
+ }
+
+ pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+ /* Select rate based on PER */
+ MlmeOldRateAdapt(pAd, pEntry, CurrRateIdx, UpRateIdx, DownRateIdx, TrainUp, TrainDown, TxErrorRatio);
+
+#ifdef DOT11N_SS3_SUPPORT
+ /* Turn off RDG when 3s and rx count > tx count*5 */
+ MlmeCheckRDG(pAd, pEntry);
+#endif /* DOT11N_SS3_SUPPORT */
+
+ /* reset all OneSecTx counters */
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ eTxBFProbing(pAd, pEntry);
+#endif /* TXBF_SUPPORT */
+
+ }
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ AP 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 APQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+ ULONG i;
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+ UCHAR CurrRateIdx;
+ ULONG AccuTxTotalCnt, TxTotalCnt, TxCnt;
+ ULONG TxErrorRatio = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ RTMP_RA_LEGACY_TB *pCurrTxRate;
+ UCHAR InitTxRateIdx, TrainUp, TrainDown;
+ CHAR Rssi, ratio;
+ ULONG TxSuccess, TxRetransmit, TxFailCount;
+#ifdef TXBF_SUPPORT
+ BOOLEAN CurrPhyETxBf, CurrPhyITxBf;
+#endif /* TXBF_SUPPORT */
+
+ pAd->ApCfg.ApQuickResponeForRateUpTimerRunning = FALSE;
+
+ /* 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;
+
+ if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst != SST_ASSOC))
+ continue;
+
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry) && (pEntry->Sst != SST_ASSOC))
+ continue;
+#endif /* APCLI_SUPPORT */
+
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(pEntry) && !WDS_IF_UP_CHECK(pAd, pEntry->MatchWDSTabIdx))
+ continue;
+#endif /* WDS_SUPPORT */
+
+
+
+ /* Do nothing if this entry didn't change */
+ if (pEntry->LastSecTxRateChangeAction == RATE_NO_CHANGE
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_FORCE_QUICK_DRS)==0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ continue;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+ pEntry->pTable = pTable;
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (ADAPT_RATE_TABLE(pTable))
+ {
+ APQuickResponeForRateUpExecAdapt(pAd, i);
+ continue;
+ }
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+ /*Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2); */
+ Rssi = RTMPAvgRssi(pAd, &pEntry->RssiSample);
+
+
+ if (pAd->MacTab.Size == 1)
+ {
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+
+ /* Update statistic counter */
+ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+ if (pAd->Antenna.field.TxPath > 1)
+ Rssi = (pEntry->RssiSample.AvgRssi0 + pEntry->RssiSample.AvgRssi1) >> 1;
+ else
+ Rssi = pEntry->RssiSample.AvgRssi0;
+
+ TxCnt = AccuTxTotalCnt;
+ }
+ else
+ {
+ TxRetransmit = pEntry->OneSecTxRetryOkCount;
+ TxSuccess = pEntry->OneSecTxNoRetryOkCount;
+ TxFailCount = pEntry->OneSecTxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ TxCnt = TxTotalCnt;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+
+#ifdef FIFO_EXT_SUPPORT
+ if ((pEntry->Aid >= 1) && (pEntry->Aid <= 8))
+ {
+ ULONG HwTxCnt, HwErrRatio;
+
+ NicGetMacFifoTxCnt(pAd, pEntry);
+ HwTxCnt = pEntry->fifoTxSucCnt + pEntry->fifoTxRtyCnt;
+ if (HwTxCnt)
+ HwErrRatio = (pEntry->fifoTxRtyCnt * 100) / HwTxCnt;
+ else
+ HwErrRatio = 0;
+
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,("%s():Aid:%d, MCS:%d, TxErrRation(Hw:0x%lx-0x%lx, Sw:0x%lx-%lx)\n",
+ __FUNCTION__, pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ HwTxCnt, HwErrRatio, TxTotalCnt, TxErrorRatio));
+
+ TxSuccess = pEntry->fifoTxSucCnt;
+ TxRetransmit = pEntry->fifoTxRtyCnt;
+ TxErrorRatio = HwErrRatio;
+ TxTotalCnt = HwTxCnt;
+ TxCnt = HwTxCnt;
+ }
+#endif /* FIFO_EXT_SUPPORT */
+ }
+
+ CurrRateIdx = pEntry->CurrTxRateIndex;
+#ifdef TXBF_SUPPORT
+ CurrPhyETxBf = pEntry->phyETxBf;
+ CurrPhyITxBf = pEntry->phyITxBf;
+#endif /* TXBF_SUPPORT */
+ pCurrTxRate = PTX_RA_LEGACY_ENTRY(pTable, CurrRateIdx);
+
+#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;
+ }
+
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug option: Concise RA log */
+ if (pAd->CommonCfg.DebugFlags & DBF_SHOW_RA_LOG)
+ MlmeRALog(pAd, pEntry, RAL_QUICK_DRS, TxErrorRatio, TxTotalCnt);
+#endif /* DBG_CTRL_SUPPORT */
+
+ if (TxCnt <= 15 && pEntry->HTPhyMode.field.MCS > 1)
+ {
+ MlmeClearAllTxQuality(pEntry);
+
+ /* Set current up MCS at the worst quality */
+ if (pEntry->LastSecTxRateChangeAction == RATE_UP)
+ {
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND);
+ }
+
+ /* Go back to the original rate */
+ MlmeRestoreLastRate(pEntry);
+
+ MlmeNewTxRate(pAd, pEntry);
+
+
+ // TODO: should we reset all OneSecTx counters?
+ /* RESET_ONE_SEC_TX_CNT(pEntry); */
+
+ continue;
+ }
+
+ pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+ /* Compare throughput */
+ do
+ {
+ ULONG OneSecTxNoRetryOKRationCount;
+
+ /*
+ Compare throughput.
+ LastTxCount is based on a time interval of "500" msec or "500-pAd->ra_fast_interval" ms.
+ */
+ if ((pEntry->LastTimeTxRateChangeAction == RATE_NO_CHANGE)
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_FORCE_QUICK_DRS)==0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ ratio = RA_INTERVAL/pAd->ra_fast_interval;
+ else
+ ratio = (RA_INTERVAL-pAd->ra_fast_interval)/pAd->ra_fast_interval;
+
+ /* downgrade TX quality if PER >= Rate-Down threshold */
+ if (TxErrorRatio >= TrainDown)
+ {
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND);
+ }
+
+ if (pAd->MacTab.Size == 1)
+ {
+ OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
+ }
+ else
+ {
+ OneSecTxNoRetryOKRationCount = pEntry->OneSecTxNoRetryOkCount * ratio + (pEntry->OneSecTxNoRetryOkCount >> 1);
+ }
+
+ /* perform DRS - consider TxRate Down first, then rate up. */
+ if (pEntry->LastSecTxRateChangeAction == RATE_UP)
+ {
+// TODO: gaa - use different criterion for train up in Old RA?
+ /*if ((pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) */
+ if (TxErrorRatio >= TrainDown)
+ {
+#ifdef TXBF_SUPPORT
+ /* If PER>50% or TP<lastTP/2 then double the TxQuality delay */
+ if ((TxErrorRatio > 50) || (OneSecTxNoRetryOKRationCount < pEntry->LastTxOkCount/2))
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND*2);
+ else
+#endif /* TXBF_SUPPORT */
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND);
+
+ MlmeRestoreLastRate(pEntry);
+ }
+ else
+ {
+ }
+ }
+ else if (pEntry->LastSecTxRateChangeAction == RATE_DOWN)
+ {
+ /* if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown)) */
+ if ((TxErrorRatio >= 50) && (TxErrorRatio >= TrainDown))
+ {
+ }
+ else if ((pEntry->LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+ {
+ MlmeRestoreLastRate(pEntry);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA,("QuickDRS: (Down) keep rate-down (L:%ld, C:%ld)\n", pEntry->LastTxOkCount, OneSecTxNoRetryOKRationCount));
+ }
+ }
+ }while (FALSE);
+
+#ifdef TXBF_SUPPORT
+ /* Remember last good non-BF rate */
+ if (!pEntry->phyETxBf && !pEntry->phyITxBf)
+ pEntry->lastNonBfRate = pEntry->CurrTxRateIndex;
+#endif /* TXBF_SUPPORT */
+
+ /* If rate changed then update the history and set the new tx rate */
+ if ((pEntry->CurrTxRateIndex != CurrRateIdx)
+#ifdef TXBF_SUPPORT
+ || (pEntry->phyETxBf!=CurrPhyETxBf) || (pEntry->phyITxBf!=CurrPhyITxBf)
+#endif /* TXBF_SUPPORT */
+ )
+ {
+ /* if rate-up happen, clear all bad history of all TX rates */
+ if (pEntry->LastSecTxRateChangeAction == RATE_DOWN)
+ {
+ pEntry->TxRateUpPenalty = 0;
+ if (pEntry->CurrTxRateIndex != CurrRateIdx)
+ MlmeClearTxQuality(pEntry);
+ }
+ /* if rate-down happen, only clear DownRate's bad history */
+ else if (pEntry->LastSecTxRateChangeAction == RATE_UP)
+ {
+ pEntry->TxRateUpPenalty = 0; /* no penalty */
+ MlmeSetTxQuality(pEntry, pEntry->CurrTxRateIndex, 0);
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0;
+ }
+
+ MlmeNewTxRate(pAd, pEntry);
+ }
+
+ // TODO: should we reset all OneSecTx counters?
+ /* RESET_ONE_SEC_TX_CNT(pEntry); */
+ }
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+/*
+ MlmeOldRateAdapt - perform Rate Adaptation based on PER using old RA algorithm
+ pEntry - the MAC table entry
+ CurrRateIdx - the index of the current rate
+ UpRateIdx, DownRateIdx - UpRate and DownRate index
+ TrainUp, TrainDown - TrainUp and Train Down threhsolds
+ TxErrorRatio - the PER
+
+ On exit:
+ pEntry->LastSecTxRateChangeAction = RATE_UP or RATE_DOWN if there was a change
+ pEntry->CurrTxRateIndex = new rate index
+ pEntry->TxQuality is updated
+*/
+VOID MlmeOldRateAdapt(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR CurrRateIdx,
+ IN UCHAR UpRateIdx,
+ IN UCHAR DownRateIdx,
+ IN ULONG TrainUp,
+ IN ULONG TrainDown,
+ IN ULONG TxErrorRatio)
+{
+ BOOLEAN bTrainUp = FALSE;
+#ifdef TXBF_SUPPORT
+ UCHAR *pTable = pEntry->pTable;
+ BOOLEAN invertTxBf = FALSE;
+#endif /* TXBF_SUPPORT */
+
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE;
+
+ pEntry->CurrTxRateStableTime++;
+
+ /* Downgrade TX quality if PER >= Rate-Down threshold */
+ if (TxErrorRatio >= TrainDown)
+ {
+ MlmeSetTxQuality(pEntry, CurrRateIdx, DRS_TX_QUALITY_WORST_BOUND);
+#ifdef TXBF_SUPPORT
+ /*
+ Need to train down. If BF and last Non-BF isn't too much lower then
+ go to last Non-BF rate. Otherwise just go to the down rate
+ */
+ if ((pEntry->phyETxBf || pEntry->phyITxBf) &&
+ (DownRateIdx - pEntry->lastNonBfRate)<2
+#ifdef DBG_CTRL_SUPPORT
+ && ((pAd->CommonCfg.DebugFlags & DBF_NO_BF_AWARE_RA)==0)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ /* Go directly to last non-BF rate without 100 msec check */
+ pEntry->CurrTxRateIndex = pEntry->lastNonBfRate;
+ pEntry->phyETxBf = pEntry->phyITxBf = FALSE;
+ MlmeNewTxRate(pAd, pEntry);
+ DBGPRINT_RAW(RT_DEBUG_INFO | DBG_FUNC_RA,("DRS: --TX rate from %d to %d \n", CurrRateIdx, pEntry->CurrTxRateIndex));
+ return;
+ }
+ else
+#endif /* TXBF_SUPPORT */
+ if (CurrRateIdx != DownRateIdx)
+ {
+ pEntry->CurrTxRateIndex = DownRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_DOWN;
+ }
+ }
+ else
+ {
+ /* Upgrade TX quality if PER <= Rate-Up threshold */
+ if (TxErrorRatio <= TrainUp)
+ {
+ bTrainUp = TRUE;
+ MlmeDecTxQuality(pEntry, CurrRateIdx); /* quality very good in CurrRate */
+
+ if (pEntry->TxRateUpPenalty)
+ pEntry->TxRateUpPenalty --;
+ else
+ MlmeDecTxQuality(pEntry, UpRateIdx); /* may improve next UP rate's quality */
+ }
+
+ if (bTrainUp)
+ {
+ /* Train up if up rate quality is 0 */
+ if ((CurrRateIdx != UpRateIdx) && (MlmeGetTxQuality(pEntry, UpRateIdx) <= 0))
+ {
+ pEntry->CurrTxRateIndex = UpRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+#ifdef TXBF_SUPPORT
+ else if (((CurrRateIdx != UpRateIdx) || (TxErrorRatio > TrainUp))
+#ifdef DBG_CTRL_SUPPORT
+ && ((pAd->CommonCfg.DebugFlags & DBF_NO_BF_AWARE_RA)==0)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ /* UpRate TxQuality is not 0. Try to invert BF state */
+ if (pEntry->phyETxBf || pEntry->phyITxBf)
+ {
+ /* BF tries same MCS, non-BF */
+ if (pEntry->TxQuality[CurrRateIdx])
+ pEntry->TxQuality[CurrRateIdx]--;
+
+ if (pEntry->TxQuality[CurrRateIdx]==0)
+ {
+ invertTxBf = TRUE;
+ pEntry->CurrTxRateIndex = CurrRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+ }
+ else if (pEntry->eTxBfEnCond>0 || pEntry->iTxBfEn)
+ {
+ RTMP_RA_LEGACY_TB *pUpRate = PTX_RA_LEGACY_ENTRY(pTable, UpRateIdx);
+ RTMP_RA_LEGACY_TB *pCurrTxRate = PTX_RA_LEGACY_ENTRY(pTable, CurrRateIdx);
+
+ /* First try Up Rate with BF */
+ if ((CurrRateIdx != UpRateIdx) && MlmeTxBfAllowed(pAd, pEntry, pUpRate))
+ {
+ if (pEntry->BfTxQuality[UpRateIdx])
+ pEntry->BfTxQuality[UpRateIdx]--;
+
+ if (pEntry->BfTxQuality[UpRateIdx]==0)
+ {
+ invertTxBf = TRUE;
+ pEntry->CurrTxRateIndex = UpRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+ }
+
+ /* Try Same Rate if Up Rate failed */
+ if (pEntry->LastSecTxRateChangeAction==RATE_NO_CHANGE &&
+ MlmeTxBfAllowed(pAd, pEntry, pCurrTxRate))
+ {
+ if (pEntry->BfTxQuality[CurrRateIdx])
+ pEntry->BfTxQuality[CurrRateIdx]--;
+
+ if (pEntry->BfTxQuality[CurrRateIdx]==0)
+ {
+ invertTxBf = TRUE;
+ pEntry->CurrTxRateIndex = CurrRateIdx;
+ pEntry->LastSecTxRateChangeAction = RATE_UP;
+ }
+ }
+ }
+ }
+#endif /* TXBF_SUPPORT */
+ }
+ }
+
+ /* Handle the rate change */
+ if (pEntry->LastSecTxRateChangeAction != RATE_NO_CHANGE)
+ {
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0;
+
+ /* Save last rate information */
+ pEntry->lastRateIdx = CurrRateIdx;
+#ifdef TXBF_SUPPORT
+ if (pEntry->eTxBfEnCond>0)
+ {
+ pEntry->lastRatePhyTxBf = pEntry->phyETxBf;
+ pEntry->phyETxBf ^= invertTxBf;
+ }
+ else
+ {
+ pEntry->lastRatePhyTxBf = pEntry->phyITxBf;
+ pEntry->phyITxBf ^= invertTxBf;
+ }
+#endif /* TXBF_SUPPORT */
+
+ /* Update TxQuality */
+ if (pEntry->LastSecTxRateChangeAction == RATE_UP)
+ {
+ /* Clear history if normal train up */
+ if (pEntry->lastRateIdx != pEntry->CurrTxRateIndex)
+ MlmeClearTxQuality(pEntry);
+ }
+ else
+ {
+ /* Clear the down rate history */
+ MlmeSetTxQuality(pEntry, pEntry->CurrTxRateIndex, 0);
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0;
+ }
+
+ /* Set timer for check in 100 msec */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ if (!pAd->ApCfg.ApQuickResponeForRateUpTimerRunning)
+ {
+ RTMPSetTimer(&pAd->ApCfg.ApQuickResponeForRateUpTimer, pAd->ra_fast_interval);
+ pAd->ApCfg.ApQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ /* Update PHY rate */
+ MlmeNewTxRate(pAd, pEntry);
+ }
+}
diff --git a/cleopatre/devkit/mt7601udrv/rate_ctrl/ra_ctrl.c b/cleopatre/devkit/mt7601udrv/rate_ctrl/ra_ctrl.c
new file mode 100644
index 0000000000..07633e649a
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/rate_ctrl/ra_ctrl.c
@@ -0,0 +1,1977 @@
+/****************************************************************************
+ * Ralink Tech Inc.
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2010, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************/
+
+#include "rt_config.h"
+
+
+
+UCHAR RateSwitchTable11B[] = {
+/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: 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~6: 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~6: 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~6: 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~6: 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,
+};
+
+
+UCHAR RateSwitchTable11N3S[] = {
+/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: 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,
+};
+
+
+UCHAR RateSwitchTable11BGN1S[] = {
+/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: 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~6: 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~6: 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 RateSwitchTable11N1SForABand[] = {
+/* Item No. Mode Curr-MCS TrainUp TrainDown */
+/* Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+ 0x09, 0x07, 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, 10, 25,
+ 0x06, 0x21, 6, 8, 14,
+ 0x07, 0x21, 7, 8, 14,
+ 0x08, 0x23, 7, 8, 14,
+};
+
+
+UCHAR RateSwitchTable11N2SForABand[] = {
+/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: 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 RateSwitchTable11BGN2SForABand[] = {
+/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: 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 RateSwitchTable11N3SForABand[] = { /* 3*3*/
+/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: 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 RateSwitchTable11BGN3SForABand[] = { /* 3*3*/
+/* Item No. Mode Curr-MCS TrainUp TrainDown Mode- Bit0: STBC, Bit1: Short GI, Bit4~6: 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,
+};
+
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+
+#ifdef RANGE_EXTEND
+#define SUPPORT_SHORT_GI_RA /* Support switching to Short GI rates in RA */
+#endif /* RANGE_EXTEND */
+
+/*
+ Rate switch tables for New Rate Adaptation
+
+ Each row has 10 bytes of data.
+ First row contains table information:
+ Byte0=the number of rate entries, Byte1=the initial rate.
+ Format of Mode byte:
+ Bit0: STBC, Bit1: Short GI, Bit4~6: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+*/
+UCHAR RateSwitchTableAdapt11N1S[] = {
+/* item no. mcs highPERThrd upMcs3 upMcs1
+ mode lowPERThrd downMcs upMcs2
+*/
+ 12, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x21, 0, 30, 50, 11, 1, 8, 1, 7,/* mcs0 */
+ 1, 0x21, 1, 20, 50, 0, 16, 9, 2, 13,/* mcs1 */
+ 2, 0x21, 2, 20, 50, 1, 17, 9, 3, 20,/* mcs2 */
+ 3, 0x21, 3, 15, 50, 2, 17, 10, 4, 26,/* mcs3 */
+ 4, 0x21, 4, 15, 30, 3, 18, 11, 5, 39,/* mcs4 */
+ 5, 0x21, 5, 10, 25, 4, 18, 12, 6, 52,/* mcs5 */
+ 6, 0x21, 6, 8, 14, 5, 19, 12, 7, 59,/* mcs6 */
+ 7, 0x21, 7, 8, 14, 6, 19, 12, 8, 65,/* mcs7 */
+ 8, 0x23, 7, 8, 14, 7, 19, 12, 8, 72,/* mcs7+short gi */
+
+ 9, 0x00, 0, 40, 101, 9 , 9, 9, 10, 1, /* cck-1M */
+ 10, 0x00, 1, 40, 50, 9, 10, 10, 11, 2, /* cck-2M */
+ 11, 0x21, 32, 30, 50, 10, 0, 8, 0, 7, /* mcs32 or 20M/mcs0 */
+};
+
+#ifdef SUPPORT_SHORT_GI_RA
+/* Indices for Short GI rates in 11N2S table */
+ #define sg07 18 /* mcs7+shortGI index */
+ #define sg14 17 /* mcs14+shortGI index */
+ #define sg15 16 /* mcs15+shortGI index */
+#endif
+
+UCHAR RateSwitchTableAdapt11N2S[] = {
+/* item no. mcs highPERThrd upMcs3 upMcs1
+ mode lowPERThrd downMcs upMcs2
+*/
+ 22, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x21, 0, 30, 50, 21, 1, 8, 1, 7,/* mcs0 */
+ 1, 0x21, 1, 20, 50, 0, 16, 9, 2, 13,/* mcs1 */
+ 2, 0x21, 2, 20, 50, 1, 17, 9, 3, 20,/* mcs2 */
+ 3, 0x21, 3, 15, 50, 2, 17, 10, 4, 26,/* mcs3 */
+ 4, 0x21, 4, 15, 30, 3, 18, 11, 5, 39,/* mcs4 */
+ 5, 0x21, 5, 10, 25, 4, 18, 12, 6, 52,/* mcs5 */
+ 6, 0x21, 6, 8, 14, 5, 19, 12, 7, 59,/* mcs6 */
+#ifdef SUPPORT_SHORT_GI_RA
+ 7, 0x21, 7, 8, 14, 6, 19, 12, sg07, 65,/* mcs7 */
+#else
+ 7, 0x21, 7, 8, 14, 6, 19, 12, 7, 65,/* mcs7 */
+#endif
+ 8, 0x20, 8, 30, 50, 0, 16, 9, 2, 13,/* mcs8 */
+ 9, 0x20, 9, 20, 50, 8, 17, 10, 4, 26,/* mcs9 */
+ 10, 0x20, 10, 20, 40, 9, 18, 11, 5, 39,/* mcs10 */
+ 11, 0x20, 11, 15, 30, 10, 18, 12, 6, 52,/* mcs11 */
+ 12, 0x20, 12, 15, 30, 11, 20, 13, 12, 78,/* mcs12 */
+ 13, 0x20, 13, 8, 20, 12, 20, 14, 13, 104,/* mcs13 */
+#ifdef SUPPORT_SHORT_GI_RA
+ 14, 0x20, 14, 8, 18, 13, 21, 15,sg14, 117,/* mcs14 */
+ 15, 0x20, 15, 8, 25, 14, 21,sg15,sg14, 130,/* mcs15 */
+ 16, 0x22, 15, 8, 25, 15, 21,sg15,sg15, 144,/* mcs15+shortGI */
+
+ 17, 0x22, 14, 8, 14, 14, 21,sg15, 15, 130, /* mcs14+shortGI */
+ 18, 0x23, 7, 8, 14, 7, 19, 12,sg07, 72, /* mcs7+shortGI */
+#else
+ 14, 0x20, 14, 8, 18, 13, 21, 15, 14, 117,/* mcs14 */
+ 15, 0x20, 15, 8, 25, 14, 21, 16, 15, 130,/* mcs15 */
+ 16, 0x22, 15, 8, 25, 15, 21, 16, 16, 144,/* mcs15+shortGI */
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 18, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+#endif
+ 19, 0x00, 0, 40, 101, 19 , 19, 19, 20, 1, /* cck-1M */
+ 20, 0x00, 1, 40, 50, 19, 20, 20, 21, 2, /* cck-2M */
+ 21, 0x21, 32, 30, 50, 20, 0, 8, 0, 7, /* mcs32 or 20M/mcs0 */
+};
+
+#ifdef SUPPORT_SHORT_GI_RA
+/* Indices for Short GI rates in 11N3S table */
+ #undef sg07
+ #undef sg14
+ #undef sg15
+ #define sg07 29 /* mcs7+shortGI index */
+ #define sg14 27 /* mcs14+shortGI index */
+ #define sg15 28 /* mcs15+shortGI index */
+ #define sg21 25 /* mcs21+shortGI index */
+ #define sg22 26 /* mcs22+shortGI index */
+ #define sg23 24 /* mcs23+shortGI index */
+#endif
+
+UCHAR RateSwitchTableAdapt11N3S[] = {
+/* item no mcs highPERThrd upMcs3 upMcs1
+ mode lowPERThrd downMcs upMcs2
+*/
+ 33, 23, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x21, 0, 30, 50, 32, 1, 8, 1, 7, /* mcs0 */
+ 1, 0x21, 1, 20, 50, 0, 16, 9, 2, 13, /* mcs1 */
+ 2, 0x21, 2, 20, 50, 1, 17, 9, 3, 20, /* mcs2 */
+ 3, 0x21, 3, 15, 50, 2, 17, 10, 4, 26, /* mcs3 */
+ 4, 0x21, 4, 15, 30, 3, 18, 11, 5, 39, /* mcs4 */
+ 5, 0x21, 5, 10, 25, 4, 18, 12, 6, 52, /* mcs5 */
+ 6, 0x21, 6, 8, 14, 5, 19, 12, 7, 59, /* mcs6 */
+#ifdef SUPPORT_SHORT_GI_RA
+ 7, 0x21, 7, 8, 14, 6, 19, 12, sg07, 65, /* mcs7 */
+#else
+ 7, 0x21, 7, 8, 14, 6, 19, 12, 7, 65, /* mcs7 */
+#endif
+ 8, 0x20, 8, 30, 50, 0, 16, 9, 2, 13, /* mcs8 */
+ 9, 0x20, 9, 20, 50, 8, 17, 10, 4, 26, /* mcs9 */
+ 10, 0x20, 10, 20, 40, 9, 18, 11, 5, 39, /* mcs10 */
+ 11, 0x20, 11, 15, 30, 10, 18, 12, 6, 52, /* mcs11 */
+ 12, 0x20, 12, 15, 30, 11, 20, 13, 12, 78, /* mcs12 */
+ 13, 0x20, 13, 8, 20, 12, 20, 14, 13, 104, /* mcs13 */
+#ifdef SUPPORT_SHORT_GI_RA
+ 14, 0x20, 14, 8, 18, 13, 21, 15, sg14, 117, /* mcs14 */
+ 15, 0x20, 15, 8, 14, 14, 21, sg15, sg14, 130, /* mcs15 */
+#else
+ 14, 0x20, 14, 8, 18, 13, 21, 15, 14, 117, /* mcs14 */
+ 15, 0x20, 15, 8, 14, 14, 21, 15, 15, 130, /* mcs15 */
+#endif
+ 16, 0x20, 16, 30, 50, 8, 17, 9, 3, 20, /* mcs16 */
+ 17, 0x20, 17, 20, 50, 16, 18, 11, 5, 39, /* mcs17 */
+ 18, 0x20, 18, 20, 40, 17, 19, 12, 7, 59, /* mcs18 */
+ 19, 0x20, 19, 15, 30, 18, 20, 13, 19, 78, /* mcs19 */
+ 20, 0x20, 20, 15, 30, 19, 21, 15, 20, 117, /* mcs20 */
+#ifdef SUPPORT_SHORT_GI_RA
+ 21, 0x20, 21, 8, 20, 20, 22, sg21, 21, 156, /* mcs21 */
+ 22, 0x20, 22, 8, 20, 21, 23, sg22, sg21, 176, /* mcs22 */
+ 23, 0x20, 23, 6, 18, 22, sg23, 23, sg22, 195, /* mcs23 */
+ 24, 0x22, 23, 6, 14, 23, sg23, sg23, sg23, 217, /* mcs23+shortGI */
+
+ 25, 0x22, 21, 6, 18, 21, sg22, 22, sg21, 173, /* mcs21+shortGI */
+ 26, 0x22, 22, 6, 18, 22, sg23, 23, sg22, 195, /* mcs22+shortGI */
+ 27, 0x22, 14, 8, 14, 14, 21, sg15, 15, 130, /* mcs14+shortGI */
+ 28, 0x22, 15, 8, 14, 15, 21, sg15, sg15, 144, /* mcs15+shortGI */
+ 29, 0x23, 7, 8, 14, 7, 19, 12, 29, 72, /* mcs7+shortGI */
+#else
+ 21, 0x20, 21, 8, 20, 20, 22, 21, 21, 156, /* mcs21 */
+ 22, 0x20, 22, 8, 20, 21, 23, 22, 22, 176, /* mcs22 */
+ 23, 0x20, 23, 6, 18, 22, 24, 23, 23, 195, /* mcs23 */
+ 24, 0x22, 23, 6, 14, 23, 24, 24, 24, 217, /* mcs23+shortGI */
+ 25, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 26, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 28, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+#endif
+ 30, 0x00, 0, 40, 101, 30 , 30, 30, 31, 1, /* cck-1M */
+ 31, 0x00, 1, 40, 50, 30, 31, 31, 32, 2, /* cck-2M */
+ 32, 0x21, 32, 30, 50, 31, 0, 8, 0, 7, /* mcs32 or 20M/mcs0 */
+};
+
+
+#ifdef DOT11_VHT_AC
+/*
+ VHT-capable rate table
+
+ Each row has 10 bytes of data.
+
+ 1. First row contains table info, which is initial used item after assoc:
+ Byte0=the number of rate entries, Byte1=the initial rate.
+
+ 2. rest rows Format:
+ [Index] [Mode] [nSS] [CurrMCS] [PERThrd Low/High] [downMCS] [upMCS3/2/1]
+
+ [Mode]:
+ bit0: STBC
+ bit1: Short GI
+ bit2~3: BW - (20M/40M/80M)
+ bit4~bit6: Mode (0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF, 4: VHT) - MODE_XXX
+ bit7: Reserved
+ [nSS]:
+ Number of Spatial Stream
+
+ Note: downMCS, upMCS3, upMCS2 and upMCS1 are zero-based array index.
+*/
+/* 1x1 VHT-capable rate table */
+UCHAR RateTableVht1S[] =
+{
+ 9, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+/* [Idx] [Mode] [MCS] [PER_Low/High] [dMCS] [upMCS3/2/1] [nSS]*/
+ 0, 0x41, 0, 30, 101, 0, 0, 0, 1, 1,
+ 1, 0x41, 1, 20, 50, 0, 0, 0, 2, 1,
+ 2, 0x41, 2, 20, 50, 1, 0, 0, 3, 1,
+ 3, 0x41, 3, 15, 50, 2, 0, 0, 4, 1,
+ 4, 0x41, 4, 15, 30, 3, 0, 0, 5, 1,
+ 5, 0x41, 5, 10, 25, 4, 0, 0, 6, 1,
+ 6, 0x41, 6, 8, 14, 5, 0, 0, 7, 1,
+ 7, 0x41, 7, 8, 14, 6, 0, 0, 8, 1,
+ 8, 0x43, 7, 8, 14, 7, 0, 0, 8, 1,
+};
+
+
+/* 2x2 VHT-capable rate table */
+UCHAR RateTableVht2S[] =
+{
+ 17, 15, 0, 0, 0, 0, 0, 0, 0, 1,
+/* [Idx] [Mode] [MCS] [PER_Low/High] [dMCS] [upMCS3/2/1] [nSS]*/
+ 0, 0x41, 0, 30, 101, 0, 0, 8, 1, 1,
+ 1, 0x41, 1, 20, 50, 0, 0, 9, 2, 1,
+ 2, 0x41, 2, 20, 50, 1, 0, 9, 3, 1,
+ 3, 0x41, 3, 15, 50, 2, 0, 10, 4, 1,
+ 4, 0x41, 4, 15, 30, 3, 0, 11, 5, 1,
+ 5, 0x41, 5, 10, 25, 4, 0, 12, 6, 1,
+ 6, 0x41, 6, 8, 14, 5, 0, 12, 7, 1,
+ 7, 0x41, 7, 8, 14, 6, 0, 12, 7, 1,
+ 8, 0x40, 0, 30, 50, 0, 0, 9, 2, 2,
+ 9, 0x40, 1, 20, 50, 8, 0, 10, 4, 2,
+ 10, 0x40, 2, 20, 50, 9, 0, 11, 5, 2,
+ 11, 0x40, 3, 15, 30, 10, 0, 12, 6, 2,
+ 12, 0x40, 4, 15, 30, 11, 0, 13, 12, 2,
+ 13, 0x40, 5, 8, 20, 12, 0, 14, 13, 2,
+ 14, 0x40, 6, 8, 18, 13, 0, 15, 14, 2,
+ 15, 0x40, 7, 8, 25, 14, 0, 16, 15, 2,
+ 16, 0x42, 7, 8, 25, 15, 0, 16, 16, 2,
+};
+#endif /* DOT11_VHT_AC */
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#endif /* DOT11_N_SUPPORT */
+
+
+
+
+/* MlmeGetSupportedMcs - fills in the table of mcs with index into the pTable
+ pAd - pointer to adapter
+ pTable - pointer to the Rate Table. Assumed to be a table without mcsGroup values
+ mcs - table of MCS index into the Rate Table. -1 => not supported
+*/
+VOID MlmeGetSupportedMcs(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *pTable,
+ OUT CHAR mcs[])
+{
+ CHAR idx;
+ RTMP_RA_LEGACY_TB *pCurrTxRate;
+
+ for (idx=0; idx<24; idx++)
+ mcs[idx] = -1;
+
+ /* check the existence and index of each needed MCS */
+ for (idx=0; idx<RATE_TABLE_SIZE(pTable); idx++)
+ {
+ pCurrTxRate = PTX_RA_LEGACY_ENTRY(pTable, idx);
+
+ /* Rate Table may contain CCK and MCS rates. Give HT/Legacy priority over CCK */
+ if (pCurrTxRate->CurrMCS==MCS_0 && (mcs[0]==-1 || pCurrTxRate->Mode!=MODE_CCK))
+ mcs[0] = idx;
+ else if (pCurrTxRate->CurrMCS==MCS_1 && (mcs[1]==-1 || pCurrTxRate->Mode!=MODE_CCK))
+ mcs[1] = idx;
+ else if (pCurrTxRate->CurrMCS==MCS_2 && (mcs[2]==-1 || pCurrTxRate->Mode!=MODE_CCK))
+ mcs[2] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_3)
+ mcs[3] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_4)
+ mcs[4] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_5)
+ mcs[5] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_6)
+ mcs[6] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))
+ mcs[7] = idx;
+#ifdef DOT11_N_SUPPORT
+ else if (pCurrTxRate->CurrMCS == MCS_12)
+ mcs[12] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_13)
+ mcs[13] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_14)
+ mcs[14] = idx;
+ else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))
+ {
+ mcs[15] = idx;
+ }
+#ifdef DOT11N_SS3_SUPPORT
+ else if (pCurrTxRate->CurrMCS == MCS_20)
+ mcs[20] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_21)
+ mcs[21] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_22)
+ mcs[22] = idx;
+ else if (pCurrTxRate->CurrMCS == MCS_23)
+ mcs[23] = idx;
+#endif /* DOT11N_SS3_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+ }
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug Option: Disable highest MCSs when picking initial MCS based on RSSI */
+ if (pAd->CommonCfg.DebugFlags & DBF_INIT_MCS_DIS1)
+ mcs[23] = mcs[15] = mcs[7] = mcs[22] = mcs[14] = mcs[6] = 0;
+#endif /* DBG_CTRL_SUPPORT */
+}
+
+
+/* MlmeClearTxQuality - Clear TxQuality history only for the active BF state */
+VOID MlmeClearTxQuality(
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+#ifdef TXBF_SUPPORT
+ if (pEntry->phyETxBf || pEntry->phyITxBf)
+ NdisZeroMemory(pEntry->BfTxQuality, sizeof(pEntry->BfTxQuality));
+ else
+#endif /* TXBF_SUPPORT */
+ NdisZeroMemory(pEntry->TxQuality, sizeof(pEntry->TxQuality));
+
+ NdisZeroMemory(pEntry->PER, sizeof(pEntry->PER));
+}
+
+
+/* MlmeClearAllTxQuality - Clear both BF and non-BF TxQuality history */
+VOID MlmeClearAllTxQuality(
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+#ifdef TXBF_SUPPORT
+ NdisZeroMemory(pEntry->BfTxQuality, sizeof(pEntry->BfTxQuality));
+#endif
+ NdisZeroMemory(pEntry->TxQuality, sizeof(pEntry->TxQuality));
+
+ NdisZeroMemory(pEntry->PER, sizeof(pEntry->PER));
+}
+
+
+/* MlmeDecTxQuality - Decrement TxQuality of specified rate table entry */
+VOID MlmeDecTxQuality(
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR rateIndex)
+{
+#ifdef TXBF_SUPPORT
+ if (pEntry->phyETxBf || pEntry->phyITxBf) {
+ if (pEntry->BfTxQuality[rateIndex])
+ pEntry->BfTxQuality[rateIndex]--;
+ }
+ else
+#endif /* TXBF_SUPPORT */
+ if (pEntry->TxQuality[rateIndex])
+ pEntry->TxQuality[rateIndex]--;
+}
+
+
+VOID MlmeSetTxQuality(
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR rateIndex,
+ IN USHORT txQuality)
+{
+#ifdef TXBF_SUPPORT
+ if (pEntry->phyETxBf || pEntry->phyITxBf)
+ pEntry->BfTxQuality[rateIndex] = txQuality;
+ else
+#endif /* TXBF_SUPPORT */
+ pEntry->TxQuality[rateIndex] = txQuality;
+}
+
+
+USHORT MlmeGetTxQuality(
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR rateIndex)
+{
+#ifdef TXBF_SUPPORT
+ if (pEntry->phyETxBf || pEntry->phyITxBf)
+ return pEntry->BfTxQuality[rateIndex];
+#endif /* TXBF_SUPPORT */
+ return pEntry->TxQuality[rateIndex];
+}
+
+
+#ifdef CONFIG_AP_SUPPORT
+VOID APMlmeSetTxRate(
+ IN RTMP_ADAPTER *pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RTMP_RA_LEGACY_TB *pTxRate)
+{
+#ifdef DOT11_N_SUPPORT
+ if ((pTxRate->STBC) && (pEntry->MaxHTPhyMode.field.STBC))
+ pEntry->HTPhyMode.field.STBC = STBC_USE;
+ else
+ pEntry->HTPhyMode.field.STBC = STBC_NONE;
+
+ if (((pTxRate->ShortGI) && (pEntry->MaxHTPhyMode.field.ShortGI))
+ || (pAd->WIFItestbed.bShortGI && pEntry->MaxHTPhyMode.field.ShortGI) )
+ pEntry->HTPhyMode.field.ShortGI = GI_400;
+ else
+ pEntry->HTPhyMode.field.ShortGI = GI_800;
+#endif /* DOT11_N_SUPPORT */
+
+ if (pTxRate->CurrMCS < MCS_AUTO)
+ pEntry->HTPhyMode.field.MCS = pTxRate->CurrMCS;
+
+ pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->WIFItestbed.bGreenField & pEntry->HTCapability.HtCapInfo.GF) && (pEntry->HTPhyMode.field.MODE == MODE_HTMIX))
+ {
+ /* force Tx GreenField */
+ pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+
+ /* BW depends on BSSWidthTrigger and Negotiated BW */
+ if (pAd->CommonCfg.bRcvBSSWidthTriggerEvents ||
+ (pEntry->MaxHTPhyMode.field.BW==BW_20) ||
+ (pAd->CommonCfg.BBPCurrentBW==BW_20))
+ pEntry->HTPhyMode.field.BW = BW_20;
+ else
+ pEntry->HTPhyMode.field.BW = BW_40;
+
+#ifdef DOT11_VHT_AC
+ if (pAd->CommonCfg.BBPCurrentBW==BW_80 &&
+ pEntry->MaxHTPhyMode.field.BW == BW_80 &&
+ pEntry->MaxHTPhyMode.field.MODE == MODE_VHT)
+ pEntry->HTPhyMode.field.BW = BW_80;
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pEntry->pTable == RateTableVht2S)
+ {
+ RTMP_RA_GRP_TB *pAdaptTbEntry = (RTMP_RA_GRP_TB *)pTxRate;
+ pEntry->HTPhyMode.field.MCS = pAdaptTbEntry->CurrMCS | ((pAdaptTbEntry->dataRate -1) <<4);
+ }
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef AGS_SUPPORT
+ if (pEntry->pTable == Ags2x2VhtRateTable)
+ {
+ RTMP_RA_AGS_TB *pAgsTbEntry = (RTMP_RA_AGS_TB *)pTxRate;
+ pEntry->HTPhyMode.field.MCS = pAgsTbEntry->CurrMCS | (pAgsTbEntry->Nss <<4);
+ }
+#endif /* AGS_SUPPORT */
+#endif /* DOT11_VHT_AC */
+
+#ifdef RANGE_EXTEND
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ /* 20 MHz Fallback */
+ if (pTxRate->Mode >= MODE_HTMIX &&
+ pEntry->HTPhyMode.field.BW == BW_40 &&
+ ADAPT_RATE_TABLE(pEntry->pTable))
+ {
+ if (pEntry->HTPhyMode.field.MCS == 32
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_DISABLE_20MHZ_MCS0) == 0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ /* Map HT Duplicate to 20MHz MCS0 */
+ pEntry->HTPhyMode.field.BW = BW_20;
+ pEntry->HTPhyMode.field.MCS = 0;
+ }
+ else if (pEntry->HTPhyMode.field.MCS == 0 &&
+ (pAd->CommonCfg.DebugFlags & DBF_FORCE_20MHZ) == 0
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_DISABLE_20MHZ_MCS1) == 0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ /* Map 40MHz MCS0 to 20MHz MCS1 */
+ pEntry->HTPhyMode.field.BW = BW_20;
+ pEntry->HTPhyMode.field.MCS = 1;
+ }
+ else if (pEntry->HTPhyMode.field.MCS==8
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_ENABLE_20MHZ_MCS8)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ /* Map 40MHz MCS8 to 20MHz MCS8 */
+ pEntry->HTPhyMode.field.BW = BW_20;
+ }
+ }
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug Option: Force BW */
+ if (pAd->CommonCfg.DebugFlags & DBF_FORCE_40MHZ)
+ {
+ pEntry->HTPhyMode.field.BW = BW_40;
+ }
+ else if (pAd->CommonCfg.DebugFlags & DBF_FORCE_20MHZ)
+ {
+ pEntry->HTPhyMode.field.BW = BW_20;
+ }
+#endif /* DBG_CTRL_SUPPORT */
+#endif /* RANGE_EXTEND */
+
+ /* Reexam each bandwidth's SGI support. */
+ if ((pEntry->HTPhyMode.field.BW==BW_20 && !CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)) ||
+ (pEntry->HTPhyMode.field.BW==BW_40 && !CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)) )
+ pEntry->HTPhyMode.field.ShortGI = GI_800;
+
+#ifdef DBG_CTRL_SUPPORT
+ /* Debug option: Force Short GI */
+ if (pAd->CommonCfg.DebugFlags & DBF_FORCE_SGI)
+ pEntry->HTPhyMode.field.ShortGI = GI_400;
+#endif /* DBG_CTRL_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+ pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+
+#ifdef FIFO_EXT_SUPPORT
+ AsicFifoExtEntryClean(pAd, pEntry);
+#endif /* FIFO_EXT_SUPPORT */
+
+
+
+}
+#endif /* CONFIG_AP_SUPPORT */
+
+
+
+
+VOID MlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR **ppTable,
+ IN UCHAR *pTableSize,
+ IN UCHAR *pInitTxRateIdx)
+{
+ do
+ {
+#ifdef DOT11_VHT_AC
+ if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) &&
+ (pEntry->SupportRateMode & SUPPORT_VHT_MODE))
+ {
+ INT mcs_idx, ss = 0;
+ for (mcs_idx = 0; mcs_idx < MAX_LEN_OF_VHT_RATES; mcs_idx++)
+ {
+ if (pEntry->SupportVHTMCS[mcs_idx])
+ {
+ if (mcs_idx <= 7)
+ ss =1;
+ if (mcs_idx >= 8)
+ ss = 2;
+ }
+ }
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ {
+ if (ss == 2)
+ *ppTable = RateTableVht2S;
+ else
+ *ppTable = RateTableVht1S;
+ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA, ("%s(): Select RateTableVht%dS\n",
+ __FUNCTION__, (ss == 2 ? 2 : 1)));
+ }
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef AGS_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_AGS)
+ {
+ if (ss == 2)
+ *ppTable = Ags2x2VhtRateTable;
+ else
+ *ppTable = Ags1x1VhtRateTable;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): Select Ags%dx%dVhtRateTable\n",
+ __FUNCTION__, (ss == 2 ? 2 : 1), (ss == 2 ? 2 : 1)));
+ }
+#endif /* AGS_SUPPORT */
+ break;
+ }
+#endif /* DOT11_VHT_AC */
+
+
+#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->SupportRateMode & (SUPPORT_OFDM_MODE)) &&
+ (pEntry->HTCapability.MCSSet[0] != 0x00) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {/* 11BGN 1S AP*/
+#ifdef AGS_SUPPORT
+ if (SUPPORT_AGS(pAd))
+ *ppTable = AGS1x1HTRateTable;
+ else
+#endif /* AGS_SUPPORT */
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N1S;
+ else
+#endif
+ if ((pAd->LatchRfRegs.Channel <= 14) && (pEntry->SupportRateMode & (SUPPORT_CCK_MODE)))
+ *ppTable = RateSwitchTable11BGN1S;
+ else
+ *ppTable = RateSwitchTable11N1SForABand;
+
+ break;
+ }
+
+#ifdef AGS_SUPPORT
+ /* only for station */
+ if (SUPPORT_AGS(pAd) &&
+ (pEntry->HTCapability.MCSSet[0] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[1] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[2] != 0x00) &&
+ (pAd->CommonCfg.TxStream == 3))
+ {/* 11N 3S */
+ *ppTable = AGS3x3HTRateTable;
+ break;
+ }
+#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->SupportRateMode & (SUPPORT_OFDM_MODE)) &&
+ (pEntry->HTCapability.MCSSet[0] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[1] != 0x00) &&
+ (((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;
+ }
+ else
+#endif /* AGS_SUPPORT */
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N2S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if ((pAd->LatchRfRegs.Channel <= 14) && (pEntry->SupportRateMode & (SUPPORT_CCK_MODE)))
+ *ppTable = RateSwitchTable11BGN2S;
+ else
+ *ppTable = RateSwitchTable11BGN2SForABand;
+
+ break;
+ }
+
+#ifdef DOT11N_SS3_SUPPORT
+ if ((pEntry->SupportRateMode & (SUPPORT_OFDM_MODE)) &&
+ (pEntry->HTCapability.MCSSet[0] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[1] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[2] != 0x00) &&
+ (pAd->CommonCfg.TxStream == 3))
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ {
+ *ppTable = RateSwitchTableAdapt11N3S;
+ }
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if ((pAd->LatchRfRegs.Channel <= 14) && (pEntry->SupportRateMode & (SUPPORT_CCK_MODE)))
+ *ppTable = RateSwitchTable11N3S;
+ else
+ *ppTable = RateSwitchTable11N3SForABand;
+
+ 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] != 0x00) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {/* 11N 1S AP*/
+#ifdef AGS_SUPPORT
+ if (SUPPORT_AGS(pAd))
+ *ppTable = AGS1x1HTRateTable;
+ else
+#endif /* AGS_SUPPORT */
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N1S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if (pAd->LatchRfRegs.Channel <= 14)
+ *ppTable = RateSwitchTable11N1S;
+ else
+ *ppTable = RateSwitchTable11N1SForABand;
+ }
+ 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] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[1] != 0x00) &&
+ (pAd->CommonCfg.TxStream == 2))
+ {/* 11N 2S AP*/
+#ifdef AGS_SUPPORT
+ if (SUPPORT_AGS(pAd))
+ *ppTable = AGS2x2HTRateTable;
+ else
+#endif /* AGS_SUPPORT */
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N2S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if (pAd->LatchRfRegs.Channel <= 14)
+ *ppTable = RateSwitchTable11N2S;
+ else
+ *ppTable = RateSwitchTable11N2SForABand;
+ }
+ break;
+ }
+
+#ifdef DOT11N_SS3_SUPPORT
+ if ((pEntry->HTCapability.MCSSet[0] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[1] != 0x00) &&
+ (pEntry->HTCapability.MCSSet[2] != 0x00) &&
+ (pAd->CommonCfg.TxStream == 3))
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N3S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ {
+ if (pAd->LatchRfRegs.Channel <= 14)
+ *ppTable = RateSwitchTable11N3S;
+ else
+ *ppTable = RateSwitchTable11N3SForABand;
+ }
+ break;
+ }
+#endif /* DOT11N_SS3_SUPPORT */
+
+#ifdef DOT11N_SS3_SUPPORT
+ if (pAd->CommonCfg.TxStream == 3)
+ {
+ if (pEntry->HTCapability.MCSSet[0] != 0x00)
+ {
+ if (pEntry->HTCapability.MCSSet[1] == 0x00)
+ { /* Only support 1SS */
+ if (pEntry->RateLen > 0)
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N1S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if ((pAd->LatchRfRegs.Channel <= 14) && (pEntry->SupportRateMode & (SUPPORT_CCK_MODE)))
+ *ppTable = RateSwitchTable11N1S;
+ else
+ *ppTable = RateSwitchTable11N1SForABand;
+ }
+ else
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N1S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if (pAd->LatchRfRegs.Channel <= 14)
+ *ppTable = RateSwitchTable11N1S;
+ else
+ *ppTable = RateSwitchTable11N1SForABand;
+ }
+ break;
+ }
+ else if (pEntry->HTCapability.MCSSet[2] == 0x00)
+ { /* Only support 2SS */
+ if (pEntry->RateLen > 0)
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N2S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if ((pAd->LatchRfRegs.Channel <= 14) && (pEntry->SupportRateMode & (SUPPORT_CCK_MODE)))
+ *ppTable = RateSwitchTable11BGN2S;
+ else
+ *ppTable = RateSwitchTable11BGN2SForABand;
+ }
+ else
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ *ppTable = RateSwitchTableAdapt11N2S;
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ if (pAd->LatchRfRegs.Channel <= 14)
+ *ppTable = RateSwitchTable11N2S;
+ else
+ *ppTable = RateSwitchTable11N2SForABand;
+ }
+ break;
+ }
+ /* For 3SS case, we use the new rate table, so don't care it here */
+ }
+ }
+#endif /* DOT11N_SS3_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+ if (((pEntry->SupportRateMode == SUPPORT_CCK_MODE) ||
+ WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_B))
+#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;
+ break;
+ }
+
+ /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))*/
+ if ((pEntry->SupportRateMode & (SUPPORT_CCK_MODE)) &&
+ (pEntry->SupportRateMode & (SUPPORT_OFDM_MODE))
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif /* DOT11_N_SUPPORT */
+ )
+ {/* B/G mixed AP*/
+ *ppTable = RateSwitchTable11BG;
+ break;
+ }
+
+ /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))*/
+ if ((pEntry->SupportRateMode & (SUPPORT_OFDM_MODE))
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif /* DOT11_N_SUPPORT */
+ )
+ {/* G only AP*/
+ *ppTable = RateSwitchTable11G;
+ break;
+ }
+#ifdef DOT11_N_SUPPORT
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+#ifdef DOT11N_SS3_SUPPORT
+ if (pAd->CommonCfg.TxStream >= 3)
+ {
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (pAd->rateAlg == RATE_ALG_GRP)
+ {
+ if (pEntry->HTCapability.MCSSet[2] == 0)
+ *ppTable = RateSwitchTableAdapt11N2S;
+ else
+ *ppTable = RateSwitchTableAdapt11N3S;
+ }
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ {
+ if (pEntry->HTCapability.MCSSet[2] == 0)
+ *ppTable = RateSwitchTable11N2S;
+ else
+ *ppTable = RateSwitchTable11N3S;
+ }
+ }
+ else
+#endif /* DOT11N_SS3_SUPPORT */
+ {
+ /*
+ Temp solution for:
+ EX: when the extend rate only supports 6, 12, 24 in
+ the association req frame. So the pEntry->RateLen is 7.
+ */
+ if (pAd->LatchRfRegs.Channel <= 14)
+ *ppTable = RateSwitchTable11BG;
+ else
+ *ppTable = RateSwitchTable11G;
+ }
+ break;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* DOT11_N_SUPPORT */
+
+ } while(FALSE);
+
+ *pTableSize = RATE_TABLE_SIZE(*ppTable);
+ *pInitTxRateIdx = RATE_TABLE_INIT_INDEX(*ppTable);
+
+}
+
+
+
+/*
+ MlmeSelectTxRate - select the MCS based on the RSSI and the available MCSs
+ pAd - pointer to adapter
+ pEntry - pointer to MAC table entry
+ mcs - table of MCS index into the Rate Table. -1 => not supported
+ Rssi - the Rssi value
+ RssiOffset - offset to apply to the Rssi
+*/
+UCHAR MlmeSelectTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN CHAR mcs[],
+ IN CHAR Rssi,
+ IN CHAR RssiOffset)
+{
+ UCHAR TxRateIdx = 0;
+ UCHAR *pTable = pEntry->pTable;
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11_VHT_AC
+ if (pTable == RateTableVht2S)
+ {
+ /* VHT mode with 2SS */
+ if (mcs[15]>=0 && (Rssi >= (-70+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_15]))
+ TxRateIdx = mcs[15];
+ else if (mcs[14]>=0 && (Rssi >= (-72+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_14]))
+ TxRateIdx = mcs[14];
+ else if (mcs[13]>=0 && (Rssi >= (-76+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_13]))
+ TxRateIdx = mcs[13];
+ else if (mcs[12]>=0 && (Rssi >= (-78+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_12]))
+ TxRateIdx = mcs[12];
+ else if (mcs[4]>=0 && (Rssi >= (-82+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_4]))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi >= (-84+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi >= (-86+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi >= (-88+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+ else if (pTable == RateTableVht1S)
+ { /* VHT mode with 1SS */
+ if (mcs[7]>=0 && (Rssi > (-72+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_7]))
+ TxRateIdx = mcs[7];
+ else if (mcs[6]>=0 && (Rssi > (-74+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_6]))
+ TxRateIdx = mcs[6];
+ else if (mcs[5]>=0 && (Rssi > (-77+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_5]))
+ TxRateIdx = mcs[5];
+ else if (mcs[4]>=0 && (Rssi > (-79+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_4]))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi > (-81+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > (-83+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > (-86+RssiOffset)) && (pEntry->SupportVHTMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+ else
+#endif /* DOT11_VHT_AC */
+#ifdef DOT11N_SS3_SUPPORT
+ if ((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11N3S) || (pTable == RateSwitchTable11BGN3SForABand)
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ || (pTable == RateSwitchTableAdapt11N3S)
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ )
+ {/* N mode with 3 stream */
+ if (mcs[23]>=0 && (Rssi >= (-66+RssiOffset)) && (pEntry->SupportHTMCS[MCS_23]))
+ TxRateIdx = mcs[23];
+ else if (mcs[22]>=0 && (Rssi >= (-70+RssiOffset)) && (pEntry->SupportHTMCS[MCS_22]))
+ TxRateIdx = mcs[22];
+ else if (mcs[21]>=0 && (Rssi >= (-72+RssiOffset)) && (pEntry->SupportHTMCS[MCS_21]))
+ TxRateIdx = mcs[21];
+ else if (mcs[20]>=0 && (Rssi >= (-74+RssiOffset)) && (pEntry->SupportHTMCS[MCS_20]))
+ TxRateIdx = mcs[20];
+ else if (mcs[13]>=0 && (Rssi >= (-76+RssiOffset)) && (pEntry->SupportHTMCS[MCS_13]))
+ TxRateIdx = mcs[13];
+ else if (mcs[12]>=0 && (Rssi >= (-78+RssiOffset)) && (pEntry->SupportHTMCS[MCS_12]))
+ TxRateIdx = mcs[12];
+ else if (mcs[4]>=0 && (Rssi >= (-82+RssiOffset)) && (pEntry->SupportHTMCS[MCS_4]))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi >= (-84+RssiOffset)) && (pEntry->SupportHTMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi >= (-86+RssiOffset)) && (pEntry->SupportHTMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi >= (-88+RssiOffset)) && (pEntry->SupportHTMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+ else
+#endif /* DOT11N_SS3_SUPPORT */
+ if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||
+ (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable11N2SForABand)
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ || (pTable == RateSwitchTableAdapt11N2S)
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ )
+ {/* N mode with 2 stream */
+ if (mcs[15]>=0 && (Rssi >= (-70+RssiOffset)) && (pEntry->SupportHTMCS[MCS_15]))
+ TxRateIdx = mcs[15];
+ else if (mcs[14]>=0 && (Rssi >= (-72+RssiOffset)) && (pEntry->SupportHTMCS[MCS_14]))
+ TxRateIdx = mcs[14];
+ else if (mcs[13]>=0 && (Rssi >= (-76+RssiOffset)) && (pEntry->SupportHTMCS[MCS_13]))
+ TxRateIdx = mcs[13];
+ else if (mcs[12]>=0 && (Rssi >= (-78+RssiOffset)) && (pEntry->SupportHTMCS[MCS_12]))
+ TxRateIdx = mcs[12];
+ else if (mcs[4]>=0 && (Rssi >= (-82+RssiOffset)) && (pEntry->SupportHTMCS[MCS_4]))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi >= (-84+RssiOffset)) && (pEntry->SupportHTMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi >= (-86+RssiOffset)) && (pEntry->SupportHTMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi >= (-88+RssiOffset)) && (pEntry->SupportHTMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+ else if ((pTable == RateSwitchTable11BGN1S) ||
+ (pTable == RateSwitchTable11N1S) ||
+ (pTable == RateSwitchTable11N1SForABand)
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ || (pTable == RateSwitchTableAdapt11N1S)
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ )
+ {/* N mode with 1 stream */
+#ifdef MT7601
+ if ( IS_MT7601(pAd))
+ {
+ //printk("RSSI=%d\n", Rssi);
+ if (mcs[7]>=0 && (Rssi > (-64+RssiOffset)) && (pEntry->SupportHTMCS[MCS_7]))
+ TxRateIdx = mcs[7];
+ else if (mcs[6]>=0 && (Rssi > (-66+RssiOffset)) && (pEntry->SupportHTMCS[MCS_6]))
+ TxRateIdx = mcs[6];
+ else if (mcs[5]>=0 && (Rssi > (-70+RssiOffset)) && (pEntry->SupportHTMCS[MCS_5]))
+ TxRateIdx = mcs[5];
+ else if (mcs[4]>=0 && (Rssi > (-73+RssiOffset)) && (pEntry->SupportHTMCS[MCS_4]))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi > (-77+RssiOffset)) && (pEntry->SupportHTMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > (-79+RssiOffset)) && (pEntry->SupportHTMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > (-81+RssiOffset)) && (pEntry->SupportHTMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else if (mcs[1]>=0 && (Rssi > (-83+RssiOffset)) && (pEntry->SupportHTMCS[MCS_0]))
+ TxRateIdx = mcs[0];
+
+ //printk("TxRateIdx = %d\n", TxRateIdx);
+ }
+ else
+#endif /* MT7601 */
+ {
+ if (mcs[7]>=0 && (Rssi > (-72+RssiOffset)) && (pEntry->SupportHTMCS[MCS_7]))
+ TxRateIdx = mcs[7];
+ else if (mcs[6]>=0 && (Rssi > (-74+RssiOffset)) && (pEntry->SupportHTMCS[MCS_6]))
+ TxRateIdx = mcs[6];
+ else if (mcs[5]>=0 && (Rssi > (-77+RssiOffset)) && (pEntry->SupportHTMCS[MCS_5]))
+ TxRateIdx = mcs[5];
+ else if (mcs[4]>=0 && (Rssi > (-79+RssiOffset)) && (pEntry->SupportHTMCS[MCS_4]))
+ TxRateIdx = mcs[4];
+ else if (mcs[3]>=0 && (Rssi > (-81+RssiOffset)) && (pEntry->SupportHTMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > (-83+RssiOffset)) && (pEntry->SupportHTMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > (-86+RssiOffset)) && (pEntry->SupportHTMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+ }
+ else
+#endif /* DOT11_N_SUPPORT */
+ {/* Legacy mode */
+ if (mcs[7]>=0 && (Rssi > -70) && (pEntry->SupportOFDMMCS[MCS_7]))
+ TxRateIdx = mcs[7];
+ else if (mcs[6]>=0 && (Rssi > -74) && (pEntry->SupportOFDMMCS[MCS_7]))
+ TxRateIdx = mcs[6];
+ else if (mcs[5]>=0 && (Rssi > -78) && (pEntry->SupportOFDMMCS[MCS_7]))
+ TxRateIdx = mcs[5];
+ else if (mcs[4]>=0 && (Rssi > -82) && (pEntry->SupportOFDMMCS[MCS_7]))
+ TxRateIdx = mcs[4];
+ else if (mcs[4] == -1) /* for B-only mode */
+ {
+ if (mcs[3]>=0 && (Rssi > -85) && (pEntry->SupportCCKMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > -87) && (pEntry->SupportCCKMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > -90) && (pEntry->SupportCCKMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else if (pEntry->SupportCCKMCS[MCS_0])
+ TxRateIdx = mcs[0];
+ else
+ TxRateIdx = mcs[3];
+ }
+ else if (mcs[3]>=0 && (Rssi > -85) && (pEntry->SupportOFDMMCS[MCS_3]))
+ TxRateIdx = mcs[3];
+ else if (mcs[2]>=0 && (Rssi > -87) && (pEntry->SupportOFDMMCS[MCS_2]))
+ TxRateIdx = mcs[2];
+ else if (mcs[1]>=0 && (Rssi > -90) && (pEntry->SupportOFDMMCS[MCS_1]))
+ TxRateIdx = mcs[1];
+ else
+ TxRateIdx = mcs[0];
+ }
+
+
+ return TxRateIdx;
+}
+
+
+/* MlmeRAInit - Initialize Rate Adaptation for this entry */
+VOID MlmeRAInit(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry)
+{
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ MlmeSetMcsGroup(pAd, pEntry);
+
+ pEntry->lastRateIdx = 1;
+ pEntry->lowTrafficCount = 0;
+ pEntry->perThrdAdj = PER_THRD_ADJ;
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ pEntry->phyETxBf = pEntry->phyITxBf = FALSE;
+ pEntry->lastRatePhyTxBf = FALSE;
+ pEntry->lastNonBfRate = 0;
+#endif /* TXBF_SUPPORT */
+
+ pEntry->fLastSecAccordingRSSI = FALSE;
+ pEntry->LastSecTxRateChangeAction = RATE_NO_CHANGE;
+ pEntry->CurrTxRateIndex = 0;
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0;
+
+ MlmeClearAllTxQuality(pEntry);
+}
+
+
+/* #define TIMESTAMP_RA_LOG */ /* Include timestamp in RA Log */
+
+/*
+ MlmeRALog - Prints concise Rate Adaptation log entry
+ The BF percentage counters are also updated
+*/
+VOID MlmeRALog(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN RA_LOG_TYPE raLogType,
+ IN ULONG TxErrorRatio,
+ IN ULONG TxTotalCnt)
+{
+#ifdef TXBF_SUPPORT
+ UINT ETxCount = pEntry->TxBFCounters.ETxSuccessCount + pEntry->TxBFCounters.ETxFailCount;
+ UINT ITxCount = pEntry->TxBFCounters.ITxSuccessCount + pEntry->TxBFCounters.ITxFailCount;
+ UINT TxCount = pEntry->TxBFCounters.TxSuccessCount + pEntry->TxBFCounters.TxFailCount + ETxCount + ITxCount;
+ ULONG bfRatio = 0;
+#endif /* TXBF_SUPPORT */
+#ifdef TIMESTAMP_RA_LOG
+ ULONG newTime;
+ static ULONG saveRATime;
+ struct timeval tval;
+
+ do_gettimeofday(&tval);
+ newTime = (tval.tv_sec*1000000L + tval.tv_usec);
+#endif
+
+ if (TxTotalCnt !=0 || raLogType==RAL_QUICK_DRS
+#ifdef DBG_CTRL_SUPPORT
+ || (pAd->CommonCfg.DebugFlags & DBF_SHOW_ZERO_RA_LOG)
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ BOOLEAN stbc, csd=FALSE;
+ ULONG tp;
+
+ /* Get STBC and StreamMode state */
+ stbc = (pEntry->HTPhyMode.field.STBC && pEntry->HTPhyMode.field.MCS<8);
+
+#ifdef STREAM_MODE_SUPPORT
+ if (pEntry->StreamModeMACReg != 0)
+ {
+ ULONG streamWord;
+
+ RTMP_IO_READ32(pAd, pEntry->StreamModeMACReg+4, &streamWord);
+ if (pEntry->HTPhyMode.field.MCS < 8)
+ csd = (streamWord & 0x30000)==0x30000;
+ else if (pEntry->HTPhyMode.field.MCS < 16)
+ csd = (streamWord & 0xC0000)==0xC0000;
+ }
+#endif /* STREAM_MODE_SUPPORT */
+
+ /* Normalized throughput - packets per RA Interval */
+ if (raLogType==RAL_QUICK_DRS)
+ tp = (100-TxErrorRatio)*TxTotalCnt*RA_INTERVAL/(100*pAd->ra_fast_interval);
+ else if (pEntry->LastSecTxRateChangeAction==RATE_NO_CHANGE
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_FORCE_QUICK_DRS)==0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ tp = (100-TxErrorRatio)*TxTotalCnt/100;
+ else
+ tp = (100-TxErrorRatio)*TxTotalCnt*RA_INTERVAL/(100*(RA_INTERVAL-pAd->ra_fast_interval));
+
+#ifdef TXBF_SUPPORT
+ /* Compute BF ratio in the last interval */
+ if ((TxCount - pEntry->LastTxCount)>0)
+ {
+ if (pEntry->HTPhyMode.field.eTxBF)
+ bfRatio = 100*(ETxCount-pEntry->LastETxCount)/(TxCount - pEntry->LastTxCount);
+ else if (pEntry->HTPhyMode.field.iTxBF)
+ bfRatio = 100*(ITxCount-pEntry->LastITxCount)/(TxCount - pEntry->LastTxCount);
+ }
+
+ if ((pEntry->HTPhyMode.field.eTxBF || pEntry->HTPhyMode.field.iTxBF)
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_DBQ_RA_LOG)==0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("%s[%d]: M=%d %c%c%c%c%c PER=%ld%% TP=%ld BF=%ld%% ",
+ raLogType==RAL_QUICK_DRS? " Q": (raLogType==RAL_NEW_DRS? "\nRA": "\nra"),
+ pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ pEntry->HTPhyMode.field.MODE==MODE_CCK? 'C': (pEntry->HTPhyMode.field.ShortGI? 'S': 'L'),
+ pEntry->HTPhyMode.field.BW? '4': '2',
+ stbc? 'S': 's',
+ csd? 'C': 'c',
+ pEntry->HTPhyMode.field.eTxBF? 'E': (pEntry->HTPhyMode.field.iTxBF? 'I': '-'),
+ TxErrorRatio, tp, bfRatio) );
+ }
+ else
+#endif /* TXBF_SUPPORT */
+#ifdef DBG_CTRL_SUPPORT
+#ifdef INCLUDE_DEBUG_QUEUE
+ if (pAd->CommonCfg.DebugFlags & DBF_DBQ_RA_LOG)
+ {
+ struct {
+ USHORT phyMode;
+ USHORT per;
+ USHORT tp;
+ USHORT bfRatio;
+ } raLogInfo;
+
+ raLogInfo.phyMode = pEntry->HTPhyMode.word;
+ raLogInfo.per = TxErrorRatio;
+ raLogInfo.tp = tp;
+#ifdef TXBF_SUPPORT
+ raLogInfo.bfRatio = bfRatio;
+#endif /* TXBF_SUPPORT */
+ dbQueueEnqueue(0x7e, (UCHAR *)&raLogInfo);
+ }
+ else
+#endif /* INCLUDE_DEBUG_QUEUE */
+#endif /* DBG_CTRL_SUPPORT */
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("%s[%d]: M=%d %c%c%c%c- PER=%ld%% TP=%ld ",
+ raLogType==RAL_QUICK_DRS? " Q": (raLogType==RAL_NEW_DRS? "\nRA": "\nra"),
+ pEntry->Aid, pEntry->HTPhyMode.field.MCS,
+ pEntry->HTPhyMode.field.MODE==MODE_CCK? 'C': (pEntry->HTPhyMode.field.ShortGI? 'S': 'L'),
+ pEntry->HTPhyMode.field.BW? '4': '2',
+ stbc? 'S': 's',
+ csd? 'C': 'c',
+ TxErrorRatio, tp) );
+ }
+ }
+
+#ifdef TXBF_SUPPORT
+ /* Remember previous counts */
+ pEntry->LastETxCount = ETxCount;
+ pEntry->LastITxCount = ITxCount;
+ pEntry->LastTxCount = TxCount;
+#endif /* TXBF_SUPPORT */
+#ifdef TIMESTAMP_RA_LOG
+ saveRATime = newTime;
+#endif
+}
+
+
+/* MlmeRestoreLastRate - restore last saved rate */
+VOID MlmeRestoreLastRate(
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ pEntry->CurrTxRateIndex = pEntry->lastRateIdx;
+#ifdef TXBF_SUPPORT
+ if (pEntry->eTxBfEnCond>0)
+ pEntry->phyETxBf = pEntry->lastRatePhyTxBf;
+ else
+ pEntry->phyITxBf = pEntry->lastRatePhyTxBf;
+#endif /* TXBF_SUPPORT */
+}
+
+
+#ifdef DOT11N_SS3_SUPPORT
+/* MlmeCheckRDG - check if RDG should be enabled or disabled */
+VOID MlmeCheckRDG(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ PUCHAR pTable = pEntry->pTable;
+
+ /* Turn off RDG when 3s and rx count > tx count*5 */
+ if (((pTable == RateSwitchTable11BGN3S) ||
+ (pTable == RateSwitchTable11BGN3SForABand) ||
+ (pTable == RateSwitchTable11N3S)
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ || (pTable == RateSwitchTableAdapt11N3S)
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ ) && pAd->RalinkCounters.OneSecReceivedByteCount > 50000 &&
+ pAd->RalinkCounters.OneSecTransmittedByteCount > 50000 &&
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE))
+ {
+ TX_LINK_CFG_STRUC TxLinkCfg;
+ ULONG TxOpThres;
+ UCHAR TableStep;
+ RTMP_RA_LEGACY_TB *pTempTxRate;
+
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ TableStep = ADAPT_RATE_TABLE(pTable)? 10: 5;
+#else
+ TableStep = 5;
+#endif
+
+ pTempTxRate = (RTMP_RA_LEGACY_TB *)(&pTable[(pEntry->CurrTxRateIndex + 1)*TableStep]);
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+
+ if (pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5) &&
+ pTempTxRate->CurrMCS != 23 && pTempTxRate->ShortGI != 1)
+ {
+ 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
+ {
+ 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 */
+
+
+#ifdef TXBF_SUPPORT
+VOID txbf_rate_adjust(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry)
+{
+ RTMP_RA_LEGACY_TB *pNextTxRate;
+ UCHAR *pTable = pEntry->pTable;
+
+
+ /* Get pointer to CurrTxRate entry */
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (ADAPT_RATE_TABLE(pTable))
+ pNextTxRate = (RTMP_RA_LEGACY_TB *)PTX_RA_GRP_ENTRY(pTable, pEntry->CurrTxRateIndex);
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ pNextTxRate = PTX_RA_LEGACY_ENTRY(pTable, pEntry->CurrTxRateIndex);
+
+ /* If BF has been disabled then force a non-BF rate */
+ if (pEntry->eTxBfEnCond==0)
+ pEntry->phyETxBf = 0;
+
+ if (pEntry->iTxBfEn==0)
+ pEntry->phyITxBf = 0;
+
+
+ /* Set BF options */
+ pEntry->HTPhyMode.field.eTxBF = pEntry->phyETxBf;
+ pEntry->HTPhyMode.field.iTxBF = pEntry->phyITxBf;
+
+ /* Give ETxBF priority over ITxBF */
+ if (pEntry->HTPhyMode.field.eTxBF)
+ pEntry->HTPhyMode.field.iTxBF = 0;
+
+ /* In ITxBF mode force GI if we have no choice */
+ if (pEntry->HTPhyMode.field.iTxBF &&
+ (pEntry->OneSecRxLGICount + pEntry->OneSecRxSGICount) > 10)
+ {
+ if (pEntry->OneSecRxSGICount==0)
+ pEntry->HTPhyMode.field.ShortGI = GI_800;
+
+ if (pEntry->OneSecRxLGICount==0)
+ {
+ if ((pEntry->HTPhyMode.field.BW==BW_20 && CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)) ||
+ (pEntry->HTPhyMode.field.BW==BW_40 && CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
+ pEntry->HTPhyMode.field.ShortGI = GI_400;
+ }
+ }
+
+ /* Disable STBC if BF is enabled */
+ if (pEntry->HTPhyMode.field.eTxBF || pEntry->HTPhyMode.field.iTxBF)
+ pEntry->HTPhyMode.field.STBC = STBC_NONE;
+ }
+#endif /* TXBF_SUPPORT */
+
+
+INT rtmp_get_rate_from_rate_tb(UCHAR *table, INT idx, RTMP_TX_RATE *tx_rate)
+{
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (ADAPT_RATE_TABLE(table)) {
+ RTMP_RA_GRP_TB *rate_entry;
+
+ rate_entry = PTX_RA_GRP_ENTRY(table, idx);
+ tx_rate->mode = rate_entry->Mode;
+ tx_rate->bw = rate_entry->BW;
+ tx_rate->mcs = rate_entry->CurrMCS;
+ tx_rate->sgi = rate_entry->ShortGI;
+ tx_rate->stbc = rate_entry->STBC;
+#ifdef DOT11_VHT_AC
+ if (table == RateTableVht1S || table == RateTableVht2S)
+ tx_rate->nss = rate_entry->dataRate;
+ else
+#endif /* DOT11_VHT_AC */
+ tx_rate->nss = 0;
+ }
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ {
+ RTMP_RA_LEGACY_TB *rate_entry;
+
+ rate_entry = PTX_RA_LEGACY_ENTRY(table, idx);
+ tx_rate->mode = rate_entry->Mode;
+ tx_rate->bw = rate_entry->BW;
+ tx_rate->mcs = rate_entry->CurrMCS;
+ tx_rate->sgi = rate_entry->ShortGI;
+ tx_rate->stbc = rate_entry->STBC;
+ tx_rate->nss = 0;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ MlmeNewTxRate - called when a new TX rate was selected. Sets TX PHY to
+ rate selected by pEntry->CurrTxRateIndex in pTable;
+*/
+VOID MlmeNewTxRate(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry)
+{
+ RTMP_RA_LEGACY_TB *pNextTxRate;
+ UCHAR *pTable = pEntry->pTable;
+ RTMP_TX_RATE tx_rate;
+
+
+ rtmp_get_rate_from_rate_tb(pEntry->pTable, pEntry->CurrTxRateIndex, &tx_rate);
+ /* Get pointer to CurrTxRate entry */
+#ifdef NEW_RATE_ADAPT_SUPPORT
+ if (ADAPT_RATE_TABLE(pTable))
+ pNextTxRate = (RTMP_RA_LEGACY_TB *)PTX_RA_GRP_ENTRY(pTable, pEntry->CurrTxRateIndex);
+ else
+#endif /* NEW_RATE_ADAPT_SUPPORT */
+ pNextTxRate = PTX_RA_LEGACY_ENTRY(pTable, pEntry->CurrTxRateIndex);
+
+ /* Set new rate */
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ APMlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+#ifdef DOT11_N_SUPPORT
+ /* Disable invalid HT Duplicate modes to prevent PHY error */
+ if (pEntry->HTPhyMode.field.MCS==32)
+ {
+ if ((pEntry->HTPhyMode.field.BW!=BW_40) && (pEntry->HTPhyMode.field.BW!=BW_80))
+ pEntry->HTPhyMode.field.MCS = 0;
+ else
+ pEntry->HTPhyMode.field.STBC = 0;
+ }
+#endif /* DOT11_N_SUPPORT */
+
+#ifdef TXBF_SUPPORT
+ if (pAd->chipCap.FlgHwTxBfCap)
+ txbf_rate_adjust(pAd, pEntry);
+#endif /* TXBF_SUPPORT */
+
+ pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+
+#ifdef STREAM_MODE_SUPPORT
+ /* Enable/disable stream mode based on MCS */
+ if (pAd->CommonCfg.StreamMode!=0 &&
+ pEntry->StreamModeMACReg!=0)
+ {
+ UINT streamWord;
+ BOOLEAN mcsDisable;
+
+ /* OFDM: depends on StreamModeMCS, CCK: always applies stream-mode */
+ mcsDisable = (pEntry->HTPhyMode.field.MCS < 16) &&
+ (pAd->CommonCfg.StreamModeMCS & (1<<pEntry->HTPhyMode.field.MCS))==0 &&
+ (pEntry->HTPhyMode.field.MODE != MODE_CCK);
+
+ streamWord = mcsDisable ? 0 : StreamModeRegVal(pAd);
+
+ /* Update Stream Mode control reg */
+ RTMP_IO_WRITE32(pAd, pEntry->StreamModeMACReg+4, streamWord | (ULONG)(pEntry->Addr[4]) | (ULONG)(pEntry->Addr[5] << 8));
+ }
+#endif /* STREAM_MODE_SUPPORT */
+}
+
+
+VOID RTMPSetSupportMCS(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR OpMode,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+#ifdef DOT11_VHT_AC
+ IN UCHAR vht_cap_len,
+ IN VHT_CAP_IE *vht_cap,
+#endif /* DOT11_VHT_AC */
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen)
+{
+ UCHAR idx, SupportedRatesLen = 0;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+
+ if (SupRateLen > 0)
+ {
+ if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(SupportedRates, SupRate, SupRateLen);
+ SupportedRatesLen = SupRateLen;
+ }
+ else
+ {
+ UCHAR RateDefault[8] = {0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c};
+
+ NdisMoveMemory(SupportedRates, RateDefault, 8);
+ SupportedRatesLen = 8;
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s():wrong SUPP RATES., Len=%d\n",
+ __FUNCTION__, SupRateLen));
+ }
+ }
+
+ if (ExtRateLen > 0)
+ {
+ if ((SupRateLen + ExtRateLen) <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(&SupportedRates[SupRateLen], ExtRate, ExtRateLen);
+ SupportedRatesLen += ExtRateLen;
+ }
+ else
+ {
+ NdisMoveMemory(&SupportedRates[SupRateLen], ExtRate, MAX_LEN_OF_SUPPORTED_RATES - ExtRateLen);
+ SupportedRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+
+ }
+ }
+
+ /* Clear Supported MCS Table */
+ NdisZeroMemory(pEntry->SupportCCKMCS, MAX_LEN_OF_CCK_RATES);
+ NdisZeroMemory(pEntry->SupportOFDMMCS, MAX_LEN_OF_OFDM_RATES);
+ NdisZeroMemory(pEntry->SupportHTMCS, MAX_LEN_OF_HT_RATES);
+#ifdef DOT11_VHT_AC
+ NdisZeroMemory(pEntry->SupportVHTMCS, MAX_LEN_OF_VHT_RATES);
+#endif /* DOT11_VHT_AC */
+
+ pEntry->SupportRateMode = 0;
+
+ for(idx = 0; idx < SupportedRatesLen; idx ++)
+ {
+ switch((SupportedRates[idx] & 0x7F)*5)
+ {
+ case 10:
+ pEntry->SupportCCKMCS[MCS_0] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_CCK_MODE;
+ break;
+
+ case 20:
+ pEntry->SupportCCKMCS[MCS_1] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_CCK_MODE;
+ break;
+
+ case 55:
+ pEntry->SupportCCKMCS[MCS_2] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_CCK_MODE;
+ break;
+
+ case 110:
+ pEntry->SupportCCKMCS[MCS_3] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_CCK_MODE;
+ break;
+
+ case 60:
+ pEntry->SupportOFDMMCS[MCS_0] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+
+ case 90:
+ pEntry->SupportOFDMMCS[MCS_1] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+
+ case 120:
+ pEntry->SupportOFDMMCS[MCS_2] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+
+ case 180:
+ pEntry->SupportOFDMMCS[MCS_3] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+
+ case 240:
+ pEntry->SupportOFDMMCS[MCS_4] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+
+ case 360:
+ pEntry->SupportOFDMMCS[MCS_5] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+
+ case 480:
+ pEntry->SupportOFDMMCS[MCS_6] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+
+ case 540:
+ pEntry->SupportOFDMMCS[MCS_7] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_OFDM_MODE;
+ break;
+ }
+ }
+
+ if (HtCapabilityLen)
+ {
+ RT_PHY_INFO *pDesired_ht_phy = NULL;
+ UCHAR j, bitmask;
+ CHAR i;
+
+
+#ifdef CONFIG_AP_SUPPORT
+ if (OpMode == OPMODE_AP)
+ {
+#ifdef WDS_SUPPORT
+ if (IS_ENTRY_WDS(pEntry))
+ pDesired_ht_phy = &pAd->WdsTab.WdsEntry[pEntry->apidx].DesiredHtPhyInfo;
+ else
+#endif /* WDS_SUPPORT */
+#ifdef APCLI_SUPPORT
+ if (IS_ENTRY_APCLI(pEntry))
+ pDesired_ht_phy = &pAd->ApCfg.ApCliTab[pEntry->apidx].DesiredHtPhyInfo;
+ else
+#endif /* APCLI_SUPPORT */
+ pDesired_ht_phy = &pAd->ApCfg.MBSSID[pEntry->apidx].DesiredHtPhyInfo;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+
+ if (pDesired_ht_phy == NULL)
+ return;
+
+ for (i = 23; i >= 0; i--)
+ {
+ j = i / 8;
+ bitmask = (1 << (i - (j * 8)));
+
+ if ((pDesired_ht_phy->MCSSet[j] & bitmask)
+ && (pHtCapability->MCSSet[j] & bitmask))
+ {
+ pEntry->SupportHTMCS[i] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_HT_MODE;
+ }
+ }
+
+#ifdef DOT11_VHT_AC
+ if ((vht_cap_len > 0)&& (vht_cap != NULL) && pDesired_ht_phy->vht_bw == VHT_BW_80)
+ {
+ /* Currently we only support for MCS0~MCS7, so don't check mcs_map */
+ NdisZeroMemory(&pEntry->SupportVHTMCS[0], sizeof(pEntry->SupportVHTMCS));
+ switch (pAd->CommonCfg.TxStream)
+ {
+ case 2:
+ if (vht_cap->mcs_set.rx_mcs_map.mcs_ss2 < VHT_MCS_CAP_NA)
+ {
+ for (i = 8; i < MAX_LEN_OF_VHT_RATES; i++)
+ pEntry->SupportVHTMCS[i] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_VHT_MODE;
+ }
+ case 1:
+ if (vht_cap->mcs_set.rx_mcs_map.mcs_ss1 < VHT_MCS_CAP_NA)
+ {
+ for (i = 0; i <= 7; i++)
+ pEntry->SupportVHTMCS[i] = TRUE;
+ pEntry->SupportRateMode |= SUPPORT_VHT_MODE;
+ }
+ default:
+ break;
+ }
+ }
+#endif /* DOT11_VHT_AC */
+ }
+}
+
+INT Set_RateAlg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTRING arg)
+{
+ UINT32 ra_alg;
+
+ ra_alg = simple_strtol(arg, 0, 10);
+
+ if ((ra_alg < RATE_ALG_MAX_NUM) && (ra_alg != pAd->rateAlg))
+ {
+ UINT32 IdEntry;
+
+ pAd->rateAlg = ra_alg;
+ for(IdEntry = 0; IdEntry < MAX_LEN_OF_MAC_TABLE; IdEntry++)
+ pAd->MacTab.Content[IdEntry].rateAlg = ra_alg;
+ }
+
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Set Alg = %d\n", __FUNCTION__, ra_alg));
+ return TRUE;
+}
+
+
diff --git a/cleopatre/devkit/mt7601udrv/tools/Makefile b/cleopatre/devkit/mt7601udrv/tools/Makefile
new file mode 100644
index 0000000000..ce4a422f8e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/tools/Makefile
@@ -0,0 +1,6 @@
+all:
+ gcc -g bin2h.c -o bin2h
+clean:
+ rm -f *.o bin2h
+
+
diff --git a/cleopatre/devkit/mt7601udrv/tools/bin2h.c b/cleopatre/devkit/mt7601udrv/tools/bin2h.c
new file mode 100644
index 0000000000..0bc8df2a1d
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/tools/bin2h.c
@@ -0,0 +1,175 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main(int argc ,char *argv[])
+{
+ FILE *infile, *outfile;
+ char infname[1024];
+ char outfname[1024];
+ char fw_name[128];
+ char *rt28xxdir;
+ char *chipset;
+ char *wow, *rt28xx_mode; /* for WOW firmware */
+ int i=0;//,n=0;
+ unsigned char c;
+
+ memset(infname,0,1024);
+ memset(outfname,0,1024);
+ memset(fw_name, 0, 128);
+
+ rt28xxdir = (char *)getenv("RT28xx_DIR");
+ chipset = (char *)getenv("CHIPSET");
+ wow = (char *)getenv("HAS_WOW_SUPPORT"); /* for WOW firmware */
+ rt28xx_mode = (char *)getenv("RT28xx_MODE");
+
+ 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);
+ strcat(outfname,rt28xxdir);
+
+ if (strncmp(chipset, "2860",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2860.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "2870",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "3090",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2860.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "2070",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "3070",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "3572",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "3573",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "3370",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "5370",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "5572",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "5592",4) == 0) {
+ strcat(infname,"/mcu/bin/rt2860.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "USB",3) == 0) {
+ strcat(infname,"/mcu/bin/rt2870.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if (strncmp(chipset, "PCI",3) == 0) {
+ strcat(infname,"/mcu/bin/rt2860.bin");
+ strcat(outfname,"/include/mcu/firmware.h");
+ strcat(fw_name, "FirmwareImage");
+ } else if ((strncmp(chipset, "6590", 4) == 0)
+ || (strncmp(chipset, "6570", 4) == 0)) {
+ strcat(infname,"/mcu/bin/MT7650.bin");
+ strcat(outfname,"/include/mcu/MT7650_firmware.h");
+ strcat(fw_name, "MT7650_FirmwareImage");
+ } else if ((strncmp(chipset, "MT7662E", 7) == 0)
+ || (strncmp(chipset, "MT7662U", 7) == 0)) {
+ strcat(infname,"/mcu/bin/MT7662.bin");
+ strcat(outfname,"/include/mcu/MT7662_firmware.h");
+ strcat(fw_name, "MT7662_FirmwareImage");
+ } else if(strncmp(chipset, "7601",4)==0) {
+ strcat(infname,"/mcu/bin/MT7601.bin");
+ strcat(outfname,"/include/mcu/MT7601_firmware.h");
+ strcat(fw_name, "MT7601_FirmwareImage");
+ } else {
+ strcat(infname,"/mcu/bin/rt2860.bin");
+ strcat(outfname,"/include/firmware.h");
+ }
+
+ /* for WOW support firmware */
+ if ((wow != NULL) && (strncmp(wow, "y", 1) == 0) && (strncmp(rt28xx_mode, "STA", 3) == 0))
+ {
+ if ((wow = strstr(infname, "rt2870")) != NULL)
+ {
+ strcpy(wow, "rt2870_wow.bin");
+ fprintf(stderr, "infname %s\n", infname);
+ }
+ }
+
+ 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);
+
+ fprintf(outfile, "UCHAR %s[] = {\n", fw_name);
+
+ 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);
+}
diff --git a/cleopatre/devkit/mt7601udrv/unload b/cleopatre/devkit/mt7601udrv/unload
new file mode 100644
index 0000000000..69afc1d219
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/unload
@@ -0,0 +1,2 @@
+ifconfig ra0 down
+rmmod mt7601Uap