From 8c1eb022607c0aba81d93b961abbfb47a2dcc325 Mon Sep 17 00:00:00 2001 From: Fisher Cheng Date: Fri, 24 May 2013 16:54:08 +0800 Subject: cleo/devkit: add MTK MT7601U drv source code, refs #4011 - Enable Wireless LAN and Wireless extension in linux26.config --- cleopatre/devkit/mt7601udrv/.gitignore | 9 + cleopatre/devkit/mt7601udrv/Makefile | 547 + cleopatre/devkit/mt7601udrv/RT2870AP.dat | 119 + cleopatre/devkit/mt7601udrv/RT2870APCard.dat | 19 + cleopatre/devkit/mt7601udrv/ap/ap.c | 2485 ++++ cleopatre/devkit/mt7601udrv/ap/ap_apcli.c | 2230 ++++ cleopatre/devkit/mt7601udrv/ap/ap_apcli_inf.c | 266 + cleopatre/devkit/mt7601udrv/ap/ap_assoc.c | 1637 +++ cleopatre/devkit/mt7601udrv/ap/ap_auth.c | 627 + cleopatre/devkit/mt7601udrv/ap/ap_autoChSel.c | 1091 ++ cleopatre/devkit/mt7601udrv/ap/ap_cfg.c | 12072 +++++++++++++++++++ cleopatre/devkit/mt7601udrv/ap/ap_connect.c | 1044 ++ cleopatre/devkit/mt7601udrv/ap/ap_data.c | 6452 ++++++++++ cleopatre/devkit/mt7601udrv/ap/ap_dls.c | 345 + cleopatre/devkit/mt7601udrv/ap/ap_ftkd.c | 80 + cleopatre/devkit/mt7601udrv/ap/ap_ids.c | 459 + cleopatre/devkit/mt7601udrv/ap/ap_mbss.c | 378 + cleopatre/devkit/mt7601udrv/ap/ap_mbss_inf.c | 273 + cleopatre/devkit/mt7601udrv/ap/ap_mlme.c | 592 + cleopatre/devkit/mt7601udrv/ap/ap_qload.c | 916 ++ cleopatre/devkit/mt7601udrv/ap/ap_sanity.c | 477 + cleopatre/devkit/mt7601udrv/ap/ap_sync.c | 1422 +++ cleopatre/devkit/mt7601udrv/ap/ap_wds.c | 1359 +++ cleopatre/devkit/mt7601udrv/ap/ap_wds_inf.c | 156 + cleopatre/devkit/mt7601udrv/ap/ap_wpa.c | 1614 +++ cleopatre/devkit/mt7601udrv/ap/apcli_assoc.c | 806 ++ cleopatre/devkit/mt7601udrv/ap/apcli_auth.c | 570 + cleopatre/devkit/mt7601udrv/ap/apcli_ctrl.c | 875 ++ cleopatre/devkit/mt7601udrv/ap/apcli_sync.c | 576 + cleopatre/devkit/mt7601udrv/ate/chips/mt7601_ate.c | 921 ++ cleopatre/devkit/mt7601udrv/ate/common/ate_usb.c | 627 + cleopatre/devkit/mt7601udrv/ate/common/rt_ate.c | 6298 ++++++++++ cleopatre/devkit/mt7601udrv/ate/common/rt_qa.c | 2497 ++++ cleopatre/devkit/mt7601udrv/ate/include/rt_ate.h | 808 ++ cleopatre/devkit/mt7601udrv/ate/include/rt_qa.h | 181 + cleopatre/devkit/mt7601udrv/chips/mt7601.c | 3382 ++++++ cleopatre/devkit/mt7601udrv/chips/rtmp_chip.c | 1041 ++ cleopatre/devkit/mt7601udrv/common/action.c | 1126 ++ cleopatre/devkit/mt7601udrv/common/ba_action.c | 2190 ++++ cleopatre/devkit/mt7601udrv/common/client_wds.c | 197 + cleopatre/devkit/mt7601udrv/common/cmm_aes.c | 1142 ++ cleopatre/devkit/mt7601udrv/common/cmm_asic.c | 2699 +++++ cleopatre/devkit/mt7601udrv/common/cmm_cfg.c | 1494 +++ cleopatre/devkit/mt7601udrv/common/cmm_cmd.c | 169 + cleopatre/devkit/mt7601udrv/common/cmm_cs.c | 763 ++ cleopatre/devkit/mt7601udrv/common/cmm_data.c | 3569 ++++++ cleopatre/devkit/mt7601udrv/common/cmm_data_usb.c | 1312 ++ cleopatre/devkit/mt7601udrv/common/cmm_dfs.c | 3136 +++++ cleopatre/devkit/mt7601udrv/common/cmm_info.c | 6151 ++++++++++ cleopatre/devkit/mt7601udrv/common/cmm_mac_usb.c | 2159 ++++ cleopatre/devkit/mt7601udrv/common/cmm_mat.c | 443 + cleopatre/devkit/mt7601udrv/common/cmm_mat_iparp.c | 694 ++ cleopatre/devkit/mt7601udrv/common/cmm_mat_ipv6.c | 824 ++ cleopatre/devkit/mt7601udrv/common/cmm_mat_pppoe.c | 1062 ++ cleopatre/devkit/mt7601udrv/common/cmm_profile.c | 5059 ++++++++ cleopatre/devkit/mt7601udrv/common/cmm_radar.c | 329 + cleopatre/devkit/mt7601udrv/common/cmm_sanity.c | 2162 ++++ cleopatre/devkit/mt7601udrv/common/cmm_sync.c | 494 + cleopatre/devkit/mt7601udrv/common/cmm_tkip.c | 923 ++ cleopatre/devkit/mt7601udrv/common/cmm_video.c | 168 + cleopatre/devkit/mt7601udrv/common/cmm_wep.c | 365 + cleopatre/devkit/mt7601udrv/common/cmm_wpa.c | 4728 ++++++++ cleopatre/devkit/mt7601udrv/common/crypt_aes.c | 1605 +++ cleopatre/devkit/mt7601udrv/common/crypt_arc4.c | 139 + .../devkit/mt7601udrv/common/crypt_biginteger.c | 1116 ++ cleopatre/devkit/mt7601udrv/common/crypt_dh.c | 227 + cleopatre/devkit/mt7601udrv/common/crypt_hmac.c | 282 + cleopatre/devkit/mt7601udrv/common/crypt_md5.c | 356 + cleopatre/devkit/mt7601udrv/common/crypt_sha2.c | 555 + cleopatre/devkit/mt7601udrv/common/ee_efuse.c | 1893 +++ cleopatre/devkit/mt7601udrv/common/ee_prom.c | 265 + cleopatre/devkit/mt7601udrv/common/eeprom.c | 85 + cleopatre/devkit/mt7601udrv/common/frq_cal.c | 28 + cleopatre/devkit/mt7601udrv/common/igmp_snoop.c | 1511 +++ cleopatre/devkit/mt7601udrv/common/image.bin | Bin 0 -> 67936 bytes cleopatre/devkit/mt7601udrv/common/misc.c | 35 + cleopatre/devkit/mt7601udrv/common/mlme.c | 4000 ++++++ cleopatre/devkit/mt7601udrv/common/multi_channel.c | 1012 ++ cleopatre/devkit/mt7601udrv/common/netif_block.c | 121 + cleopatre/devkit/mt7601udrv/common/ps.c | 370 + cleopatre/devkit/mt7601udrv/common/rt2860.bin.dfs | Bin 0 -> 8192 bytes cleopatre/devkit/mt7601udrv/common/rt2860.bin.old | Bin 0 -> 8192 bytes cleopatre/devkit/mt7601udrv/common/rt2870_wow.bin | Bin 0 -> 12288 bytes cleopatre/devkit/mt7601udrv/common/rt_channel.c | 2057 ++++ cleopatre/devkit/mt7601udrv/common/rt_os_util.c | 161 + cleopatre/devkit/mt7601udrv/common/rt_rf.c | 33 + cleopatre/devkit/mt7601udrv/common/rtmp_init.c | 3849 ++++++ cleopatre/devkit/mt7601udrv/common/rtmp_init_inf.c | 1094 ++ cleopatre/devkit/mt7601udrv/common/rtmp_timer.c | 358 + cleopatre/devkit/mt7601udrv/common/rtusb_bulk.c | 1693 +++ cleopatre/devkit/mt7601udrv/common/rtusb_data.c | 31 + cleopatre/devkit/mt7601udrv/common/rtusb_dev_id.c | 48 + cleopatre/devkit/mt7601udrv/common/rtusb_io.c | 2021 ++++ cleopatre/devkit/mt7601udrv/common/scan.c | 415 + cleopatre/devkit/mt7601udrv/common/spectrum.c | 2393 ++++ cleopatre/devkit/mt7601udrv/common/txpower.c | 1172 ++ cleopatre/devkit/mt7601udrv/common/uapsd.c | 2074 ++++ cleopatre/devkit/mt7601udrv/common/vht.c | 400 + cleopatre/devkit/mt7601udrv/common/wapi.c | 1185 ++ cleopatre/devkit/mt7601udrv/common/wfd.c | 823 ++ cleopatre/devkit/mt7601udrv/common/wsc.c | 9058 ++++++++++++++ cleopatre/devkit/mt7601udrv/common/wsc_tlv.c | 4002 ++++++ cleopatre/devkit/mt7601udrv/common/wsc_ufd.c | 598 + cleopatre/devkit/mt7601udrv/common/wsc_v2.c | 408 + cleopatre/devkit/mt7601udrv/include/action.h | 54 + cleopatre/devkit/mt7601udrv/include/ags.h | 102 + cleopatre/devkit/mt7601udrv/include/ap.h | 454 + cleopatre/devkit/mt7601udrv/include/ap_apcli.h | 275 + cleopatre/devkit/mt7601udrv/include/ap_autoChSel.h | 76 + .../devkit/mt7601udrv/include/ap_autoChSel_cmm.h | 61 + cleopatre/devkit/mt7601udrv/include/ap_cfg.h | 167 + cleopatre/devkit/mt7601udrv/include/ap_diversity.h | 142 + cleopatre/devkit/mt7601udrv/include/ap_ids.h | 76 + cleopatre/devkit/mt7601udrv/include/ap_mbss.h | 86 + cleopatre/devkit/mt7601udrv/include/ap_wds.h | 220 + cleopatre/devkit/mt7601udrv/include/br_ftph.h | 81 + cleopatre/devkit/mt7601udrv/include/cfg80211.h | 78 + cleopatre/devkit/mt7601udrv/include/cfg80211extr.h | 201 + cleopatre/devkit/mt7601udrv/include/chip/chip_id.h | 73 + cleopatre/devkit/mt7601udrv/include/chip/mt7601.h | 268 + cleopatre/devkit/mt7601udrv/include/chip/rt28xx.h | 39 + cleopatre/devkit/mt7601udrv/include/chip/rt3290.h | 114 + cleopatre/devkit/mt7601udrv/include/chip/rt6590.h | 137 + .../devkit/mt7601udrv/include/chip/rtmp_phy.h | 693 ++ cleopatre/devkit/mt7601udrv/include/chlist.h | 150 + cleopatre/devkit/mt7601udrv/include/client_wds.h | 59 + .../devkit/mt7601udrv/include/client_wds_cmm.h | 46 + cleopatre/devkit/mt7601udrv/include/crypt_aes.h | 176 + cleopatre/devkit/mt7601udrv/include/crypt_arc4.h | 57 + .../devkit/mt7601udrv/include/crypt_biginteger.h | 134 + cleopatre/devkit/mt7601udrv/include/crypt_dh.h | 65 + cleopatre/devkit/mt7601udrv/include/crypt_hmac.h | 68 + cleopatre/devkit/mt7601udrv/include/crypt_md5.h | 63 + cleopatre/devkit/mt7601udrv/include/crypt_sha2.h | 92 + cleopatre/devkit/mt7601udrv/include/cs.h | 172 + cleopatre/devkit/mt7601udrv/include/dfs.h | 571 + cleopatre/devkit/mt7601udrv/include/dot11ac_vht.h | 479 + cleopatre/devkit/mt7601udrv/include/dot11i_wpa.h | 291 + cleopatre/devkit/mt7601udrv/include/drs_extr.h | 326 + cleopatre/devkit/mt7601udrv/include/eeprom.h | 321 + cleopatre/devkit/mt7601udrv/include/firmware.h | 2396 ++++ cleopatre/devkit/mt7601udrv/include/frq_cal.h | 107 + .../devkit/mt7601udrv/include/iface/iface_util.h | 69 + .../mt7601udrv/include/iface/rtmp_reg_pcirbs.h | 384 + .../devkit/mt7601udrv/include/iface/rtmp_usb.h | 89 + cleopatre/devkit/mt7601udrv/include/igmp_snoop.h | 155 + cleopatre/devkit/mt7601udrv/include/ipv6.h | 205 + cleopatre/devkit/mt7601udrv/include/link_list.h | 182 + cleopatre/devkit/mt7601udrv/include/mac_ral/fce.h | 70 + .../devkit/mt7601udrv/include/mac_ral/mac_pci.h | 405 + .../devkit/mt7601udrv/include/mac_ral/mac_usb.h | 490 + .../mt7601udrv/include/mac_ral/nmac/ral_nmac.h | 782 ++ .../mt7601udrv/include/mac_ral/nmac/ral_nmac_pbf.h | 139 + .../mt7601udrv/include/mac_ral/nmac/ral_nmac_pci.h | 368 + .../include/mac_ral/nmac/ral_nmac_rxwi.h | 117 + .../include/mac_ral/nmac/ral_nmac_txwi.h | 249 + .../mt7601udrv/include/mac_ral/nmac/ral_nmac_usb.h | 144 + .../mt7601udrv/include/mac_ral/omac/ral_omac.h | 168 + .../mt7601udrv/include/mac_ral/omac/ral_omac_pbf.h | 104 + .../mt7601udrv/include/mac_ral/omac/ral_omac_pci.h | 270 + .../include/mac_ral/omac/ral_omac_rf_ctrl.h | 92 + .../include/mac_ral/omac/ral_omac_rxwi.h | 147 + .../include/mac_ral/omac/ral_omac_txwi.h | 143 + .../mt7601udrv/include/mac_ral/omac/ral_omac_usb.h | 70 + cleopatre/devkit/mt7601udrv/include/mac_ral/pbf.h | 93 + .../devkit/mt7601udrv/include/mac_ral/rf_ctrl.h | 146 + .../devkit/mt7601udrv/include/mac_ral/rtmp_mac.h | 2379 ++++ cleopatre/devkit/mt7601udrv/include/mat.h | 208 + .../mt7601udrv/include/mcu/MT7601_firmware.h | 2844 +++++ cleopatre/devkit/mt7601udrv/include/misc.h | 32 + cleopatre/devkit/mt7601udrv/include/misc_cmm.h | 32 + cleopatre/devkit/mt7601udrv/include/mlme.h | 1515 +++ cleopatre/devkit/mt7601udrv/include/mlme_sys.h | 9 + cleopatre/devkit/mt7601udrv/include/netif_block.h | 31 + cleopatre/devkit/mt7601udrv/include/oid.h | 1320 ++ cleopatre/devkit/mt7601udrv/include/os/rt_drv.h | 1061 ++ cleopatre/devkit/mt7601udrv/include/os/rt_linux.h | 1575 +++ .../devkit/mt7601udrv/include/os/rt_linux_cmm.h | 412 + cleopatre/devkit/mt7601udrv/include/os/rt_os.h | 83 + cleopatre/devkit/mt7601udrv/include/phy/rlt_phy.h | 275 + cleopatre/devkit/mt7601udrv/include/radar.h | 89 + cleopatre/devkit/mt7601udrv/include/rt_config.h | 211 + cleopatre/devkit/mt7601udrv/include/rt_os_net.h | 583 + cleopatre/devkit/mt7601udrv/include/rt_os_util.h | 1003 ++ cleopatre/devkit/mt7601udrv/include/rt_txbf.h | 215 + cleopatre/devkit/mt7601udrv/include/rtmp.h | 9018 ++++++++++++++ cleopatre/devkit/mt7601udrv/include/rtmp_M51.h | 53 + cleopatre/devkit/mt7601udrv/include/rtmp_and.h | 137 + cleopatre/devkit/mt7601udrv/include/rtmp_chip.h | 1095 ++ cleopatre/devkit/mt7601udrv/include/rtmp_cmd.h | 683 ++ cleopatre/devkit/mt7601udrv/include/rtmp_comm.h | 502 + cleopatre/devkit/mt7601udrv/include/rtmp_def.h | 1948 +++ cleopatre/devkit/mt7601udrv/include/rtmp_dot11.h | 98 + cleopatre/devkit/mt7601udrv/include/rtmp_iface.h | 57 + cleopatre/devkit/mt7601udrv/include/rtmp_mcu.h | 90 + cleopatre/devkit/mt7601udrv/include/rtmp_os.h | 135 + cleopatre/devkit/mt7601udrv/include/rtmp_osabl.h | 65 + cleopatre/devkit/mt7601udrv/include/rtmp_timer.h | 182 + cleopatre/devkit/mt7601udrv/include/rtmp_type.h | 192 + cleopatre/devkit/mt7601udrv/include/rtusb_io.h | 195 + cleopatre/devkit/mt7601udrv/include/spectrum.h | 215 + cleopatre/devkit/mt7601udrv/include/spectrum_def.h | 249 + cleopatre/devkit/mt7601udrv/include/sta_cfg.h | 72 + cleopatre/devkit/mt7601udrv/include/uapsd.h | 725 ++ cleopatre/devkit/mt7601udrv/include/vht.h | 28 + cleopatre/devkit/mt7601udrv/include/video.h | 12 + cleopatre/devkit/mt7601udrv/include/vr_ikans.h | 59 + cleopatre/devkit/mt7601udrv/include/vrut_ubm.h | 42 + cleopatre/devkit/mt7601udrv/include/wapi.h | 183 + cleopatre/devkit/mt7601udrv/include/wapi_def.h | 179 + cleopatre/devkit/mt7601udrv/include/wapi_sms4.h | 12 + cleopatre/devkit/mt7601udrv/include/wfd.h | 149 + cleopatre/devkit/mt7601udrv/include/wfd_cmm.h | 293 + cleopatre/devkit/mt7601udrv/include/wpa.h | 506 + cleopatre/devkit/mt7601udrv/include/wpa_cmm.h | 211 + cleopatre/devkit/mt7601udrv/include/wsc.h | 820 ++ cleopatre/devkit/mt7601udrv/include/wsc_tlv.h | 280 + cleopatre/devkit/mt7601udrv/load | 3 + cleopatre/devkit/mt7601udrv/mac/ral_nmac.c | 31 + cleopatre/devkit/mt7601udrv/mac/ral_omac.c | 67 + cleopatre/devkit/mt7601udrv/mac/rtmp_mac.c | 607 + cleopatre/devkit/mt7601udrv/mcu/bin/MT7601.bin | Bin 0 -> 45412 bytes .../mt7601udrv/mcu/bin/MT7601_formal_1.5.bin | Bin 0 -> 45412 bytes .../mt7601udrv/mcu/bin/MT7601_formal_1.5_Debug.bin | Bin 0 -> 49784 bytes cleopatre/devkit/mt7601udrv/mcu/rtmp_M51.c | 710 ++ cleopatre/devkit/mt7601udrv/mcu/rtmp_and.c | 2071 ++++ cleopatre/devkit/mt7601udrv/mcu/rtmp_mcu.c | 77 + cleopatre/devkit/mt7601udrv/mgmt/mgmt_dev.c | 58 + cleopatre/devkit/mt7601udrv/mgmt/mgmt_entrytb.c | 729 ++ cleopatre/devkit/mt7601udrv/mgmt/mgmt_ht.c | 747 ++ cleopatre/devkit/mt7601udrv/mgmt/mgmt_hw.c | 37 + cleopatre/devkit/mt7601udrv/mgmt/mgmt_vht.c | 39 + .../devkit/mt7601udrv/os/linux/Kconfig.ap.soc | 159 + .../devkit/mt7601udrv/os/linux/Kconfig.ap.usb | 111 + .../devkit/mt7601udrv/os/linux/Kconfig.sta.soc | 89 + cleopatre/devkit/mt7601udrv/os/linux/Makefile.4 | 291 + .../devkit/mt7601udrv/os/linux/Makefile.4.netif | 103 + .../devkit/mt7601udrv/os/linux/Makefile.4.util | 82 + cleopatre/devkit/mt7601udrv/os/linux/Makefile.6 | 652 + .../devkit/mt7601udrv/os/linux/Makefile.6.netif | 99 + .../devkit/mt7601udrv/os/linux/Makefile.6.util | 72 + .../devkit/mt7601udrv/os/linux/Makefile.ap.soc | 394 + .../devkit/mt7601udrv/os/linux/Makefile.ap.usb | 334 + .../devkit/mt7601udrv/os/linux/Makefile.clean | 58 + .../os/linux/Makefile.libautoprovision.6 | 9 + .../devkit/mt7601udrv/os/linux/Makefile.libwapi.4 | 23 + .../devkit/mt7601udrv/os/linux/Makefile.libwapi.6 | 11 + .../devkit/mt7601udrv/os/linux/Makefile.sta.soc | 275 + cleopatre/devkit/mt7601udrv/os/linux/ap_ioctl.c | 441 + cleopatre/devkit/mt7601udrv/os/linux/br_ftph.c | 195 + cleopatre/devkit/mt7601udrv/os/linux/cfg80211.c | 1576 +++ cleopatre/devkit/mt7601udrv/os/linux/cfg80211drv.c | 1675 +++ cleopatre/devkit/mt7601udrv/os/linux/config.mk | 1125 ++ cleopatre/devkit/mt7601udrv/os/linux/config.mk.bak | 1637 +++ cleopatre/devkit/mt7601udrv/os/linux/inf_ppa.c | 62 + cleopatre/devkit/mt7601udrv/os/linux/load | 6 + cleopatre/devkit/mt7601udrv/os/linux/rt_linux.c | 5258 ++++++++ .../devkit/mt7601udrv/os/linux/rt_linux_symb.c | 287 + cleopatre/devkit/mt7601udrv/os/linux/rt_main_dev.c | 840 ++ cleopatre/devkit/mt7601udrv/os/linux/rt_proc.c | 539 + cleopatre/devkit/mt7601udrv/os/linux/rt_profile.c | 857 ++ .../devkit/mt7601udrv/os/linux/rt_rbus_pci_drv.c | 16 + cleopatre/devkit/mt7601udrv/os/linux/rt_symb.c | 9 + cleopatre/devkit/mt7601udrv/os/linux/rt_usb.c | 1314 ++ cleopatre/devkit/mt7601udrv/os/linux/rt_usb_util.c | 603 + cleopatre/devkit/mt7601udrv/os/linux/unload | 2 + .../devkit/mt7601udrv/os/linux/usb_main_dev.c | 846 ++ cleopatre/devkit/mt7601udrv/os/linux/vr_bdlt.c | 63 + cleopatre/devkit/mt7601udrv/os/linux/vr_ikans.c | 363 + cleopatre/devkit/mt7601udrv/phy/rlt_phy.c | 436 + cleopatre/devkit/mt7601udrv/phy/rlt_rf.c | 182 + cleopatre/devkit/mt7601udrv/phy/rtmp_phy.c | 629 + cleopatre/devkit/mt7601udrv/rate_ctrl/alg_ags.c | 1181 ++ cleopatre/devkit/mt7601udrv/rate_ctrl/alg_grp.c | 1661 +++ cleopatre/devkit/mt7601udrv/rate_ctrl/alg_legacy.c | 907 ++ cleopatre/devkit/mt7601udrv/rate_ctrl/ra_ctrl.c | 1977 +++ cleopatre/devkit/mt7601udrv/tools/Makefile | 6 + cleopatre/devkit/mt7601udrv/tools/bin2h.c | 175 + cleopatre/devkit/mt7601udrv/unload | 2 + 279 files changed, 225303 insertions(+) create mode 100644 cleopatre/devkit/mt7601udrv/.gitignore create mode 100644 cleopatre/devkit/mt7601udrv/Makefile create mode 100644 cleopatre/devkit/mt7601udrv/RT2870AP.dat create mode 100644 cleopatre/devkit/mt7601udrv/RT2870APCard.dat create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_apcli.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_apcli_inf.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_assoc.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_auth.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_autoChSel.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_cfg.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_connect.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_data.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_dls.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_ftkd.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_ids.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_mbss.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_mbss_inf.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_mlme.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_qload.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_sanity.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_sync.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_wds.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_wds_inf.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/ap_wpa.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/apcli_assoc.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/apcli_auth.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/apcli_ctrl.c create mode 100644 cleopatre/devkit/mt7601udrv/ap/apcli_sync.c create mode 100644 cleopatre/devkit/mt7601udrv/ate/chips/mt7601_ate.c create mode 100644 cleopatre/devkit/mt7601udrv/ate/common/ate_usb.c create mode 100644 cleopatre/devkit/mt7601udrv/ate/common/rt_ate.c create mode 100644 cleopatre/devkit/mt7601udrv/ate/common/rt_qa.c create mode 100644 cleopatre/devkit/mt7601udrv/ate/include/rt_ate.h create mode 100644 cleopatre/devkit/mt7601udrv/ate/include/rt_qa.h create mode 100644 cleopatre/devkit/mt7601udrv/chips/mt7601.c create mode 100644 cleopatre/devkit/mt7601udrv/chips/rtmp_chip.c create mode 100644 cleopatre/devkit/mt7601udrv/common/action.c create mode 100644 cleopatre/devkit/mt7601udrv/common/ba_action.c create mode 100644 cleopatre/devkit/mt7601udrv/common/client_wds.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_aes.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_asic.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_cfg.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_cmd.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_cs.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_data.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_data_usb.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_dfs.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_info.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_mac_usb.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_mat.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_mat_iparp.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_mat_ipv6.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_mat_pppoe.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_profile.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_radar.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_sanity.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_sync.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_tkip.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_video.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_wep.c create mode 100644 cleopatre/devkit/mt7601udrv/common/cmm_wpa.c create mode 100644 cleopatre/devkit/mt7601udrv/common/crypt_aes.c create mode 100644 cleopatre/devkit/mt7601udrv/common/crypt_arc4.c create mode 100644 cleopatre/devkit/mt7601udrv/common/crypt_biginteger.c create mode 100644 cleopatre/devkit/mt7601udrv/common/crypt_dh.c create mode 100644 cleopatre/devkit/mt7601udrv/common/crypt_hmac.c create mode 100644 cleopatre/devkit/mt7601udrv/common/crypt_md5.c create mode 100644 cleopatre/devkit/mt7601udrv/common/crypt_sha2.c create mode 100644 cleopatre/devkit/mt7601udrv/common/ee_efuse.c create mode 100644 cleopatre/devkit/mt7601udrv/common/ee_prom.c create mode 100644 cleopatre/devkit/mt7601udrv/common/eeprom.c create mode 100644 cleopatre/devkit/mt7601udrv/common/frq_cal.c create mode 100644 cleopatre/devkit/mt7601udrv/common/igmp_snoop.c create mode 100644 cleopatre/devkit/mt7601udrv/common/image.bin create mode 100644 cleopatre/devkit/mt7601udrv/common/misc.c create mode 100644 cleopatre/devkit/mt7601udrv/common/mlme.c create mode 100644 cleopatre/devkit/mt7601udrv/common/multi_channel.c create mode 100644 cleopatre/devkit/mt7601udrv/common/netif_block.c create mode 100644 cleopatre/devkit/mt7601udrv/common/ps.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rt2860.bin.dfs create mode 100644 cleopatre/devkit/mt7601udrv/common/rt2860.bin.old create mode 100644 cleopatre/devkit/mt7601udrv/common/rt2870_wow.bin create mode 100644 cleopatre/devkit/mt7601udrv/common/rt_channel.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rt_os_util.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rt_rf.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rtmp_init.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rtmp_init_inf.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rtmp_timer.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rtusb_bulk.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rtusb_data.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rtusb_dev_id.c create mode 100644 cleopatre/devkit/mt7601udrv/common/rtusb_io.c create mode 100644 cleopatre/devkit/mt7601udrv/common/scan.c create mode 100644 cleopatre/devkit/mt7601udrv/common/spectrum.c create mode 100644 cleopatre/devkit/mt7601udrv/common/txpower.c create mode 100644 cleopatre/devkit/mt7601udrv/common/uapsd.c create mode 100644 cleopatre/devkit/mt7601udrv/common/vht.c create mode 100644 cleopatre/devkit/mt7601udrv/common/wapi.c create mode 100644 cleopatre/devkit/mt7601udrv/common/wfd.c create mode 100644 cleopatre/devkit/mt7601udrv/common/wsc.c create mode 100644 cleopatre/devkit/mt7601udrv/common/wsc_tlv.c create mode 100644 cleopatre/devkit/mt7601udrv/common/wsc_ufd.c create mode 100644 cleopatre/devkit/mt7601udrv/common/wsc_v2.c create mode 100644 cleopatre/devkit/mt7601udrv/include/action.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ags.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_apcli.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_autoChSel.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_autoChSel_cmm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_cfg.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_diversity.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_ids.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_mbss.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ap_wds.h create mode 100644 cleopatre/devkit/mt7601udrv/include/br_ftph.h create mode 100644 cleopatre/devkit/mt7601udrv/include/cfg80211.h create mode 100644 cleopatre/devkit/mt7601udrv/include/cfg80211extr.h create mode 100644 cleopatre/devkit/mt7601udrv/include/chip/chip_id.h create mode 100644 cleopatre/devkit/mt7601udrv/include/chip/mt7601.h create mode 100644 cleopatre/devkit/mt7601udrv/include/chip/rt28xx.h create mode 100644 cleopatre/devkit/mt7601udrv/include/chip/rt3290.h create mode 100644 cleopatre/devkit/mt7601udrv/include/chip/rt6590.h create mode 100644 cleopatre/devkit/mt7601udrv/include/chip/rtmp_phy.h create mode 100644 cleopatre/devkit/mt7601udrv/include/chlist.h create mode 100644 cleopatre/devkit/mt7601udrv/include/client_wds.h create mode 100644 cleopatre/devkit/mt7601udrv/include/client_wds_cmm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/crypt_aes.h create mode 100644 cleopatre/devkit/mt7601udrv/include/crypt_arc4.h create mode 100644 cleopatre/devkit/mt7601udrv/include/crypt_biginteger.h create mode 100644 cleopatre/devkit/mt7601udrv/include/crypt_dh.h create mode 100644 cleopatre/devkit/mt7601udrv/include/crypt_hmac.h create mode 100644 cleopatre/devkit/mt7601udrv/include/crypt_md5.h create mode 100644 cleopatre/devkit/mt7601udrv/include/crypt_sha2.h create mode 100644 cleopatre/devkit/mt7601udrv/include/cs.h create mode 100644 cleopatre/devkit/mt7601udrv/include/dfs.h create mode 100644 cleopatre/devkit/mt7601udrv/include/dot11ac_vht.h create mode 100644 cleopatre/devkit/mt7601udrv/include/dot11i_wpa.h create mode 100644 cleopatre/devkit/mt7601udrv/include/drs_extr.h create mode 100644 cleopatre/devkit/mt7601udrv/include/eeprom.h create mode 100644 cleopatre/devkit/mt7601udrv/include/firmware.h create mode 100644 cleopatre/devkit/mt7601udrv/include/frq_cal.h create mode 100644 cleopatre/devkit/mt7601udrv/include/iface/iface_util.h create mode 100644 cleopatre/devkit/mt7601udrv/include/iface/rtmp_reg_pcirbs.h create mode 100644 cleopatre/devkit/mt7601udrv/include/iface/rtmp_usb.h create mode 100644 cleopatre/devkit/mt7601udrv/include/igmp_snoop.h create mode 100644 cleopatre/devkit/mt7601udrv/include/ipv6.h create mode 100644 cleopatre/devkit/mt7601udrv/include/link_list.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/fce.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/mac_pci.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/mac_usb.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pbf.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_pci.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_rxwi.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_txwi.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/nmac/ral_nmac_usb.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pbf.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_pci.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rf_ctrl.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_rxwi.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_txwi.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/omac/ral_omac_usb.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/pbf.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/rf_ctrl.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mac_ral/rtmp_mac.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mat.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mcu/MT7601_firmware.h create mode 100644 cleopatre/devkit/mt7601udrv/include/misc.h create mode 100644 cleopatre/devkit/mt7601udrv/include/misc_cmm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mlme.h create mode 100644 cleopatre/devkit/mt7601udrv/include/mlme_sys.h create mode 100644 cleopatre/devkit/mt7601udrv/include/netif_block.h create mode 100644 cleopatre/devkit/mt7601udrv/include/oid.h create mode 100644 cleopatre/devkit/mt7601udrv/include/os/rt_drv.h create mode 100644 cleopatre/devkit/mt7601udrv/include/os/rt_linux.h create mode 100644 cleopatre/devkit/mt7601udrv/include/os/rt_linux_cmm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/os/rt_os.h create mode 100644 cleopatre/devkit/mt7601udrv/include/phy/rlt_phy.h create mode 100644 cleopatre/devkit/mt7601udrv/include/radar.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rt_config.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rt_os_net.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rt_os_util.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rt_txbf.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_M51.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_and.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_chip.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_cmd.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_comm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_def.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_dot11.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_iface.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_mcu.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_os.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_osabl.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_timer.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtmp_type.h create mode 100644 cleopatre/devkit/mt7601udrv/include/rtusb_io.h create mode 100644 cleopatre/devkit/mt7601udrv/include/spectrum.h create mode 100644 cleopatre/devkit/mt7601udrv/include/spectrum_def.h create mode 100644 cleopatre/devkit/mt7601udrv/include/sta_cfg.h create mode 100644 cleopatre/devkit/mt7601udrv/include/uapsd.h create mode 100644 cleopatre/devkit/mt7601udrv/include/vht.h create mode 100644 cleopatre/devkit/mt7601udrv/include/video.h create mode 100644 cleopatre/devkit/mt7601udrv/include/vr_ikans.h create mode 100644 cleopatre/devkit/mt7601udrv/include/vrut_ubm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wapi.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wapi_def.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wapi_sms4.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wfd.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wfd_cmm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wpa.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wpa_cmm.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wsc.h create mode 100644 cleopatre/devkit/mt7601udrv/include/wsc_tlv.h create mode 100644 cleopatre/devkit/mt7601udrv/load create mode 100644 cleopatre/devkit/mt7601udrv/mac/ral_nmac.c create mode 100644 cleopatre/devkit/mt7601udrv/mac/ral_omac.c create mode 100644 cleopatre/devkit/mt7601udrv/mac/rtmp_mac.c create mode 100644 cleopatre/devkit/mt7601udrv/mcu/bin/MT7601.bin create mode 100644 cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5.bin create mode 100644 cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5_Debug.bin create mode 100644 cleopatre/devkit/mt7601udrv/mcu/rtmp_M51.c create mode 100644 cleopatre/devkit/mt7601udrv/mcu/rtmp_and.c create mode 100644 cleopatre/devkit/mt7601udrv/mcu/rtmp_mcu.c create mode 100644 cleopatre/devkit/mt7601udrv/mgmt/mgmt_dev.c create mode 100644 cleopatre/devkit/mt7601udrv/mgmt/mgmt_entrytb.c create mode 100644 cleopatre/devkit/mt7601udrv/mgmt/mgmt_ht.c create mode 100644 cleopatre/devkit/mt7601udrv/mgmt/mgmt_hw.c create mode 100644 cleopatre/devkit/mt7601udrv/mgmt/mgmt_vht.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.soc create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Kconfig.ap.usb create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Kconfig.sta.soc create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.4 create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.netif create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.4.util create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.6 create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.netif create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.6.util create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.soc create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.ap.usb create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.clean create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.libautoprovision.6 create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.4 create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.libwapi.6 create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/Makefile.sta.soc create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/ap_ioctl.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/br_ftph.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/cfg80211.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/cfg80211drv.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/config.mk create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/config.mk.bak create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/inf_ppa.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/load create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_linux.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_linux_symb.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_main_dev.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_proc.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_profile.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_rbus_pci_drv.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_symb.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_usb.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/rt_usb_util.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/unload create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/usb_main_dev.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/vr_bdlt.c create mode 100644 cleopatre/devkit/mt7601udrv/os/linux/vr_ikans.c create mode 100644 cleopatre/devkit/mt7601udrv/phy/rlt_phy.c create mode 100644 cleopatre/devkit/mt7601udrv/phy/rlt_rf.c create mode 100644 cleopatre/devkit/mt7601udrv/phy/rtmp_phy.c create mode 100644 cleopatre/devkit/mt7601udrv/rate_ctrl/alg_ags.c create mode 100644 cleopatre/devkit/mt7601udrv/rate_ctrl/alg_grp.c create mode 100644 cleopatre/devkit/mt7601udrv/rate_ctrl/alg_legacy.c create mode 100644 cleopatre/devkit/mt7601udrv/rate_ctrl/ra_ctrl.c create mode 100644 cleopatre/devkit/mt7601udrv/tools/Makefile create mode 100644 cleopatre/devkit/mt7601udrv/tools/bin2h.c create mode 100644 cleopatre/devkit/mt7601udrv/unload (limited to 'cleopatre/devkit') 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;iBulkOutDataSizeLimit[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; apidxApCfg.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; iMacTab.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; iCommonCfg.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_indexApCfg.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; iMacTab.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; apidxApCfg.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; iMacTab.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; iApCfg.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; indexCommonCfg.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.\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; iSupportedRatesLen; 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; iSupportedRatesLen; 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; apidxApCfg.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; iApMlmeAux.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; apidxApCfg.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; iCommonCfg.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; iChannelListNum; 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; iMacTab.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; iMacTab.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;vApCfg.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; iMacTab.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; iMacTab.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; iMacTab.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; jNum; 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; iApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num; i++) + { + printk("Entry #%02d: ", i+1); + for (j=0; jApCfg.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; jApCfg.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; jApCfg.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; iApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num; i++) + { + printk("Entry #%02d: ", i+1); + for (j=0; jApCfg.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; iOS_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; iMacTab.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; iMacTab.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; iMacTab.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; iMacTab.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; iMacTab.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, ®BBP); + 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, ®BBP); + 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, ®BBP); + 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, ®BBP); + /* 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, ®BBP); + 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, ®BBP); + 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, ®BBP); + /* 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, ®BBP); + BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue); + /*Read it back for showing */ + BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, ®BBP); + 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, ®BBP); + /* 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, ®BBP); + 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, ®RF); + 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; iMacTab.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; iMacTab.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; iMacTab.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; iSharedKey[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; iSharedKey[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; apidxApCfg.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; apidxApCfg.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_1BApCfg.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. <> + 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; iApCfg.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; iBeaconOffset[i] + j, 0, 4); + } + } + +#ifdef RTMP_MAC_USB + RTUSBBssBeaconStop(pAd); +#endif /* RTMP_MAC_USB */ + + for(i=0; iApCfg.BssidNum; i++) + { + APMakeBssBeacon(pAd, i); + } + + RTMP_IO_READ32(pAd, MAC_BSSID_DW1, ®Value); + 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; iApCfg.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<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; iDataSize && iate.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; IdBssApCfg.MBSSID[IdBss].MSSIDDev = NULL; + + /* create virtual network interface */ + for(IdBss=FIRST_MBSSID; IdBssMC_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; IdBssApCfg.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; IdBssApCfg.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; IdBssApCfg.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 + + +#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; StaIdContent[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; IdBssApCfg.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; BusyTimeIdQloadBusyCountPri[BusyTimeId]); + } + + printk("\n\tSecondary Busy Time\tTimes\n"); + + for(BusyTimeId=0; BusyTimeIdQloadBusyCountSec[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; apidxApCfg.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. <> + 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; iWdsTab.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; iMacTab.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; jWdsTab.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; apidxApCfg.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; powerIndexTx20MPwrCfgGBand[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; powerIndexTx40MPwrCfgGBand[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> 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_indexRfIcType=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_indexRfIcType=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_indexRfIcType=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_indexRfIcType=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_indexbQATxStart == 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_indexMode = 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_indexbQATxStart == 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; indexChannel == 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; powerIndexTx20MPwrCfgGBand[powerIndex] == 0xffffffff) + continue; + + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgGBand[powerIndex]); + RtmpOsMsDelay(5); + } + } + else + { + /* BW=20;A band */ + for (powerIndex=0; powerIndexTx20MPwrCfgABand[powerIndex] == 0xffffffff) + continue; + + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx20MPwrCfgABand[powerIndex]); + RtmpOsMsDelay(5); + } + } + + /* 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; powerIndexTx40MPwrCfgGBand[powerIndex] == 0xffffffff) + continue; + + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgGBand[powerIndex]); + RtmpOsMsDelay(5); + } + } + else + { + /* BW=40;A band */ + for (powerIndex=0; powerIndexTx40MPwrCfgABand[powerIndex] == 0xffffffff) + continue; + + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + powerIndex*4, pAd->Tx40MPwrCfgABand[powerIndex]); + RtmpOsMsDelay(5); + } + + if ((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 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; entrystatus); + 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, ®); + + /* 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 0)) ; i++) + { + if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) + { + pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid]; + TID = pAd->BATable.BAOriEntry[i].TID; + + ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE); + } + total --; + } +} + + +VOID SendRefreshBAR( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry) +{ + FRAME_BAR FrameBar; + ULONG FrameLen; + NDIS_STATUS NStatus; + PUCHAR pOutBuffer = NULL; + USHORT Sequence; + UCHAR i, TID; + USHORT idx; + BA_ORI_ENTRY *pBAEntry; + + for (i = 0; i BAOriWcidArray[i]; + if (idx == 0) + { + continue; + } + pBAEntry = &pAd->BATable.BAOriEntry[idx]; + + if (pBAEntry->ORI_BA_Status == Originator_Done) + { + TID = pBAEntry->TID; + + ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory*/ + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n")); + return; + } + + Sequence = pEntry->TxSeq[TID]; + +#ifdef CONFIG_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; impdu_blk_pool.lock); + mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist); + if (mpdu_blk) + { +/* blk_count++; */ + /* reset mpdu_blk */ + NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu)); + } + NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); + return mpdu_blk; +} + +static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk) +{ + ASSERT(mpdu_blk); + + NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock); +/* blk_count--; */ + ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk); + NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); +} + + +static USHORT ba_indicate_reordering_mpdus_in_order( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN USHORT StartSeq) +{ + struct reordering_mpdu *mpdu_blk; + USHORT LastIndSeq = RESET_RCV_SEQ; + + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + + while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) + { + /* find in-order frame */ + if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ)) + { + break; + } + /* dequeue in-order frame from reodering list */ + mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list); + /* pass this frame up */ + ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); + /* move to next sequence */ + StartSeq = mpdu_blk->Sequence; + LastIndSeq = StartSeq; + /* free mpdu_blk */ + ba_mpdu_blk_free(pAd, mpdu_blk); + } + + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); + + /* update last indicated sequence */ + return LastIndSeq; +} + +static void ba_indicate_reordering_mpdus_le_seq( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN USHORT Sequence) +{ + struct reordering_mpdu *mpdu_blk; + + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) + { + /* find in-order frame */ + if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ)) + { + /* dequeue in-order frame from reodering list */ + mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list); + /* pass this frame up */ + ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); + /* free mpdu_blk */ + ba_mpdu_blk_free(pAd, mpdu_blk); + } + else + { + break; + } + } + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); +} + + +static void ba_refresh_reordering_mpdus( + IN PRTMP_ADAPTER pAd, + PBA_REC_ENTRY pBAEntry) +{ + struct reordering_mpdu *mpdu_blk; + + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + + /* dequeue in-order frame from reodering list */ + while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list))) + { + /* pass this frame up */ + ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); + + pBAEntry->LastIndSeq = mpdu_blk->Sequence; + ba_mpdu_blk_free(pAd, mpdu_blk); + + /* update last indicated sequence */ + } + ASSERT(pBAEntry->list.qlen == 0); + pBAEntry->LastIndSeq = RESET_RCV_SEQ; + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); +} + + +/* static */ +void ba_flush_reordering_timeout_mpdus( + IN PRTMP_ADAPTER pAd, + IN PBA_REC_ENTRY pBAEntry, + IN ULONG Now32) + +{ + USHORT Sequence; + + if ((pBAEntry == NULL) || (pBAEntry->list.qlen <= 0)) + return; + +/* if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&*/ +/* (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) ||*/ +/* (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&*/ +/* (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))*/ + if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6))) + &&(pBAEntry->list.qlen > 1) + ) + { + DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer), + (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT, + pBAEntry->LastIndSeq)); + ba_refresh_reordering_mpdus(pAd, pBAEntry); + pBAEntry->LastIndSeqAtTimer = Now32; + } + else + if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT))) + && (pBAEntry->list.qlen > 0) + ) + { +/* + DBGPRINT(RT_DEBUG_OFF, ("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer), + (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT, + pBAEntry->LastIndSeq)); +*/ + + /* force LastIndSeq to shift to LastIndSeq+1*/ + Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ; + ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence); + pBAEntry->LastIndSeqAtTimer = Now32; + pBAEntry->LastIndSeq = Sequence; + + /* indicate in-order mpdus*/ + Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence); + if (Sequence != RESET_RCV_SEQ) + { + pBAEntry->LastIndSeq = Sequence; + } + + DBGPRINT(RT_DEBUG_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<BAOriWcidArray[TID]; + if (Idx == 0) + { + /* allocate a BA session*/ + pBAEntry = BATableAllocOriEntry(pAd, &Idx); + if (pBAEntry == NULL) + { + DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n")); + return; + } + } + else + { + pBAEntry =&pAd->BATable.BAOriEntry[Idx]; + } + + if (pBAEntry->ORI_BA_Status >= Originator_WaitRes) + { + return; + } + + pEntry->BAOriWcidArray[TID] = Idx; + + /* Initialize BA session */ + pBAEntry->ORI_BA_Status = Originator_WaitRes; + pBAEntry->Wcid = pEntry->Aid; + pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit; + pBAEntry->Sequence = BA_ORI_INIT_SEQ; + pBAEntry->Token = 1; /* (2008-01-21) Jan Lee recommends it - this token can't be 0*/ + pBAEntry->TID = TID; + pBAEntry->TimeOutValue = TimeOut; + pBAEntry->pAdapter = pAd; + + if (!(pEntry->TXBAbitmap & (1<ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE); + } + else + RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); + + /* set timer to send ADDBA request */ + RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime); +} + +VOID BAOriSessionAdd( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN PFRAME_ADDBA_RSP pFrame) +{ + BA_ORI_ENTRY *pBAEntry = NULL; + BOOLEAN Cancelled; + UCHAR TID; + USHORT Idx; + PUCHAR pOutBuffer2 = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + FRAME_BAR FrameBar; + UCHAR MaxPeerBufSize; +#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<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<RECBATimer, &Cancelled); + } + else + { + RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE); + } + + + /* Set Bitmap flag.*/ + pEntry->RXBAbitmap |= (1<BARecWcidArray[TID] = Idx; + + pEntry->BADeclineBitmap &= ~(1<Aid, TID); + + DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n", + pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID])); + } + else + { + Status = FALSE; + DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n", + PRINT_MAC(pEntry->Addr), TID)); + } + return(Status); +} + + +BA_REC_ENTRY *BATableAllocRecEntry( + IN PRTMP_ADAPTER pAd, + OUT USHORT *Idx) +{ + int i; + BA_REC_ENTRY *pBAEntry = NULL; + + + NdisAcquireSpinLock(&pAd->BATabLock); + + if (pAd->BATable.numAsRecipient >= (MAX_LEN_OF_BA_REC_TABLE - 1)) + { + DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n", + pAd->BATable.numAsRecipient, (MAX_LEN_OF_BA_REC_TABLE - 1))); + goto done; + } + + /* reserve idx 0 to identify BAWcidArray[TID] as empty*/ + for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++) + { + pBAEntry =&pAd->BATable.BARecEntry[i]; + if ((pBAEntry->REC_BA_Status == Recipient_NONE)) + { + /* get one */ + pAd->BATable.numAsRecipient++; + pBAEntry->REC_BA_Status = Recipient_USED; + *Idx = i; + break; + } + } + +done: + NdisReleaseSpinLock(&pAd->BATabLock); + return pBAEntry; +} + +BA_ORI_ENTRY *BATableAllocOriEntry( + IN PRTMP_ADAPTER pAd, + OUT USHORT *Idx) +{ + int i; + BA_ORI_ENTRY *pBAEntry = NULL; + + NdisAcquireSpinLock(&pAd->BATabLock); + + if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE - 1)) + { + goto done; + } + + /* reserve idx 0 to identify BAWcidArray[TID] as empty*/ + for (i=1; iBATable.BAOriEntry[i]; + if ((pBAEntry->ORI_BA_Status == Originator_NONE)) + { + /* get one */ + pAd->BATable.numAsOriginator++; + pBAEntry->ORI_BA_Status = Originator_USED; + pBAEntry->pAdapter = pAd; + *Idx = i; + break; + } + } + +done: + NdisReleaseSpinLock(&pAd->BATabLock); + return pBAEntry; +} + + +VOID BATableFreeOriEntry( + IN PRTMP_ADAPTER pAd, + IN ULONG Idx) +{ + BA_ORI_ENTRY *pBAEntry = NULL; + MAC_TABLE_ENTRY *pEntry; + + + if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) + return; + + pBAEntry =&pAd->BATable.BAOriEntry[Idx]; + + if (pBAEntry->ORI_BA_Status != Originator_NONE) + { + pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; + pEntry->BAOriWcidArray[pBAEntry->TID] = 0; + DBGPRINT(RT_DEBUG_TRACE, ("%s: Wcid = %d, TID = %d\n", __FUNCTION__, pBAEntry->Wcid, pBAEntry->TID)); + + + NdisAcquireSpinLock(&pAd->BATabLock); + if (pBAEntry->ORI_BA_Status == Originator_Done) + { + pAd->BATable.numDoneOriginator -= 1; + pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) )); + DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient)); + /* Erase Bitmap flag.*/ + } + + ASSERT(pAd->BATable.numAsOriginator != 0); + + pAd->BATable.numAsOriginator -= 1; + + pBAEntry->ORI_BA_Status = Originator_NONE; + pBAEntry->Token = 0; + NdisReleaseSpinLock(&pAd->BATabLock); + } +} + + +VOID BATableFreeRecEntry( + IN PRTMP_ADAPTER pAd, + IN ULONG Idx) +{ + BA_REC_ENTRY *pBAEntry = NULL; + MAC_TABLE_ENTRY *pEntry; + + + if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE)) + return; + + pBAEntry =&pAd->BATable.BARecEntry[Idx]; + + if (pBAEntry->REC_BA_Status != Recipient_NONE) + { + pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; + pEntry->BARecWcidArray[pBAEntry->TID] = 0; + + NdisAcquireSpinLock(&pAd->BATabLock); + + ASSERT(pAd->BATable.numAsRecipient != 0); + + pAd->BATable.numAsRecipient -= 1; + + pBAEntry->REC_BA_Status = Recipient_NONE; + NdisReleaseSpinLock(&pAd->BATabLock); + } +} + + +VOID BAOriSessionTearDown( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR TID, + IN BOOLEAN bPassive, + IN BOOLEAN bForceSend) +{ + ULONG Idx = 0; + BA_ORI_ENTRY *pBAEntry; + BOOLEAN Cancelled; + + if (Wcid >= MAX_LEN_OF_MAC_TABLE) + { + return; + } + + + /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).*/ + Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID]; + if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) + { + if (bForceSend == TRUE) + { + /* force send specified TID DelBA*/ + MLME_DELBA_REQ_STRUCT DelbaReq; + MLME_QUEUE_ELEM *Elem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + if (Elem != NULL) + { + NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); + NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); + + COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); + DelbaReq.Wcid = Wcid; + DelbaReq.TID = TID; + DelbaReq.Initiator = ORIGINATOR; + Elem->MsgLen = sizeof(DelbaReq); + NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); + MlmeDELBAAction(pAd, Elem); +/* kfree(Elem);*/ + os_free_mem(NULL, Elem); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __FUNCTION__)); + } + } + + return; + } + + DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); + + pBAEntry = &pAd->BATable.BAOriEntry[Idx]; + DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status)); + + /* Prepare DelBA action frame and send to the peer.*/ + if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done)) + { + MLME_DELBA_REQ_STRUCT DelbaReq; + MLME_QUEUE_ELEM *Elem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + if (Elem != NULL) + { + NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); + NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); + + COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); + DelbaReq.Wcid = Wcid; + DelbaReq.TID = pBAEntry->TID; + DelbaReq.Initiator = ORIGINATOR; + Elem->MsgLen = sizeof(DelbaReq); + NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); + MlmeDELBAAction(pAd, Elem); +/* kfree(Elem);*/ + os_free_mem(NULL, Elem); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); + return; + } + } + RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); + BATableFreeOriEntry(pAd, Idx); + + if (bPassive) + { + /*BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);*/ + } +} + +VOID BARecSessionTearDown( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid, + IN UCHAR TID, + IN BOOLEAN bPassive) +{ + ULONG Idx = 0; + BA_REC_ENTRY *pBAEntry; + + if (Wcid >= MAX_LEN_OF_MAC_TABLE) + { + return; + } + + + /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).*/ + Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; + if (Idx == 0) + return; + + DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); + + + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status)); + + /* Prepare DelBA action frame and send to the peer.*/ + if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept)) + { + MLME_DELBA_REQ_STRUCT DelbaReq; + BOOLEAN Cancelled; + /*ULONG offset; */ + /*UINT32 VALUE;*/ + + RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); + + + /* 1. Send DELBA Action Frame*/ + if (bPassive == FALSE) + { + MLME_QUEUE_ELEM *Elem; /* = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + if (Elem != NULL) + { + NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); + NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); + + COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); + DelbaReq.Wcid = Wcid; + DelbaReq.TID = TID; + DelbaReq.Initiator = RECIPIENT; + Elem->MsgLen = sizeof(DelbaReq); + NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); + MlmeDELBAAction(pAd, Elem); +/* kfree(Elem);*/ + os_free_mem(NULL, Elem); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); + return; + } + } + + + + /* 2. Free resource of BA session*/ + /* flush all pending reordering mpdus */ + ba_refresh_reordering_mpdus(pAd, pBAEntry); + + NdisAcquireSpinLock(&pAd->BATabLock); + + /* Erase Bitmap flag.*/ + pBAEntry->LastIndSeq = RESET_RCV_SEQ; + pBAEntry->BAWinSize = 0; + /* Erase Bitmap flag at software mactable*/ + pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID))); + pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; + + RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); + + NdisReleaseSpinLock(&pAd->BATabLock); + + } + + BATableFreeRecEntry(pAd, Idx); +} + +VOID BASessionTearDownALL( + IN OUT PRTMP_ADAPTER pAd, + IN UCHAR Wcid) +{ + int i; + + for (i=0; ipAdapter; + + +#ifdef 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<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; iMacTab.Content[i]) || IS_ENTRY_APCLI(&pAd->MacTab.Content[i])) + CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE); + } + + /*========================================================*/ + /* MAC Register has a copy .*/ + /*========================================================*/ +/*#ifndef WIFI_TEST*/ + if( pAd->CommonCfg.bEnableTxBurst ) + { + /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode*/ + Ac0Cfg.field.AcTxop = 0x20; /* Suggest by John for TxBurst in HT Mode*/ + } + else + Ac0Cfg.field.AcTxop = 0; /* QID_AC_BE*/ +/*#else*/ +/* Ac0Cfg.field.AcTxop = 0; QID_AC_BE*/ +/*#endif */ + Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac0Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); + + Ac1Cfg.field.AcTxop = 0; /* QID_AC_BK*/ + Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac1Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); + + if (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; iTxMic[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, ®Val); + 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, ®_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(¶m, 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)¶m; + + 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(¶m, 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)¶m; + + 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; iApCfg.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; IdBssApCfg.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; iChannelListNum; 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 _)\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; iChannelListNum; 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<type); TalbeIdx++) + { + if (TalbeIdx > MAX_RD_REGION) + { + DBGPRINT(RT_DEBUG_ERROR, ("Table index out of range.\n")); + return; + } + } + + for(idx = 0; idxDFSParamFromConfig & (0x1<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; iChannelListNum; 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; iApCfg.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; iApCfg.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; iMacTab.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 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; iScanTab.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; iMacTab.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; iMacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC)) + { + if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) ) + break; + sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ", + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->apidx); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->AuthState); + sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]); + sprintf(msg+strlen(msg),"%-6d",0/*RateIdToMbps[pAd->MacTab.Content[i].HTPhyMode.word]*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d\n",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); /* ToDo*/ + + } + } + /* for compatible with old API just do the printk to console*/ + + DBGPRINT(RT_DEBUG_TRACE, ("%s", msg)); +/* kfree(msg);*/ + os_free_mem(NULL, msg); + +LabelOK: + if (pMacTab != NULL) + os_free_mem(NULL, pMacTab); +} + +#ifdef INF_AR9 +#ifdef AR9_MAPI_SUPPORT +#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; iMacTab.Content[i]; + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC)) + { + if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) ) + break; + sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ", + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->apidx); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode); + sprintf(msg+strlen(msg),"%-4d", (int)pEntry->AuthState); + sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]); + sprintf(msg+strlen(msg),"%-6d",0/*RateIdToMbps[pAd->MacTab.Content[i].HTPhyMode.word]*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); /* ToDo*/ + sprintf(msg+strlen(msg),"%-10d\n",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); /* ToDo*/ + + } + } + /* for compatible with old API just do the printk to console*/ + 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; apidxApCfg.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) + 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= &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: / */ + 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 &= (~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= +*/ +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=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; iMacTab.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; iMacTab.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= +*/ +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; scIndex1) { + for (i=0; i +*/ +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; scIndex1) { + for (i=0; i2) { + for (i=0; i + 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= + 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= +*/ +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; scIndexrows; 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; irows; 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= +*/ +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; scIndexrows; 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; irows; 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= +*/ +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= +*/ +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, ®Value.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, ®Value.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, ®Value.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; iMacTab.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; iMacTab.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; iMacTab.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; iMacTab.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; iBATable.BARecEntry[i].RxReRingLock); + } +*/ +} + + +/* +======================================================================== +Routine Description: + Calls USB_InterfaceStop and frees memory allocated for the URBs + calls NdisMDeregisterDevice and frees the memory + allocated in VNetInitialize for the Adapter Object + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RTMPFreeTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ + UINT i, acidx; + PTX_CONTEXT pNullContext = &pAd->NullContext[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; acidxTxContext[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; acidxTxContext[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; acidxTxContext[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; iMgmtRing.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; iBeaconBuf[i], HW_BEACON_OFFSET); + NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWISize); + + for (offset=0; offsetBeaconOffset[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; apidxApCfg.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; iBeaconBuf[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;iPointer 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; irx!=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(iApCfg.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; iexit!=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; ihash[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 */ +/*#include */ + +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; ihash[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; iuidHash[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; isesHash[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; iuidHash[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) + { + 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= 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; jCfgApCliBssid, &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; idxApCfg.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; jApCfg.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; iApCfg.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; iApCfg.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; IdBssApCfg.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; IdBssApCfg.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; jCommonCfg.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; iApCfg.BssidNum; i++) + pAd->ApCfg.MBSSID[i].WepStatus = Ndis802_11WEPDisabled; + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + int apidx; + + if (iApCfg.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; iApCfg.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> 8); + mac[2] = (UCHAR)(addr23 & 0xff); + mac[3] = (UCHAR)(addr23 >> 8); + mac[4] = (UCHAR)(addr45 & 0xff); + mac[5] = (UCHAR)(addr45 >> 8); + + DBGPRINT(RT_DEBUG_TRACE, ("mac addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", PRINT_MAC(mac))); + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + /* open card information file*/ + srcf = RtmpOSFileOpen(CARD_INFO_PATH, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + /* card information file does not exist */ + DBGPRINT(RT_DEBUG_TRACE, + ("--> Error opening %s\n", CARD_INFO_PATH)); + goto free_resource; + } + + /* card information file exists so reading the card information */ + memset(buffer, 0x00, MAX_INI_BUFFER_SIZE); + retval = RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE); + if (retval < 0) + { + /* read fail */ + DBGPRINT(RT_DEBUG_TRACE, + ("--> Read %s error %d\n", CARD_INFO_PATH, -retval)); + } + else + { + /* get card selection method */ + memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE); + card_select_method = MC_SELECT_CARDTYPE; /* default*/ + + if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer, TRUE)) + { + if (strcmp(tmpbuf, "CARDID") == 0) + card_select_method = MC_SELECT_CARDID; + else if (strcmp(tmpbuf, "MAC") == 0) + card_select_method = MC_SELECT_MAC; + else if (strcmp(tmpbuf, "CARDTYPE") == 0) + card_select_method = MC_SELECT_CARDTYPE; + } + + DBGPRINT(RT_DEBUG_TRACE, + ("MC> Card Selection = %d\n", card_select_method)); + + /* init*/ + card_free_id = -1; + card_nouse_id = -1; + card_same_mac_id = -1; + card_match_id = -1; + + /* search current card information records*/ + for(card_index=0; + card_index Free = %d, Same = %d, NOUSE = %d\n", + card_free_id, card_same_mac_id, card_nouse_id)); + + if ((card_same_mac_id >= 0) && + ((card_select_method == MC_SELECT_CARDID) || + (card_select_method == MC_SELECT_CARDTYPE))) + { + /* same MAC entry is found*/ + card_match_id = card_same_mac_id; + + if (card_select_method == MC_SELECT_CARDTYPE) + { + /* for CARDTYPE*/ + snprintf(card_id_buf, sizeof(card_id_buf), "%02dCARDTYPE%s", + card_match_id, RFIC_word); + + if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL) + { + /* we found the card ID*/ + LETTER_CASE_TRANSLATE(start_ptr, card_id_buf); + } + } + } + else + { + /* the card is 1st plug-in, try to find the match card profile*/ + switch(card_select_method) + { + case MC_SELECT_CARDID: /* CARDID*/ + default: + if (card_free_id >= 0) + card_match_id = card_free_id; + else + card_match_id = card_nouse_id; + break; + + case MC_SELECT_MAC: /* MAC*/ + snprintf(card_id_buf, sizeof(card_id_buf), "MAC%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); + + /* try to find the key word in the card file */ + if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL) + { + LETTER_CASE_TRANSLATE(start_ptr, card_id_buf); + + /* get the row ID (2 ASCII characters) */ + start_ptr -= 2; + card_id_buf[0] = *(start_ptr); + card_id_buf[1] = *(start_ptr+1); + card_id_buf[2] = 0x00; + + card_match_id = simple_strtol(card_id_buf, 0, 10); + } + break; + + case MC_SELECT_CARDTYPE: /* CARDTYPE*/ + card_nouse_id = -1; + + for(card_index=0; + card_index= 0) + { + /* make up search keyword*/ + switch(card_select_method) + { + case MC_SELECT_CARDID: /* CARDID*/ + snprintf(card_id_buf, sizeof(card_id_buf), "%02dCARDID", card_match_id); + break; + + case MC_SELECT_MAC: /* MAC*/ + snprintf(card_id_buf, sizeof(card_id_buf), + "%02dmac%02x:%02x:%02x:%02x:%02x:%02x", + card_match_id, + mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); + break; + + case MC_SELECT_CARDTYPE: /* CARDTYPE*/ + default: + snprintf(card_id_buf, sizeof(card_id_buf), "%02dcardtype%s", + card_match_id, RFIC_word); + break; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf)); + + /* read card file path*/ + if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer, TRUE)) + { + if (strlen(tmpbuf) < sizeof(pAd->MC_FileName)) + { + /* backup card information*/ + pAd->MC_RowID = card_match_id; /* base 0 */ + MC_CardUsed[card_match_id] = 1; + memcpy(MC_CardMac[card_match_id], mac, sizeof(mac)); + + /* backup card file path*/ + NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf)); + pAd->MC_FileName[strlen(tmpbuf)] = '\0'; + flg_match_ok = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, + ("Card Profile Name = %s\n", pAd->MC_FileName)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, + ("Card Profile Name length too large!\n")); + } + } + else + { + DBGPRINT(RT_DEBUG_ERROR, + ("Can not find search key word in card.dat!\n")); + } + + if ((flg_match_ok != TRUE) && + (card_match_id < MAX_NUM_OF_MULTIPLE_CARD)) + { + MC_CardUsed[card_match_id] = 0; + memset(MC_CardMac[card_match_id], 0, sizeof(mac)); + } + } /* if (card_match_id >= 0)*/ + } + + +/* close file*/ +retval = RtmpOSFileClose(srcf); + +free_resource: +RtmpOSFSInfoChange(&osFSInfo, FALSE); +/* kfree(buffer);*/ +/* kfree(tmpbuf);*/ +os_free_mem(NULL, buffer); +os_free_mem(NULL, tmpbuf); + +return flg_match_ok; +} +#endif /* MULTIPLE_CARD_SUPPORT */ + + +#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; jMulTestTab.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; iChannelListNum; 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; iChannelListNum; 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; iTxPower[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;iChannelListNum;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;iChannelListNum;i++) + { + DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, Flags = %x\n ", + pAd->ChannelList[i].Channel, + pAd->ChannelList[i].Power, + pAd->ChannelList[i].Power2, + pAd->ChannelList[i].Flags)); + } +#endif +} + +/* + ========================================================================== + Description: + This routine return the first channel number according to the country + code selection and RF IC selection (signal band or dual band). It is called + whenever driver need to start a site survey of all supported channels. + Return: + ch - the first channel number of current country code setting + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +UCHAR FirstChannel( + IN PRTMP_ADAPTER pAd) +{ + return pAd->ChannelList[0].Channel; +} + +/* + ========================================================================== + Description: + This routine returns the next channel number. This routine is called + during driver need to start a site survey of all supported channels. + Return: + next_channel - the next channel number valid in current country code setting. + Note: + return 0 if no more next channel + ========================================================================== + */ +UCHAR NextChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR channel) +{ + int i; + UCHAR next_channel = 0; + + for (i = 0; i < (pAd->ChannelListNum - 1); i++) + { + if (channel == pAd->ChannelList[i].Channel) + { +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + /* Only scan effected channel if this is a SCAN_2040_BSS_COEXIST*/ + /* 2009 PF#2: Nee to handle the second channel of AP fall into affected channel range.*/ + if ((pAd->MlmeAux.ScanType == SCAN_2040_BSS_COEXIST) && (pAd->ChannelList[i+1].Channel >14)) + { + channel = pAd->ChannelList[i+1].Channel; + continue; + } + else +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + { + /* Record this channel's idx in ChannelList array.*/ + next_channel = pAd->ChannelList[i+1].Channel; + break; + } + } + + } + return next_channel; +} + +/* + ========================================================================== + Description: + This routine is for Cisco Compatible Extensions 2.X + Spec31. AP Control of Client Transmit Power + Return: + None + Note: + Required by Aironet dBm(mW) + 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW), + 17dBm(50mw), 20dBm(100mW) + + We supported + 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%), + 14dBm(75%), 15dBm(100%) + + The client station's actual transmit power shall be within +/- 5dB of + the minimum value or next lower value. + ========================================================================== + */ +VOID ChangeToCellPowerLimit( + IN PRTMP_ADAPTER pAd, + IN UCHAR AironetCellPowerLimit) +{ + /* + valud 0xFF means that hasn't found power limit information + from the AP's Beacon/Probe response + */ + if (AironetCellPowerLimit == 0xFF) + return; + + if (AironetCellPowerLimit < 6) /*Used Lowest Power Percentage.*/ + pAd->CommonCfg.TxPowerPercentage = 6; + else if (AironetCellPowerLimit < 9) + pAd->CommonCfg.TxPowerPercentage = 10; + else if (AironetCellPowerLimit < 12) + pAd->CommonCfg.TxPowerPercentage = 25; + else if (AironetCellPowerLimit < 14) + pAd->CommonCfg.TxPowerPercentage = 50; + else if (AironetCellPowerLimit < 15) + pAd->CommonCfg.TxPowerPercentage = 75; + else + pAd->CommonCfg.TxPowerPercentage = 100; /*else used maximum*/ + + if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault) + pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; + +} + + +CHAR ConvertToRssi(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. <> + */ + 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> (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> 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) & 0x01) == 0) + { + InBuf[2] |= (0x1 <>8; + pValueX=OddWriteByteBuf; + + } + + for(i=0; ibUseEfuse == FALSE && pAd->bFroceEEPROMBuffer == FALSE) + return FALSE; + eFuseGetFreeBlockCount(pAd,&efusefreenum); + printk("efuseFreeNumber is %d\n",efusefreenum); + return TRUE; +} + + +INT set_eFusedump_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + USHORT InBuf[3]; + INT i=0; + + if (pAd->bUseEfuse == FALSE && pAd->bFroceEEPROMBuffer == FALSE) + return FALSE; + + for(i =0; ichipCap.EFUSE_USAGE_MAP_END/2; i++) + { + InBuf[0] = 2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + if(i%4==0) + printk("\nBlock %x:",i/8); + printk("%04x ",InBuf[2]); + } + return TRUE; +} + + +INT set_eFuseLoadFromBin_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + PSTRING src; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osfsInfo; + INT retval, memSize; + PSTRING buffer, memPtr; + INT TotalByte= 0,ReadedByte=0,CompareBuf=1; + USHORT *PDATA; + USHORT DATA; + + memSize = 128 + MAX_EEPROM_BIN_FILE_SIZE + sizeof(USHORT) * 8; +/* memPtr = kmalloc(memSize, MEM_ALLOC_FLAG);*/ + os_alloc_mem(NULL, (UCHAR **)&memPtr, memSize); + if (memPtr == NULL) + return FALSE; + + NdisZeroMemory(memPtr, memSize); + src = memPtr; /* kmalloc(128, MEM_ALLOC_FLAG);*/ + buffer = src + 128; /* kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);*/ + PDATA = (USHORT*)(buffer + MAX_EEPROM_BIN_FILE_SIZE); /* kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);*/ + + if(strlen(arg)>0) + NdisMoveMemory(src, arg, strlen(arg)); + else + NdisMoveMemory(src, EFUSE_EEPROM_DEFULT_FILE, strlen(EFUSE_EEPROM_DEFULT_FILE)); + DBGPRINT(RT_DEBUG_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;ReadedBytechipCap.EFUSE_USAGE_MAP_END % 2) != 0) + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_END-1; + } + else + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_END; + } + + if( (pAd->chipCap.EFUSE_USAGE_MAP_START % 2) != 0) + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_START-1; + } + else + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_START; + } + + do + { + /*Step 0. find the entry in the mapping table*/ + /*The address of EEPROM is 2-bytes alignment.*/ + /*The last bit is used for alignment, so it must be 0.*/ + Loop++; + tmpOffset = Offset & 0xfffe; + EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData); + + if( EFSROM_AOUT == 0x3f) + { /*find available logical address pointer */ + /*the logical address does not exist, find an empty one*/ + /*from the first address of block 45=16*45=0x2d0 to the last address of block 47*/ + /*==>48*16-3(reserved)=2FC*/ + bAllocateNewBlk=TRUE; + for (i=StartBlock; i>=EndBlock; i-=2) + { + /*Retrive the logical block nubmer form each logical address pointer*/ + /*It will access two logical address pointer each time.*/ + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + BlkNum = i+1-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + BlkNum = i-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + } + } + else + { + bAllocateNewBlk=FALSE; + BlkNum = EFSROM_AOUT; + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum)); + + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); + return FALSE; + } + /*Step 1.1.0*/ + /*If the block is not existing in mapping table, create one */ + /*and write down the 16-bytes data to the new block*/ + if(bAllocateNewBlk) + { + DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n")); + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i])); + tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; + + + RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer); + efuseDataOffset -= 4; + + } + + /*Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/ + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ; + + /*Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.*/ + eFuseCtrlStruc.field.EFSROM_MODE = 3; + + /*Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.*/ + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + /*Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.*/ + i = 0; + while(i < 100) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + + RTMPusecDelay(2); + i++; + } + + } + else + { /*Step1.2.*/ + /*If the same logical number is existing, check if the writting data and the data */ + /*saving in this block are the same.*/ + /*read current values of 16-byte block */ + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + /*Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.*/ + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + /*Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.*/ + eFuseCtrlStruc.field.EFSROM_MODE = 0; + + /*Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.*/ + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + /*Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.*/ + i = 0; + while(i < 500) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + RTMPusecDelay(2); + i++; + } + + /*Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)*/ + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]); + efuseDataOffset -= 4; + } + /*Step1.2.5. Check if the data of efuse and the writing data are the same.*/ + for(i =0; i<4; i++) + { + tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; + DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer)); + + if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i])) + bNotWrite&=TRUE; + else + { + bNotWrite&=FALSE; + break; + } + } + if(!bNotWrite) + { + printk("The data is not the same\n"); + + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = pData[i]; + + eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); + } + + } + else + return TRUE; + } + + + + /*Step 2. Write mapping table*/ + addr = pAd->chipCap.EFUSE_USAGE_MAP_START+BlkNum; + + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + /*convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry*/ + tmpOffset = Offset; + tmpOffset >>= 4; + tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40; + tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80; + + /* write the logical address*/ + if(tmpaddr%2 != 0) + InBuf[2] = tmpOffset<<8; + else + InBuf[2] = tmpOffset; + + eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0); + + /*Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted*/ + bWriteSuccess = TRUE; + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2])); + if(pData[i] != InBuf[2]) + { + bWriteSuccess = FALSE; + break; + } + } + + /*Step 4. invlidate mapping entry and find a free mapping entry if not succeed*/ + + if (!bWriteSuccess&&Loop<2) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum)); + + /* the offset of current mapping entry*/ + addr = pAd->chipCap.EFUSE_USAGE_MAP_START+BlkNum; + + /*find a new mapping entry*/ + BlkNum = 0xffff; + for (i=StartBlock; i>=EndBlock; i-=2) + { + /*Retrive the logical block nubmer form each logical address pointer*/ + /*It will access two logical address pointer each time.*/ + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i !=pAd->chipCap.EFUSE_USAGE_MAP_END) + { + BlkNum = i+1-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + BlkNum = i-pAd->chipCap.EFUSE_USAGE_MAP_START; + break; + } + } + + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum)); + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n")); + return FALSE; + } + + /*invalidate the original mapping entry if new entry is not found*/ + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + /* write the logical address*/ + if(tmpaddr%2 != 0) + { + /* Invalidate the high byte*/ + for (i=8; i<15; i++) + { + if( ( (InBuf[2] >> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <bFroceEEPROMBuffer +#ifdef RALINK_ATE + ||pAd->bEEPROMFile +#endif /* RALINK_ATE */ + ) + { + DBGPRINT(RT_DEBUG_TRACE, ("Read from EEPROM Buffer\n")); + NdisMoveMemory(pValue, &(pAd->EEPROMImage[Offset]), 2); + *pValue = le2cpu16(*pValue); + } + else + eFuseReadRegisters(pAd, Offset, 2, pValue); + return (*pValue); +} + + +int rtmp_ee_efuse_write16( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + IN USHORT data) +{ + if (pAd->bFroceEEPROMBuffer +#ifdef RALINK_ATE + ||pAd->bEEPROMFile +#endif /* RALINK_ATE */ + ) + { + data = le2cpu16(data); + DBGPRINT(RT_DEBUG_TRACE, ("Write to EEPROM Buffer\n")); + NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &data, 2); + } + else + eFuseWrite(pAd,Offset ,&data, 2); + return 0; +} + + +int RtmpEfuseSupportCheck( + IN RTMP_ADAPTER *pAd) +{ + USHORT value; + + if (IS_RT30xx(pAd) || IS_RT3593(pAd)) + { + eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value); + pAd->EFuseTag = (value & 0xff); + } + return 0; +} + + +#ifdef RALINK_ATE +INT set_eFuseBufferModeWriteBack_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT Enable; + + + if(strlen(arg)>0) + { + Enable= simple_strtol(arg, 0, 16); + } + else + return FALSE; + if(Enable==1) + { + DBGPRINT(RT_DEBUG_TRACE, ("set_eFuseBufferMode_Proc:: Call WRITEEEPROMBUF")); + eFuseWriteEeeppromBuf(pAd); + } + else + return FALSE; + return TRUE; +} +#endif /* RALINK_ATE */ + + +/* + ======================================================================== + + Routine Description: + Load EEPROM from bin file for eFuse mode + + Arguments: + Adapter Pointer to our adapter + + Return Value: + NDIS_STATUS_SUCCESS firmware image load ok + NDIS_STATUS_FAILURE image not found + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +INT eFuseLoadEEPROM( + IN PRTMP_ADAPTER pAd) +{ + PSTRING src = NULL; + INT retval; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osFSInfo; + + + src=EFUSE_BUFFER_PATH; + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + if (src && *src) + { + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening %s\n", src)); + return FALSE; + } + else + { + + memset(pAd->EEPROMImage, 0x00, MAX_EEPROM_BIN_FILE_SIZE); + + + retval =RtmpOSFileRead(srcf, (PSTRING)pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE); + if (retval > 0) + { + + retval = NDIS_STATUS_SUCCESS; + } + else + DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval)); + + } + + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n")); + return FALSE; + + } + + retval=RtmpOSFileClose(srcf); + + if (retval) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); + } + + + RtmpOSFSInfoChange(&osFSInfo, FALSE); + + return TRUE; +} + +INT eFuseWriteEeeppromBuf( + IN PRTMP_ADAPTER pAd) +{ + + PSTRING src = NULL; + INT retval; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osFSInfo; + + + src=EFUSE_BUFFER_PATH; + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + + + if (src && *src) + { + srcf = RtmpOSFileOpen(src, O_WRONLY|O_CREAT, 0); + + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening %s\n", src)); + return FALSE; + } + else + { + + RtmpOSFileWrite(srcf, (PSTRING)pAd->EEPROMImage,MAX_EEPROM_BIN_FILE_SIZE); + + } + + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n")); + return FALSE; + + } + + retval=RtmpOSFileClose(srcf); + + if (retval) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); + } + + RtmpOSFSInfoChange(&osFSInfo, FALSE); + return TRUE; +} + + +VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd, + PUINT EfuseFreeBlock) +{ + + USHORT i=0, StartBlock=0, EndBlock=0; + USHORT LogicalAddress; + USHORT FirstFreeBlock = 0xffff, LastFreeBlock = 0xffff; + + if(!pAd->bUseEfuse) + { + DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n")); + return ; + } + *EfuseFreeBlock = 0; + /* find first free block*/ + if( (pAd->chipCap.EFUSE_USAGE_MAP_START % 2) != 0) + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_START-1; + } + else + { + StartBlock = pAd->chipCap.EFUSE_USAGE_MAP_START; + } + + if( (pAd->chipCap.EFUSE_USAGE_MAP_END % 2) != 0) + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_END-1; + } + else + { + EndBlock = pAd->chipCap.EFUSE_USAGE_MAP_END; + } + + for (i = StartBlock; i <= EndBlock; i+=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + FirstFreeBlock = i; + break; + } + } + + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + FirstFreeBlock = i+1; + break; + } + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseGetFreeBlockCount, FirstFreeBlock= 0x%x\n", FirstFreeBlock)); + + /*if not find, return free block number = 0*/ + if(FirstFreeBlock == 0xffff) + { + *EfuseFreeBlock = 0; + return; + } + for (i = EndBlock; i >= StartBlock; i-=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + + if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if(i != pAd->chipCap.EFUSE_USAGE_MAP_END) + { + LastFreeBlock = i+1; + break; + } + } + + if( (LogicalAddress & 0xff) == 0) + { + if(i != (pAd->chipCap.EFUSE_USAGE_MAP_START-1)) + { + LastFreeBlock = i; + break; + } + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseGetFreeBlockCount, LastFreeBlock= 0x%x\n", LastFreeBlock)); + + /*if not find last free block, return free block number = 0, this should not happen since we have checked first free block number previously*/ + if(LastFreeBlock == 0xffff) + { + *EfuseFreeBlock = 0; + return; + } + + /* return total free block number, last free block number must >= first free block number*/ + if(LastFreeBlock < FirstFreeBlock) + { + *EfuseFreeBlock = 0; + } + else + { + *EfuseFreeBlock = LastFreeBlock - FirstFreeBlock + 1; + } + + DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is %d\n",*EfuseFreeBlock)); +} + + +INT eFuse_init(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; iiOS_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 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; MacEntryIdxMacTab.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; MacEntryIdxMacTab.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; MacEntryIdxMacTab.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 Binary files /dev/null and b/cleopatre/devkit/mt7601udrv/common/image.bin 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 + + +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; iCommonCfg.DesireRate[i] & 0x7f) + { + case 2: Rate = RATE_1; num++; break; + case 4: Rate = RATE_2; num++; break; + case 11: Rate = RATE_5_5; num++; break; + case 22: Rate = RATE_11; num++; break; + case 12: Rate = RATE_6; num++; break; + case 18: Rate = RATE_9; num++; break; + case 24: Rate = RATE_12; num++; break; + case 36: Rate = RATE_18; num++; break; + case 48: Rate = RATE_24; num++; break; + case 72: Rate = RATE_36; num++; break; + case 96: Rate = RATE_48; num++; break; + case 108: Rate = RATE_54; num++; break; + /*default: Rate = RATE_1; break;*/ + } + if (MaxDesire < Rate) MaxDesire = Rate; + } + +/*===========================================================================*/ +/*===========================================================================*/ + do + { +#ifdef CONFIG_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 Rate) + MinSupport = Rate; + } + + for (i=0; i Rate) + MinSupport = Rate; + } + + RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap); + + for (i=0; iCommonCfg.ExpectedACKRate[i] = CurrBasicRate; + } + + DBGPRINT(RT_DEBUG_TRACE,("%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; iBATable.BARecEntry[i].RxReRingLock); + } + NdisFreeSpinLock(&pAd->BATabLock); +} +#endif /* DOT11_N_SUPPORT */ + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeRadioOff( + IN PRTMP_ADAPTER pAd) +{ + RTMP_MLME_RADIO_OFF(pAd); +} + +/* IRQL = DISPATCH_LEVEL*/ +VOID MlmeRadioOn( + IN PRTMP_ADAPTER pAd) +{ + RTMP_MLME_RADIO_ON(pAd); +} + +/* +=========================================================================================== + bss_table.c +=========================================================================================== +*/ + + +/*! \brief initialize BSS table + * \param p_tab pointer to the table + * \return none + * \pre + * \post + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + */ +VOID BssTableInit(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 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; IdChanChannelListNum; 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 Binary files /dev/null and b/cleopatre/devkit/mt7601udrv/common/rt2860.bin.dfs 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 Binary files /dev/null and b/cleopatre/devkit/mt7601udrv/common/rt2860.bin.old 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 Binary files /dev/null and b/cleopatre/devkit/mt7601udrv/common/rt2870_wow.bin 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; lTxPower[l].Channel) + { + pAd->ChannelList[j].Power = pAd->TxPower[l].Power; + pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2; +#ifdef DOT11N_SS3_SUPPORT + pAd->ChannelList[j].Power3 = pAd->TxPower[l].Power3; +#endif /* DOT11N_SS3_SUPPORT */ + break; + } + } + if (l == MAX_NUM_OF_CHANNELS) + continue; + + pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment; + pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr; + pAd->ChannelList[j].DfsReq = pChDesp->DfsReq; + pAd->ChannelList[j].RegulatoryDomain = regulatoryDomain; +#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; jCurrentAddress[j], 1); + macptr=macptr+3; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Use the MAC address what is assigned from Moudle Parameter. \n")); + } + else + { + COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress); + DBGPRINT(RT_DEBUG_TRACE, ("Use the MAC address what is assigned from EEPROM. \n")); + } + + /* Set the current MAC to ASIC */ + csr2.field.Byte0 = pAd->CurrentAddress[0]; + csr2.field.Byte1 = pAd->CurrentAddress[1]; + csr2.field.Byte2 = pAd->CurrentAddress[2]; + csr2.field.Byte3 = pAd->CurrentAddress[3]; + RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word); + csr3.word = 0; + csr3.field.Byte4 = pAd->CurrentAddress[4]; + { + csr3.field.Byte5 = pAd->CurrentAddress[5]; + csr3.field.U2MeMask = 0xff; + } + RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word); + +#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; IndexchipOps.AsicMacInit != NULL) + pAd->chipOps.AsicMacInit(pAd); + + + /* Before program BBP, we need to wait BBP/RF get wake up.*/ + Index = 0; + do + { + RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &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; tidAid, tid, FALSE, FALSE); +#endif /* DOT11_N_SUPPORT */ + +#ifdef WDS_SUPPORT + /* fix WDS Jam issue*/ + if(IS_ENTRY_WDS(pEntry) + && (pEntry->LockEntryTx == FALSE) + && (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck)) + { + DBGPRINT(RT_DEBUG_TRACE, ("Entry %02x:%02x:%02x:%02x:%02x:%02x Blocked!! (Fail Cnt = %d)\n", + 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_indexSharedKey[bss_index][key_index].KeyLen = 0; + pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE; + } + } + + pAd->bLocalAdminMAC = FALSE; + pAd->EepromAccess = FALSE; + + pAd->Antenna.word = 0; + pAd->CommonCfg.BBPCurrentBW = BW_20; + + + pAd->bAutoTxAgcA = FALSE; /* Default is OFF*/ + pAd->bAutoTxAgcG = FALSE; /* Default is OFF*/ + +#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; IdMbssApCfg.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; indexCommonCfg.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; indexCommonCfg.NumOfBulkInIRP; index++) + { + RTUSBBulkReceive(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" )); + } +#endif /* RTMP_MAC_USB */ + }/* end of else*/ + + /* Set up the Mac address*/ +#ifdef CONFIG_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, ®); /* clear garbage interrupts*/ + printk("0x1300 = %08x\n", reg); + } + + { +/* u32 reg;*/ +/* UINT8 byte;*/ +/* u16 tmp;*/ + +/* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®);*/ + +/* tmp = 0x0805;*/ +/* reg = (reg & 0xffff0000) | tmp;*/ +/* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);*/ + + } + + + +#ifdef CONFIG_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 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;iTxContext[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 (RunningQueueNoLastRunningQueueNo) + { + DBGPRINT(RT_DEBUG_INFO,("SoftwareFlowControl reset %d < %d \n",RunningQueueNo,pAd->LastRunningQueueNo)); + pAd->RunningQueueNoCount++; + if (pAd->RunningQueueNoCount>=6) + { + ResetBulkOutSize=TRUE; + pAd->RunningQueueNoCount=0; + pAd->LastRunningQueueNo=RunningQueueNo; + } + } + + if (ResetBulkOutSize==TRUE) + { + for (QueIdx=0;QueIdxBulkOutDataFlag[i]==TRUE && Priority[i]>Priority[QueIdx]) + HighWorkingAcCount++; + + } + pAd->BulkOutDataSizeLimit[QueIdx]=MaxBulkOutsSizeLimit[RunningQueueNo][HighWorkingAcCount]; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Reset bulkout size AC0(BE):%7d AC1(BK):%7d AC2(VI):%7d AC3(VO):%7d %d\n",pAd->BulkOutDataSizeLimit[0] + ,pAd->BulkOutDataSizeLimit[1] + ,pAd->BulkOutDataSizeLimit[2] + ,pAd->BulkOutDataSizeLimit[3] + ,RunningQueueNo)); + } +} +#endif /* INF_AMAZON_SE */ + + +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; ireg_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; BusyCntBbpWriteLatch[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 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; + RegulatoryClassLoopCommonCfg.RegulatoryClass[RegulatoryClassLoop]; + if (RegulatoryClass >= MaxRegulatoryClassNum) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: %c%c Unknow Requlatory class (%d)\n", + __FUNCTION__, pCountry[0], pCountry[1], RegulatoryClass)); + return 0xff; + } + pChannelSet = &pRegulatoryClass[RegulatoryClass].ChannelSet; + for (ChIdx=0; ChIdxNumberOfChannels; ChIdx++) + { + if (channel == pChannelSet->ChannelList[ChIdx]) + return pChannelSet->MaxTxPwr; + + } + if (ChIdx == pChannelSet->NumberOfChannels) + return 0xff; + } + + return 0xff; +} + +typedef struct __TX_PWR_CFG +{ + UINT8 Mode; + UINT8 MCS; + UINT16 req; + UINT8 shift; + UINT32 BitMask; +} TX_PWR_CFG; + +/* Note: the size of TxPwrCfg is too large, do not put it to function */ +TX_PWR_CFG TxPwrCfg[] = { + {MODE_CCK, 0, 0, 4, 0x000000f0}, + {MODE_CCK, 1, 0, 0, 0x0000000f}, + {MODE_CCK, 2, 0, 12, 0x0000f000}, + {MODE_CCK, 3, 0, 8, 0x00000f00}, + + {MODE_OFDM, 0, 0, 20, 0x00f00000}, + {MODE_OFDM, 1, 0, 16, 0x000f0000}, + {MODE_OFDM, 2, 0, 28, 0xf0000000}, + {MODE_OFDM, 3, 0, 24, 0x0f000000}, + {MODE_OFDM, 4, 1, 4, 0x000000f0}, + {MODE_OFDM, 5, 1, 0, 0x0000000f}, + {MODE_OFDM, 6, 1, 12, 0x0000f000}, + {MODE_OFDM, 7, 1, 8, 0x00000f00} +#ifdef DOT11_N_SUPPORT + ,{MODE_HTMIX, 0, 1, 20, 0x00f00000}, + {MODE_HTMIX, 1, 1, 16, 0x000f0000}, + {MODE_HTMIX, 2, 1, 28, 0xf0000000}, + {MODE_HTMIX, 3, 1, 24, 0x0f000000}, + {MODE_HTMIX, 4, 2, 4, 0x000000f0}, + {MODE_HTMIX, 5, 2, 0, 0x0000000f}, + {MODE_HTMIX, 6, 2, 12, 0x0000f000}, + {MODE_HTMIX, 7, 2, 8, 0x00000f00}, + {MODE_HTMIX, 8, 2, 20, 0x00f00000}, + {MODE_HTMIX, 9, 2, 16, 0x000f0000}, + {MODE_HTMIX, 10, 2, 28, 0xf0000000}, + {MODE_HTMIX, 11, 2, 24, 0x0f000000}, + {MODE_HTMIX, 12, 3, 4, 0x000000f0}, + {MODE_HTMIX, 13, 3, 0, 0x0000000f}, + {MODE_HTMIX, 14, 3, 12, 0x0000f000}, + {MODE_HTMIX, 15, 3, 8, 0x00000f00} +#endif /* DOT11_N_SUPPORT */ +}; +#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG)) + +CHAR RTMP_GetTxPwr( + IN PRTMP_ADAPTER pAd, + IN HTTRANSMIT_SETTING HTTxMode) +{ + UINT32 Value; + INT Idx; + UINT8 PhyMode; + CHAR CurTxPwr; + UINT8 TxPwrRef = 0; + CHAR DaltaPwr; + ULONG TxPwr[5]; + + +#ifdef SINGLE_SKU + CurTxPwr = pAd->CommonCfg.DefineMaxTxPwr; +#else + CurTxPwr = 19; +#endif /* 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; iChannelListNum; i++) + { + if ((Channel == pAd->ChannelList[i].Channel) + &&(pAd->ChannelList[i].RemainingTimeForUse == 0)) + { + /* found radar signal in the channel. the channel can't use at least for 30 minutes.*/ + pAd->ChannelList[i].RemainingTimeForUse = 1800;/*30 min = 1800 sec*/ + Result = TRUE; + break; + } + } + } while(FALSE); + + return Result; +} + +VOID NotifyChSwAnnToPeerAPs( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pRA, + IN PUCHAR pTA, + IN UINT8 ChSwMode, + IN UINT8 Channel) +{ +#ifdef WDS_SUPPORT + if (!((pRA[0] & 0xff) == 0xff)) /* is pRA a broadcase address.*/ + { + INT i; + /* info neighbor APs that Radar signal found throgh WDS link.*/ + for (i = 0; i < MAX_WDS_ENTRY; i++) + { + if (ValidWdsEntry(pAd, i)) + { + PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr; + + /* DA equal to SA. have no necessary orignal AP which found Radar signal.*/ + if (MAC_ADDR_EQUAL(pTA, pDA)) + continue; + + /* send Channel Switch Action frame to info Neighbro APs.*/ + EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel); + } + } + } +#endif /* WDS_SUPPORT */ +} + +static VOID StartDFSProcedure( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN UINT8 ChSwMode) +{ + /* start DFS procedure*/ + pAd->CommonCfg.Channel = Channel; +#ifdef DOT11_N_SUPPORT + N_ChannelCheck(pAd); +#endif /* DOT11_N_SUPPORT */ + pAd->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> 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> 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> 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: 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: 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: 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: 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; IdAcpUAPSDEOSPFrame != 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; IdAcUAPSDTxNum = 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 */ +/*#include */ +/*#include */ +/*#include */ + +#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 +#include +#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; iMacTab.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; iStaCfg.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 */ +/*#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 = 4* + time_mid = 2* + time_high_and_version = 2* + clock_seq_high_and_reserved = + clock_seq_low = + node = 6* + hex_octet = + 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): + + *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; iMacTab.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; iMacTab.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; iSharedKey[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; iApCfg.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; jjjKeyLength; 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 */ + /* 0x106F ¡V 0x1FFF*/ + /* 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 = ""; +static const STRING *XML_SSID_START = "\n" +"\n" +" \n" +" CFG_GUID" +"\n" +" CFG_AP_GUID" +"\n" +" Ralink WPS AP\n" +" \n" +" CFG_SSID" +"\n" +" ESS\n" +" 0\n" +" 0\n" +" \n" +" CFG_AUTH" +"\n" +" CFG_ENCR" +"\n" +" CFG_KEY" +"\n" +" 0\n" +" 0\n" +" \n" +"\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 \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 "); + if (ptr) + { + pBuffer = ptr + 1; + } + + ptr = rtstrstr(pBuffer, (PSTRING)XML_SSID_END); + if (ptr == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("WscGetXmlSSID: missing \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; iNum; 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; iBbpWriteLatch[_I]; \ + RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);\ + BbpCsr.field.Busy = 0; \ + RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);\ + } \ + } \ +} + + +/* + * proc fs related macros. + */ +#define CREATE_PROC_ENTRY(x) \ + if ((pProc##x = create_proc_entry(#x, 0, pProcDir))){ \ + pProc##x->read_proc = (read_proc_t*)&x##Read; \ + pProc##x->write_proc = (write_proc_t*)&x##Write; \ + } \ + +#define IMPLEMENT_PROC_ENTRY(x,y,z) \ +static struct proc_dir_entry *pProc##x; \ +IMPLEMENT_PROC_ENTRY_READ(x,y,z) \ +IMPLEMENT_PROC_ENTRY_WRITE(x,y,z) + +#define IMPLEMENT_PROC_ENTRY_READ(x,y,z) \ +static INT x##Read(char *page, char **start, off_t off, \ + int count, int *eof, void *data){ \ + INT len; \ + sprintf(page, "%d\n", atomic_read(&x)); \ + len = strlen(page) + 1; \ + *eof = 1; \ + return len; \ +} +#define IMPLEMENT_PROC_ENTRY_WRITE(x,y,z) \ +static INT x##Write(struct file *file, const char *buffer, \ + unsigned long count, void *data){ \ + CHAR tmp[32];INT tmp_val; \ + if (count > 32) count = 32; \ + memset(tmp, 0, 32); \ + if (copy_from_user(tmp, buffer, count)) \ + return -EFAULT; \ + tmp_val = simple_strtol(tmp, 0, 10); \ + if(tmp_val > z || tmp_val < y) \ + return -EFAULT; \ + atomic_set(&x, (int)tmp_val); \ + return count; \ +} +#define DESTORY_PROC_ENTRY(x) if (pProc##x) remove_proc_entry(#x, pProcDir); + +/* + * function prototype + */ +VOID RT3XXX_AntDiversity_Init( + IN 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 + +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 */ + + + +/* 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 +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef RTMP_USB_SUPPORT +#include +#endif /* RTMP_USB_SUPPORT */ +#include +#include + +#ifdef INF_PPA_SUPPORT +#include +#include +#endif /* INF_PPA_SUPPORT */ + +/* load firmware */ +#define __KERNEL_SYSCALLS__ +#include +#include +#include +#include /* for get_unaligned() */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#include +#endif + +#ifdef RT_CFG80211_SUPPORT +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) +#include +#define EXT_BUILD_CHANNEL_LIST /* must define with CRDA */ +#else /* LINUX_VERSION_CODE */ +#undef RT_CFG80211_SUPPORT +#endif /* LINUX_VERSION_CODE */ +#endif /* RT_CFG80211_SUPPORT */ + +#ifdef MAT_SUPPORT +#include +#include +#include +#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 +#include +#endif /* KTHREAD_SUPPORT */ + + +#include "os/rt_linux_cmm.h" + +#ifdef RT_CFG80211_SUPPORT +#include "cfg80211.h" +#endif /* RT_CFG80211_SUPPORT */ + +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + +#ifdef CONFIG_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 +#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<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 + +#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; __IdAcUAPSDQueue[__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; __IdAcUAPSDQueue[__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 + +#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. */ +#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<UserPriority)) != 0) ? TRUE : FALSE)); + + + if ((pAd->force_amsdu == TRUE) && (pTxBlk->TxFrameType == TX_AMSDU_FRAME) + && (pMacEntry && ((pMacEntry->TXBAbitmap & (1<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 Binary files /dev/null and b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601.bin 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 Binary files /dev/null and b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5.bin 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 Binary files /dev/null and b/cleopatre/devkit/mt7601udrv/mcu/bin/MT7601_formal_1.5_Debug.bin 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; iMACVersion >> 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 + + +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; iMacTab.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<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 + + +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 + +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 +#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, ®Value); + 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; iBeaconOffset[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; IdChanCommonCfg.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; IdPwrTxPower[IdPwr].Channel) + { + /* init the channel info. */ + NdisMoveMemory(&pAd->ChannelList[RecId], + &pAd->TxPower[IdPwr], + sizeof(CHANNEL_TX_POWER)); + + /* keep channel number */ + pAd->ChannelList[RecId].Channel = ChanId; + + /* keep maximum tranmission power */ + pAd->ChannelList[RecId].MaxTxPwr = Power; + + /* keep DFS flag */ + if (FlgIsRadar == TRUE) + pAd->ChannelList[RecId].DfsReq = TRUE; + else + pAd->ChannelList[RecId].DfsReq = FALSE; + /* End of if */ + + /* keep DFS type */ + pAd->ChannelList[RecId].RegulatoryDomain = DfsType; + + /* re-set DFS info. */ + 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 +#include + +extern INT rt28xx_send_packets( + IN struct sk_buff *skb_p, + IN struct net_device *net_dev); + +int ifx_ra_start_xmit( + struct net_device *rx_dev, + struct net_device *tx_dev, + struct sk_buff *skb, int len) +{ + if(tx_dev != NULL) + { + SET_OS_PKT_NETDEV(skb, tx_dev); + rt28xx_send_packets(skb, tx_dev); + } + else if(rx_dev != NULL) + { + skb->protocol = eth_type_trans(skb, skb->dev); + netif_rx(skb); + } + else + { + dev_kfree_skb_any(skb); + } + return 0; +} +#endif /* INF_PPA_SUPPORT */ diff --git a/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 + +#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(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); + + /* Allow interception of SIGKILL only + * Don't allow other signals to interrupt the transmission */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + spin_lock_irqsave(¤t->sigmask_lock, flags); + flush_signals(current); + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); +#endif +#endif + + RTMP_GET_OS_PID(pTask->taskPID, current->pid); + + /* signal that we've started the thread */ + complete(&pTask->taskComplete); + +#endif +} + +static inline NDIS_STATUS __RtmpOSTaskAttach( + IN OS_TASK *pTask, + IN RTMP_OS_TASK_CALLBACK fn, + IN ULONG arg) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#ifndef KTHREAD_SUPPORT + pid_t pid_number = -1; +#endif /* KTHREAD_SUPPORT */ + +#ifdef KTHREAD_SUPPORT + pTask->task_killed = 0; + pTask->kthread_task = NULL; + pTask->kthread_task = + kthread_run((cast_fn) fn, (void *)arg, pTask->taskName); + if (IS_ERR(pTask->kthread_task)) + status = NDIS_STATUS_FAILURE; +#else + pid_number = + kernel_thread((cast_fn) fn, (void *)arg, RTMP_OS_MGMT_TASK_FLAGS); + if (pid_number < 0) { + DBGPRINT(RT_DEBUG_ERROR, + ("Attach task(%s) failed!\n", pTask->taskName)); + status = NDIS_STATUS_FAILURE; + } else { + /* Wait for the thread to start */ + wait_for_completion(&pTask->taskComplete); + status = NDIS_STATUS_SUCCESS; + } +#endif + return status; +} + +static inline NDIS_STATUS __RtmpOSTaskInit( + IN OS_TASK *pTask, + IN PSTRING pTaskName, + IN VOID *pPriv, + IN LIST_HEADER *pSemList) +{ + int len; + + ASSERT(pTask); + +#ifndef KTHREAD_SUPPORT + NdisZeroMemory((PUCHAR) (pTask), sizeof (OS_TASK)); +#endif + + len = strlen(pTaskName); + len = len > (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len; + NdisMoveMemory(&pTask->taskName[0], pTaskName, len); + pTask->priv = pPriv; + +#ifndef KTHREAD_SUPPORT + RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema), pSemList); + pTask->taskPID = THREAD_PID_INIT_VALUE; + init_completion(&pTask->taskComplete); +#endif + +#ifdef KTHREAD_SUPPORT + init_waitqueue_head(&(pTask->kthread_q)); +#endif /* KTHREAD_SUPPORT */ + + return NDIS_STATUS_SUCCESS; +} + +BOOLEAN __RtmpOSTaskWait( + IN VOID *pReserved, + IN OS_TASK *pTask, + IN INT32 *pStatus) +{ +#ifdef KTHREAD_SUPPORT + RTMP_WAIT_EVENT_INTERRUPTIBLE((*pStatus), pTask); + + if ((pTask->task_killed == 1) || ((*pStatus) != 0)) + return FALSE; +#else + + RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), (*pStatus)); + + /* unlock the device pointers */ + if ((*pStatus) != 0) { +/* RTMP_SET_FLAG_(*pFlags, fRTMP_ADAPTER_HALT_IN_PROGRESS); */ + return FALSE; + } +#endif /* KTHREAD_SUPPORT */ + + return TRUE; +} + + +#if LINUX_VERSION_CODE <= 0x20402 /* Red Hat 7.1 */ +struct net_device *alloc_netdev( + int sizeof_priv, + const char *mask, + void (*setup) (struct net_device *)) +{ + struct net_device *dev; + INT alloc_size; + + /* ensure 32-byte alignment of the private area */ + alloc_size = sizeof (*dev) + sizeof_priv + 31; + + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + if (dev == NULL) { + DBGPRINT(RT_DEBUG_ERROR, + ("alloc_netdev: Unable to allocate device memory.\n")); + return NULL; + } + + memset(dev, 0, alloc_size); + + if (sizeof_priv) + dev->priv = (void *)(((long)(dev + 1) + 31) & ~31); + + setup(dev); + strcpy(dev->name, mask); + + return dev; +} +#endif /* LINUX_VERSION_CODE */ + + +static UINT32 RtmpOSWirelessEventTranslate(IN UINT32 eventType) +{ + switch (eventType) { + case RT_WLAN_EVENT_CUSTOM: + eventType = IWEVCUSTOM; + break; + + case RT_WLAN_EVENT_CGIWAP: + eventType = SIOCGIWAP; + break; + +#if WIRELESS_EXT > 17 + case RT_WLAN_EVENT_ASSOC_REQ_IE: + eventType = IWEVASSOCREQIE; + break; +#endif /* WIRELESS_EXT */ + +#if WIRELESS_EXT >= 14 + case RT_WLAN_EVENT_SCAN: + eventType = SIOCGIWSCAN; + break; +#endif /* WIRELESS_EXT */ + + case RT_WLAN_EVENT_EXPIRED: + eventType = IWEVEXPIRED; + break; + + default: + printk("Unknown event: 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; IdLoopCfg80211_bands[IEEE80211_BAND_2GHZ]; + if (pBandInfo->RFICType & RFIC_24GHZ) + { + pBand->n_channels = CFG80211_NUM_OF_CHAN_2GHZ; + pBand->n_bitrates = NumOfRate; + pBand->channels = pChannels; + pBand->bitrates = pRates; + +#ifdef DOT11_N_SUPPORT + /* for HT, assign pBand->ht_cap */ + pBand->ht_cap.ht_supported = true; + pBand->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_SM_PS | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_DSSSCCK40; + pBand->ht_cap.ampdu_factor = 3; /* 2 ^ 16 */ + pBand->ht_cap.ampdu_density = pBandInfo->MpduDensity; + + memset(&pBand->ht_cap.mcs, 0, sizeof(pBand->ht_cap.mcs)); + CFG80211DBG(RT_DEBUG_ERROR, + ("80211> TxStream = %d\n", pBandInfo->TxStream)); + + switch(pBandInfo->TxStream) + { + case 1: + default: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + break; + + case 2: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + pBand->ht_cap.mcs.rx_mask[1] = 0xff; + break; + + case 3: + pBand->ht_cap.mcs.rx_mask[0] = 0xff; + pBand->ht_cap.mcs.rx_mask[1] = 0xff; + pBand->ht_cap.mcs.rx_mask[2] = 0xff; + break; + } + + 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 +#include +#include +#include + +#include "rt_config.h" + +int wl_proc_init(void); +int wl_proc_exit(void); + +#ifdef CONFIG_RALINK_RT2880 +#define PROCREG_DIR "rt2880" +#endif /* CONFIG_RALINK_RT2880 */ + +#ifdef CONFIG_RALINK_RT3052 +#define PROCREG_DIR "rt3052" +#endif /* CONFIG_RALINK_RT3052 */ + +#ifdef CONFIG_RALINK_RT2883 +#define PROCREG_DIR "rt2883" +#endif /* CONFIG_RALINK_RT2883 */ + +#ifdef CONFIG_RALINK_RT3883 +#define PROCREG_DIR "rt3883" +#endif /* CONFIG_RALINK_RT3883 */ + +#ifdef CONFIG_RALINK_RT5350 +#define PROCREG_DIR "rt5350" +#endif /* CONFIG_RALINK_RT5350 */ + +#ifndef PROCREG_DIR +#define PROCREG_DIR "rt2880" +#endif /* PROCREG_DIR */ + +#ifdef CONFIG_PROC_FS +extern struct proc_dir_entry *procRegDir; + +#ifdef VIDEO_TURBINE_SUPPORT +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_indexApCfg.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 +#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 "); +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; iNumberOfPipes; 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 +#include +#include +#include +#include +#include + + +#ifdef IKANOS_VX_1X0 + +#define IKANOS_PERAP_ID 7 /* IKANOS Fix Peripheral ID */ +#define K0_TO_K1(x) ((unsigned)(x)|0xA0000000) /* kseg0 to kseg1 */ +/*#define IKANOS_DEBUG */ + + +extern INT rt28xx_send_packets( + IN struct sk_buff *skb_p, + IN struct net_device *net_dev); + +static INT32 IKANOS_WlanDataFramesTx( + IN void *_pAdBuf, + IN struct net_device *pNetDev); + +static void IKANOS_WlanPktFromAp( + IN apPreHeader_t *pFrame); + +static INT32 GetSpecInfoIdxFromBssid( + IN PRTMP_ADAPTER pAd, + IN INT32 FromWhichBSSID); + + + + +/* --------------------------------- Public -------------------------------- */ + +/* +======================================================================== +Routine Description: + Init IKANOS fast path function. + +Arguments: + pApMac - the MAC of AP + +Return Value: + None + +Note: + If you want to enable RX fast path, you must call the function. +======================================================================== +*/ +void VR_IKANOS_FP_Init( + IN UINT8 BssNum, + IN UINT8 *pApMac) +{ + UINT32 i; + UINT8 mac[6]; + + + memcpy(mac, pApMac, 6); + + /* add all MAC of multiple BSS */ + for(i=0; i WLAN transmit fast path function. + +Arguments: + skb - the transmitted packet (SKB packet format) + netdev - our WLAN network device + +Return Value: + + +Note: +======================================================================== +*/ +INT32 IKANOS_DataFramesTx( + IN struct sk_buff *pSkb, + IN struct net_device *pNetDev) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pNetDev->priv; + IkanosWlanTxCbFuncP *fp = &IKANOS_WlanDataFramesTx; + + pSkb->apFlowData.txDev = pNetDev; + pSkb->apFlowData.txApId = IKANOS_PERAP_ID; + pAd->IkanosTxInfo.netdev = pNetDev; + pAd->IkanosTxInfo.fp = fp; + pSkb->apFlowData.txHandle = &(pAd->IkanosTxInfo); + ap2apFlowProcess(pSkb, pNetDev); + +#ifdef IKANOS_DEBUG + printk("ikanos> tx no fp\n"); /* debug use */ +#endif /* IKANOS_DEBUG */ + + return rt28xx_send_packets(pSkb, pNetDev); +} /* End of IKANOS_DataFramesTx */ + + +/* +======================================================================== +Routine Description: + Ikanos WLAN --> LAN transmit fast path function. + +Arguments: + pAd - WLAN control block + pRxParam - + pSkb - the transmitted packet (SKB packet format) + Length - packet length + +Return Value: + None + +Note: +======================================================================== +*/ +/* Note: because no unsigned long private parameters in apPreHeader_t can be used, + we use a global variable to record pAd. + So we can not use multiple card function in Ikanos platform. */ +PRTMP_ADAPTER pIkanosAd; + +void IKANOS_DataFrameRx( + IN PRTMP_ADAPTER pAd, + IN struct sk_buff *pSkb) +{ + apPreHeader_t *apBuf; + void *pRxParam = pSkb->dev; + UINT32 Length = pSkb->len; + + + apBuf = (apPreHeader_t *)(translateMbuf2Apbuf(pSkb, 0)); + + apBuf->flags1 = 1 << AP_FLAG1_IS_ETH_BIT; + apBuf->specInfoElement = RTMP_GET_PACKET_NET_DEVICE_MBSSID(pSkb); /* MBSS */ + pIkanosAd = pAd; + +/* apBuf->egressList[0].pEgress = NULL; */ +/* apBuf->egressList[0].pFlowID = NULL; */ + apBuf->flags2 = 0; + + apClassify(IKANOS_PERAP_ID, apBuf, (void *)IKANOS_WlanPktFromAp); + dev_kfree_skb(pSkb); +} /* End of IKANOS_DataFrameRx */ + + + + +/* --------------------------------- Private -------------------------------- */ + +/* +======================================================================== +Routine Description: + Ikanos LAN --> WLAN transmit fast path function. + +Arguments: + _pAdBuf - the transmitted packet (Ikanos packet format) + netdev - our WLAN network device + +Return Value: + + +Note: +======================================================================== +*/ +static INT32 IKANOS_WlanDataFramesTx( + IN void *_pAdBuf, + IN struct net_device *pNetDev) +{ + apPreHeader_t *pApBuf = (apPreHeader_t *)_pAdBuf; + struct sk_buff *sk = NULL; + + sk = (struct sk_buff *)translateApbuf2Mbuf(pApBuf); + if (sk == NULL) + { + printk("ikanos> translateApbuf2Mbuf returned NULL!\n"); + return 1; + } /* End of if */ + + sk->apFlowData.flags2 = 0; + sk->apFlowData.wlanFlags = 0; + sk->protocol = ETH_P_IP; + sk->dev = pNetDev; + sk->priority = 0; + + return rt28xx_send_packets(sk, pNetDev); +} /* End of IKANOS_WlanDataFramesTx */ + + +static INT32 GetSpecInfoIdxFromBssid( + IN PRTMP_ADAPTER pAd, + IN INT32 FromWhichBSSID) +{ + INT32 IfIdx = MAIN_MBSSID; + +#ifdef CONFIG_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; +} + +/* + <> + 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; ireg_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; ireg_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 PERCommonCfg.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 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=[::] +*/ +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; iMacTab.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; iMacTab.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 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; idxCurrMCS==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<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 +#include +#include + +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 -- cgit v1.2.3