diff --git a/package/lean/mt/drivers/mt_wifi/Makefile b/package/lean/mt/drivers/mt_wifi/Makefile new file mode 100644 index 000000000..3a4ae8530 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/Makefile @@ -0,0 +1,224 @@ +# All rights reserved. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=mt_wifi +P4REV:=8 +PKG_VERSION:=5.0.2.0 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME) +PKG_KCONFIG:= \ + AP_SUPPORT \ + RT_FIRST_CARD \ + RT_SECOND_CARD \ + RT_FIRST_IF_RF_OFFSET \ + RT_SECOND_IF_RF_OFFSET \ + MT_WIFI \ + WIFI_BASIC_FUNC \ + MT_WIFI_PATH \ + FIRST_IF_NONE \ + FIRST_IF_EEPROM_FLASH \ + FIRST_IF_EEPROM_EFUSE \ + RT_FIRST_CARD_EEPROM \ + SECOND_IF_NONE \ + SECOND_IF_EEPROM_FLASH \ + SECOND_IF_EEPROM_PROM \ + SECOND_IF_EEPROM_EFUSE \ + RT_SECOND_CARD_EEPROM \ + MULTI_INF_SUPPORT \ + WIFI_BASIC_FUNC \ + WIRELESS_EXT \ + WEXT_SPY \ + WEXT_PRIV \ + DOT11_N_SUPPORT \ + DOT11_VHT_AC \ + WIFI_DRIVER \ + G_BAND_256QAM_SUPPORT \ + BRCM_256QAM_SUPPORT \ + ICAP_SUPPORT \ + MT_AP_SUPPORT \ + BACKGROUND_SCAN_SUPPORT \ + SMART_CARRIER_SENSE_SUPPORT \ + MT_DFS_SUPPORT \ + HDR_TRANS_TX_SUPPORT \ + CHIP_MT7615E \ + HDR_TRANS_RX_SUPPORT \ + DBDC_MODE \ + MULTI_PROFILE_SUPPORT \ + DEFAULT_5G_PROFILE \ + SUPPORT_DYNAMIC_TXOP \ + WSC_INCLUDED \ + MT_STA_SUPPORT \ + WSC_V2_SUPPORT \ + DOT11W_PMF_SUPPORT \ + PASSPOINT_R2 \ + TXBF_SUPPORT \ + IGMP_SNOOP_SUPPORT \ + RATE_ADAPTION \ + RATE_ADAPT_AGBS_SUPPORT \ + RTMP_FLASH_SUPPORT \ + ATE_SUPPORT \ + UAPSD \ + RLT_MAC \ + RLT_BBP \ + RLT_RF \ + RTMP_MAC \ + RTMP_BBP \ + RTMP_RF \ + RTMP_PCI_SUPPORT \ + RTMP_USB_SUPPORT \ + RTMP_RBUS_SUPPORT \ + WIFI_MODE_AP \ + WIFI_MODE_STA \ + WIRELESS_EXT \ + WEXT_SPY \ + WEXT_PRIV \ + WDS_SUPPORT \ + MBSS_SUPPORT \ + APCLI_SUPPORT \ + APCLI_CERT_SUPPORT \ + MAC_REPEATER_SUPPORT \ + RALINK_RT6352 \ + RALINK_MT7620 \ + RALINK_MT7603E \ + CON_WPS_SUPPORT \ + VOW_SUPPORT \ + BAND_STEERING \ + TXOP_ARBITER \ + CFG_SUPPORT_DYNAMIC_TXOP \ + WIFI_MODE_BOTH \ + WIFI_RLT_MAC \ + RLT_MAC \ + WIFI_RTMP_MAC \ + RTMP_MAC \ + WIFI_MT_MAC \ + CHIP_MT7603E \ + CHIP_MT7615E \ + MT_MAC \ + RATE_ADAPTION \ + SUPPORT_OPENWRT \ + SDK_USER_LIGHTY \ + MUMIMO_SUPPORT \ + MU_RA_SUPPORT \ + LED_CONTROL_SUPPORT \ + RA_HW_NAT \ + RA_HW_NAT_WIFI_NEW_ARCH \ + CFG80211_SUPPORT \ + SER_SUPPORT \ + GREENAP_SUPPORT \ + RADIUS_ACCOUNTING_SUPPORT \ + TPC_SUPPORT \ + RLM_CAL_CACHE_SUPPORT \ + RF_LOCKDOWN_SUPPORT \ + PASSPOINT_R2 \ + RED_SUPPORT \ + FIRST_IF_EPAELNA \ + FIRST_IF_IPAILNA \ + FIRST_IF_IPAELNA \ + FIRST_IF_EPAILNA \ + SECOND_IF_EPAELNA \ + SECOND_IF_IPAILNA \ + SECOND_IF_IPAELNA \ + SECOND_IF_EPAILNA \ + THIRD_IF_EPAELNA \ + THIRD_IF_IPAILNA \ + THIRD_IF_IPAELNA \ + THIRD_IF_EPAILNA \ + WIFI_PKT_FWD \ + DOT11K_RRM_SUPPORT \ + DOT11R_FT_SUPPORT \ + MBO_SUPPORT \ + WIFI_PKT_FWD_V1 \ + FIRST_IF_MT7615E \ + FIRST_IF_MT7622 \ + FIRST_IF_MT7626 \ + SECOND_IF_MT7615E \ + THIRD_IF_NONE \ + THIRD_IF_MT7615E \ + RT_THIRD_CARD \ + RT_THIRD_IF_RF_OFFSET \ + THIRD_IF_EEPROM_FLASH \ + THIRD_IF_EEPROM_PROM \ + THIRD_IF_EEPROM_EFUSE \ + RT_THIRD_CARD_EEPROM \ + SPECTRUM_SUPPORT \ + MULTI_PROFILE_SUPPORT \ + PRE_CAL_TRX_SET1_SUPPORT \ + MWDS \ + MCAST_RATE_SPECIFIC \ + WLAN_HOOK \ + COEX_SUPPORT \ + EASY_SETUP_SUPPORT \ + EVENT_NOTIFIER_SUPPORT \ + AIR_MONITOR \ + WNM_SUPPORT \ + INTERWORKING \ + LINUX_NET_TXQ_SUPPORT \ + CHIP_MT7622 \ + CHIP_MT7626 \ + WHNAT_SUPPORT \ + FAST_NAT_SUPPORT \ + PRE_CAL_TRX_SET2_SUPPORT \ + LINK_TEST_SUPPORT \ + TCP_RACK_SUPPORT \ + FQ_SCH_SUPPORT \ + BRCM_256QAM_SUPPORT \ + VHT_TXBF_2G_EPIGRAM_IE_SUPPORT \ + DSCP_PRI_SUPPORT \ + PCIE_ASPM_DYM_CTRL_SUPPORT \ + +PKG_CONFIG_DEPENDS:=$(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_MTK_$c),CONFIG_$(c))) + +include $(INCLUDE_DIR)/package.mk + +TAR_CMD=$(HOST_TAR) -C $(1)/ $(TAR_OPTIONS) + +define KernelPackage/mt_wifi + CATEGORY:=Kernel modules + TITLE:=MTK wifi AP driver + DEPENDS:=+wifi-l1profile +ifneq ($(CONFIG_MTK_WHNAT_SUPPORT), ) + FILES:=$(PKG_BUILD_DIR)/mt_wifi_ap/mt_wifi.ko \ + $(PKG_BUILD_DIR)/mt_wifi/embedded/tools/plug_in/whnat/mt_whnat.ko + AUTOLOAD:=$(call AutoProbe,mt_wifi mt_whnat) +else + FILES:=$(PKG_BUILD_DIR)/mt_wifi_ap/mt_wifi.ko + AUTOLOAD:=$(call AutoProbe,mt_wifi) +endif + SUBMENU:=Wireless Drivers + MENU:=1 +endef + +define KernelPackage/mt_wifi/config + source "$(SOURCE)/config.in" +endef + + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" V=1 \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + SUBDIRS="$(PKG_BUILD_DIR)/mt_wifi_ap" \ + $(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_MTK_$c),CONFIG_$(c)=$(CONFIG_MTK_$(c)))) \ + modules +endef + +define KernelPackage/mt_wifi/install + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_DIR) $(1)/lib/wifi/ + $(INSTALL_DIR) $(1)/etc/wireless/mt7615/ + $(INSTALL_DIR) $(1)/etc_ro/Wireless/RT2860AP/ + $(INSTALL_BIN) ./files/mt7615.1.2G.dat $(1)/etc/wireless/mt7615/ + $(INSTALL_BIN) ./files/mt7615.1.5G.dat $(1)/etc/wireless/mt7615/ + $(INSTALL_BIN) ./files/SingleSKU.dat $(1)/etc_ro/Wireless/RT2860AP/ + $(INSTALL_BIN) ./files/SingleSKU_BF.dat $(1)/etc_ro/Wireless/RT2860AP/ + $(INSTALL_BIN) ./files/mt7615.lua $(1)/lib/wifi + $(INSTALL_BIN) ./files/firmware.sh $(1)/etc/init.d/ + +endef + +$(eval $(call KernelPackage,mt_wifi)) diff --git a/package/lean/mt/drivers/mt_wifi/config.in b/package/lean/mt/drivers/mt_wifi/config.in new file mode 100644 index 000000000..a4992059d --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/config.in @@ -0,0 +1,868 @@ +if PACKAGE_kmod-mt_wifi + +config MTK_SUPPORT_OPENWRT + bool + default y + depends on PACKAGE_kmod-mt_wifi + +config MTK_WIFI_DRIVER + bool + default y + depends on PACKAGE_kmod-mt_wifi + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_FIRST_IF_MT7615E + #select MTK_CHIP_MT7622 + #select MTK_CHIP_MT7626 + #select MTK_SECOND_IF_MT7615E + #select MTK_THIRD_IF_MT7615E + #select MTK_CHIP_MT7615E + +if MTK_WIFI_DRIVER + +choice + prompt "Choose First WiFi Interface" + + config MTK_FIRST_IF_MT7615E + bool "MT7615E" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7615E + + config MTK_FIRST_IF_MT7622 + bool "MT7622" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7622 + + config MTK_FIRST_IF_MT7626 + bool "MT7626" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7626 + + config MTK_FIRST_IF_NONE + bool "None" +endchoice + +choice + prompt "Choose Second WiFi Interface" + config MTK_SECOND_IF_NONE + bool "None" + + config MTK_SECOND_IF_MT7615E + bool "MT7615E" + select MTK_WIFI_MT_MAC + select MTK_CHIP_MT7615E + select MTK_MULTI_INF_SUPPORT + +endchoice + +choice + prompt "Choose Third WiFi Interface" + config MTK_THIRD_IF_NONE + bool "None" + + config MTK_THIRD_IF_MT7615E + bool "MT7615E" + select MTK_WIFI_MT_MAC + select MTK_CHIP_MT7615E + select MTK_MULTI_INF_SUPPORT + +endchoice + +config MTK_RT_FIRST_CARD + int + depends on ! MTK_FIRST_IF_NONE + default 7615 if MTK_FIRST_IF_MT7615E + default 7622 if MTK_FIRST_IF_MT7622 + default 7626 if MTK_FIRST_IF_MT7626 + +config MTK_RT_SECOND_CARD + int + depends on ! MTK_SECOND_IF_NONE + default 7615 if MTK_SECOND_IF_MT7615E + +config MTK_RT_THIRD_CARD + int + depends on ! MTK_THIRD_IF_NONE + default 7615 if MTK_THIRD_IF_MT7615E + +config MTK_RT_FIRST_IF_RF_OFFSET + hex + depends on ! MTK_FIRST_IF_NONE + default 0xc0000 + +config MTK_RT_SECOND_IF_RF_OFFSET + hex + depends on ! MTK_SECOND_IF_NONE + default 0xc8000 + +config MTK_RT_THIRD_IF_RF_OFFSET + hex + depends on ! MTK_THIRD_IF_NONE + default 0xd0000 + +config MTK_MT_WIFI + tristate "MT WIFI Driver" + select MTK_WIFI_BASIC_FUNC if MTK_MT_WIFI + default y + +config MTK_MT_WIFI_PATH + string + depends on MTK_MT_WIFI + default "mt_wifi" + +if MTK_MT_WIFI +menu "WiFi Generic Feature Options" +choice + prompt "EEPROM Type of 1st Card" + depends on ! MTK_FIRST_IF_NONE + + config MTK_FIRST_IF_EEPROM_FLASH + bool "FLASH" + + config MTK_FIRST_IF_EEPROM_PROM + bool "EEPROM" + + config MTK_FIRST_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config MTK_RT_FIRST_CARD_EEPROM + string + depends on ! MTK_FIRST_IF_NONE + default "prom" if MTK_FIRST_IF_EEPROM_PROM + default "efuse" if MTK_FIRST_IF_EEPROM_EFUSE + default "flash" if MTK_FIRST_IF_EEPROM_FLASH + +choice + prompt "EEPROM Type of 2nd Card" + depends on ! MTK_SECOND_IF_NONE + + config MTK_SECOND_IF_EEPROM_FLASH + bool "FLASH" + + config MTK_SECOND_IF_EEPROM_PROM + bool "EEPROM" + + config MTK_SECOND_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config MTK_RT_SECOND_CARD_EEPROM + string + depends on ! MTK_SECOND_IF_NONE + default "prom" if MTK_SECOND_IF_EEPROM_PROM + default "efuse" if MTK_SECOND_IF_EEPROM_EFUSE + default "flash" if MTK_SECOND_IF_EEPROM_FLASH + +choice + prompt "EEPROM Type of 3th Card" + depends on ! MTK_THIRD_IF_NONE + + config MTK_THIRD_IF_EEPROM_FLASH + bool "FLASH" + + config MTK_THIRD_IF_EEPROM_PROM + bool "EEPROM" + + config MTK_THIRD_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config MTK_RT_THIRD_CARD_EEPROM + string + depends on ! MTK_THIRD_IF_NONE + default "prom" if MTK_THIRD_IF_EEPROM_PROM + default "efuse" if MTK_THIRD_IF_EEPROM_EFUSE + default "flash" if MTK_THIRD_IF_EEPROM_FLASH + +config MTK_MULTI_INF_SUPPORT + bool + default y if !MTK_FIRST_IF_NONE && !MTK_SECOND_IF_NONE + +config MTK_WIFI_BASIC_FUNC + bool "Basic Functions" + select MTK_WIRELESS_EXT + select MTK_WEXT_SPY + select MTK_WEXT_PRIV + +config MTK_DOT11_N_SUPPORT + bool "802.11n support" + default y + +config MTK_DOT11_VHT_AC + bool "802.11AC support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_N_SUPPORT + default y + +config MTK_G_BAND_256QAM_SUPPORT + bool "2.4G 256QAM support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_VHT_AC + default y + +config MTK_BRCM_256QAM_SUPPORT + bool "BRCM 2.4G 256QAM support" + depends on MTK_WIFI_DRIVER + depends on MTK_G_BAND_256QAM_SUPPORT + default y + +config MTK_VHT_TXBF_2G_EPIGRAM_IE_SUPPORT + bool "BRCM 2.4G VHT Sounding support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_TPC_SUPPORT + bool "802.11h TPC Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_ICAP_SUPPORT + bool "ICAP Support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_SPECTRUM_SUPPORT + bool "Wifi Spectrum Support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_BACKGROUND_SCAN_SUPPORT + bool "Background Scan Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_SMART_CARRIER_SENSE_SUPPORT + bool "Smart Carrier Sense Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_MT_DFS_SUPPORT + bool "Dynamic Frequency Selection Support" + depends on MTK_WIFI_DRIVER + default y + +#config WFA_VHT_R2_PF +# bool "WFA VHT R2 Plugfest" +# depends on DOT11_VHT_AC +# default n + +config MTK_HDR_TRANS_TX_SUPPORT + bool "Tx Header Translation" + depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7622 || MTK_CHIP_MT7626 + default y + +config MTK_HDR_TRANS_RX_SUPPORT + bool "Rx Header Translation" + depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7622 || MTK_CHIP_MT7626 + default y + +config MTK_DBDC_MODE + bool "dbdc mode support" + depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7626 + select MULTI_PROFILE_SUPPORT + select DEFAULT_5G_PROFILE + default y + +config MTK_MULTI_PROFILE_SUPPORT + bool "Multi Profile Support" + depends on MTK_DBDC_MODE + default y + +config MTK_DEFAULT_5G_PROFILE + bool "5G default profile for DBDC" + depends on MTK_DBDC_MODE +# depends on MTK_MULTI_PROFILE_SUPPORT + default n + +config MTK_WSC_INCLUDED + bool "WSC (WiFi Simple Config)" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_WSC_V2_SUPPORT + bool "WSC V2(WiFi Simple Config Version 2.0)" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_DOT11W_PMF_SUPPORT + bool "PMF" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_TXBF_SUPPORT + bool "Tx Bean Forming Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_FAST_NAT_SUPPORT + bool "Fast-NAT support" +# depends on RA_HW_NAT_WIFI + default n + +config MTK_WHNAT_SUPPORT + tristate "Wifi Hardware NAT support" + depends on MTK_CHIP_MT7615E + depends on MTK_WLAN_HOOK + depends on MTK_FAST_NAT_SUPPORT + select PACKAGE_kmod-hw_nat + default n + +#config LLTD_SUPPORT +# bool "LLTD (Link Layer Topology Discovery Protocol)" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config QOS_DLS_SUPPORT +# bool "802.11e DLS ((Direct-Link Setup) Support" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config WAPI_SUPPORT +# bool "WAPI Support" +# depends on WIFI_DRIVER +# default n + +config MTK_FTM_SUPPORT + bool "FTM Support" + depends on MTK_WIFI_DRIVER + select MTK_PASSPOINT_R2 + default n + +#config CARRIER_DETECTION_SUPPORT +# bool "Carrier Detect" +# depends on WIFI_DRIVER +# default n + +config MTK_IGMP_SNOOP_SUPPORT + bool "IGMP snooping" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default y + +#config BLOCK_NET_IF +# bool "NETIF Block" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n +# help +# Support Net interface block while Tx-Sw queue full + +#config RATE_ADAPTION +# bool "New Rate Adaptation support" +# depends on WIFI_DRIVER +# default y + +#config NEW_RATE_ADAPT_SUPPORT +# bool "Intelligent Rate Adaption" +# depends on WIFI_DRIVER && RATE_ADAPTION +# default y + +#config AGS_SUPPORT +# bool "Adaptive Group Switching" +# depends on WIFI_DRIVER && RATE_ADAPTION +# depends on MT_AP_SUPPORT || MT_STA_SUPPORT +# default n + +#config RATE_ADAPT_AGBS_SUPPORT +# bool "Adaptive AGBS Mode" +# depends on WIFI_DRIVER && RATE_ADAPTION +# depends on MT_AP_SUPPORT || MT_STA_SUPPORT +# default y + +#config IDS_SUPPORT +# bool "IDS (Intrusion Detection System) Support" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config WIFI_WORK_QUEUE +# bool "Work Queue" +# depends on WIFI_DRIVER +# default n + +#config WIFI_SKB_RECYCLE +# bool "SKB Recycle(Linux)" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +config MTK_RTMP_FLASH_SUPPORT + bool "Flash Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_PRE_CAL_TRX_SET1_SUPPORT + bool "Calibration To Flash/BinFile Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_RLM_CAL_CACHE_SUPPORT + bool "RlmCalibrationCache Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_PRE_CAL_TRX_SET2_SUPPORT + bool "Pre-calibration to Flash Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_RF_LOCKDOWN_SUPPORT + bool "RF Lockdown Support" + depends on MTK_WIFI_DRIVER + default n + +config MTK_LINK_TEST_SUPPORT + bool "Link Test Support" + depends on MTK_WIFI_DRIVER + default n + +#config MTK_LED_CONTROL_SUPPORT +# bool "LED Support" +# depends on MTK_WIFI_DRIVER +# depends on MTK_MT_AP_SUPPORT +# default n + +config MTK_ATE_SUPPORT + bool "ATE/QA Support" + depends on MTK_WIFI_DRIVER + default y + +#config MTK_MEMORY_OPTIMIZATION +# bool "Memory Optimization" +# depends on MTK_WIFI_DRIVER +# default n + +config MTK_PASSPOINT_R2 + bool "Passpoint Release-2 Support" + depends on MTK_WIFI_DRIVER + select MTK_DOT11W_PMF_SUPPORT + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_MBO_SUPPORT + bool "MBO Support" + depends on MTK_WIFI_DRIVER + select MTK_INTERWORKING + select MTK_WNM_SUPPORT + select MTK_DOT11K_RRM_SUPPORT + select MTK_DOT11R_FT_SUPPORT + select MTK_DOT11W_PMF_SUPPORT + default n + +#config TRACE_TCP_PKT +# bool "TCP DATA/ACK packets trace log" +# depends on WIFI_DRIVER +# default n + +config MTK_UAPSD + bool "UAPSD support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_TCP_RACK_SUPPORT + bool "TCP Reduced ACK support" + depends on MTK_WIFI_DRIVER + default y + +#### PA_LNA_Type choice + +config MTK_RED_SUPPORT + bool "RED(Random Early Drop) support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_FQ_SCH_SUPPORT + bool "Fair Queueing support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT && MTK_VOW_SUPPORT + depends on MTK_CHIP_MT7622 + default y + +config MTK_FDB_SUPPORT + bool "FW Debug Port" + depends on MTK_WIFI_DRIVER + default n + +choice + prompt "PA LNA Type of 1st Card" + depends on ! MTK_FIRST_IF_NONE + + config MTK_FIRST_IF_EPAELNA + bool "ePAeLNA" + config MTK_FIRST_IF_IPAILNA + bool "iPAiLNA" + config MTK_FIRST_IF_IPAELNA + bool "iPAeLNA" +# config MTK_FIRST_IF_EPAILNA +# bool "ePAiLNA" +endchoice +choice + prompt "PA LNA Type of 2nd Card" + depends on ! MTK_SECOND_IF_NONE + + config MTK_SECOND_IF_EPAELNA + bool "ePAeLNA" + config MTK_SECOND_IF_IPAILNA + bool "iPAiLNA" + config MTK_SECOND_IF_IPAELNA + bool "iPAeLNA" +# config MTK_SECOND_IF_EPAILNA +# bool "ePAiLNA" +endchoice +choice + prompt "PA LNA Type of 3rd Card" + depends on ! MTK_THIRD_IF_NONE + + config MTK_THIRD_IF_EPAELNA + bool "ePAeLNA" + config MTK_THIRD_IF_IPAILNA + bool "iPAiLNA" + config MTK_THIRD_IF_IPAELNA + bool "iPAeLNA" +# config MTK_THIRD_IF_EPAILNA +# bool "ePAiLNA" +endchoice +#### PA_LNA_Type choice END + +# +# Section for chip architectures +# +# "RLT MAC Support" +config MTK_RLT_MAC + bool + depends on MTK_WIFI_DRIVER + default n + +config MTK_RLT_BBP + bool + +config MTK_RLT_RF + bool + +# "RTMP MAC Support" +config MTK_RTMP_MAC + bool + depends on MTK_WIFI_DRIVER + default n + +config MTK_RTMP_BBP + bool + +config MTK_RTMP_RF + bool + +# +# Section for interfaces +# +config MTK_RTMP_PCI_SUPPORT + bool + +config MTK_RTMP_USB_SUPPORT + bool + +config MTK_RTMP_RBUS_SUPPORT + bool + +endmenu + +menu "WiFi Operation Modes" + +config MTK_WIFI_MODE_AP + tristate "AP" + default y + select MTK_MT_AP_SUPPORT + +config MTK_WIFI_MODE_STA + tristate "STA" + select MTK_MT_STA_SUPPORT + +config MTK_WIFI_MODE_BOTH + tristate "APSTA" + select MTK_MT_AP_SUPPORT + select MTK_MT_STA_SUPPORT + + +config MTK_MT_AP_SUPPORT + tristate "Ralink RT2860 802.11n AP support" +# depends on NET_RADIO + select MTK_WIRELESS_EXT + select MTK_WEXT_SPY + select MTK_WEXT_PRIV + default y + +config MTK_WDS_SUPPORT + bool "WDS" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_MBSS_SUPPORT + bool "MBSSID" + depends on MTK_MT_AP_SUPPORT + default y + +#config NEW_MBSSID_MODE +# bool "New MBSSID MODE" +# depends on MT_AP_SUPPORT && MBSS_SUPPORT +# depends on RALINK_RT3883 || RALINK_RT3352 || RALINK_RT5350 || RALINK_RT6352 || RALINK_MT7620 +# default y + +#config ENHANCE_NEW_MBSSID_MODE +# bool "Enhanced MBSSID mode" +# depends on NEW_MBSSID_MODE +# default y + +config MTK_APCLI_SUPPORT + bool "AP-Client Support" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_APCLI_CERT_SUPPORT + bool "AP-Client TGn Cert Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_APCLI_SUPPORT + default n + +config MTK_MAC_REPEATER_SUPPORT + bool "MAC Repeater Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_APCLI_SUPPORT + depends on MTK_RALINK_RT6352 || MTK_RALINK_MT7620 || MTK_RALINK_MT7603E || MTK_MT_AP_SUPPORT + default y + +config MTK_MWDS + bool "Mixed WDS(MWDS)" + depends on MTK_MT_AP_SUPPORT + select MTK_APCLI_SUPPORT + default n + +config MTK_MUMIMO_SUPPORT + bool "MU-MIMO Support" + depends on MTK_WIFI_DRIVER + select MTK_MU_RA_SUPPORT + default y + +config MTK_MU_RA_SUPPORT + bool "MU-RGA Support" + depends on MTK_MUMIMO_SUPPORT + +config MTK_DOT11R_FT_SUPPORT + bool "802.11r Fast BSS Transition" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_DOT11K_RRM_SUPPORT + bool "802.11k Radio Resource Management" + depends on MTK_MT_AP_SUPPORT + default n + +#config SNIFFER_SUPPORT +# bool "SNIFFER" +# depends on MT_AP_SUPPORT +# default n + +config MTK_CFG80211_SUPPORT + bool "CFG80211" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_DSCP_PRI_SUPPORT + bool "Dscp Priority Mapping Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_CON_WPS_SUPPORT + bool "Concurrent WPS Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_APCLI_SUPPORT + depends on MTK_WSC_INCLUDED + depends on MTK_WSC_V2_SUPPORT +# depends on MTK_MULTI_INF_SUPPORT + default n + +#config LLTD_SUPPORT +# bool "LLTD (Link Layer Topology Discovery Protocol)" +# depends on MT_AP_SUPPORT + +#config COC_SUPPORT +# bool "CoC Support" +# depends on MT_AP_SUPPORT +# default n + +#config RT2860V2_SNMP +# bool "Net-SNMP Support" +# depends on MT_AP_SUPPORT + +config MTK_MCAST_RATE_SPECIFIC + bool "User specific tx rate of mcast pkt" + depends on MTK_MT_AP_SUPPORT + default y + +#config EXT_BUILD_CHANNEL_LIST +# bool "Extension Channel List" +# depends on MT_AP_SUPPORT + +#config AUTO_CH_SELECT_ENHANCE +# bool "Auto Channel Selection Enhancement" +# depends on MT_AP_SUPPORT + +config MTK_VOW_SUPPORT + bool "MediaAir(VOW) support" + depends on MTK_MT_AP_SUPPORT + default y + +#config AIRPLAY_SUPPORT +# bool "AIRPLAY Support" +# depends on MT_AP_SUPPORT +# default n + +config MTK_BAND_STEERING + bool "Band Steering" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_LED_CONTROL_SUPPORT + bool "LED Control Support" + default n + +config MTK_WLAN_HOOK + bool "WLAN hook Support" + depends on MTK_WIFI_DRIVER + default n + +config MTK_RADIUS_ACCOUNTING_SUPPORT + bool "Radius Accounting Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_GREENAP_SUPPORT + bool "GreenAP Support" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_PCIE_ASPM_DYM_CTRL_SUPPORT + bool "Pcie Aspm Dynamic Control Support" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_COEX_SUPPORT + bool "Coex Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_EASY_SETUP_SUPPORT + bool "Whole Home Coverage - Easy Setup" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_EVENT_NOTIFIER_SUPPORT + bool "Whole Home Coverage - Event Notifier" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_AIR_MONITOR + bool "Air Monitor" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_WNM_SUPPORT + bool "802.11v WNM Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_INTERWORKING + bool "802.11u Interworking" + depends on MTK_MT_AP_SUPPORT + default n + +#config ROAMING_ENHANCE_SUPPORT +# bool "Roaming Enhance Support" +# depends on MT_AP_SUPPORT +# depends on APCLI_SUPPORT +# default n + +config MTK_LINUX_NET_TXQ_SUPPORT + bool "NET TX Queue Support" + default n + +#config WIFI_FWD_SUPPORT +# bool "WiFi Forwarding Support" +# default n + +endmenu + +endif + +config MTK_WIFI_MT_MAC + bool + default y + depends on MTK_MT_WIFI + +if MTK_WIFI_RLT_MAC + config MTK_RLT_MAC + bool + default y +endif + +if MTK_WIFI_RTMP_MAC + config MTK_RTMP_MAC + bool + default y +endif + +if MTK_WIFI_MT_MAC + config MTK_MT_MAC + bool + default y + + config MTK_CHIP_MT7603E + bool + default n + + config MTK_CHIP_MT7615E + bool + default n + + config MTK_CHIP_MT7622 + bool + default n + + config MTK_CHIP_MT7663E + bool + default n + + config MTK_CHIP_MT7626 + bool + default n +endif + +if MTK_CHIP_MT7615E || MTK_CHIP_MT7622 || MTK_CHIP_MT7626 + config MTK_MT_MAC + bool + default y + select MTK_RATE_ADAPTION + select MTK_RATE_ADAPT_AGBS_SUPPORT + select MTK_DOT11_N_SUPPORT + select MTK_DOT11_VHT_AC + select MTK_HDR_TRANS_TX_SUPPORT + select MTK_HDR_TRANS_RX_SUPPORT +endif + +endif #MTK_WIFI_DRIVER# +endif #PACKAGE_kmod-mt_wifi# + diff --git a/package/lean/mt/drivers/mt_wifi/files/SingleSKU.dat b/package/lean/mt/drivers/mt_wifi/files/SingleSKU.dat new file mode 100644 index 000000000..be9c0d353 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/SingleSKU.dat @@ -0,0 +1,65 @@ +# Single SKU Max Power Table | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 2.4G Channel |CCK | | | |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |Txstream_Delta | | | | | | | | | | | | | | | | | | | | | +Band: 2.4G |CCK_1M |CCK_2M |CCK_5.5M |CCK_11M |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | | | | | | | | | | | | | | | | | +Ch1 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |20 |12 |18 |16 |8 | |8 | |8 | |9 |11 |12 |2 |1 |3 | | | | | | | | | | | | | | | | | | | +Ch2 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |19 |19 |10 |12 |8 | |8 | |8 | |9 |16 |12 |5 |4 |0 | | | | | | | | | | | | | | | | | | | +Ch3 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |17 |18 |16 |20 |8 | |8 | |8 | |12 |8 |20 |0 |2 |0 | | | | | | | | | | | | | | | | | | | +Ch4 |8 | |8 | |8 | |8 | |8 | |8 |8 |9 |8 | |8 | |8 | |14 |10 |14 |18 |8 | |8 | |8 | |14 |12 |10 |3 |4 |5 | | | | | | | | | | | | | | | | | | | +Ch5 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |10 |13 |11 |8 |8 | |8 | |8 | |12 |8 |9 |4 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch6 |8 | |8 | |8 | |8 | |8 | |8 |8 |13 |8 | |8 | |8 | |11 |9 |12 |16 |8 | |8 | |8 | |9 |17 |11 |5 |2 |1 | | | | | | | | | | | | | | | | | | | +Ch7 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |14 |11 |13 |18 |8 | |8 | |8 | |16 |13 |10 |2 |5 |4 | | | | | | | | | | | | | | | | | | | +Ch8 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |14 |9 |11 |10 |8 | |8 | |8 | |11 |14 |8 |5 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch9 |8 | |8 | |8 | |8 | |8 | |8 |8 |11 |8 | |8 | |8 | |12 |9 |15 |19 |8 | |8 | |8 | |14 |20 |12 |2 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch10 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |17 |14 |17 |15 |8 | |8 | |8 | |9 |17 |8 |2 |4 |2 | | | | | | | | | | | | | | | | | | | +Ch11 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |20 |10 |20 |18 |8 | |8 | |8 | |12 |8 |20 |3 |1 |4 | | | | | | | | | | | | | | | | | | | +Ch12 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |20 |16 |17 |9 |8 | |8 | |8 | |11 |20 |9 |0 |0 |1 | | | | | | | | | | | | | | | | | | | +Ch13 |8 | |8 | |8 | |8 | |8 | |8 |8 |8 |8 | |8 | |8 | |11 |16 |19 |16 |8 | |8 | |8 | |15 |12 |12 |2 |0 |2 | | | | | | | | | | | | | | | | | | | +Ch14 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |15 |17 |16 |14 |8 | |8 | |8 | |12 |14 |20 |4 |1 |5 | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 5G Channel |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |VHT80 | | | | | | | | | |VHT160 | | | | | | | | | |Txstream_Delta | | | | | +Band: 5G |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |VHT80_MCS0 |VHT80_MCS1 |VHT80_MCS2 |VHT80_MCS3 |VHT80_MCS4 |VHT80_MCS5 |VHT80_MCS6 |VHT80_MCS7 |VHT80_MCS8 |VHT80_MCS9 |VHT160_MCS0 |VHT160_MCS1 |VHT160_MCS2 |VHT160_MCS3 |VHT160_MCS4 |VHT160_MCS5 |VHT160_MCS6 |VHT160_MCS7 |VHT160_MCS8 |VHT160_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | +Ch184 |18 | |18 | |18 | |18 |18 |15 |18 | |12 | |13 | |11 |14 |16 |16 |12 | |12 | |13 | |20 |17 |16 |17 |18 | |9 | |16 | |17 |20 |18 |16 |19 | |15 | |9 | |17 |8 |17 |0 |4 |4 | | | +Ch188 |18 | |18 | |18 | |18 |18 |16 |20 | |9 | |9 | |11 |8 |12 |18 |15 | |11 | |11 | |14 |8 |17 |16 |16 | |16 | |12 | |8 |13 |19 |18 |11 | |9 | |12 | |14 |8 |13 |5 |2 |0 | | | +Ch192 |18 | |18 | |18 | |18 |18 |15 |9 | |11 | |9 | |15 |14 |11 |19 |15 | |8 | |18 | |20 |20 |8 |9 |9 | |9 | |11 | |18 |13 |14 |20 |18 | |10 | |14 | |12 |13 |16 |0 |2 |0 | | | +Ch196 |18 | |18 | |18 | |18 |18 |10 |11 | |19 | |13 | |12 |11 |10 |13 |11 | |19 | |10 | |16 |20 |15 |15 |8 | |14 | |8 | |18 |20 |15 |17 |17 | |14 | |12 | |12 |8 |16 |4 |3 |2 | | | +Ch8 |18 | |18 | |18 | |18 |18 |18 |13 | |19 | |20 | |18 |10 |9 |8 |8 | |17 | |15 | |17 |9 |18 |19 |11 | |12 | |15 | |20 |12 |12 |13 |9 | |9 | |15 | |10 |11 |17 |4 |3 |3 | | | +Ch12 |18 | |18 | |18 | |18 |18 |17 |20 | |14 | |10 | |10 |16 |15 |13 |11 | |15 | |16 | |17 |11 |15 |9 |18 | |8 | |20 | |19 |11 |9 |20 |8 | |18 | |8 | |8 |18 |18 |1 |3 |4 | | | +Ch16 |18 | |18 | |18 | |18 |18 |10 |18 | |18 | |8 | |19 |8 |12 |19 |16 | |19 | |18 | |16 |19 |12 |18 |18 | |9 | |10 | |18 |20 |20 |20 |9 | |11 | |20 | |17 |14 |16 |2 |2 |2 | | | +Ch36 |18 | |18 | |18 | |18 |18 |18 |19 | |8 | |11 | |16 |10 |9 |19 |11 | |19 | |9 | |8 |19 |8 |11 |17 | |20 | |14 | |9 |19 |19 |20 |13 | |12 | |19 | |13 |17 |9 |5 |1 |2 | | | +Ch40 |18 | |18 | |18 | |18 |18 |13 |20 | |13 | |19 | |16 |11 |14 |17 |17 | |14 | |8 | |13 |8 |10 |20 |10 | |9 | |14 | |11 |14 |17 |9 |20 | |15 | |19 | |9 |8 |11 |3 |1 |1 | | | +Ch44 |18 | |18 | |18 | |18 |18 |10 |14 | |19 | |20 | |17 |16 |12 |18 |8 | |17 | |18 | |15 |19 |14 |11 |13 | |14 | |12 | |16 |16 |19 |13 |14 | |19 | |14 | |20 |20 |11 |5 |1 |0 | | | +Ch48 |18 | |18 | |18 | |18 |18 |8 |12 | |12 | |19 | |11 |8 |11 |20 |12 | |12 | |11 | |15 |16 |10 |12 |16 | |11 | |15 | |18 |19 |17 |16 |17 | |11 | |8 | |10 |16 |16 |5 |5 |0 | | | +Ch52 |18 | |18 | |18 | |18 |18 |15 |12 | |15 | |20 | |9 |10 |10 |14 |8 | |20 | |10 | |16 |17 |18 |11 |16 | |17 | |10 | |17 |12 |13 |17 |17 | |13 | |18 | |18 |20 |13 |4 |3 |4 | | | +Ch56 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |20 |13 |14 |11 | |10 | |20 | |10 |8 |16 |12 |10 | |16 | |11 | |9 |11 |14 |17 |12 | |17 | |13 | |18 |10 |19 |0 |3 |3 | | | +Ch60 |18 | |18 | |18 | |18 |18 |14 |11 | |8 | |20 | |13 |16 |13 |11 |20 | |9 | |17 | |16 |11 |8 |12 |17 | |15 | |8 | |16 |10 |20 |19 |15 | |13 | |9 | |17 |18 |11 |4 |1 |2 | | | +Ch64 |18 | |18 | |18 | |18 |18 |13 |14 | |8 | |12 | |17 |8 |12 |18 |17 | |17 | |14 | |18 |8 |8 |20 |17 | |16 | |20 | |9 |15 |11 |10 |11 | |18 | |10 | |10 |15 |19 |2 |1 |4 | | | +Ch68 |18 | |18 | |18 | |18 |18 |14 |19 | |17 | |9 | |18 |19 |20 |12 |14 | |8 | |14 | |20 |20 |18 |9 |18 | |11 | |19 | |19 |10 |11 |8 |18 | |9 | |8 | |16 |11 |8 |3 |3 |1 | | | +Ch72 |18 | |18 | |18 | |18 |18 |19 |13 | |20 | |11 | |16 |9 |19 |20 |19 | |14 | |8 | |9 |17 |13 |19 |15 | |8 | |9 | |19 |14 |19 |15 |18 | |16 | |12 | |13 |15 |10 |4 |3 |1 | | | +Ch76 |18 | |18 | |18 | |18 |18 |17 |13 | |16 | |20 | |16 |8 |9 |20 |11 | |17 | |11 | |8 |18 |9 |20 |9 | |17 | |16 | |11 |11 |11 |18 |10 | |13 | |W | |20 |17 |8 |1 |3 |3 | | | +Ch80 |18 | |18 | |18 | |18 |18 |14 |20 | |13 | |13 | |17 |8 |10 |16 |8 | |9 | |19 | |16 |17 |17 |19 |15 | |9 | |13 | |16 |13 |14 |12 |9 | |20 | |20 | |14 |18 |18 |0 |4 |2 | | | +Ch84 |18 | |18 | |18 | |18 |18 |11 |18 | |20 | |9 | |13 |14 |11 |16 |15 | |12 | |11 | |9 |19 |13 |11 |11 | |9 | |15 | |16 |18 |13 |12 |8 | |8 | |8 | |10 |12 |15 |3 |2 |5 | | | +Ch88 |18 | |18 | |18 | |18 |18 |18 |19 | |9 | |17 | |15 |8 |19 |11 |11 | |14 | |9 | |14 |20 |20 |11 |11 | |15 | |12 | |14 |11 |8 |18 |15 | |19 | |18 | |12 |20 |16 |5 |5 |1 | | | +Ch92 |18 | |18 | |18 | |18 |18 |11 |8 | |15 | |13 | |13 |13 |13 |16 |14 | |14 | |9 | |9 |15 |20 |11 |17 | |10 | |14 | |13 |17 |11 |8 |18 | |20 | |8 | |10 |19 |18 |1 |4 |4 | | | +Ch96 |18 | |18 | |18 | |18 |18 |8 |12 | |16 | |9 | |13 |12 |9 |8 |11 | |8 | |8 | |19 |11 |15 |16 |8 | |11 | |16 | |18 |16 |9 |19 |9 | |10 | |15 | |19 |19 |15 |4 |2 |4 | | | +Ch100 |18 | |18 | |18 | |18 |18 |18 |13 | |20 | |20 | |12 |9 |19 |10 |9 | |14 | |8 | |19 |10 |17 |9 |10 | |10 | |8 | |13 |12 |11 |20 |11 | |16 | |18 | |14 |16 |19 |1 |1 |2 | | | +Ch104 |18 | |18 | |18 | |18 |18 |19 |12 | |20 | |14 | |16 |15 |9 |19 |11 | |15 | |11 | |12 |18 |15 |11 |15 | |19 | |10 | |14 |15 |19 |9 |13 | |19 | |13 | |11 |11 |17 |2 |2 |0 | | | +Ch108 |18 | |18 | |18 | |18 |18 |18 |15 | |13 | |16 | |11 |19 |19 |18 |19 | |12 | |17 | |8 |9 |10 |8 |8 | |18 | |8 | |10 |11 |17 |15 |10 | |19 | |13 | |16 |10 |15 |0 |2 |3 | | | +Ch112 |18 | |18 | |18 | |18 |18 |8 |13 | |9 | |17 | |9 |15 |17 |10 |19 | |9 | |19 | |11 |16 |14 |16 |8 | |18 | |13 | |16 |13 |17 |19 |11 | |8 | |8 | |18 |14 |17 |5 |2 |5 | | | +Ch116 |18 | |18 | |18 | |18 |18 |8 |20 | |11 | |15 | |8 |11 |8 |18 |15 | |13 | |17 | |14 |13 |9 |8 |14 | |14 | |11 | |9 |19 |17 |11 |11 | |8 | |20 | |8 |10 |20 |5 |2 |1 | | | +Ch120 |18 | |18 | |18 | |18 |18 |14 |20 | |8 | |20 | |14 |10 |10 |17 |12 | |16 | |20 | |10 |20 |17 |18 |9 | |15 | |14 | |17 |13 |14 |16 |8 | |18 | |10 | |15 |12 |12 |1 |5 |3 | | | +Ch124 |18 | |18 | |18 | |18 |18 |20 |9 | |17 | |12 | |12 |8 |14 |8 |8 | |20 | |17 | |16 |20 |13 |14 |16 | |10 | |14 | |20 |15 |17 |8 |10 | |13 | |13 | |11 |13 |9 |5 |0 |5 | | | +Ch128 |18 | |18 | |18 | |18 |18 |9 |19 | |9 | |14 | |8 |14 |11 |9 |14 | |16 | |15 | |14 |10 |15 |14 |14 | |20 | |10 | |16 |15 |11 |12 |13 | |13 | |13 | |12 |15 |20 |1 |4 |3 | | | +Ch132 |18 | |18 | |18 | |18 |18 |20 |16 | |13 | |8 | |18 |11 |20 |12 |11 | |11 | |14 | |12 |13 |8 |12 |13 | |10 | |20 | |19 |12 |13 |14 |12 | |11 | |19 | |19 |20 |8 |3 |1 |4 | | | +Ch136 |18 | |18 | |18 | |18 |18 |12 |12 | |19 | |10 | |20 |10 |8 |17 |8 | |12 | |10 | |10 |13 |13 |12 |8 | |11 | |18 | |14 |12 |17 |8 |14 | |14 | |9 | |11 |18 |14 |1 |2 |2 | | | +Ch140 |18 | |18 | |18 | |18 |18 |12 |10 | |13 | |9 | |16 |8 |20 |10 |17 | |8 | |15 | |13 |20 |15 |10 |18 | |13 | |12 | |12 |16 |18 |12 |17 | |10 | |16 | |11 |15 |14 |3 |2 |5 | | | +Ch144 |18 | |18 | |18 | |18 |18 |19 |9 | |15 | |8 | |13 |18 |17 |9 |19 | |16 | |11 | |20 |12 |15 |19 |10 | |17 | |15 | |17 |14 |9 |9 |13 | |17 | |16 | |10 |9 |10 |1 |5 |2 | | | +Ch149 |18 | |18 | |18 | |18 |18 |15 |20 | |12 | |19 | |19 |19 |10 |10 |13 | |15 | |19 | |12 |19 |10 |14 |15 | |10 | |15 | |9 |8 |11 |15 |13 | |10 | |16 | |15 |18 |12 |5 |5 |2 | | | +Ch153 |18 | |18 | |18 | |18 |18 |20 |17 | |8 | |19 | |16 |20 |13 |16 |18 | |14 | |11 | |10 |16 |16 |19 |15 | |13 | |17 | |19 |18 |19 |20 |8 | |18 | |9 | |17 |11 |11 |1 |2 |1 | | | +Ch157 |18 | |18 | |18 | |18 |18 |13 |17 | |12 | |19 | |16 |8 |17 |11 |12 | |15 | |14 | |18 |11 |12 |9 |18 | |20 | |13 | |16 |13 |20 |17 |19 | |10 | |12 | |20 |18 |16 |5 |2 |3 | | | +Ch161 |18 | |18 | |18 | |18 |18 |12 |12 | |16 | |12 | |15 |11 |18 |11 |13 | |17 | |19 | |11 |13 |13 |9 |15 | |10 | |10 | |19 |13 |20 |13 |9 | |8 | |8 | |20 |14 |12 |0 |4 |1 | | | +Ch165 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |8 |19 |15 |10 | |17 | |13 | |13 |19 |20 |8 |18 | |15 | |20 | |16 |9 |14 |11 |20 | |11 | |19 | |15 |16 |8 |1 |2 |0 | | | +Ch169 |18 | |18 | |18 | |18 |18 |8 |17 | |17 | |13 | |16 |8 |14 |18 |11 | |8 | |18 | |20 |14 |8 |17 |8 | |13 | |18 | |19 |20 |19 |20 |17 | |13 | |20 | |9 |15 |18 |0 |3 |4 | | | +Ch173 |18 | |18 | |18 | |18 |18 |14 |9 | |13 | |12 | |15 |14 |15 |10 |10 | |18 | |16 | |16 |8 |13 |16 |11 | |11 | |13 | |13 |15 |12 |20 |15 | |14 | |13 | |16 |11 |14 |3 |3 |4 | | | +Ch177 |18 | |18 | |18 | |18 |18 |19 |18 | |16 | |10 | |20 |13 |11 |16 |12 | |16 | |18 | |18 |11 |18 |8 |13 | |14 | |11 | |18 |14 |16 |16 |19 | |16 | |13 | |15 |8 |13 |5 |0 |0 | | | +Ch181 |18 | |18 | |18 | |18 |18 |20 |11 | |10 | |9 | |8 |9 |15 |15 |8 | |8 | |12 | |11 |9 |18 |20 |11 | |17 | |11 | |8 |15 |8 |18 |12 | |18 | |16 | |19 |9 |14 |4 |1 |4 | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | diff --git a/package/lean/mt/drivers/mt_wifi/files/SingleSKU_BF.dat b/package/lean/mt/drivers/mt_wifi/files/SingleSKU_BF.dat new file mode 100644 index 000000000..be9c0d353 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/SingleSKU_BF.dat @@ -0,0 +1,65 @@ +# Single SKU Max Power Table | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 2.4G Channel |CCK | | | |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |Txstream_Delta | | | | | | | | | | | | | | | | | | | | | +Band: 2.4G |CCK_1M |CCK_2M |CCK_5.5M |CCK_11M |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | | | | | | | | | | | | | | | | | +Ch1 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |20 |12 |18 |16 |8 | |8 | |8 | |9 |11 |12 |2 |1 |3 | | | | | | | | | | | | | | | | | | | +Ch2 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |19 |19 |10 |12 |8 | |8 | |8 | |9 |16 |12 |5 |4 |0 | | | | | | | | | | | | | | | | | | | +Ch3 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |17 |18 |16 |20 |8 | |8 | |8 | |12 |8 |20 |0 |2 |0 | | | | | | | | | | | | | | | | | | | +Ch4 |8 | |8 | |8 | |8 | |8 | |8 |8 |9 |8 | |8 | |8 | |14 |10 |14 |18 |8 | |8 | |8 | |14 |12 |10 |3 |4 |5 | | | | | | | | | | | | | | | | | | | +Ch5 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |10 |13 |11 |8 |8 | |8 | |8 | |12 |8 |9 |4 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch6 |8 | |8 | |8 | |8 | |8 | |8 |8 |13 |8 | |8 | |8 | |11 |9 |12 |16 |8 | |8 | |8 | |9 |17 |11 |5 |2 |1 | | | | | | | | | | | | | | | | | | | +Ch7 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |14 |11 |13 |18 |8 | |8 | |8 | |16 |13 |10 |2 |5 |4 | | | | | | | | | | | | | | | | | | | +Ch8 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |14 |9 |11 |10 |8 | |8 | |8 | |11 |14 |8 |5 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch9 |8 | |8 | |8 | |8 | |8 | |8 |8 |11 |8 | |8 | |8 | |12 |9 |15 |19 |8 | |8 | |8 | |14 |20 |12 |2 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch10 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |17 |14 |17 |15 |8 | |8 | |8 | |9 |17 |8 |2 |4 |2 | | | | | | | | | | | | | | | | | | | +Ch11 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |20 |10 |20 |18 |8 | |8 | |8 | |12 |8 |20 |3 |1 |4 | | | | | | | | | | | | | | | | | | | +Ch12 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |20 |16 |17 |9 |8 | |8 | |8 | |11 |20 |9 |0 |0 |1 | | | | | | | | | | | | | | | | | | | +Ch13 |8 | |8 | |8 | |8 | |8 | |8 |8 |8 |8 | |8 | |8 | |11 |16 |19 |16 |8 | |8 | |8 | |15 |12 |12 |2 |0 |2 | | | | | | | | | | | | | | | | | | | +Ch14 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |15 |17 |16 |14 |8 | |8 | |8 | |12 |14 |20 |4 |1 |5 | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 5G Channel |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |VHT80 | | | | | | | | | |VHT160 | | | | | | | | | |Txstream_Delta | | | | | +Band: 5G |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |VHT80_MCS0 |VHT80_MCS1 |VHT80_MCS2 |VHT80_MCS3 |VHT80_MCS4 |VHT80_MCS5 |VHT80_MCS6 |VHT80_MCS7 |VHT80_MCS8 |VHT80_MCS9 |VHT160_MCS0 |VHT160_MCS1 |VHT160_MCS2 |VHT160_MCS3 |VHT160_MCS4 |VHT160_MCS5 |VHT160_MCS6 |VHT160_MCS7 |VHT160_MCS8 |VHT160_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | +Ch184 |18 | |18 | |18 | |18 |18 |15 |18 | |12 | |13 | |11 |14 |16 |16 |12 | |12 | |13 | |20 |17 |16 |17 |18 | |9 | |16 | |17 |20 |18 |16 |19 | |15 | |9 | |17 |8 |17 |0 |4 |4 | | | +Ch188 |18 | |18 | |18 | |18 |18 |16 |20 | |9 | |9 | |11 |8 |12 |18 |15 | |11 | |11 | |14 |8 |17 |16 |16 | |16 | |12 | |8 |13 |19 |18 |11 | |9 | |12 | |14 |8 |13 |5 |2 |0 | | | +Ch192 |18 | |18 | |18 | |18 |18 |15 |9 | |11 | |9 | |15 |14 |11 |19 |15 | |8 | |18 | |20 |20 |8 |9 |9 | |9 | |11 | |18 |13 |14 |20 |18 | |10 | |14 | |12 |13 |16 |0 |2 |0 | | | +Ch196 |18 | |18 | |18 | |18 |18 |10 |11 | |19 | |13 | |12 |11 |10 |13 |11 | |19 | |10 | |16 |20 |15 |15 |8 | |14 | |8 | |18 |20 |15 |17 |17 | |14 | |12 | |12 |8 |16 |4 |3 |2 | | | +Ch8 |18 | |18 | |18 | |18 |18 |18 |13 | |19 | |20 | |18 |10 |9 |8 |8 | |17 | |15 | |17 |9 |18 |19 |11 | |12 | |15 | |20 |12 |12 |13 |9 | |9 | |15 | |10 |11 |17 |4 |3 |3 | | | +Ch12 |18 | |18 | |18 | |18 |18 |17 |20 | |14 | |10 | |10 |16 |15 |13 |11 | |15 | |16 | |17 |11 |15 |9 |18 | |8 | |20 | |19 |11 |9 |20 |8 | |18 | |8 | |8 |18 |18 |1 |3 |4 | | | +Ch16 |18 | |18 | |18 | |18 |18 |10 |18 | |18 | |8 | |19 |8 |12 |19 |16 | |19 | |18 | |16 |19 |12 |18 |18 | |9 | |10 | |18 |20 |20 |20 |9 | |11 | |20 | |17 |14 |16 |2 |2 |2 | | | +Ch36 |18 | |18 | |18 | |18 |18 |18 |19 | |8 | |11 | |16 |10 |9 |19 |11 | |19 | |9 | |8 |19 |8 |11 |17 | |20 | |14 | |9 |19 |19 |20 |13 | |12 | |19 | |13 |17 |9 |5 |1 |2 | | | +Ch40 |18 | |18 | |18 | |18 |18 |13 |20 | |13 | |19 | |16 |11 |14 |17 |17 | |14 | |8 | |13 |8 |10 |20 |10 | |9 | |14 | |11 |14 |17 |9 |20 | |15 | |19 | |9 |8 |11 |3 |1 |1 | | | +Ch44 |18 | |18 | |18 | |18 |18 |10 |14 | |19 | |20 | |17 |16 |12 |18 |8 | |17 | |18 | |15 |19 |14 |11 |13 | |14 | |12 | |16 |16 |19 |13 |14 | |19 | |14 | |20 |20 |11 |5 |1 |0 | | | +Ch48 |18 | |18 | |18 | |18 |18 |8 |12 | |12 | |19 | |11 |8 |11 |20 |12 | |12 | |11 | |15 |16 |10 |12 |16 | |11 | |15 | |18 |19 |17 |16 |17 | |11 | |8 | |10 |16 |16 |5 |5 |0 | | | +Ch52 |18 | |18 | |18 | |18 |18 |15 |12 | |15 | |20 | |9 |10 |10 |14 |8 | |20 | |10 | |16 |17 |18 |11 |16 | |17 | |10 | |17 |12 |13 |17 |17 | |13 | |18 | |18 |20 |13 |4 |3 |4 | | | +Ch56 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |20 |13 |14 |11 | |10 | |20 | |10 |8 |16 |12 |10 | |16 | |11 | |9 |11 |14 |17 |12 | |17 | |13 | |18 |10 |19 |0 |3 |3 | | | +Ch60 |18 | |18 | |18 | |18 |18 |14 |11 | |8 | |20 | |13 |16 |13 |11 |20 | |9 | |17 | |16 |11 |8 |12 |17 | |15 | |8 | |16 |10 |20 |19 |15 | |13 | |9 | |17 |18 |11 |4 |1 |2 | | | +Ch64 |18 | |18 | |18 | |18 |18 |13 |14 | |8 | |12 | |17 |8 |12 |18 |17 | |17 | |14 | |18 |8 |8 |20 |17 | |16 | |20 | |9 |15 |11 |10 |11 | |18 | |10 | |10 |15 |19 |2 |1 |4 | | | +Ch68 |18 | |18 | |18 | |18 |18 |14 |19 | |17 | |9 | |18 |19 |20 |12 |14 | |8 | |14 | |20 |20 |18 |9 |18 | |11 | |19 | |19 |10 |11 |8 |18 | |9 | |8 | |16 |11 |8 |3 |3 |1 | | | +Ch72 |18 | |18 | |18 | |18 |18 |19 |13 | |20 | |11 | |16 |9 |19 |20 |19 | |14 | |8 | |9 |17 |13 |19 |15 | |8 | |9 | |19 |14 |19 |15 |18 | |16 | |12 | |13 |15 |10 |4 |3 |1 | | | +Ch76 |18 | |18 | |18 | |18 |18 |17 |13 | |16 | |20 | |16 |8 |9 |20 |11 | |17 | |11 | |8 |18 |9 |20 |9 | |17 | |16 | |11 |11 |11 |18 |10 | |13 | |W | |20 |17 |8 |1 |3 |3 | | | +Ch80 |18 | |18 | |18 | |18 |18 |14 |20 | |13 | |13 | |17 |8 |10 |16 |8 | |9 | |19 | |16 |17 |17 |19 |15 | |9 | |13 | |16 |13 |14 |12 |9 | |20 | |20 | |14 |18 |18 |0 |4 |2 | | | +Ch84 |18 | |18 | |18 | |18 |18 |11 |18 | |20 | |9 | |13 |14 |11 |16 |15 | |12 | |11 | |9 |19 |13 |11 |11 | |9 | |15 | |16 |18 |13 |12 |8 | |8 | |8 | |10 |12 |15 |3 |2 |5 | | | +Ch88 |18 | |18 | |18 | |18 |18 |18 |19 | |9 | |17 | |15 |8 |19 |11 |11 | |14 | |9 | |14 |20 |20 |11 |11 | |15 | |12 | |14 |11 |8 |18 |15 | |19 | |18 | |12 |20 |16 |5 |5 |1 | | | +Ch92 |18 | |18 | |18 | |18 |18 |11 |8 | |15 | |13 | |13 |13 |13 |16 |14 | |14 | |9 | |9 |15 |20 |11 |17 | |10 | |14 | |13 |17 |11 |8 |18 | |20 | |8 | |10 |19 |18 |1 |4 |4 | | | +Ch96 |18 | |18 | |18 | |18 |18 |8 |12 | |16 | |9 | |13 |12 |9 |8 |11 | |8 | |8 | |19 |11 |15 |16 |8 | |11 | |16 | |18 |16 |9 |19 |9 | |10 | |15 | |19 |19 |15 |4 |2 |4 | | | +Ch100 |18 | |18 | |18 | |18 |18 |18 |13 | |20 | |20 | |12 |9 |19 |10 |9 | |14 | |8 | |19 |10 |17 |9 |10 | |10 | |8 | |13 |12 |11 |20 |11 | |16 | |18 | |14 |16 |19 |1 |1 |2 | | | +Ch104 |18 | |18 | |18 | |18 |18 |19 |12 | |20 | |14 | |16 |15 |9 |19 |11 | |15 | |11 | |12 |18 |15 |11 |15 | |19 | |10 | |14 |15 |19 |9 |13 | |19 | |13 | |11 |11 |17 |2 |2 |0 | | | +Ch108 |18 | |18 | |18 | |18 |18 |18 |15 | |13 | |16 | |11 |19 |19 |18 |19 | |12 | |17 | |8 |9 |10 |8 |8 | |18 | |8 | |10 |11 |17 |15 |10 | |19 | |13 | |16 |10 |15 |0 |2 |3 | | | +Ch112 |18 | |18 | |18 | |18 |18 |8 |13 | |9 | |17 | |9 |15 |17 |10 |19 | |9 | |19 | |11 |16 |14 |16 |8 | |18 | |13 | |16 |13 |17 |19 |11 | |8 | |8 | |18 |14 |17 |5 |2 |5 | | | +Ch116 |18 | |18 | |18 | |18 |18 |8 |20 | |11 | |15 | |8 |11 |8 |18 |15 | |13 | |17 | |14 |13 |9 |8 |14 | |14 | |11 | |9 |19 |17 |11 |11 | |8 | |20 | |8 |10 |20 |5 |2 |1 | | | +Ch120 |18 | |18 | |18 | |18 |18 |14 |20 | |8 | |20 | |14 |10 |10 |17 |12 | |16 | |20 | |10 |20 |17 |18 |9 | |15 | |14 | |17 |13 |14 |16 |8 | |18 | |10 | |15 |12 |12 |1 |5 |3 | | | +Ch124 |18 | |18 | |18 | |18 |18 |20 |9 | |17 | |12 | |12 |8 |14 |8 |8 | |20 | |17 | |16 |20 |13 |14 |16 | |10 | |14 | |20 |15 |17 |8 |10 | |13 | |13 | |11 |13 |9 |5 |0 |5 | | | +Ch128 |18 | |18 | |18 | |18 |18 |9 |19 | |9 | |14 | |8 |14 |11 |9 |14 | |16 | |15 | |14 |10 |15 |14 |14 | |20 | |10 | |16 |15 |11 |12 |13 | |13 | |13 | |12 |15 |20 |1 |4 |3 | | | +Ch132 |18 | |18 | |18 | |18 |18 |20 |16 | |13 | |8 | |18 |11 |20 |12 |11 | |11 | |14 | |12 |13 |8 |12 |13 | |10 | |20 | |19 |12 |13 |14 |12 | |11 | |19 | |19 |20 |8 |3 |1 |4 | | | +Ch136 |18 | |18 | |18 | |18 |18 |12 |12 | |19 | |10 | |20 |10 |8 |17 |8 | |12 | |10 | |10 |13 |13 |12 |8 | |11 | |18 | |14 |12 |17 |8 |14 | |14 | |9 | |11 |18 |14 |1 |2 |2 | | | +Ch140 |18 | |18 | |18 | |18 |18 |12 |10 | |13 | |9 | |16 |8 |20 |10 |17 | |8 | |15 | |13 |20 |15 |10 |18 | |13 | |12 | |12 |16 |18 |12 |17 | |10 | |16 | |11 |15 |14 |3 |2 |5 | | | +Ch144 |18 | |18 | |18 | |18 |18 |19 |9 | |15 | |8 | |13 |18 |17 |9 |19 | |16 | |11 | |20 |12 |15 |19 |10 | |17 | |15 | |17 |14 |9 |9 |13 | |17 | |16 | |10 |9 |10 |1 |5 |2 | | | +Ch149 |18 | |18 | |18 | |18 |18 |15 |20 | |12 | |19 | |19 |19 |10 |10 |13 | |15 | |19 | |12 |19 |10 |14 |15 | |10 | |15 | |9 |8 |11 |15 |13 | |10 | |16 | |15 |18 |12 |5 |5 |2 | | | +Ch153 |18 | |18 | |18 | |18 |18 |20 |17 | |8 | |19 | |16 |20 |13 |16 |18 | |14 | |11 | |10 |16 |16 |19 |15 | |13 | |17 | |19 |18 |19 |20 |8 | |18 | |9 | |17 |11 |11 |1 |2 |1 | | | +Ch157 |18 | |18 | |18 | |18 |18 |13 |17 | |12 | |19 | |16 |8 |17 |11 |12 | |15 | |14 | |18 |11 |12 |9 |18 | |20 | |13 | |16 |13 |20 |17 |19 | |10 | |12 | |20 |18 |16 |5 |2 |3 | | | +Ch161 |18 | |18 | |18 | |18 |18 |12 |12 | |16 | |12 | |15 |11 |18 |11 |13 | |17 | |19 | |11 |13 |13 |9 |15 | |10 | |10 | |19 |13 |20 |13 |9 | |8 | |8 | |20 |14 |12 |0 |4 |1 | | | +Ch165 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |8 |19 |15 |10 | |17 | |13 | |13 |19 |20 |8 |18 | |15 | |20 | |16 |9 |14 |11 |20 | |11 | |19 | |15 |16 |8 |1 |2 |0 | | | +Ch169 |18 | |18 | |18 | |18 |18 |8 |17 | |17 | |13 | |16 |8 |14 |18 |11 | |8 | |18 | |20 |14 |8 |17 |8 | |13 | |18 | |19 |20 |19 |20 |17 | |13 | |20 | |9 |15 |18 |0 |3 |4 | | | +Ch173 |18 | |18 | |18 | |18 |18 |14 |9 | |13 | |12 | |15 |14 |15 |10 |10 | |18 | |16 | |16 |8 |13 |16 |11 | |11 | |13 | |13 |15 |12 |20 |15 | |14 | |13 | |16 |11 |14 |3 |3 |4 | | | +Ch177 |18 | |18 | |18 | |18 |18 |19 |18 | |16 | |10 | |20 |13 |11 |16 |12 | |16 | |18 | |18 |11 |18 |8 |13 | |14 | |11 | |18 |14 |16 |16 |19 | |16 | |13 | |15 |8 |13 |5 |0 |0 | | | +Ch181 |18 | |18 | |18 | |18 |18 |20 |11 | |10 | |9 | |8 |9 |15 |15 |8 | |8 | |12 | |11 |9 |18 |20 |11 | |17 | |11 | |8 |15 |8 |18 |12 | |18 | |16 | |19 |9 |14 |4 |1 |4 | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | diff --git a/package/lean/mt/drivers/mt_wifi/files/firmware.sh b/package/lean/mt/drivers/mt_wifi/files/firmware.sh new file mode 100644 index 000000000..abdade9c7 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/firmware.sh @@ -0,0 +1,16 @@ +#!/bin/sh /etc/rc.common +chmod 777 /sbin/mtkwifi +START=15 +STOP=15 + +USE_PROCD=1 + +start_service() { + [ -f /etc/hotplug.d/firmware/11-mtk-wifi-e2p ] && sh /etc/hotplug.d/firmware/11-mtk-wifi-e2p +} + +stop_service() { + echo 'do nothing' > /dev/null +} + + diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615.1.2G.dat b/package/lean/mt/drivers/mt_wifi/files/mt7615.1.2G.dat new file mode 100644 index 000000000..7266446fa --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7615.1.2G.dat @@ -0,0 +1,375 @@ +Default +AccessControlList0= +AccessControlList1= +AccessControlList10= +AccessControlList11= +AccessControlList12= +AccessControlList13= +AccessControlList14= +AccessControlList15= +AccessControlList2= +AccessControlList3= +AccessControlList4= +AccessControlList5= +AccessControlList6= +AccessControlList7= +AccessControlList8= +AccessControlList9= +AccessPolicy0=0 +AccessPolicy1=0 +AccessPolicy10=0 +AccessPolicy11=0 +AccessPolicy12=0 +AccessPolicy13=0 +AccessPolicy14=0 +AccessPolicy15=0 +AccessPolicy2=0 +AccessPolicy3=0 +AccessPolicy4=0 +AccessPolicy5=0 +AccessPolicy6=0 +AccessPolicy7=0 +AccessPolicy8=0 +AccessPolicy9=0 +AckPolicy=0;0;0;0 +APACM=0;0;0;0 +APAifsn=3;7;1;1 +ApCliAuthMode= +ApCliBssid= +ApCliDefaultKeyID= +ApCliEnable= +ApCliEncrypType= +ApCliKey1Str= +ApCliKey1Str1= +ApCliKey1Type= +ApCliKey2Str= +ApCliKey2Str1= +ApCliKey2Type= +ApCliKey3Str= +ApCliKey3Str1= +ApCliKey3Type= +ApCliKey4Str= +ApCliKey4Str1= +ApCliKey4Type= +ApCliSsid= +ApCliWirelessMode= +ApCliWPAPSK= +ApCliWPAPSK1= +APCwmax=6;10;4;3 +APCwmin=4;4;3;2 +APSDCapable=1 +APTxop=0;0;94;47 +AuthMode=OPEN +AutoChannelSelect=0 +AutoChannelSkipList= +AutoProvisionEn=0 +BandSteering=0 +BasicRate=15 +BeaconPeriod=100 +BFBACKOFFenable=0 +BgndScanSkipCh= +BGProtection=0 +BndStrgBssIdx= +BSSACM=0;0;0;0 +BSSAifsn=3;7;2;2 +BSSCwmax=10;10;4;3 +BSSCwmin=4;4;3;2 +BssidNum=1 +BSSTxop=0;0;94;47 +BW_Enable=0 +BW_Guarantee_Rate= +BW_Maximum_Rate= +BW_Priority= +BW_Root=0 +CalCacheApply=0 +CarrierDetect=0 +Channel=6 +ChannelGrp= +CountryCode=US +CountryRegion=5 +CountryRegionABand=7 +CP_SUPPORT=2 +CSPeriod=6 +DBDC_MODE=1 +DebugFlags=0 +DefaultKeyID=1 +DfsCalibration=0 +DfsEnable=0 +DfsFalseAlarmPrevent=1 +DfsZeroWait=0 +DfsZeroWaitCacTime=255 +DisableOLBC=0 +DtimPeriod=1 +E2pAccessMode=2 +EAPifname=br0 +EDCCAEnable=1 +EncrypType=NONE +EthConvertMode=dongle +EtherTrafficBand=0 +Ethifname= +ETxBfEnCond=1 +FineAGC=0 +FixedTxMode= +ForceRoamSupport= +FragThreshold=2346 +FreqDelta=0 +FtSupport=0 +GreenAP=1 +G_BAND_256QAM=1 +HideSSID=0 +HT_AMSDU=0 +HT_AutoBA=1 +HT_BADecline=0 +HT_BAWinSize=64 +HT_BSSCoexistence=1 +HT_BW=1 +HT_DisallowTKIP=1 +HT_EXTCHA=1 +HT_GI=1 +HT_HTC=1 +HT_LDPC=1 +HT_LinkAdapt=0 +HT_MCS=33 +HT_MpduDensity=5 +HT_OpMode=0 +HT_PROTECT=1 +HT_RxStream=2 +HT_STBC=1 +HT_TxStream=2 +IcapMode=0 +idle_timeout_interval=0 +IEEE80211H=1 +IEEE8021X=0 +IgmpSnEnable=0 +ITxBfEn=1 +Key1Str= +Key1Str1= +Key1Str10= +Key1Str11= +Key1Str12= +Key1Str13= +Key1Str14= +Key1Str15= +Key1Str16= +Key1Str2= +Key1Str3= +Key1Str4= +Key1Str5= +Key1Str6= +Key1Str7= +Key1Str8= +Key1Str9= +Key1Type=0 +Key2Str= +Key2Str1= +Key2Str10= +Key2Str11= +Key2Str12= +Key2Str13= +Key2Str14= +Key2Str15= +Key2Str16= +Key2Str2= +Key2Str3= +Key2Str4= +Key2Str5= +Key2Str6= +Key2Str7= +Key2Str8= +Key2Str9= +Key2Type=0 +Key3Str= +Key3Str1= +Key3Str10= +Key3Str11= +Key3Str12= +Key3Str13= +Key3Str14= +Key3Str15= +Key3Str16= +Key3Str2= +Key3Str3= +Key3Str4= +Key3Str5= +Key3Str6= +Key3Str7= +Key3Str8= +Key3Str9= +Key3Type=0 +Key4Str= +Key4Str1= +Key4Str10= +Key4Str11= +Key4Str12= +Key4Str13= +Key4Str14= +Key4Str15= +Key4Str16= +Key4Str2= +Key4Str3= +Key4Str4= +Key4Str5= +Key4Str6= +Key4Str7= +Key4Str8= +Key4Str9= +Key4Type=0 +LinkTestSupport=0 +MACRepeaterEn= +MACRepeaterOuiMode=2 +MUTxRxEnable=0 +NoForwarding=0 +NoForwardingBTNBSSID=0 +own_ip_addr=10.10.10.254 +PcieAspm=0 +PERCENTAGEenable=0 +PhyRateLimit=0 +PMFMFPC=0 +PMFMFPR=0 +PMFSHA256=0 +PMKCachePeriod=10 +PowerUpCckOfdm=0:0:0:0:0:0:0 +PowerUpHT20=0:0:0:0:0:0:0 +PowerUpHT40=0:0:0:0:0:0:0 +PowerUpVHT160=0:0:0:0:0:0:0 +PowerUpVHT20=0:0:0:0:0:0:0 +PowerUpVHT40=0:0:0:0:0:0:0 +PowerUpVHT80=0:0:0:0:0:0:0 +PreAntSwitch= +PreAuth=0 +PreAuthifname=br0 +RadioLinkSelection=0 +RadioOn=1 +RADIUS_Acct_Key= +RADIUS_Acct_Port=1813 +RADIUS_Acct_Server= +RADIUS_Key1= +RADIUS_Key10= +RADIUS_Key11= +RADIUS_Key12= +RADIUS_Key13= +RADIUS_Key14= +RADIUS_Key15= +RADIUS_Key16= +RADIUS_Key2= +RADIUS_Key3= +RADIUS_Key4= +RADIUS_Key5= +RADIUS_Key6= +RADIUS_Key7= +RADIUS_Key8= +RADIUS_Key9= +RADIUS_Port=1812 +RADIUS_Server=0 +RDRegion= +RED_Enable=1 +RekeyInterval=3600 +RekeyMethod=DISABLE +RRMEnable=0 +RTSThreshold=2347 +session_timeout_interval=0 +ShortSlot=1 +SKUenable=0 +SSID= +SSID1=K2P_2G +SSID10= +SSID11= +SSID12= +SSID13= +SSID14= +SSID15= +SSID16= +SSID2= +SSID3= +SSID4= +SSID5= +SSID6= +SSID7= +SSID8= +SSID9= +StationKeepAlive=0 +StreamMode=0 +StreamModeMac0= +StreamModeMac1= +StreamModeMac2= +StreamModeMac3= +TGnWifiTest=0 +ThermalRecal=0 +TxBurst=1 +TxPower=100 +TxPreamble=1 +VHT_BW=1 +VHT_BW_SIGNAL=0 +VHT_LDPC=1 +VHT_Sec80_Channel=0 +VHT_SGI=1 +VHT_STBC=1 +VLANID=0 +VLANPriority=0 +VLANTag=0 +VOW_Airtime_Ctrl_En= +VOW_Airtime_Fairness_En=1 +VOW_BW_Ctrl=0 +VOW_Group_Backlog= +VOW_Group_DWRR_Max_Wait_Time= +VOW_Group_DWRR_Quantum= +VOW_Group_Max_Airtime_Bucket_Size= +VOW_Group_Max_Rate= +VOW_Group_Max_Rate_Bucket_Size= +VOW_Group_Max_Ratio= +VOW_Group_Max_Wait_Time= +VOW_Group_Min_Airtime_Bucket_Size= +VOW_Group_Min_Rate= +VOW_Group_Min_Rate_Bucket_Size= +VOW_Group_Min_Ratio= +VOW_Rate_Ctrl_En= +VOW_Refill_Period= +VOW_RX_En=1 +VOW_Sta_BE_DWRR_Quantum= +VOW_Sta_BK_DWRR_Quantum= +VOW_Sta_DWRR_Max_Wait_Time= +VOW_Sta_VI_DWRR_Quantum= +VOW_Sta_VO_DWRR_Quantum= +VOW_WATF_Enable= +VOW_WATF_MAC_LV0= +VOW_WATF_MAC_LV1= +VOW_WATF_MAC_LV2= +VOW_WATF_MAC_LV3= +VOW_WATF_Q_LV0= +VOW_WATF_Q_LV1= +VOW_WATF_Q_LV2= +VOW_WATF_Q_LV3= +VOW_WMM_Search_Rule_Band0= +VOW_WMM_Search_Rule_Band1= +WCNTest=0 +Wds0Key= +Wds1Key= +Wds2Key= +Wds3Key= +WdsEnable=0 +WdsEncrypType=NONE +WdsList= +WdsPhyMode=0 +WHNAT=0 +WiFiTest=0 +WirelessMode=9 +WmmCapable=1 +WPAPSK= +WPAPSK1=12345678 +WPAPSK10= +WPAPSK11= +WPAPSK12= +WPAPSK13= +WPAPSK14= +WPAPSK15= +WPAPSK16= +WPAPSK2= +WPAPSK3= +WPAPSK4= +WPAPSK5= +WPAPSK6= +WPAPSK7= +WPAPSK8= +WPAPSK9= +WscConfMode=0 +WscConfStatus=2 diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615.1.5G.dat b/package/lean/mt/drivers/mt_wifi/files/mt7615.1.5G.dat new file mode 100644 index 000000000..40cefb46a --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7615.1.5G.dat @@ -0,0 +1,375 @@ +Default +AccessControlList0= +AccessControlList1= +AccessControlList10= +AccessControlList11= +AccessControlList12= +AccessControlList13= +AccessControlList14= +AccessControlList15= +AccessControlList2= +AccessControlList3= +AccessControlList4= +AccessControlList5= +AccessControlList6= +AccessControlList7= +AccessControlList8= +AccessControlList9= +AccessPolicy0=0 +AccessPolicy1=0 +AccessPolicy10=0 +AccessPolicy11=0 +AccessPolicy12=0 +AccessPolicy13=0 +AccessPolicy14=0 +AccessPolicy15=0 +AccessPolicy2=0 +AccessPolicy3=0 +AccessPolicy4=0 +AccessPolicy5=0 +AccessPolicy6=0 +AccessPolicy7=0 +AccessPolicy8=0 +AccessPolicy9=0 +AckPolicy=0;0;0;0 +APACM=0;0;0;0 +APAifsn=3;7;1;1 +ApCliAuthMode= +ApCliBssid= +ApCliDefaultKeyID= +ApCliEnable= +ApCliEncrypType= +ApCliKey1Str= +ApCliKey1Str1= +ApCliKey1Type= +ApCliKey2Str= +ApCliKey2Str1= +ApCliKey2Type= +ApCliKey3Str= +ApCliKey3Str1= +ApCliKey3Type= +ApCliKey4Str= +ApCliKey4Str1= +ApCliKey4Type= +ApCliSsid= +ApCliWirelessMode= +ApCliWPAPSK= +ApCliWPAPSK1= +APCwmax=6;10;4;3 +APCwmin=4;4;3;2 +APSDCapable=1 +APTxop=0;0;94;47 +AuthMode=OPEN +AutoChannelSelect=0 +AutoChannelSkipList= +AutoProvisionEn=0 +BandSteering=0 +BasicRate=15 +BeaconPeriod=100 +BFBACKOFFenable=0 +BgndScanSkipCh= +BGProtection=0 +BndStrgBssIdx= +BSSACM=0;0;0;0 +BSSAifsn=3;7;2;2 +BSSCwmax=10;10;4;3 +BSSCwmin=4;4;3;2 +BssidNum=1 +BSSTxop=0;0;94;47 +BW_Enable=0 +BW_Guarantee_Rate= +BW_Maximum_Rate= +BW_Priority= +BW_Root=0 +CalCacheApply=0 +CarrierDetect=0 +Channel=36 +ChannelGrp= +CountryCode=US +CountryRegion=5 +CountryRegionABand=7 +CP_SUPPORT=2 +CSPeriod=6 +DBDC_MODE=1 +DebugFlags=0 +DefaultKeyID=1 +DfsCalibration=0 +DfsEnable=1 +DfsFalseAlarmPrevent=1 +DfsZeroWait=0 +DfsZeroWaitCacTime=255 +DisableOLBC=0 +DtimPeriod=1 +E2pAccessMode=2 +EAPifname=br0 +EDCCAEnable=1 +EncrypType=NONE +EthConvertMode=dongle +EtherTrafficBand=0 +Ethifname= +ETxBfEnCond=1 +FineAGC=0 +FixedTxMode= +ForceRoamSupport= +FragThreshold=2346 +FreqDelta=0 +FtSupport=0 +GreenAP=1 +G_BAND_256QAM=1 +HideSSID=0 +HT_AMSDU=0 +HT_AutoBA=1 +HT_BADecline=0 +HT_BAWinSize=64 +HT_BSSCoexistence=1 +HT_BW=1 +HT_DisallowTKIP=1 +HT_EXTCHA=1 +HT_GI=1 +HT_HTC=1 +HT_LDPC=1 +HT_LinkAdapt=0 +HT_MCS=33 +HT_MpduDensity=5 +HT_OpMode=0 +HT_PROTECT=1 +HT_RxStream=2 +HT_STBC=1 +HT_TxStream=2 +IcapMode=0 +idle_timeout_interval=0 +IEEE80211H=1 +IEEE8021X=0 +IgmpSnEnable=0 +ITxBfEn=1 +Key1Str= +Key1Str1= +Key1Str10= +Key1Str11= +Key1Str12= +Key1Str13= +Key1Str14= +Key1Str15= +Key1Str16= +Key1Str2= +Key1Str3= +Key1Str4= +Key1Str5= +Key1Str6= +Key1Str7= +Key1Str8= +Key1Str9= +Key1Type=0 +Key2Str= +Key2Str1= +Key2Str10= +Key2Str11= +Key2Str12= +Key2Str13= +Key2Str14= +Key2Str15= +Key2Str16= +Key2Str2= +Key2Str3= +Key2Str4= +Key2Str5= +Key2Str6= +Key2Str7= +Key2Str8= +Key2Str9= +Key2Type=0 +Key3Str= +Key3Str1= +Key3Str10= +Key3Str11= +Key3Str12= +Key3Str13= +Key3Str14= +Key3Str15= +Key3Str16= +Key3Str2= +Key3Str3= +Key3Str4= +Key3Str5= +Key3Str6= +Key3Str7= +Key3Str8= +Key3Str9= +Key3Type=0 +Key4Str= +Key4Str1= +Key4Str10= +Key4Str11= +Key4Str12= +Key4Str13= +Key4Str14= +Key4Str15= +Key4Str16= +Key4Str2= +Key4Str3= +Key4Str4= +Key4Str5= +Key4Str6= +Key4Str7= +Key4Str8= +Key4Str9= +Key4Type=0 +LinkTestSupport=0 +MACRepeaterEn= +MACRepeaterOuiMode=2 +MUTxRxEnable=1 +NoForwarding=0 +NoForwardingBTNBSSID=0 +own_ip_addr=10.10.10.254 +PcieAspm=0 +PERCENTAGEenable=0 +PhyRateLimit=0 +PMFMFPC=0 +PMFMFPR=0 +PMFSHA256=0 +PMKCachePeriod=10 +PowerUpCckOfdm=0:0:0:0:0:0:0 +PowerUpHT20=0:0:0:0:0:0:0 +PowerUpHT40=0:0:0:0:0:0:0 +PowerUpVHT160=0:0:0:0:0:0:0 +PowerUpVHT20=0:0:0:0:0:0:0 +PowerUpVHT40=0:0:0:0:0:0:0 +PowerUpVHT80=0:0:0:0:0:0:0 +PreAntSwitch= +PreAuth=0 +PreAuthifname=br0 +RadioLinkSelection=0 +RadioOn=1 +RADIUS_Acct_Key= +RADIUS_Acct_Port=1813 +RADIUS_Acct_Server= +RADIUS_Key1= +RADIUS_Key10= +RADIUS_Key11= +RADIUS_Key12= +RADIUS_Key13= +RADIUS_Key14= +RADIUS_Key15= +RADIUS_Key16= +RADIUS_Key2= +RADIUS_Key3= +RADIUS_Key4= +RADIUS_Key5= +RADIUS_Key6= +RADIUS_Key7= +RADIUS_Key8= +RADIUS_Key9= +RADIUS_Port=1812 +RADIUS_Server=0 +RDRegion= +RED_Enable=1 +RekeyInterval=3600 +RekeyMethod=DISABLE +RRMEnable=0 +RTSThreshold=2347 +session_timeout_interval=0 +ShortSlot=1 +SKUenable=0 +SSID= +SSID1=K2P_5G +SSID10= +SSID11= +SSID12= +SSID13= +SSID14= +SSID15= +SSID16= +SSID2= +SSID3= +SSID4= +SSID5= +SSID6= +SSID7= +SSID8= +SSID9= +StationKeepAlive=0 +StreamMode=0 +StreamModeMac0= +StreamModeMac1= +StreamModeMac2= +StreamModeMac3= +TGnWifiTest=0 +ThermalRecal=0 +TxBurst=1 +TxPower=100 +TxPreamble=1 +VHT_BW=1 +VHT_BW_SIGNAL=0 +VHT_LDPC=1 +VHT_Sec80_Channel=0 +VHT_SGI=1 +VHT_STBC=1 +VLANID=0 +VLANPriority=0 +VLANTag=0 +VOW_Airtime_Ctrl_En= +VOW_Airtime_Fairness_En=1 +VOW_BW_Ctrl=0 +VOW_Group_Backlog= +VOW_Group_DWRR_Max_Wait_Time= +VOW_Group_DWRR_Quantum= +VOW_Group_Max_Airtime_Bucket_Size= +VOW_Group_Max_Rate= +VOW_Group_Max_Rate_Bucket_Size= +VOW_Group_Max_Ratio= +VOW_Group_Max_Wait_Time= +VOW_Group_Min_Airtime_Bucket_Size= +VOW_Group_Min_Rate= +VOW_Group_Min_Rate_Bucket_Size= +VOW_Group_Min_Ratio= +VOW_Rate_Ctrl_En= +VOW_Refill_Period= +VOW_RX_En=1 +VOW_Sta_BE_DWRR_Quantum= +VOW_Sta_BK_DWRR_Quantum= +VOW_Sta_DWRR_Max_Wait_Time= +VOW_Sta_VI_DWRR_Quantum= +VOW_Sta_VO_DWRR_Quantum= +VOW_WATF_Enable= +VOW_WATF_MAC_LV0= +VOW_WATF_MAC_LV1= +VOW_WATF_MAC_LV2= +VOW_WATF_MAC_LV3= +VOW_WATF_Q_LV0= +VOW_WATF_Q_LV1= +VOW_WATF_Q_LV2= +VOW_WATF_Q_LV3= +VOW_WMM_Search_Rule_Band0= +VOW_WMM_Search_Rule_Band1= +WCNTest=0 +Wds0Key= +Wds1Key= +Wds2Key= +Wds3Key= +WdsEnable=0 +WdsEncrypType=NONE +WdsList= +WdsPhyMode=0 +WHNAT=0 +WiFiTest=0 +WirelessMode=14 +WmmCapable=1 +WPAPSK= +WPAPSK1=12345678 +WPAPSK10= +WPAPSK11= +WPAPSK12= +WPAPSK13= +WPAPSK14= +WPAPSK15= +WPAPSK16= +WPAPSK2= +WPAPSK3= +WPAPSK4= +WPAPSK5= +WPAPSK6= +WPAPSK7= +WPAPSK8= +WPAPSK9= +WscConfMode=0 +WscConfStatus=2 diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615.lua b/package/lean/mt/drivers/mt_wifi/files/mt7615.lua new file mode 100644 index 000000000..8612a5d0d --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7615.lua @@ -0,0 +1,219 @@ +#!/usr/bin/lua +-- Alternative for OpenWrt's /sbin/wifi. +-- Copyright Not Reserved. +-- Hua Shao + +package.path = '/lib/wifi/?.lua;'..package.path + +local vif_prefix = {"ra", "rai", "rae", "rax", "ray", "raz", + "apcli", "apclix", "apclii", "apcliy", "apclie", "apcliz", } + +local function esc(x) + return (x:gsub('%%', '%%%%') + :gsub('^%^', '%%^') + :gsub('%$$', '%%$') + :gsub('%(', '%%(') + :gsub('%)', '%%)') + :gsub('%.', '%%.') + :gsub('%[', '%%[') + :gsub('%]', '%%]') + :gsub('%*', '%%*') + :gsub('%+', '%%+') + :gsub('%-', '%%-') + :gsub('%?', '%%?')) +end + +function add_vif_into_lan(vif) + local mtkwifi = require("mtkwifi") + local brvifs = mtkwifi.__trim( + mtkwifi.read_pipe("uci get network.lan.ifname")) + if not string.match(brvifs, esc(vif)) then + nixio.syslog("debug", "mt7615_up: add "..vif.." into lan") + brvifs = brvifs.." "..vif + os.execute("uci set network.lan.ifname=\""..brvifs.."\"") + os.execute("uci commit") + -- os.execute("brctl addif br-lan "..vif) + os.execute("ubus call network.interface.lan add_device \"{\\\"name\\\":\\\""..vif.."\\\"}\"") + end +end + +function mt7615_up(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + + nixio.syslog("debug", "mt7615_up called!") + + local devs, l1parser = mtkwifi.__get_l1dat() + -- l1 profile present, good! + if l1parser and devs then + dev = devs.devname_ridx[devname] + if not dev then + nixio.syslog("err", "mt7615_up: dev "..devname.." not found!") + return + end + -- we have to bring up main_ifname first, main_ifname will create all other vifs. + if mtkwifi.exists("/sys/class/net/"..dev.main_ifname) then + nixio.syslog("debug", "mt7615_up: ifconfig "..dev.main_ifname.." up") + os.execute("ifconfig "..dev.main_ifname.." up") + add_vif_into_lan(dev.main_ifname) + else + nixio.syslog("err", "mt7615_up: main_ifname "..dev.main_ifname.." missing, quit!") + return + end + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if vif ~= dev.main_ifname and + ( string.match(vif, esc(dev.ext_ifname).."[0-9]+") + or string.match(vif, esc(dev.apcli_ifname).."[0-9]+") + or string.match(vif, esc(dev.wds_ifname).."[0-9]+") + or string.match(vif, esc(dev.mesh_ifname).."[0-9]+")) + then + nixio.syslog("debug", "mt7615_up: ifconfig "..vif.."0 up") + os.execute("ifconfig "..vif.." up") + add_vif_into_lan(vif) + -- else nixio.syslog("debug", "mt7615_up: skip "..vif..", prefix not match "..pre) + end + end + elseif mtkwifi.exists("/etc/wireless/mt7615/"..devname..".dat") then + for _, pre in ipairs(vif_prefix) do + -- we have to bring up root vif first, root vif will create all other vifs. + if mtkwifi.exists("/sys/class/net/"..pre.."0") then + nixio.syslog("debug", "mt7615_up: ifconfig "..pre.."0 up") + os.execute("ifconfig "..pre.."0 up") + add_vif_into_lan(pre.."0") + end + + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + -- nixio.syslog("debug", "mt7615_up: navigate "..pre) + if string.match(vif, pre.."[1-9]+") then + nixio.syslog("debug", "mt7615_up: ifconfig "..vif.." up") + os.execute("ifconfig "..vif.." up") + add_vif_into_lan(vif) + -- else nixio.syslog("debug", "mt7615_up: skip "..vif..", prefix not match "..pre) + end + end + end + else nixio.syslog("debug", "mt7615_up: skip "..devname..", config not exist") + end + + os.execute(" rm -rf /tmp/mtk/wifi/mt7615*.need_reload") +end + +function mt7615_down(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + nixio.syslog("debug", "mt7615_down called!") + + local devs, l1parser = mtkwifi.__get_l1dat() + -- l1 profile present, good! + if l1parser and devs then + dev = devs.devname_ridx[devname] + if not dev then + nixio.syslog("err", "mt7615_down: dev "..devname.." not found!") + return + end + + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if vif == dev.main_ifname + or string.match(vif, esc(dev.ext_ifname).."[0-9]+") + or string.match(vif, esc(dev.apcli_ifname).."[0-9]+") + or string.match(vif, esc(dev.wds_ifname).."[0-9]+") + or string.match(vif, esc(dev.mesh_ifname).."[0-9]+") + then + nixio.syslog("debug", "mt7615_down: ifconfig "..vif.." down") + os.execute("ifconfig "..vif.." down") + local brvifs = mtkwifi.__trim(mtkwifi.read_pipe("uci get network.lan.ifname")) + if string.match(brvifs, esc(vif)) then + brvifs = mtkwifi.__trim(string.gsub(brvifs, esc(vif), "")) + nixio.syslog("debug", "mt7615_down: remove "..vif.." from lan") + os.execute("uci set network.lan.ifname=\""..brvifs.."\"") + os.execute("uci commit") + os.execute("ubus call network.interface.lan remove_device \"{\\\"name\\\":\\\""..vif.."\\\"}\"") + end + -- else nixio.syslog("debug", "mt7615_down: skip "..vif..", prefix not match "..pre) + end + end + elseif mtkwifi.exists("/etc/wireless/mt7615/"..devname..".dat") then + for _, pre in ipairs(vif_prefix) do + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if string.match(vif, pre.."[0-9]+") then + nixio.syslog("debug", "mt7615_down: ifconfig "..vif.."down") + os.execute("ifconfig "..vif.." down") + local brvifs = mtkwifi.read_pipe("uci get network.lan.ifname") + if string.match(brvifs, vif) then + brvifs = mtkwifi.__trim(string.gsub(brvifs, vif, "")) + nixio.syslog("debug", "mt7615_down: remove "..vif.." from lan") + os.execute("uci set network.lan.ifname=\""..brvifs.."\"") + os.execute("uci commit") + os.execute("ubus call network.interface.lan remove_device \"{\\\"name\\\":\\\""..vif.."\\\"}\"") + end + -- else nixio.syslog("debug", "mt7615_down: skip "..vif..", prefix not match "..pre) + end + end + end + else nixio.syslog("debug", "mt7615_down: skip "..devname..", config not exist") + end + + os.execute(" rm -rf /tmp/mtk/wifi/mt7615*.need_reload") +end + +function mt7615_reload(devname) + local nixio = require("nixio") + nixio.syslog("debug", "mt7615_reload called!") + mt7615_down(devname) + mt7615_up(devname) +end + +function mt7615_restart(devname) + local nixio = require("nixio") + nixio.syslog("debug", "mt7615_restart called!") + mt7615_down(devname) + os.execute("rmmod mt7615") + os.execute("modprobe mt7615") + mt7615_up(devname) +end + +function mt7615_reset(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + nixio.syslog("debug", "mt7615_reset called!") + if mtkwifi.exists("/rom/etc/wireless/mt7615/") then + os.execute("rm -rf /etc/wireless/mt7615/") + os.execute("cp -rf /rom/etc/wireless/mt7615/ /etc/wireless/") + mt7615_reload(devname) + else + nixio.syslog("debug", "mt7615_reset: /rom"..profile.." missing, unable to reset!") + end +end + +function mt7615_status(devname) + return wifi_common_status() +end + +function mt7615_detect(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + nixio.syslog("debug", "mt7615_detect called!") + + for _,dev in ipairs(mtkwifi.get_all_devs()) do + local relname = string.format("%s%d%d",dev.maindev,dev.mainidx,dev.subidx) + print([[ +config wifi-device ]]..relname.."\n"..[[ + option type mt7615 + option vendor ralink +]]) + for _,vif in ipairs(dev.vifs) do + print([[ +config wifi-iface + option device ]]..relname.."\n"..[[ + option ifname ]]..vif.vifname.."\n"..[[ + option network lan + option mode ap + option ssid ]]..vif.__ssid.."\n") + end + end +end + diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615e-sku-bf.dat b/package/lean/mt/drivers/mt_wifi/files/mt7615e-sku-bf.dat new file mode 100644 index 000000000..be9c0d353 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7615e-sku-bf.dat @@ -0,0 +1,65 @@ +# Single SKU Max Power Table | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 2.4G Channel |CCK | | | |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |Txstream_Delta | | | | | | | | | | | | | | | | | | | | | +Band: 2.4G |CCK_1M |CCK_2M |CCK_5.5M |CCK_11M |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | | | | | | | | | | | | | | | | | +Ch1 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |20 |12 |18 |16 |8 | |8 | |8 | |9 |11 |12 |2 |1 |3 | | | | | | | | | | | | | | | | | | | +Ch2 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |19 |19 |10 |12 |8 | |8 | |8 | |9 |16 |12 |5 |4 |0 | | | | | | | | | | | | | | | | | | | +Ch3 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |17 |18 |16 |20 |8 | |8 | |8 | |12 |8 |20 |0 |2 |0 | | | | | | | | | | | | | | | | | | | +Ch4 |8 | |8 | |8 | |8 | |8 | |8 |8 |9 |8 | |8 | |8 | |14 |10 |14 |18 |8 | |8 | |8 | |14 |12 |10 |3 |4 |5 | | | | | | | | | | | | | | | | | | | +Ch5 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |10 |13 |11 |8 |8 | |8 | |8 | |12 |8 |9 |4 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch6 |8 | |8 | |8 | |8 | |8 | |8 |8 |13 |8 | |8 | |8 | |11 |9 |12 |16 |8 | |8 | |8 | |9 |17 |11 |5 |2 |1 | | | | | | | | | | | | | | | | | | | +Ch7 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |14 |11 |13 |18 |8 | |8 | |8 | |16 |13 |10 |2 |5 |4 | | | | | | | | | | | | | | | | | | | +Ch8 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |14 |9 |11 |10 |8 | |8 | |8 | |11 |14 |8 |5 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch9 |8 | |8 | |8 | |8 | |8 | |8 |8 |11 |8 | |8 | |8 | |12 |9 |15 |19 |8 | |8 | |8 | |14 |20 |12 |2 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch10 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |17 |14 |17 |15 |8 | |8 | |8 | |9 |17 |8 |2 |4 |2 | | | | | | | | | | | | | | | | | | | +Ch11 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |20 |10 |20 |18 |8 | |8 | |8 | |12 |8 |20 |3 |1 |4 | | | | | | | | | | | | | | | | | | | +Ch12 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |20 |16 |17 |9 |8 | |8 | |8 | |11 |20 |9 |0 |0 |1 | | | | | | | | | | | | | | | | | | | +Ch13 |8 | |8 | |8 | |8 | |8 | |8 |8 |8 |8 | |8 | |8 | |11 |16 |19 |16 |8 | |8 | |8 | |15 |12 |12 |2 |0 |2 | | | | | | | | | | | | | | | | | | | +Ch14 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |15 |17 |16 |14 |8 | |8 | |8 | |12 |14 |20 |4 |1 |5 | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 5G Channel |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |VHT80 | | | | | | | | | |VHT160 | | | | | | | | | |Txstream_Delta | | | | | +Band: 5G |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |VHT80_MCS0 |VHT80_MCS1 |VHT80_MCS2 |VHT80_MCS3 |VHT80_MCS4 |VHT80_MCS5 |VHT80_MCS6 |VHT80_MCS7 |VHT80_MCS8 |VHT80_MCS9 |VHT160_MCS0 |VHT160_MCS1 |VHT160_MCS2 |VHT160_MCS3 |VHT160_MCS4 |VHT160_MCS5 |VHT160_MCS6 |VHT160_MCS7 |VHT160_MCS8 |VHT160_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | +Ch184 |18 | |18 | |18 | |18 |18 |15 |18 | |12 | |13 | |11 |14 |16 |16 |12 | |12 | |13 | |20 |17 |16 |17 |18 | |9 | |16 | |17 |20 |18 |16 |19 | |15 | |9 | |17 |8 |17 |0 |4 |4 | | | +Ch188 |18 | |18 | |18 | |18 |18 |16 |20 | |9 | |9 | |11 |8 |12 |18 |15 | |11 | |11 | |14 |8 |17 |16 |16 | |16 | |12 | |8 |13 |19 |18 |11 | |9 | |12 | |14 |8 |13 |5 |2 |0 | | | +Ch192 |18 | |18 | |18 | |18 |18 |15 |9 | |11 | |9 | |15 |14 |11 |19 |15 | |8 | |18 | |20 |20 |8 |9 |9 | |9 | |11 | |18 |13 |14 |20 |18 | |10 | |14 | |12 |13 |16 |0 |2 |0 | | | +Ch196 |18 | |18 | |18 | |18 |18 |10 |11 | |19 | |13 | |12 |11 |10 |13 |11 | |19 | |10 | |16 |20 |15 |15 |8 | |14 | |8 | |18 |20 |15 |17 |17 | |14 | |12 | |12 |8 |16 |4 |3 |2 | | | +Ch8 |18 | |18 | |18 | |18 |18 |18 |13 | |19 | |20 | |18 |10 |9 |8 |8 | |17 | |15 | |17 |9 |18 |19 |11 | |12 | |15 | |20 |12 |12 |13 |9 | |9 | |15 | |10 |11 |17 |4 |3 |3 | | | +Ch12 |18 | |18 | |18 | |18 |18 |17 |20 | |14 | |10 | |10 |16 |15 |13 |11 | |15 | |16 | |17 |11 |15 |9 |18 | |8 | |20 | |19 |11 |9 |20 |8 | |18 | |8 | |8 |18 |18 |1 |3 |4 | | | +Ch16 |18 | |18 | |18 | |18 |18 |10 |18 | |18 | |8 | |19 |8 |12 |19 |16 | |19 | |18 | |16 |19 |12 |18 |18 | |9 | |10 | |18 |20 |20 |20 |9 | |11 | |20 | |17 |14 |16 |2 |2 |2 | | | +Ch36 |18 | |18 | |18 | |18 |18 |18 |19 | |8 | |11 | |16 |10 |9 |19 |11 | |19 | |9 | |8 |19 |8 |11 |17 | |20 | |14 | |9 |19 |19 |20 |13 | |12 | |19 | |13 |17 |9 |5 |1 |2 | | | +Ch40 |18 | |18 | |18 | |18 |18 |13 |20 | |13 | |19 | |16 |11 |14 |17 |17 | |14 | |8 | |13 |8 |10 |20 |10 | |9 | |14 | |11 |14 |17 |9 |20 | |15 | |19 | |9 |8 |11 |3 |1 |1 | | | +Ch44 |18 | |18 | |18 | |18 |18 |10 |14 | |19 | |20 | |17 |16 |12 |18 |8 | |17 | |18 | |15 |19 |14 |11 |13 | |14 | |12 | |16 |16 |19 |13 |14 | |19 | |14 | |20 |20 |11 |5 |1 |0 | | | +Ch48 |18 | |18 | |18 | |18 |18 |8 |12 | |12 | |19 | |11 |8 |11 |20 |12 | |12 | |11 | |15 |16 |10 |12 |16 | |11 | |15 | |18 |19 |17 |16 |17 | |11 | |8 | |10 |16 |16 |5 |5 |0 | | | +Ch52 |18 | |18 | |18 | |18 |18 |15 |12 | |15 | |20 | |9 |10 |10 |14 |8 | |20 | |10 | |16 |17 |18 |11 |16 | |17 | |10 | |17 |12 |13 |17 |17 | |13 | |18 | |18 |20 |13 |4 |3 |4 | | | +Ch56 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |20 |13 |14 |11 | |10 | |20 | |10 |8 |16 |12 |10 | |16 | |11 | |9 |11 |14 |17 |12 | |17 | |13 | |18 |10 |19 |0 |3 |3 | | | +Ch60 |18 | |18 | |18 | |18 |18 |14 |11 | |8 | |20 | |13 |16 |13 |11 |20 | |9 | |17 | |16 |11 |8 |12 |17 | |15 | |8 | |16 |10 |20 |19 |15 | |13 | |9 | |17 |18 |11 |4 |1 |2 | | | +Ch64 |18 | |18 | |18 | |18 |18 |13 |14 | |8 | |12 | |17 |8 |12 |18 |17 | |17 | |14 | |18 |8 |8 |20 |17 | |16 | |20 | |9 |15 |11 |10 |11 | |18 | |10 | |10 |15 |19 |2 |1 |4 | | | +Ch68 |18 | |18 | |18 | |18 |18 |14 |19 | |17 | |9 | |18 |19 |20 |12 |14 | |8 | |14 | |20 |20 |18 |9 |18 | |11 | |19 | |19 |10 |11 |8 |18 | |9 | |8 | |16 |11 |8 |3 |3 |1 | | | +Ch72 |18 | |18 | |18 | |18 |18 |19 |13 | |20 | |11 | |16 |9 |19 |20 |19 | |14 | |8 | |9 |17 |13 |19 |15 | |8 | |9 | |19 |14 |19 |15 |18 | |16 | |12 | |13 |15 |10 |4 |3 |1 | | | +Ch76 |18 | |18 | |18 | |18 |18 |17 |13 | |16 | |20 | |16 |8 |9 |20 |11 | |17 | |11 | |8 |18 |9 |20 |9 | |17 | |16 | |11 |11 |11 |18 |10 | |13 | |W | |20 |17 |8 |1 |3 |3 | | | +Ch80 |18 | |18 | |18 | |18 |18 |14 |20 | |13 | |13 | |17 |8 |10 |16 |8 | |9 | |19 | |16 |17 |17 |19 |15 | |9 | |13 | |16 |13 |14 |12 |9 | |20 | |20 | |14 |18 |18 |0 |4 |2 | | | +Ch84 |18 | |18 | |18 | |18 |18 |11 |18 | |20 | |9 | |13 |14 |11 |16 |15 | |12 | |11 | |9 |19 |13 |11 |11 | |9 | |15 | |16 |18 |13 |12 |8 | |8 | |8 | |10 |12 |15 |3 |2 |5 | | | +Ch88 |18 | |18 | |18 | |18 |18 |18 |19 | |9 | |17 | |15 |8 |19 |11 |11 | |14 | |9 | |14 |20 |20 |11 |11 | |15 | |12 | |14 |11 |8 |18 |15 | |19 | |18 | |12 |20 |16 |5 |5 |1 | | | +Ch92 |18 | |18 | |18 | |18 |18 |11 |8 | |15 | |13 | |13 |13 |13 |16 |14 | |14 | |9 | |9 |15 |20 |11 |17 | |10 | |14 | |13 |17 |11 |8 |18 | |20 | |8 | |10 |19 |18 |1 |4 |4 | | | +Ch96 |18 | |18 | |18 | |18 |18 |8 |12 | |16 | |9 | |13 |12 |9 |8 |11 | |8 | |8 | |19 |11 |15 |16 |8 | |11 | |16 | |18 |16 |9 |19 |9 | |10 | |15 | |19 |19 |15 |4 |2 |4 | | | +Ch100 |18 | |18 | |18 | |18 |18 |18 |13 | |20 | |20 | |12 |9 |19 |10 |9 | |14 | |8 | |19 |10 |17 |9 |10 | |10 | |8 | |13 |12 |11 |20 |11 | |16 | |18 | |14 |16 |19 |1 |1 |2 | | | +Ch104 |18 | |18 | |18 | |18 |18 |19 |12 | |20 | |14 | |16 |15 |9 |19 |11 | |15 | |11 | |12 |18 |15 |11 |15 | |19 | |10 | |14 |15 |19 |9 |13 | |19 | |13 | |11 |11 |17 |2 |2 |0 | | | +Ch108 |18 | |18 | |18 | |18 |18 |18 |15 | |13 | |16 | |11 |19 |19 |18 |19 | |12 | |17 | |8 |9 |10 |8 |8 | |18 | |8 | |10 |11 |17 |15 |10 | |19 | |13 | |16 |10 |15 |0 |2 |3 | | | +Ch112 |18 | |18 | |18 | |18 |18 |8 |13 | |9 | |17 | |9 |15 |17 |10 |19 | |9 | |19 | |11 |16 |14 |16 |8 | |18 | |13 | |16 |13 |17 |19 |11 | |8 | |8 | |18 |14 |17 |5 |2 |5 | | | +Ch116 |18 | |18 | |18 | |18 |18 |8 |20 | |11 | |15 | |8 |11 |8 |18 |15 | |13 | |17 | |14 |13 |9 |8 |14 | |14 | |11 | |9 |19 |17 |11 |11 | |8 | |20 | |8 |10 |20 |5 |2 |1 | | | +Ch120 |18 | |18 | |18 | |18 |18 |14 |20 | |8 | |20 | |14 |10 |10 |17 |12 | |16 | |20 | |10 |20 |17 |18 |9 | |15 | |14 | |17 |13 |14 |16 |8 | |18 | |10 | |15 |12 |12 |1 |5 |3 | | | +Ch124 |18 | |18 | |18 | |18 |18 |20 |9 | |17 | |12 | |12 |8 |14 |8 |8 | |20 | |17 | |16 |20 |13 |14 |16 | |10 | |14 | |20 |15 |17 |8 |10 | |13 | |13 | |11 |13 |9 |5 |0 |5 | | | +Ch128 |18 | |18 | |18 | |18 |18 |9 |19 | |9 | |14 | |8 |14 |11 |9 |14 | |16 | |15 | |14 |10 |15 |14 |14 | |20 | |10 | |16 |15 |11 |12 |13 | |13 | |13 | |12 |15 |20 |1 |4 |3 | | | +Ch132 |18 | |18 | |18 | |18 |18 |20 |16 | |13 | |8 | |18 |11 |20 |12 |11 | |11 | |14 | |12 |13 |8 |12 |13 | |10 | |20 | |19 |12 |13 |14 |12 | |11 | |19 | |19 |20 |8 |3 |1 |4 | | | +Ch136 |18 | |18 | |18 | |18 |18 |12 |12 | |19 | |10 | |20 |10 |8 |17 |8 | |12 | |10 | |10 |13 |13 |12 |8 | |11 | |18 | |14 |12 |17 |8 |14 | |14 | |9 | |11 |18 |14 |1 |2 |2 | | | +Ch140 |18 | |18 | |18 | |18 |18 |12 |10 | |13 | |9 | |16 |8 |20 |10 |17 | |8 | |15 | |13 |20 |15 |10 |18 | |13 | |12 | |12 |16 |18 |12 |17 | |10 | |16 | |11 |15 |14 |3 |2 |5 | | | +Ch144 |18 | |18 | |18 | |18 |18 |19 |9 | |15 | |8 | |13 |18 |17 |9 |19 | |16 | |11 | |20 |12 |15 |19 |10 | |17 | |15 | |17 |14 |9 |9 |13 | |17 | |16 | |10 |9 |10 |1 |5 |2 | | | +Ch149 |18 | |18 | |18 | |18 |18 |15 |20 | |12 | |19 | |19 |19 |10 |10 |13 | |15 | |19 | |12 |19 |10 |14 |15 | |10 | |15 | |9 |8 |11 |15 |13 | |10 | |16 | |15 |18 |12 |5 |5 |2 | | | +Ch153 |18 | |18 | |18 | |18 |18 |20 |17 | |8 | |19 | |16 |20 |13 |16 |18 | |14 | |11 | |10 |16 |16 |19 |15 | |13 | |17 | |19 |18 |19 |20 |8 | |18 | |9 | |17 |11 |11 |1 |2 |1 | | | +Ch157 |18 | |18 | |18 | |18 |18 |13 |17 | |12 | |19 | |16 |8 |17 |11 |12 | |15 | |14 | |18 |11 |12 |9 |18 | |20 | |13 | |16 |13 |20 |17 |19 | |10 | |12 | |20 |18 |16 |5 |2 |3 | | | +Ch161 |18 | |18 | |18 | |18 |18 |12 |12 | |16 | |12 | |15 |11 |18 |11 |13 | |17 | |19 | |11 |13 |13 |9 |15 | |10 | |10 | |19 |13 |20 |13 |9 | |8 | |8 | |20 |14 |12 |0 |4 |1 | | | +Ch165 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |8 |19 |15 |10 | |17 | |13 | |13 |19 |20 |8 |18 | |15 | |20 | |16 |9 |14 |11 |20 | |11 | |19 | |15 |16 |8 |1 |2 |0 | | | +Ch169 |18 | |18 | |18 | |18 |18 |8 |17 | |17 | |13 | |16 |8 |14 |18 |11 | |8 | |18 | |20 |14 |8 |17 |8 | |13 | |18 | |19 |20 |19 |20 |17 | |13 | |20 | |9 |15 |18 |0 |3 |4 | | | +Ch173 |18 | |18 | |18 | |18 |18 |14 |9 | |13 | |12 | |15 |14 |15 |10 |10 | |18 | |16 | |16 |8 |13 |16 |11 | |11 | |13 | |13 |15 |12 |20 |15 | |14 | |13 | |16 |11 |14 |3 |3 |4 | | | +Ch177 |18 | |18 | |18 | |18 |18 |19 |18 | |16 | |10 | |20 |13 |11 |16 |12 | |16 | |18 | |18 |11 |18 |8 |13 | |14 | |11 | |18 |14 |16 |16 |19 | |16 | |13 | |15 |8 |13 |5 |0 |0 | | | +Ch181 |18 | |18 | |18 | |18 |18 |20 |11 | |10 | |9 | |8 |9 |15 |15 |8 | |8 | |12 | |11 |9 |18 |20 |11 | |17 | |11 | |8 |15 |8 |18 |12 | |18 | |16 | |19 |9 |14 |4 |1 |4 | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615e-sku.dat b/package/lean/mt/drivers/mt_wifi/files/mt7615e-sku.dat new file mode 100644 index 000000000..be9c0d353 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7615e-sku.dat @@ -0,0 +1,65 @@ +# Single SKU Max Power Table | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 2.4G Channel |CCK | | | |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |Txstream_Delta | | | | | | | | | | | | | | | | | | | | | +Band: 2.4G |CCK_1M |CCK_2M |CCK_5.5M |CCK_11M |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | | | | | | | | | | | | | | | | | +Ch1 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |20 |12 |18 |16 |8 | |8 | |8 | |9 |11 |12 |2 |1 |3 | | | | | | | | | | | | | | | | | | | +Ch2 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |19 |19 |10 |12 |8 | |8 | |8 | |9 |16 |12 |5 |4 |0 | | | | | | | | | | | | | | | | | | | +Ch3 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |17 |18 |16 |20 |8 | |8 | |8 | |12 |8 |20 |0 |2 |0 | | | | | | | | | | | | | | | | | | | +Ch4 |8 | |8 | |8 | |8 | |8 | |8 |8 |9 |8 | |8 | |8 | |14 |10 |14 |18 |8 | |8 | |8 | |14 |12 |10 |3 |4 |5 | | | | | | | | | | | | | | | | | | | +Ch5 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |10 |13 |11 |8 |8 | |8 | |8 | |12 |8 |9 |4 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch6 |8 | |8 | |8 | |8 | |8 | |8 |8 |13 |8 | |8 | |8 | |11 |9 |12 |16 |8 | |8 | |8 | |9 |17 |11 |5 |2 |1 | | | | | | | | | | | | | | | | | | | +Ch7 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |14 |11 |13 |18 |8 | |8 | |8 | |16 |13 |10 |2 |5 |4 | | | | | | | | | | | | | | | | | | | +Ch8 |8 | |8 | |8 | |8 | |8 | |8 |8 |15 |8 | |8 | |8 | |14 |9 |11 |10 |8 | |8 | |8 | |11 |14 |8 |5 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch9 |8 | |8 | |8 | |8 | |8 | |8 |8 |11 |8 | |8 | |8 | |12 |9 |15 |19 |8 | |8 | |8 | |14 |20 |12 |2 |5 |3 | | | | | | | | | | | | | | | | | | | +Ch10 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |17 |14 |17 |15 |8 | |8 | |8 | |9 |17 |8 |2 |4 |2 | | | | | | | | | | | | | | | | | | | +Ch11 |8 | |8 | |8 | |8 | |8 | |8 |8 |14 |8 | |8 | |8 | |20 |10 |20 |18 |8 | |8 | |8 | |12 |8 |20 |3 |1 |4 | | | | | | | | | | | | | | | | | | | +Ch12 |8 | |8 | |8 | |8 | |8 | |8 |8 |18 |8 | |8 | |8 | |20 |16 |17 |9 |8 | |8 | |8 | |11 |20 |9 |0 |0 |1 | | | | | | | | | | | | | | | | | | | +Ch13 |8 | |8 | |8 | |8 | |8 | |8 |8 |8 |8 | |8 | |8 | |11 |16 |19 |16 |8 | |8 | |8 | |15 |12 |12 |2 |0 |2 | | | | | | | | | | | | | | | | | | | +Ch14 |8 | |8 | |8 | |8 | |8 | |8 |8 |10 |8 | |8 | |8 | |15 |17 |16 |14 |8 | |8 | |8 | |12 |14 |20 |4 |1 |5 | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +# 5G Channel |OFDM | | | | | | | |VHT20 | | | | | | | | | |VHT40 | | | | | | | | | |VHT80 | | | | | | | | | |VHT160 | | | | | | | | | |Txstream_Delta | | | | | +Band: 5G |OFDM_6M |OFDM_9M |OFDM_12M |OFDM_18M |OFDM_24M |OFDM_36M |OFDM_48M |OFDM_54M |VHT20_MCS0 |VHT20_MCS1 |VHT20_MCS2 |VHT20_MCS3 |VHT20_MCS4 |VHT20_MCS5 |VHT20_MCS6 |VHT20_MCS7 |VHT20_MCS8 |VHT20_MCS9 |VHT40_MCS0 |VHT40_MCS1 |VHT40_MCS2 |VHT40_MCS3 |VHT40_MCS4 |VHT40_MCS5 |VHT40_MCS6 |VHT40_MCS7 |VHT40_MCS8 |VHT40_MCS9 |VHT80_MCS0 |VHT80_MCS1 |VHT80_MCS2 |VHT80_MCS3 |VHT80_MCS4 |VHT80_MCS5 |VHT80_MCS6 |VHT80_MCS7 |VHT80_MCS8 |VHT80_MCS9 |VHT160_MCS0 |VHT160_MCS1 |VHT160_MCS2 |VHT160_MCS3 |VHT160_MCS4 |VHT160_MCS5 |VHT160_MCS6 |VHT160_MCS7 |VHT160_MCS8 |VHT160_MCS9 |Txstream_3T |Txstream_2T |Txstream_1T | | | +Ch184 |18 | |18 | |18 | |18 |18 |15 |18 | |12 | |13 | |11 |14 |16 |16 |12 | |12 | |13 | |20 |17 |16 |17 |18 | |9 | |16 | |17 |20 |18 |16 |19 | |15 | |9 | |17 |8 |17 |0 |4 |4 | | | +Ch188 |18 | |18 | |18 | |18 |18 |16 |20 | |9 | |9 | |11 |8 |12 |18 |15 | |11 | |11 | |14 |8 |17 |16 |16 | |16 | |12 | |8 |13 |19 |18 |11 | |9 | |12 | |14 |8 |13 |5 |2 |0 | | | +Ch192 |18 | |18 | |18 | |18 |18 |15 |9 | |11 | |9 | |15 |14 |11 |19 |15 | |8 | |18 | |20 |20 |8 |9 |9 | |9 | |11 | |18 |13 |14 |20 |18 | |10 | |14 | |12 |13 |16 |0 |2 |0 | | | +Ch196 |18 | |18 | |18 | |18 |18 |10 |11 | |19 | |13 | |12 |11 |10 |13 |11 | |19 | |10 | |16 |20 |15 |15 |8 | |14 | |8 | |18 |20 |15 |17 |17 | |14 | |12 | |12 |8 |16 |4 |3 |2 | | | +Ch8 |18 | |18 | |18 | |18 |18 |18 |13 | |19 | |20 | |18 |10 |9 |8 |8 | |17 | |15 | |17 |9 |18 |19 |11 | |12 | |15 | |20 |12 |12 |13 |9 | |9 | |15 | |10 |11 |17 |4 |3 |3 | | | +Ch12 |18 | |18 | |18 | |18 |18 |17 |20 | |14 | |10 | |10 |16 |15 |13 |11 | |15 | |16 | |17 |11 |15 |9 |18 | |8 | |20 | |19 |11 |9 |20 |8 | |18 | |8 | |8 |18 |18 |1 |3 |4 | | | +Ch16 |18 | |18 | |18 | |18 |18 |10 |18 | |18 | |8 | |19 |8 |12 |19 |16 | |19 | |18 | |16 |19 |12 |18 |18 | |9 | |10 | |18 |20 |20 |20 |9 | |11 | |20 | |17 |14 |16 |2 |2 |2 | | | +Ch36 |18 | |18 | |18 | |18 |18 |18 |19 | |8 | |11 | |16 |10 |9 |19 |11 | |19 | |9 | |8 |19 |8 |11 |17 | |20 | |14 | |9 |19 |19 |20 |13 | |12 | |19 | |13 |17 |9 |5 |1 |2 | | | +Ch40 |18 | |18 | |18 | |18 |18 |13 |20 | |13 | |19 | |16 |11 |14 |17 |17 | |14 | |8 | |13 |8 |10 |20 |10 | |9 | |14 | |11 |14 |17 |9 |20 | |15 | |19 | |9 |8 |11 |3 |1 |1 | | | +Ch44 |18 | |18 | |18 | |18 |18 |10 |14 | |19 | |20 | |17 |16 |12 |18 |8 | |17 | |18 | |15 |19 |14 |11 |13 | |14 | |12 | |16 |16 |19 |13 |14 | |19 | |14 | |20 |20 |11 |5 |1 |0 | | | +Ch48 |18 | |18 | |18 | |18 |18 |8 |12 | |12 | |19 | |11 |8 |11 |20 |12 | |12 | |11 | |15 |16 |10 |12 |16 | |11 | |15 | |18 |19 |17 |16 |17 | |11 | |8 | |10 |16 |16 |5 |5 |0 | | | +Ch52 |18 | |18 | |18 | |18 |18 |15 |12 | |15 | |20 | |9 |10 |10 |14 |8 | |20 | |10 | |16 |17 |18 |11 |16 | |17 | |10 | |17 |12 |13 |17 |17 | |13 | |18 | |18 |20 |13 |4 |3 |4 | | | +Ch56 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |20 |13 |14 |11 | |10 | |20 | |10 |8 |16 |12 |10 | |16 | |11 | |9 |11 |14 |17 |12 | |17 | |13 | |18 |10 |19 |0 |3 |3 | | | +Ch60 |18 | |18 | |18 | |18 |18 |14 |11 | |8 | |20 | |13 |16 |13 |11 |20 | |9 | |17 | |16 |11 |8 |12 |17 | |15 | |8 | |16 |10 |20 |19 |15 | |13 | |9 | |17 |18 |11 |4 |1 |2 | | | +Ch64 |18 | |18 | |18 | |18 |18 |13 |14 | |8 | |12 | |17 |8 |12 |18 |17 | |17 | |14 | |18 |8 |8 |20 |17 | |16 | |20 | |9 |15 |11 |10 |11 | |18 | |10 | |10 |15 |19 |2 |1 |4 | | | +Ch68 |18 | |18 | |18 | |18 |18 |14 |19 | |17 | |9 | |18 |19 |20 |12 |14 | |8 | |14 | |20 |20 |18 |9 |18 | |11 | |19 | |19 |10 |11 |8 |18 | |9 | |8 | |16 |11 |8 |3 |3 |1 | | | +Ch72 |18 | |18 | |18 | |18 |18 |19 |13 | |20 | |11 | |16 |9 |19 |20 |19 | |14 | |8 | |9 |17 |13 |19 |15 | |8 | |9 | |19 |14 |19 |15 |18 | |16 | |12 | |13 |15 |10 |4 |3 |1 | | | +Ch76 |18 | |18 | |18 | |18 |18 |17 |13 | |16 | |20 | |16 |8 |9 |20 |11 | |17 | |11 | |8 |18 |9 |20 |9 | |17 | |16 | |11 |11 |11 |18 |10 | |13 | |W | |20 |17 |8 |1 |3 |3 | | | +Ch80 |18 | |18 | |18 | |18 |18 |14 |20 | |13 | |13 | |17 |8 |10 |16 |8 | |9 | |19 | |16 |17 |17 |19 |15 | |9 | |13 | |16 |13 |14 |12 |9 | |20 | |20 | |14 |18 |18 |0 |4 |2 | | | +Ch84 |18 | |18 | |18 | |18 |18 |11 |18 | |20 | |9 | |13 |14 |11 |16 |15 | |12 | |11 | |9 |19 |13 |11 |11 | |9 | |15 | |16 |18 |13 |12 |8 | |8 | |8 | |10 |12 |15 |3 |2 |5 | | | +Ch88 |18 | |18 | |18 | |18 |18 |18 |19 | |9 | |17 | |15 |8 |19 |11 |11 | |14 | |9 | |14 |20 |20 |11 |11 | |15 | |12 | |14 |11 |8 |18 |15 | |19 | |18 | |12 |20 |16 |5 |5 |1 | | | +Ch92 |18 | |18 | |18 | |18 |18 |11 |8 | |15 | |13 | |13 |13 |13 |16 |14 | |14 | |9 | |9 |15 |20 |11 |17 | |10 | |14 | |13 |17 |11 |8 |18 | |20 | |8 | |10 |19 |18 |1 |4 |4 | | | +Ch96 |18 | |18 | |18 | |18 |18 |8 |12 | |16 | |9 | |13 |12 |9 |8 |11 | |8 | |8 | |19 |11 |15 |16 |8 | |11 | |16 | |18 |16 |9 |19 |9 | |10 | |15 | |19 |19 |15 |4 |2 |4 | | | +Ch100 |18 | |18 | |18 | |18 |18 |18 |13 | |20 | |20 | |12 |9 |19 |10 |9 | |14 | |8 | |19 |10 |17 |9 |10 | |10 | |8 | |13 |12 |11 |20 |11 | |16 | |18 | |14 |16 |19 |1 |1 |2 | | | +Ch104 |18 | |18 | |18 | |18 |18 |19 |12 | |20 | |14 | |16 |15 |9 |19 |11 | |15 | |11 | |12 |18 |15 |11 |15 | |19 | |10 | |14 |15 |19 |9 |13 | |19 | |13 | |11 |11 |17 |2 |2 |0 | | | +Ch108 |18 | |18 | |18 | |18 |18 |18 |15 | |13 | |16 | |11 |19 |19 |18 |19 | |12 | |17 | |8 |9 |10 |8 |8 | |18 | |8 | |10 |11 |17 |15 |10 | |19 | |13 | |16 |10 |15 |0 |2 |3 | | | +Ch112 |18 | |18 | |18 | |18 |18 |8 |13 | |9 | |17 | |9 |15 |17 |10 |19 | |9 | |19 | |11 |16 |14 |16 |8 | |18 | |13 | |16 |13 |17 |19 |11 | |8 | |8 | |18 |14 |17 |5 |2 |5 | | | +Ch116 |18 | |18 | |18 | |18 |18 |8 |20 | |11 | |15 | |8 |11 |8 |18 |15 | |13 | |17 | |14 |13 |9 |8 |14 | |14 | |11 | |9 |19 |17 |11 |11 | |8 | |20 | |8 |10 |20 |5 |2 |1 | | | +Ch120 |18 | |18 | |18 | |18 |18 |14 |20 | |8 | |20 | |14 |10 |10 |17 |12 | |16 | |20 | |10 |20 |17 |18 |9 | |15 | |14 | |17 |13 |14 |16 |8 | |18 | |10 | |15 |12 |12 |1 |5 |3 | | | +Ch124 |18 | |18 | |18 | |18 |18 |20 |9 | |17 | |12 | |12 |8 |14 |8 |8 | |20 | |17 | |16 |20 |13 |14 |16 | |10 | |14 | |20 |15 |17 |8 |10 | |13 | |13 | |11 |13 |9 |5 |0 |5 | | | +Ch128 |18 | |18 | |18 | |18 |18 |9 |19 | |9 | |14 | |8 |14 |11 |9 |14 | |16 | |15 | |14 |10 |15 |14 |14 | |20 | |10 | |16 |15 |11 |12 |13 | |13 | |13 | |12 |15 |20 |1 |4 |3 | | | +Ch132 |18 | |18 | |18 | |18 |18 |20 |16 | |13 | |8 | |18 |11 |20 |12 |11 | |11 | |14 | |12 |13 |8 |12 |13 | |10 | |20 | |19 |12 |13 |14 |12 | |11 | |19 | |19 |20 |8 |3 |1 |4 | | | +Ch136 |18 | |18 | |18 | |18 |18 |12 |12 | |19 | |10 | |20 |10 |8 |17 |8 | |12 | |10 | |10 |13 |13 |12 |8 | |11 | |18 | |14 |12 |17 |8 |14 | |14 | |9 | |11 |18 |14 |1 |2 |2 | | | +Ch140 |18 | |18 | |18 | |18 |18 |12 |10 | |13 | |9 | |16 |8 |20 |10 |17 | |8 | |15 | |13 |20 |15 |10 |18 | |13 | |12 | |12 |16 |18 |12 |17 | |10 | |16 | |11 |15 |14 |3 |2 |5 | | | +Ch144 |18 | |18 | |18 | |18 |18 |19 |9 | |15 | |8 | |13 |18 |17 |9 |19 | |16 | |11 | |20 |12 |15 |19 |10 | |17 | |15 | |17 |14 |9 |9 |13 | |17 | |16 | |10 |9 |10 |1 |5 |2 | | | +Ch149 |18 | |18 | |18 | |18 |18 |15 |20 | |12 | |19 | |19 |19 |10 |10 |13 | |15 | |19 | |12 |19 |10 |14 |15 | |10 | |15 | |9 |8 |11 |15 |13 | |10 | |16 | |15 |18 |12 |5 |5 |2 | | | +Ch153 |18 | |18 | |18 | |18 |18 |20 |17 | |8 | |19 | |16 |20 |13 |16 |18 | |14 | |11 | |10 |16 |16 |19 |15 | |13 | |17 | |19 |18 |19 |20 |8 | |18 | |9 | |17 |11 |11 |1 |2 |1 | | | +Ch157 |18 | |18 | |18 | |18 |18 |13 |17 | |12 | |19 | |16 |8 |17 |11 |12 | |15 | |14 | |18 |11 |12 |9 |18 | |20 | |13 | |16 |13 |20 |17 |19 | |10 | |12 | |20 |18 |16 |5 |2 |3 | | | +Ch161 |18 | |18 | |18 | |18 |18 |12 |12 | |16 | |12 | |15 |11 |18 |11 |13 | |17 | |19 | |11 |13 |13 |9 |15 | |10 | |10 | |19 |13 |20 |13 |9 | |8 | |8 | |20 |14 |12 |0 |4 |1 | | | +Ch165 |18 | |18 | |18 | |18 |18 |13 |16 | |15 | |13 | |15 |8 |19 |15 |10 | |17 | |13 | |13 |19 |20 |8 |18 | |15 | |20 | |16 |9 |14 |11 |20 | |11 | |19 | |15 |16 |8 |1 |2 |0 | | | +Ch169 |18 | |18 | |18 | |18 |18 |8 |17 | |17 | |13 | |16 |8 |14 |18 |11 | |8 | |18 | |20 |14 |8 |17 |8 | |13 | |18 | |19 |20 |19 |20 |17 | |13 | |20 | |9 |15 |18 |0 |3 |4 | | | +Ch173 |18 | |18 | |18 | |18 |18 |14 |9 | |13 | |12 | |15 |14 |15 |10 |10 | |18 | |16 | |16 |8 |13 |16 |11 | |11 | |13 | |13 |15 |12 |20 |15 | |14 | |13 | |16 |11 |14 |3 |3 |4 | | | +Ch177 |18 | |18 | |18 | |18 |18 |19 |18 | |16 | |10 | |20 |13 |11 |16 |12 | |16 | |18 | |18 |11 |18 |8 |13 | |14 | |11 | |18 |14 |16 |16 |19 | |16 | |13 | |15 |8 |13 |5 |0 |0 | | | +Ch181 |18 | |18 | |18 | |18 |18 |20 |11 | |10 | |9 | |8 |9 |15 |15 |8 | |8 | |12 | |11 |9 |18 |20 |11 | |17 | |11 | |8 |15 |8 |18 |12 | |18 | |16 | |19 |9 |14 |4 |1 |4 | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615e.1.dat b/package/lean/mt/drivers/mt_wifi/files/mt7615e.1.dat new file mode 100644 index 000000000..f58d6ba52 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7615e.1.dat @@ -0,0 +1,410 @@ +#The word of "Default" must not be removed +Default +AccessControlList0= +AccessControlList1= +AccessControlList10= +AccessControlList11= +AccessControlList12= +AccessControlList13= +AccessControlList14= +AccessControlList15= +AccessControlList2= +AccessControlList3= +AccessControlList4= +AccessControlList5= +AccessControlList6= +AccessControlList7= +AccessControlList8= +AccessControlList9= +AccessPolicy0=0 +AccessPolicy1=0 +AccessPolicy10=0 +AccessPolicy11=0 +AccessPolicy12=0 +AccessPolicy13=0 +AccessPolicy14=0 +AccessPolicy15=0 +AccessPolicy2=0 +AccessPolicy3=0 +AccessPolicy4=0 +AccessPolicy5=0 +AccessPolicy6=0 +AccessPolicy7=0 +AccessPolicy8=0 +AccessPolicy9=0 +AckPolicy=0;0;0;0 +APACM=0;0;0;0 +APAifsn=3;7;1;1 +ApCliAuthMode= +ApCliBssid= +ApCliDefaultKeyID= +ApCliEnable= +ApCliKey1Str= +ApCliKey1Str1= +ApCliKey1Type= +ApCliKey2Str= +ApCliKey2Str1= +ApCliKey2Type= +ApCliKey3Str= +ApCliKey3Str1= +ApCliKey3Type= +ApCliKey4Str= +ApCliKey4Str1= +ApCliKey4Type= +ApCliSsid= +ApCliWirelessMode= +ApCliWPAPSK= +ApCliWPAPSK1= +APCwmax=6;10;4;3 +APCwmin=4;4;3;2 +APSDCapable=1 +APTxop=0;0;94;47 +AuthMode=OPEN +AutoChannelSelect=3 +AutoChannelSkipList= +AutoProvisionEn=0 +BandSteering=0 +BasicRate=15 +BeaconPeriod=100 +BFBACKOFFenable=0 +BgndScanSkipCh= +BGProtection=0 +BndStrgBssIdx= +BSSACM=0;0;0;0 +BSSAifsn=3;7;2;2 +BSSCwmax=10;10;4;3 +BSSCwmin=4;4;3;2 +BssidNum=1 +BSSTxop=0;0;94;47 +BW_Enable=0 +BW_Guarantee_Rate= +BW_Maximum_Rate= +BW_Priority= +BW_Root=0 +CalCacheApply=0 +CarrierDetect=0 +Channel=0 +ChannelGrp= +CountryCode=US +CountryRegion=5 +CountryRegionABand=7 +CP_SUPPORT=2 +CSPeriod=6 +DBDC_MODE=0 +DebugFlags=0 +DefaultKeyID=1 +DfsCalibration=0 +DfsEnable=0 +DfsFalseAlarmPrevent=1 +DfsZeroWait=0 +DfsZeroWaitCacTime=255 +DisableOLBC=0 +DtimPeriod=1 +E2pAccessMode=2 +EAPifname=br-lan +EDCCAEnable=1 +EncrypType=NONE +EthConvertMode=dongle +EtherTrafficBand=0 +Ethifname= +ETxBfEnCond=1 +FineAGC=0 +FixedTxMode= +ForceRoamSupport= +FragThreshold=2346 +FreqDelta=0 +FtSupport=0 +GreenAP=1 +G_BAND_256QAM=1 +HideSSID=0 +HT_AMSDU=1 +HT_AutoBA=1 +HT_BADecline=0 +HT_BAWinSize=64 +HT_BSSCoexistence=1 +HT_BW=1 +HT_DisallowTKIP=1 +HT_EXTCHA=1 +HT_GI=1 +HT_HTC=1 +HT_LDPC=1 +HT_LinkAdapt=0 +HT_MCS=33 +HT_MpduDensity=5 +HT_OpMode=0 +HT_PROTECT=1 +HT_RDG=0 +HT_RxStream=4 +HT_STBC=1 +HT_TxStream=4 +IcapMode=0 +idle_timeout_interval=0 +IEEE80211H=1 +IEEE8021X=0 +IgmpSnEnable=0 +ITxBfEn=1 +Key1Str= +Key1Str1= +Key1Str10= +Key1Str11= +Key1Str12= +Key1Str13= +Key1Str14= +Key1Str15= +Key1Str16= +Key1Str2= +Key1Str3= +Key1Str4= +Key1Str5= +Key1Str6= +Key1Str7= +Key1Str8= +Key1Str9= +Key1Type=0 +Key2Str= +Key2Str1= +Key2Str10= +Key2Str11= +Key2Str12= +Key2Str13= +Key2Str14= +Key2Str15= +Key2Str16= +Key2Str2= +Key2Str3= +Key2Str4= +Key2Str5= +Key2Str6= +Key2Str7= +Key2Str8= +Key2Str9= +Key2Type=0 +Key3Str= +Key3Str1= +Key3Str10= +Key3Str11= +Key3Str12= +Key3Str13= +Key3Str14= +Key3Str15= +Key3Str16= +Key3Str2= +Key3Str3= +Key3Str4= +Key3Str5= +Key3Str6= +Key3Str7= +Key3Str8= +Key3Str9= +Key3Type=0 +Key4Str= +Key4Str1= +Key4Str10= +Key4Str11= +Key4Str12= +Key4Str13= +Key4Str14= +Key4Str15= +Key4Str16= +Key4Str2= +Key4Str3= +Key4Str4= +Key4Str5= +Key4Str6= +Key4Str7= +Key4Str8= +Key4Str9= +Key4Type=0 +LinkTestSupport=0 +MACRepeaterEn= +MACRepeaterOuiMode=2 +MeshAuthMode= +MeshAutoLink=0 +MeshDefaultkey=0 +MeshEncrypType= +MeshId= +MeshWEPKEY= +MeshWPAKEY= +MUTxRxEnable=0 +NoForwarding=0 +NoForwardingBTNBSSID=0 +own_ip_addr=192.168.1.1 +PcieAspm=0 +PERCENTAGEenable=0 +PhyRateLimit=0 +PMFMFPC=1 +PMFMFPR=0 +PMFSHA256=0 +PMKCachePeriod=10 +PowerUpCckOfdm=0:0:0:0:0:0:0 +PowerUpHT20=0:0:0:0:0:0:0 +PowerUpHT40=0:0:0:0:0:0:0 +PowerUpVHT160=0:0:0:0:0:0:0 +PowerUpVHT20=0:0:0:0:0:0:0 +PowerUpVHT40=0:0:0:0:0:0:0 +PowerUpVHT80=0:0:0:0:0:0:0 +PreAntSwitch= +PreAuth=0 +PreAuthifname=br-lan +RadioLinkSelection=0 +RadioOn=1 +RADIUS_Acct_Key= +RADIUS_Acct_Port=1813 +RADIUS_Acct_Server= +RADIUS_Key1= +RADIUS_Key10= +RADIUS_Key11= +RADIUS_Key12= +RADIUS_Key13= +RADIUS_Key14= +RADIUS_Key15= +RADIUS_Key16= +RADIUS_Key2= +RADIUS_Key3= +RADIUS_Key4= +RADIUS_Key5= +RADIUS_Key6= +RADIUS_Key7= +RADIUS_Key8= +RADIUS_Key9= +RADIUS_Port=1812 +RADIUS_Server=0 +RDRegion= +RED_Enable=1 +RekeyInterval=3600 +RekeyMethod=DISABLE +RRMEnable=0 +RTSThreshold=2347 +session_timeout_interval=0 +ShortSlot=1 +SKUenable=0 +SSID= +SSID1=WITHUSP-5.0 +SSID10= +SSID11= +SSID12= +SSID13= +SSID14= +SSID15= +SSID16= +SSID2= +SSID3= +SSID4= +SSID5= +SSID6= +SSID7= +SSID8= +SSID9= +StationKeepAlive=0 +StreamMode=0 +StreamModeMac0= +StreamModeMac1= +StreamModeMac2= +StreamModeMac3= +TGnWifiTest=0 +ThermalRecal=0 +TxBurst=1 +TxPower=100 +TxPreamble=1 +VHT_BW=1 +VHT_BW_SIGNAL=0 +VHT_LDPC=1 +VHT_Sec80_Channel=0 +VHT_SGI=1 +VHT_STBC=1 +VLANID=0 +VLANPriority=0 +VLANTag=0 +VOW_Airtime_Ctrl_En=0 +VOW_Airtime_Fairness_En=1 +VOW_BW_Ctrl=0 +VOW_Group_Backlog= +VOW_Group_DWRR_Max_Wait_Time= +VOW_Group_DWRR_Quantum= +VOW_Group_Max_Airtime_Bucket_Size= +VOW_Group_Max_Rate= +VOW_Group_Max_Rate_Bucket_Size= +VOW_Group_Max_Ratio= +VOW_Group_Max_Wait_Time= +VOW_Group_Min_Airtime_Bucket_Size= +VOW_Group_Min_Rate= +VOW_Group_Min_Rate_Bucket_Size= +VOW_Group_Min_Ratio= +VOW_Rate_Ctrl_En=0 +VOW_Refill_Period= +VOW_RX_En=1 +VOW_Sta_BE_DWRR_Quantum= +VOW_Sta_BK_DWRR_Quantum= +VOW_Sta_DWRR_Max_Wait_Time= +VOW_Sta_VI_DWRR_Quantum= +VOW_Sta_VO_DWRR_Quantum= +VOW_WATF_Enable= +VOW_WATF_MAC_LV0= +VOW_WATF_MAC_LV1= +VOW_WATF_MAC_LV2= +VOW_WATF_MAC_LV3= +VOW_WATF_Q_LV0= +VOW_WATF_Q_LV1= +VOW_WATF_Q_LV2= +VOW_WATF_Q_LV3= +VOW_WMM_Search_Rule_Band0= +VOW_WMM_Search_Rule_Band1= +WapiAsCertPath= +WapiAsIpAddr= +WapiAsPort= +Wapiifname= +WapiPsk1= +WapiPsk10= +WapiPsk11= +WapiPsk12= +WapiPsk13= +WapiPsk14= +WapiPsk15= +WapiPsk16= +WapiPsk2= +WapiPsk3= +WapiPsk4= +WapiPsk5= +WapiPsk6= +WapiPsk7= +WapiPsk8= +WapiPsk9= +WapiPskType= +WapiUserCertPath= +WCNTest=0 +Wds0Key= +Wds1Key= +Wds2Key= +Wds3Key= +WdsEnable=0 +WdsEncrypType=NONE +WdsList= +WdsPhyMode=0 +WHNAT=1 +WiFiTest=0 +WirelessMode=14 +WmmCapable=1 +WPAPSK= +WPAPSK1=12345678 +WPAPSK10= +WPAPSK11= +WPAPSK12= +WPAPSK13= +WPAPSK14= +WPAPSK15= +WPAPSK16= +WPAPSK2= +WPAPSK3= +WPAPSK4= +WPAPSK5= +WPAPSK6= +WPAPSK7= +WPAPSK8= +WPAPSK9= +WscConfMode=0 +WscConfStatus=2 +WEP1Type1=0 +WEP2Type1=0 +WEP3Type1=0 +WEP4Type1=0 +WPSRadio=0 diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615e.2.dat b/package/lean/mt/drivers/mt_wifi/files/mt7615e.2.dat new file mode 100644 index 000000000..56f39e1e9 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7615e.2.dat @@ -0,0 +1,412 @@ +#The word of "Default" must not be removed +Default +AccessControlList0= +AccessControlList1= +AccessControlList10= +AccessControlList11= +AccessControlList12= +AccessControlList13= +AccessControlList14= +AccessControlList15= +AccessControlList2= +AccessControlList3= +AccessControlList4= +AccessControlList5= +AccessControlList6= +AccessControlList7= +AccessControlList8= +AccessControlList9= +AccessPolicy0=0 +AccessPolicy1=0 +AccessPolicy10=0 +AccessPolicy11=0 +AccessPolicy12=0 +AccessPolicy13=0 +AccessPolicy14=0 +AccessPolicy15=0 +AccessPolicy2=0 +AccessPolicy3=0 +AccessPolicy4=0 +AccessPolicy5=0 +AccessPolicy6=0 +AccessPolicy7=0 +AccessPolicy8=0 +AccessPolicy9=0 +AckPolicy=0;0;0;0 +APACM=0;0;0;0 +APAifsn=3;7;1;1 +ApCliAuthMode= +ApCliBssid= +ApCliDefaultKeyID= +ApCliEnable= +ApCliEncrypType= +ApCliKey1Str= +ApCliKey1Str1= +ApCliKey1Type= +ApCliKey2Str= +ApCliKey2Str1= +ApCliKey2Type= +ApCliKey3Str= +ApCliKey3Str1= +ApCliKey3Type= +ApCliKey4Str= +ApCliKey4Str1= +ApCliKey4Type= +ApCliSsid= +ApCliWirelessMode= +ApCliWPAPSK= +ApCliWPAPSK1= +APCwmax=6;10;4;3 +APCwmin=4;4;3;2 +APSDCapable=1 +APTxop=0;0;94;47 +AuthMode=OPEN +AutoChannelSelect=3 +AutoChannelSkipList= +AutoProvisionEn=0 +BandSteering=0 +BasicRate=15 +BeaconPeriod=100 +BFBACKOFFenable=0 +BgndScanSkipCh= +BGProtection=0 +BndStrgBssIdx= +BSSACM=0;0;0;0 +BSSAifsn=3;7;2;2 +BSSCwmax=10;10;4;3 +BSSCwmin=4;4;3;2 +BssidNum=1 +BSSTxop=0;0;94;47 +BW_Enable=0 +BW_Guarantee_Rate= +BW_Maximum_Rate= +BW_Priority= +BW_Root=0 +CalCacheApply=0 +CarrierDetect=0 +Channel=0 +ChannelGrp= +CountryCode=US +CountryRegion=5 +CountryRegionABand=7 +CP_SUPPORT=2 +CSPeriod=6 +DBDC_MODE=0 +DebugFlags=0 +DefaultKeyID=1 +DfsCalibration=0 +DfsEnable=0 +DfsFalseAlarmPrevent=1 +DfsZeroWait=0 +DfsZeroWaitCacTime=255 +DisableOLBC=0 +DtimPeriod=1 +E2pAccessMode=1 +EAPifname=br-lan +EDCCAEnable=1 +EncrypType=NONE +EthConvertMode=dongle +EtherTrafficBand=0 +Ethifname= +ETxBfEnCond=1 +FineAGC=0 +FixedTxMode= +ForceRoamSupport= +FragThreshold=2346 +FreqDelta=0 +FtSupport=0 +GreenAP=1 +G_BAND_256QAM=1 +HideSSID=0 +HT_AMSDU=1 +HT_AutoBA=1 +HT_BADecline=0 +HT_BAWinSize=64 +HT_BSSCoexistence=1 +HT_BW=1 +HT_DisallowTKIP=1 +HT_EXTCHA=1 +HT_GI=1 +HT_HTC=1 +HT_LDPC=1 +HT_LinkAdapt=0 +HT_MCS=33 +HT_MpduDensity=5 +HT_OpMode=0 +HT_PROTECT=1 +HT_RDG=0 +HT_RxStream=4 +HT_STBC=1 +HT_TxStream=4 +IcapMode=0 +idle_timeout_interval=0 +IEEE80211H=1 +IEEE8021X=0 +IgmpSnEnable=0 +ITxBfEn=1 +Key1Str= +Key1Str1= +Key1Str10= +Key1Str11= +Key1Str12= +Key1Str13= +Key1Str14= +Key1Str15= +Key1Str16= +Key1Str2= +Key1Str3= +Key1Str4= +Key1Str5= +Key1Str6= +Key1Str7= +Key1Str8= +Key1Str9= +Key1Type=0 +Key2Str= +Key2Str1= +Key2Str10= +Key2Str11= +Key2Str12= +Key2Str13= +Key2Str14= +Key2Str15= +Key2Str16= +Key2Str2= +Key2Str3= +Key2Str4= +Key2Str5= +Key2Str6= +Key2Str7= +Key2Str8= +Key2Str9= +Key2Type=0 +Key3Str= +Key3Str1= +Key3Str10= +Key3Str11= +Key3Str12= +Key3Str13= +Key3Str14= +Key3Str15= +Key3Str16= +Key3Str2= +Key3Str3= +Key3Str4= +Key3Str5= +Key3Str6= +Key3Str7= +Key3Str8= +Key3Str9= +Key3Type=0 +Key4Str= +Key4Str1= +Key4Str10= +Key4Str11= +Key4Str12= +Key4Str13= +Key4Str14= +Key4Str15= +Key4Str16= +Key4Str2= +Key4Str3= +Key4Str4= +Key4Str5= +Key4Str6= +Key4Str7= +Key4Str8= +Key4Str9= +Key4Type=0 +LinkTestSupport=0 +MACRepeaterEn= +MACRepeaterOuiMode=2 +MeshAuthMode= +MeshAutoLink=0 +MeshDefaultkey=0 +MeshEncrypType= +MeshId= +MeshWEPKEY= +MeshWPAKEY= +MUTxRxEnable=0 +NoForwarding=0 +NoForwardingBTNBSSID=0 +own_ip_addr=192.168.1.1 + +PcieAspm=0 +PERCENTAGEenable=0 +PhyRateLimit=0 +PMFMFPC=1 +PMFMFPR=0 +PMFSHA256=0 +PMKCachePeriod=10 +PowerUpCckOfdm=0:0:0:0:0:0:0 +PowerUpHT20=0:0:0:0:0:0:0 +PowerUpHT40=0:0:0:0:0:0:0 +PowerUpVHT160=0:0:0:0:0:0:0 +PowerUpVHT20=0:0:0:0:0:0:0 +PowerUpVHT40=0:0:0:0:0:0:0 +PowerUpVHT80=0:0:0:0:0:0:0 +PreAntSwitch= +PreAuth=0 +PreAuthifname=br-lan +RadioLinkSelection=0 +RadioOn=1 +RADIUS_Acct_Key= +RADIUS_Acct_Port=1813 +RADIUS_Acct_Server= +RADIUS_Key1= +RADIUS_Key10= +RADIUS_Key11= +RADIUS_Key12= +RADIUS_Key13= +RADIUS_Key14= +RADIUS_Key15= +RADIUS_Key16= +RADIUS_Key2= +RADIUS_Key3= +RADIUS_Key4= +RADIUS_Key5= +RADIUS_Key6= +RADIUS_Key7= +RADIUS_Key8= +RADIUS_Key9= +RADIUS_Port=1812 +RADIUS_Server=0 +RDRegion= +RED_Enable=1 +RekeyInterval=3600 +RekeyMethod=DISABLE +RRMEnable=0 +RTSThreshold=2347 +session_timeout_interval=0 +ShortSlot=1 +SKUenable=0 +SSID= +SSID1=MTK_AP3 +SSID10= +SSID11= +SSID12= +SSID13= +SSID14= +SSID15= +SSID16= +SSID2= +SSID3= +SSID4= +SSID5= +SSID6= +SSID7= +SSID8= +SSID9= +StationKeepAlive=0 +StreamMode=0 +StreamModeMac0= +StreamModeMac1= +StreamModeMac2= +StreamModeMac3= +TGnWifiTest=0 +ThermalRecal=0 +TxBurst=1 +TxPower=100 +TxPreamble=1 +VHT_BW=1 +VHT_BW_SIGNAL=0 +VHT_LDPC=1 +VHT_Sec80_Channel=0 +VHT_SGI=1 +VHT_STBC=1 +VLANID=0 +VLANPriority=0 +VLANTag=0 +VOW_Airtime_Ctrl_En= +VOW_Airtime_Fairness_En=1 +VOW_BW_Ctrl=0 +VOW_Group_Backlog= +VOW_Group_DWRR_Max_Wait_Time= +VOW_Group_DWRR_Quantum= +VOW_Group_Max_Airtime_Bucket_Size= +VOW_Group_Max_Rate= +VOW_Group_Max_Rate_Bucket_Size= +VOW_Group_Max_Ratio= +VOW_Group_Max_Wait_Time= +VOW_Group_Min_Airtime_Bucket_Size= +VOW_Group_Min_Rate= +VOW_Group_Min_Rate_Bucket_Size= +VOW_Group_Min_Ratio= +VOW_Rate_Ctrl_En= +VOW_Refill_Period= +VOW_RX_En=1 +VOW_Sta_BE_DWRR_Quantum= +VOW_Sta_BK_DWRR_Quantum= +VOW_Sta_DWRR_Max_Wait_Time= +VOW_Sta_VI_DWRR_Quantum= +VOW_Sta_VO_DWRR_Quantum= +VOW_WATF_Enable= +VOW_WATF_MAC_LV0= +VOW_WATF_MAC_LV1= +VOW_WATF_MAC_LV2= +VOW_WATF_MAC_LV3= +VOW_WATF_Q_LV0= +VOW_WATF_Q_LV1= +VOW_WATF_Q_LV2= +VOW_WATF_Q_LV3= +VOW_WMM_Search_Rule_Band0= +VOW_WMM_Search_Rule_Band1= +WapiAsCertPath= +WapiAsIpAddr= +WapiAsPort= +Wapiifname= +WapiPsk1= +WapiPsk10= +WapiPsk11= +WapiPsk12= +WapiPsk13= +WapiPsk14= +WapiPsk15= +WapiPsk16= +WapiPsk2= +WapiPsk3= +WapiPsk4= +WapiPsk5= +WapiPsk6= +WapiPsk7= +WapiPsk8= +WapiPsk9= +WapiPskType= +WapiUserCertPath= +WCNTest=0 +Wds0Key= +Wds1Key= +Wds2Key= +Wds3Key= +WdsEnable=0 +WdsEncrypType=NONE +WdsList= +WdsPhyMode=0 +WHNAT=1 +WiFiTest=0 +WirelessMode=14 +WmmCapable=1 +WPAPSK= +WPAPSK1=12345678 +WPAPSK10= +WPAPSK11= +WPAPSK12= +WPAPSK13= +WPAPSK14= +WPAPSK15= +WPAPSK16= +WPAPSK2= +WPAPSK3= +WPAPSK4= +WPAPSK5= +WPAPSK6= +WPAPSK7= +WPAPSK8= +WPAPSK9= +WscConfMode=0 +WscConfStatus=2 +WEP1Type1=0 +WEP2Type1=0 +WEP3Type1=0 +WEP4Type1=0 +WPSRadio=0 diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7615e.eeprom.bin b/package/lean/mt/drivers/mt_wifi/files/mt7615e.eeprom.bin new file mode 100644 index 000000000..32556855c Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/files/mt7615e.eeprom.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/files/mt7622.1.dat b/package/lean/mt/drivers/mt_wifi/files/mt7622.1.dat new file mode 100644 index 000000000..49cac22a8 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/mt7622.1.dat @@ -0,0 +1,412 @@ +#The word of "Default" must not be removed +Default +AccessControlList0= +AccessControlList1= +AccessControlList10= +AccessControlList11= +AccessControlList12= +AccessControlList13= +AccessControlList14= +AccessControlList15= +AccessControlList2= +AccessControlList3= +AccessControlList4= +AccessControlList5= +AccessControlList6= +AccessControlList7= +AccessControlList8= +AccessControlList9= +AccessPolicy0=0 +AccessPolicy1=0 +AccessPolicy10=0 +AccessPolicy11=0 +AccessPolicy12=0 +AccessPolicy13=0 +AccessPolicy14=0 +AccessPolicy15=0 +AccessPolicy2=0 +AccessPolicy3=0 +AccessPolicy4=0 +AccessPolicy5=0 +AccessPolicy6=0 +AccessPolicy7=0 +AccessPolicy8=0 +AccessPolicy9=0 +AckPolicy=0;0;0;0 +APACM=0;0;0;0 +APAifsn=3;7;1;1 +ApCliAuthMode= +ApCliBssid= +ApCliDefaultKeyID= +ApCliEnable= +ApCliEncrypType= +ApCliKey1Str= +ApCliKey1Str1= +ApCliKey1Type= +ApCliKey2Str= +ApCliKey2Str1= +ApCliKey2Type= +ApCliKey3Str= +ApCliKey3Str1= +ApCliKey3Type= +ApCliKey4Str= +ApCliKey4Str1= +ApCliKey4Type= +ApCliSsid= +ApCliWirelessMode= +ApCliWPAPSK= +ApCliWPAPSK1= +APCwmax=6;10;4;3 +APCwmin=4;4;3;2 +APSDCapable=1 +APTxop=0;0;94;47 +AuthMode=OPEN +AutoChannelSelect=3 +AutoChannelSkipList= +AutoProvisionEn=0 +BandSteering=0 +BasicRate=15 +BeaconPeriod=100 +BFBACKOFFenable=0 +BgndScanSkipCh= +BGProtection=0 +BndStrgBssIdx= +BSSACM=0;0;0;0 +BSSAifsn=3;7;2;2 +BSSCwmax=10;10;4;3 +BSSCwmin=4;4;3;2 +BssidNum=1 +BSSTxop=0;0;94;47 +BW_Enable=0 +BW_Guarantee_Rate= +BW_Maximum_Rate= +BW_Priority= +BW_Root=0 +CalCacheApply=0 +CarrierDetect=0 +Channel=0 +ChannelGrp= +CountryCode=US +CountryRegion=5 +CountryRegionABand=7 +CP_SUPPORT=2 +CSPeriod=6 +DBDC_MODE=0 +DebugFlags=0 +DefaultKeyID=1 +DfsCalibration=0 +DfsEnable=0 +DfsFalseAlarmPrevent=1 +DfsZeroWait=0 +DfsZeroWaitCacTime=255 +DisableOLBC=0 +DtimPeriod=1 +E2pAccessMode=2 +EAPifname=br-lan +EDCCAEnable=1 +EncrypType=NONE +EthConvertMode=dongle +EtherTrafficBand=0 +Ethifname= +ETxBfEnCond=1 +FineAGC=0 +FixedTxMode= +ForceRoamSupport= +FragThreshold=2346 +FreqDelta=0 +FtSupport=0 +GreenAP=1 +G_BAND_256QAM=1 +HideSSID=0 +HT_AMSDU=1 +HT_AutoBA=1 +HT_BADecline=0 +HT_BAWinSize=64 +HT_BSSCoexistence=1 +HT_BW=1 +HT_DisallowTKIP=1 +HT_EXTCHA=1 +HT_GI=1 +HT_HTC=1 +HT_LDPC=1 +HT_LinkAdapt=0 +HT_MCS=33 +HT_MpduDensity=5 +HT_OpMode=0 +HT_PROTECT=1 +HT_RDG=0 +HT_RxStream=4 +HT_STBC=1 +HT_TxStream=4 +IcapMode=0 +idle_timeout_interval=0 +IEEE80211H=1 +IEEE8021X=0 +IgmpSnEnable=0 +ITxBfEn=1 +Key1Str= +Key1Str1= +Key1Str10= +Key1Str11= +Key1Str12= +Key1Str13= +Key1Str14= +Key1Str15= +Key1Str16= +Key1Str2= +Key1Str3= +Key1Str4= +Key1Str5= +Key1Str6= +Key1Str7= +Key1Str8= +Key1Str9= +Key1Type=0 +Key2Str= +Key2Str1= +Key2Str10= +Key2Str11= +Key2Str12= +Key2Str13= +Key2Str14= +Key2Str15= +Key2Str16= +Key2Str2= +Key2Str3= +Key2Str4= +Key2Str5= +Key2Str6= +Key2Str7= +Key2Str8= +Key2Str9= +Key2Type=0 +Key3Str= +Key3Str1= +Key3Str10= +Key3Str11= +Key3Str12= +Key3Str13= +Key3Str14= +Key3Str15= +Key3Str16= +Key3Str2= +Key3Str3= +Key3Str4= +Key3Str5= +Key3Str6= +Key3Str7= +Key3Str8= +Key3Str9= +Key3Type=0 +Key4Str= +Key4Str1= +Key4Str10= +Key4Str11= +Key4Str12= +Key4Str13= +Key4Str14= +Key4Str15= +Key4Str16= +Key4Str2= +Key4Str3= +Key4Str4= +Key4Str5= +Key4Str6= +Key4Str7= +Key4Str8= +Key4Str9= +Key4Type=0 +LinkTestSupport=0 +MACRepeaterEn= +MACRepeaterOuiMode=2 +MeshAuthMode= +MeshAutoLink=0 +MeshDefaultkey=0 +MeshEncrypType= +MeshId= +MeshWEPKEY= +MeshWPAKEY= +MUTxRxEnable=0 +NoForwarding=0 +NoForwardingBTNBSSID=0 +own_ip_addr=192.168.1.1 +PcieAspm=0 +PERCENTAGEenable=0 +PhyRateLimit=0 +PMFMFPC=1 +PMFMFPR=0 +PMFSHA256=0 +PMKCachePeriod=10 +PowerUpCckOfdm=0:0:0:0:0:0:0 +PowerUpHT20=0:0:0:0:0:0:0 +PowerUpHT40=0:0:0:0:0:0:0 +PowerUpVHT160=0:0:0:0:0:0:0 +PowerUpVHT20=0:0:0:0:0:0:0 +PowerUpVHT40=0:0:0:0:0:0:0 +PowerUpVHT80=0:0:0:0:0:0:0 +PreAntSwitch= +PreAuth=0 +PreAuthifname=br-lan +RadioLinkSelection=0 +RadioOn=1 +RADIUS_Acct_Key= +RADIUS_Acct_Port=1813 +RADIUS_Acct_Server= +RADIUS_Key1= +RADIUS_Key10= +RADIUS_Key11= +RADIUS_Key12= +RADIUS_Key13= +RADIUS_Key14= +RADIUS_Key15= +RADIUS_Key16= +RADIUS_Key2= +RADIUS_Key3= +RADIUS_Key4= +RADIUS_Key5= +RADIUS_Key6= +RADIUS_Key7= +RADIUS_Key8= +RADIUS_Key9= +RADIUS_Port=1812 +RADIUS_Server=0 +RDRegion= +RED_Enable=1 +RekeyInterval=3600 +RekeyMethod=DISABLE +RRMEnable=0 +RTSThreshold=2347 +session_timeout_interval=0 +ShortSlot=1 +SKUenable=0 +SSID= +SSID1=WITHUSP-2.4 +SSID10= +SSID11= +SSID12= +SSID13= +SSID14= +SSID15= +SSID16= +SSID2= +SSID3= +SSID4= +SSID5= +SSID6= +SSID7= +SSID8= +SSID9= +StationKeepAlive=0 +StreamMode=0 +StreamModeMac0= +StreamModeMac1= +StreamModeMac2= +StreamModeMac3= +TGnWifiTest=0 +ThermalRecal=0 +CCKTxStream=4 +TxBurst=1 +TxPower=100 +TxPreamble=1 +VHT_BW=0 +VHT_BW_SIGNAL=0 +VHT_LDPC=1 +VHT_Sec80_Channel=0 +VHT_SGI=1 +VHT_STBC=1 +VLANID=0 +VLANPriority=0 +VLANTag=0 +VOW_Airtime_Ctrl_En=0 +VOW_Airtime_Fairness_En=1 +VOW_BW_Ctrl=0 +VOW_Group_Backlog= +VOW_Group_DWRR_Max_Wait_Time= +VOW_Group_DWRR_Quantum= +VOW_Group_Max_Airtime_Bucket_Size= +VOW_Group_Max_Rate= +VOW_Group_Max_Rate_Bucket_Size= +VOW_Group_Max_Ratio= +VOW_Group_Max_Wait_Time= +VOW_Group_Min_Airtime_Bucket_Size= +VOW_Group_Min_Rate= +VOW_Group_Min_Rate_Bucket_Size= +VOW_Group_Min_Ratio= +VOW_Rate_Ctrl_En=0 +VOW_Refill_Period= +VOW_RX_En=1 +VOW_Sta_BE_DWRR_Quantum= +VOW_Sta_BK_DWRR_Quantum= +VOW_Sta_DWRR_Max_Wait_Time= +VOW_Sta_VI_DWRR_Quantum= +VOW_Sta_VO_DWRR_Quantum= +VOW_WATF_Enable= +VOW_WATF_MAC_LV0= +VOW_WATF_MAC_LV1= +VOW_WATF_MAC_LV2= +VOW_WATF_MAC_LV3= +VOW_WATF_Q_LV0= +VOW_WATF_Q_LV1= +VOW_WATF_Q_LV2= +VOW_WATF_Q_LV3= +VOW_WMM_Search_Rule_Band0= +VOW_WMM_Search_Rule_Band1= +WapiAsCertPath= +WapiAsIpAddr= +WapiAsPort= +Wapiifname= +WapiPsk1= +WapiPsk10= +WapiPsk11= +WapiPsk12= +WapiPsk13= +WapiPsk14= +WapiPsk15= +WapiPsk16= +WapiPsk2= +WapiPsk3= +WapiPsk4= +WapiPsk5= +WapiPsk6= +WapiPsk7= +WapiPsk8= +WapiPsk9= +WapiPskType= +WapiUserCertPath= +WCNTest=0 +Wds0Key= +Wds1Key= +Wds2Key= +Wds3Key= +WdsEnable=0 +WdsEncrypType=NONE +WdsList= +WdsPhyMode=0 +WHNAT=0 +WiFiTest=0 +WirelessMode=9 +WmmCapable=1 +WPAPSK= +WPAPSK1=12345678 +WPAPSK10= +WPAPSK11= +WPAPSK12= +WPAPSK13= +WPAPSK14= +WPAPSK15= +WPAPSK16= +WPAPSK2= +WPAPSK3= +WPAPSK4= +WPAPSK5= +WPAPSK6= +WPAPSK7= +WPAPSK8= +WPAPSK9= +WscConfMode=0 +WscConfStatus=2 +WEP1Type1=0 +WEP2Type1=0 +WEP3Type1=0 +WEP4Type1=0 +WPSRadio=0 diff --git a/package/lean/mt/drivers/mt_wifi/files/wifi_services.lua b/package/lean/mt/drivers/mt_wifi/files/wifi_services.lua new file mode 100644 index 000000000..77579d39e --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/files/wifi_services.lua @@ -0,0 +1,98 @@ +--This file is created for check some deamons like miniupnpd,8021xd... + + local mtkwifi = require("mtkwifi") + local devs = mtkwifi.get_all_devs() + local nixio = require("nixio") + +function miniupnpd_chk(devname,vif,enable) + local WAN_IF=mtkwifi.__trim(mtkwifi.read_pipe("uci -q get network.wan.ifname")) + + os.execute("rm -rf /etc/miniupnpd.conf") + os.execute("iptables -t nat -F MINIUPNPD 1>/dev/null 2>&1") + --rmeoving the rule to MINIUPNPD + os.execute("iptables-t nat -D PREROUTING -i "..WAN_IF.." -j MINIUPNPD 1>/dev/null 2>&1") + os.execute("iptables-t nat -X MINIUPNPD 1>/dev/null 2>&1") + + --removing the MINIUPNPD chain for filter + os.execute("iptables -t filter -F MINIUPNPD 1>/dev/null 2>&1") + --adding the rule to MINIUPNPD + + os.execute("iptables -t filter -D FORWARD -i "..WAN_IF.." ! -o "..WAN_IF.." -j MINIUPNPD 1>/dev/null 2>&1") + os.execute("iptables -t filter -X MINIUPNPD 1>/dev/null 2>&1") + + os.execute("iptables -t nat -N MINIUPNPD") + os.execute("iptables -t nat -A PREROUTING -i "..WAN_IF.." -j MINIUPNPD") + os.execute("iptables -t filter -N MINIUPNPD") + os.execute("iptables -t filter -A FORWARD -i "..WAN_IF.." ! -o "..WAN_IF.." -j MINIUPNPD") + + if mtkwifi.exists("/tmp/run/miniupnpd."..vif) then + os.execute("cat /tmp/run/miniupnpd."..vif.." | xargs kill -9") + end + + if enable then + local profile = mtkwifi.search_dev_and_profile()[devname] + local cfgs = mtkwifi.load_profile(profile) + local ssid_index = devs[devname]["vifs"][vif].vifidx + local wsc_conf_mode = "" + local PORT_NUM = 7777+(string.byte(vif, -1)+string.byte(vif, -2)) + local LAN_IPADDR = mtkwifi.__trim(mtkwifi.read_pipe("uci -q get network.lan.ipaddr")) + local LAN_MASK = mtkwifi.__trim(mtkwifi.read_pipe("uci -q get network.lan.netmask")) + local port = 6352 + (string.byte(vif, -1)+string.byte(vif, -2)) + LAN_IPADDR = LAN_IPADDR.."/"..LAN_MASK + wsc_conf_mode = mtkwifi.token_get(cfgs["WscConfMode"], ssid_index, "") + + local file = io.open("/etc/miniupnpd.conf", "w") + if nil == file then + nixio.syslog("debug","open file /etc/miniupnpd.conf fail") + end + + file:write("ext_ifname=",WAN_IF,'\n','\n', + "listening_ip=",LAN_IPADDR,'\n','\n', + "port=",port,'\n','\n', + "bitrate_up=800000000",'\n', + "bitrate_down=800000000",'\n','\n', + "secure_mode=no",'\n','\n', + "system_uptime=yes",'\n','\n', + "notify_interval=30",'\n','\n', + "uuid=68555350-3352-3883-2883-335030522880",'\n','\n', + "serial=12345678",'\n','\n', + "model_number=1",'\n','\n', + "enable_upnp=no",'\n','\n') + file:close() + + if wsc_conf_mode ~= "" and wsc_conf_mode ~= "0" then + os.execute("miniupnpd -m 1 -I "..vif.." -P /var/run/miniupnpd."..vif.." -G -i "..WAN_IF.." -a "..LAN_IPADDR.." -n "..PORT_NUM) + end + end +end + +function d8021xd_chk(devname,prefix,main_ifname,enable) + local profile = mtkwifi.search_dev_and_profile()[devname] + local cfgs = mtkwifi.load_profile(profile) + local auth_mode = cfgs.AuthMode + local ieee8021x = cfgs.IEEE8021X + local pat_auth_mode = {"WPA$", "WPA;", "WPA2$", "WPA2;", "WPA1WPA2$", "WPA1WPA2;"} + local pat_ieee8021x = {"1$", "1;"} + local apd_en = false + if mtkwifi.exists("/tmp/run/8021xd_"..main_ifname..".pid") then + os.execute("cat /tmp/run/8021xd_"..main_ifname..".pid | xargs kill -9") + os.execute("rm /tmp/run/8021xd_"..main_ifname..".pid") + end + if enable then + for _, pat in ipairs(pat_auth_mode) do + if string.find(auth_mode, pat) then + apd_en = true + end + end + + for _, pat in ipairs(pat_ieee8021x) do + if string.find(ieee8021x, pat) then + apd_en = true + end + end + + if apd_en then + os.execute("8021xd -p "..prefix.. " -i "..main_ifname) + end + end +end diff --git a/package/lean/mt/drivers/mt_wifi/patches/1110-mt-wifi-common.patch b/package/lean/mt/drivers/mt_wifi/patches/1110-mt-wifi-common.patch new file mode 100644 index 000000000..683adb31a --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/patches/1110-mt-wifi-common.patch @@ -0,0 +1,19 @@ +diff -urN a/mt_wifi/mt_wifi/embedded/common/cmm_info.c b/mt_wifi/mt_wifi/embedded/common/cmm_info.c +--- a/mt_wifi/embedded/common/cmm_info.c 2018-11-01 10:03:25.663408611 +0000 ++++ b/mt_wifi/embedded/common/cmm_info.c 2018-11-01 10:09:14.991395503 +0000 +@@ -3200,6 +3200,15 @@ + else + need_send = FALSE; + } ++#if 1 ++ /* [2018.11.01 hepark] To fill 5G information */ ++ else if (!strcmp(wrq->ifr_ifrn.ifrn_name, "rai0")) { ++ if (!memcmp(pEntry->wdev->if_dev->name, "rax", 3)) ++ need_send = FALSE; ++ else ++ need_send = TRUE; ++ } ++#endif + } + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC) && (need_send == TRUE)) { + pDst = &pMacTab->Entry[pMacTab->Num]; diff --git a/package/lean/mt/drivers/mt_wifi/patches/1111-fix-eeprom-flash-read-write.patch b/package/lean/mt/drivers/mt_wifi/patches/1111-fix-eeprom-flash-read-write.patch new file mode 100644 index 000000000..daebbd760 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/patches/1111-fix-eeprom-flash-read-write.patch @@ -0,0 +1,167 @@ +diff -urN a/mt_wifi/embedded/common/ee_flash.c b/mt_wifi/embedded/common/ee_flash.c +--- a/mt_wifi/embedded/common/ee_flash.c 2018-04-30 15:57:54.000000000 +0800 ++++ b/mt_wifi/embedded/common/ee_flash.c 2019-01-14 21:28:38.163721571 +0800 +@@ -111,8 +111,8 @@ + int mt_mtd_write_nm_wifi(char *name, loff_t to, size_t len, const u_char *buf); + int mt_mtd_read_nm_wifi(char *name, loff_t from, size_t len, u_char *buf); + +-#define flash_read(_ctrl, _ptr, _offset, _len) mt_mtd_read_nm_wifi("Factory", _offset, (size_t)_len, _ptr) +-#define flash_write(_ctrl, _ptr, _offset, _len) mt_mtd_write_nm_wifi("Factory", _offset, (size_t)_len, _ptr) ++#define flash_read(_ctrl, _ptr, _offset, _len) mt_mtd_read_nm_wifi("factory", _offset&0xFFFF, (size_t)_len, _ptr) ++#define flash_write(_ctrl, _ptr, _offset, _len) mt_mtd_write_nm_wifi("factory", _offset&0xFFFF, (size_t)_len, _ptr) + + #else + /* +@@ -122,8 +122,8 @@ + 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); + +-#define flash_read(_ctrl, _ptr, _offset, _len) ra_mtd_read_nm("Factory", _offset, (size_t)_len, _ptr) +-#define flash_write(_ctrl, _ptr, _offset, _len) ra_mtd_write_nm("Factory", _offset, (size_t)_len, _ptr) ++#define flash_read(_ctrl, _ptr, _offset, _len) ra_mtd_read_nm("factory", _offset&0xFFFF, (size_t)_len, _ptr) ++#define flash_write(_ctrl, _ptr, _offset, _len) ra_mtd_write_nm("factory", _offset&0xFFFF, (size_t)_len, _ptr) + + #endif /*CONFIG_WIFI_MTD*/ + #endif /*RA_MTD_RW_BY_NUM*/ +diff -urN a/mt_wifi/embedded/common/eeprom.c b/mt_wifi/embedded/common/eeprom.c +--- a/mt_wifi/embedded/common/eeprom.c 2018-04-30 15:57:54.000000000 +0800 ++++ b/mt_wifi/embedded/common/eeprom.c 2019-04-19 17:05:48.336239756 +0800 +@@ -646,7 +646,7 @@ + efuse_probe(pAd); + #endif /* RTMP_EFUSE_SUPPORT */ + +- /* rtmp_eeprom_of_platform(pAd); //for MT7615, only use E2pAccessMode parameter to get eeprom type */ ++ rtmp_eeprom_of_platform(pAd); //for MT7615, only use E2pAccessMode parameter to get eeprom type */ + + if (forceMode != E2P_NONE && forceMode < NUM_OF_E2P_MODE) { + e2p_type = forceMode; +diff -urN a/mt_wifi/os/linux/mt_wifi_mtd.c b/mt_wifi/os/linux/mt_wifi_mtd.c +--- a/mt_wifi/os/linux/mt_wifi_mtd.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/mt_wifi/os/linux/mt_wifi_mtd.c 2019-01-06 17:17:32.771446000 +0800 +@@ -0,0 +1,113 @@ ++/* ++ *************************************************************************** ++ * MediaTek Inc. ++ * ++ * All rights reserved. source code is an unpublished work and the ++ * use of a copyright notice does not imply otherwise. This source code ++ * contains confidential trade secret material of MediaTek. Any attemp ++ * or participation in deciphering, decoding, reverse engineering or in any ++ * way altering the source code is stricitly prohibited, unless the prior ++ * written consent of MediaTek, Inc. is obtained. ++ *************************************************************************** ++ Module Name: ++ mt_wifi_mtd.c ++ ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if defined (CONFIG_MIPS) ++#include ++#endif ++ ++int mt_mtd_write_nm_wifi(char *name, loff_t to, size_t len, const u_char *buf) ++{ ++ int ret = -1; ++ size_t rdlen, wrlen; ++ struct mtd_info *mtd; ++ struct erase_info ei; ++ u_char *bak = NULL; ++ ++ mtd = get_mtd_device_nm(name); ++ if (IS_ERR(mtd)) ++ return -1; ++ ++ if (len > mtd->erasesize) { ++ put_mtd_device(mtd); ++ return -E2BIG; ++ } ++ ++ bak = kmalloc(mtd->erasesize, GFP_KERNEL); ++ if (bak == NULL) { ++ put_mtd_device(mtd); ++ return -ENOMEM; ++ } ++ ++ ret = mtd_read(mtd, 0, mtd->erasesize, &rdlen, bak); ++ ++ if (ret != 0) { ++ put_mtd_device(mtd); ++ kfree(bak); ++ return ret; ++ } ++ ++ if (rdlen != mtd->erasesize) ++ printk("warning: ra_mtd_write: rdlen is not equal to erasesize\n"); ++ ++ memcpy(bak + to, buf, len); ++ ++ ei.mtd = mtd; ++ ei.callback = NULL; ++ ei.addr = 0; ++ ei.len = mtd->erasesize; ++ ei.priv = 0; ++ ++ ret = mtd_erase(mtd, &ei); ++ ++ if (ret != 0) { ++ put_mtd_device(mtd); ++ kfree(bak); ++ return ret; ++ } ++ ++ ret = mtd_write(mtd, 0, mtd->erasesize, &wrlen, bak); ++ ++ ++ ++ put_mtd_device(mtd); ++ kfree(bak); ++ return ret; ++} ++EXPORT_SYMBOL(mt_mtd_write_nm_wifi); ++ ++ ++int mt_mtd_read_nm_wifi(char *name, loff_t from, size_t len, u_char *buf) ++{ ++ int ret; ++ size_t rdlen; ++ struct mtd_info *mtd; ++ ++ mtd = get_mtd_device_nm(name); ++ if (IS_ERR(mtd)) ++ return -1; ++ ++ ret = mtd_read(mtd, from, len, &rdlen, buf); ++ ++ if (rdlen != len) ++ printk("warning: ra_mtd_read_nm: rdlen is not equal to len\n"); ++ ++ put_mtd_device(mtd); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mt_mtd_read_nm_wifi); +diff -urN a/mt_wifi_ap/Makefile b/mt_wifi_ap/Makefile +--- a/mt_wifi_ap/Makefile 2018-04-30 15:57:57.000000000 +0800 ++++ b/mt_wifi_ap/Makefile 2019-04-20 21:16:22.510780934 +0800 +@@ -678,7 +678,8 @@ + os_objs := $(SRC_DIR)/os/linux/rt_proc.o\ + $(SRC_DIR)/os/linux/rt_linux.o\ + $(SRC_DIR)/os/linux/rt_profile.o\ +- $(SRC_DIR)/os/linux/rt_main_dev.o ++ $(SRC_DIR)/os/linux/rt_main_dev.o\ ++ $(SRC_DIR)/os/linux/mt_wifi_mtd.o + + ifeq ($(CONFIG_WLAN_HOOK),y) + EXTRA_CFLAGS +=-DRTMP_WLAN_HOOK_SUPPORT diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615E1_EEPROM.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615E1_EEPROM.bin new file mode 100644 index 000000000..cbd9803d8 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615E1_EEPROM.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4.bin new file mode 100644 index 000000000..4e4514b01 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_noReOrdering.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_noReOrdering.bin new file mode 100644 index 000000000..21ace4b5f Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_noReOrdering.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain.bin new file mode 100644 index 000000000..9216e9d1c Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain_20141024_1.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain_20141024_1.bin new file mode 100644 index 000000000..8a3b8819a Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain_20141024_1.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain_20150206_1_asic.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain_20150206_1_asic.bin new file mode 100644 index 000000000..4b7b86111 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/MT7615_cr4_plain_20150206_1_asic.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615.bin new file mode 100644 index 000000000..b9f87f746 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615_E1.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615_E1.bin new file mode 100644 index 000000000..86fa1abe6 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615_E1.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615_plain.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615_plain.bin new file mode 100644 index 000000000..bc30d8dbf Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/WIFI_RAM_CODE_MT7615_plain.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM1.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM1.bin new file mode 100644 index 000000000..36a56b9c9 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM1.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM2.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM2.bin new file mode 100644 index 000000000..36a56b9c9 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM2.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM3.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM3.bin new file mode 100644 index 000000000..36a56b9c9 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAeLNA/MT7615_EEPROM3.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM1.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM1.bin new file mode 100644 index 000000000..1cfcf2f9a Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM1.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM2.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM2.bin new file mode 100644 index 000000000..1cfcf2f9a Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM2.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM3.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM3.bin new file mode 100644 index 000000000..1cfcf2f9a Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/ePAiLNA/MT7615_EEPROM3.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM1.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM1.bin new file mode 100644 index 000000000..0e589fa21 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM1.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM2.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM2.bin new file mode 100644 index 000000000..0e589fa21 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM2.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM3.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM3.bin new file mode 100644 index 000000000..0e589fa21 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAeLNA/MT7615_EEPROM3.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM1.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM1.bin new file mode 100644 index 000000000..cbd9803d8 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM1.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM2.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM2.bin new file mode 100644 index 000000000..cbd9803d8 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM2.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM3.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM3.bin new file mode 100644 index 000000000..cbd9803d8 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/iPAiLNA/MT7615_EEPROM3.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/mt7615_patch_e3_hdr.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/mt7615_patch_e3_hdr.bin new file mode 100644 index 000000000..60d708afe Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7615/mt7615_patch_e3_hdr.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/MT7622_EEPROM.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/MT7622_EEPROM.bin new file mode 100644 index 000000000..31e112eae Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/MT7622_EEPROM.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/WIFI_RAM_CODE_MT7622_E2.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/WIFI_RAM_CODE_MT7622_E2.bin new file mode 100644 index 000000000..5aa69db52 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/WIFI_RAM_CODE_MT7622_E2.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/ePAeLNA/MT7622_EEPROM.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/ePAeLNA/MT7622_EEPROM.bin new file mode 100644 index 000000000..fefe17b48 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/ePAeLNA/MT7622_EEPROM.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/iPAeLNA/MT7622_EEPROM.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/iPAeLNA/MT7622_EEPROM.bin new file mode 100644 index 000000000..3f56f1ae9 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/iPAeLNA/MT7622_EEPROM.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/iPAiLNA/MT7622_EEPROM.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/iPAiLNA/MT7622_EEPROM.bin new file mode 100644 index 000000000..783b68674 Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/iPAiLNA/MT7622_EEPROM.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/mt7622_patch_e2_hdr.bin b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/mt7622_patch_e2_hdr.bin new file mode 100644 index 000000000..6f430aa9b Binary files /dev/null and b/package/lean/mt/drivers/mt_wifi/src/bin/mt7622/mt7622_patch_e2_hdr.bin differ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/History.txt b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/History.txt new file mode 100644 index 000000000..8ac1052ee --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/History.txt @@ -0,0 +1,51 @@ +[v5.0.2.0] +- Support MT7622D and MT7615A chip +- Support Passpoint R2 +- Support MBO +- Fix background scan fail +- Fix for False Cmd timeout +- Fix ACS busytime issue after boot up +- Fix memory leakage after interface down/up repeatedly +- Fix dead lock issue when hw_ctrl task is busy. + +[v5.0.1.1] +- Support WPS1 feature on OpenWRT OS +- Fix DFS issue of selecting NOP channel after interface down/up +- Avoid DFS resetting NOP list after interface is down and up +- Fix driver and wifi_forward sync structure not sync +- Fix MT7622 + MT7615 iPA RXSELFTEST fail (Disable RMAC before performing RXSELFTEST) +- Fix for Aplci connection and channel setting is AP interface is down + +[v5.0.1.0] +- AC4300 (MT7622 + MT7615 + MT7615) AP and Repeater support +- MT7622 2.4g 4T4R ePA/eLNA support +- OpenWRT AC2600 support +- MT7622 and MT7615 pre-calibration on flash mode +- Fine tune rx delay interrupt threshold to reduce cpu loading +- Wifi boot time improvement +- Rate algorithm refine +- Thermal compensation improvement +- Fix Eapol retry for 1st connection with broadcom AP +- 11R: Direct Intra-AP roaming Fix for Single Chip DBDC scenario +- Fix when MACRepeaterOuiMode is 2. The OUI parsing logic is incorrect +- Fix audio play issue on iPA mode + +[v5.0.0.0] +- AC2600 (MT7622 + MT7615) AP and Repeater support +- MT7622 2.4g 4T4R 802.11n iPA/iLNA support +- MT7615 5g 4T4R 802.11ac support +- MT7622 Wi-Fi Warp Accelerator support for MT7615 +- Max clients for MT7622:125, MT7615:125 +- Max MBSS for MT7622:16, MT7615:16 +- Security (OPEN/WEP/WPA/WPA2/PMF) +- 256 QAM support on 2.4g n mode +- 802.11 k/v/r +- UAPSD +- WDS +- WPS2.0 +- TxBF support +- MU-MIMO (5G) +- AirTime/bandwidth Fairness (ATM/VoW) support +- Auto channel selection +- Green AP + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/LoopBack.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/LoopBack.c new file mode 100644 index 000000000..ddf9f08f0 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/LoopBack.c @@ -0,0 +1,624 @@ +#if defined(COMPOS_TESTMODE_WIN) +#include "config.h" +#else +#include "rt_config.h" +#endif + +#if defined(RTMP_USB_SUPPORT) || defined(RTMP_PCI_SUPPORT) || defined(MTK_UART_SUPPORT) +INT32 ATECheckFWROMWiFiSysOn(RTMP_ADAPTER *pAd) +{ + INT32 ntStatus = STATUS_SUCCESS; + UINT32 loop = 0; + UINT32 value = 0; + /* Step 1 polling 0x81021250 to 0 */ + /* poll SW_SYN0 == 0 */ + loop = 0; + + do { + value = MtAsicGetFwSyncValue(pAd); + + if (value == 0x0) + break; + + os_msec_delay(1); + loop++; + } while (loop <= 500); + + if (loop > 500) { + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: 2. SW_SYN0 is not at init. state (SW_SYN0 = %d)\n", __func__, value)); + ntStatus = STATUS_UNSUCCESSFUL; + } + + /* power on WiFi SYS*/ + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: 2. power on WiFi SYS\n", __func__)); + ntStatus = MtCmdPowerOnWiFiSys(pAd); + + if (ntStatus) + ntStatus = STATUS_UNSUCCESSFUL; + + /* poll SW_SYN0 == 1*/ + loop = 0; + + do { + value = MtAsicGetFwSyncValue(pAd); + + if (value == 0x1) + break; + + os_msec_delay(1); + loop++; + } while (loop <= 500); + + if (loop > 500) { + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: SW_SYN0 is not at init. state (SW_SYN0 = %d)\n", __func__, value)); + ntStatus = STATUS_UNSUCCESSFUL; + } + + return ntStatus; +} +#endif + +INT32 CheckFWROMWiFiSysOn(IN RTMP_ADAPTER *pAd) +{ + INT32 ntStatus = STATUS_SUCCESS; +#if defined(RTMP_USB_SUPPORT) || defined(RTMP_PCI_SUPPORT) || defined(MTK_UART_SUPPORT) + ntStatus = ATECheckFWROMWiFiSysOn(pAd); +#endif + return ntStatus; +} +INT32 FWSwitchToROM( + IN RTMP_ADAPTER *pAd +) +{ + INT32 ntStatus = STATUS_SUCCESS; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); +#ifdef COMPOS_TESTMODE_WIN /* Linux ready in FWRAM */ + + if (pAd->FWMode == FWROM) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: FWMode is already ROM\n", __func__)); + else if (pAd->FWMode == FWRAM) +#endif + { + /* Step 1 set firmware to ROM mode */ + /* ntStatus = FirmwareCommnadRestartDownloadFW(pAd); */ + /* if(ntStatus != STATUS_SUCCESS) */ + /* { */ + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR,("%s, RestartDownloadFW cmd failed\n",__FUNCTION__)); */ + /* } */ + NICRestartFirmware(pAd); + ntStatus = CheckFWROMWiFiSysOn(pAd); + + if (ntStatus != STATUS_SUCCESS) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, CheckFWROMWiFiSysOn failed\n", __func__)); + } + + return ntStatus; +} +void LoopBack_Start(RTMP_ADAPTER *pAd, struct _LOOPBACK_SETTING *pSetting) +{ + NTSTATUS ntStatus = STATUS_SUCCESS; + /* UINT16 BreakCount = 0; */ +#ifdef COMPOS_TESTMODE_WIN /* TODO::Fix the strcture */ +#endif + /* UINT32 Length = 0; */ + /* UINT32 RepeatIdx = 0; */ + UINT32 RxQ = 1; + /* RtlCopyMemory(&pAd->LoopBackSetting, pSetting,sizeof(struct _LOOPBACK_SETTING)); */ + os_move_mem(&pAd->LbCtrl.LoopBackSetting, pSetting, sizeof(struct _LOOPBACK_SETTING)); + /* RtlZeroMemory(&pAd->LoopBackTxRaw, LOOPBACK_SIZE); */ + os_zero_mem(&pAd->LbCtrl.LoopBackTxRaw, LOOPBACK_SIZE); + /* RtlZeroMemory(&pAd->LoopBackRxRaw, LOOPBACK_SIZE); */ + os_zero_mem(&pAd->LbCtrl.LoopBackRxRaw, LOOPBACK_SIZE); + /* RtlZeroMemory(&pAd->LoopBackResult, sizeof(struct _LOOPBACK_RESULT)); */ + os_zero_mem(&pAd->LbCtrl.LoopBackResult, sizeof(struct _LOOPBACK_RESULT)); + + if (pSetting->StartLen < sizeof(TMAC_TXD_L)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s startLength(0x%x) is shorter than sizeof(TMAC_TXD_L) (0x%lx)\n", __func__, pSetting->StartLen, (ULONG)sizeof(TMAC_TXD_L))); + return; + } + + OS_SPIN_LOCK(&pAd->LbCtrl.LoopBackLock); + pAd->LbCtrl.LoopBackWaitRx = FALSE; + OS_SPIN_UNLOCK(&pAd->LbCtrl.LoopBackLock); + pAd->LbCtrl.LoopBackRunning = TRUE; + pAd->LbCtrl.LoopBackResult.Status = RUNNING; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IsDefaultPattern %d\n", pSetting->IsDefaultPattern)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RepeatTimes %u, %u\n", pSetting->RepeatTimes, pAd->LbCtrl.LoopBackSetting.RepeatTimes)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("StartLen %d\n", pSetting->StartLen)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("StopLen %d\n", pSetting->StopLen)); + pAd->LbCtrl.LoopBackDefaultPattern = (BOOLEAN)pSetting->IsDefaultPattern; + + if (pAd->LbCtrl.DebugMode) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("In LoopBack Debug Mode\n")); + goto ATE_LPBK_DEBUG; + } + + if (!pAd->LbCtrl.LoopBackUDMA) { + ntStatus = FWSwitchToROM(pAd); + + if (ntStatus != STATUS_SUCCESS) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, Switch to ROM failed (0x%x)\n", __func__, ntStatus)); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s FWSwitchToROM\n", __func__)); + } + + + if (!pAd->LbCtrl.LoopBackUDMA) + MtCmdHIFLoopBackTest(pAd, 1, (UINT8)RxQ); + +ATE_LPBK_DEBUG: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("***************************************%s @#@# Rx[%d]***************************************\n", __func__, RxQ)); + /* pAd->LbCtrl.LoopBackTxThread = NULL; */ + /* + * ntStatus = PsCreateSystemThread(&pAd->LbCtrl.LoopBackTxTask.hThread, + * (ACCESS_MASK) 0L, + * NULL, + * NULL, + * NULL, + * LoopBack_TxThread, + * pAd); + */ + ntStatus = RtmpOSTaskAttach(&pAd->LbCtrl.LoopBackTxTask, LoopBack_TxThread, (ULONG)&pAd->LbCtrl.LoopBackTxTask); + + if (ntStatus != STATUS_SUCCESS) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, thread create fail\n", __func__)); +} +void LoopBack_Stop(RTMP_ADAPTER *pAd) +{ + UINT32 BreakCount = 0; + + while (pAd->LbCtrl.LoopBackWaitRx == TRUE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, @#@#BreakCount = %d\n", __func__, BreakCount)); + + if (BreakCount > 100) + break; + +#ifdef COMPOS_TESTMODE_WIN + RTMPusecDelay(300); +#else + RtmpusecDelay(300); +#endif + BreakCount++; + } + + if (RtmpOSTaskKill(&pAd->LbCtrl.LoopBackTxTask) == NDIS_STATUS_FAILURE) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("kill LoopBackTxTask task failed!\n")); + + if (pAd->LbCtrl.LoopBackResult.Status == RUNNING) { + pAd->LbCtrl.LoopBackResult.Status = PASS; + pAd->LbCtrl.LoopBackResult.FailReason = NO_ERROR; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("***************************************%s @#@#***************************************\n", __func__)); + pAd->LbCtrl.LoopBackRunning = FALSE; + + if (pAd->LbCtrl.DebugMode) + goto ATE_LB_DEBUG_STOP; + + + if (!pAd->LbCtrl.LoopBackUDMA) + MtCmdHIFLoopBackTest(pAd, 0, 0); + +ATE_LB_DEBUG_STOP: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s,\n", __func__)); +} +void LoopBack_Status(RTMP_ADAPTER *pAd, struct _LOOPBACK_RESULT *pResult) +{ + os_move_mem(pResult, &pAd->LbCtrl.LoopBackResult, sizeof(struct _LOOPBACK_RESULT)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Status: %d\n", __func__, pAd->LbCtrl.LoopBackResult.Status)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, FailReason: %d\n", __func__, pAd->LbCtrl.LoopBackResult.FailReason)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, RxByteCount: %d\n", __func__, pAd->LbCtrl.LoopBackResult.RxByteCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, RxPktCount: %d\n", __func__, pAd->LbCtrl.LoopBackResult.RxPktCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, TxByteCount: %d\n", __func__, pAd->LbCtrl.LoopBackResult.TxByteCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, TxPktCount: %d\n", __func__, pAd->LbCtrl.LoopBackResult.TxPktCount)); +} +void LoopBack_RawData(RTMP_ADAPTER *pAd, UINT32 *pLength, BOOLEAN IsTx, UCHAR *RawData) +{ + if (*pLength > LOOPBACK_SIZE) { + *pLength = LOOPBACK_SIZE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, max length is %d\n", __func__, LOOPBACK_SIZE)); + } + + if (IsTx) { + *pLength = pAd->LbCtrl.LoopBackTxRawLen; + /* RtlCopyMemory(RawData, &pAd->LoopBackTxRaw,*pLength); */ + os_move_mem(RawData, &pAd->LbCtrl.LoopBackTxRaw, *pLength); + } else { + *pLength = pAd->LbCtrl.LoopBackRxRawLen; + /* RtlCopyMemory(RawData, &pAd->LoopBackRxRaw,*pLength); */ + os_move_mem(RawData, &pAd->LbCtrl.LoopBackRxRaw, *pLength); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Length = 0x%x\n", __func__, *pLength)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, LoopBackRxRawLen = 0x%x\n", __func__, pAd->LbCtrl.LoopBackRxRawLen)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, LoopBackTxRawLen = 0x%x\n", __func__, pAd->LbCtrl.LoopBackTxRawLen)); +} +void LoopBack_ExpectRx(RTMP_ADAPTER *pAd, UINT32 Length, UINT8 *pRawData) +{ + PULONG ptr; + UINT8 i = 0; + + if (Length > LOOPBACK_SIZE) { + Length = LOOPBACK_SIZE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, max length is %d\n", __func__, LOOPBACK_SIZE)); + } + + /* (&pAd->LbCtrl.LoopBackExpectRx, pRawData, Length); */ + os_move_mem(&pAd->LbCtrl.LoopBackExpectRx, pRawData, Length); + ptr = (PULONG)(&pAd->LbCtrl.LoopBackExpectRx); + /* Length = ptr[0] & 0xffff; */ + pAd->LbCtrl.LoopBackExpectRxLen = Length; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Length = %d\n", __func__, Length)); + + for (i = 0; i < 20; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("TXD(TXWI) %d 0x%08lX\n", i, *(ptr + i))); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s,\n", __func__)); +} + +void LoopBack_ExpectTx(RTMP_ADAPTER *pAd, UINT32 Length, UINT8 *pRawData) +{ + PULONG ptr; + UINT8 i = 0; + + if (Length > LOOPBACK_SIZE) { + Length = LOOPBACK_SIZE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, max length is %d\n", __func__, LOOPBACK_SIZE)); + } + + /* RtlCopyMemory(&pAd->LoopBackExpectTx, pRawData, Length); */ + os_move_mem(&pAd->LbCtrl.LoopBackExpectTx, pRawData, Length); + ptr = (PULONG)(&pAd->LbCtrl.LoopBackExpectTx); + /* Length = ptr[0] & 0xffff; */ + pAd->LbCtrl.LoopBackExpectTxLen = Length; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Length = %d\n", __func__, Length)); + + for (i = 0; i < 20; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("TXD(TXWI) %d 0x%08lX\n", i, *(ptr + i))); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s,\n", __func__)); +} + +void LoopBack_Run(RTMP_ADAPTER *pAd, struct _LOOPBACK_SETTING *pSetting, UINT32 Length) +{ + if (Length > LOOPBACK_SIZE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, LOOPBACK length too long\n", __func__)); + return; + } + +#ifdef _RTMP_PCI_SUPPORT + PCILoopBack_Run(pAd, pSetting, Length); +#endif +} +void LoopBack_BitTrueCheck(RTMP_ADAPTER *pAd) +{ + if (!pAd->LbCtrl.LoopBackDefaultPattern) { /* Rx compare expect Rx */ + if (pAd->LbCtrl.LoopBackExpectRxLen != pAd->LbCtrl.LoopBackRxRawLen) { + LoopBack_Fail(pAd, BIT_TRUE_FAIL); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, ####################### TX/RX Length not equal ####################\n", __func__)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, ExpectRxLen = %d, RxRawLen = %d\n", __func__, pAd->LbCtrl.LoopBackExpectRxLen, pAd->LbCtrl.LoopBackRxRawLen)); + } else if (RTMPEqualMemory((PVOID)&pAd->LbCtrl.LoopBackExpectRx, (PVOID)&pAd->LbCtrl.LoopBackRxRaw, pAd->LbCtrl.LoopBackRxRawLen) == 0) { + if (pAd->LbCtrl.DebugMode) { + UINT32 j = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RxExpect Dump(%u): ", pAd->LbCtrl.LoopBackRxRawLen)); + + for (j = 0; j < pAd->LbCtrl.LoopBackRxRawLen; j++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02x", pAd->LbCtrl.LoopBackExpectRx[j])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RxBackRaw Dump: ")); + + for (j = 0; j < pAd->LbCtrl.LoopBackRxRawLen; j++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02x", pAd->LbCtrl.LoopBackRxRaw[j])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + } + + LoopBack_Fail(pAd, BIT_TRUE_FAIL); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, ####################### BIT_TRUE_FAIL ####################\n", __func__)); + } else + pAd->LbCtrl.LoopBackResult.FailReason = NO_ERROR; + } else { /* Rx compare Tx */ + if (pAd->LbCtrl.LoopBackTxRawLen != pAd->LbCtrl.LoopBackRxRawLen) { + LoopBack_Fail(pAd, BIT_TRUE_FAIL); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, ####################### TX/RX Length not equal ####################\n", __func__)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, TxRawLen = %d, RxRawLen = %d\n", __func__, pAd->LbCtrl.LoopBackTxRawLen, pAd->LbCtrl.LoopBackRxRawLen)); + } else if (RTMPEqualMemory((PVOID)&pAd->LbCtrl.LoopBackTxRaw, (PVOID)&pAd->LbCtrl.LoopBackRxRaw, pAd->LbCtrl.LoopBackTxRawLen) == 0) { + if (pAd->LbCtrl.DebugMode) { + UINT32 j = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("TxExpect Dump(%u): ", pAd->LbCtrl.LoopBackTxRawLen)); + + for (j = 0; j < pAd->LbCtrl.LoopBackRxRawLen; j++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x", pAd->LbCtrl.LoopBackTxRaw[j])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RxBackRaw Dump: ")); + + for (j = 0; j < pAd->LbCtrl.LoopBackRxRawLen; j++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x", pAd->LbCtrl.LoopBackRxRaw[j])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + + LoopBack_Fail(pAd, BIT_TRUE_FAIL); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, ####################### BIT_TRUE_FAIL ####################\n", __func__)); + } else { + pAd->LbCtrl.LoopBackResult.FailReason = NO_ERROR; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, ####################### BIT_TRUE OK ####################\n", __func__)); + } + } +} + +void LoopBack_Fail(RTMP_ADAPTER *pAd, enum _LOOPBACK_FAIL FailNum) +{ + if (pAd->LbCtrl.LoopBackResult.Status == RUNNING) { + pAd->LbCtrl.LoopBackResult.FailReason = FailNum; + pAd->LbCtrl.LoopBackResult.Status = FAIL; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, FailReason = %d\n", __func__, FailNum)); + } +} + +#ifdef COMPOS_TESTMODE_WIN +INT LoopBack_TxThread(IN OUT PVOID Context) +#else +INT LoopBack_TxThread(ULONG Context) +#endif +{ +#ifdef COMPOS_TESTMODE_WIN + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)Context; +#else + RTMP_OS_TASK *pTask = (RTMP_OS_TASK *)Context; + RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask); +#endif + struct _LOOPBACK_SETTING *pSetting = &pAd->LbCtrl.LoopBackSetting; + UINT32 RepeatIdx = 0; + UINT32 Length = 0; + UINT32 BreakCount = 0; + UINT32 DbgCount = 0; + /* KIRQL Irql; */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Repeat:%u\n", __func__, pSetting->RepeatTimes)); + + if (pSetting->RepeatTimes == 0) + pSetting->RepeatTimes = 0xffffffff; + + for (RepeatIdx = 0; RepeatIdx < pSetting->RepeatTimes ; RepeatIdx++) { + if (pSetting->RepeatTimes == 0xffffffff) + RepeatIdx = 0; + + for (Length = pSetting->StartLen; Length <= pSetting->StopLen; Length++) { + while (pAd->LbCtrl.LoopBackWaitRx) { + BreakCount++; +#ifdef COMPOS_TESTMODE_WIN + RTMPusecDelay(50); +#else + RtmpusecDelay(50); +#endif + + if (BreakCount > 2000) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, no Rx come back Stop1!!!\n", __func__)); + break; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, no Rx BreakCount = %d\n", __func__, BreakCount)); + } + + if (BreakCount > 2000) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, no Rx come back Stop2!!!\n", __func__)); + LoopBack_Fail(pAd, RX_TIMEOUT); + break; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, Length = %d\n", __func__, Length)); + BreakCount = 0; + + if (pAd->LbCtrl.LoopBackRunning == FALSE || pAd->LbCtrl.LoopBackResult.Status != RUNNING) + break; + + if (!pSetting->IsDefaultPattern) + Length = pAd->LbCtrl.LoopBackExpectTxLen; + + if (pAd->LbCtrl.LoopBackResult.Status == RUNNING) { + /* KeAcquireSpinLock(&pAd->LoopBackLock, &Irql); */ + OS_SPIN_LOCK(&pAd->LbCtrl.LoopBackLock); + pAd->LbCtrl.LoopBackWaitRx = TRUE; + /* KeReleaseSpinLock(&pAd->LoopBackLock, Irql); */ + OS_SPIN_UNLOCK(&pAd->LbCtrl.LoopBackLock); + LoopBack_Run(pAd, pSetting, Length); + + if (pAd->LbCtrl.LoopBackRunning == FALSE || pAd->LbCtrl.LoopBackResult.Status != RUNNING) + break; + } + +#ifdef COMPOS_TESTMODE_WIN + RTMPusecDelay(200); +#else + RtmpusecDelay(200); +#endif + DbgCount++; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, DbgCount = %d\n", __func__, DbgCount)); + + if (!pSetting->IsDefaultPattern) { + /* use script file does not need to auto increase length */ + break; + } + } + + if (pAd->LbCtrl.LoopBackRunning == FALSE || pAd->LbCtrl.LoopBackResult.Status != RUNNING) + break; + } + + if (pAd->LbCtrl.LoopBackRunning) + LoopBack_Stop(pAd); + + /* pAd->LbCtrl.LoopBackTxThread = NULL; */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("+ + + + Control Thread Terminated + + + +\n")); + /* DecrementIoCount(pAd); */ + /* PsTerminateSystemThread(STATUS_SUCCESS); */ + RtmpOSTaskNotifyToExit(&pAd->LbCtrl.LoopBackTxTask); + return 0; +} + +VOID LoopBack_Rx(RTMP_ADAPTER *pAd, UINT32 pktlen, UINT8 *pData) +{ + if (!pAd->LbCtrl.LoopBackRunning && !pAd->LbCtrl.LoopBackWaitRx) + return; + + { + UINT32 LPLength = 0; + INT32 TotalLength = (INT32)pktlen; + UINT8 *ptr = pData; + EVENT_RXD EvnRxD; + + /* FwCMDRspTxD_STRUC FwCMDRspTxD; */ + if (pAd->LbCtrl.DebugMode) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Debug Mode, Total Len:%d\n", __func__, TotalLength)); + LPLength = pktlen; + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Driver Rx LoopBackRunning\n")); + /* os_move_mem(&FwCMDRspTxD,ptr,sizeof(FwCMDRspTxD)); */ + os_move_mem(&EvnRxD, ptr, sizeof(EvnRxD)); + /* LPLength = FwCMDRspTxD.FwEventTxD.u2RxByteCount; */ + LPLength = EvnRxD.fw_rxd_0.field.length; + + if (LPLength > LOOPBACK_SIZE) { + LPLength = LOOPBACK_SIZE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, max length is %d\n", __func__, LOOPBACK_SIZE)); + } + } + + { +#ifdef COMPOS_TESTMODE_WIN /* Windows First -4 for padding bits and then add back here,Linux(?) */ + + if (!pAd->LbCtrl.LoopBackSetting.IsDefaultPattern) + LPLength = TotalLength + 4; + +#endif + /* RtlCopyMemory(&FwCMDRspTxD,ptr,sizeof(FwCMDRspTxD)); */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Total Length = %d, LPLength is %d, bytecount = %d\n", + __func__, TotalLength, LPLength, EvnRxD.fw_rxd_0.field.length)); + /* LPLength = FwCMDRspTxD.FwEventTxD.u2RxByteCount; */ + pAd->LbCtrl.LoopBackResult.RxByteCount += LPLength; + pAd->LbCtrl.LoopBackResult.RxPktCount++; + os_move_mem(&pAd->LbCtrl.LoopBackRxRaw, ptr, LPLength); + pAd->LbCtrl.LoopBackRxRawLen = LPLength; + } + + if (pAd->LbCtrl.LoopBackUDMA == FALSE) + LoopBack_BitTrueCheck(pAd); + + /* KeAcquireSpinLock(&pAdapter->LoopBackLock, &Irql); */ + OS_SPIN_LOCK(&pAd->LbCtrl.LoopBackLock); + pAd->LbCtrl.LoopBackWaitRx = FALSE; + /* KeReleaseSpinLock(&pAdapter->LoopBackLock, Irql); */ + OS_SPIN_UNLOCK(&pAd->LbCtrl.LoopBackLock); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, RxPktCount = %d\n", __func__, pAd->LbCtrl.LoopBackResult.RxPktCount)); + } +} + + +/* currently not implement PCIE loopback */ +#ifdef _RTMP_PCI_SUPPORT +void PCILoopBack_Run(RTMP_ADAPTER *pAd, struct _LOOPBACK_SETTING *pSetting, UINT32 length) +{ + UINT32 count = 0; + TMAC_TXD_L TxD; + PUCHAR ptr; + UINT8 alignment = 0; + /* UINT32 TimeOut1Second = 100; */ + UCHAR *TxDataBuffer = NULL; + UINT32 *TxDataBufferLength; + UINT32 BUF_SIZE = 0; +#ifdef COMPOS_TESTMODE_WIN + TxDataBuffer = pAd->TxDataBuffer; + BUF_SIZE = BUFFER_SIZE; + TxDataBufferLength = &pAd->TxDataBufferLength; +#else + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + + TxDataBuffer = pAd->ATECtrl.pate_pkt; + BUF_SIZE = ATE_TESTPKT_LEN; + TxDataBufferLength = &pAd->ATECtrl.TxLength; +#endif + + /* length = 1024; */ + if (pSetting->IsDefaultPattern) { + os_zero_mem(TxDataBuffer, BUF_SIZE); + os_zero_mem(&TxD, sizeof(TxD)); + ptr = TxDataBuffer + sizeof(TxD); + + for (count = 0; count < length - sizeof(TxD); count++) + ptr[count] = count % 16; + + /* set pkt content */ + TxD.TxD0.TxByteCount = length; +#ifndef MT7615 + TxD.TxD0.PIdx = 1; + TxD.TxD0.QIdx = 0; + TxD.TxD1.TxDFmt = 1; + TxD.TxD1.HdrFmt = 1; +#endif + os_move_mem(TxDataBuffer, &TxD, sizeof(TxD)); + os_move_mem(&pAd->LbCtrl.LoopBackTxRaw, TxDataBuffer, LOOPBACK_SIZE); + pAd->LbCtrl.LoopBackTxRawLen = length; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, length = %d\n", __func__, length)); + + if (length > 32) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("===buffer===\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%x 0x%x 0x%x 0x%x\n", TxDataBuffer[3], TxDataBuffer[2], TxDataBuffer[1], TxDataBuffer[0])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%x 0x%x 0x%x 0x%x\n", TxDataBuffer[7], TxDataBuffer[6], TxDataBuffer[5], TxDataBuffer[4])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%x 0x%x 0x%x 0x%x\n", TxDataBuffer[11], TxDataBuffer[10], TxDataBuffer[9], TxDataBuffer[8])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%x 0x%x 0x%x 0x%x\n", TxDataBuffer[15], TxDataBuffer[14], TxDataBuffer[13], TxDataBuffer[12])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%x 0x%x 0x%x 0x%x\n", TxDataBuffer[19], TxDataBuffer[18], TxDataBuffer[17], TxDataBuffer[16])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%x 0x%x 0x%x 0x%x\n", TxDataBuffer[23], TxDataBuffer[22], TxDataBuffer[21], TxDataBuffer[20])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%x 0x%x 0x%x 0x%x\n", TxDataBuffer[27], TxDataBuffer[26], TxDataBuffer[25], TxDataBuffer[24])); + } + + if (length % 4 != 0) + alignment = 4 - (length % 4); + + if (pAd->LbCtrl.DebugMode) { + int j = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Tx Dump: ")); + + for (j = 0; j < length; j++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x", TxDataBuffer[j])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + + /* pAd->TxDataBufferLength = length + alignment + 4 ; */ + *TxDataBufferLength = length + alignment + 4; + } else { + os_move_mem(TxDataBuffer, &pAd->LbCtrl.LoopBackExpectTx, pAd->LbCtrl.LoopBackExpectTxLen); + os_zero_mem(TxDataBuffer + length, pAd->LbCtrl.LoopBackExpectTxLen - length); + os_move_mem(&pAd->LbCtrl.LoopBackTxRaw, TxDataBuffer, length); + pAd->LbCtrl.LoopBackTxRawLen = pAd->LbCtrl.LoopBackExpectTxLen; + /* pAd->LoopBackExpectRxLen = length; */ + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, LP length = %d, alignment = %d\n", __func__, length, alignment)); + pAd->LbCtrl.LoopBackResult.TxByteCount += length; + pAd->LbCtrl.LoopBackResult.TxPktCount++; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, RxPktCount = %d\n", __func__, pAd->LbCtrl.LoopBackResult.RxPktCount)); +#ifdef COMPOS_TESTMODE_WIN + StartTx(pAd, 1, 0); +#else + ate_ctrl->TxLength = length; + MT_ATETxPkt(pAd, TESTMODE_BAND0); +#endif + + /* cannot pass UINT32 TimeOut1Second = 100; to wait_event, it will not wait.. workaround use 0 (1second instead of TimeOut1Second) */ + if (!pAd->LbCtrl.DebugMode) + if (RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&pAd->LbCtrl.LoopBackPCITxEvent, 0) != STATUS_SUCCESS) { + LoopBack_Fail(pAd, TX_TIMEOUT); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, ####################### TX_TIMEOUT ####################3\n", __func__)); + } +} +#endif + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/ate_agent.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/ate_agent.c new file mode 100644 index 000000000..55d5b9158 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/ate_agent.c @@ -0,0 +1,6146 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + ate_agent.c +*/ + +#include "rt_config.h" + +#define MCAST_WCID_TO_REMOVE 0 /* Pat: TODO */ + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) +#define ATE_ANT_USER_SEL 0x80000000 +#endif + +/* CCK Mode */ +static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; + +/* OFDM Mode */ +static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; + +/* HT Mixed Mode */ +static CHAR HTMIXRateTable[] = {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, -1}; + +/* VHT Mode */ +static CHAR VHTRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1}; + + +UINT_8 Addr1[6] = {0x00, 0x11, 0x11, 0x11, 0x11, 0x11}; +UINT_8 Addr2[6] = {0x00, 0x22, 0x22, 0x22, 0x22, 0x22}; +UINT_8 Addr3[6] = {0x00, 0x22, 0x22, 0x22, 0x22, 0x22}; + +#if defined(TXBF_SUPPORT) && defined(MT_MAC) +UCHAR TemplateFrame[32] = {0x88, 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 UINT8 BF_ON_certification; +extern UINT8 g_EBF_certification; +#else +static 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 + }; +#endif /* defined(TXBF_SUPPORT) && defined(MT_MAC) */ + +INT32 SetTxStop(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetRxStop(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +#ifdef DBG +VOID ATE_QA_Statistics(RTMP_ADAPTER *pAd, RXWI_STRUC *pRxWI, RXINFO_STRUC *pRxInfo, PHEADER_802_11 pHeader) +{ +} + + +INT32 SetEERead(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetEEWrite(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetBBPRead(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetBBPWrite(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetRFWrite(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} +#endif /* DBG */ + + +VOID EEReadAll(PRTMP_ADAPTER pAd, UINT16 *Data, UINT16 size) +{ + UINT16 Offset = 0; + UINT16 Value; + + for (Offset = 0; Offset < (size >> 1);) { + RT28xx_EEPROM_READ16(pAd, (Offset << 1), Value); + Data[Offset] = Value; + Offset++; + } +} + +INT32 SetATEDaByWtblTlv(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Octet; + RTMP_STRING *Value; + /* Tag = 0, Generic */ + CMD_WTBL_GENERIC_T rWtblGeneric = {0}; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Da = %s\n", __func__, Arg)); + + /* 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, &ATECtrl->Addr1[Octet++], 1); +#endif /* CONFIG_AP_SUPPORT */ + } + + /* sanity check */ + if (Octet != MAC_ADDR_LEN) + return FALSE; + +#ifdef MT_MAC + /* WIndex = 1, WTBL1: PeerAddress */ + rWtblGeneric.u2Tag = WTBL_GENERIC; + rWtblGeneric.u2Length = sizeof(CMD_WTBL_GENERIC_T); + NdisMoveMemory(rWtblGeneric.aucPeerAddress, ATECtrl->Addr3, MAC_ADDR_LEN); + CmdExtWtblUpdate(pAd, 1 /**/, SET_WTBL, (PUCHAR)&rWtblGeneric, sizeof(CMD_WTBL_GENERIC_T)); +#endif +#ifdef CONFIG_AP_SUPPORT + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: (DA = %02x:%02x:%02x:%02x:%02x:%02x)\n", __func__, + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], + ATECtrl->Addr1[4], ATECtrl->Addr1[5])); +#endif /* CONFIG_AP_SUPPORT */ + return TRUE; +} +INT32 SetATEQid(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + USHORT q_idx; + + q_idx = simple_strtol(Arg, 0, 10); + ATECtrl->QID = q_idx; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: QID:%u\n", __func__, q_idx)); + return TRUE; +} + +INT32 SetATETxSEnable(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UINT32 param = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Parm = %s\n", __func__, Arg)); + + param = simple_strtol(Arg, 0, 10); + ATECtrl->txs_enable = param; + + return TRUE; +} + +INT32 SetATERxFilter(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + const INT param_num = 3; + MT_RX_FILTER_CTRL_T rx_filter; + UINT32 input[param_num]; + CHAR *value; + INT i; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Parm = %s\n", __func__, arg)); + + for (i = 0; i < param_num; i++) + input[i] = 0; + + for (i = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":")) { + if (i == param_num) + break; + + input[i++] = simple_strtol(value, 0, 16); + } + + os_zero_mem(&rx_filter, sizeof(rx_filter)); + rx_filter.bPromiscuous = input[0]; + rx_filter.bFrameReport = input[1]; + rx_filter.filterMask = input[2]; + rx_filter.u1BandIdx = control_band_idx; + MtATESetRxFilter(pAd, rx_filter); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Promiscuous:%x, FrameReport:%x, filterMask:%x\n", + __func__, rx_filter.bPromiscuous, rx_filter.bFrameReport, rx_filter.filterMask)); + + if (!Ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATERxStream(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 param = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Parm = %s\n", __func__, Arg)); + + param = simple_strtol(Arg, 0, 10); + Ret = MtATESetRxPath(pAd, param, control_band_idx); + + if (!Ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATETxStream(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 param = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Parm = %s\n", __func__, Arg)); + + param = simple_strtol(Arg, 0, 10); + Ret = MtATESetTxStream(pAd, param, control_band_idx); + + if (!Ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATEMACTRx(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + const INT param_num = 3; + UINT32 input[param_num]; + CHAR *value; + INT i; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Parm = %s\n", __func__, arg)); + + for (i = 0; i < param_num; i++) + input[i] = 0; + + for (i = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":")) { + if (i == param_num) + break; + + input[i++] = simple_strtol(value, 0, 16); + } + + Ret = MtATESetMacTxRx(pAd, input[0], input[1], control_band_idx); + + if (!Ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATEMPSStart(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = 0; + UINT enable; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Parm = %s\n", __func__, arg)); + + enable = simple_strtol(arg, 0, 10); + + if (enable) + ret = ATEOp->MPSTxStart(pAd); + else + ret = ATEOp->MPSTxStop(pAd); + + if (!ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATEMPSDump(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT ret = 0; + UINT32 band_idx = simple_strtol(arg, 0, 10); + + ret = MT_SetATEMPSDump(pAd, band_idx); + + if (!ret) + return TRUE; + + return FALSE; +} + +static INT32 SetATEMPSParam(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg, UINT type) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + INT num_items = 0; + CHAR *value; + RTMP_STRING *tmp = arg; + UINT32 *mps_setting = NULL; + INT i; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Parm = %s\n", __func__, arg)); + + value = rstrtok(tmp, ":"); + + if (!value) + goto err0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("value:%s, arg:%s, tmp:%s\n", + value, arg, tmp)); + num_items = simple_strtol(value, 0, 10); + + if (!num_items) + goto err0; + + Ret = os_alloc_mem(pAd, (UCHAR **)&mps_setting, sizeof(UINT32) * (num_items)); + + if (Ret) + goto err1; + + for (i = 0, value = rstrtok(NULL, ":"); value; value = rstrtok(NULL, ":")) { + if (i == num_items) + break; + + mps_setting[i++] = simple_strtol(value, 0, 10); + } + + if (i != num_items) + goto err2; + + ATEOp->MPSSetParm(pAd, type, num_items, mps_setting); + + if (mps_setting) + os_free_mem(mps_setting); + + return TRUE; +err2: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Number of items %d is not matched with number of params %d\n", + __func__, num_items, i)); + + if (mps_setting) + os_free_mem(mps_setting); + +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Mem allocate fail\n", __func__)); +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: [%u]Format: num_itmes:param1:param2:...\n", + __func__, type)); + return FALSE; +} + +INT32 SetATEMPSPhyMode(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_PHYMODE); + return ret; +} + +INT32 SetATEMPSRate(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_RATE); + return ret; +} + + +INT32 SetATEMPSPath(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_PATH); + return ret; +} + +INT32 SetATEMPSPayloadLen(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_PAYLOAD_LEN); + return ret; +} + +INT32 SetATEMPSPktCnt(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_TX_COUNT); + return ret; +} + +INT32 SetATEMPSPwr(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_PWR_GAIN); + return ret; +} + +INT32 SetATEMPSNss(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_NSS); + return ret; +} + +INT32 SetATEMPSPktBw(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 ret = 0; + + ret = SetATEMPSParam(pAd, arg, MPS_PKT_BW); + return ret; +} + +INT32 SetATELOGDump(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_LOG_DUMP_CB *log_cb = &ATECtrl->log_dump[0]; + UINT32 log_type; + + log_type = simple_strtol(Arg, 0, 10); + + if (log_type == 0 || log_type >= ATE_LOG_TYPE_NUM) + return FALSE; + + log_cb = &ATECtrl->log_dump[log_type - 1]; + MT_ATEDumpLog(pAd, log_cb, log_type); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: log_type:%08x, driver:%08x\n", + __func__, log_type, ATECtrl->en_log)); + return TRUE; +} + +INT32 SetATELOGEnable(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 log_type; + INT32 Ret = 0; + + log_type = simple_strtol(Arg, 0, 10); + Ret = ATEOp->LogOnOff(pAd, log_type, TRUE, 2000); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: log_type:%u, driver:%08x\n", + __func__, log_type, ATECtrl->en_log)); + return TRUE; +} + +INT32 SetATELOGDisable(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 log_type; + INT32 Ret = 0; + + log_type = simple_strtol(Arg, 0, 10); + Ret = ATEOp->LogOnOff(pAd, log_type, FALSE, 0); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: log_type:%u, driver:%08x\n", + __func__, log_type, ATECtrl->en_log)); + return TRUE; +} + +INT32 SetATEDeqCnt(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ +#ifdef ATE_TXTHREAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT deq_cnt; + + deq_cnt = simple_strtol(Arg, 0, 10); + ATECtrl->deq_cnt = deq_cnt; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: deq_cnt:%d\n", __func__, deq_cnt)); +#endif + return TRUE; +} + +INT32 SetATEDa(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + return SetATEDaByWtblTlv(pAd, Arg); +} + +INT32 SetATESa(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + RTMP_STRING *Value; + INT32 Octet; + struct wifi_dev *wdev = pAd->wdev_list[ATECtrl->wdev_idx]; + UCHAR BandIdx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Sa = %s\n", __func__, Arg)); + + /* 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, &ATECtrl->Addr3[Octet++], 1); +#endif /* CONFIG_AP_SUPPORT */ + } + + /* sanity check */ + if (Octet != MAC_ADDR_LEN) + return FALSE; + +#ifdef MT_MAC + /* Set the specific MAC to ASIC */ + /* TODO: Hanmin H/W HAL offload, below code is replaced by new code above, right PIC needs further check */ +#ifdef CONFIG_AP_SUPPORT + BandIdx = HcGetBandByWdev(wdev); + AsicDevInfoUpdate( + pAd, + 0x0, + ATECtrl->Addr3, + BandIdx, + TRUE, + DEVINFO_ACTIVE_FEATURE); +#endif /* CONFIG_AP_SUPPORT */ +#endif +#ifdef CONFIG_AP_SUPPORT + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: (SA = %02x:%02x:%02x:%02x:%02x:%02x)\n", __func__, + ATECtrl->Addr3[0], ATECtrl->Addr3[1], ATECtrl->Addr3[2], ATECtrl->Addr3[3], + ATECtrl->Addr3[4], ATECtrl->Addr3[5])); +#endif /* CONFIG_AP_SUPPORT */ + return TRUE; +} + + +INT32 SetATEBssid(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + RTMP_STRING *Value; + INT32 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, &ATECtrl->Addr2[Octet++], 1); +#endif /* CONFIG_AP_SUPPORT */ + } + + /* sanity check */ + if (Octet != MAC_ADDR_LEN) + return FALSE; + +#ifdef CONFIG_AP_SUPPORT + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: (BSSID = %02x:%02x:%02x:%02x:%02x:%02x)\n", __func__, + ATECtrl->Addr2[0], ATECtrl->Addr2[1], ATECtrl->Addr2[2], ATECtrl->Addr2[3], + ATECtrl->Addr2[4], ATECtrl->Addr2[5])); +#endif /* CONFIG_AP_SUPPORT */ + return TRUE; +} + + +INT32 SetATEInitChan(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetADCDump(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATERFPower(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 RFPower; + UINT32 band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Power0 = %s\n", __FUNCTION__, Arg)); + + RFPower = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: RF_Power = %d, band_idx = %d \n", + __FUNCTION__, RFPower, band_idx)); + + TESTMODE_SET_PARAM(ATECtrl, band_idx, RF_Power, RFPower); + + return TRUE; +} + +INT32 SetATEDigitalPower(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Digital_Power = 0; + UINT32 band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Power0 = %s\n", __FUNCTION__, Arg)); + + Digital_Power = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Digital_Power = %d, band_idx = %d \n", + __FUNCTION__, Digital_Power, band_idx)); + + TESTMODE_SET_PARAM(ATECtrl, band_idx, Digital_Power, Digital_Power); + + return TRUE; +} + +INT32 SetATEDCOffset_I(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 DCOffset_I = 0; + UINT32 band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: DCOffset_I = %s\n", __FUNCTION__, Arg)); + + DCOffset_I = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: DCOffset_I = %d, band_idx = %d \n", + __FUNCTION__, DCOffset_I, band_idx)); + + TESTMODE_SET_PARAM(ATECtrl, band_idx, DcOffset_I, DCOffset_I); + + return TRUE; +} + +INT32 SetATEDCOffset_Q(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 DCOffset_Q = 0; + UINT32 band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: DCOffset_Q = %s\n", __FUNCTION__, Arg)); + + DCOffset_Q = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: DCOffset_Q = %d, band_idx = %d \n", + __FUNCTION__, DCOffset_Q, band_idx)); + + TESTMODE_SET_PARAM(ATECtrl, band_idx, DcOffset_Q, DCOffset_Q); + + return TRUE; +} + +INT32 SetATETxPower0(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + ATE_TXPOWER TxPower; + CHAR Power; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Power0 = %s\n", __func__, Arg)); + Power = simple_strtol(Arg, 0, 10); + ATECtrl->TxPower0 = Power; + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = Power; + TxPower.Dbdc_idx = ATECtrl->control_band_idx; + Ret = ATEOp->SetTxPower0(pAd, TxPower); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxPower1(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + ATE_TXPOWER TxPower; + CHAR Power; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Power1 = %s\n", __func__, Arg)); + Power = simple_strtol(Arg, 0, 10); + ATECtrl->TxPower1 = Power; + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = Power; + TxPower.Dbdc_idx = ATECtrl->control_band_idx; + Ret = ATEOp->SetTxPower1(pAd, TxPower); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxPower2(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + ATE_TXPOWER TxPower; + CHAR Power; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Power2 = %s\n", __func__, Arg)); + Power = simple_strtol(Arg, 0, 10); + ATECtrl->TxPower2 = Power; + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = Power; + TxPower.Dbdc_idx = ATECtrl->control_band_idx; + Ret = ATEOp->SetTxPower2(pAd, TxPower); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxPower3(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + ATE_TXPOWER TxPower; + CHAR Power; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Power3 = %s\n", __func__, Arg)); + Power = simple_strtol(Arg, 0, 10); + ATECtrl->TxPower3 = Power; + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = Power; + TxPower.Dbdc_idx = ATECtrl->control_band_idx; + Ret = ATEOp->SetTxPower3(pAd, TxPower); + + if (!Ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATEForceTxPower(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT8 ParamIdx; + CHAR *value = 0; + INT_8 cTxPower = 0; + UINT8 ucPhyMode = 0; + UINT8 ucTxRate = 0; + UINT8 ucBW = 0; + + /* Sanity check for input parameter */ + if (!Arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: No Parameters !! \n", __FUNCTION__)); + goto err1; + } + + /* Sanity check for input parameter format */ + if (strlen(Arg) != 11) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Wrong Parameter Format !!\n", __FUNCTION__)); + goto err1; + } + + /* Parsing input parameter */ + for (ParamIdx = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":"), ParamIdx++) { + switch (ParamIdx) { + case 0: + ucPhyMode = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + case 1: + ucTxRate = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + case 2: + ucBW = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + case 3: + cTxPower = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Set Too Much Parameters !!\n", __func__)); + goto err1; + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Band(%d), TxMode(%d), MCS(%d), BW(%d), TxPower(%d)\n", + __func__, control_band_idx, ucPhyMode, ucTxRate, ucBW, cTxPower)); + + /* Command Handler for Force Power Control */ + Ret = ATEOp->SetTxForceTxPower(pAd, cTxPower, ucPhyMode, ucTxRate, ucBW); + + if (!Ret) + return TRUE; + else + return FALSE; + err1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN "Please input parameter via format \"Phymode:TxRate:BW:TxPower\"\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN "Phymode:\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN " (2-digit) 0: CCK, 1: OFDM, 2: HT-MIXED, 3: HT-GREEN, 4: VHT\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN "TxRate:\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN " (2-digit) CCK: 00~03, OFDM: 00~07, HT-MIXED: 00~07, HT-GREEN: 00~07, VHT: 00~09\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN "BW:\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN " (2-digit) 0: BW20, 1: BW40, 2: BW80, 3:BW160\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN "TxPower:\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KGRN " (2-digit) absolute Tx power (unit: 0.5dB)\n" KNRM)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (KRED "Ex: iwpriv ra0 set ATEFORCETXPOWER=02:00:00:16\n" KNRM)); + return FALSE; + +} + +INT32 SetATETxPowerEvaluation(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxAntenna(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 Ant = 1; + const INT idx_num = 2; + UINT32 param[idx_num]; + UINT8 loop_index = 0; + CHAR *value; +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + UINT32 mode = 0; +#endif + + /* Sanity check for input parameter */ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + goto err0; + } + + /* TX path setting */ + if (!strchr(Arg, ':')) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Ant = %scontrol_band_idx = %d\n", + __func__, Arg, control_band_idx)); + Ant = simple_strtol(Arg, 0, 10); + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Mode:Value = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + for (loop_index = 0; loop_index < idx_num; loop_index++) + param[loop_index] = 0; + + for (loop_index = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":")) { + if (loop_index == idx_num) + break; + + param[loop_index] = simple_strtol(value, 0, 10); + loop_index++; + } + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + mode = param[0]; + + if (mode == ANT_MODE_SPE_IDX) + Ant = param[1] | ATE_ANT_USER_SEL; + else + Ant = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + +#else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No need to set Spe_idx.\n", __func__)); + goto err0; +#endif /* defined(MT7615) || defined(MT7622) */ + } + + Ret = ATEOp->SetTxAntenna(pAd, Ant); + + if (!Ret) + return TRUE; + +err0: + return FALSE; +} + + +INT32 SetATERxAntenna(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + CHAR Ant; + + /* Sanity check for input parameter */ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + goto err0; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Ant = %s\n", __func__, Arg)); + Ant = simple_strtol(Arg, 0, 10); + Ret = ATEOp->SetRxAntenna(pAd, Ant); + + if (!Ret) + return TRUE; + +err0: + return FALSE; +} + + +INT32 Default_Set_ATE_TX_FREQ_OFFSET_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxFreqOffset(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + UINT32 FreqOffset; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: FreqOffset = %s\n", __func__, Arg)); + FreqOffset = simple_strtol(Arg, 0, 10); + Ret = ATEOp->SetTxFreqOffset(pAd, FreqOffset); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 Default_Set_ATE_TX_BW_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxLength(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 TxLength; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: TxLength = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + TxLength = simple_strtol(Arg, 0, 10); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, TxLength, TxLength); + return TRUE; +} + + +INT32 SetATETxCount(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 TxCount = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: TxCount = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + TxCount = simple_strtol(Arg, 0, 10); + + if (TxCount == 0) + TxCount = 0xFFFFFFFF; + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, TxCount, TxCount); + return TRUE; +} + + +INT32 CheckMCSValid(PRTMP_ADAPTER pAd, UCHAR PhyMode, UCHAR Mcs) +{ + int Index; + PCHAR pRateTab = NULL; + + switch (PhyMode) { + case MODE_CCK: + pRateTab = CCKRateTable; + break; + + case MODE_OFDM: + pRateTab = OFDMRateTable; + break; + + case MODE_HTMIX: + case MODE_HTGREENFIELD: + pRateTab = HTMIXRateTable; + break; + + case MODE_VHT: + pRateTab = VHTRateTable; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Unrecognizable Tx Mode %d\n", __func__, PhyMode)); + return -1; + } + + Index = 0; + + while (pRateTab[Index] != -1) { + if (pRateTab[Index] == Mcs) + return 0; + + Index++; + } + + return -1; +} + + +INT32 SetATETxMcs(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR Mcs, PhyMode = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Mcs = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + PhyMode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PhyMode); + Mcs = simple_strtol(Arg, 0, 10); + Ret = CheckMCSValid(pAd, PhyMode, Mcs); + + if (Ret != -1) + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mcs, Mcs); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Out of range, refer to rate table.\n", __func__)); + goto err0; + } + + return TRUE; +err0: + return FALSE; +} + + +INT32 SetATEVhtNss(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR Nss = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Nss = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + Nss = simple_strtol(Arg, 0, 10); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Nss, Nss); + return TRUE; +} + + +INT32 SetATETxLdpc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR Ldpc; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Ldpc = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + Ldpc = simple_strtol(Arg, 0, 10); + + if (Ldpc > 1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Out of range (%d)\n", __func__, Ldpc)); + return FALSE; + } + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Ldpc, Ldpc); + return TRUE; +} + + +INT32 SetATETxStbc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR Stbc; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Stbc = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + Stbc = simple_strtol(Arg, 0, 10); + + if (Stbc > 1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Out of range (%d)\n", __func__, Stbc)); + return FALSE; + } + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Stbc, Stbc); + return TRUE; +} + + +INT32 SetATETxMode(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR PhyMode; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: TxMode = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + PhyMode = simple_strtol(Arg, 0, 10); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, PhyMode, PhyMode); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: TxMode = %x, control_band_idx:%u\n", + __func__, PhyMode, control_band_idx)); + return TRUE; +} + + +INT32 SetATETxGi(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR Sgi; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Sgi = %s, control_band_idx = %d\n", + __func__, Arg, control_band_idx)); + + Sgi = simple_strtol(Arg, 0, 10); + + if (Sgi > 1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : Out of range (%d)\n", __func__, Sgi)); + return FALSE; + } + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Sgi, Sgi); + return TRUE; +} + + +INT32 SetATERxFer(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETempSensor(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEReadRF(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + + Ret = ShowAllRF(pAd); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATELoadE2p(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + UINT32 Ret = 0; + RTMP_STRING *Src = EEPROM_BIN_FILE_NAME; + RTMP_OS_FD Srcf; + INT32 Retval; + USHORT *WriteEEPROM = NULL; + INT32 FileLength = 0; + UINT32 Value = (UINT32)simple_strtol(Arg, 0, 10); + RTMP_OS_FS_INFO OsFSInfo; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("===> %s (value=%d)\n\n", __func__, Value)); +#ifdef RTMP_RBUS_SUPPORT + + if (IS_RBUS_INF(pAd)) + Src = EEPROM_DEFAULT_FILE_PATH; + +#endif /* RTMP_RBUS_SUPPORT */ + Ret = os_alloc_mem(pAd, (PUCHAR *)&WriteEEPROM, EEPROM_SIZE); /* TODO verify */ + + if (Ret == NDIS_STATUS_FAILURE) + return Ret; + + 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)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Error opening file %s\n", __func__, Src)); + break; + } + + /* read the firmware from the file *.bin */ + FileLength = RtmpOSFileRead(Srcf, (RTMP_STRING *)WriteEEPROM, EEPROM_SIZE); + + if (FileLength != EEPROM_SIZE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error file length (=%d) in e2p.bin\n", + __func__, FileLength)); + break; + } + + /* write the content of .bin file to EEPROM */ +#if defined(RTMP_MAC_PCI) && defined(RTMP_PCI_SUPPORT) + + if (IS_PCI_INF(pAd)) { + UINT16 Index = 0; + UINT16 Value = 0; + INT32 E2pSize = 512;/* == 0x200 for PCI interface */ + UINT16 TempData = 0; + + for (Index = 0 ; Index < (E2pSize >> 1); Index++) { + /* "value" is especially for some compilers... */ + TempData = le2cpu16(WriteEEPROM[Index]); + Value = TempData; + RT28xx_EEPROM_WRITE16(pAd, (Index << 1), Value); + } + } + +#else + /* rt_ee_write_all(pAd, WriteEEPROM); */ +#endif /* defined(RTMP_MAC_PCI) && defined(RTMP_PCI_SUPPORT) */ + Ret = TRUE; + break; + } while (TRUE); + + /* close firmware file */ + if (IS_FILE_OPEN_ERR(Srcf)) + ; + else { + Retval = RtmpOSFileClose(Srcf); + + if (Retval) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("--> Error %d closing %s\n", -Retval, Src)); + } + } + + /* restore */ + RtmpOSFSInfoChange(&OsFSInfo, FALSE); + } + + os_free_mem(WriteEEPROM); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("<=== %s (Ret=%d)\n", __func__, Ret)); + return Ret; +} + + +#ifdef RTMP_EFUSE_SUPPORT +INT32 SetATELoadE2pFromBuf(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + BOOLEAN Ret = FALSE; + UINT32 Value = (UINT32)simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("===> %s (Value=%d)\n\n", __func__, Value)); + + if (Value > 0) { +#if defined(RTMP_MAC_PCI) && defined(RTMP_PCI_SUPPORT) + + if (IS_PCI_INF(pAd)) { + UINT16 Index = 0; + UINT16 Value = 0; + INT32 E2PSize = 512;/* == 0x200 for PCI interface */ + UINT16 TempData = 0; + + for (Index = 0; Index < (E2PSize >> 1); Index++) { + /* "value" is especially for some compilers... */ + TempData = le2cpu16(pAd->EEPROMImage[Index]); + Value = TempData; + RT28xx_EEPROM_WRITE16(pAd, (Index << 1), Value); + } + } + +#else + /* rt_ee_write_all(pAd, pAd->EEPROMImage); */ +#endif /* defined(RTMP_MAC_PCI) && defined(RTMP_PCI_SUPPORT) */ + Ret = TRUE; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("<=== %s (Ret=%d)\n", __func__, Ret)); + return Ret; +} +#endif /* RTMP_EFUSE_SUPPORT */ + + +INT32 SetATEReadE2p(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 ret; + UINT16 *Buffer = NULL; + UINT16 size = EEPROM_SIZE; + int i; + +#if defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT) + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + size = get_dev_eeprom_size(pAd); +#endif + + ret = os_alloc_mem(pAd, (PUCHAR *)&Buffer, size); + + if (ret == NDIS_STATUS_FAILURE) + return ret; + + EEReadAll(pAd, (UINT16 *)Buffer, size); + + for (i = 0; i < (size >> 1); i++) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%4.4x ", *Buffer)); + + if (((i + 1) % 16) == 0) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + Buffer++; + } + + os_free_mem(Buffer); + return TRUE; +} + + +INT32 SetATEAutoAlc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEIpg(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 ret = 0; + UINT32 value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: IPG = %s\n", __func__, Arg)); + + value = simple_strtol(Arg, 0, 10); + ATECtrl->ipg_param.ipg = value; + ret = ATEOp->SetIPG(pAd); + + if (!ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEPayload(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + RTMP_STRING *Value; + + Value = Arg; + + /* only one octet acceptable */ + if (strlen(Value) != 2) + return FALSE; + + AtoH(Value, &(ATECtrl->Payload), 1); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Set_ATE_Payload_Proc (repeated pattern = 0x%2x)\n", ATECtrl->Payload)); + return TRUE; +} + + +INT32 SetATEFixedPayload(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 Value; + + /* only one octet acceptable */ + Value = simple_strtol(Arg, 0, 10); + + if (Value == 0) + ATECtrl->FixedPayload = 2; + else + ATECtrl->FixedPayload = 1; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: (Fixed Payload = %u)\n", + __func__, ATECtrl->FixedPayload)); + return TRUE; +} + + +INT32 SetATETtr(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEShow(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; +#ifdef DBDC_MODE + struct _BAND_INFO *Info = NULL; +#endif /* DBDC_MODE */ + RTMP_STRING *Mode_String = NULL; + RTMP_STRING *TxMode_String = NULL; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT8 loop_index; + INT status = TRUE; + CHAR *value = 0; + UCHAR ExtendInfo = 0; + + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Configure Input Parameter */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + + /* sanity check for input parameter*/ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Please use parameter 0 for Summary INFO, 1 for Detail INFO!!\n", __func__)); + return FALSE; + } + + /* Parsing input parameter */ + for (loop_index = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":"), loop_index++) { + switch (loop_index) { + case 0: + ExtendInfo = simple_strtol(value, 0, 10); + break; + + default: { + status = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Set wrong parameters\n", __func__)); + break; + } + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ExtendInfo = %d\n", __func__, ExtendInfo)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx = %d !!!!!\n", + __func__, control_band_idx)); + + /* initialize pointer to structure of parameters of Band1 */ + if (control_band_idx == 0) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ATE Mode = 0x%x !!!!!\n", __func__, ATECtrl->Mode)); + } +#ifdef DBDC_MODE + else { + Info = &(ATECtrl->band_ext[0]); + + if (Info != NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ATE Mode = 0x%x !!!!!\n", __func__, Info->Mode)); + } + } + +#endif /* DBDC_MODE */ + + /* check the ATE mode */ + if (control_band_idx == 0) { + switch (ATECtrl->Mode) { + case (fATE_IDLE): + Mode_String = "ATESTART"; + break; + + case (fATE_EXIT): + Mode_String = "ATESTOP"; + break; + + 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"; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ERROR! Unknown ATE mode!\n")); + break; + } + } + } +#ifdef DBDC_MODE + else { + if (Info != NULL) { + switch (Info->Mode) { + case (fATE_IDLE): + Mode_String = "ATESTART"; + break; + + case (fATE_EXIT): + Mode_String = "ATESTOP"; + break; + + 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"; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ERROR! Unknown ATE mode!\n")); + break; + } + } + } + } + +#endif /* DBDC_MODE */ + + if (control_band_idx == 0) { + switch (ATECtrl->PhyMode) { + case MODE_CCK: + TxMode_String = "CCK"; + break; + + case MODE_OFDM: + TxMode_String = "OFDM"; + break; + + case MODE_HTMIX: + TxMode_String = "HT-Mix"; + break; + + case MODE_HTGREENFIELD: + TxMode_String = "HT-GreenField"; + break; + + case MODE_VHT: + TxMode_String = "VHT"; + break; + + default: { + TxMode_String = "Unknown phy mode"; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ERROR! Unknown phy mode!\n")); + break; + } + } + } +#ifdef DBDC_MODE + else { + if (Info != NULL) { + switch (Info->PhyMode) { + case MODE_CCK: + TxMode_String = "CCK"; + break; + + case MODE_OFDM: + TxMode_String = "OFDM"; + break; + + case MODE_HTMIX: + TxMode_String = "HT-Mix"; + break; + + case MODE_HTGREENFIELD: + TxMode_String = "HT-GreenField"; + break; + + case MODE_VHT: + TxMode_String = "VHT"; + break; + + default: { + TxMode_String = "Unknown phy mode"; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ERROR! Unknown phy mode!\n")); + break; + } + } + } + } + +#endif /* DBDC_MODE */ + /* Generic information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tBand %d Generic INFO\n", control_band_idx)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + + if (control_band_idx == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATE Mode = %s\n", Mode_String)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxAntennaSel = 0x%x\n", ATECtrl->TxAntennaSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RxAntennaSel = 0x%x\n", ATECtrl->RxAntennaSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BBPCurrentBW = %u\n", ATECtrl->BW)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("GI = %u\n", ATECtrl->Sgi)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MCS = %u\n", ATECtrl->Mcs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxMode = %s\n", TxMode_String)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n", + ATECtrl->Addr2[0], ATECtrl->Addr2[1], ATECtrl->Addr2[2], ATECtrl->Addr2[3], ATECtrl->Addr2[4], ATECtrl->Addr2[5])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n", + ATECtrl->Addr3[0], ATECtrl->Addr3[1], ATECtrl->Addr3[2], ATECtrl->Addr3[3], ATECtrl->Addr3[4], ATECtrl->Addr3[5])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Channel = %u\n", ATECtrl->Channel)); +#ifdef DOT11_VHT_AC + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Channel_2nd = %u\n", ATECtrl->Channel_2nd)); +#endif /* DOT11_VHT_AC */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Ch_Band = %d\n", ATECtrl->Ch_Band)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Control Channel = %d\n", ATECtrl->ControlChl)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxLength = %u\n", ATECtrl->TxLength)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxCount = %u\n", ATECtrl->TxCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("HW Length = %d\n", ATECtrl->HLen)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Payload Length = %d\n", ATECtrl->pl_len)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("IPG = %dus\n", ATECtrl->ipg_param.ipg)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Duty Cycle = %d%%\n", ATECtrl->duty_cycle)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Pkt Tx Time = %dus\n", ATECtrl->tx_time_param.pkt_tx_time)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Payload Pattern = 0x%02x\n", ATECtrl->Payload)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RFFreqOffset = %u\n", ATECtrl->RFFreqOffset)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SKB Allocate = %d\n", ATECtrl->is_alloc_skb)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxStatus = %d\n", ATECtrl->TxStatus)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("wdev_idx = %d\n", ATECtrl->wdev_idx)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("QID = %d\n", ATECtrl->QID)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PriSel = %d\n", ATECtrl->PriSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Nss = %d\n", ATECtrl->Nss)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PerPktBW = %d\n", ATECtrl->PerPktBW)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PrimaryBWSel = %d\n", ATECtrl->PrimaryBWSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("STBC = %d\n", ATECtrl->Stbc)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LDPC = %d\n", ATECtrl->Ldpc)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Preamble = %d\n", ATECtrl->Preamble)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("FixedPayload = %d\n", ATECtrl->FixedPayload)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Thermal Value = %d\n", ATECtrl->thermal_val)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PrimaryBWSel = %d\n", ATECtrl->PrimaryBWSel)); + } + +#ifdef DBDC_MODE + else { + if (Info != NULL) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATE Mode = %s\n", Mode_String)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxAntennaSel = 0x%x\n", Info->TxAntennaSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RxAntennaSel = 0x%x\n", Info->RxAntennaSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BBPCurrentBW = %u\n", Info->BW)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("GI = %u\n", Info->Sgi)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MCS = %u\n", Info->Mcs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxMode = %s\n", TxMode_String)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n", + Info->Addr1[0], Info->Addr1[1], Info->Addr1[2], Info->Addr1[3], Info->Addr1[4], Info->Addr1[5])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n", + Info->Addr2[0], Info->Addr2[1], Info->Addr2[2], Info->Addr2[3], Info->Addr2[4], Info->Addr2[5])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n", + Info->Addr3[0], Info->Addr3[1], Info->Addr3[2], Info->Addr3[3], Info->Addr3[4], Info->Addr3[5])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Channel = %u\n", Info->Channel)); +#ifdef DOT11_VHT_AC + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Channel_2nd = %u\n", Info->Channel_2nd)); +#endif /* DOT11_VHT_AC */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Ch_Band = %d\n", Info->Ch_Band)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Control Channel = %d\n", Info->ControlChl)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxLength = %u\n", Info->TxLength)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxCount = %u\n", Info->TxCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("HW Length = %d\n", Info->HLen)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Payload Length = %d\n", Info->pl_len)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("IPG = %dus\n", Info->ipg_param.ipg)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Duty Cycle = %d%%\n", Info->duty_cycle)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Pkt Tx Time = %dus\n", Info->tx_time_param.pkt_tx_time)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RFFreqOffset = %u\n", Info->RFFreqOffset)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SKB Allocate = %d\n", Info->is_alloc_skb)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxStatus = %d\n", Info->TxStatus)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("wdev_idx = %d\n", Info->wdev_idx)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("QID = %d\n", Info->QID)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PriSel = %d\n", Info->PriSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Nss = %d\n", Info->Nss)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PerPktBW = %d\n", Info->PerPktBW)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PrimaryBWSel = %d\n", Info->PrimaryBWSel)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("STBC = %d\n", Info->Stbc)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LDPC = %d\n", Info->Ldpc)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Preamble = %d\n", Info->Preamble)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("FixedPayload = %d\n", Info->FixedPayload)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Thermal Value = %d\n", Info->thermal_val)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PrimaryBWSel = %d\n", Info->PrimaryBWSel)); + } + } +#endif /* DBDC_MODE */ + + if (ExtendInfo) { + if (control_band_idx == 0) { + /* TX information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tTX INFO\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Sequence = %d\n", ATECtrl->seq)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxDoneCount = %d\n", ATECtrl->TxDoneCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxedCount = %d\n", ATECtrl->TxedCount)); + /* RX information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tRX INFO\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RxTotalCnt = %d\n", ATECtrl->rx_stat.RxTotalCnt[control_band_idx])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RxMacMdrdyCount = %d\n", ATECtrl->rx_stat.RxMacMdrdyCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RxMacFCSErrCount = %d\n", ATECtrl->rx_stat.RxMacFCSErrCount)); + } +#ifdef DBDC_MODE + else { + if (Info != NULL) { + /* TX information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tTX INFO\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Sequence = %d\n", Info->seq)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxDoneCount = %d\n", Info->TxDoneCount)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxedCount = %d\n", Info->TxedCount)); + /* RX information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tRX INFO\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RxTotalCnt = %d\n", ATECtrl->rx_stat.RxTotalCnt[control_band_idx])); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RxMacMdrdyCount = %d\n", ATECtrl->rx_stat.RxMacMdrdyCount_band1)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RxMacFCSErrCount = %d\n", ATECtrl->rx_stat.RxMacFCSErrCount_band1)); + } + } +#endif /* DBDC_MODE */ + /* TX power information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tTx Power INFO\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxPower0 = %d\n", ATECtrl->TxPower0)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxPower1 = %d\n", ATECtrl->TxPower1)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxPower2 = %d\n", ATECtrl->TxPower2)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TxPower3 = %d\n", ATECtrl->TxPower3)); +#ifdef ATE_TXTHREAD + /* TX thread information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tATE TX Thread INFO\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Current_Init_Thread = %d\n", ATECtrl->current_init_thread)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Dequeue Count = %d\n", ATECtrl->deq_cnt)); +#endif /* ATE_TXTHREAD */ +#ifdef TXBF_SUPPORT + /* BF related information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tBF Band %d INFO\n", control_band_idx)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("fgEBfEverEnabled = %d\n", ATECtrl->fgEBfEverEnabled)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TXBF INFO Length = %d\n", ATECtrl->txbf_info_len)); + + if (control_band_idx == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ETXBF = %d\n", ATECtrl->eTxBf)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ITXBF = %d\n", ATECtrl->iTxBf)); + } + +#ifdef DBDC_MODE + else { + if (Info != NULL) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ETXBF = %d\n", Info->eTxBf)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ITXBF = %d\n", Info->iTxBf)); + } + } + +#endif /* DBDC_MODE */ +#endif /* TXBF_SUPPORT */ + /* MU related information */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tMU INFO\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MU Enable = %d\n", ATECtrl->mu_enable)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MU Users = %d\n", ATECtrl->mu_usrs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("wcid_ref = %d\n", ATECtrl->wcid_ref)); + } + + return TRUE; +} + + +INT32 set_ate_duty_cycle(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + UINT32 duty_cycle = 0; + + /* Sanity check for input parameter */ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + goto err0; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Duty cycle=%s%%\n", __func__, Arg)); + + duty_cycle = simple_strtol(Arg, 0, 10); + + if ((duty_cycle < 0) || (duty_cycle > 100)) + goto err1; + + Ret = ATEOp->SetDutyCycle(pAd, duty_cycle); + + if (!Ret) + return TRUE; + +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Unexpected input!!\n", __func__)); +err0: + return FALSE; +} + + +INT32 set_ate_pkt_tx_time(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + UINT32 pkt_tx_time = 0; + + /* Sanity check for input parameter */ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + goto err0; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Pkt Tx time=%sus\n", __func__, Arg)); + + pkt_tx_time = simple_strtol(Arg, 0, 10); + + if (pkt_tx_time < 0) + goto err1; + + Ret = ATEOp->SetPktTxTime(pAd, pkt_tx_time); + + if (!Ret) + return TRUE; + +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Unexpected input!!\n", __func__)); +err0: + return FALSE; +} + + +INT32 set_ate_control_band_idx(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 ret = 0; + UCHAR control_band_idx; + + /* Sanity check for input parameter */ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + goto err; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Control band_idx=%s\n", __func__, Arg)); + + control_band_idx = simple_strtol(Arg, 0, 10); + ATECtrl->control_band_idx = control_band_idx; + + if (!ret) + return TRUE; + +err: + return FALSE; +} + + +#if defined(TXBF_SUPPORT) && defined(MT_MAC) +INT SetATEApplyStaToMacTblEntry(RTMP_ADAPTER *pAd) +{ + P_MANUAL_CONN pManual_cfg = &pAd->AteManualConnInfo; + UCHAR WCID = pManual_cfg->wtbl_idx; + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[WCID]; + + /* Currently, for MU-MIMO, we only care the VHT/HT Cap Info and VHT MCS set */ + os_move_mem(&pEntry->vht_cap_ie.vht_cap, &pManual_cfg->vht_cap_info, sizeof(pEntry->vht_cap_ie.vht_cap)); + os_move_mem(&pEntry->HTCapability.HtCapInfo, &pManual_cfg->ht_cap_info, sizeof(pEntry->HTCapability.HtCapInfo)); + os_move_mem(&pEntry->vht_cap_ie.mcs_set, &pManual_cfg->vht_mcs_set, sizeof(pEntry->vht_cap_ie.mcs_set)); + return TRUE; +} + + +INT SetATEApplyStaToAsic(RTMP_ADAPTER *pAd) +{ + P_MANUAL_CONN manual_cfg = &pAd->AteManualConnInfo; + UCHAR WCID = manual_cfg->wtbl_idx; + UCHAR *pAddr = &manual_cfg->peer_mac[0]; + MT_WCID_TABLE_INFO_T WtblInfo; + /* MAC_TABLE_ENTRY *mac_entry = NULL; */ +#ifdef CONFIG_WTBL_TLV_MODE +#else + struct rtmp_mac_ctrl *wtbl_ctrl = &pAd->mac_ctrl; +#endif /*CONFIG_WTBL_TLV_MODE */ +#ifdef CONFIG_WTBL_TLV_MODE +#else + + if (wtbl_ctrl->wtbl_entry_cnt[0] > 0) + WCID = (wtbl_ctrl->wtbl_entry_cnt[0] > WCID ? WCID : MCAST_WCID_TO_REMOVE); + else { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: PSE not init yet!\n", __func__)); + return FALSE; + } + +#endif /* CONFIG_WTBL_TLV_MODE */ + os_zero_mem(&WtblInfo, sizeof(MT_WCID_TABLE_INFO_T)); + WtblInfo.Wcid = WCID; + os_move_mem(&WtblInfo.Addr[0], &pAddr[0], 6); + /* TODO: shiang-MT7615, risk here!!! */ + /* if (WCID < MAX_LEN_OF_MAC_TABLE) */ + /* mac_entry = &pAd->MacTab.Content[WCID]; */ + + if (WCID == MCAST_WCID_TO_REMOVE || WCID == MAX_LEN_OF_MAC_TABLE) { + WtblInfo.MacAddrIdx = 0xe; + WtblInfo.WcidType = MT_WCID_TYPE_BMCAST; + WtblInfo.CipherSuit = WTBL_CIPHER_NONE; + } else { + /* if (!mac_entry) { */ + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, */ + /* ("%s(): mac_entry is NULL!\n", __FUNCTION__)); */ + /* return; */ + /* } */ + if (pAd->AteManualConnInfo.peer_op_type == OPMODE_AP) + WtblInfo.WcidType = MT_WCID_TYPE_AP; + else + WtblInfo.WcidType = MT_WCID_TYPE_CLI; + + WtblInfo.MacAddrIdx = manual_cfg->ownmac_idx; /* mac_entry->wdev->OmacIdx; */ + /* WtblInfo.Aid = manual_cfg->wtbl_idx; //mac_entry->Aid; */ + WtblInfo.CipherSuit = WTBL_CIPHER_NONE; + /* if (CLIENT_STATUS_TEST_FLAG(mac_entry, fCLIENT_STATUS_WMM_CAPABLE)) */ + WtblInfo.SupportQoS = TRUE; + + if (WMODE_CAP_N(manual_cfg->peer_phy_mode)) { + WtblInfo.SupportHT = TRUE; + /* if (CLIENT_STATUS_TEST_FLAG(mac_entry, fCLIENT_STATUS_RDG_CAPABLE)) */ + { + WtblInfo.SupportRDG = TRUE; + } + WtblInfo.SmpsMode = 0; /* mac_entry->MmpsMode ; */ + WtblInfo.MpduDensity = 0; /* mac_entry->MpduDensity; */ + WtblInfo.MaxRAmpduFactor = 3; /* mac_entry->MaxRAmpduFactor; */ +#ifdef DOT11_VHT_AC + + if (WMODE_CAP_AC(manual_cfg->peer_phy_mode)) + WtblInfo.SupportVHT = TRUE; + +#endif /* DOT11_VHT_AC */ + } + } + + WtblInfo.Aid = manual_cfg->aid; + WtblInfo.PfmuId = manual_cfg->pfmuId; + WtblInfo.spe_idx = manual_cfg->spe_idx; + /* + * WtblInfo.rca2 = manual_cfg->rca2; + * WtblInfo.rv = manual_cfg->rv; + */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Update WTBL table, WCID=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x, WtblInfo.MacAddrIdx=%d\n", + __func__, WCID, PRINT_MAC(pAddr), WtblInfo.MacAddrIdx)); + MtAsicUpdateRxWCIDTable(pAd, WtblInfo); +#ifdef MANUAL_MU + + if (WMODE_CAP_N(manual_cfg->peer_phy_mode)) { + MT_BA_CTRL_T BaCtrl; + INT tid; + + os_zero_mem(&BaCtrl, sizeof(MT_BA_CTRL_T)); + BaCtrl.BaSessionType = BA_SESSION_ORI; + BaCtrl.BaWinSize = 64; + BaCtrl.isAdd = TRUE; + BaCtrl.Sn = 0; + BaCtrl.Wcid = WtblInfo.Wcid; + BaCtrl.band_idx = 0; + os_move_mem(&BaCtrl.PeerAddr[0], &WtblInfo.Addr[0], MAC_ADDR_LEN); + + for (tid = 0; tid < 4; tid++) { + BaCtrl.Tid = 0; + MtAsicUpdateBASession(pAd, BaCtrl); + } + } + + dump_wtbl_info(pAd, WtblInfo.Wcid); +#endif /* MANUAL_MU */ + return TRUE; +} + + +static INT ATEMacStr2Hex(RTMP_STRING *arg, UINT8 *mac) +{ + INT i; + RTMP_STRING *token, sepValue[] = ":"; + + if (arg == NULL) + return FALSE; + + /* Mac address acceptable format 01:02:03:04:05:06 length 17*/ + if (strlen(arg) < 17) + return FALSE; + + for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++) { + if (i > 6) + break; + + if ((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token + 1)))) + return FALSE; + + AtoH(token, (&mac[i]), 1); + } + + if (i != 6) + return FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\n%02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); + return TRUE; +} + + +INT ATEManualParsingParam(RTMP_ADAPTER *pAd, RTMP_STRING *type, RTMP_STRING *val) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + UINT8 mac[MAC_ADDR_LEN] = {0}; + INT op_type = 0; + INT wtbl_idx = 1; + INT own_mac_idx = 0; + INT phy_mode = 0; + INT bw = BW_20; + INT nss = 1; + INT maxrate_mode = MODE_CCK; + INT maxrate_mcs = 0; + INT pfmuId = 0, speIdx = 24; + INT aid = 0; + UINT8 rca2 = 0, rv = 0; + UINT8 fgIsSuBFee = 0; + UINT8 fgIsMuBFee = 0; + UINT8 fgIsSGIFor20 = 0; + UINT8 fgIsSGIFor40 = 0; + UINT8 fgIsSGIFor80 = 0; + UINT8 fgIsSGIFor160 = 0; + UINT8 bFeeNsts = 0; + UINT8 mcsSupport = 0; + + if ((!type) || (!val)) + return FALSE; + + if (!wdev) + return FALSE; + + /* mac:xx:xx:xx:xx:xx:xx */ + if (strcmp("mac", type) == 0) { + if (ATEMacStr2Hex(val, &mac[0]) == FALSE) { + NdisZeroMemory(&mac[0], MAC_ADDR_LEN); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s Invalid MAC address(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid MAC address(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + NdisMoveMemory(&pAd->AteManualConnInfo.peer_mac[0], mac, MAC_ADDR_LEN); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); + } + + /* type:ap/sta */ + if (strcmp("type", type) == 0) { + if (strcmp(val, "ap") == 0) + op_type = OPMODE_AP; + else if (strcmp(val, "sta") == 0) + op_type = OPMODE_STA; + else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid type(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.peer_op_type = op_type; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: TYPE=%d\n", __func__, op_type)); + } + + /* wtbl:1~127 */ + if (strcmp("wtbl", type) == 0) { + if (strlen(val)) { + wtbl_idx = simple_strtol(val, 0, 10); + + if (wtbl_idx <= 0 || wtbl_idx > 127) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid wtbl idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + wtbl_idx = 1; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid wtbl idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.wtbl_idx = wtbl_idx; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: WTBL_IDX=%d\n", __func__, wtbl_idx)); + } + + /* ownmac:0~4, 0x10~0x1f */ + if (strcmp("ownmac", type) == 0) { + if (strlen(val)) { + own_mac_idx = simple_strtol(val, 0, 10); + + if (own_mac_idx < 0 || + (((own_mac_idx - 0) > 4) ? ((own_mac_idx - 0x10) > 0xf):FALSE)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid OwnMac idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + own_mac_idx = 1; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid wtbl idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.ownmac_idx = own_mac_idx; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: OWN_MAC_IDX=%d\n", __func__, own_mac_idx)); + } + + /* pfmuId: */ + if (strcmp("pfmuId", type) == 0) { + if (strlen(val)) { + pfmuId = simple_strtol(val, 0, 10); + + if (!(pfmuId >= 0x00 || pfmuId <= 0x3f)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid PFMU idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + pfmuId = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid PFMU idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.pfmuId = pfmuId; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: PFMU_IDX=%d\n", __func__, pfmuId)); + } + + /* aid: */ + if (strcmp("aid", type) == 0) { + if (strlen(val)) { + aid = simple_strtol(val, 0, 10); + + if (!(aid >= 0x00 || aid <= 2007)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid aid(%s), use default\n", + __func__, (val == NULL ? "" : val))); + aid = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid aid(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.aid = aid; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: AID =%d\n", __func__, aid)); + } + + /* spe-idx: */ + if (strcmp("speIdx", type) == 0) { + if (strlen(val)) { + speIdx = simple_strtol(val, 0, 10); + + if (!(speIdx >= 0 || speIdx <= 30)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid SPE idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + speIdx = 24; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid SPE idx(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.spe_idx = speIdx; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: SPE_IDX=%d\n", __func__, speIdx)); + } + + if (strcmp("mubfee", type) == 0) { + if (strlen(val)) { + fgIsMuBFee = simple_strtol(val, 0, 10); + + if (!(fgIsMuBFee == 0 || fgIsMuBFee == 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid mubfee(%s), use default\n", + __func__, (val == NULL ? "" : val))); + fgIsMuBFee = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid mubfee(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + if (fgIsMuBFee) + pAd->AteManualConnInfo.vht_cap_info.bfee_cap_mu = fgIsMuBFee; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: mubfee =%d\n", __func__, fgIsMuBFee)); + } + + if (strcmp("sgi160", type) == 0) { + if (strlen(val)) { + fgIsSGIFor160 = simple_strtol(val, 0, 10); + + if (!(fgIsSGIFor160 == 0 || fgIsSGIFor160 == 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi160(%s), use default\n", + __func__, (val == NULL ? "" : val))); + fgIsSGIFor160 = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi160(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + if (fgIsSGIFor160) + pAd->AteManualConnInfo.vht_cap_info.sgi_160M = fgIsSGIFor160; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: sgi160 =%d\n", __func__, fgIsSGIFor160)); + } + + if (strcmp("sgi80", type) == 0) { + if (strlen(val)) { + fgIsSGIFor80 = simple_strtol(val, 0, 10); + + if (!(fgIsSGIFor80 == 0 || fgIsSGIFor80 == 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi80(%s), use default\n", + __func__, (val == NULL ? "" : val))); + fgIsSGIFor80 = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi80(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + if (fgIsSGIFor80) + pAd->AteManualConnInfo.vht_cap_info.sgi_80M = fgIsSGIFor80; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: sgi80 =%d\n", __func__, fgIsSGIFor80)); + } + + if (strcmp("sgi40", type) == 0) { + if (strlen(val)) { + fgIsSGIFor40 = simple_strtol(val, 0, 10); + + if (!(fgIsSGIFor40 == 0 || fgIsSGIFor40 == 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi40(%s), use default\n", + __func__, (val == NULL ? "" : val))); + fgIsSGIFor40 = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi40(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + if (fgIsSGIFor40) + pAd->AteManualConnInfo.ht_cap_info.ShortGIfor40 = fgIsSGIFor40; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: sgi40 =%d\n", __func__, fgIsSGIFor40)); + } + + if (strcmp("sgi20", type) == 0) { + if (strlen(val)) { + fgIsSGIFor20 = simple_strtol(val, 0, 10); + + if (!(fgIsSGIFor20 == 0 || fgIsSGIFor20 == 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi20(%s), use default\n", + __func__, (val == NULL ? "" : val))); + fgIsSGIFor20 = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid sgi20(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + if (fgIsSGIFor20) + pAd->AteManualConnInfo.ht_cap_info.ShortGIfor20 = fgIsSGIFor20; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: sgi20 =%d\n", __func__, fgIsSGIFor20)); + } + + if (strcmp("rxmcsnss1", type) == 0) { + if (strlen(val)) { + mcsSupport = simple_strtol(val, 0, 10); + + if (!(mcsSupport >= 0 || mcsSupport <= 3)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss1(%s), use default\n", + __func__, (val == NULL ? "" : val))); + mcsSupport = 3; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss1(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.vht_mcs_set.rx_mcs_map.mcs_ss1 = mcsSupport; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: rxmcsnss1 =%d\n", __func__, mcsSupport)); + } + + if (strcmp("rxmcsnss2", type) == 0) { + if (strlen(val)) { + mcsSupport = simple_strtol(val, 0, 10); + + if (!(mcsSupport >= 0 || mcsSupport <= 3)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss2(%s), use default\n", + __func__, (val == NULL ? "" : val))); + mcsSupport = 3; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss2(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.vht_mcs_set.rx_mcs_map.mcs_ss2 = mcsSupport; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: rxmcsnss2 =%d\n", __func__, mcsSupport)); + } + + if (strcmp("rxmcsnss3", type) == 0) { + if (strlen(val)) { + mcsSupport = simple_strtol(val, 0, 10); + + if (!(mcsSupport >= 0 || mcsSupport <= 3)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss3(%s), use default\n", + __func__, (val == NULL ? "" : val))); + mcsSupport = 3; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss3(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.vht_mcs_set.rx_mcs_map.mcs_ss3 = mcsSupport; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: rxMcsNSS3 =%d\n", __func__, mcsSupport)); + } + + if (strcmp("rxmcsnss4", type) == 0) { + if (strlen(val)) { + mcsSupport = simple_strtol(val, 0, 10); + + if (!(mcsSupport >= 0 || mcsSupport <= 3)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss4(%s), use default\n", + __func__, (val == NULL ? "" : val))); + mcsSupport = 3; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid rxmcsnss4(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.vht_mcs_set.rx_mcs_map.mcs_ss4 = mcsSupport; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s rxmcsnss4 =%d\n", __func__, mcsSupport)); + } + + if (strcmp("subfee", type) == 0) { + if (strlen(val)) { + fgIsSuBFee = simple_strtol(val, 0, 10); + + if (!(fgIsSuBFee == 0 || fgIsSuBFee == 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid subfee(%s), use default\n", + __func__, (val == NULL ? "" : val))); + fgIsSuBFee = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid subfee(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + if (fgIsSuBFee) + pAd->AteManualConnInfo.vht_cap_info.bfee_cap_su = fgIsSuBFee; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: subfee =%d\n", __func__, fgIsSuBFee)); + } + + if (strcmp("bfeensts", type) == 0) { + if (strlen(val)) { + bFeeNsts = simple_strtol(val, 0, 10); + + if (!(bFeeNsts >= 0 || bFeeNsts < 4)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid bfeensts(%s), use default\n", + __func__, (val == NULL ? "" : val))); + bFeeNsts = 4; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid bfeensts(%s), use default\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.vht_cap_info.bfee_sts_cap = bFeeNsts; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: bfeensts =%d\n", __func__, bFeeNsts)); + } + + /* mode:a/bg/n/ac */ + if (strcmp("mode", type) == 0) { + RTMP_STRING *tok; + + tok = val; + + while (strlen(tok)) { + if (*tok == 'b') { + phy_mode |= WMODE_B; + tok++; + } else if (*tok == 'g') { + if ((*(tok + 1) == 'n') && (strlen(tok) >= 2)) { + phy_mode |= WMODE_GN; + tok += 2; + } else { + phy_mode |= WMODE_G; + tok += 1; + } + } else if (*tok == 'a') { + if ((*(tok + 1) == 'n') && (strlen(tok) >= 2)) { + phy_mode |= WMODE_AN; + tok += 2; + } else if ((*(tok + 1) == 'c') && (strlen(tok) >= 2)) { + phy_mode |= WMODE_AC; + tok += 2; + } else { + phy_mode |= WMODE_A; + tok += 1; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid phy_mode %c\n", __func__, *tok)); + tok++; + } + } + + pAd->AteManualConnInfo.peer_phy_mode = phy_mode; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: phy_mode=%s, convert to PhyMode= 0x%x\n", + __func__, (val == NULL ? "" : val), phy_mode)); + } + + /* bw:20/40/80/160 */ + if (strcmp("bw", type) == 0) { + if (strlen(val)) { + bw = simple_strtol(val, 0, 10); + + switch (bw) { + case 20: + bw = BW_20; + break; + + case 40: + bw = BW_40; + break; + + case 80: + bw = BW_80; + break; + + case 160: + bw = BW_160; + break; + + default: + bw = BW_20; + break; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid BW string(%s), use default!\n", + __func__, (val == NULL ? "" : val))); + } + + pAd->AteManualConnInfo.peer_bw = bw; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: BW=%d\n", __func__, bw)); + } + + if (strcmp("nss", type) == 0) { + if (strlen(val)) { + UINT8 ucTxPath = pAd->Antenna.field.TxPath; + + nss = simple_strtol(val, 0, 10); + +#ifdef DBDC_MODE + if (pAd->CommonCfg.dbdc_mode) { + UINT8 band_idx = HcGetBandByWdev(wdev); + + if (band_idx == DBDC_BAND0) + ucTxPath = pAd->dbdc_band0_tx_path; + else + ucTxPath = pAd->dbdc_band1_tx_path; + } +#endif + if (nss > ucTxPath) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid NSS string(%s), use default!\n", + __func__, (val == NULL ? "" : val))); + nss = 1; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid NSS setting, use default!\n", __func__)); + } + + pAd->AteManualConnInfo.peer_nss = nss; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: NSS=%d\n", __func__, nss)); + } + + /* rca2 = 0/1 */ + if (strcmp("rca2", type) == 0) { + if (strlen(val)) { + rca2 = simple_strtol(val, 0, 10); + + if (rca2 > 1) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid RCA2 string(%s), use default!\n", + __func__, (val == NULL ? "" : val))); + rca2 = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid RCA2 setting, use default!\n", __func__)); + } + + pAd->AteManualConnInfo.rca2 = rca2; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: RCA2=%d\n", __func__, rca2)); + } + + /* rv = 0/1 */ + if (strcmp("rv", type) == 0) { + if (strlen(val)) { + rv = simple_strtol(val, 0, 10); + + if (rv > 1) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid RV string(%s), use default!\n", + __func__, (val == NULL ? "" : val))); + rv = 0; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid RV setting, use default!\n", __func__)); + } + + pAd->AteManualConnInfo.rv = rv; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: RV=%d\n", __func__, rv)); + } + + /* maxrate:cck/ofdm/htmix/htgf/vht/_0~32 */ + if (strcmp("maxrate", type) == 0) { + RTMP_STRING *tok; + + if (strlen(val)) { + tok = rtstrchr(val, '_'); + + if (tok && strlen(tok) > 1) { + *tok = 0; + tok++; + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid maxmcs setting(%s), use default!\n", + __func__, (val == NULL ? "" : val))); + goto maxrate_final; + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: Invalid maxrate setting(%s), use default!\n", + __func__, (val == NULL ? "" : val))); + goto maxrate_final; + } + + if (strlen(tok)) { + maxrate_mcs = simple_strtol(tok, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%s: input MCS string(%s) =%d\n", + __func__, tok, maxrate_mcs)); + } + + if (strcmp(val, "cck") == 0) { + maxrate_mode = MODE_CCK; + + if (maxrate_mcs > 4) + maxrate_mcs = 3; + } else if (strcmp(val, "ofdm") == 0) { + maxrate_mode = MODE_OFDM; + + if (maxrate_mcs > 7) + maxrate_mcs = 7; + } else if (strcmp(val, "htmix") == 0) { + maxrate_mode = MODE_HTMIX; + + if (maxrate_mcs > 32) + maxrate_mcs = 32; + } else if (strcmp(val, "htgf") == 0) { + maxrate_mode = MODE_HTGREENFIELD; + + if (maxrate_mcs > 32) + maxrate_mcs = 32; + } else if (strcmp(val, "vht") == 0) { + maxrate_mode = MODE_VHT; + + if (maxrate_mcs > 9) + maxrate_mcs = 9; + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Invalid RateMode string(%s), use default!\n", + __func__, val)); + maxrate_mode = MODE_CCK; + maxrate_mcs = 0; + } + +maxrate_final: + pAd->AteManualConnInfo.peer_maxrate_mode = maxrate_mode; + pAd->AteManualConnInfo.peer_maxrate_mcs = maxrate_mcs; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: MAXRATE=>MODE=%d,MCS=%d\n", + __func__, maxrate_mode, maxrate_mcs)); + } + + return TRUE; +} + + +/* + * Assoc Parameters: + * mac:xx:xx:xx:xx:xx:xx-type:ap/sta-mode:a/b/g/gn/an/ac-bw:20/40/80/160-nss:1/2/3/4-pfmuId:xx-aid:xx-maxrate: + * + * @jeffrey: For MU-MIMO, we need to configure the HT/VHP cap info to emulate different STAs (# of STA >= 2) which + * supports different Tx and Rx dimension for early algorithm verification + */ +INT SetATEAssocProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + char sep_type = '-', sep_val = ':'; + RTMP_STRING *tok, *param_str, *param_type, *param_val; + INT stat; + char ucNsts; + UINT_32 rate[8]; + RA_PHY_CFG_T TxPhyCfg; + RTMP_STRING rate_str[64]; + + NdisZeroMemory(&pAd->AteManualConnInfo, sizeof(MANUAL_CONN)); + tok = arg; + + while (tok) { + if (strlen(tok)) { + param_str = tok; + tok = rtstrchr(tok, sep_type); + + if (tok) { + *tok = 0; + tok++; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: param_str=%s\n", __func__, param_str)); + + if (strlen(param_str)) { + param_type = param_str; + param_val = rtstrchr(param_str, sep_val); + + if (param_val) { + *param_val = 0; + param_val++; + } + + if (strlen(param_type) && param_val && strlen(param_val)) { + stat = ATEManualParsingParam(pAd, param_type, param_val); + + if (stat == FALSE) + goto err_dump_usage; + } + } + } else + break; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s:User manual configured peer STA info:\n", __func__)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tMAC=>0x%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->AteManualConnInfo.peer_mac))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tBAND=>%d\n", pAd->AteManualConnInfo.peer_band)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tOwnMacIdx=>%d\n", pAd->AteManualConnInfo.ownmac_idx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tWTBL_Idx=>%d\n", pAd->AteManualConnInfo.wtbl_idx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tOperationType=>%d\n", pAd->AteManualConnInfo.peer_op_type)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tPhyMode=>%d\n", pAd->AteManualConnInfo.peer_phy_mode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tBandWidth=>%d\n", pAd->AteManualConnInfo.peer_bw)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tNSS=>%d\n", pAd->AteManualConnInfo.peer_nss)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tPfmuId=>%d\n", pAd->AteManualConnInfo.pfmuId)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tAid=>%d\n", pAd->AteManualConnInfo.aid)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tSpe_idx=>%d\n", pAd->AteManualConnInfo.spe_idx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tMaxRate_Mode=>%d\n", pAd->AteManualConnInfo.peer_maxrate_mode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tMaxRate_MCS=>%d\n", pAd->AteManualConnInfo.peer_maxrate_mcs)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Now apply it to hardware!\n")); + /* This applied the manual config info into the mac table entry, including the HT/VHT cap, VHT MCS set */ + SetATEApplyStaToMacTblEntry(pAd); + /* Fixed rate configuration */ + NdisZeroMemory(&rate_str[0], sizeof(rate_str)); + sprintf(rate_str, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d", + pAd->AteManualConnInfo.wtbl_idx, + pAd->AteManualConnInfo.peer_maxrate_mode, + pAd->AteManualConnInfo.peer_bw, + pAd->AteManualConnInfo.peer_maxrate_mcs, + pAd->AteManualConnInfo.peer_nss, + 0, 0, 0, 0, 0); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tSet fixed RateInfo string as %s\n", rate_str)); + /* Set_Fixed_Rate_Proc(pAd, rate_str); */ + ucNsts = get_nsts_by_mcs(pAd->AteManualConnInfo.peer_maxrate_mode, + pAd->AteManualConnInfo.peer_maxrate_mcs, + FALSE, + pAd->AteManualConnInfo.peer_nss); + rate[0] = tx_rate_to_tmi_rate(pAd->AteManualConnInfo.peer_maxrate_mode, + pAd->AteManualConnInfo.peer_maxrate_mcs, + ucNsts, + FALSE, + 0); + rate[0] &= 0xfff; + rate[1] = rate[2] = rate[3] = rate[4] = rate[5] = rate[6] = rate[7] = rate[0]; + os_zero_mem(&TxPhyCfg, sizeof(TxPhyCfg)); + TxPhyCfg.BW = pAd->AteManualConnInfo.peer_bw; + TxPhyCfg.ShortGI = FALSE; + /* TxPhyCfg.ldpc = HT_LDPC | VHT_LDPC; */ + TxPhyCfg.ldpc = 0; + MtAsicTxCapAndRateTableUpdate(pAd, + pAd->AteManualConnInfo.wtbl_idx, + &TxPhyCfg, + rate, + FALSE); + /* WTBL configuration */ + SetATEApplyStaToAsic(pAd); + /* dump WTBL again */ + /* dump_wtbl_info(pAd, pAd->AteManualConnInfo.wtbl_idx); */ + return TRUE; +err_dump_usage: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Parameter Usage:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tiwpriv ra0 set assoc=[mac:hh:hh:hh:hh:hh:hh]-[wtbl:dd]-[ownmac:dd]-[type:xx]-[mode:mmm]-[bw:dd]-[nss:ss]-[maxrate:kkk_dd]\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\tmac: peer's mac address in hex format\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> mac:00:0c:43:12:34:56\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\twtbl: the WTBL entry index peer will occupied, in range 1~127\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> wtbl:1\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\townmac: the OwnMAC index we'll used to send frame to this peer, in range 0~4 or 16~31\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> ownmac:0\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\ttype: peer's operation type, is a ap or sta, allow input: \"ap\" or \"sta\"\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> type:ap\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\tmode: peer's phy operation mode, allow input: a/b/g/gn/an/ac\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> mode:aanac to indicate peer can support A/AN/AC mode\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\tbw: Peer's bandwidth capability, in range to 20/40/80/160\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> bw:40 indicate peer can support BW_40\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\tnss: Peer's capability for Spatial stream which can tx/rx, in range of 1~4 with restriction of Software/Hardware cap.\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> nss:2 indicate peer can support 2ss for both tx/rx\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\tmaxrate: Peer's data rate capability for tx/rx, separate as two parts and separate by '_' character\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\t\t kkk: phy modulation mode, allow input:'cck', 'ofdm', 'htmix', 'htgf', 'vht'\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\t\t dd:phy mcs rate, for CCK:0~3, OFDM:0~7, HT:0~32, VHT:0~9\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> maxrate:cck_1 indicate we only can transmit CCK and MCS 1(2Mbps) or lower MCS to peer\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> maxrate:ofdm_3 indicate we only can transmit OFDM and MCS 3(24Mbps) to peer\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t\t\tExample=> maxrate:htmix_3 indicate we only can transmit OFDM and MCS 3(24Mbps) to peer\n")); + return FALSE; +} + + + +INT SetATETxBfDutInitProc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + BOOLEAN fgBw160; + RTMP_STRING cmdStr[24]; + ULONG stTimeChk0, stTimeChk1; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + fgBw160 = simple_strtol(Arg, 0, 10); + ATECtrl->fgBw160 = fgBw160; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx = %d\n", __func__, control_band_idx)); + NdisGetSystemUpTime(&stTimeChk0); + /* Do ATESTART */ + SetATE(pAd, "ATESTART"); + /* set ATEDA=00:11:11:11:11:11 */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr1[0], 0x00); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr1[1], 0x11); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr1[2], 0x11); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr1[3], 0x11); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr1[4], 0x11); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr1[5], 0x11); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr1[0], 0x00); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr1[1], 0x11); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr1[2], 0x11); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr1[3], 0x11); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr1[4], 0x11); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr1[5], 0x11); + snprintf(cmdStr, sizeof(cmdStr), "00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x11, 0x11, 0x11, 0x11, 0x11); + SetATEDa(pAd, cmdStr); + /* set ATESA=00:22:22:22:22:22 */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr2[0], 0x00); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr2[1], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr2[2], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr2[3], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr2[4], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr2[5], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr2[0], 0x00); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr2[1], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr2[2], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr2[3], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr2[4], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr2[5], 0x22); + /* snprintf(cmdStr, sizeof(cmdStr), "00:%.2x:%.2x:%.2x:%.2x:%.2x", */ + /* 0x22, 0x22, 0x22, 0x22, 0x22); */ + /* SetATESa(pAd, cmdStr); */ + if (fgBw160) { + AsicDevInfoUpdate( + pAd, + 0x0, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } else { + if (control_band_idx == 0) { + AsicDevInfoUpdate( + pAd, + 0x0, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } else { + AsicDevInfoUpdate( + pAd, + 0x11, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } + } + + /* set ATEBSSID=00:22:22:22:22:22 */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr3[0], 0x00); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr3[1], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr3[2], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr3[3], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr3[4], 0x22); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Addr3[5], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr3[0], 0x00); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr3[1], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr3[2], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr3[3], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr3[4], 0x22); + TESTMODE_SET_PARAM(ATECtrl, 0, Addr3[5], 0x22); + /* snprintf(cmdStr, sizeof(cmdStr), "00:%.2x:%.2x:%.2x:%.2x:%.2x", */ + /* 0x22, 0x22, 0x22, 0x22, 0x22); */ + /* SetATEBssid(pAd, cmdStr); */ + if (fgBw160) { + snprintf(cmdStr, sizeof(cmdStr), "00:00:00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x22, 0x22, 0x22, 0x22, 0x22); + } else { + if (control_band_idx == 0) { + snprintf(cmdStr, sizeof(cmdStr), "00:00:00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x22, 0x22, 0x22, 0x22, 0x22); + } else { + snprintf(cmdStr, sizeof(cmdStr), "11:01:00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x22, 0x22, 0x22, 0x22, 0x22); + } + } + + Set_BssInfoUpdate(pAd, cmdStr); + /* set ATETXMODE=2 */ + SetATETxMode(pAd, "2"); + /* set ATETXMCS=0 */ + SetATETxMcs(pAd, "0"); + /* set ATETXBW=0 */ + SetATETxBw(pAd, "0"); + /* set ATETXGI=0 */ + SetATETxGi(pAd, "0"); + /* Enable i/eBF */ + SetATETXBFProc(pAd, "3"); + + if ((fgBw160) || (control_band_idx == 1)) { + /* set ATETXANT=3 2T */ + SetATETxAntenna(pAd, "3"); + /* set ATERXANT=3 2R*/ + SetATERxAntenna(pAd, "3"); + } else { + UINT8 ucTxPath = pAd->Antenna.field.TxPath; + +#ifdef DBDC_MODE + if (pAd->CommonCfg.dbdc_mode) { + if (control_band_idx == DBDC_BAND0) + ucTxPath = pAd->dbdc_band0_tx_path; + else + ucTxPath = pAd->dbdc_band1_tx_path; + } +#endif + + switch (ucTxPath) { + case TX_PATH_2: + /* set ATETXANT=3 2T */ + SetATETxAntenna(pAd, "3"); + /* set ATERXANT=3 2R*/ + SetATERxAntenna(pAd, "3"); + break; + + case TX_PATH_3: + /* set ATETXANT=7 3T */ + SetATETxAntenna(pAd, "7"); + /* set ATERXANT=7 3R*/ + SetATERxAntenna(pAd, "7"); + break; + + case TX_PATH_4: + default: + /* set ATETXANT=15 4T */ + SetATETxAntenna(pAd, "15"); + /* set ATERXANT=15 4R*/ + SetATERxAntenna(pAd, "15"); + break; + } + } + + /* SetATETxPower0(pAd, "14"); */ + ATECtrl->fgEBfEverEnabled = FALSE; + NdisGetSystemUpTime(&stTimeChk1); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Time consumption : %lu sec\n", + __func__, (stTimeChk1 - stTimeChk0) * 1000 / OS_HZ)); + + /* Init iBF phase calibration */ + if (ops->iBFPhaseCalInit) + ops->iBFPhaseCalInit(pAd); + + return TRUE; +} + + +INT SetATETxBfGdInitProc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + BOOLEAN fgBw160; + RTMP_STRING cmdStr[80]; + ULONG stTimeChk0, stTimeChk1; + + fgBw160 = simple_strtol(Arg, 0, 10); + NdisGetSystemUpTime(&stTimeChk0); + /* Do ATESTART */ + SetATE(pAd, "ATESTART"); + /* set ATEDA=00:22:22:22:22:22 */ + ATECtrl->Addr1[0] = 0x00; + ATECtrl->Addr1[1] = 0x22; + ATECtrl->Addr1[2] = 0x22; + ATECtrl->Addr1[3] = 0x22; + ATECtrl->Addr1[4] = 0x22; + ATECtrl->Addr1[5] = 0x22; + snprintf(cmdStr, sizeof(cmdStr), "00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x22, 0x22, 0x22, 0x22, 0x22); + SetATEDa(pAd, cmdStr); + /* set ATESA=00:11:11:11:11:11 */ + ATECtrl->Addr2[0] = 0x00; + ATECtrl->Addr2[1] = 0x11; + ATECtrl->Addr2[2] = 0x11; + ATECtrl->Addr2[3] = 0x11; + ATECtrl->Addr2[4] = 0x11; + ATECtrl->Addr2[5] = 0x11; + /* snprintf(cmdStr, sizeof(cmdStr), "00:%.2x:%.2x:%.2x:%.2x:%.2x", */ + /* 0x11, 0x11, 0x11, 0x11, 0x11); */ + /* SetATESa(pAd, cmdStr); */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx = %d\n", __func__, control_band_idx)); + + if (fgBw160) { + AsicDevInfoUpdate( + pAd, + 0x0, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } else { + if (control_band_idx == 0) { + AsicDevInfoUpdate( + pAd, + 0x0, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } else { + AsicDevInfoUpdate( + pAd, + 0x11, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } + } + + /* set ATEBSSID=00:22:22:22:22:22 */ + ATECtrl->Addr3[0] = 0x00; + ATECtrl->Addr3[1] = 0x22; + ATECtrl->Addr3[2] = 0x22; + ATECtrl->Addr3[3] = 0x22; + ATECtrl->Addr3[4] = 0x22; + ATECtrl->Addr3[5] = 0x22; + /* snprintf(cmdStr, sizeof(cmdStr), "00:%.2x:%.2x:%.2x:%.2x:%.2x", */ + /* 0x22, 0x22, 0x22, 0x22, 0x22); */ + /* SetATEBssid(pAd, cmdStr); */ + if (fgBw160) { + snprintf(cmdStr, sizeof(cmdStr), "00:00:00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x22, 0x22, 0x22, 0x22, 0x22); + } else { + if (control_band_idx == 0) { + snprintf(cmdStr, sizeof(cmdStr), "00:00:00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x22, 0x22, 0x22, 0x22, 0x22); + } else { + snprintf(cmdStr, sizeof(cmdStr), "11:01:00:%.2x:%.2x:%.2x:%.2x:%.2x", + 0x22, 0x22, 0x22, 0x22, 0x22); + } + } + + Set_BssInfoUpdate(pAd, cmdStr); + /* set ATETXMODE=2 */ + SetATETxMode(pAd, "2"); + /* set ATETXMCS=0 */ + SetATETxMcs(pAd, "0"); + /* set ATETXBW=0 */ + SetATETxBw(pAd, "0"); + /* set ATETXGI=0 */ + SetATETxGi(pAd, "0"); + /* set ATETXANT=1 1T */ + SetATETxAntenna(pAd, "1"); + /* set ATERXANT=1 1R*/ + SetATERxAntenna(pAd, "1"); + /* Configure WTBL */ + /* iwpriv ra0 set ManualAssoc =mac:222222222222-type:sta-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:1-pfmuId:0 */ + snprintf(cmdStr, sizeof(cmdStr), "mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x-type:ap-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:1-pfmuId:0\n", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", cmdStr)); + SetATEAssocProc(pAd, cmdStr); + NdisGetSystemUpTime(&stTimeChk1); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Time consumption : %lu sec\n", + __func__, (stTimeChk1 - stTimeChk0) * 1000 / OS_HZ)); + return TRUE; +} + + +INT32 SetATETxPacketWithBf(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + INT32 i; + UCHAR ucWlanId, ucTxCnt, *value, ucBuf[4], cmdStr[32]; + BOOLEAN fgBf; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx = %d\n", __func__, control_band_idx)); + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 8) + 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, &ucBuf[i++], 1); + } + + fgBf = ucBuf[0]; + ucWlanId = ucBuf[1]; + ucTxCnt = ucBuf[2]; + /* Assign Wlan ID for fixed rate TxD */ + ATECtrl->wcid_ref = ucWlanId; + /* Stop Rx before ready to Tx */ + SetATE(pAd, "RXSTOP"); + + /* At TxD, enable/disable BF Tx at DW6 bit28 */ + if (fgBf) { + /* Invalid iBF profile */ + TxBfProfileTagRead(pAd, 2, TRUE); + TxBfProfileTag_InValid(&pAd->rPfmuTag1, FALSE); + TxBfProfileTagWrite(pAd, + &pAd->rPfmuTag1, + &pAd->rPfmuTag2, + 2); + /* ATECtrl->eTxBf = TRUE; */ + /* ATECtrl->iTxBf = TRUE; */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, eTxBf, TRUE); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, iTxBf, TRUE); + ATECtrl->fgEBfEverEnabled = TRUE; + /* Stop Tx when the action of Tx packet is done */ + SetATE(pAd, "TXSTOP"); + /* Set the number of Tx packets */ + snprintf(cmdStr, sizeof(cmdStr), "%d", ucTxCnt); + SetATETxCount(pAd, cmdStr); + /* Start packet Tx */ + SetATE(pAd, "TXFRAME"); + } else { + if (ATECtrl->fgEBfEverEnabled == FALSE) { + /* ATECtrl->eTxBf = FALSE; */ + /* ATECtrl->iTxBf = FALSE; */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, eTxBf, FALSE); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, iTxBf, FALSE); + /* Stop Tx when the action of Tx packet is done */ + SetATE(pAd, "TXSTOP"); + /* Set the number of Tx packets */ + snprintf(cmdStr, sizeof(cmdStr), "%d", ucTxCnt); + SetATETxCount(pAd, cmdStr); + /* Start packet Tx */ + SetATE(pAd, "TXFRAME"); + } else { + /* Invalid iBF profile */ + TxBfProfileTagRead(pAd, 2, TRUE); + TxBfProfileTag_InValid(&pAd->rPfmuTag1, TRUE); + TxBfProfileTagWrite(pAd, + &pAd->rPfmuTag1, + &pAd->rPfmuTag2, + 2); + ATECtrl->fgEBfEverEnabled = FALSE; + } + } + + return TRUE; +} + + +INT32 SetATETxBfChanProfileUpdate(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + INT32 i; + UCHAR *value; + RTMP_STRING cmdStr[80]; + CHAR value_T[12]; + UCHAR strLen; + BOOLEAN fgFinalData; + UINT16 u2Buf[11] = {0}; + UINT16 u2PfmuId, u2Subcarr; + INT16 i2Phi11, i2Phi21, i2Phi31; + INT16 i2H11, i2AngleH11, i2H21, i2AngleH21, i2H31, i2AngleH31, i2H41, i2AngleH41; + INT32 Ret = 0; + UINT8 ucTxPath = pAd->Antenna.field.TxPath; + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 43) + return FALSE; + + if (!wdev) + return FALSE; + + for (i = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":")) { + if ((strlen(value) > 3) || (!isxdigit(*value)) || (!isxdigit(*(value + 1)))) + return FALSE; /*Invalid*/ + + strLen = strlen(value); + + if (strLen & 1) { + strcpy(value_T, "0"); + strncat(value_T, value, strLen); + AtoH(value_T, (PCHAR)(&u2Buf[i]), 2); + u2Buf[i] = be2cpu16(u2Buf[i]); + i++; + } + } + + u2PfmuId = u2Buf[0]; + u2Subcarr = u2Buf[1]; + fgFinalData = u2Buf[2]; + i2H11 = (INT16)(u2Buf[3] << 3) >> 3; + i2AngleH11 = (INT16)(u2Buf[4] << 3) >> 3; + i2H21 = (INT16)(u2Buf[5] << 3) >> 3; + i2AngleH21 = (INT16)(u2Buf[6] << 3) >> 3; + i2H31 = (INT16)(u2Buf[7] << 3) >> 3; + i2AngleH31 = (INT16)(u2Buf[8] << 3) >> 3; + i2H41 = (INT16)(u2Buf[9] << 3) >> 3; + i2AngleH41 = (INT16)(u2Buf[10] << 3) >> 3; + i2Phi11 = 0; + i2Phi21 = 0; + i2Phi31 = 0; + +#ifdef DBDC_MODE + if (pAd->CommonCfg.dbdc_mode) { + UINT8 band_idx = HcGetBandByWdev(wdev); + + if (band_idx == DBDC_BAND0) + ucTxPath = pAd->dbdc_band0_tx_path; + else + ucTxPath = pAd->dbdc_band1_tx_path; + } +#endif + + switch (ucTxPath) { + case TX_PATH_2: + i2Phi11 = i2AngleH21 - i2AngleH11; + i2Phi21 = 0; + i2Phi31 = 0; + break; + + case TX_PATH_3: + i2Phi11 = i2AngleH31 - i2AngleH11; + i2Phi21 = i2AngleH31 - i2AngleH21; + i2Phi31 = 0; + break; + + case TX_PATH_4: + default: +#ifdef DBDC_MODE + if (pAd->CommonCfg.dbdc_mode) { + i2Phi11 = i2AngleH21 - i2AngleH11; + i2Phi21 = 0; + i2Phi31 = 0; + } else +#endif + { + i2Phi11 = i2AngleH41 - i2AngleH11; + i2Phi21 = i2AngleH41 - i2AngleH21; + i2Phi31 = i2AngleH41 - i2AngleH31; + } + + break; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: i2AngleH11 = 0x%x, i2AngleH21 = 0x%x, i2AngleH31 = 0x%x, i2AngleH41 = 0x%x\n", + __func__, i2AngleH11, i2AngleH21, i2AngleH31, i2AngleH41)); + + /* Update the tag to enable eBF profile */ + if (fgFinalData) { + snprintf(cmdStr, sizeof(cmdStr), "%02x:01", u2PfmuId); + Set_TxBfProfileTagRead(pAd, cmdStr); + pAd->rPfmuTag1.rField.ucInvalidProf = TRUE; + Set_TxBfProfileTagWrite(pAd, cmdStr); + } + + /* Update the profile data per subcarrier */ + switch (ucTxPath) { + case TX_PATH_2: + snprintf(cmdStr, sizeof(cmdStr), "%02x:%03x:%03x:00:%03x:00:000:00:000:00:000:00:000:00:00:00:00:00", + u2PfmuId, u2Subcarr, + (UINT16)((UINT16)i2Phi11 & 0xFFF), + (UINT16)((UINT16)i2Phi21 & 0xFFF)); + break; + case TX_PATH_3: + snprintf(cmdStr, sizeof(cmdStr), "%02x:%03x:%03x:00:%03x:00:000:00:000:00:000:00:000:00:00:00:00:00", + u2PfmuId, u2Subcarr, + (UINT16)((UINT16)i2Phi11 & 0xFFF), + (UINT16)((UINT16)i2Phi21 & 0xFFF)); + break; + + case TX_PATH_4: + default: + snprintf(cmdStr, sizeof(cmdStr), "%02x:%03x:%03x:00:%03x:00:%03x:00:000:00:000:00:000:00:00:00:00:00", + u2PfmuId, u2Subcarr, + (UINT16)((UINT16)i2Phi11 & 0xFFF), + (UINT16)((UINT16)i2Phi21 & 0xFFF), + (UINT16)((UINT16)i2Phi31 & 0xFFF)); + break; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s", __func__)); + Ret = Set_TxBfProfileDataWrite(pAd, cmdStr); + return Ret; +} + + +INT32 SetATETxBfProfileRead(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 i; + UCHAR ucPfmuId, *value; + RTMP_STRING cmdStr[32]; + CHAR value_T[12]; + UCHAR strLen; + UINT16 u2Buf[2] = {0}; + UINT16 u2SubCarrier; + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 7) + return FALSE; + + for (i = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":")) { + if ((strlen(value) != 3) || (!isxdigit(*value)) || (!isxdigit(*(value + 1))) || (!isxdigit(*(value + 2)))) + return FALSE; /*Invalid*/ + + strLen = strlen(value); + + if (strLen & 1) { + strcpy(value_T, "0"); + strncat(value_T, value, strLen); + AtoH(value_T, (PCHAR)(&u2Buf[i]), 2); + u2Buf[i] = be2cpu16(u2Buf[i]); + i++; + } + } + + ucPfmuId = u2Buf[0]; + u2SubCarrier = u2Buf[1]; + snprintf(cmdStr, 11, "%.2x:01:%.2x:%.2x", ucPfmuId, (u2SubCarrier >> 8), (u2SubCarrier & 0xFF)); + Set_TxBfProfileDataRead(pAd, cmdStr); + return TRUE; +} + + +INT32 SetATETXBFProc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + UCHAR TxBfEn; +#if defined(MT7615) || defined(MT7622) + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); +#endif + TxBfEn = simple_strtol(Arg, 0, 10); +#if defined(MT7615) || defined(MT7622) + + switch (TxBfEn) { + case 0: + /* no BF */ + ATECtrl->iTxBf = FALSE; + ATECtrl->eTxBf = FALSE; + break; + + case 1: + /* ETxBF */ + ATECtrl->iTxBf = FALSE; + ATECtrl->eTxBf = TRUE; + break; + + case 2: + /* ITxBF */ + ATECtrl->iTxBf = TRUE; + ATECtrl->eTxBf = FALSE; + break; + + case 3: + /* Enable TXBF support */ + ATECtrl->iTxBf = TRUE; + ATECtrl->eTxBf = TRUE; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Set_ATE_TXBF_Proc: Invalid parameter %d\n", TxBfEn)); + Ret = TRUE; + break; + } + +#endif + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEIBfGdCal(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 i; + UCHAR ucGroup, ucGroup_L_M_H, *value, ucBuf[4]; + BOOLEAN fgSX2; + UCHAR ucPhaseCal, ucPhaseVerifyLnaGainLevel; + INT32 Ret = 0; + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 11) + 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, &ucBuf[i++], 1); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s\n", __func__)); + ucGroup = ucBuf[0]; + ucGroup_L_M_H = ucBuf[1]; + fgSX2 = ucBuf[2]; + ucPhaseCal = ucBuf[3]; + ucPhaseVerifyLnaGainLevel = 0; + Ret = CmdITxBfPhaseCal(pAd, + ucGroup, + ucGroup_L_M_H, + fgSX2, + ucPhaseCal, + ucPhaseVerifyLnaGainLevel); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEIBfInstCal(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 i; + UCHAR ucGroup, ucGroup_L_M_H, *value, ucBuf[5]; + BOOLEAN fgSX2; + UCHAR ucPhaseCal, ucPhaseLnaGainLevel; + INT32 Ret = 0; + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 14) + 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, &ucBuf[i++], 1); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s\n", __func__)); + ucGroup = ucBuf[0]; + ucGroup_L_M_H = ucBuf[1]; + fgSX2 = ucBuf[2]; + ucPhaseCal = ucBuf[3]; + ucPhaseLnaGainLevel = ucBuf[4]; + Ret = CmdITxBfPhaseCal(pAd, + ucGroup, + ucGroup_L_M_H, + fgSX2, + ucPhaseCal, + ucPhaseLnaGainLevel); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxBfLnaGain(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + UCHAR ucLnaGain; + INT32 Ret = 0; + + if (Arg == NULL) + return FALSE; + + ucLnaGain = simple_strtol(Arg, 0, 10); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s\n", __func__)); + Ret = CmdTxBfLnaGain(pAd, ucLnaGain); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEIBfProfileUpdate(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + INT32 i; + UCHAR Nr, Nc, PfmuIdx, NdpNss, *value, ucBuf[3]; + RTMP_STRING cmdStr[80]; + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 8) + 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, &ucBuf[i++], 1); + } + + PfmuIdx = ucBuf[0]; + + if ((pAd->CommonCfg.dbdc_mode) || (ATECtrl->fgBw160)) + Nr = 1; + else + Nr = pAd->Antenna.field.TxPath - 1; + + Nc = ucBuf[2]; + /* Configure iBF tag */ + /* PFMU ID */ + snprintf(cmdStr, sizeof(cmdStr), "%d", PfmuIdx); + Set_TxBfProfileTag_PfmuIdx(pAd, cmdStr); + /* ITxBf */ + Set_TxBfProfileTag_BfType(pAd, "0"); + /* BW20 */ + Set_TxBfProfileTag_DBW(pAd, "0"); + /* SU */ + Set_TxBfProfileTag_SuMu(pAd, "0"); + /* PFMU memory allocation */ + snprintf(cmdStr, 24, "00:04:00:05:00:06:00:07"); + Set_TxBfProfileTag_Mem(pAd, cmdStr); + /* Nr:Nc:Ng:LM:CB:HTCE */ + /* snprintf(cmdStr, 18, "%.2x:%.2x:00:01:00:00", Nr, Nc); */ + snprintf(cmdStr, 18, "%.2x:%.2x:00:00:00:00", Nr, Nc); + Set_TxBfProfileTag_Matrix(pAd, cmdStr); + /* SNR */ + snprintf(cmdStr, 12, "00:00:00:00"); + Set_TxBfProfileTag_SNR(pAd, cmdStr); + /* SMART Antenna */ + Set_TxBfProfileTag_SmartAnt(pAd, "0"); + /* SE index */ + Set_TxBfProfileTag_SeIdx(pAd, "0"); + /* Rmsd */ + Set_TxBfProfileTag_RmsdThrd(pAd, "0"); + /* MCS threshold */ + snprintf(cmdStr, 18, "00:00:00:00:00:00"); + Set_TxBfProfileTag_McsThrd(pAd, cmdStr); + /* Time out disable */ + Set_TxBfProfileTag_TimeOut(pAd, "255"); + /* Desired BW20 */ + Set_TxBfProfileTag_DesiredBW(pAd, "0"); + /* Nr */ + snprintf(cmdStr, sizeof(cmdStr), "%d", Nr); + Set_TxBfProfileTag_DesiredNr(pAd, cmdStr); + /* Nc */ + snprintf(cmdStr, sizeof(cmdStr), "%d", Nc); + Set_TxBfProfileTag_DesiredNc(pAd, cmdStr); + /* Invalid the tag */ + Set_TxBfProfileTag_InValid(pAd, "1"); + /* Update PFMU tag */ + snprintf(cmdStr, sizeof(cmdStr), "%d", PfmuIdx); + Set_TxBfProfileTagWrite(pAd, cmdStr); + /* Configure the BF StaRec */ + if (ATECtrl->fgBw160) { + snprintf(cmdStr, sizeof(cmdStr), "01:00:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } else { + if (control_band_idx == 0) { + snprintf(cmdStr, sizeof(cmdStr), "01:00:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } else { + snprintf(cmdStr, sizeof(cmdStr), "01:01:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } + } + Set_StaRecCmmUpdate(pAd, cmdStr); + + switch (Nr) { + case 1: + NdpNss = 8; /* MCS8, 2 streams */ + break; + + case 2: + NdpNss = 16; /* MCS16, 3 streams */ + break; + + case 3: + NdpNss = 24; /* MCS24, 4 streams */ + break; + + default: + NdpNss = 24; + break; + } + + snprintf(cmdStr, sizeof(cmdStr), "01:00:%.2x:00:00:00:%.2x:00:02:%.2x:%.2x:00:00:00:00:04:00:05:00:06:00:07:00", PfmuIdx, NdpNss, Nc, Nr); + /* MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", cmdStr)); */ + Set_StaRecBfUpdate(pAd, cmdStr); + Set_StaRecBfRead(pAd, "1"); + /* Configure WTBL */ + /* iwpriv ra0 set ManualAssoc =mac:222222222222-type:sta-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:2-pfmuId:0 */ + snprintf(cmdStr, sizeof(cmdStr), "mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x-type:sta-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:%d-pfmuId:%d\n", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5], + (Nc + 1), PfmuIdx); + /* MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", cmdStr)); */ + SetATEAssocProc(pAd, cmdStr); + /* Update the information requested by ATE Tx Gen */ + ATECtrl->pfmu_info[0].wcid = 1; + ATECtrl->pfmu_info[0].bss_idx = 0; + NdisMoveMemory(ATECtrl->pfmu_info[0].addr, ATECtrl->Addr1, MAC_ADDR_LEN); + return TRUE; +} + + +INT32 SetATEEBfProfileConfig(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + INT32 i; + UCHAR Nr, Nc, PfmuIdx, NdpNss, *value, ucBuf[3]; + RTMP_STRING cmdStr[80]; + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 8) + 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, &ucBuf[i++], 1); + } + + PfmuIdx = ucBuf[0]; + + if ((pAd->CommonCfg.dbdc_mode) || (ATECtrl->fgBw160)) + Nr = 1; + else + Nr = pAd->Antenna.field.TxPath - 1; + + Nc = ucBuf[2]; + /* Configure iBF tag */ + /* PFMU ID */ + snprintf(cmdStr, sizeof(cmdStr), "%d", PfmuIdx); + Set_TxBfProfileTag_PfmuIdx(pAd, cmdStr); + /* ETxBf */ + Set_TxBfProfileTag_BfType(pAd, "1"); + /* BW20 */ + Set_TxBfProfileTag_DBW(pAd, "0"); + /* SU */ + Set_TxBfProfileTag_SuMu(pAd, "0"); + /* PFMU memory allocation */ + snprintf(cmdStr, 24, "00:00:00:01:00:02:00:03"); + Set_TxBfProfileTag_Mem(pAd, cmdStr); + /* Nr:Nc:Ng:LM:CB:HTCE */ + snprintf(cmdStr, 18, "%.2x:%.2x:00:01:00:00", Nr, Nc); + Set_TxBfProfileTag_Matrix(pAd, cmdStr); + /* SNR */ + snprintf(cmdStr, 12, "00:00:00:00"); + Set_TxBfProfileTag_SNR(pAd, "00:00:00:00"); + /* SMART Antenna */ + Set_TxBfProfileTag_SmartAnt(pAd, "0"); + /* SE index */ + Set_TxBfProfileTag_SeIdx(pAd, "0"); + /* Rmsd */ + Set_TxBfProfileTag_RmsdThrd(pAd, "0"); + /* MCS threshold */ + snprintf(cmdStr, 18, "00:00:00:00:00:00"); + Set_TxBfProfileTag_McsThrd(pAd, cmdStr); + /* Invalid the tag */ + Set_TxBfProfileTag_InValid(pAd, "1"); + /* Update PFMU tag */ + snprintf(cmdStr, sizeof(cmdStr), "%d", PfmuIdx); + Set_TxBfProfileTagWrite(pAd, cmdStr); + /* Configure the BF StaRec */ + if (ATECtrl->fgBw160) { + snprintf(cmdStr, sizeof(cmdStr), "01:00:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } else { + if (control_band_idx == 0) { + snprintf(cmdStr, sizeof(cmdStr), "01:00:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } else { + snprintf(cmdStr, sizeof(cmdStr), "01:01:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } + } + Set_StaRecCmmUpdate(pAd, cmdStr); + + switch (Nr) { + case 1: + NdpNss = 8; /* MCS8, 2 streams */ + break; + + case 2: + NdpNss = 16; /* MCS16, 3 streams */ + break; + + case 3: + NdpNss = 24; /* MCS24, 4 streams */ + break; + + default: + NdpNss = 24; + break; + } + + snprintf(cmdStr, sizeof(cmdStr), "01:00:%.2x:00:01:00:%.2x:00:02:%.2x:%.2x:00:00:00:00:00:00:01:00:02:00:03:00", PfmuIdx, NdpNss, Nc, Nr); + /* MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", cmdStr)); */ + Set_StaRecBfUpdate(pAd, cmdStr); + Set_StaRecBfRead(pAd, "1"); + /* Configure WTBL */ + /* iwpriv ra0 set ManualAssoc =mac:222222222222-type:sta-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:2-pfmuId:0 */ + snprintf(cmdStr, sizeof(cmdStr), "mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x-type:sta-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:%d-pfmuId:%d\n", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5], + (Nc + 1), PfmuIdx); + /* MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", cmdStr)); */ + SetATEAssocProc(pAd, cmdStr); + /* Update the information requested by ATE Tx Gen */ + ATECtrl->pfmu_info[0].wcid = 1; + ATECtrl->pfmu_info[0].bss_idx = 0; + NdisMoveMemory(ATECtrl->pfmu_info[0].addr, ATECtrl->Addr1, MAC_ADDR_LEN); + return TRUE; +} + + +INT32 SetATEIBfPhaseComp(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 Ret, i; + UCHAR ucBW, ucGroup, ucBand, ucDbdcBandIdx, *value, ucBuf[5]; + BOOLEAN fgRdFromE2p, fgDisComp; + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 14) + 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, &ucBuf[i++], 1); + } + + ucBW = ucBuf[0]; + ucDbdcBandIdx = ucBuf[1]; + ucGroup = ucBuf[2]; + fgRdFromE2p = ucBuf[3]; + fgDisComp = ucBuf[4]; + ucBand = (ucGroup == 1) ? 1 : 0; + Ret = CmdITxBfPhaseComp(pAd, ucBW, ucBand, ucDbdcBandIdx, ucGroup, fgRdFromE2p, fgDisComp); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEIBfPhaseVerify(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 Ret, i; + UCHAR ucGroup, ucGroup_L_M_H, ucPhaseCalType, ucBand, *value, ucBuf[6]; + BOOLEAN fgSX2, fgRdFromE2p; + UCHAR ucPhaseVerifyLnaGainLevel; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + if (Arg == NULL) + return FALSE; + + 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, &ucBuf[i++], 1); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s\n", __func__)); + ucGroup = ucBuf[0]; + ucGroup_L_M_H = ucBuf[1]; + fgSX2 = ucBuf[2]; + ucPhaseCalType = ucBuf[3]; + ucPhaseVerifyLnaGainLevel = ucBuf[4]; + fgRdFromE2p = ucBuf[5]; + ucBand = (ucGroup == 1) ? 1 : 0; + Ret = CmdITxBfPhaseComp(pAd, + BW_20, + ucBand, + fgSX2, + ucGroup, + fgRdFromE2p, + FALSE); + + if (Ret) { + /* Free memory allocated by iBF phase calibration */ + if (ops->iBFPhaseFreeMem) + ops->iBFPhaseFreeMem(pAd); + + return FALSE; + } + + Ret = CmdITxBfPhaseCal(pAd, + ucGroup, + ucGroup_L_M_H, + fgSX2, + ucPhaseCalType, + ucPhaseVerifyLnaGainLevel); + + if (Ret) { + /* Free memory allocated by iBF phase calibration */ + if (ops->iBFPhaseFreeMem) + ops->iBFPhaseFreeMem(pAd); + + return FALSE; + } + + return TRUE; +} + + +INT32 SetATETxBfPhaseE2pUpdate(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 i; + UCHAR ucGroup, ucUpdateAllType, *value, ucBuf[3]; + BOOLEAN fgSX2; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + if (Arg == NULL) + return FALSE; + + if (strlen(Arg) != 8) + 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, &ucBuf[i++], 1); + } + + ucGroup = ucBuf[0]; + fgSX2 = ucBuf[1]; + ucUpdateAllType = ucBuf[2]; + ops->iBFPhaseCalE2PUpdate(pAd, ucGroup, fgSX2, ucUpdateAllType); + return TRUE; +} + + +INT32 SetATETxSoundingProc(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + UCHAR SoundingMode; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: SoundingMode = %s\n", __func__, Arg)); + SoundingMode = simple_strtol(Arg, 0, 10); + Ret = ATEOp->SetATETxSoundingProc(pAd, SoundingMode); + + if (!Ret) + return TRUE; + else + return FALSE; +} + +INT32 SetATEConTxETxBfInitProc( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT8 loop_index; + INT status = TRUE; + CHAR *value = 0; + UINT8 TxMode = 0; + UINT8 MCS = 0; + UINT8 BW = 0; + UINT8 VhtNss = 0; + UINT8 TRxStream = 0; + UINT8 Power = 0; + UINT8 Channel = 0; + UINT8 Channel2 = 0; + UINT8 Channl_band = 0; + UINT16 TxPktLength = 0; + UINT8 Nr = 0; + UINT8 LM = 0; + UCHAR OwnMacIdx = 0; + UCHAR wdev_idx = 0; + UCHAR WlanIdx = 1; + UCHAR BssIdx = 0; + UCHAR PfmuId = WlanIdx - 1; + ULONG stTimeChk0, stTimeChk1; + RTMP_STRING cmdStr[80]; + UCHAR *template; +#ifdef DBDC_MODE + struct _BAND_INFO *Info = &(ATECtrl->band_ext[0]); +#endif /* DBDC_MODE */ + struct wifi_dev *pWdev = NULL; + + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Configure Input Parameter */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + + /* sanity check for input parameter*/ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + return FALSE; + } + + if (strlen(Arg) != 33) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong parameter format!!\n", __func__)); + return FALSE; + } + + /* Parsing input parameter */ + for (loop_index = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":"), loop_index++) { + switch (loop_index) { + case 0: + TxMode = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 1: + MCS = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 2: + BW = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 3: + VhtNss = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 4: + TRxStream = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 5: + Power = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 6: + Channel = simple_strtol(value, 0, 10); /* 3-bit format */ + break; + + case 7: + Channel2 = simple_strtol(value, 0, 10); /* 3-bit format */ + break; + + case 8: + Channl_band = simple_strtol(value, 0, 10); /* 1-bit format */ + break; + + case 9: + TxPktLength = simple_strtol(value, 0, 10); /* 5-bit format */ + break; + + default: { + status = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Set wrong parameters\n", __func__)); + break; + } + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: TxMode = %d, MCS = %d, BW = %d, VhtNss = %d, TRxStream = %d\n", __func__, TxMode, MCS, BW, VhtNss, TRxStream)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Power = %d, Channel = %d, Channel2 = %d, Channl_band = %d, TxPktLength = %d\n", __func__, Power, Channel, Channel2, Channl_band, TxPktLength)); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Load Preliminary Configuration */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ +#ifdef CONFIG_AP_SUPPORT + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx = %d\n", __func__, control_band_idx)); +#endif /* CONFIG_AP_SUPPORT */ + + /* obtain wireless device index */ + wdev_idx = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, wdev_idx); + pWdev = pAd->wdev_list[wdev_idx]; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: wdev_idx = %d\n", __func__, wdev_idx)); + + /* obtain TemplateFrame */ + + if (control_band_idx == 0) + ATECtrl->TemplateFrame = TemplateFrame; + +#ifdef DBDC_MODE + else if (control_band_idx == 1) + NdisMoveMemory(&(Info->TemplateFrame), TemplateFrame, 32); + +#endif /*DBDC_MODE*/ + + /* sanity check for Device list */ + if (!pWdev) + goto err0; + + OwnMacIdx = pWdev->OmacIdx; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: OwnMacIdx = %d\n", __func__, OwnMacIdx)); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* DUT TxBf Initialization */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + NdisGetSystemUpTime(&stTimeChk0); + /* Start ATE Mode */ + SetATE(pAd, "ATESTART"); + /* Enable ETxBF Capability */ + CmdTxBfHwEnableStatusUpdate(pAd, TRUE, FALSE); + + /* set ATEDA=00:11:11:11:11:11 */ + if (control_band_idx == 0) { + ATECtrl->Addr1[0] = Addr1[0]; + ATECtrl->Addr1[1] = Addr1[1]; + ATECtrl->Addr1[2] = Addr1[2]; + ATECtrl->Addr1[3] = Addr1[3]; + ATECtrl->Addr1[4] = Addr1[4]; + ATECtrl->Addr1[5] = Addr1[5]; + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + Info->Addr1[0] = Addr1[0]; + Info->Addr1[1] = Addr1[1]; + Info->Addr1[2] = Addr1[2]; + Info->Addr1[3] = Addr1[3]; + Info->Addr1[4] = Addr1[4]; + Info->Addr1[5] = Addr1[5]; + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + Info->Addr1[0], Info->Addr1[1], Info->Addr1[2], Info->Addr1[3], Info->Addr1[4], Info->Addr1[5]); + } + +#endif /* DBDC_MODE */ + SetATEDa(pAd, cmdStr); + + /* set ATESA=00:22:22:22:22:22 */ + if (control_band_idx == 0) { + ATECtrl->Addr2[0] = Addr2[0]; + ATECtrl->Addr2[1] = Addr2[1]; + ATECtrl->Addr2[2] = Addr2[2]; + ATECtrl->Addr2[3] = Addr2[3]; + ATECtrl->Addr2[4] = Addr2[4]; + ATECtrl->Addr2[5] = Addr2[5]; + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + Info->Addr2[0] = Addr2[0]; + Info->Addr2[1] = Addr2[1]; + Info->Addr2[2] = Addr2[2]; + Info->Addr2[3] = Addr2[3]; + Info->Addr2[4] = Addr2[4]; + Info->Addr2[5] = Addr2[5]; + } + +#endif /* DBDC_MODE */ + + /* set ATEBSSID=00:22:22:22:22:22 */ + if (control_band_idx == 0) { + ATECtrl->Addr3[0] = Addr3[0]; + ATECtrl->Addr3[1] = Addr3[1]; + ATECtrl->Addr3[2] = Addr3[2]; + ATECtrl->Addr3[3] = Addr3[3]; + ATECtrl->Addr3[4] = Addr3[4]; + ATECtrl->Addr3[5] = Addr3[5]; + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + Info->Addr3[0] = Addr3[0]; + Info->Addr3[1] = Addr3[1]; + Info->Addr3[2] = Addr3[2]; + Info->Addr3[3] = Addr3[3]; + Info->Addr3[4] = Addr3[4]; + Info->Addr3[5] = Addr3[5]; + } + +#endif /* DBDC_MODE */ +#ifdef CONFIG_AP_SUPPORT + + if (control_band_idx == 0) { + AsicDevInfoUpdate( + pAd, + 0x0, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + AsicDevInfoUpdate( + pAd, + 0x0, + Info->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } + +#endif /* DBDC_MODE */ +#endif /* CONFIG_AP_SUPPORT */ + + /* BSS Info Update */ + if (control_band_idx == 0) { + BssIdx = 0; + /* OwnMacIdx = 0; */ + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + OwnMacIdx, BssIdx, ATECtrl->Addr3[0], ATECtrl->Addr3[1], ATECtrl->Addr3[2], ATECtrl->Addr3[3], ATECtrl->Addr3[4], ATECtrl->Addr3[5]); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + BssIdx = 1; + /* OwnMacIdx = 17; */ + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + OwnMacIdx, BssIdx, Info->Addr3[0], Info->Addr3[1], Info->Addr3[2], Info->Addr3[3], Info->Addr3[4], Info->Addr3[5]); + } + +#endif /* DBDC_MODE */ + Set_BssInfoUpdate(pAd, cmdStr); + /* Set ATE Tx Frame content */ + template = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TemplateFrame); /* structure type of TemplateFrame structure is HEADER_802_11 */ + NdisMoveMemory(template + 4, Addr1, MAC_ADDR_LEN); + NdisMoveMemory(template + 10, Addr2, MAC_ADDR_LEN); + NdisMoveMemory(template + 16, Addr3, MAC_ADDR_LEN); + /* Set Tx mode */ + snprintf(cmdStr, sizeof(cmdStr), "%d", TxMode); + SetATETxMode(pAd, cmdStr); /* 0: CCK 1: OFDM 2: HT Mixe dmode 3: HT Green Mode 4: VHT mode */ + /* RtmpOsMsDelay(100); */ + /* Set Tx MCS */ + snprintf(cmdStr, sizeof(cmdStr), "%d", MCS); + SetATETxMcs(pAd, cmdStr); + /* RtmpOsMsDelay(100); */ + /* Set Tx BW */ + snprintf(cmdStr, sizeof(cmdStr), "%d", BW); + SetATETxBw(pAd, cmdStr); /* 0: 20MHz 1: 40MHz 2: 80MHz 3: 160MHz(160C) 4: 5M 5: 10M 6: 160MHz (160NC) */ + /* RtmpOsMsDelay(100); */ + + /* Set Tx VhtNss */ + if (TxMode == 4) { + snprintf(cmdStr, sizeof(cmdStr), "%d", VhtNss); + SetATEVhtNss(pAd, cmdStr); + } + + /* set ATETXGI=0 */ + SetATETxGi(pAd, "0"); + + /* Set Tx Ant */ + /* bitwise representration, ex: 0x3 means wifi[0] and wifi[1] ON */ + if (control_band_idx == 0) { + if (TRxStream == 4) + SetATETxAntenna(pAd, "15"); /* 15 (0xF: wifi[0], wifi[1], wifi[2], wifi[3] on) */ + else if (TRxStream == 3) + SetATETxAntenna(pAd, "7"); /* 7 (0x7: wifi[0], wifi[1], wifi[2] on) */ + else if (TRxStream == 2) + SetATETxAntenna(pAd, "3"); /* 3 (0x3: wifi[0], wifi[1] on) */ + } else if (control_band_idx == 1) { + SetATETxAntenna(pAd, "3"); /* 3 (0x3: wifi[2], wifi[3] on for DBDC mode) */ + TRxStream = 2; /* force TxStream to be 2T for DBDC mode */ + } + + /* Set Rx Ant */ + /* bitwise representration, ex: 0x3 means wifi[0] and wifi[1] ON */ + if (control_band_idx == 0) { + if (TRxStream == 4) + SetATERxAntenna(pAd, "15"); /* 15 (0xF all on) */ + else if (TRxStream == 3) + SetATERxAntenna(pAd, "7"); /* 7 (0x7: wifi[0], wifi[1], wifi[2] on) */ + else if (TRxStream == 2) + SetATERxAntenna(pAd, "3"); /* 3 (0x3: wifi[0], wifi[1] on) */ + } else if (control_band_idx == 1) + SetATERxAntenna(pAd, "3"); /* 3 (0x3: wifi[2], wifi[3] on for DBDC mode */ + + /* Set ATE Channel */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Channel, Channel); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Channel_2nd, Channel2); + /* Set ATE Tx Power = 36 (unit is 0.5 dBm) */ + snprintf(cmdStr, sizeof(cmdStr), "%d", Power); + SetATETxPower0(pAd, cmdStr); + NdisGetSystemUpTime(&stTimeChk1); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): DUT Init Time consumption : %lu sec\n", + __func__, (stTimeChk1 - stTimeChk0) * 1000 / OS_HZ)); + + /* Device info Update */ + if (control_band_idx == 0) { + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + OwnMacIdx, ATECtrl->Addr2[0], ATECtrl->Addr2[1], ATECtrl->Addr2[2], ATECtrl->Addr2[3], ATECtrl->Addr2[4], ATECtrl->Addr2[5], control_band_idx); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + OwnMacIdx, Info->Addr2[0], Info->Addr2[1], Info->Addr2[2], Info->Addr2[3], Info->Addr2[4], Info->Addr2[5], control_band_idx); + } + +#endif /* DBDC_MODE */ + Set_DevInfoUpdate(pAd, cmdStr); + /* STOP AUTO Sounding */ + Set_Stop_Sounding_Proc(pAd, "1"); + /* Enable MAC Rx */ + SetATE(pAd, "RXFRAME"); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* EBF Profile Cnfiguration */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* set TxBfProfileTag_PFMU ID */ + snprintf(cmdStr, sizeof(cmdStr), "%d", PfmuId); + Set_TxBfProfileTag_PfmuIdx(pAd, cmdStr); + /* set TxBfProfileTag_Bf Type */ + Set_TxBfProfileTag_BfType(pAd, "1"); /* 0: iBF 1: eBF */ + /* set TxBfProfileTag_DBW */ + snprintf(cmdStr, sizeof(cmdStr), "%d", BW); /* 0: 20MHz 1: 40MHz 2: 80MHz 3: 160MHz(160NC) */ + Set_TxBfProfileTag_DBW(pAd, cmdStr); + /* set TxBfProfileTag_SUMU */ + Set_TxBfProfileTag_SuMu(pAd, "0"); /* 0: SU 1: MU */ + /* PFMU memory allocation */ + snprintf(cmdStr, 24, "00:00:00:01:00:02:00:03"); + Set_TxBfProfileTag_Mem(pAd, cmdStr); + + /* set TxBfProfileTag_Matrix */ + if (TxMode == 4 && ((BW == 3) || (BW == 6))) { + if (TRxStream == 4) + Nr = 1; + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Invalid Configuration for BW160!! For BW160, TxStream number must be 4!!\n", __func__)); + } else { + if (TRxStream == 4) + Nr = 3; + else if (TRxStream == 3) + Nr = 2; + else if (TRxStream == 2) + Nr = 1; + } + + if (TxMode == 4) + LM = 2; + else if (TxMode == 2) + LM = 1; + + snprintf(cmdStr, 18, "%.2x:00:00:%.2x:00:00", Nr, LM); /* Nr:Nc:Ng:LM:CB:HTCE */ + Set_TxBfProfileTag_Matrix(pAd, cmdStr); + /* set TxBfProfileTag_SNR */ + snprintf(cmdStr, 12, "00:00:00:00"); + Set_TxBfProfileTag_SNR(pAd, "00:00:00:00"); + /* set TxBfProfileTag_Smart Antenna */ + Set_TxBfProfileTag_SmartAnt(pAd, "0"); + /* set TxBfProfileTag_SE index */ + Set_TxBfProfileTag_SeIdx(pAd, "0"); + /* set TxBfProfileTag_Rmsd */ + Set_TxBfProfileTag_RmsdThrd(pAd, "0"); + /* set TxBfProfileTag_MCS Threshold */ + snprintf(cmdStr, 18, "00:00:00:00:00:00"); + Set_TxBfProfileTag_McsThrd(pAd, cmdStr); + /* set TxBfProfileTag_Invalid Tag */ + Set_TxBfProfileTag_InValid(pAd, "1"); + /* Update PFMU Tag */ + snprintf(cmdStr, sizeof(cmdStr), "00"); + Set_TxBfProfileTagWrite(pAd, cmdStr); + + /* Station Record Common Info Update */ + if (control_band_idx == 0) { + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + WlanIdx, BssIdx, ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + WlanIdx, BssIdx, Info->Addr1[0], Info->Addr1[1], Info->Addr1[2], Info->Addr1[3], Info->Addr1[4], Info->Addr1[5]); + } + +#endif /* DBDC_MODE */ + Set_StaRecCmmUpdate(pAd, cmdStr); + + /* Station Record BF Info Update */ + if (TxMode == 4) + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:00:01:09:00:09:04:00:%.2x:%.2x:00:00:00:00:00:01:00:02:00:03:00", WlanIdx, BssIdx, PfmuId, Nr, BW); + else if (TxMode == 2) { + if (TRxStream == 4) + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:00:01:00:18:00:02:00:%.2x:%.2x:00:00:00:00:00:01:00:02:00:03:00", WlanIdx, BssIdx, PfmuId, Nr, BW); + else if (TRxStream == 3) + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:00:01:00:10:00:02:00:%.2x:%.2x:00:00:00:00:00:01:00:02:00:03:00", WlanIdx, BssIdx, PfmuId, Nr, BW); + else if (TRxStream == 2) + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:00:01:00:08:00:02:00:%.2x:%.2x:00:00:00:00:00:01:00:02:00:03:00", WlanIdx, BssIdx, PfmuId, Nr, BW); + } + + Set_StaRecBfUpdate(pAd, cmdStr); + /* Read Station Record BF Info */ + Set_StaRecBfRead(pAd, "1"); + + /* Configure WTBL and Manual Association */ + /* iwpriv ra0 set ManualAssoc=mac:22:22:22:22:22:22-type:sta-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:2-pfmuId:0 */ + if (control_band_idx == 0) { + snprintf(cmdStr, sizeof(cmdStr), "mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x-type:sta-wtbl:%.2x-ownmac:%.2x-mode:aanac-bw:20-nss:2-pfmuId:0\n", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5], WlanIdx, OwnMacIdx); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + snprintf(cmdStr, sizeof(cmdStr), "mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x-type:sta-wtbl:%.2x-ownmac:%.2x-mode:aanac-bw:20-nss:2-pfmuId:0\n", + Info->Addr1[0], Info->Addr1[1], Info->Addr1[2], Info->Addr1[3], Info->Addr1[4], Info->Addr1[5], WlanIdx, OwnMacIdx); + } + +#endif /* DBDC_MODE */ + SetATEAssocProc(pAd, cmdStr); + /* Read Station Record BF Info */ + Set_StaRecBfRead(pAd, "1"); + /* Read PFMU Tag Info */ + Set_TxBfProfileTagRead(pAd, "00:01"); + /* Update the information requested by ATE Tx packet generation */ + ATECtrl->pfmu_info[PfmuId].wcid = WlanIdx; + ATECtrl->pfmu_info[PfmuId].bss_idx = BssIdx; + NdisMoveMemory(ATECtrl->pfmu_info[PfmuId].addr, ATECtrl->Addr1, MAC_ADDR_LEN); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* EBF TxBf Apply */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* WTBL Update TxBf Apply */ + Set_TxBfTxApply(pAd, "01:01:00:00:00"); + /* Read Station Bf Record */ + Set_StaRecBfRead(pAd, "1"); + /* Trigger one shot Sounding packet */ + Set_Trigger_Sounding_Proc(pAd, "00:01:00:01:00:00:00"); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Continuous packet Tx Initializaton */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Set ATE EBF Enable */ + SetATEEBfTx(pAd, "1"); /* need to before switch channel for TxStream config since TxStream only can update correct when etxbf is enable for 3T and 2T */ + /* Set ATE Channel */ + snprintf(cmdStr, sizeof(cmdStr), "%d:%d:0:%d", Channel, Channl_band, Channel2); + SetATEChannel(pAd, cmdStr); + RtmpOsMsDelay(1000); + /* Set ATE Tx packet Length (unit is byte) */ + snprintf(cmdStr, sizeof(cmdStr), "%d", TxPktLength); + SetATETxLength(pAd, cmdStr); + /* Set ATE Tx packet number = 0 (Continuous packet Tx) */ + SetATETxCount(pAd, "0"); + /* Set ATE Tx packet Length = 4 (unit is slot time) */ + SetATEIpg(pAd, "4"); + /* Set Queue Priority = 1 (WMM_BK Queue) */ + SetATEQid(pAd, "1"); + /* Set ATE Tx Dequeue size = 4 (allocate 4 packet after receiving 1 free count) (NOT Use Now!!!)*/ + /* ATE Start Continuos Packet Tx */ + /* SetATE(pAd, "TXFRAMESKB"); */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Periodical Sounding Trigger */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Trigger Periodical Sounding packet */ + Set_Trigger_Sounding_Proc(pAd, "02:01:FF:01:00:00:00"); + return status; +err0: + return FALSE; +} + + +INT32 SetATEConTxETxBfGdProc( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT8 loop_index; + INT status = TRUE; + CHAR *value = 0; + UINT32 TxMode = 0; + UINT32 MCS = 0; + UINT32 BW = 0; + UINT32 Channel = 0; + UINT8 Channel2 = 0; + UINT8 Channl_band = 0; + UINT32 CRvalue = 0; + ULONG stTimeChk0, stTimeChk1; + RTMP_STRING cmdStr[80]; + + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Configure Input Parameter */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + + /* sanity check for input parameter*/ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + return FALSE; + } + + if (strlen(Arg) != 18) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong parameter format!!\n", __func__)); + return FALSE; + } + + /* Parsing input parameter */ + for (loop_index = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":"), loop_index++) { + switch (loop_index) { + case 0: + TxMode = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 1: + MCS = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 2: + BW = simple_strtol(value, 0, 10); /* 2-bit format */ + break; + + case 3: + Channel = simple_strtol(value, 0, 10); /* 3-bit format */ + break; + + case 4: + Channel2 = simple_strtol(value, 0, 10); /* 3-bit format */ + break; + + case 5: + Channl_band = simple_strtol(value, 0, 10); /* 1-bit format */ + break; + + default: { + status = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Set wrong parameters\n", __func__)); + break; + } + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: TxMode = %d, MCS = %d, BW = %d, Channel = %d, Channel2 = %d, Channl_band = %d\n", + __func__, TxMode, MCS, BW, Channel, Channel2, Channl_band)); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* GOLDEN TxBf Initialization */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + NdisGetSystemUpTime(&stTimeChk0); + /* Start ATE Mode */ + SetATE(pAd, "ATESTART"); + /* set ATEDA=00:22:22:22:22:22 */ + ATECtrl->Addr1[0] = Addr2[0]; + ATECtrl->Addr1[1] = Addr2[1]; + ATECtrl->Addr1[2] = Addr2[2]; + ATECtrl->Addr1[3] = Addr2[3]; + ATECtrl->Addr1[4] = Addr2[4]; + ATECtrl->Addr1[5] = Addr2[5]; + snprintf(cmdStr, sizeof(cmdStr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + SetATEDa(pAd, cmdStr); + /* set ATESA=00:11:11:11:11:11 */ + ATECtrl->Addr2[0] = Addr1[0]; + ATECtrl->Addr2[1] = Addr1[1]; + ATECtrl->Addr2[2] = Addr1[2]; + ATECtrl->Addr2[3] = Addr1[3]; + ATECtrl->Addr2[4] = Addr1[4]; + ATECtrl->Addr2[5] = Addr1[5]; + /* set ATEBSSID=00:22:22:22:22:22 */ + ATECtrl->Addr3[0] = Addr3[0]; + ATECtrl->Addr3[1] = Addr3[1]; + ATECtrl->Addr3[2] = Addr3[2]; + ATECtrl->Addr3[3] = Addr3[3]; + ATECtrl->Addr3[4] = Addr3[4]; + ATECtrl->Addr3[5] = Addr3[5]; +#ifdef CONFIG_AP_SUPPORT + AsicDevInfoUpdate( + pAd, + 0x0, + ATECtrl->Addr2, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); +#endif /* CONFIG_AP_SUPPORT */ + snprintf(cmdStr, sizeof(cmdStr), "00:00:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + ATECtrl->Addr3[0], ATECtrl->Addr3[1], ATECtrl->Addr3[2], ATECtrl->Addr3[3], ATECtrl->Addr3[4], ATECtrl->Addr3[5]); + Set_BssInfoUpdate(pAd, cmdStr); + /* Set Tx mode */ + snprintf(cmdStr, sizeof(cmdStr), "%d", TxMode); + SetATETxMode(pAd, cmdStr); /* 0: CCK 1: OFDM 2: HT Mixe dmode 3: HT Green Mode 4: VHT mode */ + /* Set Tx MCS */ + snprintf(cmdStr, sizeof(cmdStr), "%d", MCS); + SetATETxMcs(pAd, cmdStr); + /* Set Tx BW */ + snprintf(cmdStr, sizeof(cmdStr), "%d", BW); + SetATETxBw(pAd, cmdStr); /* 0: 20MHz 1: 40MHz 2: 80MHz 3: 160MHz(160C) 4: 5M 5: 10M 6: 160MHz (160NC) */ + /* set ATETXGI=0 */ + SetATETxGi(pAd, "0"); + + /* Set Tx Ant */ + /* bitwise representration, ex: 0x5 means wifi[0] and wifi[2] ON */ + if ((BW == 3) || (BW == 6)) + SetATETxAntenna(pAd, "5"); /* for BW160C, BW160NC */ + else + SetATETxAntenna(pAd, "1"); /* for BW20, BW40, BW80 */ + + /* Set Rx Ant */ + /* bitwise representration, ex: 0x5 means wifi[0] and wifi[2] ON */ + if ((BW == 3) || (BW == 6)) + SetATERxAntenna(pAd, "5"); /* for BW160C, BW160NC */ + else + SetATERxAntenna(pAd, "1"); /* for BW20, BW40, BW80 */ + + /* Configure WTBL */ + /* iwpriv ra0 set ManualAssoc = mac:222222222222-type:sta-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:1-pfmuId:0 */ + snprintf(cmdStr, sizeof(cmdStr), "mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x-type:ap-wtbl:1-ownmac:0-mode:aanac-bw:20-nss:1-pfmuId:0\n", + ATECtrl->Addr1[0], ATECtrl->Addr1[1], ATECtrl->Addr1[2], ATECtrl->Addr1[3], ATECtrl->Addr1[4], ATECtrl->Addr1[5]); + SetATEAssocProc(pAd, cmdStr); + NdisGetSystemUpTime(&stTimeChk1); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: SetATETxBfGdInitProc Time consumption : %lu sec\n", + __func__, (stTimeChk1 - stTimeChk0) * 1000 / OS_HZ)); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Turn On BBP CR for Rx */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* iwpriv ra0 mac 82070280=00008001 */ + PHY_IO_WRITE32(pAd, 0x10280, 0x00008001); + /* check */ + PHY_IO_READ32(pAd, 0x10280, &CRvalue); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: <0x82070280> = 0x%x\n", __func__, CRvalue)); + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Sounding Mechanism TRx configuration */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Set Channel Info to ATE Control structure */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Channel, Channel); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Channel_2nd, Channel2); +#if !defined(CONFIG_AP_SUPPORT) && !defined(DBDC_MODE) + /* Only to prevent build error: unused variable ¡¥BandIdx¡¦*/ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_NOISY, + ("control_band_idx=%d\n", control_band_idx)); +#endif + /* Set ATE Channel */ + snprintf(cmdStr, sizeof(cmdStr), "%d:%d:0:%d", Channel, Channl_band, Channel2); + SetATEChannel(pAd, cmdStr); + RtmpOsMsDelay(1000); + /* ATE Start Continuos Packet Rx */ + SetATE(pAd, "RXFRAME"); + /* ATE MAC TRx configuration */ + MtATESetMacTxRx(pAd, 6, 1, control_band_idx); /* ENUM_ATE_MAC_RX_RXV: MAC to PHY Rx Enable */ + return status; +} + + +INT32 SetATESpeIdx( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + UINT8 loop_index; + CHAR *value = 0; + INT status = TRUE; + + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Configure Input Parameter */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + + /* sanity check for input parameter*/ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + return FALSE; + } + + if (strlen(Arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong parameter format!!\n", __func__)); + return FALSE; + } + + /* Parsing input parameter */ + for (loop_index = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":"), loop_index++) { + switch (loop_index) { + case 0: + BF_ON_certification = simple_strtol(value, 0, 10); + break; + + default: { + status = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Set wrong parameters\n", __func__)); + break; + } + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: BF_ON_certification = %d !!!!!\n", + __func__, BF_ON_certification)); + return status; +} + + +INT32 SetATEEBfTx( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT8 loop_index; + CHAR *value = 0; + UINT32 eTxBf = 0; + INT status = TRUE; + UCHAR addr[6] = {0x00, 0x11, 0x11, 0x11, 0x11, 0x11}; + UCHAR *pate_pkt; + UCHAR WlanIdx = 1; + UCHAR PfmuId = WlanIdx - 1; +#ifdef DBDC_MODE + struct _BAND_INFO *Info = &(ATECtrl->band_ext[0]); +#endif /* DBDC_MODE */ + + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Configure Input Parameter */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + + /* sanity check for input parameter*/ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + return FALSE; + } + + if (strlen(Arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong parameter format!!\n", __func__)); + return FALSE; + } + + /* Parsing input parameter */ + for (loop_index = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":"), loop_index++) { + switch (loop_index) { + case 0: + eTxBf = simple_strtol(value, 0, 10); + break; + + default: { + status = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Set wrong parameters\n", __func__)); + break; + } + } + } + +#ifdef CONFIG_AP_SUPPORT + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: control_band_idx = %d\n", __func__, control_band_idx)); +#endif /* CONFIG_AP_SUPPORT */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* EBF Configuration */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + if (control_band_idx == 0) { + ATECtrl->eTxBf = eTxBf; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: ATECtrl->eTxBf = %d !!!!!\n", __func__, ATECtrl->eTxBf)); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + Info->eTxBf = eTxBf; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Info->eTxBf = %d !!!!!\n", __func__, Info->eTxBf)); + } + +#endif /* DBDC_MODE */ + ATECtrl->wcid_ref = WlanIdx; /* For Sportan certification, only Golden */ + NdisCopyMemory(ATECtrl->pfmu_info[PfmuId].addr, addr, MAC_ADDR_LEN); + + if (control_band_idx == 0) { + if (ATECtrl->eTxBf) + SetATESpeIdx(pAd, "1"); + else + SetATESpeIdx(pAd, "0"); + } + +#ifdef DBDC_MODE + else if (control_band_idx == 1) { + if (Info->eTxBf) + SetATESpeIdx(pAd, "1"); + else + SetATESpeIdx(pAd, "0"); + } + +#endif /* DBDC_MODE */ + pate_pkt = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, pate_pkt); + /* Generate new packet with new contents */ + MT_ATEGenPkt(pAd, pate_pkt, control_band_idx); + return status; +} + + +INT32 SetATEEBFCE( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + UINT8 loop_index; + CHAR *value = 0; + INT status = TRUE; + + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + /* Configure Input Parameter */ + /*----------------------------------------------------------------------------------------------------------------------------------------*/ + + /* sanity check for input parameter*/ + if (Arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: No parameters!!\n", __func__)); + return FALSE; + } + + if (strlen(Arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong parameter format!!\n", __func__)); + return FALSE; + } + + /* Parsing input parameter */ + for (loop_index = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":"), loop_index++) { + switch (loop_index) { + case 0: + g_EBF_certification = simple_strtol(value, 0, 10); + break; + + default: { + status = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Set wrong parameters\n", __func__)); + break; + } + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: g_EBF_certification = %d !!!!!\n", + __func__, g_EBF_certification)); + return status; +} + + +INT32 SetATEEBFCEInfo( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + INT status = TRUE; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: g_EBF_certification = %d !!!!!\n", __func__, g_EBF_certification)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: BF_ON_certification = %d !!!!!\n", __func__, BF_ON_certification)); + return status; +} + +INT32 SetATEEBFCEHelp( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + INT status = TRUE; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================================================================\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ATE ETxBF Certification Procedure Guide\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================================================================\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("For HT20 mode\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 1) iwpriv ra0 set ATEEBFCE=1\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 2) iwpriv ra0 set ATEConTxETxBfGdProc=02:00:00:036:112:1 (Use in Golden Device)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 3) iwpriv ra0 set ATEConTxETxBfInitProc=02:00:00:01:04:18:036:112:1:04000\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 4) iwpriv ra0 set ATETXEBF=1 (Tx packet apply BF On)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 5) iwpriv ra0 set ATE=TXFRAME\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 6) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if apply then nonzero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 7) check IQxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 8) iwpriv ra0 set ATETXEBF=0 (Tx packet apply BF Off)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 9) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if not apply then zero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("10) check Iqxel waveformn")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("---------------------------------------------------------------------------------------------\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("For HT40 mode\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 1) iwpriv ra0 set ATEEBFCE=1\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 2) iwpriv ra0 set ATEConTxETxBfGdProc=02:00:01:036:112:1 (Use in Golden Device)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 3) iwpriv ra0 set ATEConTxETxBfInitProc=02:00:01:01:04:18:036:112:1:04000\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 4) iwpriv ra0 set ATETXEBF=1 (Tx packet apply BF On)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 5) iwpriv ra0 set ATE=TXFRAMESKB\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 6) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if apply then nonzero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 7) check IQxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 8) iwpriv ra0 set ATETXEBF=0 (Tx packet apply BF Off)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 9) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if not apply then zero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("10) check Iqxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("---------------------------------------------------------------------------------------------\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("For VHT80 mode\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 1) iwpriv ra0 set ATEEBFCE=1\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 2) iwpriv ra0 set ATEConTxETxBfGdProc=04:00:02:036:112:1 (Use in Golden Device)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 3) iwpriv ra0 set ATEConTxETxBfInitProc=04:00:02:01:04:18:036:112:1:16000\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 4) iwpriv ra0 set ATETXEBF=1 (Tx packet apply BF On)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 5) iwpriv ra0 set ATE=TXFRAMESKB\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 6) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if apply then nonzero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 7) check IQxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 8) iwpriv ra0 set ATETXEBF=0 (Tx packet apply BF Off)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 9) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if not apply then zero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("10) check Iqxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("---------------------------------------------------------------------------------------------\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("For VHT160C mode\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 1) iwpriv ra0 set ATEEBFCE=1\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 2) iwpriv ra0 set ATEConTxETxBfGdProc=04:00:03:036:112:1 (Use in Golden Device)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 3) iwpriv ra0 set ATEConTxETxBfInitProc=04:00:03:01:04:18:036:112:1:16000\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 4) iwpriv ra0 set ATETXEBF=1 (Tx packet apply BF On)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 5) iwpriv ra0 set ATE=TXFRAMESKB\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 6) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if apply then nonzero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 7) check IQxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 8) iwpriv ra0 set ATETXEBF=0 (Tx packet apply BF Off)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 9) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if not apply then zero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("10) check Iqxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("---------------------------------------------------------------------------------------------\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("For VHT160NC mode\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 1) iwpriv ra0 set ATEEBFCE=1\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 2) iwpriv ra0 set ATEConTxETxBfGdProc=04:00:06:036:112:1 (Use in Golden Device)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 3) iwpriv ra0 set ATEConTxETxBfInitProc=04:00:06:01:04:18:036:112:1:16000\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 4) iwpriv ra0 set ATETXEBF=1 (Tx packet apply BF On)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 5) iwpriv ra0 set ATE=TXFRAMESKB\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 6) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if apply then nonzero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 7) check IQxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 8) iwpriv ra0 set ATETXEBF=0 (Tx packet apply BF Off)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 9) iwpriv ra0 mac 820fa09c (check [15:0] eBF counter, if not apply then zero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("10) check Iqxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("---------------------------------------------------------------------------------------------\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("For DBDC Band1 HT20 mode\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 1) configure DBDC mode and Reboot system\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 2) iwpriv ra1 set ATEEBFCE=1\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 3) iwpriv ra1 set ATEConTxETxBfGdProc=02:00:00:36:112:1 (Use in Golden Device)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 4) iwpriv ra1 set ATEConTxETxBfInitProc=02:00:00:01:02:18:36:112:1:04000\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 5) iwpriv ra1 set ATETXEBF=1 (Tx packet apply BF On)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 6) iwpriv ra1 set ATE=TXFRAMESKB\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 7) iwpriv ra1 mac 820fa09c (check [15:0] eBF counter, if apply then nonzero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 8) check IQxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 9) iwpriv ra1 set ATETXEBF=0 (Tx packet apply BF Off)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("10) iwpriv ra1 mac 820fa09c (check [15:0] eBF counter, if not apply then zero)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("11) check Iqxel waveform\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================================================================\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" Method for Dynamical Control Tx Power\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================================================================\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 1) Follow ETxBF Certification Procedure to enable TxBf packet at first\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 2) Use command \"iwpriv ra0 set ATE=TXSTOP\" to stop Tx\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 3) Use command \"iwpriv ra0 set ATETXPOW0=XX\" to configure Tx Power DAC value for OFDM 54M\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" 4) USe command \"ra0 set ATE=TXFRAMESKB\" to start continuous packet Tx\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("=============================================================================================\n")); + return status; +} + + +#endif /* TXBF_SUPPORT && MT_MAC */ + + +INT32 SetATEHelp(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXCARS, TXFRAME, RXFRAME\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATEDA\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATESA\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATEBSSID\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATECHANNEL, range:0~14\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXPOW0, set power level of antenna 1.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXPOW1, set power level of antenna 2.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXCNT, set how many frame going to transmit.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXMCS, set MCS, reference to rate table.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, 4:VHT, reference to rate table.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATETXGI, set GI interval, 0:Long, 1:Short\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATERRF, show all RF registers.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATELDE2P, load EEPROM from .bin file.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATERE2P, display all EEPROM content.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATEAUTOALC, enable ATE auto Tx alc (Tx auto level control).\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATEIPG, set ATE Tx frame IPG.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATEPAYLOAD, set ATE payload pattern for TxFrame.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATESHOW, display all parameters of ATE.\n")); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ATEHELP, online help.\n")); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 ATESampleRssi(PRTMP_ADAPTER pAd, RXWI_STRUC *pRxWI) +{ + INT32 Ret = 0; + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +#ifdef RTMP_PCI_SUPPORT +PNDIS_PACKET ATEPayloadInit(RTMP_ADAPTER *pAd, UINT32 TxIdx) +{ + return NULL; +} +#endif /* RTMP_MAC_PCI */ + +#ifdef RTMP_PCI_SUPPORT +INT32 ATEPayloadAlloc(PRTMP_ADAPTER pAd, UINT32 Index) +{ + return NDIS_STATUS_SUCCESS; +} +#endif /* RTMP_MAC_PCI */ + +INT32 ATEInit(RTMP_ADAPTER *pAd) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + NdisZeroMemory(ATECtrl, sizeof(*ATECtrl)); +#ifdef DBDC_MODE + NdisZeroMemory(&ATECtrl->band_ext[0], sizeof(struct _BAND_INFO)); +#endif /* DBDC_MODE */ + + ATECtrl->Mode = ATE_STOP; + ATECtrl->TxCount = 0xFFFFFFFF; + ATECtrl->payload[0] = 0xAA; + ATECtrl->FixedPayload = 1; + ATECtrl->TxLength = 1058;/* 1058 : sync with QA */ + ATECtrl->BW = BW_20; + ATECtrl->PhyMode = MODE_OFDM; + ATECtrl->Mcs = 7; + ATECtrl->Sgi = 0;/* LONG GI : 800 ns*/ + if (BOARD_IS_5G_ONLY(pAd)) + ATECtrl->Channel = 36; + else + ATECtrl->Channel = 1; + ATECtrl->TxAntennaSel = 1; + ATECtrl->RxAntennaSel = 0; + ATECtrl->QID = QID_AC_BE; + ATECtrl->Addr1[0] = 0x00; + ATECtrl->Addr1[1] = 0x11; + ATECtrl->Addr1[2] = 0x22; + ATECtrl->Addr1[3] = 0xAA; + ATECtrl->Addr1[4] = 0xBB; + ATECtrl->Addr1[5] = 0xCC; + NdisMoveMemory(ATECtrl->Addr2, ATECtrl->Addr1, MAC_ADDR_LEN); + NdisMoveMemory(ATECtrl->Addr3, ATECtrl->Addr1, MAC_ADDR_LEN); + ATECtrl->bQAEnabled = FALSE; + ATECtrl->bQATxStart = FALSE; + ATECtrl->bQARxStart = FALSE; + ATECtrl->TxDoneCount = 0; + ATECtrl->duty_cycle = 0; + ATECtrl->tx_time_param.pkt_tx_time_en = FALSE; + ATECtrl->tx_time_param.pkt_tx_time = 0; + ATECtrl->ipg_param.ipg = 0; + ATECtrl->ipg_param.sig_ext = SIG_EXTENSION; + ATECtrl->ipg_param.slot_time = DEFAULT_SLOT_TIME; + ATECtrl->ipg_param.sifs_time = DEFAULT_SIFS_TIME; + ATECtrl->ipg_param.ac_num = QID_AC_BE; + ATECtrl->ipg_param.aifsn = MIN_AIFSN; + ATECtrl->ipg_param.cw = MIN_CW; + ATECtrl->ipg_param.txop = 0; + ATECtrl->control_band_idx = 0; /* Control band0 as default setting */ + /* Assign wdev_idx */ + ATECtrl->wdev_idx = 0; + ATECtrl->wmm_idx = 0; /* Need to modify after j mode implement done */ +#ifdef DBDC_MODE + ATECtrl->band_ext[0].wdev_idx = 1; + ATECtrl->band_ext[0].wmm_idx = 1; +#endif /* DBDC_MODE */ +#ifdef TXBF_SUPPORT + ATECtrl->eTxBf = FALSE; + ATECtrl->iTxBf = FALSE; +#endif + ATECtrl->TemplateFrame = TemplateFrame; +#ifdef MT_MAC + Ret = MT_ATEInit(pAd); +#endif +#ifdef CONFIG_QA + ATECtrl->TxStatus = 0; +#endif + return Ret; +} + +INT32 ATEExit(RTMP_ADAPTER *pAd) +{ + INT32 Ret = 0; + +#ifdef MT_MAC + Ret = MT_ATEExit(pAd); +#endif + return Ret; +} + +VOID ATEPeriodicExec(PVOID SystemSpecific1, PVOID FunctionContext, + PVOID SystemSpecific2, PVOID SystemSpecific3) +{ +} + +INT32 SetATE( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 mode = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Arg = %s\n", __func__, Arg)); + + mode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mode); + + if (!strcmp(Arg, "ATESTART") && (mode != ATE_START)) { /* support restart w/o ATESTOP */ + if (mode & fATE_TXCONT_ENABLE) { + /* TODO Get Correct TxfdMode*/ + UINT32 TxfdMode = 1; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Stop Continuous Tx\n", __func__)); + Ret += ATEOp->StopContinousTx(pAd, TxfdMode); + } + + if (mode & fATE_TXCARRSUPP_ENABLE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Stop Carrier Suppression Test\n", __func__)); + Ret += ATEOp->StopTxTone(pAd); + } + + /* MT76x6 Test Mode Freqency offset restore*/ + if (ATECtrl->en_man_set_freq) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MT76x6 Manual Set Frequency Restore\n")); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_ENABLE); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_VALUE); + ATECtrl->en_man_set_freq = 0; + } + + if (Ret) + goto err1; + +#if (defined(MT_MAC) && (!defined(MT7636))) +#ifdef TXBF_SUPPORT + /* Before going into ATE mode, stop sounding first */ + mt_Trigger_Sounding_Packet(pAd, + FALSE, + 0, + 0, + 0, + NULL); +#endif /* TXBF_SUPPORT */ +#endif /* MAC && undefined MT7636 */ + Ret = ATEOp->ATEStart(pAd); + } else if (!strcmp(Arg, "ATESTOP") && (mode & ATE_START)) + Ret = ATEOp->ATEStop(pAd); + else if (!strcmp(Arg, "TRXENABLE") && (mode & ATE_START)) + MtATESetMacTxRx(pAd, ASIC_MAC_TXRX, TRUE, control_band_idx); + else if (!strcmp(Arg, "TRXDISABLE") && (mode & ATE_START)) + MtATESetMacTxRx(pAd, ASIC_MAC_TXRX, FALSE, control_band_idx); + else if (!strcmp(Arg, "TXSTREAM") && (mode & ATE_START)) + MtATESetTxStream(pAd, 3, control_band_idx); + else if (!strcmp(Arg, "RXSTREAM") && (mode & ATE_START)) + MtATESetRxPath(pAd, 1, control_band_idx); + else if (!strcmp(Arg, "APSTOP") && (mode == ATE_STOP)) + Ret = ATEOp->ATEStart(pAd); + else if (!strcmp(Arg, "APSTART") && (mode & ATE_START)) + Ret = ATEOp->ATEStop(pAd); + else if (!strcmp(Arg, "TXFRAME") && (mode & ATE_START)) + Ret = ATEOp->StartTx(pAd); + +#if defined(TXBF_SUPPORT) && defined(MT_MAC) + else if (!strcmp(Arg, "TXFRAMESKB") && (mode & ATE_START)) + Ret = ATEOp->StartTxSKB(pAd); + +#endif /* defined(TXBF_SUPPORT) && defined(MT_MAC) */ + else if (!strcmp(Arg, "RXFRAME") && (mode & ATE_START)) + Ret = ATEOp->StartRx(pAd); + else if (!strcmp(Arg, "TXSTOP") && (mode & ATE_START)) + Ret = ATEOp->StopTx(pAd); + else if (!strcmp(Arg, "RXSTOP") && (mode & ATE_START)) + Ret = ATEOp->StopRx(pAd); + else if (!strcmp(Arg, "TXCONT") && (mode & ATE_START)) { + /* 0: All 1:TX0 2:TX1 */ + /* TODO: Correct band selection */ + UINT32 ant = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + /* TODO Get Correct TxfdMode*/ + UINT32 TxfdMode = 3; /* continuous payload OFDM/CCK */ + Ret = ATEOp->StartContinousTx(pAd, ant, TxfdMode); + mode |= ATE_TXCONT; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mode, mode); + } else if (!strcmp(Arg, "TXCONTSTOP") && (mode & ATE_START)) { + if (mode & fATE_TXCONT_ENABLE) { + /* TODO Get Correct TxfdMode*/ + UINT32 TxfdMode = 3; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Stop Continuous Tx\n", __func__)); + ATEOp->StopContinousTx(pAd, TxfdMode); + } + + mode &= ~ATE_TXCONT; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mode, mode); + } else if (!strcmp(Arg, "TXCARRSUPP") && (mode & ATE_START)) { + INT32 pwr1 = 0xf; + INT32 pwr2 = 0; + UINT32 ant = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + + /* 0: All 1:TX0 2:TX1 */ + switch (ant) { + case 0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: not support two 2 TXCARR\n", __func__)); + break; + + case 1: + if (ATECtrl->TxPower0 > 30) + pwr2 = (ATECtrl->TxPower0 - 30) << 1; + else { + pwr1 = (ATECtrl->TxPower0 & 0x1e) >> 1; + pwr2 = (ATECtrl->TxPower0 & 0x01) << 1; + } + + ATEOp->StartTxTone(pAd, WF0_TX_TWO_TONE_5M); + break; + + case 2: + if (ATECtrl->TxPower1 > 30) + pwr2 = (ATECtrl->TxPower1 - 30) << 1; + else { + pwr1 = (ATECtrl->TxPower1 & 0x1e) >> 1; + pwr2 = (ATECtrl->TxPower1 & 0x01) << 1; + } + + ATEOp->StartTxTone(pAd, WF1_TX_TWO_TONE_5M); + break; + } + + ATEOp->SetTxTonePower(pAd, pwr1, pwr2); + mode |= ATE_TXCARRSUPP; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mode, mode); + } else if (!strcmp(Arg, "FW_MODE_RFTEST") && (mode & ATE_START)) { + MtCmdRfTestSwitchMode(pAd, OPERATION_RFTEST_MODE, 0, RF_TEST_DEFAULT_RESP_LEN); + } else if (!strcmp(Arg, "FW_MODE_NORMAL") && (mode & ATE_START)) { + MtCmdRfTestSwitchMode(pAd, OPERATION_NORMAL_MODE, 0, RF_TEST_DEFAULT_RESP_LEN); + } else if (!strcmp(Arg, "TXCWTONESTART") && (mode & ATE_START)) { + ATEOp->TxCWTone(pAd, 1); + } else if (!strcmp(Arg, "TXCWTONESTOP") && (mode & ATE_START)) { + ATEOp->TxCWTone(pAd, 0); + } else if (!strcmp(Arg, "TXCARR") && (mode & ATE_START)) { + INT32 pwr1 = 0xf; + INT32 pwr2 = 0; + UINT32 ant = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + + switch (ant) { + case 0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: not support two 2 TXCARR\n", __func__)); + break; + + case 1: + if (ATECtrl->TxPower0 > 30) + pwr2 = (ATECtrl->TxPower0 - 30) << 1; + else { + pwr1 = (ATECtrl->TxPower0 & 0x1e) >> 1; + pwr2 = (ATECtrl->TxPower0 & 0x01) << 1; + } + + ATEOp->StartTxTone(pAd, WF0_TX_ONE_TONE_DC); + break; + + case 2: + if (ATECtrl->TxPower1 > 30) + pwr2 = (ATECtrl->TxPower1 - 30) << 1; + else { + pwr1 = (ATECtrl->TxPower1 & 0x1e) >> 1; + pwr2 = (ATECtrl->TxPower1 & 0x01) << 1; + } + + ATEOp->StartTxTone(pAd, WF1_TX_ONE_TONE_DC); + break; + } + + ATEOp->SetTxTonePower(pAd, pwr1, pwr2); + mode |= ATE_TXCARR; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mode, mode); + } + +#ifdef TXBF_SUPPORT + else if (!strcmp(Arg, "MUENABLE")) { + ATECtrl->mu_enable = TRUE; + ATECtrl->mu_usrs = 4; + TESTMODE_SET_PARAM(ATECtrl, 0, eTxBf, 1); + } else if (!strcmp(Arg, "MUDISABLE")) { + ATECtrl->mu_enable = FALSE; + ATECtrl->mu_usrs = 0; + TESTMODE_SET_PARAM(ATECtrl, 0, eTxBf, 0); + AsicSetMacTxRx(pAd, ASIC_MAC_TX, TRUE); + } else if (!strcmp(Arg, "BFENABLE")) + TESTMODE_SET_PARAM(ATECtrl, 0, eTxBf, 1); + else if (!strcmp(Arg, "BFDISABLE")) + TESTMODE_SET_PARAM(ATECtrl, 0, eTxBf, 0); + +#endif +#ifdef PRE_CAL_MT7622_SUPPORT + else if (!strcmp(Arg, "TXDPD7622") && (mode & ATE_START)) { + Ret = ATEOp->TxDPDTest7622(pAd, "0"); + Ret = 0; + } +#endif /*PRE_CAL_MT7622_SUPPORT*/ +#ifdef PRE_CAL_TRX_SET1_SUPPORT + else if (!strcmp(Arg, "RX2GSELFTEST") && (mode & ATE_START)) { + Ret = ATEOp->RxSelfTest(pAd, "0"); + Ret = 0; + } else if (!strcmp(Arg, "RX5GSELFTEST") && (mode & ATE_START)) { + Ret = ATEOp->RxSelfTest(pAd, "1"); + Ret = 0; + } else if (!strcmp(Arg, "RXSELFTEST") && (mode & ATE_START)) { + Ret = ATEOp->RxSelfTest(pAd, "2"); + Ret = 0; + } else if (!strcmp(Arg, "TX2GDPD") && (mode & ATE_START)) { + Ret = ATEOp->TxDPDTest(pAd, "0"); + Ret = 0; + } else if (!strcmp(Arg, "TX5GDPD") && (mode & ATE_START)) { + Ret = ATEOp->TxDPDTest(pAd, "1"); + Ret = 0; + } else if (!strcmp(Arg, "TXDPD") && (mode & ATE_START)) { + Ret = ATEOp->TxDPDTest(pAd, "2"); + Ret = 0; + } +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ +#ifdef PRE_CAL_TRX_SET2_SUPPORT + else if ((strcmp(Arg, "PRECAL") > 0) && (mode & ATE_START)) { + UINT32 ChGrpId = 0; + + Ret = sscanf(Arg + strlen("PRECAL") + 1, "%d", &ChGrpId); + if (Ret == 1) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: ChGrpId %d\n", + __func__, ChGrpId)); + + Ret = ATEOp->PreCalTest(pAd, 0, ChGrpId); + Ret = 0; + } else if ((strcmp(Arg, "PRECALTX") > 0) && (mode & ATE_START)) { + UINT32 ChGrpId = 0; + + Ret = sscanf(Arg + strlen("PRECALTX") + 1, "%d", &ChGrpId); + if (Ret == 1) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: ChGrpId %d\n", + __func__, ChGrpId)); + Ret = ATEOp->PreCalTest(pAd, 1, ChGrpId); + Ret = 0; + } +#endif /* PRE_CAL_TRX_SET2_SUPPORT */ + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: do nothing(param = (%s), mode = (%d))\n", + __func__, Arg, ATECtrl->Mode)); + } + + if (!Ret) + return TRUE; + +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:- RF-test stop fail, ret:%d\n", __func__, Ret)); + return FALSE; +} + + +INT32 SetATEChannel( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + INT32 Ret = 0; + const INT idx_num = 4; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 param[idx_num]; + INT i = 0; + CHAR *value; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx:%x, Channel = %s\n", + __func__, control_band_idx, Arg)); + + for (i = 0; i < idx_num; i++) + param[i] = 0; + + for (i = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":")) { + if (i == idx_num) + break; + + param[i++] = simple_strtol(value, 0, 10); + } + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Channel, param[0]); +#ifdef DOT11_VHT_AC + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Channel_2nd, param[3]); +#endif + Ret = ATEOp->SetChannel(pAd, param[0], param[2], 0, param[1]); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +#ifdef MT7615 +INT32 set_ate_channel_ext(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ +#define ATE_SET_CH_EXT_PARAM_CNT 8 + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + struct _HQA_EXT_SET_CH param; + INT32 ret = 0; + UINT32 len = 0; + UINT32 pri_ch = 0; + UINT32 band_idx = 0; + UINT32 bw = 0; + UINT32 per_pkt_bw = 0; + INT i = 0; + CHAR *value; + UINT32 data[ATE_SET_CH_EXT_PARAM_CNT] = {0}; + + len = strlen(arg); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Arg = %s\n", __func__, arg)); + + for (i = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":")) { + if (i == ATE_SET_CH_EXT_PARAM_CNT) + break; + + data[i] = simple_strtol(value, 0, 10); + i++; + } + + if (i == ATE_SET_CH_EXT_PARAM_CNT) { + param.band_idx = data[0]; + param.central_ch0 = data[1]; + param.central_ch1 = data[2]; + param.sys_bw = data[3]; + param.perpkt_bw = data[4]; + param.pri_sel = data[5]; + param.reason = data[6]; + param.ch_band = data[7]; + } else + return ret; + + if ((param.band_idx == 0) || (param.band_idx > TESTMODE_BAND_NUM)) { + ret = NDIS_STATUS_INVALID_DATA; + goto err0; + } + + band_idx = param.band_idx; + + switch (param.sys_bw) { + case ATE_BAND_WIDTH_20: + bw = BAND_WIDTH_20; + break; + + case ATE_BAND_WIDTH_40: + bw = BAND_WIDTH_40; + break; + + case ATE_BAND_WIDTH_80: + bw = BAND_WIDTH_80; + break; + + case ATE_BAND_WIDTH_10: + bw = BAND_WIDTH_10; + break; + + case ATE_BAND_WIDTH_5: + bw = BAND_WIDTH_5; + break; + + case ATE_BAND_WIDTH_160: + bw = BAND_WIDTH_160; + break; + + case ATE_BAND_WIDTH_8080: + bw = BAND_WIDTH_8080; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: Cannot find BW with param.sys_bw:%x\n", + __func__, param.sys_bw)); + bw = param.sys_bw; + break; + } + + switch (param.perpkt_bw) { + case ATE_BAND_WIDTH_20: + per_pkt_bw = BAND_WIDTH_20; + break; + + case ATE_BAND_WIDTH_40: + per_pkt_bw = BAND_WIDTH_40; + break; + + case ATE_BAND_WIDTH_80: + per_pkt_bw = BAND_WIDTH_80; + break; + + case ATE_BAND_WIDTH_10: + per_pkt_bw = BAND_WIDTH_10; + break; + + case ATE_BAND_WIDTH_5: + per_pkt_bw = BAND_WIDTH_5; + break; + + case ATE_BAND_WIDTH_160: + case ATE_BAND_WIDTH_8080: + per_pkt_bw = BAND_WIDTH_160; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: Cannot find BW with param.sys_bw:%x\n", + __func__, param.sys_bw)); + per_pkt_bw = bw; + break; + } + + /* Set Param */ + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Channel, param.central_ch0); +#ifdef DOT11_VHT_AC + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Channel_2nd, param.central_ch1); +#endif + TESTMODE_SET_PARAM(ate_ctrl, band_idx, PerPktBW, per_pkt_bw); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, BW, bw); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, PriSel, param.pri_sel); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Ch_Band, param.ch_band); + ret = ate_ops->SetChannel(pAd, param.central_ch0, param.pri_sel, param.reason, param.ch_band); + + if (ret == 0) + ret = TRUE; + +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%x, band_idx:%x, ch0:%u, ch1:%u, sys_bw:%x, bw_conver:%x, ", + __func__, len, param.band_idx, + param.central_ch0, param.central_ch1, param.sys_bw, bw)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("perpkt_bw:%x, pri_sel:%x, pri_ch:%u\n", + param.perpkt_bw, param.pri_sel, pri_ch)); + return ret; +} + + +INT32 set_ate_start_tx_ext(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ +#define ATE_START_TX_EXT_PARAM_CNT 14 + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + struct _HQA_EXT_TXV param; + ATE_TXPOWER TxPower; + INT32 ret = 0; + INT32 len = 0; + UINT32 band_idx = 0; + UINT32 Channel = 0, Ch_Band = 0, SysBw = 0, PktBw = 0; + INT i = 0; + CHAR *value; + UINT32 data[ATE_START_TX_EXT_PARAM_CNT] = {0}; + + len = strlen(arg); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Arg = %s\n", __func__, arg)); + + for (i = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":")) { + if (i == ATE_START_TX_EXT_PARAM_CNT) + break; + + data[i] = simple_strtol(value, 0, 10); + i++; + } + + if (i == ATE_START_TX_EXT_PARAM_CNT) { + param.band_idx = data[0]; + param.pkt_cnt = data[1]; + param.phymode = data[2]; + param.rate = data[3]; + param.pwr = data[4]; + param.stbc = data[5]; + param.ldpc = data[6]; + param.ibf = data[7]; + param.ebf = data[8]; + param.wlan_id = data[9]; + param.aifs = data[10]; + param.gi = data[11]; + param.tx_path = data[12]; + param.nss = data[13]; + } else + return ret; + + band_idx = param.band_idx; + + if (!param.pkt_cnt) + param.pkt_cnt = 0x8fffffff; + + TESTMODE_SET_PARAM(ate_ctrl, band_idx, TxCount, param.pkt_cnt); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, PhyMode, param.phymode); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Mcs, param.rate); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Stbc, param.stbc); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Ldpc, param.ldpc); +#ifdef TXBF_SUPPORT + TESTMODE_SET_PARAM(ate_ctrl, band_idx, iTxBf, param.ibf); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, eTxBf, param.ebf); +#endif + ate_ctrl->wcid_ref = param.wlan_id; + TESTMODE_SET_PARAM(ate_ctrl, band_idx, ipg_param.ipg, param.aifs); /* Fix me */ + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Sgi, param.gi); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, TxAntennaSel, param.tx_path); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Nss, param.nss); + Channel = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Channel); + Ch_Band = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Ch_Band); + PktBw = TESTMODE_GET_PARAM(ate_ctrl, band_idx, PerPktBW); + SysBw = TESTMODE_GET_PARAM(ate_ctrl, band_idx, BW); + + if (param.rate == 32 && PktBw != BAND_WIDTH_40 && SysBw != BAND_WIDTH_40) { + ret = -1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Bandwidth must to be 40 at MCS 32\n", __func__)); + goto err0; + } + + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = param.pwr; + TxPower.Channel = Channel; + TxPower.Dbdc_idx = band_idx; + TxPower.Band_idx = Ch_Band; + ret = ate_ops->SetTxPower0(pAd, TxPower); + ret = ate_ops->SetIPG(pAd); + ret = ate_ops->StartTx(pAd); + + if (ret == 0) + ret = TRUE; + +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: band_idx:%u, pkt_cnt:%u, phy:%u, mcs:%u, stbc:%u, ldpc:%u\n", + __func__, param.band_idx, param.pkt_cnt, param.phymode, + param.rate, param.stbc, param.ldpc)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ibf:%u, ebf:%u, wlan_id:%u, aifs:%u, gi:%u, tx_path:%x, nss:%x\n", + __func__, param.ibf, param.ebf, param.wlan_id, param.aifs, + param.gi, param.tx_path, param.nss)); + return ret; +} +#endif /* MT7615 */ + + +INT32 SetATETxBw( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + UINT16 system_bw, per_pkt_bw; + const INT idx_num = 2; + UINT32 param[idx_num]; + INT i = 0; + CHAR *value; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Bw = %s\n", __func__, Arg)); + + /* Initialization */ + for (i = 0; i < idx_num; i++) + param[i] = BAND_WIDTH_NUM; + + for (i = 0, value = rstrtok(Arg, ":"); value; value = rstrtok(NULL, ":")) { + if (i == idx_num) + break; + + param[i++] = simple_strtol(value, 0, 10); + } + + system_bw = param[0]; + per_pkt_bw = param[1]; + + Ret = ATEOp->SetBW(pAd, system_bw, per_pkt_bw); + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +VOID rtmp_ate_init(RTMP_ADAPTER *pAd) +{ + + if (ATEInit(pAd) != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: ATE initialization failed !\n", __func__)); + ATEExit(pAd); + return; + } +} + + +VOID RTMPCfgTssiGainFromEEPROM(RTMP_ADAPTER *pAd) +{ + USHORT value; + + RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_GAIN_AND_ATTENUATION, value); + value = (value & 0x00FF); + pAd->TssiGain = 0x03; /* RT5392 uses 3 as TSSI gain/attenuation default value */ + + if ((value != 0x00) && (value != 0xFF)) + pAd->TssiGain = (UCHAR) (value & 0x000F); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: EEPROM_TSSI_GAIN_AND_ATTENUATION = 0x%X, pAd->TssiGain=0x%x\n", + __func__, value, pAd->TssiGain)); +} + + +#ifdef SINGLE_SKU_V2 +INT32 SetATESingleSKUEn( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + BOOLEAN fgSKUEn = FALSE; +#ifdef DBDC_MODE + struct _BAND_INFO *Info = &(ATECtrl->band_ext[0]); +#endif /* DBDC_MODE */ + fgSKUEn = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: fgSKUEn: %d, control_band_idx: %d\n", + __func__, fgSKUEn, control_band_idx)); + + /* Update SKU Status in ATECTRL Structure */ + if (BAND0 == control_band_idx) + ATECtrl->fgTxPowerSKUEn = fgSKUEn; +#ifdef DBDC_MODE + else if (BAND1 == control_band_idx) + Info->fgTxPowerSKUEn = fgSKUEn; +#endif /* DBDC_MODE */ + +#ifdef CONFIG_HW_HAL_OFFLOAD + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_SINGLE_SKU, fgSKUEn); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + if (!Ret) + return TRUE; + else + return FALSE; +} +#endif /* SINGLE_SKU_V2 */ + + +INT32 SetATEBFBackoffMode( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ + pAd->ucBFBackOffMode = simple_strtol(Arg, 0, 10); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ucBFBackOffMode: %d\n", __func__, pAd->ucBFBackOffMode)); + return TRUE; +} + +INT32 SetATETempCompEn( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + INT32 Ret = 0; + BOOLEAN fgTempCompEn = FALSE; + + fgTempCompEn = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: fgTempCompEn: %d\n", __func__, fgTempCompEn)); + +#ifdef CONFIG_HW_HAL_OFFLOAD + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_TEMP_COMP, fgTempCompEn); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEPowerPercentEn( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + BOOLEAN fgPowerPercentEn = FALSE; +#ifdef DBDC_MODE + struct _BAND_INFO *Info = &(ATECtrl->band_ext[0]); +#endif /* DBDC_MODE */ + fgPowerPercentEn = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: fgPowerPercentEn: %d\n", __func__, fgPowerPercentEn)); + + /* Update Percentage Status in ATECTRL Structure */ + if (BAND0 == control_band_idx) + ATECtrl->fgTxPowerPercentageEn = fgPowerPercentEn; +#ifdef DBDC_MODE + else if (BAND1 == control_band_idx) + Info->fgTxPowerPercentageEn = fgPowerPercentEn; +#endif /* DBDC_MODE */ + +#ifdef CONFIG_HW_HAL_OFFLOAD + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_POWER_PERCENTAGE, fgPowerPercentEn); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATEPowerPercentCtrl( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 PowerPercentLevel = 100; +#ifdef DBDC_MODE + struct _BAND_INFO *Info = &(ATECtrl->band_ext[0]); +#endif /* DBDC_MODE */ + PowerPercentLevel = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: PowerPercentLevel = %d\n", __func__, PowerPercentLevel)); + + /* Sanity check */ + if ((PowerPercentLevel < 0) || (PowerPercentLevel > 100)) + goto err0; + + /* Update TxPower Drop Status in ATECTRL Structure */ + if (BAND0 == control_band_idx) + ATECtrl->PercentageLevel = PowerPercentLevel; +#ifdef DBDC_MODE + else if (BAND1 == control_band_idx) + Info->PercentageLevel = PowerPercentLevel; +#endif /* DBDC_MODE */ + +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = ATEOp->SetPowerDropLevel(pAd, PowerPercentLevel); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + if (!Ret) + return TRUE; + +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Please input X which is 0~100\n", __func__)); + return FALSE; +} + + +INT32 SetATEBFBackoffEn( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + BOOLEAN fgBFBackoffEn = 0; +#ifdef DBDC_MODE + struct _BAND_INFO *Info = &(ATECtrl->band_ext[0]); +#endif /* DBDC_MODE */ + fgBFBackoffEn = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: fgBFBackoffEn: %d\n", __func__, fgBFBackoffEn)); + + /* Update BF Backoff Status in ATECTRL Structure */ + if (BAND0 == control_band_idx) + ATECtrl->fgTxPowerBFBackoffEn = fgBFBackoffEn; +#ifdef DBDC_MODE + else if (BAND1 == control_band_idx) + Info->fgTxPowerBFBackoffEn = fgBFBackoffEn; +#endif /* DBDC_MODE */ + +#ifdef CONFIG_HW_HAL_OFFLOAD + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_BF_BACKOFF, fgBFBackoffEn); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETSSIEn( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + INT32 Ret = 0; + BOOLEAN fgTSSIEn = 0; + + fgTSSIEn = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: fgBFBackoffEn: %d\n", __func__, fgTSSIEn)); + +#ifdef CONFIG_HW_HAL_OFFLOAD + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_TSSI, fgTSSIEn); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + if (!Ret) + return TRUE; + else + return FALSE; +} + + +INT32 SetATETxPowerCtrlEn( + PRTMP_ADAPTER pAd, + RTMP_STRING *Arg) +{ +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#endif /* CONFIG_HW_HAL_OFFLOAD */ + INT32 Ret = 0; + BOOLEAN fgTxPowerCtrlEn = 0; + + fgTxPowerCtrlEn = simple_strtol(Arg, 0, 10); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: fgTxPowerCtrlEn: %d\n", __func__, fgTxPowerCtrlEn)); + +#ifdef CONFIG_HW_HAL_OFFLOAD + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_TXPOWER_CTRL, fgTxPowerCtrlEn); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + + if (!Ret) + return TRUE; + else + return FALSE; +} + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/LoopBack.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/LoopBack.h new file mode 100644 index 000000000..2c168a8d7 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/LoopBack.h @@ -0,0 +1,99 @@ + +#ifndef _LOOPBACK_H_ +#define _LOOPBACK_H_ + +#define LOOPBACK_SIZE (10240*6) + + +enum _LOOPBACK_STATUS { + RUNNING = 0, + PASS, + FAIL +}; + +enum _LOOPBACK_FAIL { + NO_ERROR = 0, + TX_TIMEOUT, + RX_TIMEOUT, + BIT_TRUE_FAIL +}; + +struct _LOOPBACK_SETTING { + UINT32 StartLen; + UINT32 StopLen; + UINT32 RepeatTimes; /* 0 = infinite */ + UINT32 IsDefaultPattern; + /* #ifdef RTMP_USB_SUPPORT */ + UINT32 BulkOutNumber; + UINT32 BulkInNumber; + UINT32 TxAggNumber; + UINT32 RxAggPktLmt;/* pkt numbers */ + UINT32 RxAggLmt;/* pkt size */ + UINT32 RxAggTO;/* timeout (us) */ + UINT32 RxAggEnable; + /* #endif */ +}; +/* TODO:Unify */ +#if !defined(COMPOS_TESTMODE_WIN) +#define MAX_TX_BULK_PIPE_NUM 6 +#define MAX_RX_BULK_PIPE_NUM 2 +#endif +struct _LOOPBACK_RESULT { + UINT32 Status; /* 0 running, 1 pass , 2 fail */ + UINT32 FailReason; /* 0 no error, 1 TX timeout, 2 RX timeout, 3 bit true fail */ + UINT32 TxPktCount; + UINT32 RxPktCount; + UINT32 TxByteCount; /* 0 = infinite */ + UINT32 RxByteCount; + /* #ifdef RTMP_USB_SUPPORT */ + UINT32 LastBulkOut; + /* #endif */ +}; +struct _LOOPBACK_CTRL { + BOOLEAN DebugMode; + BOOLEAN LoopBackRunning; + BOOLEAN LoopBackWaitRx; + struct _LOOPBACK_RESULT LoopBackResult; + struct _LOOPBACK_SETTING LoopBackSetting; + UINT8 LoopBackBulkoutNumber; + UCHAR LoopBackTxRaw[LOOPBACK_SIZE]; + UCHAR LoopBackRxRaw[LOOPBACK_SIZE]; + UINT32 LoopBackTxRawLen; + UINT32 LoopBackRxRawLen; + UINT32 LoopBackExpectTxLen; + UINT32 LoopBackExpectRxLen; + UCHAR LoopBackExpectTx[LOOPBACK_SIZE]; + UCHAR LoopBackExpectRx[LOOPBACK_SIZE]; + NDIS_SPIN_LOCK LoopBackLock; + BOOLEAN LoopBackDefaultPattern; + RTMP_OS_TASK LoopBackTxTask; + RTMP_OS_COMPLETION LoopBackEvent; + BOOLEAN LoopBackUDMA; +#ifdef RTMP_PCI_SUPPORT + RTMP_OS_COMPLETION LoopBackPCITxEvent; +#endif +}; + +INT32 CheckFWROMWiFiSysOn(struct _RTMP_ADAPTER *pAd); + +void LoopBack_Start(struct _RTMP_ADAPTER *pAd, struct _LOOPBACK_SETTING *pSetting); +void LoopBack_Stop(struct _RTMP_ADAPTER *pAd); +void LoopBack_Status(struct _RTMP_ADAPTER *pAd, struct _LOOPBACK_RESULT *pResult); +void LoopBack_RawData(struct _RTMP_ADAPTER *pAd, UINT32 *pLength, BOOLEAN IsTx, UINT8 *pRawData); +void LoopBack_ExpectRx(struct _RTMP_ADAPTER *pAd, UINT32 Length, UINT8 *pRawData); +void LoopBack_ExpectTx(struct _RTMP_ADAPTER *pAd, UINT32 Length, UINT8 *pRawData); +void LoopBack_Run(struct _RTMP_ADAPTER *pAd, struct _LOOPBACK_SETTING *pSetting, UINT32 length); +void LoopBack_BitTrueCheck(struct _RTMP_ADAPTER *pAd); +void LoopBack_Fail(struct _RTMP_ADAPTER *pAd, enum _LOOPBACK_FAIL FailNum); +#ifdef COMPOS_TESTMODE_WIN /* TODO::Unify thread parameter */ +INT LoopBack_TxThread(IN OUT PVOID Context); +#else +INT LoopBack_TxThread(ULONG Context); +#endif +void LoopBack_Rx(struct _RTMP_ADAPTER *pAd, UINT32 pktlen, UINT8 *pData); +#ifdef RTMP_PCI_SUPPORT +void PCILoopBack_Run(struct _RTMP_ADAPTER *pAd, struct _LOOPBACK_SETTING *pSetting, UINT32 length); +INT32 ATECheckFWROMWiFiSysOn(struct _RTMP_ADAPTER *pAd); +#endif + +#endif /* _LOOPBACK_H_ */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/ate.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/ate.h new file mode 100644 index 000000000..b6a234666 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/ate.h @@ -0,0 +1,678 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + ate.h +*/ + +#ifndef __ATE_H__ +#define __ATE_H__ +#include "LoopBack.h" + +#ifdef MT7615 +#define ARBITRARY_CCK_OFDM_TX 1 +#endif +#ifndef COMPOS_TESTMODE_WIN +/* #define LOGDUMP_TO_FILE 1 */ +#define ATE_TXTHREAD 1 +#endif +#define IOCTLBUFF 2048 +#define ATE_ON(_p) ((((_p)->ATECtrl.Mode) & ATE_START) == ATE_START) +INT32 ATEInit(struct _RTMP_ADAPTER *pAd); +INT32 ATEExit(struct _RTMP_ADAPTER *pAd); + +#define FREQ_OFFSET_MANUAL_ENABLE 0x81021238 +#define FREQ_OFFSET_MANUAL_VALUE 0x81021234 + +/* For CA53 GPIO CR remap usage */ +#define CA53_GPIO_REMAP_SIZE 0x10 + +#ifdef ARBITRARY_CCK_OFDM_TX +/* MCU PTA CR */ +#define ANT_SWITCH_CON2 0x810600CC +#define ANT_SWITCH_CON3 0x810600D0 +#define ANT_SWITCH_CON4 0x810600D4 +#define ANT_SWITCH_CON6 0x810600DC +#define ANT_SWITCH_CON7 0x810600E0 +#define ANT_SWITCH_CON8 0x810600E4 +#endif + +/* + * Use bitmap to allow coexist of ATE_TXFRAME + * and ATE_RXFRAME(i.e.,to support LoopBack mode). + */ +#define fATE_IDLE (1 << 0) +#define fATE_TX_ENABLE (1 << 1) +#define fATE_RX_ENABLE (1 << 2) +#define fATE_TXCONT_ENABLE (1 << 3) +#define fATE_TXCARR_ENABLE (1 << 4) +#define fATE_TXCARRSUPP_ENABLE (1 << 5) +#define fATE_MPS (1 << 6) +#define fATE_FFT_ENABLE (1 << 7) +#define fATE_EXIT (1 << 8) +#define fATE_IN_RFTEST (1 << 9) +#define fATE_IN_BF (1 << 10) +#define fATE_IN_ICAPOVERLAP (1 << 11) +/* Stop Transmission */ +#define ATE_TXSTOP ((~(fATE_TX_ENABLE))&(~(fATE_TXCONT_ENABLE))&(~(fATE_TXCARR_ENABLE))&(~(fATE_TXCARRSUPP_ENABLE))&(~(fATE_MPS))) +/* Stop Receiving Frames */ +#define ATE_RXSTOP (~(fATE_RX_ENABLE)) + +/* 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) +/* MPS */ +#define ATE_MPS ((fATE_TX_ENABLE)|(fATE_MPS)) + +#define ATE_FFT ((fATE_FFT_ENABLE)|(fATE_IN_RFTEST)) + +#define BULK_OUT_LOCK(pLock, IrqFlags) \ + RTMP_IRQ_LOCK((pLock), IrqFlags) + +#define BULK_OUT_UNLOCK(pLock, IrqFlags) \ + RTMP_IRQ_UNLOCK((pLock), IrqFlags) + +/* WiFi PHY mode capability */ +#define PHYMODE_CAP_24G (WMODE_B | WMODE_G | WMODE_GN) +#define PHYMODE_CAP_5G (WMODE_A | WMODE_AN | WMODE_AC) +#define PHYMODE_CAP_DUAL_BAND (PHYMODE_CAP_24G | PHYMODE_CAP_5G) + +/* ContiTxTone */ +#define WF0_TX_ONE_TONE_5M 0x0 +#define WF0_TX_TWO_TONE_5M 0x1 +#define WF1_TX_ONE_TONE_5M 0x2 +#define WF1_TX_TWO_TONE_5M 0x3 +#define WF0_TX_ONE_TONE_10M 0x4 +#define WF1_TX_ONE_TONE_10M 0x5 +#define WF0_TX_ONE_TONE_DC 0x6 +#define WF1_TX_ONE_TONE_DC 0x7 + +#define MAX_TEST_PKT_LEN 1496 +#define MIN_TEST_PKT_LEN 25 +#define MAX_TEST_BKCR_NUM 30 + +/* For packet tx time, in unit of byte */ +#define MAX_HT_AMPDU_LEN 65000 +#define MAX_VHT_MPDU_LEN 6700 /* 11454 */ +#define DEFAULT_MPDU_LEN 4096 +#define MAX_MSDU_LEN 2304 +#define MIN_MSDU_LEN 22 +#define DEFAULT_MAC_HDR_LEN 24 +#define QOS_MAC_HDR_LEN 26 + +/* For ipg and duty cycle, in unit of us */ +#define SIG_EXTENSION 6 +#define DEFAULT_SLOT_TIME 9 +#define DEFAULT_SIFS_TIME 10 +#define MAX_SIFS_TIME 127 /* ICR has 7-bit only */ /* For the ATCR/TRCR limitation 8-bit/9-bit only*/ +#define MAX_AIFSN 0xF +#define MIN_AIFSN 0x1 +#define MAX_CW 0x10 +#define MIN_CW 0x0 +#define NORMAL_CLOCK_TIME 50 /* in uint of ns */ +#define BBP_PROCESSING_TIME 1500 /* in uint of ns */ + +/* The expected enqueue packet number in one time RX event trigger */ +#define ATE_ENQUEUE_PACKET_NUM 100 + +#if defined(MT7615) || defined(MT7622) +#define ATE_TESTPKT_LEN 13311 /* Setting max packet length to 13311 on MT7615 */ +#else +#define ATE_TESTPKT_LEN 4095 /* AMPDU delimiter 12 bit, maximum 4095 */ +#endif +#define ATE_MAX_PATTERN_SIZE 128 +#define TESTMODE_BAND0 0 +#define TESTMODE_BAND1 1 +#define ATE_BF_WCID 1 +#define ATE_BFMU_NUM 4 +struct _RTMP_ADAPTER; +struct _RX_BLK; + +#ifdef DBDC_MODE +#define IS_ATE_DBDC(_pAd) _pAd->CommonCfg.dbdc_mode +#define TESTMODE_BAND_NUM 2 +#else +#define IS_ATE_DBDC(_pAd) FALSE +#define TESTMODE_BAND_NUM 1 +#endif + +/* Antenna mode */ +#define ANT_MODE_DEFAULT 0 +#define ANT_MODE_SPE_IDX 1 + +#if !defined(COMPOS_TESTMODE_WIN) +/* Allow Sleep */ +#define TESTMODE_SEM struct semaphore +#define TESTMODE_SEM_INIT(_psem, _val) sema_init(_psem, _val) +#define TESTMODE_SEM_DOWN(_psem) down(_psem) +#define TESTMODE_SEM_DOWN_INTERRUPTIBLE(_psem) down_interruptible(_psem) +#define TESTMODE_SEM_DOWN_TRYLOCK(_psem) down_trylock(_psem) +#define TESTMODE_SEM_UP(_psem) up(_psem) +#endif + +enum _TESTMODE_MODE { + HQA_VERIFY, + ATE_LOOPBACK, + MODE_NUM +}; + +enum _MPS_PARAM_TYPE { + MPS_SEQDATA, + MPS_PHYMODE, + MPS_PATH, + MPS_RATE, + MPS_PAYLOAD_LEN, + MPS_TX_COUNT, + MPS_PWR_GAIN, + MPS_PARAM_NUM, + MPS_NSS, + MPS_PKT_BW, +}; + +struct _ATE_OPERATION { + INT32 (*ATEStart)(struct _RTMP_ADAPTER *pAd); + INT32 (*ATEStop)(struct _RTMP_ADAPTER *pAd); + INT32 (*StartTx)(struct _RTMP_ADAPTER *pAd); + INT32 (*StartRx)(struct _RTMP_ADAPTER *pAd); + INT32 (*StopTx)(struct _RTMP_ADAPTER *pAd); + INT32 (*StopRx)(struct _RTMP_ADAPTER *pAd); + INT32 (*SetTxPath)(struct _RTMP_ADAPTER *pAd); + INT32 (*SetRxPath)(struct _RTMP_ADAPTER *pAd); + INT32 (*SetTxPower0)(struct _RTMP_ADAPTER *pAd, struct _ATE_TXPOWER TxPower); + INT32 (*SetTxPower1)(struct _RTMP_ADAPTER *pAd, struct _ATE_TXPOWER TxPower); + INT32 (*SetTxPower2)(struct _RTMP_ADAPTER *pAd, struct _ATE_TXPOWER TxPower); + INT32 (*SetTxPower3)(struct _RTMP_ADAPTER *pAd, struct _ATE_TXPOWER TxPower); + INT32 (*SetTxForceTxPower)(struct _RTMP_ADAPTER *pAd, INT8 cTxPower, UINT8 ucPhyMode, UINT8 ucTxRate, UINT8 ucBW); + INT32 (*SetTxPowerX)(struct _RTMP_ADAPTER *pAd, struct _ATE_TXPOWER TxPower); + INT32 (*SetTxAntenna)(struct _RTMP_ADAPTER *pAd, UINT32 Ant); + INT32 (*SetRxAntenna)(struct _RTMP_ADAPTER *pAd, UINT32 Ant); + INT32 (*SetTxFreqOffset)(struct _RTMP_ADAPTER *pAd, UINT32 FreqOffset); + INT32 (*GetTxFreqOffset)(struct _RTMP_ADAPTER *pAd, UINT32 *FreqOffset); + INT32 (*SetChannel)(struct _RTMP_ADAPTER *pAd, INT16 Value, UINT32 pri_sel, UINT32 reason, UINT32 Ch_Band); + INT32 (*SetBW)(struct _RTMP_ADAPTER *pAd, UINT16 system_bw, UINT16 per_pkt_bw); + INT32 (*SetDutyCycle)(struct _RTMP_ADAPTER *pAd, UINT32 value); + INT32 (*SetPktTxTime)(struct _RTMP_ADAPTER *pAd, UINT32 value); + INT32 (*SampleRssi)(struct _RTMP_ADAPTER *pAd, struct _RX_BLK *pRxBlk); + INT32 (*SetIPG)(struct _RTMP_ADAPTER *pAd); + INT32 (*SetSlotTime)(struct _RTMP_ADAPTER *pAd, UINT32 SlotTime, UINT32 SifsTime); + INT32 (*SetAIFS)(struct _RTMP_ADAPTER *pAd, CHAR Value); + INT32 (*SetPowerDropLevel)(struct _RTMP_ADAPTER *pAd, UINT32 PowerDropLevel); + INT32 (*SetTSSI)(struct _RTMP_ADAPTER *pAd, CHAR WFSel, CHAR Setting); + INT32 (*LowPower)(struct _RTMP_ADAPTER *pAd, UINT32 Control); + INT32 (*SetDPD)(struct _RTMP_ADAPTER *pAd, CHAR WFSel, CHAR Setting); + INT32 (*StartTxTone)(struct _RTMP_ADAPTER *pAd, UINT32 Mode); + INT32 (*SetTxTonePower)(struct _RTMP_ADAPTER *pAd, INT32 pwr1, INT pwr2); + INT32 (*SetDBDCTxTonePower)(struct _RTMP_ADAPTER *pAd, INT32 pwr1, INT pwr2, UINT32 AntIdx); + INT32 (*StopTxTone)(struct _RTMP_ADAPTER *pAd); + INT32 (*StartContinousTx)(struct _RTMP_ADAPTER *pAd, CHAR WFSel, UINT32 TxfdMode); + INT32 (*StopContinousTx)(struct _RTMP_ADAPTER *pAd, UINT32 TxfdMode); + INT32 (*EfuseGetFreeBlock)(struct _RTMP_ADAPTER *pAd, UINT32 GetFreeBlock, UINT32 *Value); + INT32 (*EfuseAccessCheck)(struct _RTMP_ADAPTER *pAd, UINT32 offset, PUCHAR pData); + INT32 (*RfRegWrite)(struct _RTMP_ADAPTER *pAd, UINT32 WFSel, UINT32 Offset, UINT32 Value); + INT32 (*RfRegRead)(struct _RTMP_ADAPTER *pAd, UINT32 WFSel, UINT32 Offset, UINT32 *Value); + INT32 (*GetFWInfo)(struct _RTMP_ADAPTER *pAd, UCHAR *FWInfo); +#ifdef PRE_CAL_MT7622_SUPPORT + INT32 (*TxDPDTest7622)(struct _RTMP_ADAPTER *pAd, RTMP_STRING * arg); +#endif /*PRE_CAL_MT7622_SUPPORT*/ +#ifdef PRE_CAL_TRX_SET1_SUPPORT + INT32 (*RxSelfTest)(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); + INT32 (*TxDPDTest)(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ +#ifdef PRE_CAL_TRX_SET2_SUPPORT + INT32 (*PreCalTest)(struct _RTMP_ADAPTER *pAd, UINT8 CalId, UINT32 ChGrpId); +#endif /* PRE_CAL_TRX_SET2_SUPPORT */ +#if defined(TXBF_SUPPORT) && defined(MT_MAC) + INT32 (*SetATETxSoundingProc)(struct _RTMP_ADAPTER *pAd, UCHAR SoundingMode); + INT32 (*StartTxSKB)(struct _RTMP_ADAPTER *pAd); +#endif /* TXBF_SUPPORT && MT_MAC */ + INT32 (*MPSSetParm)(struct _RTMP_ADAPTER *pAd, enum _MPS_PARAM_TYPE data_type, INT32 items, UINT32 *data); + INT32 (*MPSTxStart)(struct _RTMP_ADAPTER *pAd); + INT32 (*MPSTxStop)(struct _RTMP_ADAPTER *pAd); + INT32 (*SetAutoResp)(struct _RTMP_ADAPTER *pAd, UCHAR *mac, UCHAR mode); + INT32 (*SetFFTMode)(struct _RTMP_ADAPTER *pAd, UINT32 mode); + INT32 (*onOffRDD)(struct _RTMP_ADAPTER *pAd, UINT32 rdd_num, UINT32 rdd_in_sel, UINT32 is_start); + INT32 (*SetCfgOnOff)(struct _RTMP_ADAPTER *pAd, UINT32 Type, UINT32 Enable); + INT32 (*GetCfgOnOff)(struct _RTMP_ADAPTER *pAd, UINT32 Type, UINT32 *Result); + INT32 (*SetRXFilterPktLen)(struct _RTMP_ADAPTER *pAd, UINT32 Enable, UINT32 RxPktLen); +#ifdef TXPWRMANUAL + INT32 (*SetTxPwrManual)(struct _RTMP_ADAPTER *pAd, BOOLEAN fgPwrManCtrl, UINT8 u1TxPwrModeManual, UINT8 u1TxPwrBwManual, UINT8 u1TxPwrRateManual, INT8 i1TxPwrValueManual, UCHAR Band); +#endif + INT32 (*DBDCTxTone)(struct _RTMP_ADAPTER *pAd, UINT32 Control, UINT32 AntIndex, UINT32 ToneType, UINT32 ToneFreq, INT32 DcOffset_I, INT32 DcOffset_Q, UINT32 Band); + INT32 (*TxCWTone)(struct _RTMP_ADAPTER *pAd, UINT32 Control); + INT32 (*GetTxPower)(struct _RTMP_ADAPTER *pAd, UINT32 Enable, UINT32 Ch_Band, UINT32 *EfuseAddr, UINT32 *Power); + INT32 (*BssInfoUpdate)(struct _RTMP_ADAPTER *pAd, UINT32 OwnMacIdx, UINT32 BssIdx, UCHAR *Bssid); + INT32 (*DevInfoUpdate)(struct _RTMP_ADAPTER *pAd, UINT32 OwnMacIdx, UCHAR *Bssid); + INT32 (*LogOnOff)(struct _RTMP_ADAPTER *pAd, UINT32 type, UINT32 on_off, UINT32 num_log); + INT32 (*SetICapStart)(struct _RTMP_ADAPTER *pAd, BOOLEAN Trigger, BOOLEAN RingCapEn, UINT32 Event, UINT32 Node, UINT32 Len, UINT32 StopCycle, UINT32 BW, UINT32 MACTriggerEvent, UINT32 SourceAddrLSB, UINT32 SourceAddrMSB, UINT32 Band); + INT32 (*GetICapStatus)(struct _RTMP_ADAPTER *pAd); + INT32 (*GetICapIQData)(struct _RTMP_ADAPTER *pAd, PINT32 pData, PINT32 pDataLen, UINT32 IQ_Type, UINT32 WF_Num); + INT32 (*SetAntennaPort)(struct _RTMP_ADAPTER *pAd, UINT32 RfModeMask, UINT32 RfPortMask, UINT32 AntPortMask); + INT32 (*ClockSwitchDisable)(struct _RTMP_ADAPTER *pAd, UINT8 isDisable); +}; + +struct _ATE_IF_OPERATION { + INT32 (*init)(struct _RTMP_ADAPTER *pAd); + INT32 (*clean_trx_q)(struct _RTMP_ADAPTER *pAd); + INT32 (*setup_frame)(struct _RTMP_ADAPTER *pAd, UINT32 q_idx); + INT32 (*test_frame_tx)(struct _RTMP_ADAPTER *pAd); + INT32 (*test_frame_rx)(struct _RTMP_ADAPTER *pAd); + INT32 (*ate_leave)(struct _RTMP_ADAPTER *pAd); +}; + +struct _HQA_MPS_SETTING { + UINT32 phy; + UINT32 pkt_len; + UINT32 pkt_cnt; + UINT32 pwr; + UINT32 nss; + UINT32 pkt_bw; +}; + +enum _TEST_BK_CR_TYPE { + TEST_EMPTY_BKCR = 0, + TEST_MAC_BKCR, + TEST_HIF_BKCR, + TEST_PHY_BKCR, + TEST_HW_BKCR, + TEST_MCU_BKCR, + TEST_BKCR_TYPE_NUM, +}; + +struct _TESTMODE_BK_CR { + ULONG offset; + UINT32 val; + enum _TEST_BK_CR_TYPE type; +}; + +struct _ATE_RXV_LOG { + RX_VECTOR1_1ST_CYCLE rxv1_1st; + RX_VECTOR1_2ND_CYCLE rxv1_2nd; + RX_VECTOR1_3TH_CYCLE rxv1_3rd; + RX_VECTOR1_4TH_CYCLE rxv1_4th; + RX_VECTOR1_5TH_CYCLE rxv1_5th; + RX_VECTOR1_6TH_CYCLE rxv1_6th; + RX_VECTOR2_1ST_CYCLE rxv2_1st; + RX_VECTOR2_2ND_CYCLE rxv2_2nd; + RX_VECTOR2_3TH_CYCLE rxv2_3rd; +}; + +#define ATE_RDD_LOG_SIZE 8 /* Pulse size * num of pulse = 8 * 32 for one event*/ +struct _ATE_RDD_LOG { + UINT32 u4Prefix; + UINT32 u4Count; + UINT8 byPass; + UINT8 aucBuffer[ATE_RDD_LOG_SIZE]; +}; + +#define ATE_RECAL_LOG_SIZE (CAL_ALL_LEN >> 3) +struct _ATE_LOG_RECAL { + UINT32 cal_idx; + UINT32 cal_type; + UINT32 cr_addr; + UINT32 cr_val; +}; + +enum { + ATE_LOG_RXV = 1, + ATE_LOG_RDD, + ATE_LOG_RE_CAL, + ATE_LOG_TYPE_NUM, + ATE_LOG_RXINFO, + ATE_LOG_TXDUMP, + ATE_LOG_TEST, +}; + +enum { + ATE_LOG_OFF, + ATE_LOG_ON, + ATE_LOG_DUMP, + ATE_LOG_CTRL_NUM, +}; + +#define fATE_LOG_RXV (1 << ATE_LOG_RXV) +#define fATE_LOG_RDD (1 << ATE_LOG_RDD) +#define fATE_LOG_RE_CAL (1 << ATE_LOG_RE_CAL) +#define fATE_LOG_RXINFO (1 << ATE_LOG_RXINFO) +#define fATE_LOG_TXDUMP (1 << ATE_LOG_TXDUMP) +#define fATE_LOG_TEST (1 << ATE_LOG_TEST) + +struct _ATE_LOG_DUMP_ENTRY { + UINT32 log_type; + UINT8 un_dumped; + union { + struct _ATE_RXV_LOG rxv; + struct _ATE_RDD_LOG rdd; + struct _ATE_LOG_RECAL re_cal; + } log; +}; + +struct _ATE_LOG_DUMP_CB { + NDIS_SPIN_LOCK lock; + UINT8 overwritable; + UINT8 is_dumping; + UINT8 is_overwritten; + INT32 idx; + INT32 len; + UINT32 recal_curr_type; +#ifdef LOGDUMP_TO_FILE + INT32 file_idx; + RTMP_OS_FD_EXT fd; +#endif + struct _ATE_LOG_DUMP_ENTRY *entry; +}; + +#define ATE_MPS_ITEM_RUNNING (1<<0) +struct _HQA_MPS_CB { + NDIS_SPIN_LOCK lock; + UINT32 mps_cnt; + UINT32 band_idx; + UINT32 stat; + BOOLEAN setting_inuse; + UINT32 ref_idx; + struct _HQA_MPS_SETTING *mps_setting; +}; + +struct _ATE_PFMU_INFO { + UCHAR wcid; + UCHAR bss_idx; + UCHAR up; + UCHAR addr[MAC_ADDR_LEN]; +}; + +#define ATE_RXV_SIZE 9 +#define ATE_ANT_NUM 4 + +struct _ATE_RX_STATISTIC { + INT32 FreqOffsetFromRx; + UINT32 RxTotalCnt[TESTMODE_BAND_NUM]; + UINT32 NumOfAvgRssiSample; + UINT32 RxMacFCSErrCount; + UINT32 RxMacMdrdyCount; + UINT32 RxMacFCSErrCount_band1; + UINT32 RxMacMdrdyCount_band1; + CHAR LastSNR[ATE_ANT_NUM]; /* last received SNR */ + CHAR LastRssi[ATE_ANT_NUM]; /* last received RSSI */ + CHAR AvgRssi[ATE_ANT_NUM]; /* last 8 frames' average RSSI */ + CHAR MaxRssi[ATE_ANT_NUM]; + CHAR MinRssi[ATE_ANT_NUM]; + SHORT AvgRssiX8[ATE_ANT_NUM]; /* sum of last 8 frames' RSSI */ + UINT32 RSSI[ATE_ANT_NUM]; + UINT32 SNR[ATE_ANT_NUM]; + UINT32 RCPI[ATE_ANT_NUM]; + UINT32 FAGC_RSSI_IB[ATE_ANT_NUM]; + UINT32 FAGC_RSSI_WB[ATE_ANT_NUM]; +#ifdef CFG_SUPPORT_MU_MIMO + UINT32 RxMacMuPktCount; +#endif + UINT32 SIG_MCS; + UINT32 SINR; + UINT32 RXVRSSI; +}; + +struct _ATE_TX_TIME_PARAM { + BOOLEAN pkt_tx_time_en; /* The packet transmission time feature enable or disable */ + UINT32 pkt_tx_time; /* The target packet transmission time */ + UINT32 pkt_tx_len; + UINT32 pkt_msdu_len; + UINT32 pkt_hdr_len; + UINT32 pkt_ampdu_cnt; + UINT8 pkt_need_qos; + UINT8 pkt_need_amsdu; + UINT8 pkt_need_ampdu; +}; + +struct _ATE_IPG_PARAM { + UINT32 ipg; /* The target idle time */ + UINT8 sig_ext; /* Only OFDM/HT/VHT need to consider sig_ext */ + UINT16 slot_time; + UINT16 sifs_time; + UINT8 ac_num; /* 0: AC_BK, 1: AC_BE, 2: AC_VI, 3: AC_VO */ + UINT8 aifsn; + UINT16 cw; + UINT16 txop; +}; + +#ifdef DBDC_MODE +struct _BAND_INFO { + UCHAR *pate_pkt; /* Buffer for TestPkt */ + PNDIS_PACKET pkt_skb; + UINT32 is_alloc_skb; + RTMP_OS_COMPLETION tx_wait; + UCHAR TxStatus; /* TxStatus : 0 --> task is idle, 1 --> task is running */ + UINT32 Mode; + UINT32 TxAntennaSel; + UINT32 RxAntennaSel; + UCHAR backup_channel; + UCHAR backup_phymode; + UCHAR wdev_idx; + UCHAR wmm_idx; + USHORT QID; + UCHAR Channel; + UCHAR Ch_Band; + UCHAR ControlChl; + UCHAR PriSel; + UINT32 OutBandFreq; + UCHAR Nss; + UCHAR BW; + UCHAR PerPktBW; + UCHAR PrimaryBWSel; + UCHAR PhyMode; + UCHAR Stbc; + UCHAR Ldpc; /* 0:BCC 1:LDPC */ + UCHAR Sgi; + UCHAR Mcs; + UCHAR Preamble; + UINT32 FixedPayload; /* Normal:0,Repeat:1,Random:2 */ + UINT32 TxLength; + UINT32 TxCount; + UINT32 TxDoneCount; /* Tx DMA Done */ + UINT32 TxedCount; + UINT32 RFFreqOffset; + UINT32 thermal_val; + UINT32 duty_cycle; + struct _ATE_TX_TIME_PARAM tx_time_param; + struct _ATE_IPG_PARAM ipg_param; +#ifdef TXBF_SUPPORT + UCHAR eTxBf; + UCHAR iTxBf; +#endif +#ifdef DOT11_VHT_AC + UCHAR Channel_2nd; +#endif + UCHAR FAGC_Path; + /* Tx frame */ + UCHAR TemplateFrame[32]; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR Addr3[MAC_ADDR_LEN]; + UCHAR payload[ATE_MAX_PATTERN_SIZE]; + UINT32 pl_len; + USHORT HLen; /* Header Length */ + USHORT seq; + struct _HQA_MPS_CB mps_cb; + BOOLEAN fgTxPowerSKUEn; /* SKU On/Off status */ + BOOLEAN fgTxPowerPercentageEn; /* Power Percentage On/Off status */ + BOOLEAN fgTxPowerBFBackoffEn; /* BF Backoff On/Off status */ + UINT32 PercentageLevel; /* TxPower Percentage Level */ + INT32 RF_Power; + INT32 Digital_Power; + INT32 DcOffset_I; + INT32 DcOffset_Q; +}; +#endif + +#ifdef ATE_TXTHREAD +#define ATE_THREAD_NUM 1 +struct _ATE_TXTHREAD_CB { + BOOLEAN is_init; + RTMP_OS_TASK task; + NDIS_SPIN_LOCK lock; + UINT32 tx_cnt; + UINT32 txed_cnt; + UCHAR service_stat; +}; +#endif + +struct _ATE_CTRL { + struct _ATE_OPERATION *ATEOp; + struct _ATE_IF_OPERATION *ATEIfOps; + enum _TESTMODE_MODE verify_mode; + struct _HQA_MPS_CB mps_cb; + UINT32 en_log; +#ifdef ATE_TXTHREAD + struct _ATE_TXTHREAD_CB tx_thread[1]; + UINT32 current_init_thread; + INT32 deq_cnt; +#endif +#ifdef DBDC_MODE + struct _BAND_INFO band_ext[1]; +#endif + UCHAR *pate_pkt; /* Buffer for TestPkt */ + PNDIS_PACKET pkt_skb; + UINT32 is_alloc_skb; + UINT32 Mode; + CHAR TxPower0; + CHAR TxPower1; + CHAR TxPower2; + CHAR TxPower3; + UINT32 TxAntennaSel; /* band0 => TX0/TX1 , band1 => TX2/TX3 */ + UINT32 RxAntennaSel; + UCHAR backup_channel; /* Backup normal driver's channel for recovering */ + UCHAR backup_phymode; /* Backup normal driver's phymode for recovering */ + UCHAR wdev_idx; + UCHAR wmm_idx; + USHORT QID; + UCHAR Channel; + UCHAR Ch_Band; + UCHAR ControlChl; + UCHAR PriSel; + UINT32 OutBandFreq; + UCHAR Nss; + UCHAR BW; + UCHAR PerPktBW; + UCHAR PrimaryBWSel; + UCHAR PhyMode; + UCHAR Stbc; + UCHAR Ldpc; /* 0:BCC 1:LDPC */ + UCHAR Sgi; + UCHAR Mcs; + UCHAR Preamble; + UCHAR Payload; /* Payload pattern */ + UINT32 FixedPayload; + UINT32 TxLength; + UINT32 TxCount; + UINT32 TxDoneCount; /* Tx DMA Done */ + UINT32 TxedCount; + UINT32 RFFreqOffset; + UINT32 thermal_val; + UINT32 duty_cycle; + struct _ATE_TX_TIME_PARAM tx_time_param; + struct _ATE_IPG_PARAM ipg_param; +#ifdef TXBF_SUPPORT + BOOLEAN fgEBfEverEnabled; + BOOLEAN fgBw160; + UCHAR eTxBf; + UCHAR iTxBf; + UCHAR *txbf_info; + UINT32 txbf_info_len; + UCHAR iBFCalStatus; +#endif +#ifdef INTERNAL_CAPTURE_SUPPORT + EXT_EVENT_RBIST_ADDR_T icap_info; +#endif /* INTERNAL_CAPTURE_SUPPORT */ +#ifdef DOT11_VHT_AC + UCHAR Channel_2nd; +#endif + /* Common part */ + UCHAR control_band_idx; /* The band_idx which user wants to control currently */ + /* Tx frame */ + UCHAR *TemplateFrame; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR Addr3[MAC_ADDR_LEN]; + UCHAR payload[ATE_MAX_PATTERN_SIZE]; + UINT32 pl_len; + USHORT HLen; /* Header Length */ + USHORT seq; + /* MU Related */ + BOOLEAN mu_enable; + UINT32 mu_usrs; + UINT8 wcid_ref; + struct _ATE_PFMU_INFO pfmu_info[ATE_BFMU_NUM]; + /* counters */ + UINT32 num_rxv; + UINT32 num_rxdata; + UINT32 num_rxv_fcs; + UINT32 num_rxdata_fcs; + struct _ATE_RX_STATISTIC rx_stat; + struct _ATE_LOG_DUMP_CB log_dump[ATE_LOG_TYPE_NUM]; + UCHAR FAGC_Path; + /* Flag */ + BOOLEAN txs_enable; + 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 need_set_pwr; /* For MPS switch power in right context */ + UCHAR TxStatus; /* TxStatus : 0 --> task is idle, 1 --> task is running */ + UCHAR did_tx; + UCHAR did_rx; + UCHAR en_man_set_freq; + /* Restore CR */ + struct _TESTMODE_BK_CR bk_cr[MAX_TEST_BKCR_NUM]; + /* OS related */ + RTMP_OS_COMPLETION tx_wait; + RTMP_OS_COMPLETION cmd_done; + ULONG cmd_expire; +#if !defined(COMPOS_TESTMODE_WIN) + RALINK_TIMER_STRUCT PeriodicTimer; + ULONG OneSecPeriodicRound; + ULONG PeriodicRound; + OS_NDIS_SPIN_LOCK TssiSemLock; +#endif + BOOLEAN fgTxPowerSKUEn; /* SKU On/Off status */ + BOOLEAN fgTxPowerPercentageEn; /* Power Percentage On/Off status */ + BOOLEAN fgTxPowerBFBackoffEn; /* BF Backoff On/Off status */ + UINT32 PercentageLevel; /* TxPower Percentage Level */ + INT32 RF_Power; + INT32 Digital_Power; + INT32 DcOffset_I; + INT32 DcOffset_Q; +}; + +#if !defined(COMPOS_TESTMODE_WIN) +VOID RtmpDmaEnable(RTMP_ADAPTER *pAd, INT Enable); + +VOID ATE_RTUSBBulkOutDataPacket( + IN PRTMP_ADAPTER pAd, + IN UCHAR BulkOutPipeId); + +VOID ATE_RTUSBCancelPendingBulkInIRP( + IN PRTMP_ADAPTER pAd); +#endif +INT MtATESetMacTxRx(struct _RTMP_ADAPTER *pAd, INT32 TxRx, BOOLEAN Enable, UCHAR BandIdx); +#if defined(TXBF_SUPPORT) && defined(MT_MAC) +INT SetATEApplyStaToMacTblEntry(RTMP_ADAPTER *pAd); +INT SetATEApplyStaToAsic(RTMP_ADAPTER *pAd); +#endif + +#endif /* __ATE_H__ */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/ate_agent.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/ate_agent.h new file mode 100644 index 000000000..9be98b43d --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/ate_agent.h @@ -0,0 +1,161 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + ate_agent.h +*/ + +#ifndef __ATE_AGENT_H__ +#define __ATE_AGENT_H__ + +struct _RTMP_ADAPTER; + +INT32 SetTxStop(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetRxStop(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +#ifdef DBG +VOID ATE_QA_Statistics(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *pRxWI, RXINFO_STRUC *pRxInfo, PHEADER_802_11 pHeader); +#ifdef CONFIG_QA +INT32 RtmpDoAte(struct _RTMP_ADAPTER *pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, RTMP_STRING *wrq_name); +#endif +#ifdef WCX_SUPPORT +INT32 do_meta_cmd(int ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, RTMP_STRING *wrq_name); +#endif +INT32 SetEERead(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetEEWrite(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetBBPRead(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetBBPWrite(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetRFWrite(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +#endif /* DBG */ +VOID rt_ee_read_all(struct _RTMP_ADAPTER *pAd, UINT16 *Data); +VOID rt_ee_write_all(struct _RTMP_ADAPTER pAd, UINT16 *Data); +VOID rt_ee_write_bulk(struct _RTMP_ADAPTER pAd, UINT16 *Data, UINT16 offset, UINT16 length); +INT32 SetATEQid(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEDeqCnt(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEMPSDump(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSPhyMode(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSRate(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSPath(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSPayloadLen(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSPktCnt(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSPwr(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSNss(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSPktBw(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATEMPSStart(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 SetATELOGEnable(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATELOGDump(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxSEnable(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATERxFilter(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATERxStream(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxStream(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEMACTRx(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATELOGDisable(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEDa(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATESa(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEBssid(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEInitChan(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetADCDump(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxPower0(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxPower1(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxPower2(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxPower3(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEForceTxPower(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxPowerEvaluation(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxAntenna(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATERxAntenna(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATERFPower(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEDigitalPower(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEDCOffset_I(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEDCOffset_Q(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 Default_Set_ATE_TX_FREQ_OFFSET_Proc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxFreqOffset(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 Default_Set_ATE_TX_BW_Proc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxLength(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxCount(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxMcs(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEVhtNss(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxLdpc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxStbc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxMode(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxGi(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATERxFer(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEReadRF(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATELoadE2p(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +#ifdef RTMP_EFUSE_SUPPORT +INT32 SetATELoadE2pFromBuf(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +#endif /* RTMP_EFUSE_SUPPORT */ +INT32 SetATEReadE2p(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEAutoAlc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxGi(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETempSensor(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEIpg(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEPayload(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEFixedPayload(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEAssocProc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#if defined(TXBF_SUPPORT) && defined(MT_MAC) +INT32 SetATETxBfDutInitProc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxBfGdInitProc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxPacketWithBf(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxBfChanProfileUpdate(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxBfProfileRead(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETXBFProc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxSoundingProc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEIBfGdCal(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEIBfInstCal(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEIBfProfileUpdate(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEEBfProfileConfig(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEIBfPhaseComp(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEIBfPhaseVerify(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxBfLnaGain(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxBfPhaseE2pUpdate(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEConTxETxBfGdProc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEConTxETxBfInitProc(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATESpeIdx(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEEBfTx(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEEBFCE(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEEBFCEInfo(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEEBFCEHelp(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 MT_ATEGenPkt(struct _RTMP_ADAPTER *pAd, UCHAR *buf, UINT32 band_idx); +#endif /* TXBF_SUPPORT && MT_MAC */ +INT32 SetATETtr(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEShow(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEHelp(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 ATESampleRssi(struct _RTMP_ADAPTER *pAd, RXWI_STRUC *pRxWI); +VOID ATEPeriodicExec(PVOID SystemSpecific1, PVOID FunctionContext, PVOID SystemSpecific2, PVOID SystemSpecific3); +INT32 SetATE(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEChannel(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 set_ate_duty_cycle(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 set_ate_pkt_tx_time(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 set_ate_control_band_idx(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +#ifdef MT7615 +INT32 set_ate_channel_ext(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT32 set_ate_start_tx_ext(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* MT7615 */ +INT32 SetATETxBw(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 MT_ATEInit(struct _RTMP_ADAPTER *pAd); +INT32 MT_ATEExit(struct _RTMP_ADAPTER *pAd); +PNDIS_PACKET ATEPayloadInit(struct _RTMP_ADAPTER *pAd, UINT32 TxIdx); +INT32 ATEPayloadAlloc(struct _RTMP_ADAPTER *pAd, UINT32 Index); +VOID EEReadAll(struct _RTMP_ADAPTER *pAd, UINT16 *Data, UINT16 size); +VOID rtmp_ate_init(struct _RTMP_ADAPTER *pAd); +VOID RTMPCfgTssiGainFromEEPROM(struct _RTMP_ADAPTER *pAd); +#ifdef SINGLE_SKU_V2 +INT32 SetATESingleSKUEn(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +#endif /* SINGLE_SKU_V2 */ +INT32 SetATEBFBackoffMode(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETempCompEn(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEPowerPercentEn(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEPowerPercentCtrl(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATEBFBackoffEn(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETSSIEn(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); +INT32 SetATETxPowerCtrlEn(struct _RTMP_ADAPTER *pAd, RTMP_STRING *Arg); + +#endif diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/meta_agent.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/meta_agent.h new file mode 100644 index 000000000..73822c025 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/meta_agent.h @@ -0,0 +1,93 @@ + +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + qa_agent.h +*/ + +#ifndef __META_AGENT_H__ +#define __META_AGENT_H__ + +extern CH_FREQ_MAP CH_HZ_ID_MAP[]; +extern int CH_HZ_ID_MAP_NUM; +/* + * struct for command formats + */ +struct GNU_PACKED _META_CMD_HDR { + UINT32 oid; + UINT32 len_in; /* For set */ + UINT32 len_out; /* For query */ + UCHAR data[2048]; +}; + +struct GNU_PACKED _PARAM_MTK_WIFI_TEST { + UINT32 idx; + UINT32 data; +}; + +struct GNU_PACKED _PARAM_CUSTOM_EFUSE_RW { + UINT32 offset; + UINT32 data; +}; + +struct GNU_PACKED _PARAM_CUSTOM_EEPROM_RW { + UINT8 method; + UINT8 idx; + UINT8 reserved; + UINT16 data; +}; + +struct GNU_PACKED _PARAM_CUSTOM_MCR_RW { + UINT32 offset; + UINT32 data; +}; + +typedef INT32 (*META_CMD_HANDLER)(int ioctl_cmd, struct _RTMP_ADAPTER *pAd, RTMP_IOCTL_INPUT_STRUCT * wrq, META_CMD_HDR * cmd_hdr); + +INT Set_Sdio_Bist_Write(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_Sdio_Bist_Read(struct _RTMP_ADAPTER *pAd, RTMP_STRING *arg); +/* + * define for command oid + */ +#define MT_META_WIFI_TEST_TABLE_VER 0x01180000 + +#define OID_CUSTOM_IF_VER 0xFFA0C000 +#define OID_CUSTOM_MCR_RW 0xFFA0C801 +#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 +#define OID_CUSTOM_EFUSE_RW 0xFFA0C805 +#define OID_CUSTOM_TEST_MODE 0xFFA0C901 +#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 +#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 +/* NVRAM */ +#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 +#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 +#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 + +#define MT_META_WIFI_TEST_CMD_MASK 0x0000001F /* 32 cmd for 1 set, 0x1F=31*/ +#define MT_META_WIFI_TEST_SET_MASK 0x0EFFFFFF /* 32 bits width, rest 27 bits*/ + +#define SLOT_TIME_SHORT 9 +#define PARAM_EEPROM_READ_METHOD_READ 1 +#define PARAM_EEPROM_READ_METHOD_GETSIZE 0 + +/* + * MACRO + */ +#define FUNC_IDX_GET_IDX(__idx, __func_idx) \ + (__func_idx = __idx & 0x000000FF) +#define FUNC_IDX_GET_SUBFIELD(__idx, __sub) \ + (__sub = ((__idx & 0xff000000)>>24)&0x000000ff) +/* TODO: Need to put into include/rt_os.h when merge the file */ +#define MTPRIV_IOCTL_META_SET (SIOCIWFIRSTPRIV + 0x08) +#define MTPRIV_IOCTL_META_QUERY (SIOCIWFIRSTPRIV + 0x09) +#endif /* __META_AGENT_H__ */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode.h new file mode 100644 index 000000000..9d48f9ead --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode.h @@ -0,0 +1,205 @@ + +#ifndef _MT_TESTMODE_H +#define _MT_TESTMODE_H + +#include "mt_testmode_dmac.h" + + +#define TESTMODE_WCID_BAND0 2 +#define TESTMODE_WCID_BAND1 3 + +#define ATE_SINGLE_BAND 1 +#define ATE_DUAL_BAND 2 +#define ATE_GBAND_TYPE 1 +#define ATE_ABAND_TYPE 2 + +#define ATE_BAND_WIDTH_20 0 +#define ATE_BAND_WIDTH_40 1 +#define ATE_BAND_WIDTH_80 2 +#define ATE_BAND_WIDTH_10 3 +#define ATE_BAND_WIDTH_5 4 +#define ATE_BAND_WIDTH_160 5 +#define ATE_BAND_WIDTH_8080 6 + +enum { + ATE_USER_PAYLOAD, + ATE_FIXED_PAYLOAD, + ATE_RANDOM_PAYLOAD, +}; + +struct _ATE_DATA_RATE_MAP { + UCHAR mcs; /* MCS index */ + UINT32 tx_data_rate; /* Data rate in K Bit */ +}; + +struct _ATE_ANT_MAP { + UINT32 ant_sel; + UINT32 spe_idx; +}; + +struct _ATE_TXPWR_GROUP_MAP { + UINT32 start; + UINT32 end; + UINT32 group[4]; +}; + +struct _ATE_CH_KHZ_MAP { + UINT32 Channel; + UINT32 Freq; +}; + +#if defined(COMPOS_TESTMODE_WIN)/* for MT_testmode.c */ + +#define INC_RING_INDEX(_idx, _RingSize) \ + do {\ + (_idx)++; \ + if ((_idx) >= (_RingSize)) \ + _idx = 0; \ + } while (0) + +#define BAND_WIDTH_20 0 +#define BAND_WIDTH_40 1 +#define BAND_WIDTH_80 2 +#define BAND_WIDTH_160 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. */ +#define BAND_WIDTH_BOTH 5 /* BW20 + BW40 */ +#define BAND_WIDTH_5 6 +#define BAND_WIDTH_8080 7 + +#define TX1_G_BAND_TARGET_PWR 0x5E +#define TX0_G_BAND_TARGET_PWR 0x58 +enum { + PDMA_TX, + PDMA_RX, + PDMA_TX_RX, +}; +#define TESTMODE_GET_PADDR(_pstruct, _band, _member) (&_pstruct->_member) +#define TESTMODE_GET_PARAM(_pstruct, _band, _member) (_pstruct->_member) +#define TESTMODE_SET_PARAM(_pstruct, _band, _member, _val) (_pstruct->_member = _val) +#ifndef COMPOS_TESTMODE_WIN/* NDIS only */ +#define MAC_ADDR_LEN 6 +/* 2-byte Frame control field */ +struct _QAFRAME_CONTROL { + UINT16 Ver : 2; + UINT16 Type : 2; + UINT16 SubType : 4; + UINT16 ToDs : 1; + UINT16 FrDs : 1; + UINT16 MoreFrag : 1; + UINT16 Retry : 1; + UINT16 PwrMgmt : 1; + UINT16 MoreData : 1; + UINT16 Wep : 1; + UINT16 Order : 1; +}; + +struct _QAHEADER_802_11 { + struct _QAFRAME_CONTROL FC; + UINT16 Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR Addr3[MAC_ADDR_LEN]; + UINT16 Frag: 4; + UINT16 Sequence: 12; +}; +#endif /* NOT COMPOS_TESTMODE_WIN */ +#else +#ifdef DBDC_MODE +#define TESTMODE_GET_PARAM(_pstruct, _band, _member) ((_band)?_pstruct->band_ext[_band-1]._member:_pstruct->_member) +#define TESTMODE_GET_PADDR(_pstruct, _band, _member) ((_band) ? &_pstruct->band_ext[_band-1]._member : &_pstruct->_member) +#define TESTMODE_SET_PARAM(_pstruct, _band, _member, _val) ({ \ + UINT32 _ret = _val; \ + if (_band) { \ + struct _BAND_INFO *_info = &(_pstruct->band_ext[_band-1]); \ + _info->_member = _val; \ + } else \ + _pstruct->_member = _val; \ + _ret; \ + }) +#else +#define TESTMODE_GET_PADDR(_pstruct, _band, _member) (&_pstruct->_member) +#define TESTMODE_GET_PARAM(_pstruct, _band, _member) (_pstruct->_member) +#define TESTMODE_SET_PARAM(_pstruct, _band, _member, _val) ({ \ + UINT32 _ret = _val; \ + _pstruct->_member = _val; \ + _ret; \ + }) +#endif /* DBDC_MODE */ +#endif /* defined(COMPOS_TESTMODE_WIN) */ + +enum _TESTMODE_STAT_TYPE { + TESTMODE_RXV, + TESTMODE_PER_PKT, + TESTMODE_RESET_CNT, + TESTMODE_COUNTER_802_11, + TESTMODE_STAT_TYPE_NUM, +}; + +struct _RATE_TO_BE_FIX { + UINT32 TXRate: 6; + UINT32 TXMode: 3; + UINT32 Nsts: 2; + UINT32 STBC: 1; + UINT32 Reserved: 20; +}; + +struct rssi_offset_eeprom { + UINT32 **rssi_eeprom_band_offset; + UINT32 *n_band_offset; + UINT32 n_band; +}; + +INT32 MT_ATERFTestCB(struct _RTMP_ADAPTER *pAd, UINT8 *Data, UINT32 Length); +INT32 MT_SetATEMPSDump(struct _RTMP_ADAPTER *pAd, UINT32 band_idx); +INT32 MtTestModeInit(struct _RTMP_ADAPTER *pAd); +INT32 MtTestModeExit(struct _RTMP_ADAPTER *pAd); +INT MtTestModeBkCr(struct _RTMP_ADAPTER *pAd, ULONG offset, enum _TEST_BK_CR_TYPE type); +INT MtTestModeRestoreCr(struct _RTMP_ADAPTER *pAd, ULONG offset); +INT32 MT_ATETxControl(struct _RTMP_ADAPTER *pAd, UINT32 band_idx, PNDIS_PACKET pkt); +VOID MT_ATEUpdateRxStatistic(struct _RTMP_ADAPTER *pAd, enum _TESTMODE_STAT_TYPE type, VOID *data); +INT Mt_TestModeInsertPeer(struct _RTMP_ADAPTER *pAd, UINT32 band_ext, CHAR *da, CHAR *sa, CHAR *bss); +INT32 MT_ATETxPkt(struct _RTMP_ADAPTER *pAd, UINT32 band_idx); /* Export for Loopback */ +INT MtATESetMacTxRx(struct _RTMP_ADAPTER *pAd, INT32 TxRx, BOOLEAN Enable, UCHAR BandIdx); +INT MtATESetTxStream(struct _RTMP_ADAPTER *pAd, UINT32 StreamNums, UCHAR BandIdx); +INT MtATESetRxPath(struct _RTMP_ADAPTER *pAd, UINT32 RxPathSel, UCHAR BandIdx); +INT MtATESetRxFilter(struct _RTMP_ADAPTER *pAd, MT_RX_FILTER_CTRL_T filter); +INT MtATESetCleanPerStaTxQueue(struct _RTMP_ADAPTER *pAd, BOOLEAN sta_pause_enable); +INT32 MT_ATEDumpLog(struct _RTMP_ADAPTER *pAd, struct _ATE_LOG_DUMP_CB *log_cb, UINT32 log_type); +VOID MtCmdATETestResp(struct cmd_msg *msg, char *data, UINT16 len); +INT32 MtATECh2Freq(UINT32 Channel, UINT32 band_idx); +INT32 MtATEGetTxPwrGroup(UINT32 Channel, UINT32 band_idx, UINT32 Ant_idx); +INT32 MT_ATEInsertLog(struct _RTMP_ADAPTER *pAd, UCHAR *log, UINT32 log_type, UINT32 len); +#if !defined(COMPOS_TESTMODE_WIN)/* for MT_testmode.c */ +INT MT_ATERxDoneHandle(struct _RTMP_ADAPTER *pAd, RX_BLK *pRxBlk); +#endif +INT32 MtATERSSIOffset(struct _RTMP_ADAPTER *pAd, INT32 RSSI_org, UINT32 RSSI_idx, INT32 Ch_Band); +INT32 MtATETssiTrainingProc(struct _RTMP_ADAPTER *pAd, UCHAR ucBW, UCHAR ucBandIdx); +#ifdef PRE_CAL_MT7622_SUPPORT +INT MtATE_DPD_Cal_Store_Proc_7622(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /*PRE_CAL_MT7622_SUPPORT*/ +#ifdef PRE_CAL_TRX_SET1_SUPPORT +INT MtATE_DPD_Cal_Store_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT MtATE_DCOC_Cal_Store_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ + +#ifdef PRE_CAL_TRX_SET2_SUPPORT +INT MtATE_Pre_Cal_Proc(RTMP_ADAPTER *pAd, UINT8 CalId, UINT32 ChGrpId); +#endif /* PRE_CAL_TRX_SET2_SUPPORT */ + +INT32 mt_ate_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, struct _TX_BLK *tx_blk); +INT TxPowerManualCtrl(PRTMP_ADAPTER pAd, BOOLEAN fgPwrManCtrl, UINT8 u1TxPwrModeManual, UINT8 u1TxPwrBwManual, UINT8 u1TxPwrRateManual, INT8 i1TxPwrValueManual, UCHAR ucBandIdx); + +#if defined(COMPOS_TESTMODE_WIN) +#endif +#define MT_ATEInit(_pAd) ({ \ + UINT32 _ret; \ + _ret = MtTestModeInit(_pAd); \ + _ret; \ + }) + +#define MT_ATEExit(_pAd) ({ \ + UINT32 _ret; \ + _ret = MtTestModeExit(_pAd); \ + _ret; \ + }) +#endif /* _MT_TESTMODE_H */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode_dmac.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode_dmac.h new file mode 100644 index 000000000..8341a21ca --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode_dmac.h @@ -0,0 +1,27 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + mt_testmode_dmac.h +*/ + +#ifndef __MT_TESTMODE_DMAC_H__ +#define __MT_TESTMODE_DMAC_H__ + + +INT mt_ate_mac_cr_restore(struct _RTMP_ADAPTER *pAd); +INT mt_ate_mac_cr_backup_and_set(struct _RTMP_ADAPTER *pAd); +INT mt_ate_ampdu_ba_limit(struct _RTMP_ADAPTER *pAd, UINT32 band_idx, UINT8 agg_limit); +INT mt_ate_set_sta_pause_cr(struct _RTMP_ADAPTER *pAd, UINT32 band_idx); + + +#endif /* __MT_TESTMODE_DMAC_H__ */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode_smac.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode_smac.h new file mode 100644 index 000000000..6d69ceeb2 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/mt_testmode_smac.h @@ -0,0 +1,25 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + mt_testmode_smac.h +*/ + +#ifndef __MT_TESTMODE_SMAC_H__ +#define __MT_TESTMODE_SMAC_H__ + + +INT mt_ate_mac_cr_restore(struct _RTMP_ADAPTER *pAd); +INT mt_ate_mac_cr_backup_and_set(struct _RTMP_ADAPTER *pAd); + + +#endif /* __MT_TESTMODE_SMAC_H__ */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/qa_agent.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/qa_agent.h new file mode 100644 index 000000000..0999ad0d6 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/qa_agent.h @@ -0,0 +1,83 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + qa_agent.h +*/ + +#ifndef __QA_AGENT_H__ +#define __QA_AGENT_H__ + +#define HQA_CMD_MAGIC_NO 0x18142880 + +/* RX STAT */ +#define HQA_RX_STAT_MACFCSERRCNT 0x1 +#define HQA_RX_STAT_MAC_MDRDYCNT 0x2 +#define HQA_RX_STAT_PHY_MDRDYCNT 0x3 +#define HQA_RX_STAT_PHY_FCSERRCNT 0x4 +#define HQA_RX_STAT_PD 0x5 +#define HQA_RX_STAT_CCK_SIG_SFD 0x6 +#define HQA_RX_STAT_OFDM_SIG_TAG 0x7 +#define HQA_RX_STAT_RSSI 0x8 +#define HQA_RX_RESET_PHY_COUNT 0x9 +#define HQA_RX_RESET_MAC_COUNT 0xa + +/* FW Event Callback */ +VOID HQA_GetThermalValue_CB(struct cmd_msg *msg, char *Data, UINT16 Len); + + +struct GNU_PACKED _HQA_CMD_FRAME { + UINT32 MagicNo; + UINT16 Type; + UINT16 Id; + UINT16 Length; + UINT16 Sequence; + UCHAR Data[2048]; +}; + +typedef INT32(*HQA_CMD_HANDLER)( + struct _RTMP_ADAPTER *pAd, + RTMP_IOCTL_INPUT_STRUCT * wrq, + struct GNU_PACKED _HQA_CMD_FRAME * HqaCmdFrame); + +struct _HQA_CMD_TABLE { + HQA_CMD_HANDLER *CmdSet; + UINT32 CmdSetSize; + UINT32 CmdOffset; +}; + +struct GNU_PACKED _HQA_RX_STAT { + UINT32 mac_rx_fcs_err_cnt; + UINT32 mac_rx_mdrdy_cnt; + UINT32 phy_rx_fcs_err_cnt_cck; + UINT32 phy_rx_fcs_err_cnt_ofdm; + UINT32 phy_rx_pd_cck; + UINT32 phy_rx_pd_ofdm; + UINT32 phy_rx_sig_err_cck; + UINT32 phy_rx_sfd_err_cck; + UINT32 phy_rx_sig_err_ofdm; + UINT32 phy_rx_tag_err_ofdm; + UINT32 WB_RSSSI0; + UINT32 IB_RSSSI0; + UINT32 WB_RSSSI1; + UINT32 IB_RSSSI1; + UINT32 phy_rx_mdrdy_cnt_cck; + UINT32 phy_rx_mdrdy_cnt_ofdm; + UINT32 DriverRxCount; + UINT32 RCPI0; + UINT32 RCPI1; + UINT32 FreqOffsetFromRX; + UINT32 RSSI0; + UINT32 RSSI1; +}; + +#endif /* __QA_AGENT_H__ */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/testmode_common.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/testmode_common.h new file mode 100644 index 000000000..258afbb38 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/testmode_common.h @@ -0,0 +1,47 @@ + +#ifndef _TESTMODE_COMMON_H +#define _TESTMODE_COMMON_H + +#ifndef COMPOS_TESTMODE_WIN +enum _EPQID { + EP4QID = 0, + EP5QID, + EP6QID, + EP7QID, + EP8QID = 8, + EP9QID, + EPALLQID +}; +#endif +/*test mode common*/ +/* */ +/* Scheduler Register 4 (offset: 0x0594, default: 0x0000_0000) */ +/* Note: */ +/* 1. DW : double word */ +/* */ +union _SCHEDULER_REGISTER4 { + struct { + /* DW0 */ + ULONG ForceQid : 4; + ULONG ForceMode : 1; + ULONG BypassMode : 1; + ULONG HybridMode : 1; + ULONG RgPredictNoMask : 1; + ULONG RgResetScheduler : 1; + ULONG RgDoneClearHeader : 1; + ULONG SwMode : 1; + ULONG Reserves0 : 5; + ULONG RgRateMap : 14; + ULONG Reserves1 : 2; + } Default; + ULONG word; +}; + +/* MT7637 for Band display */ +#define MT7367_RO_AGC_DEBUG_2 (WF_PHY_BASE + 0x0584) +#define CR_ACI_HIT (WF_PHY_BASE + 0x0594) +/* MT7637 for Band display end */ + +/*~test mode common*/ + +#endif /* _TESTMODE_COMMON_H */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/testmode_ioctl.h b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/testmode_ioctl.h new file mode 100644 index 000000000..043957ad4 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/include/testmode_ioctl.h @@ -0,0 +1,524 @@ + +#ifndef _TESTMODE_IOCTL_H +#define _TESTMODE_IOCTL_H + +#define TM_STATUS_NOTSUPPORT 0x01 + +#if defined(COMPOS_TESTMODE_WIN) +#define PKTL_TRAN_TO_NET(_Val) _Val +#define PKTL_TRAN_TO_HOST(_Val) _Val +#define PKTS_TRAN_TO_NET(_Val) _Val +#define PKTS_TRAN_TO_HOST(_Val) _Val +#define PKTLA_TRAN_TO_HOST(_len, _byte_array) _byte_array +#define PKTLA_TRAN_TO_NET(_len, _byte_array) _byte_array +#define PKTLA_DUMP(_lvl, _len, _byte_arrary) _byte_array +#define PKTUC_DUMP(_lvl, _len, _byte_arrary) _byte_array +#else +#define PKTL_TRAN_TO_NET(_Val) OS_HTONL(_Val) +#define PKTL_TRAN_TO_HOST(_Val) OS_NTOHL(_Val) +#define PKTS_TRAN_TO_NET(_Val) OS_HTONS(_Val) +#define PKTS_TRAN_TO_HOST(_Val) OS_NTOHS(_Val) +#define PKTLA_TRAN_TO_HOST(_len, _byte_array) ({ \ + INT _cnt = 0; \ + UINT32 *_arr = (UINT32 *)_byte_array; \ + for (_cnt = 0; _cnt < _len; _cnt++) \ + _arr[_cnt] = OS_NTOHL(_arr[_cnt]); \ + _byte_array; \ + }); +#define PKTLA_TRAN_TO_NET(_len, _byte_array) ({ \ + INT _cnt = 0; \ + UINT32 *_arr = (UINT32 *)_byte_array; \ + for (_cnt = 0; _cnt < _len; _cnt++) \ + _arr[_cnt] = OS_HTONL(_arr[_cnt]); \ + _byte_array; \ + }); +#define PKTLA_DUMP(_lvl, _len, _byte_array)({ \ + INT _cnt = 0; \ + UINT32 *_arr = (UINT32 *)_byte_array; \ + for (_cnt = 0; _cnt < _len; _cnt++) \ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, _lvl, ("DWORD%d:%08x\n", _cnt, _arr[_cnt])); \ + _len; \ + }); +#define PKTUC_DUMP(_lvl, _len, _byte_array)({ \ + INT _cnt = 0; \ + UCHAR *_arr = (UCHAR *)_byte_array; \ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, _lvl, ("PKTUC_DUMP(%x): ", _len)); \ + for (_cnt = 0; _cnt < _len; _cnt++) \ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, _lvl, ("%02x", _arr[_cnt])); \ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, _lvl, ("\n")); \ + _len; \ + }); +#endif + +#if defined(COMPOS_TESTMODE_WIN) +/*********************************************************************************** + * IOCTL related definitions and data structures. + **********************************************************************************/ +typedef struct __RTMP_IOCTL_INPUT_STRUCT { + UINT32 InBufLen; + PVOID InBuf; + UINT32 OutBufLen; + PVOID OutBuf; + UINT32 *BytesRet; +} RTMP_IOCTL_INPUT_STRUCT; + +BOOLEAN mt_mac_cr_range_mapping(struct _RTMP_ADAPTER *pAd, UINT32 *mac_addr); +UINT32 mt_physical_addr_map(UINT32 addr); + +#define RTMP_IO_EFAULT 30002 +#define EFAULT (-RTMP_IO_EFAULT) +#endif /* TODO: Add lack of structure for Linux temporarily, fix during merge */ +VOID HQA_GetThermalValue_CB(struct cmd_msg *msg, char *Data, UINT16 Len); +#ifdef TXBF_SUPPORT +VOID HQA_BF_INFO_CB(RTMP_ADAPTER *pAd, unsigned char *data, UINT32 len); +#endif +/* + * #if defined(COMPOS_TESTMODE_WIN) + * #define OS_ENDIANSWAP(_Val) _Val; + * #else + * //#define OS_ENDIANSWAP(_Val) PKTL_TRAN_TO_HOST(_Val); + * #endif + */ +/* Common Part, TODO: Only common part after merge */ +/* Structure for TxBF*/ +#define HQA_BF_STR_SIZE 512 +#pragma pack(1) +struct GNU_PACKED _HQA_HIFTestParam { + UINT32 start_len; + UINT32 stop_len; + UINT32 repeat_time; + UINT32 is_def_pattern; + UINT32 bulkout_num; + UINT32 bulkin_num; + UINT32 txagg_num; + UINT32 rxagg_limit; + UINT32 rxagg_lm; + UINT32 rxagg_to; + UINT32 enable_rxagg; +}; + +#ifdef TXBF_SUPPORT +struct GNU_PACKED _HQA_BF_TAG_ALLOC { + UINT32 col_idx0; + UINT32 row_idx0; + UINT32 col_idx1; + UINT32 row_idx1; + UINT32 col_idx2; + UINT32 row_idx2; + UINT32 col_idx3; + UINT32 row_idx3; +}; + +struct GNU_PACKED _HQA_BF_TAG_MATRIX { + UINT32 nrow; + UINT32 ncol; + UINT32 ngroup; + UINT32 LM; + UINT32 code_book; + UINT32 htc_exist; +}; + +struct GNU_PACKED _HQA_BF_TAG_SNR { + UINT32 snr_sts0; + UINT32 snr_sts1; + UINT32 snr_sts2; + UINT32 snr_sts3; +}; + +struct GNU_PACKED _HQA_BF_TAG_MCS_THRD { + UINT32 mcs_lss0; + UINT32 mcs_sss0; + UINT32 mcs_lss1; + UINT32 mcs_sss1; + UINT32 mcs_lss2; + UINT32 mcs_sss2; +}; + +struct GNU_PACKED _HQA_BF_TAG_INFO { + /* Tag 1 */ + UINT32 profile; /* [6:0] : 0 ~ 63 */ + UINT32 tx_bf; /* [7] : 0: iBF, 1: eBF */ + UINT32 dbw; /* [9:8] : 0/1/2/3: DW20/40/80/160NC */ + UINT32 su_mu; /* [10] : 0:SU, 1: MU */ + UINT32 invalid; /* [11] : 0:default, 1: This profile number is invalid by SW */ + UINT32 rmsd; /* [14:12] : RMSD value from CE */ + UINT32 addr1_col_idx; /* [17 : 15] : column index : 0 ~ 5 */ + UINT32 addr1_row_idx; /* [23 : 18] : row index : 0 ~ 63 */ + UINT32 addr2_col_idx; /* [26 : 24] : column index : 0 ~ 5 */ + UINT32 addr2_row_idx; /* [31 : 27] : row index : 0 ~ 63, [32]: MSB of row index */ + UINT32 addr3_col_idx; /* [35 : 33] : column index : 0 ~ 5 */ + UINT32 addr3_row_idx; /* [41 : 36] : row index : 0 ~ 63 */ + UINT32 addr4_col_idx; /* [44 : 42] : column index : 0 ~ 5 */ + UINT32 addr4_row_idx; /* [50 : 45] : row index : 0 ~ 63 */ + UINT32 reserved1; /* [51] : Reserved */ + UINT32 nrow; /* [53 : 52] : Nrow */ + UINT32 ncol; /* [55 : 54] : Ncol */ + UINT32 ngroup; /* [57 : 56] : Ngroup */ + UINT32 LM; /* [59 : 58] : 0/1/2 */ + UINT32 code_book; /* [61:60] : Code book */ + UINT32 htc_exist; /* [62] : HtcExist */ + UINT32 reserved2; /* [63] : Reserved */ + UINT32 snr_sts0; /* [71:64] : SNR_STS0 */ + UINT32 snr_sts1; /* [79:72] : SNR_STS1 */ + UINT32 snr_sts2; /* [87:80] : SNR_STS2 */ + UINT32 snr_sts3; /* [95:88] : SNR_STS3 */ + UINT32 ibf_lanidx; /* [103:96] : iBF LNA index */ + /* Tag 2 */ + UINT32 smt_ant; /* [11:0] : Smart Ant config */ + UINT32 reserved3; /* [14:12] : Reserved */ + UINT32 se_idx; /* [19:15] : SE index */ + UINT32 rmsd_thrd; /* [22:20] : RMSD Threshold */ + UINT32 reserved4; /* [23] : Reserved */ + UINT32 mcs_thrd_l1ss; /* [27:24] : MCS TH long 1SS */ + UINT32 mcs_thrd_s1ss; /* [31:28] : MCS TH short 1SS */ + UINT32 mcs_thrd_l2ss; /* [35:32] : MCS TH long 2SS */ + UINT32 mcs_thrd_s2ss; /* [39:36] : MCS TH short 2SS */ + UINT32 mcs_thrd_l3ss; /* [43:40] : MCS TH long 3SS */ + UINT32 mcs_thrd_s3ss; /* [47:44] : MCS TH short 3SS */ + UINT32 bf_tout; /* [55:48] : iBF timeout limit */ + UINT32 reserved5; /* [63:56] : Reserved */ + UINT32 reserved6; /* [71:64] : Reserved */ + UINT32 reserved7; /* [79:72] : Reserved */ + UINT32 ibf_dbw; /* [81:80] : iBF desired DBW 0/1/2/3 : BW20/40/80/160NC */ + UINT32 ibf_ncol; /* [83:82] : iBF desired Ncol = 1 ~ 3 */ + UINT32 ibf_nrow; /* [85:84] : iBF desired Nrow = 1 ~ 4 */ + UINT32 reserved8; /* [95:86] : Reserved */ +}; + +struct GNU_PACKED _HQA_BF_STA_CMM_REC { + UINT32 wlan_idx; + UINT32 bss_idx; + UINT32 aid; + UCHAR mac[MAC_ADDR_LEN]; +}; + +enum _HQA_BF_CMD_ID { + ATE_TXBF_INIT = 1, + ATE_CHANNEL, + ATE_TX_MCS, + ATE_TX_POW0, + ATE_TX_ANT, + ATE_RX_FRAME, + ATE_RX_ANT, + ATE_TXBF_LNA_GAIN, + ATE_IBF_PHASE_COMP, + ATE_IBF_TX, + ATE_IBF_PROF_UPDATE, + ATE_EBF_PROF_UPDATE, + ATE_IBF_INST_CAL, + ATE_IBF_INST_VERIFY, + ATE_TXBF_GD_INIT, + ATE_IBF_PHASE_E2P_UPDATE +}; + +struct GNU_PACKED _HQA_BF_STA_REC { + UINT32 wlan_idx; + UINT32 bss_idx; + UINT32 PfmuId; + UINT32 su_mu; + UINT32 etxbf_cap; + UINT32 ndpa_rate; + UINT32 ndp_rate; + UINT32 report_poll_rate; + UINT32 tx_mode; + UINT32 nc; + UINT32 nr; + UINT32 cbw; + UINT32 spe_idx; + UINT32 tot_mem_req; + UINT32 mem_req_20m; + UINT32 mem_row0; + UINT32 mem_col0; + UINT32 mem_row1; + UINT32 mem_col1; + UINT32 mem_row2; + UINT32 mem_col2; + UINT32 mem_row3; + UINT32 mem_col3; +}; + +struct GNU_PACKED _HQA_BF_STA_PROFILE { + UINT32 pfmuid; + UINT32 subcarrier; + UINT32 phi11; + UINT32 psi21; + UINT32 phi21; + UINT32 psi31; + UINT32 phi31; + UINT32 psi41; + UINT32 phi22; + UINT32 psi32; + UINT32 phi32; + UINT32 psi42; + UINT32 phi33; + UINT32 psi43; + UINT32 snr00; + UINT32 snr01; + UINT32 snr02; + UINT32 snr03; +}; + +struct GNU_PACKED _HQA_BF_SOUNDING { + UINT32 su_mu; + UINT32 mu_num; + UINT32 snd_interval; + UINT32 wlan_id0; + UINT32 wlan_id1; + UINT32 wlan_id2; + UINT32 wlan_id3; + UINT32 band_idx; +}; + +struct GNU_PACKED _HQA_BF_MANUAL_CONN { + UCHAR mac[MAC_ADDR_LEN]; + UINT32 type; + UINT32 wtbl_idx; + UINT32 ownmac_idx; + UINT32 phymode; + UINT32 bw; + UINT32 pfmuid; + UINT32 marate_mode; + UINT32 marate_mcs; + UINT32 nss; + UINT32 spe_idx; + UINT32 rca2; + UINT32 rv; + UINT32 aid; +}; + +struct GNU_PACKED _HQA_PWR_MANUAL { + UINT32 u4PwrManCtrl; + UINT32 u4TxPwrModeManual; + UINT32 u4TxPwrBwManual; + UINT32 u4TxPwrRateManual; + UINT32 i4TxPwrValueManual; + UINT32 u4Band; +}; + +#ifdef CFG_SUPPORT_MU_MIMO +/* Structure for MU-MIMO */ +struct _HQA_MU_STA_PARAM { + UINT32 gid[2]; + UINT32 up[4]; +}; + +struct _HQA_MU_TBL { + UINT32 su_mu; + UCHAR tbl[0]; +}; + +struct GNU_PACKED _HQA_MU_USR_INIT_MCS { + UINT32 user0; + UINT32 user1; + UINT32 user2; + UINT32 user3; +}; + +struct GNU_PACKED _HQA_MU_USR_LQ { + UINT32 usr0_bpsk; + UINT32 usr0_qpsk; + UINT32 usr0_16qam; + UINT32 usr0_64qam; + UINT32 usr0_256qam; + UINT32 usr1_bpsk; + UINT32 usr1_qpsk; + UINT32 usr1_16qam; + UINT32 usr1_64qam; + UINT32 usr1_256qam; + UINT32 usr2_bpsk; + UINT32 usr2_qpsk; + UINT32 usr2_16qam; + UINT32 usr2_64qam; + UINT32 usr2_256qam; + UINT32 usr3_bpsk; + UINT32 usr3_qpsk; + UINT32 usr3_16qam; + UINT32 usr3_64qam; + UINT32 usr3_256qam; +}; + +struct GNU_PACKED _HQA_MU_GRP_INFO { + UINT32 grp_idx; + UINT32 num_usr; + UINT32 usr0_ldpc; + UINT32 usr1_ldpc; + UINT32 usr2_ldpc; + UINT32 usr3_ldpc; + UINT32 usr0_nss; + UINT32 usr1_nss; + UINT32 usr2_nss; + UINT32 usr3_nss; + UINT32 gid; + UINT32 usr0_up; + UINT32 usr1_up; + UINT32 usr2_up; + UINT32 usr3_up; + UINT32 usr0_pfmu_id; + UINT32 usr1_pfmu_id; + UINT32 usr2_pfmu_id; + UINT32 usr3_pfmu_id; + UINT32 initMCS0; + UINT32 initMCS1; + UINT32 initMCS2; + UINT32 initMCS3; + UCHAR usr0_mac[MAC_ADDR_LEN]; + UCHAR usr1_mac[MAC_ADDR_LEN]; + UCHAR usr2_mac[MAC_ADDR_LEN]; + UCHAR usr3_mac[MAC_ADDR_LEN]; +}; +#endif/* CFG_SUPPORT_MU_MIMO */ +#endif /* TXBF_SUPPORT */ +#pragma pack() + +/* DBDC Tx Ext */ +#pragma pack(1) +struct GNU_PACKED _HQA_EXT_SET_CH { + UINT32 ext_id; + UINT32 num_param; + UINT32 band_idx; + UINT32 central_ch0; + UINT32 central_ch1; + UINT32 sys_bw; + UINT32 perpkt_bw; + UINT32 pri_sel; + UINT32 reason; + UINT32 ch_band; + UINT32 out_band_freq; +}; + +struct GNU_PACKED _HQA_EXT_TX_CONTENT { + UINT32 ext_id; + UINT32 num_param; + UINT32 band_idx; + UINT32 FC; + UINT32 dur; + UINT32 seq; + UINT32 gen_payload_rule; /* Normal:0,Repeat:1,Random:2 */ + UINT32 txlen; + UINT32 payload_len; + UCHAR addr1[MAC_ADDR_LEN]; + UCHAR addr2[MAC_ADDR_LEN]; + UCHAR addr3[MAC_ADDR_LEN]; + UCHAR payload[0]; +}; + +struct GNU_PACKED _HQA_EXT_TXV { + UINT32 ext_id; + UINT32 num_param; + UINT32 band_idx; + UINT32 pkt_cnt; + UINT32 phymode; + UINT32 rate; + UINT32 pwr; + UINT32 stbc; + UINT32 ldpc; + UINT32 ibf; + UINT32 ebf; + UINT32 wlan_id; + UINT32 aifs; + UINT32 gi; + UINT32 tx_path; + UINT32 nss; +}; + +struct GNU_PACKED _HQA_CMD_FRAME { + UINT32 MagicNo; + UINT16 Type; + UINT16 Id; + UINT16 Length; + UINT16 Sequence; + UINT8 Data[IOCTLBUFF]; +}; +#pragma pack() + +typedef INT32(*HQA_CMD_HANDLER)( + struct _RTMP_ADAPTER *pAd, + struct __RTMP_IOCTL_INPUT_STRUCT *wrq, + struct _HQA_CMD_FRAME *HqaCmdFrame); + +struct _HQA_CMD_TABLE { + HQA_CMD_HANDLER *CmdSet; + UINT32 CmdSetSize; + UINT32 CmdOffset; +}; + +struct GNU_PACKED _HQA_RX_STAT { + UINT32 mac_rx_fcs_err_cnt; + UINT32 mac_rx_mdrdy_cnt; + UINT32 phy_rx_fcs_err_cnt_cck; + UINT32 phy_rx_fcs_err_cnt_ofdm; + UINT32 phy_rx_pd_cck; + UINT32 phy_rx_pd_ofdm; + UINT32 phy_rx_sig_err_cck; + UINT32 phy_rx_sfd_err_cck; + UINT32 phy_rx_sig_err_ofdm; + UINT32 phy_rx_tag_err_ofdm; + UINT32 WB_RSSSI0; + UINT32 IB_RSSSI0; + UINT32 WB_RSSSI1; + UINT32 IB_RSSSI1; + UINT32 phy_rx_mdrdy_cnt_cck; + UINT32 phy_rx_mdrdy_cnt_ofdm; + UINT32 DriverRxCount; + UINT32 RCPI0; + UINT32 RCPI1; + INT32 FreqOffsetFromRX; + UINT32 RSSI0; + UINT32 RSSI1; + UINT32 rx_fifo_full; + /* #ifdef MT7615 */ + UINT32 mac_rx_len_mismatch; + UINT32 mac_rx_fcs_err_cnt_band1; + UINT32 mac_rx_mdrdy_cnt_band1; + UINT32 FAGC_IB_RSSSI[4]; + UINT32 FAGC_WB_RSSSI[4]; + UINT32 Inst_IB_RSSSI[4]; + UINT32 Inst_WB_RSSSI[4]; + UINT32 ACIHitLow; + UINT32 ACIHitHigh; + UINT32 DriverRxCount1; + UINT32 RCPI2; + UINT32 RCPI3; + UINT32 RSSI2; + UINT32 RSSI3; + UINT32 SNR0; + UINT32 SNR1; + UINT32 SNR2; + UINT32 SNR3; + UINT32 rx_fifo_full_band1; + UINT32 mac_rx_len_mismatch_band1; + UINT32 phy_rx_pd_cck_band1; + UINT32 phy_rx_pd_ofdm_band1; + UINT32 phy_rx_sig_err_cck_band1; + UINT32 phy_rx_sfd_err_cck_band1; + UINT32 phy_rx_sig_err_ofdm_band1; + UINT32 phy_rx_tag_err_ofdm_band1; + UINT32 phy_rx_mdrdy_cnt_cck_band1; + UINT32 phy_rx_mdrdy_cnt_ofdm_band1; + UINT32 phy_rx_fcs_err_cnt_cck_band1; + UINT32 phy_rx_fcs_err_cnt_ofdm_band1; + UINT32 MuPktCount; + UINT32 SIG_MCS; + UINT32 SINR; + UINT32 RXVRSSI; + /* #endif */ + UINT32 mac_rx_fcs_ok_cnt; /* MT7622 only */ +}; + +UINT32 HQA_CMDHandler(struct _RTMP_ADAPTER *pAd, struct __RTMP_IOCTL_INPUT_STRUCT *Wrq, struct _HQA_CMD_FRAME *HqaCmdFrame); + +#define TM_CMDREQ 0x0008 +#define TM_CMDRSP 0x8008 +#define HQA_CMD_MAGIC_NO 0x18142880 + +#define HQA_CMD_REQ 0x0005 +#define HQA_CMD_RSP 0x8005 +#define TMR_HW_VER_100 100 +#define TMR_HW_VER_150 150 +#define TMR_HW_VER_200 200 + + +#define HQA_CMD_MAGIC_NO 0x18142880 +#define EFUSE_ADDR_FREQUENCY_OFFSET_MT7637 0xF4/* MT7637 */ + +#endif /* _TESTMODE_IOCTL_H */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/meta_agent.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/meta_agent.c new file mode 100644 index 000000000..d8e2fc108 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/meta_agent.c @@ -0,0 +1,2131 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + meta_agent.c +*/ +#include "rt_config.h" + +enum _WIFI_SUB_TEST_STATE { + WIFI_SUB_TEST_STANDBY, + WIFI_SUB_TEST_RESET, + WIFI_SUB_TEST_TX, + WIFI_SUB_TEST_RX, + WIFI_SUB_TEST_OUTPUT_PWR, + WIFI_SUB_TEST_LOCAL_FREQ, + WIFI_SUB_TEST_CARR_SUPPRESSION, + WIFI_SUB_TEST_CONTI_WAVE, + NUM_STATE +}; +#define _DUMP_HEX_ 1 +static enum _WIFI_SUB_TEST_STATE g_SUB_TEST_STATE = WIFI_SUB_TEST_STANDBY; +static UINT32 g_MT_META_ATCMD_TBL_VERSION = MT_META_WIFI_TEST_TABLE_VER; + +static BOOLEAN valid_ch(UCHAR Ch) +{ + int chIdx; + + for (chIdx = 0; chIdx < CH_HZ_ID_MAP_NUM; chIdx++) { + if ((Ch) == CH_HZ_ID_MAP[chIdx].channel) + return true; + } + + return false; +} + +static INT32 resp_to_meta(INT32 ioctl_cmd, struct _META_CMD_HDR *rsp, RTMP_IOCTL_INPUT_STRUCT *wrq, INT32 len, INT32 status) +{ + if (ioctl_cmd == MTPRIV_IOCTL_META_SET) + rsp->len_in = len; + else if (ioctl_cmd == MTPRIV_IOCTL_META_QUERY) + rsp->len_out = len; + + wrq->u.data.length = sizeof(rsp->oid) + sizeof(rsp->len_in) + sizeof(rsp->len_out) + len; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WRQ->u.data.length = %u, oid: %lu, rsp: %lu, rsp->len: 0x%x\n", wrq->u.data.length, sizeof(rsp->oid), sizeof(rsp->len_in), len)); + + if (copy_to_user(wrq->u.data.pointer, (UCHAR *)(rsp), wrq->u.data.length)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("copy_to_user() fail in %s\n", __func__)); + return -EFAULT; + } + +#ifdef _DUMP_HEX_ + { + UCHAR *pSrcBufVA = wrq->u.data.pointer; + UINT32 SrcBufLen = wrq->u.data.length; + unsigned char *pt; + INT32 x; + + pt = pSrcBufVA; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: %p, len = %d\n", "META_IOCTL Ret Content", pSrcBufVA, SrcBufLen)); + + for (x = 0; x < SrcBufLen; x++) { + if (x % 16 == 0) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("0x%04x : ", x)); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02x ", ((unsigned char)pt[x]))); + + if (x % 16 == 15) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n", __func__)); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + } +#endif + return 0; +} + +static INT32 wifi_sub_test_stop(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = 0; + INT32 val = 0; + UINT32 Mode; + + memcpy((PUCHAR)&val, ¶m->data, 4); + + switch (g_SUB_TEST_STATE) { + case WIFI_SUB_TEST_STANDBY: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, WIFI_SUB_TEST_STANDBY\n", __func__)); + break; + + case WIFI_SUB_TEST_RESET: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, WIFI_SUB_TEST_RESET\n", __func__)); + break; + + case WIFI_SUB_TEST_TX: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, WIFI_SUB_TEST_TX STOP\n", __func__)); + Mode = ATECtrl->Mode; + ATECtrl->Mode &= ATE_TXSTOP; + ATECtrl->bQATxStart = FALSE; + ret = ATEOp->StopTx(pAd, Mode); + ATECtrl->TxStatus = 0; + break; + + case WIFI_SUB_TEST_RX: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, WIFI_SUB_TEST_RX STOP\n", __func__)); + ATECtrl->Mode &= ATE_RXSTOP; + ATECtrl->bQARxStart = FALSE; + ret = ATEOp->StopRx(pAd); + break; + + case WIFI_SUB_TEST_OUTPUT_PWR: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Conti. Tx stop\n", __func__)); + ret = ATEOp->StopContinousTx(pAd, TESTMODE_BAND0); + break; + + case WIFI_SUB_TEST_LOCAL_FREQ: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Tx Tone DC stop\n", __func__)); + ret = ATEOp->StopTxTone(pAd); + break; + + case WIFI_SUB_TEST_CARR_SUPPRESSION: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Tx Carrier Suppression stop\n", __func__)); + ret = ATEOp->StopTxTone(pAd); + break; + + case WIFI_SUB_TEST_CONTI_WAVE: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, Conti. Tx stop\n", __func__)); + ret = ATEOp->StopContinousTx(pAd, TESTMODE_BAND0); + break; + + default: + break; + } + + g_SUB_TEST_STATE = WIFI_SUB_TEST_STANDBY; + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_start_tx(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + ret = ATEOp->StartTx(pAd); + g_SUB_TEST_STATE = WIFI_SUB_TEST_TX; + + if (ATECtrl->bQATxStart == TRUE) + ATECtrl->TxStatus = 1; + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_start_rx(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + g_SUB_TEST_STATE = WIFI_SUB_TEST_RX; + ret = ATEOp->StartRx(pAd); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_reset(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + + if (ioctl_cmd == MTPRIV_IOCTL_META_SET) { + /* 1. Table Version */ + g_MT_META_ATCMD_TBL_VERSION = 0x01000002; + /* 3. Rate */ + ATECtrl->PhyMode = MODE_CCK; + ATECtrl->Mcs = 1; + /* 4. Preamble, follow PhyMode, and always using long preamble currently, in mac/mt_mac.c line. 754 */ + /* 6. Packet Length */ + ATECtrl->TxLength = 1024; + /* 7. Packet Count */ + ATECtrl->TxCount = 1000; + /* 15. BW */ + ATECtrl->BW = BW_20; + /* 16. GI */ + ATECtrl->Sgi = 0; + /* 18. CH FREQ */ + ATEOp->SetTxFreqOffset(pAd, 0); + /* 23. TODO: Slow Clk Mode (?)*/ + /* 29. TODO: TSSI */ + /* 31. Tx Power mode - always dBm */ + /* 65. TODO: CW Mode (?) */ + /* 71. CH BW */ + ATECtrl->BW = BW_20; + /* 72. Data BW */ + /* ATECtrl->PerPktBW = BW_20; */ + /* 73. Primary setting */ + ATECtrl->ControlChl = 1; + ATECtrl->Channel = 1; + /* 74. J mode Setting (tone) */ + g_SUB_TEST_STATE = WIFI_SUB_TEST_STANDBY; + } else { + if (g_SUB_TEST_STATE != WIFI_SUB_TEST_STANDBY) + ret = NDIS_STATUS_FAILURE; + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + } + + return ret; +} + +static INT32 wifi_sub_test_output_pwr(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + /* TODO: Correct band selection */ + ret = ATEOp->StartContinousTx(pAd, ATECtrl->TxAntennaSel, TESTMODE_BAND0); + g_SUB_TEST_STATE = WIFI_SUB_TEST_OUTPUT_PWR; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, val:0x%x\n", __func__, val)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_local_freq(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_FAILURE; + INT32 val = 0; + INT32 mode = 8; + INT32 pwr1 = 0xf; + INT32 pwr2 = 0; + CHAR txpwr = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + + /* TxAntennaSel, 0: All 1:TX0 2:TX1 */ + if (ATECtrl->TxAntennaSel == 1) { + mode = WF0_TX_ONE_TONE_DC; + txpwr = ATECtrl->TxPower0; + } else if (ATECtrl->TxAntennaSel == 2) { + mode = WF1_TX_ONE_TONE_DC; + txpwr = ATECtrl->TxPower1; + } else + goto meta_tx_suppress_done; + + if (txpwr > 30) + pwr2 = (txpwr - 30) << 1; + else { + pwr1 = (txpwr & 0x1e) >> 1; + pwr2 = (txpwr & 0x01) << 1; + } + + ret = ATEOp->StartTxTone(pAd, mode); + ret = ATEOp->SetTxTonePower(pAd, pwr1, pwr2); + g_SUB_TEST_STATE = WIFI_SUB_TEST_LOCAL_FREQ; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: TX Tone DC, TxPower:0x%x, pwr1:0x%x, pwr2:0x%x\n", __func__, txpwr, pwr1, pwr2)); +meta_tx_suppress_done: + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_rf_suppression(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_FAILURE; + INT32 val = 0; + INT32 mode = 8; + INT32 pwr1 = 0xf; + INT32 pwr2 = 0; + CHAR txpwr = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + + /* TxAntennaSel, 0: All 1:TX0 2:TX1 */ + if (ATECtrl->TxAntennaSel == 1) { + mode = WF0_TX_TWO_TONE_5M; + txpwr = ATECtrl->TxPower0; + } else if (ATECtrl->TxAntennaSel == 2) { + mode = WF1_TX_TWO_TONE_5M; + txpwr = ATECtrl->TxPower1; + } else + goto meta_tx_suppress_done; + + if (txpwr > 30) + pwr2 = (txpwr - 30) << 1; + else { + pwr1 = (txpwr & 0x1e) >> 1; + pwr2 = (txpwr & 0x01) << 1; + } + + ret = ATEOp->StartTxTone(pAd, mode); + ret = ATEOp->SetTxTonePower(pAd, pwr1, pwr2); + g_SUB_TEST_STATE = WIFI_SUB_TEST_CARR_SUPPRESSION; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: TXCARR, TxPower:0x%x, pwr1:0x%x, pwr2:0x%x\n", __func__, txpwr, pwr1, pwr2)); +meta_tx_suppress_done: + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_trx_iq_cali(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + /* UINT8 Action = 0, Mode = 0, CalItem = 0; */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + /* + * Enter RF test mode + * TODO: Don't know when to go back to normal mode, Mode = OPERATION_NORMAL_MODE; + */ + /* CmdRfTest(pAd, ACTION_SWITCH_TO_RFTEST, OPERATION_RFTEST_MODE, 0); */ + MtCmdRfTestSwitchMode(pAd, OPERATION_RFTEST_MODE, 0); + /* Sec, operation + * 6: Tx IQ Cal + * 10: Rx FIIIQ Cal + * 11: Rx FDIQ Cal + */ + /* CmdRfTest(pAd, ACTION_IN_RFTEST, OPERATION_RFTEST_MODE, 6); */ + /* CmdRfTest(pAd, ACTION_IN_RFTEST, OPERATION_RFTEST_MODE, 10); */ + /* CmdRfTest(pAd, ACTION_IN_RFTEST, OPERATION_RFTEST_MODE, 11); */ + MtCmdDoCalibration(pAd, 6); + MtCmdDoCalibration(pAd, 10); + MtCmdDoCalibration(pAd, 11); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_tssi_cali(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + /* + * Enter RF test mode + * TODO: Don't know when to go back to normal mode, Mode = OPERATION_NORMAL_MODE; + */ + /* CmdRfTest(pAd, ACTION_SWITCH_TO_RFTEST, OPERATION_RFTEST_MODE, 0); */ + MtCmdRfTestSwitchMode(pAd, OPERATION_RFTEST_MODE, 0); + /* Sec, operation + * 6: Tx IQ Cal + */ + /* CmdRfTest(pAd, ACTION_IN_RFTEST, OPERATION_RFTEST_MODE, 7); */ + MtCmdDoCalibration(pAd, 7); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_dpd_cali(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + /* + * Enter RF test mode + * TODO: Don't know when to go back to normal mode, Mode = OPERATION_NORMAL_MODE; + */ + /* CmdRfTest(pAd, ACTION_SWITCH_TO_RFTEST, OPERATION_RFTEST_MODE, 0); */ + MtCmdRfTestSwitchMode(pAd, OPERATION_RFTEST_MODE, 0); + /* Sec, operation + * 6: Tx IQ Cal + */ + /* CmdRfTest(pAd, ACTION_IN_RFTEST, OPERATION_RFTEST_MODE, 9); */ + MtCmdDoCalibration(pAd, 9); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_conti_waveform(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + /* TODO: Correct band selection */ + ret = ATEOp->StartContinousTx(pAd, ATECtrl->TxAntennaSel, TESTMODE_BAND0); + g_SUB_TEST_STATE = WIFI_SUB_TEST_CONTI_WAVE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, val:0x%x\n", __func__, val)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_sub_test_start_icap(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static META_CMD_HANDLER WIFI_TEST_CMD_SUBTEST[] = { + wifi_sub_test_stop, + wifi_sub_test_start_tx, + wifi_sub_test_start_rx, + wifi_sub_test_reset, + wifi_sub_test_output_pwr, + wifi_sub_test_local_freq, + wifi_sub_test_rf_suppression, + wifi_sub_test_trx_iq_cali, + wifi_sub_test_tssi_cali, + wifi_sub_test_dpd_cali, + wifi_sub_test_conti_waveform, + wifi_sub_test_start_icap, +}; + +static INT32 wifi_test_version(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + INT32 status = NDIS_STATUS_SUCCESS; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n%s: version:%04x !\n", __func__, g_MT_META_ATCMD_TBL_VERSION)); + memcpy(¶m->data, &g_MT_META_ATCMD_TBL_VERSION, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(struct _PARAM_MTK_WIFI_TEST), status); + return status; +} + +static INT32 wifi_test_cmd(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 op = param->data; + + if (op > (sizeof(WIFI_TEST_CMD_SUBTEST) / sizeof(META_CMD_HANDLER))) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:op_idx: %04x, size of handle tbl: %lu\n", __func__, op, sizeof(WIFI_TEST_CMD_SUBTEST) / sizeof(META_CMD_HANDLER))); + return NDIS_STATUS_INVALID_DATA; + } + + ret = (*WIFI_TEST_CMD_SUBTEST[op])(ioctl_cmd, pAd, WRQ, cmd_hdr); + return ret; +} + +static INT32 wifi_test_pwr_cfg(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, sizeof(val)); + /* val = OS_NTOHS(val); */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val:0x%x\n", __func__, val)); + /* TODO Add in the setting of another Tx Power, txpwr1*/ + pAd->ATECtrl.TxPower0 = val; + ret = ATEOp->SetTxPower0(pAd, val, 0); + /* ret = ATEOp->SetTxPower1(pAd, val); */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_rate_cfg(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, sizeof(val)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val:0x%x\n", __func__, val)); + + if ((val >> 31) & 0x00000001) { + /* b31(msb) set(1) - 11n MCS:0~15, 32 */ + val &= 0x7FFFFFF; + + if (((val > 15) && (val < 32)) + || (val > 32)) + return -1; + + if (val == 32) + val = 17; /* for corresponding to idx of OFDMRateTable */ + + /* case MODE_HTMIX / case MODE_HTGREENFIELD */ + ATECtrl->PhyMode = MODE_HTMIX; + } else { + /* b31(msb) set(0) - CCK:0~3, OFDM:4~11 */ + val &= 0x7FFFFFF; + + if ((val < 0) || (val > 11)) + return -1; + else if ((val < 4) && (val >= 0)) { + /*KOKO: Not sure why there are 8 entries in CCKRateTable */ + ATECtrl->PhyMode = MODE_CCK; + } else { + ATECtrl->PhyMode = MODE_OFDM; + val -= 4; + } + } + + ATECtrl->Mcs = (UCHAR)val; + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_preamble_cfg(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Val: %x\n", __func__, val)); + + switch (val) { + case 0: /* Normal: don't know what is for normal, anyway choose OFDM */ + val = MODE_OFDM; + break; + + case 1: /* Have to check if its short preamble by default in CCK */ + val = MODE_CCK; + break; + + case 2: + val = MODE_HTMIX; + break; + + case 3: + val = MODE_HTGREENFIELD; + break; + + case 4: + val = MODE_VHT; + break; + + default: + break; + } + + ATECtrl->PhyMode = (UCHAR)val; + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_antenna_cfg(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Val: %x\n", __func__, val)); + ret = ATEOp->SetTxAntenna(pAd, (CHAR)val); + ret = ATEOp->SetRxAntenna(pAd, (CHAR)val); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_pkt_len_cfg(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + + if ((val < 24) || (val > (MAX_FRAME_SIZE - 34/* == 2312 */))) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Out of range (%d), it should be in range of 24~%d.\n", __func__, val, + (MAX_FRAME_SIZE - 34/* == 2312 */))); + return -1; + } + + ATECtrl->TxLength = val; + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: TxLength = %x\n", __func__, ATECtrl->TxLength)); + return ret; +} + +static INT32 wifi_test_set_pkt_cnt(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val: %u\n", __func__, val)); + + if (val == 0) + ATECtrl->TxCount = 0xFFFFFFFF; + else + ATECtrl->TxCount = val; + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} +/* + * Since different chip has different wifi Tx off time duration, meta tool do not set it + */ +static INT32 wifi_test_set_pkt_interval(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 val = 0; + UINT32 slot_t = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + /* TODO: "Val will be round-up to (19+9n)us", quoted from doc. Ref. 6630 FW */ + slot_t = (val - 19 + SLOT_TIME_SHORT - 1) / SLOT_TIME_SHORT; + ATEOp->SetAIFS(pAd, (UINT32)slot_t); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_tmp_comp(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + return ret; +} + +static INT32 wifi_test_txop_en(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + return ret; +} + +static INT32 wifi_test_set_ack(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + return ret; +} + +static INT32 wifi_test_set_pkt_content(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + return ret; +} + +static INT32 wifi_test_set_retry_cnt(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + return ret; +} + +static INT32 wifi_test_set_qos_q(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + + if (val > 4) + return NDIS_STATUS_INVALID_DATA; + + /* ATECtrl->q_idx = (UCHAR)val; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_bw(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val: 0x%x\n", __func__, val)); + + if (val > 3) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s, Invalid Parameter(%x)\n", __func__, val)); + ret = -1; + goto _meta_set_bw_err; + } + + if (val == 0) { + ATECtrl->BW = BW_20; + ATECtrl->ControlChl = ATECtrl->Channel; + } else { + ATECtrl->BW = BW_40; + ATECtrl->ControlChl = ATECtrl->Channel; + + switch (val) { + case 1: + case 2: /* Upper 20MHz of a 40MHz Ch, ex. Ch6 upper, then control ch will be Ch4 */ + ATECtrl->ControlChl -= 2; + + if (!valid_ch(ATECtrl->ControlChl)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s-case1/2, Invalid ControlChl(%x)\n", __func__, ATECtrl->ControlChl)); + ATECtrl->ControlChl = ATECtrl->Channel; + ATECtrl->Channel += 2; + } + + break; + + case 3: /* Lower 20MHz of a 40MHz Ch, ex. Ch6 lower, then control ch will be Ch8 */ + ATECtrl->Channel += 2; + + if (!valid_ch(ATECtrl->Channel)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s-case3, Invalid ControlChl(%x)\n", __func__, ATECtrl->ControlChl)); + ATECtrl->Channel = ATECtrl->ControlChl; + ATECtrl->ControlChl -= 2; + } + + break; + + default: + break; + } + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Channel = %d, Control ch: 0x%x, BW = %d\n", __func__, ATECtrl->Channel, ATECtrl->ControlChl, ATECtrl->BW)); + ret = ATEOp->SetBW(pAd, ATECtrl->BW); +_meta_set_bw_err: + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +/* + * param: + * 0: normal GI + * 1: short GI + */ +static INT32 wifi_test_set_gi(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val:0x%x\n", __func__, val)); + + if (val > 1 || val < 0) + return -1; + + ATECtrl->Sgi = (UCHAR)val; + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_stbc(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + ATECtrl->Stbc = (UCHAR)val; + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_ch_freq(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + INT32 ch = 1; + + memcpy((PUCHAR)&val, ¶m->data, 4); + /* TODO: Need to check the value passed from host */ + RTMP_MapKHZ2ChannelID(val / 1000, &ch); + ATECtrl->Channel = ch; + ATECtrl->ControlChl = ATECtrl->Channel; + + /* Set Control channel according to BW */ + switch (ATECtrl->BW) { + case BW_20: + break; + + case BW_40: + case BW_80: + default: + + /* Lower 20MHz of a 40MHz Ch, ex. Ch6 lower, then control ch will be Ch8 */ + if (ATECtrl->ControlChl > 2) + ATECtrl->ControlChl -= 2; + else + ATECtrl->ControlChl += 2; + + break; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val:%d, ch: 0x%x, Control ch: 0x%x\n", __func__, val, ATECtrl->Channel, ATECtrl->ControlChl)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_rifs(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_tr_switch(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_rf_sx_en(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_pll_en(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_slow_clk_en(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_adc_clk_mode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_measure_mode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_vlt_comp(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_dpd_tx_gain(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_dpd_en(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_tssi_en(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + INT32 wf_sel = 0; + + /* TODO: Plan to use upper 16 bits for antenna selection, lower 16 bits for on/off */ + memcpy((PUCHAR)&val, ¶m->data, 4); + val = val & 0x0000ffff; + memcpy((PUCHAR)&wf_sel, ¶m->data, 4); + wf_sel = ((wf_sel & 0xffff0000) >> 16) & 0x0000ffff; + ATEOp->SetTSSI(pAd, (CHAR)wf_sel, (CHAR)val); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_tx_gain_code(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_tx_pwr_mode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static META_CMD_HANDLER WIFI_TEST_CMD_SET1[] = { + wifi_test_version, + wifi_test_cmd, + wifi_test_pwr_cfg, + wifi_test_rate_cfg, + wifi_test_preamble_cfg, + wifi_test_antenna_cfg, + wifi_test_pkt_len_cfg, + wifi_test_set_pkt_cnt, + wifi_test_set_pkt_interval, + wifi_test_tmp_comp, + wifi_test_txop_en, + wifi_test_set_ack, + wifi_test_set_pkt_content, + wifi_test_set_retry_cnt, + wifi_test_set_qos_q, + wifi_test_set_bw, + wifi_test_set_gi, + wifi_test_set_stbc, + wifi_test_set_ch_freq, + wifi_test_set_rifs, + wifi_test_tr_switch, + wifi_test_rf_sx_en, + wifi_test_pll_en, + wifi_test_slow_clk_en, + wifi_test_adc_clk_mode, + wifi_test_measure_mode, + wifi_test_vlt_comp, + wifi_test_get_dpd_tx_gain, + wifi_test_dpd_en, + wifi_test_tssi_en, + wifi_test_get_tx_gain_code, + wifi_test_tx_pwr_mode, +}; + +static INT32 wifi_test_get_tx_cnt(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + + memcpy(¶m->data, &ATECtrl->TxDoneCount, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_tx_ok_cnt(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_rx_ok_cnt(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)(&cmd_hdr->data); + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 mcs_err = 0; + UINT32 mac_mdrdy = 0; + UINT32 value = 0; + + /* Get latest FCSErr. sync iwpriv & HQA same FCSErr result */ + NICUpdateRawCounters(pAd); + mcs_err = ATECtrl->RxMacFCSErrCount; + RTMP_IO_READ32(pAd, MIB_MSDR10, &value); + ATECtrl->RxMacMdrdyCount += value; + mac_mdrdy = ATECtrl->RxMacMdrdyCount; + value = mac_mdrdy - mcs_err; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, rx_ok: %u, err: %u\n", __func__, value, ATECtrl->RxMacFCSErrCount)); + memcpy(¶m->data, &value, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_rx_err_cnt(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)(&cmd_hdr->data); + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 mcs_err = 0; + + /* Get latest FCSErr. sync iwpriv & HQA same FCSErr result */ + NICUpdateRawCounters(pAd); + mcs_err = ATECtrl->RxMacFCSErrCount; + memcpy(¶m->data, &mcs_err, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, mcs_err: %u\n", __func__, mcs_err)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_result_len(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_trx_iq_cal(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_tssi_cal(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_dpd_cal(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_rxv_dump(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_rx_stat(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_rpi_ipi(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_tmp_sensor(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_vlt_sensor(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_read_efuse(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_rx_rssi(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 value = 0; + + /* HqaRxStat.DriverRxCount = OS_NTOHL(ATECtrl->RxTotalCnt); */ + /* HqaRxStat.RCPI0 = OS_NTOHL(ATECtrl->RCPI0); */ + /* HqaRxStat.RCPI1 = OS_NTOHL(ATECtrl->RCPI1); */ + /* HqaRxStat.FreqOffsetFromRX = OS_NTOHL(ATECtrl->FreqOffsetFromRx); */ + value |= (0x000000ff & ATECtrl->LastRssi0); + value = value << 8; + value |= (0x000000ff & ATECtrl->MaxRssi0); + value = value << 8; + value |= (0x000000ff & ATECtrl->MinRssi0); + value = value << 8; + value |= (0x000000ff & ATECtrl->AvgRssi0); + memcpy(¶m->data, &value, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, value:0x%x, last:0x%x,max:0x%x, min:0x%x, avg:0x%x\n", + __func__, value, ATECtrl->LastRssi0, ATECtrl->MaxRssi0, ATECtrl->MinRssi0, ATECtrl->AvgRssi0)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_fw_info(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0x0001; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(¶m->data, &val, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_dri_info(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0x7636; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(¶m->data, &val, 4); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_pwr_detector(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_get_phy_rssi(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 IBRssi0, IBRssi1, WBRssi0, WBRssi1; + UINT32 value; + + RTMP_IO_READ32(pAd, RO_AGC_DEBUG_2, &value); + IBRssi0 = (value & 0xFF000000) >> 24; + + if (IBRssi0 > 128) + IBRssi0 -= 256; + + WBRssi0 = (value & 0x00FF0000) >> 16; + + if (WBRssi0 > 128) + WBRssi0 -= 256; + + /* Rx1 Rssi */ + IBRssi1 = (value & 0x0000FF00) >> 8; + + if (IBRssi1 > 128) + IBRssi1 -= 256; + + WBRssi1 = (value & 0x000000FF); + + if (WBRssi1 > 128) + WBRssi1 -= 256; + + value = 0; + value |= (0x000000ff & WBRssi0); + value <<= 16; + value |= (0x000000ff & IBRssi0); + memcpy(¶m->data, &value, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, Return: 0x%x, WBRssi:0x%x, IBRssi:0x%x\n", __func__, value, WBRssi0, IBRssi0)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_get_rx_rssi1(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + UINT32 value = 0; + + /* HqaRxStat.DriverRxCount = OS_NTOHL(ATECtrl->RxTotalCnt); */ + /* HqaRxStat.RCPI0 = OS_NTOHL(ATECtrl->RCPI0); */ + /* HqaRxStat.RCPI1 = OS_NTOHL(ATECtrl->RCPI1); */ + /* HqaRxStat.FreqOffsetFromRX = OS_NTOHL(ATECtrl->FreqOffsetFromRx); */ + value |= (0x000000ff & ATECtrl->LastRssi1); + value = value << 8; + value |= (0x000000ff & ATECtrl->MaxRssi1); + value = value << 8; + value |= (0x000000ff & ATECtrl->MinRssi1); + value = value << 8; + value |= (0x000000ff & ATECtrl->AvgRssi1); + memcpy(¶m->data, &value, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, value:0x%x, last:0x%x,max:0x%x, min:0x%x, avg:0x%x\n", + __func__, value, ATECtrl->LastRssi1, ATECtrl->MaxRssi1, ATECtrl->MinRssi1, ATECtrl->AvgRssi1)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*param), ret); + return ret; +} + +static INT32 wifi_test_pwr_cfg_tx1(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + UINT32 value = 0; + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, sizeof(val)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val:0x%x\n", __func__, val)); + pAd->ATECtrl.TxPower1 = val; + /* TODO Add in the setting of another Tx Power, txpwr1*/ + ret = ATEOp->SetTxPower0(pAd, val, 0); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return value; +} + +static INT32 wifi_test_tx_path_sel(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Val: %x\n", __func__, val)); + ret = ATEOp->SetTxAntenna(pAd, (CHAR)val); + return ret; +} + +static INT32 wifi_test_rx_path_sel(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Val: %x\n", __func__, val)); + ret = ATEOp->SetRxAntenna(pAd, (CHAR)val); + return ret; +} + +static META_CMD_HANDLER WIFI_TEST_CMD_SET2[] = { + wifi_test_get_tx_cnt, /* 32 */ + wifi_test_get_tx_ok_cnt, + wifi_test_rx_ok_cnt, + wifi_test_rx_err_cnt, + wifi_test_get_result_len, /* For next 6 command */ + wifi_test_get_trx_iq_cal, + wifi_test_get_tssi_cal, + wifi_test_get_dpd_cal, + wifi_test_rxv_dump, + wifi_test_get_rx_stat, + wifi_test_get_rpi_ipi, + wifi_test_get_tmp_sensor, + wifi_test_get_vlt_sensor, + wifi_test_read_efuse, + wifi_test_get_rx_rssi, + wifi_test_get_fw_info, + wifi_test_get_dri_info, + wifi_test_get_pwr_detector, + wifi_test_get_phy_rssi, /* 50 */ + wifi_test_pwr_cfg_tx1, + wifi_test_tx_path_sel, + wifi_test_rx_path_sel, + wifi_test_get_rx_rssi1, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static INT32 wifi_test_set_dpd(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_cw_mode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, val: %d, Ant: 0x%x\n", __func__, val, ATECtrl->TxAntennaSel)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_jp_ch_flt_en(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_write_efuse(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + UINT32 offset = 0; + + FUNC_IDX_GET_SUBFIELD(param->idx, offset); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_ra(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_ta(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_rx_match_rule(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_ch_bw(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + + switch (val) { + case 0: + ATECtrl->BW = BW_20; + break; + + case 1: + ATECtrl->BW = BW_40; + break; + + case 2: + ATECtrl->BW = BW_80; + break; + + case 3: + default: + /* Not support yet */ + return -1; + } + + ATECtrl->ControlChl = ATECtrl->Channel; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Channel = %d, ContrlChl: 0x%x, BW = %d\n", __func__, ATECtrl->Channel, ATECtrl->ControlChl, ATECtrl->BW)); + ret = ATEOp->SetBW(pAd, ATECtrl->BW); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_data_bw(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + /* struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val:0x%x\n", __func__, val)); + + switch (val) { + case 0: + /* ATECtrl->PerPktBW = BW_20; */ + break; + + case 1: + /* ATECtrl->PerPktBW = BW_40; */ + break; + + case 2: + /* ATECtrl->PerPktBW = BW_80; */ + break; + + case 3: + default: + /* Not support yet */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, Invalid Paramter(%x)\n", __func__, val)); + ret = -1; + break; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Channel = %d, BW = %d\n", __func__, ATECtrl->Channel, ATECtrl->BW)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_primary(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + /* struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + ATECtrl->ControlChl = val; + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_encode_mode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + INT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy((PUCHAR)&val, ¶m->data, 4); + /* ATECtrl->Ldpc = val; */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_jmode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _PARAM_MTK_WIFI_TEST *param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = NDIS_STATUS_FAILURE; + INT32 val = 0; + INT32 mode = 8; + INT32 pwr1 = 0xf; + INT32 pwr2 = 0; + CHAR txpwr = 0; + + memcpy((PUCHAR)&val, ¶m->data, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, val: %d, Ant: 0x%x\n", __func__, val, ATECtrl->TxAntennaSel)); + + /* TxAntennaSel, 0: All 1:TX0 2:TX1 */ + /* val, 0: disable, 1.5M single tone, 2.10M single tone */ + switch (val) { + case 1: + if (ATECtrl->TxAntennaSel == 1) { + mode = WF0_TX_ONE_TONE_5M; + txpwr = ATECtrl->TxPower0; + } else if (ATECtrl->TxAntennaSel == 2) { + mode = WF1_TX_ONE_TONE_5M; + txpwr = ATECtrl->TxPower1; + } else + goto meta_jmode_done; + + ret = ATEOp->StartTxTone(pAd, mode); + break; + + case 2: + if (ATECtrl->TxAntennaSel == 1) { + mode = WF0_TX_ONE_TONE_10M; + txpwr = ATECtrl->TxPower0; + } else if (ATECtrl->TxAntennaSel == 2) { + mode = WF1_TX_ONE_TONE_10M; + txpwr = ATECtrl->TxPower1; + } else + goto meta_jmode_done; + + ret = ATEOp->StartTxTone(pAd, mode); + break; + + default: + ret = ATEOp->StopTxTone(pAd); + goto meta_jmode_done; + } + + if (txpwr > 30) + pwr2 = (txpwr - 30) << 1; + else { + pwr1 = (txpwr & 0x1e) >> 1; + pwr2 = (txpwr & 0x01) << 1; + } + + ret = ATEOp->SetTxTonePower(pAd, pwr1, pwr2); +meta_jmode_done: + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_inter_cap_cont(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_inter_cap_trig(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_inter_cap_size(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + /* INT32 val = 0; */ + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static INT32 wifi_test_set_inter_cap_trig_offset(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static META_CMD_HANDLER WIFI_TEST_CMD_SET3[] = { + wifi_test_set_dpd, /* 64 */ + wifi_test_set_cw_mode, + wifi_test_jp_ch_flt_en, + wifi_test_write_efuse, + wifi_test_set_ra, + wifi_test_set_ta, + wifi_test_set_rx_match_rule, + wifi_test_set_ch_bw, + wifi_test_set_data_bw, + wifi_test_set_primary, + wifi_test_set_encode_mode, + wifi_test_set_jmode, + wifi_test_set_inter_cap_cont, + wifi_test_set_inter_cap_trig, + wifi_test_set_inter_cap_size, + wifi_test_set_inter_cap_trig_offset,/* 84 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 95 */ +}; + +static INT32 wifi_test_set_mod_patch(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + /* struct _PARAM_MTK_WIFI_TEST* param = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; */ + /* struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); */ + INT32 ret = NDIS_STATUS_SUCCESS; + + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, ret); + return ret; +} + +static META_CMD_HANDLER WIFI_TEST_CMD_SET5[] = { + wifi_test_set_mod_patch, /* 128 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + + +/* + * Command Set for OID_CUSTOM_MTK_WIFI_TEST + */ +static META_CMD_HANDLER *WIFI_TEST_CMD_SETS[] = { + WIFI_TEST_CMD_SET1, /* 0~31 */ + WIFI_TEST_CMD_SET2, /* 32~63 */ + WIFI_TEST_CMD_SET3, /* 64~95 */ + NULL, /* 96~127 */ + WIFI_TEST_CMD_SET5, /* 128~149 */ +}; +/* + * Buffer Length: 4 + * Return value: Chip Number, ex:0x00006620 + */ +static INT32 oid_if_version(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _META_CMD_HDR *cmd = cmd_hdr; + INT32 status = NDIS_STATUS_SUCCESS; + UINT32 value = 0x00006620; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: oid = 0x%04x, len:0x%x!\n", __func__, cmd_hdr->oid, cmd_hdr->len_in)); + memcpy(&cmd->data, &value, 4); + status = resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 4, status); + return status; +} + +/* + * Both SET/QUERY, using struct _PARAM_CUSTOM_MCR_RW for payload + */ +static INT32 oid_mcr_rw(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + PARAM_CUSTOM_MCR_RW *cmd = (PARAM_CUSTOM_MCR_RW *)cmd_hdr->data; + INT32 status = NDIS_STATUS_SUCCESS; + UINT32 value = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: MCR Access Offset = 0x%x\n", __func__, cmd->offset)); + + /* Check if access F/W Domain MCR (due to WiFiSYS is placed from 0x6000-0000*/ + if (ioctl_cmd == MTPRIV_IOCTL_META_SET) { + if (cmd->offset & 0xFFFF0000) { + RTMP_IO_WRITE32(pAd, cmd->offset, cmd->data); + RTMP_IO_READ32(pAd, cmd->offset, &value); + } else { + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: MCR Set Offset 0x%x, write in data: 0x%x, read after write: 0x%x\n", __func__, cmd->offset, cmd->data, value)); + } else if (ioctl_cmd == MTPRIV_IOCTL_META_QUERY) { + if (cmd->offset & 0xFFFF0000) + RTMP_IO_READ32(pAd, cmd->offset, &value); + else { + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: MCR Query Offset = 0x%02x, Val: 0x%x\n", __func__, cmd->offset, value)); + } else { + status = NDIS_STATUS_INVALID_DATA; + goto _mcr_rw_err; + } + + memcpy(&cmd->data, &value, 4); +_mcr_rw_err: + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*cmd), status); + return status; +} + +/* + * Both SET/QUERY, using struct _PARAM_CUSTOM_EEPROM_RW for payload + */ +static INT32 oid_eeprom_rw(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + PARAM_CUSTOM_EEPROM_RW *cmd = (PARAM_CUSTOM_EEPROM_RW *)cmd_hdr->data; + INT32 status = NDIS_STATUS_SUCCESS; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n%s: EEPROM Write Data = 0x%02x !\n", __func__, cmd->data)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*cmd), status); + return status; +} + +/* + * QUERY, using struct _PARAM_CUSTOM_EFUSE_RW for payload + */ +static INT32 oid_efuse_rw(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + PARAM_CUSTOM_EFUSE_RW *cmd = (PARAM_CUSTOM_EFUSE_RW *)cmd_hdr->data; + INT32 status = NDIS_STATUS_SUCCESS; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n%s: EFUSE Write Data = 0x%02x !\n", __func__, cmd->data)); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*cmd), status); + return status; +} + +/* + * Like ATEStart (?) + */ +static INT32 oid_test_mode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + INT32 status = NDIS_STATUS_SUCCESS; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: oid = 0x%04x, len:0x%x\n", __func__, cmd_hdr->oid, cmd_hdr->len_in)); + ATECtrl->bQAEnabled = TRUE; + /* Prepare feedback as soon as we can to avoid QA timeout. */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, status); + /* Initialization */ + g_SUB_TEST_STATE = WIFI_SUB_TEST_STANDBY; + ATECtrl->Channel = 1; + ATECtrl->ControlChl = 1; + status = ATEOp->ATEStart(pAd); + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, status); + return status; +} + +/* + * Like ATEStop (?) + */ +static INT32 oid_abort_test_mode(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + INT32 status = NDIS_STATUS_SUCCESS; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: oid = 0x%04x, len:0x%x!\n", __func__, cmd_hdr->oid, cmd_hdr->len_in)); + ATECtrl->bQAEnabled = FALSE; + /* Prepare feedback as soon as we can to avoid QA timeout. */ + resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 0, status); + status = ATEOp->ATEStop(pAd); + return status; +} + +/* + * Bunch of further commands + */ +static INT32 oid_mt_wifi_test(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + INT32 status = NDIS_STATUS_SUCCESS; + struct _PARAM_MTK_WIFI_TEST *cmd = (struct _PARAM_MTK_WIFI_TEST *)cmd_hdr->data; + INT32 idx = 0; + INT32 set_idx = 0; + INT32 handle_idx = 0; + + FUNC_IDX_GET_IDX(cmd->idx, idx); + set_idx = ((idx & ~MT_META_WIFI_TEST_CMD_MASK) >> 5)&MT_META_WIFI_TEST_SET_MASK; + handle_idx = idx & MT_META_WIFI_TEST_CMD_MASK; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: cmd->idx:0x%x ,set_idx:0x%04x, handle_idx:0x%04x\n", __func__, cmd->idx, set_idx, handle_idx)); + + if (!WIFI_TEST_CMD_SETS[set_idx]) + goto err_handle; + + if (!(*WIFI_TEST_CMD_SETS[set_idx][handle_idx])) + goto err_handle; + + (*WIFI_TEST_CMD_SETS[set_idx][handle_idx])(ioctl_cmd, pAd, WRQ, cmd_hdr); + return status; +err_handle: + return NDIS_STATUS_INVALID_DATA; +} + +static INT32 oid_cfg_src_type(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _META_CMD_HDR *cmd = cmd_hdr; + INT32 status = NDIS_STATUS_SUCCESS; + UINT32 value = 1; /* 1 For NVRAM */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: len:0x%x!\n", __func__, cmd->len_in)); + memcpy(&cmd->data, &value, 4); + status = resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 4, status); + return status; +} + +static INT32 oid_eeprom_type(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + struct _META_CMD_HDR *cmd = cmd_hdr; + INT32 status = NDIS_STATUS_SUCCESS; + UINT32 value = 0; /* 0 For EEPROM Not Present */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: len:0x%x!\n", __func__, cmd_hdr->len_in)); + memcpy(&cmd->data, &value, 4); + status = resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, 4, status); + return status; +} + +static INT32 oid_nvram_rw(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _META_CMD_HDR *cmd_hdr) +{ + PARAM_CUSTOM_NVRAM_RW *cmd = (PARAM_CUSTOM_NVRAM_RW *)cmd_hdr->data; + INT32 status = NDIS_STATUS_SUCCESS; + UINT16 value = 0; + UINT8 idx = cmd->idx << 1; + + if (ioctl_cmd == MTPRIV_IOCTL_META_SET) { + memcpy((PUCHAR)&value, &cmd->data, 4); + pAd->EEPROMImage[idx] = (0xff00 & value) >> 8; + pAd->EEPROMImage[idx + 1] = (0x00ff & value); + rtmp_ee_write_to_bin(pAd); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s-SET, method:0x%x ,offset:0x%x, valu:0x%x, EEPROMImage:0x%x\n", __func__, cmd->method, idx, value, pAd->EEPROMImage[idx])); + } else if (ioctl_cmd == MTPRIV_IOCTL_META_QUERY) { + if (cmd->method == PARAM_EEPROM_READ_METHOD_READ) { + value |= pAd->EEPROMImage[idx]; + value <<= 8; + value |= pAd->EEPROMImage[idx + 1]; + } else if (cmd->method == PARAM_EEPROM_READ_METHOD_GETSIZE) + value = EEPROM_SIZE; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s-QUREY, method:0x%x ,offset:0x%x, valu:0x%x\n", __func__, cmd->method, idx, value)); + } else { + } + + memcpy(&cmd->data, &value, 4); + status = resp_to_meta(ioctl_cmd, cmd_hdr, WRQ, sizeof(*cmd), status); + return status; +} + +/* + * Handler for Each OID + */ +static META_CMD_HANDLER OID_HANDLE[] = { + oid_if_version, + oid_mcr_rw, + oid_eeprom_rw, + oid_efuse_rw, + oid_test_mode, + oid_abort_test_mode, + oid_mt_wifi_test, + oid_cfg_src_type, + oid_eeprom_type, + oid_nvram_rw, +}; + +INT32 do_meta_cmd(INT32 ioctl_cmd, PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, RTMP_STRING *wrq_name) +{ + INT32 Status = NDIS_STATUS_SUCCESS; + struct _META_CMD_HDR *cmd_hdr; + UINT32 oid = 0; + INT32 ret = 0; + + os_alloc_mem_suspend(pAd, (UCHAR **)&cmd_hdr, sizeof(*cmd_hdr)); + + if (!cmd_hdr) { + Status = -ENOMEM; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, cmd_hdr NULL\n", __func__)); + goto ERROR0; + } + + if (!WRQ) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s. wrq is null\n", __func__)); + goto ERROR0; + } + + os_zero_mem(cmd_hdr, sizeof(*cmd_hdr)); + Status = copy_from_user((PUCHAR)cmd_hdr, WRQ->u.data.pointer, WRQ->u.data.length); +#ifdef _DUMP_HEX_ + { + UCHAR *pSrcBufVA = WRQ->u.data.pointer; + UINT32 SrcBufLen = WRQ->u.data.length; + unsigned char *pt; + INT32 x; + + pt = pSrcBufVA; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: %p, len = %d\n", + "META_IOCTL Content", pSrcBufVA, SrcBufLen)); + + for (x = 0; x < SrcBufLen; x++) { + if (x % 16 == 0) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("0x%04x : ", x)); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02x ", (unsigned char)pt[x])); + + if (x % 16 == 15) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + } +#endif + + if (Status) { + Status = -EFAULT; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, copy_from_user error\n", __func__)); + goto ERROR1; + } + + oid = cmd_hdr->oid; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() ==>,OID:0x%x, len:0x%x\n", __func__, oid, WRQ->u.data.length)); + + switch (oid) { + case OID_CUSTOM_IF_VER: + ret = (*OID_HANDLE[0])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_MCR_RW: + ret = (*OID_HANDLE[1])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_EEPROM_RW: + ret = (*OID_HANDLE[2])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_EFUSE_RW: + ret = (*OID_HANDLE[3])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_TEST_MODE: + ret = (*OID_HANDLE[4])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_ABORT_TEST_MODE: + ret = (*OID_HANDLE[5])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_MTK_WIFI_TEST: + ret = (*OID_HANDLE[6])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_CFG_SRC_TYPE: + ret = (*OID_HANDLE[7])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_EEPROM_TYPE: + ret = (*OID_HANDLE[8])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + case OID_CUSTOM_MTK_NVRAM_RW: + ret = (*OID_HANDLE[9])(ioctl_cmd, pAd, WRQ, cmd_hdr); + break; + + default: + Status = NDIS_STATUS_FAILURE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Unknown oid number of AT command = %x\n", oid)); + goto ERROR1; + } + +ERROR1: + os_free_mem(cmd_hdr); +ERROR0: + return Status; +} diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_ate.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_ate.c new file mode 100644 index 000000000..cfbca19c7 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_ate.c @@ -0,0 +1,1379 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + mt_ate.c +*/ +#include "rt_config.h" +static VOID MtATEWTBL2Update(RTMP_ADAPTER *pAd, UCHAR wcid) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + union WTBL_2_DW9 wtbl_2_d9 = {.word = 0}; + UINT32 rate[8]; /* reg_val; */ + UCHAR stbc, bw, nss, preamble; /* , wait_cnt = 0; */ + + bw = 2; + wtbl_2_d9.field.fcap = bw; + wtbl_2_d9.field.ccbw_sel = bw; + wtbl_2_d9.field.cbrn = 7; /* change bw as (fcap/2) if rate_idx > 7, temporary code */ + + if (ATECtrl->Sgi) { + wtbl_2_d9.field.g2 = 1; + wtbl_2_d9.field.g4 = 1; + wtbl_2_d9.field.g8 = 1; + wtbl_2_d9.field.g16 = 1; + } else { + wtbl_2_d9.field.g2 = 0; + wtbl_2_d9.field.g4 = 0; + wtbl_2_d9.field.g8 = 0; + wtbl_2_d9.field.g16 = 0; + } + + wtbl_2_d9.field.rate_idx = 0; + + if (ATECtrl->PhyMode == MODE_CCK) + preamble = SHORT_PREAMBLE; + else + preamble = LONG_PREAMBLE; + + stbc = ATECtrl->Stbc; + nss = 1; + rate[0] = tx_rate_to_tmi_rate(ATECtrl->PhyMode, + ATECtrl->Mcs, + nss, + stbc, + preamble); + rate[0] &= 0xfff; + rate[1] = rate[2] = rate[3] = rate[4] = rate[5] = rate[6] = rate[7] = rate[0]; + /* Wtbl2RateTableUpdate(pAd, wcid, wtbl_2_d9.word, rate); */ +} +static INT32 MT_ATERestoreInit(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Rx receive for 10000us workaround\n", __func__)); + /* Workaround CR Restore */ + /* Tx/Rx Antenna Setting Restore */ + MtAsicSetRxPath(pAd, 0); + /* TxRx switch workaround */ + AsicSetMacTxRx(pAd, ASIC_MAC_RX, TRUE); + RtmpusecDelay(10000); + AsicSetMacTxRx(pAd, ASIC_MAC_RX, FALSE); + /* Flag Resotre */ + ATECtrl->did_tx = 0; + ATECtrl->did_rx = 0; + + return Ret; +} + +static INT32 MT_ATESetTxPower0(RTMP_ADAPTER *pAd, CHAR Value) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->TxPower0 = Value; + ATECtrl->TxPower1 = Value; /* pAd->EEPROMImage[TX1_G_BAND_TARGET_PWR]; */ + CmdSetTxPowerCtrl(pAd, ATECtrl->Channel); + return Ret; +} + +static INT32 MT_ATESetTxPower1(RTMP_ADAPTER *pAd, CHAR Value) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + + ATECtrl->TxPower1 = Value; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + /* Same as Power0 */ + if (ATECtrl->TxPower0 != ATECtrl->TxPower1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: power1 do not same as power0\n", __func__)); + Ret = -1; + } + + return Ret; +} + + +static INT32 MT_ATEStart(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + BOOLEAN bCalFree = 0; +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID]; +#endif + INT32 i; + + i = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* Stop send TX packets */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); + /* Reset ATE TX/RX Counter */ + ATECtrl->TxDoneCount = 0; + ATECtrl->RxTotalCnt = 0; + ATECtrl->TxLength = 1024; + ATECtrl->LastRssi0 = 0; + ATECtrl->AvgRssi0X8 = 0; + ATECtrl->AvgRssi0 = 0; + ATECtrl->MaxRssi0 = 0xff; + ATECtrl->MinRssi0 = 0; + ATECtrl->LastRssi1 = 0; + ATECtrl->AvgRssi1X8 = 0; + ATECtrl->AvgRssi1 = 0; + ATECtrl->MaxRssi1 = 0xff; + ATECtrl->MinRssi1 = 0; + ATECtrl->LastRssi2 = 0; + ATECtrl->AvgRssi2X8 = 0; + ATECtrl->AvgRssi2 = 0; + ATECtrl->MaxRssi2 = 0xff; + ATECtrl->MinRssi2 = 0; + ATECtrl->QID = QID_AC_BE; + ATECtrl->tx_coherent = 0; + ATECtrl->cmd_expire = RTMPMsecsToJiffies(3000); + RTMP_OS_INIT_COMPLETION(&ATECtrl->cmd_done); + ATECtrl->TxPower0 = pAd->EEPROMImage[TX0_G_BAND_TARGET_PWR]; + ATECtrl->TxPower1 = pAd->EEPROMImage[TX1_G_BAND_TARGET_PWR]; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Init Txpower, Tx0:%x, Tx1:%x\n", __func__, ATECtrl->TxPower0, ATECtrl->TxPower1)); +#ifdef CONFIG_QA + MtAsicGetRxStat(pAd, HQA_RX_RESET_PHY_COUNT); + ATECtrl->RxMacMdrdyCount = 0; + ATECtrl->RxMacFCSErrCount = 0; +#endif /* CONFIG_QA */ +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + AsicSetMacTxRx(pAd, ASIC_MAC_RX, FALSE); + /* Disable TX PDMA */ + AsicSetWPDMA(pAd, PDMA_TX, 0); +#ifdef CONFIG_AP_SUPPORT + APStop(pAd, pMbss, AP_BSS_OPER_ALL); +#endif /* CONFIG_AP_SUPPORT */ +#ifdef RTMP_MAC_PCI + if_ops->init(pAd); + if_ops->clean_trx_q(pAd); +#endif /* RTMP_MAC_PCI */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 1); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + + /* MT7636 Test Mode Freqency offset restore*/ + if (ATECtrl->en_man_set_freq == 1) { + if (IS_MT76x6(pAd) || IS_MT7637(pAd)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MT76x6 Manual Set Frequency Restore\n")); + RTMP_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_ENABLE, ATECtrl->en_man_freq_restore); + RTMP_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_VALUE, ATECtrl->normal_freq_restore); + } + + ATECtrl->normal_freq_restore = 0; + ATECtrl->en_man_freq_restore = 0; + ATECtrl->en_man_set_freq = 0; + } + + if (ATECtrl->Mode & fATE_TXCONT_ENABLE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s ,Stop Continuous Tx\n", __func__)); + ATEOp->StopContinousTx(pAd); + } + + if (ATECtrl->Mode & fATE_TXCARRSUPP_ENABLE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s ,Stop Carrier Suppression Test\n", __func__)); + ATEOp->StopTxTone(pAd); + } + + ATECtrl->Mode = ATE_START; + ATECtrl->Mode &= ATE_RXSTOP; + ATECtrl->en_man_set_freq = 0; + ATECtrl->normal_freq_restore = 0; + ATECtrl->en_man_freq_restore = 0; + ATECtrl->TxDoneCount = 0; + ATECtrl->RxTotalCnt = 0; +#ifdef CONFIG_QA + MtAsicGetRxStat(pAd, HQA_RX_RESET_PHY_COUNT); + MtAsicGetRxStat(pAd, HQA_RX_RESET_MAC_COUNT); + ATECtrl->RxMacFCSErrCount = 0; + ATECtrl->RxMacMdrdyCount = 0; +#endif + MtATEWTBL2Update(pAd, 0); + return Ret; +} + + +static INT32 MT_ATEStop(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID]; +#endif + UCHAR Channel = HcGetRadioChannel(pAd); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + AsicSetMacTxRx(pAd, ASIC_MAC_RXV, FALSE); + NICInitializeAdapter(pAd); +#ifdef RTMP_MAC_PCI + + if (if_ops->clean_test_rx_frame) + if_ops->clean_test_rx_frame(pAd); + +#endif /* RTMP_MAC_PCI */ + /* if usb call this two function , FW will hang~~ */ + + if (if_ops->clean_trx_q) + if_ops->clean_trx_q(pAd); + + if (if_ops->ate_leave) + if_ops->ate_leave(pAd); + + AsicSetRxFilter(pAd); + RTMPEnableRxTx(pAd); + hc_reset_radio(pAd); +#ifdef CONFIG_AP_SUPPORT + APStartUp(pAd, pMbss, AP_BSS_OPER_ALL); +#endif /* CONFIG_AP_SUPPROT */ + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + + /* MT7636 Test Mode Freqency offset restore*/ + if (ATECtrl->en_man_set_freq == 1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MT76x6 Manual Set Frequency Restore\n")); + RTMP_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_ENABLE, ATECtrl->en_man_freq_restore); + RTMP_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_VALUE, ATECtrl->normal_freq_restore); + ATECtrl->normal_freq_restore = 0; + ATECtrl->en_man_freq_restore = 0; + ATECtrl->en_man_set_freq = 0; + } + + RTMP_OS_EXIT_COMPLETION(&ATECtrl->cmd_done); + ATECtrl->Mode = ATE_STOP; + + if ((MTK_REV_GTE(pAd, MT7603, MT7603E1)) || + (MTK_REV_GTE(pAd, MT7628, MT7628E1))) { + UINT32 Value; + + RTMP_IO_READ32(pAd, CR_RFINTF_00, &Value); + Value &= ~CR_RFINTF_CAL_NSS_MASK; + Value |= CR_RFINTF_CAL_NSS(0x0); + RTMP_IO_WRITE32(pAd, CR_RFINTF_00, Value); + } + + return Ret; +} + + +#ifdef RTMP_PCI_SUPPORT +static INT32 MT_ATESetupFrame(RTMP_ADAPTER *pAd, UINT32 TxIdx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + RTMP_TX_RING *pTxRing = &pAd->PciHif.TxRing[QID_AC_BE]; + PUCHAR pDMAHeaderBufVA = (PUCHAR)pTxRing->Cell[TxIdx].DmaBuf.AllocVa; + TXD_STRUC *pTxD; + MAC_TX_INFO Info; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 TXWISize = cap->TXWISize; + PNDIS_PACKET pPacket = NULL; + HTTRANSMIT_SETTING Transmit; + TX_BLK TxBlk; + INT32 Ret = 0; +#ifdef RT_BIG_ENDIAN + TXD_STRUC *pDestTxD; + UCHAR TxHwInfo[TXD_SIZE]; +#endif /* RT_BIG_ENDIAN */ + + ATECtrl->HLen = LENGTH_802_11; + NdisZeroMemory(&Transmit, sizeof(Transmit)); + NdisZeroMemory(&TxBlk, sizeof(TxBlk)); + /* Fill Mac Tx info */ + NdisZeroMemory(&Info, sizeof(Info)); + /* LMAC queue index (AC0) */ + Info.q_idx = 0; + Info.WCID = 0; + Info.hdr_len = ATECtrl->HLen; + Info.hdr_pad = 0; + Info.BM = IS_BM_MAC_ADDR(ATECtrl->Addr1); + /* no ack */ + Info.Ack = 0; + Info.bss_idx = 0; + /* no frag */ + Info.FRAG = 0; + /* no protection */ + Info.prot = 0; + Info.Length = ATECtrl->TxLength; + /* TX Path setting */ + Info.AntPri = 0; + Info.SpeEn = 0; + + switch (ATECtrl->TxAntennaSel) { + case 0: /* Both */ + Info.AntPri = 0; + Info.SpeEn = 1; + break; + + case 1: /* TX0 */ + Info.AntPri = 0; + Info.SpeEn = 0; + break; + + case 2: /* TX1 */ + Info.AntPri = 2; /* b'010 */ + Info.SpeEn = 0; + break; + } + + /* Fill Transmit setting */ + Transmit.field.MCS = ATECtrl->Mcs; + Transmit.field.BW = ATECtrl->BW; + Transmit.field.ShortGI = ATECtrl->Sgi; + Transmit.field.STBC = ATECtrl->Stbc; + Transmit.field.MODE = ATECtrl->PhyMode; + + if (ATECtrl->PhyMode == MODE_CCK) { + Info.Preamble = LONG_PREAMBLE; + + if (ATECtrl->Mcs == 9) { + Transmit.field.MCS = 0; + Info.Preamble = SHORT_PREAMBLE; + } else if (ATECtrl->Mcs == 10) { + Transmit.field.MCS = 1; + Info.Preamble = SHORT_PREAMBLE; + } else if (ATECtrl->Mcs == 11) { + Transmit.field.MCS = 2; + Info.Preamble = SHORT_PREAMBLE; + } + } + + Info.IsAutoRate = FALSE; + pAd->archOps.write_tmac_info_fixed_rate(pAd, pDMAHeaderBufVA, &Info, &Transmit); + NdisMoveMemory(pDMAHeaderBufVA + TXWISize, ATECtrl->TemplateFrame, ATECtrl->HLen); + NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 4, ATECtrl->Addr1, MAC_ADDR_LEN); + NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 10, ATECtrl->Addr2, MAC_ADDR_LEN); + NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 16, ATECtrl->Addr3, MAC_ADDR_LEN); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE); +#endif /* RT_BIG_ENDIAN */ + pPacket = ATEPayloadInit(pAd, TxIdx); + + if (pPacket == NULL) { + ATECtrl->TxCount = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: fail to init frame payload.\n", __func__)); + return -1; + } + + pTxRing->Cell[TxIdx].pNdisPacket = pPacket; + pTxD = (TXD_STRUC *)pTxRing->Cell[TxIdx].AllocVa; +#ifndef RT_BIG_ENDIAN + pTxD = (TXD_STRUC *)pTxRing->Cell[TxIdx].AllocVa; +#else + pDestTxD = (TXD_STRUC *)pTxRing->Cell[TxIdx].AllocVa; + NdisMoveMemory(&TxHwInfo[0], (UCHAR *)pDestTxD, TXD_SIZE); + pTxD = (TXD_STRUC *)&TxHwInfo[0]; +#endif + TxBlk.SrcBufLen = GET_OS_PKT_LEN(ATECtrl->pAtePacket[TxIdx]); + TxBlk.pSrcBufData = (PUCHAR)ATECtrl->AteAllocVa[TxIdx]; + NdisZeroMemory(pTxD, TXD_SIZE); + /* build Tx descriptor */ + pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); + pTxD->SDLen0 = TXWISize + ATECtrl->HLen; + pTxD->LastSec0 = 0; + pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, &TxBlk, 0, 1, RTMP_PCI_DMA_TODEVICE); + pTxD->SDLen1 = GET_OS_PKT_LEN(ATECtrl->pAtePacket[TxIdx]); + pTxD->LastSec1 = 1; + pTxD->DMADONE = 0; +#ifdef RT_BIG_ENDIAN + MTMacInfoEndianChange(pAd, pDMAHeaderBufVA, TYPE_TMACINFO, sizeof(TMAC_TXD_L)); + RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE); + RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); + WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); +#endif + return Ret; +} +#endif + + + + +static INT32 MT_ATEStartTx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + UINT32 Value = 0; + INT32 Ret = 0; +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; +#endif + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + /* TxRx switch workaround */ + if (ATECtrl->did_rx == 1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: DID Rx Before\n", __func__)); + MT_ATERestoreInit(pAd); + } + + MtCmdChannelSwitch(pAd, ATECtrl->ControlChl, ATECtrl->Channel, ATECtrl->BW, + pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, FALSE); + AsicSetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE); + /* Stop send TX packets */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + /* Disable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX, 0); + /* Polling TX/RX path until packets empty */ + + if (if_ops->clean_trx_q) + if_ops->clean_trx_q(pAd); + + + /* Turn on RX again if set before */ + if (ATECtrl->Mode & ATE_RXFRAME) + AsicSetMacTxRx(pAd, ASIC_MAC_RX_RXV, TRUE); + + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + if (if_ops->setup_frame) + if_ops->setup_frame(pAd, QID_AC_BE); + + if (if_ops->test_frame_tx) { + if_ops->test_frame_tx(pAd); + + if (ATECtrl->TxCount != 0xFFFFFFFF) + ATECtrl->TxCount += ATECtrl->TxDoneCount; + + ATECtrl->Mode |= ATE_TXFRAME; + } else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: no tx test frame callback function\n", __func__)); + + + /* Low temperature high rate EVM degrade Patch v2 */ + if ((MTK_REV_GTE(pAd, MT7603, MT7603E1)) || + (MTK_REV_GTE(pAd, MT7628, MT7628E1))) { + if (ATECtrl->TxAntennaSel == 0) { + RTMP_IO_READ32(pAd, CR_RFINTF_00, &Value); + Value &= ~CR_RFINTF_CAL_NSS_MASK; + Value |= CR_RFINTF_CAL_NSS(0x0); + RTMP_IO_WRITE32(pAd, CR_RFINTF_00, Value); + } else if (ATECtrl->TxAntennaSel == 1) { + RTMP_IO_READ32(pAd, CR_RFINTF_00, &Value); + Value &= ~CR_RFINTF_CAL_NSS_MASK; + Value |= CR_RFINTF_CAL_NSS(0x0); + RTMP_IO_WRITE32(pAd, CR_RFINTF_00, Value); + } else if (ATECtrl->TxAntennaSel == 2) { + RTMP_IO_READ32(pAd, CR_RFINTF_00, &Value); + Value &= ~CR_RFINTF_CAL_NSS_MASK; + Value |= CR_RFINTF_CAL_NSS(0x1); + RTMP_IO_WRITE32(pAd, CR_RFINTF_00, Value); + } + } + + ATECtrl->did_tx = 1; + return Ret; +} + + +static INT32 MT_ATEStartRx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0, Value; + UINT32 reg; +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; +#endif + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + RTMP_IO_READ32(pAd, ARB_SCR, ®); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: ARB_SCR:%x\n", __func__, reg)); + reg &= ~MT_ARB_SCR_RXDIS; + RTMP_IO_WRITE32(pAd, ARB_SCR, reg); + AsicSetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE); + /* Stop send TX packets */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + AsicSetWPDMA(pAd, PDMA_TX, 0); + + if (if_ops->clean_trx_q) + if_ops->clean_trx_q(pAd); + + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + /* Turn on TX again if set before */ + if (ATECtrl->Mode & ATE_TXFRAME) + AsicSetMacTxRx(pAd, ASIC_MAC_TX, TRUE); + + /* reset counter when iwpriv only */ + if (ATECtrl->bQAEnabled != TRUE) + ATECtrl->RxTotalCnt = 0; + + pAd->WlanCounters[0].FCSErrorCount.u.LowPart = 0; + RTMP_IO_READ32(pAd, RMAC_RFCR, &Value); + Value |= RM_FRAME_REPORT_EN; + RTMP_IO_WRITE32(pAd, RMAC_RFCR, Value); + AsicSetMacTxRx(pAd, ASIC_MAC_RX_RXV, TRUE); + /* Enable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 1); + ATECtrl->Mode |= ATE_RXFRAME; + ATECtrl->did_rx = 1; + return Ret; +} + + +static INT32 MT_ATEStopTx(RTMP_ADAPTER *pAd, UINT32 Mode) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 num_of_tx_ring = GET_NUM_OF_TX_RING(cap); + INT32 Ret = 0; + INT32 acidx; + + acidx = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if ((Mode & ATE_TXFRAME) || (Mode == ATE_STOP)) { + /* Disable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 0); + + if (if_ops->clean_trx_q) + if_ops->clean_trx_q(pAd); + + ATECtrl->Mode &= ~ATE_TXFRAME; + /* Enable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 1); + } + + return Ret; +} + + +static INT32 MT_ATEStopRx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + INT32 i; + UINT32 reg; + + i = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Ret = AsicSetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE); + RTMP_IO_READ32(pAd, ARB_SCR, ®); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: ARB_SCR:%x\n", __func__, reg)); + reg |= MT_ARB_SCR_RXDIS; + RTMP_IO_WRITE32(pAd, ARB_SCR, reg); + ATECtrl->Mode &= ~ATE_RXFRAME; + return Ret; +} + + +static INT32 MT_ATESetTxAntenna(RTMP_ADAPTER *pAd, CHAR Ant) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UINT32 Value; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* 0: All 1:TX0 2:TX1 */ + ATECtrl->TxAntennaSel = Ant; + + if ((MTK_REV_GTE(pAd, MT7603, MT7603E1)) || + (MTK_REV_GTE(pAd, MT7628, MT7628E1))) { + UCHAR ePA; +#ifdef RTMP_EFUSE_SUPPORT + + if (pAd->E2pAccessMode == E2P_NONE) { + UINT16 v_efuse = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: E2P_NONE\n", __func__)); + rtmp_ee_efuse_read16(pAd, 0x35, &v_efuse); + + if (v_efuse == 0) + ePA = pAd->EEPROMImage[0x35]; + else + ePA = (v_efuse >> 8) & 0x00FF; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("E2P_NONE, EFUSE Value == 0x%x, ePA:0x%x\n", v_efuse, ePA)); + } else if (pAd->E2pAccessMode == E2P_EFUSE_MODE) { + UINT16 v_efuse = 0; + + rtmp_ee_efuse_read16(pAd, 0x35, &v_efuse); + ePA = (v_efuse >> 8) & 0x00FF; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("EFUSE_MODE, EFUSE Value == 0x%x, ePA:0x%x\n", v_efuse, ePA)); + } else +#endif /* RTMP_EFUSE_SUPPORT */ + { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: BIN/FLASH/EEPROM_MODE(0x%x), get value in buffer\n", __func__, pAd->E2pAccessMode)); + ePA = pAd->EEPROMImage[0x35]; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: ePA:0x%x, E2pAccessMode:0x%x\n", __func__, ePA, pAd->E2pAccessMode)); + + if (ATECtrl->TxAntennaSel == 0) { + RTMP_IO_READ32(pAd, CR_RFINTF_00, &Value); + Value &= ~CR_RFINTF_CAL_NSS_MASK; + Value |= CR_RFINTF_CAL_NSS(0x0); + RTMP_IO_WRITE32(pAd, CR_RFINTF_00, Value); + + /* ePA Tx1 patch, bit[1]: 2.4G ePA Enable, same as Tx0 */ + if (ePA & 0x02) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + UINT32 value; + + RTMP_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(0x81060008) << 19; + RemapOffset = GET_REMAP_2_OFFSET(0x81060008); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + + if ((MTK_REV_GTE(pAd, MT7603, MT7603E1)) || + (MTK_REV_GTE(pAd, MT7603, MT7603E2))) { + value = 0x04852390; + RTMP_IO_WRITE32(pAd, 0x80000 + RemapOffset, value); + } else if (MTK_REV_GTE(pAd, MT7628, MT7628E1)) { + value = 0x00489523; + RTMP_IO_WRITE32(pAd, 0x80000 + RemapOffset, value); + } + + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } + } else if (ATECtrl->TxAntennaSel == 1) { + RTMP_IO_READ32(pAd, CR_RFINTF_00, &Value); + Value &= ~CR_RFINTF_CAL_NSS_MASK; + Value |= CR_RFINTF_CAL_NSS(0x0); + RTMP_IO_WRITE32(pAd, CR_RFINTF_00, Value); + + /* ePA Tx1 patch, bit[1]: 2.4G ePA Enable */ + if (ePA & 0x02) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + UINT32 value; + + RTMP_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(0x81060008) << 19; + RemapOffset = GET_REMAP_2_OFFSET(0x81060008); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + + if ((MTK_REV_GTE(pAd, MT7603, MT7603E1)) || + (MTK_REV_GTE(pAd, MT7603, MT7603E2))) { + value = 0x04852390; + RTMP_IO_WRITE32(pAd, 0x80000 + RemapOffset, value); + } else if (MTK_REV_GTE(pAd, MT7628, MT7628E1)) { + value = 0x00489523; + RTMP_IO_WRITE32(pAd, 0x80000 + RemapOffset, value); + } + + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } + } else if (ATECtrl->TxAntennaSel == 2) { + RTMP_IO_READ32(pAd, CR_RFINTF_00, &Value); + Value &= ~CR_RFINTF_CAL_NSS_MASK; + Value |= CR_RFINTF_CAL_NSS(0x1); + RTMP_IO_WRITE32(pAd, CR_RFINTF_00, Value); + + /* ePA Tx1 patch, bit[1]: 2.4G ePA Enable */ + if (ePA & 0x02) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + UINT32 value; + + RTMP_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(0x81060008) << 19; + RemapOffset = GET_REMAP_2_OFFSET(0x81060008); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + + if ((MTK_REV_GTE(pAd, MT7603, MT7603E1)) || + (MTK_REV_GTE(pAd, MT7603, MT7603E2))) { + value = 0x04856790; + RTMP_IO_WRITE32(pAd, 0x80000 + RemapOffset, value); + } else if (MTK_REV_GTE(pAd, MT7628, MT7628E1)) { + value = 0x00489567; + RTMP_IO_WRITE32(pAd, 0x80000 + RemapOffset, value); + } + + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } + } + } + + return Ret; +} + + +static INT32 MT_ATESetRxAntenna(RTMP_ADAPTER *pAd, CHAR Ant) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->RxAntennaSel = Ant; + /* set RX path */ + MtAsicSetRxPath(pAd, (UINT32)ATECtrl->RxAntennaSel, 0); + return Ret; +} + + +static INT32 MT_ATESetTxFreqOffset(RTMP_ADAPTER *pAd, UINT32 FreqOffset) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UINT32 reg = 0; + + ATECtrl->RFFreqOffset = FreqOffset; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (IS_MT76x6(pAd) || IS_MT7637(pAd)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MT76x6 Manual Set Frequency\n")); + RTMP_IO_READ32(pAd, FREQ_OFFSET_MANUAL_ENABLE, ®); + + if (ATECtrl->en_man_freq_restore == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MT76x6 Normal Set Frequency BK\n")); + ATECtrl->en_man_freq_restore = reg; + } + + reg = (reg & 0xFFFF80FF) | (0x7F << 8); + RTMP_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_ENABLE, reg); + ATECtrl->en_man_set_freq = 1; + } + + if (ATECtrl->en_man_set_freq == 1) { + RTMP_IO_READ32(pAd, FREQ_OFFSET_MANUAL_VALUE, ®); + + if (ATECtrl->normal_freq_restore == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MT76x6 Normal Frequency BK\n")); + ATECtrl->normal_freq_restore = reg; + } + + reg = (reg & 0xFFFF80FF) | (ATECtrl->RFFreqOffset << 8); + RTMP_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_VALUE, reg); + } else + MtAsicSetRfFreqOffset(pAd, ATECtrl->RFFreqOffset); + + return Ret; +} + +static INT32 MT_ATESetChannel(RTMP_ADAPTER *pAd, INT16 Value) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MtCmdChannelSwitch(pAd, ATECtrl->ControlChl, ATECtrl->Channel, ATECtrl->BW, + pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, FALSE); + return Ret; +} + + +static INT32 MT_ATESetBW(RTMP_ADAPTER *pAd, INT16 Value) +{ + INT32 Ret = 0; + UINT32 val = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + RTMP_IO_READ32(pAd, AGG_BWCR, &val); + val &= (~0x0c); + + switch (Value) { + case BW_20: + val |= (0); + break; + + case BW_40: + val |= (0x1 << 2); + break; + + case BW_80: + val |= (0x2 << 2); + break; + } + + RTMP_IO_WRITE32(pAd, AGG_BWCR, val); + /* TODO: check CMD_CH_PRIV_ACTION_BW_REQ */ + /* CmdChPrivilege(pAd, CMD_CH_PRIV_ACTION_BW_REQ, ATECtrl->ControlChl, ATECtrl->Channel, */ + /* ATECtrl->BW, pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath); */ + return Ret; +} + + +static INT32 MT_ATESampleRssi(RTMP_ADAPTER *pAd, RX_BLK *RxBlk) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + + if (RxBlk->rx_signal.raw_rssi[0] != 0) { + ATECtrl->LastRssi0 = ConvertToRssi(pAd, + (struct raw_rssi_info *)(&RxBlk->rx_signal.raw_rssi[0]), RSSI_IDX_0); + + if (ATECtrl->MaxRssi0 < ATECtrl->LastRssi0) + ATECtrl->MaxRssi0 = ATECtrl->LastRssi0; + + if (ATECtrl->MinRssi0 > ATECtrl->LastRssi0) + ATECtrl->MinRssi0 = ATECtrl->LastRssi0; + + ATECtrl->AvgRssi0X8 = (ATECtrl->AvgRssi0X8 - ATECtrl->AvgRssi0) + + ATECtrl->LastRssi0; + ATECtrl->AvgRssi0 = ATECtrl->AvgRssi0X8 >> 3; + } + + if (RxBlk->rx_signal.raw_rssi[1] != 0) { + ATECtrl->LastRssi1 = ConvertToRssi(pAd, + (struct raw_rssi_info *)(&RxBlk->rx_signal.raw_rssi[0]), RSSI_IDX_1); + + if (ATECtrl->MaxRssi1 < ATECtrl->LastRssi1) + ATECtrl->MaxRssi1 = ATECtrl->LastRssi1; + + if (ATECtrl->MinRssi1 > ATECtrl->LastRssi1) + ATECtrl->MinRssi1 = ATECtrl->LastRssi1; + + ATECtrl->AvgRssi1X8 = (ATECtrl->AvgRssi1X8 - ATECtrl->AvgRssi1) + + ATECtrl->LastRssi1; + ATECtrl->AvgRssi1 = ATECtrl->AvgRssi1X8 >> 3; + } + + ATECtrl->LastSNR0 = RxBlk->rx_signal.raw_snr[0]; + ATECtrl->LastSNR1 = RxBlk->rx_signal.raw_snr[1]; + ATECtrl->NumOfAvgRssiSample++; + return Ret; +} + +static INT32 MT_ATESetAIFS(RTMP_ADAPTER *pAd, CHAR Value) +{ + INT32 Ret = 0; + UINT val = Value & 0x000000ff; + + /* Test mode use AC0 for TX */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Value:%x\n", __func__, val)); + AsicSetWmmParam(pAd, 0, WMM_PARAM_AC_0, WMM_PARAM_AIFSN, val); + return Ret; +} + +static INT32 MT_ATESetTSSI(RTMP_ADAPTER *pAd, CHAR WFSel, CHAR Setting) +{ + INT32 Ret = 0; + + Ret = MtAsicSetTSSI(pAd, Setting, WFSel); + return Ret; +} + +static INT32 MT_ATESetDPD(RTMP_ADAPTER *pAd, CHAR WFSel, CHAR Setting) +{ + /* !!TEST MODE ONLY!! Normal Mode control by FW and Never disable */ + /* WF0 = 0, WF1 = 1, WF ALL = 2 */ + INT32 Ret = 0; + + Ret = MtAsicSetDPD(pAd, Setting, WFSel); + return Ret; +} + +static INT32 MT_ATEStartTxTone(RTMP_ADAPTER *pAd, UINT32 Mode) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MtAsicSetTxToneTest(pAd, 1, Mode); + return Ret; +} + +static INT32 MT_ATESetTxTonePower(RTMP_ADAPTER *pAd, INT32 pwr1, INT32 pwr2) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: pwr1:%d, pwr2:%d\n", __func__, pwr1, pwr2)); + MtAsicSetTxTonePower(pAd, pwr1, pwr2); + return Ret; +} + +static INT32 MT_ATEStopTxTone(RTMP_ADAPTER *pAd) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MtAsicSetTxToneTest(pAd, 0, 0); + return Ret; +} + +static INT32 MT_ATEStartContinousTx(RTMP_ADAPTER *pAd, CHAR WFSel) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + CmdTxContinous(pAd, ATECtrl->PhyMode, ATECtrl->BW, ATECtrl->ControlChl, ATECtrl->Mcs, ATECtrl->TxAntennaSel, 1); + return Ret; +} + +static INT32 MT_ATEStopContinousTx(RTMP_ADAPTER *pAd) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + + CmdTxContinous(pAd, ATECtrl->PhyMode, ATECtrl->BW, ATECtrl->ControlChl, ATECtrl->Mcs, ATECtrl->TxAntennaSel, 0); + return Ret; +} + +static INT32 MT_RfRegWrite(RTMP_ADAPTER *pAd, UINT32 WFSel, UINT32 Offset, UINT32 Value) +{ + INT32 Ret = 0; + + Ret = MtCmdRFRegAccessWrite(pAd, WFSel, Offset, Value); + return Ret; +} + + +static INT32 MT_RfRegRead(RTMP_ADAPTER *pAd, UINT32 WFSel, UINT32 Offset, UINT32 *Value) +{ + INT32 Ret = 0; + + Ret = MtCmdRFRegAccessRead(pAd, WFSel, Offset, Value); + return Ret; +} + + +static INT32 MT_GetFWInfo(RTMP_ADAPTER *pAd, UCHAR *FWInfo) +{ + struct fwdl_ctrl *ctrl = &pAd->MCUCtrl.fwdl_ctrl; + + memcpy(FWInfo, ctrl->fw_profile[WM_CPU].source.img_ptr + ctrl->fw_profile[WM_CPU].source.img_len - 36, 36); + return 0; +} + + +#ifdef TXBF_SUPPORT +/* + *========================================================================== + * Description: + * Set ATE Tx Beamforming mode + * + * Return: + * TRUE if all parameters are OK, FALSE otherwise + *========================================================================== +*/ +INT MT_SetATETxBfProc(RTMP_ADAPTER *pAd, UCHAR TxBfEnFlg) +{ + /* PATE_INFO pATEInfo = &(pAd->ate); */ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + + switch (TxBfEnFlg) { + case 0: + /* no BF */ + ATECtrl->iTxBf = FALSE; + ATECtrl->eTxBf = FALSE; + break; + + case 1: + /* ETxBF */ + ATECtrl->iTxBf = FALSE; + ATECtrl->eTxBf = TRUE; + break; + + case 2: + /* ITxBF */ + ATECtrl->iTxBf = TRUE; + ATECtrl->eTxBf = FALSE; + break; + + case 3: + /* Enable TXBF support */ + ATECtrl->iTxBf = TRUE; + ATECtrl->eTxBf = TRUE; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Set_ATE_TXBF_Proc: Invalid parameter %d\n", TxBfEnFlg)); + break; + } + +#ifdef MT_MAC + + if (ATECtrl->eTxBf == TRUE) { + /* Enable sounding trigger in FW */ + AsicBfSoundingPeriodicTriggerCtrl(pAd, BSSID_WCID, TRUE); + } else { + /* Disable sounding trigger in FW */ + AsicBfSoundingPeriodicTriggerCtrl(pAd, BSSID_WCID, FALSE); + } + +#endif + return TRUE; +} + + +#ifdef MT_MAC +/* + *========================================================================== + *Description: + * Enable sounding trigger + * + * Return: + * TRUE if all parameters are OK, FALSE otherwise + *========================================================================== +*/ +INT MT_SetATESoundingProc(RTMP_ADAPTER *pAd, UCHAR SDEnFlg) +{ + /* Enable sounding trigger in FW */ + return AsicBfSoundingPeriodicTriggerCtrl(pAd, BSSID_WCID, SDEnFlg); +} +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + + + +#ifdef RTMP_MAC_PCI +static INT32 pci_ate_init(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 Index; + RTMP_TX_RING *pTxRing = &pAd->PciHif.TxRing[QID_AC_BE]; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + HIF_IO_READ32(pAd, pTxRing->hw_didx_addr, &pTxRing->TxDmaIdx); + pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx; + pTxRing->TxCpuIdx = pTxRing->TxDmaIdx; + HIF_IO_WRITE32(pAd, pTxRing->hw_cidx_addr, pTxRing->TxCpuIdx); + + for (Index = 0; Index < TX_RING_SIZE; Index++) { + if (ATEPayloadAlloc(pAd, Index) != (NDIS_STATUS_SUCCESS)) { + ATECtrl->allocated = 0; + goto pci_ate_init_err; + } + } + + ATECtrl->allocated = 1; + RTMP_ASIC_INTERRUPT_ENABLE(pAd); + return NDIS_STATUS_SUCCESS; +pci_ate_init_err: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Allocate test packet fail at pakcet%d\n", __func__, Index)); + return NDIS_STATUS_FAILURE; +} + +static INT32 pci_clean_q(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 Index; + TXD_STRUC *pTxD = NULL; + RTMP_TX_RING *pTxRing = &pAd->PciHif.TxRing[QID_AC_BE]; +#ifdef RT_BIG_ENDIAN + TXD_STRUC *pDestTxD = NULL; + UCHAR TxHwInfo[TXD_SIZE]; +#endif + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s -->\n", __func__)); + + /* Polling TX/RX path until packets empty */ + if (ATECtrl->tx_coherent == 0) + MTPciPollTxRxEmpty(pAd); + + for (Index = 0; Index < TX_RING_SIZE; Index++) { + PNDIS_PACKET pPacket; + + pPacket = pTxRing->Cell[Index].pNextNdisPacket; + + if (pPacket) + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, RTMP_PCI_DMA_TODEVICE); + +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); + WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); +#endif + } + + return NDIS_STATUS_SUCCESS; +} + +static INT32 pci_setup_frame(RTMP_ADAPTER *pAd, UINT32 q_idx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 Index; + UINT32 TxIdx = 0; + RTMP_TX_RING *pTxRing = &pAd->PciHif.TxRing[QID_AC_BE]; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s -->,\n", __func__)); + + if (ATECtrl->allocated == 0) + goto pci_setup_frame_err; + + HIF_IO_READ32(pAd, pTxRing->hw_didx_addr, &pTxRing->TxDmaIdx); + pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx; + pTxRing->TxCpuIdx = pTxRing->TxDmaIdx; + HIF_IO_WRITE32(pAd, pTxRing->hw_cidx_addr, pTxRing->TxCpuIdx); + + if (ATECtrl->bQAEnabled != TRUE) /* reset in start tx when iwpriv */ + ATECtrl->TxDoneCount = 0; + + for (Index = 0; Index < TX_RING_SIZE; Index++) + pTxRing->Cell[Index].pNdisPacket = ATECtrl->pAtePacket[Index]; + + for (Index = 0; (Index < TX_RING_SIZE) && (Index < ATECtrl->TxCount); Index++) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Index = %d, ATECtrl->TxCount = %u\n", Index, ATECtrl->TxCount)); + TxIdx = pTxRing->TxCpuIdx; + + if (MT_ATESetupFrame(pAd, TxIdx) != 0) + return NDIS_STATUS_FAILURE; + + if (((Index + 1) < TX_RING_SIZE) && (Index < ATECtrl->TxCount)) + INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: TxCpuIdx: %u, TxDmaIdx: %u\n", __func__, pTxRing->TxCpuIdx, pTxRing->TxDmaIdx)); + return NDIS_STATUS_SUCCESS; +pci_setup_frame_err: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Setup frame fail\n", __func__)); + return NDIS_STATUS_FAILURE; +} + +static INT32 pci_test_frame_tx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + RTMP_TX_RING *pTxRing = &pAd->PciHif.TxRing[QID_AC_BE]; + + if (ATECtrl->allocated == 0) + goto pci_tx_frame_err; + + /* Enable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 1); + ATECtrl->Mode |= ATE_TXFRAME; + HIF_IO_WRITE32(pAd, pTxRing->hw_cidx_addr, pTxRing->TxCpuIdx); + return NDIS_STATUS_SUCCESS; +pci_tx_frame_err: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: tx frame fail\n", __func__)); + return NDIS_STATUS_FAILURE; +} + +static INT32 pci_clean_test_rx_frame(RTMP_ADAPTER *pAd) +{ + UINT32 Index, RingNum; + RXD_STRUC *pRxD = NULL; +#ifdef RT_BIG_ENDIAN + RXD_STRUC *pDestRxD; + UCHAR RxHwInfo[RXD_SIZE]; +#endif + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 num_of_rx_ring = GET_NUM_OF_RX_RING(cap); + + for (RingNum = 0; RingNum < num_of_rx_ring; RingNum++) { + for (Index = 0; Index < RX_RING_SIZE; Index++) { +#ifdef RT_BIG_ENDIAN + pDestRxD = (RXD_STRUC *)pAd->PciHif.RxRing[0].Cell[Index].AllocVa; + NdisMoveMemory(&RxHwInfo[0], pDestRxD, RXD_SIZE); + pRxD = (RXD_STRUC *)&RxHwInfo[0]; + RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD); +#else + /* Point to Rx indexed rx ring descriptor */ + pRxD = (RXD_STRUC *)pAd->PciHif.RxRing[0].Cell[Index].AllocVa; +#endif + pRxD->DDONE = 0; +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD); + WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, FALSE, TYPE_RXD); +#endif + } + } + + return NDIS_STATUS_SUCCESS; +} + +static INT32 pci_ate_leave(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 Index; + TXD_STRUC *pTxD = NULL; + RTMP_TX_RING *pTxRing = &pAd->PciHif.TxRing[QID_AC_BE]; +#ifdef RT_BIG_ENDIAN + TXD_STRUC *pDestTxD = NULL; + UCHAR tx_hw_info[TXD_SIZE]; +#endif /* RT_BIG_ENDIAN */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s -->,\n", __func__)); + NICReadEEPROMParameters(pAd, NULL); + NICInitAsicFromEEPROM(pAd); + + if (ATECtrl->allocated == 1) { + /* Disable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 0); + + for (Index = 0; Index < TX_RING_SIZE; Index++) { + PNDIS_PACKET pPacket; +#ifndef RT_BIG_ENDIAN + pTxD = (TXD_STRUC *)pAd->PciHif.TxRing[QID_AC_BE].Cell[Index].AllocVa; +#else + pDestTxD = (TXD_STRUC *)pAd->TxRing[QID_AC_BE].Cell[Index].AllocVa; + NdisMoveMemory(&tx_hw_info[0], (UCHAR *)pDestTxD, TXD_SIZE); + pTxD = (TXD_STRUC *)&tx_hw_info[0]; + RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); +#endif /* !RT_BIG_ENDIAN */ + pTxD->DMADONE = 0; + pPacket = pTxRing->Cell[Index].pNdisPacket; + + if (pPacket) { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, RTMP_PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + + /* Always assign pNdisPacket as NULL after clear */ + pTxRing->Cell[Index].pNdisPacket = NULL; + pPacket = pTxRing->Cell[Index].pNextNdisPacket; + + if (pPacket) { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, RTMP_PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + + /* Always assign pNextNdisPacket as NULL after clear */ + pTxRing->Cell[Index].pNextNdisPacket = NULL; +#ifdef RT_BIG_ENDIAN + RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); + WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); +#endif /* RT_BIG_ENDIAN */ + } + + ATECtrl->allocated = 0; + } + + return NDIS_STATUS_SUCCESS; +} +#endif +static struct _ATE_OPERATION MT_ATEOp = { + .ATEStart = MT_ATEStart, + .ATEStop = MT_ATEStop, + .StartTx = MT_ATEStartTx, + .StartRx = MT_ATEStartRx, + .StopTx = MT_ATEStopTx, + .StopRx = MT_ATEStopRx, + .SetTxPower0 = MT_ATESetTxPower0, + .SetTxPower1 = MT_ATESetTxPower1, + .SetTxAntenna = MT_ATESetTxAntenna, + .SetRxAntenna = MT_ATESetRxAntenna, + .SetTxFreqOffset = MT_ATESetTxFreqOffset, + .SetChannel = MT_ATESetChannel, + .SetBW = MT_ATESetBW, +#if !defined(COMPOS_TESTMODE_WIN)/* 1 todo RX_BLK */ + .SampleRssi = MT_ATESampleRssi, +#endif + .SetAIFS = MT_ATESetAIFS, + .SetTSSI = MT_ATESetTSSI, + .SetDPD = MT_ATESetDPD, + .StartTxTone = MT_ATEStartTxTone, + .SetTxTonePower = MT_ATESetTxTonePower, + .StopTxTone = MT_ATEStopTxTone, + .StartContinousTx = MT_ATEStartContinousTx, + .StopContinousTx = MT_ATEStopContinousTx, + .RfRegWrite = MT_RfRegWrite, + .RfRegRead = MT_RfRegRead, + .GetFWInfo = MT_GetFWInfo, +#if defined(TXBF_SUPPORT) && defined(MT_MAC) + .SetATETxBfProc = MT_SetATETxBfProc, + .SetATETxSoundingProc = MT_SetATESoundingProc, +#endif /* MT_MAC */ +}; + +#ifdef RTMP_MAC_PCI +static struct _ATE_IF_OPERATION ate_if_ops = { + .init = pci_ate_init, + .clean_trx_q = pci_clean_q, + .clean_test_rx_frame = pci_clean_test_rx_frame, + .setup_frame = pci_setup_frame, + .test_frame_tx = pci_test_frame_tx, + .ate_leave = pci_ate_leave, +}; +#else +static struct _ATE_IF_OPERATION ate_if_ops = { + .init = NULL, + .clean_trx_q = NULL, + .setup_frame = NULL, + .test_frame_tx = NULL, + .ate_leave = NULL, +}; +#endif /* RTMP_MAC_PCI */ + +INT32 MT_ATEInit(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + + ATECtrl->ATEOp = &MT_ATEOp; + ATECtrl->ATEIfOps = &ate_if_ops; + return 0; +} diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode.c new file mode 100644 index 000000000..fb1d54682 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode.c @@ -0,0 +1,7909 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + Module Name: + mt_testmode.c + +*/ + +#ifdef COMPOS_TESTMODE_WIN +#include "config.h" +#else +#include "rt_config.h" +#endif + +#define MCAST_WCID_TO_REMOVE 0 /* Pat: TODO */ + +struct _ATE_DATA_RATE_MAP cck_mode_mcs_to_data_rate_map[] = { + {0, 1000}, + {1, 2000}, + {2, 5500}, + {3, 11000}, + {9, 2000}, + {10, 5500}, + {11, 11000}, +}; + +struct _ATE_DATA_RATE_MAP ofdm_mode_mcs_to_data_rate_map[] = { + {0, 6000}, + {1, 9000}, + {2, 12000}, + {3, 18000}, + {4, 24000}, + {5, 36000}, + {6, 48500}, + {7, 54000}, +}; + +struct _ATE_DATA_RATE_MAP n_mode_mcs_to_data_rate_map[] = { + {0, 6500}, + {1, 13000}, + {2, 19500}, + {3, 26000}, + {4, 39000}, + {5, 52000}, + {6, 58500}, + {7, 65000}, + {32, 6000}, /* MCS32 */ +}; + +struct _ATE_DATA_RATE_MAP ac_mode_mcs_to_data_rate_map_bw20[] = { + {0, 65}, /* in unit of 100k */ + {1, 130}, + {2, 195}, + {3, 260}, + {4, 390}, + {5, 520}, + {6, 585}, + {7, 650}, + {8, 780}, +}; + +struct _ATE_DATA_RATE_MAP ac_mode_mcs_to_data_rate_map_bw40[] = { + {0, 135}, /* in unit of 100k */ + {1, 270}, + {2, 405}, + {3, 540}, + {4, 810}, + {5, 1080}, + {6, 1215}, + {7, 1350}, + {8, 1620}, + {9, 1800}, +}; + + +struct _ATE_DATA_RATE_MAP ac_mode_mcs_to_data_rate_map_bw80[] = { + {0, 293}, /* in unit of 100k */ + {1, 585}, + {2, 878}, + {3, 1170}, + {4, 1755}, + {5, 2340}, + {6, 2633}, + {7, 2925}, + {8, 3510}, + {9, 3900}, +}; + +struct _ATE_DATA_RATE_MAP ac_mode_mcs_to_data_rate_map_bw160[] = { + {0, 585}, /* in unit of 100k */ + {1, 1170}, + {2, 1755}, + {3, 2340}, + {4, 3510}, + {5, 4680}, + {6, 5265}, + {7, 5850}, + {8, 7020}, + {9, 7800}, +}; + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) +#define ATE_ANT_USER_SEL 0x80000000 +/* BIT[0]:all, BIT[X==1]:ant(X-1) sel */ +struct _ATE_ANT_MAP ant_to_spe_idx_map[] = { + /* All */ + {0x0, 0}, + {0xf, 0}, + /* 1 Ant */ + {0x1, 0}, /* Tx0 */ + {0x2, 1}, /* Tx1 */ + {0x4, 3}, /* Tx2 */ + {0x8, 9}, /* Tx3 */ + /* 2 Ant */ + {0x3, 0}, + {0x5, 2}, + {0x9, 8}, + {0x6, 4}, + {0xa, 6}, + {0xc, 16}, + /* 3 Ant */ + {0x7, 0}, /* 0_1_2 */ + {0xb, 10}, /* 0_1_3 */ + {0xd, 12}, /* 0_2_3 */ + {0xe, 18}, /* 1_2_3 */ +}; + +struct _ATE_TXPWR_GROUP_MAP txpwr_group_map[] = { + {2407, 2484, {DMAC_TX0_G_BAND_TARGET_PWR, DMAC_TX1_G_BAND_TARGET_PWR, DMAC_TX2_G_BAND_TARGET_PWR, DMAC_TX3_G_BAND_TARGET_PWR} }, + {4910, 5140, {DMAC_GRP0_TX0_A_BAND_TARGET_PWR, DMAC_GRP0_TX1_A_BAND_TARGET_PWR, DMAC_GRP0_TX2_A_BAND_TARGET_PWR, DMAC_GRP0_TX3_A_BAND_TARGET_PWR} }, + {5140, 5250, {DMAC_GRP1_TX0_A_BAND_TARGET_PWR, DMAC_GRP1_TX1_A_BAND_TARGET_PWR, DMAC_GRP1_TX2_A_BAND_TARGET_PWR, DMAC_GRP1_TX3_A_BAND_TARGET_PWR} }, + {5250, 5360, {DMAC_GRP2_TX0_A_BAND_TARGET_PWR, DMAC_GRP2_TX1_A_BAND_TARGET_PWR, DMAC_GRP2_TX2_A_BAND_TARGET_PWR, DMAC_GRP2_TX3_A_BAND_TARGET_PWR} }, + {5360, 5470, {DMAC_GRP3_TX0_A_BAND_TARGET_PWR, DMAC_GRP3_TX1_A_BAND_TARGET_PWR, DMAC_GRP3_TX2_A_BAND_TARGET_PWR, DMAC_GRP3_TX3_A_BAND_TARGET_PWR} }, + {5470, 5580, {DMAC_GRP4_TX0_A_BAND_TARGET_PWR, DMAC_GRP4_TX1_A_BAND_TARGET_PWR, DMAC_GRP4_TX2_A_BAND_TARGET_PWR, DMAC_GRP4_TX3_A_BAND_TARGET_PWR} }, + {5580, 5690, {DMAC_GRP5_TX0_A_BAND_TARGET_PWR, DMAC_GRP5_TX1_A_BAND_TARGET_PWR, DMAC_GRP5_TX2_A_BAND_TARGET_PWR, DMAC_GRP5_TX3_A_BAND_TARGET_PWR} }, + {5690, 5800, {DMAC_GRP6_TX0_A_BAND_TARGET_PWR, DMAC_GRP6_TX1_A_BAND_TARGET_PWR, DMAC_GRP6_TX2_A_BAND_TARGET_PWR, DMAC_GRP6_TX3_A_BAND_TARGET_PWR} }, + {5800, 5925, {DMAC_GRP7_TX0_A_BAND_TARGET_PWR, DMAC_GRP7_TX1_A_BAND_TARGET_PWR, DMAC_GRP7_TX2_A_BAND_TARGET_PWR, DMAC_GRP7_TX3_A_BAND_TARGET_PWR} } }; + +#elif defined(MT7637) +/* todo: efuse structure need unify, MT7636 will fail in this flow */ +#define EFUSE_ADDR_TX0POWER_54M_2_4G 0x58/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_4920_5140 0x64/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_5150_5250 0x69/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_5250_5360 0x6E/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_5360_5470 0x73/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_5470_5580 0x78/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_5580_5690 0x7D/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_5690_5800 0x82/* MT7637 */ +#define EFUSE_ADDR_TX0POWER_54M_5810_5925 0x87/* MT7637 */ + +struct _ATE_TXPWR_GROUP_MAP txpwr_group_map[] = { + {2407, 2484, {EFUSE_ADDR_TX0POWER_54M_2_4G} }, + {4910, 5140, {EFUSE_ADDR_TX0POWER_54M_4920_5140} }, + {5140, 5250, {EFUSE_ADDR_TX0POWER_54M_5150_5250} }, + {5250, 5360, {EFUSE_ADDR_TX0POWER_54M_5250_5360} }, + {5360, 5470, {EFUSE_ADDR_TX0POWER_54M_5360_5470} }, + {5470, 5580, {EFUSE_ADDR_TX0POWER_54M_5470_5580} }, + {5580, 5690, {EFUSE_ADDR_TX0POWER_54M_5580_5690} }, + {5690, 5800, {EFUSE_ADDR_TX0POWER_54M_5690_5800} }, + {5800, 5925, {EFUSE_ADDR_TX0POWER_54M_5810_5925} }, +}; +#else +/* todo: efuse structure need unify, MT7636 will fail in this flow */ +struct _ATE_TXPWR_GROUP_MAP txpwr_group_map[] = { + {0}, +}; +#endif + +#ifdef MT7615 +#define RSSIOFFSET_24G_WF0 0x130 +#define RSSIOFFSET_24G_WF1 (RSSIOFFSET_24G_WF0 + 0x1) +#define RSSIOFFSET_24G_WF2 (RSSIOFFSET_24G_WF0 + 0x2) +#define RSSIOFFSET_24G_WF3 (RSSIOFFSET_24G_WF0 + 0x3) +#define RSSIOFFSET_5G_WF0 0x134 +#define RSSIOFFSET_5G_WF1 (RSSIOFFSET_5G_WF0 + 0x1) +#define RSSIOFFSET_5G_WF2 (RSSIOFFSET_5G_WF0 + 0x2) +#define RSSIOFFSET_5G_WF3 (RSSIOFFSET_5G_WF0 + 0x3) + +static UINT32 rssi_eeprom_band_24G_offset[] = {RSSIOFFSET_24G_WF0, + RSSIOFFSET_24G_WF1, + RSSIOFFSET_24G_WF2, + RSSIOFFSET_24G_WF3}; + +static UINT32 rssi_eeprom_band_5G_offset[] = {RSSIOFFSET_5G_WF0, + RSSIOFFSET_5G_WF1, + RSSIOFFSET_5G_WF2, + RSSIOFFSET_5G_WF3}; + +static UINT32 *_rssi_eeprom_band_offset[] = {rssi_eeprom_band_24G_offset, rssi_eeprom_band_5G_offset}; + +static UINT32 _n_band_offset[] = {ARRAY_SIZE(rssi_eeprom_band_24G_offset), ARRAY_SIZE(rssi_eeprom_band_5G_offset)}; +#else +static UINT32 *_rssi_eeprom_band_offset[] = {NULL}; +static UINT32 _n_band_offset[] = {0}; +#endif + +#ifdef PRE_CAL_TRX_SET2_SUPPORT +static UINT16 PreCalGroupList[] = { + 0x00ED, /* 0 - Ch group 0,2,3,5,6,7 */ + 0x01FF, /*All group 0 ~ 8*/ +}; +static UINT8 PreCalItemList[] = { + 0x1F, /* 0 - Pre-cal Bit[0]:TXLPF, Bit[1]:TXIQ, Bit[2]:TXDC, Bit[3]:RXFI, Bit[4]:RXFD */ +}; +#endif /* PRE_CAL_TRX_SET2_SUPPORT */ + +struct rssi_offset_eeprom eeprom_rssi_offset = { +#ifndef COMPOS_TESTMODE_WIN + .rssi_eeprom_band_offset = _rssi_eeprom_band_offset, + .n_band_offset = _n_band_offset, + .n_band = ARRAY_SIZE(_rssi_eeprom_band_offset), +#else + _rssi_eeprom_band_offset, + _n_band_offset, + sizeof(_rssi_eeprom_band_offset) / sizeof(_rssi_eeprom_band_offset[0]), +#endif +}; + +#if defined(TXBF_SUPPORT) && defined(MT_MAC) +UINT8 g_EBF_certification; +UINT8 BF_ON_certification; +extern UCHAR TemplateFrame[32]; +#endif /* TXBF_SUPPORT && MT_MAC */ + +VOID MtATEDummyFunc(VOID) +{ +} +/* Private Function Prototype */ +static INT32 MT_ATEMPSRelease(RTMP_ADAPTER *pAd); +static INT32 MT_ATEMPSInit(RTMP_ADAPTER *pAd); +static INT32 MT_ATEMPSLoadSetting(RTMP_ADAPTER *pAd, UINT32 band_idx); +#ifdef ATE_TXTHREAD +static INT32 MT_ATEMPSRunStatCheck(RTMP_ADAPTER *pAd, UINT32 band_idx); +#endif +#ifdef LOGDUMP_TO_FILE +static INT32 MT_ATERDDParseResult(struct _ATE_LOG_DUMP_ENTRY entry, INT idx, RTMP_OS_FD_EXT fd); +static INT MT_ATEWriteFd(RTMP_STRING *log, RTMP_OS_FD_EXT srcf); +#else +static INT32 MT_ATERDDParseResult(struct _ATE_LOG_DUMP_ENTRY entry, INT idx); +#endif +static INT32 MT_MPSTxStop(RTMP_ADAPTER *pAd); +static INT32 MT_ATELogOnOff(struct _RTMP_ADAPTER *pAd, UINT32 type, UINT32 on_off, UINT32 size); +static INT32 MT_ATESetICapStart(RTMP_ADAPTER *pAd, BOOLEAN Trigger, BOOLEAN RingCapEn, UINT32 Event, UINT32 Node, UINT32 Len, UINT32 StopCycle, UINT32 BW, UINT32 MACTriggerEvent, UINT32 SourceAddrLSB, UINT32 SourceAddrMSB, UINT32 Band); +static INT32 MT_ATEGetICapStatus(RTMP_ADAPTER *pAd); +static INT32 MT_ATEGetICapIQData(RTMP_ADAPTER *pAd, PINT32 pData, PINT32 pDataLen, UINT32 IQ_Type, UINT32 WF_Num); +/* static INT32 MT_ATEInsertLog(RTMP_ADAPTER *pAd, UCHAR *log, UINT32 log_type, UINT32 len); */ + +/* #if CFG_eBF_Sportan_Certification */ +INT32 MT_ATEGenPkt(RTMP_ADAPTER *pAd, UCHAR *buf, UINT32 band_idx); +/* #else */ +/* static INT32 MT_ATEGenPkt(RTMP_ADAPTER *pAd, UCHAR *buf, UINT32 band_idx); */ +/* #endif */ + + +INT MtATESetMacTxRx(RTMP_ADAPTER *pAd, INT32 TxRx, BOOLEAN Enable, UCHAR BandIdx) +{ + INT ret = 0; +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _EXT_CMD_ATE_TEST_MODE_T param; + UINT8 testmode_en = 1; + + os_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = testmode_en; + param.ucAteIdx = EXT_ATE_SET_TRX; + param.Data.rAteSetTrx.ucType = TxRx; + param.Data.rAteSetTrx.ucEnable = Enable; + param.Data.rAteSetTrx.ucBand = BandIdx; /* TODO::Fix it after 7615 merge */ + /* Make sure FW command configuration completed for store TX packet in PLE first + * Use aucReserved[1] for uxATEIdx extension feasibility + */ + param.aucReserved[1] = INIT_CMD_SET_AND_WAIT_RETRY_RSP; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: TxRx:%x, Enable:%x, BandIdx:%x\n", + __func__, param.Data.rAteSetTrx.ucType, + param.Data.rAteSetTrx.ucEnable, + param.Data.rAteSetTrx.ucBand)); + ret = MtCmdATETest(pAd, ¶m); +#else + ret = MtAsicSetMacTxRx(pAd, TxRx, Enable, BandIdx); +#endif + return ret; +} + + +INT MtATESetTxStream(RTMP_ADAPTER *pAd, UINT32 StreamNums, UCHAR BandIdx) +{ + INT ret = 0; +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _EXT_CMD_ATE_TEST_MODE_T param; + UINT8 testmode_en = 1; + + os_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = testmode_en; + param.ucAteIdx = EXT_ATE_SET_TX_STREAM; + param.Data.rAteSetTxStream.ucStreamNum = StreamNums; + param.Data.rAteSetTxStream.ucBand = BandIdx; + ret = MtCmdATETest(pAd, ¶m); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: StreamNum:%x BandIdx:%x\n", __func__, StreamNums, BandIdx)); +#else + ret = MtAsicSetTxStream(pAd, StreamNums, BandIdx); +#endif + return ret; +} + + +INT MtATESetRxPath(RTMP_ADAPTER *pAd, UINT32 RxPathSel, UCHAR u1BandIdx) +{ + INT ret = 0; +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _EXT_CMD_ATE_TEST_MODE_T param; + UINT8 testmode_en = 1; + + os_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = testmode_en; + param.ucAteIdx = EXT_ATE_SET_RX_PATH; + + /* Set Rx Ant 2/3 for Band 1 */ + if (u1BandIdx) + RxPathSel = RxPathSel << 2; + + param.Data.rAteSetRxPath.ucType = RxPathSel; + param.Data.rAteSetRxPath.ucBand = u1BandIdx; + ret = MtCmdATETest(pAd, ¶m); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: RxPathSel:%x BandIdx:%x\n", __func__, RxPathSel, u1BandIdx)); +#else + ret = MtAsicSetRxPath(pAd, RxPathSel, u1BandIdx); +#endif + return ret; +} + + +INT MtATESetRxFilter(RTMP_ADAPTER *pAd, MT_RX_FILTER_CTRL_T filter) +{ + INT ret = 0; +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _EXT_CMD_ATE_TEST_MODE_T param; + UINT8 testmode_en = 1; + + os_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = testmode_en; + param.ucAteIdx = EXT_ATE_SET_RX_FILTER; + param.Data.rAteSetRxFilter.ucBand = filter.u1BandIdx; /* TODO::Fix it after 7615 merge */ + + if (filter.bPromiscuous) + param.Data.rAteSetRxFilter.ucPromiscuousMode = 1; + else { + param.Data.rAteSetRxFilter.ucReportEn = (UCHAR)filter.bFrameReport; + param.Data.rAteSetRxFilter.u4FilterMask = cpu2le32(filter.filterMask); + } + + ret = MtCmdATETest(pAd, ¶m); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: BandIdx:%x\n", __func__, filter.u1BandIdx)); +#else + ret = MtAsicSetRxFilter(pAd, filter); +#endif + return ret; +} + + +INT MtATESetCleanPerStaTxQueue(RTMP_ADAPTER *pAd, BOOLEAN sta_pause_enable) +{ + INT ret = 0; +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _EXT_CMD_ATE_TEST_MODE_T param; + UINT8 testmode_en = 1; + + os_zero_mem(¶m, sizeof(param)); + param.ucAteTestModeEn = testmode_en; + param.ucAteIdx = EXT_ATE_SET_CLEAN_PERSTA_TXQUEUE; + param.Data.rAteSetCleanPerStaTxQueue.fgStaPauseEnable = sta_pause_enable; + /* Give a same STA ID */ + param.Data.rAteSetCleanPerStaTxQueue.ucStaID = 0; + + ret = MtCmdATETest(pAd, ¶m); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: sta_pause_enable:%x\n", __func__, sta_pause_enable)); +#else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Function do not support yet.\n", __func__)); +#endif + return ret; +} + +#ifdef ARBITRARY_CCK_OFDM_TX +VOID MtATEInitCCK_OFDM_Path(RTMP_ADAPTER *pAd, UCHAR BandIdx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 i = 0; + UINT32 value = 0; + UINT32 MAC_RDVLE, MAC_ADDR, MAC_WRMASK, MAC_WRVALUE; + + if (IS_ATE_DBDC(pAd)) { + UINT32 idx = 0; + + /* PTA mux */ + if (BandIdx == 0) { + /* 0x810600D0[4:0] = 0x8; */ + MAC_ADDR = ANT_SWITCH_CON3; + MAC_WRMASK = 0xFFFFFFE0; + MAC_WRVALUE = 0x8 << 0; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600D4[20:16] = 0xE; */ + MAC_ADDR = ANT_SWITCH_CON4; + MAC_WRMASK = 0xFFE0FFFF; + MAC_WRVALUE = 0xE << 16; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } else { + /* 0x810600E0[11:8] = 0x5; */ + MAC_ADDR = ANT_SWITCH_CON7; + MAC_WRMASK = 0xFFFFF0FF; + MAC_WRVALUE = 0x5 << 8; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600E4[27:24] = 0xB; */ + MAC_ADDR = ANT_SWITCH_CON8; + MAC_WRMASK = 0xF0FFFFFF; + MAC_WRVALUE = 0xB << 24; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + /* iPA */ + for (i = 0; i < 2; i++) { + idx = BandIdx * 2 + i; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Reset WF_%d\n", __func__, idx)); + ATEOp->RfRegRead(pAd, idx, 0x48, &value); + value &= ~(0x3FF << 20); /* bit[29:20] */ + value |= (3 << 20); + ATEOp->RfRegWrite(pAd, idx, 0x48, value); + } + } else { + /* PTA mux */ + /* Gband */ + /* 0x810600D0[4:0] = 0x8; */ + MAC_ADDR = ANT_SWITCH_CON3; + MAC_WRMASK = 0xFFFFFFE0; + MAC_WRVALUE = 0x8 << 0; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600D4[20:16] = 0xE; */ + MAC_ADDR = ANT_SWITCH_CON4; + MAC_WRMASK = 0xFFE0FFFF; + MAC_WRVALUE = 0xE << 16; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600DC[3:0] = 0x0; */ + MAC_ADDR = ANT_SWITCH_CON6; + MAC_WRMASK = 0xFFFFFFF0; + MAC_WRVALUE = 0x0 << 0; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600E0[19:16] = 0x6; */ + MAC_ADDR = ANT_SWITCH_CON7; + MAC_WRMASK = 0xFFF0FFFF; + MAC_WRVALUE = 0x6 << 16; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* Aband */ + /* 0x810600D4[12:8] = 0xD; */ + MAC_ADDR = ANT_SWITCH_CON4; + MAC_WRMASK = 0xFFFFE0FF; + MAC_WRVALUE = 0xD << 8; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600CC[28:24] = 0x13; */ + MAC_ADDR = ANT_SWITCH_CON2; + MAC_WRMASK = 0xE0FFFFFF; + MAC_WRVALUE = 0x13 << 24; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600E0[11:8] = 0x5; */ + MAC_ADDR = ANT_SWITCH_CON7; + MAC_WRMASK = 0xFFFFF0FF; + MAC_WRVALUE = 0x5 << 8; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + /* 0x810600E4[27:24] = 0xB; */ + MAC_ADDR = ANT_SWITCH_CON8; + MAC_WRMASK = 0xF0FFFFFF; + MAC_WRVALUE = 0xB << 24; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + + for (i = 0; i < 4; i++) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Reset WF_%d\n", __func__, i)); + ATEOp->RfRegRead(pAd, i, 0x48, &value); + value &= ~(0x3FF << 20); /* bit[29:20] */ + value |= (3 << 20); + ATEOp->RfRegWrite(pAd, i, 0x48, value); + } + } +} + + +VOID MtATESetCCK_OFDM_Path(RTMP_ADAPTER *pAd, UINT32 TxPathSel, UCHAR BandIdx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 i = 0; + UINT32 value = 0; + UINT32 MAC_RDVLE, MAC_ADDR, MAC_WRMASK, MAC_WRVALUE; + + if (IS_ATE_DBDC(pAd)) { + UINT32 idx = 0; + + /* PTA mux */ + if (BandIdx == 0) { + if ((TxPathSel & (1 << 0)) == 0) { + /* 0x810600D0[4:0] = 0x1B; */ + MAC_ADDR = ANT_SWITCH_CON3; + MAC_WRMASK = 0xFFFFFFE0; + MAC_WRVALUE = 0x1B << 0; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 1)) == 0) { + /* 0x810600D4[20:16] = 0x1B; */ + MAC_ADDR = ANT_SWITCH_CON4; + MAC_WRMASK = 0xFFE0FFFF; + MAC_WRVALUE = 0x1B << 16; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + } else { + if ((TxPathSel & (1 << 0)) == 0) { + /* 0x810600E0[11:8] = 0xF; */ + MAC_ADDR = ANT_SWITCH_CON7; + MAC_WRMASK = 0xFFFFF0FF; + MAC_WRVALUE = 0xF << 8; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 1)) == 0) { + /* 0x810600E4[27:24] = 0xF; */ + MAC_ADDR = ANT_SWITCH_CON8; + MAC_WRMASK = 0xF0FFFFFF; + MAC_WRVALUE = 0xF << 24; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + } + + for (i = 0; i < 2; i++) { + if ((TxPathSel & (1 << i)) == 0) { + idx = BandIdx * 2 + i; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Disable WF_%d, TxSel=%x\n", __func__, idx, TxPathSel)); + ATEOp->RfRegRead(pAd, idx, 0x48, &value); + value &= ~(0x3FF << 20); /* bit[29:20] */ + value = value | (2 << 28) | (2 << 26) | (8 << 20); + ATEOp->RfRegWrite(pAd, idx, 0x48, value); + } + } + } else { + /* PTA mux */ + /* Gband */ + if ((TxPathSel & (1 << 0)) == 0) { + /* 0x810600D0[4:0] = 0x1B; */ + MAC_ADDR = ANT_SWITCH_CON3; + MAC_WRMASK = 0xFFFFFFE0; + MAC_WRVALUE = 0x1B << 0; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 1)) == 0) { + /* 0x810600D4[20:16] = 0x1B; */ + MAC_ADDR = ANT_SWITCH_CON4; + MAC_WRMASK = 0xFFE0FFFF; + MAC_WRVALUE = 0x1B << 16; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 2)) == 0) { + /* 0x810600DC[3:0] = 0xF; */ + MAC_ADDR = ANT_SWITCH_CON6; + MAC_WRMASK = 0xFFFFFFF0; + MAC_WRVALUE = 0xF << 0; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 3)) == 0) { + /* 0x810600E0[19:16] = 0xF; */ + MAC_ADDR = ANT_SWITCH_CON7; + MAC_WRMASK = 0xFFF0FFFF; + MAC_WRVALUE = 0xF << 16; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + /* Aband */ + if ((TxPathSel & (1 << 0)) == 0) { + /* 0x810600D4[12:8] = 0x1B; */ + MAC_ADDR = ANT_SWITCH_CON4; + MAC_WRMASK = 0xFFFFE0FF; + MAC_WRVALUE = 0x1B << 8; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 1)) == 0) { + /* 0x810600CC[28:24] = 0x1B; */ + MAC_ADDR = ANT_SWITCH_CON2; + MAC_WRMASK = 0xE0FFFFFF; + MAC_WRVALUE = 0x1B << 24; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 2)) == 0) { + /* 0x810600E0[11:8] = 0xF; */ + MAC_ADDR = ANT_SWITCH_CON7; + MAC_WRMASK = 0xFFFFF0FF; + MAC_WRVALUE = 0xF << 8; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + if ((TxPathSel & (1 << 3)) == 0) { + /* 0x810600E4[27:24] = 0xF; */ + MAC_ADDR = ANT_SWITCH_CON8; + MAC_WRMASK = 0xF0FFFFFF; + MAC_WRVALUE = 0xF << 24; + MCU_IO_READ32(pAd, MAC_ADDR, &MAC_RDVLE); + MAC_RDVLE = (MAC_RDVLE & MAC_WRMASK) | MAC_WRVALUE; + MCU_IO_WRITE32(pAd, MAC_ADDR, MAC_RDVLE); + } + + for (i = 0; i < 4; i++) { + if ((TxPathSel & (1 << i)) == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Disable WF_%d, TxSel=%x\n", __func__, i, TxPathSel)); + ATEOp->RfRegRead(pAd, i, 0x48, &value); + value &= ~(0x3FF << 20); /* bit[29:20] */ + value = value | (2 << 28) | (2 << 26) | (8 << 20); + ATEOp->RfRegWrite(pAd, i, 0x48, value); + } + } + } +} +#endif + + +#ifdef ATE_TXTHREAD +static INT TestMode_TxThread(ULONG Context); +static INT32 TESTMODE_TXTHREAD_INIT(RTMP_ADAPTER *pAd, INT thread_idx); +static INT32 TESTMODE_TXTHREAD_RELEASE(RTMP_ADAPTER *pAd, INT thread_idx); +static VOID TESTMODEThreadProceedTx(RTMP_ADAPTER *pAd, UINT32 band_idx); +static VOID TESTMODEThreadStopTx(RTMP_ADAPTER *pAd, INT thread_idx); + + +static INT MT_ATETxHandler(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ate_ctrl = &pAd->ATECtrl; + UINT32 mode = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Mode); + USHORT q_idx = TESTMODE_GET_PARAM(ate_ctrl, band_idx, QID); + INT32 dequeue_size = ate_ctrl->deq_cnt; + INT32 multi_users = 0; + UINT32 txed_cnt = 0; + UINT32 tx_cnt = 0; + UCHAR hwq_idx = q_idx; + RTMP_ARCH_OP *arch_ops = &pAd->archOps; +#if defined(MT7615) || defined(MT7622) + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ate_ctrl, band_idx, ipg_param); + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ate_ctrl, band_idx, tx_time_param); + UINT32 pkt_tx_time = tx_time_param->pkt_tx_time; + UINT8 need_ampdu = tx_time_param->pkt_need_ampdu; + UINT32 ipg = ipg_param->ipg; +#endif /* defined(MT7615) || defined(MT7622) */ + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + if (IS_MT7615(pAd) || IS_MT7622(pAd) || IS_P18(pAd) || IS_MT7663(pAd)) { + UCHAR wdev_idx = TESTMODE_GET_PARAM(ate_ctrl, band_idx, wdev_idx); + struct wifi_dev *wdev = pAd->wdev_list[wdev_idx]; + + hwq_idx = arch_ops->get_resource_idx(pAd, wdev, TX_MGMT, q_idx); + } +#endif /* defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) */ + txed_cnt = TESTMODE_GET_PARAM(ate_ctrl, band_idx, TxedCount); + tx_cnt = TESTMODE_GET_PARAM(ate_ctrl, band_idx, TxCount); + + do { + ULONG free_num; +ate_thread_dequeue: +#ifdef COMPOS_TESTMODE_WIN + free_num = 1; +#else + free_num = 0; + + if ((q_idx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) + free_num = GET_TXRING_FREENO(pAd, hwq_idx); + else + free_num = GET_MGMTRING_FREENO(pAd, hwq_idx); + +#endif /* COMPOS_TESTMODE_WIN */ + + if (multi_users > 0) { + UCHAR *pate_pkt = TESTMODE_GET_PARAM(ate_ctrl, band_idx, pate_pkt); + + ate_ctrl->wcid_ref = multi_users; + ret = MT_ATEGenPkt(pAd, pate_pkt, band_idx); + } + + mode = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Mode); + + if (mode & ATE_STOP) + break; + + if (!(mode & ATE_TXFRAME)) + break; + + if (!free_num) + break; + +#if defined(MT7615) || defined(MT7622) +round_tx: + + if (((pkt_tx_time > 0) || (ipg > 0)) && + (pAd->mgmt_que.Number >= MGMT_QUE_MAX_NUMS)) + break; + +#endif /* defined(MT7615) || defined(MT7622) */ + + /* For ATE TX thread TX packet counter control */ + if (tx_cnt <= txed_cnt) + break; + + ret = MT_ATETxPkt(pAd, band_idx); + + if (ret) + break; + + txed_cnt++; +#if defined(MT7615) || defined(MT7622) + if (((pkt_tx_time > 0) && need_ampdu) || (ipg > 0)) { + PKT_TOKEN_CB *pktTokenCb = (PKT_TOKEN_CB *) pAd->PktTokenCb; + UINT32 free_token_cnt = pktTokenCb->tx_id_list.list->FreeTokenCnt; + UINT32 pkt_tx_token_id_max = pktTokenCb->pkt_tx_tkid_max; + + free_num = GET_TXRING_FREENO(pAd, hwq_idx); + + if ((free_token_cnt > (pkt_tx_token_id_max - ATE_ENQUEUE_PACKET_NUM)) && (free_num > 0)) { + if (pAd->mgmt_que.Number < MGMT_QUE_MAX_NUMS) + goto round_tx; + } + } +#endif /* defined(MT7615) || defined(MT7622) */ + dequeue_size--; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:: band_idx:%u, tx_cnt:%u, txed_cnt:%u, deque:%d, multi_user:%u, free:%lu\n", + __func__, band_idx, tx_cnt, txed_cnt, + dequeue_size, multi_users, free_num)); + + if (!dequeue_size) { + multi_users--; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:: Dequeue %d finish, multi_user:%d\n", + __func__, dequeue_size, multi_users)); + } else + goto ate_thread_dequeue; + } while (multi_users > 0); + + TESTMODE_SET_PARAM(ate_ctrl, band_idx, TxedCount, txed_cnt); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, TxCount, tx_cnt); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:: band_idx:%u, tx_cnt:%u, txed_cnt:%u, deque:%d\n", + __func__, band_idx, tx_cnt, txed_cnt, dequeue_size)); + return ret; +} + + +static INT32 Mt_ATEThreadGetBandIdx(RTMP_ADAPTER *pAd, UINT8 *stat) +{ + UINT8 mask = 0; + + mask = 1 << TESTMODE_BAND0; + + if (*stat & mask) { + *stat &= ~mask; + return TESTMODE_BAND0; + } + + mask = 1 << TESTMODE_BAND1; + + if (IS_ATE_DBDC(pAd) && (*stat & mask)) { + *stat &= ~mask; + return TESTMODE_BAND1; + } + + return -1; +} + +static INT TestMode_TxThread(ULONG Context) +{ + int status; + INT32 ret = 0; + RTMP_OS_TASK *pTask = (RTMP_OS_TASK *)Context; + RTMP_ADAPTER *pAd = NULL; + struct _ATE_CTRL *ate_ctrl = NULL; + struct _ATE_TXTHREAD_CB *cb = NULL; + INT32 band_idx = 0; + UINT8 service_stat = 0; + UINT32 mode = 0; + + if (!pTask) + goto err1; + + pAd = (RTMP_ADAPTER *)RTMP_OS_TASK_DATA_GET(pTask); + ate_ctrl = &pAd->ATECtrl; + cb = &ate_ctrl->tx_thread[0]; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: Init thread %u for band %u\n", + __func__, ate_ctrl->current_init_thread, band_idx)); + RTMP_OS_COMPLETE(&ate_ctrl->cmd_done); + + while (!RTMP_OS_TASK_IS_KILLED(pTask)) { + if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE) { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } + + service_stat = 0; + RTMP_SEM_LOCK(&cb->lock); + service_stat = cb->service_stat; + + /* AsicSetWPDMA(pAd, PDMA_TX_RX, 0); */ + do { + if (!service_stat) + break; + + band_idx = Mt_ATEThreadGetBandIdx(pAd, &service_stat); + + if (band_idx == -1) + break; + + ret = MT_ATETxHandler(pAd, band_idx); + } while (1); + + cb->service_stat = service_stat; + /* AsicSetWPDMA(pAd, PDMA_TX_RX, 1); */ + RTMP_SEM_UNLOCK(&cb->lock); + + if (band_idx == -1) + goto err1; + + mode = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Mode); + + if (mode & fATE_MPS) { + MT_ATEMPSRunStatCheck(pAd, band_idx); + MT_ATEMPSLoadSetting(pAd, band_idx); + } + + schedule(); + + if (ret) + break; + } + +err1: + if (pTask) + RtmpOSTaskNotifyToExit(pTask); + if (pAd) + MtATESetMacTxRx(pAd, ASIC_MAC_TX, TRUE, band_idx); + cb->is_init = FALSE; + + if (ret) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: abnormal leave err %d\n", __func__, ret)); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: leave\n", __func__)); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + return ret; +} + + +static INT32 TESTMODE_TXTHREAD_INIT(RTMP_ADAPTER *pAd, INT thread_idx) +{ + INT32 Ret = 0; + CHAR thread_name[64] = "ATE_Thread"; + struct _ATE_CTRL *ate_ctrl = &pAd->ATECtrl; + struct _ATE_TXTHREAD_CB *tx_cb = &pAd->ATECtrl.tx_thread[thread_idx]; + + ate_ctrl->deq_cnt = 1; + + if (!ate_ctrl->tx_thread[thread_idx].is_init) { + NdisZeroMemory(tx_cb, sizeof(*tx_cb)); + /* sprintf(thread_name, "ATE_Thread%d", thread_idx); */ + RTMP_OS_TASK_INIT(&tx_cb->task, thread_name, pAd); + ate_ctrl->current_init_thread = thread_idx; + NdisAllocateSpinLock(pAd, &tx_cb->lock); + Ret = RtmpOSTaskAttach(&tx_cb->task, TestMode_TxThread, (ULONG)&tx_cb->task); + + if (!RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&ate_ctrl->cmd_done, ate_ctrl->cmd_expire)) + goto err0; + + if (Ret != STATUS_SUCCESS) + goto err0; + + tx_cb->is_init = TRUE; + } else { + tx_cb->txed_cnt = 0; + tx_cb->tx_cnt = 0; + } + + tx_cb->service_stat = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Initialize thread_idx=%d\n", + __func__, thread_idx)); + return Ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: tx thread create fail\n", __func__)); + return Ret; +} + + +static INT32 TESTMODE_TXTHREAD_RELEASE(RTMP_ADAPTER *pAd, INT thread_idx) +{ + INT32 Ret = 0; + struct _ATE_TXTHREAD_CB *tx_cb = &pAd->ATECtrl.tx_thread[thread_idx]; + + if (&tx_cb->task) + Ret = RtmpOSTaskKill(&tx_cb->task); + + if (Ret == NDIS_STATUS_FAILURE) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("kill ATE Tx task failed!\n")); + else + tx_cb->is_init = FALSE; + + NdisFreeSpinLock(&tx_cb->lock); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Release thread_idx=%d\n", + __func__, thread_idx)); + return Ret; +} + + +static INT MT_ATEThreadSetService(RTMP_ADAPTER *pAd, UINT32 band_idx, UINT8 *stat) +{ + UINT8 mask = 0; + + if (IS_ATE_DBDC(pAd) && (band_idx == TESTMODE_BAND1)) + mask = 1 << TESTMODE_BAND1; + else + mask = 1 << TESTMODE_BAND0; + + *stat |= mask; + return 0; +} + + +static VOID TESTMODEThreadProceedTx(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + struct _ATE_TXTHREAD_CB *tx_cb = NULL; + tx_cb = &pAd->ATECtrl.tx_thread[0]; + RTMP_SEM_LOCK(&tx_cb->lock); + MT_ATEThreadSetService(pAd, band_idx, &tx_cb->service_stat); + RTMP_SEM_UNLOCK(&tx_cb->lock); + RtmpOsTaskWakeUp(&tx_cb->task); +} + + +static VOID TESTMODEThreadStopTx(RTMP_ADAPTER *pAd, INT thread_idx) +{ + struct _ATE_TXTHREAD_CB *tx_cb = &pAd->ATECtrl.tx_thread[thread_idx]; + tx_cb->txed_cnt = 0; + tx_cb->tx_cnt = 0; +} +#endif /* ATE_TXTHREAD */ + + +VOID MT_ATEUpdateRxStatistic(RTMP_ADAPTER *pAd, enum _TESTMODE_STAT_TYPE type, VOID *data) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_RX_STATISTIC *rx_stat = &ATECtrl->rx_stat; + UCHAR *uData = (UCHAR *)data; + + RX_VECTOR1_1ST_CYCLE *RXV1_1ST_CYCLE = (RX_VECTOR1_1ST_CYCLE *)(uData + 8); + RX_VECTOR1_3TH_CYCLE *RXV1_3TH_CYCLE = (RX_VECTOR1_3TH_CYCLE *)(uData + 16); + RX_VECTOR1_5TH_CYCLE *RXV1_5TH_CYCLE = (RX_VECTOR1_5TH_CYCLE *)(uData + 24); +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + RX_VECTOR1_2ND_CYCLE *RXV1_2ND_CYCLE = (RX_VECTOR1_2ND_CYCLE *)(uData + 12); + RX_VECTOR1_4TH_CYCLE *RXV1_4TH_CYCLE = (RX_VECTOR1_4TH_CYCLE *)(uData + 20); + + /* RX_VECTOR2_1ST_CYCLE *RXV2_1ST_CYCLE = (RX_VECTOR2_1ST_CYCLE *)(uData + 32); */ + RX_VECTOR2_3TH_CYCLE *RXV2_3TH_CYCLE = (RX_VECTOR2_3TH_CYCLE *)(uData + 40); +#else + RX_VECTOR2_2ND_CYCLE *RXV2_2ND_CYCLE = (RX_VECTOR2_2ND_CYCLE *)(uData + 36); + RX_VECTOR1_6TH_CYCLE *RXV1_6TH_CYCLE = (RX_VECTOR1_6TH_CYCLE *)(uData + 28); +#endif /* defined(MT7615) || defined(MT7622) */ + + if (type == TESTMODE_RXV) { +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + INT16 foe = 0; + UINT32 i = 0; + + if (RXV1_1ST_CYCLE->TxMode == MODE_CCK) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("\t%s: MODE_CCK RX\n", __func__)); + foe = (RXV1_5TH_CYCLE->MISC1 & 0x7ff); + foe = (foe * 1000) >> 11; + } else { + UINT8 cbw = RXV1_1ST_CYCLE->FrMode; + UINT32 foe_const = ((1 << (cbw + 1)) & 0xf) * 10000; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("\t%s: MODE_OFDM RX\n", __func__)); + foe = (RXV1_5TH_CYCLE->MISC1 & 0xfff); + + if (foe >= 2048) + foe = foe - 4096; + + foe = (foe * foe_const) >> 15; + } + + rx_stat->FreqOffsetFromRx = foe; + rx_stat->RCPI[0] = RXV1_4TH_CYCLE->RCPI0; + rx_stat->RCPI[1] = RXV1_4TH_CYCLE->RCPI1; + rx_stat->RCPI[2] = RXV1_4TH_CYCLE->RCPI2; + rx_stat->RCPI[3] = RXV1_4TH_CYCLE->RCPI3; + rx_stat->RSSI[0] = (RXV1_4TH_CYCLE->RCPI0 >> 1) - 110; + rx_stat->RSSI[1] = (RXV1_4TH_CYCLE->RCPI1 >> 1) - 110; + rx_stat->RSSI[2] = (RXV1_4TH_CYCLE->RCPI2 >> 1) - 110; + rx_stat->RSSI[3] = (RXV1_4TH_CYCLE->RCPI3 >> 1) - 110; + rx_stat->FAGC_RSSI_IB[0] = + RXV1_3TH_CYCLE->IBRssiRx; + rx_stat->FAGC_RSSI_WB[0] = + RXV1_3TH_CYCLE->WBRssiRx; + rx_stat->FAGC_RSSI_IB[1] = + RXV1_3TH_CYCLE->IBRssiRx; + rx_stat->FAGC_RSSI_WB[1] = + RXV1_3TH_CYCLE->WBRssiRx; + rx_stat->FAGC_RSSI_IB[2] = + RXV1_3TH_CYCLE->IBRssiRx; + rx_stat->FAGC_RSSI_WB[2] = + RXV1_3TH_CYCLE->WBRssiRx; + rx_stat->FAGC_RSSI_IB[3] = + RXV1_3TH_CYCLE->IBRssiRx; + rx_stat->FAGC_RSSI_WB[3] = + RXV1_3TH_CYCLE->WBRssiRx; + rx_stat->SNR[0] = (RXV1_5TH_CYCLE->MISC1 >> 19) - 16; + + for (i = 0; i < 4; i++) { + if (rx_stat->FAGC_RSSI_IB[i] >= 128) + rx_stat->FAGC_RSSI_IB[i] -= 256; + + if (rx_stat->FAGC_RSSI_WB[i] >= 128) + rx_stat->FAGC_RSSI_WB[i] -= 256; + } + +#ifdef CFG_SUPPORT_MU_MIMO + + if (RXV1_2ND_CYCLE->RxValidIndicator && + ((RXV1_2ND_CYCLE->GroupId != 0) && + (RXV1_2ND_CYCLE->GroupId != 63))) { + rx_stat->RxMacMuPktCount++; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: get MU packet #%d\n", + __func__, rx_stat->RxMacMuPktCount)); + } + +#endif + rx_stat->SIG_MCS = RXV1_1ST_CYCLE->TxRate; + rx_stat->SINR = (*(UINT32 *)RXV2_3TH_CYCLE) & 0x00FFFFFF; /* bit[23:0] */ + rx_stat->RXVRSSI = RXV1_3TH_CYCLE->IBRssiRx; +#else + rx_stat->FreqOffsetFromRx = RXV1_5TH_CYCLE->FoE; + rx_stat->RCPI[0] = RXV1_3TH_CYCLE->Rcpi0; + rx_stat->RCPI[1] = RXV1_3TH_CYCLE->Rcpi1; + rx_stat->SNR[0] = RXV1_5TH_CYCLE->LTF_SNR0; + rx_stat->SNR[1] = RXV2_2ND_CYCLE->OfdmLtfSNR1; + rx_stat->RSSI[0] = RXV1_3TH_CYCLE->Rcpi0 / 2 - 110; + rx_stat->RSSI[1] = RXV1_3TH_CYCLE->Rcpi1 / 2 - 110; +#endif /* defined(MT7615) || defined(MT7622) */ + + if (pAd->ATECtrl.en_log & fATE_LOG_RXV) + MT_ATEInsertLog(pAd, data, fATE_LOG_RXV, sizeof(struct _ATE_RXV_LOG)); + + if (pAd->ATECtrl.en_log & fATE_LOG_RXINFO) { + UINT32 nsts = 0; +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + nsts = RXV1_2ND_CYCLE->NstsField; +#else + nsts = RXV1_6TH_CYCLE->NsTsField; +#endif +#if !defined(COMPOS_TESTMODE_WIN) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tPhyMode=%d(%s)\n", + RXV1_1ST_CYCLE->TxMode, get_phymode_str(RXV1_1ST_CYCLE->TxMode))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tMCS=%d\n", RXV1_1ST_CYCLE->TxRate)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tBW=%d\n", RXV1_1ST_CYCLE->FrMode)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tSGI=%d\n", RXV1_1ST_CYCLE->HtShortGi)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tSTBC=%d\n", RXV1_1ST_CYCLE->HtStbc)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tLDPC=%d\n", RXV1_1ST_CYCLE->HtAdCode)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tNsts=%d\n", nsts)); +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + } else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: EN_LOG:%x\n", __func__, pAd->ATECtrl.en_log)); + } else if (type == TESTMODE_RESET_CNT) { + NdisZeroMemory(rx_stat, sizeof(*rx_stat)); + rx_stat->MaxRssi[0] = 0xff; + rx_stat->MaxRssi[1] = 0xff; +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + rx_stat->MaxRssi[2] = 0xff; + rx_stat->MaxRssi[3] = 0xff; +#endif + } else if (type == TESTMODE_COUNTER_802_11) { + COUNTER_802_11 *wlanCounter = (COUNTER_802_11 *)data; + rx_stat->RxMacFCSErrCount = + wlanCounter->FCSErrorCount.u.LowPart; + } +} + + +INT MtTestModeBkCr(PRTMP_ADAPTER pAd, ULONG offset, enum _TEST_BK_CR_TYPE type) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _TESTMODE_BK_CR *bks = ATECtrl->bk_cr; + struct _TESTMODE_BK_CR *entry = NULL; + INT32 i; + + if ((type >= TEST_BKCR_TYPE_NUM) || (type == TEST_EMPTY_BKCR)) + return NDIS_STATUS_INVALID_DATA; + + for (i = 0; i < MAX_TEST_BKCR_NUM; i++) { + struct _TESTMODE_BK_CR *tmp = &bks[i]; + + if ((tmp->type == TEST_EMPTY_BKCR) && (entry == NULL)) { + entry = tmp; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: find emptyp bk entry %d\n", __func__, i)); + } else if ((tmp->type == type) && (tmp->offset == offset)) { + entry = tmp; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: update bk entry %d\n", __func__, i)); + break; + } + } + + if (!entry) + return NDIS_STATUS_RESOURCES; + + entry->type = type; + entry->offset = offset; + + switch (type) { + case TEST_MAC_BKCR: + MAC_IO_READ32(pAd, offset, &entry->val); + break; + + case TEST_HIF_BKCR: + HIF_IO_READ32(pAd, offset, &entry->val); + break; + + case TEST_PHY_BKCR: + PHY_IO_READ32(pAd, offset, &entry->val); + break; + + case TEST_HW_BKCR: + HW_IO_READ32(pAd, offset, &entry->val); + break; + + case TEST_MCU_BKCR: + MCU_IO_READ32(pAd, offset, &entry->val); + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: bk-type not supported\n", __func__)); + entry->type = TEST_EMPTY_BKCR; + entry->offset = 0; + break; + } + + return NDIS_STATUS_SUCCESS; +} + + +INT MtTestModeRestoreCr(PRTMP_ADAPTER pAd, ULONG offset) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _TESTMODE_BK_CR *bks = ATECtrl->bk_cr; + struct _TESTMODE_BK_CR *entry = NULL; + INT32 i; + + for (i = 0; i < MAX_TEST_BKCR_NUM; i++) { + struct _TESTMODE_BK_CR *tmp = &bks[i]; + + if (tmp->offset == offset) { + entry = tmp; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: find entry %d\n", __func__, i)); + break; + } + } + + if (!entry) + return NDIS_STATUS_INVALID_DATA; + + switch (entry->type) { + case TEST_MAC_BKCR: + MAC_IO_WRITE32(pAd, offset, entry->val); + break; + + case TEST_HIF_BKCR: + HIF_IO_WRITE32(pAd, offset, entry->val); + break; + + case TEST_PHY_BKCR: + PHY_IO_WRITE32(pAd, offset, entry->val); + break; + + case TEST_HW_BKCR: + HW_IO_WRITE32(pAd, offset, entry->val); + break; + + case TEST_MCU_BKCR: + MCU_IO_WRITE32(pAd, offset, entry->val); + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: bk-type not supported\n", __func__)); + entry->type = TEST_EMPTY_BKCR; + entry->offset = 0; + break; + } + + entry->type = TEST_EMPTY_BKCR; + entry->offset = 0; + entry->val = 0; + return NDIS_STATUS_SUCCESS; +} + + +static INT32 MtATEPayloadInit(RTMP_ADAPTER *pAd, UCHAR *pPacket, UINT32 len, UINT32 band_idx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 policy = TESTMODE_GET_PARAM(ATECtrl, band_idx, FixedPayload); + UCHAR *payload = TESTMODE_GET_PARAM(ATECtrl, band_idx, payload); + UINT32 pl_len = TESTMODE_GET_PARAM(ATECtrl, band_idx, pl_len); + UINT32 pos = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: len:%d, band_idx:%u, len:%u, pl_len:%u, policy:%x\n", + __func__, len, band_idx, len, pl_len, policy)); + + if (policy == ATE_RANDOM_PAYLOAD) { + for (pos = 0; pos < len; pos++) + pPacket[pos] = RandomByte(pAd); + + return 0; + } + + if (!payload) + return NDIS_STATUS_FAILURE; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: payload:%x\n", __func__, payload[0])); + + if (pl_len == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Payload length can't be 0!!\n", __func__)); + return NDIS_STATUS_FAILURE; + } + + if (policy == ATE_USER_PAYLOAD) { + NdisZeroMemory(pPacket, len); + NdisMoveMemory(pPacket, payload, pl_len); + } else if (policy == ATE_FIXED_PAYLOAD) { + for (pos = 0; pos < len; pos += pl_len) + NdisMoveMemory(&pPacket[pos], payload, pl_len); + } + + return 0; +} + + + + + + +static INT32 MT_ATESetTxPowerX(RTMP_ADAPTER *pAd, ATE_TXPOWER TxPower) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UINT32 Channel = TESTMODE_GET_PARAM(ATECtrl, TxPower.Dbdc_idx, Channel); + UINT32 Ch_Band = TESTMODE_GET_PARAM(ATECtrl, TxPower.Dbdc_idx, Ch_Band); + + if (TxPower.Channel == 0) + TxPower.Channel = Channel; + + TxPower.Band_idx = Ch_Band ? Ch_Band : TxPower.Band_idx; + + if (TxPower.Channel > 14) + TxPower.Band_idx = 1; /* 5G band */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Channel:%d Power:%x Ch_Band:%d Ant:%d\n", + __func__, TxPower.Channel, TxPower.Power, TxPower.Band_idx, TxPower.Ant_idx)); + + if (TxPower.Power <= 0) + return Ret; + + switch (TxPower.Ant_idx) { + case 0: + ATECtrl->TxPower0 = TxPower.Power; + break; + + case 1: + ATECtrl->TxPower1 = TxPower.Power; + break; + + case 2: + ATECtrl->TxPower2 = TxPower.Power; + break; + + case 3: + ATECtrl->TxPower3 = TxPower.Power; + break; + + default: + break; + } + + Ret = MtCmdSetTxPowerCtrl(pAd, TxPower); + return Ret; +} + + +static INT32 MT_ATESetTxPower0(RTMP_ADAPTER *pAd, ATE_TXPOWER TxPower) +{ + INT32 Ret = 0; + TxPower.Ant_idx = 0; + Ret = MT_ATESetTxPowerX(pAd, TxPower); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + + +static INT32 MT_ATESetTxPower1(RTMP_ADAPTER *pAd, ATE_TXPOWER TxPower) +{ + INT32 Ret = 0; + TxPower.Ant_idx = 1; + Ret = MT_ATESetTxPowerX(pAd, TxPower); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + + +static INT32 MT_ATESetTxPower2(RTMP_ADAPTER *pAd, ATE_TXPOWER TxPower) +{ + INT32 Ret = 0; + TxPower.Ant_idx = 2; + Ret = MT_ATESetTxPowerX(pAd, TxPower); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + + +static INT32 MT_ATESetTxPower3(RTMP_ADAPTER *pAd, ATE_TXPOWER TxPower) +{ + INT32 Ret = 0; + TxPower.Ant_idx = 3; + Ret = MT_ATESetTxPowerX(pAd, TxPower); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + +static INT32 MT_ATESetForceTxPower(RTMP_ADAPTER *pAd, INT8 cTxPower, UINT8 ucPhyMode, UINT8 ucTxRate, UINT8 ucBW) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + /* update related Tx parameters */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, PhyMode, ucPhyMode); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mcs, ucTxRate); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, BW, ucBW); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Band(%d), TxMode(%d), MCS(%d), BW(%d), TxPower(%d)\n", + __FUNCTION__, control_band_idx, ucPhyMode, ucTxRate, ucBW, cTxPower)); + + /* firmware command for Force Tx Power Conrtrol */ + MtCmdSetForceTxPowerCtrl(pAd, control_band_idx, cTxPower, ucPhyMode, ucTxRate, ucBW); + + return Ret; +} + +#ifdef LOGDUMP_TO_FILE +static INT32 MT_ATEDumpReCal(struct _ATE_LOG_DUMP_ENTRY entry, INT idx, RTMP_OS_FD_EXT srcf) +#else +static INT32 MT_ATEDumpReCal(struct _ATE_LOG_DUMP_ENTRY entry, INT idx) +#endif +{ + struct _ATE_LOG_RECAL re_cal = entry.log.re_cal; + INT32 ret = 0; +#ifdef LOGDUMP_TO_FILE + INT len = 7 + 2 * 3 + 8 * 3 + 1; + CHAR msg[len]; + os_zero_mem(msg, len); +#endif + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, */ + /* ("CalType:%x ", re_cal.cal_type)); */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[Recal][%08x][%08x]%08x\n", re_cal.cal_type, re_cal.cr_addr, re_cal.cr_val)); + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, */ + /* ("%08x\n", re_cal.cr_val)); */ +#ifdef LOGDUMP_TO_FILE + sprintf(msg, "[Recal][%08x][%08x]%08x\n", re_cal.cal_type, re_cal.cr_addr, re_cal.cr_val); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("Length:%d %s\n", strlen(msg), msg)); + MT_ATEWriteFd(msg, srcf); +#endif + return ret; +} + +static INT32 MT_ATEInsertReCal(struct _ATE_LOG_DUMP_ENTRY *entry, UCHAR *data, UINT32 len) +{ + struct _ATE_LOG_RECAL *re_cal = NULL; + INT32 ret = 0; + + if (!entry) + goto err0; + + if (!data) + goto err0; + + os_zero_mem(entry, sizeof(*entry)); + entry->log_type = fATE_LOG_RE_CAL; + entry->un_dumped = TRUE; + re_cal = &entry->log.re_cal; + NdisMoveMemory((UINT8 *)re_cal, data, + sizeof(*re_cal)); + return ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: NULL entry %p, data %p\n", + __func__, entry, data)); + return NDIS_STATUS_FAILURE; +} + + +static INT32 MT_ATEInsertRDD(struct _ATE_LOG_DUMP_ENTRY *entry, UCHAR *data, UINT32 len) +{ + INT ret = 0; + + if (!entry) + goto err0; + + if (!data) + goto err0; + + os_zero_mem(entry, sizeof(*entry)); + entry->log_type = fATE_LOG_RDD; + entry->un_dumped = TRUE; + + if (len > sizeof(entry->log.rdd)) + len = sizeof(entry->log.rdd); + + NdisMoveMemory((UCHAR *)&entry->log.rdd, data, len); + return ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: NULL entry %p, data %p\n", + __func__, entry, data)); + return -1; +} + + +static INT32 MT_ATEInsertRXV(struct _ATE_LOG_DUMP_ENTRY *entry, UCHAR *data, UINT32 len) +{ + RX_VECTOR1_1ST_CYCLE *RXV1_1ST_CYCLE = (RX_VECTOR1_1ST_CYCLE *)(data + 8); + RX_VECTOR1_2ND_CYCLE *RXV1_2ND_CYCLE = (RX_VECTOR1_2ND_CYCLE *)(data + 12); + RX_VECTOR1_3TH_CYCLE *RXV1_3TH_CYCLE = (RX_VECTOR1_3TH_CYCLE *)(data + 16); + RX_VECTOR1_4TH_CYCLE *RXV1_4TH_CYCLE = (RX_VECTOR1_4TH_CYCLE *)(data + 20); + RX_VECTOR1_5TH_CYCLE *RXV1_5TH_CYCLE = (RX_VECTOR1_5TH_CYCLE *)(data + 24); + RX_VECTOR1_6TH_CYCLE *RXV1_6TH_CYCLE = (RX_VECTOR1_6TH_CYCLE *)(data + 28); + RX_VECTOR2_1ST_CYCLE *RXV2_1ST_CYCLE = (RX_VECTOR2_1ST_CYCLE *)(data + 32); + RX_VECTOR2_2ND_CYCLE *RXV2_2ND_CYCLE = (RX_VECTOR2_2ND_CYCLE *)(data + 36); + RX_VECTOR2_3TH_CYCLE *RXV2_3TH_CYCLE = (RX_VECTOR2_3TH_CYCLE *)(data + 40); + + if (!entry) + goto err0; + + if (!data) + goto err0; + + os_zero_mem(entry, sizeof(*entry)); + entry->log_type = fATE_LOG_RXV; + entry->un_dumped = TRUE; + + if (RXV1_1ST_CYCLE) + entry->log.rxv.rxv1_1st = *RXV1_1ST_CYCLE; + + if (RXV1_2ND_CYCLE) + entry->log.rxv.rxv1_2nd = *RXV1_2ND_CYCLE; + + if (RXV1_3TH_CYCLE) + entry->log.rxv.rxv1_3rd = *RXV1_3TH_CYCLE; + + if (RXV1_4TH_CYCLE) + entry->log.rxv.rxv1_4th = *RXV1_4TH_CYCLE; + + if (RXV1_5TH_CYCLE) + entry->log.rxv.rxv1_5th = *RXV1_5TH_CYCLE; + + if (RXV1_6TH_CYCLE) + entry->log.rxv.rxv1_6th = *RXV1_6TH_CYCLE; + + if (RXV2_1ST_CYCLE) + entry->log.rxv.rxv2_1st = *RXV2_1ST_CYCLE; + + if (RXV2_2ND_CYCLE) + entry->log.rxv.rxv2_2nd = *RXV2_2ND_CYCLE; + + if (RXV2_3TH_CYCLE) + entry->log.rxv.rxv2_3rd = *RXV2_3TH_CYCLE; + + return 0; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: NULL entry %p, data %p\n", + __func__, entry, data)); + return -1; +} + + +#ifdef LOGDUMP_TO_FILE +static INT32 MT_ATEDumpRXV(struct _ATE_LOG_DUMP_ENTRY entry, INT idx, RTMP_OS_FD_EXT srcf) +#else +static INT32 MT_ATEDumpRXV(struct _ATE_LOG_DUMP_ENTRY entry, INT idx) +#endif +{ + INT32 ret = 0; + struct _ATE_RXV_LOG log = entry.log.rxv; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%%[RXV DUMP START][%d]\n", idx)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD1]%08x\n", *((UINT32 *)&log.rxv1_1st))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD2]%08x\n", *((UINT32 *)&log.rxv1_2nd))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD3]%08x\n", *((UINT32 *)&log.rxv1_3rd))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD4]%08x\n", *((UINT32 *)&log.rxv1_4th))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD5]%08x\n", *((UINT32 *)&log.rxv1_5th))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD6]%08x\n", *((UINT32 *)&log.rxv1_6th))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD7]%08x\n", *((UINT32 *)&log.rxv2_1st))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD8]%08x\n", *((UINT32 *)&log.rxv2_2nd))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXVD9]%08x\n", *((UINT32 *)&log.rxv2_3rd))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[RXV DUMP END]\n")); + return ret; +} + +#ifdef LOGDUMP_TO_FILE +static INT MT_ATEWriteFd(RTMP_STRING *log, RTMP_OS_FD_EXT srcf) +{ + INT ret = 0; + INT len = strlen(log); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: Write len %d\n", __func__, len)); + ret = os_file_write(srcf, log, len); + return ret; +} + + +static RTMP_OS_FD_EXT MT_ATEGetFileFd(UINT32 log_type, INT idx) +{ + RTMP_STRING src[64]; + RTMP_OS_FD_EXT srcf; + + switch (log_type) { + case ATE_LOG_RXV: + sprintf(src, "RXVDump_v%d.txt", idx); + break; + + case ATE_LOG_RDD: + sprintf(src, "RDDDump_v%d.txt", idx); + break; + + case ATE_LOG_RE_CAL: + sprintf(src, "RECALDump_v%08x.txt", (UINT32)idx); + break; + + default: + srcf.Status = NDIS_STATUS_FAILURE; + goto err0; + } + + /* srcf = os_file_open(src, O_WRONLY|O_CREAT|O_TRUNC, 0); */ + srcf = os_file_open(src, O_WRONLY | O_CREAT | O_APPEND, 0); + return srcf; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown log type %08x\n", + __func__, log_type)); + return srcf; +} + + +static INT32 MT_ATEReleaseLogFd(RTMP_OS_FD_EXT *srcf) +{ + UCHAR ret = 0; + + if (os_file_close(*srcf) != 0) + goto err0; + + return ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Error closing file\n", __func__)); + return NDIS_STATUS_FAILURE; +} +#endif + + +#if defined(COMPOS_TESTMODE_WIN) +static INT32 MT_ATEDumpRXVToFile(RTMP_ADAPTER *pAd, struct _ATE_LOG_DUMP_CB *log_cb, UINT32 idx) +{ + /* todo: check this function work properly under all the case. */ + UINT32 copyIndex = 0; + KIRQL oldIrql; + UCHAR tempBuffer[512]; + struct _ATE_RXV_LOG log; + struct _ATE_LOG_DUMP_ENTRY *entry; + UCHAR *writeBuffer = (UCHAR *)WINAllocateMemory(CALIBRATION_BUFFER_SIZE); + RTMPMoveMemory(writeBuffer, "[LOG DUMP START]\n", strlen("[LOG DUMP START]\n")); + copyIndex += strlen("[LOG DUMP START]\n"); + + do { + if (log_cb->entry[idx].un_dumped) { + entry = &log_cb->entry[idx]; + log = entry->log.rxv; + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), + "[%d]", idx); + RTMPMoveMemory(&writeBuffer[copyIndex], + tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RTMPMoveMemory(&writeBuffer[copyIndex], "[RXV DUMP START]\r\n", strlen("[RXV DUMP START]\r\n")); + copyIndex += strlen("[RXV DUMP START]\r\n"); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD1]%08x\r\n", *((UINT32 *)&log.rxv1_1st)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD2]%08x\r\n", *((UINT32 *)&log.rxv1_2nd)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD3]%08x\r\n", *((UINT32 *)&log.rxv1_3rd)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD4]%08x\r\n", *((UINT32 *)&log.rxv1_4th)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD5]%08x\r\n", *((UINT32 *)&log.rxv1_5th)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD6]%08x\r\n", *((UINT32 *)&log.rxv1_6th)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD7]%08x\r\n", *((UINT32 *)&log.rxv2_1st)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD8]%08x\r\n", *((UINT32 *)&log.rxv2_2nd)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RtlStringCbPrintfA(tempBuffer, sizeof(tempBuffer), "[RXVD9]%08x\r\n", *((UINT32 *)&log.rxv2_3rd)); + RTMPMoveMemory(&writeBuffer[copyIndex], tempBuffer, strlen(tempBuffer)); + copyIndex += strlen(tempBuffer); + RTMPMoveMemory(&writeBuffer[copyIndex], "[RXV DUMP END]\r\n", strlen("[RXV DUMP END]\r\n")); + copyIndex += strlen("[RXV DUMP END]\r\n"); + log_cb->entry[idx].un_dumped = FALSE; + } + + INC_RING_INDEX(idx, log_cb->len); + } while (idx != log_cb->idx); + + RTMPMoveMemory(&writeBuffer[copyIndex], "[LOG DUMP END]\r\n", strlen("[LOG DUMP END]\r\n")); + copyIndex += strlen("[LOG DUMP END]\r\n"); + + if (pAd->ReCalibrationSize + copyIndex < + CALIBRATION_BUFFER_SIZE) { + KeAcquireSpinLock(&pAd->RxVectorDumpLock, + &oldIrql); + RTMPMoveMemory( + &pAd->RxVectorDumpBuffer[pAd->RxVectorDumpSize], + writeBuffer, copyIndex); + pAd->RxVectorDumpSize += copyIndex; + KeReleaseSpinLock(&pAd->RxVectorDumpLock, + oldIrql); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RxVectorDumpSize = 0x%x, Dump size = 0x%x\n", + pAd->RxVectorDumpSize, copyIndex)); + + if (copyIndex > 0 && pAd->bIsCalDumpThreadRunning) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", pAd->ReCalibrationBuffer)); + KeSetEvent(&pAd->WriteEvent, 0, FALSE); + } else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Calibration buffer 0x%x + dump size 0x%x over Limit 0x%x\n", + pAd->RxVectorDumpSize, copyIndex, CALIBRATION_BUFFER_SIZE)); + } + + WINFreeMemory(writeBuffer); + writeBuffer = NULL; +} + + +#endif /*#if defined(COMPOS_TESTMODE_WIN)*/ + + +INT32 MT_ATEInsertLog(RTMP_ADAPTER *pAd, UCHAR *log, UINT32 log_type, UINT32 len) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_LOG_DUMP_CB *log_cb = NULL; + INT idx = 0; + INT logcb_idx = 0; + UINT32 is_dumping = 0; + INT32 (*insert_func)(struct _ATE_LOG_DUMP_ENTRY *entry, UCHAR *data, UINT32 len) = NULL; + + switch (log_type) { + case fATE_LOG_RXV: + insert_func = MT_ATEInsertRXV; + logcb_idx = ATE_LOG_RXV - 1; + break; + + case fATE_LOG_RDD: + insert_func = MT_ATEInsertRDD; + logcb_idx = ATE_LOG_RDD - 1; + break; + + case fATE_LOG_RE_CAL: + insert_func = MT_ATEInsertReCal; + logcb_idx = ATE_LOG_RE_CAL - 1; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown log type %08x\n", __func__, log_type)); + break; + } + + if (!insert_func) + goto err0; + + log_cb = &ATECtrl->log_dump[logcb_idx]; + idx = log_cb->idx; + OS_SPIN_LOCK(&log_cb->lock); + is_dumping = log_cb->is_dumping; + OS_SPIN_UNLOCK(&log_cb->lock); + + if (is_dumping) + goto err1; + + if ((log_cb->idx + 1) == log_cb->len) { + if (!log_cb->overwritable) + goto err0; + else + log_cb->is_overwritten = TRUE; + } + + OS_SPIN_LOCK(&log_cb->lock); + + if (log_cb->entry == NULL) { + OS_SPIN_UNLOCK(&log_cb->lock); + goto err0; + } + + ret = insert_func(&log_cb->entry[idx], log, len); + OS_SPIN_UNLOCK(&log_cb->lock); + + if (ret) + goto err0; + + INC_RING_INDEX(log_cb->idx, log_cb->len); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_LOUD, ("%s: idx:%d, log_cb->idx:%d, log_type:%08x\n", + __func__, idx, log_cb->idx, log_type)); + return ret; +err0: + if (log_cb) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("[WARN]%s: idx:%x, overwritable:%x, log_type:%08x\n", + __func__, idx, log_cb->overwritable, log_type)); +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s: Log dumping\n", __func__)); + return -NDIS_STATUS_RESOURCES; +} + + +INT32 MT_ATEDumpLog(RTMP_ADAPTER *pAd, struct _ATE_LOG_DUMP_CB *log_cb, UINT32 log_type) +{ + INT32 ret = 0; + INT idx = 0; + UINT32 u4BufferCounter = 0; +#ifdef LOGDUMP_TO_FILE + INT32 (*dump_func)(struct _ATE_LOG_DUMP_ENTRY, INT idx, RTMP_OS_FD_EXT fd) = NULL; +#else + INT32 (*dump_func)(struct _ATE_LOG_DUMP_ENTRY, INT idx) = NULL; +#endif + INT debug_lvl = DebugLevel; + CHAR Log_type[64]; +#ifdef LOGDUMP_TO_FILE + INT len = 5 + 2 * 3 + 5 + 1; + CHAR msg[len]; + os_zero_mem(msg, len); +#endif + + if (!log_cb->entry) + goto err0; + + /* For QAtool log buffer limitation. We should record the current index for next function called. */ + if (pAd->fgQAtoolBatchDumpSupport) + idx = pAd->u2LogEntryIdx; + + if (log_cb->is_overwritten) + idx = log_cb->idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: idx:%d, log_type:%08x, log_cb->idx:%d\n", __func__, idx, log_type, log_cb->idx)); + + switch (log_type) { + case ATE_LOG_RXV: + dump_func = MT_ATEDumpRXV; + strcpy(Log_type, "LOG"); + break; + + case ATE_LOG_RDD: + dump_func = MT_ATERDDParseResult; + strcpy(Log_type, "RDD"); + break; + + case ATE_LOG_RE_CAL: + dump_func = MT_ATEDumpReCal; + strcpy(Log_type, "RECAL"); + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown log type %08x\n", __func__, log_type)); + break; + } + + if (!dump_func) + goto err0; + +#ifdef LOGDUMP_TO_FILE + + if (log_type == ATE_LOG_RE_CAL) + log_cb->fd = MT_ATEGetFileFd(log_type, log_cb->recal_curr_type); + else + log_cb->fd = MT_ATEGetFileFd(log_type, log_cb->file_idx); + + if (log_cb->fd.Status) + goto err1; + + if (log_type == ATE_LOG_RE_CAL) { + sprintf(msg, "[Recal][%08x][START]\n", log_cb->recal_curr_type); + MT_ATEWriteFd(msg, log_cb->fd); + } + +#endif + DebugLevel = DBG_LVL_OFF; + OS_SPIN_LOCK(&log_cb->lock); + log_cb->is_dumping = TRUE; + OS_SPIN_UNLOCK(&log_cb->lock); +#if defined(COMPOS_TESTMODE_WIN) + /* dump RX vector to file */ + CreateThread(pAd); + MT_ATEDumpRXVToFile(pAd, log_cb, idx); +#else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[%s DUMP START]\n", Log_type)); + pAd->fgDumpStart = 1; + + do { + if (log_cb->entry[idx].un_dumped) { + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[%d]", idx)); */ +#ifdef LOGDUMP_TO_FILE + dump_func(log_cb->entry[idx], idx, log_cb->fd); +#else + dump_func(log_cb->entry[idx], idx); +#endif + log_cb->entry[idx].un_dumped = FALSE; + u4BufferCounter++; + } + + /* The size of per entry is 38 bytes and for QAtool log buffer limitation. */ + if ((pAd->fgQAtoolBatchDumpSupport) && + (u4BufferCounter >= (1 << (CONFIG_LOG_BUF_SHIFT - 1)) / 38)) { + pAd->u2LogEntryIdx = idx; + break; + } + + INC_RING_INDEX(idx, log_cb->len); + } while (idx != log_cb->idx); + +#ifdef LOGDUMP_TO_FILE + + if (log_type == ATE_LOG_RE_CAL) { + sprintf(msg, "[Recal][%08x][END]\n", log_cb->recal_curr_type); + MT_ATEWriteFd(msg, log_cb->fd); + } + +#endif + + if ((idx == log_cb->idx) && (pAd->fgDumpStart)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[%s DUMP END]\n", Log_type)); + pAd->fgDumpStart = 0; + } + +#endif + OS_SPIN_LOCK(&log_cb->lock); + log_cb->is_dumping = FALSE; + OS_SPIN_UNLOCK(&log_cb->lock); + DebugLevel = debug_lvl; +#ifdef LOGDUMP_TO_FILE + MT_ATEReleaseLogFd(&log_cb->fd); + log_cb->file_idx++; +#endif + return ret; +#ifdef LOGDUMP_TO_FILE +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Error opening log file\n", __func__)); +#endif +err0: + return -1; +} + + +static INT32 MT_ATEInitLogCB(RTMP_ADAPTER *pAd, struct _ATE_LOG_DUMP_CB *log_cb, UINT32 size, UCHAR overwrite) +{ + INT32 ret = 0; + + if (!log_cb->entry) { + NdisZeroMemory(log_cb, sizeof(*log_cb)); + ret = os_alloc_mem(pAd, (PUCHAR *)&log_cb->entry, size * sizeof(struct _ATE_LOG_DUMP_ENTRY)); + + if (ret) + goto err0; + + os_zero_mem(log_cb->entry, size * sizeof(struct _ATE_LOG_DUMP_ENTRY)); + log_cb->len = size; + NdisAllocateSpinLock(pAd, &log_cb->lock); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s-v4, init log cb size %u, log_cb->len:%u\n", __func__, size, log_cb->len)); + } + + log_cb->overwritable = overwrite; + log_cb->is_overwritten = FALSE; + log_cb->idx = 0; +#ifdef LOGDUMP_TO_FILE + log_cb->file_idx = 0; +#endif + return ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s: Alcated memory fail! size %u\n", __func__, size)); + return ret; +} + +static INT32 MT_ATEReleaseLogDump(RTMP_ADAPTER *pAd) +{ + INT32 ret = 0; + struct _ATE_CTRL *ate_ctrl = &pAd->ATECtrl; + struct _ATE_LOG_DUMP_CB *log_cb = NULL; + INT i = 0; + ate_ctrl->en_log = 0; + + for (i = 0; i < (ATE_LOG_TYPE_NUM - 1); i++) { + log_cb = &ate_ctrl->log_dump[i]; + + if (log_cb->entry) { + os_free_mem(log_cb->entry); + NdisFreeSpinLock(&log_cb->lock); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: release log cb type %d\n", __func__, i + 1)); + } + } + + return ret; +} + + +static VOID MT_ATEAirTimeOnOff(struct _RTMP_ADAPTER *pAd, BOOLEAN Enable) +{ + UINT32 Value; + + if (!Enable) { + MAC_IO_READ32(pAd, RMAC_AIRTIME0, &Value); + Value = Value & (~RX_AIRTIME_EN); + MAC_IO_WRITE32(pAd, RMAC_AIRTIME0, Value); + } +} + + +static INT32 MT_ATELogOnOff(struct _RTMP_ADAPTER *pAd, UINT32 type, UINT32 on_off, UINT32 size) +{ + INT ret = 0; + UINT32 mask = 0; + UCHAR overwrite = TRUE; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_LOG_DUMP_CB *log_cb = NULL; + + switch (type) { + case ATE_LOG_RXV: + mask = fATE_LOG_RXV; + /* Disable RX airtime function to avoid affecting RXV2 Cycle3 */ + /* HW design of RXV2 Cycle3 will be shared for RXV debug function and RX airtime funciotn. */ + MT_ATEAirTimeOnOff(pAd, 0); + break; + + case ATE_LOG_RDD: + overwrite = FALSE; + mask = fATE_LOG_RDD; + break; + + case ATE_LOG_RE_CAL: + /* size = ATE_RECAL_LOG_SIZE; */ + mask = fATE_LOG_RE_CAL; + break; + + case ATE_LOG_RXINFO: + mask = fATE_LOG_RXINFO; + break; + + case ATE_LOG_TXDUMP: + mask = fATE_LOG_TXDUMP; + break; + + case ATE_LOG_TEST: + mask = fATE_LOG_TEST; + break; + + default: + goto err0; + } + + if (type < ATE_LOG_TYPE_NUM) + log_cb = &ATECtrl->log_dump[type - 1]; + + if (on_off == ATE_LOG_ON) { + if (log_cb) + ret = MT_ATEInitLogCB(pAd, log_cb, size, overwrite); + + if (ret) + goto err1; + + ATECtrl->en_log |= mask; + + if (pAd->fgQAtoolBatchDumpSupport) + pAd->u2LogEntryIdx = 0; + } else if (on_off == ATE_LOG_OFF) { + ATECtrl->en_log &= ~mask; + + if (pAd->fgQAtoolBatchDumpSupport) + pAd->u2LogEntryIdx = 0; + } else if (on_off == ATE_LOG_DUMP) { + if (log_cb) + ret = MT_ATEDumpLog(pAd, log_cb, type); + + if (ret) + goto err1; + } else + goto err2; + + return ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s log type %d not supported\n", __func__, type)); +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s log type %d init logCB fail\n", __func__, type)); +err2: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s log ctrl %d not supported\n", __func__, on_off)); + return -1; +} + + +static INT32 MT_ATESetICapStart( + RTMP_ADAPTER *pAd, + BOOLEAN Trigger, + BOOLEAN RingCapEn, + UINT32 Event, + UINT32 Node, + UINT32 Len, + UINT32 StopCycle, + UINT32 BW, + UINT32 MACTriggerEvent, + UINT32 SourceAddrLSB, + UINT32 SourceAddrMSB, + UINT32 Band) +{ + INT32 Ret = 0; +#ifdef INTERNAL_CAPTURE_SUPPORT + INT32 retval = 0; + RBIST_CAP_START_T *prICapInfo = NULL; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + +#ifdef INTERNAL_CAPTURE_SUPPORT + retval = os_alloc_mem(pAd, (UCHAR **)&prICapInfo, sizeof(RBIST_CAP_START_T)); + if (retval != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : Not enough memory for dynamic allocating !!\n", __func__)); + goto error; + } + os_zero_mem(prICapInfo, sizeof(RBIST_CAP_START_T)); + + prICapInfo->fgTrigger = Trigger; + prICapInfo->fgRingCapEn = RingCapEn; + prICapInfo->u4TriggerEvent = Event; + prICapInfo->u4CaptureNode = Node; + prICapInfo->u4CaptureLen = Len; + prICapInfo->u4CapStopCycle = StopCycle; + prICapInfo->u4BW = BW; + prICapInfo->u4MACTriggerEvent = MACTriggerEvent; + prICapInfo->u4SourceAddressLSB = SourceAddrLSB; + prICapInfo->u4SourceAddressMSB = SourceAddrMSB; + prICapInfo->u4BandIdx = Band; + + if (ops->ICapStart != NULL) + Ret = ops->ICapStart(pAd, (UINT8 *)prICapInfo); + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : The function is not hooked !!\n", __func__)); + } + +error: + if (prICapInfo != NULL) + os_free_mem(prICapInfo); +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + return Ret; +} + + +static INT32 MT_ATEGetICapStatus(RTMP_ADAPTER *pAd) +{ + INT32 Ret = 0; +#ifdef INTERNAL_CAPTURE_SUPPORT + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (ops->ICapStatus != NULL) { + Ret = ops->ICapStatus(pAd); + + if (IS_MT7615(pAd)) { + UINT32 StartAddr1, StartAddr2, StartAddr3, EndAddr; + UINT32 StopAddr, Wrap; + + RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&ate_ctrl->cmd_done, ate_ctrl->cmd_expire); + StartAddr1 = ate_ctrl->icap_info.u4StartAddr1; + StartAddr2 = ate_ctrl->icap_info.u4StartAddr2; + StartAddr3 = ate_ctrl->icap_info.u4StartAddr3; + EndAddr = ate_ctrl->icap_info.u4EndAddr; + StopAddr = ate_ctrl->icap_info.u4StopAddr; + Wrap = ate_ctrl->icap_info.u4Wrap; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, StartAddr1:%02x StartAddr2:%02x StartAddr3:%02x EndAddr:%02x StopAddr:%02x Wrap:%02x\n", + __func__, StartAddr1, StartAddr2, StartAddr3, EndAddr, StopAddr, Wrap)); + } + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : The function is not hooked !!\n", __func__)); + } +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + return Ret; +} + + +static INT32 MT_ATEGetICapIQData(RTMP_ADAPTER + *pAd, + PINT32 pData, + PINT32 pDataLen, + UINT32 IQ_Type, + UINT32 WF_Num) +{ + INT32 Ret = 0; +#ifdef INTERNAL_CAPTURE_SUPPORT + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (ops->ICapGetIQData != NULL) + Ret = ops->ICapGetIQData(pAd, pData, pDataLen, IQ_Type, WF_Num); + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : The function is not hooked !!\n", __func__)); + } +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + return Ret; +} + + +#if !defined(COMPOS_TESTMODE_WIN) /* 1todo too many OS private function */ +INT MT_ATERxDoneHandle(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + INC_COUNTER64(pAd->WlanCounters[0].ReceivedFragmentCount); + + { + UINT32 chfreq0 = 0, chfreq1 = 0; + union _RMAC_RXD_0_UNION *rxd_0; + UINT32 pkt_type; + RXD_BASE_STRUCT *rxd_base = (RXD_BASE_STRUCT *)pRxBlk->rmac_info; + + rxd_0 = (union _RMAC_RXD_0_UNION *)pRxBlk->rmac_info; + pkt_type = RMAC_RX_PKT_TYPE(rxd_0->word); + + switch (pkt_type) { + case RMAC_RX_PKT_TYPE_RX_NORMAL: + MAC_IO_READ32(pAd, RMAC_CHFREQ0, &chfreq0); +#ifdef MT7615 + MAC_IO_READ32(pAd, RMAC_CHFREQ1, &chfreq1); +#endif /* MT7615 */ + break; + + default: + break; + } + + ATEOp->SampleRssi(pAd, pRxBlk); + + /* RX packet counter calculate by chfreq of RXD */ + if (rxd_base->RxD1.ChFreq == chfreq0) + ATECtrl->rx_stat.RxTotalCnt[TESTMODE_BAND0]++; + +#ifdef MT7615 + else if (rxd_base->RxD1.ChFreq == chfreq1) + ATECtrl->rx_stat.RxTotalCnt[TESTMODE_BAND1]++; + +#endif /* MT7615 */ + else + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong chfreq!!\n""\tRXD.ch_freq: %x, chfreq0: %x, chfreq0: %x\n", + __func__, rxd_base->RxD1.ChFreq, chfreq0, chfreq1)); + } + /* LoopBack_Rx(pAd, pRxBlk->MPDUtotalByteCnt, pRxBlk->pRxPacket); */ + return TRUE; +} + + +INT8 mt_ate_release_wdev(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct wifi_dev *pWdev = NULL; + UCHAR wdev_idx; + + wdev_idx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wdev_idx); + + /* To close wdev */ + pWdev = pAd->wdev_list[wdev_idx]; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: wdev_idx=%d\n", __func__, ATECtrl->wdev_idx)); + + if (!pWdev) + goto err; + + if (wdev_do_close(pWdev) != TRUE) + ret = -1; + + /* Restore normal driver setting when release wdev */ + pWdev->channel = TESTMODE_GET_PARAM(ATECtrl, band_idx, backup_channel); + pWdev->PhyMode = TESTMODE_GET_PARAM(ATECtrl, band_idx, backup_phymode); + + return ret; + +err: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Cannot get wdev by idx:%d\n", __func__, wdev_idx)); + + return -1; +} + + +INT8 mt_ate_init_wdev(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct wifi_dev *pWdev = NULL; + UCHAR wdev_idx; + UCHAR channel; + + wdev_idx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wdev_idx); + channel = TESTMODE_GET_PARAM(ATECtrl, band_idx, Channel); + + /* To open wdev */ + pWdev = pAd->wdev_list[wdev_idx]; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: wdev_idx=%d, channel=%d\n", + __func__, wdev_idx, channel)); + + if (!pWdev) + goto err; + + /* Backup normal driver setting when init wdev */ + TESTMODE_SET_PARAM(ATECtrl, band_idx, backup_channel, pWdev->channel); + TESTMODE_SET_PARAM(ATECtrl, band_idx, backup_phymode, pWdev->PhyMode); + + pWdev->channel = channel; + + if (band_idx == TESTMODE_BAND0) + pWdev->PhyMode = PHYMODE_CAP_24G; + else if (band_idx == TESTMODE_BAND1) + pWdev->PhyMode = PHYMODE_CAP_5G; + else + pWdev->PhyMode = PHYMODE_CAP_24G; + + if (wdev_do_open(pWdev) != TRUE) + ret = -1; + if (wdev_edca_acquire(pAd, pWdev) != TRUE) + ret = -1; + + HcSetEdca(pWdev); + + return ret; + +err: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Cannot get wdev by idx:%d\n", __func__, wdev_idx)); + + return -1; +} + + +static INT32 MT_ATEReleaseBandInfo(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; +#ifdef DBDC_MODE + INT32 idx = band_idx - 1; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + + if (ATECtrl->band_ext[idx].pate_pkt) { + os_free_mem(ATECtrl->band_ext[idx].pate_pkt); + ATECtrl->band_ext[idx].pate_pkt = NULL; + } +#endif + return ret; +} + + +static INT32 MT_ATEInitBandInfo(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; +#ifdef DBDC_MODE + INT32 idx = band_idx - 1; + UCHAR *payload = NULL; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + RTMP_OS_COMPLETION *tx_wait = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_wait); + CHAR addr[MAC_ADDR_LEN] = {0x00, 0x11, 0x22, 0xBA, 0x2D, 0x11}; + + if (ATECtrl->band_ext[idx].pate_pkt) + os_free_mem(ATECtrl->band_ext[idx].pate_pkt); + + ret = os_alloc_mem(pAd, (PUCHAR *)&ATECtrl->band_ext[idx].pate_pkt, ATE_TESTPKT_LEN); + TESTMODE_SET_PARAM(ATECtrl, band_idx, Channel, 36); + TESTMODE_SET_PARAM(ATECtrl, band_idx, ControlChl, 36); + TESTMODE_SET_PARAM(ATECtrl, band_idx, BW, 0); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxDoneCount, 0); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxedCount, 0); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxLength, 1024); + TESTMODE_SET_PARAM(ATECtrl, band_idx, pl_len, 1); + TESTMODE_SET_PARAM(ATECtrl, band_idx, QID, QID_AC_BE); + + payload = TESTMODE_GET_PARAM(ATECtrl, band_idx, payload); + payload[0] = 0xAA; + TESTMODE_SET_PARAM(ATECtrl, band_idx, HLen, LENGTH_802_11); + TESTMODE_SET_PARAM(ATECtrl, band_idx, FixedPayload, 1); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxCount, 0); + ATECtrl->band_ext[idx].pkt_skb = NULL; + NdisMoveMemory(ATECtrl->band_ext[idx].TemplateFrame, ATECtrl->TemplateFrame, 32); + NdisMoveMemory(ATECtrl->band_ext[idx].Addr1, addr, MAC_ADDR_LEN); + NdisMoveMemory(ATECtrl->band_ext[idx].Addr2, addr, MAC_ADDR_LEN); + NdisMoveMemory(ATECtrl->band_ext[idx].Addr3, addr, MAC_ADDR_LEN); + RTMP_OS_INIT_COMPLETION(tx_wait); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: idx:%u, pkt:%p\n", + __func__, idx, ATECtrl->band_ext[idx].pate_pkt)); +#endif + return ret; +} + + +static INT32 MT_ATEStart(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; +#if defined(MT7615) || defined(MT7622) + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; +#else +#endif /* defined(MT7615) || defined(MT7622) */ + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; + BOOLEAN Cancelled; + MT_RX_FILTER_CTRL_T rx_filter; +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID]; +#endif +#ifdef DBDC_MODE + struct _BAND_INFO *Info = &(ATECtrl->band_ext[0]); +#endif /* DBDC_MODE */ + + /* Remind FW that Enable ATE mode */ + MtCmdATEModeCtrl(pAd, 1); + +#if (defined(MT_MAC) && (!defined(MT7636))) +#ifdef TXBF_SUPPORT + /* Before going into ATE mode, stop sounding first */ + mt_Trigger_Sounding_Packet(pAd, FALSE, 0, 0, 0, NULL); +#endif /* TXBF_SUPPORT */ +#endif /* MAC && undefined MT7636 */ + + /* Make sure ATEInit successfully when interface up */ + if (ATECtrl->Mode & ATE_START) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ATE has already started, wdev_idx:%u\n", __func__, ATECtrl->wdev_idx)); +#ifdef DBDC_MODE + if (IS_ATE_DBDC(pAd)) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ATE has already started, wdev_idx:%u\n", __func__, Info->wdev_idx)); +#endif /* DBDC_MODE */ + + return Ret; + } + + /* Allocate ATE TX packet buffer */ + if (!ATECtrl->pate_pkt) + Ret = os_alloc_mem(pAd, (PUCHAR *)&ATECtrl->pate_pkt, ATE_TESTPKT_LEN); + + if (Ret) + goto err2; + + /* ATE data structure initialization */ + ATECtrl->Channel = 1; + ATECtrl->ControlChl = 1; + ATECtrl->BW = 0; + ATECtrl->en_man_set_freq = 0; + ATECtrl->TxDoneCount = 0; + ATECtrl->TxedCount = 0; + ATECtrl->TxLength = 1024; + ATECtrl->pl_len = 1; + ATECtrl->payload[0] = 0xAA; + ATECtrl->QID = QID_AC_BE; + ATECtrl->HLen = LENGTH_802_11; + RTMP_OS_INIT_COMPLETION(&ATECtrl->tx_wait); + +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + mt_asic_pcie_aspm_dym_ctrl(pAd, DBDC_BAND0, FALSE, FALSE); + if (pAd->CommonCfg.dbdc_mode) + mt_asic_pcie_aspm_dym_ctrl(pAd, DBDC_BAND1, FALSE, FALSE); + set_pcie_aspm_dym_ctrl_cap(pAd, FALSE); +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ + + MT_ATEUpdateRxStatistic(pAd, TESTMODE_RESET_CNT, NULL); + /* + * Backup original CRs and change to ATE mode specific CR setting, + * restore it back when back to normal mode + */ + mt_ate_mac_cr_backup_and_set(pAd); + + /* Common Part */ + /* ATECtrl->en_log = fATE_LOG_TXDUMP; */ + ATECtrl->en_log = 0; + ATECtrl->verify_mode = HQA_VERIFY; + ATECtrl->cmd_expire = RTMPMsecsToJiffies(3000); + RTMP_OS_INIT_COMPLETION(&ATECtrl->cmd_done); + ATECtrl->TxPower0 = pAd->EEPROMImage[TX0_G_BAND_TARGET_PWR]; + ATECtrl->TxPower1 = pAd->EEPROMImage[TX1_G_BAND_TARGET_PWR]; + NdisZeroMemory(ATECtrl->log_dump, sizeof(ATECtrl->log_dump[0])*ATE_LOG_TYPE_NUM); + MT_ATEMPSInit(pAd); + NdisZeroMemory(ATECtrl->pfmu_info, sizeof(ATECtrl->pfmu_info[0])*ATE_BFMU_NUM); +#ifdef CONFIG_QA + MtAsicGetRxStat(pAd, HQA_RX_RESET_PHY_COUNT); + MtAsicGetRxStat(pAd, HQA_RX_RESET_MAC_COUNT); +#endif +#ifdef ATE_TXTHREAD + Ret = TESTMODE_TXTHREAD_INIT(pAd, 0); + + if (Ret) + goto err3; +#endif /* ATE_TXTHREAD */ + + MtATESetMacTxRx(pAd, ASIC_MAC_RX, FALSE, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) + MtATESetMacTxRx(pAd, ASIC_MAC_RX, FALSE, TESTMODE_BAND1); + + /* Rx filter */ + os_zero_mem(&rx_filter, sizeof(rx_filter)); + rx_filter.bPromiscuous = FALSE; + rx_filter.bFrameReport = TRUE; + rx_filter.filterMask = RX_NDPA | RX_NOT_OWN_BTIM | + RX_NOT_OWN_UCAST | + RX_RTS | RX_CTS | RX_CTRL_RSV | + RX_BC_MC_DIFF_BSSID_A2 | + RX_BC_MC_DIFF_BSSID_A3 | RX_BC_MC_OWN_MAC_A3 | + RX_PROTOCOL_VERSION | + RX_FCS_ERROR; + rx_filter.u1BandIdx = TESTMODE_BAND0; + Ret = MtATESetRxFilter(pAd, rx_filter); + + if (IS_ATE_DBDC(pAd)) { + rx_filter.u1BandIdx = TESTMODE_BAND1; + Ret = MtATESetRxFilter(pAd, rx_filter); + } + + /* Stop send TX packets */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; + IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + /* Disable TX PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, FALSE); + Ret = if_ops->init(pAd); + Ret += if_ops->clean_trx_q(pAd); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) { + /* WifiSysApLinkUp(pAd, &pAd->ApCfg.MBSSID[IdBss].wdev); */ + pAd->ApCfg.MBSSID[IdBss].wdev.protection = 0; + } + } + } +#endif + AsicSetWPDMA(pAd, PDMA_TX_RX, TRUE); +#ifdef CONFIG_AP_SUPPORT + APStop(pAd, pMbss, AP_BSS_OPER_ALL); +#endif /* CONFIG_AP_SUPPORT */ + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + + if (Ret) + goto err0; + + /* MtTestModeWTBL2Update(pAd, 0); */ + RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SYSEM_READY); + + /* call wdev_do_open must behind ATE status be set */ + ATECtrl->Mode = ATE_START; + if (IS_ATE_DBDC(pAd)) + TESTMODE_SET_PARAM(ATECtrl, TESTMODE_BAND1, Mode, ATE_START); + + Ret = mt_ate_init_wdev(pAd, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) { + Ret = MT_ATEInitBandInfo(pAd, TESTMODE_BAND1); + Ret += mt_ate_init_wdev(pAd, TESTMODE_BAND1); + } + +#if defined(MT7615) || defined(MT7622) + /* Tx Power related Status Initialization + Disable TX power related behavior when enter test mode */ + ATECtrl->fgTxPowerSKUEn = FALSE; + ATECtrl->fgTxPowerPercentageEn = FALSE; + ATECtrl->fgTxPowerBFBackoffEn = FALSE; + ATECtrl->PercentageLevel = 100; +#ifdef DBDC_MODE + if (IS_ATE_DBDC(pAd)) { + Info->fgTxPowerSKUEn = FALSE; + Info->fgTxPowerPercentageEn = FALSE; + Info->fgTxPowerBFBackoffEn = FALSE; + Info->PercentageLevel = 100; + } +#endif /* DBDC_MODE */ + + /* Disable Tx Power related feature for ATE mode */ +#ifdef CONFIG_HW_HAL_OFFLOAD + /* SKU */ + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_SINGLE_SKU, FALSE); + /* Power Percentage */ + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_POWER_PERCENTAGE, FALSE); + /* Power Drop */ + ATEOp->SetPowerDropLevel(pAd, 100); + /* BF Backoff */ + ATEOp->SetCfgOnOff(pAd, EXT_CFG_ONOFF_BF_BACKOFF, FALSE); +#endif /* CONFIG_HW_HAL_OFFLOAD */ +#else +#endif /* defined(MT7615) || defined(MT7622) */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: wdev_idx:%u\n", __func__, ATECtrl->wdev_idx)); +#ifdef DBDC_MODE + if (IS_ATE_DBDC(pAd)) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: wdev_idx:%u\n", __func__, Info->wdev_idx)); +#endif /* DBDC_MODE */ + + return Ret; + +#ifdef ATE_TXTHREAD +err3: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: initial value fail, ret:%d\n", __func__, Ret)); + ATECtrl->Mode = ATE_STOP; + MT_ATEReleaseLogDump(pAd); +#endif /* ATE_TXTHREAD */ +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): if init fail, ret:%d\n", __func__, Ret)); +err2: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Allocate test packet fail at pakcet\n", __func__)); + + return Ret; +} + + +static INT32 MT_ATEStop(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; + MT_RX_FILTER_CTRL_T rx_filter; +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss; + INT32 MaxNumBss = pAd->ApCfg.BssidNum; /* TODO: Delete after merge MT_ATEStop with Windows Test Mode */ + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID]; +#endif + PNDIS_PACKET *pkt_skb = NULL; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if ((ATECtrl->Mode & ATE_STOP) || !(ATECtrl->Mode & ATE_START)) + goto err2; + + mt_ate_mac_cr_restore(pAd); + + if (ATECtrl->Mode & ATE_FFT) { + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + Ret = ATEOp->SetFFTMode(pAd, 0); + Ret += MtCmdRfTestSwitchMode(pAd, OPERATION_NORMAL_MODE, 0, RF_TEST_DEFAULT_RESP_LEN); + /* For FW to switch back to normal mode stable time */ + mdelay(2000); + + if (Ret) + goto err0; + + ATECtrl->Mode &= ~ATE_FFT; + } + + if (ATECtrl->Mode & fATE_IN_RFTEST) { + Ret += MtCmdRfTestSwitchMode(pAd, OPERATION_NORMAL_MODE, 0, RF_TEST_DEFAULT_RESP_LEN); + /* For FW to switch back to normal mode stable time */ + mdelay(2000); + + if (Ret) + goto err0; + } + + /* MT76x6 Test Mode Freqency offset restore*/ + if (ATECtrl->en_man_set_freq) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Manual Set Frequency Restore\n")); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_ENABLE); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_VALUE); + ATECtrl->en_man_set_freq = 0; + } + + os_zero_mem(&rx_filter, sizeof(rx_filter)); + rx_filter.bPromiscuous = FALSE; + rx_filter.bFrameReport = FALSE; + rx_filter.filterMask = RX_NDPA | RX_NOT_OWN_BTIM | + RX_NOT_OWN_UCAST | + RX_RTS | RX_CTS | RX_CTRL_RSV | + RX_BC_MC_DIFF_BSSID_A2 | + RX_BC_MC_DIFF_BSSID_A3 | RX_BC_MC_OWN_MAC_A3 | + RX_PROTOCOL_VERSION | + RX_FCS_ERROR; + rx_filter.u1BandIdx = 0; + Ret = MtATESetRxFilter(pAd, rx_filter); + + if (IS_ATE_DBDC(pAd)) { + rx_filter.u1BandIdx = 1; + Ret = MtATESetRxFilter(pAd, rx_filter); + } + + MT_ATEReleaseLogDump(pAd); + MT_ATEMPSRelease(pAd); + + /* Release skb */ + pkt_skb = &ATECtrl->pkt_skb; + + if (*pkt_skb) { + RELEASE_NDIS_PACKET(pAd, *pkt_skb, NDIS_STATUS_SUCCESS); + *pkt_skb = NULL; + } + +#ifdef DBDC_MODE + if (IS_ATE_DBDC(pAd)) { + pkt_skb = &ATECtrl->band_ext[TESTMODE_BAND1 - 1].pkt_skb; + + if (*pkt_skb) { + RELEASE_NDIS_PACKET(pAd, *pkt_skb, NDIS_STATUS_SUCCESS); + *pkt_skb = NULL; + } + } +#endif /*DBDC_MODE */ +#ifdef ATE_TXTHREAD + Ret = TESTMODE_TXTHREAD_RELEASE(pAd, 0); + msleep(2); +#endif /* ATE_TXTHREAD */ + + if (if_ops->clean_trx_q) + Ret = if_ops->clean_trx_q(pAd); + + if (if_ops->ate_leave) + Ret += if_ops->ate_leave(pAd); + + if (Ret) + goto err1; + + Ret = mt_ate_release_wdev(pAd, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) { + Ret = mt_ate_release_wdev(pAd, TESTMODE_BAND1); + Ret += MT_ATEReleaseBandInfo(pAd, TESTMODE_BAND1); + } + + NICInitializeAdapter(pAd); + + /* RTMPEnableRxTx(pAd); */ + if (pAd->CommonCfg.bTXRX_RXV_ON) { + MtATESetMacTxRx(pAd, ASIC_MAC_TXRX_RXV, TRUE, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) + MtATESetMacTxRx(pAd, ASIC_MAC_TXRX_RXV, TRUE, TESTMODE_BAND1); + } else { + /* Normal mode enabled RXV and interface down up will crash if disalbe it */ + MtATESetMacTxRx(pAd, ASIC_MAC_TXRX_RXV, TRUE, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) + MtATESetMacTxRx(pAd, ASIC_MAC_TXRX_RXV, TRUE, TESTMODE_BAND1); + } + +#ifdef ARBITRARY_CCK_OFDM_TX + if (IS_MT7615(pAd)) { + MtATEInitCCK_OFDM_Path(pAd, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) + MtATEInitCCK_OFDM_Path(pAd, TESTMODE_BAND1); + } +#endif + RTMP_OS_EXIT_COMPLETION(&ATECtrl->cmd_done); + ATECtrl->Mode = ATE_STOP; + TESTMODE_SET_PARAM(ATECtrl, TESTMODE_BAND1, Mode, ATE_STOP); + MtCmdATEModeCtrl(pAd, 0); /* Remind FW that Disable ATE mode */ + RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV); + +#ifdef CONFIG_AP_SUPPORT + APStartUp(pAd, pMbss, AP_BSS_OPER_ALL); +#endif /* CONFIG_AP_SUPPROT */ + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; + IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE( + pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + + if (Ret) + goto err1; + + return Ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: RF-test stop fail, ret:%d\n", __func__, Ret)); +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: if stop fail, ret:%d\n", __func__, Ret)); +err2: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: ATE has already stopped ret:%d\n", __func__, Ret)); + + ATECtrl->Mode = ATE_STOP; + return Ret; +} +#else +static INT32 MT_ATEStart(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; +#ifdef CAL_FREE_IC_SUPPORT + BOOLEAN bCalFree = 0; +#endif /* CAL_FREE_IC_SUPPORT */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: 2\n", __func__)); +#ifdef CAL_FREE_IC_SUPPORT + RTMP_CAL_FREE_IC_CHECK(pAd, bCalFree); + + if (bCalFree) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Cal Free IC!!\n")); + RTMP_CAL_FREE_DATA_GET(pAd); + } else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Non Cal Free IC!!\n")); + +#endif /* CAL_FREE_IC_SUPPORT */ + + /* MT7636 Test Mode Freqency offset restore*/ + if (ATECtrl->en_man_set_freq) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MT76x6 Manual Set Frequency Restore\n")); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_ENABLE); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_VALUE); + ATECtrl->en_man_set_freq = 0; + } + + if (ATECtrl->Mode & fATE_TXCONT_ENABLE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Stop Continuous Tx\n", __func__)); + ATEOp->StopContinousTx(pAd, 0); + } + + if (ATECtrl->Mode & fATE_TXCARRSUPP_ENABLE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Stop Carrier Suppression Test\n", __func__)); + ATEOp->StopTxTone(pAd); + } + + /* Reset ATE TX/RX Counter */ + ATECtrl->TxLength = 1024; + ATECtrl->QID = QID_AC_BE; + ATECtrl->TxPower0 = 0x10; + ATECtrl->TxPower1 = 0x10; + ATECtrl->en_man_set_freq = 0; + ATECtrl->TxDoneCount = 0; + ATECtrl->Mode = ATE_START; + MtAsicGetRxStat(pAd, HQA_RX_RESET_PHY_COUNT); + MtAsicGetRxStat(pAd, HQA_RX_RESET_MAC_COUNT); + /* MtTestModeWTBL2Update(pAd, 0); */ + return Ret; +} + + +static INT32 MT_ATEStop(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MtATESetMacTxRx(pAd, ASIC_MAC_RXV, FALSE, TESTMODE_BAND0); + + /* RTMPEnableRxTx(pAd); */ + + /* MT7636 Test Mode Freqency offset restore*/ + if (ATECtrl->en_man_set_freq) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MT76x6 Manual Set Frequency Restore\n")); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_ENABLE); + MtTestModeRestoreCr(pAd, FREQ_OFFSET_MANUAL_VALUE); + ATECtrl->en_man_set_freq = 0; + } + + ATECtrl->Mode = ATE_STOP; + return Ret; +} +#endif + + +INT mt_ate_set_tmac_info(RTMP_ADAPTER *pAd, TMAC_INFO *tmac_info, UINT32 band_idx) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UCHAR *addr1 = NULL; + UCHAR phy_mode = 0; + UCHAR mcs = 0; + UCHAR vht_nss = 1; + UINT32 ant_sel = 0; + INT wdev_idx = 0; + UINT32 pkt_tx_time = tx_time_param->pkt_tx_time; + UINT8 need_qos = tx_time_param->pkt_need_qos; + UINT8 need_amsdu = tx_time_param->pkt_need_amsdu; + UINT8 need_ampdu = tx_time_param->pkt_need_ampdu; +#if !defined(COMPOS_TESTMODE_WIN) + struct wifi_dev *pWdev = NULL; +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + UCHAR WmmIdx; +#endif /* defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) */ + BOOLEAN fgSPE; + + wdev_idx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wdev_idx); + pWdev = pAd->wdev_list[wdev_idx]; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: wdev_idx=%d\n", __func__, wdev_idx)); + + if (!pWdev) + goto err0; + +#endif + TESTMODE_SET_PARAM(ATECtrl, band_idx, HLen, LENGTH_802_11); + addr1 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr1); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s:: addr1: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, PRINT_MAC(addr1))); + ant_sel = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxAntennaSel); + phy_mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, PhyMode); + mcs = TESTMODE_GET_PARAM(ATECtrl, band_idx, Mcs); + vht_nss = TESTMODE_GET_PARAM(ATECtrl, band_idx, Nss); + /* Fill TMAC_INFO */ + NdisZeroMemory(tmac_info, sizeof(*tmac_info)); + tmac_info->LongFmt = TRUE; + + if (pkt_tx_time > 0) { + tmac_info->WifiHdrLen = (UINT8) tx_time_param->pkt_hdr_len; + tmac_info->PktLen = (UINT16) tx_time_param->pkt_msdu_len; + tmac_info->NeedTrans = FALSE; + + if (need_qos | need_amsdu | need_ampdu) { + tmac_info->HdrPad = 2; + tmac_info->BmcPkt = FALSE; + tmac_info->UserPriority = 0; + } else { + tmac_info->HdrPad = 0; + tmac_info->BmcPkt = IS_BM_MAC_ADDR(addr1); + tmac_info->UserPriority = 0; + } + } else { + tmac_info->WifiHdrLen = (UINT8)TESTMODE_GET_PARAM(ATECtrl, band_idx, HLen); + tmac_info->HdrPad = 0; + tmac_info->PktLen = (UINT16)TESTMODE_GET_PARAM(ATECtrl, band_idx, TxLength); + tmac_info->BmcPkt = IS_BM_MAC_ADDR(addr1); + } + + /* no ack */ + if ((pkt_tx_time > 0) && (need_ampdu)) + tmac_info->bAckRequired = 1; + else + tmac_info->bAckRequired = 0; + +#if !defined(COMPOS_TESTMODE_WIN) + tmac_info->FrmType = FC_TYPE_DATA; + tmac_info->SubType = SUBTYPE_QDATA; + tmac_info->OwnMacIdx = pWdev->OmacIdx; +#else + tmac_info->OwnMacIdx = 0; +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: tmac_info->OwnMacIdx=%d\n", __func__, tmac_info->OwnMacIdx)); + /* no frag */ + tmac_info->FragIdx = 0; + /* no protection */ + tmac_info->CipherAlg = 0; + /* TX Path setting */ + tmac_info->VhtNss = vht_nss ? vht_nss : 1; + tmac_info->AntPri = 0; + tmac_info->SpeEn = 0; + + /* Timing Measure setting */ + if ((pAd->pTmrCtrlStruct != NULL) && (pAd->pTmrCtrlStruct->TmrEnable == TMR_INITIATOR)) + tmac_info->TimingMeasure = 1; + + /* band_idx for TX ring choose */ + tmac_info->band_idx = band_idx; + + switch (ant_sel) { + case 0: /* Both */ + tmac_info->AntPri = 0; + tmac_info->SpeEn = 1; + break; + + case 1: /* TX0 */ + tmac_info->AntPri = 0; + tmac_info->SpeEn = 0; + break; + + case 2: /* TX1 */ + tmac_info->AntPri = 2; /* b'010 */ + tmac_info->SpeEn = 0; + break; + } + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + /* Need to modify the way of wmm_idx getting */ + WmmIdx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wmm_idx); + tmac_info->WmmSet = WmmIdx; + + if (IS_MT7615(pAd) || IS_MT7622(pAd) || IS_P18(pAd) || IS_MT7663(pAd)) { + if (ant_sel & ATE_ANT_USER_SEL) { + ant_sel &= ~ATE_ANT_USER_SEL; + tmac_info->AntPri = ant_sel; + } else { + INT map_idx = 0; + + for (map_idx = 0; map_idx < ARRAY_SIZE(ant_to_spe_idx_map); map_idx++) { + if (ant_sel == ant_to_spe_idx_map[map_idx].ant_sel) + break; + } + + if (map_idx == ARRAY_SIZE(ant_to_spe_idx_map)) + tmac_info->AntPri = 0; + else + tmac_info->AntPri = ant_to_spe_idx_map[map_idx].spe_idx; + } + +#if defined(TXBF_SUPPORT) && defined(MT_MAC) + + if (g_EBF_certification) { + if (BF_ON_certification) { + tmac_info->AntPri = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("tmac_info->AntPri = 0\n")); + } else { + tmac_info->AntPri = 24; /* 24 */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("tmac_info->AntPri = 24\n")); + } + } + +#endif /* defined(TXBF_SUPPORT) && defined(MT_MAC) */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s:: ant_sel:%x, ant_pri:%u, vht_nss:%x, TxD.VhtNss:%x\n", + __func__, ant_sel, tmac_info->AntPri, vht_nss, tmac_info->VhtNss)); + } + +#endif /* defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) */ + /* Fill transmit setting */ + tmac_info->TxRadioSet.RateCode = mcs; + tmac_info->TxRadioSet.CurrentPerPktBW = TESTMODE_GET_PARAM(ATECtrl, band_idx, PerPktBW); + tmac_info->TxRadioSet.ShortGI = TESTMODE_GET_PARAM(ATECtrl, band_idx, Sgi); + tmac_info->TxRadioSet.Stbc = TESTMODE_GET_PARAM(ATECtrl, band_idx, Stbc); + tmac_info->TxRadioSet.PhyMode = phy_mode; + tmac_info->TxRadioSet.Ldpc = TESTMODE_GET_PARAM(ATECtrl, band_idx, Ldpc); + + tmac_info->QueIdx = dmac_wmm_swq_2_hw_ac_que[tmac_info->WmmSet][TESTMODE_GET_PARAM(ATECtrl, band_idx, QID)]; + + if ((pkt_tx_time > 0) && (need_ampdu)) { + tmac_info->Wcid = ATECtrl->wcid_ref; + tmac_info->FixRate = 0; + tmac_info->BaDisable = FALSE; + tmac_info->RemainTxCnt = 1; + } else { + tmac_info->Wcid = 0; + tmac_info->FixRate = 1; + tmac_info->BaDisable = TRUE; + tmac_info->RemainTxCnt = 15; + } + + if (ATECtrl->txs_enable) { + tmac_info->TxS2Host = TRUE; + tmac_info->TxS2Mcu = FALSE; + tmac_info->TxSFmt = 1; + } + + if (phy_mode == MODE_CCK) { + tmac_info->TxRadioSet.Premable = LONG_PREAMBLE; + + if (mcs == MCS_9) { + tmac_info->TxRadioSet.RateCode = 0; + tmac_info->TxRadioSet.Premable = SHORT_PREAMBLE; + } else if (mcs == MCS_10) { + tmac_info->TxRadioSet.RateCode = 1; + tmac_info->TxRadioSet.Premable = SHORT_PREAMBLE; + } else if (mcs == MCS_11) { + tmac_info->TxRadioSet.RateCode = 2; + tmac_info->TxRadioSet.Premable = SHORT_PREAMBLE; + } + } + +#ifdef TXBF_SUPPORT + else { + UCHAR iTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, iTxBf); + UCHAR eTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, eTxBf); + + if (iTxBf || eTxBf) { + tmac_info->TxRadioSet.ItxBFEnable = iTxBf; + tmac_info->TxRadioSet.EtxBFEnable = eTxBf; + } + } + +#endif /* TXBF_SUPPORT */ + tmac_info->Wcid = ATECtrl->wcid_ref; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: tmac_info->TxRadioSet.EtxBFEnable=%d, tmac_info->Wcid=%d\n", + __func__, tmac_info->TxRadioSet.EtxBFEnable, tmac_info->Wcid)); + + if (tmac_info->AntPri >= 24) + fgSPE = TRUE; + else + fgSPE = FALSE; + +#ifdef SINGLE_SKU_V2 + /* Update Power offset according to Band, Phymode, MCS, BW, Nss, SPE */ + tmac_info->PowerOffset = SKUTxPwrOffsetGet(pAd, + band_idx, ATECtrl->PerPktBW, ATECtrl->PhyMode, + ATECtrl->Mcs, + ATECtrl->Nss, fgSPE); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: tmac_info->PowerOffset = 0x%x (%d)\n", + __func__, tmac_info->PowerOffset, tmac_info->PowerOffset)); + + if (tmac_info->PowerOffset < -16) + tmac_info->PowerOffset = -16; + else if (tmac_info->PowerOffset > 15) + tmac_info->PowerOffset = 15; +#endif /* SINGLE_SKU_V2 */ + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + if ((pkt_tx_time > 0) && (need_ampdu)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: tmac_info->Wcid/Wmmset/QueIdx=%d/%d/%d\n", + __func__, tmac_info->Wcid, tmac_info->WmmSet, tmac_info->QueIdx)); + } +#endif /* defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) */ + return Ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s:: Cannot get Wdev by idx:%d\n", __func__, wdev_idx)); + return -1; +} + + +UINT32 mt_ate_get_txlen_by_pkt_tx_time(struct _ATE_CTRL *ATECtrl, UINT32 band_idx) +{ + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UINT32 txlen = 0; + UINT32 hlen = 0; + UINT32 tx_data_rate = 0; + UINT32 pkt_tx_time = 0; + UCHAR phy_mode = 0; + UCHAR mcs = 0, mcs_1ss, nss = 1; + UCHAR bw = 0, bw_fact = 1; + UCHAR sgi = 0; + + /* + * 1. Get the tx data rate + * 2. Get the packet tx time + * 3. Calculate the packet length by tx_data_rate and packet_tx_time + * 4. Return txlen + */ + pkt_tx_time = tx_time_param->pkt_tx_time; + hlen = TESTMODE_GET_PARAM(ATECtrl, band_idx, HLen); + phy_mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, PhyMode); + mcs = TESTMODE_GET_PARAM(ATECtrl, band_idx, Mcs); + bw = TESTMODE_GET_PARAM(ATECtrl, band_idx, BW); + sgi = TESTMODE_GET_PARAM(ATECtrl, band_idx, Sgi); + mcs_1ss = mcs; + + if (phy_mode == MODE_CCK) { /* Legacy CCK mode */ + UINT8 cck_map_idx = 0; + + for (cck_map_idx = 0; + cck_map_idx < ARRAY_SIZE(cck_mode_mcs_to_data_rate_map); cck_map_idx++) { + if (mcs_1ss == cck_mode_mcs_to_data_rate_map[cck_map_idx].mcs) + break; + } + + if (cck_map_idx == ARRAY_SIZE(cck_mode_mcs_to_data_rate_map)) { + tx_data_rate = cck_mode_mcs_to_data_rate_map[0].tx_data_rate; + mcs = mcs_1ss = cck_mode_mcs_to_data_rate_map[0].mcs; + TESTMODE_SET_PARAM(ATECtrl, band_idx, Mcs, mcs); + } else + tx_data_rate = cck_mode_mcs_to_data_rate_map[cck_map_idx].tx_data_rate; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 1000 / 8; + } else if (phy_mode == MODE_OFDM) { /* Legacy OFDM mode */ + UINT8 ofdm_map_idx = 0; + + for (ofdm_map_idx = 0; ofdm_map_idx < ARRAY_SIZE(ofdm_mode_mcs_to_data_rate_map); ofdm_map_idx++) { + if (mcs_1ss == ofdm_mode_mcs_to_data_rate_map[ofdm_map_idx].mcs) + break; + } + + if (ofdm_map_idx == ARRAY_SIZE(ofdm_mode_mcs_to_data_rate_map)) { + tx_data_rate = ofdm_mode_mcs_to_data_rate_map[0].tx_data_rate; + mcs = mcs_1ss = ofdm_mode_mcs_to_data_rate_map[0].mcs; + TESTMODE_SET_PARAM(ATECtrl, band_idx, Mcs, mcs); + } else + tx_data_rate = ofdm_mode_mcs_to_data_rate_map[ofdm_map_idx].tx_data_rate; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 1000 / 8; + } else if (phy_mode == MODE_HTMIX || phy_mode == MODE_HTGREENFIELD) { /* HT mode */ + UINT8 n_map_idx = 0; + + if (mcs != MCS_32) { + mcs_1ss = mcs % 8; + nss = (mcs / 8) + 1; + bw_fact = (bw == BW_40) ? 2 : 1; + } else { + bw_fact = 1; + nss = 1; + } + + for (n_map_idx = 0; n_map_idx < ARRAY_SIZE(n_mode_mcs_to_data_rate_map); n_map_idx++) { + if (mcs_1ss == n_mode_mcs_to_data_rate_map[n_map_idx].mcs) + break; + } + + if (n_map_idx == ARRAY_SIZE(n_mode_mcs_to_data_rate_map)) { + tx_data_rate = n_mode_mcs_to_data_rate_map[0].tx_data_rate; + mcs = mcs_1ss = n_mode_mcs_to_data_rate_map[0].mcs; + TESTMODE_SET_PARAM(ATECtrl, band_idx, Mcs, mcs); + } else + tx_data_rate = n_mode_mcs_to_data_rate_map[n_map_idx].tx_data_rate; + + tx_data_rate = tx_data_rate * nss * bw_fact; + + if (sgi == 1) + tx_data_rate = (tx_data_rate / 9) * 10; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 1000 / 8; + } else if (phy_mode == MODE_VHT) { /* VHT mode */ + UINT8 ac_map_idx = 0; + struct _ATE_DATA_RATE_MAP *vht_rate_map; + UINT32 array_cnt = 0; + + if (bw == BW_20) { + vht_rate_map = ac_mode_mcs_to_data_rate_map_bw20; + array_cnt = ARRAY_SIZE(ac_mode_mcs_to_data_rate_map_bw20); + } else if (bw == BW_40) { + vht_rate_map = ac_mode_mcs_to_data_rate_map_bw40; + array_cnt = ARRAY_SIZE(ac_mode_mcs_to_data_rate_map_bw40); + } else if (bw == BW_80) { + vht_rate_map = ac_mode_mcs_to_data_rate_map_bw80; + array_cnt = ARRAY_SIZE(ac_mode_mcs_to_data_rate_map_bw80); + } else if (bw == BW_160) { + vht_rate_map = ac_mode_mcs_to_data_rate_map_bw160; + array_cnt = ARRAY_SIZE(ac_mode_mcs_to_data_rate_map_bw160); + } else { + vht_rate_map = ac_mode_mcs_to_data_rate_map_bw20; + array_cnt = ARRAY_SIZE(ac_mode_mcs_to_data_rate_map_bw20); + } + + for (ac_map_idx = 0; ac_map_idx < array_cnt; ac_map_idx++) { + if (mcs == vht_rate_map[ac_map_idx].mcs) + break; + } + + if (ac_map_idx == array_cnt) { + tx_data_rate = vht_rate_map[0].tx_data_rate; + mcs = mcs_1ss = vht_rate_map[0].mcs; + TESTMODE_SET_PARAM(ATECtrl, band_idx, Mcs, mcs); + } else + tx_data_rate = vht_rate_map[ac_map_idx].tx_data_rate; + + /* TODO: Need to check for SGI equation! */ + if (sgi == 1) + tx_data_rate = (tx_data_rate / 9) * 10; + + /* Transfer from bit to byte with expected tx time */ + txlen = pkt_tx_time * tx_data_rate / 10 / 8; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: phy_mode=%d, mcs/mcs_1ss=%d/%d, nss=%d, bw/bw_fact=%d/%d, sgi=%d\n", + __func__, phy_mode, mcs, mcs_1ss, nss, bw, bw_fact, sgi)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: txlen=%d, pkt_tx_time=%d, tx_data_rate=%d\n", + __func__, txlen, pkt_tx_time, tx_data_rate)); + + if (phy_mode == MODE_VHT) { + if (txlen >= (MAX_VHT_MPDU_LEN * 64)) { + txlen = (MAX_VHT_MPDU_LEN * 64); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Expected txlen > VHT mode PPDU max length, reduce the txlen=%d\n", + __func__, txlen)); + } + } else if (phy_mode == MODE_HTMIX || phy_mode == MODE_HTGREENFIELD) { + if (txlen >= MAX_HT_AMPDU_LEN) { + txlen = MAX_HT_AMPDU_LEN; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Expected txlen > HT mode PPDU max length, reduce the txlen=%d\n", __func__, txlen)); + } + } else if (phy_mode == MODE_OFDM) { + if (txlen >= MAX_MSDU_LEN) { + txlen = MAX_MSDU_LEN; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Expected txlen > OFDM mode PPDU max length, reduce the txlen=%d\n", __func__, txlen)); + } + } else if (phy_mode == MODE_CCK) { + if (txlen >= MAX_MSDU_LEN) { + txlen = MAX_MSDU_LEN; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Expected txlen > CCK mode PPDU max length, reduce the txlen=%d\n", __func__, txlen)); + } + } + + return txlen; +} + + +UINT32 mt_ate_get_hlen_by_pkt_tx_time( + struct _ATE_CTRL *ATECtrl, + UINT32 band_idx, + UINT32 txlen, + BOOLEAN *need_qos, + BOOLEAN *need_amsdu, + BOOLEAN *need_ampdu) +{ + UINT32 pkt_len = 0; + UINT32 hlen = 0; + UCHAR phy_mode = 0; + UCHAR use_data_frame = 1; + /* + * 1. Get the tx data rate + * 2. Check if need to send packet with AMPDU format + * 3. Check if need to send packet with AMSDU-in-AMPDU format + * 4. Return the expected packet header length by tx packet type + * if need to has QoS field and HTC field. + */ + phy_mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, PhyMode); + pkt_len = txlen; + + if (pkt_len <= MIN_MSDU_LEN) { + use_data_frame = 0; + /* Here we need to go mgmt/ctrl frame mode */ + } else if (pkt_len <= MAX_MSDU_LEN) { + if (phy_mode == MODE_VHT) + *need_qos = 1; + } else if (pkt_len <= DEFAULT_MPDU_LEN) { + if (phy_mode == MODE_HTMIX || phy_mode == MODE_HTGREENFIELD) { + *need_amsdu = 1; + *need_qos = 1; + } else if (phy_mode == MODE_VHT) + *need_qos = 1; + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Can't generate frame with such length for CCK/OFDM mode!!\n", __func__)); + } + } else if (pkt_len <= MAX_VHT_MPDU_LEN) { + if (phy_mode == MODE_VHT) + *need_qos = 1; + else if (phy_mode == MODE_HTMIX || phy_mode == MODE_HTGREENFIELD) { + *need_ampdu = 1; + *need_amsdu = 1; + *need_qos = 1; + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Can't generate frame with such length for CCK/OFDM mode!!\n", __func__)); + } + } else { + if ((phy_mode == MODE_VHT) || (phy_mode == MODE_HTMIX || phy_mode == MODE_HTGREENFIELD)) { + *need_ampdu = 1; + *need_amsdu = 1; + *need_qos = 1; + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Can't generate frame with such length for CCK/OFDM mode!!\n", __func__)); + } + } + + hlen = TESTMODE_GET_PARAM(ATECtrl, band_idx, HLen); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: original header len=%d\n", __func__, hlen)); + + if (use_data_frame) { + hlen = DEFAULT_MAC_HDR_LEN; + + if (*need_qos) + hlen = QOS_MAC_HDR_LEN; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: pkt_len=%d, need_qos/amsdu/ampdu/dataframe/hlen=%d/%d/%d/%d/%d\n", + __func__, pkt_len, *need_qos, *need_amsdu, *need_ampdu, use_data_frame, hlen)); + return hlen; +} + + +INT mt_ate_wtbl_cfg(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT ret; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UINT8 need_qos, need_amsdu, need_ampdu; + UCHAR phy_mode, mcs, nss, bw, sgi, stbc; + struct cmd_wtbl_dw_mask_set dw_set[7]; + UINT32 wtbl_rate = 0, ant_sel = 0; + need_qos = tx_time_param->pkt_need_qos; + need_amsdu = tx_time_param->pkt_need_amsdu; + need_ampdu = tx_time_param->pkt_need_ampdu; + phy_mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, PhyMode); + mcs = TESTMODE_GET_PARAM(ATECtrl, band_idx, Mcs); + nss = TESTMODE_GET_PARAM(ATECtrl, band_idx, Nss); + bw = TESTMODE_GET_PARAM(ATECtrl, band_idx, BW); + sgi = TESTMODE_GET_PARAM(ATECtrl, band_idx, Sgi); + stbc = TESTMODE_GET_PARAM(ATECtrl, band_idx, Stbc); + ant_sel = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxAntennaSel); + NdisZeroMemory((UCHAR *)&dw_set[0], sizeof(dw_set)); + /* Decide TxCap, HT/VHT/LPDC (DW2) */ + dw_set[0].ucWhichDW = 2; + dw_set[0].u4DwMask = 0x9FFFFFFF; + + switch (phy_mode) { + case MODE_HTMIX: + case MODE_HTGREENFIELD: + dw_set[0].u4DwValue = (0x1 << 29); + break; + + case MODE_VHT: + dw_set[0].u4DwValue = (0x3 << 29); + break; + + default: + dw_set[0].u4DwValue = 0; + break; + }; + + /* Decide AF/I_PSM (DW3) */ + dw_set[1].ucWhichDW = 3; + + dw_set[1].u4DwMask = 0xD8E0F000; + + if (need_ampdu) { +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + + if (IS_MT7615(pAd) || IS_MT7622(pAd) || IS_P18(pAd) || IS_MT7663(pAd)) { + if (ant_sel & ATE_ANT_USER_SEL) + ant_sel &= ~ATE_ANT_USER_SEL; + else { + INT map_idx = 0; + + for (map_idx = 0; map_idx < ARRAY_SIZE(ant_to_spe_idx_map); map_idx++) { + if (ant_sel == ant_to_spe_idx_map[map_idx].ant_sel) + break; + } + + if (map_idx == ARRAY_SIZE(ant_to_spe_idx_map)) + ant_sel = 0; + else + ant_sel = ant_to_spe_idx_map[map_idx].spe_idx; + } + } + +#endif /* defined(MT7615) || defined(MT7622) */ + dw_set[1].u4DwValue = (0x1 << 29) + | (0x7 << 24) + | ((ant_sel & 0x1F) << 16) + | ((ant_sel & 0x7) << 9) + | ((ant_sel & 0x7) << 6) + | ((ant_sel & 0x7) << 3) + | ((ant_sel & 0x7) << 0); + } else + dw_set[1].u4DwValue = 0; + + /* Decide BA-enable/BA-winsize/BA-bitmap (DW4) */ + dw_set[2].ucWhichDW = 4; + dw_set[2].u4DwMask = 0x0; + + if (need_ampdu) + dw_set[2].u4DwValue = 0xFFFFFFFF; + else + dw_set[2].u4DwValue = 0x0; + + /* Decide FCAP/G2/G4/G8/G16/QoS-enable (DW5 )*/ + dw_set[3].ucWhichDW = 5; + dw_set[3].u4DwMask = 0xFFF7C0FF; + + switch (bw) { + case BW_20: + dw_set[3].u4DwValue = (bw << 12) | (sgi << 8); + break; + + case BW_40: + dw_set[3].u4DwValue = (bw << 12) | (sgi << 9); + break; + + case BW_80: + dw_set[3].u4DwValue = (bw << 12) | (sgi << 10); + break; + + case BW_160: + dw_set[3].u4DwValue = (bw << 12) | (sgi << 11); + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: Can't find such bw, use default\n", __func__)); + dw_set[3].u4DwValue = (BW_20 << 12) | (sgi << 8); + break; + } + + if (phy_mode == MODE_HTMIX || phy_mode == MODE_HTGREENFIELD || phy_mode == MODE_VHT) { + /* QoS enable by phymode */ + dw_set[3].u4DwValue |= (1 << 19); + } + + /* Use phymode/mcs/nss/STBC decide RateInfo (DW6~8) */ + /* step 1. depends on ATE command tx rate, convert to 12-bits WTBL-rate value */ + /* wtbl_rate = ((STBC & 0x1) << 11) | ((Nss & 0x3)<< 9) | ((phy_mode & 0x3) << 6) | ((mcs & 0x3f) << 0) */ + if (phy_mode == MODE_CCK) + wtbl_rate = tx_rate_to_tmi_rate(phy_mode, mcs, (nss + 1), stbc, 1); + else + wtbl_rate = tx_rate_to_tmi_rate(phy_mode, mcs, (nss + 1), stbc, 0); + + /* step 2. set WTBL RAW DW 6: ((rate3 & 0xff)<< 24) | ((rate2 & 0xfff) << 12) | ((rate1 & 0xfff) << 0) */ + dw_set[4].ucWhichDW = 6; + dw_set[4].u4DwMask = 0x0; + dw_set[4].u4DwValue = ((wtbl_rate & 0xFF) << 24) + | ((wtbl_rate & 0xFFF) << 12) + | ((wtbl_rate & 0xFFF) << 0); + dw_set[5].ucWhichDW = 7; + dw_set[5].u4DwMask = 0x0; + dw_set[5].u4DwValue = ((wtbl_rate & 0xF) << 28) + | ((wtbl_rate & 0xFFF) << 16) + | ((wtbl_rate & 0xFFF) << 4) + | (((wtbl_rate & 0xF00) >> 8) << 0); + dw_set[6].ucWhichDW = 8; + dw_set[6].u4DwMask = 0x0; + dw_set[6].u4DwValue = ((wtbl_rate & 0xFFF) << 20) + | ((wtbl_rate & 0xFFF) << 8) + | (((wtbl_rate & 0xFF0) >> 4) << 0); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: phy_mode=%d, mcs=%d, nss=%d, stbc=%d, wtbl_rate=0x%x\n", + __func__, phy_mode, mcs, nss, stbc, wtbl_rate)); + ret = WtblResetAndDWsSet(pAd, ATECtrl->wcid_ref, 1, sizeof(dw_set) / sizeof(struct cmd_wtbl_dw_mask_set), dw_set); + return ret; +} + + +INT32 mt_ate_ampdu_frame(RTMP_ADAPTER *pAd, UCHAR *buf, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UCHAR *addr1, *addr2, *addr3; + UCHAR phy_mode; + UCHAR *tmac_info, *pheader, *payload, *frm_template; + UINT32 txlen, hlen; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->TXWISize; + UINT32 new_txlen, new_hlen; + UINT8 need_qos, need_amsdu, need_ampdu; + UINT32 per_mpdu_len = 0; + UINT8 ampdu_agg_cnt = 0; + phy_mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, PhyMode); + new_txlen = tx_time_param->pkt_tx_len; + new_hlen = tx_time_param->pkt_hdr_len; + need_qos = tx_time_param->pkt_need_qos; + need_amsdu = tx_time_param->pkt_need_amsdu; + need_ampdu = tx_time_param->pkt_need_ampdu; + + if (phy_mode == MODE_VHT) + per_mpdu_len = (MAX_VHT_MPDU_LEN - 100); /* include mac header length */ + else + per_mpdu_len = (DEFAULT_MPDU_LEN - 100); /* include mac header length */ + + tx_time_param->pkt_msdu_len = per_mpdu_len; + ampdu_agg_cnt = new_txlen / per_mpdu_len; + + if (new_txlen % per_mpdu_len) + ampdu_agg_cnt++; + + tx_time_param->pkt_ampdu_cnt = ampdu_agg_cnt; + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + ret = mt_ate_ampdu_ba_limit(pAd, band_idx, ampdu_agg_cnt); + ret = mt_ate_set_sta_pause_cr(pAd, band_idx); +#endif /* defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) */ + addr1 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr1); + addr2 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr2); + addr3 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr3); + txlen = tx_time_param->pkt_msdu_len; + hlen = tx_time_param->pkt_hdr_len; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(wcid:%d, txlen/hlen/buf=%d/%d/%p, pkt_tx_len/pkt_msdu_len/pkt_ampdu_cnt=%d/%d/%d)\n" + "\tDA: %02x:%02x:%02x:%02x:%02x:%02x\n" + "\tSA: %02x:%02x:%02x:%02x:%02x:%02x\n" + "\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, ATECtrl->wcid_ref, txlen, hlen, buf, + tx_time_param->pkt_tx_len, tx_time_param->pkt_msdu_len, + tx_time_param->pkt_ampdu_cnt, PRINT_MAC(addr1), PRINT_MAC(addr2), PRINT_MAC(addr3))); + tmac_info = buf; + pheader = (buf + tx_hw_hdr_len); + payload = (pheader + hlen); + NdisZeroMemory(buf, ATE_TESTPKT_LEN); +#ifdef TXBF_SUPPORT + { + UCHAR iTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, iTxBf); + UCHAR eTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, eTxBf); + + /* Use wcid 1~4 */ + if (iTxBf || eTxBf) { + if ((ATECtrl->wcid_ref > ATE_BFMU_NUM) || (ATECtrl->wcid_ref < 1)) + ATECtrl->wcid_ref = ATE_BF_WCID; + + addr1 = ATECtrl->pfmu_info[ATECtrl->wcid_ref - 1].addr; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:: DA: %02x:%02x:%02x:%02x:%02x:%02x, wcid=%u\n", + __func__, PRINT_MAC(addr1), ATECtrl->wcid_ref)); + } +#endif + frm_template = TESTMODE_GET_PARAM(ATECtrl, band_idx, TemplateFrame); + NdisMoveMemory(pheader, frm_template, hlen); + NdisMoveMemory(pheader + 4, addr1, MAC_ADDR_LEN); + NdisMoveMemory(pheader + 10, addr2, MAC_ADDR_LEN); + NdisMoveMemory(pheader + 16, addr3, MAC_ADDR_LEN); + ret = MtATEPayloadInit(pAd, payload, txlen - hlen, band_idx); +#if !defined(COMPOS_TESTMODE_WIN) + + if (ATECtrl->en_log & fATE_LOG_TXDUMP) { + INT i = 0; + PHEADER_802_11 hdr = (HEADER_802_11 *)pheader; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[TXCONTENT DUMP START]\n")); + dump_tmac_info(pAd, tmac_info); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[TXD RAW]: ")); + + for (i = 0; i < tx_hw_hdr_len; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%04x", tmac_info[i])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\nADDR1: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr1))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR2: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr2))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR3: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr3))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("FC: %04x\n", *(UINT16 *)(&hdr->FC))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFrom DS: %x\n", hdr->FC.FrDs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tTo DS: %x\n", hdr->FC.ToDs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[CONTENT RAW]: ")); + + for (i = 0; i < (txlen - hlen); i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%02x", payload[i])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n[TXCONTENT DUMP END]\n")); + } + +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + TESTMODE_SET_PARAM(ATECtrl, band_idx, is_alloc_skb, 0); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pheader, DIR_WRITE, FALSE); +#ifdef MT_MAC + + if (IS_HIF_TYPE(pAd, HIF_MT)) + MTMacInfoEndianChange(pAd, tmac_info, TYPE_TMACINFO, sizeof(TMAC_TXD_L)); + +#endif +#endif + return ret; +} + + +INT32 mt_ate_non_ampdu_frame(RTMP_ADAPTER *pAd, UCHAR *buf, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UCHAR *tmac_info, *pheader, *payload, *addr1, *addr2, *addr3, *frm_template; + UINT32 txlen, hlen; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->TXWISize; + addr1 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr1); + addr2 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr2); + addr3 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr3); + txlen = tx_time_param->pkt_msdu_len; + hlen = tx_time_param->pkt_hdr_len; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(wcid:%d, txlen/hlen/buf=%d/%d/%p, pkt_tx_len/pkt_msdu_len=%d/%d)\n" + "\tDA: %02x:%02x:%02x:%02x:%02x:%02x\n" + "\tSA: %02x:%02x:%02x:%02x:%02x:%02x\n" + "\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, ATECtrl->wcid_ref, + txlen, hlen, buf, + tx_time_param->pkt_tx_len, + tx_time_param->pkt_msdu_len, + PRINT_MAC(addr1), PRINT_MAC(addr2), + PRINT_MAC(addr3))); + tmac_info = buf; + pheader = (buf + tx_hw_hdr_len); + payload = (pheader + hlen); + NdisZeroMemory(buf, ATE_TESTPKT_LEN); +#ifdef TXBF_SUPPORT + { + UCHAR iTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, iTxBf); + UCHAR eTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, eTxBf); + + /* Use wcid 1~4 */ + if (iTxBf || eTxBf) { + if ((ATECtrl->wcid_ref > ATE_BFMU_NUM) || (ATECtrl->wcid_ref < 1)) + ATECtrl->wcid_ref = ATE_BF_WCID; + + addr1 = ATECtrl->pfmu_info[ATECtrl->wcid_ref - 1].addr; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:: DA: %02x:%02x:%02x:%02x:%02x:%02x, wcid=%u\n", + __func__, PRINT_MAC(addr1), ATECtrl->wcid_ref)); + } +#endif + frm_template = TESTMODE_GET_PARAM(ATECtrl, band_idx, TemplateFrame); + NdisMoveMemory(pheader, frm_template, hlen); + NdisMoveMemory(pheader + 4, addr1, MAC_ADDR_LEN); + NdisMoveMemory(pheader + 10, addr2, MAC_ADDR_LEN); + NdisMoveMemory(pheader + 16, addr3, MAC_ADDR_LEN); + ret = MtATEPayloadInit(pAd, payload, txlen - hlen, band_idx); +#if !defined(COMPOS_TESTMODE_WIN) + + if (ATECtrl->en_log & fATE_LOG_TXDUMP) { + INT i = 0; + PHEADER_802_11 hdr = (HEADER_802_11 *)pheader; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[TXCONTENT DUMP START]\n")); + dump_tmac_info(pAd, tmac_info); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[TXD RAW]: ")); + + for (i = 0; i < tx_hw_hdr_len; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%04x", tmac_info[i])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\nADDR1: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr1))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR2: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr2))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR3: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr3))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("FC: %04x\n", *(UINT16 *)(&hdr->FC))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFrom DS: %x\n", hdr->FC.FrDs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tTo DS: %x\n", hdr->FC.ToDs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[CONTENT RAW]: ")); + + for (i = 0; i < (txlen - hlen); i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%02x", payload[i])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n[TXCONTENT DUMP END]\n")); + } + +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + TESTMODE_SET_PARAM(ATECtrl, band_idx, is_alloc_skb, 0); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pheader, DIR_WRITE, FALSE); +#ifdef MT_MAC + + if (IS_HIF_TYPE(pAd, HIF_MT)) + MTMacInfoEndianChange(pAd, tmac_info, TYPE_TMACINFO, sizeof(TMAC_TXD_L)); + +#endif +#endif + return ret; +} + + +INT32 MT_ATEGenBurstPkt(RTMP_ADAPTER *pAd, UCHAR *buf, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UINT32 new_txlen, new_hlen; + UINT8 need_qos, need_amsdu, need_ampdu; + new_txlen = tx_time_param->pkt_tx_len; + new_hlen = tx_time_param->pkt_hdr_len; + need_qos = tx_time_param->pkt_need_qos; + need_amsdu = tx_time_param->pkt_need_amsdu; + need_ampdu = tx_time_param->pkt_need_ampdu; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: new_txlen/new_hlen=%d/%d, qos/amsdu/ampdu=%d/%d/%d\n", + __func__, new_txlen, new_hlen, need_qos, need_amsdu, need_ampdu)); + + /* Update WTBL if necessary */ + if (need_ampdu) + mt_ate_wtbl_cfg(pAd, band_idx); + + /* Generate tx packet */ + if (need_ampdu) + ret = mt_ate_ampdu_frame(pAd, buf, band_idx); + else { + /* No aggregation, directly go with specific length and through ALTX queue */ + tx_time_param->pkt_ampdu_cnt = 1; + tx_time_param->pkt_msdu_len = new_txlen; + ret = mt_ate_non_ampdu_frame(pAd, buf, band_idx); + } + + return ret; +} + + +INT32 MT_ATEGenPkt(RTMP_ADAPTER *pAd, UCHAR *buf, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UCHAR *tmac_info, *pheader, *payload, *addr1, *addr2, *addr3, *template; + UINT32 txlen, hlen, pkt_tx_time; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->TXWISize; + + if (!buf) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: NULL buf, band_idx:%u\n", __func__, band_idx)); + return NDIS_STATUS_FAILURE; + } + + /* For long packet implemetation */ + tx_time_param->pkt_tx_len = 0; + tx_time_param->pkt_hdr_len = 0; + tx_time_param->pkt_need_qos = 0; + tx_time_param->pkt_need_amsdu = 0; + tx_time_param->pkt_need_ampdu = 0; + tx_time_param->pkt_ampdu_cnt = 0; + pkt_tx_time = tx_time_param->pkt_tx_time; + + if (pkt_tx_time > 0) { + UINT8 need_qos = 0, need_amsdu = 0, need_ampdu = 0; + UINT32 new_txlen = mt_ate_get_txlen_by_pkt_tx_time(ATECtrl, band_idx); + UINT32 new_hlen; + txlen = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxLength); + hlen = TESTMODE_GET_PARAM(ATECtrl, band_idx, HLen); + + if (new_txlen > 0) + txlen = new_txlen; + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Can't get txlen by pkt tx time\n", __func__)); + } + + new_hlen = mt_ate_get_hlen_by_pkt_tx_time(ATECtrl, band_idx, txlen, &need_qos, &need_amsdu, &need_ampdu); + + if (new_hlen > 0) + hlen = new_hlen; + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Can't get hdrlen by pkt tx time\n", __func__)); + } + + tx_time_param->pkt_tx_len = new_txlen; + tx_time_param->pkt_hdr_len = hlen; + tx_time_param->pkt_need_qos = need_qos; + tx_time_param->pkt_need_amsdu = need_amsdu; + tx_time_param->pkt_need_ampdu = need_ampdu; + /* New packet generation function */ + ret = MT_ATEGenBurstPkt(pAd, buf, band_idx); + return ret; + } + + addr1 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr1); + addr2 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr2); + addr3 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Addr3); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(wcid:%d)::\tDA: %02x:%02x:%02x:%02x:%02x:%02x\n\tSA: %02x:%02x:%02x:%02x:%02x:%02x\n\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, ATECtrl->wcid_ref, PRINT_MAC(addr1), PRINT_MAC(addr2), PRINT_MAC(addr3))); + template = TESTMODE_GET_PARAM(ATECtrl, band_idx, TemplateFrame); + txlen = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxLength); + hlen = TESTMODE_GET_PARAM(ATECtrl, band_idx, HLen); + + /* Error check for txlen */ + if (txlen == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: TX length can't be 0!!\n", __func__)); + return NDIS_STATUS_FAILURE; + } + + tmac_info = buf; + pheader = (buf + tx_hw_hdr_len); + payload = (pheader + hlen); + NdisZeroMemory(buf, ATE_TESTPKT_LEN); +#ifdef TXBF_SUPPORT + { + UCHAR iTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, iTxBf); + UCHAR eTxBf = TESTMODE_GET_PARAM(ATECtrl, band_idx, eTxBf); + + /* Use wcid 1~4 */ + if (iTxBf || eTxBf) { + if ((ATECtrl->wcid_ref > ATE_BFMU_NUM) || (ATECtrl->wcid_ref < 1)) + ATECtrl->wcid_ref = ATE_BF_WCID; + + addr1 = ATECtrl->pfmu_info[ATECtrl->wcid_ref - 1].addr; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:: DA: %02x:%02x:%02x:%02x:%02x:%02x, wcid=%u\n", __func__, PRINT_MAC(addr1), ATECtrl->wcid_ref)); + } +#endif + NdisMoveMemory(pheader, template, hlen); + NdisMoveMemory(pheader + 4, addr1, MAC_ADDR_LEN); + NdisMoveMemory(pheader + 10, addr2, MAC_ADDR_LEN); + NdisMoveMemory(pheader + 16, addr3, MAC_ADDR_LEN); + ret = MtATEPayloadInit(pAd, payload, txlen - hlen, band_idx); +#if !defined(COMPOS_TESTMODE_WIN) + + if (ATECtrl->en_log & fATE_LOG_TXDUMP) { + INT i = 0; + PHEADER_802_11 hdr = (HEADER_802_11 *)pheader; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[TXCONTENT DUMP START]\n")); + dump_tmac_info(pAd, tmac_info); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[TXD RAW]: ")); + + for (i = 0; i < tx_hw_hdr_len; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%04x", tmac_info[i])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\nADDR1: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr1))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR2: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr2))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("ADDR3: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(hdr->Addr3))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("FC: %04x\n", *(UINT16 *)(&hdr->FC))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFrom DS: %x\n", hdr->FC.FrDs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tTo DS: %x\n", hdr->FC.ToDs)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[CONTENT RAW]: ")); + + for (i = 0; i < (txlen - hlen); i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%02x", payload[i])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n[TXCONTENT DUMP END]\n")); + } + +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + TESTMODE_SET_PARAM(ATECtrl, band_idx, is_alloc_skb, 0); +#ifdef RT_BIG_ENDIAN + RTMPFrameEndianChange(pAd, (PUCHAR)pheader, DIR_WRITE, FALSE); +#ifdef MT_MAC + + if (IS_HIF_TYPE(pAd, HIF_MT)) + MTMacInfoEndianChange(pAd, tmac_info, TYPE_TMACINFO, sizeof(TMAC_TXD_L)); + +#endif +#endif + return ret; +} + + +UINT32 mt_ate_mcs32_handle(RTMP_ADAPTER *pAd, UINT8 wcid_ref, UINT8 bw) +{ + INT32 ret = 0; + UINT32 DwMask = 0; +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + + if (IS_MT7615(pAd) || IS_MT7622(pAd) || IS_P18(pAd) || IS_MT7663(pAd)) { + union WTBL_DW5 wtbl_txcap; + DwMask = ~(3 << 12); /* only update fcap bit[13:12] */ + wtbl_txcap.field.fcap = bw; + /* WTBLDW5 */ + WtblDwSet(pAd, wcid_ref, 1, 5, DwMask, wtbl_txcap.word); + return ret; + } + +#else + { + union WTBL_2_DW9 wtbl_txcap; + DwMask = ~(3 << 14); /* only update fcap bit[15:14] */ + wtbl_txcap.field.fcap = bw; + /* WTBL2DW9 */ + WtblDwSet(pAd, wcid_ref, 2, 9, DwMask, wtbl_txcap.word); + } +#endif + return ret; +} + + +#if !defined(COMPOS_TESTMODE_WIN) /* 1todo too many OS private functio */ +INT32 MT_ATETxPkt(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + PNDIS_PACKET pkt; + INT32 ret = 0; + PACKET_INFO PacketInfo; + UCHAR *pSrcBufVA; + UINT SrcBufLen; + PNDIS_PACKET *pkt_skb = NULL; + UCHAR *pate_pkt = TESTMODE_GET_PARAM(ATECtrl, band_idx, pate_pkt); + UINT32 txlen = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxLength); + UINT32 tx_cnt = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxCount); + UINT32 txdone_cnt = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxDoneCount); + USHORT qid = TESTMODE_GET_PARAM(ATECtrl, band_idx, QID); + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->TXWISize; + UCHAR wdev_idx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wdev_idx); + struct wifi_dev *wdev = wdev_search_by_idx(pAd, wdev_idx); + UINT32 pkt_tx_time = tx_time_param->pkt_tx_time; + UINT8 need_ampdu = tx_time_param->pkt_need_ampdu; + struct sk_buff *skb = NULL; + struct sk_buff *skb2 = NULL; + int alloced; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: band_idx:%u, tx_cnt:%u, txdone_cnt:%u, pate_pkt:%p, ring Idx:%u\n", + __func__, band_idx, tx_cnt, txdone_cnt, pate_pkt, qid)); + + if (!pate_pkt) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: invalid pate_pkt(%p)\n", __func__, pate_pkt)); + goto done; + } + + if (band_idx == 0) + pkt_skb = &ATECtrl->pkt_skb; + +#ifdef DBDC_MODE + else if (IS_ATE_DBDC(pAd) && band_idx == 1) + pkt_skb = &ATECtrl->band_ext[band_idx - 1].pkt_skb; +#endif /* DBDC_MODE */ + alloced = TESTMODE_GET_PARAM(ATECtrl, band_idx, is_alloc_skb); + + if (!alloced) { + if (*pkt_skb) + RELEASE_NDIS_PACKET(pAd, *pkt_skb, NDIS_STATUS_SUCCESS); + + if (pkt_tx_time > 0) + txlen = tx_time_param->pkt_msdu_len; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: Alloc pkt, txlen=%d, tx_hw_hdr_len=%d, total=%d\n", __func__, txlen, tx_hw_hdr_len, txlen + tx_hw_hdr_len)); + ret = RTMPAllocateNdisPacket(pAd, pkt_skb, NULL, 0, pate_pkt, txlen + tx_hw_hdr_len); + + if (ret != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: AllocateNdisPacket fail\n", __func__)); + goto done; + } + + TESTMODE_SET_PARAM(ATECtrl, band_idx, is_alloc_skb, 1); + } + + skb = (struct sk_buff *)(*pkt_skb); + OS_PKT_CLONE(pAd, skb, skb2, GFP_ATOMIC); + + if (skb2 == NULL) { + RELEASE_NDIS_PACKET(pAd, *pkt_skb, NDIS_STATUS_SUCCESS); + pkt_skb = NULL; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: clone pakcet fail\n", __func__)); + goto done; + } + + pkt = (PNDIS_PACKET)skb2; + RTMP_SET_PACKET_WDEV(pkt, wdev_idx); + + if (pkt_tx_time > 0) { + UINT8 wcid = ATECtrl->wcid_ref; + RTMP_SET_PACKET_WCID(pkt, wcid); + } + + RTMP_QueryPacketInfo(pkt, &PacketInfo, &pSrcBufVA, &SrcBufLen); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:: allocate pkt, wdev_idx=%d, q_idx:%x, pkt_va:%p, VA:%p, Len:%u\n", + __func__, wdev_idx, qid, pkt, pSrcBufVA, SrcBufLen)); + /* Set the packet type to ATE frame before enqueue packet */ + RTMP_SET_PACKET_TXTYPE(pkt, TX_ATE_FRAME); + + if ((pkt_tx_time > 0) && (need_ampdu)) { + RTMP_SET_PACKET_TYPE(pkt, TX_DATA); + RTMP_SET_PACKET_QUEIDX(pkt, QID_AC_BE); + } else { + RTMP_SET_PACKET_TYPE(pkt, TX_MGMT); + RTMP_SET_PACKET_QUEIDX(pkt, 0); + } + + ret = send_mlme_pkt(pAd, pkt, wdev, qid, FALSE); +done: + return ret; +} + + +static UINT32 MT_ATEGetBandIdx(RTMP_ADAPTER *pAd, PNDIS_PACKET pkt) +{ + UINT32 band_idx = 0; + UCHAR wdev_idx = 0; + struct wifi_dev *wdev = NULL; + + wdev_idx = RTMP_GET_PACKET_WDEV(pkt); + + if (wdev_idx >= WDEV_NUM_MAX) + goto err0; + + wdev = pAd->wdev_list[wdev_idx]; + + if (!wdev) + goto err0; + + band_idx = HcGetBandByChannel(pAd, wdev->channel); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: wdev_idx:%x\n", __func__, wdev_idx)); + return band_idx; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: cannot find wdev by idx:%x\n", __func__, wdev_idx)); + return -1; +} + + +INT32 MT_ATETxControl(RTMP_ADAPTER *pAd, UINT32 band_idx, PNDIS_PACKET pkt) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 txdone_cnt = 0, tx_cnt = 0, mode = 0; + + if (ATECtrl->verify_mode == ATE_LOOPBACK) { + if (pAd->LbCtrl.LoopBackWaitRx) { +#ifdef RTMP_PCI_SUPPORT + + if (IS_PCI_INF(pAd)) + RTMP_OS_COMPLETE(&pAd->LbCtrl.LoopBackPCITxEvent); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Not supported in this interface yet\n")); + } + +#else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Not supported in this interface yet\n")); +#endif + } + } else if (ATECtrl->verify_mode == HQA_VERIFY) { + /* Need to get band_idx first if free token done */ + if (pkt) + band_idx = MT_ATEGetBandIdx(pAd, pkt); + + if (band_idx == -1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong band_idx %u\n", __func__, band_idx)); + goto done; + } + + txdone_cnt = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxDoneCount); + tx_cnt = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxCount); + mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, Mode); + + /* Do not count in packet number when TX is not in start stage */ + if (!(mode & ATE_TXFRAME)) + return ret; + + /* Triggered when RX tasklet free token */ + if (pkt) { + pAd->RalinkCounters.KickTxCount++; + txdone_cnt++; + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxDoneCount, txdone_cnt); + } + +#ifdef ATE_TXTHREAD + TESTMODEThreadProceedTx(pAd, band_idx); +#else + + if ((mode & ATE_TXFRAME) && (txdone_cnt < tx_cnt)) + ret = MT_ATETxPkt(pAd, band_idx); + else if ((mode & ATE_TXFRAME) && + (txdone_cnt == tx_cnt)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("All Tx is done\n")); + + if (mode & fATE_MPS) { + RTMP_OS_COMPLETION *tx_wait = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_wait); + RTMP_OS_COMPLETE(tx_wait); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Finish one MPS Item\n")); + } + + /* Tx status enters idle mode */ + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxStatus, 0); + } else if (!(mode & ATE_TXFRAME)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Stop TX bottom is pressed\n")); + + if (mode & fATE_MPS) { + RTMP_OS_COMPLETION *tx_wait = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_wait); + mode &= ~fATE_MPS; + TESTMODE_SET_PARAM(ATECtrl, band_idx, Mode, mode); + RTMP_OS_COMPLETE(tx_wait); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MPS STOP\n")); + } + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("ATE:: DO NOT match any condition, Mode:0x%x, TxCnt:%u, TxDone:%u\n", mode, tx_cnt, txdone_cnt)); + } + + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxDoneCount, txdone_cnt); +#endif + } + +done: + return ret; +} + + +static INT32 mt_ate_calculate_duty_cycle(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, ipg_param); + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, tx_time_param); + UINT32 ipg, pkt_tx_time, duty_cycle; + ipg = ipg_param->ipg; + pkt_tx_time = tx_time_param->pkt_tx_time; + duty_cycle = TESTMODE_GET_PARAM(ATECtrl, band_idx, duty_cycle); + + /* Calculate needed ipg/pkt_tx_time and duty_cycle */ + if ((duty_cycle > 0) && (pkt_tx_time == 0) && (ipg == 0)) { + /* TODO: need to consider this case in the future */ + duty_cycle = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: There are no pkt_tx_time/ipg!!\n" + "%s: Use default transmission setting and set duty_cycle=%d\n", + __func__, __func__, duty_cycle)); + } else if ((duty_cycle > 0) && (pkt_tx_time > 0) && (ipg == 0)) { + ipg = ((pkt_tx_time * 100) / duty_cycle) - pkt_tx_time; + ipg_param->ipg = ipg; + /* If IPG value is not make sense, there's error handle when get ipg parameter */ + ret = ATEOp->SetIPG(pAd); + } else if ((duty_cycle > 0) && (pkt_tx_time == 0) && (ipg > 0)) { + /* If pkt_tx_time is not make sense, there's error handle when start TX */ + pkt_tx_time = (duty_cycle * ipg) / (100 - duty_cycle); + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Already existed pkt_tx_time/ipg, can't set duty_cycle!!\n" + "%s: Expected duty_cycle=%d%%\n", __func__, __func__, duty_cycle)); + duty_cycle = (pkt_tx_time * 100) / (pkt_tx_time + ipg); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Real duty_cycle=%d%%\n", __func__, duty_cycle)); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: duty_cycle=%d%%, ipg=%dus, pkt_tx_time=%dus\n", + __func__, duty_cycle, ipg, pkt_tx_time)); + tx_time_param->pkt_tx_time = pkt_tx_time; + TESTMODE_SET_PARAM(ATECtrl, band_idx, duty_cycle, duty_cycle); + return ret; +} + + +static UINT16 mt_ate_set_ifs_cr(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, ipg_param); + UINT16 slot_time, sifs_time; + UINT32 txv_time = 0, i2t_chk_time = 0, tr2t_chk_time = 0; + UINT32 value = 0; + slot_time = ipg_param->slot_time; + sifs_time = ipg_param->sifs_time; + /* in uint of ns */ + MAC_IO_READ32(pAd, TMAC_ATCR, &txv_time); + txv_time *= NORMAL_CLOCK_TIME; + i2t_chk_time = (UINT32)(slot_time * 1000) - txv_time - BBP_PROCESSING_TIME; + tr2t_chk_time = (UINT32)(sifs_time * 1000) - txv_time - BBP_PROCESSING_TIME; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: txv_time=%dns, i2t_chk_time=%dns, tr2t_chk_time=%dns\n", + __func__, txv_time, i2t_chk_time, tr2t_chk_time)); + i2t_chk_time /= NORMAL_CLOCK_TIME; + tr2t_chk_time /= NORMAL_CLOCK_TIME; + + if (band_idx == TESTMODE_BAND0) { + MAC_IO_READ32(pAd, TMAC_TRCR0, &value); + value = (value & 0xFE00FE00) + | ((i2t_chk_time & 0x1FF) << 16) + | ((tr2t_chk_time & 0x1FF) << 0); + MAC_IO_WRITE32(pAd, TMAC_TRCR0, value); + } else if (band_idx == TESTMODE_BAND1) { + MAC_IO_READ32(pAd, TMAC_TRCR1, &value); + value = (value & 0xFE00FE00) + | ((i2t_chk_time & 0x1FF) << 16) + | ((tr2t_chk_time & 0x1FF) << 0); + MAC_IO_WRITE32(pAd, TMAC_TRCR1, value); + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Invalid band_idx!!\n", __func__)); + return FALSE; + } + + return ret; +} + + +static INT32 mt_ate_set_wmm_param_by_qid(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, ipg_param); + INT wdev_idx = 0; + UCHAR WmmIdx = 0xFF; + USHORT qid; + UINT16 slot_time, sifs_time, cw; + UINT8 ac_num, aifsn; +#if !defined(COMPOS_TESTMODE_WIN) + struct wifi_dev *pWdev = NULL; + wdev_idx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wdev_idx); + pWdev = pAd->wdev_list[wdev_idx]; + + if (pWdev) { + WmmIdx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wmm_idx); + + if (WmmIdx > 3) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: wdev_idx=%d, invalid WmmIdx=%d, reset to 0!\n", __func__, wdev_idx, WmmIdx)); + WmmIdx = 0xFF; + } + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Invalid WDEV, reset WmmIdx to 0!\n", __func__)); + WmmIdx = 0xFF; + } + +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: wdev_idx=%d, WmmIdx=%d\n", __func__, wdev_idx, WmmIdx)); + qid = TESTMODE_GET_PARAM(ATECtrl, band_idx, QID); + + if ((qid != QID_AC_BE) && (qid != TxQ_IDX_ALTX0) && (qid != TxQ_IDX_ALTX1)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Impossible!\n", __func__)); + return FALSE; + } + + slot_time = ipg_param->slot_time; + sifs_time = ipg_param->sifs_time; + ac_num = qid; + aifsn = ipg_param->aifsn; + cw = ipg_param->cw; + ret = MtAsicSetWmmParam(pAd, WmmIdx, (UINT32)ac_num, WMM_PARAM_AIFSN, (UINT32)aifsn); + ret = MtAsicSetWmmParam(pAd, WmmIdx, (UINT32)ac_num, WMM_PARAM_CWMIN, (UINT32)cw); + ret = MtAsicSetWmmParam(pAd, WmmIdx, (UINT32)ac_num, WMM_PARAM_CWMAX, (UINT32)cw); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: qid=%d, slot_time=%d, sifs_time=%d, ac_num=%d, aifsn=%d, cw=%d\n", + __func__, qid, slot_time, sifs_time, ac_num, aifsn, cw)); + return ret; +} + + +static INT32 mt_ate_apply_ipg_param(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ATECtrl, band_idx, ipg_param); + UINT32 ipg; + UINT16 slot_time, sifs_time, cw; + UINT8 aifsn; + ipg = ipg_param->ipg; + + if (ipg > 0) { + /* Get packet qIdx and decide which CR set need to be changed */ + slot_time = ipg_param->slot_time; + sifs_time = ipg_param->sifs_time; + aifsn = ipg_param->aifsn; + cw = ipg_param->cw; + } else { + /* Write default value back to HW */ + slot_time = DEFAULT_SLOT_TIME; + sifs_time = DEFAULT_SIFS_TIME; + aifsn = MIN_AIFSN; + cw = 0; + } + + ipg_param->slot_time = slot_time; + ipg_param->sifs_time = sifs_time; + ipg_param->aifsn = aifsn; + ipg_param->cw = cw; + ret = mt_ate_set_ifs_cr(pAd, band_idx); +#ifdef CONFIG_HW_HAL_OFFLOAD + ret = MtCmdATESetSlotTime(pAd, (UINT8)slot_time, (UINT8)sifs_time, RIFS_TIME, EIFS_TIME, (UINT8)band_idx); +#endif + ret = mt_ate_set_wmm_param_by_qid(pAd, band_idx); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ipg=%d, slot_time=%d, sifs_time=%d, aifsn=%d, cw=%d\n", + __func__, ipg, slot_time, sifs_time, aifsn, cw)); + return ret; +} + +BOOLEAN mt_ate_fill_offload_tx_blk(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + PACKET_INFO PacketInfo; + PNDIS_PACKET pPacket; + + pPacket = pTxBlk->pPacket; + pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + + if (RTMP_GET_PACKET_MGMT_PKT(pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_CT_WithTxD); + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); + + if (IS_ASIC_CAP(pAd, fASIC_CAP_TX_HDR_TRANS)) { + if ((pTxBlk->TxFrameType == TX_LEGACY_FRAME) || (pTxBlk->TxFrameType == TX_AMSDU_FRAME) || (pTxBlk->TxFrameType == TX_MCAST_FRAME)) + TX_BLK_SET_FLAG(pTxBlk, fTX_HDR_TRANS); + } + + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader; + return TRUE; +} + +INT32 mt_ate_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *tx_blk) +{ + INT32 ret = 0; + UINT32 band_idx = HcGetBandByWdev(wdev); + TMAC_INFO tmac_info; + PQUEUE_ENTRY q_entry; + RTMP_ARCH_OP *arch_ops = &pAd->archOps; + + q_entry = RemoveHeadQueue(&tx_blk->TxPacketList); + tx_blk->pPacket = QUEUE_ENTRY_TO_PACKET(q_entry); + RTMP_SET_PACKET_WCID(tx_blk->pPacket, 0); + + /* Fill TX blk for ATE mode */ + ret = mt_ate_fill_offload_tx_blk(pAd, wdev, tx_blk); + + /* TMAC_INFO setup for ATE mode */ + ret = mt_ate_set_tmac_info(pAd, &tmac_info, band_idx); + + if (ret) + return ret; + + return arch_ops->ate_hw_tx(pAd, &tmac_info, tx_blk); +} + + +#endif + + +#if !defined(COMPOS_TESTMODE_WIN) /* 1todo too many OS private function */ +static INT32 MT_ATEStartTx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; + UCHAR cntrol_band_idx = ATECtrl->control_band_idx; + UCHAR *pate_pkt = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, pate_pkt); + UCHAR cntl_ch = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, ControlChl); + UCHAR ch = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, Channel); + UINT32 mode = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, Mode); + UINT32 tx_cnt = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, TxCount); + UCHAR bw = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, BW); + INT8 wdev_idx = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, wdev_idx); + UINT32 Rate = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, Mcs); + UINT32 duty_cycle = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, duty_cycle); +#ifdef ARBITRARY_CCK_OFDM_TX + UINT32 tx_sel = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, TxAntennaSel); + UINT8 phymode = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, PhyMode); +#endif +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; +#endif + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: cntrol_band_idx:%u, ch:%x, cntl_ch:%x, wdev_idx:%x\n", + __func__, cntrol_band_idx, ch, cntl_ch, wdev_idx)); + + if (!pate_pkt) + goto err0; + + /* TxRx swtich Recover */ + + if (mode & ATE_TXFRAME) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: already in TXFRAME mode now, tx is on-going!\n", __func__)); + goto err1; + } + + MtATESetMacTxRx(pAd, ASIC_MAC_TX, TRUE, cntrol_band_idx); +#ifdef ARBITRARY_CCK_OFDM_TX + if (IS_MT7615(pAd)) { + MtATEInitCCK_OFDM_Path(pAd, cntrol_band_idx); + + if (phymode == MODE_CCK || phymode == MODE_OFDM) + MtATESetCCK_OFDM_Path(pAd, tx_sel, cntrol_band_idx); + } +#endif + + if (Rate == 32) + mt_ate_mcs32_handle(pAd, ATECtrl->wcid_ref, bw); + + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE, cntrol_band_idx); + msleep(30); + /* Stop send TX packets from upper layer */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* The first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + /* Disable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX, 0); + + /* Polling TX/RX path until packets empty */ + if (if_ops->clean_trx_q) + if_ops->clean_trx_q(pAd); + + if (mode & ATE_RXFRAME) + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, TRUE, cntrol_band_idx); + + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + /* Enable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 1); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + /* Calculate duty_cycle related parameter first */ + if (duty_cycle > 0) + Ret = mt_ate_calculate_duty_cycle(pAd, cntrol_band_idx); + + /* Prepare Tx packet */ + if (if_ops->setup_frame) + Ret = if_ops->setup_frame(pAd, QID_AC_BE); + else + Ret = MT_ATEGenPkt(pAd, pate_pkt, cntrol_band_idx); + + if (Ret) + goto err0; + + /* Apply IPG setting to HW */ + Ret = mt_ate_apply_ipg_param(pAd, cntrol_band_idx); + + if (tx_cnt != 0xFFFFFFFF) { +#ifndef ATE_TXTHREAD + tx_cnt += TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, TxDoneCount); +#endif + TESTMODE_SET_PARAM(ATECtrl, cntrol_band_idx, TxCount, tx_cnt); + } + + /* Tx Frame */ + mode |= ATE_TXFRAME; + TESTMODE_SET_PARAM(ATECtrl, cntrol_band_idx, Mode, mode); + + if (if_ops->test_frame_tx) + Ret = if_ops->test_frame_tx(pAd); + else { + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ATECtrl, cntrol_band_idx, ipg_param); + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, cntrol_band_idx, tx_time_param); + UINT32 ipg = ipg_param->ipg; + UINT32 pkt_tx_time = tx_time_param->pkt_tx_time; + + if ((pkt_tx_time > 0) || (ipg > 0)) { + PKT_TOKEN_CB *pktTokenCb = (PKT_TOKEN_CB *) pAd->PktTokenCb; + UINT32 pkt_cnt, input_cnt; + UINT32 ate_tx_cnt = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, TxCount); + UINT32 txed_cnt = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, TxedCount); + UINT32 pkt_ampdu_cnt = tx_time_param->pkt_ampdu_cnt; + UINT32 pkt_enqueue_cnt = pktTokenCb->pkt_tx_tkid_max / 2; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ate_tx_cnt=0x%x, pkt_ampdu_cnt=%d, pkt_enqueue_cnt=%d, pkt_tx_time=%d, ipg=%d\n", + __func__, ate_tx_cnt, pkt_ampdu_cnt, pkt_enqueue_cnt, pkt_tx_time, ipg)); + MtATESetMacTxRx(pAd, ASIC_MAC_TX, FALSE, cntrol_band_idx); + + if (ate_tx_cnt > pkt_ampdu_cnt) + input_cnt = ate_tx_cnt; + else + input_cnt = pkt_ampdu_cnt; + + input_cnt = input_cnt > pkt_enqueue_cnt ? pkt_enqueue_cnt : input_cnt; + + /* Enqueue packet in HW queue in advance */ + for (pkt_cnt = 0; pkt_cnt < input_cnt; pkt_cnt++) { + MT_ATETxPkt(pAd, cntrol_band_idx); + txed_cnt++; + } + + TESTMODE_SET_PARAM(ATECtrl, cntrol_band_idx, TxedCount, txed_cnt); + Ret = MT_ATETxControl(pAd, cntrol_band_idx, NULL); + MtATESetMacTxRx(pAd, ASIC_MAC_TX, TRUE, cntrol_band_idx); + } else + Ret = MT_ATETxControl(pAd, cntrol_band_idx, NULL); + } + + if (Ret) + goto err0; + + ATECtrl->did_tx = 1; +err1: + return Ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Err %d, wdev_idx:%x\n", __func__, Ret, wdev_idx)); + return Ret; +} + + +static INT32 MT_ATEStartRx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; + UCHAR cntrol_band_idx = ATECtrl->control_band_idx; + UINT32 mode = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, Mode); +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; +#endif + + if (mode & ATE_RXFRAME) + goto err0; + + /* Firmware offloading CR need to msleep(30) Currently for the second NETDEV_STOP_QUEUE */ + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE, cntrol_band_idx); + msleep(30); + /* Stop send TX packets */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + AsicSetWPDMA(pAd, PDMA_TX, 0); + + if (if_ops->clean_trx_q) + if_ops->clean_trx_q(pAd); + + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE(pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + /* Turn on TX again if set before */ + if (mode & ATE_TXFRAME) + MtATESetMacTxRx(pAd, ASIC_MAC_TX, TRUE, cntrol_band_idx); + + /* reset counter when iwpriv only */ + if (ATECtrl->bQAEnabled != TRUE) { + ATECtrl->rx_stat.RxTotalCnt[0] = 0; + + if (IS_ATE_DBDC(pAd)) + ATECtrl->rx_stat.RxTotalCnt[1] = 0; + } + + pAd->WlanCounters[0].FCSErrorCount.u.LowPart = 0; + /* Enable PDMA */ + AsicSetWPDMA(pAd, PDMA_TX_RX, 1); + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, TRUE, cntrol_band_idx); +#ifdef CONFIG_HW_HAL_OFFLOAD + MtCmdSetPhyCounter(pAd, 0, TESTMODE_BAND0); + MtCmdSetPhyCounter(pAd, 1, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) { + MtCmdSetPhyCounter(pAd, 0, TESTMODE_BAND1); + MtCmdSetPhyCounter(pAd, 1, TESTMODE_BAND1); + } + +#endif /* CONFIG_HW_HAL_OFFLOAD */ + msleep(30); + mode |= ATE_RXFRAME; + TESTMODE_SET_PARAM(ATECtrl, cntrol_band_idx, Mode, mode); + + if (if_ops->test_frame_rx) + if_ops->test_frame_rx(pAd); + + ATECtrl->did_rx = 1; +err0: + return Ret; +} + + +static INT32 MT_ATEStopTx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; +#ifdef ATE_TXTHREAD + INT32 thread_idx = 0; +#endif + UCHAR cntrol_band_idx = ATECtrl->control_band_idx; + UINT32 Mode = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, Mode); + struct qm_ops *ops = pAd->qm_ops; + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ATECtrl, cntrol_band_idx, ipg_param); + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, cntrol_band_idx, tx_time_param); + UINT32 ipg = ipg_param->ipg; + UINT32 pkt_tx_time = tx_time_param->pkt_tx_time; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: cntrol_band_idx=%u\n", __func__, cntrol_band_idx)); + + TESTMODE_SET_PARAM(ATECtrl, cntrol_band_idx, TxedCount, 0); +#ifdef ATE_TXTHREAD + TESTMODEThreadStopTx(pAd, thread_idx); +#endif + + if ((Mode & ATE_TXFRAME) || (Mode == ATE_STOP)) { + Mode &= ~ATE_TXFRAME; + TESTMODE_SET_PARAM(ATECtrl, cntrol_band_idx, Mode, Mode); + + if ((pkt_tx_time > 0) || (ipg > 0)) { + /* Flush SW queue */ + if (ops->sta_clean_queue) + ops->sta_clean_queue(pAd, WCID_ALL); + + /* Clean per sta TX queue and disable STA pause CRs for transmitting packet */ + MtATESetCleanPerStaTxQueue(pAd, FALSE); + } +#ifdef ARBITRARY_CCK_OFDM_TX + if (IS_MT7615(pAd)) { + MtATEInitCCK_OFDM_Path(pAd, cntrol_band_idx); + } +#endif + } + + return Ret; +} + + +static INT32 MT_ATEStopRx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; + UCHAR cntrol_band_idx = ATECtrl->control_band_idx; + UINT32 Mode = TESTMODE_GET_PARAM(ATECtrl, cntrol_band_idx, Mode); + + Ret = MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE, cntrol_band_idx); + Mode &= ~ATE_RXFRAME; + TESTMODE_SET_PARAM(ATECtrl, cntrol_band_idx, Mode, Mode); + + if (if_ops->clean_trx_q) + if_ops->clean_trx_q(pAd); + + return Ret; +} +#else +static INT32 MT_ATEStartTx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; +#ifdef COMPOS_TESTMODE_WIN + Ret = StartTx(pAd, 0, 0); +#endif + ATECtrl->did_tx = 1; + return Ret; +} + +static INT32 MT_ATEStartRx(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; +#ifdef COMPOS_TESTMODE_WIN + Ret = StartRx0(pAd); + Ret = StartRx1(pAd); +#endif + ATECtrl->did_rx = 1; + return Ret; +} + + +static INT32 MT_ATEStopTx(RTMP_ADAPTER *pAd, UINT32 Mode) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; +#ifdef COMPOS_TESTMODE_WIN + Ret = StopTx(pAd); +#endif + ATECtrl->Mode &= ~ATE_TXFRAME; + return Ret; +} + + +static INT32 MT_ATEStopRx(RTMP_ADAPTER *pAd) +{ + INT32 Ret = 0; +#ifdef COMPOS_TESTMODE_WIN + Ret = StopRx0(pAd); + Ret = StopRx1(pAd); +#endif + return Ret; +} +#endif + + +static INT32 MT_ATESetTxAntenna(RTMP_ADAPTER *pAd, UINT32 Ant) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Ant = 0x%x, control_band_idx = %d\n", + __func__, Ant, control_band_idx)); + + /* For TXD setting, change to stream number when ATE set channel (MtCmdSetTxRxPath) */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, TxAntennaSel, Ant); + +#if !defined(COMPOS_TESTMODE_WIN)/* 1 todo only 7603/7628 E1? */ +#endif + return Ret; +} + + +static INT32 MT_ATESetRxAntenna(RTMP_ADAPTER *pAd, UINT32 Ant) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Ant = 0x%x, control_band_idx = %d\n", + __func__, Ant, control_band_idx)); + + /* After mt7615 its 4 bit mask for Rx0,1,2,3 */ + /* Send to FW and take effect when ATE set channel (MtCmdSetTxRxPath) */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, RxAntennaSel, Ant); + + return Ret; +} + + +static INT32 MT_ATESetTxFreqOffset(RTMP_ADAPTER *pAd, UINT32 FreqOffset) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + ATECtrl->RFFreqOffset = FreqOffset; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = MtCmdSetFreqOffset(pAd, FreqOffset); +#else + + if ((IS_MT76x6(pAd)) && + !(ATECtrl->en_man_set_freq)) { + UINT32 reg = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MT76x6 Manual Set Freq bk ori val\n")); + MtTestModeBkCr(pAd, FREQ_OFFSET_MANUAL_ENABLE, TEST_HW_BKCR); + MtTestModeBkCr(pAd, FREQ_OFFSET_MANUAL_VALUE, TEST_HW_BKCR); + reg = (reg & 0xFFFF80FF) | (0x7F << 8); + HW_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_ENABLE, reg); + ATECtrl->en_man_set_freq = 1; + } + + if (ATECtrl->en_man_set_freq) { + UINT32 reg = 0; + HW_IO_READ32(pAd, FREQ_OFFSET_MANUAL_VALUE, ®); + reg = (reg & 0xFFFF80FF) | (ATECtrl->RFFreqOffset << 8); + HW_IO_WRITE32(pAd, FREQ_OFFSET_MANUAL_VALUE, reg); + } else + MtAsicSetRfFreqOffset(pAd, ATECtrl->RFFreqOffset); + +#endif + return Ret; +} + + +static INT32 MT_ATEGetTxFreqOffset(RTMP_ADAPTER *pAd, UINT32 *FreqOffset) +{ + INT32 Ret = 0; +#if defined(COMPOS_TESTMODE_WIN) + EXT_EVENT_ID_ATE_TEST_MODE_T *pResult = (EXT_EVENT_ID_ATE_TEST_MODE_T *)((UINT8 *) pAd->FWRspContent + sizeof(EVENT_RXD)); +#endif +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = MtCmdGetFreqOffset(pAd, FreqOffset); + os_msec_delay(30); +#if defined(COMPOS_TESTMODE_WIN) + *FreqOffset = OS_NTOHL(pResult->aucAteResult); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: FreqOffset:%X pResult->aucAteResult = %X\n", + __func__, *FreqOffset, pResult->aucAteResult)); +#endif +#endif + return Ret; +} + +static INT32 MT_ATESetChannel(RTMP_ADAPTER *pAd, + INT16 Value, UINT32 pri_sel, + UINT32 reason, + UINT32 Ch_Band) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR ctrl_ch = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR ch = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Channel); + UCHAR bw = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, BW); + UCHAR wdev_idx = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, wdev_idx); + UINT8 phymode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PhyMode); + UINT32 tx_sel = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + UINT32 rx_sel = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, RxAntennaSel); + UINT32 out_band_freq = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, OutBandFreq); + + /* Backup several parameters before TSSI calibration */ + UCHAR ucPerPktBW_backup; + UCHAR ucPhyMode_backup; + UCHAR ucMcs_backup; + UCHAR ucNss_backup; + UINT32 u4TxLength_backup; + +#ifdef TXBF_SUPPORT + UINT32 iTxBf = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, iTxBf); + UINT32 eTxBf = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, eTxBf); +#endif + INT i = 0; + UINT32 tx_stream_num = 0; + UINT32 max_stream_num = 0; + MT_SWITCH_CHANNEL_CFG ch_cfg; + INT32 ch_offset = 0; + const INT bw40_sel[] = { -2, 2}; +#ifdef DOT11_VHT_AC + const INT bw80_sel[] = { -6, -2, 2, 6}; + const INT bw160_sel[] = { -14, -10, -6, -2, 2, 6, 10, 14}; + UCHAR ch2 = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Channel_2nd); +#endif + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); +#if !defined(COMPOS_TESTMODE_WIN) + struct wifi_dev *pWdev = NULL; + + /* To update wdev setting according to ch_band */ + pWdev = pAd->wdev_list[wdev_idx]; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: wdev_idx=%d, ch=%d\n", + __func__, wdev_idx, ch)); + + if (!pWdev) + goto err; + + pWdev->channel = ch; + + if (Ch_Band == 0) + pWdev->PhyMode = PHYMODE_CAP_24G; + else if (Ch_Band == 1) + pWdev->PhyMode = PHYMODE_CAP_5G; + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Error ch_band=%d!!\n", __func__, Ch_Band)); + return -1; + } + + Ret = wdev_attr_update(pAd, pWdev); +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + + if (IS_ATE_DBDC(pAd)) + max_stream_num = cap->max_nss / 2 ? cap->max_nss / 2 : 1; + else + max_stream_num = cap->max_nss; + + /* 0: 20M; 1: 40M; 2: 80M; 3: 160M; 4: 10M; 5: 5M; 6: 80+80MHz */ + switch (bw) { + case BW_40: + if (pri_sel >= 2) + goto err0; + + ctrl_ch = ch + bw40_sel[pri_sel]; + ch_offset = bw40_sel[pri_sel]; + + if ((INT32)(ch + ch_offset) <= 0 || (INT32)(ch - ch_offset) <= 0) + goto err1; + + break; +#ifdef DOT11_VHT_AC + + case BW_8080: + if (pri_sel >= 8) + goto err0; + + if ((ch2 < ch) && ch2) { + UCHAR tmp = ch; + ch = ch2; + ch2 = tmp; + } + + if (pri_sel < 4) { + ctrl_ch = ch + bw80_sel[pri_sel]; + ch_offset = bw80_sel[pri_sel]; + + if ((INT32)(ch + ch_offset) <= 0 || (INT32)(ch - ch_offset) <= 0) + goto err1; + } else { + ctrl_ch = ch2 + bw80_sel[pri_sel - 4]; + ch_offset = bw80_sel[pri_sel - 4]; + + if ((INT32)(ch2 + ch_offset) <= 0 || (INT32)(ch2 - ch_offset) <= 0) + goto err1; + } + + break; + + case BW_80: + if (pri_sel >= 4) + goto err0; + + ctrl_ch = ch + bw80_sel[pri_sel]; + ch_offset = bw80_sel[pri_sel]; + + if ((INT32)(ch + ch_offset) <= 0 || (INT32)(ch - ch_offset) <= 0) + goto err1; + + break; + + case BW_160: + if (pri_sel >= 8) + goto err0; + + ctrl_ch = ch + bw160_sel[pri_sel]; + ch_offset = bw160_sel[pri_sel]; + + if ((INT32)(ch + ch_offset) <= 0 || (INT32)(ch - ch_offset) <= 0) + goto err1; + + break; +#endif + + case BW_20: + default: + ctrl_ch = ch; + break; + } + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, ControlChl, ctrl_ch); + NdisZeroMemory(&ch_cfg, sizeof(ch_cfg)); + ch_cfg.ControlChannel = ctrl_ch; + ch_cfg.CentralChannel = ch; + ch_cfg.Bw = bw; +#ifdef DOT11_VHT_AC + if (ch_cfg.Bw == BW_8080) + ch_cfg.ControlChannel2 = ch2; + +#endif + + switch (phymode) { + case MODE_CCK: + case MODE_OFDM: +#ifdef ARBITRARY_CCK_OFDM_TX + if (IS_MT7615(pAd)) { + tx_stream_num = max_stream_num; + } else +#endif + { + /* To get TX max stream number from TX antenna bit mask + tx_sel=2 -> tx_stream_num=2 + tx_sel=4 -> tx_stream_num=3 + tx_sel=8 -> tx_stream_num=4 + */ + for (i = max_stream_num; i > 0; i--) { + if (tx_sel & BIT(i-1)) { + tx_stream_num = i; + break; + } + } + } + break; + + case MODE_HTMIX: + case MODE_HTGREENFIELD: + case MODE_VHT: +#ifdef TXBF_SUPPORT + if (iTxBf || eTxBf) { + for (i = 0; i < 4; i++) { + if (tx_sel & (1 << i)) + tx_stream_num++; + else + break; + } + } else + tx_stream_num = max_stream_num; + +#else + tx_stream_num = max_stream_num; +#endif + break; + + default: + tx_stream_num = max_stream_num; + } + + /* Set Rx ant 2/3 for band1 */ + if (control_band_idx) + rx_sel = rx_sel << 2; + + tx_stream_num = tx_stream_num ? tx_stream_num : 1; + tx_stream_num = tx_stream_num <= max_stream_num ? tx_stream_num : max_stream_num; + + /* What FW needs is Tx stream num and Rx antenna path */ + ch_cfg.TxStream = tx_stream_num; + ch_cfg.RxStream = rx_sel; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: T/Rx_sel:%x/%x, Tx Stream:%x, phymode:%x\n", + __func__, tx_sel, rx_sel, tx_stream_num, phymode)); + +#if defined(COMPOS_TESTMODE_WIN) + switch (reason) { + case CH_SWITCH_SCAN: + ch_cfg.bScan = TRUE; + ch_cfg.isMCC = FALSE; + break; + + case CH_SWITCH_INTERNAL_USED_BY_FW_3: + /* MCC */ + ch_cfg.bScan = FALSE; + ch_cfg.isMCC = TRUE; + break; + + case CH_SWITCH_BY_NORMAL_TX_RX: + deafult: + ch_cfg.bScan = FALSE; + ch_cfg.isMCC = FALSE; + break; + } /* switch(reason) */ + +#else + ch_cfg.bScan = FALSE; +#endif + ch_cfg.BandIdx = control_band_idx; + ch_cfg.Channel_Band = Ch_Band; + ch_cfg.OutBandFreq = out_band_freq; + +#ifdef MT7615 +#ifdef PRE_CAL_TRX_SET1_SUPPORT + mt7615_apply_cal_data(pAd, ch_cfg); +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ +#endif + + /* Align normal mode set channel flow */ + MtCmdChannelSwitch(pAd, ch_cfg); + /* MtCmdSetTxRxPath will configure TX/RX CR setting by FW */ + MtCmdSetTxRxPath(pAd, ch_cfg); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx:%u, bw:%x, ch:%u, ctrl_ch:%u, cntl_ch2:%u, pri_sel:%x\n", + __func__, control_band_idx, bw, ch, ctrl_ch, ch_cfg.ControlChannel2, pri_sel)); + + ucPerPktBW_backup = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PerPktBW); + ucPhyMode_backup = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PhyMode); + ucMcs_backup = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mcs); + ucNss_backup = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Nss); + u4TxLength_backup = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxLength); + + /* 160C/160NC TSSI workaround */ + Ret = MtATETssiTrainingProc(pAd, ch_cfg.Bw, control_band_idx); + + /* Recovery several parameter after TSSI calibration */ + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, PerPktBW, ucPerPktBW_backup); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, PhyMode, ucPhyMode_backup); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mcs, ucMcs_backup); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Nss, ucNss_backup); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, TxLength, u4TxLength_backup); + +#ifdef SINGLE_SKU_V2 +#ifdef TXBF_SUPPORT +#ifdef MT_MAC +#if defined(MT7615) || defined(MT7622) + TxPowerBfBackoffParaCtrl(pAd, ch_cfg.Channel_Band, ch_cfg.ControlChannel, ch_cfg.BandIdx); +#else +#endif /* defined(MT7615) || defined(MT7622) */ +#endif /*MT_MAC*/ +#endif /*TXBF_SUPPORT*/ +#endif /*SINGLE_SKU_V2*/ + return Ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Invalid pri_sel:%x, Set Channel Fail\n", __func__, pri_sel)); +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Invalid Control Channel:%u|%u, Set Channel Fail\n", __func__, ctrl_ch, ch - ch_offset)); +#if !defined(COMPOS_TESTMODE_WIN) +err: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Cannot get Wdev by idx:%d\n", __func__, wdev_idx)); +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + return -1; +} + + +static INT32 MT_ATESetBW(RTMP_ADAPTER *pAd, UINT16 system_bw, UINT16 per_pkt_bw) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + if (per_pkt_bw == BW_NUM) { + if (system_bw == BW_8080) + per_pkt_bw = BW_160; + else + per_pkt_bw = system_bw; + } else { + if (per_pkt_bw > system_bw) + per_pkt_bw = system_bw; + } + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, BW, system_bw); + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, PerPktBW, per_pkt_bw); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: System BW=%d, Per Packet BW=%d, control_band_idx=%d\n", + __func__, system_bw, per_pkt_bw, control_band_idx)); + return Ret; +} + + +static INT32 mt_ate_set_duty_cycle(RTMP_ADAPTER *pAd, UINT32 value) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + UINT32 duty_cycle = value; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, duty_cycle, duty_cycle); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Duty cycle=%d%%, control_band_idx=%d\n", + __func__, duty_cycle, control_band_idx)); + return ret; +} + + +static INT32 mt_ate_set_pkt_tx_time(RTMP_ADAPTER *pAd, UINT32 value) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + struct _ATE_TX_TIME_PARAM *tx_time_param = TESTMODE_GET_PADDR(ATECtrl, control_band_idx, tx_time_param); + + tx_time_param->pkt_tx_time = value; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Pkt Tx time=%dus, control_band_idx=%d\n", + __func__, tx_time_param->pkt_tx_time, control_band_idx)); + return ret; +} + + +#if !defined(COMPOS_TESTMODE_WIN)/* 1 todo RX_BLK */ +static INT32 MT_ATESampleRssi(RTMP_ADAPTER *pAd, RX_BLK *RxBlk) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_RX_STATISTIC *rx_stat = + &ATECtrl->rx_stat; + INT32 Ret = 0; + INT i = 0; + UINT32 ANT_NUM = pAd->Antenna.field.TxPath; + + for (i = 0; i < ANT_NUM; i++) { + if (RxBlk->rx_signal.raw_rssi[i] != 0) { + rx_stat->LastRssi[i] = ConvertToRssi(pAd, (struct raw_rssi_info *)(&RxBlk->rx_signal.raw_rssi[i]), i); + + if (rx_stat->MaxRssi[i] < rx_stat->LastRssi[i]) + rx_stat->MaxRssi[i] = rx_stat->LastRssi[i]; + + if (rx_stat->MinRssi[i] > rx_stat->LastRssi[i]) + rx_stat->MinRssi[i] = rx_stat->LastRssi[i]; + + rx_stat->AvgRssiX8[i] = (rx_stat->AvgRssiX8[i] - rx_stat->AvgRssi[i]) + rx_stat->LastRssi[i]; + rx_stat->AvgRssi[i] = rx_stat->AvgRssiX8[i] >> 3; + } + + rx_stat->LastSNR[i] = RxBlk->rx_signal.raw_snr[i]; + } + + rx_stat->NumOfAvgRssiSample++; + return Ret; +} +#endif + + +static UINT8 sigext_time_list[] = { + 0, /* CCK */ + 6, /* OFDM */ + 6, /* HTMIX */ + 6, /* HTGREENFIELD */ + 6, /* VHT */ +}; +static UINT8 mt_ate_get_sigext_time_by_phymode(UCHAR phy_mode) +{ + UINT8 sigext_time = 0; + + switch (phy_mode) { + case MODE_CCK: + sigext_time = sigext_time_list[MODE_CCK]; + break; + + case MODE_OFDM: + sigext_time = sigext_time_list[MODE_OFDM]; + break; + + case MODE_HTMIX: + sigext_time = sigext_time_list[MODE_HTMIX]; + break; + + case MODE_HTGREENFIELD: + sigext_time = sigext_time_list[MODE_HTGREENFIELD]; + break; + + case MODE_VHT: + sigext_time = sigext_time_list[MODE_VHT]; + break; + + default: + sigext_time = sigext_time_list[MODE_OFDM]; + break; + } + + return sigext_time; +} + + +static UINT16 slot_time_list[] = { + 9, /* CCK */ + 9, /* OFDM */ + 9, /* HTMIX */ + 9, /* HTGREENFIELD */ + 9, /* VHT */ +}; +static UINT16 mt_ate_get_slot_time_by_phymode(UCHAR phy_mode) +{ + UINT16 slot_time = 0; + + switch (phy_mode) { + case MODE_CCK: + slot_time = slot_time_list[MODE_CCK]; + break; + + case MODE_OFDM: + slot_time = slot_time_list[MODE_OFDM]; + break; + + case MODE_HTMIX: + slot_time = slot_time_list[MODE_HTMIX]; + break; + + case MODE_HTGREENFIELD: + slot_time = slot_time_list[MODE_HTGREENFIELD]; + break; + + case MODE_VHT: + slot_time = slot_time_list[MODE_VHT]; + break; + + default: + slot_time = slot_time_list[MODE_OFDM]; + break; + } + + return slot_time; +} + + +static UINT16 mt_ate_get_cw(UINT32 ipg, UINT16 slot_time) +{ + INT cnt = 0, val; + val = (ipg + slot_time) / slot_time; + + while (val >>= 1) + cnt++; + + if (cnt >= MAX_CW) + cnt = MAX_CW; + + return cnt; +} + + +static INT32 mt_ate_get_ipg_param(RTMP_ADAPTER *pAd) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UCHAR control_band_idx = ATECtrl->control_band_idx; + struct _ATE_IPG_PARAM *ipg_param = TESTMODE_GET_PADDR(ATECtrl, control_band_idx, ipg_param); + UCHAR phy_mode; + UINT32 ipg, real_ipg; + UINT8 sig_ext, aifsn; + UINT16 slot_time, sifs_time, cw; + + phy_mode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PhyMode); + ipg = ipg_param->ipg; + sig_ext = mt_ate_get_sigext_time_by_phymode(phy_mode); + slot_time = mt_ate_get_slot_time_by_phymode(phy_mode); + sifs_time = DEFAULT_SIFS_TIME; + /* + * 1. ipg = sig_ext + sifs_time + slot_time + * 2. ipg = sig_ext + sifs_time + aifsn * slot_time + ((1 << cw) - 1) * slot_time + * If it's CCK mode, there's no need to consider sig_ext + * And it's no need to count in backoff time in older ATE driver design, configure SIFS/SLOT only + * Consider which ac queue will be used each case + */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Expected ipg=%d, control_band_idx=%d\n", + __func__, ipg, control_band_idx)); + + if (ipg < (sig_ext + sifs_time + slot_time)) { + UINT32 duty_cycle = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, duty_cycle); + + ipg_param->ipg = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Invalid IPG!! sig_ext=%d, slot_time=%d, sifs_time=%d\n" + "%s: Set ipg=%d\n", + __func__, sig_ext, slot_time, sifs_time, __func__, ipg)); + + if (duty_cycle > 0) { + duty_cycle = 0; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, duty_cycle, duty_cycle); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Invalid IPG with such duty_cycle and pkt_tx_time!!\n" + "%s: Set duty_cycle=%d\n", __func__, __func__, duty_cycle)); + } + + return ret; + } + + ipg -= sig_ext; + + if (ipg <= (MAX_SIFS_TIME + slot_time)) { + sifs_time = ipg - slot_time; + aifsn = MIN_AIFSN; + cw = 0; + } else { + cw = mt_ate_get_cw(ipg, slot_time); + ipg -= ((1 << cw) - 1) * slot_time; + aifsn = ipg / slot_time; + + if (aifsn >= MAX_AIFSN) + aifsn = MAX_AIFSN; + + ipg -= aifsn * slot_time; + + if (ipg <= DEFAULT_SIFS_TIME) + sifs_time = DEFAULT_SIFS_TIME; + else if ((ipg > DEFAULT_SIFS_TIME) && + (ipg <= MAX_SIFS_TIME)) + sifs_time = ipg; + else + sifs_time = MAX_SIFS_TIME; + } + + real_ipg = sig_ext + sifs_time + aifsn * slot_time + + ((1 << cw) - 1) * slot_time; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: sig_ext=%d, slot_time=%d, sifs_time=%d, aifsn=%d, cw=%d\n", + __func__, sig_ext, slot_time, sifs_time, aifsn, cw)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Real ipg=%d\n", __func__, real_ipg)); + ipg_param->sig_ext = sig_ext; + ipg_param->slot_time = slot_time; + ipg_param->sifs_time = sifs_time; + ipg_param->aifsn = aifsn; + ipg_param->cw = cw; + ipg_param->txop = 0; + return ret; +} + + +static INT32 mt_ate_set_ipg(RTMP_ADAPTER *pAd) +{ + INT32 ret = 0; + + ret = mt_ate_get_ipg_param(pAd); + return ret; +} + + +static INT32 mt_ate_set_slot_time(RTMP_ADAPTER *pAd, UINT32 SlotTime, UINT32 SifsTime) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: SlotTime:%d, SifsTime:%d, control_band_idx:%d\n", + __func__, + SlotTime, + SifsTime, + control_band_idx)); +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = MtCmdATESetSlotTime(pAd, (UINT8)SlotTime, (UINT8)SifsTime, RIFS_TIME, EIFS_TIME, control_band_idx); +#endif + return Ret; +} + + +static INT32 MT_ATESetAIFS(RTMP_ADAPTER *pAd, CHAR Value) +{ + INT32 Ret = 0; + UINT val = Value & 0x000000ff; + /* Test mode use AC0 for TX */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Value:%x\n", __func__, val)); + MtAsicSetWmmParam(pAd, 0, WMM_PARAM_AC_0, WMM_PARAM_AIFSN, val); + return Ret; +} + + +static INT32 MT_ATESetPowerDropLevel(RTMP_ADAPTER *pAd, UINT32 PowerDropLevel) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: PowerDropLevel:%d, control_band_idx:%d\n", + __func__, PowerDropLevel, control_band_idx)); +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = MtCmdATESetPowerDropLevel(pAd, (UINT8)PowerDropLevel, control_band_idx); +#endif /* CONFIG_HW_HAL_OFFLOAD */ + return Ret; +} + + +static INT32 MT_ATESetTSSI(RTMP_ADAPTER *pAd, CHAR WFSel, CHAR Setting) +{ + INT32 Ret = 0; + Ret = MtAsicSetTSSI(pAd, Setting, WFSel); + return Ret; +} + + +static INT32 MT_ATELowPower(RTMP_ADAPTER *pAd, UINT32 Control) +{ + INT32 Ret = 0; +#if !defined(COMPOS_TESTMODE_WIN) + + if (Control) + MlmeLpEnter(pAd); + else + MlmeLpExit(pAd); + +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + return Ret; +} + + +static INT32 MT_ATESetDPD(RTMP_ADAPTER *pAd, CHAR WFSel, CHAR Setting) +{ + /* !!TEST MODE ONLY!! Normal Mode control by FW and Never disable */ + /* WF0 = 0, WF1 = 1, WF ALL = 2 */ + INT32 Ret = 0; + Ret = MtAsicSetDPD(pAd, Setting, WFSel); + return Ret; +} + + +static INT32 MT_ATEStartTxTone(RTMP_ADAPTER *pAd, UINT32 Mode) +{ + INT32 Ret = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + +static INT32 MT_ATEDBDCTxTone(RTMP_ADAPTER *pAd, + UINT32 Control, + UINT32 AntIndex, + UINT32 ToneType, + UINT32 ToneFreq, + INT32 DcOffset_I, + INT32 DcOffset_Q, + UINT32 Band) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MtCmdTxTone(pAd, control_band_idx, Control, AntIndex, ToneType, ToneFreq, DcOffset_I, DcOffset_Q, Band); + return Ret; +} + +static INT32 MT_ATETxCWTone(RTMP_ADAPTER *pAd, UINT32 Control) +{ + INT32 Ret = 0; + UINT32 Channel = 0; + UINT32 AntMask = 0; + UINT32 AntIdx = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT8 band_idx = ATECtrl->control_band_idx; + UINT32 Band = 0; + INT32 pwr1 = 0, pwr2 = 0; + INT32 DcOffset_I = 0, DcOffset_Q = 0; + + if (band_idx == -1) + return -1; + + AntMask = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxAntennaSel); + Channel = TESTMODE_GET_PARAM(ATECtrl, band_idx, Channel); + pwr1 = TESTMODE_GET_PARAM(ATECtrl, band_idx, RF_Power); + pwr2 = TESTMODE_GET_PARAM(ATECtrl, band_idx, Digital_Power); + DcOffset_I = TESTMODE_GET_PARAM(ATECtrl, band_idx, DcOffset_I); + DcOffset_Q = TESTMODE_GET_PARAM(ATECtrl, band_idx, DcOffset_Q); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Control = %d Channel=%d AntMask=0x%x\n", + __FUNCTION__, Control, Channel, AntMask)); + + if (Channel <= 14) + Band = 2407000; + else + Band = 5000000; + + /* Set RF and Digital Gain */ + for (AntIdx = 0; AntIdx <= 3; AntIdx++) { + if (Control == 0) { + MtCmdTxTonePower(pAd, RF_AT_EXT_FUNCID_TX_TONE_RF_GAIN, 0, + AntIdx, band_idx); + MtCmdTxTonePower(pAd, RF_AT_EXT_FUNCID_TX_TONE_DIGITAL_GAIN, 0, + AntIdx, band_idx); + } else { + if (AntMask & BIT(AntIdx)) { + MtCmdTxTonePower(pAd, RF_AT_EXT_FUNCID_TX_TONE_RF_GAIN, pwr1, + AntIdx, band_idx); + MtCmdTxTonePower(pAd, RF_AT_EXT_FUNCID_TX_TONE_DIGITAL_GAIN, pwr2, + AntIdx, band_idx); + } + } + } + /* Send Command to firmware */ + MtCmdTxTone(pAd, band_idx, Control, AntMask, 0, 0, + (Control == 1) ? DcOffset_I : 0, + (Control == 1) ? DcOffset_Q : 0, + Band); + + /* Firmware currently ignores AntMask when starting Tx Tone, + * and starts TX Tone on all the antennas. Take care of the + * same in driver for now */ + if (Control == 1) { + for (AntIdx = 0; AntIdx <= 3; AntIdx++) { + if (!(AntMask & BIT(AntIdx))) { + UINT32 CRvalue = 0; + PHY_IO_READ32(pAd, 0x10610, &CRvalue); + PHY_IO_WRITE32(pAd, 0x10610, + CRvalue & ~BIT(16+AntIdx) & ~BIT(24+AntIdx)); + } + } + } + + return Ret; +} + +static INT32 MT_ATESetTxTonePower(RTMP_ADAPTER *pAd, INT32 pwr1, INT32 pwr2) +{ + INT32 Ret = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: pwr1:%d, pwr2:%d\n", __func__, pwr1, pwr2)); + return Ret; +} + +static INT32 MT_ATESetDBDCTxTonePower(RTMP_ADAPTER *pAd, INT32 pwr1, INT32 pwr2, UINT32 AntIdx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: pwr1:%d, pwr2:%d, AntIdx:%d, control_band_idx:%d\n", + __func__, pwr1, pwr2, AntIdx, control_band_idx)); + MtCmdTxTonePower(pAd, RF_AT_EXT_FUNCID_TX_TONE_RF_GAIN, pwr1, AntIdx, (UINT8)control_band_idx); + MtCmdTxTonePower(pAd, RF_AT_EXT_FUNCID_TX_TONE_DIGITAL_GAIN, pwr2, AntIdx, (UINT8)control_band_idx); + return Ret; +} + + +static INT32 MT_ATEStopTxTone(RTMP_ADAPTER *pAd) +{ + INT32 Ret = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + + +static INT32 MT_ATEStartContinousTx(RTMP_ADAPTER *pAd, CHAR WFSel, UINT32 TxfdMode) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 Phymode = 0, BW = 0, Pri_Ch = 0, Rate = 0, Central_Ch = 0, ant_sel = 0; + + Phymode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PhyMode); + BW = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, BW); + Pri_Ch = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, ControlChl); + Central_Ch = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Channel); + Rate = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mcs); + ant_sel = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + + if (BW == ATE_BAND_WIDTH_8080) + BW = 3; + + if (BW == ATE_BAND_WIDTH_160) + BW = 4; + + { + UINT32 Control = 1; + MtCmdTxContinous(pAd, Phymode, BW, Pri_Ch, Central_Ch, Rate, ant_sel, TxfdMode, control_band_idx, Control); + } + return Ret; +} + + +static INT32 MT_ATEStopContinousTx(RTMP_ADAPTER *pAd, UINT32 TxfdMode) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 Phymode = 0, BW = 0, Pri_Ch = 0, Rate = 0, Central_Ch = 0, ant_sel; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Phymode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PhyMode); + BW = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, BW); + Pri_Ch = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, ControlChl); + Central_Ch = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Channel); + Rate = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mcs); + ant_sel = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + { + UINT32 Control = 0; + Ret = MtCmdTxContinous(pAd, Phymode, BW, Pri_Ch, Central_Ch, Rate, ant_sel, TxfdMode, control_band_idx, Control); + } + return Ret; +} + + +static INT32 MT_OnOffRDD(struct _RTMP_ADAPTER *pAd, UINT32 rdd_idx, UINT32 rdd_in_sel, UINT32 is_start) +{ + INT32 Ret = 0; + BOOLEAN arb_rx_on = FALSE; + arb_rx_on = is_start ? TRUE : FALSE; + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, arb_rx_on, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, arb_rx_on, TESTMODE_BAND1); + + Ret = MtCmdSetRDDTestExt(pAd, rdd_idx, rdd_in_sel, is_start); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s ARB Rx On:%x\n", __func__, arb_rx_on)); + return Ret; +} + +#ifdef TXPWRMANUAL +static INT32 MT_ATESetTxPwrManual(RTMP_ADAPTER *pAd, BOOLEAN fgPwrManCtrl, UINT8 u1TxPwrModeManual, UINT8 u1TxPwrBwManual, UINT8 u1TxPwrRateManual, INT8 i1TxPwrValueManual, UCHAR Band) +{ + INT Ret = 0; + + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("-----------------------------------------------------------------------------\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Set wrong parameters\n", __func__)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" CCK (0) only supports rate setting: 0 ~ 3 and no supports different BW\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" OFDM (1) only supports rate setting: 0 ~ 7 and no supports different BW\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" HT20 (2) only supports rate setting: MCS 0 ~ 7 \n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" HT40 (2) only supports rate setting: MCS 0 ~ 8 \n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" VHT20 (3) only supports rate setting: 0 ~ 9\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" VHT40 (3) only supports rate setting: 0\n")); + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("-----------------------------------------------------------------------------\n")); + + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: fgPwrManCtrl:%d, u1TxPwrModeManual:%d, u1TxPwrBwManual:%d, u1TxPwrRateManual:%d, i1TxPwrValueManual:%d, Band:%d\n", + __func__, fgPwrManCtrl, u1TxPwrModeManual, u1TxPwrBwManual, + u1TxPwrRateManual, i1TxPwrValueManual, Band)); + + + /*BW : 0:BW20, 1: BW40, 2: BW80, 3: BW160*/ + if (u1TxPwrBwManual == 0) + u1TxPwrBwManual = 20; + else if (u1TxPwrBwManual == 1) + u1TxPwrBwManual = 40; + else if (u1TxPwrBwManual == 2) + u1TxPwrBwManual = 80; + else + u1TxPwrBwManual = 160; + + /*QA tool: 0:CCK, 1:OFDM, 2:HT-MIXED, 3: HT-GREEN,4: VHT */ + /*FW: 0:CCK, 1:OFDM, 2:HT, 3:VHT*/ + if (u1TxPwrModeManual == 2 || u1TxPwrModeManual == 3) + u1TxPwrModeManual = 2; + else if (u1TxPwrModeManual == 4) + u1TxPwrModeManual = 3; + + + /* sanity check for Other input parameter */ + switch (u1TxPwrModeManual) { + case 0: + if (u1TxPwrRateManual > 3 || u1TxPwrBwManual > 0) + Ret = NDIS_STATUS_FAILURE; + break; + case 1: + if (u1TxPwrRateManual > 7 || u1TxPwrBwManual > 0) + Ret = NDIS_STATUS_FAILURE; + break; + case 2: + if (u1TxPwrBwManual == 20) { + if (u1TxPwrRateManual > 7) + Ret = NDIS_STATUS_FAILURE; + } else if (u1TxPwrBwManual == 40) { + if (u1TxPwrRateManual > 8) + Ret = NDIS_STATUS_FAILURE; + } else + Ret = NDIS_STATUS_FAILURE; + break; + case 3: + if (u1TxPwrBwManual == 20) { + if (u1TxPwrRateManual > 9) + Ret = NDIS_STATUS_FAILURE; + } else if (u1TxPwrBwManual == 40) { + if (u1TxPwrRateManual > 0) + Ret = NDIS_STATUS_FAILURE; + } else + Ret = NDIS_STATUS_FAILURE; + break; + default: + Ret = TxPowerManualCtrl (pAd, fgPwrManCtrl, u1TxPwrModeManual, u1TxPwrBwManual, u1TxPwrRateManual, i1TxPwrValueManual, Band); + } + return Ret; +} +#endif + +static INT32 MT_ATESetCfgOnOff(RTMP_ADAPTER *pAd, UINT32 Type, UINT32 Enable) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Type:%d, Enable:%d, control_band_idx:%d\n", + __func__, Type, Enable, control_band_idx)); +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = MtCmdCfgOnOff(pAd, Type, Enable, control_band_idx); +#endif + return Ret; +} + +static INT32 MT_ATEGetCfgOnOff(RTMP_ADAPTER *pAd, UINT32 Type, UINT32 *Result) +{ + INT32 Ret = 0; +#if defined(COMPOS_TESTMODE_WIN) + UINT32 Value = 0; + GET_TSSI_STATUS_T *pResult = (GET_TSSI_STATUS_T *)((UINT8 *)pAd->FWRspContent + sizeof(EVENT_RXD) + sizeof(EXT_EVENT_ATE_TEST_MODE_T)); +#endif +#ifdef CONFIG_HW_HAL_OFFLOAD + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + Ret = MtCmdGetCfgOnOff(pAd, Type, control_band_idx, Result); + os_msec_delay(30); +#endif +#if defined(COMPOS_TESTMODE_WIN) + *Result = OS_NTOHL(pResult->ucEnable); +#endif + return Ret; +} + +static INT32 MT_ATESetAntennaPort(RTMP_ADAPTER *pAd, UINT32 RfModeMask, UINT32 RfPortMask, UINT32 AntPortMask) +{ + INT32 Ret = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: RfModeMask:%d RfPortMask:%d AntPortMask:%d\n", + __func__, (UINT8)RfModeMask, (UINT8)RfPortMask, + (UINT8)AntPortMask)); +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = MtCmdSetAntennaPort(pAd, (UINT8)RfModeMask, (UINT8)RfPortMask, (UINT8)AntPortMask); +#endif + return Ret; +} + + +static INT32 MT_ATEFWPacketCMDClockSwitchDisable( + RTMP_ADAPTER *pAd, UINT8 isDisable) +{ + INT32 Ret = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: isDsiable=%d\n", __func__, (UINT8)isDisable)); + Ret = MtCmdClockSwitchDisable(pAd, isDisable); + return Ret; +} + + +static INT32 MT_ATESetRXFilterPktLen(RTMP_ADAPTER *pAd, UINT32 Enable, UINT32 RxPktLen) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Enable:%d, control_band_idx:%d, RxPktLen:%d\n", + __func__, Enable, control_band_idx, RxPktLen)); +#ifdef CONFIG_HW_HAL_OFFLOAD + Ret = MtCmdRxFilterPktLen(pAd, Enable, control_band_idx, RxPktLen); +#endif + return Ret; +} + + +static INT32 MT_ATEGetTxPower(RTMP_ADAPTER *pAd, UINT32 Channel, UINT32 Ch_Band, UINT32 *EfuseAddr, UINT32 *Power) +{ + INT32 Ret = 0; +#if defined(COMPOS_TESTMODE_WIN) + EXT_EVENT_ID_GET_TX_POWER_T *pResult = (EXT_EVENT_ID_GET_TX_POWER_T *)((UINT8 *) pAd->FWRspContent + sizeof(EVENT_RXD)); +#endif + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + EXT_EVENT_ID_GET_TX_POWER_T TxPowerResult; + INT32 Type = 1; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Channel:%d, control_band_idx:%d, Ch_Band:%d\n", + __func__, Channel, control_band_idx, Ch_Band)); + Ret = MtCmdGetTxPower(pAd, Type, Channel, control_band_idx, Ch_Band, &TxPowerResult); + os_msec_delay(30); +#if defined(MT7615) || defined(MT7622) + *EfuseAddr = TxPowerResult.ucEfuseAddr; + *Power = TxPowerResult.ucEfuseContent; +#else +#endif /* defined(MT7615) || defined(MT7622) */ +#if defined(COMPOS_TESTMODE_WIN) + *EfuseAddr = OS_NTOHL(pResult->ucEfuseAddr); + *Power = OS_NTOHL(pResult->ucEfuseContent); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: EfuseAddr:%d Power:%d\n", __func__, *EfuseAddr, *Power)); + return Ret; +} + + +static INT32 MT_ATEBssInfoUpdate(RTMP_ADAPTER *pAd, UINT32 OwnMacIdx, UINT32 BssIdx, UCHAR *Bssid) +{ + INT32 Ret = 0; +#if !defined(COMPOS_TESTMODE_WIN) /* TODO::UNIYSW */ + BSS_INFO_ARGUMENT_T bss_info_argument; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: OwnMacIdx:%d BssIdx:%d Bssid:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, OwnMacIdx, BssIdx, PRINT_MAC(Bssid))); + NdisZeroMemory(&bss_info_argument, sizeof(BSS_INFO_ARGUMENT_T)); + bss_info_argument.OwnMacIdx = OwnMacIdx; + bss_info_argument.ucBssIndex = BssIdx; + os_move_mem(bss_info_argument.Bssid, Bssid, MAC_ADDR_LEN); + bss_info_argument.ucBcMcWlanIdx = MCAST_WCID_TO_REMOVE; + bss_info_argument.NetworkType = NETWORK_INFRA; + bss_info_argument.u4ConnectionType = CONNECTION_INFRA_AP; + bss_info_argument.CipherSuit = Ndis802_11WEPDisabled; + bss_info_argument.bss_state = BSS_ACTIVE; + bss_info_argument.u4BssInfoFeature = BSS_INFO_BASIC_FEATURE; + Ret = AsicBssInfoUpdate(pAd, bss_info_argument); +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + return Ret; +} + + +static INT32 MT_ATEDevInfoUpdate(RTMP_ADAPTER *pAd, UINT32 OwnMacIdx, UCHAR *Bssid) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: control_band_idx:%d OwnMacIdx:%d Bssid:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, control_band_idx, OwnMacIdx, PRINT_MAC(Bssid))); +#if !defined(COMPOS_TESTMODE_WIN) /* TODO::UNIYSW */ + Ret = AsicDevInfoUpdate(pAd, OwnMacIdx, Bssid, control_band_idx, TRUE, DEVINFO_ACTIVE_FEATURE); +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + return Ret; +} + +static INT32 MT_SetFFTMode(struct _RTMP_ADAPTER *pAd, UINT32 mode) +{ + INT32 Ret = 0; + return Ret; +} + + +#ifdef LOGDUMP_TO_FILE +static INT32 MT_ATERDDParseResult(struct _ATE_LOG_DUMP_ENTRY entry, INT idx, RTMP_OS_FD_EXT fd) +#else +static INT32 MT_ATERDDParseResult(struct _ATE_LOG_DUMP_ENTRY entry, INT idx) +#endif +{ + struct _ATE_RDD_LOG *result = &entry.log.rdd; + UINT32 *pulse = (UINT32 *)result->aucBuffer; + + if (!result->byPass) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[RDD]0x%08x %08x\n", result->u4Prefix, result->u4Count)); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[RDD]0x%08x %08x\n", pulse[0], pulse[1])); + return 0; +} + + +INT32 MT_ATERFTestCB(RTMP_ADAPTER *pAd, UINT8 *Data, UINT32 Length) +{ + INT32 ret = 0; + EXT_EVENT_RF_TEST_RESULT_T *result = (EXT_EVENT_RF_TEST_RESULT_T *)Data; + EXT_EVENT_RF_TEST_DATA_T *data = (EXT_EVENT_RF_TEST_DATA_T *)result->aucEvent; + static INT total; + static INT EventType; + static UINT32 recal_type; + BOOLEAN test_done = FALSE; + + /* Length of Event ACK */ + if (Length == sizeof(struct _EVENT_EXT_CMD_RESULT_T)) + test_done = TRUE; + + if (test_done) + goto done; +#ifdef PRE_CAL_MT7622_SUPPORT + if ((!pAd->bPreCalMode) && (!(pAd->ATECtrl.Mode & fATE_IN_RFTEST))) +#else + if (!(pAd->ATECtrl.Mode & fATE_IN_RFTEST)) +#endif /* PRE_CAL_MT7622_SUPPORT */ + return ret; + result->u4FuncIndex = le2cpu32(result->u4FuncIndex); + EventType = result->u4FuncIndex; + + switch (EventType) { + case RDD_TEST_MODE: + if (pAd->ATECtrl.en_log & fATE_LOG_RDD) { + struct _ATE_RDD_LOG unit; + struct _EVENT_WIFI_RDD_TEST_T *log = + (struct _EVENT_WIFI_RDD_TEST_T *)Data; + UINT64 *data = (UINT64 *)log->aucBuffer; + INT i = 0; + UINT len = 0; + + log->u4FuncLength = le2cpu32(log->u4FuncLength); + log->u4Prefix = le2cpu32(log->u4Prefix); + log->u4Count = le2cpu32(log->u4Count); + + len = (log->u4FuncLength - sizeof(struct _EVENT_WIFI_RDD_TEST_T) + + sizeof(log->u4FuncIndex) + sizeof(log->u4FuncIndex))>>3; + + if (pAd->ATECtrl.en_log & fATE_LOG_TEST) { + const UINT dbg_len = (log->u4FuncLength - sizeof(struct _EVENT_WIFI_RDD_TEST_T) + sizeof(log->u4FuncIndex) + sizeof(log->u4FuncIndex)) >> 2; + UINT32 *tmp = (UINT32 *)log->aucBuffer; + + for (i = 0; i < dbg_len; i++) + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RDD RAW DWORD%d:%08x\n", i, tmp[i])); + + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: RDD FuncLen:%u, len:%u, prefix:%08x, cnt:%u\n", + __func__, log->u4FuncLength, len, log->u4Prefix, log->u4Count)); + } + + os_zero_mem(&unit, sizeof(unit)); + unit.u4Prefix = log->u4Prefix; + unit.u4Count = log->u4Count; + + for (i = 0; i < len; i++) { + NdisMoveMemory(unit.aucBuffer, data++, ATE_RDD_LOG_SIZE); + MT_ATEInsertLog(pAd, (UCHAR *)&unit, fATE_LOG_RDD, sizeof(unit)); + /* byPass is used @ logDump, if the same event, don't dump same message */ + unit.byPass = TRUE; + } + } + + break; + +#ifdef INTERNAL_CAPTURE_SUPPORT + case GET_ICAP_CAPTURE_STATUS: + if (IS_MT7615(pAd)) + ExtEventICapStatusHandler(pAd, Data, Length); + break; + + case GET_ICAP_RAW_DATA: + RTEnqueueInternalCmd(pAd, CMDTHRED_ICAP_DUMP_RAW_DATA, (VOID *)Data, Length); + break; +#endif/* INTERNAL_CAPTURE_SUPPORT */ + + case RE_CALIBRATION: + if (data) { + struct _ATE_LOG_RECAL re_cal; + INT i = 0; + UINT32 cal_idx = 0; + UINT32 cal_type = 0; + UINT32 len = 0; + UINT32 *dump_tmp = (UINT32 *)data->aucData; + struct _ATE_LOG_DUMP_CB *log_cb = NULL; +#ifdef PRE_CAL_MT7622_SUPPORT + UINT32 *cal_log = NULL; + + if (pAd->bPreCalMode) + os_alloc_mem(pAd, (UCHAR **)&cal_log, CAL_LOG_SIZE); +#endif /* PRE_CAL_MT7622_SUPPORT */ + data->u4CalIndex = le2cpu32(data->u4CalIndex); + data->u4CalType = le2cpu32(data->u4CalType); + result->u4PayloadLength = le2cpu32(result->u4PayloadLength); + cal_idx = data->u4CalIndex; + cal_type = data->u4CalType; + len = result->u4PayloadLength; + len = (len - sizeof(EXT_EVENT_RF_TEST_DATA_T)) >> 2; + log_cb = &pAd->ATECtrl.log_dump[ATE_LOG_RE_CAL - 1]; + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, */ + /* ("CalType:%x\n", cal_type)); */ + re_cal.cal_idx = cal_idx; + re_cal.cal_type = cal_type; + + if (total == 0) { + recal_type = cal_type; + log_cb->recal_curr_type = recal_type; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("[Recal][%08x][START]\n", recal_type)); + } + + total += result->u4PayloadLength; + + if ((cal_type == CAL_ALL) && + (total == CAL_ALL_LEN)) + test_done = TRUE; + + for (i = 0; i < len; i++) { + dump_tmp[i] = le2cpu32(dump_tmp[i]); + if (i & 0x1) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%08x\n", dump_tmp[i])); + re_cal.cr_val = dump_tmp[i]; +#ifdef PRE_CAL_MT7622_SUPPORT + if (cal_log) + cal_log[(i-1)/2] = dump_tmp[i]; +#endif /* PRE_CAL_MT7622_SUPPORT */ + if (pAd->ATECtrl.en_log & fATE_LOG_RE_CAL) + MT_ATEInsertLog(pAd, (UCHAR *)&re_cal, fATE_LOG_RE_CAL, sizeof(re_cal)); + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("[Recal][%08x][%08x]", cal_type, dump_tmp[i])); + re_cal.cr_addr = dump_tmp[i]; + } + } +#ifdef PRE_CAL_MT7622_SUPPORT + if (pAd->bPreCalMode) { + if (cal_type == TX_LPFG) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[cal_type][TX_LPFG]len=%d\n", len)); + RTMPZeroMemory(pAd->CalTXLPFGImage, CAL_TXLPFG_SIZE); + memcpy(pAd->CalTXLPFGImage, cal_log, CAL_TXLPFG_SIZE); + } else if (cal_type == TX_DCIQC) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[cal_type][TX_DCIQC]len=%d\n", len)); + RTMPZeroMemory(pAd->CalTXDCIQImage, CAL_TXDCIQ_SIZE); + memcpy(pAd->CalTXDCIQImage, cal_log, CAL_TXDCIQ_SIZE); + } else if (cal_type == TX_DPD_LINK) { + UINT16 tmp_len = (len/2) * sizeof(UINT32); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[cal_type][TX_DPD], ofset=%x, len =%d\n", + pAd->TxDpdCalOfst, tmp_len)); + memcpy(pAd->CalTXDPDImage + pAd->TxDpdCalOfst, cal_log, tmp_len); + pAd->TxDpdCalOfst += tmp_len; + } + os_free_mem(cal_log); + } +#endif /* PRE_CAL_MT7622_SUPPORT */ + } + break; + + case CALIBRATION_BYPASS: + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: No RF Test Event %x Dump\n", __func__, result->u4FuncIndex)); + break; + } + +done: + + if (test_done) { + if (EventType == RE_CALIBRATION) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("[Recal][%08x][END]\n", recal_type)); + } + + total = 0; + EventType = 0; + recal_type = 0; + } + + return ret; +} + + +#ifdef ATE_TXTHREAD +static INT32 MT_ATEMPSRunStatCheck(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _HQA_MPS_CB *mps_cb = TESTMODE_GET_PADDR(ATECtrl, band_idx, mps_cb); + struct _HQA_MPS_SETTING *mps_setting = NULL; + UINT32 txed_cnt = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxedCount); + UINT32 tx_cnt = TESTMODE_GET_PARAM(ATECtrl, band_idx, TxCount); + UINT32 idx = 0; + INT32 ret = 0; + + if (!mps_cb) + goto err0; + + mps_setting = mps_cb->mps_setting; + + if (!mps_setting) + goto err0; + + idx = mps_cb->ref_idx; + + if ((mps_cb->stat & ATE_MPS_ITEM_RUNNING) && (txed_cnt >= tx_cnt)) { + /* UCHAR mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, Mode); */ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: MPS Item Finished idx:%d mps_cnt:%d\n", __func__, idx, mps_cb->mps_cnt)); + OS_SPIN_LOCK(&mps_cb->lock); + mps_cb->stat = 0; + OS_SPIN_UNLOCK(&mps_cb->lock); + + if (idx > mps_cb->mps_cnt) { + UINT32 mode = TESTMODE_GET_PARAM(ATECtrl, band_idx, Mode); + mode &= ~fATE_MPS; + mps_cb->setting_inuse = FALSE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: MPS All Finished idx:%d mps_cnt:%d\n", __func__, idx, mps_cb->mps_cnt)); + TESTMODE_SET_PARAM(ATECtrl, band_idx, Mode, mode); + ret = MT_MPSTxStop(pAd); + } + } + + return ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: mps_cb/mps_setting NULL %p %p\n", __func__, mps_cb, mps_setting)); + return -1; +} +#endif + + +static INT32 MT_ATEMPSLoadSetting(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_op = ATECtrl->ATEOp; + struct _HQA_MPS_CB *mps_cb = TESTMODE_GET_PADDR(ATECtrl, band_idx, mps_cb); + struct _HQA_MPS_SETTING *mps_setting = NULL; + UCHAR *pate_pkt = TESTMODE_GET_PARAM(ATECtrl, band_idx, pate_pkt); + INT idx = 0; + UCHAR phymode = 0; + CHAR ant_sel = 0; + UCHAR mcs = 0; + INT32 ret = 0; + UINT32 pwr = 0; + UINT32 pkt_len = 0; + UINT32 pkt_cnt = 0; + UINT32 nss = 0; + UINT32 pkt_bw = 0; + UINT32 Channel = TESTMODE_GET_PARAM(ATECtrl, band_idx, Channel); + UINT32 Ch_Band = TESTMODE_GET_PARAM(ATECtrl, band_idx, Ch_Band); + ATE_TXPOWER TxPower; + os_zero_mem(&TxPower, sizeof(TxPower)); + + if (!mps_cb) + goto err0; + + mps_setting = mps_cb->mps_setting; + + if (!mps_setting) + goto err0; + + OS_SPIN_LOCK(&mps_cb->lock); + + if (mps_cb->stat & ATE_MPS_ITEM_RUNNING) + goto err1; + + mps_cb->stat |= ATE_MPS_ITEM_RUNNING; + idx = mps_cb->ref_idx; + + if (idx > mps_cb->mps_cnt) + goto err2; + + phymode = (mps_setting[idx].phy & 0x0f000000) >> 24; + ant_sel = (mps_setting[idx].phy & 0x00ffff00) >> 8; + mcs = (mps_setting[idx].phy & 0x000000ff); + pwr = mps_setting[idx].pwr; + pkt_len = mps_setting[idx].pkt_len; + pkt_cnt = mps_setting[idx].pkt_cnt; + nss = mps_setting[idx].nss; + pkt_bw = mps_setting[idx].pkt_bw; + TESTMODE_SET_PARAM(ATECtrl, band_idx, PhyMode, phymode); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxAntennaSel, ant_sel); + TESTMODE_SET_PARAM(ATECtrl, band_idx, Mcs, mcs); + TESTMODE_SET_PARAM(ATECtrl, band_idx, Nss, nss); + TESTMODE_SET_PARAM(ATECtrl, band_idx, PerPktBW, pkt_bw); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxLength, pkt_len); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxCount, pkt_cnt); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxDoneCount, 0); + TESTMODE_SET_PARAM(ATECtrl, band_idx, TxedCount, 0); + ATECtrl->TxPower0 = pwr; + TxPower.Power = pwr; + TxPower.Channel = Channel; + TxPower.Dbdc_idx = band_idx; + TxPower.Band_idx = Ch_Band; + OS_SPIN_UNLOCK(&mps_cb->lock); + ret = ate_op->SetTxPower0(pAd, TxPower); + ATECtrl->need_set_pwr = TRUE; + + if (mps_cb->ref_idx != 1) + ret = MT_ATEGenPkt(pAd, pate_pkt, band_idx); + + mps_cb->ref_idx++; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Item[%d], PhyMode:%x, TxPath:%x, Rate:%x, PktLen:%u, PktCount:%u, Pwr:%x\n", + idx, phymode, ant_sel, mcs, pkt_len, pkt_cnt, pwr)); + return ret; +err2: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: mps_cb->ref_idx %d mps_cnt %d\n", __func__, mps_cb->ref_idx, mps_cb->mps_cnt)); +err1: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: item[%d] is running\n", __func__, mps_cb->ref_idx - 1)); + OS_SPIN_UNLOCK(&mps_cb->lock); + return ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: mps_cb/mps_setting NULL %p %p\n", __func__, mps_cb, mps_setting)); + return -1; +} + + +static INT32 MT_ATEMPSInit(RTMP_ADAPTER *pAd) +{ + INT ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _HQA_MPS_CB *mps_cb = &ATECtrl->mps_cb; + + if (mps_cb->mps_setting) + os_free_mem(mps_cb->mps_setting); + + NdisZeroMemory(mps_cb, sizeof(*mps_cb)); + mps_cb->setting_inuse = FALSE; + mps_cb->mps_cnt = 0; + mps_cb->band_idx = 0; + mps_cb->stat = 0; + mps_cb->ref_idx = 1; + mps_cb->mps_setting = NULL; + NdisAllocateSpinLock(pAd, &mps_cb->lock); + return ret; +} + + +static INT32 MT_ATEMPSRelease(RTMP_ADAPTER *pAd) +{ + INT ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _HQA_MPS_CB *mps_cb = &ATECtrl->mps_cb; + + if (mps_cb->mps_setting) + os_free_mem(mps_cb->mps_setting); + + mps_cb->mps_setting = NULL; + mps_cb->setting_inuse = FALSE; + mps_cb->mps_cnt = 0; + mps_cb->stat = 0; + mps_cb->band_idx = 0; + mps_cb->ref_idx = 1; + NdisFreeSpinLock(&mps_cb->lock); + return ret; +} + + +INT32 MT_SetATEMPSDump(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _HQA_MPS_CB *mps_cb = &ATECtrl->mps_cb; + struct _HQA_MPS_SETTING *mps_setting = mps_cb->mps_setting; + UINT32 i = 0; + mps_cb = TESTMODE_GET_PADDR(ATECtrl, band_idx, mps_cb); + mps_setting = mps_cb->mps_setting; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s-band[%u]::\n", __func__, band_idx)); + + if (!mps_setting) + return -1; + + for (i = 1; i <= mps_cb->mps_cnt; i++) { + UINT32 phy = (mps_setting[i].phy & ~0xf0ffffff) >> 24; + UINT32 path = (mps_setting[i].phy & ~0xff0000ff) >> 8; + UINT32 rate = (mps_setting[i].phy & ~0xffffff00); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Item[%d], PhyMode:%x, TxPath:%x, Rate:%x, PktLen:%u, PktCount:%u, Pwr:%x Nss:%u, Bw:%u\n", + i, phy, path, rate, mps_setting[i].pkt_len, + mps_setting[i].pkt_cnt, mps_setting[i].pwr, + mps_setting[i].nss, mps_setting[i].pkt_bw)); + } + + return 0; +} + + +static INT32 MT_MPSSetParm(RTMP_ADAPTER *pAd, enum _MPS_PARAM_TYPE type, INT32 items, UINT32 *data) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + INT32 i = 0; + UINT32 mode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mode); + struct _HQA_MPS_CB *mps_cb = TESTMODE_GET_PADDR(ATECtrl, control_band_idx, mps_cb); + struct _HQA_MPS_SETTING *mps_setting; + + if ((items > 1024) || (items == 0)) + goto MT_MPSSetParm_RET_FAIL; + + if (mode & fATE_MPS) + goto MT_MPSSetParm_RET_FAIL; + + if (!mps_cb->mps_setting && !mps_cb->mps_cnt) { + mps_cb->mps_cnt = items; + mps_cb->band_idx = control_band_idx; + ret = os_alloc_mem(pAd, (UCHAR **)&mps_cb->mps_setting, sizeof(struct _HQA_MPS_SETTING) * (items + 1)); + + if (ret == NDIS_STATUS_FAILURE) + goto MT_MPSSetParm_RET_FAIL; + + NdisZeroMemory(mps_cb->mps_setting, sizeof(struct _HQA_MPS_SETTING) * (items + 1)); + } + + mps_setting = mps_cb->mps_setting; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: control_band_idx:%u, items:%d, Mode:%x, mps_cb:%p, mps_set:%p\n", + __func__, control_band_idx, items, mode, mps_cb, mps_setting)); + + switch (type) { + case MPS_SEQDATA: + mps_setting[0].phy = 1; + + for (i = 0; i < items; i++) + mps_setting[i + 1].phy = data[i]; + + break; + + case MPS_PHYMODE: + mps_setting[0].phy = 1; + + for (i = 0; i < items; i++) { + mps_setting[i + 1].phy &= 0xf0ffffff; + mps_setting[i + 1].phy |= (data[i] << 24) & 0x0f000000; + } + + break; + + case MPS_PATH: + mps_setting[0].phy = 1; + + for (i = 0; i < items; i++) { + mps_setting[i + 1].phy &= 0xff0000ff; + mps_setting[i + 1].phy |= (data[i] << 8) & 0x00ffff00; + } + + break; + + case MPS_RATE: + mps_setting[0].phy = 1; + + for (i = 0; i < items; i++) { + mps_setting[i + 1].phy &= 0xffffff00; + mps_setting[i + 1].phy |= (0x000000ff & data[i]); + } + + break; + + case MPS_PAYLOAD_LEN: + mps_setting[0].pkt_len = 1; + + for (i = 0; i < items; i++) { + if (data[i] > MAX_TEST_PKT_LEN) + data[i] = MAX_TEST_PKT_LEN; + else if (data[i] < MIN_TEST_PKT_LEN) + data[i] = MIN_TEST_PKT_LEN; + + mps_setting[i + 1].pkt_len = data[i]; + } + + break; + + case MPS_TX_COUNT: + mps_setting[0].pkt_cnt = 1; + + for (i = 0; i < items; i++) + mps_setting[i + 1].pkt_cnt = data[i]; + + break; + + case MPS_PWR_GAIN: + mps_setting[0].pwr = 1; + + for (i = 0; i < items; i++) + mps_setting[i + 1].pwr = data[i]; + + break; + + case MPS_NSS: + mps_setting[0].nss = 1; + + for (i = 0; i < items; i++) + mps_setting[i + 1].nss = data[i]; + + break; + + case MPS_PKT_BW: + mps_setting[0].pkt_bw = 1; + + for (i = 0; i < items; i++) + mps_setting[i + 1].pkt_bw = data[i]; + + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: unknown setting type\n", __func__)); + break; + } + + return ret; +MT_MPSSetParm_RET_FAIL: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s-fail, control_band_idx:%u, items:%d, Mode:%x\n", + __func__, control_band_idx, items, mode)); + return NDIS_STATUS_FAILURE; +} + + +static INT32 MT_MPSTxStart(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + struct _HQA_MPS_CB *mps_cb = TESTMODE_GET_PADDR(ATECtrl, control_band_idx, mps_cb); + struct _HQA_MPS_SETTING *mps_setting = mps_cb->mps_setting; + UINT32 mode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mode); + UINT32 mps_cnt = mps_cb->mps_cnt; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx:%u, items:%u\n", + __func__, control_band_idx, mps_cnt)); + + if (!mps_setting || !mps_cnt || (mode & ATE_MPS)) + goto MPS_START_ERR; + + if (mps_cb->setting_inuse) + goto MPS_START_ERR; + + mode |= fATE_MPS; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mode, mode); + mps_cb->ref_idx = 1; + mps_cb->setting_inuse = TRUE; + ret = MT_SetATEMPSDump(pAd, control_band_idx); + ret = MT_ATEMPSLoadSetting(pAd, control_band_idx); + ret = ATEOp->StartTx(pAd); + return ret; +MPS_START_ERR: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s error, mode:0x%x, mps_cnt:%x, MPS_SETTING: %p\n", + __func__, mode, mps_cnt, mps_setting)); + return ret; +} + + +static INT32 MT_MPSTxStop(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UINT32 mode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mode); + struct _HQA_MPS_CB *mps_cb = TESTMODE_GET_PADDR(ATECtrl, control_band_idx, mps_cb); + struct _HQA_MPS_SETTING *mps_setting = mps_cb->mps_setting; + + mode &= ~ATE_TXFRAME; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: control_band_idx:%u, Mode:%x, inuse:%x, setting_addr:%p\n", + __func__, control_band_idx, mode, mps_cb->setting_inuse, mps_setting)); + + if (!(mode & ATE_MPS) && mps_setting && !mps_cb->setting_inuse) { + struct _HQA_MPS_SETTING **setting_addr = &(mps_cb->mps_setting); + mps_cb->mps_cnt = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: bf free mem %p\n", __func__, mps_setting)); + os_free_mem(*setting_addr); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: af free mem %p\n", __func__, mps_setting)); + *setting_addr = NULL; + } + + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mode, mode); + return ret; +} + + +static INT32 MT_ATESetAutoResp(RTMP_ADAPTER *pAd, UCHAR *mac, UCHAR mode) +{ + INT32 ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR *sa = NULL; +#ifdef CONFIG_AP_SUPPORT + sa = ATECtrl->Addr3; +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); +#if !defined(COMPOS_TESTMODE_WIN) + + if (mode) { + if (sa) + NdisMoveMemory(sa, mac, MAC_ADDR_LEN); + + AsicDevInfoUpdate( + pAd, + 0x0, + mac, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } else { + AsicDevInfoUpdate( + pAd, + 0x0, + pAd->CurrentAddress, + control_band_idx, + TRUE, + DEVINFO_ACTIVE_FEATURE); + } + +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + return ret; +} + + +static INT32 MT_EfuseGetFreeBlock(RTMP_ADAPTER *pAd, UINT32 GetFreeBlock, UINT32 *Value) +{ + INT32 Ret = 0; +#if defined(COMPOS_TESTMODE_WIN) + EXT_EVENT_EFUSE_FREE_BLOCK_T *pResult = (EXT_EVENT_EFUSE_FREE_BLOCK_T *)((UINT8 *) pAd->FWRspContent + sizeof(EVENT_RXD)); +#endif + Ret = MtCmdEfuseFreeBlockCount(pAd, GetFreeBlock, Value); +#if defined(COMPOS_TESTMODE_WIN) + /* workaround for MtCmdEfuseFreeBlockCount not waiting event back when repoen QA second times */ + RTMPusecDelay(30000); + *Value = OS_NTOHL(pResult->ucFreeBlockNum); +#endif + return Ret; +} + + + + +static INT32 MT_RfRegWrite(RTMP_ADAPTER *pAd, UINT32 WFSel, UINT32 Offset, UINT32 Value) +{ + INT32 Ret = 0; + Ret = MtCmdRFRegAccessWrite(pAd, WFSel, Offset, Value); + return Ret; +} + + +static INT32 MT_RfRegRead(RTMP_ADAPTER *pAd, UINT32 WFSel, UINT32 Offset, UINT32 *Value) +{ + INT32 Ret = 0; +#if defined(COMPOS_TESTMODE_WIN) + EXT_CMD_RF_REG_ACCESS_T *pResult = (EXT_CMD_RF_REG_ACCESS_T *)((UINT8 *)pAd->FWRspContent + sizeof(EVENT_RXD)); +#endif + Ret = MtCmdRFRegAccessRead(pAd, WFSel, Offset, Value); +#if defined(COMPOS_TESTMODE_WIN) + *Value = OS_NTOHL(pResult->u4Data); +#endif + return Ret; +} + + +static INT32 MT_GetFWInfo(RTMP_ADAPTER *pAd, UCHAR *FWInfo) +{ + struct fwdl_ctrl *ctrl = &pAd->MCUCtrl.fwdl_ctrl; + UCHAR op_mode; + UINT32 loop; + UCHAR date[8] = {'\0'}; + UCHAR time[6] = {'\0'}; + UCHAR *kernel_info = NULL; + UINT8 month = 0; + UCHAR *month_array[12] = { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + }; + + /* Get information from kernel */ + for (loop = 0; loop < 12; loop++) { + kernel_info = strstr(utsname()->version, month_array[loop]); + + if (kernel_info) + break; + } + + op_mode = (UCHAR) + pAd->OpMode; /* 0: STA, 1: AP, 2: ADHOC, 3: APSTA */ + /* Driver build time */ + os_move_mem(&time[0], kernel_info + 7, 2); + os_move_mem(&time[2], kernel_info + 10, 2); + os_move_mem(&time[4], kernel_info + 13, 2); + /* Driver build date */ + os_move_mem(&date[0], kernel_info + 20, 4); + os_move_mem(&date[6], kernel_info + 4, 2); + + for (loop = 0; loop < 12; loop++) { + if (os_cmp_mem(month_array[loop], kernel_info, 3) == 0) { + month = loop + 1; + break; + } + } + + date[4] = month / 10 % 10 + '0'; + date[5] = month % 10 + '0'; + /* Command combination */ + os_move_mem(FWInfo, &op_mode, sizeof(op_mode)); + os_move_mem((FWInfo + sizeof(op_mode)), &date, sizeof(date)); + os_move_mem((FWInfo + sizeof(op_mode) + sizeof(date)), &time, sizeof(time)); + os_move_mem((FWInfo + sizeof(op_mode) + sizeof(date) + sizeof(time)), \ + ctrl->fw_profile[WM_CPU].source.img_ptr + ctrl->fw_profile[WM_CPU].source.img_len - 19, 15); + return 0; +} + + +#ifdef TXBF_SUPPORT +/* ========================================================================== + * Description: + * Set ATE Tx Beamforming mode + * + * Return: + * TRUE if all parameters are OK, FALSE otherwise + * ========================================================================== + */ + + +#ifdef MT_MAC +/* + *========================================================================== + * Description: + * Enable sounding trigger + * + * Return: + * TRUE if all parameters are OK, FALSE otherwise + *========================================================================== +*/ +INT MT_SetATESoundingProc(RTMP_ADAPTER *pAd, UCHAR SDEnFlg) +{ + /* struct _ATE_CTRL *AteCtrl = &pAd->ATECtrl; */ + /* Enable sounding trigger in FW */ + /* return CmdETxBfSoundingPeriodicTriggerCtrl(pAd, BSSID_WCID, SDEnFlg); */ + /* return MtCmdETxBfSoundingPeriodicTriggerCtrl(pAd, BSSID_WCID, SDEnFlg, AteCtrl->BW); */ + return -1; +} + + +static INT32 MT_ATEStartTxSKB(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *if_ops = ATECtrl->ATEIfOps; + INT32 Ret = 0; + UCHAR control_band_idx = ATECtrl->control_band_idx; + UCHAR *pate_pkt = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, pate_pkt); + UCHAR cntl_ch = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, ControlChl); + UCHAR ch = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Channel); + UINT32 mode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mode); + UINT32 tx_cnt = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxCount); + UCHAR bw = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, BW); + /* MT_SWITCH_CHANNEL_CFG ch_cfg; */ + INT8 wdev_idx = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, wdev_idx); +#ifdef ARBITRARY_CCK_OFDM_TX + UINT32 tx_sel = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxAntennaSel); + UINT8 phymode = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, PhyMode); +#endif + UINT32 Rate = TESTMODE_GET_PARAM(ATECtrl, control_band_idx, Mcs); +#ifdef CONFIG_AP_SUPPORT + INT32 IdBss, MaxNumBss = pAd->ApCfg.BssidNum; +#endif +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + union WTBL_DW5 wtbl_txcap; +#else + union WTBL_2_DW9 wtbl_txcap; +#endif + UINT32 DwMask = 0; + UINT32 Ring = 0; + CMD_WTBL_RAW_DATA_RW_T rWtblRawDataRw = {0}; + rWtblRawDataRw.u2Tag = WTBL_RAW_DATA_RW; + rWtblRawDataRw.u2Length = sizeof(CMD_WTBL_RAW_DATA_RW_T); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: control_band_idx:%u, ch:%x, cntl_ch:%x, wdev_idx:%x\n", + __func__, control_band_idx, ch, cntl_ch, wdev_idx)); + + if (!pate_pkt) + goto err0; + + /* TxRx swtich Recover */ + + if (mode & ATE_TXFRAME) + goto err1; + + MtATESetMacTxRx(pAd, ASIC_MAC_TX, TRUE, control_band_idx); +#ifdef ARBITRARY_CCK_OFDM_TX + if (IS_MT7615(pAd)) { + MtATEInitCCK_OFDM_Path(pAd, control_band_idx); + + if (phymode == MODE_CCK || phymode == MODE_OFDM) + MtATESetCCK_OFDM_Path(pAd, tx_sel, control_band_idx); + } +#endif + + if (Rate == 32) { +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + DwMask = ~(3 << 12); /* only update fcap bit[13:12] */ + wtbl_txcap.field.fcap = bw; + /* WTBLDW5 */ + WtblDwSet(pAd, ATECtrl->wcid_ref, 1, 5, DwMask, wtbl_txcap.word); +#else + DwMask = ~(3 << 14); /* only update fcap bit[15:14] */ + wtbl_txcap.field.fcap = bw; + /* WTBL2DW9 */ + WtblDwSet(pAd, ATECtrl->wcid_ref, 2, 9, DwMask, wtbl_txcap.word); +#endif + } + + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE, control_band_idx); + msleep(30); + /* Stop send TX packets */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; + IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_STOP_QUEUE( + pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_SET_FLAG(pAd, + fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + if (mode & ATE_RXFRAME) + MtATESetMacTxRx(pAd, ASIC_MAC_RX_RXV, TRUE, control_band_idx); + + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (MaxNumBss > MAX_MBSSID_NUM(pAd)) + MaxNumBss = MAX_MBSSID_NUM(pAd); + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; + IdBss < MAX_MBSSID_NUM(pAd); IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev) + RTMP_OS_NETDEV_START_QUEUE( + pAd->ApCfg.MBSSID[IdBss].wdev.if_dev); + } + } +#endif + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET); + + /* Prepare Tx packet */ + if (if_ops->setup_frame) + Ret = if_ops->setup_frame(pAd, QID_AC_BE); + else + Ret = MT_ATEGenPkt(pAd, pate_pkt, control_band_idx); + + if (Ret) + goto err0; + + if (tx_cnt != 0xFFFFFFFF) { +#ifndef ATE_TXTHREAD + tx_cnt += TESTMODE_GET_PARAM(ATECtrl, control_band_idx, TxDoneCount); +#endif + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, TxCount, tx_cnt); + } + + /* Tx Frame */ + mode |= ATE_TXFRAME; + TESTMODE_SET_PARAM(ATECtrl, control_band_idx, Mode, mode); + + if (if_ops->test_frame_tx) + Ret = if_ops->test_frame_tx(pAd); + else { + MtATESetMacTxRx(pAd, ASIC_MAC_TX, FALSE, control_band_idx); + + for (Ring = 0; Ring < 2000; Ring++) + MT_ATETxPkt(pAd, control_band_idx); + + Ret = MT_ATETxControl(pAd, control_band_idx, NULL); + MtATESetMacTxRx(pAd, ASIC_MAC_TX, TRUE, control_band_idx); + } + + if (Ret) + goto err0; + + ATECtrl->did_tx = 1; +err1: + return Ret; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Err %d, wdev_idx:%x\n", __func__, Ret, wdev_idx)); + return Ret; +} +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + + + + +#ifdef RTMP_MAC_PCI +static INT32 pci_ate_init(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT ret = 0; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (!ATECtrl->pate_pkt) + ret = os_alloc_mem(pAd, (PUCHAR *)&ATECtrl->pate_pkt, ATE_TESTPKT_LEN); + + if (ret) + goto err0; + + RTMP_ASIC_INTERRUPT_ENABLE(pAd); + return NDIS_STATUS_SUCCESS; +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Allocate test packet fail at pakcet\n", __func__)); + return NDIS_STATUS_FAILURE; +} + + +static INT32 pci_clean_q(RTMP_ADAPTER *pAd) +{ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return NDIS_STATUS_SUCCESS; +} + +static INT32 pci_ate_leave(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + NICReadEEPROMParameters(pAd, NULL); + NICInitAsicFromEEPROM(pAd); + + if (ATECtrl->pate_pkt) { + os_free_mem(ATECtrl->pate_pkt); + ATECtrl->pate_pkt = NULL; + } + + return NDIS_STATUS_SUCCESS; +} +#endif + + + + +#ifdef RTMP_MAC_PCI +static UINT32 MT_TestModeIfOpInit_PCI(struct _ATE_IF_OPERATION *ATEIfOps) +{ + UINT32 Status = 0; + ATEIfOps->init = pci_ate_init; + ATEIfOps->clean_trx_q = pci_clean_q; + ATEIfOps->setup_frame = NULL; + ATEIfOps->test_frame_tx = NULL; + ATEIfOps->test_frame_rx = NULL; + ATEIfOps->ate_leave = pci_ate_leave; + return Status; +} + +#elif defined(RTMP_MAC_USB) +static UINT32 MT_TestModeIfOpInit_USB(struct _ATE_IF_OPERATION *ATEIfOps) +{ + UINT32 Status = 0; + ATEIfOps->init = usb_ate_init; + ATEIfOps->clean_trx_q = usb_clean_q; + ATEIfOps->setup_frame = usb_setup_frame; + ATEIfOps->test_frame_tx = usb_test_frame_tx; + ATEIfOps->test_frame_rx = usb_test_frame_rx; + ATEIfOps->ate_leave = usb_ate_leave; + return Status; +} +#elif defined(RTMP_MAC_SDIO) +static UINT32 MT_TestModeIfOpInit_SDIO( + struct _ATE_IF_OPERATION *ATEIfOps) +{ + UINT32 Status = 0; + ATEIfOps->init = sdio_ate_init; + ATEIfOps->clean_trx_q = sdio_clean_q; + ATEIfOps->setup_frame = sdio_setup_frame; + ATEIfOps->test_frame_tx = sdio_test_frame_tx; + ATEIfOps->test_frame_rx = NULL; + ATEIfOps->ate_leave = sdio_test_leave; + return Status; +} +#else +static UINT32 MT_TestModeIfOpInit_NotSupport(struct _ATE_IF_OPERATION *ATEIfOps) +{ + UINT32 Status = 0; + ATEIfOps->init = NULL; + ATEIfOps->clean_trx_q = NULL; + ATEIfOps->setup_frame = NULL; + ATEIfOps->test_frame_tx = NULL; + ATEIfOps->test_frame_rx = NULL; + ATEIfOps->ate_leave = NULL; + return Status; +} +#endif + + +static UINT32 MT_TestModeIfOpInit(RTMP_ADAPTER *pAd) +{ + UINT32 Status = 0; + struct _ATE_CTRL *AteCtrl = &pAd->ATECtrl; + struct _ATE_IF_OPERATION *ATEIfOps = NULL; + os_alloc_mem(pAd, (PUCHAR *)&ATEIfOps, sizeof(*ATEIfOps)); +#if defined(RTMP_MAC_PCI) + MT_TestModeIfOpInit_PCI(ATEIfOps); +#elif defined(RTMP_MAC_SDIO) + MT_TestModeIfOpInit_SDIO(ATEIfOps); +#elif defined(RTMP_MAC_USB) + MT_TestModeIfOpInit_USB(ATEIfOps); +#else + MT_TestModeIfOpInit_NotSupport(ATEIfOps); +#endif + AteCtrl->ATEIfOps = ATEIfOps; + return Status; +} + + +static UINT32 MT_TestModeOpInit(RTMP_ADAPTER *pAd) +{ + UINT32 Status = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *AteOp = NULL; + os_alloc_mem(pAd, (PUCHAR *)&AteOp, sizeof(*AteOp)); + AteOp->ATEStart = MT_ATEStart; + AteOp->ATEStop = MT_ATEStop; + AteOp->StartTx = MT_ATEStartTx; + AteOp->StartRx = MT_ATEStartRx; + AteOp->StopTx = MT_ATEStopTx; + AteOp->StopRx = MT_ATEStopRx; + AteOp->SetTxPower0 = MT_ATESetTxPower0; + AteOp->SetTxPower1 = MT_ATESetTxPower1; + AteOp->SetTxPower2 = MT_ATESetTxPower2; + AteOp->SetTxPower3 = MT_ATESetTxPower3; + AteOp->SetTxForceTxPower = MT_ATESetForceTxPower; + AteOp->SetTxPowerX = MT_ATESetTxPowerX; + AteOp->SetTxAntenna = MT_ATESetTxAntenna; + AteOp->SetRxAntenna = MT_ATESetRxAntenna; + AteOp->SetTxFreqOffset = MT_ATESetTxFreqOffset; + AteOp->GetTxFreqOffset = MT_ATEGetTxFreqOffset; + AteOp->SetChannel = MT_ATESetChannel; + AteOp->SetBW = MT_ATESetBW; + AteOp->SetDutyCycle = mt_ate_set_duty_cycle; + AteOp->SetPktTxTime = mt_ate_set_pkt_tx_time; +#ifdef PRE_CAL_MT7622_SUPPORT + AteOp->TxDPDTest7622 = MtATE_DPD_Cal_Store_Proc_7622; +#endif /*PRE_CAL_MT7622_SUPPORT*/ +#ifdef PRE_CAL_TRX_SET1_SUPPORT + AteOp->RxSelfTest = MtATE_DCOC_Cal_Store_Proc; + AteOp->TxDPDTest = MtATE_DPD_Cal_Store_Proc; +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ +#ifdef PRE_CAL_TRX_SET2_SUPPORT + AteOp->PreCalTest = MtATE_Pre_Cal_Proc; +#endif /* PRE_CAL_TRX_SET2_SUPPORT */ +#if !defined(COMPOS_TESTMODE_WIN)/* 1 todo RX_BLK */ + AteOp->SampleRssi = MT_ATESampleRssi; +#endif + AteOp->SetIPG = mt_ate_set_ipg; + AteOp->SetSlotTime = mt_ate_set_slot_time; + AteOp->SetAIFS = MT_ATESetAIFS; + AteOp->SetPowerDropLevel = MT_ATESetPowerDropLevel; + AteOp->SetTSSI = MT_ATESetTSSI; + AteOp->LowPower = MT_ATELowPower; + AteOp->SetDPD = MT_ATESetDPD; + AteOp->StartTxTone = MT_ATEStartTxTone; + AteOp->DBDCTxTone = MT_ATEDBDCTxTone; +#ifdef TXPWRMANUAL + AteOp->SetTxPwrManual = MT_ATESetTxPwrManual; +#endif + AteOp->SetDBDCTxTonePower = MT_ATESetDBDCTxTonePower; + AteOp->SetTxTonePower = MT_ATESetTxTonePower; + AteOp->TxCWTone = MT_ATETxCWTone; + AteOp->StopTxTone = MT_ATEStopTxTone; + AteOp->StartContinousTx = MT_ATEStartContinousTx; + AteOp->StopContinousTx = MT_ATEStopContinousTx; + AteOp->RfRegWrite = MT_RfRegWrite; + AteOp->RfRegRead = MT_RfRegRead; + AteOp->EfuseGetFreeBlock = MT_EfuseGetFreeBlock; + AteOp->GetFWInfo = MT_GetFWInfo; +#if defined(TXBF_SUPPORT) && defined(MT_MAC) + AteOp->SetATETxSoundingProc = MT_SetATESoundingProc; + AteOp->StartTxSKB = MT_ATEStartTxSKB; +#endif /* MT_MAC */ + AteOp->SetICapStart = MT_ATESetICapStart; + AteOp->GetICapStatus = MT_ATEGetICapStatus; + AteOp->GetICapIQData = MT_ATEGetICapIQData; + AteOp->MPSSetParm = MT_MPSSetParm, + AteOp->MPSTxStart = MT_MPSTxStart, + AteOp->MPSTxStop = MT_MPSTxStop, + AteOp->SetAutoResp = MT_ATESetAutoResp, + AteOp->SetFFTMode = MT_SetFFTMode, + AteOp->onOffRDD = MT_OnOffRDD, + AteOp->SetCfgOnOff = MT_ATESetCfgOnOff, + AteOp->GetCfgOnOff = MT_ATEGetCfgOnOff, + AteOp->SetRXFilterPktLen = MT_ATESetRXFilterPktLen, + AteOp->GetTxPower = MT_ATEGetTxPower, + AteOp->BssInfoUpdate = MT_ATEBssInfoUpdate, + AteOp->DevInfoUpdate = MT_ATEDevInfoUpdate, + AteOp->LogOnOff = MT_ATELogOnOff, + AteOp->SetAntennaPort = MT_ATESetAntennaPort, + AteOp->ClockSwitchDisable = MT_ATEFWPacketCMDClockSwitchDisable, + ATECtrl->ATEOp = AteOp; + return Status; +} + + +INT32 MtTestModeInit(RTMP_ADAPTER *pAd) +{ + INT32 Status = 0; + Status = MT_TestModeOpInit(pAd); + Status = MT_TestModeIfOpInit(pAd); + pAd->ATECtrl.pate_pkt = NULL; + RTMP_OS_TASK_INIT(&pAd->LbCtrl.LoopBackTxTask, "ATE_LoopBackTask", pAd); + /*Unify*/ +#ifdef RTMP_PCI_SUPPORT + + if (IS_PCI_INF(pAd)) + RTMP_OS_INIT_COMPLETION(&pAd->LbCtrl.LoopBackPCITxEvent); + +#endif + RTMP_OS_INIT_COMPLETION(&pAd->LbCtrl.LoopBackEvent); + os_zero_mem(&pAd->LbCtrl.LoopBackResult, sizeof(struct _LOOPBACK_RESULT)); + pAd->LbCtrl.DebugMode = FALSE; + pAd->LbCtrl.LoopBackRunning = FALSE; + pAd->LbCtrl.LoopBackWaitRx = FALSE; + pAd->LbCtrl.LoopBackUDMA = FALSE; + NdisAllocateSpinLock(pAd, &pAd->LbCtrl.LoopBackLock); +#ifdef ATE_TXTHREAD + pAd->ATECtrl.tx_thread[0].is_init = FALSE; +#endif + pAd->ATECtrl.pkt_skb = NULL; + return Status; +} + + +INT32 MtTestModeExit(RTMP_ADAPTER *pAd) +{ + UINT32 Status = 0; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *AteOp = NULL; + struct _ATE_IF_OPERATION *ATEIfOps = NULL; + AteOp = ATECtrl->ATEOp; + ATEIfOps = ATECtrl->ATEIfOps; + os_free_mem(ATEIfOps); + os_free_mem(AteOp); + +#ifdef RTMP_PCI_SUPPORT + + if (IS_PCI_INF(pAd)) + RTMP_OS_EXIT_COMPLETION(&pAd->LbCtrl.LoopBackPCITxEvent); + +#endif + RTMP_OS_EXIT_COMPLETION(&pAd->LbCtrl.LoopBackEvent); + NdisFreeSpinLock(&pAd->LbCtrl.LoopBackLock); + return Status; +} + + +INT32 MtATECh2Freq(UINT32 Channel, UINT32 band_idx) +{ + UINT32 Freq = 0; + + switch (band_idx) { + case 0: + if (Channel >= 1 && Channel <= 13) + Freq = 2407 + Channel * 5; + else if (Channel == 14) + Freq = 2484; + + break; + + case 1: + if (Channel >= 7 && Channel <= 181) + Freq = 5000 + Channel * 5; + else if (Channel >= 184 && Channel <= 196) + Freq = 4000 + Channel * 5; + else if (Channel == 6) + Freq = 5032; + else if (Channel == 182) + Freq = 4912; + else if (Channel == 183) + Freq = 4917; + + break; + + default: + break; + } + + return Freq; +} + + +INT32 MtATEGetTxPwrGroup(UINT32 Channel, UINT32 band_idx, UINT32 Ant_idx) +{ + UINT32 Group = 0; + UINT32 Freq = MtATECh2Freq(Channel, band_idx); + UINT32 i; + UINT32 NumOfMap = (sizeof(txpwr_group_map) / sizeof(struct _ATE_TXPWR_GROUP_MAP)); + + for (i = 0; i < NumOfMap; ++i) { + if (Freq > txpwr_group_map[i].start && Freq <= txpwr_group_map[i].end) { + Group = txpwr_group_map[i].group[Ant_idx]; + break; + } + } + + return Group; +} + +INT32 MtATERSSIOffset(PRTMP_ADAPTER pAd, INT32 rssi_orig, UINT32 ant_idx, INT32 ch_band) +{ + UCHAR rssi_offset = 0; + UINT32 *band_offset = NULL; + UINT32 offset = 0; + + if (ch_band > eeprom_rssi_offset.n_band - 1) + return rssi_orig; + + if (eeprom_rssi_offset.rssi_eeprom_band_offset[ch_band]) + band_offset = eeprom_rssi_offset.rssi_eeprom_band_offset[ch_band]; + else + return rssi_orig; + + if ((ant_idx > + eeprom_rssi_offset.n_band_offset[ch_band] - 1)) + return rssi_orig; + else if (band_offset[ant_idx] == 0) + return rssi_orig; + + offset = band_offset[ant_idx]; + rssi_offset = pAd->EEPROMImage[offset]; + + if (rssi_offset & (1 << 7) && rssi_offset != 0xFF) { + if (rssi_offset & (1 << 6)) + return rssi_orig + (rssi_offset & 0x3f); + else + return rssi_orig - (rssi_offset & 0x3f); + } + + return rssi_orig; +} +#ifdef PRE_CAL_MT7622_SUPPORT +INT MtATE_DPD_Cal_Store_Proc_7622(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 u4CalId; + UINT8 i = 0; + USHORT doCal1 = 0; + MT_SWITCH_CHANNEL_CFG ch_cfg; + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Currently not in FLASH or BIN MODE,return.\n", __func__)); + return FALSE; + } + /* set channel command , per group calibration - set to channel 7, BW20 */ + ch_cfg.Bw = BW_20; + ch_cfg.CentralChannel = 7; + ch_cfg.TxStream = 4; + ch_cfg.RxStream = 4; + ch_cfg.ControlChannel = 7; + ch_cfg.ControlChannel2 = 0; + ch_cfg.BandIdx = 0; + ch_cfg.bScan = 0; + MtCmdChannelSwitch(pAd, ch_cfg); + + pAd->bPreCalMode = TRUE; + /* Retest Recal - TXLPFG */ + u4CalId = TX_LPFG; + MtCmdRfTestRecal(pAd, u4CalId, TX_LPFG_RESP_LEN); + + /* Retest Recal - TXDCIQ */ + u4CalId = TX_DCIQC; + MtCmdRfTestRecal(pAd, u4CalId, TX_DCIQ_RESP_LEN); + + pAd->TxDpdCalOfst = 0; + RTMPZeroMemory(pAd->CalTXDPDImage, CAL_TXDPD_SIZE); + + /* Retest Recal - TXDPD */ + for (i = 1; i <= 14; i++) { + ch_cfg.CentralChannel = i; + ch_cfg.ControlChannel = i; + MtCmdChannelSwitch(pAd, ch_cfg); + u4CalId = TX_DPD_LINK; + MtCmdRfTestRecal(pAd, u4CalId, TX_DPD_LINK_RESP_LEN); + } + + /* raise DoCalibrate bits */ + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_ee_bin_read16(pAd, 0x52, &doCal1); + +#ifdef RTMP_FLASH_SUPPORT + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + rtmp_ee_flash_read(pAd, 0x52, &doCal1); +#endif + /* raise bit3 */ + doCal1 |= (1 << 3); + if (pAd->E2pAccessMode == E2P_BIN_MODE) { + rtmp_ee_bin_write16(pAd, 0x52, doCal1); + rtmp_ee_write_to_bin(pAd); /* writeback to eeprom file */ + } +#ifdef RTMP_FLASH_SUPPORT + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + rtmp_ee_flash_write(pAd, 0x52, doCal1); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("raised E2P 0x52 = %x\n", doCal1)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("====================\n")); + pAd->bPreCalMode = FALSE; + return TRUE; +} +#endif /* PRE_CAL_MT7622_SUPPORT */ + +#ifdef PRE_CAL_TRX_SET1_SUPPORT +INT MtATE_DPD_Cal_Store_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + ULONG x = simple_strtol(arg, 0, 10); + TXDPD_RESULT_T TxDpdResult; + BOOLEAN toCR = FALSE; /* CR to Flash/Bin file */ + UINT16 CentralFreq = 0; + UINT8 BW = 0; + UINT8 i = 0; + UINT8 j = 0; + ULONG CalOffset = 0; + USHORT doCal1 = 0; + UINT8 RetryTimes = 5; + BOOLEAN DPDPassOrFail = TRUE; + BOOLEAN kABand = TRUE; + BOOLEAN kGBand = TRUE; + + if (x == 0) { /* 2G */ + kABand = FALSE; + kGBand = TRUE; + } else if (x == 1) { /* 5G */ + kABand = TRUE; + kGBand = FALSE; + } else { /* all K */ + kABand = TRUE; + kGBand = TRUE; + } + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Currently not in FLASH or BIN MODE,return.\n", __func__)); + return FALSE; + } + /* Stop TX RX MAC */ + SetATE(pAd, "TXSTOP"); + SetATE(pAd, "RXSTOP"); + + /* TXDPD ABand */ + if (kABand) { + RTMPZeroMemory(pAd->CalDPDAPart1Image, TXDPD_IMAGE1_SIZE); + + /* TXDPD A20 */ + for (i = 0; i < DPD_A20_SIZE; i++) { + BW = BW_20; + CentralFreq = DPD_A20Freq[i]; + CalOffset = i * TXDPD_SIZE; + + for (j = 0; j < RetryTimes; j++) { + RTMPZeroMemory(&TxDpdResult, sizeof(TXDPD_RESULT_T)); + MtCmdGetTXDPDCalResult(pAd, toCR, CentralFreq, BW, ABAND, FALSE, FALSE, &TxDpdResult); + RtmpusecDelay(10); + + if (TxDpdResult.ResultSuccess) + break; + } + + if (TxDpdResult.ResultSuccess) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("==========TX A20 P1 freq %d save to flash offset %lx ========\n", CentralFreq, DPDPART1_OFFSET + CalOffset)); + ShowDPDData(pAd, TxDpdResult); + memcpy(pAd->CalDPDAPart1Image + CalOffset, &TxDpdResult.u4DPDG0_WF0_Prim, TXDPD_SIZE); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("!!!!!! A20 freq %d TX still failed after %d retries !!!!!!!!\n", CentralFreq, RetryTimes)); + DPDPassOrFail = FALSE; + goto exit; + } + } + +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + RtmpFlashWrite(pAd->hdev_ctrl, pAd->CalDPDAPart1Image, + get_dev_eeprom_offset(pAd) + DPDPART1_OFFSET, TXDPD_PART1_LIMIT * TXDPD_SIZE); + +#endif + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_cal_write_to_bin(pAd, pAd->CalDPDAPart1Image, DPDPART1_OFFSET, TXDPD_PART1_LIMIT * TXDPD_SIZE); + + RtmpusecDelay(20000); + } + /* TXDPD G20 */ + if (kGBand) { + RTMPZeroMemory(pAd->CalDPDAPart2Image, TXDPD_IMAGE2_SIZE); + + for (i = 0; i < DPD_G20_SIZE; i++) { + BW = BW_20; + CentralFreq = DPD_G20Freq[i]; + CalOffset = i * TXDPD_SIZE; + + for (j = 0; j < RetryTimes; j++) { + RTMPZeroMemory(&TxDpdResult, sizeof(TXDPD_RESULT_T)); + MtCmdGetTXDPDCalResult(pAd, toCR, CentralFreq, BW, GBAND, FALSE, FALSE, &TxDpdResult); + RtmpusecDelay(10); + + if (TxDpdResult.ResultSuccess) + break; + } + + if (TxDpdResult.ResultSuccess) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("==========TX G20 freq %d save to flash offset %lx ========\n", CentralFreq, DPDPART1_OFFSET + DPD_A20_SIZE * TXDPD_SIZE + CalOffset)); + ShowDPDData(pAd, TxDpdResult); + memcpy(pAd->CalDPDAPart2Image + CalOffset, &TxDpdResult.u4DPDG0_WF0_Prim, TXDPD_SIZE); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("!!!!!! G20 freq %d TX still failed after %d retries !!!!!!!!\n", CentralFreq, RetryTimes)); + DPDPassOrFail = FALSE; + goto exit; + } + } + +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + RtmpFlashWrite(pAd->hdev_ctrl, pAd->CalDPDAPart2Image, + get_dev_eeprom_offset(pAd) + DPDPART2_OFFSET, (DPD_G20_SIZE * TXDPD_SIZE)); + +#endif + + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_cal_write_to_bin(pAd, pAd->CalDPDAPart2Image, DPDPART2_OFFSET, (DPD_G20_SIZE * TXDPD_SIZE)); + } + + /* raise DoCalibrate bits */ + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_ee_bin_read16(pAd, 0x52, &doCal1); + +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + rtmp_ee_flash_read(pAd, 0x52, &doCal1); + +#endif + doCal1 |= (1 << 0); + /* raise bit 4 to denote 16 entry TXDPD */ + doCal1 |= (1 << 4); + + if (pAd->E2pAccessMode == E2P_BIN_MODE) { + rtmp_ee_bin_write16(pAd, 0x52, doCal1); + rtmp_ee_write_to_bin(pAd); /* writeback to eeprom file */ + } + +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + rtmp_ee_flash_write(pAd, 0x52, doCal1); + +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("raised E2P 0x52 = %x\n", doCal1)); + + /* reload test -- for debug only */ + if (pAd->KtoFlashDebug) { + ULONG CalOffset = 0; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n######################### reload caldata for debug ####################################\n")); + RtmpusecDelay(20000); + +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) { + RtmpFlashRead(pAd->hdev_ctrl, pAd->CalDPDAPart1Image, + get_dev_eeprom_offset(pAd) + DPDPART1_OFFSET, TXDPD_IMAGE1_SIZE); + RtmpFlashRead(pAd->hdev_ctrl, pAd->CalDPDAPart2Image, + get_dev_eeprom_offset(pAd) + DPDPART2_OFFSET, TXDPD_IMAGE2_SIZE); + } +#endif + + if (pAd->E2pAccessMode == E2P_BIN_MODE) { + rtmp_cal_load_from_bin(pAd, pAd->CalDPDAPart1Image, DPDPART1_OFFSET, TXDPD_IMAGE1_SIZE); + rtmp_cal_load_from_bin(pAd, pAd->CalDPDAPart2Image, DPDPART2_OFFSET, TXDPD_IMAGE2_SIZE); + } + + /* Find flash offset base on CentralFreq */ + for (i = 0; i < DPD_ALL_SIZE; i++) { + CalOffset = i * TXDPD_SIZE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: reload flash offset [%lx] freq [%d]=================\n", + __func__, CalOffset + DPDPART1_OFFSET, DPD_AllFreq[i])); + + if (i < DPD_A20_SIZE) + memcpy(&TxDpdResult.u4DPDG0_WF0_Prim, pAd->CalDPDAPart1Image + CalOffset, TXDPD_SIZE); + else { + CalOffset = (i - DPD_A20_SIZE) * TXDPD_SIZE; + memcpy(&TxDpdResult.u4DPDG0_WF0_Prim, pAd->CalDPDAPart2Image + CalOffset, TXDPD_SIZE); + } + + ShowDPDData(pAd, TxDpdResult); + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("raised E2P 0x52 = %x\n", doCal1)); +exit: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("====================\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("TX_SELF_TEST : [%s]\n", + (DPDPassOrFail == TRUE) ? "PASS" : "FAIL")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("====================\n")); + return TRUE; +} + + +INT MtATE_DCOC_Cal_Store_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + ULONG x = simple_strtol(arg, 0, 10); + RXDCOC_RESULT_T RxDcocResult; + BOOLEAN toCR = FALSE; + UINT16 CentralFreq = 0; + UINT8 BW = 0; + UINT8 i = 0; + UINT8 j = 0; + ULONG CalOffset = 0; + USHORT doCal1 = 0; + UINT8 RetryTimes = 5; + BOOLEAN DCOCPassOrFail = TRUE; + BOOLEAN kABand = TRUE; + BOOLEAN kGBand = TRUE; + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Currently not in FLASH or BIN MODE,return.\n", + __func__)); + return FALSE; + } + + RTMPZeroMemory(pAd->CalDCOCImage, DCOC_IMAGE_SIZE); + + if (x == 0) { /* 2G */ + kABand = FALSE; + kGBand = TRUE; + } else if (x == 1) { /* 5G */ + kABand = TRUE; + kGBand = FALSE; + } else { /* all K */ + kABand = TRUE; + kGBand = TRUE; + } + /* Disable RMAC */ + MtATESetMacTxRx(pAd, ASIC_MAC_RX, FALSE, TESTMODE_BAND0); + if (IS_ATE_DBDC(pAd)) + MtATESetMacTxRx(pAd, ASIC_MAC_RX, FALSE, TESTMODE_BAND1); + + /* RXDCOC ABand */ + if (kABand) { + for (i = 0; i < K_A20_SIZE; i++) { + BW = BW_20; + CentralFreq = K_A20Freq[i]; + CalOffset = i * RXDCOC_SIZE; + + for (j = 0; j < RetryTimes; j++) { + RTMPZeroMemory(&RxDcocResult, sizeof(RXDCOC_RESULT_T)); + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, BW, ABAND, FALSE, FALSE, &RxDcocResult); + RtmpusecDelay(10); + + if (RxDcocResult.ResultSuccess) + break; + } + + if (RxDcocResult.ResultSuccess) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("========== A20 freq %d save to offset %lx ========\n", + CentralFreq, DCOC_OFFSET + CalOffset)); + ShowDCOCData(pAd, RxDcocResult); + memcpy(pAd->CalDCOCImage + CalOffset, &RxDcocResult.ucDCOCTBL_I_WF0_SX0_LNA[0], RXDCOC_SIZE); + } else { + ShowDCOCData(pAd, RxDcocResult); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("!!!!!! A20 freq %d RX still failed after %d retries !!!!!!!!\n", CentralFreq, RetryTimes)); + DCOCPassOrFail = FALSE; + goto exit; + } + } + + for (i = 0; i < K_A40_SIZE; i++) { + BW = BW_40; + CentralFreq = K_A40Freq[i]; + CalOffset = (K_A20_SIZE + i) * RXDCOC_SIZE; + + for (j = 0; j < RetryTimes; j++) { + RTMPZeroMemory(&RxDcocResult, sizeof(RXDCOC_RESULT_T)); + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, BW, ABAND, FALSE, FALSE, &RxDcocResult); + RtmpusecDelay(10); + + if (RxDcocResult.ResultSuccess) + break; + } + + if (RxDcocResult.ResultSuccess) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("========== A40 freq %d save to offset %lx ========\n", + CentralFreq, DCOC_OFFSET + CalOffset)); + ShowDCOCData(pAd, RxDcocResult); + memcpy(pAd->CalDCOCImage + CalOffset, &RxDcocResult.ucDCOCTBL_I_WF0_SX0_LNA[0], RXDCOC_SIZE); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("!!!!!! A40 freq %d RX still failed after %d retries !!!!!!!!\n", CentralFreq, RetryTimes)); + DCOCPassOrFail = FALSE; + goto exit; + } + } + + for (i = 0; i < K_A80_SIZE; i++) { + BW = BW_80; + CentralFreq = K_A80Freq[i]; + CalOffset = (K_A20_SIZE + K_A40_SIZE + i) * RXDCOC_SIZE; + + for (j = 0; j < RetryTimes; j++) { + RTMPZeroMemory(&RxDcocResult, sizeof(RXDCOC_RESULT_T)); + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, BW, ABAND, FALSE, FALSE, &RxDcocResult); + RtmpusecDelay(10); + + if (RxDcocResult.ResultSuccess) + break; + } + + if (RxDcocResult.ResultSuccess) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("========== A80 freq %d save to offset %lx ========\n", CentralFreq, DCOC_OFFSET + CalOffset)); + ShowDCOCData(pAd, RxDcocResult); + memcpy(pAd->CalDCOCImage + CalOffset, &RxDcocResult.ucDCOCTBL_I_WF0_SX0_LNA[0], RXDCOC_SIZE); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("!!!!!! A80 freq %d RX still failed after %d retries !!!!!!!!\n", CentralFreq, RetryTimes)); + DCOCPassOrFail = FALSE; + goto exit; + } + } + } + + /* RXDCOC GBand */ + if (kGBand) { + for (i = 0; i < K_G20_SIZE; i++) { + BW = BW_20; + CentralFreq = K_G20Freq[i]; + CalOffset = (K_A20_SIZE + K_A40_SIZE + K_A80_SIZE + i) * RXDCOC_SIZE; + + for (j = 0; j < RetryTimes; j++) { + RTMPZeroMemory(&RxDcocResult, sizeof(RXDCOC_RESULT_T)); + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, BW, GBAND, FALSE, FALSE, &RxDcocResult); + RtmpusecDelay(10); + + if (RxDcocResult.ResultSuccess) + break; + } + + if (RxDcocResult.ResultSuccess) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("========== G20 freq %d save to offset %lx ========\n", CentralFreq, DCOC_OFFSET + CalOffset)); + ShowDCOCData(pAd, RxDcocResult); + memcpy(pAd->CalDCOCImage + CalOffset, &RxDcocResult.ucDCOCTBL_I_WF0_SX0_LNA[0], RXDCOC_SIZE); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("!!!!!! G20 freq %d RX still failed after %d retries !!!!!!!!\n", CentralFreq, RetryTimes)); + DCOCPassOrFail = FALSE; + goto exit; + } + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("========== save to offset %x size %d========\n", +#ifdef RTMP_FLASH_SUPPORT + get_dev_eeprom_offset(pAd) + +#endif + DCOC_OFFSET, (K_ALL_SIZE * RXDCOC_SIZE))); +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + RtmpFlashWrite(pAd->hdev_ctrl, pAd->CalDCOCImage, + get_dev_eeprom_offset(pAd) + DCOC_OFFSET, (K_ALL_SIZE * RXDCOC_SIZE)); + +#endif + + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_cal_write_to_bin(pAd, pAd->CalDCOCImage, DCOC_OFFSET, (K_ALL_SIZE * RXDCOC_SIZE)); + + /* raise DoCalibrate bits */ +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + rtmp_ee_flash_read(pAd, 0x52, &doCal1); + +#endif + + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_ee_bin_read16(pAd, 0x52, &doCal1); + + doCal1 |= (1 << 1); +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + rtmp_ee_flash_write(pAd, 0x52, doCal1); + +#endif + + if (pAd->E2pAccessMode == E2P_BIN_MODE) { + rtmp_ee_bin_write16(pAd, 0x52, doCal1); + rtmp_ee_write_to_bin( + pAd); /* XXX: remember to writeback modified eeprom to file */ + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("raised E2P 0x52 = %x\n", doCal1)); + + if (pAd->KtoFlashDebug) { + ULONG CalOffset = 0; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("######################### reload caldata for debug ####################################\n")); + RtmpusecDelay(20000); +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + RtmpFlashRead(pAd->hdev_ctrl, pAd->CalDCOCImage, + get_dev_eeprom_offset(pAd) + DCOC_OFFSET, (K_ALL_SIZE * RXDCOC_SIZE)); + +#endif + + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_cal_load_from_bin(pAd, pAd->CalDCOCImage, DCOC_OFFSET, (K_ALL_SIZE * RXDCOC_SIZE)); + + /* Find offset base on CentralFreq */ + for (i = 0; i < K_ALL_SIZE; i++) { + CalOffset = i * RXDCOC_SIZE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: reload from offset [%lx] freq [%d]=================\n", + __func__, CalOffset + DCOC_OFFSET, K_AllFreq[i])); + memcpy(&RxDcocResult.ucDCOCTBL_I_WF0_SX0_LNA[0], + pAd->CalDCOCImage + CalOffset, RXDCOC_SIZE); + ShowDCOCData(pAd, RxDcocResult); + } + } + +exit: + /* Enable RMAC */ + MtATESetMacTxRx(pAd, ASIC_MAC_RX, TRUE, TESTMODE_BAND0); + if (IS_ATE_DBDC(pAd)) + MtATESetMacTxRx(pAd, ASIC_MAC_RX, TRUE, TESTMODE_BAND1); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("====================\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RX_SELF_TEST : [%s]\n", + (DCOCPassOrFail == TRUE) ? "PASS" : "FAIL")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("====================\n")); + return TRUE; +} +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ + +#ifdef PRE_CAL_TRX_SET2_SUPPORT +INT MtATE_Pre_Cal_Proc(RTMP_ADAPTER *pAd, UINT8 CalId, UINT32 ChGrpId) +{ + INT32 ret = NDIS_STATUS_SUCCESS; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Cal Id = %d, ChGrpId = %d\n", __func__, CalId, ChGrpId)); + /* Initialization */ + pAd->PreCalWriteOffSet = 0; + pAd->ChGrpMap = PreCalGroupList[ChGrpId]; + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) { + pAd->PreCalStoreBuffer = pAd->EEPROMImage + PRECALPART_OFFSET; + } else { + ret = os_alloc_mem(pAd, &pAd->PreCalStoreBuffer, PRE_CAL_SIZE); + + if (ret != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\x1b[42m %s : Not enough memory for pre-cal stored buffer!!\x1b[m\n", __func__)); + } + } + + if (ret == NDIS_STATUS_SUCCESS) + MtCmdGetPreCalResult(pAd, PreCalItemList[CalId], PreCalGroupList[ChGrpId]); + + return TRUE; +} +#endif/* PRE_CAL_TRX_SET2_SUPPORT */ + +INT32 MtATETssiTrainingProc(RTMP_ADAPTER *pAd, UCHAR ucBW, UCHAR ucBandIdx) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 ret = 0; + + /* only applu TSSI Training for MT7615 */ + if (IS_MT7615(pAd)) { + if (ucBW == BW_8080 || ucBW == BW_160) { + /* Check iPA or ePA status */ + MtEPAcheck(pAd); + + /* TSSI Training only for IPA case */ + if (!pAd->fgEPA) { + UCHAR PerPktBW, PhyMode, Mcs, Nss; + UINT32 TxLength; + + /* Backup parameters for Phymode, BW, Rate, VHTNss, TxLength */ + PerPktBW = TESTMODE_GET_PARAM(ATECtrl, ucBandIdx, PerPktBW); + PhyMode = TESTMODE_GET_PARAM(ATECtrl, ucBandIdx, PhyMode); + Mcs = TESTMODE_GET_PARAM(ATECtrl, ucBandIdx, Mcs); + Nss = TESTMODE_GET_PARAM(ATECtrl, ucBandIdx, Nss); + TxLength = TESTMODE_GET_PARAM(ATECtrl, ucBandIdx, TxLength); + + /* Config TSSI Tracking enable */ + MtATETSSITracking(pAd, TRUE); + /* Config FCBW ON */ + MtATEFCBWCfg(pAd, TRUE); + /* Config DBW 80MHz */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, PerPktBW, BW_80); + /* Config VHT mode */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, PhyMode, MODE_VHT); + /* Config MCS rate */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, Mcs, MCS_9); + /* Config 4 Nss */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, Nss, 4); + /* Config Tx packet length */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, TxLength, 100); + /* Start Tx for 25ms */ + ATEOp->StartTx(pAd); + RtmpOsMsDelay(25); + /* Stop Tx */ + ATEOp->StopTx(pAd); + /* Save compensation value to Global variable (FCBW on case) */ + MtTSSICompBackup(pAd, TRUE); + /* Config FCBW OFF */ + MtATEFCBWCfg(pAd, FALSE); + /* Config DBW 160MHz */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, PerPktBW, BW_160); + /* Config VHT mode */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, PhyMode, MODE_VHT); + /* Config MCS rate */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, Mcs, MCS_9); + /* Config 2 Nss */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, Nss, 2); + /* Config Tx packet length */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, TxLength, 100); + /* Start Tx for 25ms */ + ATEOp->StartTx(pAd); + RtmpOsMsDelay(25); + /* Stop Tx */ + ATEOp->StopTx(pAd); + /* Save compensation value to Global variable (FCBW off case) */ + MtTSSICompBackup(pAd, FALSE); + /* Config Compensation CR */ + MtTSSICompCfg(pAd); + /* Config TSSI Tracking disable */ + MtATETSSITracking(pAd, FALSE); + /* Config FCBW ON */ + MtATEFCBWCfg(pAd, TRUE); + + /* Resotre paratemters for Phymode, BW, Rate, VHTNss, TxLength */ + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, PerPktBW, PerPktBW); + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, PhyMode, PhyMode); + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, Mcs, Mcs); + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, Nss, Nss); + TESTMODE_SET_PARAM(ATECtrl, ucBandIdx, TxLength, TxLength); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: TSSI Training Done!!\n", __func__)); + } + } + } + + return ret; +} diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode_dmac.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode_dmac.c new file mode 100644 index 000000000..6b5ae51a5 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode_dmac.c @@ -0,0 +1,214 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + Module Name: + mt_testmode_dmac.c + +*/ + +#ifdef COMPOS_TESTMODE_WIN +#include "config.h" +#else +#include "rt_config.h" +#endif + + +INT mt_ate_mac_cr_restore(RTMP_ADAPTER *pAd) +{ +#if defined(MT7615) || defined(MT7622) + if (IS_MT7615(pAd) || IS_MT7622(pAd)) { + /* Data frame protection CR recover */ + MtTestModeRestoreCr(pAd, AGG_PCR); + /* RTS threshold CR recover */ + MtTestModeRestoreCr(pAd, AGG_PCR1); +#ifdef DBDC_MODE + if (IS_ATE_DBDC(pAd)) { + MtTestModeRestoreCr(pAd, AGG_PCR2); + } +#endif /* DBDC_MODE */ + /* BA related CR recover */ + MtTestModeRestoreCr(pAd, AGG_AALCR0); + MtTestModeRestoreCr(pAd, AGG_AALCR1); + MtTestModeRestoreCr(pAd, AGG_AALCR2); + MtTestModeRestoreCr(pAd, AGG_AALCR3); + MtTestModeRestoreCr(pAd, AGG_AWSCR0); + MtTestModeRestoreCr(pAd, AGG_AWSCR1); + /* Station pause CR recover */ + MtTestModeRestoreCr(pAd, STATION_PAUSE0); + MtTestModeRestoreCr(pAd, STATION_PAUSE1); + MtTestModeRestoreCr(pAd, STATION_PAUSE2); + MtTestModeRestoreCr(pAd, STATION_PAUSE3); + /* Enable HW BAR feature */ + MtTestModeRestoreCr(pAd, AGG_MRCR); + /* IPG related CR recover */ + MtTestModeRestoreCr(pAd, TMAC_TRCR0); + MtTestModeRestoreCr(pAd, TMAC_ICR_BAND_0); + MtTestModeRestoreCr(pAd, ARB_DRNGR0); + MtTestModeRestoreCr(pAd, ARB_DRNGR1); + MtTestModeRestoreCr(pAd, ARB_WMMAC01); + MtTestModeRestoreCr(pAd, ARB_WMMAC11); + MtTestModeRestoreCr(pAd, ARB_WMMAC21); + MtTestModeRestoreCr(pAd, ARB_WMMAC31); + MtTestModeRestoreCr(pAd, ARB_WMMALTX0); +#ifdef DBDC_MODE + if (IS_ATE_DBDC(pAd)) { + MtTestModeRestoreCr(pAd, TMAC_TRCR1); + MtTestModeRestoreCr(pAd, TMAC_ICR_BAND_1); + MtTestModeRestoreCr(pAd, ARB_WMMALTX1); + } +#endif /* DBDC_MODE */ + } +#endif /* defined(MT7615) || defined(MT7622) */ + + return 0; +} + + +INT mt_ate_mac_cr_backup_and_set(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + + NdisZeroMemory(&ATECtrl->bk_cr, sizeof(struct _TESTMODE_BK_CR)*MAX_TEST_BKCR_NUM); +#if defined(MT7615) || defined(MT7622) + /* TODO: check if following operation also need to do for other chips */ + if (IS_MT7615(pAd) || IS_MT7622(pAd)) { + UINT32 val = 0; + /* Enable data frame protection for test mode */ + MtTestModeBkCr(pAd, AGG_PCR, TEST_MAC_BKCR); + MAC_IO_READ32(pAd, AGG_PCR, &val); + val = 0x80008; + MAC_IO_WRITE32(pAd, AGG_PCR, val); + /* RTS threshold need to change to 1 for test mode */ + MtTestModeBkCr(pAd, AGG_PCR1, TEST_MAC_BKCR); + MAC_IO_READ32(pAd, AGG_PCR1, &val); + /* val &= 0x0FFFFFFF; */ + /* val |= 0x10000000; */ + /* Setting RTS threshold to max value to aviod send RTS in test mode */ + val = 0xFE0FFFFF; + MAC_IO_WRITE32(pAd, AGG_PCR1, val); +#ifdef DBDC_MODE + /* RTS threshold disable for band1 */ + if (IS_ATE_DBDC(pAd)) { + MtTestModeBkCr(pAd, AGG_PCR2, TEST_MAC_BKCR); + MAC_IO_READ32(pAd, AGG_PCR2, &val); + val = 0xFE0FFFFF; + MAC_IO_WRITE32(pAd, AGG_PCR2, val); + } +#endif /* DBDC_MODE */ + /* BA related CR backup */ + MtTestModeBkCr(pAd, AGG_AALCR0, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, AGG_AALCR1, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, AGG_AALCR2, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, AGG_AALCR3, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, AGG_AWSCR0, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, AGG_AWSCR1, TEST_MAC_BKCR); + /* Station pause CR backup for TX after reset WTBL */ + MtTestModeBkCr(pAd, STATION_PAUSE0, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, STATION_PAUSE1, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, STATION_PAUSE2, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, STATION_PAUSE3, TEST_MAC_BKCR); + /* HW BAR feature */ + MtTestModeBkCr(pAd, AGG_MRCR, TEST_MAC_BKCR); + MAC_IO_READ32(pAd, AGG_MRCR, &val); + val &= ~BAR_TX_CNT_LIMIT_MASK; + val |= BAR_TX_CNT_LIMIT(0); + MAC_IO_WRITE32(pAd, AGG_MRCR, val); + /* IPG related CR back up */ + MtTestModeBkCr(pAd, TMAC_TRCR0, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, TMAC_ICR_BAND_0, TEST_MAC_BKCR); /* IFS CR, for SIFS/SLOT time control */ + MtTestModeBkCr(pAd, ARB_DRNGR0, TEST_MAC_BKCR); /* For fixing backoff random number */ + MtTestModeBkCr(pAd, ARB_DRNGR1, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, ARB_WMMAC01, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, ARB_WMMAC11, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, ARB_WMMAC21, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, ARB_WMMAC31, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, ARB_WMMALTX0, TEST_MAC_BKCR); +#ifdef DBDC_MODE + if (IS_ATE_DBDC(pAd)) { + MtTestModeBkCr(pAd, TMAC_TRCR1, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, TMAC_ICR_BAND_1, TEST_MAC_BKCR); + MtTestModeBkCr(pAd, ARB_WMMALTX1, TEST_MAC_BKCR); + } +#endif /* DBDC_MODE */ + } +#endif /* defined(MT7615) || defined(MT7622) */ + return 0; +} + + +UINT32 agg_cnt_array[] = {AGG_AALCR0, AGG_AALCR1, AGG_AALCR2, AGG_AALCR3}; +INT mt_ate_ampdu_ba_limit(RTMP_ADAPTER *pAd, UINT32 band_idx, UINT8 agg_limit) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 value; + INT wdev_idx = 0; + UCHAR WmmIdx = 0xFF; +#if !defined(COMPOS_TESTMODE_WIN) + struct wifi_dev *pWdev = NULL; + + wdev_idx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wdev_idx); + pWdev = pAd->wdev_list[wdev_idx]; + + if (pWdev) { + WmmIdx = TESTMODE_GET_PARAM(ATECtrl, band_idx, wmm_idx); + + if (WmmIdx > 3) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: wdev_idx=%d, invalid WmmIdx=%d, reset to 0!\n", + __func__, wdev_idx, WmmIdx)); + WmmIdx = 0xFF; + } + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: invalid WDEV, reset WmmIdx to 0!\n", __func__)); + WmmIdx = 0xFF; + } + +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: wdev_idx=%d, WmmIdx=%d\n", + __func__, wdev_idx, WmmIdx)); + value = ((agg_limit & 0x3F) << 24) + | ((agg_limit & 0x3F) << 16) + | ((agg_limit & 0x3F) << 8) + | ((agg_limit & 0x3F) << 0); + + if (WmmIdx <= 3) + MAC_IO_WRITE32(pAd, agg_cnt_array[WmmIdx], value); + else { + MAC_IO_WRITE32(pAd, AGG_AALCR0, value); + MAC_IO_WRITE32(pAd, AGG_AALCR1, value); + MAC_IO_WRITE32(pAd, AGG_AALCR2, value); + MAC_IO_WRITE32(pAd, AGG_AALCR3, value); + } + + value = 0x0; + MAC_IO_WRITE32(pAd, AGG_AWSCR0, value); + + return 0; +} + + +INT mt_ate_set_sta_pause_cr(RTMP_ADAPTER *pAd, UINT32 band_idx) +{ + INT32 ret = 0; + UINT32 value; + + /* Set station pause CRs to 0 for TX after reset WTBL */ + /* The CR meaning in normal mode is that stop to TX packet when STA disconnect */ + value = 0x0; + MAC_IO_WRITE32(pAd, STATION_PAUSE0, value); + MAC_IO_WRITE32(pAd, STATION_PAUSE1, value); + MAC_IO_WRITE32(pAd, STATION_PAUSE2, value); + MAC_IO_WRITE32(pAd, STATION_PAUSE3, value); + + return ret; +} diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode_smac.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode_smac.c new file mode 100644 index 000000000..972ae9e80 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/mt_mac/mt_testmode_smac.c @@ -0,0 +1,56 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + Module Name: + mt_testmode_smac.c + +*/ + +#ifdef COMPOS_TESTMODE_WIN +#include "config.h" +#else +#include "rt_config.h" +#endif + + +INT mt_ate_mac_cr_restore(RTMP_ADAPTER *pAd) +{ + /* Data frame protection CR recover */ + MtTestModeRestoreCr(pAd, AGG_PCR); + /* RTS threshold CR recover */ + MtTestModeRestoreCr(pAd, AGG_PCR1); + + return 0; +} + + +INT mt_ate_mac_cr_backup_and_set(RTMP_ADAPTER *pAd) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + UINT32 val = 0; + + NdisZeroMemory(&ATECtrl->bk_cr, sizeof(struct _TESTMODE_BK_CR)*MAX_TEST_BKCR_NUM); + /* Enable data frame protection for test mode */ + MtTestModeBkCr(pAd, AGG_PCR, TEST_MAC_BKCR); + MAC_IO_READ32(pAd, AGG_PCR, &val); + val = 0x80008; + MAC_IO_WRITE32(pAd, AGG_PCR, val); + /* RTS threshold need to change to 1 for test mode */ + MtTestModeBkCr(pAd, AGG_PCR1, TEST_MAC_BKCR); + MAC_IO_READ32(pAd, AGG_PCR1, &val); + /* val &= 0x0FFFFFFF; */ + /* val |= 0x10000000; */ + /* Setting RTS threshold to max value to aviod send RTS in test mode */ + val = 0xFE0FFFFF; + MAC_IO_WRITE32(pAd, AGG_PCR1, val); + + return 0; +} diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/qa_agent.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/qa_agent.c new file mode 100644 index 000000000..1f1b30302 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/qa_agent.c @@ -0,0 +1,1806 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + qa_agent.c +*/ + +#include "rt_config.h" + +static INT ResponseToQA( + struct _HQA_CMD_FRAME *HqaCmdFrame, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + INT32 Length, + INT32 Status) +{ + HqaCmdFrame->Length = OS_HTONS((Length)); + Status = OS_HTONS((Status)); + memcpy(HqaCmdFrame->Data, &Status, 2); + WRQ->u.data.length = sizeof((HqaCmdFrame)->MagicNo) + sizeof((HqaCmdFrame)->Type) + + sizeof((HqaCmdFrame)->Id) + sizeof((HqaCmdFrame)->Length) + + sizeof((HqaCmdFrame)->Sequence) + OS_NTOHS((HqaCmdFrame)->Length); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WRQ->u.data.length = %d\n", WRQ->u.data.length)); + + if (copy_to_user(WRQ->u.data.pointer, (UCHAR *)(HqaCmdFrame), WRQ->u.data.length)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("copy_to_user() fail in %s\n", __func__)); + return -EFAULT; + } + + return 0; +} + + +static INT32 HQA_OpenAdapter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->bQAEnabled = TRUE; + /* Prepare feedback as soon as we can to avoid QA timeout. */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + Ret = ATEOp->ATEStart(pAd); + return Ret; +} + + +static INT32 HQA_CloseAdapter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->bQAEnabled = FALSE; + /* Prepare feedback as soon as we can to avoid QA timeout. */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + Ret = ATEOp->ATEStop(pAd); + return Ret; +} + + +static INT32 HQA_StartTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 TxCount; + UINT16 TxLength; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&TxCount, HqaCmdFrame->Data, 4); + TxCount = OS_NTOHL(TxCount); + memcpy(&TxLength, HqaCmdFrame->Data + 4, 2); + TxLength = OS_NTOHS(TxLength); + + if (TxCount == 0) + ATECtrl->TxCount = 0xFFFFFFFF; + else + ATECtrl->TxCount = TxCount; + + ATECtrl->TxLength = TxLength; + ATECtrl->bQATxStart = TRUE; + Ret = ATEOp->StartTx(pAd); + + if (ATECtrl->bQATxStart == TRUE) + ATECtrl->TxStatus = 1; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StartTxExt( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + + +static INT32 HQA_StartTxContiTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StartTxCarrier( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StartRx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->bQARxStart = TRUE; + Ret = ATEOp->StartRx(pAd); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 Mode; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Mode = ATECtrl->Mode; + ATECtrl->Mode &= ATE_TXSTOP; + ATECtrl->bQATxStart = FALSE; + Ret = ATEOp->StopTx(pAd, Mode); + ATECtrl->TxStatus = 0; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopContiTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + { + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + CmdTxContinous(pAd, ATECtrl->PhyMode, ATECtrl->BW, ATECtrl->ControlChl, ATECtrl->Mcs, ATECtrl->TxAntennaSel, 0); + } + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopTxCarrier( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopRx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->Mode &= ATE_RXSTOP; + ATECtrl->bQARxStart = FALSE; + Ret = ATEOp->StopRx(pAd); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxPath( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT16 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + Value = OS_NTOHS(Value); + Ret = ATEOp->SetTxAntenna(pAd, (CHAR)Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetRxPath( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT16 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + Value = OS_NTOHS(Value); + Ret = ATEOp->SetRxAntenna(pAd, (CHAR)Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxIPG( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + + if (Value > 15) + Value = 15; + else if (Value == 0) + Value = 1; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, (" %s, val:%d,0x%04x\n", __func__, Value, Value)); + ATEOp->SetAIFS(pAd, (UINT32)Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxPower0( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT16 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + Value = OS_NTOHS(Value); + Ret = ATEOp->SetTxPower0(pAd, Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HAQ_SetTxPower1( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT16 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + Value = OS_NTOHS(Value); + Ret = ATEOp->SetTxPower1(pAd, Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET0[] = { + /* cmd id start from 0x1000 */ + HQA_OpenAdapter, /* 0x1000 */ + HQA_CloseAdapter, /* 0x1001 */ + HQA_StartTx, /* 0x1002 */ + HQA_StartTxExt, /* 0x1003 */ + HQA_StartTxContiTx, /* 0x1004 */ + HQA_StartTxCarrier, /* 0x1005 */ + HQA_StartRx, /* 0x1006 */ + HQA_StopTx, /* 0x1007 */ + HQA_StopContiTx, /* 0x1008 */ + HQA_StopTxCarrier, /* 0x1009 */ + HQA_StopRx, /* 0x100A */ + HQA_SetTxPath, /* 0x100B */ + HQA_SetRxPath, /* 0x100C */ + HQA_SetTxIPG, /* 0x100D */ + HQA_SetTxPower0, /* 0x100E */ + HAQ_SetTxPower1, /* 0x100F */ +}; + + +static INT32 HQA_SetChannel( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATECtrl->Channel = Value; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Channel = %d, BW = %d\n", __func__, ATECtrl->Channel, ATECtrl->BW)); + + if (ATECtrl->BW == BW_20) + ATECtrl->ControlChl = ATECtrl->Channel; + else if (ATECtrl->BW == BW_40) + ATECtrl->ControlChl = ATECtrl->Channel - 2; + + Ret = ATEOp->SetChannel(pAd, Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetPreamble( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATECtrl->PhyMode = (UCHAR)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetRate( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATECtrl->Mcs = (UCHAR)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetNss( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetSystemBW( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATECtrl->BW = Value; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Channel = %d, BW = %d\n", __func__, ATECtrl->Channel, ATECtrl->BW)); + + if (ATECtrl->BW == BW_20) + ATECtrl->ControlChl = ATECtrl->Channel; + else if (ATECtrl->BW == BW_40) + ATECtrl->ControlChl = ATECtrl->Channel - 2; + + Ret = ATEOp->SetBW(pAd, Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetPerPktBW( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetPrimaryBW( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetFreqOffset( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATEOp->SetTxFreqOffset(pAd, (UINT32)Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetAutoResponder( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTssiOnOff( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0, WFSel; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ON/OFF:4 WF Sel:4 */ + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + memcpy((PUCHAR)&WFSel, HqaCmdFrame->Data + 4, 4); + WFSel = OS_NTOHL(WFSel); + ATEOp->SetTSSI(pAd, (CHAR)WFSel, (CHAR)Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetRxHighLowTemperatureCompensation( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET1[] = { + /* cmd id start from 0x1100 */ + HQA_SetChannel, /* 0x1100 */ + HQA_SetPreamble, /* 0x1101 */ + HQA_SetRate, /* 0x1102 */ + HQA_SetNss, /* 0x1103 */ + HQA_SetSystemBW, /* 0x1104 */ + HQA_SetPerPktBW, /* 0x1105 */ + HQA_SetPrimaryBW, /* 0x1106 */ + HQA_SetFreqOffset, /* 0x1107 */ + HQA_SetAutoResponder, /* 0x1108 */ + HQA_SetTssiOnOff, /* 0x1109 */ + HQA_SetRxHighLowTemperatureCompensation, /* 0x110A */ +}; + + +static INT32 HQA_ResetTxRxCounter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MtAsicGetRxStat(pAd, HQA_RX_RESET_PHY_COUNT); + MtAsicGetRxStat(pAd, HQA_RX_RESET_MAC_COUNT); + ATECtrl->RxTotalCnt = 0; + ATECtrl->TxDoneCount = 0; + ATECtrl->RxMacFCSErrCount = 0; + ATECtrl->RxMacMdrdyCount = 0; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetStatistics( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetRxOKData( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetRxOKOther( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetRxAllPktCount( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetTxTransmitted( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + Value = ATECtrl->TxDoneCount; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: TxDoneCount = %d\n", __func__, ATECtrl->TxDoneCount)); + Value = OS_HTONL(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + + +static INT32 HQA_GetHwCounter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_CalibrationOperation( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET2[] = { + /* cmd id start from 0x1200 */ + HQA_ResetTxRxCounter, /* 0x1200 */ + HQA_GetStatistics, /* 0x1201 */ + HQA_GetRxOKData, /* 0x1202 */ + HQA_GetRxOKOther, /* 0x1203 */ + HQA_GetRxAllPktCount, /* 0x1204 */ + HQA_GetTxTransmitted, /* 0x1205 */ + HQA_GetHwCounter, /* 0x1206 */ + HQA_CalibrationOperation, /* 0x1207 */ +}; + + +static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len) +{ + ULONG i; + USHORT *pDst, *pSrc; + + pDst = (USHORT *) dst; + pSrc = (USHORT *) src; + + for (i = 0; i < (len >> 1); i++) { + *pDst = OS_NTOHS(*pSrc); + pDst++; + pSrc++; + } + + if ((len % 2) != 0) { + memcpy(pDst, pSrc, (len % 2)); + *pDst = OS_NTOHS(*pDst); + } +} + + +static INT32 HQA_MacBbpRegRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Offset, Value; + BOOLEAN IsFound; + + memcpy(&Offset, HqaCmdFrame->Data, 4); + Offset = OS_NTOHL(Offset); + IsFound = mt_mac_cr_range_mapping(pAd, &Offset); + + if (!IsFound) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + + RTMP_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(Offset) << 19; + RemapOffset = GET_REMAP_2_OFFSET(Offset); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + RTMP_IO_READ32(pAd, 0x80000 + RemapOffset, &Value); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } else + RTMP_IO_READ32(pAd, Offset, &Value); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Offset = %x, Value = %x\n", __func__, Offset, Value)); + Value = OS_HTONL(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + + +static INT32 HQA_MacBbpRegWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Offset, Value; + BOOLEAN IsFound; + + memcpy(&Offset, HqaCmdFrame->Data, 4); + memcpy(&Value, HqaCmdFrame->Data + 4, 4); + Offset = OS_NTOHL(Offset); + Value = OS_NTOHL(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Offset = %x, Value = %x\n", __func__, Offset, Value)); + IsFound = mt_mac_cr_range_mapping(pAd, &Offset); + + if (!IsFound) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + + RTMP_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(Offset) << 19; + RemapOffset = GET_REMAP_2_OFFSET(Offset); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + RTMP_IO_WRITE32(pAd, 0x80000 + RemapOffset, Value); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } else + RTMP_IO_WRITE32(pAd, Offset, Value); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *Dst, UINT32 Offset, UINT32 Len) +{ + UINT32 Index, Value = 0; + UCHAR *pDst; + BOOLEAN IsFound; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("\n\n")); + + for (Index = 0 ; Index < (Len >> 2); Index++) { + pDst = (Dst + (Index << 2)); + IsFound = mt_mac_cr_range_mapping(pAd, &Offset); + + if (!IsFound) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + + RTMP_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(Offset) << 19; + RemapOffset = GET_REMAP_2_OFFSET(Offset); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + RTMP_IO_READ32(pAd, 0x80000 + RemapOffset, &Value); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } else + RTMP_IO_READ32(pAd, Offset, &Value); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Offset = %x, Value = %x\n", __func__, Offset, Value)); + Value = OS_HTONL(Value); + memmove(pDst, &Value, 4); + Offset += 4; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("\n\n")); +} + + +static INT32 HQA_MACBbpRegBulkRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Offset; + UINT16 Len, Tmp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 4); + Offset = OS_NTOHL(Offset); + memcpy(&Len, HqaCmdFrame->Data + 4, 2); + Len = OS_NTOHS(Len); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Offset = %x, Len(unit: 4bytes) = %d\n", __func__, Offset, Len)); + + if (Len > 371) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : length requested is too large, make it smaller\n", __func__)); + HqaCmdFrame->Length = OS_HTONS(2); + Tmp = OS_HTONS(1); + memcpy(HqaCmdFrame->Data, &Tmp, 2); + return -EFAULT; + } + + RTMP_IO_READ_BULK(pAd, HqaCmdFrame->Data + 2, Offset, (Len << 2));/* unit in four bytes*/ + ResponseToQA(HqaCmdFrame, WRQ, 2 + (Len << 2), Ret); + return Ret; +} + + +static INT32 HQA_RfRegBulkRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0, Index; + UINT32 WfSel, Offset, Length, Value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy(&WfSel, HqaCmdFrame->Data, 4); + WfSel = OS_NTOHL(WfSel); + memcpy(&Offset, HqaCmdFrame->Data + 4, 4); + Offset = OS_NTOHL(Offset); + memcpy(&Length, HqaCmdFrame->Data + 8, 4); + Length = OS_NTOHL(Length); + + for (Index = 0; Index < Length; Index++) { + Ret = ATEOp->RfRegRead(pAd, WfSel, Offset + Index * 4, &Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Wfsel = %d, Offset = %x, Value = %x\n", __func__, WfSel, + Offset + Index * 4, Value)); + + if (Ret) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Wfsel = %d, Offset = %x, Value = %x fail\n", WfSel, + Offset + Index * 4, Value)); + break; + } + + Value = OS_HTONL(Value); + memcpy(HqaCmdFrame->Data + 2 + (Index * 4), &Value, 4); + } + + ResponseToQA(HqaCmdFrame, WRQ, 2 + (Length * 4), Ret); + return Ret; +} + + +static INT32 HQA_RfRegBulkWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0, Index; + UINT32 WfSel, Offset, Length, Value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&WfSel, HqaCmdFrame->Data, 4); + WfSel = OS_NTOHL(WfSel); + memcpy(&Offset, HqaCmdFrame->Data + 4, 4); + Offset = OS_NTOHL(Offset); + memcpy(&Length, HqaCmdFrame->Data + 8, 4); + Length = OS_NTOHL(Length); + + for (Index = 0; Index < Length; Index++) { + memcpy(&Value, HqaCmdFrame->Data + 12 + (Index * 4), 4); + Value = OS_NTOHL(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Wfsel = %d, Offset = %x, Value = %x\n", __func__, + WfSel, Offset + Index * 4, Value)); + Ret = ATEOp->RfRegWrite(pAd, WfSel, Offset + Index * 4, Value); + + if (Ret) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Wfsel = %d, Offset = %x, Value = %x fail\n", WfSel, + Offset + Index * 4, Value)); + break; + } + } + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_ReadEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 Offset = 0, Value = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = OS_NTOHS(Offset); + RT28xx_EEPROM_READ16(pAd, Offset, Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("e2p r %02Xh = 0x%02X\n" + , (Offset & 0x00FF), (Value & 0x00FF))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("e2p r %02Xh = 0x%02X\n" + , (Offset & 0x00FF) + 1, (Value & 0xFF00) >> 8)); + Value = OS_HTONS(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 2); + ResponseToQA(HqaCmdFrame, WRQ, 4, Ret); + return Ret; +} + + +static INT32 HQA_WriteEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 Offset = 0, Value = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = OS_NTOHS(Offset); + memcpy(&Value, HqaCmdFrame->Data + 2, 2); + Value = OS_NTOHS(Value); + RT28xx_EEPROM_WRITE16(pAd, Offset, Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("e2p w 0x%04X = 0x%04X\n", Offset, Value)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("e2p w %02Xh = 0x%02X\n" + , (Offset & 0x00FF), (Value & 0x00FF))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("e2p w %02Xh = 0x%02X\n" + , (Offset & 0x00FF) + 1, (Value & 0xFF00) >> 8)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_ReadBulkEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 Offset; + UINT16 Len; + UINT16 Buffer[EEPROM_SIZE >> 1]; /* TODO Build warning frame size > 1024 for stack */ + + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = OS_NTOHS(Offset); + memcpy(&Len, HqaCmdFrame->Data + 2, 2); + Len = OS_NTOHS(Len); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Offset = %x, Length = %x\n", __func__, Offset, Len)); + EEReadAll(pAd, (UINT16 *)Buffer); + + if (Offset + Len <= EEPROM_SIZE) + memcpy_exs(pAd, HqaCmdFrame->Data + 2, (UCHAR *)Buffer + Offset, Len); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : exceed EEPROM size\n", __func__)); + Len = 0; + Ret = -1; + } + + ResponseToQA(HqaCmdFrame, WRQ, 2 + Len, Ret); + return Ret; +} + + +static VOID EEWriteBulk(PRTMP_ADAPTER pAd, UINT16 *Data, UINT16 Offset, UINT16 Length) +{ + UINT16 Pos; + UINT16 Value; + UINT16 Len = Length; + + for (Pos = 0; Pos < (Len >> 1);) { + Value = Data[Pos]; + RT28xx_EEPROM_WRITE16(pAd, Offset + (Pos * 2), Value); + Pos++; + } +} + + +static INT32 HQA_WriteBulkEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + USHORT Offset; + USHORT Len; + USHORT Buffer[EEPROM_SIZE >> 1]; /* TODO Build warning frame size > 1024 for stack */ + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = OS_NTOHS(Offset); + memcpy(&Len, HqaCmdFrame->Data + 2, 2); + Len = OS_NTOHS(Len); + memcpy_exs(pAd, (UCHAR *)Buffer + Offset, (UCHAR *)HqaCmdFrame->Data + 4, Len); +#if defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT) + + if (Len == 16) + memcpy(pAd->EEPROMImage + Offset, (UCHAR *)Buffer + Offset, Len); + + if (Offset == 0x1f0) + rtmp_ee_flash_write_all(pAd); + + if (Len != 16) +#endif + { + if ((Offset + Len) <= EEPROM_SIZE) + EEWriteBulk(pAd, (UINT16 *)(((UCHAR *)Buffer) + Offset), Offset, Len); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: exceed EEPROM size(%d)\n", __func__, EEPROM_SIZE)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Offset = %u\n", Offset)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Length = %u\n", Len)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Offset + Length=%u\n", (Offset + Len))); + } + } + + ResponseToQA(HqaCmdFrame, WRQ, 2 + Len, Ret); + return Ret; +} + + +#ifdef RTMP_EFUSE_SUPPORT +static INT32 HQA_CheckEfuseMode( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Value; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (pAd->bUseEfuse) + Value = 1; + else + Value = 0; + + Value = OS_HTONL(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + + +static INT32 HQA_GetFreeEfuseBlock( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Value; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + eFuseGetFreeBlockCount(pAd, &Value); + Value = OS_HTONL(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + + +static INT32 HQA_GetEfuseBlockNr( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_WriteEFuseFromBuffer( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} +#endif /* RTMP_EFUSE_SUPPORT */ + + +static HQA_CMD_HANDLER HQA_CMD_SET3[] = { + /* cmd id start from 0x1300 */ + HQA_MacBbpRegRead, /* 0x1300 */ + HQA_MacBbpRegWrite, /* 0x1301 */ + HQA_MACBbpRegBulkRead, /* 0x1302 */ + HQA_RfRegBulkRead, /* 0x1303 */ + HQA_RfRegBulkWrite, /* 0x1304 */ + HQA_ReadEEPROM, /* 0x1305 */ + HQA_WriteEEPROM, /* 0x1306 */ + HQA_ReadBulkEEPROM, /* 0x1307 */ + HQA_WriteBulkEEPROM, /* 0x1308 */ +#ifdef RTMP_EFUSE_SUPPORT + HQA_CheckEfuseMode, /* 0x1309 */ + HQA_GetFreeEfuseBlock, /* 0x130A */ + HQA_GetEfuseBlockNr, /* 0x130B */ + HQA_WriteEFuseFromBuffer, /* 0x130C */ +#endif /* RTMP_EFUSE_SUPPORT */ +}; + + +static INT32 HQA_ReadTempReferenceValue( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +VOID HQA_GetThermalValue_CB(struct cmd_msg *msg, char *Data, UINT16 Len) +{ + struct _EXT_EVENT_GET_SENSOR_RESULT_T *EventExtCmdResult = (struct _EXT_EVENT_GET_SENSOR_RESULT_T *)Data; + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + EventExtCmdResult->u4SensorResult = le2cpu32(EventExtCmdResult->u4SensorResult); + ATECtrl->thermal_val = EventExtCmdResult->u4SensorResult; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, value: 0x%x\n", __func__, EventExtCmdResult->u4SensorResult)); + RTMP_OS_COMPLETE(&ATECtrl->cmd_done); +} + +static INT32 HQA_GetThermalValue( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + UINT32 SensorResult = 0; + + MtCmdGetThermalSensorResult(pAd, 0, &SensorResult); + Ret = RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&ATECtrl->cmd_done, ATECtrl->cmd_expire); + ATECtrl->thermal_val = OS_HTONL(ATECtrl->thermal_val); + NdisMoveMemory(HqaCmdFrame->Data + 2, &ATECtrl->thermal_val, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + + +static INT32 HQA_SetSideBandOption( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET4[] = { + /* cmd id start from 0x1400 */ + HQA_ReadTempReferenceValue, /* 0x1400 */ + HQA_GetThermalValue, /* 0x1401 */ + HQA_SetSideBandOption, /* 0x1402 */ +}; + + +static INT32 HQA_GetFWInfo( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Ret = ATEOp->GetFWInfo(pAd, HqaCmdFrame->Data + 2); + ResponseToQA(HqaCmdFrame, WRQ, 38, Ret); + return Ret; +} + + +static INT32 HQA_GetRxStatisticsAll( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 value = 0; + UINT32 IBRssi0, IBRssi1, WBRssi0, WBRssi1; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _HQA_RX_STAT HqaRxStat; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memset(&HqaRxStat, 0, sizeof(struct _HQA_RX_STAT)); + /* Get latest FCSErr. sync iwpriv & HQA same FCSErr result */ + NICUpdateRawCountersNew(pAd); + HqaRxStat.mac_rx_fcs_err_cnt = OS_NTOHL(ATECtrl->RxMacFCSErrCount); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MAC_MDRDYCNT); + ATECtrl->RxMacMdrdyCount += value; + HqaRxStat.mac_rx_mdrdy_cnt = OS_NTOHL(ATECtrl->RxMacMdrdyCount); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PHY_FCSERRCNT); + HqaRxStat.phy_rx_fcs_err_cnt_ofdm = OS_NTOHL(value >> 16); + HqaRxStat.phy_rx_fcs_err_cnt_cck = OS_NTOHL(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PD); + HqaRxStat.phy_rx_pd_ofdm = OS_NTOHL(value >> 16); + HqaRxStat.phy_rx_pd_cck = OS_NTOHL(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_CCK_SIG_SFD); + HqaRxStat.phy_rx_sig_err_cck = OS_NTOHL(value >> 16); + HqaRxStat.phy_rx_sfd_err_cck = OS_NTOHL(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_OFDM_SIG_TAG); + HqaRxStat.phy_rx_sig_err_ofdm = OS_NTOHL(value >> 16); + HqaRxStat.phy_rx_tag_err_ofdm = OS_NTOHL(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_RSSI); + IBRssi0 = (value & 0xFF000000) >> 24; + + if (IBRssi0 > 128) + IBRssi0 -= 256; + + WBRssi0 = (value & 0x00FF0000) >> 16; + + if (WBRssi0 > 128) + WBRssi0 -= 256; + + IBRssi1 = (value & 0x0000FF00) >> 8; + + if (IBRssi1 > 128) + IBRssi1 -= 256; + + WBRssi1 = (value & 0x000000FF); + + if (WBRssi1 > 128) + WBRssi1 -= 256; + + HqaRxStat.IB_RSSSI0 = OS_NTOHL(IBRssi0); + HqaRxStat.WB_RSSSI0 = OS_NTOHL(WBRssi0); + HqaRxStat.IB_RSSSI1 = OS_NTOHL(IBRssi1); + HqaRxStat.WB_RSSSI1 = OS_NTOHL(WBRssi1); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PHY_MDRDYCNT); + HqaRxStat.phy_rx_mdrdy_cnt_ofdm = OS_NTOHL(value >> 16); + HqaRxStat.phy_rx_mdrdy_cnt_cck = OS_NTOHL(value & 0xFFFF); + HqaRxStat.DriverRxCount = OS_NTOHL(ATECtrl->RxTotalCnt); + HqaRxStat.RCPI0 = OS_NTOHL(ATECtrl->RCPI0); + HqaRxStat.RCPI1 = OS_NTOHL(ATECtrl->RCPI1); + HqaRxStat.FreqOffsetFromRX = OS_NTOHL(ATECtrl->FreqOffsetFromRx); + HqaRxStat.RSSI0 = OS_NTOHL(ATECtrl->RSSI0); + HqaRxStat.RSSI1 = OS_NTOHL(ATECtrl->RSSI1); + memcpy(HqaCmdFrame->Data + 2, &(HqaRxStat), sizeof(struct _HQA_RX_STAT)); + ResponseToQA(HqaCmdFrame, WRQ, (2 + sizeof(struct _HQA_RX_STAT)), Ret); + return Ret; +} + + +static INT32 HQA_StartContinousTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0, WFSel = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* Modulation:4 BW:4 PRI_CH:4 RATE:4 WFSel:4 */ + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATECtrl->PhyMode = (UCHAR)Value; + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + Value = OS_NTOHL(Value); + ATECtrl->BW = (UCHAR)Value; + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 8, 4); + Value = OS_NTOHL(Value); + /* ATECtrl->ControlChl = (UCHAR)Value; //TODO QA Tool send this parameter with 0, which leads to error in channel switch, mask temperarily */ + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 12, 4); + Value = OS_NTOHL(Value); + ATECtrl->Mcs = (UCHAR)Value; + memcpy((PUCHAR)&WFSel, (PUCHAR)&HqaCmdFrame->Data + 16, 4); + WFSel = OS_NTOHL(WFSel); + /* ATECtrl->TxAntennaSel = WFSel; */ + ATEOp->StartContinousTx(pAd, (CHAR)WFSel); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetSTBC( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATECtrl->Stbc = (UCHAR)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetShortGI( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATECtrl->Sgi = (UCHAR)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetDPD( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0, WFSel; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ON/OFF:4 WF Sel:4 */ + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + memcpy((PUCHAR)&WFSel, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + WFSel = OS_NTOHL(WFSel); + ATEOp->SetDPD(pAd, (CHAR)WFSel, (CHAR)Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StartContiTxTone( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + ATEOp->StartTxTone(pAd, Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_StopContiTxTone( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATEOp->StopTxTone(pAd); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_CalibrationTestMode( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 ICapLen = 0; + INT32 Ret = 0; + UINT8 Mode = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + memcpy((PUCHAR)&ICapLen, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + ICapLen = OS_NTOHL(ICapLen); + + if (Value == 0) + Mode = OPERATION_NORMAL_MODE; + else if (Value == 1) + Mode = OPERATION_RFTEST_MODE; + else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s Mode = %d error!!!\n", __func__, Value)); + + /* CmdRfTest(pAd, ACTION_SWITCH_TO_RFTEST, Mode, 0); */ + MtCmdRfTestSwitchMode(pAd, Mode, ICapLen, 0); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_DoCalibrationTestItem( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Value = 0; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + /* CmdRfTest(pAd, ACTION_IN_RFTEST, 0, Value); */ + MtCmdDoCalibration(pAd, Value); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_eFusePhysicalWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_eFusePhysicalRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_eFuseLogicalRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_eFuseLogicalWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_TMRSetting( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_GetRxSNR( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0, Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Value = OS_NTOHL(ATECtrl->SNR0); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + Value = OS_NTOHL(ATECtrl->SNR1); + memcpy(HqaCmdFrame->Data + 6, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 10, Ret); + return Ret; +} + + +static INT32 HQA_WriteBufferDone( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + + switch (Value) { + case E2P_EFUSE_MODE: + Set_EepromBufferWriteBack_Proc(pAd, "1"); + break; + + case E2P_FLASH_MODE: + Set_EepromBufferWriteBack_Proc(pAd, "2"); + break; + + case E2P_EEPROM_MODE: + Set_EepromBufferWriteBack_Proc(pAd, "3"); + break; + + case E2P_BIN_MODE: + Set_EepromBufferWriteBack_Proc(pAd, "4"); + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Unknow write back mode(%d)\n", __func__, Value)); + } + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_FFT( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + INT32 Ret = 0; + static UINT32 RFCR, OMA0R0, OMA0R1, OMA1R0, OMA1R1, OMA2R0, OMA2R1, OMA3R0, OMA3R1, OMA4R0, OMA4R1; + + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = OS_NTOHL(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: %d\n", __func__, Value)); + + if (Value == 0) { + RTMP_IO_WRITE32(pAd, RMAC_RFCR, RFCR); + RTMP_IO_WRITE32(pAd, RMAC_OMA0R0, OMA0R0); + RTMP_IO_WRITE32(pAd, RMAC_OMA0R1, OMA0R1); + RTMP_IO_WRITE32(pAd, RMAC_OMA1R0, OMA1R0); + RTMP_IO_WRITE32(pAd, RMAC_OMA1R1, OMA1R1); + RTMP_IO_WRITE32(pAd, RMAC_OMA2R0, OMA2R0); + RTMP_IO_WRITE32(pAd, RMAC_OMA2R1, OMA2R1); + RTMP_IO_WRITE32(pAd, RMAC_OMA3R0, OMA3R0); + RTMP_IO_WRITE32(pAd, RMAC_OMA3R1, OMA3R1); + RTMP_IO_WRITE32(pAd, RMAC_OMA4R0, OMA4R0); + RTMP_IO_WRITE32(pAd, RMAC_OMA4R1, OMA4R1); + AsicSetWPDMA(pAd, PDMA_TX_RX, 1); + /* CmdRfTest(pAd, ACTION_SWITCH_TO_RFTEST, OPERATION_NORMAL_MODE, 0); */ + MtCmdRfTestSwitchMode(pAd, OPERATION_NORMAL_MODE, 120); + AsicSetMacTxRx(pAd, ASIC_MAC_RX_RXV, FALSE); + } else { + /* backup CR value */ + RTMP_IO_READ32(pAd, RMAC_RFCR, &RFCR); + RTMP_IO_READ32(pAd, RMAC_OMA0R0, &OMA0R0); + RTMP_IO_READ32(pAd, RMAC_OMA0R1, &OMA0R1); + RTMP_IO_READ32(pAd, RMAC_OMA1R0, &OMA1R0); + RTMP_IO_READ32(pAd, RMAC_OMA1R1, &OMA1R1); + RTMP_IO_READ32(pAd, RMAC_OMA2R0, &OMA2R0); + RTMP_IO_READ32(pAd, RMAC_OMA2R1, &OMA2R1); + RTMP_IO_READ32(pAd, RMAC_OMA3R0, &OMA3R0); + RTMP_IO_READ32(pAd, RMAC_OMA3R1, &OMA3R1); + RTMP_IO_READ32(pAd, RMAC_OMA4R0, &OMA4R0); + RTMP_IO_READ32(pAd, RMAC_OMA4R1, &OMA4R1); + RTMP_IO_READ32(pAd, RMAC_RFCR, &Value); + Value |= RM_FRAME_REPORT_EN; + RTMP_IO_WRITE32(pAd, RMAC_RFCR, Value); + /* set RMAC don't let packet go up */ + RTMP_IO_WRITE32(pAd, RMAC_RFCR, 0x001FEFFB); + RTMP_IO_WRITE32(pAd, RMAC_OMA0R0, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA0R1, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA1R0, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA1R1, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA2R0, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA2R1, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA3R0, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA3R1, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA4R0, 0x00000000); + RTMP_IO_WRITE32(pAd, RMAC_OMA4R1, 0x00000000); + AsicSetWPDMA(pAd, PDMA_TX_RX, 0); + AsicSetMacTxRx(pAd, ASIC_MAC_RX_RXV, TRUE); + } + + return Ret; +} +static INT32 HQA_SetTxTonePower(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + INT32 Ret = 0; + INT32 pwr1 = 0; + INT32 pwr2 = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + pwr1 = OS_NTOHL(Value); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + pwr2 = OS_NTOHL(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s, pwr1:%d, pwr2:%d\n", __func__, pwr1, pwr2)); + ATEOp->SetTxTonePower(pAd, pwr1, pwr2); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET5[] = { + /* cmd id start from 0x1500 */ + HQA_GetFWInfo, /* 0x1500 */ + HQA_StartContinousTx, /* 0x1501 */ + HQA_SetSTBC, /* 0x1502 */ + HQA_SetShortGI, /* 0x1503 */ + HQA_SetDPD, /* 0x1504 */ + HQA_SetTssiOnOff, /* 0x1505 */ + HQA_GetRxStatisticsAll, /* 0x1506 */ + HQA_StartContiTxTone, /* 0x1507 */ + HQA_StopContiTxTone, /* 0x1508 */ + HQA_CalibrationTestMode, /* 0x1509 */ + HQA_DoCalibrationTestItem, /* 0x150A */ + HQA_eFusePhysicalWrite, /* 0x150B */ + HQA_eFusePhysicalRead, /* 0x150C */ + HQA_eFuseLogicalRead, /* 0x150D */ + HQA_eFuseLogicalWrite, /* 0x150E */ + HQA_TMRSetting, /* 0x150F */ + HQA_GetRxSNR, /* 0x1510 */ + HQA_WriteBufferDone, /* 0x1511 */ + HQA_FFT, /* 0x1512 */ + HQA_SetTxTonePower, /* 0x1513 */ +}; + + +static struct _HQA_CMD_TABLE HQA_CMD_TABLES[] = { + { + HQA_CMD_SET0, + sizeof(HQA_CMD_SET0) / sizeof(HQA_CMD_HANDLER), + 0x1000, + }, + { + HQA_CMD_SET1, + sizeof(HQA_CMD_SET1) / sizeof(HQA_CMD_HANDLER), + 0x1100, + }, + { + HQA_CMD_SET2, + sizeof(HQA_CMD_SET2) / sizeof(HQA_CMD_HANDLER), + 0x1200, + }, + { + HQA_CMD_SET3, + sizeof(HQA_CMD_SET3) / sizeof(HQA_CMD_HANDLER), + 0x1300, + }, + { + HQA_CMD_SET4, + sizeof(HQA_CMD_SET4) / sizeof(HQA_CMD_HANDLER), + 0x1400, + }, + { + HQA_CMD_SET5, + sizeof(HQA_CMD_SET5) / sizeof(HQA_CMD_HANDLER), + 0x1500, + }, +}; + + +static INT32 HQA_CMDHandler( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Status = NDIS_STATUS_SUCCESS; + USHORT CmdId; + UINT32 TableIndex = 0; + + CmdId = OS_NTOHS(HqaCmdFrame->Id); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n%s: Command_Id = 0x%04x !\n", __func__, CmdId)); + + while (TableIndex < (sizeof(HQA_CMD_TABLES) / sizeof(struct _HQA_CMD_TABLE))) { + int CmdIndex = 0; + + CmdIndex = CmdId - HQA_CMD_TABLES[TableIndex].CmdOffset; + + if ((CmdIndex >= 0) && (CmdIndex < HQA_CMD_TABLES[TableIndex].CmdSetSize)) { + HQA_CMD_HANDLER *pCmdSet; + + pCmdSet = HQA_CMD_TABLES[TableIndex].CmdSet; + + if (pCmdSet[CmdIndex] != NULL) + Status = (*pCmdSet[CmdIndex])(pAd, WRQ, HqaCmdFrame); + + break; + } + + TableIndex++; + } + + return Status; +} + + +INT32 RtmpDoAte( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + RTMP_STRING *wrq_name) +{ + INT32 Status = NDIS_STATUS_SUCCESS; + struct _HQA_CMD_FRAME *HqaCmdFrame; + UINT32 ATEMagicNum; + + os_alloc_mem_suspend(pAd, (UCHAR **)&HqaCmdFrame, sizeof(*HqaCmdFrame)); + + if (!HqaCmdFrame) { + Status = -ENOMEM; + goto ERROR0; + } + + os_zero_mem(HqaCmdFrame, sizeof(*HqaCmdFrame)); + Status = copy_from_user((PUCHAR)HqaCmdFrame, WRQ->u.data.pointer, + WRQ->u.data.length); + + if (Status) { + Status = -EFAULT; + goto ERROR1; + } + + ATEMagicNum = OS_NTOHL(HqaCmdFrame->MagicNo); + + switch (ATEMagicNum) { + case HQA_CMD_MAGIC_NO: + Status = HQA_CMDHandler(pAd, WRQ, HqaCmdFrame); + break; + + default: + Status = NDIS_STATUS_FAILURE; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Unknown magic number of HQA command = %x\n", ATEMagicNum)); + break; + } + +ERROR1: + os_free_mem(HqaCmdFrame); +ERROR0: + return Status; +} diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/testmode_ioctl.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/testmode_ioctl.c new file mode 100644 index 000000000..bf74c52ea --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/ate/testmode_ioctl.c @@ -0,0 +1,7040 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + testmode_ioctl.c +*/ + +#if defined(COMPOS_TESTMODE_WIN) +#include "config.h" +#else +#include "rt_config.h" +#include "hdev/hdev.h" +#endif + + + +static INT EthGetParamAndShiftBuff(BOOLEAN convert, UINT size, UCHAR **buf, + IN UCHAR *out) +{ + if (!(*buf)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("*buf NULL pointer with size:%u\n", size)); + return -1; + } + + if (!out) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("out NULL pointer with size:%u\n", size)); + return -1; + } + + NdisMoveMemory(out, *buf, size); + *buf = *buf + size; + + if (!convert) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s::size %u, ", __func__, size)); + return 0; + } + + if (size == sizeof(UINT32)) { + UINT32 *tmp = (UINT32 *)out; + *tmp = PKTL_TRAN_TO_HOST(*tmp); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s::size %u, val: %u\n", __func__, size, *tmp)); + } else if (size == sizeof(UINT16)) { + UINT16 *tmp = (UINT16 *)out; + *tmp = PKTS_TRAN_TO_HOST(*tmp); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s::size %u, val: %u\n", __func__, size, *tmp)); + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s::size %u not supported\n", __func__, size)); + return -1; + } + + return 0; +} + + +/* 1to do removed later */ +/* to seperate Windows ndis/WDM and Linux */ +#if defined(COMPOS_TESTMODE_WIN) +UINT32 mt_dft_mac_cr_range[] = { + 0x50022000, 0x50022000, 0xc84, /* USB Controller */ + 0x50029000, 0x50029000, 0x210, /* USB DMA */ + 0x800c006c, 0x800c006c, 0x100, /* PSE Client */ + 0x60000000, 0x20000, 0x200, /* WF_CFG */ + 0x60100000, 0x21000, 0x200, /* WF_TRB */ + 0x60110000, 0x21200, 0x200, /* WF_AGG */ + 0x60120000, 0x21400, 0x200, /* WF_ARB */ + 0x60130000, 0x21600, 0x200, /* WF_TMAC */ + 0x60140000, 0x21800, 0x200, /* WF_RMAC */ + 0x60150000, 0x21A00, 0x200, /* WF_SEC */ + 0x60160000, 0x21C00, 0x200, /* WF_DMA */ + 0x60170000, 0x21E00, 0x200, /* WF_CFGOFF */ + 0x60180000, 0x22000, 0x1000, /* WF_PF */ + 0x60190000, 0x23000, 0x200, /* WF_WTBLOFF */ + 0x601A0000, 0x23200, 0x200, /* WF_ETBF */ + + 0x60300000, 0x24000, 0x400, /* WF_LPON */ + 0x60310000, 0x24400, 0x200, /* WF_INT */ + 0x60320000, 0x28000, 0x4000, /* WF_WTBLON */ + 0x60330000, 0x2C000, 0x200, /* WF_MIB */ + 0x60400000, 0x2D000, 0x200, /* WF_AON */ + + 0x80020000, 0x00000, 0x2000, /* TOP_CFG */ + 0x80000000, 0x02000, 0x2000, /* MCU_CFG */ + 0x50000000, 0x04000, 0x4000, /* PDMA_CFG */ + 0xA0000000, 0x08000, 0x8000, /* PSE_CFG */ + 0x60200000, 0x10000, 0x10000, /* WF_PHY */ + + 0x0, 0x0, 0x0, +}; +BOOLEAN mt_mac_cr_range_mapping(RTMP_ADAPTER *pAd, UINT32 *mac_addr) +{ + UINT32 mac_addr_hif = *mac_addr; + INT idx = 0; + BOOLEAN IsFound = 0; + UINT32 *mac_cr_range = NULL; + + if (IS_MT7603(pAd) || IS_MT7628(pAd) || IS_MT76x6(pAd) || IS_MT7637(pAd)) + mac_cr_range = &mt_dft_mac_cr_range[0]; + + if (!mac_cr_range) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: NotSupported Chip for this function!\n", __func__)); + return IsFound; + } + + if (mac_addr_hif >= 0x40000) { + do { + if (mac_addr_hif >= mac_cr_range[idx] && + mac_addr_hif < (mac_cr_range[idx] + mac_cr_range[idx + 2])) { + mac_addr_hif -= mac_cr_range[idx]; + mac_addr_hif += mac_cr_range[idx + 1]; + IsFound = 1; + break; + } + + idx += 3; + } while (mac_cr_range[idx] != 0); + } else + IsFound = 1; + + *mac_addr = mac_addr_hif; + return IsFound; +} + + +UINT32 mt_physical_addr_map(UINT32 addr) +{ + UINT32 global_addr = 0x0, idx = 1; + extern UINT32 mt_mac_cr_range[]; + + if (addr < 0x2000) + global_addr = 0x80020000 + addr; + else if ((addr >= 0x2000) && (addr < 0x4000)) + global_addr = 0x80000000 + addr - 0x2000; + else if ((addr >= 0x4000) && (addr < 0x8000)) + global_addr = 0x50000000 + addr - 0x4000; + else if ((addr >= 0x8000) && (addr < 0x10000)) + global_addr = 0xa0000000 + addr - 0x8000; + else if ((addr >= 0x10000) && (addr < 0x20000)) + global_addr = 0x60200000 + addr - 0x10000; + else if ((addr >= 0x20000) && (addr < 0x40000)) { + do { + if ((addr >= mt_mac_cr_range[idx]) && (addr < (mt_mac_cr_range[idx] + mt_mac_cr_range[idx + 1]))) { + global_addr = mt_mac_cr_range[idx - 1] + (addr - mt_mac_cr_range[idx]); + break; + } + + idx += 3; + } while (mt_mac_cr_range[idx] != 0); + + if (mt_mac_cr_range[idx] == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Unknow addr range = %x !!!\n", __func__, addr)); + } + } else + global_addr = addr; + + return global_addr; +} + + +static INT32 ResponseToQA( + struct _HQA_CMD_FRAME *HqaCmdFrame, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + UINT32 Length, + INT32 Status) +{ + NdisMoveMemory(HqaCmdFrame->Data, &Status, 2); + HqaCmdFrame->Length = (UINT16)Length; + *WRQ->BytesRet = sizeof((HqaCmdFrame)->MagicNo) + sizeof((HqaCmdFrame)->Type) + + sizeof((HqaCmdFrame)->Id) + sizeof((HqaCmdFrame)->Length) + + sizeof((HqaCmdFrame)->Sequence) + Length; + + if (*WRQ->BytesRet > WRQ->OutBufLen) + *WRQ->BytesRet = WRQ->OutBufLen; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: OutBufLen = 0x%x\n", __func__, WRQ->OutBufLen)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: BytesRet = 0x%x\n", __func__, *WRQ->BytesRet)); + RTMPMoveMemory(WRQ->OutBuf, WRQ->InBuf, *WRQ->BytesRet); + return Status; +} + + +#else /* defined(COMPOS_TESTMODE_WIN) */ +static INT ResponseToQA( + struct _HQA_CMD_FRAME *HqaCmdFrame, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + INT32 Length, + INT32 Status) +{ + HqaCmdFrame->Length = PKTS_TRAN_TO_NET((Length)); + Status = PKTS_TRAN_TO_NET((Status)); + NdisCopyMemory(HqaCmdFrame->Data, &Status, 2); + WRQ->u.data.length = sizeof((HqaCmdFrame)->MagicNo) + sizeof((HqaCmdFrame)->Type) + + sizeof((HqaCmdFrame)->Id) + sizeof((HqaCmdFrame)->Length) + + sizeof((HqaCmdFrame)->Sequence) + PKTS_TRAN_TO_HOST((HqaCmdFrame)->Length); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("WRQ->u.data.length = %d, usr_addr:%p, hqa_addr:%p\n", + WRQ->u.data.length, WRQ->u.data.pointer, HqaCmdFrame)); + + if (copy_to_user(WRQ->u.data.pointer, (UCHAR *)(HqaCmdFrame), WRQ->u.data.length)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("copy_to_user() fail in %s\n", __func__)); + return -EFAULT; + } + + return 0; +} +#endif /* TODO: Add lack of functions temporarily, and delete after merge */ + + +static INT32 HQA_OpenAdapter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->bQAEnabled = TRUE; + /* Prepare feedback as soon as we can to avoid QA timeout. */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + + if (ATEOp->ATEStart) + Ret = ATEOp->ATEStart(pAd); + else + Ret = TM_STATUS_NOTSUPPORT; + + return Ret; +} + +static INT32 HQA_CloseAdapter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->bQAEnabled = FALSE; + /* Prepare feedback as soon as we can to avoid QA timeout. */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + + if (ATEOp->ATEStop) + Ret = ATEOp->ATEStop(pAd); + else + Ret = TM_STATUS_NOTSUPPORT; + + return Ret; +} + +static INT32 HQA_StartTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 TxCount; + UINT16 TxLength; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&TxCount, HqaCmdFrame->Data, 4); + memcpy(&TxLength, HqaCmdFrame->Data + 4, 2); + TxCount = PKTL_TRAN_TO_HOST(TxCount); + TxLength = PKTS_TRAN_TO_HOST(TxLength); + TESTMODE_SET_PARAM(ATECtrl, TESTMODE_BAND0, TxCount, TxCount); + TESTMODE_SET_PARAM(ATECtrl, TESTMODE_BAND0, TxLength, TxLength); + ATECtrl->bQATxStart = TRUE; + + if (ATEOp->StartTx) + Ret = ATEOp->StartTx(pAd); + else + Ret = TM_STATUS_NOTSUPPORT; + + if (ATECtrl->bQATxStart == TRUE) + ATECtrl->TxStatus = 1; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_StartTxExt( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_StartTxContiTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_StartTxCarrier( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StartRx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ATECtrl->bQARxStart = TRUE; + + if (ATEOp->StartRx) + Ret = ATEOp->StartRx(pAd); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 Mode; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Mode = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND0, Mode); + Mode &= ATE_TXSTOP; + TESTMODE_SET_PARAM(ATECtrl, TESTMODE_BAND0, Mode, Mode); + ATECtrl->bQATxStart = FALSE; + + if (ATEOp->StopTx) + Ret = ATEOp->StopTx(pAd); + else + Ret = TM_STATUS_NOTSUPPORT; + + ATECtrl->TxStatus = 0; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopContiTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + /* TODO Get Correct TxfdMode*/ + UINT32 TxfdMode = 1; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + { + if (ATEOp->StopContinousTx) + ATEOp->StopContinousTx(pAd, TxfdMode); + else + Ret = TM_STATUS_NOTSUPPORT; + } + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_StopTxCarrier( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopRx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 Mode; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Mode = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND0, Mode); + Mode &= ATE_RXSTOP; + TESTMODE_SET_PARAM(ATECtrl, TESTMODE_BAND0, Mode, Mode); + ATECtrl->bQARxStart = FALSE; + + if (ATEOp->StopRx) + Ret = ATEOp->StopRx(pAd); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxPath( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT16 Value = 0; + INT32 ant_sel = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + ant_sel = PKTS_TRAN_TO_HOST(Value); + + if (ant_sel & 0x8000) { + ant_sel &= 0x7FFF; + ant_sel |= 0x80000000; + } + + if (ATEOp->SetTxAntenna) + Ret = ATEOp->SetTxAntenna(pAd, ant_sel); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetRxPath( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT16 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + Value = PKTS_TRAN_TO_HOST(Value); + + if (ATEOp->SetRxAntenna) + Ret = ATEOp->SetRxAntenna(pAd, (CHAR)Value); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxIPG( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): val:%d,0x%04x\n", __func__, Value, Value)); + + if (ATEOp->SetAIFS) + ATEOp->SetAIFS(pAd, (UINT32)Value); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxPower0( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT16 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + ATE_TXPOWER TxPower; + UINT8 band_idx = TESTMODE_BAND0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + Value = PKTS_TRAN_TO_HOST(Value); + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = Value; + TxPower.Dbdc_idx = band_idx; + + if (ATEOp->SetTxPower0) + Ret = ATEOp->SetTxPower0(pAd, TxPower); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HAQ_SetTxPower1( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT16 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + ATE_TXPOWER TxPower; + UINT8 band_idx = TESTMODE_BAND0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 2); + Value = PKTS_TRAN_TO_HOST(Value); + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = Value; + TxPower.Dbdc_idx = band_idx; + + if (ATEOp->SetTxPower1) + Ret = ATEOp->SetTxPower1(pAd, TxPower); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxPowerExt( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + ATE_TXPOWER TxPower; + UINT32 power = 0; + UINT32 Channel = 0; + UINT32 dbdc_idx = 0; + UINT32 band_idx = 0; + UINT32 ant_idx = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&power); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&dbdc_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Channel); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&band_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ant_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Ant_idx = ant_idx; + TxPower.Power = power; + TxPower.Channel = Channel; + TxPower.Dbdc_idx = dbdc_idx; + TxPower.Band_idx = band_idx; + + if (ATEOp->SetTxPowerX) + Ret = ATEOp->SetTxPowerX(pAd, TxPower); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +#ifdef TXPWRMANUAL +static INT32 HQA_SetTxPwrManual( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + + INT16 Ret = 0; + struct _HQA_PWR_MANUAL manual_pwr; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + /* Setting parameters */ + BOOLEAN fgPwrManCtrl = FALSE; + UINT8 u1TxPwrModeManual = 0; + UINT8 u1TxPwrBwManual = 0; + UINT8 u1TxPwrRateManual = 0; + INT8 i1TxPwrValueManual = 0; + UCHAR Band = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s\n", __func__)); + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_pwr.u4PwrManCtrl); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_pwr.u4Band); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_pwr.i4TxPwrValueManual); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_pwr.u4TxPwrModeManual); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_pwr.u4TxPwrRateManual); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_pwr.u4TxPwrBwManual); + + fgPwrManCtrl = manual_pwr.u4PwrManCtrl; + u1TxPwrModeManual = manual_pwr.u4TxPwrModeManual; + u1TxPwrBwManual = manual_pwr.u4TxPwrBwManual; + u1TxPwrRateManual = manual_pwr.u4TxPwrRateManual; + i1TxPwrValueManual = manual_pwr.i4TxPwrValueManual; + Band = manual_pwr.u4Band; + + + if (ATEOp->SetTxPwrManual) + ATEOp->SetTxPwrManual(pAd, fgPwrManCtrl, u1TxPwrModeManual, u1TxPwrBwManual, u1TxPwrRateManual, i1TxPwrValueManual, Band); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} +#endif + + +static INT32 HQA_AntennaSel( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + /* todo wait FW confirm */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetOnOFF( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __FUNCTION__)); */ + return Ret; +} + + +static INT32 HQA_FWPacketCMD_ClockSwitchDisable( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 isDisable = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + EthGetParamAndShiftBuff(TRUE, sizeof(isDisable), &data, (UCHAR *)&isDisable); + ATEOp->ClockSwitchDisable(pAd, isDisable); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTxPowerEval( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __FUNCTION__)); */ + return Ret; +} + + +static INT32 HQA_AntennaSelExt(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 RfModeMask = 0; + UINT32 RfPortMask = 0; + UINT32 AntPortMask = 0; + UINT32 BandIdx = 0; + UCHAR *data = HqaCmdFrame->Data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + NdisMoveMemory((PUCHAR)&BandIdx, data, sizeof(BandIdx)); + data += sizeof(BandIdx); + BandIdx = PKTL_TRAN_TO_HOST(BandIdx); + NdisMoveMemory((PUCHAR)&RfModeMask, data, sizeof(RfModeMask)); + data += sizeof(RfModeMask); + RfModeMask = PKTL_TRAN_TO_HOST(RfModeMask); + NdisMoveMemory((PUCHAR)&RfPortMask, data, sizeof(RfPortMask)); + data += sizeof(RfPortMask); + RfPortMask = PKTL_TRAN_TO_HOST(RfPortMask); + NdisMoveMemory((PUCHAR)&AntPortMask, data, sizeof(AntPortMask)); + data += sizeof(AntPortMask); + AntPortMask = PKTL_TRAN_TO_HOST(AntPortMask); +#if defined(COMPOS_TESTMODE_WIN) + pAd->AntennaMainAux = AntPortMask; +#endif + ATECtrl->control_band_idx = (UCHAR)BandIdx; + + Ret = ATEOp->SetAntennaPort(pAd, RfModeMask, RfPortMask, AntPortMask); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: BandIdx:%x, RfModeMask:%x, RfPortMask:%x, AntPortMask:%x\n", + __func__, BandIdx, RfModeMask, RfPortMask, AntPortMask)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET0[] = { + /* cmd id start from 0x1000 */ + HQA_OpenAdapter, /* 0x1000 */ + HQA_CloseAdapter, /* 0x1001 */ + HQA_StartTx, /* 0x1002 */ + HQA_StartTxExt, /* 0x1003 */ + HQA_StartTxContiTx, /* 0x1004 */ + HQA_StartTxCarrier, /* 0x1005 */ + HQA_StartRx, /* 0x1006 */ + HQA_StopTx, /* 0x1007 */ + HQA_StopContiTx, /* 0x1008 */ + HQA_StopTxCarrier, /* 0x1009 */ + HQA_StopRx, /* 0x100A */ + HQA_SetTxPath, /* 0x100B */ + HQA_SetRxPath, /* 0x100C */ + HQA_SetTxIPG, /* 0x100D */ + HQA_SetTxPower0, /* 0x100E */ + HAQ_SetTxPower1, /* 0x100F */ + HQA_SetTxPowerEval, /* 0x1010 */ + HQA_SetTxPowerExt, /* 0x1011 */ + HQA_SetOnOFF, /* 0x1012 */ + HQA_AntennaSel, /* 0x1013 */ + HQA_FWPacketCMD_ClockSwitchDisable, /* 0x1014 */ + HQA_AntennaSelExt, /* 0x1015 */ + NULL,/* 0x1016 */ + NULL,/* 0x1017 */ +#ifdef TXPWRMANUAL + HQA_SetTxPwrManual, /* 0x1018 */ +#endif +}; + + +static INT32 HQA_SetChannel( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Ret = 0; + UINT32 Value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((UINT8 *)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Channel = %d, BW = %d\n", + __func__, ATECtrl->Channel, ATECtrl->BW)); + ATECtrl->Channel = (UINT8)Value; + + if (ATEOp->SetChannel) + Ret = ATEOp->SetChannel(pAd, (UINT16)Value, 0, 0, 0); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetPreamble( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + /* 000: Legacy CCK + * 001: Legacy OFDM + * 010: HT Mixed mode + * 011: HT Green field mode + * 100: VHT mode + */ + ATECtrl->PhyMode = (UCHAR)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetRate( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + ATECtrl->Mcs = (UCHAR)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetNss( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetSystemBW( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + /* 0: BW_20, 1:BW_40, 2:BW_80, 3:BW_160*/ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: BW = %d\n", __func__, Value)); + + ATECtrl->BW = Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetPerPktBW( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: %u\n", __func__, Value)); + + if (Value > ATECtrl->BW) + Value = ATECtrl->BW; + + ATECtrl->PerPktBW = Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetPrimaryBW( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetFreqOffset( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + + if (ATEOp->SetTxFreqOffset) + ATEOp->SetTxFreqOffset(pAd, (UINT32)Value); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetAutoResponder( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetTssiOnOff( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0, WFSel; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ON/OFF:4 WF Sel:4 */ + memcpy((PUCHAR)&Value, HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + memcpy((PUCHAR)&WFSel, HqaCmdFrame->Data + 4, 4); + WFSel = PKTL_TRAN_TO_HOST(WFSel); + + if (ATEOp->SetTSSI) + ATEOp->SetTSSI(pAd, (CHAR)WFSel, (CHAR)Value); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_SetRxHighLowTemperatureCompensation( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_LowPower( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Control = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + EthGetParamAndShiftBuff(TRUE, sizeof(Control), &data, (UCHAR *)&Control); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s Control:%d\n", __func__, Control)); + + if (ATEOp->LowPower) + ATEOp->LowPower(pAd, Control); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET1[] = { + /* cmd id start from 0x1100 */ + HQA_SetChannel, /* 0x1100 */ + HQA_SetPreamble, /* 0x1101 */ + HQA_SetRate, /* 0x1102 */ + HQA_SetNss, /* 0x1103 */ + HQA_SetSystemBW, /* 0x1104 */ + HQA_SetPerPktBW, /* 0x1105 */ + HQA_SetPrimaryBW, /* 0x1106 */ + HQA_SetFreqOffset, /* 0x1107 */ + HQA_SetAutoResponder, /* 0x1108 */ + HQA_SetTssiOnOff, /* 0x1109 */ + HQA_SetRxHighLowTemperatureCompensation,/* 0x110A */ + HQA_LowPower, /* 0x110B */ +}; + + +static INT32 HQA_ResetTxRxCounter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + MtAsicGetRxStat(pAd, HQA_RX_RESET_PHY_COUNT); + MtAsicGetRxStat(pAd, HQA_RX_RESET_MAC_COUNT); +#ifdef CONFIG_HW_HAL_OFFLOAD + MtCmdSetPhyCounter(pAd, 0, TESTMODE_BAND0); + MtCmdSetPhyCounter(pAd, 1, TESTMODE_BAND0); + + if (IS_ATE_DBDC(pAd)) { + MtCmdSetPhyCounter(pAd, 0, TESTMODE_BAND1); + MtCmdSetPhyCounter(pAd, 1, TESTMODE_BAND1); + } + +#endif + MT_ATEUpdateRxStatistic(pAd, TESTMODE_RESET_CNT, NULL); + ATECtrl->TxDoneCount = 0; + + if (IS_ATE_DBDC(pAd)) + TESTMODE_SET_PARAM(ATECtrl, TESTMODE_BAND1, TxDoneCount, 0); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetChipID( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 ChipId; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + RTMP_IO_READ32(pAd, TOP_HCR, &ChipId); + ChipId = OS_NTOHL(ChipId); + memcpy(HqaCmdFrame->Data + 2, &ChipId, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + + +static INT32 HQA_GetStatistics( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} +/* 1 todo not support yet */ +static INT32 HQA_GetRxOKData( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_GetRxOKOther( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_GetRxAllPktCount( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetTxTransmitted( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + Value = ATECtrl->TxDoneCount; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): TxDoneCount = %d\n", __func__, ATECtrl->TxDoneCount)); + Value = PKTL_TRAN_TO_NET(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_GetHwCounter( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_CalibrationOperation( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_CalibrationBypassExt( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UINT32 item = 0; + UINT32 band_idx = 0; + UCHAR *data = HqaCmdFrame->Data; + + NdisMoveMemory((UCHAR *)&item, data, sizeof(item)); + data += sizeof(item); + item = PKTL_TRAN_TO_HOST(item); + NdisMoveMemory((UCHAR *)&band_idx, data, sizeof(band_idx)); + data += sizeof(band_idx); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + MtCmdDoCalibration(pAd, CALIBRATION_BYPASS, item, band_idx); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: item:%x, band_idx:%x\n", + __func__, item, band_idx)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetRXVectorIdx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UINT32 band_idx = 0; + UINT32 Group_1 = 0, Group_2 = 0; + UCHAR *data = HqaCmdFrame->Data; + + NdisMoveMemory((UCHAR *)&band_idx, data, sizeof(band_idx)); + data += sizeof(band_idx); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + NdisMoveMemory((UCHAR *)&Group_1, data, sizeof(Group_1)); + data += sizeof(Group_1); + Group_1 = PKTL_TRAN_TO_HOST(Group_1); + NdisMoveMemory((UCHAR *)&Group_2, data, sizeof(Group_2)); + data += sizeof(Group_2); + Group_2 = PKTL_TRAN_TO_HOST(Group_2); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + +#ifdef CONFIG_HW_HAL_OFFLOAD + MtCmdSetRxvIndex(pAd, Group_1, Group_2, band_idx); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: band_idx:%d, G1:%d, G2:%d\n", + __func__, band_idx, Group_1, Group_2)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetFAGCRssiPath( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ate_ctrl = &pAd->ATECtrl; + INT32 Ret = 0; + UINT32 band_idx = 0; + UINT32 FAGC_Path = 0; + UCHAR *data = HqaCmdFrame->Data; + + NdisMoveMemory((UCHAR *)&band_idx, data, sizeof(band_idx)); + data += sizeof(band_idx); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + NdisMoveMemory((UCHAR *)&FAGC_Path, data, sizeof(FAGC_Path)); + data += sizeof(FAGC_Path); + FAGC_Path = PKTL_TRAN_TO_HOST(FAGC_Path); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, FAGC_Path, FAGC_Path); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + +#ifdef CONFIG_HW_HAL_OFFLOAD + MtCmdSetFAGCPath(pAd, FAGC_Path, band_idx); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: band_idx:%d, FAGC_Path%d\n", + __func__, band_idx, FAGC_Path)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET2[] = { + /* cmd id start from 0x1200 */ + HQA_ResetTxRxCounter, /* 0x1200 */ + HQA_GetStatistics, /* 0x1201 */ + HQA_GetRxOKData, /* 0x1202 */ + HQA_GetRxOKOther, /* 0x1203 */ + HQA_GetRxAllPktCount, /* 0x1204 */ + HQA_GetTxTransmitted, /* 0x1205 */ + HQA_GetHwCounter, /* 0x1206 */ + HQA_CalibrationOperation, /* 0x1207 */ + HQA_CalibrationBypassExt, /* 0x1208 */ + HQA_SetRXVectorIdx, /* 0x1209 */ + HQA_SetFAGCRssiPath, /* 0x120A */ +}; + + +#if !defined(COMPOS_TESTMODE_WIN) +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 = PKTS_TRAN_TO_HOST(*pSrc); + pDst++; + pSrc++; + } + + if ((len % 2) != 0) { + memcpy(pDst, pSrc, (len % 2)); + *pDst = PKTS_TRAN_TO_HOST(*pDst); + } +} +#endif + + +static INT32 HQA_MacBbpRegRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Offset, Value; + BOOLEAN IsFound; + + memcpy(&Offset, HqaCmdFrame->Data, 4); + Offset = PKTL_TRAN_TO_HOST(Offset); + IsFound = mt_mac_cr_range_mapping(pAd, &Offset); +#if defined(COMPOS_TESTMODE_WIN) + Offset = mt_physical_addr_map(Offset); + IsFound = TRUE; +#endif + + if (!IsFound) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + + HW_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(Offset) << 19; + RemapOffset = GET_REMAP_2_OFFSET(Offset); + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + HW_IO_READ32(pAd, 0x80000 + RemapOffset, &Value); + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } else + HW_IO_READ32(pAd, Offset, &Value); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Offset = %x, Value = %x\n", __func__, Offset, Value)); + Value = PKTL_TRAN_TO_NET(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + + +static INT32 HQA_MacBbpRegWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Offset, Value; + BOOLEAN IsFound; + + memcpy(&Offset, HqaCmdFrame->Data, 4); + memcpy(&Value, HqaCmdFrame->Data + 4, 4); + Offset = PKTL_TRAN_TO_HOST(Offset); + Value = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Offset = %x, Value = %x\n", __func__, Offset, Value)); + IsFound = mt_mac_cr_range_mapping(pAd, &Offset); +#if defined(COMPOS_TESTMODE_WIN) + Offset = mt_physical_addr_map(Offset); + IsFound = TRUE; +#endif + + if (!IsFound) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + + HW_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(Offset) << 19; + RemapOffset = GET_REMAP_2_OFFSET(Offset); + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + HW_IO_WRITE32(pAd, 0x80000 + RemapOffset, Value); + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } else + HW_IO_WRITE32(pAd, Offset, Value); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +#if !defined(COMPOS_TESTMODE_WIN) +#define REG_SIZE 128 +RTMP_REG_PAIR RegPair[REG_SIZE]; + +VOID RTMP_IO_MCU_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *Dst, UINT32 Offset, UINT32 Len) +{ + UINT32 Index, Value = 0; + UCHAR *pDst; + UINT32 NumOfReg = (Len >> 2); + UINT32 Reg_idx = 0; /* Rate is 0 to REG_SIZE-1 */ + UINT32 i; + UCHAR OffsetByte = 0x4; + UINT32 Ret_idx = 0; + + for (Index = 0 ; Index < NumOfReg; Index++) { + RegPair[Reg_idx].Register = Offset + OffsetByte * Index; + + /* Read CR per REG_SIZE or lastest CR */ + if (Reg_idx == REG_SIZE - 1 || Index == NumOfReg - 1) { + MtCmdMultipleMacRegAccessRead(pAd, RegPair, Reg_idx + 1); + + for (i = 0; i <= Reg_idx; i++) { + pDst = (Dst + ((Ret_idx) << 2)); + Value = RegPair[i].Value; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: Offset = %x, Value = %x\n", + __func__, RegPair[i].Register, Value)); + Value = PKTL_TRAN_TO_NET(Value); + memmove(pDst, &Value, 4); + Ret_idx++; + } + + Reg_idx = 0; + } else + Reg_idx++; + } +} +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + + +VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *Dst, UINT32 Offset, UINT32 Len) +{ + UINT32 Index, Value = 0; + UCHAR *pDst; + UINT32 NumOfReg = (Len >> 2); + BOOLEAN IsFound; + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("\n\n")); +#if !defined(COMPOS_TESTMODE_WIN) + IsFound = mt_mac_cr_range_mapping(pAd, &Offset); + + if (!IsFound && NumOfReg > 1 && Offset && !(ATECtrl->Mode & fATE_IN_ICAPOVERLAP)) { + RTMP_IO_MCU_READ_BULK(pAd, Dst, Offset, Len); + return; + } + +#endif /* !defined(COMPOS_TESTMODE_WIN) */ + + for (Index = 0 ; Index < NumOfReg; Index++) { + pDst = (Dst + (Index << 2)); + IsFound = mt_mac_cr_range_mapping(pAd, &Offset); +#if defined(COMPOS_TESTMODE_WIN) + Offset = mt_physical_addr_map(Offset); + IsFound = TRUE; +#endif + + if (!IsFound) { + UINT32 RemapBase, RemapOffset; + UINT32 RestoreValue; + + HW_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RemapBase = GET_REMAP_2_BASE(Offset) << 19; + RemapOffset = GET_REMAP_2_OFFSET(Offset); + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RemapBase); + HW_IO_READ32(pAd, 0x80000 + RemapOffset, &Value); + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + } else + HW_IO_READ32(pAd, Offset, &Value); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Offset = %x, Value = %x\n", __func__, Offset, Value)); + Value = PKTL_TRAN_TO_NET(Value); + memmove(pDst, &Value, 4); + Offset += 4; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("\n\n")); +} + + +static INT32 HQA_MACBbpRegBulkRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Offset; + UINT16 Len, Tmp; + INT debug_lvl = DebugLevel; + + DebugLevel = DBG_LVL_OFF; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 4); + Offset = PKTL_TRAN_TO_HOST(Offset); + memcpy(&Len, HqaCmdFrame->Data + 4, 2); + Len = PKTS_TRAN_TO_HOST(Len); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Offset = %x, Len(unit: 4bytes) = %d\n", __func__, Offset, Len)); + + if (Len > 371) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: length requested is too large, make it smaller\n", __func__)); + HqaCmdFrame->Length = PKTS_TRAN_TO_NET(2); + Tmp = PKTS_TRAN_TO_NET(1); + memcpy(HqaCmdFrame->Data, &Tmp, 2); + return -EFAULT; + } + + RTMP_IO_READ_BULK(pAd, HqaCmdFrame->Data + 2, Offset, (Len << 2));/* unit in four bytes*/ + ResponseToQA(HqaCmdFrame, WRQ, 2 + (Len << 2), Ret); + DebugLevel = debug_lvl; + return Ret; +} + + +static INT32 HQA_RfRegBulkRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Index, WfSel, Offset, Length, Value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy(&WfSel, HqaCmdFrame->Data, 4); + WfSel = PKTL_TRAN_TO_HOST(WfSel); + memcpy(&Offset, HqaCmdFrame->Data + 4, 4); + Offset = PKTL_TRAN_TO_HOST(Offset); + memcpy(&Length, HqaCmdFrame->Data + 8, 4); + Length = PKTL_TRAN_TO_HOST(Length); + + if (ATEOp->RfRegRead) { + for (Index = 0; Index < Length; Index++) { + Ret = ATEOp->RfRegRead(pAd, WfSel, Offset + Index * 4, &Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Wfsel = %d, Offset = %x, Value = %x\n", + __func__, WfSel, Offset + Index * 4, Value)); + + if (Ret) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Wfsel = %d, Offset = %x, Value = %x fail\n", + WfSel, Offset + Index * 4, Value)); + break; + } + + Value = PKTL_TRAN_TO_NET(Value); + memcpy(HqaCmdFrame->Data + 2 + (Index * 4), &Value, 4); + } + } else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2 + (Length * 4), Ret); + return Ret; +} + + +static INT32 HQA_RfRegBulkWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Index, WfSel, Offset, Length, Value; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&WfSel, HqaCmdFrame->Data, 4); + WfSel = PKTL_TRAN_TO_HOST(WfSel); + memcpy(&Offset, HqaCmdFrame->Data + 4, 4); + Offset = PKTL_TRAN_TO_HOST(Offset); + memcpy(&Length, HqaCmdFrame->Data + 8, 4); + Length = PKTL_TRAN_TO_HOST(Length); + + if (ATEOp->RfRegWrite) { + for (Index = 0; Index < Length; Index++) { + memcpy(&Value, HqaCmdFrame->Data + 12 + (Index * 4), 4); + Value = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Wfsel = %d, Offset = %x, Value = %x\n", + __func__, WfSel, Offset + Index * 4, Value)); + Ret = ATEOp->RfRegWrite(pAd, WfSel, Offset + Index * 4, Value); + + if (Ret) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Wfsel = %d, Offset = %x, Value = %x fail\n", + WfSel, Offset + Index * 4, Value)); + break; + } + } + } else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_ReadEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; +#if !defined(COMPOS_TESTMODE_WIN)/* 1Todo RT28xx_EEPROM_READ16 */ + UINT16 Offset = 0, Value = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = PKTS_TRAN_TO_HOST(Offset); + RT28xx_EEPROM_READ16(pAd, Offset, Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("e2p r %02Xh = 0x%02X\n", (Offset & 0x00FF), (Value & 0x00FF))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("e2p r %02Xh = 0x%02X\n", (Offset & 0x00FF) + 1, (Value & 0xFF00) >> 8)); + Value = PKTS_TRAN_TO_NET(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 2); +#endif + ResponseToQA(HqaCmdFrame, WRQ, 4, Ret); + return Ret; +} + + +static INT32 HQA_WriteEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 Offset = 0, Value = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = PKTS_TRAN_TO_HOST(Offset); + memcpy(&Value, HqaCmdFrame->Data + 2, 2); + Value = PKTS_TRAN_TO_HOST(Value); +#if defined(COMPOS_TESTMODE_WIN) + NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &Value, 2); +#else + RT28xx_EEPROM_WRITE16(pAd, Offset, Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("e2p w 0x%04X = 0x%04X\n", Offset, Value)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("e2p w %02Xh = 0x%02X\n", (Offset & 0x00FF), (Value & 0x00FF))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("e2p w %02Xh = 0x%02X\n", (Offset & 0x00FF) + 1, (Value & 0xFF00) >> 8)); +#endif + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_ReadBulkEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 Offset; + UINT16 Len; + UINT16 size = EEPROM_SIZE; + UINT16 *Buffer = NULL; + struct _RTMP_CHIP_CAP *cap; + + cap = hc_get_chip_cap(pAd->hdev_ctrl); + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = PKTS_TRAN_TO_HOST(Offset); + memcpy(&Len, HqaCmdFrame->Data + 2, 2); + Len = PKTS_TRAN_TO_HOST(Len); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Offset = %x, Length = %x\n", __func__, Offset, Len)); +#if defined(RTMP_RBUS_SUPPORT) || defined(RTMP_FLASH_SUPPORT) + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + size = get_dev_eeprom_size(pAd); +#endif + +#if !defined(COMPOS_TESTMODE_WIN) /* 1Todo EEReadAll */ + RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev); + Ret = os_alloc_mem(pAd, (PUCHAR *)&Buffer, size); /* TODO verify */ + + if (Ret == NDIS_STATUS_FAILURE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: allocate memory for read EEPROM fail\n", __func__)); + Len = 0; + goto HQA_ReadBulkEEPROM_RET; + } + + EEReadAll(pAd, (UINT16 *)Buffer, size); + + if (Offset + Len <= size) + memcpy_exs(pAd, HqaCmdFrame->Data + 2, (UCHAR *)Buffer + Offset, Len); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: exceed EEPROM size\n", __func__)); + Len = 0; + Ret = -1; + } + + os_free_mem(Buffer); + RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev); +#else + + if (Offset + Len <= cap->EFUSE_BUFFER_CONTENT_SIZE) + os_move_mem(HqaCmdFrame->Data + 2, (UCHAR *)pAd->EEPROMImage + Offset, Len); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: exceed EEPROM size\n", __func__)); + Len = 0; + Ret = -1; + } + +#endif +HQA_ReadBulkEEPROM_RET: + ResponseToQA(HqaCmdFrame, WRQ, 2 + Len, Ret); + return Ret; +} + + +static VOID EEWriteBulk(PRTMP_ADAPTER pAd, UINT16 *Data, UINT16 Offset, UINT16 Length) +{ +#if !defined(COMPOS_TESTMODE_WIN) /* 1Todo struct _ATE_CTRL RT28xx_EEPROM_WRITE16 */ + UINT16 Pos; + UINT16 Value; + UINT16 Len = Length; + + for (Pos = 0; Pos < (Len >> 1);) { + Value = Data[Pos]; + RT28xx_EEPROM_WRITE16(pAd, Offset + (Pos * 2), Value); + Pos++; + } + +#endif +} + + +static INT32 HQA_WriteBulkEEPROM( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; +#if !defined(COMPOS_TESTMODE_WIN) /* 1Todo RT28xx_EEPROM_WRITE16 */ + USHORT Offset; + USHORT Len; + UINT16 *Buffer = NULL; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + memcpy(&Offset, HqaCmdFrame->Data, 2); + Offset = PKTS_TRAN_TO_HOST(Offset); + memcpy(&Len, HqaCmdFrame->Data + 2, 2); + Len = PKTS_TRAN_TO_HOST(Len); + Ret = os_alloc_mem(pAd, (PUCHAR *)&Buffer, EEPROM_SIZE); /* TODO verify */ + + if (Ret == NDIS_STATUS_FAILURE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: allocate memory for read EEPROM fail\n", __func__)); + goto HQA_WriteBulkEEPROM_RET; + } + + memcpy_exs(pAd, (UCHAR *)Buffer + Offset, (UCHAR *)HqaCmdFrame->Data + 4, Len); +#if defined(RTMP_FLASH_SUPPORT) + + if (Len == 16) + memcpy(pAd->EEPROMImage + Offset, (UCHAR *)Buffer + Offset, Len); + + if ((Offset + Len) == EEPROM_SIZE) + rtmp_ee_flash_write_all(pAd); + + if (Len != 16) +#endif /* RTMP_FLASH_SUPPORT */ + { + if ((Offset + Len) <= EEPROM_SIZE) + EEWriteBulk(pAd, (UINT16 *)(((UCHAR *)Buffer) + Offset), Offset, Len); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: exceed EEPROM size(%d)\n", __func__, EEPROM_SIZE)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Offset = %u\n", Offset)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Length = %u\n", Len)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Offset + Length=%u\n", (Offset + Len))); + } + } + +HQA_WriteBulkEEPROM_RET: + ResponseToQA(HqaCmdFrame, WRQ, 2 + Len, Ret); + if (Buffer) + os_free_mem(Buffer); +#endif + return Ret; +} + + +#ifdef RTMP_EFUSE_SUPPORT +static INT32 HQA_CheckEfuseMode( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; +#if !defined(COMPOS_TESTMODE_WIN) /* 1Todo eFuseGetFreeBlockCount */ + UINT32 Value; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (pAd->bUseEfuse) + Value = 1; + else + Value = 0; + + Value = PKTL_TRAN_TO_NET(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); +#endif + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + + +static INT32 HQA_GetFreeEfuseBlock( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; +#if !defined(COMPOS_TESTMODE_WIN) /* 1Todo eFuseGetFreeBlockCount */ + /* remove this block when command RSP function ready */ + UINT32 Value; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + eFuseGetFreeBlockCount(pAd, &Value); + Value = PKTL_TRAN_TO_NET(Value); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); +#else + INT32 GetFreeBlock = 0; + UINT32 Result = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: GetFreeBlock:%d\n", __func__, GetFreeBlock)); + + if (ATEOp->EfuseGetFreeBlock) { + ATEOp->EfuseGetFreeBlock(pAd, GetFreeBlock, &Result); + Result = PKTL_TRAN_TO_HOST(Result); + memcpy(HqaCmdFrame->Data + 2, &Result, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + } else { + Ret = TM_STATUS_NOTSUPPORT; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + } + +#endif + return Ret; +} + + +/* 1 todo not support yet */ +static INT32 HQA_GetEfuseBlockNr( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_WriteEFuseFromBuffer( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} +#endif /* RTMP_EFUSE_SUPPORT */ + + +static INT32 HQA_GetTxPower( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Channel = 0, Band = 0, Ch_Band = 0, EfuseAddr = 0, Power = 0; + INT32 offset = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Channel, (PUCHAR)&HqaCmdFrame->Data, sizeof(Channel)); + Channel = PKTL_TRAN_TO_HOST(Channel); + offset += sizeof(Channel); + memcpy((PUCHAR)&Band, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Band)); + Band = PKTL_TRAN_TO_HOST(Band); + offset += sizeof(Band); + memcpy((PUCHAR)&Ch_Band, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Ch_Band)); + Ch_Band = PKTL_TRAN_TO_HOST(Ch_Band); + offset += sizeof(Ch_Band); + + ATECtrl->control_band_idx = (UCHAR)Band; + + if (ATEOp->GetTxPower) { + ATEOp->GetTxPower(pAd, Channel, Ch_Band, &EfuseAddr, &Power); + os_msec_delay(30); +#if defined(MT7615) || defined(MT7622) + EfuseAddr = PKTL_TRAN_TO_HOST(EfuseAddr); + Power = PKTL_TRAN_TO_HOST(Power); + memcpy(HqaCmdFrame->Data + 2, &EfuseAddr, 4); + memcpy(HqaCmdFrame->Data + 2 + 4, &Power, 4); +#else +#endif /* defined(MT7615) || defined(MT7622) */ + } else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 10, Ret); + return Ret; +} + + +static INT32 HQA_SetCfgOnOff( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Type, Enable, Band; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Type, HqaCmdFrame->Data, 4); + Type = PKTL_TRAN_TO_HOST(Type); + memcpy((PUCHAR)&Enable, HqaCmdFrame->Data + 4, 4); + Enable = PKTL_TRAN_TO_HOST(Enable); + memcpy((PUCHAR)&Band, HqaCmdFrame->Data + 8, 4); + Band = PKTL_TRAN_TO_HOST(Band); + + ATECtrl->control_band_idx = (UCHAR)Band; + + if (ATEOp->SetCfgOnOff) + ATEOp->SetCfgOnOff(pAd, Type, Enable); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetFreqOffset( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 FreqOffset = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (ATEOp->GetTxFreqOffset) { + ATEOp->GetTxFreqOffset(pAd, &FreqOffset); + FreqOffset = PKTL_TRAN_TO_HOST(FreqOffset); + memcpy(HqaCmdFrame->Data + 2, &FreqOffset, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + } else { + Ret = TM_STATUS_NOTSUPPORT; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + } + + return Ret; +} + +static INT32 HQA_DBDCTXTone( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 BandIdx = 0, Control = 0, AntIndex = 0, ToneType = 0, ToneFreq = 0, DcOffset_I = 0, DcOffset_Q = 0, Band = 0; + INT32 RF_Power = 0, Digital_Power = 0; + INT32 offset = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* BandIdx:4 Control:4 AntIndex:4 ToneType:4 ToneFreq:4 DcOffset_I:4 DcOffset_Q:4 Band:4 */ + memcpy((PUCHAR)&BandIdx, (PUCHAR)&HqaCmdFrame->Data, sizeof(BandIdx)); + BandIdx = PKTL_TRAN_TO_HOST(BandIdx); + offset += sizeof(BandIdx); + memcpy((PUCHAR)&Control, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Control)); + Control = PKTL_TRAN_TO_HOST(Control); + offset += sizeof(Control); + memcpy((PUCHAR)&AntIndex, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(AntIndex)); + AntIndex = PKTL_TRAN_TO_HOST(AntIndex); + offset += sizeof(AntIndex); + memcpy((PUCHAR)&ToneType, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(ToneType)); + ToneType = PKTL_TRAN_TO_HOST(ToneType); + offset += sizeof(ToneType); + memcpy((PUCHAR)&ToneFreq, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(ToneFreq)); + ToneFreq = PKTL_TRAN_TO_HOST(ToneFreq); + offset += sizeof(ToneFreq); + memcpy((PUCHAR)&DcOffset_I, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(DcOffset_I)); + DcOffset_I = PKTL_TRAN_TO_HOST(DcOffset_I); + offset += sizeof(DcOffset_I); + memcpy((PUCHAR)&DcOffset_Q, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(DcOffset_Q)); + DcOffset_Q = PKTL_TRAN_TO_HOST(DcOffset_Q); + offset += sizeof(DcOffset_Q); + memcpy((PUCHAR)&Band, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Band)); + Band = PKTL_TRAN_TO_HOST(Band); + offset += sizeof(Band); + memcpy((PUCHAR)&RF_Power, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(RF_Power)); + RF_Power = PKTL_TRAN_TO_HOST(RF_Power); + offset += sizeof(RF_Power); + memcpy((PUCHAR)&Digital_Power, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Digital_Power)); + Digital_Power = PKTL_TRAN_TO_HOST(Digital_Power); + offset += sizeof(Digital_Power); + + ATECtrl->control_band_idx = (UCHAR)BandIdx; + + if (ATEOp->SetDBDCTxTonePower) + ATEOp->SetDBDCTxTonePower(pAd, RF_Power, Digital_Power, AntIndex); + else + Ret = TM_STATUS_NOTSUPPORT; + + if (ATEOp->DBDCTxTone) + ATEOp->DBDCTxTone(pAd, Control, AntIndex, ToneType, ToneFreq, DcOffset_I, DcOffset_Q, Band); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_DBDCContinuousTX( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Band = 0, Control = 0, AntMask = 0, Phymode = 0, BW = 0; + INT32 Pri_Ch = 0, Rate = 0, Central_Ch = 0, TxfdMode; + INT32 offset = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* Band:4 Control:4 AntIndex:4 Modulation:4 BW:4 Pri_Ch:4 Rate:4 */ + memcpy((PUCHAR)&Band, (PUCHAR)&HqaCmdFrame->Data, sizeof(Band)); + Band = PKTL_TRAN_TO_HOST(Band); + offset += sizeof(Band); + memcpy((PUCHAR)&Control, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Control)); + Control = PKTL_TRAN_TO_HOST(Control); + offset += sizeof(Control); + memcpy((PUCHAR)&AntMask, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(AntMask)); + AntMask = PKTL_TRAN_TO_HOST(AntMask); + offset += sizeof(AntMask); + memcpy((PUCHAR)&Phymode, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Phymode)); + Phymode = PKTL_TRAN_TO_HOST(Phymode); + offset += sizeof(Phymode); + memcpy((PUCHAR)&BW, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(BW)); + BW = PKTL_TRAN_TO_HOST(BW); + offset += sizeof(BW); + memcpy((PUCHAR)&Pri_Ch, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Pri_Ch)); + Pri_Ch = PKTL_TRAN_TO_HOST(Pri_Ch); + offset += sizeof(Pri_Ch); + memcpy((PUCHAR)&Rate, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Rate)); + Rate = PKTL_TRAN_TO_HOST(Rate); + offset += sizeof(Rate); + memcpy((PUCHAR)&Central_Ch, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Central_Ch)); + Central_Ch = PKTL_TRAN_TO_HOST(Central_Ch); + offset += sizeof(Central_Ch); + memcpy((PUCHAR)&TxfdMode, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(TxfdMode)); + TxfdMode = PKTL_TRAN_TO_HOST(TxfdMode); + offset += sizeof(TxfdMode); + + ATECtrl->control_band_idx = (UCHAR)Band; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Band = %d, Control = %d, AntIndex = %d, Phymode = %d, BW = %d, CH = %d, Rate = %d, Central_Ch = %d, TxfdMode = %d\n", + __func__, Band, Control, AntMask, Phymode, BW, Pri_Ch, Rate, Central_Ch, TxfdMode)); + + if (Control) { + if (ATEOp->StartContinousTx) { + TESTMODE_SET_PARAM(ATECtrl, Band, PhyMode, Phymode); + TESTMODE_SET_PARAM(ATECtrl, Band, BW, BW); + TESTMODE_SET_PARAM(ATECtrl, Band, ControlChl, Pri_Ch); + TESTMODE_SET_PARAM(ATECtrl, Band, Channel, Central_Ch); + TESTMODE_SET_PARAM(ATECtrl, Band, Mcs, Rate); + TESTMODE_SET_PARAM(ATECtrl, Band, TxAntennaSel, AntMask); + ATEOp->StartContinousTx(pAd, AntMask, TxfdMode); + } else + Ret = TM_STATUS_NOTSUPPORT; + } else { + if (ATEOp->StopContinousTx) + ATEOp->StopContinousTx(pAd, TxfdMode); + else + Ret = TM_STATUS_NOTSUPPORT; + } + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_SetRXFilterPktLen( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Band = 0, Control = 0, RxPktlen = 0; + INT32 offset = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Band, (PUCHAR)&HqaCmdFrame->Data, sizeof(Band)); + Band = PKTL_TRAN_TO_HOST(Band); + offset += sizeof(Band); + memcpy((PUCHAR)&Control, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Control)); + Control = PKTL_TRAN_TO_HOST(Control); + offset += sizeof(Control); + memcpy((PUCHAR)&RxPktlen, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(RxPktlen)); + RxPktlen = PKTL_TRAN_TO_HOST(RxPktlen); + offset += sizeof(RxPktlen); + + ATECtrl->control_band_idx = (UCHAR)Band; + + if (ATEOp->SetRXFilterPktLen) + ATEOp->SetRXFilterPktLen(pAd, Control, RxPktlen); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetTXInfo( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + UINT32 txed_band0 = 0; + UINT32 txed_band1 = 0; + UCHAR *data = HqaCmdFrame->Data + 2; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + txed_band0 = TESTMODE_GET_PARAM(ate_ctrl, 0, TxDoneCount); + txed_band1 = TESTMODE_GET_PARAM(ate_ctrl, 1, TxDoneCount); + txed_band0 = PKTL_TRAN_TO_NET(txed_band0); + txed_band1 = PKTL_TRAN_TO_NET(txed_band1); + NdisMoveMemory(data, (UCHAR *)&txed_band0, sizeof(txed_band0)); + data += sizeof(txed_band0); + NdisMoveMemory(data, (UCHAR *)&txed_band1, sizeof(txed_band1)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(txed_band0) + sizeof(txed_band1), Ret); + return Ret; +} + + +static INT32 HQA_GetCfgOnOff( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Type = 0, Band = 0; + UINT32 Result = 0; + INT32 offset = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Type, (PUCHAR)&HqaCmdFrame->Data, sizeof(Type)); + Type = PKTL_TRAN_TO_HOST(Type); + offset += sizeof(Type); + memcpy((PUCHAR)&Band, (PUCHAR)&HqaCmdFrame->Data + offset, sizeof(Band)); + Band = PKTL_TRAN_TO_HOST(Band); + offset += sizeof(Band); + + ATECtrl->control_band_idx = (UCHAR)Band; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Type:%d Band:%d\n", __func__, Type, Band)); + + if (ATEOp->GetCfgOnOff) { +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + + /*FW not support Get Rate power (Type=2)*/ + if ((IS_MT7615(pAd) || IS_MT7622(pAd) || IS_P18(pAd) || IS_MT7663(pAd)) && Type != 2) +#endif + { + ATEOp->GetCfgOnOff(pAd, Type, &Result); + } + + Result = PKTL_TRAN_TO_HOST(Result); + memcpy(HqaCmdFrame->Data + 2, &Result, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + } else { + Ret = TM_STATUS_NOTSUPPORT; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + } + + return Ret; +} + + +static INT32 HQA_SetBufferBin( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; +#if defined(COMPOS_TESTMODE_WIN) + UINT32 buffer_mode_merge = 0; + UCHAR *data = HqaCmdFrame->Data; + + EthGetParamAndShiftBuff(TRUE, sizeof(buffer_mode_merge), &data, (UCHAR *)&buffer_mode_merge); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("buffer_mode_merge = %d\n", buffer_mode_merge)); + + if (buffer_mode_merge == 0) + pAd->CalFreeMerge = FALSE; + else + pAd->CalFreeMerge = TRUE; + +#else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s not support this commmand, to disable cal-free merge use DisableCalFree in profile setting\n", __func__)); +#endif + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_CA53RegRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 ret = 0; + unsigned long offset; + UINT32 value; + + NdisMoveMemory((PUCHAR)&offset, (PUCHAR)&HqaCmdFrame->Data, sizeof(unsigned long)); + + offset = PKTL_TRAN_TO_HOST(offset); + offset = (unsigned long)ioremap(offset, CA53_GPIO_REMAP_SIZE); + RTMP_SYS_IO_READ32(offset, &value); + iounmap((void *)offset); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: offset = %lx, value = %x\n", __func__, offset, value)); + + value = PKTL_TRAN_TO_NET(value); + NdisMoveMemory(HqaCmdFrame->Data + 2, (UCHAR *)&value, sizeof(value)); + + ResponseToQA(HqaCmdFrame, WRQ, 6, ret); + return ret; +} + + +static INT32 HQA_CA53RegWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 ret = 0; + unsigned long offset; + UINT32 value; + + NdisMoveMemory((PUCHAR)&offset, (PUCHAR)&HqaCmdFrame->Data, sizeof(unsigned long)); + /* Shift 4 bytes only because dll cmd format */ + NdisMoveMemory((PUCHAR)&value, (PUCHAR)&HqaCmdFrame->Data + 4, sizeof(UINT32)); + + offset = PKTL_TRAN_TO_HOST(offset); + value = PKTL_TRAN_TO_HOST(value); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: offset = %lx, value = %x\n", __func__, offset, value)); + + offset = (unsigned long)ioremap(offset, CA53_GPIO_REMAP_SIZE); + RTMP_SYS_IO_WRITE32(offset, value); + iounmap((void *)offset); + + ResponseToQA(HqaCmdFrame, WRQ, 2, ret); + return ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET3[] = { + /* cmd id start from 0x1300 */ + HQA_MacBbpRegRead, /* 0x1300 */ + HQA_MacBbpRegWrite, /* 0x1301 */ + HQA_MACBbpRegBulkRead, /* 0x1302 */ + HQA_RfRegBulkRead, /* 0x1303 */ + HQA_RfRegBulkWrite, /* 0x1304 */ + HQA_ReadEEPROM, /* 0x1305 */ + HQA_WriteEEPROM, /* 0x1306 */ + HQA_ReadBulkEEPROM, /* 0x1307 */ + HQA_WriteBulkEEPROM, /* 0x1308 */ +#ifdef RTMP_EFUSE_SUPPORT + HQA_CheckEfuseMode, /* 0x1309 */ + HQA_GetFreeEfuseBlock, /* 0x130A */ + HQA_GetEfuseBlockNr, /* 0x130B */ + HQA_WriteEFuseFromBuffer, /* 0x130C */ +#endif /* RTMP_EFUSE_SUPPORT */ + HQA_GetTxPower, /* 0x130D */ + HQA_SetCfgOnOff, /* 0x130E */ + HQA_GetFreqOffset, /* 0x130F */ + HQA_DBDCTXTone, /* 0x1310 */ + HQA_DBDCContinuousTX, /* 0x1311 */ + HQA_SetRXFilterPktLen, /* 0x1312 */ + HQA_GetTXInfo, /* 0x1313 */ + HQA_GetCfgOnOff, /* 0x1314 */ + NULL, + HQA_SetBufferBin, /* 0x1316 */ + NULL, /* 0x1317 */ + HQA_CA53RegRead, /* 0x1318 */ + HQA_CA53RegWrite, /* 0x1319 */ +}; + + +/* 1 todo not support yet */ +static INT32 HQA_ReadTempReferenceValue( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +VOID HQA_GetThermalValue_CB(struct cmd_msg *msg, char *Data, UINT16 Len) +{ + struct _EXT_EVENT_GET_SENSOR_RESULT_T *EventExtCmdResult = (struct _EXT_EVENT_GET_SENSOR_RESULT_T *)Data; + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + EventExtCmdResult->u4SensorResult = le2cpu32(EventExtCmdResult->u4SensorResult); + ATECtrl->thermal_val = EventExtCmdResult->u4SensorResult; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): value: 0x%x\n", __func__, EventExtCmdResult->u4SensorResult)); +#if !defined(COMPOS_TESTMODE_WIN)/* 1 todo windows no need RTMP_OS_COMPLETE */ + RTMP_OS_COMPLETE(&ATECtrl->cmd_done); +#endif +} + +static INT32 HQA_GetThermalValue( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* CmdGetThemalSensorResult(pAd, 0); 0: get temperature; 1: get adc */ + MtCmdGetThermalSensorResult(pAd, 0, &ATECtrl->thermal_val); /* 0: get temperature; 1: get adc */ + Value = PKTL_TRAN_TO_HOST(ATECtrl->thermal_val); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 6, Ret); + return Ret; +} + +/* 1 todo not support yet */ +static INT32 HQA_SetSideBandOption( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET4[] = { + /* cmd id start from 0x1400 */ + HQA_ReadTempReferenceValue, /* 0x1400 */ + HQA_GetThermalValue, /* 0x1401 */ + HQA_SetSideBandOption, /* 0x1402 */ +}; + + +static INT32 hqa_get_fw_info( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + if (ATEOp->GetFWInfo) + Ret = ATEOp->GetFWInfo(pAd, HqaCmdFrame->Data + 2); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, (2+1+8+6+15), Ret); + return Ret; +} + + +static INT32 HQA_StartContinousTx( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0, WFSel = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + /* TODO Get Correct TxfdMode*/ + UINT32 TxfdMode = 1; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* Modulation:4 BW:4 PRI_CH:4 RATE:4 WFSel:4 */ + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + ATECtrl->PhyMode = (UCHAR)Value; + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + Value = PKTL_TRAN_TO_HOST(Value); + ATECtrl->BW = (UCHAR)Value; + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 8, 4); + Value = PKTL_TRAN_TO_HOST(Value); + ATECtrl->ControlChl = (UCHAR)Value; + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 12, 4); + Value = PKTL_TRAN_TO_HOST(Value); + ATECtrl->Mcs = (UCHAR)Value; + memcpy((PUCHAR)&WFSel, (PUCHAR)&HqaCmdFrame->Data + 16, 4); + WFSel = PKTL_TRAN_TO_HOST(WFSel); + + if (ATEOp->StartContinousTx) + ATEOp->StartContinousTx(pAd, (CHAR)WFSel, TxfdMode); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetSTBC( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((UINT8 *)&Value, (UINT8 *)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + ATECtrl->Stbc = (UINT8)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetShortGI( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + ATECtrl->Sgi = (UCHAR)Value; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetDPD( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0, WFSel; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ON/OFF:4 WF Sel:4 */ + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + memcpy((PUCHAR)&WFSel, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + WFSel = PKTL_TRAN_TO_HOST(WFSel); + + if (ATEOp->SetDPD) + ATEOp->SetDPD(pAd, (CHAR)WFSel, (CHAR)Value); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + + return Ret; +} + + +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) +static VOID HQA_ParseRxRssiCR(PRTMP_ADAPTER pAd, struct _HQA_RX_STAT *HqaRxStat, INT type, UINT32 value, UINT32 Ch_Band) +{ + UINT32 IBRssi0 = 0, IBRssi1 = 0, WBRssi0 = 0, WBRssi1 = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Value : %02x\n", __func__, value)); + if (IS_MT7615(pAd)) { + IBRssi0 = (value & 0xFF000000) >> 24; + if (IBRssi0 >= 128) + IBRssi0 -= 256; + WBRssi0 = (value & 0x00FF0000) >> 16; + if (WBRssi0 >= 128) + WBRssi0 -= 256; + IBRssi1 = (value & 0x0000FF00) >> 8; + if (IBRssi1 >= 128) + IBRssi1 -= 256; + WBRssi1 = (value & 0x000000FF); + if (WBRssi1 >= 128) + WBRssi1 -= 256; + } else if (IS_MT7622(pAd)) { + IBRssi1 = (value & 0xFF000000) >> 24; + if (IBRssi1 >= 128) + IBRssi1 -= 256; + WBRssi1 = (value & 0x00FF0000) >> 16; + if (WBRssi1 >= 128) + WBRssi1 -= 256; + IBRssi0 = (value & 0x0000FF00) >> 8; + if (IBRssi0 >= 128) + IBRssi0 -= 256; + WBRssi0 = (value & 0x000000FF); + if (WBRssi0 >= 128) + WBRssi0 -= 256; + } + + if (type == HQA_RX_STAT_RSSI) { + IBRssi0 = MtATERSSIOffset(pAd, IBRssi0, 0, Ch_Band); + IBRssi1 = MtATERSSIOffset(pAd, IBRssi1, 1, Ch_Band); + WBRssi0 = MtATERSSIOffset(pAd, WBRssi0, 0, Ch_Band); + WBRssi1 = MtATERSSIOffset(pAd, WBRssi1, 1, Ch_Band); + HqaRxStat->IB_RSSSI0 = PKTL_TRAN_TO_HOST(IBRssi0); + HqaRxStat->WB_RSSSI0 = PKTL_TRAN_TO_HOST(WBRssi0); + HqaRxStat->IB_RSSSI1 = PKTL_TRAN_TO_HOST(IBRssi1); + HqaRxStat->WB_RSSSI1 = PKTL_TRAN_TO_HOST(WBRssi1); + HqaRxStat->Inst_IB_RSSSI[0] = PKTL_TRAN_TO_HOST(IBRssi0); + HqaRxStat->Inst_WB_RSSSI[0] = PKTL_TRAN_TO_HOST(WBRssi0); + HqaRxStat->Inst_IB_RSSSI[1] = PKTL_TRAN_TO_HOST(IBRssi1); + HqaRxStat->Inst_WB_RSSSI[1] = PKTL_TRAN_TO_HOST(WBRssi1); + } else { + IBRssi0 = MtATERSSIOffset(pAd, IBRssi0, 2, Ch_Band); + IBRssi1 = MtATERSSIOffset(pAd, IBRssi1, 3, Ch_Band); + WBRssi0 = MtATERSSIOffset(pAd, WBRssi0, 2, Ch_Band); + WBRssi1 = MtATERSSIOffset(pAd, WBRssi1, 3, Ch_Band); + HqaRxStat->Inst_IB_RSSSI[2] = PKTL_TRAN_TO_HOST(IBRssi0); + HqaRxStat->Inst_WB_RSSSI[2] = PKTL_TRAN_TO_HOST(WBRssi0); + HqaRxStat->Inst_IB_RSSSI[3] = PKTL_TRAN_TO_HOST(IBRssi1); + HqaRxStat->Inst_WB_RSSSI[3] = PKTL_TRAN_TO_HOST(WBRssi1); + } +} +#else +static VOID HQA_ParseRxRssiCR(PRTMP_ADAPTER pAd, struct _HQA_RX_STAT *HqaRxStat, INT type, UINT32 value, UINT32 Ch_Band) +{ + UINT32 IBRssi0, IBRssi1, WBRssi0, WBRssi1; + + /*[31:24]IBRSSI0 [23:16]WBRSSI0 [15:8]IBRSSI1 [7:0]WBRSSI1*/ + IBRssi0 = (value & 0xFF000000) >> 24; + + if (IBRssi0 > 128) + IBRssi0 -= 256; + + WBRssi0 = (value & 0x00FF0000) >> 16; + + if (WBRssi0 > 128) + WBRssi0 -= 256; + + IBRssi1 = (value & 0x0000FF00) >> 8; + + if (IBRssi1 > 128) + IBRssi1 -= 256; + + WBRssi1 = (value & 0x000000FF); + + if (WBRssi1 > 128) + WBRssi1 -= 256; + + HqaRxStat->IB_RSSSI0 = PKTL_TRAN_TO_HOST(IBRssi0); + HqaRxStat->WB_RSSSI0 = PKTL_TRAN_TO_HOST(WBRssi0); + HqaRxStat->IB_RSSSI1 = PKTL_TRAN_TO_HOST(IBRssi1); + HqaRxStat->WB_RSSSI1 = PKTL_TRAN_TO_HOST(WBRssi1); +} +#endif + + +static INT32 HQA_GetRxStatisticsAll( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _HQA_RX_STAT HqaRxStat; + UINT32 rx_driver_cnt = 0; + INT i = 0; + UINT32 Ch_Band_0 = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND0, Ch_Band); + UINT32 Ch_Band_1 = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND0, Ch_Band); + UCHAR FAGC_Path_0 = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND0, FAGC_Path); + UCHAR FAGC_Path_1 = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND0, FAGC_Path); + + if (IS_ATE_DBDC(pAd)) { + Ch_Band_1 = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND1, Ch_Band); + FAGC_Path_1 = TESTMODE_GET_PARAM(ATECtrl, TESTMODE_BAND1, FAGC_Path); + } + + memset(&HqaRxStat, 0, sizeof(struct _HQA_RX_STAT)); + + /* MAC COUNT */ +#if defined(MT7615) || defined(MT7637) || defined(MT7622) || defined(P18) || defined(MT7663) + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MACFCSERRCNT); + ATECtrl->rx_stat.RxMacFCSErrCount = value; + HqaRxStat.mac_rx_fcs_err_cnt = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RxMacFCSErrCount); +#else + /* Get latest FCSErr. sync iwpriv & HQA same FCSErr result */ + NICUpdateRawCounters(pAd); + HqaRxStat.mac_rx_fcs_err_cnt = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RxMacFCSErrCount); +#endif + value = MtAsicGetRxStat(pAd, HQA_RX_FIFO_FULL_COUNT); + HqaRxStat.rx_fifo_full = PKTL_TRAN_TO_HOST(value); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MAC_MDRDYCNT); + ATECtrl->rx_stat.RxMacMdrdyCount = value; + HqaRxStat.mac_rx_mdrdy_cnt = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RxMacMdrdyCount); +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MAC_RXLENMISMATCH); + HqaRxStat.mac_rx_len_mismatch = PKTL_TRAN_TO_HOST(value); + + if (IS_ATE_DBDC(pAd)) { + value = MtAsicGetRxStat(pAd, HQA_RX_FIFO_FULL_COUNT_BAND1); + HqaRxStat.rx_fifo_full_band1 = PKTL_TRAN_TO_HOST(value); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MACFCSERRCNT_BAND1); + ATECtrl->rx_stat.RxMacFCSErrCount_band1 = value; + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MAC_MDRDYCNT_BAND1); + ATECtrl->rx_stat.RxMacMdrdyCount_band1 = value; + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MAC_RXLENMISMATCH_BAND1); + HqaRxStat.mac_rx_len_mismatch_band1 = PKTL_TRAN_TO_HOST(value); + HqaRxStat.mac_rx_fcs_err_cnt_band1 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RxMacFCSErrCount_band1); + HqaRxStat.mac_rx_mdrdy_cnt_band1 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RxMacMdrdyCount_band1); + } +#endif +#ifdef MT7622 + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_MAC_FCS_OK_COUNT); + HqaRxStat.mac_rx_fcs_ok_cnt = PKTL_TRAN_TO_HOST(value); +#endif /* MT7622 */ + + /* PHY COUNT */ + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PHY_FCSERRCNT); + HqaRxStat.phy_rx_fcs_err_cnt_ofdm = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_fcs_err_cnt_cck = PKTL_TRAN_TO_HOST(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PD); + HqaRxStat.phy_rx_pd_ofdm = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_pd_cck = PKTL_TRAN_TO_HOST(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_CCK_SIG_SFD); + HqaRxStat.phy_rx_sig_err_cck = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_sfd_err_cck = PKTL_TRAN_TO_HOST(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_OFDM_SIG_TAG); + HqaRxStat.phy_rx_sig_err_ofdm = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_tag_err_ofdm = PKTL_TRAN_TO_HOST(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_RSSI); + HQA_ParseRxRssiCR(pAd, &HqaRxStat, HQA_RX_STAT_RSSI, value, Ch_Band_0); +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_RSSI_RX23); + HQA_ParseRxRssiCR(pAd, &HqaRxStat, HQA_RX_STAT_RSSI_RX23, value, Ch_Band_1); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_ACI_HITL); + HqaRxStat.ACIHitLow = PKTL_TRAN_TO_HOST((value >> 18) & 0x1); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_ACI_HITH); + HqaRxStat.ACIHitHigh = PKTL_TRAN_TO_HOST((value >> 18) & 0x1); +#endif + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PHY_MDRDYCNT); + HqaRxStat.phy_rx_mdrdy_cnt_ofdm = PKTL_TRAN_TO_HOST(value >> 16); + if (IS_MT7615(pAd)) + HqaRxStat.phy_rx_mdrdy_cnt_cck = PKTL_TRAN_TO_HOST(value & 0xFFFF); + else if (IS_MT7622(pAd)) { + /* HW issue and SW workaround */ + HqaRxStat.phy_rx_mdrdy_cnt_cck = PKTL_TRAN_TO_HOST((value & 0xFFFF)/2); + } + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PHY_MDRDYCNT_BAND1); + HqaRxStat.phy_rx_mdrdy_cnt_ofdm_band1 = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_mdrdy_cnt_cck_band1 = PKTL_TRAN_TO_HOST(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_PD_BAND1); + HqaRxStat.phy_rx_pd_ofdm_band1 = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_pd_cck_band1 = PKTL_TRAN_TO_HOST(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_CCK_SIG_SFD_BAND1); + HqaRxStat.phy_rx_sig_err_cck_band1 = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_sfd_err_cck_band1 = PKTL_TRAN_TO_HOST(value & 0xFFFF); + value = MtAsicGetRxStat(pAd, HQA_RX_STAT_OFDM_SIG_TAG_BAND1); + HqaRxStat.phy_rx_sig_err_ofdm_band1 = PKTL_TRAN_TO_HOST(value >> 16); + HqaRxStat.phy_rx_tag_err_ofdm_band1 = PKTL_TRAN_TO_HOST(value & 0xFFFF); + + /* DRIVER COUNT */ + rx_driver_cnt = ATECtrl->rx_stat.RxTotalCnt[0]; + HqaRxStat.DriverRxCount = PKTL_TRAN_TO_HOST(rx_driver_cnt); +#ifdef MT7615 +#ifdef CFG_SUPPORT_MU_MIMO + HqaRxStat.MuPktCount = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RxMacMuPktCount); +#endif +#endif +#ifdef MT7615 + rx_driver_cnt = 0; + + if (IS_ATE_DBDC(pAd)) + rx_driver_cnt = ATECtrl->rx_stat.RxTotalCnt[1]; + + HqaRxStat.DriverRxCount1 = PKTL_TRAN_TO_HOST(rx_driver_cnt); +#endif + + /* RXV COUNT */ + for (i = 0; i < 4; i++) { + if (i < 2) + ATECtrl->rx_stat.FAGC_RSSI_IB[i] = MtATERSSIOffset(pAd, ATECtrl->rx_stat.FAGC_RSSI_IB[i], FAGC_Path_0, Ch_Band_0); + else + ATECtrl->rx_stat.FAGC_RSSI_IB[i] = MtATERSSIOffset(pAd, ATECtrl->rx_stat.FAGC_RSSI_IB[i], FAGC_Path_1, Ch_Band_1); + + HqaRxStat.FAGC_IB_RSSSI[i] = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.FAGC_RSSI_IB[i]); + } + + for (i = 0; i < 4; i++) { + if (i < 2) + ATECtrl->rx_stat.FAGC_RSSI_WB[i] = MtATERSSIOffset(pAd, ATECtrl->rx_stat.FAGC_RSSI_WB[i], FAGC_Path_0, Ch_Band_0); + else + ATECtrl->rx_stat.FAGC_RSSI_WB[i] = MtATERSSIOffset(pAd, ATECtrl->rx_stat.FAGC_RSSI_WB[i], FAGC_Path_1, Ch_Band_1); + + HqaRxStat.FAGC_WB_RSSSI[i] = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.FAGC_RSSI_WB[i]); + } + + HqaRxStat.RCPI0 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RCPI[0]); + HqaRxStat.RCPI1 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RCPI[1]); + HqaRxStat.FreqOffsetFromRX = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.FreqOffsetFromRx); + HqaRxStat.RSSI0 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RSSI[0]); + HqaRxStat.RSSI1 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RSSI[1]); +#if defined(MT7615) || defined(MT7622) + HqaRxStat.RCPI2 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RCPI[2]); + HqaRxStat.RCPI3 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RCPI[3]); + HqaRxStat.RSSI2 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RSSI[2]); + HqaRxStat.RSSI3 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RSSI[3]); + HqaRxStat.SNR0 = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.SNR[0]); + HqaRxStat.SIG_MCS = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.SIG_MCS); + HqaRxStat.SINR = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.SINR); + HqaRxStat.RXVRSSI = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.RXVRSSI); +#endif /* defined(MT7615) || defined(MT7622) */ + { + for (i = 0; i < 4; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Report[0]: RCPI[%d]:%x\n", + i, ATECtrl->rx_stat.RCPI[i])); + + for (i = 0; i < 4; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Report[1]: FAGC_RSSI_IB[%d]:%x\n", + i, ATECtrl->rx_stat.FAGC_RSSI_IB[i])); + + for (i = 0; i < 4; i++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Report[2]: FAGC_RSSI_WB[%d]:%x\n", + i, ATECtrl->rx_stat.FAGC_RSSI_WB[i])); + } + memcpy(HqaCmdFrame->Data + 2, &(HqaRxStat), sizeof(struct _HQA_RX_STAT)); + ResponseToQA(HqaCmdFrame, WRQ, (2 + sizeof(struct _HQA_RX_STAT)), Ret); + return Ret; +} + + +static INT32 HQA_StartContiTxTone( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + + if (ATEOp->StartTxTone) + ATEOp->StartTxTone(pAd, Value); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_StopContiTxTone( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + /* MtAsicSetTxToneTest(pAd, 0, 0); */ + if (ATEOp->StopTxTone) + ATEOp->StopTxTone(pAd); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_CalibrationTestMode( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Value = 0; + INT32 Ret = 0; + UINT8 Mode = 0; + INT32 ICaplen = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + NdisMoveMemory((PUCHAR)&ICaplen, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + ICaplen = PKTL_TRAN_TO_HOST(ICaplen); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: mode = %X ICapLen= %X\n", __func__, Value, ICaplen)); + + if (Value == 0) { + if (ATECtrl->Mode & ATE_FFT) + ATECtrl->Mode &= ~ATE_FFT; + + ATECtrl->Mode &= ~fATE_IN_RFTEST; + Mode = OPERATION_NORMAL_MODE; + } else if (Value == 1) { + ATECtrl->Mode |= fATE_IN_RFTEST; + Mode = OPERATION_RFTEST_MODE; + } else if (Value == 2) { + ATECtrl->Mode |= fATE_IN_RFTEST; + Mode = OPERATION_ICAP_MODE; + } else if (Value == 3) { + ATECtrl->Mode |= fATE_IN_RFTEST; + ATECtrl->Mode |= fATE_IN_ICAPOVERLAP; + Mode = OPERATION_ICAP_OVERLAP; + } else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: Mode = %d error!!!\n", __func__, Value)); + + MtCmdRfTestSwitchMode(pAd, Mode, ICaplen, RF_TEST_DEFAULT_RESP_LEN); +#if !defined(COMPOS_TESTMODE_WIN) + msleep(100); + RcUpdateBandCtrl((struct hdev_ctrl *)pAd->hdev_ctrl); +#endif + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_DoCalibrationTestItem( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &pAd->ATECtrl; + INT32 Ret = 0; + UINT32 item = 0; + UINT32 band_idx = 0; + UCHAR *data = HqaCmdFrame->Data; + + NdisMoveMemory((UCHAR *)&item, data, sizeof(item)); + data += sizeof(item); + item = PKTL_TRAN_TO_HOST(item); + NdisMoveMemory((UCHAR *)&band_idx, data, sizeof(band_idx)); + data += sizeof(band_idx); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + +#if defined(COMPOS_TESTMODE_WIN) + CreateThread(pAd); + pAd->ReCalID = item; + OpenFile(&pAd->hReCalibrationFile, RE_CALIBRATION_FILE, FILE_OPEN_IF, FILE_APPEND_DATA); + WriteFile("[RECAL DUMP START]\r\n", strlen("[RECAL DUMP START]\r\n"), pAd->hReCalibrationFile); +#endif + MtCmdDoCalibration(pAd, RE_CALIBRATION, item, band_idx); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s, item:%x, band_idx:%x\n" + , __func__, item, band_idx)); +#if defined(COMPOS_TESTMODE_WIN) + os_msec_delay(1000); + WriteFile("[RECAL DUMP END]\r\n", strlen("[RECAL DUMP END]\r\n"), pAd->hReCalibrationFile); + CloseFile(pAd->hReCalibrationFile); + /* create log dump finish file */ + OpenFile(&pAd->hReCalibrationFile, RE_CALIBRATION_FINISH_FILE, FILE_OPEN_IF, FILE_APPEND_DATA); + CloseFile(pAd->hReCalibrationFile); +#endif + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_eFusePhysicalWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_eFusePhysicalRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_eFuseLogicalRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_eFuseLogicalWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + /* ToDo */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TMRSetting( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; +#if !defined(COMPOS_TESTMODE_WIN) + UCHAR *data = HqaCmdFrame->Data; + UINT32 value = 0, version = 0; + CHAR TMR_Value[8]; + CHAR TMR_HW_Version[8]; + + EthGetParamAndShiftBuff(TRUE, sizeof(value), &data, (UCHAR *)&value); + EthGetParamAndShiftBuff(TRUE, sizeof(version), &data, (UCHAR *)&version); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: TMR setting: %u, TMR version: %u\n", + __func__, value, version)); + + if (version == TMR_HW_VER_100) + version = TMR_VER_1_0; + else if (version == TMR_HW_VER_150) + version = TMR_VER_1_5; + else if (version == TMR_HW_VER_200) + version = TMR_VER_2_0; + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Wrong version %d!!\n", __func__, version)); + return FALSE; + } + + sprintf(TMR_Value, "%d", value); + sprintf(TMR_HW_Version, "%d", version); + setTmrVerProc(pAd, TMR_HW_Version); + setTmrEnableProc(pAd, TMR_Value); +#endif + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetRxSNR( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Value = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Value = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.SNR[0]); + memcpy(HqaCmdFrame->Data + 2, &Value, 4); + Value = PKTL_TRAN_TO_HOST(ATECtrl->rx_stat.SNR[1]); + memcpy(HqaCmdFrame->Data + 6, &Value, 4); + ResponseToQA(HqaCmdFrame, WRQ, 10, Ret); + return Ret; +} + + +static INT32 HQA_WriteBufferDone( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); +#if !defined(COMPOS_TESTMODE_WIN) /* 1Todo Set_EepromBufferWriteBack_Proc */ + + switch (Value) { + case E2P_EFUSE_MODE: +#ifdef RF_LOCKDOWN + /* update status of Effuse write back */ + pAd->fgQAEffuseWriteBack = TRUE; +#endif /* RF_LOCKDOWN */ + Set_EepromBufferWriteBack_Proc(pAd, "1"); + break; + + case E2P_FLASH_MODE: + Set_EepromBufferWriteBack_Proc(pAd, "2"); + break; + + case E2P_EEPROM_MODE: + Set_EepromBufferWriteBack_Proc(pAd, "3"); + break; + + case E2P_BIN_MODE: + Set_EepromBufferWriteBack_Proc(pAd, "4"); + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Unknow write back mode(%d)\n", __func__, Value)); + } + +#endif +#ifdef RF_LOCKDOWN + /* update status of Effuse write back */ + pAd->fgQAEffuseWriteBack = FALSE; +#endif /* RF_LOCKDOWN */ + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_FFT( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 Value = 0; + INT32 Ret = 0; + + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + Value = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: %d\n", __func__, Value)); + Ret = ATEOp->SetFFTMode(pAd, Value); + return Ret; +} + +static INT32 HQA_SetTxTonePower(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Value = 0; + INT32 pwr1 = 0; + INT32 pwr2 = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + pwr1 = PKTL_TRAN_TO_HOST(Value); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + pwr2 = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: pwr1:%d, pwr2:%d\n", __func__, pwr1, pwr2)); + + if (ATEOp->SetTxTonePower) + ATEOp->SetTxTonePower(pAd, pwr1, pwr2); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetAIFS(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Value = 0; + UINT32 SlotTime = 0; + UINT32 SifsTime = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data, 4); + SlotTime = PKTL_TRAN_TO_HOST(Value); + memcpy((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + SifsTime = PKTL_TRAN_TO_HOST(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: SlotTime:%d, SifsTime:%d\n", __func__, SlotTime, SifsTime)); + + if (ATEOp->SetSlotTime) + ATEOp->SetSlotTime(pAd, SlotTime, SifsTime); + else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MPSSetSeqData(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + UINT32 len = 0; + INT32 Ret = 0; + UINT32 i = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 *mps_setting = NULL; + UINT32 band_idx = 0; + UINT32 offset = 0; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length) / sizeof(UINT32) - 1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u\n", __func__, len)); + + if ((len > 512) || (len == 0)) + goto MPS_SEQ_DATA_RET; + + Ret = os_alloc_mem(pAd, (UCHAR **)&mps_setting, sizeof(UINT32) * (len)); + + if (Ret == NDIS_STATUS_FAILURE) + goto MPS_SEQ_DATA_RET; + + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = OS_NTOHL(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + for (i = 0; i < len; i++) { + offset = 4 + 4 * i; + + if (offset + 4 > sizeof(HqaCmdFrame->Data)) /* Reserved at least 4 byte availbale data */ + break; + + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + offset, 4); + mps_setting[i] = PKTL_TRAN_TO_HOST(Value); + } + + ATEOp->MPSSetParm(pAd, MPS_SEQDATA, len, mps_setting); + os_free_mem(mps_setting); +MPS_SEQ_DATA_RET: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u, MPS_CNT:%u\n", __func__, len, ATECtrl->mps_cb.mps_cnt)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MPSSetPayloadLength(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + UINT32 len = 0; + INT32 Ret = 0; + UINT32 i = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 *mps_setting = NULL; + UINT32 band_idx = 0; + UINT32 offset = 0; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length) / 4 - 1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u\n", __func__, len)); + + if ((len > 1024) || (len == 0)) + goto MPS_PKT_LEN_RET; + + Ret = os_alloc_mem(pAd, (UCHAR **)&mps_setting, sizeof(UINT32) * (len)); + + if (Ret == NDIS_STATUS_FAILURE) + goto MPS_PKT_LEN_RET; + + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + for (i = 0; i < len; i++) { + offset = 4 + 4 * i; + + if (offset + 4 > sizeof(HqaCmdFrame->Data)) /* Reserved at least 4 byte availbale data */ + break; + + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + offset, 4); + mps_setting[i] = PKTL_TRAN_TO_HOST(Value); + } + + ATEOp->MPSSetParm(pAd, MPS_PAYLOAD_LEN, len, mps_setting); + os_free_mem(mps_setting); +MPS_PKT_LEN_RET: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u, MPS_CNT:%u\n", __func__, len, ATECtrl->mps_cb.mps_cnt)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MPSSetPacketCount(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + UINT32 len = 0; + INT32 Ret = 0; + UINT32 i = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 *mps_setting = NULL; + UINT32 band_idx = 0; + UINT32 offset = 0; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length) / 4 - 1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u\n", __func__, len)); + + if ((len > 1024) || (len == 0)) + goto MPS_PKT_CNT_RET; + + Ret = os_alloc_mem(pAd, (UCHAR **)&mps_setting, sizeof(UINT32) * (len)); + + if (Ret == NDIS_STATUS_FAILURE) + goto MPS_PKT_CNT_RET; + + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + for (i = 0; i < len; i++) { + offset = 4 + 4 * i; + + if (offset + 4 > sizeof(HqaCmdFrame->Data)) /* Reserved at least 4 byte availbale data */ + break; + + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + offset, 4); + mps_setting[i] = PKTL_TRAN_TO_HOST(Value); + } + + ATEOp->MPSSetParm(pAd, MPS_TX_COUNT, len, mps_setting); + os_free_mem(mps_setting); +MPS_PKT_CNT_RET: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u, MPS_CNT:%u\n", __func__, len, ATECtrl->mps_cb.mps_cnt)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_MPSSetPowerGain(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + UINT32 len = 0; + INT32 Ret = 0; + UINT32 i = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 *mps_setting = NULL; + UINT32 band_idx = 0; + UINT32 offset = 0; + + len = PKTS_TRAN_TO_NET(HqaCmdFrame->Length) / 4 - 1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u\n", __func__, len)); + + if ((len > 1024) || (len == 0)) + goto MPS_SET_PWR_RET; + + Ret = os_alloc_mem(pAd, (UCHAR **)&mps_setting, sizeof(UINT32) * (len)); + + if (Ret == NDIS_STATUS_FAILURE) + goto MPS_SET_PWR_RET; + + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + for (i = 0; i < len; i++) { + offset = 4 + 4 * i; + + if (offset + 4 > sizeof(HqaCmdFrame->Data)) /* Reserved at least 4 byte availbale data */ + break; + + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + offset, 4); + mps_setting[i] = PKTL_TRAN_TO_HOST(Value); + } + + ATEOp->MPSSetParm(pAd, MPS_PWR_GAIN, len, mps_setting); + os_free_mem(mps_setting); +MPS_SET_PWR_RET: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u, MPS_CNT:%u\n", __func__, len, ATECtrl->mps_cb.mps_cnt)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MPSStart(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + INT32 Ret = 0; + UINT32 band_idx = 0; + + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + Ret = ATEOp->MPSTxStart(pAd); + + if (WRQ) + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + + return Ret; +} + +static INT32 HQA_MPSStop(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 band_idx = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + Ret = ATEOp->MPSTxStop(pAd); + + if (WRQ) + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + + return Ret; +} + +static INT32 HQA_MPSSetNss(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + UINT32 len = 0; + INT32 Ret = 0; + UINT32 i = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 *mps_setting = NULL; + UINT32 band_idx = 0; + UINT32 offset = 0; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length) / sizeof(UINT32) - 1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u\n", __func__, len)); + + if ((len > 512) || (len == 0)) + goto out; + + Ret = os_alloc_mem(pAd, (UCHAR **)&mps_setting, sizeof(UINT32) * (len)); + + if (Ret == NDIS_STATUS_FAILURE) + goto out; + + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = OS_NTOHL(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + for (i = 0; i < len; i++) { + offset = 4 + 4 * i; + + if (offset + 4 > sizeof(HqaCmdFrame->Data)) /* Reserved at least 4 byte availbale data */ + break; + + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + offset, 4); + mps_setting[i] = PKTL_TRAN_TO_HOST(Value); + } + + ATEOp->MPSSetParm(pAd, MPS_NSS, len, mps_setting); + os_free_mem(mps_setting); +out: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u, MPS_CNT:%u\n", __func__, len, ATECtrl->mps_cb.mps_cnt)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MPSSetPerpacketBW(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Value = 0; + UINT32 len = 0; + INT32 Ret = 0; + UINT32 i = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UINT32 *mps_setting = NULL; + UINT32 band_idx = 0; + UINT32 per_pkt_bw = 0; + UINT32 offset = 0; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length) / sizeof(UINT32) - 1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u\n", __func__, len)); + + if ((len > 512) || (len == 0)) + goto out; + + Ret = os_alloc_mem(pAd, (UCHAR **)&mps_setting, sizeof(UINT32) * (len)); + + if (Ret == NDIS_STATUS_FAILURE) + goto out; + + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + band_idx = OS_NTOHL(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + for (i = 0; i < len; i++) { + offset = 4 + 4 * i; + + if (offset + 4 > sizeof(HqaCmdFrame->Data)) /* Reserved at least 4 byte availbale data */ + break; + + NdisMoveMemory((PUCHAR)&Value, (PUCHAR)&HqaCmdFrame->Data + offset, 4); + per_pkt_bw = PKTL_TRAN_TO_HOST(Value); + + switch (per_pkt_bw) { + case ATE_BAND_WIDTH_20: + per_pkt_bw = BAND_WIDTH_20; + break; + + case ATE_BAND_WIDTH_40: + per_pkt_bw = BAND_WIDTH_40; + break; + + case ATE_BAND_WIDTH_80: + per_pkt_bw = BAND_WIDTH_80; + break; + + case ATE_BAND_WIDTH_10: + per_pkt_bw = BAND_WIDTH_10; + break; + + case ATE_BAND_WIDTH_5: + per_pkt_bw = BAND_WIDTH_5; + break; + + case ATE_BAND_WIDTH_160: + case ATE_BAND_WIDTH_8080: + per_pkt_bw = BAND_WIDTH_160; + break; + + default: + per_pkt_bw = BAND_WIDTH_20; + break; + } + + mps_setting[i] = per_pkt_bw; + } + + ATEOp->MPSSetParm(pAd, MPS_PKT_BW, len, mps_setting); + os_free_mem(mps_setting); +out: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: len:%u, MPS_CNT:%u\n", __func__, len, ATECtrl->mps_cb.mps_cnt)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_CheckEfuseModeType(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 val = 0; + INT32 Ret = 0; + +#if !defined(COMPOS_TESTMODE_WIN) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: %x\n", __func__, pAd->E2pCtrl.e2pCurMode)); + val = PKTL_TRAN_TO_NET(pAd->E2pCtrl.e2pCurMode); /* Fix me::pAd unify */ +#endif + NdisMoveMemory(HqaCmdFrame->Data + 2, &(val), sizeof(val)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(val), Ret); + return Ret; +} + + +static INT32 HQA_CheckEfuseNativeModeType(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 val = 0; + INT32 Ret = 0; + +#if !defined(COMPOS_TESTMODE_WIN) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: %x\n", __func__, pAd->E2pAccessMode)); + val = PKTL_TRAN_TO_NET(pAd->E2pAccessMode); /* Fix me::pAd unify */ +#endif + NdisMoveMemory(HqaCmdFrame->Data + 2, &(val), sizeof(val)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(val), Ret); + return Ret; +} + + +static INT32 HQA_SetBandMode(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UCHAR *data = HqaCmdFrame->Data; + UINT32 band_mode = 0; + UINT32 band_type = 0; + + NdisMoveMemory((UCHAR *)&band_mode, data, sizeof(band_mode)); + data += sizeof(band_mode); + band_mode = PKTL_TRAN_TO_HOST(band_mode); + NdisMoveMemory((UCHAR *)&band_type, data, sizeof(band_type)); + data += sizeof(band_type); + band_type = PKTL_TRAN_TO_HOST(band_type); +#ifndef COMPOS_TESTMODE_WIN + + /* todo: windows do not have Set_WirelessMode_Proc function */ + if (band_mode == ATE_SINGLE_BAND) { + if (band_type == ATE_ABAND_TYPE) + Set_WirelessMode_Proc(pAd, "14"); + else if (band_type == ATE_GBAND_TYPE) + Set_WirelessMode_Proc(pAd, "9"); + else + Ret = -1; + } + +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: band_mode:%x, band_type:%x\n", + __func__, band_mode, band_type)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_GetBandMode(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 band_mode = 0; + UCHAR *data = HqaCmdFrame->Data; + UINT32 band_idx = 0; + UINT32 is_dbdc = IS_ATE_DBDC(pAd); + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&band_idx); + + /* + DLL will query two times per band0/band1 if DBDC chip set. + 0: no this band + 1: 2.4G + 2: 5G + 3. 2.4G+5G + */ + if (is_dbdc) { + band_mode = (band_idx == TESTMODE_BAND0) ? 1 : 2; + } else { + band_mode = 3; /* Always report 2.4+5G*/ + + /* If is_dbdc=0, band_idx should not be 1 so return band_mode=0 */ + if (band_idx == TESTMODE_BAND1) + band_mode = 0; + } + + band_mode = PKTL_TRAN_TO_HOST(band_mode); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: is_dbdc:%x, band_mode:%x, band_idx:%x\n", + __func__, is_dbdc, band_mode, band_idx)); + NdisMoveMemory(HqaCmdFrame->Data + 2, &(band_mode), sizeof(band_mode)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(band_mode), Ret); + return Ret; +} + + +static INT32 HQA_RDDStartExt(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 rdd_num = 0; + UINT32 rdd_in_sel = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + NdisMoveMemory((PUCHAR)&rdd_num, data, sizeof(rdd_num)); + rdd_num = PKTL_TRAN_TO_HOST(rdd_num); + data += sizeof(rdd_num); + NdisMoveMemory((PUCHAR)&rdd_in_sel, data, sizeof(rdd_in_sel)); + rdd_in_sel = PKTL_TRAN_TO_HOST(rdd_in_sel); + Ret = ate_ops->onOffRDD(pAd, rdd_num, rdd_in_sel, 1); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: %x\n", __func__, rdd_num)); + return Ret; +} + + +static INT32 HQA_RDDStopExt(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 rdd_num = 0; + UINT32 rdd_in_sel = 0; + INT32 Ret = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + NdisMoveMemory((PUCHAR)&rdd_num, data, sizeof(rdd_num)); + rdd_num = PKTL_TRAN_TO_HOST(rdd_num); + data += sizeof(rdd_num); + NdisMoveMemory((PUCHAR)&rdd_in_sel, data, sizeof(rdd_in_sel)); + rdd_in_sel = PKTL_TRAN_TO_HOST(rdd_in_sel); + Ret = ate_ops->onOffRDD(pAd, rdd_num, rdd_in_sel, 0); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: %x\n", __func__, rdd_num)); + return Ret; +} + + +static INT32 HQA_BssInfoUpdate(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 OwnMacIdx = 0, BssIdx = 0; + UCHAR Bssid[MAC_ADDR_LEN]; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + EthGetParamAndShiftBuff(TRUE, sizeof(OwnMacIdx), &data, (UCHAR *)&OwnMacIdx); + EthGetParamAndShiftBuff(TRUE, sizeof(BssIdx), &data, (UCHAR *)&BssIdx); + EthGetParamAndShiftBuff(FALSE, sizeof(Bssid), &data, Bssid); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: BssIdx:%d Bssid:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, BssIdx, PRINT_MAC(Bssid))); + Ret = ATEOp->BssInfoUpdate(pAd, OwnMacIdx, BssIdx, Bssid); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_DevInfoUpdate(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Band = 0, OwnMacIdx = 0; + UCHAR Bssid[MAC_ADDR_LEN]; + INT32 Ret = 0; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + EthGetParamAndShiftBuff(TRUE, sizeof(Band), &data, (UCHAR *)&Band); + EthGetParamAndShiftBuff(TRUE, sizeof(OwnMacIdx), &data, (UCHAR *)&OwnMacIdx); + EthGetParamAndShiftBuff(FALSE, sizeof(Bssid), &data, Bssid); + ATECtrl->control_band_idx = (UCHAR)Band; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Band:%d OwnMacIdx:%d Bssid:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, Band, OwnMacIdx, PRINT_MAC(Bssid))); + Ret = ATEOp->DevInfoUpdate(pAd, OwnMacIdx, Bssid); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_LogOnOff(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 band_idx = 0; + UINT32 log_type = 0; + UINT32 log_ctrl = 0; + UINT32 log_size = 200; + UCHAR *data = HqaCmdFrame->Data; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + + NdisMoveMemory((PUCHAR)&band_idx, data, sizeof(band_idx)); + data += sizeof(band_idx); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + NdisMoveMemory((PUCHAR)&log_type, data, sizeof(log_type)); + data += sizeof(log_type); + log_type = PKTL_TRAN_TO_HOST(log_type); + NdisMoveMemory((PUCHAR)&log_ctrl, data, sizeof(log_ctrl)); + data += sizeof(log_ctrl); + log_ctrl = PKTL_TRAN_TO_HOST(log_ctrl); + NdisMoveMemory((PUCHAR)&log_size, data, sizeof(log_size)); + data += sizeof(log_size); + log_size = PKTL_TRAN_TO_HOST(log_size); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + Ret = ATEOp->LogOnOff(pAd, log_type, log_ctrl, log_size); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: band_idx:%x, log_type:%x, log_ctrl:%x, en_log:%x, log_size:%u\n", + __func__, band_idx, log_type, log_ctrl, ATECtrl->en_log, log_size)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetPowerToBufferBin(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + INT32 Ret = 0; + UINT32 band_idx = 0; + UINT32 power = 0; + UINT32 channel = 0; + UINT32 antenna_idx = 0; + UINT32 efuse_offset = 0; + UCHAR *data = HqaCmdFrame->Data; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + NdisMoveMemory((PUCHAR)&power, data, sizeof(power)); + data += sizeof(power); + power = PKTL_TRAN_TO_HOST(power); + NdisMoveMemory((PUCHAR)&channel, data, sizeof(channel)); + data += sizeof(channel); + channel = PKTL_TRAN_TO_HOST(channel); + NdisMoveMemory((PUCHAR)&band_idx, data, sizeof(band_idx)); + data += sizeof(band_idx); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ATECtrl->control_band_idx = (UCHAR)band_idx; + + /* for MT7615 */ + efuse_offset = MtATEGetTxPwrGroup(channel, band_idx, antenna_idx); + + if (efuse_offset >= cap->EFUSE_BUFFER_CONTENT_SIZE) + Ret = -1; + else { + pAd->EEPROMImage[efuse_offset] = power; + Ret = 0; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: power:%x, channel:%x, band_idx:%x, offset:%x, antenna_idx:%x\n", + __func__, power, channel, band_idx, efuse_offset, antenna_idx)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_SetFrequencyOffsetToBufferBin(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Not support\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_HIFTestSetStartLoopback(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 len = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _HQA_HIFTestParam tmp, *param; + struct _LOOPBACK_SETTING set; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + NdisMoveMemory((UCHAR *)&tmp, HqaCmdFrame->Data, sizeof(tmp)); + param = PKTLA_TRAN_TO_HOST(len / 4, &tmp); + set.StartLen = param->start_len; + set.StopLen = param->stop_len; + set.RepeatTimes = param->repeat_time; + set.IsDefaultPattern = param->is_def_pattern; + set.BulkOutNumber = param->bulkout_num; + set.BulkInNumber = param->bulkin_num; + set.TxAggNumber = param->txagg_num; + set.RxAggPktLmt = param->rxagg_limit; + set.RxAggLmt = param->rxagg_lm; + set.RxAggTO = param->rxagg_to; + set.RxAggEnable = param->enable_rxagg; + ate_ctrl->verify_mode = ATE_LOOPBACK; + + if (!pAd->LbCtrl.LoopBackRunning) + LoopBack_Start(pAd, &set); + else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s: LB is running\n", __func__)); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: start_len:%u, stop_len:%u, repeat:%u, is_default:%u, bulkout_num:%u, bulkin_num:%u, txagg_num:%u, rxagg_limit:%u, rxagg_lm:%u, rxagg_to:%u, enable_rxagg:%u\n", + __func__, param->start_len, param->stop_len, param->repeat_time, param->is_def_pattern, + param->bulkout_num, param->bulkin_num, param->txagg_num, param->rxagg_limit, param->rxagg_lm, param->rxagg_to, param->enable_rxagg)); + return Ret; +} + + +static INT32 HQA_HIFTestSetStopLoopback(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s\n", __func__)); + + if (pAd->LbCtrl.LoopBackRunning) + LoopBack_Stop(pAd); + + pAd->LbCtrl.DebugMode = FALSE; + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_HIFTestGetStatus(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _LOOPBACK_RESULT tmp, *resp; + + LoopBack_Status(pAd, &tmp); + resp = PKTLA_TRAN_TO_NET(sizeof(tmp) / 4, &tmp); + NdisMoveMemory(HqaCmdFrame->Data + 2, (UCHAR *)resp, sizeof(tmp)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(tmp), Ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s\n", __func__)); + return Ret; +} + + +static INT32 HQA_HIFTestSetTxData(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 len = 0; + UINT32 tx_len = 0; + UCHAR *raw = NULL; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + NdisMoveMemory(&tx_len, HqaCmdFrame->Data, sizeof(tx_len)); + tx_len = PKTL_TRAN_TO_HOST(tx_len); + raw = HqaCmdFrame->Data + sizeof(UINT32); + + if (pAd->LbCtrl.DebugMode) { + UINT32 j = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: TxExpect Dump(%u): ", __func__, tx_len)); + + for (j = 0; j < tx_len; j++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x", raw[j])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + + LoopBack_ExpectTx(pAd, tx_len, raw); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%u, tx_len:%u\n", __func__, len, tx_len)); + return Ret; +} + + +static INT32 HQA_HIFTestSetRxData(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + UINT32 rx_len = 0; + UCHAR *raw = NULL; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + NdisMoveMemory(&rx_len, HqaCmdFrame->Data, sizeof(rx_len)); + rx_len = PKTL_TRAN_TO_HOST(rx_len); + raw = HqaCmdFrame->Data + sizeof(UINT32); + + if (pAd->LbCtrl.DebugMode) { + UINT32 j = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: RxExpect Dump(%u): ", __func__, rx_len)); + + for (j = 0; j < rx_len; j++) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x", raw[j])); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + + LoopBack_ExpectRx(pAd, rx_len, raw); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%u, rx_len:%u\n", __func__, len, rx_len)); + return Ret; +} + + +static INT32 HQA_HIFTestGetTxRxData(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UCHAR *out = HqaCmdFrame->Data + 2; + /* TODO:: Need check ated allocate size */ + UINT32 tlen = 0; + UINT32 out_len = 0; + UINT32 tmp = 0; + + /* Tx Data */ + LoopBack_RawData(pAd, &out_len, TRUE, out + sizeof(UINT32)); + tmp = PKTL_TRAN_TO_NET(out_len); + NdisMoveMemory(out, &tmp, sizeof(UINT32)); + tlen += out_len; + out += out_len + sizeof(UINT32); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: tx_out_len:%u\n", __func__, out_len)); + /* Rx Data */ + LoopBack_RawData(pAd, &out_len, FALSE, out + sizeof(UINT32)); + tmp = PKTL_TRAN_TO_NET(out_len); + NdisMoveMemory(out, &tmp, sizeof(UINT32)); + tlen += out_len; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: rx_out_len:%u, total_len:%u\n", __func__, out_len, tlen)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + tlen + sizeof(UINT32) * 2, Ret); + return Ret; +} + + +static INT32 HQA_UDMAAction(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 val = 0; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + NdisMoveMemory(HqaCmdFrame->Data + 2, &(val), sizeof(val)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_WIFIPowerOff(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 val = 0; + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + NdisMoveMemory(HqaCmdFrame->Data + 2, &(val), sizeof(val)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 ToDoFunction(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET5[] = { + /* cmd id start from 0x1500 */ + hqa_get_fw_info, /* 0x1500 */ + HQA_StartContinousTx, /* 0x1501 */ + HQA_SetSTBC, /* 0x1502 */ + HQA_SetShortGI, /* 0x1503 */ + HQA_SetDPD, /* 0x1504 */ + HQA_SetTssiOnOff, /* 0x1505 */ + HQA_GetRxStatisticsAll, /* 0x1506 */ + HQA_StartContiTxTone, /* 0x1507 */ + HQA_StopContiTxTone, /* 0x1508 */ + HQA_CalibrationTestMode, /* 0x1509 */ + HQA_DoCalibrationTestItem, /* 0x150A */ + HQA_eFusePhysicalWrite, /* 0x150B */ + HQA_eFusePhysicalRead, /* 0x150C */ + HQA_eFuseLogicalRead, /* 0x150D */ + HQA_eFuseLogicalWrite, /* 0x150E */ + HQA_TMRSetting, /* 0x150F */ + HQA_GetRxSNR, /* 0x1510 */ + HQA_WriteBufferDone, /* 0x1511 */ + HQA_FFT, /* 0x1512 */ + HQA_SetTxTonePower, /* 0x1513 */ + HQA_GetChipID, /* 0x1514 */ + HQA_MPSSetSeqData, /* 0x1515 */ + HQA_MPSSetPayloadLength, /* 0x1516 */ + HQA_MPSSetPacketCount, /* 0x1517 */ + HQA_MPSSetPowerGain, /* 0x1518 */ + HQA_MPSStart, /* 0x1519 */ + HQA_MPSStop, /* 0x151A */ + ToDoFunction, /* 0x151B */ + ToDoFunction, /* 0x151C */ + ToDoFunction, /* 0x151D */ + ToDoFunction, /* 0x151E */ + ToDoFunction, /* 0x151F */ + ToDoFunction, /* 0x1520 */ + HQA_SetAIFS, /* 0x1521 */ + HQA_CheckEfuseModeType, /* 0x1522 */ + HQA_CheckEfuseNativeModeType, /* 0x1523 */ + HQA_HIFTestSetStartLoopback, /* 0x1524 */ + HQA_HIFTestSetStopLoopback, /* 0x1525 */ + HQA_HIFTestGetStatus, /* 0x1526 */ + HQA_HIFTestSetTxData, /* 0x1527 */ + HQA_HIFTestSetRxData, /* 0x1528 */ + HQA_HIFTestGetTxRxData, /* 0x1529 */ + HQA_UDMAAction, /* 0x152A */ + HQA_WIFIPowerOff, /* 0x152B */ + HQA_SetBandMode, /* 0x152C */ + HQA_GetBandMode, /* 0x152D */ + HQA_RDDStartExt, /* 0x152E */ + HQA_RDDStopExt, /* 0x152F */ + ToDoFunction, /* 0x1530 */ + HQA_BssInfoUpdate, /* 0x1531 */ + HQA_DevInfoUpdate, /* 0x1532 */ + HQA_LogOnOff, /* 0x1533 */ + HQA_SetPowerToBufferBin, /* 0x1534 */ + HQA_SetFrequencyOffsetToBufferBin, /* 0x1535 */ + HQA_MPSSetNss, /* 0x1536 */ + HQA_MPSSetPerpacketBW, /* 0x1537 */ +}; + + +#ifdef TXBF_SUPPORT +#if defined(MT7615) || defined(MT7637) || defined(MT7622) +VOID HQA_BF_INFO_CB(RTMP_ADAPTER *pAd, unsigned char *data, UINT32 len) +{ + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _EXT_EVENT_BF_STATUS_T *bf_info = (struct _EXT_EVENT_BF_STATUS_T *)data; + struct _EXT_EVENT_IBF_STATUS_T *ibf_info = (struct _EXT_EVENT_IBF_STATUS_T *)data; + UINT32 status = 0; + UINT32 data_len = 0; + UCHAR *bf_data = bf_info->aucBuffer; + + if (!(ate_ctrl->Mode & fATE_IN_BF)) + return; + + ate_ctrl->txbf_info_len = 0; + os_alloc_mem(pAd, (UCHAR **)&ate_ctrl->txbf_info, sizeof(UCHAR)*len); + + if (!ate_ctrl->txbf_info) { + status = NDIS_STATUS_RESOURCES; + goto err0; + } + + os_zero_mem(ate_ctrl->txbf_info, sizeof(UCHAR)*len); + ate_ctrl->txbf_info_len = len; + + switch (bf_info->ucBfDataFormatID) { + case BF_PFMU_TAG: + if (bf_info->fgBFer) + data_len = sizeof(PFMU_PROFILE_TAG1) + sizeof(PFMU_PROFILE_TAG2); + else + data_len = sizeof(PFMU_PROFILE_TAG1); + + NdisMoveMemory(ate_ctrl->txbf_info, bf_data, data_len); + ate_ctrl->txbf_info_len = data_len; + break; + + case BF_PFMU_DATA: + NdisMoveMemory(ate_ctrl->txbf_info, bf_data, sizeof(PFMU_DATA)); + data_len = sizeof(PFMU_DATA); + ate_ctrl->txbf_info_len = data_len; + break; + + case BF_CAL_PHASE: + ate_ctrl->iBFCalStatus = ibf_info->ucStatus; + break; + + case BF_QD_DATA: + NdisMoveMemory(ate_ctrl->txbf_info, bf_data, sizeof(BF_QD)); + data_len = sizeof(BF_QD); + ate_ctrl->txbf_info_len = data_len; + break; + + default: + break; + } + +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s(%x)\n", __func__, status)); + RTMP_OS_COMPLETE(&ate_ctrl->cmd_done); +} +#else +VOID HQA_BF_INFO_CB(RTMP_ADAPTER *pAd, unsigned char *data, UINT32 len) +{ + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s not supported yet\n", __func__)); +} +#endif /* MT7615 */ + + +static INT32 HQA_TxBfProfileTagInValid(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 invalid = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto BF_PROFILE_TAG_INVALID_FAIL; + } + + NdisMoveMemory((PUCHAR)&invalid, (PUCHAR)&HqaCmdFrame->Data, sizeof(invalid)); + invalid = PKTL_TRAN_TO_HOST(invalid); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%u", invalid); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_InValid(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%u, str:%s\n", __func__, invalid, cmd)); + os_free_mem(cmd); +BF_PROFILE_TAG_INVALID_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagPfmuIdx(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 pfmuidx = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto BF_PROFILE_TAG_PFMU_FAIL; + } + + NdisMoveMemory((PUCHAR)&pfmuidx, (PUCHAR)&HqaCmdFrame->Data, sizeof(pfmuidx)); + pfmuidx = PKTL_TRAN_TO_HOST(pfmuidx); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%u", pfmuidx); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_PfmuIdx(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%u, str:%s\n", __func__, pfmuidx, cmd)); + os_free_mem(cmd); +BF_PROFILE_TAG_PFMU_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagBfType(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 bftype = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto BF_PROFILE_TAG_BFTYPE_FAIL; + } + + NdisMoveMemory((PUCHAR)&bftype, (PUCHAR)&HqaCmdFrame->Data, 4); + bftype = PKTL_TRAN_TO_HOST(bftype); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%u", bftype); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_BfType(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%u, str:%s\n", __func__, bftype, cmd)); + os_free_mem(cmd); +BF_PROFILE_TAG_BFTYPE_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagBw(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 tag_bw = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto BF_PROFILE_TAG_BW_FAIL; + } + + NdisMoveMemory((PUCHAR)&tag_bw, (PUCHAR)&HqaCmdFrame->Data, 4); + tag_bw = PKTL_TRAN_TO_HOST(tag_bw); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%u", tag_bw); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_DBW(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%u, str:%s\n", __func__, tag_bw, cmd)); + os_free_mem(cmd); +BF_PROFILE_TAG_BW_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagSuMu(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 su_mu = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto BF_PROFILE_TAG_SUMU_FAIL; + } + + NdisMoveMemory((PUCHAR)&su_mu, (PUCHAR)&HqaCmdFrame->Data, 4); + su_mu = PKTL_TRAN_TO_HOST(su_mu); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%u", su_mu); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_SuMu(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%u, str:%s\n", __func__, su_mu, cmd)); + os_free_mem(cmd); +BF_PROFILE_TAG_SUMU_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagMemAlloc(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + struct _HQA_BF_TAG_ALLOC tmp, *layout = NULL; + RTMP_STRING *cmd = NULL; + + if (!HqaCmdFrame) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: HqaCmdFrame is NULL\n", __func__)); + Ret = NDIS_STATUS_INVALID_DATA; + return Ret; + } + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_MEMALLOC_FAIL; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + + if (len > sizeof(tmp)) { + Ret = NDIS_STATUS_INVALID_DATA; + goto HQA_TAG_MEMALLOC_FAIL; + } + + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + layout = PKTLA_TRAN_TO_HOST(len / 4, &tmp); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + layout->col_idx0, layout->row_idx0, layout->col_idx1, layout->row_idx1, + layout->col_idx2, layout->row_idx2, layout->col_idx3, layout->row_idx3); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_Mem(pAd, cmd); +#endif +HQA_TAG_MEMALLOC_FAIL: + + if (cmd) + os_free_mem(cmd); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + if (layout) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: col0/row0:%x/%x, col1/row1:%x/%x, col2/row2:%x/%x, col3/row3:%x/%x\n", + __func__, layout->col_idx0, layout->row_idx0, layout->col_idx1, layout->row_idx1, layout->col_idx2, layout->row_idx2, layout->col_idx3, layout->row_idx3)); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagMatrix(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + struct _HQA_BF_TAG_MATRIX tmp, *matrix = NULL; + RTMP_STRING *cmd; + + if (!HqaCmdFrame) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: HqaCmdFrame is NULL\n", __func__)); + Ret = NDIS_STATUS_INVALID_DATA; + return Ret; + } + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_MATRIX_FAIL; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + matrix = PKTLA_TRAN_TO_HOST(len / 4, &tmp); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x:%02x", matrix->nrow, matrix->ncol, matrix->ngroup, matrix->LM, matrix->code_book, matrix->htc_exist); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_Matrix(pAd, cmd); +#endif + os_free_mem(cmd); +HQA_TAG_MATRIX_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + if (matrix) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: nrow:%x, ncol:%x, ngroup:%x, LM:%x, code_book:%x, htc:%x\n", + __func__, matrix->nrow, matrix->ncol, matrix->ngroup, matrix->LM, matrix->code_book, matrix->htc_exist)); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagSnr(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + struct _HQA_BF_TAG_SNR tmp, *snr = NULL; + RTMP_STRING *cmd; + + if (!HqaCmdFrame) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: HqaCmdFrame is NULL\n", __func__)); + Ret = NDIS_STATUS_INVALID_DATA; + return Ret; + } + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_SNR_FAIL; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + snr = PKTLA_TRAN_TO_HOST(len / 4, &tmp); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x:%02x:%02x", snr->snr_sts0, snr->snr_sts1, snr->snr_sts2, snr->snr_sts3); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_SNR(pAd, cmd); +#endif + os_free_mem(cmd); +HQA_TAG_SNR_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + if (snr) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: snr_sts0:%x, snr_sts1:%x, snr_sts2:%x, snr_sts3:%x,\n", + __func__, snr->snr_sts0, snr->snr_sts1, snr->snr_sts2, snr->snr_sts3)); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagSmtAnt(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 smt_ant = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_SMTANT_FAIL; + } + + NdisMoveMemory((PUCHAR)&smt_ant, (PUCHAR)&HqaCmdFrame->Data, 4); + /* + * DBDC mode: + * If Use Band 0, set [11:6]=0x0, set [5:0] as Ant cfg. + * If Use Band 1, set [11:6] as Ant cfg, set [5:0] = 0x0. + * Non-DBDC mode: + * Set [11:0] as Ant cfg. + */ + smt_ant = PKTL_TRAN_TO_HOST(smt_ant); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", smt_ant); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_SmartAnt(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, str:%s\n", __func__, smt_ant, cmd)); + os_free_mem(cmd); +HQA_TAG_SMTANT_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagSeIdx(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 se_idx = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_SEIDX_FAIL; + } + + NdisMoveMemory((PUCHAR)&se_idx, (PUCHAR)&HqaCmdFrame->Data, 4); + se_idx = PKTL_TRAN_TO_HOST(se_idx); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", se_idx); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_SeIdx(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, str:%s\n", __func__, se_idx, cmd)); + os_free_mem(cmd); +HQA_TAG_SEIDX_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagRmsdThrd(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 rmsd_thrd = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_RMSDTHRD_FAIL; + } + + NdisMoveMemory((PUCHAR)&rmsd_thrd, (PUCHAR)&HqaCmdFrame->Data, 4); + rmsd_thrd = PKTL_TRAN_TO_HOST(rmsd_thrd); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", rmsd_thrd); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_RmsdThrd(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, cmd:%s\n", __func__, rmsd_thrd, cmd)); + os_free_mem(cmd); +HQA_TAG_RMSDTHRD_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagMcsThrd(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + struct _HQA_BF_TAG_MCS_THRD tmp, *mcs_thrd = NULL; + RTMP_STRING *cmd; + + if (!HqaCmdFrame) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: HqaCmdFrame is NULL\n", __func__)); + Ret = NDIS_STATUS_INVALID_DATA; + return Ret; + } + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_MCSTHRD_FAIL; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + mcs_thrd = PKTLA_TRAN_TO_HOST(len / 4, &tmp); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x:%02x", mcs_thrd->mcs_lss0, mcs_thrd->mcs_sss0, mcs_thrd->mcs_lss1, mcs_thrd->mcs_sss1, mcs_thrd->mcs_lss2, mcs_thrd->mcs_sss2); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_McsThrd(pAd, cmd); +#endif + os_free_mem(cmd); +HQA_TAG_MCSTHRD_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + if (mcs_thrd) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%x, mcs_lss0:%x, mcs_sss0:%x, mcs_lss1:%x, mcs_sss1:%x, mcs_lss2:%x, mcs_sss2:%x\n", + __func__, len, mcs_thrd->mcs_lss0, mcs_thrd->mcs_sss0, mcs_thrd->mcs_lss1, mcs_thrd->mcs_sss1, mcs_thrd->mcs_lss2, mcs_thrd->mcs_sss2)); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagTimeOut(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 bf_tout = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_TOUT_FAIL; + } + + NdisMoveMemory((PUCHAR)&bf_tout, (PUCHAR)&HqaCmdFrame->Data, 4); + bf_tout = PKTL_TRAN_TO_HOST(bf_tout); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", bf_tout); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_TimeOut(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, str:%s\n", __func__, bf_tout, cmd)); + os_free_mem(cmd); +HQA_TAG_TOUT_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagDesiredBw(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 desire_bw = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_DBW_FAIL; + } + + NdisMoveMemory((PUCHAR)&desire_bw, (PUCHAR)&HqaCmdFrame->Data, 4); + desire_bw = PKTL_TRAN_TO_HOST(desire_bw); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", desire_bw); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_DesiredBW(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, str:%s\n", __func__, desire_bw, cmd)); + os_free_mem(cmd); +HQA_TAG_DBW_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagDesiredNc(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 desire_nc = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_DNC_FAIL; + } + + NdisMoveMemory((PUCHAR)&desire_nc, (PUCHAR)&HqaCmdFrame->Data, 4); + desire_nc = PKTL_TRAN_TO_HOST(desire_nc); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", desire_nc); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_DesiredNc(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, str:%s\n", __func__, desire_nc, cmd)); + os_free_mem(cmd); +HQA_TAG_DNC_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagDesiredNr(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 desire_nr = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_DNR_FAIL; + } + + NdisMoveMemory((PUCHAR)&desire_nr, (PUCHAR)&HqaCmdFrame->Data, 4); + desire_nr = PKTL_TRAN_TO_HOST(desire_nr); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", desire_nr); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTag_DesiredNr(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, str:%s\n", __func__, desire_nr, cmd)); + os_free_mem(cmd); +HQA_TAG_DNR_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_TxBfProfileTagWrite(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 idx = 0; /* WLAN_IDX */ + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_WRITE_FAIL; + } + + NdisMoveMemory((PUCHAR)&idx, (PUCHAR)&HqaCmdFrame->Data, 4); + idx = PKTL_TRAN_TO_HOST(idx); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", idx); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileTagWrite(pAd, cmd); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x, str:%s\n", __func__, idx, cmd)); + os_free_mem(cmd); +HQA_TAG_WRITE_FAIL: + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TxBfProfileTagRead(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 idx = 0, isBFer = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + UCHAR *out = NULL; + RTMP_STRING *cmd; + + ate_ctrl->txbf_info = NULL; + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_READ_FAIL; + } + + ate_ctrl->Mode |= fATE_IN_BF; + NdisMoveMemory((PUCHAR)&idx, (PUCHAR)&HqaCmdFrame->Data, 4); + idx = PKTL_TRAN_TO_HOST(idx); + NdisMoveMemory((PUCHAR)&isBFer, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + isBFer = PKTL_TRAN_TO_HOST(isBFer); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x", idx, isBFer); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x %x, str:%s\n", __func__, idx, isBFer, cmd)); + /* #ifdef MT7615 */ +#if defined(MT7615) || defined(MT7637) || defined(MT7622) + Set_TxBfProfileTagRead(pAd, cmd); + RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&ate_ctrl->cmd_done, ate_ctrl->cmd_expire); +#endif + + if (!ate_ctrl->txbf_info) + goto HQA_TAG_READ_FAIL; + + out = PKTLA_TRAN_TO_NET(ate_ctrl->txbf_info_len / 4, ate_ctrl->txbf_info); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: val:%x %x, str:%s\n", __func__, idx, isBFer, cmd)); + NdisMoveMemory((PUCHAR)&HqaCmdFrame->Data + 2, (PUCHAR)out, ate_ctrl->txbf_info_len); + ate_ctrl->Mode &= ~fATE_IN_BF; + os_free_mem(ate_ctrl->txbf_info); +HQA_TAG_READ_FAIL: + + if (cmd) + os_free_mem(cmd); + + ResponseToQA(HqaCmdFrame, WRQ, 2 + ate_ctrl->txbf_info_len, Ret); + return Ret; +} + + +static INT32 HQA_StaRecCmmUpdate(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + struct _HQA_BF_STA_CMM_REC tmp, *rec = NULL; + RTMP_STRING *cmd; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_PFMU_INFO *pfmu_info = NULL; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto err0; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + + if (len > sizeof(tmp)) { + Ret = NDIS_STATUS_INVALID_DATA; + goto err0; + } + + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + rec = PKTLA_TRAN_TO_HOST((len - MAC_ADDR_LEN) / 4, &tmp); + + if (rec->wlan_idx > ATE_BFMU_NUM) { + Ret = NDIS_STATUS_INVALID_DATA; + goto err0; + } + + pfmu_info = &ate_ctrl->pfmu_info[rec->wlan_idx - 1]; + pfmu_info->wcid = rec->wlan_idx; + pfmu_info->bss_idx = rec->bss_idx; + NdisMoveMemory(pfmu_info->addr, rec->mac, MAC_ADDR_LEN); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", rec->wlan_idx, rec->bss_idx, rec->aid, PRINT_MAC(rec->mac)); +#if defined(MT7615) || defined(MT7622) + Set_StaRecCmmUpdate(pAd, cmd); +#endif +err0: + + if (cmd) + os_free_mem(cmd); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + if (rec) + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: wlan_idx:%x, bss_idx:%x, aid:%x, mac:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, rec->wlan_idx, rec->bss_idx, rec->aid, PRINT_MAC(rec->mac))); + + return Ret; +} + + +static INT32 HQA_StaRecBfUpdate(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + struct _HQA_BF_STA_REC tmp, *rec = NULL; + RTMP_STRING *cmd; + + if (!HqaCmdFrame) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: HqaCmdFrame is NULL\n", __func__)); + Ret = NDIS_STATUS_INVALID_DATA; + return Ret; + } + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_STAREC_BF_UPDATE_FAIL; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + + if (len > sizeof(tmp)) { + Ret = NDIS_STATUS_INVALID_DATA; + goto HQA_STAREC_BF_UPDATE_FAIL; + } + + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + rec = PKTLA_TRAN_TO_HOST((len) / 4, &tmp); + PKTLA_DUMP(DBG_LVL_OFF, sizeof(*rec) / 4, rec); /* Del after debug */ + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + rec->wlan_idx, rec->bss_idx, rec->PfmuId, rec->su_mu, rec->etxbf_cap, rec->ndpa_rate, rec->ndp_rate, rec->report_poll_rate, + rec->tx_mode, rec->nc, rec->nr, rec->cbw, rec->spe_idx, rec->tot_mem_req, rec->mem_req_20m, rec->mem_row0, rec->mem_col0, + rec->mem_row1, rec->mem_col1, rec->mem_row2, rec->mem_col2, rec->mem_row3, rec->mem_col3); +#if defined(MT7615) || defined(MT7622) + Set_StaRecBfUpdate(pAd, cmd); +#endif +HQA_STAREC_BF_UPDATE_FAIL: + + if (cmd) + os_free_mem(cmd); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + if (rec) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", __func__, + rec->wlan_idx, rec->bss_idx, rec->PfmuId, rec->su_mu, rec->etxbf_cap, rec->ndpa_rate, rec->ndp_rate, rec->report_poll_rate, + rec->tx_mode, rec->nc, rec->nr, rec->cbw, rec->tot_mem_req, rec->mem_req_20m, rec->mem_row0, rec->mem_col0, rec->mem_row1, + rec->mem_col1, rec->mem_row2, rec->mem_col2, rec->mem_row3, rec->mem_col3)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: wlan_idx:%x, bss_idx:%x\n", + __func__, rec->wlan_idx, rec->bss_idx)); + } + return Ret; +} + + +static INT32 HQA_BFProfileDataRead(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 idx = 0, fgBFer = 0, subcarrIdx = 0, subcarr_start = 0, subcarr_end = 0; + UINT32 offset = 0; + UINT32 NumOfsub = 0; + UCHAR *SubIdx = NULL; + UCHAR *out = NULL; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + RTMP_STRING *cmd; + INT debug_lvl = DebugLevel; + + ate_ctrl->txbf_info = NULL; + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto BF_PROFILE_DATA_READ_FAIL; + } + + ate_ctrl->Mode |= fATE_IN_BF; + NdisMoveMemory((PUCHAR)&idx, (PUCHAR)&HqaCmdFrame->Data, 4); + idx = PKTL_TRAN_TO_HOST(idx); + NdisMoveMemory((PUCHAR)&fgBFer, (PUCHAR)&HqaCmdFrame->Data + 4, 4); + fgBFer = PKTL_TRAN_TO_HOST(fgBFer); + NdisMoveMemory((PUCHAR)&subcarr_start, (PUCHAR)&HqaCmdFrame->Data + 4 + 4, 4); + subcarr_start = PKTL_TRAN_TO_HOST(subcarr_start); + NdisMoveMemory((PUCHAR)&subcarr_end, (PUCHAR)&HqaCmdFrame->Data + 4 + 4 + 4, 4); + subcarr_end = PKTL_TRAN_TO_HOST(subcarr_end); + NumOfsub = subcarr_end - subcarr_start + 1; + NumOfsub = PKTL_TRAN_TO_HOST(NumOfsub); + NdisMoveMemory((PUCHAR)&HqaCmdFrame->Data + 2, (PUCHAR)&NumOfsub, sizeof(NumOfsub)); + offset += sizeof(NumOfsub); + DebugLevel = DBG_LVL_OFF; + + for (subcarrIdx = subcarr_start; subcarrIdx <= subcarr_end; subcarrIdx++) { + ate_ctrl->txbf_info = NULL; + SubIdx = (UCHAR *)&subcarrIdx; + memset(cmd, 0x00, HQA_BF_STR_SIZE); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: idx:%02x fgBFer:%02x Sub_H:%02x Sub_L:%02x subidx:%d\n", + __func__, idx, fgBFer, SubIdx[1], SubIdx[0], subcarrIdx)); + sprintf(cmd, "%02x:%02x:%02x:%02x", idx, fgBFer, SubIdx[1], SubIdx[0]); + /* #ifdef MT7615 */ +#if defined(MT7615) || defined(MT7637) || defined(MT7622) + Set_TxBfProfileDataRead(pAd, cmd); + RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&ate_ctrl->cmd_done, ate_ctrl->cmd_expire); +#endif + + if (!ate_ctrl->txbf_info) + goto BF_PROFILE_DATA_READ_FAIL; + + out = PKTLA_TRAN_TO_NET(ate_ctrl->txbf_info_len / 4, ate_ctrl->txbf_info); + NdisMoveMemory((PUCHAR)&HqaCmdFrame->Data + 2 + offset, (PUCHAR)out, ate_ctrl->txbf_info_len); + offset += ate_ctrl->txbf_info_len; + os_free_mem(ate_ctrl->txbf_info); + } + + ate_ctrl->Mode &= ~fATE_IN_BF; +BF_PROFILE_DATA_READ_FAIL: + + if (cmd) + os_free_mem(cmd); + + ResponseToQA(HqaCmdFrame, WRQ, 2 + offset, Ret); + DebugLevel = debug_lvl; + return Ret; +} + +static INT32 HQA_BFProfileDataWrite(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + INT debug_lvl = DebugLevel; + struct _HQA_BF_STA_PROFILE tmp, *profile; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto BF_PROFILE_DATA_WRITE_FAIL; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + if (len > sizeof(struct _HQA_BF_STA_PROFILE)) { + len = sizeof(struct _HQA_BF_STA_PROFILE); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: command length is wrong\n", __func__)); + } + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + profile = PKTLA_TRAN_TO_HOST((len) / sizeof(UINT32), &tmp); + DebugLevel = DBG_LVL_OFF; + PKTLA_DUMP(DBG_LVL_INFO, sizeof(tmp) / sizeof(UINT32), &tmp); /* Del after debug */ + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:", profile->pfmuid); + sprintf(cmd + strlen(cmd), "%03x:", profile->subcarrier); + sprintf(cmd + strlen(cmd), "%03x:", profile->phi11); + sprintf(cmd + strlen(cmd), "%02x:", profile->psi21); + sprintf(cmd + strlen(cmd), "%03x:", profile->phi21); + sprintf(cmd + strlen(cmd), "%02x:", profile->psi31); + sprintf(cmd + strlen(cmd), "%03x:", profile->phi31); + sprintf(cmd + strlen(cmd), "%02x:", profile->psi41); + sprintf(cmd + strlen(cmd), "%03x:", profile->phi22); + sprintf(cmd + strlen(cmd), "%02x:", profile->psi32); + sprintf(cmd + strlen(cmd), "%03x:", profile->phi32); + sprintf(cmd + strlen(cmd), "%02x:", profile->psi42); + sprintf(cmd + strlen(cmd), "%03x:", profile->phi33); + sprintf(cmd + strlen(cmd), "%02x:", profile->psi43); + sprintf(cmd + strlen(cmd), "%02x:", profile->snr00); + sprintf(cmd + strlen(cmd), "%02x:", profile->snr01); + sprintf(cmd + strlen(cmd), "%02x:", profile->snr02); + sprintf(cmd + strlen(cmd), "%02x", profile->snr03); +#if defined(MT7615) || defined(MT7622) + Set_TxBfProfileDataWrite(pAd, cmd); +#endif + os_free_mem(cmd); +BF_PROFILE_DATA_WRITE_FAIL: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + DebugLevel = debug_lvl; + return Ret; +} + +static INT32 HQA_BFQdRead(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + UCHAR *out = NULL; + RTMP_STRING *cmd; + INT32 subcarrier_idx = 0; + + ate_ctrl->txbf_info = NULL; + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR)*(HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_BF_QD_READ_FAIL; + } + + ate_ctrl->Mode |= fATE_IN_BF; + + NdisMoveMemory((PUCHAR)&subcarrier_idx, HqaCmdFrame->Data, sizeof(subcarrier_idx)); + subcarrier_idx = PKTL_TRAN_TO_HOST(subcarrier_idx); + + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", subcarrier_idx); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s, val:%u, str:%s\n", __func__, subcarrier_idx, cmd)); +#if defined(MT7615) || defined(MT7622) + Set_TxBfQdRead(pAd, cmd); + RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&ate_ctrl->cmd_done, ate_ctrl->cmd_expire); +#endif + if (!ate_ctrl->txbf_info) + goto HQA_BF_QD_READ_FAIL; + + out = (PUCHAR)ate_ctrl->txbf_info; + + PKTLA_DUMP(DBG_LVL_INFO, 14, out); + NdisMoveMemory((PUCHAR)&HqaCmdFrame->Data + 2, (PUCHAR)out, ate_ctrl->txbf_info_len); + ate_ctrl->Mode &= ~fATE_IN_BF; + os_free_mem(ate_ctrl->txbf_info); +HQA_BF_QD_READ_FAIL: + if (cmd) + os_free_mem(cmd); + + ResponseToQA(HqaCmdFrame, WRQ, 2 + ate_ctrl->txbf_info_len, Ret); + return Ret; +} + +static INT32 HQA_BFSounding(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + struct _HQA_BF_SOUNDING tmp, *param; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto HQA_BFSOUNDING_FAIL; + } + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + + if (len > sizeof(tmp)) { + Ret = NDIS_STATUS_INVALID_DATA; + goto HQA_BFSOUNDING_FAIL; + } + + NdisMoveMemory((PUCHAR)&tmp, (PUCHAR)&HqaCmdFrame->Data, len); + param = PKTLA_TRAN_TO_HOST((len) / sizeof(UINT32), &tmp); + PKTLA_DUMP(DBG_LVL_OFF, sizeof(*param) / sizeof(UINT32), param); /* Del after debug */ + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x:%02x:%02x", param->su_mu, param->mu_num, param->snd_interval, param->wlan_id0, param->wlan_id1, param->wlan_id2, param->wlan_id3); +#if defined(MT7615) || defined(MT7622) + MtATESetMacTxRx(pAd, ASIC_MAC_TX, TRUE, param->band_idx); + Set_Trigger_Sounding_Proc(pAd, cmd); +#endif +HQA_BFSOUNDING_FAIL: + + if (cmd) + os_free_mem(cmd); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TXBFSoundingStop(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + +#if defined(MT7615) || defined(MT7622) + Set_Stop_Sounding_Proc(pAd, NULL); +#endif + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_TXBFProfileDataWriteAllExt(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 bw = 0; + UINT32 profile_idx = 0; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto err0; + } + + NdisMoveMemory((PUCHAR)&bw, (PUCHAR)&HqaCmdFrame->Data, sizeof(bw)); + NdisMoveMemory((PUCHAR)&profile_idx, (PUCHAR)&HqaCmdFrame->Data + sizeof(bw), sizeof(profile_idx)); + bw = PKTL_TRAN_TO_HOST(bw); + profile_idx = PKTL_TRAN_TO_HOST(profile_idx); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%x:%x", profile_idx, bw); +err0: + + if (cmd) + os_free_mem(cmd); + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: bw:%x, profile_idx:%x\n", __func__, bw, profile_idx)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +#ifdef MT_MAC +static INT32 HQA_TxBfTxApply(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 eBF_enable = 0; + UINT32 iBF_enable = 0; + UINT32 wlan_id = 0; + UINT32 MuTx_enable = 0; + UINT32 iBFPhaseCali = 1; + RTMP_STRING *cmd; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + UCHAR *data = HqaCmdFrame->Data; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + Ret = NDIS_STATUS_RESOURCES; + goto err0; + } + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&eBF_enable); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&iBF_enable); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&wlan_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&MuTx_enable); + TESTMODE_SET_PARAM(ate_ctrl, wlan_id, eTxBf, eBF_enable); + TESTMODE_SET_PARAM(ate_ctrl, wlan_id, iTxBf, iBF_enable); + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x", wlan_id, eBF_enable, iBF_enable, MuTx_enable, iBFPhaseCali); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: wlan_id:%x, eBF enable:%x, iBF enable:%x, MuTx:%x\n", + __func__, wlan_id, eBF_enable, iBF_enable, MuTx_enable)); + Set_TxBfTxApply(pAd, cmd); +err0: + + if (cmd) + os_free_mem(cmd); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_ManualAssoc(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + P_MANUAL_CONN manual_cfg = &pAd->AteManualConnInfo; + struct _HQA_BF_MANUAL_CONN manual_conn; + RTMP_STRING rate_str[64]; + char ucNsts; + UINT_32 rate[8]; + RA_PHY_CFG_T TxPhyCfg; + UCHAR *data = HqaCmdFrame->Data; + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.type); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.wtbl_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.ownmac_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.phymode); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.bw); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.pfmuid); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.marate_mode); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.marate_mcs); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.spe_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&manual_conn.aid); + EthGetParamAndShiftBuff(FALSE, MAC_ADDR_LEN, &data, (UCHAR *)manual_conn.mac); + manual_cfg->peer_op_type = manual_conn.type; + manual_cfg->wtbl_idx = manual_conn.wtbl_idx; + manual_cfg->ownmac_idx = manual_conn.ownmac_idx; + + switch (manual_conn.phymode) { + /* abggnanac */ + case 0: + manual_cfg->peer_phy_mode = WMODE_B | WMODE_G | WMODE_GN | WMODE_A | WMODE_AN | WMODE_AC; + break; + + /* bggnan */ + case 1: + manual_cfg->peer_phy_mode = WMODE_B | WMODE_GN | WMODE_G | WMODE_AN; + break; + + /* aanac */ + case 2: + manual_cfg->peer_phy_mode = WMODE_A | WMODE_AN | WMODE_AC; + break; + + default: + manual_cfg->peer_phy_mode = WMODE_B | WMODE_G | WMODE_GN | WMODE_A | WMODE_AN | WMODE_AC; + break; + } + + switch (manual_conn.bw) { + case ATE_BAND_WIDTH_20: + manual_cfg->peer_bw = BAND_WIDTH_20; + break; + + case ATE_BAND_WIDTH_40: + manual_cfg->peer_bw = BAND_WIDTH_40; + break; + + case ATE_BAND_WIDTH_80: + manual_cfg->peer_bw = BAND_WIDTH_80; + break; + + case ATE_BAND_WIDTH_10: + manual_cfg->peer_bw = BAND_WIDTH_10; + break; + + case ATE_BAND_WIDTH_5: + manual_cfg->peer_bw = BAND_WIDTH_5; + break; + + case ATE_BAND_WIDTH_160: + manual_cfg->peer_bw = BAND_WIDTH_160; + break; + + case ATE_BAND_WIDTH_8080: + manual_cfg->peer_bw = BAND_WIDTH_8080; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: Cannot find BW with manual_conn.bw:%x\n", + __func__, manual_conn.bw)); + manual_cfg->peer_bw = manual_conn.bw; + break; + } + + manual_cfg->pfmuId = manual_conn.pfmuid; + manual_cfg->peer_maxrate_mode = manual_conn.marate_mode; + manual_cfg->peer_maxrate_mcs = manual_conn.marate_mcs; + manual_cfg->spe_idx = manual_conn.spe_idx; + manual_cfg->aid = manual_conn.aid; + manual_cfg->peer_nss = 1; /* MU */ + NdisMoveMemory(manual_cfg->peer_mac, manual_conn.mac, MAC_ADDR_LEN); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:User manual configured peer STA info:\n", __func__)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tMAC=>0x%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->AteManualConnInfo.peer_mac))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tBAND=>%d\n", pAd->AteManualConnInfo.peer_band)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tOwnMacIdx=>%d\n", pAd->AteManualConnInfo.ownmac_idx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tWTBL_Idx=>%d\n", pAd->AteManualConnInfo.wtbl_idx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tOperationType=>%d\n", pAd->AteManualConnInfo.peer_op_type)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPhyMode=>%d\n", pAd->AteManualConnInfo.peer_phy_mode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tBandWidth=>%d\n", pAd->AteManualConnInfo.peer_bw)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tNSS=>%d\n", pAd->AteManualConnInfo.peer_nss)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPfmuId=>%d\n", pAd->AteManualConnInfo.pfmuId)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAid=>%d\n", pAd->AteManualConnInfo.aid)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tSpe_idx=>%d\n", pAd->AteManualConnInfo.spe_idx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tMaxRate_Mode=>%d\n", pAd->AteManualConnInfo.peer_maxrate_mode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tMaxRate_MCS=>%d\n", pAd->AteManualConnInfo.peer_maxrate_mcs)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Now apply it to hardware!\n")); + /* This applied the manual config info into the mac table entry, including the HT/VHT cap, VHT MCS set */ + SetATEApplyStaToMacTblEntry(pAd); + /* Fixed rate configuration */ + NdisZeroMemory(&rate_str[0], sizeof(rate_str)); + sprintf(rate_str, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d", + pAd->AteManualConnInfo.wtbl_idx, + pAd->AteManualConnInfo.peer_maxrate_mode, + pAd->AteManualConnInfo.peer_bw, + pAd->AteManualConnInfo.peer_maxrate_mcs, + pAd->AteManualConnInfo.peer_nss, + 0, 0, 0, 0, 0); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tSet fixed RateInfo string as %s\n", rate_str)); + /* Set_Fixed_Rate_Proc(pAd, rate_str); */ + ucNsts = get_nsts_by_mcs(pAd->AteManualConnInfo.peer_maxrate_mode, + pAd->AteManualConnInfo.peer_maxrate_mcs, + FALSE, + pAd->AteManualConnInfo.peer_nss); + rate[0] = tx_rate_to_tmi_rate(pAd->AteManualConnInfo.peer_maxrate_mode, + pAd->AteManualConnInfo.peer_maxrate_mcs, + ucNsts, + FALSE, + 0); + rate[0] &= 0xfff; + rate[1] = rate[2] = rate[3] = rate[4] = rate[5] = rate[6] = rate[7] = rate[0]; + os_zero_mem(&TxPhyCfg, sizeof(TxPhyCfg)); + TxPhyCfg.BW = pAd->AteManualConnInfo.peer_bw; + TxPhyCfg.ShortGI = FALSE; + /* TxPhyCfg.ldpc = HT_LDPC | VHT_LDPC; */ + TxPhyCfg.ldpc = 0; + MtAsicTxCapAndRateTableUpdate(pAd, + pAd->AteManualConnInfo.wtbl_idx, + &TxPhyCfg, + rate, + FALSE); + /* WTBL configuration */ + SetATEApplyStaToAsic(pAd); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} +#else +static INT32 HQA_eBFEnable(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 enable = 0; + UINT32 band_idx = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + + NdisMoveMemory((PUCHAR)&enable, (PUCHAR)&HqaCmdFrame->Data, sizeof(enable)); + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data + sizeof(enable), sizeof(band_idx)); + enable = PKTL_TRAN_TO_HOST(enable); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + TESTMODE_SET_PARAM(ate_ctrl, band_idx, eTxBf, enable); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: enable:%x, band_idx:%x\n", __func__, enable, band_idx)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_iBFEnable(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 enable = 0; + UINT32 band_idx = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + + NdisMoveMemory((PUCHAR)&enable, (PUCHAR)&HqaCmdFrame->Data, sizeof(enable)); + NdisMoveMemory((PUCHAR)&band_idx, (PUCHAR)&HqaCmdFrame->Data + sizeof(enable), sizeof(band_idx)); + enable = PKTL_TRAN_TO_HOST(enable); + band_idx = PKTL_TRAN_TO_HOST(band_idx); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + TESTMODE_SET_PARAM(ate_ctrl, band_idx, iTxBf, enable); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: enable:%x, band_idx:%x\n", __func__, enable, band_idx)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} +#endif + + +static HQA_CMD_HANDLER HQA_TXBF_CMDS[] = { + HQA_TxBfProfileTagInValid, /* 0x1540 */ + HQA_TxBfProfileTagPfmuIdx, /* 0x1541 */ + HQA_TxBfProfileTagBfType, /* 0x1542 */ + HQA_TxBfProfileTagBw, /* 0x1543 */ + HQA_TxBfProfileTagSuMu, /* 0x1544 */ + HQA_TxBfProfileTagMemAlloc, /* 0x1545 */ + HQA_TxBfProfileTagMatrix, /* 0x1546 */ + HQA_TxBfProfileTagSnr, /* 0x1547 */ + HQA_TxBfProfileTagSmtAnt, /* 0x1548 */ + HQA_TxBfProfileTagSeIdx, /* 0x1549 */ + HQA_TxBfProfileTagRmsdThrd, /* 0x154A */ + HQA_TxBfProfileTagMcsThrd, /* 0x154B */ + HQA_TxBfProfileTagTimeOut, /* 0x154C */ + HQA_TxBfProfileTagDesiredBw, /* 0x154D */ + HQA_TxBfProfileTagDesiredNc, /* 0x154E */ + HQA_TxBfProfileTagDesiredNr, /* 0x154F */ + HQA_TxBfProfileTagWrite, /* 0x1550 */ + HQA_TxBfProfileTagRead, /* 0x1551 */ + HQA_StaRecCmmUpdate, /* 0x1552 */ + HQA_StaRecBfUpdate, /* 0x1553 */ + HQA_BFProfileDataRead, /* 0x1554 */ + HQA_BFProfileDataWrite, /* 0x1555 */ + HQA_BFSounding, /* 0x1556 */ + HQA_TXBFSoundingStop, /* 0x1557 */ + HQA_TXBFProfileDataWriteAllExt, /* 0x1558 */ +#ifdef MT_MAC + HQA_TxBfTxApply, /* 0x1559 */ + HQA_ManualAssoc, /* 0x155A */ +#else + HQA_eBFEnable, /* 0x1559 */ + HQA_iBFEnable, /* 0x155A */ +#endif + HQA_BFQdRead /* 0x155B */ +}; + +#ifdef CFG_SUPPORT_MU_MIMO +static INT32 HQA_MUGetInitMCS(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 gid = 0; + MU_STRUCT_MU_GROUP_INIT_MCS init_mcs; + struct _HQA_MU_USR_INIT_MCS out; + + NdisMoveMemory((UCHAR *)&gid, HqaCmdFrame->Data, sizeof(gid)); + gid = PKTS_TRAN_TO_HOST(gid); + os_zero_mem(&init_mcs, sizeof(init_mcs)); + os_zero_mem(&out, sizeof(out)); + Ret = hqa_wifi_test_mu_get_init_mcs(pAd, gid, &init_mcs); + out.user0 = init_mcs.user0InitMCS; + out.user1 = init_mcs.user1InitMCS; + out.user2 = init_mcs.user2InitMCS; + out.user3 = init_mcs.user3InitMCS; + NdisMoveMemory(HqaCmdFrame->Data + 2, (UCHAR *)&out, sizeof(out)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: gid:%u\n", __func__, gid)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(init_mcs), Ret); + return Ret; +} + + +static INT32 HQA_MUCalInitMCS(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + /* INT32 gid = 0; */ + MU_STRUCT_SET_CALC_INIT_MCS param; + UCHAR *data = HqaCmdFrame->Data; + + os_zero_mem(¶m, sizeof(param)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.num_of_user); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.bandwidth); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.nss_of_user0); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.nss_of_user1); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.nss_of_user2); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.nss_of_user3); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.pf_mu_id_of_user0); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.pf_mu_id_of_user1); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.pf_mu_id_of_user2); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.pf_mu_id_of_user3); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.num_of_txer); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.spe_index); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.group_index); + Ret = hqa_wifi_test_mu_cal_init_mcs(pAd, ¶m); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: spe_idx:%d\n", __func__, param.spe_index)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MUCalLQ(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 Type = 0; + INT32 gid = 0; + UINT32 txer = 0; + UCHAR *data = HqaCmdFrame->Data; + MU_STRUCT_SET_SU_CALC_LQ param_su; + MU_STRUCT_SET_CALC_LQ param_mu; + + os_zero_mem(¶m_su, sizeof(param_su)); + os_zero_mem(¶m_mu, sizeof(param_mu)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Type); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.num_of_user); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.bandwidth); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.nss_of_user0); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.nss_of_user1); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.nss_of_user2); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.nss_of_user3); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.pf_mu_id_of_user0); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.pf_mu_id_of_user1); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.pf_mu_id_of_user2); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.pf_mu_id_of_user3); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.num_of_txer); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.spe_index); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_mu.group_index); + param_su.num_of_user = param_mu.num_of_user; + param_su.bandwidth = param_mu.bandwidth; + param_su.nss_of_user0 = param_mu.nss_of_user0; + param_su.pf_mu_id_of_user0 = param_mu.pf_mu_id_of_user0; + param_su.num_of_txer = param_mu.num_of_txer; + param_su.spe_index = param_mu.spe_index; + param_su.group_index = param_mu.group_index; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: gid:%u, txer:%u spe_idx:%d\n", + __func__, gid, txer, param_mu.spe_index)); + + if (Type == 0) + Ret = hqa_wifi_test_su_cal_lq(pAd, ¶m_su); + else + Ret = hqa_wifi_test_mu_cal_lq(pAd, ¶m_mu); + + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + + return Ret; +} + + +static INT32 HQA_MUGetLQ(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT32 Type = 0; + UCHAR *data = HqaCmdFrame->Data; + SU_STRUCT_LQ_REPORT lq_su; + MU_STRUCT_LQ_REPORT lq_mu; + + os_zero_mem(&lq_su, sizeof(lq_su)); + os_zero_mem(&lq_mu, sizeof(lq_mu)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Type); + + /* TODO:: Check if structure changed*/ + if (Type == 0) { + Ret = hqa_wifi_test_su_get_lq(pAd, &lq_su); + PKTLA_DUMP(DBG_LVL_OFF, sizeof(lq_su) / sizeof(int), &lq_su); + NdisMoveMemory(HqaCmdFrame->Data + 2, (UCHAR *)&lq_su, sizeof(lq_su)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(lq_su), Ret); + } else { + Ret = hqa_wifi_test_mu_get_lq(pAd, &lq_mu); + PKTLA_DUMP(DBG_LVL_OFF, sizeof(lq_mu) / sizeof(int), &lq_mu); + NdisMoveMemory(HqaCmdFrame->Data + 2, (UCHAR *)&lq_mu, sizeof(lq_mu)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(lq_mu), Ret); + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + return Ret; +} + + +static INT32 HQA_MUSetSNROffset(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 offset = 0; + + NdisMoveMemory((UCHAR *)&offset, HqaCmdFrame->Data, sizeof(offset)); + offset = PKTL_TRAN_TO_HOST(offset); + Ret = hqa_wifi_test_snr_offset_set(pAd, offset); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: offset:%x\n", __func__, offset)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MUSetZeroNss(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 zero_nss = 0; + + NdisMoveMemory((UCHAR *)&zero_nss, HqaCmdFrame->Data, sizeof(zero_nss)); + zero_nss = PKTL_TRAN_TO_HOST(zero_nss); + Ret = hqa_wifi_test_mu_set_zero_nss(pAd, (UCHAR)zero_nss); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: zero_nss:%x\n", __func__, zero_nss)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MUSetSpeedUpLQ(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 spdup_lq = 0; + + NdisMoveMemory((UCHAR *)&spdup_lq, HqaCmdFrame->Data, sizeof(spdup_lq)); + spdup_lq = PKTL_TRAN_TO_HOST(spdup_lq); + Ret = hqa_wifi_test_mu_speed_up_lq(pAd, spdup_lq); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: spdup_lq:%x\n", __func__, spdup_lq)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MUSetMUTable(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + UCHAR *tbl = NULL; + UINT32 su_mu = 0; + MU_STRUCT_MU_TABLE info; + + os_zero_mem(&info, sizeof(info)); + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length) - sizeof(su_mu); + NdisMoveMemory((UCHAR *)&su_mu, HqaCmdFrame->Data, sizeof(su_mu)); + su_mu = PKTL_TRAN_TO_HOST(su_mu); + Ret = os_alloc_mem(pAd, (UCHAR **)&tbl, sizeof(UCHAR) * len); + + if (Ret) + goto err0; + + os_zero_mem(tbl, len); + NdisMoveMemory((UCHAR *)tbl, HqaCmdFrame->Data + sizeof(su_mu), len); + info.type = su_mu; + info.length = len; + info.prTable = tbl; + Ret = hqa_wifi_test_mu_table_set(pAd, &info); +err0: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%u, su_mu:%u\n", __func__, len, su_mu)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MUSetGroup(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + UINT32 val32; + UCHAR *data = HqaCmdFrame->Data; + MU_STRUCT_MU_GROUP grp; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.groupIndex = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.numOfUser = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user0Ldpc = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user1Ldpc = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user2Ldpc = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user3Ldpc = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.shortGI = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.bw = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user0Nss = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user1Nss = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user2Nss = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user3Nss = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.groupId = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user0UP = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user1UP = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user2UP = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user3UP = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user0MuPfId = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user1MuPfId = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user2MuPfId = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user3MuPfId = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user0InitMCS = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user1InitMCS = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user2InitMCS = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + grp.user3InitMCS = val32; + NdisMoveMemory(grp.aucUser0MacAddr, data, MAC_ADDR_LEN); + data += MAC_ADDR_LEN; + NdisMoveMemory(grp.aucUser1MacAddr, data, MAC_ADDR_LEN); + data += MAC_ADDR_LEN; + NdisMoveMemory(grp.aucUser2MacAddr, data, MAC_ADDR_LEN); + data += MAC_ADDR_LEN; + NdisMoveMemory(grp.aucUser3MacAddr, data, MAC_ADDR_LEN); + Ret = hqa_wifi_test_mu_group_set(pAd, &grp); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%x\n", __func__, len)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("0:%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(grp.aucUser0MacAddr))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("1:%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(grp.aucUser1MacAddr))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("2:%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(grp.aucUser2MacAddr))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("3:%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(grp.aucUser3MacAddr))); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MUGetQD(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + INT debug_lvl = DebugLevel; + INT32 subcarrier_idx = 0; + MU_STRUCT_MU_QD qd; + + NdisMoveMemory((PUCHAR)&subcarrier_idx, HqaCmdFrame->Data, sizeof(subcarrier_idx)); + NdisZeroMemory(&qd, sizeof(qd)); + subcarrier_idx = PKTL_TRAN_TO_HOST(subcarrier_idx); + DebugLevel = DBG_LVL_OFF; + Ret = hqa_wifi_test_mu_get_qd(pAd, subcarrier_idx, &qd); + PKTLA_DUMP(DBG_LVL_INFO, sizeof(qd) / sizeof(int), &qd); + NdisMoveMemory(HqaCmdFrame->Data + 2, (UCHAR *)&qd, sizeof(qd)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: sub:%u, qd.length:%zu, pqd:%p, HqaCmd->Data:%p\n", + __func__, subcarrier_idx, sizeof(qd), &qd, HqaCmdFrame->Data)); + ResponseToQA(HqaCmdFrame, WRQ, 2 + sizeof(qd), Ret); + DebugLevel = debug_lvl; + return Ret; +} + + +static INT32 HQA_MUSetEnable(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT32 is_enable = 0; + /* struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); */ + NdisMoveMemory((PUCHAR)&is_enable, HqaCmdFrame->Data, sizeof(is_enable)); + is_enable = PKTL_TRAN_TO_HOST(is_enable); + Ret = hqa_wifi_test_mu_set_enable(pAd, is_enable); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: MU is_enable:%x\n", __func__, is_enable)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + +static INT32 HQA_MUSetGID_UP(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + UINT16 len = 0; + UCHAR *data = HqaCmdFrame->Data; + UINT32 val32 = 0; + INT i = 0; + MU_STRUCT_MU_STA_PARAM param; + + os_zero_mem(¶m, sizeof(param)); + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + + for (i = 0; i < 2; i++) { + NdisMoveMemory(&val32, data, sizeof(val32)); + val32 = PKTL_TRAN_TO_HOST(val32); + param.gid[i] = val32; + data += sizeof(val32); + } + + for (i = 0; i < 4; i++) { + NdisMoveMemory(&val32, data, sizeof(val32)); + val32 = PKTL_TRAN_TO_HOST(val32); + param.up[i] = val32; + data += sizeof(val32); + } + + /* Del after debug */ + PKTLA_DUMP(DBG_LVL_OFF, sizeof(param) / sizeof(UINT32), ¶m); + Ret = hqa_wifi_test_mu_set_sta_gid_and_up(pAd, ¶m); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static INT32 HQA_MUTriggerTx(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + struct _ATE_CTRL *ate_ctrl = &pAd->ATECtrl; + INT32 Ret = 0; + UINT16 len = 0; + UINT32 val32; + UINT32 band_idx = 0; + UCHAR *data = HqaCmdFrame->Data; + MU_STRUCT_TRIGGER_MU_TX_FRAME_PARAM mu_tx_param; + + len = PKTS_TRAN_TO_HOST(HqaCmdFrame->Length); + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + band_idx = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + mu_tx_param.fgIsRandomPattern = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + mu_tx_param.msduPayloadLength0 = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + mu_tx_param.msduPayloadLength1 = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + mu_tx_param.msduPayloadLength2 = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + mu_tx_param.msduPayloadLength3 = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + mu_tx_param.u4MuPacketCount = val32; + Ret = EthGetParamAndShiftBuff(TRUE, sizeof(val32), &data, (UCHAR *)&val32); + mu_tx_param.u4NumOfSTAs = val32; + NdisMoveMemory(mu_tx_param.macAddrs[0], data, MAC_ADDR_LEN); + data += MAC_ADDR_LEN; + NdisMoveMemory(mu_tx_param.macAddrs[1], data, MAC_ADDR_LEN); + data += MAC_ADDR_LEN; + NdisMoveMemory(mu_tx_param.macAddrs[2], data, MAC_ADDR_LEN); + data += MAC_ADDR_LEN; + NdisMoveMemory(mu_tx_param.macAddrs[3], data, MAC_ADDR_LEN); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + Ret = hqa_wifi_test_mu_trigger_mu_tx(pAd, &mu_tx_param); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%x\n", __func__, len)); + ResponseToQA(HqaCmdFrame, WRQ, 2, Ret); + return Ret; +} + + +static HQA_CMD_HANDLER HQA_TXMU_CMDS[] = { + HQA_MUGetInitMCS, /* 0x1560 */ + HQA_MUCalInitMCS, /* 0x1561 */ + HQA_MUCalLQ, /* 0x1562 */ + HQA_MUGetLQ, /* 0x1563 */ + HQA_MUSetSNROffset, /* 0x1564 */ + HQA_MUSetZeroNss, /* 0x1565 */ + HQA_MUSetSpeedUpLQ, /* 0x1566 */ + HQA_MUSetMUTable, /* 0x1567 */ + HQA_MUSetGroup, /* 0x1568 */ + HQA_MUGetQD, /* 0x1569 */ + HQA_MUSetEnable, /* 0x156A */ + HQA_MUSetGID_UP, /* 0x156B */ + HQA_MUTriggerTx, /* 0x156C */ +}; +#endif /* CFG_SUPPORT_MU_MIMO */ +#endif /* TXBF_SUPPORT */ + + +static INT32 HQA_CapWiFiSpectrum(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *WRQ, struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; +#ifdef INTERNAL_CAPTURE_SUPPORT + /* Set Param*/ + UINT32 Control, Trigger, RingCapEn, Event, Node, Len, StopCycle, BW, MACTriggerEvent, Band; + UINT32 SourceAddrLSB = 0; + UINT32 SourceAddrMSB = 0; + UCHAR SourceAddress[MAC_ADDR_LEN]; + /* Get Param*/ + UINT32 Value, i; + UINT32 RespLen = 2; + UINT32 WF_Num, IQ_Type; + PINT32 pData = NULL; + PINT32 pDataLen = NULL; + struct _ATE_CTRL *ATECtrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ATEOp = ATECtrl->ATEOp; + UCHAR *data = HqaCmdFrame->Data; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:", __func__)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Control); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Control:%d\n", Control)); + + if (Control == 1) { + if (ATEOp->SetICapStart) { + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Trigger); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Trigger:%d\n", Trigger)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&RingCapEn); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RingCapEn:%d\n", RingCapEn)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Event); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Event:%d\n", Event)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Node); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Node:%d\n", Node)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Len); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Len:%d\n", Len)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&StopCycle); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("StopCycle:%d\n", StopCycle)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&BW); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("BW:%d\n", BW)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&MACTriggerEvent); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MACTriggerEvent:%d\n", MACTriggerEvent)); + EthGetParamAndShiftBuff(FALSE, MAC_ADDR_LEN, &data, (UCHAR *)SourceAddress); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("SourceAddress:%02x:%02x:%02x:%02x:%02x:%02x\n ", PRINT_MAC(SourceAddress))); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&Band); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Band:%d\n", Band)); + + ATECtrl->control_band_idx = (UCHAR)Band; + + SourceAddrLSB = ((SourceAddress[0]) | (SourceAddress[1] << 8) | (SourceAddress[2]) << 16 | (SourceAddress[3]) << 24); + SourceAddrMSB = ((SourceAddress[4]) | (SourceAddress[5] << 8) | (0x1 << 16)); + ATEOp->SetICapStart(pAd, Trigger, RingCapEn, Event, Node, Len, StopCycle, BW, MACTriggerEvent, SourceAddrLSB, SourceAddrMSB, Band); + } else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, RespLen, Ret); + } else if (Control == 2) { + if (ATEOp->GetICapStatus) { + Ret = ATEOp->GetICapStatus(pAd); + + if (IS_MT7615(pAd)) { + EXT_EVENT_RBIST_ADDR_T *icap_info = &(pAd->ATECtrl.icap_info); + + Value = PKTL_TRAN_TO_HOST(icap_info->u4StartAddr1); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(icap_info->u4StartAddr2); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(icap_info->u4StartAddr3); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(icap_info->u4EndAddr); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(icap_info->u4StopAddr); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(icap_info->u4Wrap); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s, StartAddr1:%02x StartAddr2:%02x StartAddr3:%02x EndAddr:%02x StopAddr:%02x Wrap:%02x\n", + __func__, icap_info->u4StartAddr1, icap_info->u4StartAddr2, icap_info->u4StartAddr3, + icap_info->u4EndAddr, icap_info->u4StopAddr, icap_info->u4Wrap)); + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Status = %d", __func__, Ret)); + } + } else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, RespLen, Ret); + } else if (Control == 3) { + if (ATEOp->GetICapIQData) { + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&WF_Num); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WF_Num:%d\n", WF_Num)); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&IQ_Type); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IQ_Type:%d\n", IQ_Type)); + { + UINT32 Len; + INT32 retval; + UCHAR *data = HqaCmdFrame->Data; + + /* Dynamic allocate memory for data length */ + retval = os_alloc_mem(pAd, (UCHAR **)&pDataLen, sizeof(INT32)); + if (retval != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : Not enough memory for dynamic allocating !!\n", __func__)); + goto error; + } + + /* Dynamic allocate memory for 1KByte data buffer */ + Len = ICAP_EVENT_DATA_SAMPLE * sizeof(INT32); + retval = os_alloc_mem(pAd, (UCHAR **)&pData, Len); + if (retval != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : Not enough memory for dynamic allocating !!\n", __func__)); + goto error; + } + + ATEOp->GetICapIQData(pAd, pData, pDataLen, IQ_Type, WF_Num); + Value = PKTL_TRAN_TO_HOST(Control); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(WF_Num); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(IQ_Type); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + Value = PKTL_TRAN_TO_HOST(*pDataLen); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + + for (i = 0; i < *pDataLen; i++) { + INT32 Value; + Value = PKTL_TRAN_TO_HOST(pData[i]); + NdisMoveMemory(data + RespLen, (UCHAR *)&Value, sizeof(Value)); + RespLen += sizeof(Value); + } + +error: + if (pDataLen != NULL) + os_free_mem(pDataLen); + if (pData != NULL) + os_free_mem(pData); + } + } else + Ret = TM_STATUS_NOTSUPPORT; + + ResponseToQA(HqaCmdFrame, WRQ, RespLen, Ret); + } + + /* else */ + /* ResponseToQA(HqaCmdFrame, WRQ, RespLen, Ret); */ +#endif /* INTERNAL_CAPTURE_SUPPORT */ + + return Ret; +} + + +static HQA_CMD_HANDLER HQA_ICAP_CMDS[] = { + HQA_CapWiFiSpectrum, /* 0x1580 */ +}; + + +static INT32 hqa_set_channel_ext(PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *wrq, + struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UINT32 len = 0; + struct _HQA_EXT_SET_CH param; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + UCHAR *data = cmd_frame->Data; + UINT32 pri_ch = 0; + UINT32 band_idx = 0; + UINT32 bw = 0; + UINT32 per_pkt_bw = 0; + + len = PKTS_TRAN_TO_HOST(cmd_frame->Length); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.num_param); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.band_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.central_ch0); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.central_ch1); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.sys_bw); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.perpkt_bw); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.pri_sel); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.reason); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.ch_band); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.out_band_freq); + + if (param.band_idx > TESTMODE_BAND_NUM-1) { + ret = NDIS_STATUS_INVALID_DATA; + goto err0; + } + + band_idx = param.band_idx; + + switch (param.sys_bw) { + case ATE_BAND_WIDTH_20: + bw = BAND_WIDTH_20; + break; + + case ATE_BAND_WIDTH_40: + bw = BAND_WIDTH_40; + break; + + case ATE_BAND_WIDTH_80: + bw = BAND_WIDTH_80; + break; + + case ATE_BAND_WIDTH_10: + bw = BAND_WIDTH_10; + break; + + case ATE_BAND_WIDTH_5: + bw = BAND_WIDTH_5; + break; + + case ATE_BAND_WIDTH_160: + bw = BAND_WIDTH_160; + break; + + case ATE_BAND_WIDTH_8080: + bw = BAND_WIDTH_8080; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: Cannot find BW with param.sys_bw:%x\n", + __func__, param.sys_bw)); + bw = param.sys_bw; + break; + } + + switch (param.perpkt_bw) { + case ATE_BAND_WIDTH_20: + per_pkt_bw = BAND_WIDTH_20; + break; + + case ATE_BAND_WIDTH_40: + per_pkt_bw = BAND_WIDTH_40; + break; + + case ATE_BAND_WIDTH_80: + per_pkt_bw = BAND_WIDTH_80; + break; + + case ATE_BAND_WIDTH_10: + per_pkt_bw = BAND_WIDTH_10; + break; + + case ATE_BAND_WIDTH_5: + per_pkt_bw = BAND_WIDTH_5; + break; + + case ATE_BAND_WIDTH_160: + case ATE_BAND_WIDTH_8080: + per_pkt_bw = BAND_WIDTH_160; + break; + + default: + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: Cannot find BW with param.sys_bw:%x\n", + __func__, param.sys_bw)); + per_pkt_bw = bw; + break; + } + + /* Set Param */ + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Channel, param.central_ch0); +#ifdef DOT11_VHT_AC + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Channel_2nd, param.central_ch1); +#endif + TESTMODE_SET_PARAM(ate_ctrl, band_idx, PerPktBW, per_pkt_bw); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, BW, bw); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, PriSel, param.pri_sel); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Ch_Band, param.ch_band); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, OutBandFreq, param.out_band_freq); + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + ate_ops->SetChannel(pAd, param.central_ch0, param.pri_sel, param.reason, param.ch_band); +err0: + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)¶m.ext_id, 4); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: len:%x, num_param:%x, band_idx:%x, ch0:%u, ch1:%u, sys_bw:%x, bw_conver:%x, ", + __func__, len, param.num_param, param.band_idx, + param.central_ch0, param.central_ch1, param.sys_bw, bw)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("perpkt_bw:%x, pri_sel:%x, pri_ch:%u\n", + param.perpkt_bw, param.pri_sel, pri_ch)); + ResponseToQA(cmd_frame, wrq, 6, ret); + return ret; +} + + +static INT32 hqa_set_txcontent_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UINT32 len = 0, pl_len = 0; + struct _HQA_EXT_TX_CONTENT param; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_TX_TIME_PARAM *tx_time_param = NULL; + UCHAR *data = cmd_frame->Data; + HEADER_802_11 *phdr = NULL; + UCHAR *addr1, *addr2, *addr3, *payload; + UINT32 band_idx = 0; + + len = PKTS_TRAN_TO_HOST(cmd_frame->Length); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.num_param); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.band_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.FC); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.dur); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.seq); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.gen_payload_rule); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.txlen); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.payload_len); + EthGetParamAndShiftBuff(FALSE, MAC_ADDR_LEN, &data, param.addr1); + EthGetParamAndShiftBuff(FALSE, MAC_ADDR_LEN, &data, param.addr2); + EthGetParamAndShiftBuff(FALSE, MAC_ADDR_LEN, &data, param.addr3); + + /* 52 for the size before payload */ + if (param.payload_len > ATE_MAX_PATTERN_SIZE) + param.payload_len = ATE_MAX_PATTERN_SIZE; + + /* Set Param */ + band_idx = param.band_idx; + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + addr1 = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Addr1); + addr2 = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Addr2); + addr3 = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Addr3); + NdisMoveMemory(addr1, param.addr1, MAC_ADDR_LEN); + NdisMoveMemory(addr2, param.addr2, MAC_ADDR_LEN); + NdisMoveMemory(addr3, param.addr3, MAC_ADDR_LEN); + phdr = (HEADER_802_11 *)TESTMODE_GET_PARAM(ate_ctrl, band_idx, TemplateFrame); + pl_len = TESTMODE_GET_PARAM(ate_ctrl, band_idx, pl_len); + /* pl_addr = TESTMODE_GET_PADDR(ate_ctrl, band_idx, payload); */ + payload = TESTMODE_GET_PARAM(ate_ctrl, band_idx, payload); + NdisMoveMemory(&phdr->FC, ¶m.FC, sizeof(phdr->FC)); + phdr->Duration = (UINT16)param.dur; + phdr->Sequence = (UINT16)param.seq; + TESTMODE_SET_PARAM(ate_ctrl, band_idx, FixedPayload, param.gen_payload_rule); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, TxLength, param.txlen); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, pl_len, param.payload_len); + /* payload = *pl_addr; */ + + /* Error check for txlen and payload_len */ + if ((param.txlen == 0) || (param.payload_len == 0)) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: txlen/payload_len=%d/%d can't be 0!!\n", + __func__, param.txlen, param.payload_len)); + return NDIS_STATUS_FAILURE; + } + + /* Packet TX time feature implementation */ + tx_time_param = TESTMODE_GET_PADDR(ate_ctrl, band_idx, tx_time_param); + if (tx_time_param->pkt_tx_time_en == TRUE) { + tx_time_param->pkt_tx_time = param.txlen; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: FC:%04x, dur:%u, seq:%u, plen:%u, pkt_tx_time:%u, GENPKT:%u\n", + __func__, param.FC, param.dur, param.seq, param.payload_len, + tx_time_param->pkt_tx_time, param.gen_payload_rule)); + + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: FC:%04x, dur:%u, seq:%u, plen:%u, txlen:%u, GENPKT:%u\n", + __func__, param.FC, param.dur, param.seq, param.payload_len, + param.txlen, param.gen_payload_rule)); + } + + EthGetParamAndShiftBuff(FALSE, param.payload_len, &data, payload); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)¶m.ext_id, sizeof(param.ext_id)); + ResponseToQA(cmd_frame, wrq, 2 + sizeof(param.ext_id), ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: addr1:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, PRINT_MAC(addr1))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: addr2:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, PRINT_MAC(addr2))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: addr3:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, PRINT_MAC(addr3))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ret:%u, len:%u, param_len:%u\n", + __func__, ret, param.payload_len, pl_len)); + + return ret; +} + + +static INT32 hqa_start_tx_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + INT32 len = 0; + UINT32 band_idx = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + UCHAR *data = cmd_frame->Data; + struct _HQA_EXT_TXV param; + ATE_TXPOWER TxPower; + UINT32 Channel = 0, Ch_Band = 0, SysBw = 0, PktBw = 0; + + len = PKTS_TRAN_TO_HOST(cmd_frame->Length); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.num_param); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.band_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.pkt_cnt); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.phymode); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.rate); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.pwr); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.stbc); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.ldpc); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.ibf); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.ebf); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.wlan_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.aifs); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.gi); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.tx_path); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m.nss); + band_idx = param.band_idx; + + if (!param.pkt_cnt) + param.pkt_cnt = 0x8fffffff; + + TESTMODE_SET_PARAM(ate_ctrl, band_idx, TxCount, param.pkt_cnt); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, PhyMode, param.phymode); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Mcs, param.rate); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Stbc, param.stbc); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Ldpc, param.ldpc); +#ifdef TXBF_SUPPORT + TESTMODE_SET_PARAM(ate_ctrl, band_idx, iTxBf, param.ibf); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, eTxBf, param.ebf); +#endif + ate_ctrl->wcid_ref = param.wlan_id; + /* TODO: Need to modify */ + TESTMODE_SET_PARAM(ate_ctrl, band_idx, ipg_param.ipg, param.aifs); /* Fix me */ + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Sgi, param.gi); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, TxAntennaSel, param.tx_path); + TESTMODE_SET_PARAM(ate_ctrl, band_idx, Nss, param.nss); + Channel = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Channel); + Ch_Band = TESTMODE_GET_PARAM(ate_ctrl, band_idx, Ch_Band); + PktBw = TESTMODE_GET_PARAM(ate_ctrl, band_idx, PerPktBW); + SysBw = TESTMODE_GET_PARAM(ate_ctrl, band_idx, BW); + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + if (param.rate == 32 && PktBw != BAND_WIDTH_40 && SysBw != BAND_WIDTH_40) { + ret = -1; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Bandwidth must to be 40 at MCS 32\n", __func__)); + goto err0; + } + + os_zero_mem(&TxPower, sizeof(TxPower)); + TxPower.Power = param.pwr; + TxPower.Channel = Channel; + TxPower.Dbdc_idx = band_idx; + TxPower.Band_idx = Ch_Band; + ret = ate_ops->SetTxPower0(pAd, TxPower); + ret = ate_ops->SetIPG(pAd); + ret = ate_ops->StartTx(pAd); +err0: + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)¶m.ext_id, sizeof(param.ext_id)); + ResponseToQA(cmd_frame, wrq, 2 + sizeof(param.ext_id), ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: band_idx:%u, pkt_cnt:%u, phy:%u, mcs:%u, stbc:%u, ldpc:%u\n", + __func__, param.band_idx, param.pkt_cnt, param.phymode, + param.rate, param.stbc, param.ldpc)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: ibf:%u, ebf:%u, wlan_id:%u, aifs:%u, gi:%u, tx_path:%x, nss:%x\n", + __func__, param.ibf, param.ebf, param.wlan_id, param.aifs, + param.gi, param.tx_path, param.nss)); + return ret; +} + + +static INT32 hqa_start_rx_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + UCHAR *data = cmd_frame->Data; + UINT32 ext_id = 0; + UINT32 param_num = 0; + UINT32 band_idx = 0; + UINT32 rx_path = 0; + UCHAR own_mac[MAC_ADDR_LEN]; + + NdisZeroMemory(own_mac, MAC_ADDR_LEN); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_num); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&band_idx); + EthGetParamAndShiftBuff(FALSE, MAC_ADDR_LEN, &data, (UCHAR *)&own_mac); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&rx_path); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + ret = ate_ops->SetRxAntenna(pAd, rx_path); + ret = ate_ops->SetAutoResp(pAd, own_mac, 1); + ret = ate_ops->StartRx(pAd); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: param num:%u, band_sel:%u, rx_path:%x, mac:%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, param_num, band_idx, rx_path, PRINT_MAC(own_mac))); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); + ResponseToQA(cmd_frame, wrq, 2 + sizeof(ext_id), ret); + return ret; +} + + +static INT32 hqa_stop_tx_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + UINT32 ext_id = 0; + UINT32 param_num = 0; + UINT32 band_idx = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_num); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&band_idx); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + ret = ate_ops->StopTx(pAd); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); + ResponseToQA(cmd_frame, wrq, 2 + sizeof(ext_id), ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: band_idx:%u\n", __func__, band_idx)); + return ret; +} + +static INT32 hqa_stop_rx_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + UINT32 ext_id = 0; + UINT32 param_num = 0; + UINT32 band_idx = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_OPERATION *ate_ops = ate_ctrl->ATEOp; + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)¶m_num); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&band_idx); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + ret = ate_ops->StopRx(pAd); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); + ResponseToQA(cmd_frame, wrq, 2 + sizeof(ext_id), ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: band_idx:%u\n", __func__, band_idx)); + return ret; +} + + +static INT32 hqa_set_tx_time(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + UINT32 ext_id = 0; + UINT32 band_idx = 0; + UINT32 is_tx_time = 0; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + struct _ATE_TX_TIME_PARAM *tx_time_param = NULL; + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&band_idx); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&is_tx_time); + tx_time_param = TESTMODE_GET_PADDR(ate_ctrl, band_idx, tx_time_param); + + ate_ctrl->control_band_idx = (UCHAR)band_idx; + + /* 0: use tx length, 1: use tx time */ + if (is_tx_time == 1) { + tx_time_param->pkt_tx_time_en = TRUE; + } else { + tx_time_param->pkt_tx_time_en = FALSE; + tx_time_param->pkt_tx_time = 0; /* Reset to 0 when start TX everytime */ + } + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); + ResponseToQA(cmd_frame, wrq, 2 + sizeof(ext_id), ret); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: band_idx:%u, is_tx_time:%d\n", __func__, band_idx, is_tx_time)); + return ret; +} + + +#ifdef TXBF_SUPPORT +static INT32 hqa_iBFGetStatus_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + UINT32 ext_id = 0; + UINT32 u4Status = 0; + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + + if (!ate_ctrl->txbf_info) + goto HQA_TAG_DNC_FAIL; + + u4Status = ate_ctrl->iBFCalStatus; + ate_ctrl->Mode &= ~fATE_IN_BF; + os_free_mem(ate_ctrl->txbf_info); + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF,("%s, val:%x\n", __FUNCTION__, u4Status)); */ + ext_id = PKTL_TRAN_TO_HOST(ext_id); + u4Status = PKTL_TRAN_TO_HOST(u4Status); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); + NdisMoveMemory(cmd_frame->Data + 6, &u4Status, 4); +HQA_TAG_DNC_FAIL: + ResponseToQA(cmd_frame, wrq, 10, ret); + return ret; +} + + +static INT32 hqa_iBFSetValue_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + struct _ATE_CTRL *ate_ctrl = &(pAd->ATECtrl); + UINT32 ext_id = 0; + UINT32 u4Action = 0; + UINT32 u4InArg[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + RTMP_STRING *cmd; + + ate_ctrl->txbf_info = NULL; + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + ret = NDIS_STATUS_RESOURCES; + goto HQA_IBF_CMD_FAIL; + } + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4Action); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[0]); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[1]); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[2]); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[3]); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[4]); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[5]); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[6]); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4InArg[7]); + + switch (u4Action) { + case ATE_TXBF_INIT: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", (UCHAR)u4InArg[0]); + SetATETxBfDutInitProc(pAd, cmd); + break; + + case ATE_CHANNEL: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + + if (u4InArg[1] == 1) + sprintf(cmd, "%d:1", (UCHAR)u4InArg[0]); + else + sprintf(cmd, "%d", (UCHAR)u4InArg[0]); + + SetATEChannel(pAd, cmd); + break; + + case ATE_TX_MCS: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", (UCHAR)u4InArg[0]); + SetATETxMcs(pAd, cmd); + break; + + case ATE_TX_POW0: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", (UCHAR)u4InArg[0]); + SetATETxPower0(pAd, cmd); + break; + + case ATE_TX_ANT: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", (UCHAR)u4InArg[0]); + SetATETxAntenna(pAd, cmd); + break; + + case ATE_RX_FRAME: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "RXFRAME"); + SetATE(pAd, cmd); + break; + + case ATE_RX_ANT: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", (UCHAR)u4InArg[0]); + SetATERxAntenna(pAd, cmd); + break; + + case ATE_TXBF_LNA_GAIN: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%d", (UCHAR)u4InArg[0]); + SetATETxBfLnaGain(pAd, cmd); + break; + + case ATE_IBF_PHASE_COMP: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* BW:DBDC idx:Group:Read from E2P:Dis compensation */ + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x", + u4InArg[0], u4InArg[1], + u4InArg[2], u4InArg[3], + u4InArg[4]); + + if (SetATEIBfPhaseComp(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ATE_IBF_PHASE_COMP is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + break; + + case ATE_IBF_TX: + u4InArg[2] = 0; /* for test purpose */ + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* fgBf:WLAN idx:Txcnt */ + sprintf(cmd, "%02x:%02x:%02x", + u4InArg[0], u4InArg[1], + u4InArg[2]); + + if (SetATETxPacketWithBf(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ATE_IBF_TX is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + break; + + case ATE_IBF_PROF_UPDATE: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* Pfmu idx:Nr:Nc */ + sprintf(cmd, "%02x:%02x:%02x", + u4InArg[0], u4InArg[1], + u4InArg[2]); + + if (SetATEIBfProfileUpdate(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ATE_IBF_PROF_UPDATE is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* Wlan Id:EBf:IBf:Mu:PhaseCalFlg */ + sprintf(cmd, "01:00:01:00:01"); + + if (Set_TxBfTxApply(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" IBF flag setting in WTBL is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + break; + + case ATE_EBF_PROF_UPDATE: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* Pfmu idx:Nr:Nc */ + sprintf(cmd, "%02x:%02x:%02x", + u4InArg[0], u4InArg[1], + u4InArg[2]); + + if (SetATEEBfProfileConfig(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ATE_EBF_PROF_UPDATE is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + break; + + case ATE_IBF_INST_CAL: + ate_ctrl->Mode |= fATE_IN_BF; + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* Group idx:Group_L_M_H:fgSX2:Calibration type:Lna level */ + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x", + u4InArg[0], u4InArg[1], + u4InArg[2], u4InArg[3], + u4InArg[4]); + + if (SetATEIBfInstCal(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ATE_IBF_GD_CAL is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + break; + + case ATE_IBF_INST_VERIFY: + ate_ctrl->Mode |= fATE_IN_BF; + u4InArg[3] = 4; /* iBF phase verification with instrument */ + u4InArg[4] = 1; /* Force LNA gain is middle gain */ + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* Group idx:Group_L_M_H:fgSX2:Calibration type:Lna level */ + sprintf(cmd, "%02x:%02x:%02x:%02x:%02x", + u4InArg[0], u4InArg[1], + u4InArg[2], u4InArg[3], + u4InArg[4]); + + if (SetATEIBfInstCal(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ATE_IBF_INST_VERIFY is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + break; + + case ATE_TXBF_GD_INIT: + break; + + case ATE_IBF_PHASE_E2P_UPDATE: + memset(cmd, 0x00, HQA_BF_STR_SIZE); + /* Group idx:fgSX2:E2P update type */ + sprintf(cmd, "%02x:%02x:%02x", + u4InArg[0], u4InArg[1], + u4InArg[2]); + pAd->fgCalibrationFail = FALSE; /* Enable EEPROM write of calibrated phase */ + + if (SetATETxBfPhaseE2pUpdate(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ATE_IBF_PHASE_E2P_UPDATE is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_IBF_CMD_FAIL; + } + + break; + + default: + break; + } + + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF,("%s, Action ID : %d, str:%s\n", __FUNCTION__, u4Action, cmd)); */ + os_free_mem(cmd); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); +HQA_IBF_CMD_FAIL: + ResponseToQA(cmd_frame, wrq, 6, ret); + return ret; +} + + +static INT32 hqa_iBFChanProfUpdate_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + UINT32 ext_id = 0; + UINT32 u4PfmuId, u4Subcarr, fgFinalData; + UINT32 i2H11, i2AngleH11, i2H21, i2AngleH21, i2H31, i2AngleH31, i2H41, i2AngleH41; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + ret = NDIS_STATUS_RESOURCES; + goto HQA_PROFILE_UPDATE_FAIL; + } + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4PfmuId); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4Subcarr); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&fgFinalData); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2H11); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2AngleH11); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2H21); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2AngleH21); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2H31); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2AngleH31); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2H41); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&i2AngleH41); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%03x:%03x:%03x:%03x:%03x:%03x:%03x:%03x:%03x:%03x:%03x", + u4PfmuId, u4Subcarr, fgFinalData, i2H11, i2AngleH11, i2H21, i2AngleH21, + i2H31, i2AngleH31, i2H41, i2AngleH41); + + if (SetATETxBfChanProfileUpdate(pAd, cmd) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" SetATETxBfChanProfileUpdate is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_PROFILE_UPDATE_FAIL; + } + + /* MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF,("%s, str:%s\n", __FUNCTION__, cmd)); */ + os_free_mem(cmd); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); +HQA_PROFILE_UPDATE_FAIL: + ResponseToQA(cmd_frame, wrq, 6, ret); + return ret; +} + + +static INT32 hqa_iBFChanProfUpdateAll_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + UINT32 ext_id = 0; + UINT32 u4PfmuId, u4Temp; + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4PfmuId); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4Temp); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4Temp); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4Temp); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4Temp); + + if (TxBfProfileDataWrite20MAll(pAd, u4PfmuId, data) == FALSE) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" SetATETxBfChanProfileUpdate is failed!!\n")); + ret = NDIS_STATUS_FAILURE; + goto HQA_PROFILE_UPDATE_FAIL; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: str:%d\n", __func__, u4PfmuId)); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); +HQA_PROFILE_UPDATE_FAIL: + ResponseToQA(cmd_frame, wrq, 6, ret); + return ret; +} + + +static INT32 hqa_iBFProfileRead_ext(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + UCHAR *data = cmd_frame->Data; + UINT32 ext_id = 0; + UINT32 u4PfmuId, u4Subcarr; + RTMP_STRING *cmd; + + os_alloc_mem(pAd, (UCHAR **)&cmd, sizeof(CHAR) * (HQA_BF_STR_SIZE)); + + if (!cmd) { + ret = NDIS_STATUS_RESOURCES; + goto HQA_TAG_DNC_FAIL; + } + + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&ext_id); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4PfmuId); + EthGetParamAndShiftBuff(TRUE, sizeof(UINT32), &data, (UCHAR *)&u4Subcarr); + memset(cmd, 0x00, HQA_BF_STR_SIZE); + sprintf(cmd, "%03x:%03x", (UCHAR)u4PfmuId, (UCHAR)u4Subcarr); + SetATETxBfProfileRead(pAd, cmd); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: str:%s\n", __func__, cmd)); + os_free_mem(cmd); + NdisMoveMemory(cmd_frame->Data + 2, (UCHAR *)&ext_id, sizeof(ext_id)); + NdisMoveMemory(cmd_frame->Data + 6, (UCHAR *)&pAd->prof, sizeof(PFMU_DATA)); +HQA_TAG_DNC_FAIL: + ResponseToQA(cmd_frame, wrq, (6 + sizeof(PFMU_DATA)), ret); + return ret; +} +#endif /* TXBF_SUPPORT */ + + +static HQA_CMD_HANDLER hqa_ext_cmd_set[] = { + NULL, + hqa_set_channel_ext, /* 0x00000001 */ + hqa_set_txcontent_ext, /* 0x00000002 */ + hqa_start_tx_ext, /* 0x00000003 */ + hqa_start_rx_ext, /* 0x00000004 */ + hqa_stop_tx_ext, /* 0x00000005 */ + hqa_stop_rx_ext, /* 0x00000006 */ + NULL, /* 0x00000007 */ +#ifdef TXBF_SUPPORT + hqa_iBFSetValue_ext, /* 0x00000008 */ + hqa_iBFGetStatus_ext, /* 0x00000009 */ + hqa_iBFChanProfUpdate_ext, /* 0x0000000A */ + hqa_iBFProfileRead_ext, /* 0x0000000B */ + hqa_iBFChanProfUpdateAll_ext, /* 0x0000000C */ +#endif /* TXBF_SUPPORT */ + NULL, /* 0x0000000D */ + NULL, /* 0x0000000E */ + NULL, /* 0x0000000F */ + NULL, /* 0x00000010 */ + NULL, /* 0x00000011 */ + NULL, /* 0x00000012 */ + NULL, /* 0x00000013 */ + NULL, /* 0x00000014 */ + NULL, /* 0x00000015 */ + NULL, /* 0x00000016 */ + NULL, /* 0x00000017 */ + NULL, /* 0x00000018 */ + NULL, /* 0x00000019 */ + NULL, /* 0x0000001A */ + NULL, /* 0x0000001B */ + NULL, /* 0x0000001C */ + NULL, /* 0x0000001D */ + NULL, /* 0x0000001E */ + NULL, /* 0x0000001F */ + NULL, /* 0x00000020 */ + NULL, /* 0x00000021 */ + NULL, /* 0x00000022 */ + NULL, /* 0x00000023 */ + NULL, /* 0x00000024 */ + NULL, /* 0x00000025 */ + hqa_set_tx_time, /* 0x00000026 */ +}; + + +static INT32 hqa_ext_cmds(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, struct _HQA_CMD_FRAME *cmd_frame) +{ + INT32 ret = 0; + INT32 idx = 0; + + NdisMoveMemory((PUCHAR)&idx, (PUCHAR)&cmd_frame->Data, 4); + idx = PKTL_TRAN_TO_HOST(idx); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: 0x%x\n", __FUNCTION__, idx)); + + if (idx >= (sizeof(hqa_ext_cmd_set)/sizeof(HQA_CMD_HANDLER))) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: cmd idx 0x%x is over bounded\n", + __FUNCTION__, idx)); + return ret; + } + + + if (hqa_ext_cmd_set[idx] != NULL) + ret = (*hqa_ext_cmd_set[idx])(pAd, wrq, cmd_frame); + else + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: cmd idx 0x%x is not supported\n", + __FUNCTION__, idx)); + + return ret; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET6[] = { + /* cmd id start from 0x1600 */ + hqa_ext_cmds, /* 0x1600 */ +}; + + +static INT32 HQA_MCU_RegRead( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + +static INT32 HQA_MCU_RegWrite( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + INT32 Ret = 0; + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + return Ret; +} + + +static INT32 HQA_MCUTest( + PRTMP_ADAPTER pAd, + RTMP_IOCTL_INPUT_STRUCT *WRQ, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT16 ntStatus = 0x00; + return ntStatus; +} + + +static HQA_CMD_HANDLER HQA_CMD_SET7[] = { + /* cmd id start from 0x2100 */ + HQA_MCU_RegRead, /* 0x2100 */ + HQA_MCU_RegWrite, /* 0x2101 */ + HQA_MCUTest, /* 0x2102 */ +}; + + +static struct _HQA_CMD_TABLE HQA_CMD_TABLES[] = { + { + HQA_CMD_SET0, + sizeof(HQA_CMD_SET0) / sizeof(HQA_CMD_HANDLER), + 0x1000, + }, + { + HQA_CMD_SET1, + sizeof(HQA_CMD_SET1) / sizeof(HQA_CMD_HANDLER), + 0x1100, + }, + { + HQA_CMD_SET2, + sizeof(HQA_CMD_SET2) / sizeof(HQA_CMD_HANDLER), + 0x1200, + }, + { + HQA_CMD_SET3, + sizeof(HQA_CMD_SET3) / sizeof(HQA_CMD_HANDLER), + 0x1300, + }, + { + HQA_CMD_SET4, + sizeof(HQA_CMD_SET4) / sizeof(HQA_CMD_HANDLER), + 0x1400, + }, + { + HQA_CMD_SET5, + sizeof(HQA_CMD_SET5) / sizeof(HQA_CMD_HANDLER), + 0x1500, + }, +#ifdef TXBF_SUPPORT + { + HQA_TXBF_CMDS, + sizeof(HQA_TXBF_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1540, + }, +#ifdef CFG_SUPPORT_MU_MIMO + { + HQA_TXMU_CMDS, + sizeof(HQA_TXMU_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1560, + }, +#endif +#endif + { + HQA_ICAP_CMDS, + sizeof(HQA_ICAP_CMDS) / sizeof(HQA_CMD_HANDLER), + 0x1580, + }, + { + HQA_CMD_SET6, + sizeof(HQA_CMD_SET6) / sizeof(HQA_CMD_HANDLER), + 0x1600, + }, + { + HQA_CMD_SET7, + sizeof(HQA_CMD_SET7) / sizeof(HQA_CMD_HANDLER), + 0x2100, + }, +}; + + +UINT32 HQA_CMDHandler( + RTMP_ADAPTER *pAd, + RTMP_IOCTL_INPUT_STRUCT *Wrq, + struct _HQA_CMD_FRAME *HqaCmdFrame) +{ + UINT32 Status = NDIS_STATUS_SUCCESS; + UINT16 CmdId; + UINT32 TableIndex = 0; + UINT32 ATEMagicNum = 0; + + ATEMagicNum = PKTL_TRAN_TO_HOST(HqaCmdFrame->MagicNo); + + if (ATEMagicNum != HQA_CMD_MAGIC_NO) + return TM_STATUS_NOTSUPPORT; + + CmdId = PKTS_TRAN_TO_HOST(HqaCmdFrame->Id); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: Command_Id = 0x%04x, testmode_ioctl\n", __func__, CmdId)); + + while (TableIndex < (sizeof(HQA_CMD_TABLES) / sizeof(struct _HQA_CMD_TABLE))) { + UINT32 CmdIndex = 0; + + CmdIndex = CmdId - HQA_CMD_TABLES[TableIndex].CmdOffset; + + if (CmdIndex < HQA_CMD_TABLES[TableIndex].CmdSetSize) { + HQA_CMD_HANDLER *pCmdSet; + + pCmdSet = HQA_CMD_TABLES[TableIndex].CmdSet; + + if (pCmdSet[CmdIndex] != NULL) + Status = (*pCmdSet[CmdIndex])(pAd, Wrq, HqaCmdFrame); + + break; + } + + TableIndex++; + } + + if (CmdId == HQA_CMD_REQ) { + HqaCmdFrame->Type = HQA_CMD_RSP; + /* HqaCmdFrame->Type = 0x8005; */ + } else + HqaCmdFrame->Type = TM_CMDRSP; + + return Status; +} diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7615.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7615.c new file mode 100644 index 000000000..d9e0d6a7f --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7615.c @@ -0,0 +1,3088 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + mt7615.c +*/ + +#include "rt_config.h" +#include "chip/mt7615_cr.h" +#include "mcu/mt7615_firmware.h" +#include "mcu/mt7615_cr4_firmware.h" +#ifdef NEED_ROM_PATCH +#include "mcu/mt7615_rom_patch.h" +#endif /* NEED_ROM_PATCH */ + +#include "hdev/hdev_basic.h" + + +/* ePAeLNA shall always be included as default */ +#include "eeprom/mt7615_e2p_ePAeLNA.h" + +#if defined(CONFIG_FIRST_IF_IPAILNA) || defined(CONFIG_SECOND_IF_IPAILNA) || defined(CONFIG_THIRD_IF_IPAILNA) +#include "eeprom/mt7615_e2p_iPAiLNA.h" +#endif +#if defined(CONFIG_FIRST_IF_IPAELNA) || defined(CONFIG_SECOND_IF_IPAELNA) || defined(CONFIG_THIRD_IF_IPAELNA) +#include "eeprom/mt7615_e2p_iPAeLNA.h" +#endif +#if defined(CONFIG_FIRST_IF_EPAILNA) || defined(CONFIG_SECOND_IF_EPAILNA) || defined(CONFIG_THIRD_IF_EPAILNA) +#include "eeprom/mt7615_e2p_ePAiLNA.h" +#endif + +#ifdef CONFIG_AP_SUPPORT +#define DEFAULT_BIN_FILE "/etc_ro/wlan/MT7615E_EEPROM1.bin" +#else +#define DEFAULT_BIN_FILE "/etc/MT7615E_EEPROM1.bin" +#endif /* CONFIG_AP_SUPPORT */ + +#ifdef CONFIG_RT_SECOND_CARD +#define SECOND_BIN_FILE "/etc_ro/wlan/MT7615E_EEPROM2.bin" +#endif /* CONFIG_RT_SECOND_CARD */ +#ifdef CONFIG_RT_THIRD_CARD +#define THIRD_BIN_FILE "/etc_ro/wlan/MT7615E_EEPROM3.bin" +#endif /* CONFIG_RT_THIRD_CARD */ + +#ifdef WIFI_SPECTRUM_SUPPORT +extern RBIST_DESC_T MT7615_SPECTRUM_DESC[]; +extern UINT8 MT7615_SpectrumBankNum; +#endif /* WIFI_SPECTRUM_SUPPORT */ + +UCHAR mt7615_ba_range[] = {4, 8, 12, 24, 36, 48, 54, 64}; + + + +static VOID mt7615_bbp_adjust(RTMP_ADAPTER *pAd, UCHAR Channel) +{ + /*do nothing, change to use radio_resource control*/ + /*here should do bbp setting only, bbp is full-offload to fw*/ +} + + +#if defined(PRE_CAL_TRX_SET1_SUPPORT) || defined(RLM_CAL_CACHE_SUPPORT) || defined(PRE_CAL_TRX_SET2_SUPPORT) +/* RXDCOC */ +UINT16 K_A20Freq[] = {4980, 5805, 5905}; +UINT16 K_A40Freq[] = {5190, 5230, 5270, 5310, 5350 + , 5390, 5430, 5470, 5510, 5550, 5590, 5630, 5670, 5710, 5755, 5795, 5835, 5875 + }; /* delta should <=10 */ +UINT16 K_A80Freq[] = {5210, 5290, 5370, 5450, 5530, 5610, 5690, 5775, 5855}; +UINT16 K_G20Freq[] = {2417, 2432, 2447, 2467}; /* delta should <=5 */ +UINT16 K_AllFreq[] = {4980, 5805, 5905, 5190, 5230, 5270, 5310, 5350, 5390, 5430 + , 5470, 5510, 5550, 5590, 5630, 5670, 5710, 5755, 5795, 5835, 5875, 5210, 5290 + , 5370, 5450, 5530, 5610, 5690, 5775, 5855, 2417, 2432, 2447, 2467 + }; + +UINT16 K_A20_SIZE = (sizeof(K_A20Freq) / sizeof(UINT16)); +UINT16 K_A40_SIZE = (sizeof(K_A40Freq) / sizeof(UINT16)); +UINT16 K_A80_SIZE = (sizeof(K_A80Freq) / sizeof(UINT16)); +UINT16 K_G20_SIZE = (sizeof(K_G20Freq) / sizeof(UINT16)); +UINT16 K_ALL_SIZE = (sizeof(K_AllFreq) / sizeof(UINT16)); + +/* TXDPD */ +UINT16 DPD_A20Freq[] = {4920, 4940, 4960, 4980, 5040, 5060, 5080, 5180, 5200, + 5220, 5240, 5260, 5280, 5300, 5320, 5340, 5360, 5380, 5400, 5420, 5440, 5460, 5480, + 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5720, 5745, 5765, + 5785, 5805, 5825, 5845, 5865, 5885, 5905 + }; +UINT16 DPD_G20Freq[] = {2422, 2442, 2462}; +UINT16 DPD_AllFreq[] = {4920, 4940, 4960, 4980, 5040, 5060, 5080, 5180, 5200, + 5220, 5240, 5260, 5280, 5300, 5320, 5340, 5360, 5380, 5400, 5420, 5440, 5460, 5480, + 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5720, 5745, 5765, + 5785, 5805, 5825, 5845, 5865, 5885, 5905, 2422, 2442, 2462 + }; + +UINT16 DPD_A20_SIZE = (sizeof(DPD_A20Freq) / sizeof(UINT16)); +UINT16 DPD_G20_SIZE = (sizeof(DPD_G20Freq) / sizeof(UINT16)); +UINT16 DPD_ALL_SIZE = (sizeof(DPD_AllFreq) / sizeof(UINT16)); +#endif + +#ifdef PRE_CAL_TRX_SET1_SUPPORT +void ShowDPDData(RTMP_ADAPTER *pAd, TXDPD_RESULT_T TxDPDResult) +{ + /* UINT i=0; */ + UINT j = 0; + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : Currently not in FLASH or BIN MODE,return.\n", __func__)); + return; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF0]: u4DPDG0_WF0_Prim = 0x%x\n", TxDPDResult.u4DPDG0_WF0_Prim)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF1]: u4DPDG0_WF1_Prim = 0x%x\n", TxDPDResult.u4DPDG0_WF1_Prim)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2]: u4DPDG0_WF2_Prim = 0x%x\n", TxDPDResult.u4DPDG0_WF2_Prim)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2]: u4DPDG0_WF2_Sec = 0x%x\n", TxDPDResult.u4DPDG0_WF2_Sec)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3]: u4DPDG0_WF3_Prim = 0x%x\n", TxDPDResult.u4DPDG0_WF3_Prim)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3]: u4DPDG0_WF3_Sec = 0x%x\n", TxDPDResult.u4DPDG0_WF3_Sec)); + + for (j = 0; j < 16; j++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF0]: ucDPDLUTEntry_WF0_B0_6[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF0_B0_6[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF0]: ucDPDLUTEntry_WF0_B16_23[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF0_B16_23[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF1]: ucDPDLUTEntry_WF1_B0_6[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF1_B0_6[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF1]: ucDPDLUTEntry_WF1_B16_23[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF1_B16_23[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2]: ucDPDLUTEntry_WF2_B0_6[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF2_B0_6[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2]: ucDPDLUTEntry_WF2_B16_23[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF2_B16_23[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2]: ucDPDLUTEntry_WF2_B8_14[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF2_B8_14[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2]: ucDPDLUTEntry_WF2_B24_31[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF2_B24_31[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3]: ucDPDLUTEntry_WF3_B0_6[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF3_B0_6[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3]: ucDPDLUTEntry_WF3_B16_23[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF3_B16_23[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3]: ucDPDLUTEntry_WF3_B8_14[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF3_B8_14[j])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3]: ucDPDLUTEntry_WF3_B24_31[%d] = 0x%x\n", j, TxDPDResult.ucDPDLUTEntry_WF3_B24_31[j])); + } +} + + +void ShowDCOCData(RTMP_ADAPTER *pAd, RXDCOC_RESULT_T RxDcocResult) +{ + UINT i = 0; + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : Currently not in FLASH or BIN MODE,return.\n", __func__)); + return; + } + + for (i = 0; i < 4; i++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF0 SX0]: ucDCOCTBL_I_WF0_SX0_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF0_SX0_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF0_SX0_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF0_SX0_LNA[i])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF0 SX2]: ucDCOCTBL_I_WF0_SX2_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF0_SX2_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF0_SX2_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF0_SX2_LNA[i])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF1 SX0]: ucDCOCTBL_I_WF1_SX0_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF1_SX0_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF1_SX0_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF1_SX0_LNA[i])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF1 SX2]: ucDCOCTBL_I_WF1_SX2_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF1_SX2_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF1_SX2_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF1_SX2_LNA[i])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2 SX0]: ucDCOCTBL_I_WF2_SX0_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF2_SX0_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF2_SX0_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF2_SX0_LNA[i])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF2 SX2]: ucDCOCTBL_I_WF2_SX2_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF2_SX2_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF2_SX2_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF2_SX2_LNA[i])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3 SX0]: ucDCOCTBL_I_WF3_SX0_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF3_SX0_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF3_SX0_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF3_SX0_LNA[i])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("[WF3 SX2]: ucDCOCTBL_I_WF3_SX2_LNA[%d] = 0x%x \tucDCOCTBL_Q_WF3_SX2_LNA[%d] = 0x%x\n" + , i, RxDcocResult.ucDCOCTBL_I_WF3_SX2_LNA[i] + , i, RxDcocResult.ucDCOCTBL_Q_WF3_SX2_LNA[i])); + } +} + +BOOLEAN mt7615_dpd_check_illegal(RTMP_ADAPTER *pAd, MT_SWITCH_CHANNEL_CFG SwChCfg, UINT16 BW160Central) +{ + UINT16 CentralFreq = 0; + UINT8 i = 0; + BOOLEAN ChannelIsIllegal = FALSE; + + if (SwChCfg.Bw == BW_8080 || SwChCfg.Bw == BW_160) + CentralFreq = BW160Central * 5 + 5000; + else + CentralFreq = SwChCfg.CentralChannel * 5 + 5000; + + if (SwChCfg.Bw == BW_20) { + for (i = 0; i < DPD_ALL_SIZE; i++) { + if (CentralFreq == DPD_AllFreq[i]) + break; + } + + if (i == DPD_ALL_SIZE) + ChannelIsIllegal = TRUE; + } else if (SwChCfg.Bw == BW_40) { + for (i = 0; i < K_A40_SIZE; i++) { + if (CentralFreq == K_A40Freq[i]) + break; + } + + if (i == K_A40_SIZE) + ChannelIsIllegal = TRUE; + } else if (SwChCfg.Bw == BW_80 || SwChCfg.Bw == BW_8080) { + for (i = 0; i < K_A80_SIZE; i++) { + if (CentralFreq == K_A80Freq[i]) + break; + } + + if (i == K_A80_SIZE) + ChannelIsIllegal = TRUE; + } else if (SwChCfg.Bw == BW_160) { + if (BW160Central == 199) + ChannelIsIllegal = TRUE; + } + + if (ChannelIsIllegal) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : non-IEEE CH, ONLINE CAL, FREQ[%d] CANT FIND LEGAL CHANNEL TO APPLY, PLEASE CHECK!!\n" + , __func__, CentralFreq)); + } + + return ChannelIsIllegal; +} + +void mt7615_apply_dpd(RTMP_ADAPTER *pAd, MT_SWITCH_CHANNEL_CFG SwChCfg, UINT16 BW160Central, BOOLEAN bSecBW80) +{ + UINT8 i = 0; + UINT8 Band = 0; + UINT16 CentralFreq = 0; + ULONG Offset = 0; + TXDPD_RESULT_T TxDPDResult; + BOOLEAN toCR = TRUE; + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Currently not in FLASH or BIN MODE,return.\n", __func__)); + return; + } + + if (SwChCfg.CentralChannel == 14) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s() : CH 14 don't need DPD , return!!!\n", __func__)); + return; + } else if (SwChCfg.CentralChannel < 14) { /* 2G */ + Band = GBAND; + + if (SwChCfg.CentralChannel >= 1 && SwChCfg.CentralChannel <= 4) + CentralFreq = 2422; + else if (SwChCfg.CentralChannel >= 5 && SwChCfg.CentralChannel <= 9) + CentralFreq = 2442; + else if (SwChCfg.CentralChannel >= 10 && SwChCfg.CentralChannel <= 13) + CentralFreq = 2462; + else + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : can't find cent freq for CH %d , should not happen!!!\n", + __func__, SwChCfg.CentralChannel)); + } else { /* 5G */ + Band = ABAND; + + /* + * by the rule DE suggests, + * 1. BW20 directly apply , illegal channel online cal. + * 2. BW40/80/160 add center frequency by 10 MHz to find a nearest calibrated BW20 CH + * 3. if center freq + 10MHz = different group , then use center freq -10 MHz to apply + */ + + if (mt7615_dpd_check_illegal(pAd, SwChCfg, BW160Central) == TRUE) { + MtCmdGetTXDPDCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, TRUE, &TxDPDResult); + return; + } + + if (SwChCfg.Bw == BW_20) + CentralFreq = SwChCfg.CentralChannel * 5 + 5000; + else if (SwChCfg.Bw == BW_160 || SwChCfg.Bw == BW_8080) { + UINT32 Central = BW160Central * 5 + 5000; + UINT32 CentralAdd10M = (BW160Central + 2) * 5 + 5000; + + if (ChannelFreqToGroup(Central) != ChannelFreqToGroup(CentralAdd10M)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("==== Different Group Central %d @ group %d Central+10 @ group %d !!\n" + , Central, ChannelFreqToGroup(Central), ChannelFreqToGroup(CentralAdd10M))); + CentralFreq = (BW160Central - 2) * 5 + 5000; + } else + CentralFreq = (BW160Central + 2) * 5 + 5000; + } else { + UINT32 Central = SwChCfg.CentralChannel * 5 + 5000; + UINT32 CentralAdd10M = (SwChCfg.CentralChannel + 2) * 5 + 5000; + + if (ChannelFreqToGroup(Central) != ChannelFreqToGroup(CentralAdd10M)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("==== Different Group Central %d @ group %d Central+10 @ group %d !!\n" + , Central, ChannelFreqToGroup(Central), ChannelFreqToGroup(CentralAdd10M))); + CentralFreq = (SwChCfg.CentralChannel - 2) * 5 + 5000; + } else + CentralFreq = (SwChCfg.CentralChannel + 2) * 5 + 5000; + } + } + + /* Find offset base on CentralFreq */ + for (i = 0; i < DPD_ALL_SIZE; i++) { + if (DPD_AllFreq[i] == CentralFreq) + break; + } + + if (i == DPD_ALL_SIZE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : UNEXPECTED ONLINE CAL, FREQ[%d] CANT FIND LEGAL CHANNEL TO APPLY, PLEASE CHECK!!\n" + , __func__, CentralFreq)); + /* send command to tell FW do online K */ + MtCmdGetTXDPDCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, TRUE, &TxDPDResult); + return; + } + + if (i < TXDPD_PART1_LIMIT) { + Offset = i * TXDPD_SIZE; + memcpy(&TxDPDResult.u4DPDG0_WF0_Prim, pAd->CalDPDAPart1Image + Offset, TXDPD_SIZE); + } else { + Offset = (i - TXDPD_PART1_LIMIT) * TXDPD_SIZE; + memcpy(&TxDPDResult.u4DPDG0_WF0_Prim, pAd->CalDPDAPart2Image + Offset, TXDPD_SIZE); + } + + if (SwChCfg.Bw == BW_160 || SwChCfg.Bw == BW_8080) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : reload 160 Central CH [%d] BW [%d] from cetral freq [%d] i[%d] offset [%x]\n", + __func__, BW160Central, SwChCfg.Bw, CentralFreq, i, DPDPART1_OFFSET + i * TXDPD_SIZE)); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : reload Central CH [%d] BW [%d] from cetral freq [%d] i[%d] offset [%x]\n", + __func__, SwChCfg.CentralChannel, SwChCfg.Bw + , CentralFreq, i, DPDPART1_OFFSET + i * TXDPD_SIZE)); + } + + ShowDPDData(pAd, TxDPDResult); + MtCmdGetTXDPDCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, FALSE, &TxDPDResult); +} + +void mt7615_apply_dcoc(RTMP_ADAPTER *pAd, MT_SWITCH_CHANNEL_CFG SwChCfg, UINT16 BW160Central, BOOLEAN bSecBW80) +{ + UINT8 i = 0; + UINT8 Band = 0; + UINT16 CentralFreq = 0; + ULONG Offset = 0; + RXDCOC_RESULT_T RxDcocResult; + BOOLEAN toCR = TRUE; + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Currently not in FLASH or BIN MODE,return.\n", __func__)); + return; + } + + /* + * 11j TODO - + * currently SwChCfg.Channel_Band is always 0 , can't judge 11j channels + * should add code below to convert to correct frequency if SwChCfg.Channel_Band is corrected. + */ + if (SwChCfg.CentralChannel <= 14) { /* 2G */ + Band = GBAND; + + if (SwChCfg.CentralChannel >= 1 && SwChCfg.CentralChannel <= 3) + CentralFreq = 2417; + else if (SwChCfg.CentralChannel >= 4 && SwChCfg.CentralChannel <= 6) + CentralFreq = 2432; + else if (SwChCfg.CentralChannel >= 7 && SwChCfg.CentralChannel <= 9) + CentralFreq = 2447; + else if (SwChCfg.CentralChannel >= 10 && SwChCfg.CentralChannel <= 14) + CentralFreq = 2467; + else + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : can't find cent freq for CH %d , should not happen!!!\n", + __func__, SwChCfg.CentralChannel)); + } else { /* 5G */ + Band = ABAND; + CentralFreq = SwChCfg.CentralChannel * 5 + 5000; + + if (SwChCfg.Bw == BW_160 || SwChCfg.Bw == BW_8080) + CentralFreq = BW160Central * 5 + 5000; + else if (SwChCfg.Bw == BW_20 && SwChCfg.CentralChannel == 161) + CentralFreq = 5805; + else if (SwChCfg.Bw == BW_20) { + /* find nearest BW40 central to apply */ + for (i = 0; i < K_A40_SIZE; i++) { + UINT delta = (CentralFreq >= K_A40Freq[i]) ? (CentralFreq - K_A40Freq[i]) : (K_A40Freq[i] - CentralFreq); + + if (delta <= 10) { + CentralFreq = K_A40Freq[i]; + break; + } + } + + if (i == K_A40_SIZE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : UNEXPECTED. FREQ[%d] CANT FIND LEGAL CHANNEL TO APPLY, PLEASE CHECK!!\n" + , __func__, CentralFreq)); + /* send command to tell FW do online K */ + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, TRUE, &RxDcocResult); + return; + } + } else if (SwChCfg.Bw == BW_40) { + /* prevent illegal channel */ + for (i = 0; i < K_A40_SIZE; i++) { + if (CentralFreq == K_A40Freq[i]) + break; + } + + if (i == K_A40_SIZE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : UNEXPECTED. FREQ[%d] @BW[%d] CANT FIND LEGAL CHANNEL TO APPLY, PLEASE CHECK!!\n" + , __func__, CentralFreq, BW_40)); + /* send command to tell FW do online K */ + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, TRUE, &RxDcocResult); + return; + } + } else if (SwChCfg.Bw == BW_80) { + /* prevent illegal channel */ + for (i = 0; i < K_A80_SIZE; i++) { + if (CentralFreq == K_A80Freq[i]) + break; + } + + if (i == K_A80_SIZE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : UNEXPECTED. FREQ[%d] @BW[%d] CANT FIND LEGAL CHANNEL TO APPLY, PLEASE CHECK!!\n" + , __func__, CentralFreq, BW_80)); + /* send command to tell FW do online K */ + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, TRUE, &RxDcocResult); + return; + } + } + } + + /* Find offset base on CentralFreq */ + for (i = 0; i < K_ALL_SIZE; i++) { + if (K_AllFreq[i] == CentralFreq) + break; + } + + if (i == K_ALL_SIZE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : UNEXPECTED. FREQ[%d] CANT FIND LEGAL CHANNEL TO APPLY, PLEASE CHECK!!\n" + , __func__, CentralFreq)); + /* send command to tell FW do online K */ + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, TRUE, &RxDcocResult); + return; + } + + Offset = i * RXDCOC_SIZE; + + if (SwChCfg.Bw == BW_160 || SwChCfg.Bw == BW_8080) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : reload 160 Central CH [%d] BW [%d] from cetral freq [%d] offset [%lx]\n", + __func__, BW160Central, SwChCfg.Bw, CentralFreq, DCOC_FLASH_OFFSET + Offset)); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : reload Central CH [%d] BW [%d] from cetral freq [%d] offset [%lx]\n", + __func__, SwChCfg.CentralChannel, SwChCfg.Bw, CentralFreq, DCOC_FLASH_OFFSET + Offset)); + } + + memcpy(&RxDcocResult.ucDCOCTBL_I_WF0_SX0_LNA[0], pAd->CalDCOCImage + Offset, RXDCOC_SIZE); + ShowDCOCData(pAd, RxDcocResult); + MtCmdGetRXDCOCCalResult(pAd, toCR, CentralFreq, SwChCfg.Bw, Band, bSecBW80, FALSE, &RxDcocResult); +} + +static BOOLEAN find_both_central_for_bw160(MT_SWITCH_CHANNEL_CFG SwChCfg, UCHAR *CentPrim80, UCHAR *CentSec80) +{ + BOOLEAN found = FALSE; + + switch (SwChCfg.CentralChannel) { + case 50: + case 82: + case 114: + case 163: + if (SwChCfg.ControlChannel < SwChCfg.CentralChannel) { + *CentPrim80 = SwChCfg.CentralChannel - 8; + *CentSec80 = SwChCfg.CentralChannel + 8; + } else { + *CentPrim80 = SwChCfg.CentralChannel + 8; + *CentSec80 = SwChCfg.CentralChannel - 8; + } + + found = TRUE; + break; + + default: + *CentPrim80 = 199; + *CentSec80 = 199; + found = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s() : ERROR!!!! unknown bw160 central %d !!!! shall do online K\n" + , __func__, SwChCfg.CentralChannel)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s() : ControlChannel [%d], CentralChannel [%d] => PrimCentral [%d] , SecCentral [%d]\n" + , __func__, SwChCfg.ControlChannel, SwChCfg.CentralChannel, *CentPrim80, *CentSec80)); + return found; +} +void mt7615_apply_cal_data(RTMP_ADAPTER *pAd, MT_SWITCH_CHANNEL_CFG SwChCfg) +{ + USHORT doCal1 = 0; + + if (pAd->E2pAccessMode != E2P_FLASH_MODE && pAd->E2pAccessMode != E2P_BIN_MODE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Currently not in FLASH or BIN MODE,return.\n", __func__)); + return; + } + +#ifdef RTMP_FLASH_SUPPORT + + if (pAd->E2pAccessMode == E2P_FLASH_MODE) + rtmp_ee_flash_read(pAd, 0x52, &doCal1); + +#endif + + if (pAd->E2pAccessMode == E2P_BIN_MODE) + rtmp_ee_bin_read16(pAd, 0x52, &doCal1); + + if (/* pAd->bDCOCReloaded && */ (doCal1 & (1 << 1)) != 0) { /* 0x52 bit 1 for Reload RXDCOC on/off */ + UCHAR CentPrim80 = 0, CentSec80 = 0; + + if (SwChCfg.Bw == BW_160) { + find_both_central_for_bw160(SwChCfg, &CentPrim80, &CentSec80); + mt7615_apply_dcoc(pAd, SwChCfg, CentPrim80, FALSE); + mt7615_apply_dcoc(pAd, SwChCfg, CentSec80, TRUE); + } else if (SwChCfg.Bw == BW_8080) { + UINT abs_cent1 = ABS(SwChCfg.ControlChannel, SwChCfg.CentralChannel); + UINT abs_cent2 = ABS(SwChCfg.ControlChannel, SwChCfg.ControlChannel2); + + if (abs_cent1 < abs_cent2) { + /* prim 80 is CentralChannel */ + CentPrim80 = SwChCfg.CentralChannel; + CentSec80 = SwChCfg.ControlChannel2; + } else { + /* prim 80 is ControlChannel2 */ + CentPrim80 = SwChCfg.ControlChannel2; + CentSec80 = SwChCfg.CentralChannel; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("###### BW_8080 ControlCH %d ControlChannel2 %d CentralChannel %d [ABS %d , %d] => prim80 [%d] sec80 [%d] ############\n" + , SwChCfg.ControlChannel, SwChCfg.ControlChannel2, SwChCfg.CentralChannel, + abs_cent1, abs_cent2, CentPrim80, CentSec80)); + mt7615_apply_dcoc(pAd, SwChCfg, CentPrim80, FALSE); + mt7615_apply_dcoc(pAd, SwChCfg, CentSec80, TRUE); + } else + mt7615_apply_dcoc(pAd, SwChCfg, 0, FALSE); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : eeprom 0x52 bit 1 is 0, do runtime cal , skip RX reload\n", __func__)); + } + + if (/* pAd->bDPDReloaded && */ (doCal1 & (0x1)) != 0) { /* 0x52 bit 0 for Reload TXDPD on/off */ + UCHAR CentPrim80 = 0, CentSec80 = 0; + + if (SwChCfg.Bw == BW_160) { + find_both_central_for_bw160(SwChCfg, &CentPrim80, &CentSec80); + mt7615_apply_dpd(pAd, SwChCfg, CentPrim80, FALSE); + mt7615_apply_dpd(pAd, SwChCfg, CentSec80, TRUE); + } else if (SwChCfg.Bw == BW_8080) { + UINT abs_cent1 = ABS(SwChCfg.ControlChannel, SwChCfg.CentralChannel); + UINT abs_cent2 = ABS(SwChCfg.ControlChannel, SwChCfg.ControlChannel2); + + if (abs_cent1 < abs_cent2) { + /* prim 80 is CentralChannel */ + CentPrim80 = SwChCfg.CentralChannel; + CentSec80 = SwChCfg.ControlChannel2; + } else { + /* prim 80 is ControlChannel2 */ + CentPrim80 = SwChCfg.ControlChannel2; + CentSec80 = SwChCfg.CentralChannel; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("###### BW_8080 ControlCH %d ControlChannel2 %d CentralChannel %d [ABS %d , %d] => prim80 [%d] sec80 [%d] ############\n" + , SwChCfg.ControlChannel, SwChCfg.ControlChannel2, SwChCfg.CentralChannel, + abs_cent1, abs_cent2, CentPrim80, CentSec80)); + mt7615_apply_dpd(pAd, SwChCfg, CentPrim80, FALSE); + mt7615_apply_dpd(pAd, SwChCfg, CentSec80, TRUE); + } else + mt7615_apply_dpd(pAd, SwChCfg, 0, FALSE); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s() : eeprom 0x52 bit 0 is 0, do runtime cal , skip TX reload\n", __func__)); + } +} +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ + +static void mt7615_switch_channel(RTMP_ADAPTER *pAd, MT_SWITCH_CHANNEL_CFG SwChCfg) +{ +#ifdef PRE_CAL_TRX_SET1_SUPPORT + mt7615_apply_cal_data(pAd, SwChCfg); +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ + + if (SwChCfg.Bw == BW_8080) { + if ((SwChCfg.ControlChannel2 - SwChCfg.CentralChannel) == 16 || + (SwChCfg.CentralChannel - SwChCfg.ControlChannel2) == 16) { + SwChCfg.Bw = BW_160; + SwChCfg.CentralChannel = (SwChCfg.CentralChannel + SwChCfg.ControlChannel2)/2; + SwChCfg.ControlChannel2 = 0; + } + } + + + MtCmdChannelSwitch(pAd, SwChCfg); + + if (!SwChCfg.bScan) + MtCmdSetTxRxPath(pAd, SwChCfg); + + pAd->LatchRfRegs.Channel = SwChCfg.CentralChannel; + +#ifdef SINGLE_SKU_V2 +#ifdef TXBF_SUPPORT +#ifdef MT_MAC +#ifdef CONFIG_ATE +#if defined(MT7615) || defined(MT7622) + TxPowerBfBackoffParaCtrl(pAd, SwChCfg.Channel_Band, SwChCfg.ControlChannel, SwChCfg.BandIdx); +#endif /* defined(MT7615) || defined(MT7622) */ +#endif /* CONFIG_ATE */ +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ +#endif /* SINGLE_SKU_V2 */ +} + +#ifdef NEW_SET_RX_STREAM +static INT mt7615_set_RxStream(RTMP_ADAPTER *pAd, UINT32 StreamNums, UCHAR BandIdx) +{ + UINT32 path = 0; + UINT i; +#ifdef DBDC_MODE + + if (pAd->CommonCfg.dbdc_mode == TRUE) { + if (StreamNums > 2) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s():illegal StreamNums(%d) for BandIdx(%d)!DBDC max can allow 2SS\n", + __func__, StreamNums, BandIdx)); + StreamNums = 2; + } + + for (i = 0; i < StreamNums; i++) + path |= 1 << i; + + if (BandIdx == 1) + path = path << 2; + } else +#endif /* DBDC_MODE */ + { + if (StreamNums > 4) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s():illegal StreamNums(%d)\n", + __func__, StreamNums)); + StreamNums = 4; + } + + for (i = 0; i < StreamNums; i++) + path |= 1 << i; + } + + return MtCmdSetRxPath(pAd, path, BandIdx); +} +#endif + +static inline VOID bufferModeFieldSet(RTMP_ADAPTER *pAd, EXT_CMD_EFUSE_BUFFER_MODE_T *pCmd, UINT16 addr) +{ + UINT32 i = pCmd->ucCount; + pCmd->BinContent[i] = pAd->EEPROMImage[addr]; + pCmd->ucCount++; +} + + +static VOID mt7615_bufferModeEfuseFill(RTMP_ADAPTER *pAd, EXT_CMD_EFUSE_BUFFER_MODE_T *pCmd) +{ + UINT16 i = 0; + pCmd->ucCount = 0; + + for (i = EFUSE_CONTENT_START; i <= EFUSE_CONTENT_END; i++) + bufferModeFieldSet(pAd, pCmd, i); + + /*must minus last add*/ + pCmd->ucCount--; +} + +#ifdef CAL_FREE_IC_SUPPORT +static UINT32 ICAL[] = {0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68, 0x69, + 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87, + 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0, 0xa1, + 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4, + 0xf7, 0xff, 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, + 0x154, 0x155, 0x159, 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, + 0x16d, 0x16e, 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, + 0x186, 0x187, 0x18b, 0x18c + }; +static UINT32 ICAL_NUM = (sizeof(ICAL) / sizeof(UINT32)); +static UINT32 ICAL_JUST_MERGE[] = {0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, + 0x118, 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1, 0x3b2}; +static UINT32 ICAL_JUST_MERGE_NUM = (sizeof(ICAL_JUST_MERGE) / sizeof(UINT32)); + +static inline BOOLEAN check_valid(RTMP_ADAPTER *pAd, UINT16 Offset) +{ + UINT16 Value = 0; + BOOLEAN NotValid; + + if ((Offset % 2) != 0) { + NotValid = rtmp_ee_efuse_read16(pAd, Offset - 1, &Value); + + if (NotValid) + return FALSE; + + if (((Value >> 8) & 0xff) == 0x00) + return FALSE; + } else { + NotValid = rtmp_ee_efuse_read16(pAd, Offset, &Value); + + if (NotValid) + return FALSE; + + if ((Value & 0xff) == 0x00) + return FALSE; + } + + return TRUE; +} + +static BOOLEAN mt7615_is_cal_free_ic(RTMP_ADAPTER *pAd) +{ + UINT32 i; + + for (i = 0; i < ICAL_NUM; i++) + if (check_valid(pAd, ICAL[i]) == FALSE) + return FALSE; + + return TRUE; +} + +static inline VOID cal_free_data_get_from_addr(RTMP_ADAPTER *ad, UINT16 Offset) +{ + UINT16 value; + + if ((Offset % 2) != 0) { + rtmp_ee_efuse_read16(ad, Offset - 1, &value); + ad->EEPROMImage[Offset] = (value >> 8) & 0xFF; + } else { + rtmp_ee_efuse_read16(ad, Offset, &value); + ad->EEPROMImage[Offset] = value & 0xFF; + } +} + +static VOID mt7615_cal_free_data_get(RTMP_ADAPTER *ad) +{ + UINT32 i; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", __func__)); + + for (i = 0; i < ICAL_NUM; i++) + cal_free_data_get_from_addr(ad, ICAL[i]); + + for (i = 0; i < ICAL_JUST_MERGE_NUM; i++) + cal_free_data_get_from_addr(ad, ICAL_JUST_MERGE[i]); +} + +static BOOLEAN mt7615_check_is_cal_free_merge(RTMP_ADAPTER *pAd) +{ + UINT32 i; + UINT16 Offset; + UINT16 value; + + for (i = 0; i < ICAL_NUM; i++) { + Offset = ICAL[i]; + + if (Offset >= MAX_EEPROM_BUFFER_SIZE) + return FALSE; + + if ((Offset % 2) != 0) { + rtmp_ee_efuse_read16(pAd, Offset - 1, &value); + value = (value >> 8) & 0xFF; + } else { + rtmp_ee_efuse_read16(pAd, Offset, &value); + value = value & 0xFF; + } + + if (pAd->EEPROMImage[Offset] != value) + return FALSE; + } + + for (i = 0; i < ICAL_JUST_MERGE_NUM; i++) { + Offset = ICAL_JUST_MERGE[i]; + + if (Offset >= MAX_EEPROM_BUFFER_SIZE) + return FALSE; + + if ((Offset % 2) != 0) { + rtmp_ee_efuse_read16(pAd, Offset - 1, &value); + value = (value >> 8) & 0xFF; + } else { + rtmp_ee_efuse_read16(pAd, Offset, &value); + value = value & 0xFF; + } + + if (pAd->EEPROMImage[Offset] != value) + return FALSE; + } + + return TRUE; +} + +#endif /* CAL_FREE_IC_SUPPORT */ + +#ifdef RF_LOCKDOWN + +static UINT32 RFLOCK[] = { 0x03F, 0x040, 0x041, 0x056, 0x057, 0x058, 0x059, 0x05A, 0x05B, 0x05C, 0x05D, 0x05E, 0x05F, 0x060, 0x061, 0x062, + 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06A, 0x06B, 0x06C, 0x06D, 0x06E, 0x06F, 0x070, 0x071, 0x072, + 0x073, 0x074, 0x075, 0x076, 0x077, 0x078, 0x079, 0x07A, 0x07B, 0x07C, 0x07D, 0x07E, 0x07F, 0x080, 0x081, 0x082, + 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089, 0x08A, 0x08B, 0x08C, 0x08D, 0x08E, 0x08F, 0x090, 0x091, 0x092, + 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09A, 0x09B, 0x09C, 0x09D, 0x09E, 0x09F, 0x0A0, 0x0A1, 0x0A2, + 0x0A3, 0x0A4, 0x0A5, 0x0A6, 0x0A7, 0x0A8, 0x0A9, 0x0AA, 0x0AB, 0x0AC, 0x0AD, 0x0AE, 0x0AF, 0x0B0, 0x0B1, 0x0B2, + 0x0B3, 0x0B4, 0x0B5, 0x0B6, 0x0B7, 0x0B8, 0x0B9, 0x0BA, 0x0BB, 0x0BC, 0x0BD, 0x0BE, 0x0BF, 0x0C0, 0x0C1, 0x0C2, + 0x0C3, 0x0C4, 0x0C5, 0x0C6, 0x0C7, 0x0C8, 0x0C9, 0x0CA, 0x0CB, 0x0CC, 0x0CD, 0x0CE, 0x0CF, 0x0D0, 0x0D1, 0x0D2, + 0x0D3, 0x0D4, 0x0D5, 0x0D6, 0x0D7, 0x0D8, 0x0D9, 0x0DA, 0x0DB, 0x0DC, 0x0DD, 0x0DE, 0x0DF, 0x0E0, 0x0E1, 0x0E2, + 0x0E3, 0x0E4, 0x0E5, 0x0E6, 0x0E7, 0x0E8, 0x0E9, 0x0EA, 0x0EB, 0x0EC, 0x0ED, 0x0EE, 0x0EF, 0x0F0, 0x0F2, 0x0F3, + 0x118, 0x11C, 0x11D, 0x11E, 0x11F, 0x12C, 0x12D, 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, 0x148, + 0x149, 0x14A, 0x14B, 0x14C, 0x14D, 0x14E, 0x14F, 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, 0x158, + 0x159, 0x15A, 0x15B, 0x15C, 0x15D, 0x15E, 0x15F, 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167, 0x168, + 0x169, 0x16A, 0x16B, 0x16C, 0x16D, 0x16E, 0x16F, 0x170, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0x177, 0x178, + 0x179, 0x17A, 0x17B, 0x17C, 0x17D, 0x17E, 0x17F, 0x180, 0x181, 0x182, 0x183, 0x184, 0x185, 0x186, 0x187, 0x188, + 0x189, 0x18A, 0x18B, 0x18C, 0x18D, 0x18E, 0x18F, 0x190, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, + 0x199, 0x19A, 0x19B, 0x19C, 0x19D, 0x19E, 0x19F, 0x1A0, 0x1A2, 0x1A3, 0x1A4, 0x1A5, 0x1A6, 0x1A7, 0x1A8, 0x1A9, + 0x1AA, 0x1AB, 0x1AC, 0x1AD, 0x1AE, 0x1AF, 0x1B0, 0x1B1, 0x1B2, 0x3AC, 0x3AD, 0x3AE, 0x3AF + }; + +static UINT32 RFLOCK_NUM = (sizeof(RFLOCK) / sizeof(UINT32)); + +static BOOLEAN mt7615_check_RF_lock_down(RTMP_ADAPTER *pAd) +{ + UCHAR block[EFUSE_BLOCK_SIZE] = ""; + USHORT offset = 0; + UINT isVaild = 0; + BOOL RFlockDown; + /* RF lock down column (0x12C) */ + offset = RF_LOCKDOWN_EEPROME_BLOCK_OFFSET; + MtCmdEfuseAccessRead(pAd, offset, &block[0], &isVaild); + + if (((block[RF_LOCKDOWN_EEPROME_COLUMN_OFFSET] & RF_LOCKDOWN_EEPROME_BIT) >> RF_LOCKDOWN_EEPROME_BIT_OFFSET)) + RFlockDown = TRUE; + else + RFlockDown = FALSE; + + return RFlockDown; +} + +static BOOLEAN mt7615_write_RF_lock_parameter(RTMP_ADAPTER *pAd, USHORT offset) +{ + BOOLEAN RFParaWrite; + BOOLEAN fgRFlock = FALSE; + UINT16 RFlock_index = 0; +#ifdef CAL_FREE_IC_SUPPORT + BOOLEAN fgCalFree = FALSE; + UINT16 CalFree_index = 0; +#endif /* CAL_FREE_IC_SUPPORT */ + + /* Priority rule 1: RF lock paramter or not? */ + /* Priority rule 2: Apply cal free or not? */ + /* Priority rule 3: Cal free parameter or not? */ + + /* Check whether the offset exist in RF Lock Table or not */ + for (RFlock_index = pAd->RFlockTempIdx; RFlock_index < RFLOCK_NUM; RFlock_index++) { + if (RFLOCK[RFlock_index] == offset) { + fgRFlock = TRUE; + pAd->RFlockTempIdx = RFlock_index; + break; + } + } + +#ifdef CAL_FREE_IC_SUPPORT + + /* Check whether the offset exist in Cal Free Table or not */ + for (CalFree_index = pAd->CalFreeTempIdx; CalFree_index < ICAL_NUM; CalFree_index++) { + if (ICAL[CalFree_index] == offset) { + fgCalFree = TRUE; + pAd->CalFreeTempIdx = CalFree_index; + break; + } + } + + /* Check whether the offset exist in Cal Free (Merge but not check) Table or not */ + for (CalFree_index = 0; CalFree_index < ICAL_JUST_MERGE_NUM; CalFree_index++) { + if (ICAL_JUST_MERGE[CalFree_index] == offset) { + fgCalFree = TRUE; + break; + } + } + +#endif /* CAL_FREE_IC_SUPPORT */ + + /* Determine whether this offset needs to be written or not when RF lockdown */ + if (fgRFlock) { +#ifdef CAL_FREE_IC_SUPPORT + + if (pAd->fgCalFreeApply) { + if (fgCalFree) + RFParaWrite = FALSE; + else + RFParaWrite = TRUE; + } else + RFParaWrite = TRUE; + +#else + RFParaWrite = TRUE; +#endif + } else + RFParaWrite = FALSE; + + return RFParaWrite; +} + +static BOOLEAN mt7615_merge_RF_lock_parameter(RTMP_ADAPTER *pAd) +{ + UCHAR block[EFUSE_BLOCK_SIZE] = ""; + struct _RTMP_CHIP_CAP *chip_cap = hc_get_chip_cap(pAd->hdev_ctrl); + USHORT length = chip_cap->EEPROM_DEFAULT_BIN_SIZE; + UCHAR *ptr = pAd->EEPROMImage; + UCHAR index; + USHORT offset = 0; + UINT isVaild = 0; + BOOL WriteStatus; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + /* Merge RF parameters in Effuse to E2p buffer */ + if (chip_check_rf_lock_down(pAd)) { + /* Check Effuse Content block by block */ + for (offset = 0; offset < length; offset += EFUSE_BLOCK_SIZE) { + MtCmdEfuseAccessRead(pAd, offset, &block[0], &isVaild); + + /* Check the Needed contents are different and update the E2p content by Effuse */ + for (index = 0; index < EFUSE_BLOCK_SIZE; index++) { + /* Obtain the status of this E2p column need to write or not */ + WriteStatus = ops->write_RF_lock_parameter(pAd, offset + index); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("Effuse[0x%04x]: Write(%d)\n", offset + index, WriteStatus)); + + if ((block[index] != ptr[index]) && (WriteStatus)) + ptr[index] = block[index]; + else + continue; + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("index 0x%04x: ", offset + index)); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("orignal E2p value=0x%04x, write value=0x%04x\n", ptr[index], + block[index])); + } + + ptr += EFUSE_BLOCK_SIZE; + } + } + + return TRUE; +} + +static UCHAR mt7615_Read_Effuse_parameter(RTMP_ADAPTER *pAd, USHORT offset) +{ + UCHAR block[EFUSE_BLOCK_SIZE] = ""; + UINT isVaild = 0; + UINT16 BlockOffset, IndexOffset; + UCHAR RFUnlock = 0xFF; + /* Obtain corresponding BlockOffset and IndexOffset for Effuse contents access */ + IndexOffset = offset % EFUSE_BLOCK_SIZE; + BlockOffset = offset - IndexOffset; + + /* Merge RF parameters in Effuse to E2p buffer */ + if (chip_check_rf_lock_down(pAd)) { + /* Check Effuse Content block by block */ + MtCmdEfuseAccessRead(pAd, BlockOffset, &block[0], &isVaild); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Read Effuse[0x%x]: 0x%x ", offset, block[IndexOffset])); + return block[IndexOffset]; + } + + return RFUnlock; +} + +static BOOLEAN mt7615_Config_Effuse_Country(RTMP_ADAPTER *pAd) +{ + UCHAR Buffer0, Buffer1; + UCHAR CountryCode[2]; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + /* Read Effuse Content */ + if (ops->Read_Effuse_parameter != NULL) { + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + /* Country Region 2G */ + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + Buffer0 = ops->Read_Effuse_parameter(pAd, COUNTRY_REGION_2G_EEPROME_OFFSET); + + /* Check the RF lock status */ + if (Buffer0 != 0xFF) { + /* Check Validation bit for content */ + if (((Buffer0) & (COUNTRY_REGION_VALIDATION_MASK)) >> (COUNTRY_REGION_VALIDATION_OFFSET)) + pAd->CommonCfg.CountryRegion = ((Buffer0) & (COUNTRY_REGION_CONTENT_MASK)); + } + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + /* Country Region 5G */ + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + Buffer1 = ops->Read_Effuse_parameter(pAd, COUNTRY_REGION_5G_EEPROME_OFFSET); + + /* Check the RF lock status */ + if (Buffer1 != 0xFF) { + /* Check Validation bit for content */ + if (((Buffer1) & (COUNTRY_REGION_VALIDATION_MASK)) >> (COUNTRY_REGION_VALIDATION_OFFSET)) + pAd->CommonCfg.CountryRegionForABand = ((Buffer1) & (COUNTRY_REGION_CONTENT_MASK)); + } + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + /* Country Code */ + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + CountryCode[0] = ops->Read_Effuse_parameter(pAd, COUNTRY_CODE_BYTE0_EEPROME_OFFSET); + CountryCode[1] = ops->Read_Effuse_parameter(pAd, COUNTRY_CODE_BYTE1_EEPROME_OFFSET); + + /* Check the RF lock status */ + if ((CountryCode[0] != 0xFF) && (CountryCode[1] != 0xFF)) { + /* Check Validation for content */ + if ((CountryCode[0] != 0x00) && (CountryCode[1] != 0x00)) { + pAd->CommonCfg.CountryCode[0] = CountryCode[0]; + pAd->CommonCfg.CountryCode[1] = CountryCode[1]; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("pAd->CommonCfg.CountryCode[0]: 0x%x, %c ", + pAd->CommonCfg.CountryCode[0], pAd->CommonCfg.CountryCode[0])); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("pAd->CommonCfg.CountryCode[1]: 0x%x, %c ", + pAd->CommonCfg.CountryCode[1], pAd->CommonCfg.CountryCode[1])); + } + } + } + + return TRUE; +} +#endif /* RF_LOCKDOWN */ + +#ifdef CFG_SUPPORT_MU_MIMO +#ifdef MANUAL_MU +INT mu_update_profile_tb(RTMP_ADAPTER *pAd, INT profile_id, UCHAR wlan_id) +{ +} + +INT mu_update_grp_table(RTMP_ADAPTER *pAd, INT grp_id) +{ + return TRUE; +} + + +INT mu_update_cluster_tb(RTMP_ADAPTER *pAd, UCHAR c_id, UINT32 *m_ship, UINT32 *u_pos) +{ + UINT32 entry_base, mac_val, offset; + ASSERT(c_id <= 31); + MAC_IO_READ32(pAd, MU_MUCR1, &mac_val); + + if (c_id < 16) + mac_val &= (~MUCR1_CLUSTER_TAB_REMAP_CTRL_MASK); + else + mac_val |= MUCR1_CLUSTER_TAB_REMAP_CTRL_MASK; + + MAC_IO_WRITE32(pAd, MU_MUCR1, mac_val); + entry_base = MU_CLUSTER_TABLE_BASE + (c_id & (~0x10)) * 24; + /* update membership */ + MAC_IO_WRITE32(pAd, entry_base + 0x0, m_ship[0]); + MAC_IO_WRITE32(pAd, entry_base + 0x4, m_ship[1]); + /* Update user position */ + MAC_IO_WRITE32(pAd, entry_base + 0x8, u_pos[0]); + MAC_IO_WRITE32(pAd, entry_base + 0xc, u_pos[1]); + MAC_IO_WRITE32(pAd, entry_base + 0x10, u_pos[2]); + MAC_IO_WRITE32(pAd, entry_base + 0x14, u_pos[3]); + return TRUE; +} + + +INT mu_get_wlanId_ac_len(RTMP_ADAPTER *pAd, UINT32 wlan_id, UINT ac) +{ + return TRUE; +} + + +INT mu_get_mu_tx_retry_cnt(RTMP_ADAPTER *pAd) +{ + return TRUE; +} + + +INT mu_get_pfid_tx_stat(RTMP_ADAPTER *pAd) +{ +} + +INT mu_get_gpid_rate_per_stat(RTMP_ADAPTER *pAd) +{ + return TRUE; +} + + +INT mt7615_mu_init(RTMP_ADAPTER *pAd) +{ + UINT32 mac_val; + /**************************************************************************** + MU Part + ****************************************************************************/ + /* After power on initial setting, AC legnth clear */ + MAC_IO_READ32(pAd, MU_MUCR4, &mac_val); + mac_val = 0x1; + MAC_IO_WRITE32(pAd, MU_MUCR4, mac_val); /* 820fe010= 0x0000_0001 */ + /* PFID table */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0x0, 0x1e000); /* 820fe780= 0x0001_e000 */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0x4, 0x1e103); /* 820fe784= 0x0001_e103 */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0x8, 0x1e205); /* 820fe788= 0x0001_e205 */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0xc, 0x1e306); /* 820fe78c= 0x0001_e306 */ + /* Cluster table */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x0, 0x0); /* 820fe400= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x8, 0x0); /* 820fe408= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x20, 0x2); /* 820fe420= 0x0000_0002 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x28, 0x0); /* 820fe428= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x40, 0x2); /* 820fe440= 0x0000_0002 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x48, 0x4); /* 820fe448= 0x0000_0004 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x60, 0x0); /* 820fe460= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x68, 0x0); /* 820fe468= 0x0000_0000 */ + /* Group rate table */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0x0, 0x4109); /* 820ff000= 0x0000_4109 */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0x4, 0x99); /* 820ff004= 0x0000_0099 */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0x8, 0x800000f0); /* 820ff008= 0x8000_00f0 */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0xc, 0x99); /* 820ff00c= 0x0000_0099 */ + /* SU Tx minimum setting */ + MAC_IO_WRITE32(pAd, MU_MUCR2, 0x10000001); /* 820fe008= 0x1000_0001 */ + /* MU max group search entry = 1 group entry */ + MAC_IO_WRITE32(pAd, MU_MUCR1, 0x0); /* 820fe004= 0x0000_0000 */ + /* MU enable */ + MAC_IO_READ32(pAd, MU_MUCR0, &mac_val); + mac_val |= 1; + MAC_IO_WRITE32(pAd, MU_MUCR0, 0x1); /* 820fe000= 0x1000_0001 */ + /**************************************************************************** + M2M Part + ****************************************************************************/ + /* Enable M2M MU temp mode */ + MAC_IO_READ32(pAd, RMAC_M2M_BAND_CTRL, &mac_val); + mac_val |= (1 << 16); + MAC_IO_WRITE32(pAd, RMAC_M2M_BAND_CTRL, mac_val); + /**************************************************************************** + AGG Part + ****************************************************************************/ + /* 820f20e0[15] = 1 or 0 all need to be verified, because + a). if primary is the fake peer, and peer will not ACK to us, cannot setup the TxOP + b). Or can use CTS2Self to setup the TxOP + */ + MAC_IO_READ32(pAd, AGG_MUCR, &mac_val); + mac_val &= (~MUCR_PRIM_BAR_MASK); + /* mac_val |= (1 << MUCR_PRIM_BAR_BIT); */ + MAC_IO_WRITE32(pAd, AGG_MUCR, mac_val); /* 820fe000= 0x1000_0001 */ + return TRUE; +} +#endif /* MANUAL_MU */ +#endif /* CFG_SUPPORT_MU_MIMO */ + +#ifndef MAC_INIT_OFFLOAD +#endif /* MAC_INIT_OFFLOAD */ + +#ifdef CONFIG_RALINK_MT7621 +static VOID mt7615_hif_set_pcie_read_params(RTMP_ADAPTER *pAd) +{ + UINT32 reg_val; + + HIF_IO_READ32(pAd, PCI_CFG_DEVICE_CONTROL, ®_val); + reg_val &= PCI_CFG_MAX_PAYLOAD_SIZE_UMASK; + reg_val &= PCI_CFG_MAX_READ_REQ_UMASK; + reg_val |= (PCI_CFG_MAX_PAYLOAD_SIZE_4K | PCI_CFG_MAX_READ_REQ_4K); + + HIF_IO_WRITE32(pAd, PCI_CFG_DEVICE_CONTROL, reg_val); + + HIF_IO_READ32(pAd, PCI_K_CNT2, ®_val); + reg_val &= K_CNT_MAX_PAYLOAD_SIZE_UMASK; + reg_val |= (K_CNT_MAX_PAYLOAD_SIZE_4K); + HIF_IO_WRITE32(pAd, PCI_K_CNT2, reg_val); + + HIF_IO_READ32(pAd, PCI_K_CONF_FUNC0_4, ®_val); + reg_val &= K_CONF_MAX_PAYLOAD_SIZE_UMASK; + reg_val |= (K_CONF_MAX_PAYLOAD_SIZE_4K); + HIF_IO_WRITE32(pAd, PCI_K_CONF_FUNC0_4, reg_val); + + HIF_IO_READ32(pAd, MT_WPDMA_PAUSE_RX_Q_TH10, ®_val); + reg_val &= TX_PRE_ADDR_ALIGN_MODE_UMASK; + HIF_IO_WRITE32(pAd, MT_WPDMA_PAUSE_RX_Q_TH10, reg_val); +} +#endif + + +static VOID mt7615_init_mac_cr(RTMP_ADAPTER *pAd) +{ + UINT32 mac_val; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s()-->\n", __func__)); + +#ifdef CONFIG_RALINK_MT7621 + mt7615_hif_set_pcie_read_params(pAd); +#endif + + +#ifndef MAC_INIT_OFFLOAD + /* Set TxFreeEvent packet only go through CR4 */ + HW_IO_READ32(pAd, PLE_HIF_REPORT, &mac_val); + mac_val |= 0x1; + HW_IO_WRITE32(pAd, PLE_HIF_REPORT, mac_val); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): Set TxRxEventPkt path 0x%0x = 0x%08x\n", + __func__, PLE_HIF_REPORT, mac_val)); + /* Set PP Flow control */ + HW_IO_READ32(pAd, PP_PAGECTL_0, &mac_val); + mac_val &= ~(PAGECTL_0_PSE_PG_CNT_MASK); + mac_val |= 0x30; + HW_IO_WRITE32(pAd, PP_PAGECTL_0, mac_val); + HW_IO_READ32(pAd, PP_PAGECTL_1, &mac_val); + mac_val &= ~(PAGECTL_1_PLE_PG_CNT_MASK); + mac_val |= 0x10; + HW_IO_WRITE32(pAd, PP_PAGECTL_1, mac_val); + HW_IO_READ32(pAd, PP_PAGECTL_2, &mac_val); + mac_val &= ~(PAGECTL_2_CUT_PG_CNT_MASK); + mac_val |= 0x30; + HW_IO_WRITE32(pAd, PP_PAGECTL_2, mac_val); + /* Check PP CT setting */ + HW_IO_READ32(pAd, PP_RXCUTDISP, &mac_val); + /* mac_val |= 0x2; */ + /* RTMP_IO_WRITE32(pAd, mac_reg, mac_val); */ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): Get CutThroughPathController CR 0x%0x = 0x%08x\n", + __func__, PP_RXCUTDISP, mac_val)); +#if defined(COMPOS_WIN) || defined(COMPOS_TESTMODE_WIN) +#else + /* TxS Setting */ + InitTxSTypeTable(pAd); +#endif + MtAsicSetTxSClassifyFilter(pAd, TXS2HOST, TXS2H_QID1, TXS2HOST_AGGNUMS, 0x00, 0); +#ifdef DBDC_MODE + MtAsicSetTxSClassifyFilter(pAd, TXS2HOST, TXS2H_QID1, TXS2HOST_AGGNUMS, 0x00, 1); +#endif /*DBDC_MODE*/ +#endif /*MAC_INIT_OFFLOAD*/ + /* MAC D0 2x / MAC D0 1x clock enable */ + MAC_IO_READ32(pAd, CFG_CCR, &mac_val); + mac_val |= (BIT31 | BIT25); + MAC_IO_WRITE32(pAd, CFG_CCR, mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: MAC D0 2x 1x initial(val=%x)\n", __func__, mac_val)); +#ifdef DBDC_MODE + MAC_IO_READ32(pAd, CFG_CCR, &mac_val); + mac_val |= (BIT30 | BIT24); + MAC_IO_WRITE32(pAd, CFG_CCR, mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: MAC D1 2x 1x initial(val=%x)\n", __func__, mac_val)); +#endif /* DBDC_MODE */ + /* Disable RX Header Translation */ + MAC_IO_READ32(pAd, DMA_DCR0, &mac_val); + mac_val &= ~(DMA_DCR0_RX_HDR_TRANS_EN_BIT | + DMA_DCR0_RX_HDR_TRANS_MODE_BIT | + DMA_DCR0_RX_RM_VLAN_BIT | DMA_DCR0_RX_INS_VLAN_BIT | + DMA_DCR0_RX_HDR_TRANS_CHK_BSSID); +#ifdef HDR_TRANS_RX_SUPPORT + if (IS_ASIC_CAP(pAd, fASIC_CAP_RX_HDR_TRANS)) { + UINT32 mac_val2; + mac_val |= DMA_DCR0_RX_HDR_TRANS_EN_BIT; + /* TODO: UnifiedSW, take care about Windows for translation mode! */ + /* mac_val |= DMA_DCR0_RX_HDR_TRANS_MODE_BIT; */ + mac_val |= DMA_DCR0_RX_HDR_TRANS_CHK_BSSID | DMA_DCR0_RX_RM_VLAN_BIT; + MAC_IO_READ32(pAd, DMA_DCR1, &mac_val2); + mac_val2 |= RHTR_AMS_VLAN_EN; + MAC_IO_WRITE32(pAd, DMA_DCR1, mac_val2); + } + +#endif /* HDR_TRANS_RX_SUPPORT */ + MAC_IO_WRITE32(pAd, DMA_DCR0, mac_val); + /* CCA Setting */ + MAC_IO_READ32(pAd, TMAC_TRCR0, &mac_val); + mac_val &= ~CCA_SRC_SEL_MASK; + mac_val |= CCA_SRC_SEL(0x2); + mac_val &= ~CCA_SEC_SRC_SEL_MASK; + mac_val |= CCA_SEC_SRC_SEL(0x0); + MAC_IO_WRITE32(pAd, TMAC_TRCR0, mac_val); + MAC_IO_READ32(pAd, TMAC_TRCR0, &mac_val); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): TMAC_TRCR0=0x%x\n", __func__, mac_val)); +#ifdef DBDC_MODE + MAC_IO_WRITE32(pAd, TMAC_TRCR1, mac_val); + MAC_IO_READ32(pAd, TMAC_TRCR1, &mac_val); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): TMAC_TRCR1=0x%x\n", __func__, mac_val)); +#endif /*DBDC_MODE*/ + /* ---Add by shiang for MT7615 RFB ED issue */ + /* Set BAR rate as 0FDM 6M default, remove after fw set */ + MAC_IO_WRITE32(pAd, AGG_ACR0, 0x04b00496); + MAC_IO_WRITE32(pAd, AGG_ACR1, 0x04b00496); + /*Add by Star for zero delimiter*/ + MAC_IO_READ32(pAd, TMAC_CTCR0, &mac_val); + mac_val &= ~INS_DDLMT_REFTIME_MASK; + mac_val |= INS_DDLMT_REFTIME(0x3f); + mac_val |= DUMMY_DELIMIT_INSERTION; + mac_val |= INS_DDLMT_DENSITY(3); + MAC_IO_WRITE32(pAd, TMAC_CTCR0, mac_val); + MAC_IO_READ32(pAd, DMA_BN0TCFR0, &mac_val); + mac_val &= ~TXS_BAF; + MAC_IO_WRITE32(pAd, DMA_BN0TCFR0, mac_val); + + /* Temporary setting for RTS */ + /*if no protect should enable for CTS-2-Self, WHQA_00025629*/ + if (MTK_REV_GTE(pAd, MT7615, MT7615E1) && MTK_REV_LT(pAd, MT7615, MT7615E3) && pAd->CommonCfg.dbdc_mode) + MAC_IO_WRITE32(pAd, AGG_PCR1, 0xfe0fffff); + else { + MAC_IO_WRITE32(pAd, AGG_PCR1, 0x0400092b);/* sync MT7615 MP2.1 */ + MAC_IO_READ32(pAd, AGG_SCR, &mac_val); + mac_val |= NLNAV_MID_PTEC_DIS; + MAC_IO_WRITE32(pAd, AGG_SCR, mac_val); + } + + /*Default disable rf low power beacon mode*/ +#define WIFI_SYS_PHY 0x10000 +#define RF_LOW_BEACON_BAND0 (WIFI_SYS_PHY+0x1900) +#define RF_LOW_BEACON_BAND1 (WIFI_SYS_PHY+0x1d00) + PHY_IO_READ32(pAd, RF_LOW_BEACON_BAND0, &mac_val); + mac_val &= ~(0x3 << 8); + mac_val |= (0x2 << 8); + PHY_IO_WRITE32(pAd, RF_LOW_BEACON_BAND0, mac_val); + PHY_IO_READ32(pAd, RF_LOW_BEACON_BAND1, &mac_val); + mac_val &= ~(0x3 << 8); + mac_val |= (0x2 << 8); + PHY_IO_WRITE32(pAd, RF_LOW_BEACON_BAND1, mac_val); +} + + + + + + +static VOID MT7615BBPInit(RTMP_ADAPTER *pAd) +{ + BOOLEAN isDBDC = FALSE, band_vld[2]; + INT idx, cbw[2] = {0}; + INT cent_ch[2] = {0}, prim_ch[2] = {0}, prim_ch_idx[2] = {0}; + INT band[2] = {0}; + INT txStream[2] = {0}; + UCHAR use_bands; + band_vld[0] = TRUE; + cbw[0] = RF_BW_20; + cent_ch[0] = 1; + prim_ch[0] = 1; + band[0] = BAND_24G; + txStream[0] = 2; +#ifdef DOT11_VHT_AC + prim_ch_idx[0] = vht_prim_ch_idx(cent_ch[0], prim_ch[0], cbw[0]); +#endif /* DOT11_VHT_AC */ + + /* Disable PHY shaping filter for Japan Region */ + if (pAd->CommonCfg.RDDurRegion == JAP) + MtCmdPhyShapingFilterDisable(pAd); + + band_vld[1] = FALSE; + use_bands = 1; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s():BBP Initialization.....\n", __func__)); + + for (idx = 0; idx < 2; idx++) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tBand %d: valid=%d, isDBDC=%d, Band=%d, CBW=%d, CentCh/PrimCh=%d/%d, prim_ch_idx=%d, txStream=%d\n", + idx, band_vld[idx], isDBDC, band[idx], cbw[idx], cent_ch[idx], prim_ch[idx], + prim_ch_idx[idx], txStream[idx])); + } + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() todo\n", __func__)); +} + + +static void mt7615_init_rf_cr(RTMP_ADAPTER *ad) +{ +} + +/* Read power per rate */ +void mt7615_get_tx_pwr_per_rate(RTMP_ADAPTER *pAd) +{ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() todo\n", __func__)); +} + + +void mt7615_get_tx_pwr_info(RTMP_ADAPTER *pAd) +{ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() todo\n", __func__)); +} + + +static void mt7615_antenna_default_reset( + struct _RTMP_ADAPTER *pAd, + EEPROM_ANTENNA_STRUC *pAntenna) +{ + USHORT value; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 max_nss = cap->max_nss; + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + if (pObj->DeviceID == NIC7611_PCIe_DEVICE_ID) + pAd->RfIcType = RFIC_7611; + + pAntenna->word = 0; + pAd->RfIcType = RFIC_7615; + pAntenna->field.TxPath = (pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET] >> 4) & 0x0F; + pAntenna->field.RxPath = pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET] & 0x0F; + + if (pAntenna->field.TxPath > max_nss) + pAntenna->field.TxPath = max_nss; + + if (pAntenna->field.RxPath > max_nss) + pAntenna->field.RxPath = max_nss; + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): TxPath = %d, RxPath = %d\n", + __func__, pAntenna->field.TxPath, pAntenna->field.RxPath)); + +#ifdef DBDC_MODE + if (max_nss == 4) { + RT28xx_EEPROM_READ16(pAd, EEPROM_DBDC_ANTENNA_CFG_OFFSET, value); + value &= 0xFF; + pAd->dbdc_band0_rx_path = (value & DBDC_BAND0_RX_MASK) >> DBDC_BAND0_RX_OFFSET; + pAd->dbdc_band0_tx_path = (value & DBDC_BAND0_TX_MASK) >> DBDC_BAND0_TX_OFFSET; + pAd->dbdc_band1_rx_path = (value & DBDC_BAND1_RX_MASK) >> DBDC_BAND1_RX_OFFSET; + pAd->dbdc_band1_tx_path = (value & DBDC_BAND1_TX_MASK) >> DBDC_BAND1_TX_OFFSET; + + if ((pAd->dbdc_band0_rx_path == 0) || (pAd->dbdc_band0_rx_path > 2)) + pAd->dbdc_band0_rx_path = 2; + + if ((pAd->dbdc_band0_tx_path == 0) || (pAd->dbdc_band0_tx_path > 2)) + pAd->dbdc_band0_tx_path = 2; + + if ((pAd->dbdc_band1_rx_path == 0) || (pAd->dbdc_band1_rx_path > 2)) + pAd->dbdc_band1_rx_path = 2; + + if ((pAd->dbdc_band1_tx_path == 0) || (pAd->dbdc_band1_tx_path > 2)) + pAd->dbdc_band1_tx_path = 2; + + } else { + pAd->dbdc_band0_rx_path = 1; + pAd->dbdc_band0_tx_path = 1; + pAd->dbdc_band1_rx_path = 1; + pAd->dbdc_band1_tx_path = 1; + } + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): DBDC BAND0 TxPath = %d, RxPath = %d\n", + __func__, pAd->dbdc_band0_tx_path, pAd->dbdc_band0_rx_path)); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): DBDC BAND1 TxPath = %d, RxPath = %d\n", + __func__, pAd->dbdc_band1_tx_path, pAd->dbdc_band1_rx_path)); +#endif + +} + + +static VOID mt7615_fw_prepare(RTMP_ADAPTER *pAd) +{ + struct fwdl_ctrl *ctrl = &pAd->MCUCtrl.fwdl_ctrl; + +#ifdef NEED_ROM_PATCH + ctrl->patch_profile[WM_CPU].source.header_ptr = mt7615_rom_patch; + ctrl->patch_profile[WM_CPU].source.header_len = sizeof(mt7615_rom_patch); + ctrl->patch_profile[WM_CPU].source.bin_name = MT7615_ROM_PATCH_BIN_FILE_NAME; +#endif + + ctrl->fw_profile[WM_CPU].source.header_ptr = MT7615_FirmwareImage; + ctrl->fw_profile[WM_CPU].source.header_len = sizeof(MT7615_FirmwareImage); + ctrl->fw_profile[WM_CPU].source.bin_name = MT7615_BIN_FILE_NAME; + + ctrl->fw_profile[WA_CPU].source.header_ptr = MT7615_CR4_FirmwareImage; + ctrl->fw_profile[WA_CPU].source.header_len = sizeof(MT7615_CR4_FirmwareImage); + ctrl->fw_profile[WA_CPU].source.bin_name = ""; +} +static VOID mt7615_fwdl_datapath_setup(RTMP_ADAPTER *pAd, BOOLEAN init) +{ + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + if (init == TRUE) + ops->pci_kick_out_cmd_msg = AndesMTPciKickOutCmdMsgFwDlRing; + else + ops->pci_kick_out_cmd_msg = AndesMTPciKickOutCmdMsg; + +#ifdef CONFIG_RALINK_MT7621 + /* + * Need to limit PDMA Tx burst size to 128 byte for MT7621 FW DL + * and restore to 256 byte afterward. + */ + if (init == TRUE) { + WPDMA_GLO_CFG_STRUC GloCfg; + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); + GloCfg.MT7615_E3_field.tx_bt_size_bit0 = 1; + GloCfg.MT7615_E3_field.tx_bt_size_bit21 = 1; + HIF_IO_WRITE32(pAd, MT_WPDMA_GLO_CFG, GloCfg.word); + } else { + WPDMA_GLO_CFG_STRUC GloCfg; + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); + GloCfg.MT7615_E3_field.tx_bt_size_bit0 = 0; + GloCfg.MT7615_E3_field.tx_bt_size_bit21 = 2; + HIF_IO_WRITE32(pAd, MT_WPDMA_GLO_CFG, GloCfg.word); + } +#endif +} + + + + +#ifdef DBDC_MODE +static UCHAR MT7615BandGetByIdx(RTMP_ADAPTER *pAd, UCHAR BandIdx) +{ + switch (BandIdx) { + case 0: + return RFIC_DUAL_BAND; + break; + + case 1: + return RFIC_5GHZ; + break; + + default: + return RFIC_DUAL_BAND; + } +} +#endif + + +void mt7615_heart_beat_check(RTMP_ADAPTER *pAd) +{ +#define HEART_BEAT_CHECK_PERIOD 30 +#define N9_HEART_BEAT_ADDR 0xc2ec /* 0x820682ec, PSE dummy CR */ +#define CR4_HEART_BEAT_ADDR 0x80200 + UINT32 mac_val; + UINT8 cr4_detect = FALSE; + UINT8 n9_detect = FALSE; + RTMP_STRING *str = NULL; + UINT32 RestoreValue; + + if ((pAd->Mlme.PeriodicRound % HEART_BEAT_CHECK_PERIOD) == 0) { + + if (pAd->heart_beat_stop == TRUE) + return; + + MAC_IO_READ32(pAd, N9_HEART_BEAT_ADDR, &mac_val); + + if (mac_val == pAd->pre_n9_heart_beat_cnt) + pAd->pre_n9_heart_beat_cnt = ~mac_val; + else if (~mac_val == pAd->pre_n9_heart_beat_cnt) + n9_detect = TRUE; + else + pAd->pre_n9_heart_beat_cnt = mac_val; + + /*Wrong : MAC_IO_READ32(pAd, CR4_HEART_BEAT_ADDR, &mac_val); + CR4 Heart Beat cannot read directly, need remap HW. */ + RTMP_IO_READ32(pAd, MCU_PCIE_REMAP_2, &RestoreValue); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, 0x82000000); + RTMP_IO_READ32(pAd, CR4_HEART_BEAT_ADDR, &mac_val); + RTMP_IO_WRITE32(pAd, MCU_PCIE_REMAP_2, RestoreValue); + + if (mac_val == pAd->pre_cr4_heart_beat_cnt) + pAd->pre_cr4_heart_beat_cnt = ~mac_val; + else if (~mac_val == pAd->pre_cr4_heart_beat_cnt) + cr4_detect = TRUE; + else + pAd->pre_cr4_heart_beat_cnt = mac_val; + + if (n9_detect && cr4_detect) + str = "N9 and CR4 heart beat stop!!\n"; + else if (n9_detect) + str = "N9 heart beat stop!!\n"; + else if (cr4_detect) + str = "CR4 heart beat stop!!\n"; + + if (str != NULL) { + pAd->heart_beat_stop = TRUE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[%s]:%s", RtmpOsGetNetDevName(pAd->net_dev), str)); +#ifdef MT_FDB + show_fdb_n9_log(pAd, NULL); + show_fdb_cr4_log(pAd, NULL); +#endif /* MT_FDB */ +#ifdef ERR_RECOVERY + ser_sys_reset(str); +#endif + } + } +} + + +#ifdef TXBF_SUPPORT +void mt7615_setETxBFCap( + IN RTMP_ADAPTER *pAd, + IN TXBF_STATUS_INFO * pTxBfInfo) +{ + HT_BF_CAP *pTxBFCap = pTxBfInfo->pHtTxBFCap; + + if (pTxBfInfo->cmmCfgETxBfEnCond > 0) { + switch (pTxBfInfo->cmmCfgETxBfEnCond) { + case SUBF_ALL: + default: + pTxBFCap->RxNDPCapable = TRUE; + pTxBFCap->TxNDPCapable = (pTxBfInfo->ucRxPathNum > 1) ? TRUE : FALSE; + pTxBFCap->ExpNoComSteerCapable = FALSE; + pTxBFCap->ExpComSteerCapable = TRUE;/* !pTxBfInfo->cmmCfgETxBfNoncompress; */ + pTxBFCap->ExpNoComBF = 0; /* HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->ExpComBF = + HT_ExBF_FB_CAP_IMMEDIATE;/* pTxBfInfo->cmmCfgETxBfNoncompress? HT_ExBF_FB_CAP_NONE: HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->MinGrouping = 3; + pTxBFCap->NoComSteerBFAntSup = 0; + pTxBFCap->ComSteerBFAntSup = 3; + pTxBFCap->TxSoundCapable = FALSE; /* Support staggered sounding frames */ + pTxBFCap->ChanEstimation = pTxBfInfo->ucRxPathNum - 1; + break; + + case SUBF_BFER: + pTxBFCap->RxNDPCapable = FALSE; + pTxBFCap->TxNDPCapable = (pTxBfInfo->ucRxPathNum > 1) ? TRUE : FALSE; + pTxBFCap->ExpNoComSteerCapable = FALSE; + pTxBFCap->ExpComSteerCapable = TRUE;/* !pTxBfInfo->cmmCfgETxBfNoncompress; */ + pTxBFCap->ExpNoComBF = 0; /* HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->ExpComBF = + HT_ExBF_FB_CAP_IMMEDIATE;/* pTxBfInfo->cmmCfgETxBfNoncompress? HT_ExBF_FB_CAP_NONE: HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->MinGrouping = 3; + pTxBFCap->NoComSteerBFAntSup = 0; + pTxBFCap->ComSteerBFAntSup = 3; + pTxBFCap->TxSoundCapable = FALSE; /* Support staggered sounding frames */ + pTxBFCap->ChanEstimation = pTxBfInfo->ucRxPathNum - 1; + break; + + case SUBF_BFEE: + pTxBFCap->RxNDPCapable = TRUE; + pTxBFCap->TxNDPCapable = FALSE; + pTxBFCap->ExpNoComSteerCapable = FALSE; + pTxBFCap->ExpComSteerCapable = TRUE;/* !pTxBfInfo->cmmCfgETxBfNoncompress; */ + pTxBFCap->ExpNoComBF = 0; /* HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->ExpComBF = + HT_ExBF_FB_CAP_IMMEDIATE;/* pTxBfInfo->cmmCfgETxBfNoncompress? HT_ExBF_FB_CAP_NONE: HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->MinGrouping = 3; + pTxBFCap->NoComSteerBFAntSup = 0; + pTxBFCap->ComSteerBFAntSup = 3; + pTxBFCap->TxSoundCapable = FALSE; /* Support staggered sounding frames */ + pTxBFCap->ChanEstimation = pTxBfInfo->ucRxPathNum - 1; + break; + } + } else + memset(pTxBFCap, 0, sizeof(*pTxBFCap)); +} + + +#ifdef VHT_TXBF_SUPPORT +void mt7615_setVHTETxBFCap( + IN RTMP_ADAPTER *pAd, + IN TXBF_STATUS_INFO * pTxBfInfo) +{ + VHT_CAP_INFO *pTxBFCap = pTxBfInfo->pVhtTxBFCap; + + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: cmmCfgETxBfEnCond = %d\n", __FUNCTION__, (UCHAR)pTxBfInfo->cmmCfgETxBfEnCond)); */ + + if (pTxBfInfo->cmmCfgETxBfEnCond > 0) { + switch (pTxBfInfo->cmmCfgETxBfEnCond) { + case SUBF_ALL: + default: + pTxBFCap->bfee_cap_su = 1; + pTxBFCap->bfer_cap_su = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; +#ifdef CFG_SUPPORT_MU_MIMO + + switch (pAd->CommonCfg.MUTxRxEnable) { + case MUBF_OFF: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; + break; + + case MUBF_BFER: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; + break; + + case MUBF_BFEE: + pTxBFCap->bfee_cap_mu = 1; + pTxBFCap->bfer_cap_mu = 0; + break; + + case MUBF_ALL: + pTxBFCap->bfee_cap_mu = 1; + pTxBFCap->bfer_cap_mu = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: set wrong parameters\n", __func__)); + break; + } + +#else + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; +#endif /* CFG_SUPPORT_MU_MIMO */ + pTxBFCap->bfee_sts_cap = 3; + pTxBFCap->num_snd_dimension = pTxBfInfo->ucTxPathNum - 1; + break; + + case SUBF_BFER: + pTxBFCap->bfee_cap_su = 0; + pTxBFCap->bfer_cap_su = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; +#ifdef CFG_SUPPORT_MU_MIMO + + switch (pAd->CommonCfg.MUTxRxEnable) { + case MUBF_OFF: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; + break; + + case MUBF_BFER: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; + break; + + case MUBF_BFEE: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; + break; + + case MUBF_ALL: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: set wrong parameters\n", __func__)); + break; + } + +#else + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; +#endif /* CFG_SUPPORT_MU_MIMO */ + pTxBFCap->bfee_sts_cap = 0; + pTxBFCap->num_snd_dimension = pTxBfInfo->ucTxPathNum - 1; + break; + + case SUBF_BFEE: + pTxBFCap->bfee_cap_su = 1; + pTxBFCap->bfer_cap_su = 0; +#ifdef CFG_SUPPORT_MU_MIMO + + switch (pAd->CommonCfg.MUTxRxEnable) { + case MUBF_OFF: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; + break; + + case MUBF_BFER: + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; + break; + + case MUBF_BFEE: + pTxBFCap->bfee_cap_mu = 1; + pTxBFCap->bfer_cap_mu = 0; + break; + + case MUBF_ALL: + pTxBFCap->bfee_cap_mu = 1; + pTxBFCap->bfer_cap_mu = 0; + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: set wrong parameters\n", __func__)); + break; + } + +#else + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfer_cap_mu = 0; +#endif /* CFG_SUPPORT_MU_MIMO */ + pTxBFCap->bfee_sts_cap = 3; + pTxBFCap->num_snd_dimension = pTxBfInfo->ucTxPathNum - 1; + break; + } + } else { + pTxBFCap->num_snd_dimension = 0; + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfee_cap_su = 0; + pTxBFCap->bfer_cap_mu = 0; + pTxBFCap->bfer_cap_su = 0; + pTxBFCap->bfee_sts_cap = 0; + } +} +#endif /* VHT_TXBF_SUPPORT */ +#endif /* TXBF_SUPPORT */ + +#ifdef SMART_CARRIER_SENSE_SUPPORT +VOID mt7615_SmartCarrierSense( + IN RTMP_ADAPTER *pAd) +{ + PSMART_CARRIER_SENSE_CTRL pSCSCtrl; + BOOL RxOnly = FALSE; + UINT32 TotalTP = 0, CrValue = 0; + INT32 CckPdBlkBundry = 0, OfdmPdBlkBundry = 0; + UCHAR i; + UCHAR idx; + UINT32 MaxRtsRtyCount = 0; + UINT32 MaxRtsCount = 0; + UINT32 TempValue = 0; + BOOL WriteCr = FALSE; + UINT32 PdCount = 0, MdrdyCount = 0; + pSCSCtrl = &pAd->SCSCtrl; + + /* 2. Tx/Rx */ + /* MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, */ + /* ("%s Band0:Tx/Rx=%d/%d MinRSSI=%d, Band1:Tx/Rx=%d/%d, MinRSSI=%d\n", */ + /* __FUNCTION__, pAd->SCSCtrl.OneSecTxByteCount[0], pAd->SCSCtrl.OneSecRxByteCount[0], pAd->SCSCtrl.SCSMinRssi[0], */ + /* pAd->SCSCtrl.OneSecTxByteCount[1], pAd->SCSCtrl.OneSecRxByteCount[1], pAd->SCSCtrl.SCSMinRssi[1])); */ + + /* 3. based on minRssi to adjust PD_BLOCK_TH */ + for (i = 0; i < 1; i++) { /* NO DBDC support. */ + for (idx = 0; idx < 4; idx++) { + HW_IO_READ32(pAd, MIB_MB0SDR0 + (idx * BssOffset) + (i * BandOffset), &CrValue); + TempValue = (CrValue >> RtsRtyCountOffset) & RtsCountMask; + + if (TempValue > MaxRtsRtyCount) { + MaxRtsRtyCount = TempValue; + MaxRtsCount = CrValue & RtsCountMask; + } + } + + pSCSCtrl->RtsCount[i] = MaxRtsCount; + pSCSCtrl->RtsRtyCount[i] = MaxRtsRtyCount; + PdCount = pAd->MsMibBucket.PdCount[i][pAd->MsMibBucket.CurIdx]; + MdrdyCount = pAd->MsMibBucket.MdrdyCount[i][pAd->MsMibBucket.CurIdx]; + /* printk("PD_count=%x, MDRSY_count=%x\n", CrValue, CrValue2); */ + pSCSCtrl->CckFalseCcaCount[i] = (PdCount & 0xffff) - (MdrdyCount & 0xffff); + pSCSCtrl->OfdmFalseCcaCount[i] = ((PdCount & 0xffff0000) >> 16) - ((MdrdyCount & 0xffff0000) >> 16); + + if (pSCSCtrl->SCSEnable[i] == SCS_ENABLE) { + TotalTP = (pSCSCtrl->OneSecTxByteCount[i] + pSCSCtrl->OneSecRxByteCount[i]); + + if ((pSCSCtrl->OneSecTxByteCount[i]) * 9 < pSCSCtrl->OneSecRxByteCount[i]) + RxOnly = TRUE; + + /* if (1 TotalTP > pSCSCtrl->SCSTrafficThreshold[i]) {*/ /* default 2M */ + if ((pSCSCtrl->RtsCount[i] > 0 || pSCSCtrl->RtsRtyCount[i] > 0) && RxOnly == FALSE) { + /* Set PD_BLOCKING_BOUNDARY */ + CckPdBlkBundry = min(((pSCSCtrl->SCSMinRssi[i] - pSCSCtrl->SCSMinRssiTolerance[i]) + 256), + pSCSCtrl->CckFixedRssiBond[i]); + + /* CCK part */ + if ((pSCSCtrl->CckFalseCcaCount[i] > pSCSCtrl->CckFalseCcaUpBond[i])) { /* Decrease coverage */ + if (MaxRtsCount > (MaxRtsRtyCount + (MaxRtsRtyCount >> 1))) { /* RTS PER < 40% */ + if (pAd->SCSCtrl.CckPdBlkTh[i] == PdBlkCckThDefault && CckPdBlkBundry > FastInitTh) { + pAd->SCSCtrl.CckPdBlkTh[i] = FastInitTh; + WriteCr = TRUE; + } + /* pSCSCtrl->CckPdBlkTh[i] += 2; //One step is 2dB. */ + else if ((pSCSCtrl->CckPdBlkTh[i] + OneStep) <= CckPdBlkBundry) { + pSCSCtrl->CckPdBlkTh[i] += OneStep; + /* Write to CR */ + WriteCr = TRUE; + } else if (pSCSCtrl->CckPdBlkTh[i] > CckPdBlkBundry) { + pSCSCtrl->CckPdBlkTh[i] = CckPdBlkBundry; + /* Write to CR */ + WriteCr = TRUE; + } + } + } else if (pSCSCtrl->CckFalseCcaCount[i] < pSCSCtrl->CckFalseCcaLowBond[i] || + (MaxRtsCount + (MaxRtsCount >> 1)) < MaxRtsRtyCount) { /* Increase coverage */ + if (pSCSCtrl->CckPdBlkTh[i] - OneStep >= PdBlkCckThDefault) { + pSCSCtrl->CckPdBlkTh[i] -= OneStep; + + if (pSCSCtrl->CckPdBlkTh[i] > CckPdBlkBundry) /* Tracking mini RSSI to prevent out of service rage. */ + pSCSCtrl->CckPdBlkTh[i] = CckPdBlkBundry; + + /* Write to CR */ + WriteCr = TRUE; + } + } else { /* Stable stat */ + if (pSCSCtrl->CckPdBlkTh[i] > CckPdBlkBundry) { /* Tracking mini RSSI to prevent out of service rage. */ + pSCSCtrl->CckPdBlkTh[i] = CckPdBlkBundry; + WriteCr = TRUE; + } + } + + if (WriteCr) { /* Write for CCK PD blocking */ + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_7, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCckThOffset); /* Bit[8:1] */ + CrValue |= (pSCSCtrl->CckPdBlkTh[i] << PdBlkCckThOffset); + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_7, CrValue); + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_8, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCck1RThOffset); /* Bit[31:24] */ + CrValue |= (pSCSCtrl->CckPdBlkTh[i] << PdBlkCck1RThOffset); + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_8, CrValue); + } + + WriteCr = FALSE; /* Clear */ + /* OFDM part */ + /* Set PD_BLOCKING_BOUNDARY */ + OfdmPdBlkBundry = min(((pSCSCtrl->SCSMinRssi[i] - pSCSCtrl->SCSMinRssiTolerance[i]) * 2 + 512), + pSCSCtrl->OfdmFixedRssiBond[i]); + + if (pSCSCtrl->OfdmFalseCcaCount[i] > pSCSCtrl->OfdmFalseCcaUpBond[i]) { /* Decrease coverage */ + if (MaxRtsCount > (MaxRtsRtyCount + (MaxRtsRtyCount >> 1))) { /* RTS PER < 40% */ + if (pAd->SCSCtrl.OfdmPdBlkTh[i] == PdBlkOfmdThDefault && OfdmPdBlkBundry > FastInitThOfdm) { + pAd->SCSCtrl.OfdmPdBlkTh[i] = FastInitThOfdm; + WriteCr = TRUE; + } + + if ((pSCSCtrl->OfdmPdBlkTh[i] + OneStep) <= OfdmPdBlkBundry) { + pSCSCtrl->OfdmPdBlkTh[i] += OneStep; + /* Write to CR */ + WriteCr = TRUE; + } else if (pSCSCtrl->OfdmPdBlkTh[i] > OfdmPdBlkBundry) { + pSCSCtrl->OfdmPdBlkTh[i] = OfdmPdBlkBundry; + /* Write to CR */ + WriteCr = TRUE; + } + } + } else if (pSCSCtrl->OfdmFalseCcaCount[i] < pSCSCtrl->OfdmFalseCcaLowBond[i] || + (MaxRtsCount + (MaxRtsCount >> 1)) < MaxRtsRtyCount) { /* Increase coverage */ + if (pSCSCtrl->OfdmPdBlkTh[i] - OneStep >= PdBlkOfmdThDefault) { + pSCSCtrl->OfdmPdBlkTh[i] -= OneStep; + + if (pSCSCtrl->OfdmPdBlkTh[i] > OfdmPdBlkBundry) /* Tracking mini RSSI to prevent out of service rage. */ + pSCSCtrl->OfdmPdBlkTh[i] = OfdmPdBlkBundry; + + /* Write to CR */ + WriteCr = TRUE; + } + } else { /* Stable stat */ + if (pSCSCtrl->OfdmPdBlkTh[i] > OfdmPdBlkBundry) { /* Tracking mini RSSI to prevent out of service rage. */ + pSCSCtrl->OfdmPdBlkTh[i] = OfdmPdBlkBundry; + WriteCr = TRUE; + } + } + + if (WriteCr) { /* Write for OFDM PD blocking */ + if (i == 0) { + HW_IO_READ32(pAd, PHY_MIN_PRI_PWR, &CrValue); + CrValue &= ~(PdBlkOfmdThMask << PdBlkOfmdThOffset); /* OFDM PD BLOCKING TH */ + CrValue |= (pSCSCtrl->OfdmPdBlkTh[i] << PdBlkOfmdThOffset); + HW_IO_WRITE32(pAd, PHY_MIN_PRI_PWR, CrValue); + } else if (i == 1) { /* DBDC */ + HW_IO_READ32(pAd, BAND1_PHY_MIN_PRI_PWR, &CrValue); + CrValue &= ~(PdBlkOfmdThMask << PdBlkOfmdThOffsetB1); /* OFDM PD BLOCKING TH */ + CrValue |= (pSCSCtrl->OfdmPdBlkTh[i] << PdBlkOfmdThOffsetB1); + HW_IO_WRITE32(pAd, BAND1_PHY_MIN_PRI_PWR, CrValue); + } + } + } else { /* Disable SCS No traffic */ + if (pSCSCtrl->CckPdBlkTh[i] != PdBlkCckThDefault) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("Disable SCS due to RtsCount=%d RxOnly=%d\n", + pSCSCtrl->RtsCount[i], RxOnly)); + pSCSCtrl->CckPdBlkTh[i] = PdBlkCckThDefault; + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_7, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCckThOffset); /* Bit[8:1] */ + CrValue |= (PdBlkCckThDefault << PdBlkCckThOffset); /* 0x92 is default value -110dBm */ + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_7, CrValue); + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_8, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCck1RThOffset); /* Bit[31:24] */ + CrValue |= (PdBlkCckThDefault << PdBlkCck1RThOffset); /* 0x92 is default value -110dBm */ + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_8, CrValue); + } + + if (pSCSCtrl->OfdmPdBlkTh[i] != PdBlkOfmdThDefault) { + if (i == 0) { + pSCSCtrl->OfdmPdBlkTh[i] = PdBlkOfmdThDefault; + HW_IO_READ32(pAd, PHY_MIN_PRI_PWR, &CrValue); + CrValue &= ~(PdBlkOfmdThMask << PdBlkOfmdThOffset); /* OFDM PD BLOCKING TH */ + CrValue |= (PdBlkOfmdThDefault << PdBlkOfmdThOffset); + HW_IO_WRITE32(pAd, PHY_MIN_PRI_PWR, CrValue); + } else if (i == 1) { + pSCSCtrl->OfdmPdBlkTh[i] = PdBlkOfmdThDefault; + HW_IO_READ32(pAd, BAND1_PHY_MIN_PRI_PWR, &CrValue); + CrValue &= ~(PdBlkOfmdThMask << PdBlkOfmdThOffsetB1); /* OFDM PD BLOCKING TH */ + CrValue |= (PdBlkOfmdThDefault << PdBlkOfmdThOffsetB1); + HW_IO_WRITE32(pAd, BAND1_PHY_MIN_PRI_PWR, CrValue); + } + } + } + } else if (pSCSCtrl->SCSEnable[i] == SCS_DISABLE) { + if (pSCSCtrl->CckPdBlkTh[i] != PdBlkCckThDefault) { + pSCSCtrl->CckPdBlkTh[i] = PdBlkCckThDefault; + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_7, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCckThOffset); /* Bit[8:1] */ + CrValue |= (PdBlkCckThDefault << PdBlkCckThOffset); /* 0x92 is default value -110dBm */ + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_7, CrValue); + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_8, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCck1RThOffset); /* Bit[31:24] */ + CrValue |= (PdBlkCckThDefault << PdBlkCck1RThOffset); /* 0x92 is default value -110dBm */ + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_8, CrValue); + } + + if (pSCSCtrl->OfdmPdBlkTh[i] != PdBlkOfmdThDefault) { + if (i == 0) { + pSCSCtrl->OfdmPdBlkTh[i] = PdBlkOfmdThDefault; + HW_IO_READ32(pAd, PHY_MIN_PRI_PWR, &CrValue); + CrValue &= ~(PdBlkOfmdThMask << PdBlkOfmdThOffset); /* OFDM PD BLOCKING TH */ + CrValue |= (PdBlkOfmdThDefault << PdBlkOfmdThOffset); + HW_IO_WRITE32(pAd, PHY_MIN_PRI_PWR, CrValue); + } else if (i == 1) { + pSCSCtrl->OfdmPdBlkTh[i] = PdBlkOfmdThDefault; + HW_IO_READ32(pAd, BAND1_PHY_MIN_PRI_PWR, &CrValue); + CrValue &= ~(PdBlkOfmdThMask << PdBlkOfmdThOffsetB1); /* OFDM PD BLOCKING TH */ + CrValue |= (PdBlkOfmdThDefault << PdBlkOfmdThOffsetB1); + HW_IO_WRITE32(pAd, BAND1_PHY_MIN_PRI_PWR, CrValue); + } + } + } + } +} + +VOID mt7615_SetSCS( + IN RTMP_ADAPTER *pAd, + IN UCHAR BandIdx, + IN UINT32 value) +{ + UINT32 CrValue; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): BandIdx=%d, SCSEnable=%d\n", __func__, BandIdx, value)); + + if (value > 500) /* traffic threshold.*/ + pAd->SCSCtrl.SCSTrafficThreshold[BandIdx] = value; + else if (value == SCS_DISABLE) { + pAd->SCSCtrl.SCSEnable[BandIdx] = SCS_DISABLE; + pAd->SCSCtrl.SCSStatus[BandIdx] = PD_BLOCKING_OFF; + /* Disable PD blocking and reset related CR */ + HW_IO_READ32(pAd, PHY_MIN_PRI_PWR, &CrValue); + /* CrValue &= ~(0x1 << PdBlkEnabeOffset); Bit[19] */ + CrValue &= ~(PdBlkOfmdThMask << PdBlkOfmdThOffset); /* OFDM PD BLOCKING TH */ + CrValue |= (PdBlkOfmdThDefault << PdBlkOfmdThOffset); + HW_IO_WRITE32(pAd, PHY_MIN_PRI_PWR, CrValue); + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_7, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCckThOffset); /* Bit[8:1] */ + CrValue |= (PdBlkCckThDefault << PdBlkCckThOffset); /* 0x92 is default value -110dBm */ + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_7, CrValue); + HW_IO_READ32(pAd, PHY_RXTD_CCKPD_8, &CrValue); + CrValue &= ~(PdBlkCckThMask << PdBlkCck1RThOffset); /* Bit[31:24] */ + CrValue |= (PdBlkCckThDefault << PdBlkCck1RThOffset); /* 0x92 is default value -110dBm */ + HW_IO_WRITE32(pAd, PHY_RXTD_CCKPD_8, CrValue); + } else if (value == SCS_ENABLE) + pAd->SCSCtrl.SCSEnable[BandIdx] = SCS_ENABLE; +} +#endif /* SMART_CARRIER_SENSE_SUPPORT */ + + +UCHAR *mt7615_get_default_bin_image(RTMP_ADAPTER *pAd) +{ +#ifdef MULTI_INF_SUPPORT + + if (multi_inf_get_idx(pAd) == 0) { +#if defined(CONFIG_FIRST_IF_IPAILNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 1st iPAiLNA default bin.\n")); + return MT7615_E2PImage1_iPAiLNA; +#elif defined(CONFIG_FIRST_IF_IPAELNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 1st iPAeLNA default bin.\n")); + return MT7615_E2PImage1_iPAeLNA; +#elif defined(CONFIG_FIRST_IF_EPAILNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 1st ePAiLNA default bin.\n")); + return MT7615_E2PImage1_ePAiLNA; +#else + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 1st ePAeLNA default bin.\n")); + return MT7615_E2PImage1_ePAeLNA; +#endif + } + +#if defined(CONFIG_RT_SECOND_CARD) + else if (multi_inf_get_idx(pAd) == 1) { +#if defined(CONFIG_SECOND_IF_IPAILNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 2nd iPAiLNA default bin.\n")); + return MT7615_E2PImage2_iPAiLNA; +#elif defined(CONFIG_SECOND_IF_IPAELNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 2nd iPAeLNA default bin.\n")); + return MT7615_E2PImage2_iPAeLNA; +#elif defined(CONFIG_SECOND_IF_EPAILNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 2nd ePAiLNA default bin.\n")); + return MT7615_E2PImage2_ePAiLNA; +#else + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 2nd ePAeLNA default bin.\n")); + return MT7615_E2PImage2_ePAeLNA; +#endif + } + +#endif /* CONFIG_RT_SECOND_CARD */ +#if defined(CONFIG_RT_THIRD_CARD) + else if (multi_inf_get_idx(pAd) == 2) { +#if defined(CONFIG_THIRD_IF_IPAILNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 3rd iPAiLNA default bin.\n")); + return MT7615_E2PImage3_iPAiLNA; +#elif defined(CONFIG_THIRD_IF_IPAELNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 3rd iPAeLNA default bin.\n")); + return MT7615_E2PImage3_iPAeLNA; +#elif defined(CONFIG_THIRD_IF_EPAILNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 3rd ePAiLNA default bin.\n")); + return MT7615_E2PImage3_ePAiLNA; +#else + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Use 3rd ePAeLNA default bin.\n")); + return MT7615_E2PImage3_ePAeLNA; +#endif + } + +#endif /* CONFIG_RT_THIRD_CARD */ + else +#endif /* MULTI_INF_SUPPORT */ + { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use the default ePAeLNA bin image!\n")); + return MT7615_E2PImage1_ePAeLNA; + } + + return NULL; +} + +UCHAR *mt7615_get_default_bin_image_file(RTMP_ADAPTER *pAd) +{ +#ifdef MULTI_INF_SUPPORT + if (multi_inf_get_idx(pAd) == 0) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use %dst %s default bin.\n", multi_inf_get_idx(pAd), DEFAULT_BIN_FILE)); + return DEFAULT_BIN_FILE; + } +#if defined(MT_SECOND_CARD) + else if (multi_inf_get_idx(pAd) == 1) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use %dst %s default bin.\n", multi_inf_get_idx(pAd), SECOND_BIN_FILE)); + return SECOND_BIN_FILE; + } +#endif /* MT_SECOND_CARD */ +#if defined(MT_THIRD_CARD) + else if (multi_inf_get_idx(pAd) == 2) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use %dst %s default bin.\n", multi_inf_get_idx(pAd), THIRD_BIN_FILE)); + return THIRD_BIN_FILE; + } +#endif /* MT_THIRD_CARD */ + else +#endif /* MULTI_INF_SUPPORT */ + { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use the default %s bin image!\n", DEFAULT_BIN_FILE)); + + return DEFAULT_BIN_FILE; + } + + return NULL; +} + +static INT hif_set_WPDMA(RTMP_ADAPTER *pAd, INT32 TxRx, BOOLEAN enable, UINT8 WPDMABurstSIZE) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + UINT32 Value1; + UINT32 Value2; +#ifdef CONFIG_DELAY_INT + UINT32 Value; +#endif + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); + HW_IO_READ32(pAd, 0x7158, &Value1); + HW_IO_READ32(pAd, 0x7000, &Value2); +#ifdef CONFIG_DELAY_INT + HIF_IO_READ32(pAd, MT_DELAY_INT_CFG, &Value); +#endif + + switch (TxRx) { + case PDMA_TX: + if (enable == TRUE) { + GloCfg.MT7615_field.EnableTxDMA = 1; + GloCfg.MT7615_field.EnTXWriteBackDDONE = 1; + GloCfg.MT7615_field.WPDMABurstSIZE = WPDMABurstSIZE; + GloCfg.MT7615_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2_PREFETCH; + Value1 |= (1 << 16); +#ifdef CONFIG_DELAY_INT + Value |= TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value |= TX_MAX_PINT(TX_PENDING_INT_NUMS); + Value &= ~TX_MAX_PTIME_MASK; + Value |= TX_MAX_PTIME(TX_PENDING_INT_TIME); +#endif + } else { + GloCfg.MT7615_field.EnableTxDMA = 0; + /* disable pdma pre-fetch */ + GloCfg.MT7615_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2; +#ifdef CONFIG_DELAY_INT + Value &= ~TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value &= ~TX_MAX_PTIME_MASK; +#endif + } + + Value2 &= ~BIT23; + break; + + case PDMA_RX: + if (enable == TRUE) { + GloCfg.MT7615_field.EnableRxDMA = 1; + GloCfg.MT7615_field.WPDMABurstSIZE = WPDMABurstSIZE; + GloCfg.MT7615_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2_PREFETCH; + Value1 |= (1 << 16); +#ifdef CONFIG_DELAY_INT + Value |= RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value |= RX_MAX_PINT(RX_PENDING_INT_NUMS); + Value &= ~RX_MAX_PTIME_MASK; + Value |= RX_MAX_PTIME(RX_PENDING_INT_TIME); +#endif + } else { + GloCfg.MT7615_field.EnableRxDMA = 0; + /* disable pdma pre-fetch */ + GloCfg.MT7615_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2; +#ifdef CONFIG_DELAY_INT + Value &= ~RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value &= ~RX_MAX_PTIME_MASK; +#endif + } + + Value2 &= ~BIT23; + break; + + case PDMA_TX_RX: + if (enable == TRUE) { + GloCfg.MT7615_field.EnableTxDMA = 1; + GloCfg.MT7615_field.EnableRxDMA = 1; + GloCfg.MT7615_field.EnTXWriteBackDDONE = 1; + GloCfg.MT7615_field.WPDMABurstSIZE = WPDMABurstSIZE; + GloCfg.MT7615_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2_PREFETCH; + + if (MTK_REV_GTE(pAd, MT7615, MT7615E3)) { + + +#ifdef CONFIG_RALINK_MT7621 + /* + * Tx Burst Size: three bits are used to specify + * 32DW, bit0:0, bit21:10 + */ + GloCfg.MT7615_E3_field.tx_bt_size_bit0 = 0; + GloCfg.MT7615_E3_field.tx_bt_size_bit21 = 2; +#else + + /* + * Tx Burst Size: three bits are used to specify + * 32DW, bit0:1, bit21:1 + */ + GloCfg.MT7615_E3_field.tx_bt_size_bit0 = 1; + GloCfg.MT7615_E3_field.tx_bt_size_bit21 = 1; +#endif + GloCfg.MT7615_E3_field.first_token_only = 1; + } + + Value1 |= (1 << 16); +#ifdef CONFIG_DELAY_INT + Value |= TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value |= TX_MAX_PINT(TX_PENDING_INT_NUMS); + Value &= ~TX_MAX_PTIME_MASK; + Value |= TX_MAX_PTIME(TX_PENDING_INT_TIME); + Value |= RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value |= RX_MAX_PINT(RX_PENDING_INT_NUMS); + Value &= ~RX_MAX_PTIME_MASK; + Value |= RX_MAX_PTIME(RX_PENDING_INT_TIME); +#endif + } else { + GloCfg.MT7615_field.EnableRxDMA = 0; + GloCfg.MT7615_field.EnableTxDMA = 0; + /* disable pdma pre-fetch */ + GloCfg.MT7615_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2; +#ifdef CONFIG_DELAY_INT + Value &= ~TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value &= ~TX_MAX_PTIME_MASK; + Value &= ~RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value &= ~RX_MAX_PTIME_MASK; +#endif + } + + Value2 &= ~BIT23; + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown path (%d\n", __func__, TxRx)); + break; + } + + HIF_IO_WRITE32(pAd, MT_WPDMA_GLO_CFG, GloCfg.word); + HW_IO_WRITE32(pAd, 0x7158, Value1); + HW_IO_WRITE32(pAd, 0x7000, Value2); +#ifdef CONFIG_DELAY_INT + HIF_IO_WRITE32(pAd, MT_DELAY_INT_CFG, Value); +#endif +#define WPDMA_DISABLE -1 + + if (!enable) + TxRx = WPDMA_DISABLE; + + WLAN_HOOK_CALL(WLAN_HOOK_DMA_SET, pAd, &TxRx); + return TRUE; +} + +static BOOLEAN hif_wait_WPDMA_idle(struct _RTMP_ADAPTER *pAd, INT round, INT wait_us) +{ + INT i = 0; + + WPDMA_GLO_CFG_STRUC GloCfg; + /* TODO: shiang-MT7615 */ + do { + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); + + if ((GloCfg.MT7615_field.TxDMABusy == 0) && (GloCfg.MT7615_field.RxDMABusy == 0)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_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); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("==> DMABusy\n")); + return FALSE; +} + +static BOOLEAN hif_reset_WPDMA(RTMP_ADAPTER *pAd) +{ + UINT32 value = 0; + + /* pdma0 hw reset (w/o dma scheduler) + activate: write 1 clear + scope: PDMA + PDMA: + logic reset: Y + register reset: N (but DMA_IDX will be reset to 0) + */ + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &value); + value |= SW_RST; + HIF_IO_WRITE32(pAd, MT_WPDMA_GLO_CFG, value); + + return TRUE; +} + +static INT32 get_fw_sync_value(RTMP_ADAPTER *pAd) +{ + UINT32 value; + + MAC_IO_READ32(pAd, TOP_MISC2, &value); + value = value & 0x00000007; + + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: current sync CR = 0x%x\n", __func__, value)); + return value; +} + +static VOID fw_own(RTMP_ADAPTER *pAd) +{ + if (MTK_REV_GTE(pAd, MT7615, MT7615E1) && MTK_REV_LT(pAd, MT7615, MT7615E3)) { + /* Write any value to HIF_FUN_CAP to set FW own */ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Write any value to HIF_FUN_CAP to set FW own\n", __func__)); + HIF_IO_WRITE32(pAd, HIF_FUN_CAP, 1); + pAd->bDrvOwn = FALSE; + } else { + if (pAd->bDrvOwn == FALSE) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s()::Return since already in Fw Own...\n", __func__)); + return; + } + + HIF_IO_WRITE32(pAd, MT_CFG_LPCR_HOST, MT_HOST_SET_OWN); + pAd->bDrvOwn = FALSE; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s()::Set Fw Own\n", __func__)); + } +} + +static VOID n9_wdt_reset(RTMP_ADAPTER *pAd) +{ +#define WDT_SWRST_CR_PA 0x81080044 +#define MCU_POWER_ON 0x01 +#define HOST_TRIGGER_WDT_SWRST 0x1209 + UINT32 top_clock_gen0_value = 0; + UINT32 top_clock_gen1_value = 0; + UINT32 top_misc_value = 0; + UINT32 origonal_remap_cr_value = 0; + UINT32 remap_cr_record_base_address = 0; + UINT32 offset_between_target_and_remap_cr_base = 0; + /* switch hclk to XTAL source, 0x80021100[1:0] = 2'b00 */ + HW_IO_READ32(pAd, TOP_CKGEN0, &top_clock_gen0_value); + top_clock_gen0_value &= ~(BIT0 | BIT1); + HW_IO_WRITE32(pAd, TOP_CKGEN0, top_clock_gen0_value); + /* Set HCLK divider to 1:1, 0x80021104[1:0] = 2'b00 */ + HW_IO_READ32(pAd, TOP_CKGEN1, &top_clock_gen1_value); + top_clock_gen1_value &= ~(BIT0 | BIT1); + HW_IO_WRITE32(pAd, TOP_CKGEN1, top_clock_gen1_value); + /* disable HIF can be reset by WDT 0x80021130[30]=1'b0 */ + HW_IO_READ32(pAd, TOP_MISC, &top_misc_value); + top_misc_value &= ~(BIT30); + HW_IO_WRITE32(pAd, TOP_MISC, top_misc_value); + /* enable WDT reset mode and trigger WDT reset 0x81080044 = 0x1209 */ + /* keep the origonal remap cr1 value for restore */ + HW_IO_READ32(pAd, MCU_PCIE_REMAP_1, &origonal_remap_cr_value); + /* do PCI-E remap for CR4 PDMA physical base address to 0x40000 */ + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_1, WDT_SWRST_CR_PA); + HW_IO_READ32(pAd, MCU_PCIE_REMAP_1, &remap_cr_record_base_address); + + if ((WDT_SWRST_CR_PA - remap_cr_record_base_address) > REMAP_1_OFFSET_MASK) { + /* restore the origonal remap cr1 value */ + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_1, origonal_remap_cr_value); + } + + offset_between_target_and_remap_cr_base = + ((WDT_SWRST_CR_PA - remap_cr_record_base_address) & REMAP_1_OFFSET_MASK); + RTMP_IO_WRITE32(pAd, MT_PCI_REMAP_ADDR_1 + offset_between_target_and_remap_cr_base, + HOST_TRIGGER_WDT_SWRST); + /* restore the origonal remap cr1 value */ + HW_IO_WRITE32(pAd, MCU_PCIE_REMAP_1, origonal_remap_cr_value); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s()::N9 WDT reset down\n", __func__)); +} + +static INT32 driver_own(RTMP_ADAPTER *pAd) +{ + INT32 Ret = NDIS_STATUS_SUCCESS; + UINT32 retrycnt = 0; +#define MAX_RETRY_CNT 4 + + if (MTK_REV_GTE(pAd, MT7615, MT7615E1) && MTK_REV_LT(pAd, MT7615, MT7615E3)) { + UINT32 Counter = 0; + /* Write any value to HIF_SYS_REV clear FW own */ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): Write any value to HIF_SYS_REV to clear FW own\n", __func__)); + HIF_IO_WRITE32(pAd, HIF_SYS_REV, 1); + + /* Poll driver own status */ + while (Counter < FW_OWN_POLLING_COUNTER) { + RtmpusecDelay(1000); + + if (pAd->bDrvOwn == TRUE) + break; + + Counter++; + }; + + if (pAd->bDrvOwn) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): Successed to clear FW own\n", __func__)); + else { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Fail to clear FW own (%d)\n", __func__, Counter)); + Ret = NDIS_STATUS_FAILURE; + } + } else { + UINT32 counter = 0; + UINT32 Value; + + do { + retrycnt++; + + if (pAd->bDrvOwn == TRUE) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s()::Return since already in Driver Own...\n", __func__)); + return Ret; + } + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s()::Try to Clear FW Own...\n", __func__)); + /* Write CR to get driver own */ + HIF_IO_WRITE32(pAd, MT_CFG_LPCR_HOST, MT_HOST_CLR_OWN); + /* Poll driver own status */ + counter = 0; + + while (counter < FW_OWN_POLLING_COUNTER) { + RtmpusecDelay(1000); + + if (pAd->bDrvOwn == TRUE) + break; + + counter++; + }; + + if (counter == FW_OWN_POLLING_COUNTER) { + HIF_IO_READ32(pAd, MT_CFG_LPCR_HOST, &Value); + + if (!(Value & MT_HOST_SET_OWN)) + pAd->bDrvOwn = TRUE; + } + + if (pAd->bDrvOwn) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s()::Success to clear FW Own\n", __func__)); + else { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s()::Fail to clear FW Own (%d)\n", __func__, counter)); + + if (retrycnt >= MAX_RETRY_CNT) + Ret = NDIS_STATUS_FAILURE; + else + n9_wdt_reset(pAd); + } + } while (pAd->bDrvOwn == FALSE && retrycnt < MAX_RETRY_CNT); + } + + return Ret; +} + +static struct dly_ctl_cfg mt7615_rx_dly_ctl_ul_tbl[] = { + {0, 0x811c}, + {300, 0xa01c}, + {550, 0xc01f}, +}; + +static struct dly_ctl_cfg mt7615_rx_dly_ctl_dl_tbl[] = { + {0, 0x811c}, +}; + +static RTMP_CHIP_OP MT7615_ChipOp = {0}; +static RTMP_CHIP_CAP MT7615_ChipCap = {0}; + + +static VOID mt7615_chipCap_init(RTMP_ADAPTER *pAd, BOOLEAN b11nOnly, BOOLEAN bThreeAnt) +{ + if (bThreeAnt) + MT7615_ChipCap.max_nss = 3; + else + MT7615_ChipCap.max_nss = 4; + +#ifdef DOT11_VHT_AC + MT7615_ChipCap.max_vht_mcs = VHT_MCS_CAP_9; +#ifdef G_BAND_256QAM + if (BOARD_IS_NO_256QAM(pAd)) + MT7615_ChipCap.g_band_256_qam = FALSE; + else + MT7615_ChipCap.g_band_256_qam = TRUE; + +#endif +#endif /* DOT11_VHT_AC */ + MT7615_ChipCap.TXWISize = sizeof(TMAC_TXD_L); /* 32 */ + MT7615_ChipCap.RXWISize = 28; + MT7615_ChipCap.num_of_tx_ring = 2; + MT7615_ChipCap.num_of_rx_ring = 2; + + MT7615_ChipCap.tx_ring_size = 1024; + MT7615_ChipCap.rx0_ring_size = 1024; + MT7615_ChipCap.rx1_ring_size = 512; + + MT7615_ChipCap.WtblHwNum = MT7615_MT_WTBL_SIZE; +#ifdef RTMP_MAC_PCI + MT7615_ChipCap.WPDMABurstSIZE = 3; +#endif + MT7615_ChipCap.SnrFormula = SNR_FORMULA4; + MT7615_ChipCap.FlgIsHwWapiSup = TRUE; + MT7615_ChipCap.FlgIsHwAntennaDiversitySup = FALSE; +#ifdef STREAM_MODE_SUPPORT + MT7615_ChipCap.FlgHwStreamMode = FALSE; +#endif +#ifdef TXBF_SUPPORT + MT7615_ChipCap.FlgHwTxBfCap = (TXBF_HW_CAP | TXBF_AID_HW_LIMIT); +#endif + MT7615_ChipCap.asic_caps = (fASIC_CAP_PMF_ENC | fASIC_CAP_MCS_LUT); + MT7615_ChipCap.asic_caps |= fASIC_CAP_HW_DAMSDU; +#ifdef HDR_TRANS_TX_SUPPORT + MT7615_ChipCap.asic_caps |= fASIC_CAP_TX_HDR_TRANS; +#endif /* HDR_TRANS_TX_SUPPORT */ +#ifdef HDR_TRANS_RX_SUPPORT + MT7615_ChipCap.asic_caps |= fASIC_CAP_RX_HDR_TRANS; +#endif /* HDR_TRANS_RX_SUPPORT */ + MT7615_ChipCap.asic_caps |= (fASIC_CAP_CT | fASIC_CAP_MCU_OFFLOAD); + MT7615_ChipCap.asic_caps |= fASIC_CAP_WMM_PKTDETECT_OFFLOAD; +#ifdef RX_SCATTER + + if (MTK_REV_GTE(pAd, MT7615, MT7615E3)) + MT7615_ChipCap.asic_caps |= fASIC_CAP_RX_DMA_SCATTER; + +#endif +#ifdef DBDC_MODE + MT7615_ChipCap.asic_caps |= fASIC_CAP_DBDC; +#endif /* DBDC_MODE */ + +#ifdef WHNAT_SUPPORT + MT7615_ChipCap.asic_caps |= fASIC_CAP_WHNAT; +#endif + + MT7615_ChipCap.asic_caps |= fASIC_CAP_RX_DLY; + +#if defined(WHNAT_SUPPORT) + MT7615_ChipCap.asic_caps &= ~fASIC_CAP_RX_DLY; +#endif + +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + MT7615_ChipCap.asic_caps |= fASIC_CAP_PCIE_ASPM_DYM_CTRL; +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ + + if (b11nOnly) { + MT7615_ChipCap.phy_caps = (fPHY_CAP_24G | fPHY_CAP_5G | \ + fPHY_CAP_HT | \ + fPHY_CAP_TXBF | fPHY_CAP_LDPC | \ + fPHY_CAP_BW40); + } else { + MT7615_ChipCap.phy_caps = (fPHY_CAP_24G | fPHY_CAP_5G | \ + fPHY_CAP_HT | fPHY_CAP_VHT | \ + fPHY_CAP_TXBF | fPHY_CAP_LDPC | fPHY_CAP_MUMIMO | \ + fPHY_CAP_BW40 | fPHY_CAP_BW80 | fPHY_CAP_BW160C | fPHY_CAP_BW160NC); + } + + MT7615_ChipCap.MaxNumOfRfId = MAX_RF_ID; + MT7615_ChipCap.pRFRegTable = NULL; + MT7615_ChipCap.MaxNumOfBbpId = 200; + MT7615_ChipCap.pBBPRegTable = NULL; + MT7615_ChipCap.bbpRegTbSize = 0; +#ifdef NEW_MBSSID_MODE +#ifdef ENHANCE_NEW_MBSSID_MODE + MT7615_ChipCap.MBSSIDMode = MBSSID_MODE4; +#else + MT7615_ChipCap.MBSSIDMode = MBSSID_MODE1; +#endif /* ENHANCE_NEW_MBSSID_MODE */ +#else + MT7615_ChipCap.MBSSIDMode = MBSSID_MODE0; +#endif /* NEW_MBSSID_MODE */ +#ifdef RTMP_EFUSE_SUPPORT + MT7615_ChipCap.EFUSE_USAGE_MAP_START = 0x3c0; + MT7615_ChipCap.EFUSE_USAGE_MAP_END = 0x3fb; + MT7615_ChipCap.EFUSE_USAGE_MAP_SIZE = 60; + MT7615_ChipCap.EFUSE_RESERVED_SIZE = 59; /* Cal-Free is 22 free block */ +#endif + MT7615_ChipCap.EEPROM_DEFAULT_BIN = mt7615_get_default_bin_image(pAd); + MT7615_ChipCap.EEPROM_DEFAULT_BIN_FILE = mt7615_get_default_bin_image_file(pAd); + MT7615_ChipCap.EEPROM_DEFAULT_BIN_SIZE = sizeof(MT7615_E2PImage1_ePAeLNA); + MT7615_ChipCap.EFUSE_BUFFER_CONTENT_SIZE = EFUSE_CONTENT_SIZE; +#ifdef CONFIG_ANDES_SUPPORT +#ifdef NEED_ROM_PATCH + MT7615_ChipCap.need_load_patch = BIT(WM_CPU); +#else + MT7615_ChipCap.need_load_patch = 0; +#endif /* NEED_ROM_PATCH */ + MT7615_ChipCap.need_load_fw = BIT(WM_CPU) | BIT(WA_CPU); + MT7615_ChipCap.load_patch_flow = PATCH_FLOW_V1; + MT7615_ChipCap.load_fw_flow = FW_FLOW_V1; + MT7615_ChipCap.load_patch_method = BIT(HEADER_METHOD); + MT7615_ChipCap.load_fw_method = BIT(HEADER_METHOD); + MT7615_ChipCap.patch_format = PATCH_FORMAT_V1; + MT7615_ChipCap.fw_format = FW_FORMAT_V2; + MT7615_ChipCap.rom_patch_offset = MT7615_ROM_PATCH_START_ADDRESS; +#endif + MT7615_ChipCap.MCUType = ANDES | CR4; + /* TODO: shiang-MT7615, fix me for this */ +#ifdef UNIFY_FW_CMD + MT7615_ChipCap.cmd_header_len = sizeof(FW_TXD) + sizeof(TMAC_TXD_L); +#else + MT7615_ChipCap.cmd_header_len = 12; /* sizeof(FW_TXD),*/ +#endif /* UNIFY_FW_CMD */ + MT7615_ChipCap.cmd_padding_len = 0; +#ifdef CARRIER_DETECTION_SUPPORT + MT7615_ChipCap.carrier_func = TONE_RADAR_V2; +#endif + MT7615_ChipCap.hw_ops_ver = HWCTRL_OP_TYPE_V1; + MT7615_ChipCap.hif_type = HIF_MT; + MT7615_ChipCap.mac_type = MAC_MT; + MT7615_ChipCap.rf_type = RF_MT; + MT7615_ChipCap.TxAggLimit = 64; + MT7615_ChipCap.RxBAWinSize = 64; + MT7615_ChipCap.max_amsdu_len = MPDU_7991_OCTETS; + MT7615_ChipCap.ht_max_ampdu_len_exp = 3; +#ifdef DOT11_VHT_AC + MT7615_ChipCap.max_mpdu_len = MPDU_11454_OCTETS; + MT7615_ChipCap.vht_max_ampdu_len_exp = 7; +#endif /* DOT11_VHT_AC */ + MT7615_ChipCap.default_txop = 0x60; + MT7615_ChipCap.CurrentTxOP = 0x0; +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + MT7615_ChipCap.fgRateAdaptFWOffload = TRUE; +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + /*for multi-wmm*/ + MT7615_ChipCap.WmmHwNum = MT7615_MT_WMM_SIZE; + MT7615_ChipCap.PDA_PORT = MT7615_PDA_PORT; + MT7615_ChipCap.SupportAMSDU = TRUE; + MT7615_ChipCap.APPSMode = APPS_MODE2; +#ifdef MT_WOW_SUPPORT + MT7615_ChipCap.nWakeupInterface = WOW_WAKEUP_BY_PCIE; +#endif /* MT_WOW_SUPPORT */ + MT7615_ChipCap.CtParseLen = MT7615_CT_PARSE_LEN; + MT7615_ChipCap.qm = FAST_PATH_QM; + MT7615_ChipCap.qm_tm = TASKLET_METHOD; + MT7615_ChipCap.hif_tm = TASKLET_METHOD; + MT7615_ChipCap.wmm_detect_method = WMM_DETECT_METHOD1; + /* for interrupt enable mask */ + + MT7615_ChipCap.int_enable_mask = MT_CoherentInt | MT_MacInt | MT_INT_RX_DLY | MT_INT_T2_DONE | + MT_INT_T3_DONE | MT_FW_CLR_OWN_INT; + +#if defined(WHNAT_SUPPORT) + MT7615_ChipCap.int_enable_mask = MT_CoherentInt | MT_MacInt | MT_INT_R0_DONE + | MT_INT_R1_DONE | MT_INT_T2_DONE | + MT_INT_T3_DONE | MT_FW_CLR_OWN_INT; +#endif + + MT7615_ChipCap.hif_pkt_type[HIF_TX_IDX0] = TX_DATA; + MT7615_ChipCap.hif_pkt_type[HIF_TX_IDX1] = TX_DATA; + MT7615_ChipCap.hif_pkt_type[HIF_TX_IDX2] = TX_CMD; + MT7615_ChipCap.hif_pkt_type[HIF_TX_IDX3] = TX_FW_DL; +#if defined(ERR_RECOVERY) || defined(CONFIG_FWOWN_SUPPORT) + MT7615_ChipCap.int_enable_mask |= MT_McuCommand; +#endif /* ERR_RECOVERY || CONFIG_FWOWN_SUPPORT */ + +#ifdef WIFI_SPECTRUM_SUPPORT + MT7615_ChipCap.pSpectrumDesc = MT7615_SPECTRUM_DESC; + MT7615_ChipCap.SpectrumBankNum = MT7615_SpectrumBankNum; + MT7615_ChipCap.SpectrumWF0ADC = MT7615_CAP_WF0_ADC; + MT7615_ChipCap.SpectrumWF1ADC = MT7615_CAP_WF1_ADC; + MT7615_ChipCap.SpectrumWF2ADC = MT7615_CAP_WF2_ADC; + MT7615_ChipCap.SpectrumWF3ADC = MT7615_CAP_WF3_ADC; + MT7615_ChipCap.SpectrumWF0FIIQ = MT7615_CAP_WF0_FIIQ; + MT7615_ChipCap.SpectrumWF1FIIQ = MT7615_CAP_WF1_FIIQ; + MT7615_ChipCap.SpectrumWF2FIIQ = MT7615_CAP_WF2_FIIQ; + MT7615_ChipCap.SpectrumWF3FIIQ = MT7615_CAP_WF3_FIIQ; + MT7615_ChipCap.SpectrumWF0FDIQ = MT7615_CAP_WF0_FDIQ; + MT7615_ChipCap.SpectrumWF1FDIQ = MT7615_CAP_WF1_FDIQ; + MT7615_ChipCap.SpectrumWF2FDIQ = MT7615_CAP_WF2_FDIQ; + MT7615_ChipCap.SpectrumWF3FDIQ = MT7615_CAP_WF3_FDIQ; +#endif /* WIFI_SPECTRUM_SUPPORT */ + MT7615_ChipCap.band_cnt = 2; + MT7615_ChipCap.txd_type = TXD_V1; + MT7615_ChipCap.ba_range = mt7615_ba_range; + MT7615_ChipCap.tx_delay_support = FALSE; +} + + +static VOID mt7615_chipOp_init(void) +{ + MT7615_ChipOp.ChipBBPAdjust = mt7615_bbp_adjust; + MT7615_ChipOp.ChipSwitchChannel = mt7615_switch_channel; +#ifdef NEW_SET_RX_STREAM + MT7615_ChipOp.ChipSetRxStream = mt7615_set_RxStream; +#endif + MT7615_ChipOp.AsicMacInit = mt7615_init_mac_cr; + MT7615_ChipOp.AsicBbpInit = MT7615BBPInit; + MT7615_ChipOp.AsicRfInit = mt7615_init_rf_cr; + MT7615_ChipOp.AsicAntennaDefaultReset = mt7615_antenna_default_reset; + MT7615_ChipOp.AsicHaltAction = NULL; + MT7615_ChipOp.AsicReverseRfFromSleepMode = NULL; +#ifdef CARRIER_DETECTION_SUPPORT + MT7615_ChipOp.ToneRadarProgram = ToneRadarProgram_v2; +#endif + MT7615_ChipOp.DisableTxRx = NULL; +#ifdef RTMP_PCI_SUPPORT + /* MT7615_ChipOp.AsicRadioOn = RT28xxPciAsicRadioOn; */ + /* MT7615_ChipOp.AsicRadioOff = RT28xxPciAsicRadioOff; */ +#endif + MT7615_ChipOp.show_pwr_info = NULL; +#ifdef CAL_FREE_IC_SUPPORT + MT7615_ChipOp.is_cal_free_ic = mt7615_is_cal_free_ic; + MT7615_ChipOp.cal_free_data_get = mt7615_cal_free_data_get; + MT7615_ChipOp.check_is_cal_free_merge = mt7615_check_is_cal_free_merge; +#endif /* CAL_FREE_IC_SUPPORT */ +#ifdef RF_LOCKDOWN + MT7615_ChipOp.check_RF_lock_down = mt7615_check_RF_lock_down; + MT7615_ChipOp.write_RF_lock_parameter = mt7615_write_RF_lock_parameter; + MT7615_ChipOp.merge_RF_lock_parameter = mt7615_merge_RF_lock_parameter; + MT7615_ChipOp.Read_Effuse_parameter = mt7615_Read_Effuse_parameter; + MT7615_ChipOp.Config_Effuse_Country = mt7615_Config_Effuse_Country; +#endif /* RF_LOCKDOWN */ +#ifdef MT_WOW_SUPPORT + MT7615_ChipOp.AsicWOWEnable = MT76xxAndesWOWEnable; + MT7615_ChipOp.AsicWOWDisable = MT76xxAndesWOWDisable; + /* MT7615_ChipOp.AsicWOWInit = MT76xxAndesWOWInit, */ +#endif /* MT_WOW_SUPPORT */ + MT7615_ChipOp.MtCmdTx = MtCmdSendMsg; + MT7615_ChipOp.prepare_fwdl_img = mt7615_fw_prepare; + MT7615_ChipOp.fwdl_datapath_setup = mt7615_fwdl_datapath_setup; +#ifdef DBDC_MODE + MT7615_ChipOp.BandGetByIdx = MT7615BandGetByIdx; +#endif +#ifdef TXBF_SUPPORT + MT7615_ChipOp.ClientSupportsETxBF = mt_WrapClientSupportsETxBF; + MT7615_ChipOp.iBFPhaseComp = mt7615_iBFPhaseComp; + MT7615_ChipOp.iBFPhaseCalInit = mt7615_iBFPhaseCalInit; + MT7615_ChipOp.iBFPhaseFreeMem = mt7615_iBFPhaseFreeMem; + MT7615_ChipOp.iBFPhaseCalE2PUpdate = mt7615_iBFPhaseCalE2PUpdate; + MT7615_ChipOp.iBFPhaseCalReport = mt7615_iBFPhaseCalReport; +#ifdef VHT_TXBF_SUPPORT + MT7615_ChipOp.ClientSupportsVhtETxBF = mt_WrapClientSupportsVhtETxBF; +#endif + MT7615_ChipOp.TxBFInit = mt_WrapTxBFInit; + MT7615_ChipOp.setETxBFCap = mt7615_setETxBFCap; + MT7615_ChipOp.BfStaRecUpdate = mt_AsicBfStaRecUpdate; + MT7615_ChipOp.BfStaRecRelease = mt_AsicBfStaRecRelease; + MT7615_ChipOp.BfPfmuMemAlloc = CmdPfmuMemAlloc; + MT7615_ChipOp.TxBfTxApplyCtrl = CmdTxBfTxApplyCtrl; + MT7615_ChipOp.BfApClientCluster = CmdTxBfApClientCluster; + MT7615_ChipOp.BfReptClonedStaToNormalSta = CmdTxBfReptClonedStaToNormalSta; + MT7615_ChipOp.BfPfmuMemRelease = CmdPfmuMemRelease; + MT7615_ChipOp.BfHwEnStatusUpdate = CmdTxBfHwEnableStatusUpdate; + MT7615_ChipOp.BfModuleEnCtrl = CmdTxBfModuleEnCtrl; + MT7615_ChipOp.BfeeHwCtrl = CmdTxBfeeHwCtrl; +#ifdef VHT_TXBF_SUPPORT + MT7615_ChipOp.ClientSupportsVhtETxBF = mt_WrapClientSupportsVhtETxBF; + MT7615_ChipOp.setVHTETxBFCap = mt7615_setVHTETxBFCap; +#endif /* VHT_TXBF_SUPPORT */ +#endif /* TXBF_SUPPORT */ + MT7615_ChipOp.bufferModeEfuseFill = mt7615_bufferModeEfuseFill; +#ifdef SMART_CARRIER_SENSE_SUPPORT + MT7615_ChipOp.SmartCarrierSense = mt7615_SmartCarrierSense; + MT7615_ChipOp.ChipSetSCS = mt7615_SetSCS; +#endif /* SMART_CARRIER_SENSE_SUPPORT */ +#ifdef GREENAP_SUPPORT + MT7615_ChipOp.EnableAPMIMOPS = enable_greenap; + MT7615_ChipOp.DisableAPMIMOPS = disable_greenap; +#endif /* GREENAP_SUPPORT */ +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + MT7615_ChipOp.pcie_aspm_dym_ctrl = rtmp_pcie_aspm_dym_ctrl; +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ + MT7615_ChipOp.heart_beat_check = mt7615_heart_beat_check; +#ifdef INTERNAL_CAPTURE_SUPPORT + MT7615_ChipOp.ICapStart = MtCmdRfTestICapStart; + MT7615_ChipOp.ICapStatus = MtCmdRfTestGen1ICapStatus; +#endif /* INTERNAL_CAPTURE_SUPPORT */ +#ifdef WIFI_SPECTRUM_SUPPORT + MT7615_ChipOp.SpectrumStart = MtCmdWifiSpectrumStart; + MT7615_ChipOp.SpectrumStatus = MtCmdWifiSpectrumGen1Status; + MT7615_ChipOp.SpectrumCmdRawDataProc = MtCmdWifiSpectrumRawDataProc; + MT7615_ChipOp.SpectrumEventRawDataHandler = ExtEventWifiSpectrumRawDataHandler; +#endif /* WIFI_SPECTRUM_SUPPORT */ + +#ifdef CONFIG_RALINK_MT7621 + MT7615_ChipOp.hif_set_pcie_read_params = + mt7615_hif_set_pcie_read_params; +#endif /* CONFIG_RALINK_MT7621*/ + MT7615_ChipOp.hif_set_dma = hif_set_WPDMA; + MT7615_ChipOp.hif_wait_dma_idle = hif_wait_WPDMA_idle; + MT7615_ChipOp.hif_reset_dma = hif_reset_WPDMA; + MT7615_ChipOp.get_fw_sync_value = get_fw_sync_value; + MT7615_ChipOp.read_chl_pwr = NULL; + MT7615_ChipOp.parse_RXV_packet = parse_RXV_packet_v2; + MT7615_ChipOp.txs_handler = txs_handler_v2; + MT7615_ChipOp.driver_own = driver_own; + MT7615_ChipOp.fw_own = fw_own; +} + + +VOID mt7615_init(RTMP_ADAPTER *pAd) +{ + struct _RTMP_CHIP_CAP *pChipCap = hc_get_chip_cap(pAd->hdev_ctrl); + struct _RTMP_CHIP_DBG *chip_dbg = hc_get_chip_dbg(pAd->hdev_ctrl); + struct tr_delay_control *tr_delay_ctl = &pAd->tr_ctl.tr_delay_ctl; + UINT32 Value; + BOOLEAN b11nOnly = FALSE, bThreeAnt = FALSE; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s()-->\n", __func__)); + RTMP_IO_READ32(pAd, STRAP_STA, &Value); + + if (GET_THREE_ANT(Value)) { + bThreeAnt = TRUE; + + if (GET_11N_ONLY(Value)) + b11nOnly = TRUE; + } + + mt7615_chipCap_init(pAd, b11nOnly, bThreeAnt); + mt7615_chipOp_init(); + NdisMoveMemory(pChipCap, &MT7615_ChipCap, sizeof(RTMP_CHIP_CAP)); + hc_register_chip_ops(pAd->hdev_ctrl, &MT7615_ChipOp); + pChipCap->hif_type = HIF_MT; +#if defined(COMPOS_WIN) || defined(COMPOS_TESTMODE_WIN) +#else + Mt7615AsicArchOpsInit(pAd); +#endif + mt7615_chip_dbg_init(chip_dbg); + mt_phy_probe(pAd); + /* TODO: shiang-MT7615, debug for firmware download!! */ + pChipCap->tx_hw_hdr_len = pChipCap->TXWISize; + pChipCap->rx_hw_hdr_len = pChipCap->RXWISize; + + RTMP_DRS_ALG_INIT(pAd, RATE_ALG_AGBS); + /* + Following function configure beacon related parameters + in pChipCap + FlgIsSupSpecBcnBuf / BcnMaxHwNum / + WcidHwRsvNum / BcnMaxHwSize / BcnBase[] + */ + mt_chip_bcn_parameter_init(pAd); + pChipCap->OmacNums = 5; + pChipCap->BssNums = 4; + pChipCap->ExtMbssOmacStartIdx = 0x10; + pChipCap->RepeaterStartIdx = 0x20; +#ifdef AIR_MONITOR + pChipCap->MaxRepeaterNum = 16; +#else + pChipCap->MaxRepeaterNum = 32; +#endif /* AIR_MONITOR */ +#ifdef BCN_OFFLOAD_SUPPORT + pChipCap->fgBcnOffloadSupport = TRUE; + pChipCap->fgIsNeedPretbttIntEvent = FALSE; +#endif + + if (MTK_REV_GTE(pAd, MT7615, MT7615E3)) + pChipCap->TmrHwVer = TMR_VER_1_5; + else + pChipCap->TmrHwVer = TMR_VER_1_0; + +#ifdef DOT11W_PMF_SUPPORT + pChipCap->FlgPMFEncrtptMode = PMF_ENCRYPT_MODE_2; +#endif /* DOT11W_PMF_SUPPORT */ + /* For calibration log buffer size limitation issue */ + pAd->fgQAtoolBatchDumpSupport = TRUE; +#ifdef RED_SUPPORT + pAd->red_have_cr4 = TRUE; +#endif /* RED_SUPPORT */ + pAd->cp_have_cr4 = TRUE; +#ifdef CONFIG_AP_SUPPORT + /*VOW CR Address offset - Gen_1*/ + pAd->vow_gen.VOW_GEN = VOW_GEN_1; +#endif/* CONFIG_AP_SUPPORT */ + + if (IS_ASIC_CAP(pAd, fASIC_CAP_RX_DLY)) { + tr_delay_ctl->ul_rx_dly_ctl_tbl = mt7615_rx_dly_ctl_ul_tbl; + tr_delay_ctl->ul_rx_dly_ctl_tbl_size = (sizeof(mt7615_rx_dly_ctl_ul_tbl) / sizeof(mt7615_rx_dly_ctl_ul_tbl[0])); + tr_delay_ctl->dl_rx_dly_ctl_tbl = mt7615_rx_dly_ctl_dl_tbl; + tr_delay_ctl->dl_rx_dly_ctl_tbl_size = (sizeof(mt7615_rx_dly_ctl_dl_tbl) / sizeof(mt7615_rx_dly_ctl_dl_tbl[0])); + } + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<--%s()\n", __func__)); +} + +#if defined(COMPOS_WIN) || defined(COMPOS_TESTMODE_WIN) +#else +INT Mt7615AsicArchOpsInit(RTMP_ADAPTER *pAd) +{ + RTMP_ARCH_OP *arch_ops = &pAd->archOps; + arch_ops->archGetCrcErrCnt = MtAsicGetCrcErrCnt; + arch_ops->archGetCCACnt = MtAsicGetCCACnt; + arch_ops->archGetChBusyCnt = MtAsicGetChBusyCnt; + arch_ops->archSetAutoFallBack = MtAsicSetAutoFallBack; + arch_ops->archAutoFallbackInit = MtAsicAutoFallbackInit; + arch_ops->archUpdateProtect = MtAsicUpdateProtectByFw; + arch_ops->archUpdateRtsThld = MtAsicUpdateRtsThldByFw; + arch_ops->archSwitchChannel = MtAsicSwitchChannel; + arch_ops->asic_rts_on_off = mt_asic_rts_on_off; + arch_ops->asic_ampdu_efficiency_on_off = MtAsicAMPDUEfficiencyAdjust; + arch_ops->archResetBBPAgent = MtAsicResetBBPAgent; + arch_ops->archSetDevMac = MtAsicSetDevMacByFw; + arch_ops->archSetBssid = MtAsicSetBssidByFw; + arch_ops->archSetStaRec = MtAsicSetStaRecByFw; + arch_ops->archUpdateStaRecBa = MtAsicUpdateStaRecBaByFw; +#ifdef CONFIG_AP_SUPPORT + arch_ops->archSetMbssMode = MtAsicSetMbssMode; +#endif /* CONFIG_AP_SUPPORT */ + arch_ops->archDelWcidTab = MtAsicDelWcidTabByFw; +#ifdef HTC_DECRYPT_IOT + arch_ops->archSetWcidAAD_OM = MtAsicSetWcidAAD_OMByFw; +#endif /* HTC_DECRYPT_IOT */ + arch_ops->archAddRemoveKeyTab = MtAsicAddRemoveKeyTabByFw; +#ifdef BCN_OFFLOAD_SUPPORT + arch_ops->archEnableBeacon = NULL; + arch_ops->archDisableBeacon = NULL; + arch_ops->archUpdateBeacon = MtUpdateBcnAndTimToMcu; +#else + arch_ops->archEnableBeacon = MtDmacAsicEnableBeacon; + arch_ops->archDisableBeacon = MtDmacAsicDisableBeacon; + arch_ops->archUpdateBeacon = MtUpdateBeaconToAsic; +#endif +#ifdef APCLI_SUPPORT +#ifdef MAC_REPEATER_SUPPORT + arch_ops->archSetReptFuncEnable = MtAsicSetReptFuncEnableByFw; + arch_ops->archInsertRepeaterEntry = MtAsicInsertRepeaterEntryByFw; + arch_ops->archRemoveRepeaterEntry = MtAsicRemoveRepeaterEntryByFw; + arch_ops->archInsertRepeaterRootEntry = MtAsicInsertRepeaterRootEntryByFw; +#endif /* MAC_REPEATER_SUPPORT */ +#endif /* APCLI_SUPPORT */ +#ifdef DOT11_N_SUPPORT + arch_ops->archSetRDG = NULL; +#endif /* DOT11_N_SUPPORT */ + arch_ops->archSetPiggyBack = MtAsicSetPiggyBack; + arch_ops->archSetPreTbtt = NULL;/* offload to BssInfoUpdateByFw */ + arch_ops->archSetGPTimer = MtAsicSetGPTimer; + arch_ops->archSetChBusyStat = MtAsicSetChBusyStat; + arch_ops->archGetTsfTime = MtAsicGetTsfTimeByFirmware; + arch_ops->archDisableSync = NULL;/* MtAsicDisableSyncByDriver; */ + arch_ops->archSetSyncModeAndEnable = NULL;/* MtAsicEnableBssSyncByDriver; */ + arch_ops->archSetWmmParam = MtAsicSetWmmParam; + arch_ops->archGetWmmParam = MtAsicGetWmmParam; + arch_ops->archSetEdcaParm = MtAsicSetEdcaParm; + arch_ops->archSetRetryLimit = MtAsicSetRetryLimit; + arch_ops->archGetRetryLimit = MtAsicGetRetryLimit; + arch_ops->archSetSlotTime = MtAsicSetSlotTime; + arch_ops->archGetTxTsc = MtAsicGetTxTscByDriver; + arch_ops->archAddSharedKeyEntry = MtAsicAddSharedKeyEntry; + arch_ops->archRemoveSharedKeyEntry = MtAsicRemoveSharedKeyEntry; + arch_ops->archAddPairwiseKeyEntry = MtAsicAddPairwiseKeyEntry; + arch_ops->archSetBW = MtAsicSetBW; + arch_ops->archSetCtrlCh = mt_mac_set_ctrlch; + arch_ops->archWaitMacTxRxIdle = MtAsicWaitMacTxRxIdle; +#ifdef MAC_INIT_OFFLOAD + arch_ops->archSetMacTxRx = MtAsicSetMacTxRxByFw; + arch_ops->archSetRxvFilter = MtAsicSetRxvFilter; +#else + arch_ops->archSetMacTxRx = MtAsicSetMacTxRx; +#endif /*MAC_INIT_OFFLOAD*/ + arch_ops->archSetMacWD = MtAsicSetMacWD; +#ifdef MAC_APCLI_SUPPORT + arch_ops->archSetApCliBssid = MtAsicSetApCliBssid; +#endif /* MAC_APCLI_SUPPORT */ + arch_ops->archTOPInit = MtAsicTOPInit; + arch_ops->archSetTmrCR = MtSetTmrCRByFw; +#ifdef CONFIG_AP_SUPPORT + /* TODO: Fix me */ + arch_ops->archSetMbssWdevIfAddr = MtAsicSetMbssWdevIfAddrGen2; + arch_ops->archSetMbssHwCRSetting = MtDmacSetMbssHwCRSetting; + arch_ops->archSetExtTTTTHwCRSetting = MtDmacSetExtTTTTHwCRSetting; + arch_ops->archSetExtMbssEnableCR = MtDmacSetExtMbssEnableCR; +#endif /* CONFIG_AP_SUPPORT */ +#ifdef DBDC_MODE + arch_ops->archSetDbdcCtrl = MtAsicSetDbdcCtrlByFw; + arch_ops->archGetDbdcCtrl = MtAsicGetDbdcCtrlByFw; +#endif /*DBDC_MODE*/ + arch_ops->archUpdateRxWCIDTable = MtAsicUpdateRxWCIDTableByFw; +#ifdef TXBF_SUPPORT + arch_ops->archUpdateClientBfCap = mt_AsicClientBfCap; +#endif /* TXBF_SUPPORT */ + arch_ops->archUpdateBASession = MtAsicUpdateBASessionByFw; + arch_ops->archGetTidSn = MtAsicGetTidSnByDriver; + arch_ops->archSetSMPS = MtAsicSetSMPSByFw; + arch_ops->archRxHeaderTransCtl = MtAsicRxHeaderTransCtl; + arch_ops->archRxHeaderTaranBLCtl = MtAsicRxHeaderTaranBLCtl; + arch_ops->rx_pkt_process = mt_rx_pkt_process; +#ifdef MAC_INIT_OFFLOAD + arch_ops->archSetMacMaxLen = NULL; +#else + arch_ops->archSetMacMaxLen = MtAsicSetMacMaxLen; +#endif +#ifdef MAC_INIT_OFFLOAD + arch_ops->archSetTxStream = NULL; +#else + arch_ops->archSetTxStream = MtAsicSetTxStream; +#endif + arch_ops->archSetRxStream = NULL;/* MtAsicSetRxStream; */ +#ifdef MAC_INIT_OFFLOAD + arch_ops->archSetRxFilter = NULL;/* MtAsicSetRxFilter; */ +#else + arch_ops->archSetRxFilter = MtAsicSetRxFilter; +#endif +#ifdef DOT11_VHT_AC + arch_ops->archSetRtsSignalTA = MtAsicSetRtsSignalTA; +#endif /* DOT11_VHT_AC */ +#ifdef IGMP_SNOOP_SUPPORT + arch_ops->archMcastEntryInsert = CmdMcastEntryInsert; + arch_ops->archMcastEntryDelete = CmdMcastEntryDelete; +#endif + arch_ops->write_txp_info = mtd_write_txp_info_by_cr4; + arch_ops->write_tmac_info_fixed_rate = mtd_write_tmac_info_fixed_rate; + arch_ops->write_tmac_info = mtd_write_tmac_info; + arch_ops->write_tx_resource = mtd_pci_write_tx_resource; + arch_ops->write_frag_tx_resource = mt_pci_write_frag_tx_resource; + arch_ops->kickout_data_tx = pci_kickout_data_tx; + + arch_ops->get_pkt_from_rx_resource = mtd_pci_get_pkt_from_rx_resource; + + if (IS_ASIC_CAP(pAd, fASIC_CAP_WHNAT)) + arch_ops->get_pkt_from_rx1_resource = mtd_pci_get_pkt_from_rx_resource_io; + else + arch_ops->get_pkt_from_rx1_resource = mtd_pci_get_pkt_from_rx_resource; + + arch_ops->get_resource_idx = HcGetTxRingIdx; + arch_ops->get_tx_resource_free_num = pci_get_tx_resource_free_num; + arch_ops->check_hw_resource = mtd_check_hw_resource; + arch_ops->inc_resource_full_cnt = pci_inc_resource_full_cnt; + arch_ops->get_resource_state = pci_get_resource_state; + arch_ops->set_resource_state = pci_set_resource_state; + arch_ops->check_resource_state = pci_check_resource_state; + arch_ops->get_hif_buf = mt_pci_get_hif_buf; + arch_ops->hw_tx = mtd_hw_tx; + arch_ops->mlme_hw_tx = mtd_mlme_hw_tx; +#ifdef CONFIG_ATE + arch_ops->ate_hw_tx = mtd_ate_hw_tx; +#endif + arch_ops->rx_done_handle = mtd_rx_done_handle; + arch_ops->tx_dma_done_handle = mtd_tx_dma_done_handle; + arch_ops->cmd_dma_done_handle = mt_cmd_dma_done_handle; + arch_ops->fwdl_dma_done_handle = mt_fwdl_dma_done_handle; + + if (IS_ASIC_CAP(pAd, fASIC_CAP_RX_DLY)) + arch_ops->hw_isr = mtd_isr; + else + arch_ops->hw_isr = mtd_non_rx_delay_isr; + + return TRUE; +} +#endif + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7615_dbg.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7615_dbg.c new file mode 100644 index 000000000..c6223ba82 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7615_dbg.c @@ -0,0 +1,1147 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** +*/ + +#include "rt_config.h" +#include "chip/mt7615_cr.h" +#include "hdev/hdev.h" + +static INT pse_pg_cnt[] = {256, 512, 512, 1024, 768, 1536, 1024, 2048, 1280, 2560, 1536, 3072, 1792, 3584, 0, 0}; +static INT ple_pg_cnt[] = {512, 1024, 1024, 2048, 1536, 3072, 2048, 4095, 0}; +static EMPTY_QUEUE_INFO_T Queue_Empty_info[] = { + {"CPU Q0", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, /* 4~15 not defined */ + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0}, /* Q16 */ + {"BMC Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_0}, + {"BCN Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_0}, + {"PSMP Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0}, + {"ALTX Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1}, + {"BMC Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_1}, + {"BCN Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_1}, + {"PSMP Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, /* 24~29 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1E}, + {"RLS2 Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} +}; +static PCHAR sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"}; + +static INT32 chip_dump_ps_table(struct hdev_ctrl *ctrl, UINT32 ent_type, BOOLEAN bReptCli) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + int i; + UINT32 ps_stat[4] = {0}; + UINT32 regValue = 0; + UINT8 bmc_cnt[4] = {0}; + UINT8 ext_bmc_cnt[15] = {0}; + + HW_IO_READ32(pAd, PLE_STATION_PAUSE0, &ps_stat[0]); + HW_IO_READ32(pAd, PLE_STATION_PAUSE1, &ps_stat[1]); + HW_IO_READ32(pAd, PLE_STATION_PAUSE2, &ps_stat[2]); + HW_IO_READ32(pAd, PLE_STATION_PAUSE3, &ps_stat[3]); + HW_IO_READ32(pAd, ARB_BMCCR0, ®Value); + bmc_cnt[0] = regValue & 0xff; + bmc_cnt[1] = (regValue & 0xff00) >> 8; + bmc_cnt[2] = (regValue & 0xff0000) >> 16; + bmc_cnt[3] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR1, ®Value); + ext_bmc_cnt[0] = regValue & 0xff; + ext_bmc_cnt[1] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[2] = (regValue & 0xff0000) >> 16; + ext_bmc_cnt[3] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR2, ®Value); + ext_bmc_cnt[4] = regValue & 0xff; + ext_bmc_cnt[5] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[6] = (regValue & 0xff0000) >> 16; + ext_bmc_cnt[7] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR3, ®Value); + ext_bmc_cnt[8] = regValue & 0xff; + ext_bmc_cnt[9] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[10] = (regValue & 0xff0000) >> 16; + ext_bmc_cnt[11] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR4, ®Value); + ext_bmc_cnt[12] = regValue & 0xff; + ext_bmc_cnt[13] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[14] = (regValue & 0xff0000) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PS_info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%08x %08x %08x %08x\n", ps_stat[0], ps_stat[1], ps_stat[2], + ps_stat[3])); + + for (i = 0; i < 4; i++) { + if (bmc_cnt[i]) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BMC(%x)%d ", i, bmc_cnt[i])); + } + + for (i = 0; i < 15; i++) { + if (ext_bmc_cnt[i]) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BMC(%x)%d ", i + 0x11, ext_bmc_cnt[i])); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n\n")); + /* Dump PS info from FW */ + CmdExtGeneralTestAPPWS(pAd, APPWS_ACTION_DUMP_INFO); + return TRUE; +} + +static INT32 chip_show_tmac_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 Value; + RTMP_ADAPTER *pAd = ctrl->priv; + + RTMP_IO_READ32(pAd, TMAC_TCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TX Stream = %d\n", GET_TMAC_TCR_TX_STREAM_NUM(Value) + 1)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TX RIFS Enable = %d\n", GET_TX_RIFS_EN(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RX RIFS Mode = %d\n", GET_RX_RIFS_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TXOP TBTT Control = %d\n", GET_TXOP_TBTT_CONTROL(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TXOP TBTT Stop Control = %d\n", GET_TBTT_TX_STOP_CONTROL(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TXOP Burst Stop = %d\n", GET_TXOP_BURST_STOP(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RDG Mode = %d\n", GET_RDG_RA_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RDG Responser Enable = %d\n", GET_RDG_RESP_EN(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Smoothing = %d\n", GET_SMOOTHING(Value))); + RTMP_IO_READ32(pAd, TMAC_PSCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Save RXPE Off Time(unit 2us) = %d\n", + GET_APS_OFF_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Save RXPE On Time(unit 2us) = %d\n", APS_ON_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Save Halt Time (unit 32us) = %d\n", + GET_APS_HALT_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Enable = %d\n", GET_APS_EN(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC0 TXOP = 0x%x (unit: 32us)\n", GET_AC0LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC1 TXOP = 0x%x (unit: 32us)\n", GET_AC1LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC2 TXOP = 0x%x (unit: 32us)\n", GET_AC2LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC3 TXOP = 0x%x (unit: 32us)\n", GET_AC3LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR3, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC10 TXOP = 0x%x (unit: 32us)\n", GET_AC10LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC11 TXOP = 0x%x (unit: 32us)\n", GET_AC11LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR2, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC12 TXOP = 0x%x (unit: 32us)\n", GET_AC12LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC13 TXOP = 0x%x (unit: 32us)\n", GET_AC13LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ICR_BAND_0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("EIFS Time, Band0 (unit: 1us) = %d\n", GET_ICR_EIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RIFS Time, Band0 (unit: 1us) = %d\n", GET_ICR_RIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SIFS Time, Band0 (unit: 1us) = %d\n", GET_ICR_SIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SLOT Time, Band0 (unit: 1us) = %d\n", GET_ICR_SLOT_TIME(Value))); + RTMP_IO_READ32(pAd, TMAC_ICR_BAND_1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("EIFS Time, Band1 (unit: 1us) = %d\n", GET_ICR_EIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RIFS Time, Band1 (unit: 1us) = %d\n", GET_ICR_RIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SIFS Time, Band1 (unit: 1us) = %d\n", GET_ICR_SIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SLOT Time, Band1 (unit: 1us) = %d\n", GET_ICR_SLOT_TIME(Value))); + RTMP_IO_READ32(pAd, TMAC_ATCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Aggregation Timeout (unit: 50ns) = 0x%x\n", GET_AGG_TOUT(Value))); + return 0; +} + +static INT32 chip_show_agg_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 Value; + RTMP_ADAPTER *pAd = ctrl->priv; + + RTMP_IO_READ32(pAd, AGG_PCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MM Protection = %d\n", GET_MM_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("GF Protection = %d\n", GET_GF_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Protection Mode = %d\n", GET_PROTECTION_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BW40 Protection = %d\n", GET_BW40_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RIFS Protection = %d\n", GET_RIFS_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BW80 Protection = %d\n", GET_BW80_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BW160 Protection = %d\n", GET_BW160_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ERP Protection = 0x%x\n", GET_ERP_PROTECTION(Value))); + RTMP_IO_READ32(pAd, AGG_PCR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RTS Threshold(packet length) = 0x%x\n", GET_RTS_THRESHOLD(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RTS PKT Nums Threshold = %d\n", GET_RTS_PKT_NUM_THRESHOLD(Value))); + RTMP_IO_READ32(pAd, AGG_MRCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RTS Retry Count Limit = %d\n", GET_RTS_RTY_CNT_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Frame Tx Count Limit = %d\n", GET_BAR_TX_CNT_LIMIT(Value))); + RTMP_IO_READ32(pAd, AGG_ACR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AMPDU No BA Rule = %d\n", GET_AMPDU_NO_BA_RULE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AMPDU No BA AR Rule = %d\n", + GET_AGG_ACR_AMPDU_NO_BA_AR_RULE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Tx Rate = 0x%x\n", GET_BAR_RATE_TX_RATE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Tx Mode = 0x%x\n", GET_BAR_RATE_TX_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Nsts = %d\n", GET_BAR_RATE_NSTS(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR STBC = %d\n", GET_BAR_RATE_STBC(Value))); + RTMP_IO_READ32(pAd, AGG_AALCR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC0 Agg limit = %d\n", GET_AC0_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC1 Agg limit = %d\n", GET_AC1_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC2 Agg limit = %d\n", GET_AC2_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC3 Agg limit = %d\n", GET_AC3_AGG_LIMIT(Value))); + RTMP_IO_READ32(pAd, AGG_AALCR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC10 Agg limit = %d\n", GET_AC10_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC11 Agg limit = %d\n", GET_AC11_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC12 Agg limit = %d\n", GET_AC12_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC13 Agg limit = %d\n", GET_AC13_AGG_LIMIT(Value))); + RTMP_IO_READ32(pAd, AGG_AWSCR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize0 limit = %d\n", GET_WINSIZE0(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize1 limit = %d\n", GET_WINSIZE1(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize2 limit = %d\n", GET_WINSIZE2(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize3 limit = %d\n", GET_WINSIZE3(Value))); + RTMP_IO_READ32(pAd, AGG_AWSCR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize4 limit = %d\n", GET_WINSIZE4(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize5 limit = %d\n", GET_WINSIZE5(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize6 limit = %d\n", GET_WINSIZE6(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize7 limit = %d\n", GET_WINSIZE7(Value))); + return 0; +} + +static INT32 chip_dump_mib_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + RTMP_CHIP_CAP *pChipCap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 bss_nums = pChipCap->BssNums; + UINT32 mac_val, mac_val1, idx, band_idx = 0, band_offset = 0, ampdu_cnt[7]; + UINT32 msdr6, msdr7, msdr8, msdr9, msdr10, msdr16, msdr17, msdr18, msdr19, msdr20, msdr21; + UINT32 mbxsdr[bss_nums][4]; + UINT32 mbtcr[16], mbtbcr[16], mbrcr[16], mbrbcr[16]; + UINT32 btcr[bss_nums], btbcr[bss_nums], brcr[bss_nums], brbcr[bss_nums], btdcr[bss_nums], brdcr[bss_nums]; + UINT32 mu_cnt[5]; + + for (band_idx = 0; band_idx < pChipCap->band_cnt; band_idx++) { + if (arg != NULL && band_idx != simple_strtoul(arg, 0, 10)) + continue; + + band_offset = 0x200 * band_idx; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Band %d MIB Status\n", band_idx)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===============================\n")); + RTMP_IO_READ32(pAd, MIB_M0SCR0 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MIB Status Control=0x%x\n", mac_val)); + RTMP_IO_READ32(pAd, MIB_M0PBSCR + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MIB Per-BSS Status Control=0x%x\n", mac_val)); + + RTMP_IO_READ32(pAd, MIB_M0SDR6 + band_offset, &msdr6); + RTMP_IO_READ32(pAd, MIB_M0SDR7 + band_offset, &msdr7); + RTMP_IO_READ32(pAd, MIB_M0SDR8 + band_offset, &msdr8); + RTMP_IO_READ32(pAd, MIB_M0SDR9 + band_offset, &msdr9); + RTMP_IO_READ32(pAd, MIB_M0SDR10 + band_offset, &msdr10); + RTMP_IO_READ32(pAd, MIB_M0SDR16 + band_offset, &msdr16); + RTMP_IO_READ32(pAd, MIB_M0SDR17 + band_offset, &msdr17); + RTMP_IO_READ32(pAd, MIB_M0SDR18 + band_offset, &msdr18); + RTMP_IO_READ32(pAd, MIB_M0SDR19 + band_offset, &msdr19); + RTMP_IO_READ32(pAd, MIB_M0SDR20 + band_offset, &msdr20); + RTMP_IO_READ32(pAd, MIB_M0SDR21 + band_offset, &msdr21); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Phy/Timing Related Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tChannelIdleCnt=0x%x\n", msdr6 & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tCCA_NAV_Tx_Time=0x%x\n", msdr9 & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx_MDRDY_CNT=0x%x\n", msdr10 & 0x3ffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCCK_MDRDY_TIME=0x%x, OFDM_MDRDY_TIME=0x%x, OFDM_GREEN_MDRDY_TIME=0x%x\n", + msdr19 & 0x3ffffff, msdr20 & 0x3ffffff, msdr21 & 0x3ffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tPrim CCA Time=0x%x\n", msdr16 & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tSec CCA Time=0x%x\n", msdr17 & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tPrim ED Time=0x%x\n", msdr18 & 0xffffff)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Tx Related Counters(Generic)===\n")); + RTMP_IO_READ32(pAd, MIB_M0SDR0 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tBeaconTxCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0DR0 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 20MHz Cnt=0x%x\n", mac_val & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 40MHz Cnt=0x%x\n", (mac_val >> 16) & 0xffff)); + RTMP_IO_READ32(pAd, MIB_M0DR1 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 80MHz Cnt=0x%x\n", mac_val & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 160MHz Cnt=0x%x\n", (mac_val >> 16) & 0xffff)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===AMPDU Related Counters===\n")); + RTMP_IO_READ32(pAd, MIB_M0SDR12 + band_offset, &du_cnt[0]); + RTMP_IO_READ32(pAd, MIB_M0SDR14 + band_offset, &du_cnt[1]); + RTMP_IO_READ32(pAd, MIB_M0SDR15 + band_offset, &du_cnt[2]); + RTMP_IO_READ32(pAd, MIB_M0DR2 + band_offset, &du_cnt[3]); + RTMP_IO_READ32(pAd, MIB_M0DR3 + band_offset, &du_cnt[4]); + RTMP_IO_READ32(pAd, MIB_M0DR4 + band_offset, &du_cnt[5]); + RTMP_IO_READ32(pAd, MIB_M0DR5 + band_offset, &du_cnt[6]); + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx BA_Cnt=0x%x\n", ampdu_cnt[0] & 0xffff)); */ + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx AMPDU_Burst_Cnt=0x%x\n", (ampdu_cnt[0] >> 16 ) & 0xffff)); */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx AMPDU_Pkt_Cnt=0x%x\n", ampdu_cnt[0])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx AMPDU_MPDU_Pkt_Cnt=0x%x\n", ampdu_cnt[1] & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tAMPDU SuccessCnt=0x%x\n", ampdu_cnt[2] & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx Agg Range: \t1 \t2~5 \t6~15 \t16~22 \t23~33 \t34~49 \t50~57 \t58~64\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\t\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", + (ampdu_cnt[3]) & 0xffff, (ampdu_cnt[3] >> 16) & 0xffff, + (ampdu_cnt[4]) & 0xffff, (ampdu_cnt[4] >> 16) & 0xffff, + (ampdu_cnt[5]) & 0xffff, (ampdu_cnt[5] >> 16) & 0xffff, + (ampdu_cnt[6]) & 0xffff, (ampdu_cnt[6] >> 16) & 0xffff)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===MU Related Counters===\n")); + MAC_IO_READ32(pAd, MIB_M0SDR34, &mu_cnt[0]); + MAC_IO_READ32(pAd, MIB_M0DR8, &mu_cnt[1]); + MAC_IO_READ32(pAd, MIB_M0DR9, &mu_cnt[2]); + MAC_IO_READ32(pAd, MIB_M0DR10, &mu_cnt[3]); + MAC_IO_READ32(pAd, MIB_M0DR11, &mu_cnt[4]); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMUBF_TX_COUNT=0x%x\n", mu_cnt[0] & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMU_TX_MPDU_COUNT(Ok+Fail)=0x%x\n", mu_cnt[1])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMU_TX_OK_MPDU_COUNT=0x%x\n", mu_cnt[2])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMU_TO_SU_PPDU_COUNT=0x%x\n", mu_cnt[3] & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tSU_TX_OK_MPDU_COUNT=0x%x\n", mu_cnt[4])); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Rx Related Counters(Generic)===\n")); + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tVector Overflow Drop Cnt=0x%x\n", (msdr6 >> 16 ) & 0xffff)); */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tVector Mismacth Cnt=0x%x\n", msdr7 & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tDelimiter Fail Cnt=0x%x\n", msdr8 & 0xffff)); + RTMP_IO_READ32(pAd, MIB_M0SDR3 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxFCSErrCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR4 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxFifoFullCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR11 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxLenMismatch=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR5 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxMPDUCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR29 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tPFDropCnt=0x%x\n", (mac_val & 0x00ff))); + RTMP_IO_READ32(pAd, MIB_M0SDR22 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx AMPDU Cnt=0x%x\n", mac_val)); + /* TODO: shiang-MT7615, is MIB_M0SDR23 used for Rx total byte count for all or just AMPDU only??? */ + RTMP_IO_READ32(pAd, MIB_M0SDR23 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx Total ByteCnt=0x%x\n", mac_val)); + } + + for (idx = 0; idx < bss_nums; idx++) { + RTMP_IO_READ32(pAd, WTBL_BTCRn + idx * 4, &btcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BTBCRn + idx * 4, &btbcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BRCRn + idx * 4, &brcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BRBCRn + idx * 4, &brbcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BTDCRn + idx * 4, &btdcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BRDCRn + idx * 4, &brdcr[idx]); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Per-BSS Related Tx/Rx Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BSS Idx TxCnt/DataCnt TxByteCnt RxCnt/DataCnt RxByteCnt\n")); + + for (idx = 0; idx < bss_nums; idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%d\t 0x%x/0x%x\t 0x%x \t 0x%x/0x%x \t 0x%x\n", + idx, btcr[idx], btdcr[idx], btbcr[idx], + brcr[idx], brdcr[idx], brbcr[idx])); + } + + for (idx = 0; idx < bss_nums; idx++) { + RTMP_IO_READ32(pAd, MIB_MB0SDR0 + idx * 0x10, &mbxsdr[idx][0]); + RTMP_IO_READ32(pAd, MIB_MB0SDR1 + idx * 0x10, &mbxsdr[idx][1]); + RTMP_IO_READ32(pAd, MIB_MB0SDR2 + idx * 0x10, &mbxsdr[idx][2]); + RTMP_IO_READ32(pAd, MIB_MB0SDR3 + idx * 0x10, &mbxsdr[idx][3]); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Per-MBSS Related MIB Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BSS Idx RTSTx/RetryCnt BAMissCnt AckFailCnt FrmRetry1/2/3Cnt\n")); + + for (idx = 0; idx < bss_nums; idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%d:\t0x%x/0x%x 0x%x \t 0x%x \t 0x%x/0x%x/0x%x\n", + idx, mbxsdr[idx][0], (mbxsdr[idx][0] >> 16) & 0xffff, + mbxsdr[idx][1], (mbxsdr[idx][1] >> 16) & 0xffff, + mbxsdr[idx][2], (mbxsdr[idx][2] >> 16) & 0xffff, + mbxsdr[idx][3] & 0xffff)); + } + + for (idx = 0; idx < 16; idx++) { + RTMP_IO_READ32(pAd, WTBL_MBTCRn + idx * 4, &mbtcr[idx]); + RTMP_IO_READ32(pAd, WTBL_MBTBCRn + idx * 4, &mbtbcr[idx]); + RTMP_IO_READ32(pAd, WTBL_MBRCRn + idx * 4, &mbrcr[idx]); + RTMP_IO_READ32(pAd, WTBL_MBRBCRn + idx * 4, &mbrbcr[idx]); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Per-MBSS Related Tx/Rx Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MBSSIdx TxCnt TxByteCnt RxCnt RxByteCnt\n")); + + for (idx = 0; idx < 16; idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%d\t 0x%x\t 0x%x \t 0x%x \t 0x%x\n", + idx, mbtcr[idx], mbtbcr[idx], mbrcr[idx], mbrbcr[idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Dummy delimiter insertion result===\n")); + RTMP_IO_READ32(pAd, MIB_M0DR6, &mac_val); + RTMP_IO_READ32(pAd, MIB_M0DR7, &mac_val1); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Range1 = %d\t Range2 = %d\t Range3 = %d\t Range4 = %d\n", + GET_TX_DDLMT_RNG1_CNT(mac_val), GET_TX_DDLMT_RNG2_CNT(mac_val), GET_TX_DDLMT_RNG3_CNT(mac_val1), GET_TX_DDLMT_RNG4_CNT(mac_val1))); +#ifdef TRACELOG_TCP_PKT + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TCP RxAck = %d\t TxData = %d", + pAd->u4TcpRxAckCnt, pAd->u4TcpTxDataCnt)); + pAd->u4TcpRxAckCnt = 0; + pAd->u4TcpTxDataCnt = 0; +#endif /* TRACELOG_TCP_PKT */ + return TRUE; +} + +static INT32 chip_show_pse_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + UINT32 pse_buf_ctrl, pg_sz, pg_num; + UINT32 pse_stat, pg_flow_ctrl[16] = {0}; + UINT32 fpg_cnt, ffa_cnt, fpg_head, fpg_tail; + UINT32 max_q, min_q, rsv_pg, used_pg; + INT32 i; + + HW_IO_READ32(pAd, PSE_PBUF_CTRL, &pse_buf_ctrl); + HW_IO_READ32(pAd, PSE_QUEUE_EMPTY, &pse_stat); + HW_IO_READ32(pAd, PSE_FREEPG_CNT, &pg_flow_ctrl[0]); + HW_IO_READ32(pAd, PSE_FREEPG_HEAD_TAIL, &pg_flow_ctrl[1]); + HW_IO_READ32(pAd, PSE_PG_HIF0_GROUP, &pg_flow_ctrl[2]); + HW_IO_READ32(pAd, PSE_HIF0_PG_INFO, &pg_flow_ctrl[3]); + HW_IO_READ32(pAd, PSE_PG_HIF1_GROUP, &pg_flow_ctrl[4]); + HW_IO_READ32(pAd, PSE_HIF1_PG_INFO, &pg_flow_ctrl[5]); + HW_IO_READ32(pAd, PSE_PG_CPU_GROUP, &pg_flow_ctrl[6]); + HW_IO_READ32(pAd, PSE_CPU_PG_INFO, &pg_flow_ctrl[7]); + HW_IO_READ32(pAd, PSE_PG_LMAC0_GROUP, &pg_flow_ctrl[8]); + HW_IO_READ32(pAd, PSE_LMAC0_PG_INFO, &pg_flow_ctrl[9]); + HW_IO_READ32(pAd, PSE_PG_LMAC1_GROUP, &pg_flow_ctrl[10]); + HW_IO_READ32(pAd, PSE_LMAC1_PG_INFO, &pg_flow_ctrl[11]); + HW_IO_READ32(pAd, PSE_PG_LMAC2_GROUP, &pg_flow_ctrl[12]); + HW_IO_READ32(pAd, PSE_LMAC2_PG_INFO, &pg_flow_ctrl[13]); + HW_IO_READ32(pAd, PSE_PG_PLE_GROUP, &pg_flow_ctrl[14]); + HW_IO_READ32(pAd, PSE_PLE_PG_INFO, &pg_flow_ctrl[15]); + /* Configuration Info */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PSE Configuration Info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPacket Buffer Control(0x82068014): 0x%08x\n", pse_buf_ctrl)); + pg_sz = (pse_buf_ctrl & (0x1 << 31)) >> 31; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Size=%d(%d bytes per page)\n", pg_sz, (pg_sz == 1 ? 256 : 128))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Offset=%d(in unit of 64KB)\n", GET_PSE_PBUF_OFFSET(pse_buf_ctrl))); + pg_num = PSE_GET_TOTAL_PAGE_CFG(pse_buf_ctrl); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tConfigured Total Page=%d(%d pages)\n", pg_num, (pg_num < 14 ? pse_pg_cnt[pg_num] : 0))); + pg_num = (pse_buf_ctrl & PSE_TOTAL_PAGE_NUM_MASK); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tAvailable Total Page=%d pages\n", pg_num)); + /* Page Flow Control */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PSE Page Flow Control:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page counter(0x82068100): 0x%08x\n", pg_flow_ctrl[0])); + fpg_cnt = pg_flow_ctrl[0] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe toal page number of free=0x%03x\n", fpg_cnt)); + ffa_cnt = (pg_flow_ctrl[0] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe free page numbers of free for all=0x%03x\n", ffa_cnt)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page head and tail(0x82068104): 0x%08x\n", pg_flow_ctrl[1])); + fpg_head = pg_flow_ctrl[1] & 0xfff; + fpg_tail = (pg_flow_ctrl[1] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", fpg_tail, fpg_head)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of HIF0 group(0x82068110): 0x%08x\n", pg_flow_ctrl[2])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF0 group page status(0x82068114): 0x%08x\n", pg_flow_ctrl[3])); + min_q = pg_flow_ctrl[2] & 0xfff; + max_q = (pg_flow_ctrl[2] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of HIF0 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[3] & 0xfff; + used_pg = (pg_flow_ctrl[3] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of HIF0 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of HIF1 group(0x82068118): 0x%08x\n", pg_flow_ctrl[4])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF1 group page status(0x8206811c): 0x%08x\n", pg_flow_ctrl[5])); + min_q = pg_flow_ctrl[4] & 0xfff; + max_q = (pg_flow_ctrl[4] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of HIF1 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[5] & 0xfff; + used_pg = (pg_flow_ctrl[5] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of HIF1 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of CPU group(0x82068150): 0x%08x\n", pg_flow_ctrl[6])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCPU group page status(0x82068154): 0x%08x\n", pg_flow_ctrl[7])); + min_q = pg_flow_ctrl[6] & 0xfff; + max_q = (pg_flow_ctrl[6] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[7] & 0xfff; + used_pg = (pg_flow_ctrl[7] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of LMAC0 group(0x82068170): 0x%08x\n", pg_flow_ctrl[8])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tLMAC0 group page status(0x82068174): 0x%08x\n", pg_flow_ctrl[9])); + min_q = pg_flow_ctrl[8] & 0xfff; + max_q = (pg_flow_ctrl[8] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of LMAC0 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[9] & 0xfff; + used_pg = (pg_flow_ctrl[9] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of LMAC0 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of LMAC1 group(0x82068178): 0x%08x\n", pg_flow_ctrl[10])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tLMAC1 group page status(0x8206817c): 0x%08x\n", pg_flow_ctrl[11])); + min_q = pg_flow_ctrl[10] & 0xfff; + max_q = (pg_flow_ctrl[10] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of LMAC1 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[11] & 0xfff; + used_pg = (pg_flow_ctrl[11] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of LMAC1 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of LMAC2 group(0x82068180): 0x%08x\n", pg_flow_ctrl[11])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tLMAC2 group page status(0x82068184): 0x%08x\n", pg_flow_ctrl[12])); + min_q = pg_flow_ctrl[12] & 0xfff; + max_q = (pg_flow_ctrl[12] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of LMAC2 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[13] & 0xfff; + used_pg = (pg_flow_ctrl[13] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of LMAC2 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of PLE group(0x82068190): 0x%08x\n", pg_flow_ctrl[14])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPLE group page status(0x82068194): 0x%08x\n", pg_flow_ctrl[15])); + min_q = pg_flow_ctrl[14] & 0xfff; + max_q = (pg_flow_ctrl[14] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of PLE group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[15] & 0xfff; + used_pg = (pg_flow_ctrl[15] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of PLE group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + /* Queue Empty Status */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PSE Queue Empty Status:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tQUEUE_EMPTY(0x820680b0): 0x%08x\n", pse_stat)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tCPU Q0/1/2/3 empty=%d/%d/%d/%d\n", + pse_stat & 0x1, ((pse_stat & 0x2) >> 1), + ((pse_stat & 0x4) >> 2), ((pse_stat & 0x8) >> 3))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tHIF Q0/1 empty=%d/%d\n", + ((pse_stat & (0x1 << 16)) >> 16), ((pse_stat & (0x1 << 17)) >> 17))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tLMAC TX Q empty=%d\n", + ((pse_stat & (0x1 << 24)) >> 24))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tRLS_Q empty=%d\n", + ((pse_stat & (0x1 << 31)) >> 31))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Nonempty Q info:\n")); + + for (i = 0; i < 31; i++) { + if (((pse_stat & (0x1 << i)) >> i) == 0) { + UINT32 hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (i < 4) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCPU Q%d: ", i)); + fl_que_ctrl[0] |= (0x1 << 14); + fl_que_ctrl[0] |= (i << 8); + } else if (i == 16) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tHIF Q0: ")); + fl_que_ctrl[0] |= (0x0 << 14); + fl_que_ctrl[0] |= (0x0 << 8); + } else if (i == 17) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tHIF Q1: ")); + fl_que_ctrl[0] |= (0x0 << 14); + fl_que_ctrl[0] |= (0x1 << 8); + } else if (i == 24) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tLMAC TX Q: ")); + fl_que_ctrl[0] |= (0x2 << 14); + fl_que_ctrl[0] |= (0x0 << 8); + } else if (i == 31) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRLS Q: ")); + fl_que_ctrl[0] |= (0x3 << 14); + fl_que_ctrl[0] |= (i << 8); + } else + continue; + + fl_que_ctrl[0] |= (0x1 << 31); + HW_IO_WRITE32(pAd, PSE_FL_QUE_CTRL_0, fl_que_ctrl[0]); + HW_IO_READ32(pAd, PSE_FL_QUE_CTRL_2, &fl_que_ctrl[1]); + HW_IO_READ32(pAd, PSE_FL_QUE_CTRL_3, &fl_que_ctrl[2]); + hfid = fl_que_ctrl[1] & 0xfff; + tfid = (fl_que_ctrl[1] & 0xfff << 16) >> 16; + pktcnt = fl_que_ctrl[2] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("tail/head fid = 0x%03x/0x%03x, pkt cnt = %x\n", + tfid, hfid, pktcnt)); + } + } + + return TRUE; +} + +static INT32 chip_show_protect_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 val; + RTMP_ADAPTER *pAd = ctrl->priv; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" -Proetction\n")); + RTMP_IO_READ32(pAd, AGG_PCR, &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" > AGG_PCR 0x%08x\n", val)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" -RTS Threshold\n")); + RTMP_IO_READ32(pAd, AGG_PCR1, &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" > AGG_PCR1 0x%08x\n", val)); + return TRUE; +} + +static INT32 chip_show_cca_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 val; + RTMP_ADAPTER *pAd = ctrl->priv; + + MAC_IO_READ32(pAd, RMAC_DEBUG_CR, &val); + val |= (1 << 31); /* For Band0 */ + MAC_IO_WRITE32(pAd, RMAC_DEBUG_CR, val); + /* Debug CR */ + MAC_IO_WRITE32(pAd, (WF_CFG_OFF_BASE + 0x2c), 0xf); + MAC_IO_WRITE32(pAd, (WF_CFG_BASE + 0x14), 0x1f); + MAC_IO_WRITE32(pAd, (WF_CFG_BASE + 0x18), 0x06060606); + MAC_IO_WRITE32(pAd, (WF_CFG_BASE + 0x4c), 0x1c1c1d1d); + MAC_IO_READ32(pAd, (WF_CFG_BASE + 0x24), &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("CCA for BAND0 info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("-- CCA Prim: %d, SE20: %d, SEC40: %d\n", + ((val & (1 << 14)) >> 14), ((val & (1 << 6)) >> 6), + ((val & (1 << 5)) >> 5))); + MAC_IO_READ32(pAd, RMAC_DEBUG_CR, &val); + val &= ~(1 << 31); /* For Band1 */ + MAC_IO_WRITE32(pAd, RMAC_DEBUG_CR, val); + MAC_IO_READ32(pAd, (WF_CFG_BASE + 0x24), &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("CCA for BAND1 info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("-- CCA Prim: %d, SE20: %d, SEC40: %d\n", + ((val & (1 << 14)) >> 14), ((val & (1 << 6)) >> 6), + ((val & (1 << 5)) >> 5))); + return 0; +} + +static INT32 chip_set_cca_en(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + BOOLEAN enable; + UINT32 val; + RTMP_ADAPTER *pAd = ctrl->priv; + + enable = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Enable CCA on Band0 SEC40: %s\n", (enable) ? "ON" : "OFF")); + /* RF CR for BAND0 CCA */ + PHY_IO_READ32(pAd, PHY_BAND0_PHY_CCA, &val); + val |= ((1 << 18) | (1 << 2)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("-- Force Mode: %d, Force CCA SEC40: %d [0x%08x]\n", + ((val & (1 << 18)) >> 18), ((val & (1 << 2)) >> 2), val)); + PHY_IO_WRITE32(pAd, PHY_BAND0_PHY_CCA, val); + /* TMAC_TCR for the normal Tx BW */ + MAC_IO_READ32(pAd, TMAC_TCR, &val); + val &= ~(PRE_RTS_IDLE_DET_DIS); + val |= DCH_DET_DIS; + MAC_IO_WRITE32(pAd, TMAC_TCR, val); + return TRUE; +} + + + +static VOID dump_arb_debug_info(RTMP_ADAPTER *pAd, UCHAR bandidx) +{ + UINT32 mac_val; + UINT32 idx; + + MAC_IO_WRITE32(pAd, CFG_DBG_EN, 0x1f); + MAC_IO_WRITE32(pAd, CFG_DBG_L1_MOD_SEL, 0x04040404); + + if (bandidx == DBDC_BAND0) + MAC_IO_WRITE32(pAd, ARB_DCR, 0x12121212); /* BCN0 */ + else + MAC_IO_WRITE32(pAd, ARB_DCR, 0x16161616); /* BCN1 */ + +#define CFG_DBG_L1_SEL_N_GET(_A, _S, _pV) \ + { \ + MAC_IO_WRITE32(_A, CFG_DBG_L1_SEL, _S); \ + MAC_IO_READ32(_A, CFG_DBG0, _pV); \ + } + + CFG_DBG_L1_SEL_N_GET(pAd, 0x04040404, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BCN ARB Debug Flag04=0x%08x\n", mac_val)); + CFG_DBG_L1_SEL_N_GET(pAd, 0x06060606, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BCN ARB Debug Flag06=0x%08x\n", mac_val)); + CFG_DBG_L1_SEL_N_GET(pAd, 0x08080808, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BCN ARB Debug Flag08=0x%08x\n", mac_val)); + + for (idx = 0; idx <= 18; idx++) { + /* ARB CR DCR = 0x A A A A, A = 2 Hex digits, A=0~18. 0~3: BSSID[0~3]; 4~18:BSSID[0_1~0_15] */ + UINT32 BSSID_SEL = idx << 24 | idx << 16 | idx << 8 | idx; + + MAC_IO_WRITE32(pAd, ARB_DCR, BSSID_SEL); + + if (idx <= 3) { + CFG_DBG_L1_SEL_N_GET(pAd, 0x0a0a0a0a, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BCN(BSSID%d) FSM Debug Flag0a=0x%08x\n", idx, mac_val)); + CFG_DBG_L1_SEL_N_GET(pAd, 0x0b0b0b0b, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BCN(BSSID%d) FSM Debug Flag0b=0x%08x\n", idx, mac_val)); + } else { + CFG_DBG_L1_SEL_N_GET(pAd, 0x0a0a0a0a, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BCN(BSSID0_%d) FSM Debug Flag0a=0x%08x\n", (idx - 3), mac_val)); + CFG_DBG_L1_SEL_N_GET(pAd, 0x0b0b0b0b, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BCN(BSSID0_%d) FSM Debug Flag0b=0x%08x\n", (idx - 3), mac_val)); + } + } +} + +static VOID chip_show_bcn_info(struct hdev_ctrl *ctrl, UCHAR bandidx) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + UINT32 mac_val; + UINT32 addr; + UINT32 idx; + UINT32 band_offset = 0x200 * bandidx; + struct _RTMP_CHIP_DBG *chip_dbg = hc_get_chip_dbg(ctrl); + + if (chip_dbg->dump_mib_info) { + if (bandidx == DBDC_BAND0) + chip_dbg->dump_mib_info(pAd->hdev_ctrl, "0"); + else + chip_dbg->dump_mib_info(pAd->hdev_ctrl, "1"); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + show_trinfo_proc(pAd, ""); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + ShowPLEInfo(pAd, NULL); +#ifdef ERR_RECOVERY + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + ShowSerProc2(pAd, ""); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + show_swqinfo(pAd, ""); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + if (chip_dbg->show_pse_info) + chip_dbg->show_pse_info(pAd->hdev_ctrl, NULL); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + show_tpinfo_proc(pAd, NULL); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + Show_MibBucket_Proc(pAd, ""); + MAC_IO_READ32(pAd, ARB_BFCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ARB_BFCR(0x820f3190)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, ARB_SCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ARB_SCR(0x820f3080)=0x%08x\n", mac_val)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x820f3100~0x820f3154:\n")); + + for (addr = ARB_TQSW0; addr <= ARB_TQPM1; addr = addr + 4) { + if ((addr & 0xf) == 0 && (addr != ARB_TQSW0)) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MAC_IO_READ32(pAd, ARB_BFCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ARB_BFCR(0x820f3190)=0x%08x\n", mac_val)); + /* (WF_LP) Debug CRs */ + MAC_IO_READ32(pAd, LPON_T0STR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_T0STR(0x820fb028)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, LPON_PISR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_PISR(0x820fb030)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, LPON_T0TPCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_T0TPCR(0x820fb34)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, LPON_MPTCR0, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_MPTCR0(0x820fb05c)=0x%08x\n", mac_val)); + /* (WF_INT_WAKEUP) Interrupt CRs */ + MAC_IO_READ32(pAd, WISR0, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("WISR0(0x820fc000)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, WIER0, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("WIER0(0x820fc008)=0x%08x\n", mac_val)); + /* (UMAC) CR used to record SER status */ + MAC_IO_READ32(pAd, PSE_SPARE_DUMMY_CR1, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SER PSE Error INT status(0x820681e4)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PSE_SPARE_DUMMY_CR2, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SER PLE Error INT status(0x820681e8)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PSE_SPARE_DUMMY_CR3, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SER LMAC WDT status(0x820682e8)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PP_SPARE_DUMMY_CR5, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CritialErrorRecord0(0x8206c064)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PP_SPARE_DUMMY_CR6, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CritialErrorRecord1(0x8206c068)=0x%08x\n", mac_val)); + + dump_arb_debug_info(pAd, bandidx); + +#define CR4_HEART_BEAT_STS 0x80200 + MAC_IO_READ32(pAd, CR4_HEART_BEAT_STS, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CR4 heart beat status (0x80200)=0x%08x\n", mac_val)); + MtCmdFwLog2Host(pAd, 1, 0); + MAC_IO_READ32(pAd, RO_BAND0_PHYCTRL_STS + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RO_BAND0_PHYCTRL_STS(0x%08x)= 0x%08x\n", 0x82070230 + band_offset, mac_val)); + /* 0x82070618~0x8207065c */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x%08x~0x%08x:\n", + 0x82070618 + band_offset, 0x8207065c + band_offset)); + + for (addr = PHY_BAND0_PHYMUX_6; addr <= PHY_BAND0_PHYMUX_23; addr = addr + 4) { + if ((addr & 0xf) == 8 && (addr != PHY_BAND0_PHYMUX_6)) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + /* 0x8207227c~0x82072294 */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x%08x~0x%08x:\n", + 0x8207227c + band_offset, 0x82072294 + band_offset)); + + for (addr = RO_BAND0_RXTD_DEBUG0; addr <= RO_BAND0_RXTD_DEBUG6; addr = addr + 4) { + if (addr == RO_BAND0_RXTD_DEBUG4) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + /* 0x820721a0~0x820721b8 */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x%08x~0x%08x:\n", + 0x820721a0 + band_offset, 0x820721b8 + band_offset)); + + for (addr = RO_BAND0_AGC_DEBUG_0; addr <= RO_BAND0_AGC_DEBUG_6; addr = addr + 4) { + if (addr == RO_BAND0_AGC_DEBUG_4) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + /* + + Write 0x82070614[22:20]=0 + Write 0x82070614[22:20]=5 + + // read the following registers by 10 times + 0X8207_020C + 0x8207_0210 + 0x8207_0214 + 0x8207_021C + 0x8207_0220 + // End of Loop + + */ + MAC_IO_READ32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, &mac_val); + mac_val &= ~(BITS(20, 22)); + MAC_IO_WRITE32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, mac_val); + MAC_IO_READ32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, &mac_val); + mac_val &= ~(BITS(20, 22)); + mac_val |= (BIT(20) | BIT(22)); + MAC_IO_WRITE32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, mac_val); + + for (idx = 0; idx < 10; idx++) { + if (IS_MT7615(pAd)) { + MAC_IO_READ32(pAd, RO_BAND0_PHYCTRL_STS0 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("loop %d addr(0x%8x)=0x%08x ", + idx, 0x8207020c + band_offset, mac_val)); + MAC_IO_READ32(pAd, RO_BAND0_PHYCTRL_STS1 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr(0x%08x)=0x%08x ", + 0x82070210 + band_offset, mac_val)); + MAC_IO_READ32(pAd, RO_BAND0_PHYCTRL_STS2 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr(0x%08x)=0x%08x ", + 0x82070214 + band_offset, mac_val)); + MAC_IO_READ32(pAd, RO_BAND0_PHYCTRL_STS4 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr(0x%08x)=0x%08x ", + 0x8207021c + band_offset, mac_val)); + MAC_IO_READ32(pAd, RO_BAND0_PHYCTRL_STS5 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr(0x%08x)=0x%08x\n", + 0x82070220 + band_offset, mac_val)); + } + MAC_IO_READ32(pAd, ARB_BFCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("loop %d ARB_BFCR(0x820f3190)=0x%08x\n", idx, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); +} + +static INT32 chip_show_ple_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + UINT32 ple_buf_ctrl[3] = {0}, pg_sz, pg_num, bit_field_1, bit_field_2; + UINT32 ple_stat[17] = {0}, pg_flow_ctrl[6] = {0}; + UINT32 sta_pause[4] = {0}, dis_sta_map[4] = {0}; + UINT32 fpg_cnt, ffa_cnt, fpg_head, fpg_tail, hif_max_q, hif_min_q; + UINT32 rpg_hif, upg_hif, cpu_max_q, cpu_min_q, rpg_cpu, upg_cpu; + INT32 i, j; + UINT32 dumptxd = 0; + + if (arg != NULL) + dumptxd = os_str_toul(arg, 0, 16); + + HW_IO_READ32(pAd, PLE_PBUF_CTRL, &ple_buf_ctrl[0]); + HW_IO_READ32(pAd, PLE_RELEASE_CTRL, &ple_buf_ctrl[1]); + HW_IO_READ32(pAd, PLE_HIF_REPORT, &ple_buf_ctrl[2]); + HW_IO_READ32(pAd, PLE_QUEUE_EMPTY, &ple_stat[0]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_0, &ple_stat[1]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_1, &ple_stat[2]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_2, &ple_stat[3]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_3, &ple_stat[4]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_0, &ple_stat[5]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_1, &ple_stat[6]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_2, &ple_stat[7]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_3, &ple_stat[8]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_0, &ple_stat[9]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_1, &ple_stat[10]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_2, &ple_stat[11]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_3, &ple_stat[12]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_0, &ple_stat[13]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_1, &ple_stat[14]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_2, &ple_stat[15]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_3, &ple_stat[16]); + HW_IO_READ32(pAd, PLE_FREEPG_CNT, &pg_flow_ctrl[0]); + HW_IO_READ32(pAd, PLE_FREEPG_HEAD_TAIL, &pg_flow_ctrl[1]); + HW_IO_READ32(pAd, PLE_PG_HIF_GROUP, &pg_flow_ctrl[2]); + HW_IO_READ32(pAd, PLE_HIF_PG_INFO, &pg_flow_ctrl[3]); + HW_IO_READ32(pAd, PLE_PG_CPU_GROUP, &pg_flow_ctrl[4]); + HW_IO_READ32(pAd, PLE_CPU_PG_INFO, &pg_flow_ctrl[5]); + HW_IO_READ32(pAd, DIS_STA_MAP0, &dis_sta_map[0]); + HW_IO_READ32(pAd, DIS_STA_MAP1, &dis_sta_map[1]); + HW_IO_READ32(pAd, DIS_STA_MAP2, &dis_sta_map[2]); + HW_IO_READ32(pAd, DIS_STA_MAP3, &dis_sta_map[3]); + HW_IO_READ32(pAd, STATION_PAUSE0, &sta_pause[0]); + HW_IO_READ32(pAd, STATION_PAUSE1, &sta_pause[1]); + HW_IO_READ32(pAd, STATION_PAUSE2, &sta_pause[2]); + HW_IO_READ32(pAd, STATION_PAUSE3, &sta_pause[3]); + /* Configuration Info */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PLE Configuration Info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPacket Buffer Control(0x82060014): 0x%08x\n", ple_buf_ctrl[0])); + pg_sz = (ple_buf_ctrl[0] & (0x1 << 31)) >> 31; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Size=%d(%d bytes per page)\n", pg_sz, (pg_sz == 1 ? 128 : 64))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Offset=%d(in unit of 64KB)\n", (ple_buf_ctrl[0] & (0xf << 20)) >> 20)); + pg_num = (ple_buf_ctrl[0] & (0xf << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tConfigured Total Page=%d(%d pages)\n", pg_num, (pg_num < 8 ? ple_pg_cnt[pg_num] : 0))); + pg_num = (ple_buf_ctrl[0] & 0xfff); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tAvailable Total Page=%d pages\n", (ple_buf_ctrl[0] & 0xfff))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tRelease Control(0x82060030): 0x%08x\n", ple_buf_ctrl[1])); + bit_field_1 = (ple_buf_ctrl[1] & 0x1f); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 6)) >> 6); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tNormalTx Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 8)) >> 8); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 14)) >> 14); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tDropTx Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 16)) >> 16); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 22)) >> 22); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tBCN0 Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 24)) >> 24); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 30)) >> 30); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tBCN1 Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF Report Control(0x82060034): 0x%08x\n", ple_buf_ctrl[2])); + bit_field_1 = ((ple_buf_ctrl[2] & (0x1 << 1)) >> 1); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tHostReportQSel/HostReportDisable=%d/%d\n", + (ple_buf_ctrl[2] & 0x1), bit_field_1)); + /* Page Flow Control */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PLE Page Flow Control:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page counter(0x82060100): 0x%08x\n", pg_flow_ctrl[0])); + fpg_cnt = pg_flow_ctrl[0] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe toal page number of free=0x%03x\n", fpg_cnt)); + ffa_cnt = (pg_flow_ctrl[0] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe free page numbers of free for all=0x%03x\n", ffa_cnt)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page head and tail(0x82060104): 0x%08x\n", pg_flow_ctrl[1])); + fpg_head = pg_flow_ctrl[1] & 0xfff; + fpg_tail = (pg_flow_ctrl[1] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", fpg_tail, fpg_head)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of HIF group(0x82060110): 0x%08x\n", pg_flow_ctrl[2])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF group page status(0x82060114): 0x%08x\n", pg_flow_ctrl[3])); + hif_min_q = pg_flow_ctrl[2] & 0xfff; + hif_max_q = (pg_flow_ctrl[2] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of HIF group=0x%03x/0x%03x\n", hif_max_q, hif_min_q)); + rpg_hif = pg_flow_ctrl[3] & 0xfff; + upg_hif = (pg_flow_ctrl[3] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of HIF group=0x%03x/0x%03x\n", upg_hif, rpg_hif)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of CPU group(0x82060150): 0x%08x\n", pg_flow_ctrl[4])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCPU group page status(0x82060154): 0x%08x\n", pg_flow_ctrl[5])); + cpu_min_q = pg_flow_ctrl[4] & 0xfff; + cpu_max_q = (pg_flow_ctrl[4] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", cpu_max_q, cpu_min_q)); + rpg_cpu = pg_flow_ctrl[5] & 0xfff; + upg_cpu = (pg_flow_ctrl[5] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", upg_cpu, rpg_cpu)); + + if (((ple_stat[0] & (0x1 << 24)) >> 24) == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY0(0x82060300): 0x%08x\n", ple_stat[1])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY1(0x82060304): 0x%08x\n", ple_stat[2])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY2(0x82060308): 0x%08x\n", ple_stat[3])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY3(0x8206030c): 0x%08x\n", ple_stat[4])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY0(0x82060310): 0x%08x\n", ple_stat[5])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY1(0x82060314): 0x%08x\n", ple_stat[6])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY2(0x82060318): 0x%08x\n", ple_stat[7])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY3(0x8206031c): 0x%08x\n", ple_stat[8])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY0(0x82060320): 0x%08x\n", ple_stat[9])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY1(0x82060324): 0x%08x\n", ple_stat[10])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY2(0x82060328): 0x%08x\n", ple_stat[11])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY3(0x8206032c): 0x%08x\n", ple_stat[12])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY0(0x82060330): 0x%08x\n", ple_stat[13])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY1(0x82060334): 0x%08x\n", ple_stat[14])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY2(0x82060338): 0x%08x\n", ple_stat[15])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY3(0x8206033c): 0x%08x\n", ple_stat[16])); + + for (j = 0; j < 16; j++) { + if (j % 4 == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\n\tNonempty AC%d Q of STA#: ", j / 4)); + } + + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%d ", i + (j % 4) * 32)); + } + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Nonempty Q info:\n")); + + for (i = 0; i < 31; i++) { + if (((ple_stat[0] & (0x1 << i)) >> i) == 0) { + UINT32 hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (Queue_Empty_info[i].QueueName != NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t%s: ", Queue_Empty_info[i].QueueName)); + fl_que_ctrl[0] |= (0x1 << 31); + fl_que_ctrl[0] |= (Queue_Empty_info[i].Portid << 14); + fl_que_ctrl[0] |= (Queue_Empty_info[i].Queueid << 8); + } else + continue; + + HW_IO_WRITE32(pAd, PLE_FL_QUE_CTRL_0, fl_que_ctrl[0]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_2, &fl_que_ctrl[1]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_3, &fl_que_ctrl[2]); + hfid = fl_que_ctrl[1] & 0xfff; + tfid = (fl_que_ctrl[1] & 0xfff << 16) >> 16; + pktcnt = fl_que_ctrl[2] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("tail/head fid = 0x%03x/0x%03x, pkt cnt = %x\n", + tfid, hfid, pktcnt)); + + if (pktcnt > 0 && dumptxd > 0) + ShowTXDInfo(pAd, hfid); + } + } + + for (j = 0; j < 16; j++) { /* show AC Q info */ + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + UINT32 hfid, tfid, pktcnt, ac_num = j / 4, ctrlvalue = 0; + UINT32 sta_num = i + (j % 4) * 32, fl_que_ctrl[3] = {0}; + struct wifi_dev *wdev = wdev_search_by_wcid(pAd, sta_num); + UINT32 wmmidx = 0; + + if (wdev) + wmmidx = HcGetWmmIdx(pAd, wdev); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tSTA%d AC%d: ", sta_num, ac_num)); + fl_que_ctrl[0] |= (0x1 << 31); + fl_que_ctrl[0] |= (0x2 << 14); + fl_que_ctrl[0] |= (ac_num << 8); + fl_que_ctrl[0] |= sta_num; + HW_IO_WRITE32(pAd, PLE_FL_QUE_CTRL_0, fl_que_ctrl[0]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_2, &fl_que_ctrl[1]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_3, &fl_que_ctrl[2]); + hfid = fl_que_ctrl[1] & 0xfff; + tfid = (fl_que_ctrl[1] & 0xfff << 16) >> 16; + pktcnt = fl_que_ctrl[2] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("tail/head fid = 0x%03x/0x%03x, pkt cnt = %x", + tfid, hfid, pktcnt)); + + if (((sta_pause[j % 4] & 0x1 << i) >> i) == 1) + ctrlvalue = 2; + + if (((dis_sta_map[j % 4] & 0x1 << i) >> i) == 1) + ctrlvalue = 1; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" ctrl = %s", sta_ctrl_reg[ctrlvalue])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" (wmmidx=%d)\n", wmmidx)); + + if (pktcnt > 0 && dumptxd > 0) + ShowTXDInfo(pAd, hfid); + } + } + } + + return TRUE; +} + +VOID mt7615_chip_dbg_init(struct _RTMP_CHIP_DBG *dbg_ops) +{ + dbg_ops->dump_ps_table = chip_dump_ps_table; + dbg_ops->dump_mib_info = chip_dump_mib_info; + dbg_ops->show_tmac_info = chip_show_tmac_info; + dbg_ops->show_agg_info = chip_show_agg_info; + dbg_ops->show_dmasch_info = NULL; /* mt7615 has no dmasch */ + dbg_ops->show_pse_info = chip_show_pse_info; + dbg_ops->show_pse_data = NULL; /* read PSE data from host is not supported */ + dbg_ops->show_protect_info = chip_show_protect_info; + dbg_ops->show_cca_info = chip_show_cca_info; + dbg_ops->set_cca_en = chip_set_cca_en; + dbg_ops->show_txv_info = NULL; + dbg_ops->show_bcn_info = chip_show_bcn_info; + dbg_ops->show_ple_info = chip_show_ple_info; +} + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7622.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7622.c new file mode 100644 index 000000000..6acad0f18 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7622.c @@ -0,0 +1,2261 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + mt7622.c +*/ + +#include "rt_config.h" +#include "chip/mt7622_cr.h" +#include "mcu/mt7622_firmware_e2.h" +#ifdef NEED_ROM_PATCH +#include "mcu/mt7622_rom_patch_e2.h" +#endif /* NEED_ROM_PATCH */ + +/* ePAeLNA shall always be included as default */ +#include "eeprom/mt7622_e2p_ePAeLNA.h" + +#if defined(CONFIG_FIRST_IF_IPAILNA) +#include "eeprom/mt7622_e2p_iPAiLNA.h" +#endif +#if defined(CONFIG_FIRST_IF_IPAELNA) +#include "eeprom/mt7622_e2p_iPAeLNA.h" +#endif + +#ifdef CONFIG_AP_SUPPORT +#define DEFAULT_BIN_FILE "/etc_ro/wlan/MT7622_EEPROM.bin" +#else +#define DEFAULT_BIN_FILE "/etc/MT7622_EEPROM.bin" +#endif /* CONFIG_AP_SUPPORT */ + +#ifdef INTERNAL_CAPTURE_SUPPORT +extern RBIST_DESC_T MT7622_ICAP_DESC[]; +extern UINT8 MT7622_ICapBankNum; +#endif /* INTERNAL_CAPTURE_SUPPORT */ + +#ifdef WIFI_SPECTRUM_SUPPORT +extern RBIST_DESC_T MT7622_SPECTRUM_DESC[]; +extern UINT8 MT7622_SpectrumBankNum; +#endif /* WIFI_SPECTRUM_SUPPORT */ + +UCHAR mt7622_ba_range[] = {4, 8, 12, 24, 36, 48, 54, 64}; + +static UINT32 UNMASK[] = {0x30, 0x31, 0x32, 0x33, 0x38, 0x39, 0x3d, 0x3e, 0x48, 0x49, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68, 0x69, 0xf4, 0xf7, + 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0x10d, 0x10e, 0x10f, + 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 0x119, 0x11a, 0x11b, + 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, + 0x155, 0x156, 0x157, 0x158, 0x159, 0x15a, 0x15b, 0x15c, 0x15d, + 0x1d0, 0x1d1, 0x1d2, 0x1d3, 0x1d4, 0x1d5, 0x1d6, 0x1d7, 0x1d8, 0x1d9, 0x1da, 0x1db, 0x1dc, 0x1dd, 0x1de, 0x1df, + 0x1e0, 0x1e1, 0x1e2, 0x1e3, 0x1e4, 0x1e5, 0x1e6, 0x1e7, 0x1e8, 0x1e9, 0x1ea, 0x1eb, 0x1ec, 0x1ed, 0x1ee, 0x1ef, + 0x1f0, 0x1f1, 0x1f2, 0x1f3, 0x1f4, 0x1f5, 0x1f6, 0x1f7, + 0x358, 0x359, 0x35a, 0x35b, 0x35c, 0x35d, 0x35e, 0x35f, + 0x360, 0x361, 0x362, 0x363, 0x364, 0x365, 0x366, 0x367, 0x368, 0x369, 0x36a, 0x36b, 0x36c, 0x36d, 0x36e, 0x36f, + 0x370, 0x371, 0x372, 0x373, 0x374, 0x375, 0x376, 0x377, 0x378, 0x379, 0x37a, 0x37b, 0x37c, 0x37d, 0x37e, 0x37f, + 0x380, 0x381, 0x382, 0x383, 0x384, 0x385, 0x386, 0x387, 0x388, 0x389, 0x38a, 0x38b, 0x38c, 0x38d, 0x38e, 0x38f, + 0x390, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e, 0x39f, + 0x3a0, 0x3a1, 0x3a2, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a8, 0x3a9, 0x3aa, 0x3ab, 0x3ac, 0x3ad, 0x3ae, 0x3af, + 0x3b0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7, 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf, + 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7, 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x3cc, 0x3cd, 0x3ce, 0x3cf, + 0x3d0, 0x3d1, 0x3d2, 0x3d3, 0x3d4, 0x3d5, 0x3d6, 0x3d7, 0x3d8, 0x3d9, 0x3da, 0x3db + }; /* keep efuse field only */ + +#ifdef MT7622_FPGA +REG_CHK_PAIR hif_dft_cr[] = { + {HIF_BASE + 0x00, 0xffffffff, 0x76030001}, + {HIF_BASE + 0x04, 0xffffffff, 0x1b}, + {HIF_BASE + 0x10, 0xffffffff, 0x3f01}, + {HIF_BASE + 0x20, 0xffffffff, 0xe01001e0}, + {HIF_BASE + 0x24, 0xffffffff, 0x1e00000f}, + + {HIF_BASE + 0x200, 0xffffffff, 0x0}, + {HIF_BASE + 0x204, 0xffffffff, 0x0}, + {HIF_BASE + 0x208, 0xffffffff, 0x10001870}, + {HIF_BASE + 0x20c, 0xffffffff, 0x0}, + {HIF_BASE + 0x210, 0xffffffff, 0x0}, + {HIF_BASE + 0x214, 0xffffffff, 0x0}, + {HIF_BASE + 0x218, 0xffffffff, 0x0}, + {HIF_BASE + 0x21c, 0xffffffff, 0x0}, + {HIF_BASE + 0x220, 0xffffffff, 0x0}, + {HIF_BASE + 0x224, 0xffffffff, 0x0}, + {HIF_BASE + 0x234, 0xffffffff, 0x0}, + {HIF_BASE + 0x244, 0xffffffff, 0x0}, + {HIF_BASE + 0x300, 0xffffffff, 0x0}, + {HIF_BASE + 0x304, 0xffffffff, 0x0}, + {HIF_BASE + 0x308, 0xffffffff, 0x0}, + {HIF_BASE + 0x30c, 0xffffffff, 0x0}, + {HIF_BASE + 0x310, 0xffffffff, 0x0}, + {HIF_BASE + 0x314, 0xffffffff, 0x0}, + {HIF_BASE + 0x318, 0xffffffff, 0x0}, + {HIF_BASE + 0x31c, 0xffffffff, 0x0}, + {HIF_BASE + 0x320, 0xffffffff, 0x0}, + {HIF_BASE + 0x324, 0xffffffff, 0x0}, + {HIF_BASE + 0x328, 0xffffffff, 0x0}, + {HIF_BASE + 0x32c, 0xffffffff, 0x0}, + {HIF_BASE + 0x330, 0xffffffff, 0x0}, + {HIF_BASE + 0x334, 0xffffffff, 0x0}, + {HIF_BASE + 0x338, 0xffffffff, 0x0}, + {HIF_BASE + 0x33c, 0xffffffff, 0x0}, + + {HIF_BASE + 0x400, 0xffffffff, 0x0}, + {HIF_BASE + 0x404, 0xffffffff, 0x0}, + {HIF_BASE + 0x408, 0xffffffff, 0x0}, + {HIF_BASE + 0x40c, 0xffffffff, 0x0}, + {HIF_BASE + 0x410, 0xffffffff, 0x0}, + {HIF_BASE + 0x414, 0xffffffff, 0x0}, + {HIF_BASE + 0x418, 0xffffffff, 0x0}, + {HIF_BASE + 0x41c, 0xffffffff, 0x0}, +}; + + +INT mt7622_chk_hif_default_cr_setting(RTMP_ADAPTER *pAd) +{ + UINT32 val; + INT i; + BOOLEAN match = TRUE; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): Default CR Setting Checking for HIF!\n", __func__)); + + for (i = 0; i < sizeof(hif_dft_cr) / sizeof(REG_CHK_PAIR); i++) { + RTMP_IO_READ32(pAd, hif_dft_cr[i].Register, &val); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t Reg(%x): Current=0x%x(0x%x), Default=0x%x, Mask=0x%x, Match=%s\n", + hif_dft_cr[i].Register, val, (val & hif_dft_cr[i].Mask), + hif_dft_cr[i].Value, hif_dft_cr[i].Mask, + ((val & hif_dft_cr[i].Mask) != hif_dft_cr[i].Value) ? "No" : "Yes")); + + if ((val & hif_dft_cr[i].Mask) != hif_dft_cr[i].Value) + match = FALSE; + } + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): Checking Done, Result=> %s match!\n", + __func__, match == TRUE ? "All" : "No")); + return match; +} + + +REG_CHK_PAIR top_dft_cr[] = { + {TOP_CFG_BASE + 0x1000, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1004, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1008, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1010, 0xffffffff, 0x0}, + + {TOP_CFG_BASE + 0x1100, 0xffffffff, 0x26110310}, + {TOP_CFG_BASE + 0x1108, 0x0000ff00, 0x1400}, + {TOP_CFG_BASE + 0x110c, 0x00000000, 0x0}, + {TOP_CFG_BASE + 0x1110, 0x0f0f00ff, 0x02090040}, + {TOP_CFG_BASE + 0x1124, 0xf000f00f, 0x00000008}, + {TOP_CFG_BASE + 0x1130, 0x000f0000, 0x0}, + {TOP_CFG_BASE + 0x1134, 0x00000000, 0x0}, + {TOP_CFG_BASE + 0x1140, 0x00ff00ff, 0x0}, + + {TOP_CFG_BASE + 0x1200, 0x00000000, 0x0}, + {TOP_CFG_BASE + 0x1204, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1208, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x120c, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1210, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1214, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1218, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x121c, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1220, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1224, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1228, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x122c, 0x000fffff, 0x0}, + {TOP_CFG_BASE + 0x1234, 0x00ffffff, 0x0}, + {TOP_CFG_BASE + 0x1238, 0x00ffffff, 0x0}, + {TOP_CFG_BASE + 0x123c, 0xffffffff, 0x5c1fee80}, + {TOP_CFG_BASE + 0x1240, 0xffffffff, 0x6874ae05}, + {TOP_CFG_BASE + 0x1244, 0xffffffff, 0x00fb89f1}, + + {TOP_CFG_BASE + 0x1300, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1304, 0xffffffff, 0x8f020006}, + {TOP_CFG_BASE + 0x1308, 0xffffffff, 0x18010000}, + {TOP_CFG_BASE + 0x130c, 0xffffffff, 0x0130484f}, + {TOP_CFG_BASE + 0x1310, 0xffffffff, 0xff000004}, + {TOP_CFG_BASE + 0x1314, 0xffffffff, 0xf0000084}, + {TOP_CFG_BASE + 0x1318, 0x00000000, 0x0}, + {TOP_CFG_BASE + 0x131c, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1320, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1324, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1328, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x132c, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1330, 0xffffffff, 0x00007800}, + {TOP_CFG_BASE + 0x1334, 0x00000000, 0x0}, + {TOP_CFG_BASE + 0x1338, 0xffffffff, 0x0000000a}, + {TOP_CFG_BASE + 0x1400, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1404, 0xffffffff, 0x00005180}, + {TOP_CFG_BASE + 0x1408, 0xffffffff, 0x00001f00}, + {TOP_CFG_BASE + 0x140c, 0xffffffff, 0x00000020}, + {TOP_CFG_BASE + 0x1410, 0xffffffff, 0x0000003a}, + {TOP_CFG_BASE + 0x141c, 0xffffffff, 0x0}, + + {TOP_CFG_BASE + 0x1500, 0xffffffff, 0x0}, + {TOP_CFG_BASE + 0x1504, 0xffffffff, 0x0}, +}; + +INT mt7622_chk_top_default_cr_setting(RTMP_ADAPTER *pAd) +{ + UINT32 val; + INT i; + BOOLEAN match = TRUE; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): Default CR Setting Checking for TOP!\n", __func__)); + + for (i = 0; i < sizeof(top_dft_cr) / sizeof(REG_CHK_PAIR); i++) { + RTMP_IO_READ32(pAd, top_dft_cr[i].Register, &val); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t Reg(%x): Current=0x%x(0x%x), Default=0x%x, Mask=0x%x, Match=%s\n", + top_dft_cr[i].Register, val, (val & top_dft_cr[i].Mask), + top_dft_cr[i].Value, top_dft_cr[i].Mask, + ((val & top_dft_cr[i].Mask) != top_dft_cr[i].Value) ? "No" : "Yes")); + + if ((val & top_dft_cr[i].Mask) != top_dft_cr[i].Value) + match = FALSE; + } + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): Checking Done, Result=> %s match!\n", + __func__, match == TRUE ? "All" : "No")); + return match; +} +#endif /* MT7622_FPGA */ + + +static VOID mt7622_bbp_adjust(RTMP_ADAPTER *pAd, UCHAR Channel) +{ + /*do nothing, change to use radio_resource control*/ + /*here should do bbp setting only, bbp is full-offload to fw*/ +} + + +/* TODO: Star */ +static void mt7622_switch_channel(RTMP_ADAPTER *pAd, MT_SWITCH_CHANNEL_CFG SwChCfg) +{ + MtCmdChannelSwitch(pAd, SwChCfg); + MtCmdSetTxRxPath(pAd, SwChCfg); + pAd->LatchRfRegs.Channel = SwChCfg.CentralChannel; +#ifdef SINGLE_SKU_V2 +#ifdef TXBF_SUPPORT +#ifdef MT_MAC +#if defined(MT7615) || defined(MT7622) + TxPowerBfBackoffParaCtrl(pAd, SwChCfg.Channel_Band, SwChCfg.ControlChannel, SwChCfg.BandIdx); +#endif /* defined(MT7615) || defined(MT7622) */ +#endif /*MT_MAC*/ +#endif /*TXBF_SUPPORT*/ +#endif /*SINGLE_SKU_V2*/ +} + +#ifdef NEW_SET_RX_STREAM +static INT mt7622_set_RxStream(RTMP_ADAPTER *pAd, UINT32 StreamNums, UCHAR BandIdx) +{ + UINT32 path = 0; + UINT i; + + if (StreamNums > 4) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s():illegal StreamNums(%d)\n", + __func__, StreamNums)); + StreamNums = 4; + } + + for (i = 0; i < StreamNums; i++) + path |= 1 << i; + + return MtCmdSetRxPath(pAd, path, BandIdx); +} +#endif + +static inline VOID bufferModeFieldSet(RTMP_ADAPTER *pAd, EXT_CMD_EFUSE_BUFFER_MODE_T *pCmd, UINT16 addr) +{ + UINT32 i = pCmd->ucCount; + pCmd->BinContent[i] = pAd->EEPROMImage[addr]; + pCmd->ucCount++; +} + + +static VOID mt7622_bufferModeEfuseFill(RTMP_ADAPTER *pAd, EXT_CMD_EFUSE_BUFFER_MODE_T *pCmd) +{ + UINT16 i = 0; + pCmd->ucCount = 0; + + for (i = 0x34; i <= 0x3DB; i++) + bufferModeFieldSet(pAd, pCmd, i); + + /*must minus last add*/ + pCmd->ucCount--; +} + + +static VOID mt7622_keep_efuse_field_only(RTMP_ADAPTER *pAd, UCHAR *buffer) +{ + UINT16 i = 0; + UINT16 offset = 0; + + for (i = 0; i < (sizeof(UNMASK)/sizeof(UINT32)); i++) { + offset = UNMASK[i]; + buffer[offset] = pAd->EEPROMImage[offset]; + } +} + + +#ifdef CAL_FREE_IC_SUPPORT +static UINT32 ICAL[] = {0x53, 0x54, 0x55, 0xf4, 0xf7, 0x144, 0x156, 0x15b}; +static UINT32 ICAL_NUM = (sizeof(ICAL) / sizeof(UINT32)); +static inline BOOLEAN check_valid(RTMP_ADAPTER *pAd, UINT16 Offset) +{ + UINT16 Value = 0; + BOOLEAN NotValid; + + if ((Offset % 2) != 0) { + NotValid = rtmp_ee_efuse_read16(pAd, Offset - 1, &Value); + + if (NotValid == FALSE) + return TRUE; + } else { + NotValid = rtmp_ee_efuse_read16(pAd, Offset, &Value); + + if (NotValid == FALSE) + return TRUE; + } + + return FALSE; +} +static BOOLEAN mt7622_is_cal_free_ic(RTMP_ADAPTER *pAd) +{ + UINT32 i; + + for (i = 0; i < ICAL_NUM; i++) + if (check_valid(pAd, ICAL[i]) == TRUE) + return TRUE; + + return FALSE; +} + +static inline VOID cal_free_data_get_from_addr(RTMP_ADAPTER *ad, UINT16 Offset) +{ + UINT16 value; + BOOLEAN NotValid; + + if ((Offset % 2) != 0) { + NotValid = rtmp_ee_efuse_read16(ad, Offset - 1, &value); + + if (NotValid == FALSE && ((value & 0xff00) != 0)) + ad->EEPROMImage[Offset] = (value >> 8) & 0xFF; + } else { + NotValid = rtmp_ee_efuse_read16(ad, Offset, &value); + + if (NotValid == FALSE && ((value & 0xff) != 0)) + ad->EEPROMImage[Offset] = value & 0xFF; + } +} + +static VOID mt7622_cal_free_data_get(RTMP_ADAPTER *ad) + +{ + UINT32 i; + + for (i = 0; i < ICAL_NUM; i++) + cal_free_data_get_from_addr(ad, ICAL[i]); +} +#endif /* CAL_FREE_IC_SUPPORT */ + +static INT32 mt7622_dma_shdl_init(RTMP_ADAPTER *pAd) +{ + UINT32 value; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + HIF_DMASHDL_IO_READ32(pAd, MT_HIF_DMASHDL_PKT_MAX_SIZE, &value); + value &= ~(PLE_PKT_MAX_SIZE_MASK | PSE_PKT_MAX_SIZE_MASK); + value |= PLE_PKT_MAX_SIZE_NUM(0x1); + value |= PSE_PKT_MAX_SIZE_NUM(0x8); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_PKT_MAX_SIZE, value); + + /* only enable group 0, 1, 2, 4, 5 */ + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_REFILL_CTRL, 0xffc80000); + value = DMASHDL_MIN_QUOTA_NUM(0x10); + value |= DMASHDL_MAX_QUOTA_NUM(0x800); + + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_GROUP0_CTRL, value); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_GROUP1_CTRL, value); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_GROUP2_CTRL, value); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_GROUP4_CTRL, value); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_GROUP5_CTRL, value); + + if ((cap->qm == GENERIC_QM) || (cap->qm == GENERIC_FAIR_QM)) { + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_Q_MAP0, 0x42104210); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_Q_MAP1, 0x42104210); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_Q_MAP2, 0x00000005); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_Q_MAP3, 0x0); + + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_SHDL_SET0, 0x6012345f); + HIF_DMASHDL_IO_WRITE32(pAd, MT_HIF_DMASHDL_SHDL_SET1, 0xedcba987); + } + + return TRUE; +} + + + +#ifdef CFG_SUPPORT_MU_MIMO +#ifdef MANUAL_MU +INT mu_update_profile_tb(RTMP_ADAPTER *pAd, INT profile_id, UCHAR wlan_id) +{ +} + +INT mu_update_grp_table(RTMP_ADAPTER *pAd, INT grp_id) +{ + return TRUE; +} + + +INT mu_update_cluster_tb(RTMP_ADAPTER *pAd, UCHAR c_id, UINT32 *m_ship, UINT32 *u_pos) +{ + UINT32 entry_base, mac_val, offset; + ASSERT(c_id <= 31); + MAC_IO_READ32(pAd, MU_MUCR1, &mac_val); + + if (c_id < 16) + mac_val &= (~MUCR1_CLUSTER_TAB_REMAP_CTRL_MASK); + else + mac_val |= MUCR1_CLUSTER_TAB_REMAP_CTRL_MASK; + + MAC_IO_WRITE32(pAd, MU_MUCR1, mac_val); + entry_base = MU_CLUSTER_TABLE_BASE + (c_id & (~0x10)) * 24; + /* update membership */ + MAC_IO_WRITE32(pAd, entry_base + 0x0, m_ship[0]); + MAC_IO_WRITE32(pAd, entry_base + 0x4, m_ship[1]); + /* Update user position */ + MAC_IO_WRITE32(pAd, entry_base + 0x8, u_pos[0]); + MAC_IO_WRITE32(pAd, entry_base + 0xc, u_pos[1]); + MAC_IO_WRITE32(pAd, entry_base + 0x10, u_pos[2]); + MAC_IO_WRITE32(pAd, entry_base + 0x14, u_pos[3]); + return TRUE; +} + + +INT mu_get_wlanId_ac_len(RTMP_ADAPTER *pAd, UINT32 wlan_id, UINT ac) +{ + return TRUE; +} + + +INT mu_get_mu_tx_retry_cnt(RTMP_ADAPTER *pAd) +{ + return TRUE; +} + + +INT mu_get_pfid_tx_stat(RTMP_ADAPTER *pAd) +{ +} + +INT mu_get_gpid_rate_per_stat(RTMP_ADAPTER *pAd) +{ + return TRUE; +} + + +INT mt7622_mu_init(RTMP_ADAPTER *pAd) +{ + UINT32 mac_val; + /**************************************************************************** + MU Part + ****************************************************************************/ + /* After power on initial setting, AC legnth clear */ + MAC_IO_READ32(pAd, MU_MUCR4, &mac_val); + mac_val = 0x1; + MAC_IO_WRITE32(pAd, MU_MUCR4, mac_val); /* 820fe010= 0x0000_0001 */ + /* PFID table */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0x0, 0x1e000); /* 820fe780= 0x0001_e000 */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0x4, 0x1e103); /* 820fe784= 0x0001_e103 */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0x8, 0x1e205); /* 820fe788= 0x0001_e205 */ + MAC_IO_WRITE32(pAd, MU_PROFILE_TABLE_BASE + 0xc, 0x1e306); /* 820fe78c= 0x0001_e306 */ + /* Cluster table */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x0, 0x0); /* 820fe400= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x8, 0x0); /* 820fe408= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x20, 0x2); /* 820fe420= 0x0000_0002 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x28, 0x0); /* 820fe428= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x40, 0x2); /* 820fe440= 0x0000_0002 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x48, 0x4); /* 820fe448= 0x0000_0004 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x60, 0x0); /* 820fe460= 0x0000_0000 */ + MAC_IO_WRITE32(pAd, MU_CLUSTER_TABLE_BASE + 0x68, 0x0); /* 820fe468= 0x0000_0000 */ + /* Group rate table */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0x0, 0x4109); /* 820ff000= 0x0000_4109 */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0x4, 0x99); /* 820ff004= 0x0000_0099 */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0x8, 0x800000f0); /* 820ff008= 0x8000_00f0 */ + MAC_IO_WRITE32(pAd, MU_GRP_TABLE_RATE_MAP + 0xc, 0x99); /* 820ff00c= 0x0000_0099 */ + /* SU Tx minimum setting */ + MAC_IO_WRITE32(pAd, MU_MUCR2, 0x10000001); /* 820fe008= 0x1000_0001 */ + /* MU max group search entry = 1 group entry */ + MAC_IO_WRITE32(pAd, MU_MUCR1, 0x0); /* 820fe004= 0x0000_0000 */ + /* MU enable */ + MAC_IO_READ32(pAd, MU_MUCR0, &mac_val); + mac_val |= 1; + MAC_IO_WRITE32(pAd, MU_MUCR0, 0x1); /* 820fe000= 0x1000_0001 */ + /**************************************************************************** + M2M Part + ****************************************************************************/ + /* Enable M2M MU temp mode */ + MAC_IO_READ32(pAd, RMAC_M2M_BAND_CTRL, &mac_val); + mac_val |= (1 << 16); + MAC_IO_WRITE32(pAd, RMAC_M2M_BAND_CTRL, mac_val); + /**************************************************************************** + AGG Part + ****************************************************************************/ + /* 820f20e0[15] = 1 or 0 all need to be verified, because + a). if primary is the fake peer, and peer will not ACK to us, cannot setup the TxOP + b). Or can use CTS2Self to setup the TxOP + */ + MAC_IO_READ32(pAd, AGG_MUCR, &mac_val); + mac_val &= (~MUCR_PRIM_BAR_MASK); + /* mac_val |= (1 << MUCR_PRIM_BAR_BIT); */ + MAC_IO_WRITE32(pAd, AGG_MUCR, mac_val); /* 820fe000= 0x1000_0001 */ + return TRUE; +} +#endif /* MANUAL_MU */ +#endif /* CFG_SUPPORT_MU_MIMO */ + +#ifndef MAC_INIT_OFFLOAD +#endif /* MAC_INIT_OFFLOAD */ + +/* need to confirm with DE, wilsonl */ +static VOID mt7622_init_mac_cr(RTMP_ADAPTER *pAd) +{ + UINT32 mac_val; + +#ifndef MAC_INIT_OFFLOAD + /* need to confirm with DE, wilsonl */ + /* done, confirmed by Austin */ + /* Set TxFreeEvent packet only go through CR4 */ + HW_IO_READ32(pAd, PLE_HIF_REPORT, &mac_val); + mac_val |= 0x1; + HW_IO_WRITE32(pAd, PLE_HIF_REPORT, mac_val); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): Set TxRxEventPkt path 0x%0x = 0x%08x\n", + __func__, PLE_HIF_REPORT, mac_val)); + + HW_IO_READ32(pAd, PP_PAGECTL_2, &mac_val); + mac_val &= ~(PAGECTL_2_CUT_PG_CNT_MASK); + mac_val |= 0x30; + HW_IO_WRITE32(pAd, PP_PAGECTL_2, mac_val); + +#if defined(COMPOS_WIN) || defined(COMPOS_TESTMODE_WIN) +#else + /* TxS Setting */ + InitTxSTypeTable(pAd); +#endif + MtAsicSetTxSClassifyFilter(pAd, TXS2HOST, TXS2H_QID1, TXS2HOST_AGGNUMS, 0x00, 0); +#endif /*MAC_INIT_OFFLOAD*/ + /* MAC D0 2x / MAC D0 1x clock enable */ + MAC_IO_READ32(pAd, CFG_CCR, &mac_val); + mac_val |= (BIT31 | BIT25); + MAC_IO_WRITE32(pAd, CFG_CCR, mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: MAC D0 2x 1x initial(val=%x)\n", __func__, mac_val)); + /* Disable RX Header Translation */ + MAC_IO_READ32(pAd, DMA_DCR0, &mac_val); + mac_val &= ~(DMA_DCR0_RX_HDR_TRANS_EN_BIT | DMA_DCR0_RX_HDR_TRANS_MODE_BIT | + DMA_DCR0_RX_RM_VLAN_BIT | DMA_DCR0_RX_INS_VLAN_BIT | + DMA_DCR0_RX_HDR_TRANS_CHK_BSSID); +#ifdef HDR_TRANS_RX_SUPPORT + + if (IS_ASIC_CAP(pAd, fASIC_CAP_RX_HDR_TRANS)) { + UINT32 mac_val2; + mac_val |= DMA_DCR0_RX_HDR_TRANS_EN_BIT | DMA_DCR0_RX_RM_VLAN_BIT | + DMA_DCR0_RX_HDR_TRANS_CHK_BSSID; + /* TODO: UnifiedSW, take care about Windows for translation mode! */ + /* mac_val |= DMA_DCR0_RX_HDR_TRANS_MODE_BIT; */ + MAC_IO_READ32(pAd, DMA_DCR1, &mac_val2); + mac_val2 |= RHTR_AMS_VLAN_EN; + MAC_IO_WRITE32(pAd, DMA_DCR1, mac_val2); + } + +#endif /* HDR_TRANS_RX_SUPPORT */ + MAC_IO_WRITE32(pAd, DMA_DCR0, mac_val); + /* CCA Setting */ + MAC_IO_READ32(pAd, TMAC_TRCR0, &mac_val); + mac_val &= ~CCA_SRC_SEL_MASK; + mac_val |= CCA_SRC_SEL(0x2); + mac_val &= ~CCA_SEC_SRC_SEL_MASK; + mac_val |= CCA_SEC_SRC_SEL(0x0); + MAC_IO_WRITE32(pAd, TMAC_TRCR0, mac_val); + MAC_IO_READ32(pAd, TMAC_TRCR0, &mac_val); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): TMAC_TRCR0=0x%x\n", __func__, mac_val)); + /* ---Add by shiang for MT7615 RFB ED issue */ + /* Set BAR rate as 0FDM 6M default, remove after fw set */ + MAC_IO_WRITE32(pAd, AGG_ACR0, 0x04b10496); + /*Add by Star for zero delimiter*/ + MAC_IO_READ32(pAd, TMAC_CTCR0, &mac_val); + mac_val &= ~INS_DDLMT_REFTIME_MASK; + mac_val |= INS_DDLMT_REFTIME(0x3f); + mac_val |= DUMMY_DELIMIT_INSERTION; + mac_val |= INS_DDLMT_DENSITY(3); + MAC_IO_WRITE32(pAd, TMAC_CTCR0, mac_val); + + /* Temporary setting for RTS */ + /*if no protect should enable for CTS-2-Self, WHQA_00025629*/ + MAC_IO_WRITE32(pAd, AGG_PCR1, 0x0400092b);/* sync MT7615 MP2.1 */ + MAC_IO_READ32(pAd, AGG_SCR, &mac_val); + mac_val |= NLNAV_MID_PTEC_DIS; + MAC_IO_WRITE32(pAd, AGG_SCR, mac_val); + + /*Default disable rf low power beacon mode*/ +#define WIFI_SYS_PHY 0x10000 +#define RF_LOW_BEACON_BAND0 (WIFI_SYS_PHY+0x1900) +#define RF_LOW_BEACON_BAND1 (WIFI_SYS_PHY+0x1d00) + PHY_IO_READ32(pAd, RF_LOW_BEACON_BAND0, &mac_val); + mac_val &= ~(0x3 << 8); + mac_val |= (0x2 << 8); + PHY_IO_WRITE32(pAd, RF_LOW_BEACON_BAND0, mac_val); + PHY_IO_READ32(pAd, RF_LOW_BEACON_BAND1, &mac_val); + mac_val &= ~(0x3 << 8); + mac_val |= (0x2 << 8); + PHY_IO_WRITE32(pAd, RF_LOW_BEACON_BAND1, mac_val); +} + + + + + +static VOID MT7622BBPInit(RTMP_ADAPTER *pAd) +{ + /* Disable PHY shaping filter for Japan Region */ + if (pAd->CommonCfg.RDDurRegion == JAP) + MtCmdPhyShapingFilterDisable(pAd); + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() todo\n", __func__)); +} + + +static void mt7622_init_rf_cr(RTMP_ADAPTER *ad) +{ +} + +/* Read power per rate */ +void mt7622_get_tx_pwr_per_rate(RTMP_ADAPTER *pAd) +{ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() todo\n", __func__)); +} + + +void mt7622_get_tx_pwr_info(RTMP_ADAPTER *pAd) +{ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() todo\n", __func__)); +} + + +static void mt7622_antenna_default_reset( + struct _RTMP_ADAPTER *pAd, + EEPROM_ANTENNA_STRUC *pAntenna) +{ + pAntenna->word = 0; + pAd->RfIcType = RFIC_7622; +#ifndef TXBF_SUPPORT + pAntenna->field.TxPath = 4; + pAntenna->field.RxPath = 4; +#else + pAntenna->field.TxPath = (pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET] >> 4) & 0x0F; + pAntenna->field.RxPath = pAd->EEPROMDefaultValue[EEPROM_NIC_CFG1_OFFSET] & 0x0F; +#endif /* TXBF_SUPPORT */ +} + + +static VOID mt7622_fw_prepare(RTMP_ADAPTER *pAd) +{ + struct fwdl_ctrl *ctrl = &pAd->MCUCtrl.fwdl_ctrl; + +#ifdef NEED_ROM_PATCH + /* Use E2 rom patch as default */ + ctrl->patch_profile[WM_CPU].source.header_ptr = mt7622_rom_patch_e2; + ctrl->patch_profile[WM_CPU].source.header_len = sizeof(mt7622_rom_patch_e2); + ctrl->patch_profile[WM_CPU].source.bin_name = MT7622_ROM_PATCH_BIN_FILE_NAME_E2; +#endif /* NEED_ROM_PATCH */ + + ctrl->fw_profile[WM_CPU].source.header_ptr = MT7622_FirmwareImage_E2; + ctrl->fw_profile[WM_CPU].source.header_len = sizeof(MT7622_FirmwareImage_E2); + ctrl->fw_profile[WM_CPU].source.bin_name = MT7622_RAM_BIN_FILE_NAME_E2; +} + +static VOID mt7622_fwdl_datapath_setup(RTMP_ADAPTER *pAd, BOOLEAN init) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + if (init == TRUE) { + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); + GloCfg.MT7622_field.fw_ring_bp_tx_sch = 1; + HIF_IO_WRITE32(pAd, MT_WPDMA_GLO_CFG, GloCfg.word); + + ops->pci_kick_out_cmd_msg = AndesMTPciKickOutCmdMsgFwDlRing; + } else { + ops->pci_kick_out_cmd_msg = AndesMTPciKickOutCmdMsg; + + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); + GloCfg.MT7622_field.fw_ring_bp_tx_sch = 0; + HIF_IO_WRITE32(pAd, MT_WPDMA_GLO_CFG, GloCfg.word); + } +} + + + + +#ifdef TXBF_SUPPORT +void mt7622_setETxBFCap( + IN RTMP_ADAPTER *pAd, + IN TXBF_STATUS_INFO * pTxBfInfo) +{ + HT_BF_CAP *pTxBFCap = pTxBfInfo->pHtTxBFCap; + + if (pTxBfInfo->cmmCfgETxBfEnCond > 0) { + switch (pTxBfInfo->cmmCfgETxBfEnCond) { + case SUBF_ALL: + default: + pTxBFCap->RxNDPCapable = TRUE; + pTxBFCap->TxNDPCapable = (pTxBfInfo->ucRxPathNum > 1) ? TRUE : FALSE; + pTxBFCap->ExpNoComSteerCapable = FALSE; + pTxBFCap->ExpComSteerCapable = TRUE;/* !pTxBfInfo->cmmCfgETxBfNoncompress; */ + pTxBFCap->ExpNoComBF = 0; /* HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->ExpComBF = + HT_ExBF_FB_CAP_IMMEDIATE;/* pTxBfInfo->cmmCfgETxBfNoncompress? HT_ExBF_FB_CAP_NONE: HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->MinGrouping = 3; + pTxBFCap->NoComSteerBFAntSup = 0; + pTxBFCap->ComSteerBFAntSup = 3; + pTxBFCap->TxSoundCapable = FALSE; /* Support staggered sounding frames */ + pTxBFCap->ChanEstimation = pTxBfInfo->ucRxPathNum - 1; + break; + + case SUBF_BFER: + pTxBFCap->RxNDPCapable = FALSE; + pTxBFCap->TxNDPCapable = (pTxBfInfo->ucRxPathNum > 1) ? TRUE : FALSE; + pTxBFCap->ExpNoComSteerCapable = FALSE; + pTxBFCap->ExpComSteerCapable = TRUE;/* !pTxBfInfo->cmmCfgETxBfNoncompress; */ + pTxBFCap->ExpNoComBF = 0; /* HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->ExpComBF = + HT_ExBF_FB_CAP_IMMEDIATE;/* pTxBfInfo->cmmCfgETxBfNoncompress? HT_ExBF_FB_CAP_NONE: HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->MinGrouping = 3; + pTxBFCap->NoComSteerBFAntSup = 0; + pTxBFCap->ComSteerBFAntSup = 3; + pTxBFCap->TxSoundCapable = FALSE; /* Support staggered sounding frames */ + pTxBFCap->ChanEstimation = pTxBfInfo->ucRxPathNum - 1; + break; + + case SUBF_BFEE: + pTxBFCap->RxNDPCapable = TRUE; + pTxBFCap->TxNDPCapable = FALSE; + pTxBFCap->ExpNoComSteerCapable = FALSE; + pTxBFCap->ExpComSteerCapable = TRUE;/* !pTxBfInfo->cmmCfgETxBfNoncompress; */ + pTxBFCap->ExpNoComBF = 0; /* HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->ExpComBF = + HT_ExBF_FB_CAP_IMMEDIATE;/* pTxBfInfo->cmmCfgETxBfNoncompress? HT_ExBF_FB_CAP_NONE: HT_ExBF_FB_CAP_IMMEDIATE; */ + pTxBFCap->MinGrouping = 3; + pTxBFCap->NoComSteerBFAntSup = 0; + pTxBFCap->ComSteerBFAntSup = 3; + pTxBFCap->TxSoundCapable = FALSE; /* Support staggered sounding frames */ + pTxBFCap->ChanEstimation = pTxBfInfo->ucRxPathNum - 1; + break; + } + } else + memset(pTxBFCap, 0, sizeof(*pTxBFCap)); +} + +#ifdef VHT_TXBF_SUPPORT +void mt7622_setVHTETxBFCap( + IN RTMP_ADAPTER *pAd, + IN TXBF_STATUS_INFO * pTxBfInfo) +{ + VHT_CAP_INFO *pTxBFCap = pTxBfInfo->pVhtTxBFCap; + + if (pTxBfInfo->cmmCfgETxBfIncapable) { + pTxBFCap->num_snd_dimension = 0; + pTxBFCap->bfee_cap_mu = 0; + pTxBFCap->bfee_cap_su = 0; + pTxBFCap->bfer_cap_mu = 0; + pTxBFCap->bfer_cap_su = 0; + pTxBFCap->bfee_sts_cap = 0; + } else { + pTxBFCap->bfee_cap_su = 1; + pTxBFCap->bfer_cap_su = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; + pTxBFCap->bfee_cap_mu = 1; + pTxBFCap->bfer_cap_mu = (pTxBfInfo->ucTxPathNum > 1) ? 1 : 0; + pTxBFCap->bfee_sts_cap = 3; + pTxBFCap->num_snd_dimension = pTxBfInfo->ucTxPathNum - 1; + } +} +#endif /* VHT_TXBF_SUPPORT */ +#endif /* TXBF_SUPPORT */ + +#ifdef HOST_RESUME_DONE_ACK_SUPPORT +static void mt7622_host_resume_done_ack( + struct _RTMP_ADAPTER *pAd) +{ + mt_cmd_host_resume_done_ack(pAd); +} +#endif /* HOST_RESUME_DONE_ACK_SUPPORT */ + +#ifdef RF_LOCKDOWN +static UINT32 ICAL[] = {0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68, 0x69, + 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87, + 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0, 0xa1, + 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4, + 0xf7, 0xff, 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, + 0x154, 0x155, 0x159, 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, + 0x16d, 0x16e, 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, + 0x186, 0x187, 0x18b, 0x18c + }; /* check and merge */ + +static UINT32 ICAL_NUM = (sizeof(ICAL) / sizeof(UINT32)); +static UINT32 ICAL_JUST_MERGE[] = {0x118, 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1, 0x3b2}; /* merge but nott check */ +static UINT32 ICAL_JUST_MERGE_NUM = (sizeof(ICAL_JUST_MERGE) / sizeof(UINT32)); + +static UINT32 RFLOCK[] = { 0x03F, 0x040, 0x041, 0x056, 0x057, 0x058, 0x059, 0x05A, 0x05B, 0x05C, 0x05D, 0x05E, 0x05F, 0x060, 0x061, 0x062, + 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06A, 0x06B, 0x06C, 0x06D, 0x06E, 0x06F, 0x070, 0x071, 0x072, + 0x073, 0x074, 0x075, 0x076, 0x077, 0x078, 0x079, 0x07A, 0x07B, 0x07C, 0x07D, 0x07E, 0x07F, 0x080, 0x081, 0x082, + 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089, 0x08A, 0x08B, 0x08C, 0x08D, 0x08E, 0x08F, 0x090, 0x091, 0x092, + 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09A, 0x09B, 0x09C, 0x09D, 0x09E, 0x09F, 0x0A0, 0x0A1, 0x0A2, + 0x0A3, 0x0A4, 0x0A5, 0x0A6, 0x0A7, 0x0A8, 0x0A9, 0x0AA, 0x0AB, 0x0AC, 0x0AD, 0x0AE, 0x0AF, 0x0B0, 0x0B1, 0x0B2, + 0x0B3, 0x0B4, 0x0B5, 0x0B6, 0x0B7, 0x0B8, 0x0B9, 0x0BA, 0x0BB, 0x0BC, 0x0BD, 0x0BE, 0x0BF, 0x0C0, 0x0C1, 0x0C2, + 0x0C3, 0x0C4, 0x0C5, 0x0C6, 0x0C7, 0x0C8, 0x0C9, 0x0CA, 0x0CB, 0x0CC, 0x0CD, 0x0CE, 0x0CF, 0x0D0, 0x0D1, 0x0D2, + 0x0D3, 0x0D4, 0x0D5, 0x0D6, 0x0D7, 0x0D8, 0x0D9, 0x0DA, 0x0DB, 0x0DC, 0x0DD, 0x0DE, 0x0DF, 0x0E0, 0x0E1, 0x0E2, + 0x0E3, 0x0E4, 0x0E5, 0x0E6, 0x0E7, 0x0E8, 0x0E9, 0x0EA, 0x0EB, 0x0EC, 0x0ED, 0x0EE, 0x0EF, 0x0F0, 0x0F2, 0x0F3, + 0x118, 0x11C, 0x11D, 0x11E, 0x11F, 0x12C, 0x12D, 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, 0x148, + 0x149, 0x14A, 0x14B, 0x14C, 0x14D, 0x14E, 0x14F, 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, 0x158, + 0x159, 0x15A, 0x15B, 0x15C, 0x15D, 0x15E, 0x15F, 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167, 0x168, + 0x169, 0x16A, 0x16B, 0x16C, 0x16D, 0x16E, 0x16F, 0x170, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0x177, 0x178, + 0x179, 0x17A, 0x17B, 0x17C, 0x17D, 0x17E, 0x17F, 0x180, 0x181, 0x182, 0x183, 0x184, 0x185, 0x186, 0x187, 0x188, + 0x189, 0x18A, 0x18B, 0x18C, 0x18D, 0x18E, 0x18F, 0x190, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, + 0x199, 0x19A, 0x19B, 0x19C, 0x19D, 0x19E, 0x19F, 0x1A0, 0x1A2, 0x1A3, 0x1A4, 0x1A5, 0x1A6, 0x1A7, 0x1A8, 0x1A9, + 0x1AA, 0x1AB, 0x1AC, 0x1AD, 0x1AE, 0x1AF, 0x1B0, 0x1B1, 0x1B2, 0x3AC, 0x3AD, 0x3AE, 0x3AF + }; + +static UINT32 RFLOCK_NUM = (sizeof(RFLOCK) / sizeof(UINT32)); + +static BOOLEAN mt7622_check_RF_lock_down(RTMP_ADAPTER *pAd) +{ + UCHAR block[EFUSE_BLOCK_SIZE] = ""; + USHORT offset = 0; + UINT isVaild = 0; + BOOL RFlockDown; + /* RF lock down column (0x12C) */ + offset = RF_LOCKDOWN_EEPROME_BLOCK_OFFSET; + MtCmdEfuseAccessRead(pAd, offset, &block[0], &isVaild); + + if (((block[RF_LOCKDOWN_EEPROME_COLUMN_OFFSET] & RF_LOCKDOWN_EEPROME_BIT) >> RF_LOCKDOWN_EEPROME_BIT_OFFSET) == TRUE) + RFlockDown = TRUE; + else + RFlockDown = FALSE; + + return RFlockDown; +} + +static BOOLEAN mt7622_write_RF_lock_parameter(RTMP_ADAPTER *pAd, USHORT offset) +{ + BOOLEAN RFParaWrite; + BOOLEAN fgRFlock = FALSE; + UINT16 RFlock_index = 0; +#ifdef CAL_FREE_IC_SUPPORT + BOOLEAN fgCalFree = FALSE; + UINT16 CalFree_index = 0; +#endif /* CAL_FREE_IC_SUPPORT */ + + /* Priority rule 1: RF lock paramter or not? */ + /* Priority rule 2: Apply cal free or not? */ + /* Priority rule 3: Cal free parameter or not? */ + + /* Check whether the offset exist in RF Lock Table or not */ + for (RFlock_index = pAd->RFlockTempIdx; RFlock_index < RFLOCK_NUM; RFlock_index++) { + if (RFLOCK[RFlock_index] == offset) { + fgRFlock = TRUE; + pAd->RFlockTempIdx = RFlock_index; + break; + } + } + +#ifdef CAL_FREE_IC_SUPPORT + + /* Check whether the offset exist in Cal Free Table or not */ + for (CalFree_index = pAd->CalFreeTempIdx; CalFree_index < ICAL_NUM; CalFree_index++) { + if (ICAL[CalFree_index] == offset) { + fgCalFree = TRUE; + pAd->CalFreeTempIdx = CalFree_index; + break; + } + } + + /* Check whether the offset exist in Cal Free (Merge but not check) Table or not */ + for (CalFree_index = 0; CalFree_index < ICAL_JUST_MERGE_NUM; CalFree_index++) { + if (ICAL_JUST_MERGE[CalFree_index] == offset) { + fgCalFree = TRUE; + break; + } + } + +#endif /* CAL_FREE_IC_SUPPORT */ + + /* Determine whether this offset needs to be written or not when RF lockdown */ + if (fgRFlock) { +#ifdef CAL_FREE_IC_SUPPORT + + if (pAd->fgCalFreeApply) { + if (fgCalFree) + RFParaWrite = FALSE; + else + RFParaWrite = TRUE; + } else + RFParaWrite = TRUE; + +#else + RFParaWrite = TRUE; +#endif + } else + RFParaWrite = FALSE; + + return RFParaWrite; +} + +static BOOLEAN mt7622_merge_RF_lock_parameter(RTMP_ADAPTER *pAd) +{ + UCHAR block[EFUSE_BLOCK_SIZE] = ""; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + USHORT length = cap->EEPROM_DEFAULT_BIN_SIZE; + UCHAR *ptr = pAd->EEPROMImage; + UCHAR index; + USHORT offset = 0; + UINT isVaild = 0; + BOOL WriteStatus; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + /* Merge RF parameters in Effuse to E2p buffer */ + if (chip_check_rf_lock_down(pAd)) { + /* Check Effuse Content block by block */ + for (offset = 0; offset < length; offset += EFUSE_BLOCK_SIZE) { + MtCmdEfuseAccessRead(pAd, offset, &block[0], &isVaild); + + /* Check the Needed contents are different and update the E2p content by Effuse */ + for (index = 0; index < EFUSE_BLOCK_SIZE; index++) { + /* Obtain the status of this E2p column need to write or not */ + WriteStatus = ops->write_RF_lock_parameter(pAd, offset + index); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("Effuse[0x%04x]: Write(%d)\n", offset + index, WriteStatus)); + + if ((block[index] != ptr[index]) && (WriteStatus)) + ptr[index] = block[index]; + else + continue; + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("index 0x%04x: ", offset + index)); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("orignal E2p value=0x%04x, write value=0x%04x\n", ptr[index], + block[index])); + } + + ptr += EFUSE_BLOCK_SIZE; + } + } + + return TRUE; +} + +static UCHAR mt7622_Read_Effuse_parameter(RTMP_ADAPTER *pAd, USHORT offset) +{ + UCHAR block[EFUSE_BLOCK_SIZE] = ""; + UINT isVaild = 0; + UINT16 BlockOffset, IndexOffset; + UCHAR RFUnlock = 0xFF; + /* Obtain corresponding BlockOffset and IndexOffset for Effuse contents access */ + IndexOffset = offset % EFUSE_BLOCK_SIZE; + BlockOffset = offset - IndexOffset; + + /* Merge RF parameters in Effuse to E2p buffer */ + if (chip_check_rf_lock_down(pAd)) { + /* Check Effuse Content block by block */ + MtCmdEfuseAccessRead(pAd, BlockOffset, &block[0], &isVaild); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Read Effuse[0x%x]: 0x%x ", offset, block[IndexOffset])); + return block[IndexOffset]; + } + + return RFUnlock; +} + +static BOOLEAN mt7622_Config_Effuse_Country(RTMP_ADAPTER *pAd) +{ + UCHAR Buffer0, Buffer1; + UCHAR CountryCode[2]; + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + /* Read Effuse Content */ + if (ops->Read_Effuse_parameter != NULL) { + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + /* Country Region 2G */ + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + Buffer0 = ops->Read_Effuse_parameter(pAd, COUNTRY_REGION_2G_EEPROME_OFFSET); + + /* Check the RF lock status */ + if (Buffer0 != 0xFF) { + /* Check Validation bit for content */ + if (((Buffer0) & (COUNTRY_REGION_VALIDATION_MASK)) >> (COUNTRY_REGION_VALIDATION_OFFSET)) + pAd->CommonCfg.CountryRegion = ((Buffer0) & (COUNTRY_REGION_CONTENT_MASK)); + } + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + /* Country Region 5G */ + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + Buffer1 = ops->Read_Effuse_parameter(pAd, COUNTRY_REGION_5G_EEPROME_OFFSET); + + /* Check the RF lock status */ + if (Buffer1 != 0xFF) { + /* Check Validation bit for content */ + if (((Buffer1) & (COUNTRY_REGION_VALIDATION_MASK)) >> (COUNTRY_REGION_VALIDATION_OFFSET)) + pAd->CommonCfg.CountryRegionForABand = ((Buffer1) & (COUNTRY_REGION_CONTENT_MASK)); + } + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + /* Country Code */ + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + CountryCode[0] = ops->Read_Effuse_parameter(pAd, COUNTRY_CODE_BYTE0_EEPROME_OFFSET); + CountryCode[1] = ops->Read_Effuse_parameter(pAd, COUNTRY_CODE_BYTE1_EEPROME_OFFSET); + + /* Check the RF lock status */ + if ((CountryCode[0] != 0xFF) && (CountryCode[1] != 0xFF)) { + /* Check Validation for content */ + if ((CountryCode[0] != 0x00) && (CountryCode[1] != 0x00)) { + pAd->CommonCfg.CountryCode[0] = CountryCode[0]; + pAd->CommonCfg.CountryCode[1] = CountryCode[1]; + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("pAd->CommonCfg.CountryCode[0]: 0x%x, %c ", + pAd->CommonCfg.CountryCode[0], pAd->CommonCfg.CountryCode[0])); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("pAd->CommonCfg.CountryCode[1]: 0x%x, %c ", + pAd->CommonCfg.CountryCode[1], pAd->CommonCfg.CountryCode[1])); + } + } + } + + return TRUE; +} +#endif /* RF_LOCKDOWN */ + +UCHAR *mt7622_get_default_bin_image(VOID) +{ +#if defined(CONFIG_FIRST_IF_IPAILNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use 1st iPAiLNA default bin.\n")); + return MT7622_E2PImage_iPAiLNA; +#elif defined(CONFIG_FIRST_IF_IPAELNA) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use 1st iPAeLNA default bin.\n")); + return MT7622_E2PImage_iPAeLNA; +#else + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use 1st ePAeLNA default bin.\n")); + return MT7622_E2PImage_ePAeLNA; +#endif + + return NULL; +} + +UCHAR *mt7622_get_default_bin_image_file(VOID) +{ + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Use 1st %s default bin.\n", DEFAULT_BIN_FILE)); + return DEFAULT_BIN_FILE; +} + +static INT hif_set_WPDMA(RTMP_ADAPTER *pAd, INT32 TxRx, BOOLEAN enable, UINT8 WPDMABurstSIZE) +{ + WPDMA_GLO_CFG_STRUC GloCfg; +#ifdef CONFIG_DELAY_INT + UINT32 Value; +#endif + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); +#ifdef CONFIG_DELAY_INT + HIF_IO_READ32(pAd, MT_DELAY_INT_CFG, &Value); +#endif + + switch (TxRx) { + case PDMA_TX: + if (enable == TRUE) { + GloCfg.MT7622_field.EnableTxDMA = 1; + GloCfg.MT7622_field.EnTXWriteBackDDONE = 1; + GloCfg.MT7622_field.WPDMABurstSIZE = WPDMABurstSIZE; + GloCfg.MT7622_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2_PREFETCH; +#ifdef CONFIG_DELAY_INT + Value |= TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value |= TX_MAX_PINT(TX_PENDING_INT_NUMS); + Value &= ~TX_MAX_PTIME_MASK; + Value |= TX_MAX_PTIME(TX_PENDING_INT_TIME); +#endif + } else { + GloCfg.MT7622_field.EnableTxDMA = 0; +#ifdef CONFIG_DELAY_INT + Value &= ~TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value &= ~TX_MAX_PTIME_MASK; +#endif + } + + break; + + case PDMA_RX: + if (enable == TRUE) { + GloCfg.MT7622_field.EnableRxDMA = 1; + GloCfg.MT7622_field.WPDMABurstSIZE = WPDMABurstSIZE; + GloCfg.MT7622_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2_PREFETCH; +#ifdef CONFIG_DELAY_INT + Value |= RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value |= RX_MAX_PINT(RX_PENDING_INT_NUMS); + Value &= ~RX_MAX_PTIME_MASK; + Value |= RX_MAX_PTIME(RX_PENDING_INT_TIME); +#endif + } else { + GloCfg.MT7622_field.EnableRxDMA = 0; +#ifdef CONFIG_DELAY_INT + Value &= ~RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value &= ~RX_MAX_PTIME_MASK; +#endif + } + + break; + + case PDMA_TX_RX: + if (enable == TRUE) { + GloCfg.MT7622_field.EnableTxDMA = 1; + GloCfg.MT7622_field.EnableRxDMA = 1; + GloCfg.MT7622_field.EnTXWriteBackDDONE = 1; + GloCfg.MT7622_field.WPDMABurstSIZE = WPDMABurstSIZE; + GloCfg.MT7622_field.multi_dma_en = MULTI_DMA_EN_FEATURE_2_PREFETCH; + +#ifdef CONFIG_DELAY_INT + Value |= TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value |= TX_MAX_PINT(TX_PENDING_INT_NUMS); + Value &= ~TX_MAX_PTIME_MASK; + Value |= TX_MAX_PTIME(TX_PENDING_INT_TIME); + Value |= RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value |= RX_MAX_PINT(RX_PENDING_INT_NUMS); + Value &= ~RX_MAX_PTIME_MASK; + Value |= RX_MAX_PTIME(RX_PENDING_INT_TIME); +#endif + } else { + GloCfg.MT7622_field.EnableRxDMA = 0; + GloCfg.MT7622_field.EnableTxDMA = 0; +#ifdef CONFIG_DELAY_INT + Value &= ~TX_DLY_INT_EN; + Value &= ~TX_MAX_PINT_MASK; + Value &= ~TX_MAX_PTIME_MASK; + Value &= ~RX_DLY_INT_EN; + Value &= ~RX_MAX_PINT_MASK; + Value &= ~RX_MAX_PTIME_MASK; +#endif + } + + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown path (%d\n", __func__, TxRx)); + break; + } + + HIF_IO_WRITE32(pAd, MT_WPDMA_GLO_CFG, GloCfg.word); +#ifdef CONFIG_DELAY_INT + HIF_IO_WRITE32(pAd, MT_DELAY_INT_CFG, Value); +#endif + +#define WPDMA_DISABLE -1 + + if (!enable) + TxRx = WPDMA_DISABLE; + + WLAN_HOOK_CALL(WLAN_HOOK_DMA_SET, pAd, &TxRx); + return TRUE; +} + +static BOOLEAN hif_wait_WPDMA_idle(struct _RTMP_ADAPTER *pAd, INT round, INT wait_us) +{ + INT i = 0; + + WPDMA_GLO_CFG_STRUC GloCfg; + /* TODO: shiang-MT7615 */ + do { + HIF_IO_READ32(pAd, MT_WPDMA_GLO_CFG, &GloCfg.word); + + if ((GloCfg.MT7622_field.TxDMABusy == 0) && (GloCfg.MT7622_field.RxDMABusy == 0)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_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); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("==> DMABusy\n")); + return FALSE; +} + +static BOOLEAN hif_reset_WPDMA(RTMP_ADAPTER *pAd) +{ + UINT32 value = 0; + + /* pdma0 hw reset (w/ dma scheduler) + activate: toggle (active low) + scope: PDMA + DMASCH + Tx/Rx FIFO + PDMA: + logic reset: Y + register reset: N (but DMA_IDX will be reset to 0) + DMASCH: + logic reset: Y + register reset: Y + */ + HIF_PDMA_IO_READ32(pAd, MT_HIF_SYS_SW_RST, &value); + value &= ~(HIF_DATA_PATH_RESET_N); + HIF_PDMA_IO_WRITE32(pAd, MT_HIF_SYS_SW_RST, value); + HIF_PDMA_IO_READ32(pAd, MT_HIF_SYS_SW_RST, &value); + value |= (HIF_DATA_PATH_RESET_N); + HIF_PDMA_IO_WRITE32(pAd, MT_HIF_SYS_SW_RST, value); + + return TRUE; +} + +static INT32 get_fw_sync_value(RTMP_ADAPTER *pAd) +{ + UINT32 value; + + RTMP_IO_READ32(pAd, TOP_OFF_RSV, &value); + value = (value & 0x00070000) >> 16; + + MTWF_LOG(DBG_CAT_FW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: current sync CR = 0x%x\n", __func__, value)); + return value; +} + +VOID mt7622_trigger_intr_to_mcu(BOOLEAN enable) +{ + unsigned long addr; + unsigned int value; + + addr = (unsigned long)ioremap(HIF_INTR_BASE, HIF_REMAP_SIZE); + RTMP_SYS_IO_READ32(addr, &value); + + /* write 0 to assert interrupt */ + if (enable == TRUE) + value &= ~HIF_INTR_VALUE; + else + value |= HIF_INTR_VALUE; + + RTMP_SYS_IO_WRITE32(addr, value); + iounmap((void *)addr); +} + +static VOID fw_own(RTMP_ADAPTER *pAd) +{ + UINT32 counter, value; + + if (pAd->bDrvOwn == FALSE) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s()::Return since already in Fw Own...\n", __func__)); + return; + } + + /* trigger hif interrupt to MCU */ + mt7622_trigger_intr_to_mcu(TRUE); + + /* Write any value to HIF_FUN_CAP to set FW own */ + HIF_IO_WRITE32(pAd, MT_CFG_LPCR_HOST, MT_HOST_SET_OWN); + + /* Poll driver own status */ + counter = 0; + + while (counter < FW_OWN_POLLING_COUNTER) { + RtmpusecDelay(1000); + HIF_IO_READ32(pAd, MT_CFG_LPCR_HOST, &value); + + if (value & MT_HOST_SET_OWN) { + pAd->bDrvOwn = FALSE; + break; + } + + counter++; + } + + mt7622_trigger_intr_to_mcu(FALSE); + + if (!pAd->bDrvOwn) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s()::Success to set FW Own\n", __func__)); + else + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s()::Fail to set FW Own (%d)\n", __func__, counter)); +} + +static INT32 driver_own(RTMP_ADAPTER *pAd) +{ + INT32 Ret = NDIS_STATUS_SUCCESS; + UINT32 counter, value; + + if (pAd->bDrvOwn == TRUE) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s()::Return since already in Driver Own...\n", __func__)); + return Ret; + } + + /* trigger hif interrupt to MCU */ + mt7622_trigger_intr_to_mcu(TRUE); + + /* Write CR to get driver own */ + HIF_IO_WRITE32(pAd, MT_CFG_LPCR_HOST, MT_HOST_CLR_OWN); + + /* Poll driver own status */ + counter = 0; + + while (counter < FW_OWN_POLLING_COUNTER) { + RtmpusecDelay(1000); + + /* polling case */ + HIF_IO_READ32(pAd, MT_CFG_LPCR_HOST, &value); + if (!(value & MT_HOST_SET_OWN)) { + pAd->bDrvOwn = TRUE; + break; + } + + /* interrupt case */ + if (pAd->bDrvOwn) + break; + + counter++; + } + + mt7622_trigger_intr_to_mcu(FALSE); + + if (pAd->bDrvOwn) + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s()::Success to clear Fw Own\n", __func__)); + else { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s()::Fail to clear Fw Own (%d)\n", __func__, counter)); + Ret = NDIS_STATUS_FAILURE; + } + + return Ret; +} + +void mt7622_heart_beat_check(RTMP_ADAPTER *pAd) +{ +#define HEART_BEAT_CHECK_PERIOD 30 +#define N9_HEART_BEAT_ADDR 0x2300 /* TOP_CONFIG_DUMMY_SER_RECOVER_RECORD, dummy CR, defined in N9 FW */ + UINT32 mac_val; + UINT8 n9_detect = FALSE; + RTMP_STRING *str = NULL; + + if ((pAd->Mlme.PeriodicRound % HEART_BEAT_CHECK_PERIOD) == 0) { + + if (pAd->heart_beat_stop == TRUE) + return; + + MAC_IO_READ32(pAd, N9_HEART_BEAT_ADDR, &mac_val); + + if (mac_val == pAd->pre_n9_heart_beat_cnt) + pAd->pre_n9_heart_beat_cnt = ~mac_val; + else if (~mac_val == pAd->pre_n9_heart_beat_cnt) + n9_detect = TRUE; + else + pAd->pre_n9_heart_beat_cnt = mac_val; + + if (n9_detect) + str = "N9 heart beat stop!!\n"; + + if (str != NULL) { + pAd->heart_beat_stop = TRUE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[%s]:%s", RtmpOsGetNetDevName(pAd->net_dev), str)); +#ifdef MT_FDB + show_fdb_n9_log(pAd, NULL); +#endif /* MT_FDB */ +#ifdef ERR_RECOVERY + ser_sys_reset(str); +#endif + } + } +} + + +#ifdef CONFIG_PROPRIETARY_DRIVER +#define EFUSE_NIC_CONFIG_1 0x36 +#define EFUSE_TSSI_MASK 0x20 +#define EFUSE_WIFI_CONFIG 0x3E +#define EFUSE_PA_LNA_MASK 0xC +#define EFUSE_PA_MASK 0x8 +#define EFUSE_PA_LNA_SHIFT 2 +#define EFUSE_PA_SHIFT 3 + +static INT32 mt7622_tssi_set(struct _RTMP_ADAPTER *ad, UCHAR *efuse) +{ + UCHAR *nic_cfg1 = &efuse[EFUSE_NIC_CONFIG_1 + 1]; + UCHAR mode = (*nic_cfg1 & EFUSE_TSSI_MASK) ? 1 : 0; + UCHAR *wifi_cfg = &efuse[EFUSE_WIFI_CONFIG]; + UCHAR pa_mode = (*wifi_cfg & EFUSE_PA_MASK) >> EFUSE_PA_SHIFT; + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): nic_cfg1=%x, mode=%d\n", __func__, *nic_cfg1, mode)); + if (pa_mode && mode) + return rbus_tssi_set(ad, mode); + else + return 0; +} + +static INT32 mt7622_pa_lna_set(struct _RTMP_ADAPTER *ad, UCHAR *efuse) +{ + UINT8 antCtrl = 0; + UINT8 polCtrl = 0; + UINT8 wifiConfig1, wifiConfig2, coexType, wifiPolarity1, wifiPolarity2; + UCHAR wifiStreams; + UINT32 efuse_settings = 0; + + wifiConfig1 = efuse[EFUSE_ANTENNA_CONFIG_POS1]; + wifiConfig2 = efuse[EFUSE_ANTENNA_CONFIG_POS2]; + coexType = efuse[EFUSE_ANTENNA_COEX_TYPE_POS]; + wifiPolarity1 = efuse[EFUSE_ANTENNA_POLARITY_POS1]; + wifiPolarity2 = efuse[EFUSE_ANTENNA_POLARITY_POS2]; + wifiStreams = efuse[EFUSE_ANTENNA_STREAMS_POS]; + + antCtrl |= GetGbandPaLna(wifiConfig1); + antCtrl |= ((GetFEMPowerSave(wifiConfig2)) << FEM_PWR_SAV_OFFSET); + antCtrl |= (GetStreams(wifiConfig2) << 2); + antCtrl |= ((GetCoex(coexType)) << COEX_TYPE_OFFSET); + antCtrl |= ((GetSmartAntMode(wifiConfig1)) << SMART_ANT_OFFSET); + antCtrl |= ((GetPIP(wifiConfig2)) << BT_PIP_OFFSET); + polCtrl |= (GetPolTRSWN(wifiPolarity1)); + polCtrl |= ((GetPolTRSWP(wifiPolarity1)) << POLARITY_TRSW_P_OFFSET); + polCtrl |= ((GetPolLNA(wifiPolarity1)) << POLARITY_LNA_OFFSET); + polCtrl |= ((GetPolPA(wifiPolarity1)) << POLARITY_PA_OFFSET); + polCtrl |= ((GetSAntpol(wifiPolarity2)) << SMART_ANT_POLARITY_OFFSET); + polCtrl |= ((GetPIPPol(wifiPolarity2)) << BT_PIP_POLARITY_OFFSET); + polCtrl |= ((GetVLINPol(wifiPolarity2)) << VLIN_LINEARITY_OFFSET); + polCtrl |= ((GetSharedPin(wifiPolarity2)) << SHARED_PIN_OFFSET); + efuse_settings |= (antCtrl | (polCtrl << 8) | (wifiStreams << 16)); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): read antCtrl = %d, polCtrl = %d, wifiStreams = %02x\n", __func__, antCtrl, polCtrl, wifiStreams)); + return rbus_pa_lna_set(ad, efuse_settings); +} + +#endif /*CONFIG_PROPRIETARY_DRIVER*/ + +static struct dly_ctl_cfg mt7622_rx_dly_ctl_ul_tbl[] = { + {0, 0x811c}, + {300, 0xa01c}, + {500, 0xc01f}, +}; + +static struct dly_ctl_cfg mt7622_rx_dly_ctl_dl_tbl[] = { + {0, 0x811c}, +}; + +static RTMP_CHIP_OP MT7622_ChipOp = {0}; +static RTMP_CHIP_CAP MT7622_ChipCap = {0}; + +static VOID mt7622_chipCap_init(void) +{ +#ifdef DOT11_VHT_AC + MT7622_ChipCap.max_vht_mcs = VHT_MCS_CAP_9; + MT7622_ChipCap.max_mpdu_len = MPDU_3895_OCTETS; + MT7622_ChipCap.vht_max_ampdu_len_exp = 7; +#ifdef G_BAND_256QAM + MT7622_ChipCap.g_band_256_qam = TRUE; +#endif +#endif /* DOT11_VHT_AC */ + MT7622_ChipCap.TXWISize = sizeof(TMAC_TXD_L); + MT7622_ChipCap.RXWISize = 28; + MT7622_ChipCap.tx_hw_hdr_len = MT7622_ChipCap.TXWISize; + MT7622_ChipCap.rx_hw_hdr_len = MT7622_ChipCap.RXWISize; + MT7622_ChipCap.num_of_tx_ring = 6; + MT7622_ChipCap.num_of_rx_ring = 2; + MT7622_ChipCap.tx_ring_size = 512; + MT7622_ChipCap.rx0_ring_size = 512; + MT7622_ChipCap.rx1_ring_size = 512; + MT7622_ChipCap.asic_caps = (fASIC_CAP_PMF_ENC | fASIC_CAP_MCS_LUT + | fASIC_CAP_CT | fASIC_CAP_HW_DAMSDU); +#ifdef RX_CUT_THROUGH + MT7622_ChipCap.asic_caps |= fASIC_CAP_BA_OFFLOAD; +#endif +#ifdef HDR_TRANS_TX_SUPPORT + MT7622_ChipCap.asic_caps |= fASIC_CAP_TX_HDR_TRANS; +#endif +#ifdef HDR_TRANS_RX_SUPPORT + MT7622_ChipCap.asic_caps |= fASIC_CAP_RX_HDR_TRANS; +#endif +#ifdef CONFIG_CSO_SUPPORT + MT7622_ChipCap.asic_caps |= fASIC_CAP_CSO; +#endif +#ifdef RX_SCATTER + MT7622_ChipCap.asic_caps |= fASIC_CAP_RX_DMA_SCATTER; +#endif + + MT7622_ChipCap.asic_caps |= fASIC_CAP_RX_DLY; + +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + MT7622_ChipCap.asic_caps &= ~fASIC_CAP_PCIE_ASPM_DYM_CTRL; +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ + + MT7622_ChipCap.phy_caps = (fPHY_CAP_24G | fPHY_CAP_HT | \ + fPHY_CAP_TXBF | fPHY_CAP_LDPC | \ + fPHY_CAP_BW40); + MT7622_ChipCap.hw_ops_ver = HWCTRL_OP_TYPE_V2; + MT7622_ChipCap.hif_type = HIF_MT; + MT7622_ChipCap.mac_type = MAC_MT; + MT7622_ChipCap.MCUType = ANDES; + MT7622_ChipCap.rf_type = RF_MT; + MT7622_ChipCap.pRFRegTable = NULL; + MT7622_ChipCap.pBBPRegTable = NULL; + MT7622_ChipCap.bbpRegTbSize = 0; + MT7622_ChipCap.MaxNumOfRfId = MAX_RF_ID; + MT7622_ChipCap.MaxNumOfBbpId = 200; + MT7622_ChipCap.WtblHwNum = MT7622_MT_WTBL_SIZE; + MT7622_ChipCap.FlgIsHwWapiSup = TRUE; + MT7622_ChipCap.FlgIsHwAntennaDiversitySup = FALSE; +#ifdef STREAM_MODE_SUPPORT + MT7622_ChipCap.FlgHwStreamMode = FALSE; +#endif +#ifdef TXBF_SUPPORT + MT7622_ChipCap.FlgHwTxBfCap = TXBF_HW_CAP; +#endif + MT7622_ChipCap.SnrFormula = SNR_FORMULA4; + MT7622_ChipCap.max_nss = 4; + /* todo Ellis */ +#ifdef RTMP_EFUSE_SUPPORT + MT7622_ChipCap.EFUSE_USAGE_MAP_START = 0x3c0; + MT7622_ChipCap.EFUSE_USAGE_MAP_END = 0x3fb; + MT7622_ChipCap.EFUSE_USAGE_MAP_SIZE = 60; + MT7622_ChipCap.EFUSE_RESERVED_SIZE = 59; /* Cal-Free is 22 free block */ +#endif + MT7622_ChipCap.EEPROM_DEFAULT_BIN = mt7622_get_default_bin_image(); + MT7622_ChipCap.EEPROM_DEFAULT_BIN_FILE = mt7622_get_default_bin_image_file(); + MT7622_ChipCap.EEPROM_DEFAULT_BIN_SIZE = sizeof(MT7622_E2PImage_ePAeLNA); + MT7622_ChipCap.EFUSE_BUFFER_CONTENT_SIZE = EFUSE_CONTENT_SIZE; +#ifdef CARRIER_DETECTION_SUPPORT + MT7622_ChipCap.carrier_func = TONE_RADAR_V2; +#endif +#ifdef RTMP_MAC_PCI + MT7622_ChipCap.WPDMABurstSIZE = 3; +#endif +#ifdef NEW_MBSSID_MODE +#ifdef ENHANCE_NEW_MBSSID_MODE + MT7622_ChipCap.MBSSIDMode = MBSSID_MODE4; +#else + MT7622_ChipCap.MBSSIDMode = MBSSID_MODE1; +#endif /* ENHANCE_NEW_MBSSID_MODE */ +#else + MT7622_ChipCap.MBSSIDMode = MBSSID_MODE0; +#endif /* NEW_MBSSID_MODE */ +#ifdef DOT11W_PMF_SUPPORT + /* sync with Ellis, wilsonl */ + MT7622_ChipCap.FlgPMFEncrtptMode = PMF_ENCRYPT_MODE_2; +#endif /* DOT11W_PMF_SUPPORT */ +#ifdef CONFIG_ANDES_SUPPORT +#ifdef NEED_ROM_PATCH + MT7622_ChipCap.need_load_patch = BIT(WM_CPU); +#else + MT7622_ChipCap.need_load_patch = 0; +#endif + MT7622_ChipCap.need_load_fw = BIT(WM_CPU); + MT7622_ChipCap.load_patch_flow = PATCH_FLOW_V1; + MT7622_ChipCap.load_fw_flow = FW_FLOW_V1; + MT7622_ChipCap.patch_format = PATCH_FORMAT_V1; + MT7622_ChipCap.fw_format = FW_FORMAT_V2; + MT7622_ChipCap.load_fw_method = BIT(HEADER_METHOD); + MT7622_ChipCap.load_patch_method = BIT(BIN_METHOD) | BIT(HEADER_METHOD); + MT7622_ChipCap.rom_patch_offset = MT7622_ROM_PATCH_START_ADDRESS; +#endif +#ifdef UNIFY_FW_CMD /* todo wilsonl */ + MT7622_ChipCap.cmd_header_len = sizeof(FW_TXD) + sizeof(TMAC_TXD_L); +#else + MT7622_ChipCap.cmd_header_len = 12; /* sizeof(FW_TXD) */ +#endif + MT7622_ChipCap.cmd_padding_len = 0; + MT7622_ChipCap.TxAggLimit = 64; + MT7622_ChipCap.RxBAWinSize = 64; + MT7622_ChipCap.ht_max_ampdu_len_exp = 3; +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + /* enabled later, wilsonl */ + MT7622_ChipCap.fgRateAdaptFWOffload = TRUE; +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + MT7622_ChipCap.WmmHwNum = MT7622_MT_WMM_SIZE; /* for multi-wmm */ + MT7622_ChipCap.PDA_PORT = MT7622_PDA_PORT; + MT7622_ChipCap.SupportAMSDU = TRUE; + /* sync with Pat, wilsonl */ + MT7622_ChipCap.APPSMode = APPS_MODE2; + MT7622_ChipCap.CtParseLen = MT7622_CT_PARSE_LEN; + MT7622_ChipCap.qm = GENERIC_QM; + MT7622_ChipCap.qm_tm = TASKLET_METHOD; + MT7622_ChipCap.hif_tm = TASKLET_METHOD; + MT7622_ChipCap.wmm_detect_method = WMM_DETECT_METHOD1; + + /* for interrupt enable mask */ + MT7622_ChipCap.int_enable_mask = MT_CoherentInt | MT_MacInt | MT_INT_RX_DLY | + MT_INT_T3_DONE | MT_INT_T15_DONE | MT_FW_CLR_OWN_INT; + + MT7622_ChipCap.hif_pkt_type[HIF_TX_IDX0] = TX_DATA; + MT7622_ChipCap.hif_pkt_type[HIF_TX_IDX1] = TX_DATA; + MT7622_ChipCap.hif_pkt_type[HIF_TX_IDX2] = TX_DATA; + MT7622_ChipCap.hif_pkt_type[HIF_TX_IDX3] = TX_FW_DL; + MT7622_ChipCap.hif_pkt_type[HIF_TX_IDX4] = TX_DATA; + MT7622_ChipCap.hif_pkt_type[HIF_TX_IDX5] = TX_ALTX; + MT7622_ChipCap.hif_pkt_type[HIF_TX_IDX15] = TX_CMD; +#if defined(ERR_RECOVERY) || defined(CONFIG_FWOWN_SUPPORT) + MT7622_ChipCap.int_enable_mask |= MT_McuCommand; +#endif /* ERR_RECOVERY || CONFIG_FWOWN_SUPPORT */ +#ifdef INTERNAL_CAPTURE_SUPPORT + MT7622_ChipCap.pICapDesc = MT7622_ICAP_DESC; + MT7622_ChipCap.ICapBankNum = MT7622_ICapBankNum; + MT7622_ChipCap.ICapADCIQCnt = MT7622_ICAP_FOUR_WAY_ADC_IQ_DATA_CNT; + MT7622_ChipCap.ICapIQCIQCnt = MT7622_ICAP_FOUR_WAY_IQC_IQ_DATA_CNT; + MT7622_ChipCap.ICapBankSmplCnt = MT7622_ICAP_BANK_SAMPLE_CNT; + MT7622_ChipCap.ICapFourWayADC = MT7622_CAP_FOUR_WAY_ADC; + MT7622_ChipCap.ICapFourWayFIIQ = MT7622_CAP_FOUR_WAY_FIIQ; + MT7622_ChipCap.ICapFourWayFDIQ = MT7622_CAP_FOUR_WAY_FDIQ; +#endif /* INTERNAL_CAPTURE_SUPPORT */ +#ifdef WIFI_SPECTRUM_SUPPORT + MT7622_ChipCap.pSpectrumDesc = MT7622_SPECTRUM_DESC; + MT7622_ChipCap.SpectrumBankNum = MT7622_SpectrumBankNum; + MT7622_ChipCap.SpectrumWF0ADC = MT7622_CAP_WF0_ADC; + MT7622_ChipCap.SpectrumWF1ADC = MT7622_CAP_WF1_ADC; + MT7622_ChipCap.SpectrumWF2ADC = MT7622_CAP_WF2_ADC; + MT7622_ChipCap.SpectrumWF3ADC = MT7622_CAP_WF3_ADC; + MT7622_ChipCap.SpectrumWF0FIIQ = MT7622_CAP_WF0_FIIQ; + MT7622_ChipCap.SpectrumWF1FIIQ = MT7622_CAP_WF1_FIIQ; + MT7622_ChipCap.SpectrumWF2FIIQ = MT7622_CAP_WF2_FIIQ; + MT7622_ChipCap.SpectrumWF3FIIQ = MT7622_CAP_WF3_FIIQ; + MT7622_ChipCap.SpectrumWF0FDIQ = MT7622_CAP_WF0_FDIQ; + MT7622_ChipCap.SpectrumWF1FDIQ = MT7622_CAP_WF1_FDIQ; + MT7622_ChipCap.SpectrumWF2FDIQ = MT7622_CAP_WF2_FDIQ; + MT7622_ChipCap.SpectrumWF3FDIQ = MT7622_CAP_WF3_FDIQ; +#endif /* WIFI_SPECTRUM_SUPPORT */ + MT7622_ChipCap.band_cnt = 1; +#ifdef COEX_SUPPORT + MT7622_ChipCap.TxBAWinSize = 64; +#endif /* COEX_SUPPORT*/ + MT7622_ChipCap.ba_range = mt7622_ba_range; + MT7622_ChipCap.txd_type = TXD_V1; + MT7622_ChipCap.tx_delay_support = TRUE; +} + +static VOID mt7622_chipOp_init(void) +{ + MT7622_ChipOp.AsicRfInit = mt7622_init_rf_cr; + MT7622_ChipOp.AsicBbpInit = MT7622BBPInit; + MT7622_ChipOp.AsicMacInit = mt7622_init_mac_cr; + MT7622_ChipOp.AsicReverseRfFromSleepMode = NULL; + MT7622_ChipOp.AsicHaltAction = NULL; + /* BBP adjust */ + MT7622_ChipOp.ChipBBPAdjust = mt7622_bbp_adjust; + /* AGC */ + MT7622_ChipOp.ChipSwitchChannel = mt7622_switch_channel; +#ifdef NEW_SET_RX_STREAM + MT7622_ChipOp.ChipSetRxStream = mt7622_set_RxStream; +#endif + MT7622_ChipOp.AsicAntennaDefaultReset = mt7622_antenna_default_reset; +#ifdef CAL_FREE_IC_SUPPORT + /* do not need, turn off compile flag, wilsonl */ + MT7622_ChipOp.is_cal_free_ic = mt7622_is_cal_free_ic; + MT7622_ChipOp.cal_free_data_get = mt7622_cal_free_data_get; +#endif /* CAL_FREE_IC_SUPPORT */ +#ifdef CARRIER_DETECTION_SUPPORT + MT7622_ChipOp.ToneRadarProgram = ToneRadarProgram_v2; +#endif + MT7622_ChipOp.DisableTxRx = NULL; /* 302 */ +#ifdef RTMP_PCI_SUPPORT + /* sync with Pat, Hammin, wilsonl */ + /* MT7622_ChipOp.AsicRadioOn = RT28xxPciAsicRadioOn; */ + /* MT7622_ChipOp.AsicRadioOff = RT28xxPciAsicRadioOff; */ +#endif +#ifdef RF_LOCKDOWN + MT7622_ChipOp.check_RF_lock_down = mt7622_check_RF_lock_down; + MT7622_ChipOp.write_RF_lock_parameter = mt7622_write_RF_lock_parameter; + MT7622_ChipOp.merge_RF_lock_parameter = mt7622_merge_RF_lock_parameter; + MT7622_ChipOp.Read_Effuse_parameter = mt7622_Read_Effuse_parameter; + MT7622_ChipOp.Config_Effuse_Country = mt7622_Config_Effuse_Country; +#endif /* RF_LOCKDOWN */ +#ifdef MT_WOW_SUPPORT + /* do not need, turn off compile flag, wilsonl */ + MT7622_ChipOp.AsicWOWEnable = MT76xxAndesWOWEnable; + MT7622_ChipOp.AsicWOWDisable = MT76xxAndesWOWDisable; + /* MT7622_ChipOp.AsicWOWInit = MT76xxAndesWOWInit, */ +#endif /* MT_WOW_SUPPORT */ + MT7622_ChipOp.show_pwr_info = NULL; + MT7622_ChipOp.bufferModeEfuseFill = mt7622_bufferModeEfuseFill; + /* For MT7622 keep efuse field only */ + MT7622_ChipOp.keep_efuse_field_only = mt7622_keep_efuse_field_only; + MT7622_ChipOp.MtCmdTx = MtCmdSendMsg; + MT7622_ChipOp.prepare_fwdl_img = mt7622_fw_prepare; + MT7622_ChipOp.fwdl_datapath_setup = mt7622_fwdl_datapath_setup; +#ifdef TXBF_SUPPORT + MT7622_ChipOp.TxBFInit = mt_WrapTxBFInit; + MT7622_ChipOp.ClientSupportsETxBF = mt_WrapClientSupportsETxBF; + MT7622_ChipOp.iBFPhaseComp = mt7622_iBFPhaseComp; + MT7622_ChipOp.iBFPhaseCalInit = mt7622_iBFPhaseCalInit; + MT7622_ChipOp.iBFPhaseFreeMem = mt7622_iBFPhaseFreeMem; + MT7622_ChipOp.iBFPhaseCalE2PUpdate = mt7622_iBFPhaseCalE2PUpdate; + MT7622_ChipOp.iBFPhaseCalReport = mt7622_iBFPhaseCalReport; + MT7622_ChipOp.setETxBFCap = mt7622_setETxBFCap; + MT7622_ChipOp.BfStaRecUpdate = mt_AsicBfStaRecUpdate; + MT7622_ChipOp.BfStaRecRelease = mt_AsicBfStaRecRelease; + MT7622_ChipOp.BfPfmuMemAlloc = CmdPfmuMemAlloc; + MT7622_ChipOp.BfPfmuMemRelease = CmdPfmuMemRelease; + MT7622_ChipOp.TxBfTxApplyCtrl = CmdTxBfTxApplyCtrl; + MT7622_ChipOp.BfApClientCluster = CmdTxBfApClientCluster; + MT7622_ChipOp.BfHwEnStatusUpdate = CmdTxBfHwEnableStatusUpdate; + MT7622_ChipOp.BfeeHwCtrl = CmdTxBfeeHwCtrl; + MT7622_ChipOp.BfModuleEnCtrl = NULL; +#endif /* TXBF_SUPPORT */ +#ifdef GREENAP_SUPPORT + MT7622_ChipOp.EnableAPMIMOPS = enable_greenap; + MT7622_ChipOp.DisableAPMIMOPS = disable_greenap; +#endif /* GREENAP_SUPPORT */ +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + MT7622_ChipOp.pcie_aspm_dym_ctrl = NULL; +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ +#ifdef INTERNAL_CAPTURE_SUPPORT + MT7622_ChipOp.ICapStart = MtCmdRfTestICapStart; + MT7622_ChipOp.ICapStatus = MtCmdRfTestGen2ICapStatus; + MT7622_ChipOp.ICapCmdRawDataProc = MtCmdRfTestICapRawDataProc; + MT7622_ChipOp.ICapGetIQData = Get_RBIST_IQ_Data; + MT7622_ChipOp.ICapEventRawDataHandler = ExtEventICap96BitRawDataHandler; +#endif /* INTERNAL_CAPTURE_SUPPORT */ +#ifdef WIFI_SPECTRUM_SUPPORT + MT7622_ChipOp.SpectrumStart = MtCmdWifiSpectrumStart; + MT7622_ChipOp.SpectrumStatus = MtCmdWifiSpectrumGen2Status; + MT7622_ChipOp.SpectrumCmdRawDataProc = MtCmdWifiSpectrumRawDataProc; + MT7622_ChipOp.SpectrumEventRawDataHandler = ExtEventWifiSpectrumRawDataHandler; +#endif /* WIFI_SPECTRUM_SUPPORT */ + MT7622_ChipOp.dma_shdl_init = mt7622_dma_shdl_init; +#ifdef SMART_CARRIER_SENSE_SUPPORT + MT7622_ChipOp.SmartCarrierSense = SmartCarrierSense_Gen3; + MT7622_ChipOp.ChipSetSCS = SetSCS; +#endif /* SMART_CARRIER_SENSE_SUPPORT */ +#ifdef MT7622_FPGA + MT7622_ChipOp.chk_hif_default_cr_setting = mt7622_chk_hif_default_cr_setting; + MT7622_ChipOp.chk_top_default_cr_setting = mt7622_chk_top_default_cr_setting +#endif +#ifdef HOST_RESUME_DONE_ACK_SUPPORT + MT7622_ChipOp.HostResumeDoneAck = mt7622_host_resume_done_ack; +#endif /* HOST_RESUME_DONE_ACK_SUPPORT */ + MT7622_ChipOp.hif_set_dma = hif_set_WPDMA; + MT7622_ChipOp.hif_wait_dma_idle = hif_wait_WPDMA_idle; + MT7622_ChipOp.hif_reset_dma = hif_reset_WPDMA; + MT7622_ChipOp.get_fw_sync_value = get_fw_sync_value; + MT7622_ChipOp.read_chl_pwr = NULL; + MT7622_ChipOp.parse_RXV_packet = parse_RXV_packet_v2; + MT7622_ChipOp.txs_handler = txs_handler_v2; + MT7622_ChipOp.driver_own = driver_own; + MT7622_ChipOp.fw_own = fw_own; +#ifdef CONFIG_PROPRIETARY_DRIVER + MT7622_ChipOp.tssi_set = mt7622_tssi_set; + MT7622_ChipOp.pa_lna_set = mt7622_pa_lna_set; +#endif /*CONFIG_PROPRIETARY_DRIVER*/ + MT7622_ChipOp.heart_beat_check = mt7622_heart_beat_check; +} + + +VOID mt7622_init(RTMP_ADAPTER *pAd) +{ + RTMP_CHIP_CAP *pChipCap = hc_get_chip_cap(pAd->hdev_ctrl); + struct _RTMP_CHIP_DBG *chip_dbg = hc_get_chip_dbg(pAd->hdev_ctrl); + struct tr_delay_control *tr_delay_ctl = &pAd->tr_ctl.tr_delay_ctl; + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s()-->\n", __func__)); + mt7622_chipCap_init(); + mt7622_chipOp_init(); + NdisMoveMemory(pChipCap, &MT7622_ChipCap, sizeof(RTMP_CHIP_CAP)); + hc_register_chip_ops(pAd->hdev_ctrl, &MT7622_ChipOp); +#if defined(COMPOS_WIN) || defined(COMPOS_TESTMODE_WIN) +#else + Mt7622AsicArchOpsInit(pAd); +#endif + mt7622_chip_dbg_init(chip_dbg); + mt_phy_probe(pAd); + RTMP_DRS_ALG_INIT(pAd, RATE_ALG_AGBS); + /* Following function configure beacon related parameters in pChipCap + * FlgIsSupSpecBcnBuf / BcnMaxHwNum / WcidHwRsvNum / BcnMaxHwSize / BcnBase[] + */ + /* sync with Cater, wilsonl */ + mt_chip_bcn_parameter_init(pAd); + /* sync with Cater, wilsonl */ + pChipCap->OmacNums = 5; + pChipCap->BssNums = 4; + pChipCap->ExtMbssOmacStartIdx = 0x10; + pChipCap->RepeaterStartIdx = 0x20; +#ifdef AIR_MONITOR + pChipCap->MaxRepeaterNum = 16; +#else + pChipCap->MaxRepeaterNum = 32; +#endif /* AIR_MONITOR */ +#ifdef BCN_OFFLOAD_SUPPORT + pChipCap->fgBcnOffloadSupport = TRUE; + pChipCap->fgIsNeedPretbttIntEvent = FALSE; +#endif + /* TMR HW version */ + pChipCap->TmrHwVer = TMR_VER_2_0; + + /* For calibration log buffer size limitation issue */ + pAd->fgQAtoolBatchDumpSupport = TRUE; +#ifdef RED_SUPPORT + pAd->red_have_cr4 = FALSE; +#endif /* RED_SUPPORT */ + pAd->cp_have_cr4 = FALSE; +#ifdef CONFIG_AP_SUPPORT + /*VOW CR Address offset - Gen_2*/ + pAd->vow_gen.VOW_GEN = VOW_GEN_2; +#endif /* #ifdef CONFIG_AP_SUPPORT */ + tr_delay_ctl->ul_rx_dly_ctl_tbl = mt7622_rx_dly_ctl_ul_tbl; + tr_delay_ctl->ul_rx_dly_ctl_tbl_size = (sizeof(mt7622_rx_dly_ctl_ul_tbl) / sizeof(mt7622_rx_dly_ctl_ul_tbl[0])); + tr_delay_ctl->dl_rx_dly_ctl_tbl = mt7622_rx_dly_ctl_dl_tbl; + tr_delay_ctl->dl_rx_dly_ctl_tbl_size = (sizeof(mt7622_rx_dly_ctl_dl_tbl) / sizeof(mt7622_rx_dly_ctl_dl_tbl[0])); + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<--%s()\n", __func__)); +} + +#ifdef COEX_SUPPORT +void mt7622_antenna_sel_cfg(RTMP_ADAPTER *pAd) +{ + + UINT8 antCtrl = 0; + UINT8 polCtrl = 0; + UINT8 wifiConfig1, wifiConfig2, coexType, wifiPolarity1, wifiPolarity2; + UINT16 value = 0; + UCHAR wifiStreams; + + if (pAd->eeprom_type == EEPROM_EFUSE) { + /* WiFi_Config/Polarity Setting read for Antenna Selection Configuraiton*/ + rtmp_ee_efuse_read16(pAd, EFUSE_ANTENNA_CONFIG_POS1, &value); + wifiConfig1 = (UCHAR)(value & 0x00FF); + + rtmp_ee_efuse_read16(pAd, (EFUSE_ANTENNA_CONFIG_POS2-1), &value); + wifiConfig2 = (UCHAR)((value >> 8) & 0x00FF); + + rtmp_ee_efuse_read16(pAd, EFUSE_ANTENNA_COEX_TYPE_POS, &value); + coexType = (UCHAR)(value & 0x00FF); + + rtmp_ee_efuse_read16(pAd, EFUSE_ANTENNA_POLARITY_POS1, &value); + wifiPolarity1 = (UCHAR)(value & 0x00FF); + wifiPolarity2 = (UCHAR)((value >> 8) & 0x00FF); /* EFUSE_ANTENNA_POLARITY_POS2 */ + + rtmp_ee_efuse_read16(pAd, EFUSE_ANTENNA_STREAMS_POS, &value); + wifiStreams = (UCHAR)(value & 0x00FF); + } else if (pAd->eeprom_type == EEPROM_FLASH) { + wifiConfig1 = (pAd->EEPROMImage[EFUSE_ANTENNA_CONFIG_POS1]); + wifiConfig2 = (pAd->EEPROMImage[EFUSE_ANTENNA_CONFIG_POS2]); + coexType = (pAd->EEPROMImage[EFUSE_ANTENNA_COEX_TYPE_POS]); + wifiPolarity1 = (pAd->EEPROMImage[EFUSE_ANTENNA_POLARITY_POS1]); + wifiPolarity2 = (pAd->EEPROMImage[EFUSE_ANTENNA_POLARITY_POS2]); + wifiStreams = (pAd->EEPROMImage[EFUSE_ANTENNA_STREAMS_POS]); + } + + antCtrl |= GetStreams(wifiConfig2); + antCtrl |= ((GetFEMPowerSave(wifiConfig2)) << FEM_PWR_SAV_OFFSET); + antCtrl |= ((GetGbandPaLna(wifiConfig1)) << PA_LNA_CFG_OFFSET); + antCtrl |= ((GetCoex(coexType)) << COEX_TYPE_OFFSET); + antCtrl |= ((GetSmartAntMode(wifiConfig1)) << SMART_ANT_OFFSET); + antCtrl |= ((GetPIP(wifiConfig2)) << BT_PIP_OFFSET); + polCtrl |= (GetPolTRSWN(wifiPolarity1)); + polCtrl |= ((GetPolTRSWP(wifiPolarity1)) << POLARITY_TRSW_P_OFFSET); + polCtrl |= ((GetPolLNA(wifiPolarity1)) << POLARITY_LNA_OFFSET); + polCtrl |= ((GetPolPA(wifiPolarity1)) << POLARITY_PA_OFFSET); + polCtrl |= ((GetSAntpol(wifiPolarity2)) << SMART_ANT_POLARITY_OFFSET); + polCtrl |= ((GetPIPPol(wifiPolarity2)) << BT_PIP_POLARITY_OFFSET); + polCtrl |= ((GetVLINPol(wifiPolarity2)) << VLIN_LINEARITY_OFFSET); + polCtrl |= ((GetSharedPin(wifiPolarity2)) << SHARED_PIN_OFFSET); + MTWF_LOG(DBG_CAT_INIT, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("read antCtrl = %d, polCtrl = %d \n", antCtrl, polCtrl)); + mt7622_pin_mux_control_setup(pAd, antCtrl, polCtrl, wifiStreams); +} + + +/**************************************************************************************************************** + * Function: _mt7668_pin_mux_control_setup + * Purpose: + * 1. This function select pin mux for specified properties and used antenna pins. + ****************************************************************************************************************/ +void mt7622_pin_mux_control_setup(RTMP_ADAPTER *pAd, UCHAR antCtrl, UCHAR polCtrl, UCHAR wifiStreams) +{ + UINT32 usedPins; + UINT32 regAonVal; + /* Get used pin. */ + usedPins = mt7622_antsel_get_used_pin(pAd, antCtrl, polCtrl, wifiStreams); + + /* Set pin mux for ANTSEL_0, ANTSEL_1, ANTSEL_2 , ANT_SEL_3, ANT_SEL_7, ANT_SEL_8, ANT_SEL_9, ANT_SEL_10 */ + + regAonVal = mt7622_gpio_get(GPIO_GPIO_MODE9); + + if (usedPins & BIT(ANT_SEL_0)) { + regAonVal &= ~GPIO91_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO91_MODE_OFFSET) & GPIO91_MODE); + } + if (usedPins & BIT(ANT_SEL_1)) { + regAonVal &= ~GPIO92_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO92_MODE_OFFSET) & GPIO92_MODE); + } + if (usedPins & BIT(ANT_SEL_2)) { + regAonVal &= ~GPIO93_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO93_MODE_OFFSET) & GPIO93_MODE); + } + if (usedPins & BIT(ANT_SEL_3)) { + regAonVal &= ~GPIO94_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO94_MODE_OFFSET) & GPIO94_MODE); + } + + if (usedPins & BIT(ANT_SEL_7)) { + regAonVal &= ~GPIO98_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO98_MODE_OFFSET) & GPIO98_MODE); + } + if (usedPins & BIT(ANT_SEL_8)) { + regAonVal &= ~GPIO99_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO99_MODE_OFFSET) & GPIO99_MODE); + } + if (usedPins & BIT(ANT_SEL_9)) { + regAonVal &= ~GPIO100_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO100_MODE_OFFSET) & GPIO100_MODE); + } + if (usedPins & BIT(ANT_SEL_10)) { + regAonVal &= ~GPIO101_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO101_MODE_OFFSET) & GPIO101_MODE); + } + + mt7622_gpio_set(GPIO_GPIO_MODE9, regAonVal); + + /* Set pin mux for ANTSEL_4, ANTSEL_5, ANTSEL_6 */ + + regAonVal = mt7622_gpio_get(GPIO_GPIO_MODE8); + if (usedPins & BIT(ANT_SEL_4)) { + regAonVal &= ~GPIO95_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO95_MODE_OFFSET) & GPIO95_MODE); + } + if (usedPins & BIT(ANT_SEL_5)) { + regAonVal &= ~GPIO96_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO96_MODE_OFFSET) & GPIO96_MODE); + } + if (usedPins & BIT(ANT_SEL_6)) { + regAonVal &= ~GPIO97_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO97_MODE_OFFSET) & GPIO97_MODE); + } + + mt7622_gpio_set(GPIO_GPIO_MODE8, regAonVal); + + /* Set pin mux for ANTSEL_12, ANTSEL_13, ANTSEL_14, ANTSEL_15, ANTSEL_26, ANTSEL_27, ANTSEL_28, ANTSEL_29 */ + + regAonVal = mt7622_gpio_get(GPIO_GPIO_MODE1); + + if (usedPins & BIT(ANT_SEL_12)) { + regAonVal &= ~GPIO73_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO73_MODE_OFFSET) & GPIO73_MODE); + } + if (usedPins & BIT(ANT_SEL_13)) { + regAonVal &= ~GPIO74_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO74_MODE_OFFSET) & GPIO74_MODE); + } + if (usedPins & BIT(ANT_SEL_14)) { + regAonVal &= ~GPIO75_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO75_MODE_OFFSET) & GPIO75_MODE); + } + if (usedPins & BIT(ANT_SEL_15)) { + regAonVal &= ~GPIO76_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO76_MODE_OFFSET) & GPIO76_MODE); + } + if (usedPins & BIT(ANT_SEL_26)) { + regAonVal &= ~GPIO18_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO18_MODE_OFFSET) & GPIO18_MODE); + } + if (usedPins & BIT(ANT_SEL_27)) { + regAonVal &= ~GPIO19_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO19_MODE_OFFSET) & GPIO19_MODE); + } + if (usedPins & BIT(ANT_SEL_28)) { + regAonVal &= ~GPIO20_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO20_MODE_OFFSET) & GPIO20_MODE); + } + if (usedPins & BIT(ANT_SEL_29)) { + regAonVal &= ~GPIO21_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO21_MODE_OFFSET) & GPIO21_MODE); + } + + mt7622_gpio_set(GPIO_GPIO_MODE1, regAonVal); + + /* Set pin mux for ANTSEL_22, ANTSEL_23, ANTSEL_17, ANTSEL_24, ANTSEL_25, ANTSEL_16 */ + regAonVal = mt7622_gpio_get(GPIO_GPIO_MODE2); + if (usedPins & BIT(ANT_SEL_22)) { + regAonVal &= ~GPIO34_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO34_MODE_OFFSET) & GPIO34_MODE); + } + if (usedPins & BIT(ANT_SEL_23)) { + regAonVal &= ~GPIO35_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO35_MODE_OFFSET) & GPIO35_MODE); + } + if (usedPins & BIT(ANT_SEL_17)) { + regAonVal &= ~GPIO78_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO78_MODE_OFFSET) & GPIO78_MODE); + } + if (usedPins & BIT(ANT_SEL_24)) { + regAonVal &= ~GPIO36_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO36_MODE_OFFSET) & GPIO36_MODE); + } + if (usedPins & BIT(ANT_SEL_25)) { + regAonVal &= ~GPIO37_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO37_MODE_OFFSET) & GPIO37_MODE); + } + if (usedPins & BIT(ANT_SEL_16)) { + regAonVal &= ~GPIO77_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO77_MODE_OFFSET) & GPIO77_MODE); + } + mt7622_gpio_set(GPIO_GPIO_MODE2, regAonVal); + + /* Set pin mux for ANTSEL_18, ANTSEL_19, ANTSEL_20, ANTSEL_21 */ + + regAonVal = mt7622_gpio_get(GPIO_GPIO_MODE10); + if (usedPins & BIT(ANT_SEL_18)) { + regAonVal &= ~GPIO79_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO79_MODE_OFFSET) & GPIO79_MODE); + } + if (usedPins & BIT(ANT_SEL_19)) { + regAonVal &= ~GPIO80_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO80_MODE_OFFSET) & GPIO80_MODE); + } + if (usedPins & BIT(ANT_SEL_20)) { + regAonVal &= ~GPIO81_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO81_MODE_OFFSET) & GPIO81_MODE); + } + if (usedPins & BIT(ANT_SEL_21)) { + regAonVal &= ~GPIO82_MODE; + regAonVal |= ((PINMUX_FUCTION_ANTSEL << GPIO82_MODE_OFFSET) & GPIO82_MODE); + } + + mt7622_gpio_set(GPIO_GPIO_MODE10, regAonVal); +} + + + +UINT32 mt7622_antsel_get_used_pin(RTMP_ADAPTER *pAd, UCHAR antCtrl, UCHAR polCtrl, UCHAR wifiStreams) +{ + UCHAR G_bandPaLna = GetGbandPaLna(antCtrl); + UINT32 usedPins = 0; + UCHAR sharePin = GetSharePinSupport(polCtrl); + + if (G_bandPaLna) /* ePA or eLNA Enable Case */ { + + switch (wifiStreams) { + case CONFIG_4x4: + /* Check 2.4G LNA. */ + if (G_bandPaLna == CONFIG_EPA_ELNA) /* ePAeLNA */ + usedPins |= USED_PIN_EPA_ELNA_4x4; + else if (G_bandPaLna == CONFIG_EPA_ILNA) /* ePAiLNA */ + usedPins |= USED_PIN_EPA_ILNA_4x4; + else if (G_bandPaLna == CONFIG_IPA_ELNA) /* iPAeLNA */ + usedPins |= USED_PIN_IPA_ELNA_4x4; + + if (!sharePin) + usedPins |= (USED_PIN_WF3_TRSW_P | USED_PIN_WF3_TRSW_N); + + + case CONFIG_3x3: + /* Check 2.4G LNA. */ + if (G_bandPaLna == CONFIG_EPA_ELNA) /* ePAeLNA */ + usedPins |= USED_PIN_EPA_ELNA_3x3; + else if (G_bandPaLna == CONFIG_EPA_ILNA) /* ePAiLNA */ + usedPins |= USED_PIN_EPA_ILNA_3x3; + else if (G_bandPaLna == CONFIG_IPA_ELNA) /* iPAeLNA */ + usedPins |= USED_PIN_IPA_ELNA_3x3; + + if (!sharePin) + usedPins |= (USED_PIN_WF2_TRSW_P | USED_PIN_WF2_TRSW_N); + + + case CONFIG_2x2: + /* Check 2.4G LNA. */ + if (G_bandPaLna == CONFIG_EPA_ELNA) /* ePAeLNA */ + usedPins |= USED_PIN_EPA_ELNA_2x2; + else if (G_bandPaLna == CONFIG_EPA_ILNA) /* ePAiLNA */ + usedPins |= USED_PIN_EPA_ILNA_2x2; + else if (G_bandPaLna == CONFIG_IPA_ELNA) /* iPAeLNA */ + usedPins |= USED_PIN_IPA_ELNA_2x2; + + if (!sharePin) + usedPins |= (USED_PIN_WF1_TRSW_P | USED_PIN_WF1_TRSW_N); + + case CONFIG_1x1: + /* Check 2.4G LNA. */ + if (G_bandPaLna == CONFIG_EPA_ELNA) /* ePAeLNA */ + usedPins |= USED_PIN_EPA_ELNA_1x1; + else if (G_bandPaLna == CONFIG_EPA_ILNA) /* ePAiLNA */ + usedPins |= USED_PIN_EPA_ILNA_1x1; + else if (G_bandPaLna == CONFIG_IPA_ELNA) /* iPAeLNA */ + usedPins |= USED_PIN_IPA_ELNA_1x1; + + usedPins |= (USED_PIN_WF0_TRSW_P | USED_PIN_WF0_TRSW_N); + + default: + break; + } + } + return usedPins; +} + +UINT32 mt7622_gpio_get(UINT32 offset) +{ + UINT32 gpioVal; + ULONG gpioVirt; + + gpioVirt = (ULONG)ioremap(GPIO_BASE_ADDR + offset, 0x20); + gpioVal = (UINT32)ioread32((void *)gpioVirt); + iounmap((void *)gpioVirt); + MTWF_LOG(DBG_CAT_INIT, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("read gpioVal = %x\n", gpioVal)); + return gpioVal; +} + +void mt7622_gpio_set(UINT32 offset, UINT32 gpioVal) +{ + ULONG gpioVirt; + + gpioVirt = (ULONG)ioremap(GPIO_BASE_ADDR + offset, 0x20); + iowrite32(gpioVal, (void *) gpioVirt); + iounmap((void *) gpioVirt); + MTWF_LOG(DBG_CAT_INIT, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Write gpioVal = %x\n", gpioVal)); + +} +#endif + +#if defined(COMPOS_WIN) || defined(COMPOS_TESTMODE_WIN) +#else +INT Mt7622AsicArchOpsInit(RTMP_ADAPTER *pAd) +{ + RTMP_ARCH_OP *arch_ops = &pAd->archOps; + arch_ops->archGetCrcErrCnt = MtAsicGetCrcErrCnt; + arch_ops->archGetCCACnt = MtAsicGetCCACnt; + arch_ops->archGetChBusyCnt = MtAsicGetChBusyCnt; + arch_ops->archSetAutoFallBack = MtAsicSetAutoFallBack; + arch_ops->archAutoFallbackInit = MtAsicAutoFallbackInit; + arch_ops->archUpdateProtect = MtAsicUpdateProtectByFw; + arch_ops->archUpdateRtsThld = MtAsicUpdateRtsThldByFw; + arch_ops->archSwitchChannel = MtAsicSwitchChannel; + arch_ops->archSetRDG = NULL; + arch_ops->archResetBBPAgent = MtAsicResetBBPAgent; + arch_ops->archSetDevMac = MtAsicSetDevMacByFw; + arch_ops->archSetBssid = MtAsicSetBssidByFw; + arch_ops->archSetStaRec = MtAsicSetStaRecByFw; + arch_ops->archUpdateStaRecBa = MtAsicUpdateStaRecBaByFw; + arch_ops->asic_rts_on_off = NULL; /* mt_asic_rts_on_off; */ +#ifdef CONFIG_AP_SUPPORT + arch_ops->archSetMbssMode = MtAsicSetMbssMode; + arch_ops->archSetMbssWdevIfAddr = MtAsicSetMbssWdevIfAddrGen2; + arch_ops->archSetMbssHwCRSetting = MtDmacSetMbssHwCRSetting; + arch_ops->archSetExtTTTTHwCRSetting = MtDmacSetExtTTTTHwCRSetting; + arch_ops->archSetExtMbssEnableCR = MtDmacSetExtMbssEnableCR; +#endif /* CONFIG_AP_SUPPORT */ + arch_ops->archDelWcidTab = MtAsicDelWcidTabByFw; +#ifdef HTC_DECRYPT_IOT + arch_ops->archSetWcidAAD_OM = MtAsicSetWcidAAD_OMByFw; +#endif /* HTC_DECRYPT_IOT */ + arch_ops->archAddRemoveKeyTab = MtAsicAddRemoveKeyTabByFw; +#ifdef BCN_OFFLOAD_SUPPORT + /* sync with Carter, wilsonl */ + arch_ops->archEnableBeacon = NULL; + arch_ops->archDisableBeacon = NULL; + arch_ops->archUpdateBeacon = MtUpdateBcnAndTimToMcu; +#else + arch_ops->archEnableBeacon = MtDmacAsicEnableBeacon; + arch_ops->archDisableBeacon = MtDmacAsicDisableBeacon; + arch_ops->archUpdateBeacon = MtUpdateBeaconToAsic; +#endif +#ifdef APCLI_SUPPORT +#ifdef MAC_REPEATER_SUPPORT + arch_ops->archSetReptFuncEnable = MtAsicSetReptFuncEnableByFw; + arch_ops->archInsertRepeaterEntry = MtAsicInsertRepeaterEntryByFw; + arch_ops->archRemoveRepeaterEntry = MtAsicRemoveRepeaterEntryByFw; + arch_ops->archInsertRepeaterRootEntry = MtAsicInsertRepeaterRootEntryByFw; +#endif /* MAC_REPEATER_SUPPORT */ +#endif /* APCLI_SUPPORT */ + arch_ops->archSetPiggyBack = MtAsicSetPiggyBack; + arch_ops->archSetPreTbtt = NULL;/* offload to BssInfoUpdateByFw */ + arch_ops->archSetGPTimer = MtAsicSetGPTimer; + arch_ops->archSetChBusyStat = MtAsicSetChBusyStat; + arch_ops->archGetTsfTime = MtAsicGetTsfTimeByFirmware; + arch_ops->archDisableSync = NULL;/* MtAsicDisableSyncByDriver; */ + arch_ops->archSetSyncModeAndEnable = NULL;/* MtAsicEnableBssSyncByDriver; */ + arch_ops->archSetWmmParam = MtAsicSetWmmParam; + arch_ops->archGetWmmParam = MtAsicGetWmmParam; + arch_ops->archSetEdcaParm = MtAsicSetEdcaParm; + arch_ops->archSetRetryLimit = MtAsicSetRetryLimit; + arch_ops->archGetRetryLimit = MtAsicGetRetryLimit; + arch_ops->archSetSlotTime = MtAsicSetSlotTime; + arch_ops->archGetTxTsc = MtAsicGetTxTscByDriver; + arch_ops->archAddSharedKeyEntry = MtAsicAddSharedKeyEntry; + arch_ops->archRemoveSharedKeyEntry = MtAsicRemoveSharedKeyEntry; + arch_ops->archAddPairwiseKeyEntry = MtAsicAddPairwiseKeyEntry; + arch_ops->archSetBW = MtAsicSetBW; + arch_ops->archSetCtrlCh = mt_mac_set_ctrlch; + arch_ops->archWaitMacTxRxIdle = MtAsicWaitMacTxRxIdle; +#ifdef MAC_INIT_OFFLOAD + arch_ops->archSetMacTxRx = MtAsicSetMacTxRxByFw; + arch_ops->archSetRxvFilter = MtAsicSetRxvFilter; + arch_ops->archSetMacMaxLen = NULL; + arch_ops->archSetTxStream = NULL; + arch_ops->archSetRxFilter = NULL;/* MtAsicSetRxFilter; */ +#else + arch_ops->archSetMacTxRx = MtAsicSetMacTxRx; + arch_ops->archSetMacMaxLen = MtAsicSetMacMaxLen; + arch_ops->archSetTxStream = MtAsicSetTxStream; + arch_ops->archSetRxFilter = MtAsicSetRxFilter; +#endif /*MAC_INIT_OFFLOAD*/ + arch_ops->archSetMacWD = MtAsicSetMacWD; +#ifdef MAC_APCLI_SUPPORT + arch_ops->archSetApCliBssid = MtAsicSetApCliBssid; +#endif /* MAC_APCLI_SUPPORT */ + arch_ops->archTOPInit = MtAsicTOPInit; + arch_ops->archSetTmrCR = MtSetTmrCRByFw; + arch_ops->archUpdateRxWCIDTable = MtAsicUpdateRxWCIDTableByFw; +#ifdef TXBF_SUPPORT + arch_ops->archUpdateClientBfCap = mt_AsicClientBfCap; +#endif /* TXBF_SUPPORT */ + arch_ops->archUpdateBASession = MtAsicUpdateBASessionByFw; + arch_ops->archGetTidSn = MtAsicGetTidSnByDriver; + arch_ops->archSetSMPS = MtAsicSetSMPSByDriver; + arch_ops->archRxHeaderTransCtl = MtAsicRxHeaderTransCtl; + arch_ops->archRxHeaderTaranBLCtl = MtAsicRxHeaderTaranBLCtl; + arch_ops->rx_pkt_process = mt_rx_pkt_process; + arch_ops->archSetRxStream = NULL;/* MtAsicSetRxStream; */ +#ifdef IGMP_SNOOP_SUPPORT + arch_ops->archMcastEntryInsert = MulticastFilterTableInsertEntry; + arch_ops->archMcastEntryDelete = MulticastFilterTableDeleteEntry; +#endif + arch_ops->write_txp_info = mtd_write_txp_info_by_host; + arch_ops->write_tmac_info_fixed_rate = mtd_write_tmac_info_fixed_rate; + arch_ops->write_tmac_info = mtd_write_tmac_info_by_host; + arch_ops->write_tx_resource = mtd_pci_write_tx_resource; + arch_ops->write_frag_tx_resource = mt_pci_write_frag_tx_resource; + arch_ops->kickout_data_tx = pci_kickout_data_tx; + arch_ops->get_pkt_from_rx_resource = mtd_pci_get_pkt_from_rx_resource; + arch_ops->get_pkt_from_rx1_resource = mtd_pci_get_pkt_from_rx_resource; + arch_ops->get_resource_idx = mtd_pci_get_resource_idx; + arch_ops->get_tx_resource_free_num = pci_get_tx_resource_free_num; + arch_ops->check_hw_resource = mtd_check_hw_resource; + arch_ops->inc_resource_full_cnt = pci_inc_resource_full_cnt; + arch_ops->get_resource_state = pci_get_resource_state; + arch_ops->set_resource_state = pci_set_resource_state; + arch_ops->check_resource_state = pci_check_resource_state; + arch_ops->get_hif_buf = mt_pci_get_hif_buf; + arch_ops->hw_tx = mtd_hw_tx; + arch_ops->mlme_hw_tx = mtd_mlme_hw_tx; +#ifdef CONFIG_ATE + arch_ops->ate_hw_tx = mtd_ate_hw_tx; +#endif + arch_ops->rx_done_handle = mtd_rx_done_handle; + arch_ops->tx_dma_done_handle = mtd_tx_dma_done_handle; + arch_ops->cmd_dma_done_handle = mt_cmd_dma_done_handle; + arch_ops->fwdl_dma_done_handle = mt_fwdl_dma_done_handle; + arch_ops->hw_isr = mtd_isr; +#ifdef RED_SUPPORT + arch_ops->archRedMarkPktDrop = RedMarkPktDrop; + arch_ops->archRedRecordCP = RedRecordCP; + arch_ops->archRedEnqueueFail = RedEnqueueFail; +#endif + return TRUE; +} +#endif + + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7622_dbg.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7622_dbg.c new file mode 100644 index 000000000..e18cfd34d --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/mt7622_dbg.c @@ -0,0 +1,1333 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** +*/ + +#include "rt_config.h" +#include "chip/mt7622_cr.h" +#include "hdev/hdev.h" + +static INT pse_pg_cnt[] = {256, 512, 512, 1024, 768, 1536, 1024, 2048, 1280, 2560, 1536, 3072, 1792, 3584, 0, 0}; +static EMPTY_QUEUE_INFO_T Queue_Empty_info[] = { + {"CPU Q0", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_0}, + {"CPU Q1", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_1}, + {"CPU Q2", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_2}, + {"CPU Q3", ENUM_UMAC_CPU_PORT_1, ENUM_UMAC_CTX_Q_3}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, /* 4~7 not defined */ + {"ALTX Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0}, /* Q16 */ + {"BMC Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_0}, + {"BCN Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_0}, + {"PSMP Q0", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0}, + {"ALTX Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1}, + {"BMC Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BMC_1}, + {"BCN Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_BNC_1}, + {"PSMP Q1", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1}, + {"NAF Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NAF}, + {"NBCN Q", ENUM_UMAC_LMAC_PORT_2, ENUM_UMAC_LMAC_PLE_TX_Q_NBCN}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, + {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, {NULL, 0, 0}, /* 18~29 not defined */ + {"RLS Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1E}, + {"RLS2 Q", ENUM_PLE_CTRL_PSE_PORT_3, ENUM_UMAC_PLE_CTRL_P3_Q_0X1F} +}; +static PCHAR sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"}; + +static INT32 chip_dump_ps_table(struct hdev_ctrl *ctrl, UINT32 ent_type, BOOLEAN bReptCli) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + int i; + UINT32 ps_stat[4] = {0}; + UINT32 regValue = 0; + UINT8 bmc_cnt[4] = {0}; + UINT8 ext_bmc_cnt[15] = {0}; + + HW_IO_READ32(pAd, PLE_STATION_PAUSE0, &ps_stat[0]); + HW_IO_READ32(pAd, PLE_STATION_PAUSE1, &ps_stat[1]); + HW_IO_READ32(pAd, PLE_STATION_PAUSE2, &ps_stat[2]); + HW_IO_READ32(pAd, PLE_STATION_PAUSE3, &ps_stat[3]); + HW_IO_READ32(pAd, ARB_BMCCR0, ®Value); + bmc_cnt[0] = regValue & 0xff; + bmc_cnt[1] = (regValue & 0xff00) >> 8; + bmc_cnt[2] = (regValue & 0xff0000) >> 16; + bmc_cnt[3] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR1, ®Value); + ext_bmc_cnt[0] = regValue & 0xff; + ext_bmc_cnt[1] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[2] = (regValue & 0xff0000) >> 16; + ext_bmc_cnt[3] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR2, ®Value); + ext_bmc_cnt[4] = regValue & 0xff; + ext_bmc_cnt[5] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[6] = (regValue & 0xff0000) >> 16; + ext_bmc_cnt[7] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR3, ®Value); + ext_bmc_cnt[8] = regValue & 0xff; + ext_bmc_cnt[9] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[10] = (regValue & 0xff0000) >> 16; + ext_bmc_cnt[11] = (regValue & 0xff000000) >> 24; + HW_IO_READ32(pAd, ARB_BMCCR4, ®Value); + ext_bmc_cnt[12] = regValue & 0xff; + ext_bmc_cnt[13] = (regValue & 0xff00) >> 8; + ext_bmc_cnt[14] = (regValue & 0xff0000) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PS_info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%08x %08x %08x %08x\n", ps_stat[0], ps_stat[1], ps_stat[2], + ps_stat[3])); + + for (i = 0; i < 4; i++) { + if (bmc_cnt[i]) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BMC(%x)%d ", i, bmc_cnt[i])); + } + + for (i = 0; i < 15; i++) { + if (ext_bmc_cnt[i]) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BMC(%x)%d ", i + 0x11, ext_bmc_cnt[i])); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n\n")); + /* Dump PS info from FW */ + CmdExtGeneralTestAPPWS(pAd, APPWS_ACTION_DUMP_INFO); + return TRUE; +} + +static INT32 chip_show_tmac_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 Value; + RTMP_ADAPTER *pAd = ctrl->priv; + + RTMP_IO_READ32(pAd, TMAC_TCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TX Stream = %d\n", GET_TMAC_TCR_TX_STREAM_NUM(Value) + 1)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TX RIFS Enable = %d\n", GET_TX_RIFS_EN(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RX RIFS Mode = %d\n", GET_RX_RIFS_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TXOP TBTT Control = %d\n", GET_TXOP_TBTT_CONTROL(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TXOP TBTT Stop Control = %d\n", GET_TBTT_TX_STOP_CONTROL(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TXOP Burst Stop = %d\n", GET_TXOP_BURST_STOP(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RDG Mode = %d\n", GET_RDG_RA_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RDG Responser Enable = %d\n", GET_RDG_RESP_EN(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Smoothing = %d\n", GET_SMOOTHING(Value))); + RTMP_IO_READ32(pAd, TMAC_PSCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Save RXPE Off Time(unit 2us) = %d\n", + GET_APS_OFF_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Save RXPE On Time(unit 2us) = %d\n", APS_ON_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Save Halt Time (unit 32us) = %d\n", + GET_APS_HALT_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP Power Enable = %d\n", GET_APS_EN(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC0 TXOP = 0x%x (unit: 32us)\n", GET_AC0LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC1 TXOP = 0x%x (unit: 32us)\n", GET_AC1LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC2 TXOP = 0x%x (unit: 32us)\n", GET_AC2LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC3 TXOP = 0x%x (unit: 32us)\n", GET_AC3LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR3, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC10 TXOP = 0x%x (unit: 32us)\n", GET_AC10LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC11 TXOP = 0x%x (unit: 32us)\n", GET_AC11LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ACTXOPLR2, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC12 TXOP = 0x%x (unit: 32us)\n", GET_AC12LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC13 TXOP = 0x%x (unit: 32us)\n", GET_AC13LIMIT(Value))); + RTMP_IO_READ32(pAd, TMAC_ICR_BAND_0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("EIFS Time, Band0 (unit: 1us) = %d\n", GET_ICR_EIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RIFS Time, Band0 (unit: 1us) = %d\n", GET_ICR_RIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SIFS Time, Band0 (unit: 1us) = %d\n", GET_ICR_SIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SLOT Time, Band0 (unit: 1us) = %d\n", GET_ICR_SLOT_TIME(Value))); + RTMP_IO_READ32(pAd, TMAC_ICR_BAND_1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("EIFS Time, Band1 (unit: 1us) = %d\n", GET_ICR_EIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RIFS Time, Band1 (unit: 1us) = %d\n", GET_ICR_RIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SIFS Time, Band1 (unit: 1us) = %d\n", GET_ICR_SIFS_TIME(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SLOT Time, Band1 (unit: 1us) = %d\n", GET_ICR_SLOT_TIME(Value))); + RTMP_IO_READ32(pAd, TMAC_ATCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Aggregation Timeout (unit: 50ns) = 0x%x\n", GET_AGG_TOUT(Value))); + return 0; +} + +static INT32 chip_show_agg_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 Value; + RTMP_ADAPTER *pAd = ctrl->priv; + + RTMP_IO_READ32(pAd, AGG_PCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MM Protection = %d\n", GET_MM_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("GF Protection = %d\n", GET_GF_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Protection Mode = %d\n", GET_PROTECTION_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BW40 Protection = %d\n", GET_BW40_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RIFS Protection = %d\n", GET_RIFS_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BW80 Protection = %d\n", GET_BW80_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BW160 Protection = %d\n", GET_BW160_PROTECTION(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ERP Protection = 0x%x\n", GET_ERP_PROTECTION(Value))); + RTMP_IO_READ32(pAd, AGG_PCR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RTS Threshold(packet length) = 0x%x\n", GET_RTS_THRESHOLD(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RTS PKT Nums Threshold = %d\n", GET_RTS_PKT_NUM_THRESHOLD(Value))); + RTMP_IO_READ32(pAd, AGG_MRCR, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RTS Retry Count Limit = %d\n", GET_RTS_RTY_CNT_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Frame Tx Count Limit = %d\n", GET_BAR_TX_CNT_LIMIT(Value))); + RTMP_IO_READ32(pAd, AGG_ACR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AMPDU No BA Rule = %d\n", GET_AMPDU_NO_BA_RULE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AMPDU No BA AR Rule = %d\n", + GET_AGG_ACR_AMPDU_NO_BA_AR_RULE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Tx Rate = 0x%x\n", GET_BAR_RATE_TX_RATE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Tx Mode = 0x%x\n", GET_BAR_RATE_TX_MODE(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR Nsts = %d\n", GET_BAR_RATE_NSTS(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BAR STBC = %d\n", GET_BAR_RATE_STBC(Value))); + RTMP_IO_READ32(pAd, AGG_AALCR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC0 Agg limit = %d\n", GET_AC0_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC1 Agg limit = %d\n", GET_AC1_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC2 Agg limit = %d\n", GET_AC2_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC3 Agg limit = %d\n", GET_AC3_AGG_LIMIT(Value))); + RTMP_IO_READ32(pAd, AGG_AALCR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC10 Agg limit = %d\n", GET_AC10_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC11 Agg limit = %d\n", GET_AC11_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC12 Agg limit = %d\n", GET_AC12_AGG_LIMIT(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AC13 Agg limit = %d\n", GET_AC13_AGG_LIMIT(Value))); + RTMP_IO_READ32(pAd, AGG_AWSCR0, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize0 limit = %d\n", GET_WINSIZE0(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize1 limit = %d\n", GET_WINSIZE1(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize2 limit = %d\n", GET_WINSIZE2(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize3 limit = %d\n", GET_WINSIZE3(Value))); + RTMP_IO_READ32(pAd, AGG_AWSCR1, &Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize4 limit = %d\n", GET_WINSIZE4(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize5 limit = %d\n", GET_WINSIZE5(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize6 limit = %d\n", GET_WINSIZE6(Value))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Winsize7 limit = %d\n", GET_WINSIZE7(Value))); + return 0; +} + +static INT32 chip_dump_mib_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + RTMP_CHIP_CAP *pChipCap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 bss_nums = pChipCap->BssNums; + UINT32 mac_val, mac_val1, idx, band_idx = 0, band_offset = 0, ampdu_cnt[7]; + UINT32 msdr6, msdr7, msdr8, msdr9, msdr10, msdr16, msdr17, msdr18, msdr19, msdr20, msdr21; + UINT32 mbxsdr[bss_nums][4]; + UINT32 mbtcr[16], mbtbcr[16], mbrcr[16], mbrbcr[16]; + UINT32 btcr[bss_nums], btbcr[bss_nums], brcr[bss_nums], brbcr[bss_nums], btdcr[bss_nums], brdcr[bss_nums]; + UINT32 mu_cnt[5]; + + for (band_idx = 0; band_idx < pChipCap->band_cnt; band_idx++) { + if (arg != NULL && band_idx != simple_strtoul(arg, 0, 10)) + continue; + + band_offset = 0x200 * band_idx; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Band %d MIB Status\n", band_idx)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===============================\n")); + RTMP_IO_READ32(pAd, MIB_M0SCR0 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MIB Status Control=0x%x\n", mac_val)); + RTMP_IO_READ32(pAd, MIB_M0PBSCR + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MIB Per-BSS Status Control=0x%x\n", mac_val)); + + RTMP_IO_READ32(pAd, MIB_M0SDR6 + band_offset, &msdr6); + RTMP_IO_READ32(pAd, MIB_M0SDR7 + band_offset, &msdr7); + RTMP_IO_READ32(pAd, MIB_M0SDR8 + band_offset, &msdr8); + RTMP_IO_READ32(pAd, MIB_M0SDR9 + band_offset, &msdr9); + RTMP_IO_READ32(pAd, MIB_M0SDR10 + band_offset, &msdr10); + RTMP_IO_READ32(pAd, MIB_M0SDR16 + band_offset, &msdr16); + RTMP_IO_READ32(pAd, MIB_M0SDR17 + band_offset, &msdr17); + RTMP_IO_READ32(pAd, MIB_M0SDR18 + band_offset, &msdr18); + RTMP_IO_READ32(pAd, MIB_M0SDR19 + band_offset, &msdr19); + RTMP_IO_READ32(pAd, MIB_M0SDR20 + band_offset, &msdr20); + RTMP_IO_READ32(pAd, MIB_M0SDR21 + band_offset, &msdr21); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Phy/Timing Related Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tChannelIdleCnt=0x%x\n", msdr6 & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tCCA_NAV_Tx_Time=0x%x\n", msdr9 & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx_MDRDY_CNT=0x%x\n", msdr10 & 0x3ffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCCK_MDRDY_TIME=0x%x, OFDM_MDRDY_TIME=0x%x, OFDM_GREEN_MDRDY_TIME=0x%x\n", + msdr19 & 0x3ffffff, msdr20 & 0x3ffffff, msdr21 & 0x3ffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tPrim CCA Time=0x%x\n", msdr16 & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tSec CCA Time=0x%x\n", msdr17 & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tPrim ED Time=0x%x\n", msdr18 & 0xffffff)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Tx Related Counters(Generic)===\n")); + RTMP_IO_READ32(pAd, MIB_M0SDR0 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tBeaconTxCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0DR0 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 20MHz Cnt=0x%x\n", mac_val & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 40MHz Cnt=0x%x\n", (mac_val >> 16) & 0xffff)); + RTMP_IO_READ32(pAd, MIB_M0DR1 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 80MHz Cnt=0x%x\n", mac_val & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx 160MHz Cnt=0x%x\n", (mac_val >> 16) & 0xffff)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===AMPDU Related Counters===\n")); + RTMP_IO_READ32(pAd, MIB_M0SDR12 + band_offset, &du_cnt[0]); + RTMP_IO_READ32(pAd, MIB_M0SDR14 + band_offset, &du_cnt[1]); + RTMP_IO_READ32(pAd, MIB_M0SDR15 + band_offset, &du_cnt[2]); + RTMP_IO_READ32(pAd, MIB_M0DR2 + band_offset, &du_cnt[3]); + RTMP_IO_READ32(pAd, MIB_M0DR3 + band_offset, &du_cnt[4]); + RTMP_IO_READ32(pAd, MIB_M0DR4 + band_offset, &du_cnt[5]); + RTMP_IO_READ32(pAd, MIB_M0DR5 + band_offset, &du_cnt[6]); + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx BA_Cnt=0x%x\n", ampdu_cnt[0] & 0xffff)); */ + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx AMPDU_Burst_Cnt=0x%x\n", (ampdu_cnt[0] >> 16 ) & 0xffff)); */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx AMPDU_Pkt_Cnt=0x%x\n", ampdu_cnt[0])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx AMPDU_MPDU_Pkt_Cnt=0x%x\n", ampdu_cnt[1] & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tAMPDU SuccessCnt=0x%x\n", ampdu_cnt[2] & 0xffffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tTx Agg Range: \t1 \t2~5 \t6~15 \t16~22 \t23~33 \t34~49 \t50~57 \t58~64\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\t\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", + (ampdu_cnt[3]) & 0xffff, (ampdu_cnt[3] >> 16) & 0xffff, + (ampdu_cnt[4]) & 0xffff, (ampdu_cnt[4] >> 16) & 0xffff, + (ampdu_cnt[5]) & 0xffff, (ampdu_cnt[5] >> 16) & 0xffff, + (ampdu_cnt[6]) & 0xffff, (ampdu_cnt[6] >> 16) & 0xffff)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===MU Related Counters===\n")); + MAC_IO_READ32(pAd, MIB_M0SDR34, &mu_cnt[0]); + MAC_IO_READ32(pAd, MIB_M0DR8, &mu_cnt[1]); + MAC_IO_READ32(pAd, MIB_M0DR9, &mu_cnt[2]); + MAC_IO_READ32(pAd, MIB_M0DR10, &mu_cnt[3]); + MAC_IO_READ32(pAd, MIB_M0DR11, &mu_cnt[4]); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMUBF_TX_COUNT=0x%x\n", mu_cnt[0] & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMU_TX_MPDU_COUNT(Ok+Fail)=0x%x\n", mu_cnt[1])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMU_TX_OK_MPDU_COUNT=0x%x\n", mu_cnt[2])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMU_TO_SU_PPDU_COUNT=0x%x\n", mu_cnt[3] & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tSU_TX_OK_MPDU_COUNT=0x%x\n", mu_cnt[4])); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Rx Related Counters(Generic)===\n")); + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tVector Overflow Drop Cnt=0x%x\n", (msdr6 >> 16 ) & 0xffff)); */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tVector Mismacth Cnt=0x%x\n", msdr7 & 0xffff)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tDelimiter Fail Cnt=0x%x\n", msdr8 & 0xffff)); + RTMP_IO_READ32(pAd, MIB_M0SDR3 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxFCSErrCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR4 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxFifoFullCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR11 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxLenMismatch=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR5 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRxMPDUCnt=0x%x\n", (mac_val & 0xffff))); + RTMP_IO_READ32(pAd, MIB_M0SDR29 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tPFDropCnt=0x%x\n", (mac_val & 0x00ff))); + RTMP_IO_READ32(pAd, MIB_M0SDR22 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx AMPDU Cnt=0x%x\n", mac_val)); + /* TODO: shiang-MT7615, is MIB_M0SDR23 used for Rx total byte count for all or just AMPDU only??? */ + RTMP_IO_READ32(pAd, MIB_M0SDR23 + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRx Total ByteCnt=0x%x\n", mac_val)); + } + + for (idx = 0; idx < bss_nums; idx++) { + RTMP_IO_READ32(pAd, WTBL_BTCRn + idx * 4, &btcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BTBCRn + idx * 4, &btbcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BRCRn + idx * 4, &brcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BRBCRn + idx * 4, &brbcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BTDCRn + idx * 4, &btdcr[idx]); + RTMP_IO_READ32(pAd, WTBL_BRDCRn + idx * 4, &brdcr[idx]); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Per-BSS Related Tx/Rx Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BSS Idx TxCnt/DataCnt TxByteCnt RxCnt/DataCnt RxByteCnt\n")); + + for (idx = 0; idx < bss_nums; idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%d\t 0x%x/0x%x\t 0x%x \t 0x%x/0x%x \t 0x%x\n", + idx, btcr[idx], btdcr[idx], btbcr[idx], + brcr[idx], brdcr[idx], brbcr[idx])); + } + + for (idx = 0; idx < bss_nums; idx++) { + RTMP_IO_READ32(pAd, MIB_MB0SDR0 + idx * 0x10, &mbxsdr[idx][0]); + RTMP_IO_READ32(pAd, MIB_MB0SDR1 + idx * 0x10, &mbxsdr[idx][1]); + RTMP_IO_READ32(pAd, MIB_MB0SDR2 + idx * 0x10, &mbxsdr[idx][2]); + RTMP_IO_READ32(pAd, MIB_MB0SDR3 + idx * 0x10, &mbxsdr[idx][3]); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Per-MBSS Related MIB Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BSS Idx RTSTx/RetryCnt BAMissCnt AckFailCnt FrmRetry1/2/3Cnt\n")); + + for (idx = 0; idx < bss_nums; idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%d:\t0x%x/0x%x 0x%x \t 0x%x \t 0x%x/0x%x/0x%x\n", + idx, mbxsdr[idx][0], (mbxsdr[idx][0] >> 16) & 0xffff, + mbxsdr[idx][1], (mbxsdr[idx][1] >> 16) & 0xffff, + mbxsdr[idx][2], (mbxsdr[idx][2] >> 16) & 0xffff, + mbxsdr[idx][3] & 0xffff)); + } + + for (idx = 0; idx < 16; idx++) { + RTMP_IO_READ32(pAd, WTBL_MBTCRn + idx * 4, &mbtcr[idx]); + RTMP_IO_READ32(pAd, WTBL_MBTBCRn + idx * 4, &mbtbcr[idx]); + RTMP_IO_READ32(pAd, WTBL_MBRCRn + idx * 4, &mbrcr[idx]); + RTMP_IO_READ32(pAd, WTBL_MBRBCRn + idx * 4, &mbrbcr[idx]); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Per-MBSS Related Tx/Rx Counters===\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MBSSIdx TxCnt TxByteCnt RxCnt RxByteCnt\n")); + + for (idx = 0; idx < 16; idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%d\t 0x%x\t 0x%x \t 0x%x \t 0x%x\n", + idx, mbtcr[idx], mbtbcr[idx], mbrcr[idx], mbrbcr[idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("===Dummy delimiter insertion result===\n")); + RTMP_IO_READ32(pAd, MIB_M0DR6, &mac_val); + RTMP_IO_READ32(pAd, MIB_M0DR7, &mac_val1); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Range1 = %d\t Range2 = %d\t Range3 = %d\t Range4 = %d\n", + GET_TX_DDLMT_RNG1_CNT(mac_val), GET_TX_DDLMT_RNG2_CNT(mac_val), GET_TX_DDLMT_RNG3_CNT(mac_val1), GET_TX_DDLMT_RNG4_CNT(mac_val1))); +#ifdef TRACELOG_TCP_PKT + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TCP RxAck = %d\t TxData = %d", + pAd->u4TcpRxAckCnt, pAd->u4TcpTxDataCnt)); + pAd->u4TcpRxAckCnt = 0; + pAd->u4TcpTxDataCnt = 0; +#endif /* TRACELOG_TCP_PKT */ + return TRUE; +} + +static INT32 chip_show_pse_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + UINT32 pse_buf_ctrl, pg_sz, pg_num; + UINT32 pse_stat, pg_flow_ctrl[16] = {0}; + UINT32 fpg_cnt, ffa_cnt, fpg_head, fpg_tail; + UINT32 max_q, min_q, rsv_pg, used_pg; + INT32 i; + + HW_IO_READ32(pAd, PSE_PBUF_CTRL, &pse_buf_ctrl); + HW_IO_READ32(pAd, PSE_QUEUE_EMPTY, &pse_stat); + HW_IO_READ32(pAd, PSE_FREEPG_CNT, &pg_flow_ctrl[0]); + HW_IO_READ32(pAd, PSE_FREEPG_HEAD_TAIL, &pg_flow_ctrl[1]); + HW_IO_READ32(pAd, PSE_PG_HIF0_GROUP, &pg_flow_ctrl[2]); + HW_IO_READ32(pAd, PSE_HIF0_PG_INFO, &pg_flow_ctrl[3]); + HW_IO_READ32(pAd, PSE_PG_HIF1_GROUP, &pg_flow_ctrl[4]); + HW_IO_READ32(pAd, PSE_HIF1_PG_INFO, &pg_flow_ctrl[5]); + HW_IO_READ32(pAd, PSE_PG_CPU_GROUP, &pg_flow_ctrl[6]); + HW_IO_READ32(pAd, PSE_CPU_PG_INFO, &pg_flow_ctrl[7]); + HW_IO_READ32(pAd, PSE_PG_LMAC0_GROUP, &pg_flow_ctrl[8]); + HW_IO_READ32(pAd, PSE_LMAC0_PG_INFO, &pg_flow_ctrl[9]); + HW_IO_READ32(pAd, PSE_PG_LMAC1_GROUP, &pg_flow_ctrl[10]); + HW_IO_READ32(pAd, PSE_LMAC1_PG_INFO, &pg_flow_ctrl[11]); + HW_IO_READ32(pAd, PSE_PG_LMAC2_GROUP, &pg_flow_ctrl[12]); + HW_IO_READ32(pAd, PSE_LMAC2_PG_INFO, &pg_flow_ctrl[13]); + HW_IO_READ32(pAd, PSE_PG_PLE_GROUP, &pg_flow_ctrl[14]); + HW_IO_READ32(pAd, PSE_PLE_PG_INFO, &pg_flow_ctrl[15]); + /* Configuration Info */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PSE Configuration Info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPacket Buffer Control(0x82068014): 0x%08x\n", pse_buf_ctrl)); + pg_sz = (pse_buf_ctrl & (0x1 << 31)) >> 31; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Size=%d(%d bytes per page)\n", pg_sz, (pg_sz == 1 ? 256 : 128))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Offset=%d(in unit of 64KB)\n", GET_PSE_PBUF_OFFSET(pse_buf_ctrl))); + pg_num = PSE_GET_TOTAL_PAGE_CFG(pse_buf_ctrl); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tConfigured Total Page=%d(%d pages)\n", pg_num, (pg_num < 14 ? pse_pg_cnt[pg_num] : 0))); + pg_num = (pse_buf_ctrl & PSE_TOTAL_PAGE_NUM_MASK); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t\tAvailable Total Page=%d pages\n", pg_num)); + /* Page Flow Control */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PSE Page Flow Control:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page counter(0x82068100): 0x%08x\n", pg_flow_ctrl[0])); + fpg_cnt = pg_flow_ctrl[0] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe toal page number of free=0x%03x\n", fpg_cnt)); + ffa_cnt = (pg_flow_ctrl[0] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe free page numbers of free for all=0x%03x\n", ffa_cnt)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page head and tail(0x82068104): 0x%08x\n", pg_flow_ctrl[1])); + fpg_head = pg_flow_ctrl[1] & 0xfff; + fpg_tail = (pg_flow_ctrl[1] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", fpg_tail, fpg_head)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of HIF0 group(0x82068110): 0x%08x\n", pg_flow_ctrl[2])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF0 group page status(0x82068114): 0x%08x\n", pg_flow_ctrl[3])); + min_q = pg_flow_ctrl[2] & 0xfff; + max_q = (pg_flow_ctrl[2] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of HIF0 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[3] & 0xfff; + used_pg = (pg_flow_ctrl[3] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of HIF0 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of HIF1 group(0x82068118): 0x%08x\n", pg_flow_ctrl[4])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF1 group page status(0x8206811c): 0x%08x\n", pg_flow_ctrl[5])); + min_q = pg_flow_ctrl[4] & 0xfff; + max_q = (pg_flow_ctrl[4] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of HIF1 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[5] & 0xfff; + used_pg = (pg_flow_ctrl[5] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of HIF1 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of CPU group(0x82068150): 0x%08x\n", pg_flow_ctrl[6])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCPU group page status(0x82068154): 0x%08x\n", pg_flow_ctrl[7])); + min_q = pg_flow_ctrl[6] & 0xfff; + max_q = (pg_flow_ctrl[6] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[7] & 0xfff; + used_pg = (pg_flow_ctrl[7] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of LMAC0 group(0x82068170): 0x%08x\n", pg_flow_ctrl[8])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tLMAC0 group page status(0x82068174): 0x%08x\n", pg_flow_ctrl[9])); + min_q = pg_flow_ctrl[8] & 0xfff; + max_q = (pg_flow_ctrl[8] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of LMAC0 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[9] & 0xfff; + used_pg = (pg_flow_ctrl[9] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of LMAC0 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of LMAC1 group(0x82068178): 0x%08x\n", pg_flow_ctrl[10])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tLMAC1 group page status(0x8206817c): 0x%08x\n", pg_flow_ctrl[11])); + min_q = pg_flow_ctrl[10] & 0xfff; + max_q = (pg_flow_ctrl[10] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of LMAC1 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[11] & 0xfff; + used_pg = (pg_flow_ctrl[11] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of LMAC1 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of LMAC2 group(0x82068180): 0x%08x\n", pg_flow_ctrl[11])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tLMAC2 group page status(0x82068184): 0x%08x\n", pg_flow_ctrl[12])); + min_q = pg_flow_ctrl[12] & 0xfff; + max_q = (pg_flow_ctrl[12] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of LMAC2 group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[13] & 0xfff; + used_pg = (pg_flow_ctrl[13] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of LMAC2 group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of PLE group(0x82068190): 0x%08x\n", pg_flow_ctrl[14])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPLE group page status(0x82068194): 0x%08x\n", pg_flow_ctrl[15])); + min_q = pg_flow_ctrl[14] & 0xfff; + max_q = (pg_flow_ctrl[14] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of PLE group=0x%03x/0x%03x\n", max_q, min_q)); + rsv_pg = pg_flow_ctrl[15] & 0xfff; + used_pg = (pg_flow_ctrl[15] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of PLE group=0x%03x/0x%03x\n", used_pg, rsv_pg)); + /* Queue Empty Status */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PSE Queue Empty Status:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tQUEUE_EMPTY(0x820680b0): 0x%08x\n", pse_stat)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tCPU Q0/1/2/3 empty=%d/%d/%d/%d\n", + pse_stat & 0x1, ((pse_stat & 0x2) >> 1), + ((pse_stat & 0x4) >> 2), ((pse_stat & 0x8) >> 3))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tHIF Q0/1 empty=%d/%d\n", + ((pse_stat & (0x1 << 16)) >> 16), ((pse_stat & (0x1 << 17)) >> 17))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tLMAC TX Q empty=%d\n", + ((pse_stat & (0x1 << 24)) >> 24))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tRLS_Q empty=%d\n", + ((pse_stat & (0x1 << 31)) >> 31))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Nonempty Q info:\n")); + + for (i = 0; i < 31; i++) { + if (((pse_stat & (0x1 << i)) >> i) == 0) { + UINT32 hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (i < 4) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCPU Q%d: ", i)); + fl_que_ctrl[0] |= (0x1 << 14); + fl_que_ctrl[0] |= (i << 8); + } else if (i == 16) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tHIF Q0: ")); + fl_que_ctrl[0] |= (0x0 << 14); + fl_que_ctrl[0] |= (0x0 << 8); + } else if (i == 17) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tHIF Q1: ")); + fl_que_ctrl[0] |= (0x0 << 14); + fl_que_ctrl[0] |= (0x1 << 8); + } else if (i == 24) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tLMAC TX Q: ")); + fl_que_ctrl[0] |= (0x2 << 14); + fl_que_ctrl[0] |= (0x0 << 8); + } else if (i == 31) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tRLS Q: ")); + fl_que_ctrl[0] |= (0x3 << 14); + fl_que_ctrl[0] |= (i << 8); + } else + continue; + + fl_que_ctrl[0] |= (0x1 << 31); + HW_IO_WRITE32(pAd, PSE_FL_QUE_CTRL_0, fl_que_ctrl[0]); + HW_IO_READ32(pAd, PSE_FL_QUE_CTRL_2, &fl_que_ctrl[1]); + HW_IO_READ32(pAd, PSE_FL_QUE_CTRL_3, &fl_que_ctrl[2]); + hfid = fl_que_ctrl[1] & 0xfff; + tfid = (fl_que_ctrl[1] & 0xfff << 16) >> 16; + pktcnt = fl_que_ctrl[2] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("tail/head fid = 0x%03x/0x%03x, pkt cnt = %x\n", + tfid, hfid, pktcnt)); + } + } + + return TRUE; +} + +static INT32 chip_show_protect_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 val; + RTMP_ADAPTER *pAd = ctrl->priv; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" -Proetction\n")); + RTMP_IO_READ32(pAd, AGG_PCR, &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" > AGG_PCR 0x%08x\n", val)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" -RTS Threshold\n")); + RTMP_IO_READ32(pAd, AGG_PCR1, &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" > AGG_PCR1 0x%08x\n", val)); + return TRUE; +} + +static INT32 chip_show_cca_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + UINT32 val; + RTMP_ADAPTER *pAd = ctrl->priv; + + MAC_IO_READ32(pAd, RMAC_DEBUG_CR, &val); + val |= (1 << 31); /* For Band0 */ + MAC_IO_WRITE32(pAd, RMAC_DEBUG_CR, val); + /* Debug CR */ + MAC_IO_WRITE32(pAd, (WF_CFG_OFF_BASE + 0x2c), 0xf); + MAC_IO_WRITE32(pAd, (WF_CFG_BASE + 0x14), 0x1f); + MAC_IO_WRITE32(pAd, (WF_CFG_BASE + 0x18), 0x06060606); + MAC_IO_WRITE32(pAd, (WF_CFG_BASE + 0x4c), 0x1c1c1d1d); + MAC_IO_READ32(pAd, (WF_CFG_BASE + 0x24), &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("CCA for BAND0 info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("-- CCA Prim: %d, SE20: %d, SEC40: %d\n", + ((val & (1 << 14)) >> 14), ((val & (1 << 6)) >> 6), + ((val & (1 << 5)) >> 5))); + MAC_IO_READ32(pAd, RMAC_DEBUG_CR, &val); + val &= ~(1 << 31); /* For Band1 */ + MAC_IO_WRITE32(pAd, RMAC_DEBUG_CR, val); + MAC_IO_READ32(pAd, (WF_CFG_BASE + 0x24), &val); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("CCA for BAND1 info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("-- CCA Prim: %d, SE20: %d, SEC40: %d\n", + ((val & (1 << 14)) >> 14), ((val & (1 << 6)) >> 6), + ((val & (1 << 5)) >> 5))); + return 0; +} + +static INT32 chip_set_cca_en(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + BOOLEAN enable; + UINT32 val; + RTMP_ADAPTER *pAd = ctrl->priv; + + enable = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Enable CCA on Band0 SEC40: %s\n", (enable) ? "ON" : "OFF")); + /* RF CR for BAND0 CCA */ + PHY_IO_READ32(pAd, PHY_BAND0_PHY_CCA, &val); + val |= ((1 << 18) | (1 << 2)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("-- Force Mode: %d, Force CCA SEC40: %d [0x%08x]\n", + ((val & (1 << 18)) >> 18), ((val & (1 << 2)) >> 2), val)); + PHY_IO_WRITE32(pAd, PHY_BAND0_PHY_CCA, val); + /* TMAC_TCR for the normal Tx BW */ + MAC_IO_READ32(pAd, TMAC_TCR, &val); + val &= ~(PRE_RTS_IDLE_DET_DIS); + val |= DCH_DET_DIS; + MAC_IO_WRITE32(pAd, TMAC_TCR, val); + return TRUE; +} + +static INT32 chip_show_dmasch_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + UINT32 value; + UINT32 ple_pkt_max_sz; + UINT32 pse_pkt_max_sz; + UINT32 max_quota; + UINT32 min_quota; + UINT32 rsv_cnt; + UINT32 src_cnt; + UINT32 pse_rsv_cnt = 0; + UINT32 pse_src_cnt = 0; + UINT32 odd_group_pktin_cnt = 0; + UINT32 odd_group_ask_cnt = 0; + UINT32 pktin_cnt; + UINT32 ask_cnt; + UINT32 total_src_cnt = 0; + UINT32 total_rsv_cnt = 0; + UINT32 ffa_cnt; + UINT32 free_pg_cnt; + UINT32 Group_Mapping_Q[16] = {0}; + UINT32 qmapping_addr = MT_HIF_DMASHDL_Q_MAP0; + UINT32 status_addr = MT_HIF_DMASHDL_STATUS_RD_GP0; + UINT32 quota_addr = MT_HIF_DMASHDL_GROUP0_CTRL; + UINT32 pkt_cnt_addr = MT_HIF_DMASHDLRD_GP_PKT_CNT_0; + UINT32 mapping_mask = 0xf; + UINT32 mapping_offset = 0; + UINT32 mapping_qidx; + UINT32 groupidx = 0; + UINT8 idx = 0; + BOOLEAN pktin_int_refill_ena; + BOOLEAN pdma_add_int_refill_ena; + BOOLEAN ple_add_int_refill_ena; + BOOLEAN ple_sub_ena; + BOOLEAN hif_ask_sub_ena; + BOOLEAN ple_txd_gt_max_size_flag_clr; + UINT32 ple_rpg_hif; + UINT32 ple_upg_hif; + UINT32 pse_rpg_hif = 0; + UINT32 pse_upg_hif = 0; + UCHAR is_mismatch = FALSE; + + for (mapping_qidx = 0; mapping_qidx < 32; mapping_qidx++) { + UINT32 mapping_group; + + idx = 0; + + if (mapping_qidx == 0) { + qmapping_addr = MT_HIF_DMASHDL_Q_MAP0; + mapping_mask = 0xf; + mapping_offset = 0; + } else if ((mapping_qidx % 8) == 0) { + qmapping_addr += 0x4; + mapping_mask = 0xf; + mapping_offset = 0; + } else { + mapping_offset += 4; + mapping_mask = 0xf << mapping_offset; + } + + HIF_DMASHDL_IO_READ32(pAd, qmapping_addr, &value); + mapping_group = (value & mapping_mask) >> mapping_offset; + Group_Mapping_Q[mapping_group] |= 1 << mapping_qidx; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Dma scheduler info:\n")); + HIF_DMASHDL_IO_READ32(pAd, MT_HIF_DMASHDL_CTRL_SIGNAL, &value); + pktin_int_refill_ena = (value & DMASHDL_PKTIN_INT_REFILL_ENA) ? TRUE : FALSE; + pdma_add_int_refill_ena = (value & DMASHDL_PDMA_ADD_INT_REFILL_ENA) ? TRUE : FALSE; + ple_add_int_refill_ena = (value & DMASHDL_PLE_ADD_INT_REFILL_ENA) ? TRUE : FALSE; + ple_sub_ena = (value & DMASHDL_PLE_SUB_ENA) ? TRUE : FALSE; + hif_ask_sub_ena = (value & DMASHDL_HIF_ASK_SUB_ENA) ? TRUE : FALSE; + ple_txd_gt_max_size_flag_clr = (value & DMASHDL_PLE_TXD_GT_MAX_SIZE_FLAG_CLR) ? TRUE : FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("DMASHDL Ctrl Signal(0x5000A018): 0x%08x\n", value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tple_txd_gt_max_size_flag_clr(BIT0) = %d\n", ple_txd_gt_max_size_flag_clr)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\thif_ask_sub_ena(BIT16) = %d\n", hif_ask_sub_ena)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tple_sub_ena(BIT17) = %d\n", ple_sub_ena)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tple_add_int_refill_ena(BIT29) = %d\n", ple_add_int_refill_ena)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tpdma_add_int_refill_ena(BIT30) = %d\n", pdma_add_int_refill_ena)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tpktin_int_refill(BIT31)_ena = %d\n", pktin_int_refill_ena)); + HIF_DMASHDL_IO_READ32(pAd, MT_HIF_DMASHDL_PKT_MAX_SIZE, &value); + ple_pkt_max_sz = GET_PLE_PKT_MAX_SIZE_NUM(value); + pse_pkt_max_sz = GET_PSE_PKT_MAX_SIZE_NUM(value); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("DMASHDL Packet_max_size(0x5000A01c): 0x%08x\n", value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PLE/PSE packet max size=0x%03x/0x%03x\n", + ple_pkt_max_sz, pse_pkt_max_sz)); + HIF_DMASHDL_IO_READ32(pAd, MT_HIF_DMASHDL_ERROR_FLAG_CTRL, &value); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("DMASHDL ERR FLAG CTRL(0x5000A09c): 0x%08x\n", value)); + HIF_DMASHDL_IO_READ32(pAd, MT_HIF_DMASHDL_STATUS_RD, &value); + ffa_cnt = (value & DMASHDL_FFA_CNT_MASK) >> DMASHDL_FFA_CNT_OFFSET; + free_pg_cnt = (value & DMASHDL_FREE_PG_CNT_MASK) >> DMASHDL_FREE_PG_CNT_OFFSET; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("DMASHDL Status_RD(0x5000A100): 0x%08x\n", value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("free page cnt = 0x%03x, ffa cnt = 0x%03x\n", free_pg_cnt, ffa_cnt)); + + for (groupidx = 0; groupidx < 16; groupidx++) { + idx = 0; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Group %d info:", groupidx)); + HIF_DMASHDL_IO_READ32(pAd, status_addr, &value); + rsv_cnt = (value & DMASHDL_RSV_CNT_MASK) >> DMASHDL_RSV_CNT_OFFSET; + src_cnt = (value & DMASHDL_SRC_CNT_MASK) >> DMASHDL_SRC_CNT_OFFSET; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tDMASHDL Status_RD_GP%d(0x%08x): 0x%08x\n", groupidx, status_addr, value)); + HIF_DMASHDL_IO_READ32(pAd, quota_addr, &value); + max_quota = (value & DMASHDL_MAX_QUOTA_MASK) >> DMASHDL_MAX_QUOTA_OFFSET; + min_quota = (value & DMASHDL_MIN_QUOTA_MASK) >> DMASHDL_MIN_QUOTA_OFFSET; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tDMASHDL Group%d control(0x%08x): 0x%08x\n", groupidx, quota_addr, value)); + + if ((groupidx & 0x1) == 0) { + HIF_DMASHDL_IO_READ32(pAd, pkt_cnt_addr, &value); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tDMASHDL RD_group_pkt_cnt_%d(0x%08x): 0x%08x\n", groupidx / 2, pkt_cnt_addr, value)); + odd_group_pktin_cnt = GET_ODD_GROUP_PKT_IN_CNT(value); + odd_group_ask_cnt = GET_ODD_GROUP_ASK_CNT(value); + pktin_cnt = GET_EVEN_GROUP_PKT_IN_CNT(value); + ask_cnt = GET_EVEN_GROUP_ASK_CNT(value); + } else { + pktin_cnt = odd_group_pktin_cnt; + ask_cnt = odd_group_ask_cnt; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\trsv_cnt = 0x%03x, src_cnt = 0x%03x\n", rsv_cnt, src_cnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tmax/min quota = 0x%03x/ 0x%03x\n", max_quota, min_quota)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tpktin_cnt = 0x%02x, ask_cnt = 0x%02x", pktin_cnt, ask_cnt)); + + if (hif_ask_sub_ena && pktin_cnt != ask_cnt) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (", mismatch!")); + is_mismatch = TRUE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + if (groupidx == 15 && Group_Mapping_Q[groupidx] == 0) { /* Group15 is for PSE */ + pse_src_cnt = src_cnt; + pse_rsv_cnt = rsv_cnt; + break; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tMapping Qidx:")); + + while (Group_Mapping_Q[groupidx] != 0) { + if (Group_Mapping_Q[groupidx] & 0x1) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Q%d ", idx)); + + Group_Mapping_Q[groupidx] >>= 1; + idx++; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + total_src_cnt += src_cnt; + total_rsv_cnt += rsv_cnt; + status_addr = status_addr + 4; + quota_addr = quota_addr + 4; + + if (groupidx & 0x1) + pkt_cnt_addr = pkt_cnt_addr + 4; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\nCounter Check:\n")); + MAC_IO_READ32(pAd, PLE_HIF_PG_INFO, &value); + ple_rpg_hif = value & 0xfff; + ple_upg_hif = (value & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PLE:\n\tThe used/reserved pages of PLE HIF group=0x%03x/0x%03x\n", + ple_upg_hif, ple_rpg_hif)); + MAC_IO_READ32(pAd, PSE_HIF1_PG_INFO, &value); + pse_rpg_hif = value & 0xfff; + pse_upg_hif = (value & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PSE:\n\tThe used/reserved pages of PSE HIF group=0x%03x/0x%03x\n", + pse_upg_hif, pse_rpg_hif)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("DMASHDL:\n\tThe total used pages of group0~14=0x%03x", + total_src_cnt)); + + if (ple_upg_hif != total_src_cnt) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (", mismatch!")); + is_mismatch = TRUE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tThe total reserved pages of group0~14=0x%03x\n", + total_rsv_cnt)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tThe total ffa pages of group0~14=0x%03x\n", + ffa_cnt)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tThe total free pages of group0~14=0x%03x", + free_pg_cnt)); + + if (free_pg_cnt != total_rsv_cnt + ffa_cnt) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (", mismatch(total_rsv_cnt + ffa_cnt in DMASHDL)")); + is_mismatch = TRUE; + } + + if (free_pg_cnt != ple_rpg_hif) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (", mismatch(reserved pages in PLE)")); + is_mismatch = TRUE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tThe used pages of group15=0x%03x", pse_src_cnt)); + + if (pse_upg_hif != pse_src_cnt) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (", mismatch!")); + is_mismatch = TRUE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tThe reserved pages of group15=0x%03x", pse_rsv_cnt)); + + if (pse_rpg_hif != pse_rsv_cnt) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (", mismatch!")); + is_mismatch = TRUE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + if (!is_mismatch) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("DMASHDL: no counter mismatch\n")); + + return TRUE; +} + +static VOID chip_show_bcn_info(struct hdev_ctrl *ctrl, UCHAR bandidx) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + UINT32 mac_val; + UINT32 addr; + UINT32 idx; + UINT32 band_offset = 0x200 * bandidx; + struct _RTMP_CHIP_DBG *chip_dbg = hc_get_chip_dbg(ctrl); + + if (chip_dbg->dump_mib_info) { + if (bandidx == DBDC_BAND0) + chip_dbg->dump_mib_info(pAd->hdev_ctrl, "0"); + else + chip_dbg->dump_mib_info(pAd->hdev_ctrl, "1"); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + show_trinfo_proc(pAd, ""); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + ShowPLEInfo(pAd, NULL); +#ifdef ERR_RECOVERY + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + ShowSerProc2(pAd, ""); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + show_swqinfo(pAd, ""); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + if (chip_dbg->show_pse_info) + chip_dbg->show_pse_info(pAd->hdev_ctrl, NULL); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + show_tpinfo_proc(pAd, NULL); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + Show_MibBucket_Proc(pAd, ""); + MAC_IO_READ32(pAd, ARB_BFCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ARB_BFCR(0x820f3190)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, ARB_SCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ARB_SCR(0x820f3080)=0x%08x\n", mac_val)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x820f3100~0x820f3154:\n")); + + for (addr = ARB_TQSW0; addr <= ARB_TQPM1; addr = addr + 4) { + if ((addr & 0xf) == 0 && (addr != ARB_TQSW0)) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MAC_IO_READ32(pAd, ARB_BFCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ARB_BFCR(0x820f3190)=0x%08x\n", mac_val)); + /* (WF_LP) Debug CRs */ + MAC_IO_READ32(pAd, LPON_T0STR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_T0STR(0x820fb028)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, LPON_PISR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_PISR(0x820fb030)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, LPON_T0TPCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_T0TPCR(0x820fb34)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, LPON_MPTCR0, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LPON_MPTCR0(0x820fb05c)=0x%08x\n", mac_val)); + /* (WF_INT_WAKEUP) Interrupt CRs */ + MAC_IO_READ32(pAd, WISR0, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("WISR0(0x820fc000)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, WIER0, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("WIER0(0x820fc008)=0x%08x\n", mac_val)); + /* (UMAC) CR used to record SER status */ + MAC_IO_READ32(pAd, PSE_SPARE_DUMMY_CR1, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SER PSE Error INT status(0x820681e4)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PSE_SPARE_DUMMY_CR2, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SER PLE Error INT status(0x820681e8)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PSE_SPARE_DUMMY_CR3, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("SER LMAC WDT status(0x820682e8)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PP_SPARE_DUMMY_CR5, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CritialErrorRecord0(0x8206c064)=0x%08x\n", mac_val)); + MAC_IO_READ32(pAd, PP_SPARE_DUMMY_CR6, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CritialErrorRecord1(0x8206c068)=0x%08x\n", mac_val)); + +#define CR4_HEART_BEAT_STS 0x80200 + MAC_IO_READ32(pAd, CR4_HEART_BEAT_STS, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CR4 heart beat status (0x80200)=0x%08x\n", mac_val)); + MtCmdFwLog2Host(pAd, 1, 0); + MAC_IO_READ32(pAd, RO_BAND0_PHYCTRL_STS + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RO_BAND0_PHYCTRL_STS(0x%08x)= 0x%08x\n", 0x82070230 + band_offset, mac_val)); + /* 0x82070618~0x8207065c */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x%08x~0x%08x:\n", + 0x82070618 + band_offset, 0x8207065c + band_offset)); + + for (addr = PHY_BAND0_PHYMUX_6; addr <= PHY_BAND0_PHYMUX_23; addr = addr + 4) { + if ((addr & 0xf) == 8 && (addr != PHY_BAND0_PHYMUX_6)) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + /* 0x8207227c~0x82072294 */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x%08x~0x%08x:\n", + 0x8207227c + band_offset, 0x82072294 + band_offset)); + + for (addr = RO_BAND0_RXTD_DEBUG0; addr <= RO_BAND0_RXTD_DEBUG6; addr = addr + 4) { + if (addr == RO_BAND0_RXTD_DEBUG4) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + /* 0x820721a0~0x820721b8 */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("dump 0x%08x~0x%08x:\n", + 0x820721a0 + band_offset, 0x820721b8 + band_offset)); + + for (addr = RO_BAND0_AGC_DEBUG_0; addr <= RO_BAND0_AGC_DEBUG_6; addr = addr + 4) { + if (addr == RO_BAND0_AGC_DEBUG_4) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + MAC_IO_READ32(pAd, addr + band_offset, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("addr 0x%05x=0x%08x ", addr, mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + /* + + Write 0x82070614[22:20]=0 + Write 0x82070614[22:20]=5 + + // read the following registers by 10 times + 0X8207_020C + 0x8207_0210 + 0x8207_0214 + 0x8207_021C + 0x8207_0220 + // End of Loop + + */ + MAC_IO_READ32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, &mac_val); + mac_val &= ~(BITS(20, 22)); + MAC_IO_WRITE32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, mac_val); + MAC_IO_READ32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, &mac_val); + mac_val &= ~(BITS(20, 22)); + mac_val |= (BIT(20) | BIT(22)); + MAC_IO_WRITE32(pAd, PHY_BAND0_PHYMUX_5 + band_offset, mac_val); + + for (idx = 0; idx < 10; idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("loop %d:\n", idx)); + + MAC_IO_READ32(pAd, ARB_BFCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tARB_BFCR(0x820f3190)=0x%08x\n", mac_val)); + + MAC_IO_READ32(pAd, AGG_SCR, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tAGG_SCR(0x820F20FC)=0x%08x\n", mac_val)); + + /* DMA debug register */ + MAC_IO_READ32(pAd, DMA_DBG_00, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tDMA_DBG_00(0x820F70D0)=0x%08x\n", mac_val)); + + MAC_IO_READ32(pAd, DMA_DBG_01, &mac_val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tDMA_DBG_01(0x820F70D4)=0x%08x\n", mac_val)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); +} + +static INT32 chip_show_ple_info(struct hdev_ctrl *ctrl, RTMP_STRING *arg) +{ + RTMP_ADAPTER *pAd = ctrl->priv; + UINT32 ple_buf_ctrl[3] = {0}, pg_sz, pg_num, bit_field_1, bit_field_2; + UINT32 ple_stat[17] = {0}, pg_flow_ctrl[6] = {0}; + UINT32 sta_pause[4] = {0}, dis_sta_map[4] = {0}; + UINT32 fpg_cnt, ffa_cnt, fpg_head, fpg_tail, hif_max_q, hif_min_q; + UINT32 rpg_hif, upg_hif, cpu_max_q, cpu_min_q, rpg_cpu, upg_cpu; + INT32 i, j; + UINT32 dumptxd = 0; + + if (arg != NULL) + dumptxd = os_str_toul(arg, 0, 16); + + HW_IO_READ32(pAd, PLE_PBUF_CTRL, &ple_buf_ctrl[0]); + HW_IO_READ32(pAd, PLE_RELEASE_CTRL, &ple_buf_ctrl[1]); + HW_IO_READ32(pAd, PLE_HIF_REPORT, &ple_buf_ctrl[2]); + HW_IO_READ32(pAd, PLE_QUEUE_EMPTY, &ple_stat[0]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_0, &ple_stat[1]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_1, &ple_stat[2]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_2, &ple_stat[3]); + HW_IO_READ32(pAd, PLE_AC0_QUEUE_EMPTY_3, &ple_stat[4]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_0, &ple_stat[5]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_1, &ple_stat[6]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_2, &ple_stat[7]); + HW_IO_READ32(pAd, PLE_AC1_QUEUE_EMPTY_3, &ple_stat[8]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_0, &ple_stat[9]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_1, &ple_stat[10]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_2, &ple_stat[11]); + HW_IO_READ32(pAd, PLE_AC2_QUEUE_EMPTY_3, &ple_stat[12]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_0, &ple_stat[13]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_1, &ple_stat[14]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_2, &ple_stat[15]); + HW_IO_READ32(pAd, PLE_AC3_QUEUE_EMPTY_3, &ple_stat[16]); + HW_IO_READ32(pAd, PLE_FREEPG_CNT, &pg_flow_ctrl[0]); + HW_IO_READ32(pAd, PLE_FREEPG_HEAD_TAIL, &pg_flow_ctrl[1]); + HW_IO_READ32(pAd, PLE_PG_HIF_GROUP, &pg_flow_ctrl[2]); + HW_IO_READ32(pAd, PLE_HIF_PG_INFO, &pg_flow_ctrl[3]); + HW_IO_READ32(pAd, PLE_PG_CPU_GROUP, &pg_flow_ctrl[4]); + HW_IO_READ32(pAd, PLE_CPU_PG_INFO, &pg_flow_ctrl[5]); + HW_IO_READ32(pAd, DIS_STA_MAP0, &dis_sta_map[0]); + HW_IO_READ32(pAd, DIS_STA_MAP1, &dis_sta_map[1]); + HW_IO_READ32(pAd, DIS_STA_MAP2, &dis_sta_map[2]); + HW_IO_READ32(pAd, DIS_STA_MAP3, &dis_sta_map[3]); + HW_IO_READ32(pAd, STATION_PAUSE0, &sta_pause[0]); + HW_IO_READ32(pAd, STATION_PAUSE1, &sta_pause[1]); + HW_IO_READ32(pAd, STATION_PAUSE2, &sta_pause[2]); + HW_IO_READ32(pAd, STATION_PAUSE3, &sta_pause[3]); + /* Configuration Info */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PLE Configuration Info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tPacket Buffer Control(0x82060014): 0x%08x\n", ple_buf_ctrl[0])); + pg_sz = (ple_buf_ctrl[0] & (0x1 << 31)) >> 31; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Size=%d(%d bytes per page)\n", pg_sz, (pg_sz == 1 ? 128 : 64))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tPage Offset=%d(in unit of 16KB)\n", (ple_buf_ctrl[0] & (0xf << 20)) >> 20)); + pg_num = (ple_buf_ctrl[0] & 0xfff); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tTotal Page=%d pages\n", (ple_buf_ctrl[0] & 0xfff))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tRelease Control(0x82060030): 0x%08x\n", ple_buf_ctrl[1])); + bit_field_1 = (ple_buf_ctrl[1] & 0x1f); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 6)) >> 6); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tNormalTx Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 8)) >> 8); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 14)) >> 14); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tDropTx Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 16)) >> 16); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 22)) >> 22); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tBCN0 Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + bit_field_1 = ((ple_buf_ctrl[1] & (0x1f << 24)) >> 24); + bit_field_2 = ((ple_buf_ctrl[1] & (0x3 << 30)) >> 30); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tBCN1 Release Pid/Qid=%d/%d\n", bit_field_2, bit_field_1)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF Report Control(0x82060034): 0x%08x\n", ple_buf_ctrl[2])); + bit_field_1 = ((ple_buf_ctrl[2] & (0x1 << 1)) >> 1); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tHostReportQSel/HostReportDisable=%d/%d\n", + (ple_buf_ctrl[2] & 0x1), bit_field_1)); + /* Page Flow Control */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("PLE Page Flow Control:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page counter(0x82060100): 0x%08x\n", pg_flow_ctrl[0])); + fpg_cnt = pg_flow_ctrl[0] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe toal page number of free=0x%03x\n", fpg_cnt)); + ffa_cnt = (pg_flow_ctrl[0] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe free page numbers of free for all=0x%03x\n", ffa_cnt)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tFree page head and tail(0x82060104): 0x%08x\n", pg_flow_ctrl[1])); + fpg_head = pg_flow_ctrl[1] & 0xfff; + fpg_tail = (pg_flow_ctrl[1] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe tail/head page of free page list=0x%03x/0x%03x\n", fpg_tail, fpg_head)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of HIF group(0x82060110): 0x%08x\n", pg_flow_ctrl[2])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tHIF group page status(0x82060114): 0x%08x\n", pg_flow_ctrl[3])); + hif_min_q = pg_flow_ctrl[2] & 0xfff; + hif_max_q = (pg_flow_ctrl[2] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of HIF group=0x%03x/0x%03x\n", hif_max_q, hif_min_q)); + rpg_hif = pg_flow_ctrl[3] & 0xfff; + upg_hif = (pg_flow_ctrl[3] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of HIF group=0x%03x/0x%03x\n", upg_hif, rpg_hif)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tReserved page counter of CPU group(0x82060150): 0x%08x\n", pg_flow_ctrl[4])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tCPU group page status(0x82060154): 0x%08x\n", pg_flow_ctrl[5])); + cpu_min_q = pg_flow_ctrl[4] & 0xfff; + cpu_max_q = (pg_flow_ctrl[4] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe max/min quota pages of CPU group=0x%03x/0x%03x\n", cpu_max_q, cpu_min_q)); + rpg_cpu = pg_flow_ctrl[5] & 0xfff; + upg_cpu = (pg_flow_ctrl[5] & (0xfff << 16)) >> 16; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t\tThe used/reserved pages of CPU group=0x%03x/0x%03x\n", upg_cpu, rpg_cpu)); + + if (((ple_stat[0] & (0x1 << 24)) >> 24) == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY0(0x82060300): 0x%08x\n", ple_stat[1])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY1(0x82060304): 0x%08x\n", ple_stat[2])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY2(0x82060308): 0x%08x\n", ple_stat[3])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC0_QUEUE_EMPTY3(0x8206030c): 0x%08x\n", ple_stat[4])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY0(0x82060310): 0x%08x\n", ple_stat[5])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY1(0x82060314): 0x%08x\n", ple_stat[6])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY2(0x82060318): 0x%08x\n", ple_stat[7])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC1_QUEUE_EMPTY3(0x8206031c): 0x%08x\n", ple_stat[8])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY0(0x82060320): 0x%08x\n", ple_stat[9])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY1(0x82060324): 0x%08x\n", ple_stat[10])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY2(0x82060328): 0x%08x\n", ple_stat[11])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC2_QUEUE_EMPTY3(0x8206032c): 0x%08x\n", ple_stat[12])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY0(0x82060330): 0x%08x\n", ple_stat[13])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY1(0x82060334): 0x%08x\n", ple_stat[14])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY2(0x82060338): 0x%08x\n", ple_stat[15])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tAC3_QUEUE_EMPTY3(0x8206033c): 0x%08x\n", ple_stat[16])); + + for (j = 0; j < 16; j++) { + if (j % 4 == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\n\tNonempty AC%d Q of STA#: ", j / 4)); + } + + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%d ", i + (j % 4) * 32)); + } + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Nonempty Q info:\n")); + + for (i = 0; i < 31; i++) { + if (((ple_stat[0] & (0x1 << i)) >> i) == 0) { + UINT32 hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; + + if (Queue_Empty_info[i].QueueName != NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t%s: ", Queue_Empty_info[i].QueueName)); + fl_que_ctrl[0] |= (0x1 << 31); + fl_que_ctrl[0] |= (Queue_Empty_info[i].Portid << 14); + fl_que_ctrl[0] |= (Queue_Empty_info[i].Queueid << 8); + } else + continue; + + HW_IO_WRITE32(pAd, PLE_FL_QUE_CTRL_0, fl_que_ctrl[0]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_2, &fl_que_ctrl[1]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_3, &fl_que_ctrl[2]); + hfid = fl_que_ctrl[1] & 0xfff; + tfid = (fl_que_ctrl[1] & 0xfff << 16) >> 16; + pktcnt = fl_que_ctrl[2] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("tail/head fid = 0x%03x/0x%03x, pkt cnt = %x\n", + tfid, hfid, pktcnt)); + + if (pktcnt > 0 && dumptxd > 0) + ShowTXDInfo(pAd, hfid); + } + } + + for (j = 0; j < 16; j++) { /* show AC Q info */ + for (i = 0; i < 32; i++) { + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { + UINT32 hfid, tfid, pktcnt, ac_num = j / 4, ctrlvalue = 0; + UINT32 sta_num = i + (j % 4) * 32, fl_que_ctrl[3] = {0}; + struct wifi_dev *wdev = wdev_search_by_wcid(pAd, sta_num); + UINT32 wmmidx = 0; + + if (wdev) + wmmidx = HcGetWmmIdx(pAd, wdev); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tSTA%d AC%d: ", sta_num, ac_num)); + fl_que_ctrl[0] |= (0x1 << 31); + fl_que_ctrl[0] |= (0x2 << 14); + fl_que_ctrl[0] |= (ac_num << 8); + fl_que_ctrl[0] |= sta_num; + HW_IO_WRITE32(pAd, PLE_FL_QUE_CTRL_0, fl_que_ctrl[0]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_2, &fl_que_ctrl[1]); + HW_IO_READ32(pAd, PLE_FL_QUE_CTRL_3, &fl_que_ctrl[2]); + hfid = fl_que_ctrl[1] & 0xfff; + tfid = (fl_que_ctrl[1] & 0xfff << 16) >> 16; + pktcnt = fl_que_ctrl[2] & 0xfff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("tail/head fid = 0x%03x/0x%03x, pkt cnt = %x", + tfid, hfid, pktcnt)); + + if (((sta_pause[j % 4] & 0x1 << i) >> i) == 1) + ctrlvalue = 2; + + if (((dis_sta_map[j % 4] & 0x1 << i) >> i) == 1) + ctrlvalue = 1; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" ctrl = %s", sta_ctrl_reg[ctrlvalue])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (" (wmmidx=%d)\n", wmmidx)); + + if (pktcnt > 0 && dumptxd > 0) + ShowTXDInfo(pAd, hfid); + } + } + } + + return TRUE; +} + +VOID mt7622_chip_dbg_init(struct _RTMP_CHIP_DBG *dbg_ops) +{ + dbg_ops->dump_ps_table = chip_dump_ps_table; + dbg_ops->dump_mib_info = chip_dump_mib_info; + dbg_ops->show_tmac_info = chip_show_tmac_info; + dbg_ops->show_agg_info = chip_show_agg_info; + dbg_ops->show_dmasch_info = chip_show_dmasch_info; + dbg_ops->show_pse_info = chip_show_pse_info; + dbg_ops->show_pse_data = NULL; /* read PSE data from host is not supported */ + dbg_ops->show_protect_info = chip_show_protect_info; + dbg_ops->show_cca_info = chip_show_cca_info; + dbg_ops->set_cca_en = chip_set_cca_en; + dbg_ops->show_txv_info = NULL; + dbg_ops->show_bcn_info = chip_show_bcn_info; + dbg_ops->show_ple_info = chip_show_ple_info; +} + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/rtmp_chip.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/rtmp_chip.c new file mode 100644 index 000000000..7d2eadae6 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/chips/rtmp_chip.c @@ -0,0 +1,255 @@ +/* + *************************************************************************** + * 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" + +/* +======================================================================== +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) +{ +} + + +/* +======================================================================== +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; + } +} + +/* +======================================================================== +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 = hc_get_chip_cap(pAd->hdev_ctrl); + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + pChipCap->FlgIsSupSpecBcnBuf = FALSE; + pChipCap->BcnMaxHwNum = 8; + pChipCap->BcnMaxNum = (pChipCap->BcnMaxHwNum - MAX_MESH_NUM - MAX_APCLI_NUM); + pChipCap->BcnMaxHwSize = 0x1000; + pChipCap->BcnBase[0] = 0x7800; + pChipCap->BcnBase[1] = 0x7A00; + pChipCap->BcnBase[2] = 0x7C00; + pChipCap->BcnBase[3] = 0x7E00; + pChipCap->BcnBase[4] = 0x7200; + pChipCap->BcnBase[5] = 0x7400; + pChipCap->BcnBase[6] = 0x5DC0; + pChipCap->BcnBase[7] = 0x5BC0; + + /* + If the MAX_MBSSID_NUM is larger than 6, + it shall reserve some WCID space(wcid 222~253) for beacon frames. + - these wcid 238~253 are reserved for beacon#6(ra6). + - these wcid 222~237 are reserved for beacon#7(ra7). + */ + if (pChipCap->BcnMaxNum == 8) + pChipCap->WcidHwRsvNum = 222; + else if (pChipCap->BcnMaxNum == 7) + pChipCap->WcidHwRsvNum = 238; + else + pChipCap->WcidHwRsvNum = 255; + + ops->BeaconUpdate = RtmpChipWriteMemory; +} + +UINT8 NICGetBandSupported(RTMP_ADAPTER *pAd) +{ + if (BOARD_IS_5G_ONLY(pAd)) + return RFIC_5GHZ; + else if (BOARD_IS_2G_ONLY(pAd)) + return RFIC_24GHZ; + else if (RFIC_IS_5G_BAND(pAd)) + return RFIC_DUAL_BAND; + else + return RFIC_24GHZ; +} + + +INT WaitForAsicReady(RTMP_ADAPTER *pAd) +{ + return TRUE; +} + + +INT AsicGetMacVersion(RTMP_ADAPTER *pAd) +{ + UINT32 reg = 0; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + /* TODO: shiang-7603 */ + if (cap->hif_type == HIF_MT) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(%d): Not support for HIF_MT yet!\n", + __func__, __LINE__)); + return FALSE; + } + + if (WaitForAsicReady(pAd) == TRUE) { + RTMP_IO_READ32(pAd, reg, &pAd->MACVersion); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("MACVersion[Ver:Rev]=0x%08x : 0x%08x\n", + pAd->MACVersion, pAd->ChipID)); + return TRUE; + } else { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() failed!\n", __func__)); + return FALSE; + } +} + + +/* +======================================================================== +Routine Description: + Initialize chip related information. + +Arguments: + pCB - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +int RtmpChipOpsHook(VOID *pCB) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pCB; + RTMP_CHIP_CAP *pChipCap = hc_get_chip_cap(pAd->hdev_ctrl); + int ret = 0; + +#ifdef MT_DFS_SUPPORT + /* Initial new DFS channel list */ + DfsSetNewChInit(pAd); +#endif + + /* sanity check */ + if (WaitForAsicReady(pAd) == FALSE) + return -1; + + /* TODO: shiang-7603 */ + if (IS_MT7603(pAd) || IS_MT7628(pAd) || IS_MT76x6(pAd) || IS_MT7637(pAd) || IS_MT7615(pAd)) { + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(%d): Not support for HIF_MT yet! MACVersion=0x%x\n", + __func__, __LINE__, pAd->MACVersion)); + } + + if (pAd->MACVersion == 0xffffffff) + return -1; + + /* default init */ + RTMP_DRS_ALG_INIT(pAd, RATE_ALG_LEGACY); +#ifdef RTMP_RBUS_SUPPORT + + if (pAd->infType == RTMP_DEV_INF_RBUS) { + /* wilsonl, need DE provide info */ +#ifndef MT7622 + RTMP_SYS_IO_READ32(0xb000000c, &pAd->CommonCfg.CID); + RTMP_SYS_IO_READ32(0xb0000000, &pAd->CommonCfg.CN); +#endif + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("CN: %lx\tCID = %lx\n", + pAd->CommonCfg.CN, pAd->CommonCfg.CID)); + } + +#endif /* RTMP_RBUS_SUPPORT */ + /*initial chip hook function*/ + WfSysPreInit(pAd); + + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Chip specific bbpRegTbSize=%d!\n", pChipCap->bbpRegTbSize)); + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Chip VCO calibration mode = %d!\n", pChipCap->FlgIsVcoReCalMode)); +#ifdef DOT11W_PMF_SUPPORT + MTWF_LOG(DBG_CAT_HW, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[PMF] Encryption mode = %d\n", pChipCap->FlgPMFEncrtptMode)); +#endif /* DOT11W_PMF_SUPPORT */ + return ret; +} + + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Kconfig b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Kconfig new file mode 100644 index 000000000..8cb9f595d --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Kconfig @@ -0,0 +1,528 @@ +config MT_WIFI + tristate "MT WIFI Driver" + select WIFI_BASIC_FUNC if MT_WIFI + +config MT_WIFI_PATH + string + depends on MT_WIFI + default "mt_wifi" + +if MT_WIFI +menu "WiFi Generic Feature Options" +choice + prompt "EEPROM Type of 1st Card" + depends on ! FIRST_IF_NONE + + config FIRST_IF_EEPROM_FLASH + bool "FLASH" + + config FIRST_IF_EEPROM_EFUSE + bool "EFUSE" +endchoice + +config RT_FIRST_CARD_EEPROM + string + depends on ! FIRST_IF_NONE + default "flash" if FIRST_IF_EEPROM_FLASH + +choice + prompt "EEPROM Type of 2nd Card" + depends on ! SECOND_IF_NONE + + config SECOND_IF_EEPROM_FLASH + bool "FLASH" + + config SECOND_IF_EEPROM_PROM + bool "EEPROM" + + config SECOND_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config RT_SECOND_CARD_EEPROM + string + depends on ! SECOND_IF_NONE + default "prom" if SECOND_IF_EEPROM_PROM + default "efuse" if SECOND_IF_EEPROM_EFUSE + default "flash" if SECOND_IF_EEPROM_FLASH + +choice + prompt "EEPROM Type of 3th Card" + depends on ! THIRD_IF_NONE + + config THIRD_IF_EEPROM_FLASH + bool "FLASH" + + config THIRD_IF_EEPROM_PROM + bool "EEPROM" + + config THIRD_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config RT_THIRD_CARD_EEPROM + string + depends on ! THIRD_IF_NONE + default "prom" if THIRD_IF_EEPROM_PROM + default "efuse" if THIRD_IF_EEPROM_EFUSE + default "flash" if THIRD_IF_EEPROM_FLASH + +config MULTI_INF_SUPPORT + bool + default y if !FIRST_IF_NONE && !SECOND_IF_NONE + +config WIFI_BASIC_FUNC + bool "Basic Functions" + select WIRELESS_EXT + select WEXT_SPY + select WEXT_PRIV + +config DOT11_N_SUPPORT + bool "802.11n support" + default y + +config DOT11_VHT_AC + bool "802.11AC support" + depends on WIFI_DRIVER + depends on DOT11_N_SUPPORT + default y + +config G_BAND_256QAM_SUPPORT + bool "2.4G 256QAM support" + depends on WIFI_DRIVER + depends on DOT11_VHT_AC + default y + +config TPC_SUPPORT + bool "802.11h TPC Support" + depends on WIFI_DRIVER + default y + +config ICAP_SUPPORT + bool "ICAP Support" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT + default y + +config SPECTRUM_SUPPORT + bool "Wifi Spectrum Support" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT + default y + +config BACKGROUND_SCAN_SUPPORT + bool "Background Scan Support" + depends on WIFI_DRIVER + default y + +config SMART_CARRIER_SENSE_SUPPORT + bool "Smart Carrier Sense Support" + depends on WIFI_DRIVER + default y + +config MT_DFS_SUPPORT + bool "Dynamic Frequency Selection Support" + depends on WIFI_DRIVER + default y + +#config WFA_VHT_R2_PF +# bool "WFA VHT R2 Plugfest" +# depends on DOT11_VHT_AC +# default n + +config HDR_TRANS_TX_SUPPORT + bool "Tx Header Translation" + depends on CHIP_MT7615E || CHIP_MT7622 || CHIP_MT7663E + default y + +config HDR_TRANS_RX_SUPPORT + bool "Rx Header Translation" + depends on CHIP_MT7615E || CHIP_MT7622 || CHIP_MT7663E + default y + +config DBDC_MODE + bool "dbdc mode support" + depends on CHIP_MT7615E + select MULTI_PROFILE_SUPPORT +# select DEFAULT_5G_PROFILE + default y + +config MULTI_PROFILE_SUPPORT + bool "Multi Profile Support" + depends on DBDC_MODE + default y + +config DEFAULT_5G_PROFILE + bool "5G default profile for DBDC" + depends on DBDC_MODE + default n + +config WSC_INCLUDED + bool "WSC (WiFi Simple Config)" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT || MT_STA_SUPPORT + default y + +config WSC_V2_SUPPORT + bool "WSC V2(WiFi Simple Config Version 2.0)" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT || MT_STA_SUPPORT + default y + +config DOT11W_PMF_SUPPORT + bool "PMF" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT || MT_STA_SUPPORT + default y + +config TXBF_SUPPORT + bool "Tx Bean Forming Support" + depends on WIFI_DRIVER + default y + +config FAST_NAT_SUPPORT + bool "Fast-NAT support" + depends on RA_HW_NAT_WIFI + default n + +config WHNAT_SUPPORT + tristate "Wifi Hardware NAT support" + depends on CHIP_MT7615E + depends on WLAN_HOOK + depends on FAST_NAT_SUPPORT + default n + +#config LLTD_SUPPORT +# bool "LLTD (Link Layer Topology Discovery Protocol)" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config QOS_DLS_SUPPORT +# bool "802.11e DLS ((Direct-Link Setup) Support" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config WAPI_SUPPORT +# bool "WAPI Support" +# depends on WIFI_DRIVER +# default n + +config FTM_SUPPORT + bool "FTM Support" + depends on WIFI_DRIVER + select PASSPOINT_R2 + default n + +config MBO_SUPPORT + bool "MBO Support" + depends on WIFI_DRIVER + select INTERWORKING + select WNM_SUPPORT + select DOT11K_RRM_SUPPORT + select DOT11R_FT_SUPPORT + select DOT11W_PMF_SUPPORT + select PASSPOINT_R2 + default n + +#config CARRIER_DETECTION_SUPPORT +# bool "Carrier Detect" +# depends on WIFI_DRIVER +# default n + +config IGMP_SNOOP_SUPPORT + bool "IGMP snooping" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT + default y + +#config BLOCK_NET_IF +# bool "NETIF Block" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n +# help +# Support Net interface block while Tx-Sw queue full + +#config RATE_ADAPTION +# bool "New Rate Adaptation support" +# depends on WIFI_DRIVER +# default y + +#config NEW_RATE_ADAPT_SUPPORT +# bool "Intelligent Rate Adaption" +# depends on WIFI_DRIVER && RATE_ADAPTION +# default y + +#config AGS_SUPPORT +# bool "Adaptive Group Switching" +# depends on WIFI_DRIVER && RATE_ADAPTION +# depends on MT_AP_SUPPORT || MT_STA_SUPPORT +# default n + +#config RATE_ADAPT_AGBS_SUPPORT +# bool "Adaptive AGBS Mode" +# depends on WIFI_DRIVER && RATE_ADAPTION +# depends on MT_AP_SUPPORT || MT_STA_SUPPORT +# default y + +#config IDS_SUPPORT +# bool "IDS (Intrusion Detection System) Support" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config WIFI_WORK_QUEUE +# bool "Work Queue" +# depends on WIFI_DRIVER +# default n + +#config WIFI_SKB_RECYCLE +# bool "SKB Recycle(Linux)" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +config RTMP_FLASH_SUPPORT + bool "Flash Support" + depends on WIFI_DRIVER + default y + +config PRE_CAL_TRX_SET1_SUPPORT + bool "Calibration To Flash/BinFile Support" + depends on WIFI_DRIVER + default y + +config RLM_CAL_CACHE_SUPPORT + bool "RlmCalibrationCache Support" + depends on WIFI_DRIVER + default y + +config PRE_CAL_TRX_SET2_SUPPORT + bool "Pre-calibration to Flash Support" + depends on WIFI_DRIVER + default y + +config RF_LOCKDOWN_SUPPORT + bool "RF Lockdown Support" + depends on WIFI_DRIVER + default n + +config LINK_TEST_SUPPORT + bool "Link Test Support" + depends on WIFI_DRIVER + default y + +#config LED_CONTROL_SUPPORT +# bool "LED Support" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +config ATE_SUPPORT + bool "ATE/QA Support" + depends on WIFI_DRIVER + default y + +#config MEMORY_OPTIMIZATION +# bool "Memory Optimization" +# depends on WIFI_DRIVER +# default n + +config PASSPOINT_R2 + bool "Passpoint Release-2 Support" + depends on WIFI_DRIVER + select DOT11W_PMF_SUPPORT + depends on MT_AP_SUPPORT + default n + +#config TRACE_TCP_PKT +# bool "TCP DATA/ACK packets trace log" +# depends on WIFI_DRIVER +# default n + +config UAPSD + bool "UAPSD support" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT || MT_STA_SUPPORT + default y + +config TCP_RACK_SUPPORT + bool "TCP Reduced ACK support" + depends on WIFI_DRIVER + default n + +#### PA_LNA_Type choice + +config RED_SUPPORT + bool "RED(Random Early Drop) support" + depends on WIFI_DRIVER + depends on MT_AP_SUPPORT || MT_STA_SUPPORT + default y + +config FDB_SUPPORT + bool "FW Debug Port" + depends on WIFI_DRIVER + default n + +choice + prompt "PA LNA Type of 1st Card" + depends on ! FIRST_IF_NONE + + config FIRST_IF_EPAELNA + bool "ePAeLNA" + config FIRST_IF_IPAILNA + bool "iPAiLNA" + config FIRST_IF_IPAELNA + bool "iPAeLNA" +# config FIRST_IF_EPAILNA +# bool "ePAiLNA" +endchoice +choice + prompt "PA LNA Type of 2nd Card" + depends on ! SECOND_IF_NONE + + config SECOND_IF_EPAELNA + bool "ePAeLNA" + config SECOND_IF_IPAILNA + bool "iPAiLNA" + config SECOND_IF_IPAELNA + bool "iPAeLNA" +# config SECOND_IF_EPAILNA +# bool "ePAiLNA" +endchoice +choice + prompt "PA LNA Type of 3rd Card" + depends on ! THIRD_IF_NONE + + config THIRD_IF_EPAELNA + bool "ePAeLNA" + config THIRD_IF_IPAILNA + bool "iPAiLNA" + config THIRD_IF_IPAELNA + bool "iPAeLNA" +# config THIRD_IF_EPAILNA +# bool "ePAiLNA" +endchoice +#### PA_LNA_Type choice END + +# +# Section for chip architectures +# +# "RLT MAC Support" +config RLT_MAC + bool + depends on WIFI_DRIVER + default n + +config RLT_BBP + bool + +config RLT_RF + bool + +# "RTMP MAC Support" +config RTMP_MAC + bool + depends on WIFI_DRIVER + default n + +config RTMP_BBP + bool + +config RTMP_RF + bool + +# +# Section for interfaces +# +config RTMP_PCI_SUPPORT + bool + +config RTMP_USB_SUPPORT + bool + +config RTMP_RBUS_SUPPORT + bool + +endmenu + +menu "WiFi Operation Modes" + choice + prompt "Main Mode" + default WIFI_MODE_AP + + config WIFI_MODE_AP + tristate "AP" + select MT_AP_SUPPORT + + config WIFI_MODE_STA + tristate "STA" + select MT_STA_SUPPORT + + config WIFI_MODE_BOTH + tristate "APSTA" + select MT_AP_SUPPORT + select MT_STA_SUPPORT + endchoice + + if WIFI_MODE_AP || WIFI_MODE_BOTH + source "drivers/net/wireless/mt_wifi_ap/Kconfig" + endif + + if WIFI_MODE_STA || WIFI_MODE_BOTH + source "drivers/net/wireless/mt_wifi_sta/Kconfig" + endif +endmenu + +endif + +if WIFI_RLT_MAC + config RLT_MAC + bool + default y +endif + +if WIFI_RTMP_MAC + config RTMP_MAC + bool + default y +endif + +if WIFI_MT_MAC + config MT_MAC + bool + default y + + config CHIP_MT7603E + bool + default n + + config CHIP_MT7615E + bool + default n + + config CHIP_MT7622 + bool + default n + + config CHIP_MT7663E + bool + default n +endif + +if CHIP_MT7615E + config MT_MAC + bool + default y + select RATE_ADAPTION + select RATE_ADAPT_AGBS_SUPPORT + select DOT11_N_SUPPORT + select DOT11_VHT_AC + select HDR_TRANS_TX_SUPPORT + select HDR_TRANS_RX_SUPPORT +endif + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Makefile b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Makefile new file mode 100644 index 000000000..98c53dcfc --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Makefile @@ -0,0 +1,527 @@ +ifeq ($(WIFI_MODE),) +RT28xx_MODE = AP +else +RT28xx_MODE = $(WIFI_MODE) +endif + +ifeq ($(TARGET),) +TARGET = LINUX +endif + +# CHIPSET +ifeq ($(CHIPSET),) +CHIPSET = mt7622 mt7615 +endif + +MODULE = $(word 1, $(CHIPSET)) + +#OS ABL - YES or NO +OSABL = NO + +ifneq ($(TARGET),THREADX) +#RT28xx_DIR = home directory of RT28xx source code +RT28xx_EMBEDDED_DIR = $(shell pwd) +RT28xx_DIR = $(shell cd ..;pwd) +#RT28xx_BIN_DIR = parent directory of bin folder, used by bin2h +RT28xx_BIN_DIR = $(shell cd ../..;pwd) +RT28xx_OS_DIR = $(RT28xx_DIR)/os +endif + +include $(RT28xx_OS_DIR)/linux/config.mk + +RTMP_SRC_DIR = $(RT28xx_DIR)/RT$(MODULE) + +ifeq ($(PLATFORM),) +#PLATFORM: Target platform +PLATFORM = PC +#PLATFORM = BB_SOC +#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 = SMDK +#PLATFORM = RMI +#PLATFORM = RMI_64 +#PLATFORM = KODAK_DC +#PLATFORM = DM6446 +#PLATFORM = FREESCALE8377 +#PLATFORM = BL2348 +#PLATFORM = BL23570 +#PLATFORM = BLUBB +#PLATFORM = BLPMP +#PLATFORM = MT85XX +#PLATFORM = MT53XX +#PLATFORM = NXP_TV550 +#PLATFORM = MVL5 +#PLATFORM = UBICOM_IPX8 +#PLATFORM = INTELP6 +#PLATFORM = MT7620 +#PLATFORM = MT7621 +#PLATFORM = MT7622 +endif + +#APSOC +ifeq ($(CHIPSET),mt7628) +PLATFORM = MT7628 +endif + +#RELEASE Package +RELEASE = FormalRelease + +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),BB_SOC) +LINUX_SRC = $(KERNEL_DIR) +#CROSS_COMPILE = /opt/trendchip/mips-linux-uclibc/usr/bin/mips-linux-uclibc- +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),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),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),MT53XX) +TARGET = LINUX +#****** For system auto build ****** +#LINUX_SRC=$(KERNEL_OBJ_ROOT)/$(KERNEL_VER)/$(KERNEL_CONFIG)_modules +#****** For local build ****** +# uncomment the following lines +VM_LINUX_ROOT ?= $(word 1, $(subst /vm_linux/,/vm_linux /, $(shell pwd))) +LINUX_ROOT ?= $(VM_LINUX_ROOT) +LINUX_SRC=$(VM_LINUX_ROOT)/output/Sony_android/Fiji_EU_JB/rel/obj/kernel/chiling/kernel/linux-3.4/_android_smp_mod_defconfig_modules +OBJ_ROOT ?= $(VM_LINUX_ROOT)/output/Sony_android/Fiji_EU_JB/rel/obj +export KERNEL_OBJ_ROOT=$(LINUX_SRC)/../.. +ifeq ($(CROSS_COMPILE),) +CROSS_COMPILE=/mtkoss/gnuarm/vfp_4.5.1_2.6.27_cortex-a9-rhel4/i686/bin/armv7a-mediatek451_001_vfp-linux-gnueabi- +endif +ifeq "$(CC)" "gcc" +CC ?= $(CROSS_COMPILE)gcc +endif +$(warning =============================================) +$(warning CC=$(CC) for wifi driver LINUX_SRC=$(LINUX_SRC)) +$(warning TARGET=$(TARGET)) +$(warning =============================================) +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),MT7621) +LINUX_SRC = /mtkoss/linux_headers/linux-headers-3.10.14-mips +CROSS_COMPILE = /opt/buildroot-gcc463/usr/bin/mipsel-linux- +ARCH = mips +export $ARCH +endif + +ifeq ($(PLATFORM),MT7628) +LINUX_SRC = /root/Working/MT7628_SDK_2013_0912/RT288x_SDK/source/linux-2.6.36.x +CROSS_COMPILE = /opt/buildroot-gcc342/bin/mipsel-linux- +endif + +ifeq ($(PLATFORM),MT7622) +LINUX_SRC = /mtkoss/linux_headers/linux-headers-4.4.24-arm64/ +CROSS_COMPILE = /opt/buildroot-gcc492_arm64/usr/bin/aarch64-linux- +ARCH = arm64 +export $ARCH +endif + +export OSABL RT28xx_DIR RT28xx_BIN_DIR RT28xx_OS_DIR RT28xx_EMBEDDED_DIR RT28xx_MODE LINUX_SRC CROSS_COMPILE CROSS_COMPILE_INCLUDE PLATFORM RELEASE CHIPSET MODULE RTMP_SRC_DIR LINUX_SRC_MODULE TARGET HAS_WOW_SUPPORT HAS_FPGA_MODE HAS_RX_CUT_THROUGH + +# The targets that may be used. +PHONY += all build_tools test UCOS THREADX LINUX release prerelease clean uninstall install libwapi osabl sdk_build_tools + +ifeq ($(TARGET),LINUX) +all: build_tools $(TARGET) plug_in +else +all: $(TARGET) +endif + +build_sku_tables: + $(MAKE) -C $(RT28xx_DIR)/txpwr + $(RT28xx_DIR)/txpwr/dat2h + +build_tools: + $(MAKE) -C tools + $(RT28xx_EMBEDDED_DIR)/tools/bin2h + +sdk_build_tools: + if [ -f $(RT28xx_DIR)/eeprom_log ]; then \ + rm -f $(RT28xx_DIR)/eeprom_log + fi + echo $(EE_TYPE) >> eeprom_log + echo $(CHIPSET) >> eeprom_log + if [ -f $(RT28xx_DIR)/eeprom/SA/MT7603E_EEPROM.bin ]; then \ + echo 'find SA/MT7603E_EEPROM.bin' >> eeprom_log ; \ + cp -f $(RT28xx_DIR)/eeprom/SA/MT7603E_EEPROM.bin $(RT28xx_DIR)/eeprom/MT7603E_EEPROM.bin ; \ + else \ + cp -f $(RT28xx_DIR)/eeprom/$(EE_TYPE)/MT7603E_EEPROM.bin $(RT28xx_DIR)/eeprom/MT7603E_EEPROM.bin ; \ + fi + $(MAKE) -C tools + $(RT28xx_EMBEDDED_DIR)/tools/bin2h +# rm -f $(RT28xx_DIR)/eeprom/SA/MT7603E_EEPROM.bin + +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_OS_DIR)/Threadx -f $(RT28xx_OS_DIR)/ThreadX/Makefile + +LINUX: +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + +ifeq ($(OSABL),YES) + cp -f $(RT28xx_OS_DIR)/linux/Makefile.4.util $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(RT28xx_OS_DIR)/linux/ +endif + + cp -f $(RT28xx_OS_DIR)/linux/Makefile.4 $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(RT28xx_OS_DIR)/linux/ + +ifeq ($(OSABL),YES) + cp -f $(RT28xx_OS_DIR)/linux/Makefile.4.netif $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(RT28xx_OS_DIR)/linux/ +endif + +else + +ifeq ($(OSABL),YES) + cp -f $(RT28xx_OS_DIR)/linux/Makefile.6.util $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_OS_DIR)/linux modules +endif + + cp -f $(RT28xx_OS_DIR)/linux/Makefile.6 $(RT28xx_OS_DIR)/linux/Makefile +ifeq ($(PLATFORM),DM6446) + $(MAKE) ARCH=arm CROSS_COMPILE=arm_v5t_le- -C $(LINUX_SRC) SUBDIRS=$(RT28xx_OS_DIR)/linux modules +else ifeq ($(PLATFORM),FREESCALE8377) + $(MAKE) ARCH=powerpc CROSS_COMPILE=$(CROSS_COMPILE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_OS_DIR)/linux modules +else ifeq ($(PLATFORM), $(filter $(PLATFORM), MT7622 MT7621)) + $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_OS_DIR)/linux modules +else + $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_OS_DIR)/linux modules +endif + +ifeq ($(OSABL),YES) + cp -f $(RT28xx_OS_DIR)/linux/Makefile.6.netif $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_OS_DIR)/linux modules +endif + +endif + +check_build: + $(RT28xx_EMBEDDED_DIR)/tools/check_build_script.sh + +plug_in: + $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_EMBEDDED_DIR)/tools/plug_in MODULE_FLAGS="$(WFLAGS)" + +release: build_tools + $(MAKE) -C $(RT28xx_EMBEDDED_DIR)/striptool -f Makefile.release clean + $(MAKE) -C $(RT28xx_EMBEDDED_DIR)/striptool -f Makefile.release + striptool/striptool.out +ifeq ($(RELEASE), DPO) + gcc -o embedded/striptool/banner striptool/banner.c + ./embedded/striptool/banner -b embedded/striptool/copyright.gpl -s DPO/ -d DPO_GPL -R + ./embedded/striptool/banner -b embedded/striptool/copyright.frm -s DPO_GPL/include/firmware.h +endif + +prerelease: +ifeq ($(MODULE), 2880) + $(MAKE) -C $(RT28xx_OS_DIR)/linux -f Makefile.release.2880 prerelease +else + $(MAKE) -C $(RT28xx_OS_DIR)/linux -f Makefile.release prerelease +endif + cp $(RT28xx_OS_DIR)/linux/Makefile.DPB $(RTMP_SRC_DIR)/os/linux/. + cp $(RT28xx_OS_DIR)/linux/Makefile.DPA $(RTMP_SRC_DIR)/os/linux/. + cp $(RT28xx_OS_DIR)/linux/Makefile.DPC $(RTMP_SRC_DIR)/os/linux/. +ifeq ($(RT28xx_MODE),STA) + cp $(RT28xx_OS_DIR)/linux/Makefile.DPD $(RTMP_SRC_DIR)/os/linux/. + cp $(RT28xx_OS_DIR)/linux/Makefile.DPO $(RTMP_SRC_DIR)/os/linux/. +endif + +clean: +ifeq ($(TARGET), LINUX) + cp -f $(RT28xx_OS_DIR)/linux/Makefile.clean $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(RT28xx_OS_DIR)/linux clean + rm -rf $(RT28xx_OS_DIR)/linux/Makefile +endif +ifeq ($(TARGET), UCOS) + $(MAKE) -C $(RT28xx_OS_DIR)/ucos clean MODE=$(RT28xx_MODE) +endif +ifeq ($(TARGET), ECOS) + $(MAKE) -C $(RT28xx_OS_DIR)/ecos clean MODE=$(RT28xx_MODE) +endif + +uninstall: +ifeq ($(TARGET), LINUX) +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + $(MAKE) -C $(RT28xx_OS_DIR)/linux -f Makefile.4 uninstall +else + $(MAKE) -C $(RT28xx_OS_DIR)/linux -f Makefile.6 uninstall +endif +endif + +install: +ifeq ($(TARGET), LINUX) +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + $(MAKE) -C $(RT28xx_OS_DIR)/linux -f Makefile.4 install +else + $(MAKE) -C $(RT28xx_OS_DIR)/linux -f Makefile.6 install +endif +endif + +libwapi: +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + cp -f embedded/os/linux/Makefile.libwapi.4 $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(RT28xx_OS_DIR)/linux/ +else + cp -f embedded/os/linux/Makefile.libwapi.6 $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(RT28xx_OS_DIR)/linux modules +endif + +osutil: +ifeq ($(OSABL),YES) +ifneq (,$(findstring 2.4,$(LINUX_SRC))) + cp -f os/linux/Makefile.4.util $(RT28xx_OS_DIR)/linux/Makefile + $(MAKE) -C $(RT28xx_DIR)/os/linux/ +else + cp -f os/linux/Makefile.6.util $(RT28xx_OS_DIR)/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/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Pack_Release.sh b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Pack_Release.sh new file mode 100644 index 000000000..4c88add80 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Pack_Release.sh @@ -0,0 +1,92 @@ +EmbeddedDir=`pwd` +BaseCodeDir=`dirname $EmbeddedDir` +HomeDir=`dirname $BaseCodeDir` +dir_main=mt_wifi +dir_ap=mt_wifi_ap +dir_sta=mt_wifi_sta +release_profile=$BaseCodeDir/Release.log +#module_name=`basename $BaseCodeDir` +module_name=`cat $release_profile | line` +release_version=`sed -e '1d' $release_profile | line` +release_date=`sed -e '1,2d' $release_profile | line` +package_name=$module_name\_$release_version\_$release_date +############################ + + cd $HomeDir + + ### Creat dir_main ### + if [ -d $dir_main ]; then + rm -rf $dir_main + fi + + if [ -d $dir_ap ]; then + rm -rf $dir_ap + fi + + #if [ -d $dir_sta ]; then + # rm -rf $dir_sta + #fi + + if [ -d $HomeDir/../temp_release ]; then + rm -rf $HomeDir/../temp_release + fi + + mv $BaseCodeDir $HomeDir/../temp_release + rm -rf * + mv $HomeDir/../temp_release $dir_main + #cp Kconfig $dir_main/ + rm $dir_main/embedded/Pack_Release.sh $dir_main/Release.log + + mkdir $dir_ap + cp $dir_main/os/linux/Kconfig.mt_wifi_ap $dir_ap/Kconfig + cp $dir_main/os/linux/Makefile.mt_wifi_ap $dir_ap/Makefile + cp $dir_main/os/linux/Kconfig.mt_wifi $dir_main/embedded/Kconfig + #mv $dir_main/embedded/$dir_sta ./ + + ### Creat dir_ap ### + #if [ -d $dir_ap ]; then + # rm -rf $dir_ap + #fi + #mkdir $dir_ap + #if [ ! -d $dir_ap ]; then + # echo "Error! Cannot creat folder [$dir_ap]" + # exit 1 + #fi + # + # + #cp $BaseCodeDir/os/linux/Makefile.rlt_wifi_ap $dir_ap/Makefile + #cp $BaseCodeDir/os/linux/Kconfig.rlt_wifi_ap $dir_ap/Kconfig + + if [ ! -d $dir_ap ]; then + echo "Error! [$dir_ap] doesn't exist." + exit 1 + fi + + #if [ ! -d $dir_sta ]; then + # echo "Error! [$dir_sta] doesn't exist." + # exit 1 + #fi + + if [ "$1" == "auto_build" ]; then + if [ -d ../$dir_main\_auto_build ]; then + rm -rf ../$dir_main\_auto_build + fi + if [ -d ../$dir_ap\_auto_build ]; then + rm -rf ../$dir_ap\_auto_build + fi + #if [ -d ../$dir_sta\_auto_build ]; then + # rm -rf ../$dir_sta\_auto_build + #fi + mv $dir_main ../$dir_main\_auto_build + mv $dir_ap ../$dir_ap\_auto_build + #mv $dir_sta ../$dir_sta\_auto_build + cd ../../ + #rm -rf release + else + rm $dir_main/embedded/*auto_build* + tar -jcvf $package_name\.tar.bz2 $dir_main $dir_ap + #tar -jcvf $package_name\.tar.bz2 $dir_main $dir_ap $dir_sta + #rm -rf $dir_main $dir_ap $dir_sta + fi + +############################ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Release.sh b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Release.sh new file mode 100644 index 000000000..ec7f0d06b --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Release.sh @@ -0,0 +1,134 @@ +OSABL=NO +EmbeddedDir=`pwd` +BaseCodeDir=`dirname $EmbeddedDir` +ChipName="mt7615" +WiFiMode=AP +DriverVersion="V4.4.0.2" +Release="DPA" +Note=$1 +Description="Formal release." +release_profile=Release.log +###### Fixed Settings ###### +Day=`date +%d` +Month=`date +%m` +Year=`date +%Y` +Date=$Year$Month$Day +Hour=`date +%H` +Minute=`date +%M` +HomeDir=`dirname $BaseCodeDir` +#ModuleName=mt$ChipName\_wifi_$DriverVersion +ModulePrefix=MT7615_LinuxAP +ModuleName=$ModulePrefix\_$DriverVersion +WorkDir=$HomeDir/release +TargetDir=$WorkDir/$ModuleName\_$Date\_$Hour$Minute +############################ + + +if [ ! -d $WorkDir ]; then + mkdir $WorkDir +fi + +BaseCodeDir=`readlink -f $BaseCodeDir` #get full path +if [ ! -d $BaseCodeDir ] ; then + echo "Error: BaseCodeDir ($BaseCodeDir) does not exist." + exit 1; +fi + +cp -a $BaseCodeDir $TargetDir +if [ ! -d $TargetDir ] ; then + echo "Error: TargetDir ($TargetDir) does not exist." + exit 1; +fi + +cd $TargetDir + +if [ -f /home/haipin/script/chmod_644.sh ]; then + /home/haipin/script/chmod_644.sh +fi + +if [ -f /home/haipin/script/clean.sh ]; then + /home/haipin/script/clean.sh +fi + +for i in $Release; do + cd $TargetDir/embedded + ####### Remove unwanted files that do not processed by strip tool ####### // TODO + rm os/linux/Makefile.libautoprovision.6 common/rt2860.bin common/rt2870_sw_ch_offload.bin common/RT85592.bin + rm tools/mt7662e_ap.sh tools/mt7662e_sta.sh tools/i.sh tools/trace.sh + rm ../eeprom/MT7601*.bin ../eeprom/MT7603*.bin ../eeprom/MT7628*.bin ../eeprom/MT7637*.bin ../eeprom/MT7662*.bin + rm ../eeprom/MT7636*.bin + rm ../mcu/bin/*_FPGA*.bin ../mcu/bin/*_plain*.bin ../mcu/bin/*_test*.bin + rm ../mcu/bin/*7601* ../mcu/bin/*7603* ../mcu/bin/*7612* ../mcu/bin/*7636* ../mcu/bin/*7637* + rm ../mcu/bin/*7610* ../mcu/bin/*7650* ../mcu/bin/*7662* ../mcu/bin/*7628* + rm ../os/linux/Kconfig.ap* ../os/linux/Kconfig.sta* ../os/linux/Kconfig.rlt* ../os/linux/Kconfig.wifi + rm ../os/linux/Makefile.ap* ../os/linux/Makefile.sta* ../os/linux/Makefile.2880* ../os/linux/Makefile.rlt* + ######################################################################### + + ## Regenerate Firmware ## + #rm -rf include/mcu/mt7628_firmware.h + #rm -rf include/mcu/mt7628_e2_firmware.h + make build_tools CHIPSET=$ChipName + ## Regenerate SKU tables ## + make build_sku_tables CHIPSET=$ChipName + +if [ "$1" != "auto_build" ]; then + make release WIFI_MODE=$WiFiMode CHIPSET=$ChipName RELEASE=$i +else + make release WIFI_MODE=$WiFiMode CHIPSET=$ChipName RELEASE=$i AUTO_BUILD=y +fi + + if [ -d $i ]; then + lower=`echo $i | tr A-Z a-z` #transfer "DPA DPB DPC DPD" to lower case + #ReleaseDir=$ModuleName\_$lower\_$Date + ReleaseDir=$ModuleName\_$i\_$Date + #ReleaseDir=$ModuleName\_$Date + #ReleaseDir=$ModulePrefix + mv $i $TargetDir/$ReleaseDir + ReleaseDir=$TargetDir/$ReleaseDir + + #if [ "$i" == "DPA" ]; then + cd $ReleaseDir/embedded + + find . -name "*Card.dat" -exec rm -rf {} \; #// TODO + find . -name "*2870*.dat" -exec rm -rf {} \; + rm -rf doc/*History*.txt doc/*README* doc/RT_WIFI_Revision_History_2010_April.xls doc/RT2860card.readme + rm -rf Makefile.OSABL threadX.MakeFile vxworks.makefile History.txt RT2860AP.dat + rm -rf os/linux/Makefile.2880.* + rm -rf Release.sh load.4 load.6 load unload + #rm -rf Makefile + cd $TargetDir/embedded + #fi + + ### Generate profile for release ### + echo $ModulePrefix > $ReleaseDir/$release_profile + echo $DriverVersion >> $ReleaseDir/$release_profile + echo $Date >> $ReleaseDir/$release_profile + cp Pack_Release.sh $ReleaseDir/embedded + ##Copy sku_tables .dat to release package## + cp -R $TargetDir/txpwr/sku_tables $ReleaseDir/txpwr/ + cd $ReleaseDir/embedded + sh Pack_Release.sh $1 + + #tar -jcvf $ReleaseDir.tar.bz2 $ReleaseDir + else + echo "Error: ReleaseDir ($i) does not exist" + exit 1 + fi + +done + +#####Log File##### +#if [ "$1" != "auto_build" ]; then +# cd $TargetDir/embedded +# echo "OSABL = $OSABL" > Release.log +# echo "BaseCodeDir = $BaseCodeDir" >> Release.log +# echo "ChipName = $ChipName" >> Release.log +# echo "DriverVersion = $DriverVersion" >> Release.log + #echo "BuildDir = $BuildDir" >> Release.log +# echo "Release = $Release" >> Release.log +# if [ "$Description" != "" ]; then +# echo "Description = $Description" >> Release.log +# fi +# echo "Note: $Note" >> Release.log +#fi +################## diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Release_Notes.txt b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Release_Notes.txt new file mode 100644 index 000000000..d42fd7629 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/Release_Notes.txt @@ -0,0 +1,97 @@ +[ V4.4.0.2 ] + Support function: + 1. MU-MIMO support. + 2. BW160 for IEEE 802.11 new standard modification. + 3. Multiple default bin file support. + 4. Single SKU for TxBF. + 5. Repeater - WiFi Forwarding Module support + + Issue Fixed: + 1. Endurance and robustness enhancement. + 2. DFS - Fix "channel closing time too long" issue. + 3. 802.11R - Fixed AP would delete STA if STA send disassoc + frame which BSSID is AP's BSSID but DA is another AP. + 4. Fix Auto Channel Selection trigger by iwpriv command. + 5. Fix BA session overflow issue. + +[ V4.4.0.1 ] + Support function: + 1. 802.11R/802.11K I-phone compliant. + 2. Single SKU table now can also take TxBF for reference. + Issue Fixed: + 1. Fix throughput degrade after radio off/on. + 2. Fix CCK TX Power unstable issue. + 3. Reduce bootup calibration time. + 4. Fix firmware download failed after s/w reboot. + 5. Fix RX AMSDU reordering issue. + 6. Fix Counter Measure failed to recover connection access. + 7. Fix DFS NOP and CAC issue. + +[ V4.4.0.0 ] +Formal Release: + Support function: + 1. Tx Beamforming Support + 2. Calibration Data Save in Flash Support + + Issue Fixed: + 1. Fixed a kernel panic issues in repeater mode under heavy traffic loading + 2. Improve stability when playing video streaming and under heavy traffic loading + +[ V4.4.0.0 ] +Beta release 2: + Support function: + 1. DFS master mode and client mode + 2. IGMP snooping + 3. Single SKU + 4. Tx Power Percentage + 5. ApCli Connection Trial + 6. LED + + Issue Fixed: + 1. Site survey cannot find APs in other channels + 2. Correct data rate displayed in iwconfig + 3. Support DFS master/slave mode + 4. Support LED + 5. Fix kernel panic issue during interface down/up + 6. Fix scan list cannot correctly show AP with 11ac capability issue. + 7. 2.4G repeater performance improvement + 8. Support DFS master/slave mode + +[ V4.4.0.0 ] +Beta release 1: + Support function: + 1. 802.11n certification of (AP mode) + 2. Band Steering + 3. Thermal Protection + 4. Concurrent WPS + + Issue Fixed: + 1. Reduce the total time of Wifi interface up + 2. IOT: Fix Iphone-6/S6 set to only BW20 when connected. + 3. Reduce total number of tx/rx packet token to avoid run out of system memory under heavy loading. + 4. Performance improvement of multi-client/repeater/RvR(Waterfall) . + 5. Fix system crash issue during interface down/up + 6. Fix connection stability issue and looping issue of repeater mode. + 7. Fix jitter and packet loss issues in Verivave tests. + 8. Fix potential memory leackage issues. + + Known issues: + 1. 5G Peek Tx/Rx performance on MT7621. (around 850~940Mbps) + 2. Peek throughput drop about 20~30Mbps (happens ramdonly with about 15% chances) + 3. CPU loading increased about 3~5% while running peek throughput. + + +[ V4.4.0.0 ] +Alpha release 1: + support function: + 1. 80211.ac + 2. WPS + 3. Apcli / MAC Repeater + 4. PMF + + Known issues: + 1. VHT MCS8/9 not stable. + 2. Repeater connection stability + 3. DBDC performance + 4. When peer is Ralink device, RDG+Security shows ICV Error + 5. Occasionally Tx/Rx Stop (E3 fix) diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap.c new file mode 100644 index 000000000..9aa241623 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap.c @@ -0,0 +1,3717 @@ +/**************************************************************************** +* 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" +#define VLAN_HDR_LEN 4 +#ifdef VENDOR_FEATURE7_SUPPORT +#include "arris_wps_gpio_handler.h" +#endif +#define MCAST_WCID_TO_REMOVE 0 /* Pat: TODO */ + +#if defined(VOW_SUPPORT) && defined(CONFIG_AP_SUPPORT) +extern VOID vow_avg_pkt_len_reset(struct _RTMP_ADAPTER *ad); +extern VOID vow_avg_pkt_len_calculate(struct _MAC_TABLE_ENTRY *entry); +#endif +#ifdef IAPP_SUPPORT +BOOLEAN IAPP_L2_Update_Frame_Send(RTMP_ADAPTER *pAd, UINT8 *mac, INT wdev_idx); +#endif /*IAPP_SUPPORT*/ +static VOID dynamic_ampdu_efficiency_adjust_all(struct _RTMP_ADAPTER *ad); +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" +}; +UCHAR get_apidx_by_addr(RTMP_ADAPTER *pAd, UCHAR *addr) +{ + UCHAR apidx; + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + if (RTMPEqualMemory(addr, pAd->ApCfg.MBSSID[apidx].wdev.bssid, MAC_ADDR_LEN)) + break; + } + + return apidx; +} + +static INT ap_mlme_set_capability(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss) +{ + struct wifi_dev *wdev = &pMbss->wdev; + BOOLEAN SpectrumMgmt = FALSE; +#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 ((wdev->channel > 14) && pAd->CommonCfg.bIEEE80211H == TRUE) + SpectrumMgmt = TRUE; + +#endif /* A_BAND_SUPPORT */ + pMbss->CapabilityInfo = CAP_GENERATE(1, + 0, + IS_SECURITY_Entry(wdev), + (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1), + pAd->CommonCfg.bUseShortSlotTime, + SpectrumMgmt); +#ifdef DOT11K_RRM_SUPPORT + + if (IS_RRM_ENABLE(wdev)) + pMbss->CapabilityInfo |= RRM_CAP_BIT; + +#endif /* DOT11K_RRM_SUPPORT */ + + if (pMbss->wdev.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->wdev.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 */ + return TRUE; +} + + +UCHAR ApAutoChannelAtBootUp(RTMP_ADAPTER *pAd, struct wifi_dev *wdev) +{ +#define SINGLE_BAND 0 +#define DUAL_BAND 1 + + UCHAR NewChannel; + BOOLEAN IsAband; + UCHAR BandIdx = BAND0; + AUTO_CH_CTRL *pAutoChCtrl = NULL; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s----------------->\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: AutoChannelBootup = %d\n", + __func__, pAd->ApCfg.bAutoChannelAtBootup)); + + if (!pAd->ApCfg.bAutoChannelAtBootup) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s<-----------------\n", __func__)); + return FALSE; + } + + if (!wdev) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\x1b[41m %s(): wdev is NULL !!\x1b[m\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s<-----------------\n", __func__)); + return FALSE; + } + + BandIdx = HcGetBandByWdev(wdev); + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + /* Now Enable RxTx*/ + RTMPEnableRxTx(pAd); + + if (wdev->channel == 0) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: PhyMode: %d\n", __func__, wdev->PhyMode)); + + if (WMODE_CAP_5G(wdev->PhyMode)) + IsAband = TRUE; + else + IsAband = FALSE; + + /* Now we can receive the beacon and do ACS */ + if (pAutoChCtrl->AutoChSelCtrl.ACSChStat != ACS_CH_STATE_SELECTED) { + /* Disable MibBucket during doing ACS */ + pAd->MsMibBucket.Enabled = FALSE; + pAd->OneSecMibBucket.Enabled[BandIdx] = FALSE; + + NewChannel = APAutoSelectChannel(pAd, wdev, pAd->ApCfg.AutoChannelAlg, IsAband); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s : Auto channel selection: Selected channel = %d, IsAband = %d\n", __func__, NewChannel, IsAband)); + } else { + NewChannel = pAutoChCtrl->AutoChSelCtrl.SelCh; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[ApAutoChannelAtBootUp] ACS of BandIdx = %d is already DONE, Channel = %d\n", BandIdx, NewChannel)); + } + + /* Update channel of wdev as new channel */ + AutoChSelUpdateChannel(pAd, NewChannel, IsAband, wdev); +#ifdef MT_DFS_SUPPORT + /* Check new channel is DFS channel or not */ + RadarStateCheck(pAd, wdev); +#endif + /* Update primay channel */ + wlan_operate_set_prim_ch(wdev, wdev->channel); + + /* Enable MibBucket after ACS done */ + pAd->MsMibBucket.Enabled = TRUE; + pAd->OneSecMibBucket.Enabled[BandIdx] = TRUE; +#ifdef MT_DFS_SUPPORT + DfsBuildChannelList(pAd, wdev); +#endif + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s<-----------------\n", __func__)); + return TRUE; +} + + +/* + ========================================================================== + Description: + Check to see the exist of long preamble STA in associated list + ========================================================================== + */ +static BOOLEAN ApCheckLongPreambleSTA(RTMP_ADAPTER *pAd) +{ + UCHAR i; + + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; + + if (!IS_ENTRY_CLIENT(pEntry) || (pEntry->Sst != SST_ASSOC)) + continue; + + if (!CAP_IS_SHORT_PREAMBLE_ON(pEntry->CapabilityInfo)) { + return TRUE; + } + } + + return FALSE; +} + +/* + ========================================================================== + Description: + Initialize AP specific data especially the NDIS packet pool that's + used for wireless client bridging. + ========================================================================== + */ +static VOID ap_run_at_boot(struct _RTMP_ADAPTER *pAd, struct wifi_dev *wdev) +{ + if (ApAutoChannelAtBootUp(pAd, wdev) != TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\x1b[41m %s() : ACS is disable !!\x1b[m\n", __func__)); + } + +#ifdef BACKGROUND_SCAN_SUPPORT + { +#ifdef DOT11_VHT_AC + UCHAR vht_bw = wlan_operate_get_vht_bw(wdev); +#endif + + if (pAd->CommonCfg.dbdc_mode == TRUE) { + pAd->BgndScanCtrl.BgndScanSupport = 0; + pAd->BgndScanCtrl.DfsZeroWaitSupport = 0; + } + +#ifdef DOT11_VHT_AC + else if (vht_bw == VHT_BW_160 || vht_bw == VHT_BW_8080) { + pAd->BgndScanCtrl.BgndScanSupport = 0; + pAd->BgndScanCtrl.DfsZeroWaitSupport = 0; + } + +#endif /* DOT11_VHT_AC */ + else + pAd->BgndScanCtrl.BgndScanSupport = 1; + +#ifdef MT_DFS_SUPPORT + /* Update bInitMbssZeroWait for MBSS Zero Wait */ + UPDATE_MT_INIT_ZEROWAIT_MBSS(pAd, FALSE); +#endif /* MT_DFS_SUPPORT */ + } +#endif /* BACKGROUND_SCAN_SUPPORT */ +} + + + +NDIS_STATUS APOneShotSettingInitialize(RTMP_ADAPTER *pAd) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("---> APOneShotSettingInitialize\n")); + RTMPInitTimer(pAd, &pAd->ApCfg.CounterMeasureTimer, GET_TIMER_FUNCTION(CMTimerExec), pAd, FALSE); +#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 IGMP_SNOOP_SUPPORT + MulticastFilterTableInit(pAd, &pAd->pMulticastFilterTable); +#endif /* IGMP_SNOOP_SUPPORT */ +#ifdef DOT11K_RRM_SUPPORT + RRM_CfgInit(pAd); +#endif /* DOT11K_RRM_SUPPORT */ + /* Init BssTab & ChannelInfo tabbles for auto channel select.*/ + AutoChBssTableInit(pAd); + ChannelInfoInit(pAd); +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + RTMP_11N_D3_TimerInit(pAd); +#endif /* DOT11N_DRAFT3 */ +#endif /*DOT11_N_SUPPORT*/ + + /* beacon init for USB/SDIO */ + asic_bss_beacon_init(pAd); + +#ifdef AP_QLOAD_SUPPORT + QBSS_LoadInit(pAd); +#endif /* AP_QLOAD_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. + */ +#ifdef RTMP_RBUS_SUPPORT + + if (pAd->infType == RTMP_DEV_INF_RBUS) { +#ifdef VIDEO_TURBINE_SUPPORT + VideoTurbineDynamicTune(pAd); +#endif /* VIDEO_TURBINE_SUPPORT */ + } + +#endif /* RTMP_RBUS_SUPPORT */ +#ifdef MAT_SUPPORT + MATEngineInit(pAd); +#endif /* MAT_SUPPORT */ +#ifdef CLIENT_WDS + CliWds_ProxyTabInit(pAd); +#endif /* CLIENT_WDS */ + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<--- APOneShotSettingInitialize\n")); + return Status; +} + + +/* + ========================================================================== + Description: + Shutdown AP and free AP specific resources + ========================================================================== + */ +VOID APShutdown(RTMP_ADAPTER *pAd) +{ + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID]; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("---> APShutdown\n")); +#ifdef MT_MAC + /* Disable RX */ + /* MtAsicSetMacTxRx(pAd, ASIC_MAC_RX, FALSE,0); */ +#ifdef RTMP_MAC_PCI + APStop(pAd, pMbss, AP_BSS_OPER_ALL); +#endif /* RTMP_MAC_PCI */ + /* MlmeRadioOff(pAd); */ +#else + MlmeRadioOff(pAd); +#ifdef RTMP_MAC_PCI + APStop(pAd, pMbss, AP_BSS_OPER_ALL); +#endif /* RTMP_MAC_PCI */ +#endif + /*remove sw related timer and table*/ + rtmp_ap_exit(pAd); +#ifdef FTM_SUPPORT + FtmMgmtExit(pAd); +#endif /* FTM_SUPPORT */ + NdisFreeSpinLock(&pAd->MacTabLock); +#ifdef WDS_SUPPORT + NdisFreeSpinLock(&pAd->WdsTab.WdsTabLock); +#endif /* WDS_SUPPORT */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<--- APShutdown\n")); +} + + + +/* + ========================================================================== + 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(RTMP_ADAPTER *pAd, struct _BSS_STRUCT *mbss) +{ + UCHAR i, ErpIeContent = 0; + BOOLEAN ShortSlotCapable = pAd->CommonCfg.bUseShortSlotTime; + BOOLEAN bUseBGProtection; + BOOLEAN LegacyBssExist; + MAC_TABLE_ENTRY *pEntry = NULL; + USHORT *pCapInfo = NULL; + struct wifi_dev *wdev = &mbss->wdev; + ADD_HT_INFO_IE *addht = wlan_operate_get_addht(wdev); + UCHAR Channel = wdev->channel; + UCHAR PhyMode = wdev->PhyMode; + + if (WMODE_EQUAL(PhyMode, WMODE_B)) + return; + + for (i = 1; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + + if (!IS_ENTRY_CLIENT(pEntry) || (pEntry->Sst != SST_ASSOC)) + continue; + + if (wdev != pEntry->wdev) + 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; + + 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 (Channel > 14) + bUseBGProtection = FALSE; + +#endif /* A_BAND_SUPPORT */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("-- bUseBGProtection: %s, BG_PROTECT_INUSED: %s, ERP IE Content: 0x%x\n", + (bUseBGProtection) ? "Yes" : "No", + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) ? "Yes" : "No", + ErpIeContent)); + + if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { + USHORT OperationMode = 0; + BOOLEAN bNonGFExist = 0; +#ifdef DOT11_N_SUPPORT + OperationMode = addht->AddHtInfo2.OperaionMode; + bNonGFExist = pAd->MacTab.fAnyStationNonGF; +#endif /* DOT11_N_SUPPORT */ + + if (bUseBGProtection) + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); + else + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); + + } + + /* 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 (Channel > 14) + ShortSlotCapable = TRUE; + +#endif /* A_BAND_SUPPORT */ + pCapInfo = &(mbss->CapabilityInfo); + + /* In A-band, the ShortSlotTime bit should be ignored. */ + if (ShortSlotCapable +#ifdef A_BAND_SUPPORT + && (Channel <= 14) +#endif /* A_BAND_SUPPORT */ + ) + (*pCapInfo) |= 0x0400; + else + (*pCapInfo) &= 0xfbff; + + if (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong) + (*pCapInfo) &= (~0x020); + else + (*pCapInfo) |= 0x020; + + + /*update slot time only when value is difference*/ + if (pAd->CommonCfg.bUseShortSlotTime != ShortSlotCapable) { + HW_SET_SLOTTIME(pAd, ShortSlotCapable, Channel, NULL); + pAd->CommonCfg.bUseShortSlotTime = ShortSlotCapable; + } +} + + + +static INT ap_hw_tb_init(RTMP_ADAPTER *pAd) +{ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s():Reset WCID Table\n", __func__)); + HW_SET_DEL_ASIC_WCID(pAd, WCID_ALL); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s():Reset Sec Table\n", __func__)); + return TRUE; +} + + +/* + ========================================================================== + 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 APStartUpForMbss(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss) +{ + struct wifi_dev *wdev = &pMbss->wdev; + BOOLEAN bWmmCapable = FALSE; + EDCA_PARM *pEdca = NULL, *pBssEdca = NULL; + UCHAR phy_mode = pAd->CommonCfg.cfg_wmode; + UCHAR ucBandIdx = 0; +#ifdef GREENAP_SUPPORT + struct greenap_ctrl *greenap = &pAd->ApCfg.greenap; + UCHAR amount_of_band = HcGetAmountOfBand(pAd); +#endif /* GREENAP_SUPPORT */ +#if defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) + BOOLEAN bZeroWaitStop; +#endif /* defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) */ +#if defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) + bZeroWaitStop = MbssZeroWaitStopValidate(pAd, pMbss->wdev.channel, pMbss->mbss_idx); +#endif /* defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("===> %s(), CfgMode:%d\n", __func__, phy_mode)); + + /*Ssid length sanity check.*/ + if ((pMbss->SsidLen <= 0) || (pMbss->SsidLen > MAX_LEN_OF_SSID)) { + NdisMoveMemory(pMbss->Ssid, "HT_AP", 5); + pMbss->Ssid[5] = '0' + pMbss->mbss_idx; + pMbss->SsidLen = 6; + } + + if (wdev->func_idx == 0) + MgmtTableSetMcastEntry(pAd, MCAST_WCID_TO_REMOVE); + + APSecInit(pAd, wdev); + + + +#if defined(WAPP_SUPPORT) + wapp_init(pAd, pMbss); +#endif + + ap_mlme_set_capability(pAd, pMbss); +#ifdef WSC_V2_SUPPORT + + if (wdev->WscControl.WscV2Info.bEnableWpsV2) { + /* + WPS V2 doesn't support Chiper WEP and TKIP. + */ + struct _SECURITY_CONFIG *pSecConfig = &wdev->SecConfig; + + if (IS_CIPHER_WEP_TKIP_ONLY(pSecConfig->PairwiseCipher) + || (pMbss->bHideSsid)) + WscOnOff(pAd, wdev->func_idx, TRUE); + else + WscOnOff(pAd, wdev->func_idx, FALSE); + } + +#endif /* WSC_V2_SUPPORT */ + + /* If any BSS is WMM Capable, we need to config HW CRs */ + if (wdev->bWmmCapable) + bWmmCapable = TRUE; + + if (WMODE_CAP_N(wdev->PhyMode) || bWmmCapable) { + pEdca = &pAd->CommonCfg.APEdcaParm[wdev->EdcaIdx]; + + /* EDCA parameters used for AP's own transmission */ + if (pEdca->bValid == FALSE) + set_default_ap_edca_param(pEdca); + + pBssEdca = wlan_config_get_ht_edca(wdev); + + if (pBssEdca) { + /* EDCA parameters to be annouced in outgoing BEACON, used by WMM STA */ + if (pBssEdca->bValid == FALSE) + set_default_sta_edca_param(pBssEdca); + } + } + +#ifdef DOT11_N_SUPPORT + BuildChannelList(pAd, wdev); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[APStartUpForMbss] BuildChannelList, #711\n")); + RTMPSetPhyMode(pAd, wdev, wdev->PhyMode); + /*update rate info for wdev*/ + RTMPUpdateRateInfo(wdev->PhyMode, &wdev->rate); + + if (!WMODE_CAP_N(wdev->PhyMode)) + wlan_config_set_ht_bw(wdev, HT_BW_20); + +#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) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_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) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Enable 20/40 BSSCoex Channel Scan(BssCoex=%d)\n", + pAd->CommonCfg.bBssCoexEnable)); + APOverlappingBSSScan(pAd, wdev); + } + +#endif /* DOT11N_DRAFT3 */ +#endif /*DOT11_N_SUPPORT*/ + MlmeUpdateTxRates(pAd, FALSE, wdev->func_idx); +#ifdef DOT11_N_SUPPORT + + if (WMODE_CAP_N(wdev->PhyMode)) + MlmeUpdateHtTxRates(pAd, wdev->func_idx); + +#endif /* DOT11_N_SUPPORT */ + + if (WDEV_WITH_BCN_ABILITY(wdev) && wdev->bAllowBeaconing) { + if (wdev_do_linkup(wdev, NULL) != TRUE) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: link up fail!!\n", __func__)); + } + +#if defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) + ZeroWaitUpdateForMbss(pAd, bZeroWaitStop, pMbss->wdev.channel, pMbss->mbss_idx); +#endif /* defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) */ + +#ifdef SINGLE_SKU_V2 +#ifdef RF_LOCKDOWN + + /* Check RF lock Status */ + if (chip_check_rf_lock_down(pAd)) { + pAd->CommonCfg.SKUenable[ucBandIdx] = TRUE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: RF lock down!! SKUenable = 1!!\n", __func__)); + } + +#endif /* RF_LOCKDOWN */ + +#if defined(MT7615) || defined(MT7622) + /* enable/disable SKU via profile */ + TxPowerSKUCtrl(pAd, pAd->CommonCfg.SKUenable[ucBandIdx], ucBandIdx); + + /* enable/disable BF Backoff via profile */ + TxPowerBfBackoffCtrl(pAd, pAd->CommonCfg.BFBACKOFFenable[ucBandIdx], ucBandIdx); +#else +#endif /* defined(MT7615) || defined(MT7622) */ +#endif /* SINGLE_SKU_V2*/ + /* enable/disable Power Percentage via profile */ + TxPowerPercentCtrl(pAd, pAd->CommonCfg.PERCENTAGEenable[ucBandIdx], ucBandIdx); + + /* Tx Power Percentage value via profile */ + TxPowerDropCtrl(pAd, pAd->CommonCfg.ucTxPowerPercentage[ucBandIdx], ucBandIdx); + +/* Config Tx CCK Stream */ + TxCCKStreamCtrl(pAd, pAd->CommonCfg.CCKTxStream[ucBandIdx], ucBandIdx); + +#ifdef RF_LOCKDOWN + + /* Check RF lock Status */ + if (chip_check_rf_lock_down(pAd)) { + pAd->CommonCfg.BFBACKOFFenable[ucBandIdx] = TRUE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: RF lock down!! BFBACKOFFenable = 1!!\n", __func__)); + } + +#endif /* RF_LOCKDOWN */ +#ifdef TX_POWER_CONTROL_SUPPORT + /* config Power boost table via profile */ + TxPwrUpCtrl(pAd, ucBandIdx, POWER_UP_CATE_CCK_OFDM, + pAd->CommonCfg.cPowerUpCckOfdm[ucBandIdx]); + TxPwrUpCtrl(pAd, ucBandIdx, POWER_UP_CATE_HT20, + pAd->CommonCfg.cPowerUpHt20[ucBandIdx]); + TxPwrUpCtrl(pAd, ucBandIdx, POWER_UP_CATE_HT40, + pAd->CommonCfg.cPowerUpHt40[ucBandIdx]); + TxPwrUpCtrl(pAd, ucBandIdx, POWER_UP_CATE_VHT20, + pAd->CommonCfg.cPowerUpVht20[ucBandIdx]); + TxPwrUpCtrl(pAd, ucBandIdx, POWER_UP_CATE_VHT40, + pAd->CommonCfg.cPowerUpVht40[ucBandIdx]); + TxPwrUpCtrl(pAd, ucBandIdx, POWER_UP_CATE_VHT80, + pAd->CommonCfg.cPowerUpVht80[ucBandIdx]); + TxPwrUpCtrl(pAd, ucBandIdx, POWER_UP_CATE_VHT160, + pAd->CommonCfg.cPowerUpVht160[ucBandIdx]); +#endif /* TX_POWER_CONTROL_SUPPORT */ + /*init tx/rx stream */ + hc_set_rrm_init(wdev); +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + + if (wf_drv_tbl.wf_fwd_check_device_hook) + wf_drv_tbl.wf_fwd_check_device_hook(wdev->if_dev, INT_MBSSID, pMbss->mbss_idx, wdev->channel, 1); + +#endif /* CONFIG_WIFI_PKT_FWD */ + +#if defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) + /* Update bInitMbssZeroWait for MBSS Zero Wait */ + UPDATE_MT_INIT_ZEROWAIT_MBSS(pAd, FALSE); +#endif /* defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) */ +#ifdef VOW_SUPPORT + vow_mbss_init(pAd, wdev); +#endif /* VOW_SUPPORT */ +#ifdef GREENAP_SUPPORT + greenap_check_allow_status(pAd, greenap); + + if (greenap_get_capability(greenap) && greenap_get_allow_status(greenap)) { + for (ucBandIdx = 0; ucBandIdx < amount_of_band; ucBandIdx++) { + greenap_check_peer_connection_status( + pAd, + ucBandIdx, + FALSE, + greenap_get_allow_status(greenap)); + } + } + +#endif /* GREENAP_SUPPORT */ +#ifdef BAND_STEERING +#ifdef CONFIG_AP_SUPPORT + if (pAd->ApCfg.BandSteering) { + PBND_STRG_CLI_TABLE table; + + table = Get_BndStrgTable(pAd, pMbss->mbss_idx); + + if (!table) { + /* Init time table may not init as wdev not populated */ + BndStrg_TableInit(pAd, pMbss->mbss_idx); + table = Get_BndStrgTable(pAd, pMbss->mbss_idx); + } + + if (table) { + /* Inform daemon interface ready */ + BndStrg_SetInfFlags(pAd, &pMbss->wdev, table, TRUE); + } + } +#endif /* CONFIG_AP_SUPPORT */ +#endif /* BAND_STEERING */ + +#ifdef CONFIG_DOT11U_INTERWORKING + pMbss->GASCtrl.b11U_enable = 1; +#endif /* CONFIG_DOT11U_INTERWORKING */ + +} + +VOID APStartUpByBss(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss) +{ + struct wifi_dev *wdev; + + if (pMbss == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() Invalid Mbss\n", + __func__)); + return; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("===> %s() mbss_idx %d\n", __func__, pMbss->mbss_idx)); + wdev = &pMbss->wdev; + + + /* Workaround start: Let Rx packet can be dequeued from PSE or Tx CMD will fail */ + /* Workaround end */ + + /* setup tx preamble */ + MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble); + /* Clear BG-Protection flag */ + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); + /* default NO_PROTECTION */ + AsicUpdateProtect(pAd); + + /* Update devinfo for any phymode change */ + if (wdev_do_open(wdev) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() open fail!!!\n", __func__)); + + /* Update ERP */ + ApUpdateCapabilityAndErpIe(pAd, pMbss); + + APStartUpForMbss(pAd, pMbss); +#ifdef DOT11_N_SUPPORT + /* Update HT & GF Protect */ + APUpdateOperationMode(pAd, wdev); +#endif /* DOT11_N_SUPPORT */ + + /* Set the RadarDetect Mode as Normal, bc the APUpdateAllBeaconFram() will refer this parameter. */ + /*pAd->Dot11_H.RDMode = RD_NORMAL_MODE;*/ +#ifdef LED_CONTROL_SUPPORT + RTMPSetLED(pAd, LED_LINK_UP); +#endif /* LED_CONTROL_SUPPORT */ +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + WifiFwdSet(pAd->CommonCfg.WfFwdDisabled); +#endif /* CONFIG_WIFI_PKT_FWD */ + ApLogEvent(pAd, pAd->CurrentAddress, EVENT_RESET_ACCESS_POINT); + pAd->Mlme.PeriodicRound = 0; + pAd->Mlme.OneSecPeriodicRound = 0; + pAd->MacTab.MsduLifeTime = 5; /* default 5 seconds */ + OPSTATUS_SET_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED); + RTMP_IndicateMediaState(pAd, NdisMediaStateConnected); + + /* beacon init for USB/SDIO */ + asic_bss_beacon_init(pAd); + + /* start sending BEACON out */ + UpdateBeaconHandler(pAd, wdev, BCN_UPDATE_IF_STATE_CHG); + /* + Set group re-key timer if necessary. + It must be processed after clear flag "fRTMP_ADAPTER_HALT_IN_PROGRESS" + */ + APStartRekeyTimer(pAd, wdev); + +#ifdef CARRIER_DETECTION_SUPPORT + + if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) + CarrierDetectionStart(pAd); + +#endif /* CARRIER_DETECTION_SUPPORT */ + + /* Pre-tbtt interrupt setting. */ + AsicSetPreTbtt(pAd, TRUE, HW_BSSID_0); +#ifdef IDS_SUPPORT + + /* Start IDS timer */ + if (pAd->ApCfg.IdsEnable) { +#ifdef SYSTEM_LOG_SUPPORT + + if (pAd->CommonCfg.bWirelessEvent == FALSE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("!!! WARNING !!! The WirelessEvent parameter doesn't be enabled\n")); + +#endif /* SYSTEM_LOG_SUPPORT */ + RTMPIdsStart(pAd); + } + +#endif /* IDS_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + FT_Init(pAd); +#endif /* DOT11R_FT_SUPPORT */ +#ifdef SMART_ANTENNA + RtmpSAStart(pAd); +#endif /* SMART_ANTENNA */ + RTMP_ASIC_INTERRUPT_ENABLE(pAd); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SYSEM_READY); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Main bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pAd->ApCfg.MBSSID[BSS0].wdev.bssid))); +#ifdef NF_SUPPORT + if (IS_MT7615(pAd)) + enable_nf_support(pAd); +#endif + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<=== %s()\n", __func__)); +#ifdef VENDOR_FEATURE7_SUPPORT + { + UCHAR event_msg[48] = {0}; + + if (WMODE_CAP_5G(pAd->ApCfg.MBSSID[BSS0].wdev.PhyMode)) + sprintf(event_msg, "%sGHz AP start/restart successful\n", "5"); + else + sprintf(event_msg, "%sGHz AP start/restart successful\n", "2.4"); + + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_LOG_SAVE, 0, event_msg, strlen(event_msg)); + } +#endif +} + +VOID APStartUp(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss, ENUM_AP_BSS_OPER oper) +{ + UINT32 idx; + BSS_STRUCT *pCurMbss = NULL; + UCHAR ch = 0; + + /* Don't care pMbss if operation is for all */ + if ((pMbss == NULL) && (oper != AP_BSS_OPER_ALL)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() Invalid oper(%d)\n", + __func__, oper)); + return; + } + + if (pMbss) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(), oper(%d) bssid(%d)=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, oper, pMbss->mbss_idx, PRINT_MAC(pMbss->wdev.bssid))); + else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(), oper(%d)\n", + __func__, oper)); + + switch (oper) { + case AP_BSS_OPER_ALL: + for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { + pCurMbss = &pAd->ApCfg.MBSSID[idx]; + pCurMbss->mbss_idx = idx; + + APStartUpByBss(pAd, pCurMbss); + } + break; + case AP_BSS_OPER_BY_RF: + ch = pMbss->wdev.channel; + for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { + pCurMbss = &pAd->ApCfg.MBSSID[idx]; + pCurMbss->mbss_idx = idx; + + /* check MBSS status is up */ + if (!pCurMbss->wdev.if_up_down_state) + continue; + + /* check MBSS work on the same RF(channel) */ + if (pCurMbss->wdev.channel != ch) + continue; + + APStartUpByBss(pAd, pCurMbss); + } + break; + + case AP_BSS_OPER_SINGLE: + default: + APStartUpByBss(pAd, pMbss); + break; + } + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_SYSEM_READY); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<=== %s()\n", __func__)); +} + +/*Only first time will run it*/ +VOID APInitForMain(RTMP_ADAPTER *pAd) +{ + BSS_STRUCT *pMbss = NULL; + UINT32 apidx = 0; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("===> %s()\n", __func__)); + AsicDisableSync(pAd, HW_BSSID_0);/* don't gen beacon, reset tsf timer, don't gen interrupt. */ + /*reset hw wtbl*/ + ap_hw_tb_init(pAd); + pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID]; + pMbss->mbss_idx = MAIN_MBSSID; + /*update main runtime attribute*/ + +#ifdef DOT11_N_SUPPORT + AsicSetRalinkBurstMode(pAd, pAd->CommonCfg.bRalinkBurstMode); +#ifdef PIGGYBACK_SUPPORT + AsicSetPiggyBack(pAd, pAd->CommonCfg.bPiggyBackCapable); +#endif /* PIGGYBACK_SUPPORT */ +#endif /* DOT11_N_SUPPORT */ + /* Workaround start: Let Rx packet can be dequeued from PSE or Tx CMD will fail */ + /* Workaround end */ + /* Clear BG-Protection flag */ + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); + MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble); + /* 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); + ApUpdateCapabilityAndErpIe(pAd, pMbss); +#ifdef DOT11_N_SUPPORT + APUpdateOperationMode(pAd, &pMbss->wdev); +#endif /* DOT11_N_SUPPORT */ +#ifdef LED_CONTROL_SUPPORT + RTMPSetLED(pAd, LED_LINK_UP); +#endif /* LED_CONTROL_SUPPORT */ +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + WifiFwdSet(pAd->CommonCfg.WfFwdDisabled); +#endif /* CONFIG_WIFI_PKT_FWD */ + ApLogEvent(pAd, pAd->CurrentAddress, EVENT_RESET_ACCESS_POINT); + pAd->Mlme.PeriodicRound = 0; + pAd->Mlme.OneSecPeriodicRound = 0; + pAd->MacTab.MsduLifeTime = 5; /* default 5 seconds */ + 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); + /* + Set group re-key timer if necessary. + It must be processed after clear flag "fRTMP_ADAPTER_HALT_IN_PROGRESS" + */ + APStartRekeyTimer(pAd, &pMbss->wdev); + /* RadarStateCheck(pAd); */ + +#ifdef CARRIER_DETECTION_SUPPORT + + if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) + CarrierDetectionStart(pAd); + +#endif /* CARRIER_DETECTION_SUPPORT */ + + /* Pre-tbtt interrupt setting. */ + AsicSetPreTbtt(pAd, TRUE, HW_BSSID_0); + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + pMbss = &pAd->ApCfg.MBSSID[apidx]; + OPSTATUS_SET_FLAG_WDEV(&pMbss->wdev, fOP_AP_STATUS_MEDIA_STATE_CONNECTED); + } + +#ifdef IDS_SUPPORT + + /* Start IDS timer */ + if (pAd->ApCfg.IdsEnable) { +#ifdef SYSTEM_LOG_SUPPORT + + if (pAd->CommonCfg.bWirelessEvent == FALSE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("!!! WARNING !!! The WirelessEvent parameter doesn't be enabled\n")); + +#endif /* SYSTEM_LOG_SUPPORT */ + RTMPIdsStart(pAd); + } + +#endif /* IDS_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + FT_Init(pAd); +#endif /* DOT11R_FT_SUPPORT */ +#ifdef SMART_ANTENNA + RtmpSAStart(pAd); +#endif /* SMART_ANTENNA */ +#ifdef BAND_STEERING + + if (pAd->ApCfg.BandSteering) + BndStrg_Init(pAd); + +#endif /* BAND_STEERING */ + RTMP_ASIC_INTERRUPT_ENABLE(pAd); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Main bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pAd->ApCfg.MBSSID[BSS0].wdev.bssid))); +#ifdef VENDOR_FEATURE7_SUPPORT + { + UCHAR event_msg[48] = {0}; + + if (WMODE_CAP_5G(pAd->ApCfg.MBSSID[BSS0].wdev.PhyMode)) + sprintf(event_msg, "%sGHz AP start/restart successful\n", "5"); + else + sprintf(event_msg, "%sGHz AP start/restart successful\n", "2.4"); + + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_LOG_SAVE, + 0 /*dummy*/, event_msg, strlen(event_msg)); + } +#endif + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<=== %s()\n", __func__)); +} + +VOID APStopByBss(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss) +{ + BOOLEAN Cancelled; + INT idx; + struct wifi_dev *wdev, *wdev_bss; +#ifdef GREENAP_SUPPORT + struct greenap_ctrl *greenap = &pAd->ApCfg.greenap; +#endif /* GREENAP_SUPPORT */ + + if (pMbss == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() Invalid Mbss\n", + __func__)); + return; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("===> %s() mbss_idx %d\n", __func__, pMbss->mbss_idx)); + wdev_bss = &pMbss->wdev; + + /* */ + /* 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 CARRIER_DETECTION_SUPPORT + + if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) { + /* make sure CarrierDetect wont send CTS */ + CarrierDetectionStop(pAd); + } + +#endif /* CARRIER_DETECTION_SUPPORT */ +#ifdef APCLI_SUPPORT + { + for (idx = 0; idx < MAX_APCLI_NUM; idx++) { + wdev = &pAd->ApCfg.ApCliTab[idx].wdev; + + if (wdev->channel == wdev_bss->channel) { + UINT8 enable = pAd->ApCfg.ApCliTab[idx].Enable; + + if (enable) { + pAd->ApCfg.ApCliTab[idx].Enable = FALSE; + ApCliIfDown(pAd); + pAd->ApCfg.ApCliTab[idx].Enable = enable; + } + } + } + } +#endif /* APCLI_SUPPORT */ + + /*AP mode*/ + MacTableResetWdev(pAd, wdev_bss); + OPSTATUS_CLEAR_FLAG_WDEV(wdev_bss, fOP_AP_STATUS_MEDIA_STATE_CONNECTED); +#ifdef GREENAP_SUPPORT + if (greenap_get_capability(greenap) && greenap_get_allow_status(greenap)) + greenap_exit(pAd, wdev_bss, greenap); +#endif /* GREENAP_SUPPORT */ + + CMDHandler(pAd); + /* Disable pre-tbtt interrupt */ + AsicSetPreTbtt(pAd, FALSE, HW_BSSID_0); + /* Disable piggyback */ + AsicSetPiggyBack(pAd, FALSE); + + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { + AsicDisableSync(pAd, HW_BSSID_0); +#ifdef LED_CONTROL_SUPPORT + /* Set LED */ + RTMPSetLED(pAd, LED_LINK_DOWN); +#endif /* LED_CONTROL_SUPPORT */ + } + + /* beacon exit for USB/SDIO */ + asic_bss_beacon_exit(pAd); + + + + +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + + if (wf_drv_tbl.wf_fwd_entry_delete_hook) + wf_drv_tbl.wf_fwd_entry_delete_hook(pAd->net_dev, wdev_bss->if_dev, 0); + + if (wf_drv_tbl.wf_fwd_check_device_hook) + wf_drv_tbl.wf_fwd_check_device_hook(wdev_bss->if_dev, + INT_MBSSID, pMbss->mbss_idx, wdev_bss->channel, 0); + +#endif /* CONFIG_WIFI_PKT_FWD */ + /* clear protection to default */ + wdev_bss->protection = 0; + + if (wdev_do_linkdown(wdev_bss) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() linkdown fail!!!\n", __func__)); + + if (WMODE_CAP_5G(wdev_bss->PhyMode)) { +#ifdef MT_DFS_SUPPORT /* Jelly20150217 */ + WrapDfsRadarDetectStop(pAd); + /* Zero wait hand off recovery for CAC period + interface down case */ + DfsZeroHandOffRecovery(pAd, wdev_bss); +#endif + } + + /* Update devinfo for any phymode change */ + if (wdev_do_close(wdev_bss) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() close fail!!!\n", __func__)); + + APReleaseRekeyTimer(pAd, wdev_bss); +#ifdef BAND_STEERING + if (pAd->ApCfg.BandSteering) { + PBND_STRG_CLI_TABLE table; + + table = Get_BndStrgTable(pAd, idx); + if (table) { + /* Inform daemon interface ready */ + BndStrg_SetInfFlags(pAd, &pMbss->wdev, table, FALSE); + } + } +#endif /* BAND_STEERING */ + + if (pAd->ApCfg.CMTimerRunning == TRUE) { + RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled); + pAd->ApCfg.CMTimerRunning = FALSE; + pAd->ApCfg.BANClass3Data = FALSE; + } + +#ifdef IDS_SUPPORT + /* if necessary, cancel IDS timer */ + RTMPIdsStop(pAd); +#endif /* IDS_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + FT_Release(pAd); +#endif /* DOT11R_FT_SUPPORT */ +#ifdef SMART_ANTENNA + RtmpSAStop(pAd); +#endif /* SMART_ANTENNA */ +#ifdef VOW_SUPPORT + vow_reset(pAd); +#endif /* VOW_SUPPORT */ +#if defined(CONFIG_MAP_SUPPORT) && defined(WAPP_SUPPORT) + wapp_send_bss_stop_rsp(pAd, wdev_bss); +#endif /*WAPP_SUPPORT*/ +} + +VOID APStop(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss, ENUM_AP_BSS_OPER oper) +{ + UINT32 idx; + BSS_STRUCT *pCurMbss = NULL; + UCHAR ch = 0; + + /* Don't care pMbss if operation is for all */ + if ((pMbss == NULL) && (oper != AP_BSS_OPER_ALL)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s() Invalid oper(%d)\n", + __func__, oper)); + return; + } + + if (pMbss) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(), oper(%d) bssid(%d)=%02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, oper, pMbss->mbss_idx, PRINT_MAC(pMbss->wdev.bssid))); + else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(), oper(%d)\n", + __func__, oper)); + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_SYSEM_READY); + + switch (oper) { + case AP_BSS_OPER_ALL: + for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { + pCurMbss = &pAd->ApCfg.MBSSID[idx]; + pCurMbss->mbss_idx = idx; + + APStopByBss(pAd, pCurMbss); + } + break; + case AP_BSS_OPER_BY_RF: + ch = pMbss->wdev.channel; + for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { + pCurMbss = &pAd->ApCfg.MBSSID[idx]; + pCurMbss->mbss_idx = idx; + + /* check MBSS status is up */ + if (!pCurMbss->wdev.if_up_down_state) + continue; + + /* check MBSS work on the same RF(channel) */ + if (pCurMbss->wdev.channel != ch) + continue; + + APStopByBss(pAd, pCurMbss); + } + break; + + case AP_BSS_OPER_SINGLE: + default: + APStopByBss(pAd, pMbss); + break; + } + + CMDHandler(pAd); + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<=== %s()\n", __func__)); +} + +/* + ========================================================================== + Description: + This routine is used to clean up a specified power-saving queue. It's + used whenever a wireless client is deleted. + ========================================================================== + */ +VOID APCleanupPsQueue(RTMP_ADAPTER *pAd, QUEUE_HEADER *pQueue) +{ + PQUEUE_ENTRY pEntry; + PNDIS_PACKET pPacket; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): (0x%08lx)...\n", __func__, (ULONG)pQueue)); + + while (pQueue->Head) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s():%u...\n", __func__, 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); + } +} + +/* +* +*/ +static VOID avg_pkt_len_reset(struct _RTMP_ADAPTER *ad) +{ +#if defined(VOW_SUPPORT) && defined(CONFIG_AP_SUPPORT) + vow_avg_pkt_len_reset(ad); +#endif + ad->mcli_ctl.pkt_avg_len = 0; + ad->mcli_ctl.sta_nums = 0; +} + +/* +* +*/ +static VOID avg_pkt_len_calculate(struct _MAC_TABLE_ENTRY *entry) +{ + struct _RTMP_ADAPTER *ad = entry->wdev->sys_handle; + UINT32 avg_pkt_len = 0; + struct multi_cli_ctl *mctrl = &ad->mcli_ctl; + +#if defined(VOW_SUPPORT) && defined(CONFIG_AP_SUPPORT) + vow_avg_pkt_len_calculate(entry); +#endif + if (!ad->CommonCfg.dbdc_mode) + return; + + if (entry->avg_tx_pkts > 0) + avg_pkt_len = (UINT32)(entry->AvgTxBytes / entry->avg_tx_pkts); + + if ((avg_pkt_len > VERIWAVE_INVALID_PKT_LEN_HIGH) || + (avg_pkt_len < VERIWAVE_INVALID_PKT_LEN_LOW)) + return; + /*moving average for pkt avg length*/ + mctrl->pkt_avg_len = + ((mctrl->pkt_avg_len * mctrl->sta_nums) + avg_pkt_len) / (mctrl->sta_nums + 1); + mctrl->sta_nums++; +} + +#define FAR_CLIENT_RSSI (-70) +#define FAR_CLIENT_DELTA_RSSI (10) +static VOID CalFarClientNum(struct _RTMP_ADAPTER *ad, struct _MAC_TABLE_ENTRY *entry) +{ + UINT8 idx; + CHAR avg_rssi[4]; + + for (idx = 0; idx < 4; idx++) + avg_rssi[idx] = ad->ApCfg.RssiSample.LastRssi[idx] - ad->BbpRssiToDbmDelta; + + for (idx = 0; idx < 4; idx++) { + if ((entry->RssiSample.AvgRssi[idx] < FAR_CLIENT_RSSI) && + (entry->RssiSample.AvgRssi[idx] != -127)) { + if ((avg_rssi[idx] - entry->RssiSample.AvgRssi[idx]) >= FAR_CLIENT_DELTA_RSSI) { + ad->nearfar_far_client_num++; + break; + } + } + } +} + +/* +* +*/ +static VOID dynamic_amsdu_protect_adjust(struct _RTMP_ADAPTER *ad) +{ + UCHAR amsdu_cnt = 4, band_idx = 0; + ULONG per = 0; + ULONG tx_cnt; + ULONG tx_fail_cnt; + COUNTER_802_11 *wlan_ct = NULL; + struct wifi_dev *wdev = NULL; + UINT16 multi_client_num_th = 0, veriwave_tp_amsdu_dis_th = 0; + + /*concurrent case, not adjust*/ + if (ad->txop_ctl[DBDC_BAND0].multi_client_nums > 0) { +#if DBDC_BAND_NUM == 2 + if (ad->txop_ctl[DBDC_BAND1].multi_client_nums > 0) + return; +#endif + band_idx = DBDC_BAND0; + } +#if DBDC_BAND_NUM == 2 + else if (ad->txop_ctl[DBDC_BAND1].multi_client_nums > 0) + band_idx = DBDC_BAND1; +#endif + else + return; + + wlan_ct = &ad->WlanCounters[band_idx]; + wdev = ad->txop_ctl[band_idx].cur_wdev; + + if (WMODE_CAP_2G(wdev->PhyMode)) { + multi_client_num_th = MULTI_CLIENT_2G_NUMS_TH; + veriwave_tp_amsdu_dis_th = VERIWAVE_2G_TP_AMSDU_DIS_TH; + } else if (WMODE_CAP_5G(wdev->PhyMode)) { + multi_client_num_th = MULTI_CLIENT_NUMS_TH; + veriwave_tp_amsdu_dis_th = VERIWAVE_TP_AMSDU_DIS_TH; + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s[%d]\n", __func__, __LINE__)); + return; + } + + /*adjust amsdu*/ + if (ad->txop_ctl[band_idx].multi_client_nums == multi_client_num_th) { + if (ad->mcli_ctl.pkt_avg_len > VERIWAVE_PKT_LEN_LOW) + amsdu_cnt = 2; + + } else { + if (ad->txop_ctl[band_idx].multi_client_nums > 1) { + if (ad->mcli_ctl.pkt_avg_len > veriwave_tp_amsdu_dis_th) + amsdu_cnt = 1; + else if (ad->mcli_ctl.pkt_avg_len > VERIWAVE_PKT_LEN_LOW) + amsdu_cnt = 2; + } + } + + if (ad->mcli_ctl.amsdu_cnt != amsdu_cnt) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): change amsdu %d to %d\n", + __func__, ad->mcli_ctl.amsdu_cnt, amsdu_cnt)); + ad->mcli_ctl.amsdu_cnt = amsdu_cnt; + amsdu_cnt = 4; + if (IS_ASIC_CAP(ad, fASIC_CAP_MCU_OFFLOAD)) + MtCmdCr4Set(ad, CR4_SET_ID_CONFIG_STA_AMSDU_MAX_NUM, 255, amsdu_cnt); + else + ad->amsdu_max_num = amsdu_cnt; + } + /* reset */ + ad->nearfar_far_client_num = 0; + + /*only change protection scenario when sta more than 2*/ + if (ad->txop_ctl[band_idx].multi_client_nums < 2) { + ad->mcli_ctl.last_tx_cnt = wlan_ct->AmpduSuccessCount.u.LowPart; + ad->mcli_ctl.last_tx_fail_cnt = wlan_ct->AmpduFailCount.u.LowPart; + if (ad->mcli_ctl.c2s_only == TRUE) { + asic_rts_on_off(wdev, TRUE); + ad->mcli_ctl.c2s_only = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s(): enable RTS\n", __func__)); + } + return; + } + + tx_cnt = wlan_ct->AmpduSuccessCount.u.LowPart - ad->mcli_ctl.last_tx_cnt; + tx_fail_cnt = wlan_ct->AmpduFailCount.u.LowPart - ad->mcli_ctl.last_tx_fail_cnt; + + ad->mcli_ctl.last_tx_cnt = wlan_ct->AmpduSuccessCount.u.LowPart; + ad->mcli_ctl.last_tx_fail_cnt = wlan_ct->AmpduFailCount.u.LowPart; + + if (tx_cnt > 0) { + per = (100 * tx_fail_cnt) / (tx_fail_cnt + tx_cnt); + if ((ad->mcli_ctl.c2s_only == FALSE) && (per < VERIWAVE_PER_RTS_DIS_TH_LOW_MARK)) { + asic_rts_on_off(wdev, FALSE); + ad->mcli_ctl.c2s_only = TRUE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s(): disable RTS, per=%lu\n", + __func__, per)); + } else if ((ad->mcli_ctl.c2s_only == TRUE) && (per >= VERIWAVE_PER_RTS_DIS_TH_HIGH_MARK)) { + asic_rts_on_off(wdev, TRUE); + ad->mcli_ctl.c2s_only = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s(): enable RTS, per=%lu\n", + __func__, per)); + } + } + +} +#if defined(VOW_SUPPORT) && defined(CONFIG_AP_SUPPORT) +static VOID dynamic_airtime_fairness_adjust(struct _RTMP_ADAPTER *ad) +{ + BOOLEAN shrink_flag = FALSE; + BOOLEAN mc_flg = FALSE, fband_2g = FALSE; + UCHAR band_idx = 0; + UINT16 multi_client_num_th = 0, veriwave_tp_amsdu_dis_th = 0; + struct wifi_dev *wdev = NULL; + + if (!ad->vow_cfg.en_airtime_fairness) + return; + + /*concurrent case, not adjust*/ + if (ad->txop_ctl[DBDC_BAND0].multi_client_nums > 0) { +#if DBDC_BAND_NUM == 2 + if (ad->txop_ctl[DBDC_BAND1].multi_client_nums > 0) + return; +#endif + band_idx = DBDC_BAND0; + } +#if DBDC_BAND_NUM == 2 + else if (ad->txop_ctl[DBDC_BAND1].multi_client_nums > 0) + band_idx = DBDC_BAND1; +#endif + else + return; + + wdev = ad->txop_ctl[band_idx].cur_wdev; + + if (WMODE_CAP_2G(wdev->PhyMode)) { + multi_client_num_th = MULTI_CLIENT_2G_NUMS_TH; + veriwave_tp_amsdu_dis_th = VERIWAVE_2G_TP_AMSDU_DIS_TH; + fband_2g = TRUE; + } else if (WMODE_CAP_5G(wdev->PhyMode)) { + multi_client_num_th = MULTI_CLIENT_NUMS_TH; + veriwave_tp_amsdu_dis_th = VERIWAVE_TP_AMSDU_DIS_TH; + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s[%d]\n", __func__, __LINE__)); + return; + } + + /*adjust amsdu*/ + if (ad->txop_ctl[band_idx].multi_client_nums == multi_client_num_th) { + if (ad->vow_mcli_ctl.pkt_avg_len > VERIWAVE_PKT_LEN_LOW) + shrink_flag = TRUE; + + } else { + if (ad->txop_ctl[band_idx].multi_client_nums > 1) { + if (ad->vow_mcli_ctl.pkt_avg_len > veriwave_tp_amsdu_dis_th) + shrink_flag = TRUE; + else if (ad->vow_mcli_ctl.pkt_avg_len > VERIWAVE_PKT_LEN_LOW) + shrink_flag = TRUE; + } + } + + if (ad->txop_ctl[band_idx].multi_client_nums == multi_client_num_th) + mc_flg = TRUE; + + if (ad->vow_sta_frr_flag != shrink_flag) { + /* adj airtime quantum only when WATF is not enabled */ + ad->vow_sta_frr_flag = shrink_flag; + if (ad->vow_cfg.en_airtime_fairness && ad->vow_sta_frr_quantum && !vow_watf_is_enabled(ad)) { + if ((shrink_flag == TRUE) & (ad->nearfar_far_client_num <= 1) && mc_flg) + RTMP_SET_STA_DWRR_QUANTUM(ad, FALSE, ad->vow_sta_frr_quantum);/* fast round robin */ + else + RTMP_SET_STA_DWRR_QUANTUM(ad, TRUE, 0);/* restore */ + } + + } + return; +} +#endif /* defined (VOW_SUPPORT) && defined(CONFIG_AP_SUPPORT) */ + +#ifdef WHNAT_SUPPORT +static VOID tx_offload_counter_update(struct _RTMP_ADAPTER *ad, struct _MAC_TABLE_ENTRY *entry) +{ +#ifdef CONFIG_AP_SUPPORT + if (IS_ENTRY_CLIENT(entry) && entry->pMbss) { + entry->pMbss->TxCount += entry->one_sec_tx_pkts; + entry->pMbss->TransmittedByteCount += entry->OneSecTxBytes; + } +#endif /*CONFIG_AP_SUPPORT*/ + +#ifdef APCLI_SUPPORT + if ((IS_ENTRY_APCLI(entry) +#ifdef MAC_REPEATER_SUPPORT + || IS_ENTRY_REPEATER(entry) +#endif /*MAC_REPEATER_SUPPORT*/ + ) && entry->pApCli) { + struct _APCLI_STRUCT *apcli_entry = entry->pApCli; + apcli_entry->TxCount += entry->one_sec_tx_pkts; + apcli_entry->TransmittedByteCount += entry->OneSecTxBytes; + } +#endif /*APCLI_SUPPORT*/ + +#ifdef WDS_SUPPORT + + if (IS_ENTRY_WDS(entry)) { + ad->WdsTab.WdsEntry[entry->func_tb_idx].WdsCounter.TransmittedFragmentCount.QuadPart += entry->one_sec_tx_pkts; + ad->WdsTab.WdsEntry[entry->func_tb_idx].WdsCounter.TransmittedByteCount += entry->OneSecTxBytes; + } +#endif /* WDS_SUPPORT */ +} +#endif /*WHNAT_SUPPORT*/ + +static VOID do_sta_keep_action(struct _RTMP_ADAPTER *ad, struct _MAC_TABLE_ENTRY *entry, BOOLEAN is_no_rx) +{ +#ifdef IAPP_SUPPORT + if (entry->wdev && + is_no_rx && + (ad->Mlme.PeriodicRound % STA_KEEP_ALIVE_NOTIFY_L2) == 0) { + IAPP_L2_Update_Frame_Send(ad, entry->Addr, entry->wdev->wdev_idx); + } +#endif /*IAPP_SUPPORT*/ +} + +/* + ========================================================================== + 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(RTMP_ADAPTER *pAd) +{ + int wcid, startWcid; +#ifdef DOT11_N_SUPPORT + BOOLEAN bRdgActive = FALSE; + BOOLEAN bRalinkBurstMode; +#endif /* DOT11_N_SUPPORT */ +#ifdef RTMP_MAC_PCI + unsigned long IrqFlags; +#endif /* RTMP_MAC_PCI */ + MAC_TABLE *pMacTable; + CHAR avgRssi; + BSS_STRUCT *pMbss; +#ifdef WFA_VHT_PF + RSSI_SAMPLE *worst_rssi = NULL; + int worst_rssi_sta_idx = 0; +#endif /* WFA_VHT_PF */ +#ifdef MT_MAC + BOOLEAN bPreAnyStationInPsm = FALSE; +#endif /* MT_MAC */ + UINT BandIdx = 0; +#ifdef SMART_CARRIER_SENSE_SUPPORT + CHAR tmpRssi = 0; +#endif /* SMART_CARRIER_SENSE_SUPPORT */ +#ifdef APCLI_SUPPORT + ULONG apcli_avg_tx = 0; + ULONG apcli_avg_rx = 0; + struct wifi_dev *apcli_wdev = NULL; +#endif /* APCLI_SUPPORT */ + struct wifi_dev *sta_wdev = NULL; + struct wifi_dev *txop_wdev = NULL; + UCHAR sta_hit_2g_infra_case_number = 0; + struct _RTMP_CHIP_CAP *cap; + BOOLEAN is_no_rx_cnt = FALSE; + + cap = hc_get_chip_cap(pAd->hdev_ctrl); + pMacTable = &pAd->MacTab; +#ifdef MT_MAC + bPreAnyStationInPsm = pMacTable->fAnyStationInPsm; +#endif /* MT_MAC */ + pMacTable->fAnyStationInPsm = FALSE; + pMacTable->fAnyStationBadAtheros = FALSE; + pMacTable->fAnyTxOPForceDisable = FALSE; + pMacTable->fAllStationAsRalink[0] = TRUE; + pMacTable->fAllStationAsRalink[1] = TRUE; + pMacTable->fCurrentStaBw40 = FALSE; +#ifdef DOT11_N_SUPPORT + pMacTable->fAnyStationNonGF = FALSE; + pMacTable->fAnyStation20Only = FALSE; + pMacTable->fAnyStationIsLegacy = FALSE; + pMacTable->fAnyStationMIMOPSDynamic = FALSE; +#ifdef DOT11N_DRAFT3 + pMacTable->fAnyStaFortyIntolerant = FALSE; +#endif /* DOT11N_DRAFT3 */ + pMacTable->fAllStationGainGoodMCS = TRUE; +#endif /* DOT11_N_SUPPORT */ + startWcid = 1; +#ifdef SMART_CARRIER_SENSE_SUPPORT + + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + pAd->SCSCtrl.SCSMinRssi[BandIdx] = 0; /* (Reset)The minimum RSSI of STA */ + pAd->SCSCtrl.OneSecRxByteCount[BandIdx] = 0; + pAd->SCSCtrl.OneSecTxByteCount[BandIdx] = 0; + } + +#endif /* SMART_CARRIER_SENSE_SUPPORT */ + + avg_pkt_len_reset(pAd); + /*TODO: Carter, modification start Wcid, Aid shall not simply equal to WCID.*/ + for (wcid = startWcid; VALID_UCAST_ENTRY_WCID(pAd, wcid); wcid++) { + MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[wcid]; + STA_TR_ENTRY *tr_entry = &pMacTable->tr_entry[wcid]; + BOOLEAN bDisconnectSta = FALSE; + + if (IS_ENTRY_NONE(pEntry)) + continue; + +#ifdef HTC_DECRYPT_IOT + + if (pEntry && (IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry) || IS_ENTRY_REPEATER(pEntry))) { + if (pEntry->HTC_AAD_OM_CountDown > 0) /* count down to start all new pEntry->HTC_ICVErrCnt */ + pEntry->HTC_AAD_OM_CountDown--; + } + +#endif /* HTC_DECRYPT_IOT */ +#ifdef SMART_CARRIER_SENSE_SUPPORT + + if (IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry) || IS_ENTRY_REPEATER(pEntry)) { + BandIdx = HcGetBandByWdev(pEntry->wdev); + pAd->SCSCtrl.OneSecRxByteCount[BandIdx] += pEntry->OneSecRxBytes; + pAd->SCSCtrl.OneSecTxByteCount[BandIdx] += pEntry->OneSecTxBytes; + + if (pAd->SCSCtrl.SCSEnable[BandIdx] == SCS_ENABLE) { + tmpRssi = RTMPMinRssi(pAd, pEntry->RssiSample.AvgRssi[0], pEntry->RssiSample.AvgRssi[1], + pEntry->RssiSample.AvgRssi[2], pEntry->RssiSample.AvgRssi[3]); + + if (tmpRssi < pAd->SCSCtrl.SCSMinRssi[BandIdx]) + pAd->SCSCtrl.SCSMinRssi[BandIdx] = tmpRssi; + } + } + +#endif /* SMART_CARRIER_SENSE_SUPPORT */ +#ifdef RACTRL_LIMIT_MAX_PHY_RATE +#ifdef DOT11_VHT_AC + + if (pAd->MacTab.Size == 0) + pAd->fgRaLimitPhyRate = FALSE; + else if ((pAd->fgRaLimitPhyRate == FALSE) && !IS_ENTRY_NONE(pEntry)) { + UINT16 u2TxTP; + BOOLEAN fgPhyModeCheck = FALSE; + + u2TxTP = pEntry->OneSecTxBytes >> BYTES_PER_SEC_TO_MBPS; + + if (pEntry->SupportRateMode & SUPPORT_VHT_MODE) { + if (pEntry->MaxHTPhyMode.field.BW == BW_160) + fgPhyModeCheck = TRUE; + + if (RACTRL_LIMIT_MAX_PHY_RATE >= MAX_PHY_RATE_3SS) { + if (pEntry->SupportVHTMCS4SS) + fgPhyModeCheck = TRUE; + } else if (RACTRL_LIMIT_MAX_PHY_RATE >= MAX_PHY_RATE_2SS) { + if (pEntry->SupportVHTMCS3SS) + fgPhyModeCheck = TRUE; + } else + fgPhyModeCheck = TRUE; + } + + if ((u2TxTP > LIMIT_MAX_PHY_RATE_THRESHOLD) && fgPhyModeCheck) { + MtCmdSetMaxPhyRate(pAd, RACTRL_LIMIT_MAX_PHY_RATE); + pAd->fgRaLimitPhyRate = TRUE; + } + } + +#endif /* DOT11_VHT_AC */ +#endif /* RACTRL_LIMIT_MAX_PHY_RATE */ +#ifdef APCLI_SUPPORT + + if (IS_ENTRY_APCLI(pEntry) && (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) { + PAPCLI_STRUCT pApCliEntry = &pAd->ApCfg.ApCliTab[pEntry->func_tb_idx]; + + pApCliEntry->OneSecTxBytes = pEntry->OneSecTxBytes; + pApCliEntry->OneSecRxBytes = pEntry->OneSecRxBytes; +#ifdef APCLI_CERT_SUPPORT + + if (pApCliEntry->NeedFallback == TRUE) { + pApCliEntry->NeedFallback = FALSE; + + if (pAd->bApCliCertTest == TRUE) { +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + if (cap->fgRateAdaptFWOffload == TRUE) { + CMD_STAREC_AUTO_RATE_UPDATE_T rRaParam; + + NdisZeroMemory(&rRaParam, sizeof(CMD_STAREC_AUTO_RATE_UPDATE_T)); + rRaParam.u4Field = RA_PARAM_HT_2040_COEX; + RAParamUpdate(pAd, pEntry, &rRaParam); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("FallBack APClient BW to 20MHz\n")); + } +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + } + } + +#endif /* APCLI_CERT_SUPPORT */ + } + +#endif /* APCLI_SUPPORT */ + +#ifdef WHNAT_SUPPORT + if ((pAd->CommonCfg.whnat_en) && (IS_ASIC_CAP(pAd, fASIC_CAP_MCU_OFFLOAD))) { + MtCmdCr4Query(pAd, CR4_QUERY_OPTION_GET_TX_STATISTICS, wcid, 0); + tx_offload_counter_update(pAd, pEntry); + } + else +#endif + { + pEntry->AvgTxBytes = (pEntry->AvgTxBytes == 0) ? + pEntry->OneSecTxBytes : + ((pEntry->AvgTxBytes + pEntry->OneSecTxBytes) >> 1); + pEntry->OneSecTxBytes = 0; + pEntry->avg_tx_pkts = (pEntry->avg_tx_pkts == 0) ? \ + pEntry->one_sec_tx_pkts : \ + ((pEntry->avg_tx_pkts + pEntry->one_sec_tx_pkts) >> 1); + pEntry->one_sec_tx_pkts = 0; + } + + pEntry->AvgRxBytes = (pEntry->AvgRxBytes == 0) ? + pEntry->OneSecRxBytes : + ((pEntry->AvgRxBytes + pEntry->OneSecRxBytes) >> 1); + pEntry->OneSecRxBytes = 0; + + HW_GET_TX_STATISTIC(pAd, GET_TX_STAT_ENTRY_TX_CNT, wcid); +#ifdef APCLI_SUPPORT + + if ((IS_ENTRY_APCLI(pEntry) || IS_ENTRY_REPEATER(pEntry)) + && (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED) + ) { +#ifdef MAC_REPEATER_SUPPORT + + if (pEntry->bReptCli) { + pEntry->ReptCliIdleCount++; + + if ((pEntry->bReptEthCli) + && (pEntry->ReptCliIdleCount >= MAC_TABLE_AGEOUT_TIME) + && (pEntry->bReptEthBridgeCli == FALSE)) { /* Do NOT ageout br0 link. @2016/1/27 */ + REPEATER_CLIENT_ENTRY *pReptCliEntry = NULL; + + pReptCliEntry = &pAd->ApCfg.pRepeaterCliPool[pEntry->MatchReptCliIdx]; + + if (pReptCliEntry) + pReptCliEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_MTM_REMOVE_STA; + + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + pEntry->MatchReptCliIdx)); + RTMP_MLME_HANDLER(pAd); + continue; + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + + if (IS_ENTRY_APCLI(pEntry)) + apcli_wdev = pEntry->wdev; + + apcli_avg_tx += pEntry->AvgTxBytes; + apcli_avg_rx += pEntry->AvgRxBytes; + + if (((pAd->Mlme.OneSecPeriodicRound % 10) == 8) +#ifdef CONFIG_MULTI_CHANNEL + && (pAd->Mlme.bStartMcc == FALSE) +#endif /* CONFIG_MULTI_CHANNEL */ + ) { + /* 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, PWR_ACTIVE); + continue; + } + } + +#endif /* APCLI_SUPPORT */ + + if (!IS_ENTRY_CLIENT(pEntry)) + continue; + + if (pEntry->fgGband256QAMSupport && (pEntry->RXBAbitmap != 0) && (pEntry->TXBAbitmap != 0) && + sta_hit_2g_infra_case_number <= STA_NUMBER_FOR_TRIGGER) { + sta_wdev = pEntry->wdev; + + if (WMODE_CAP_2G(sta_wdev->PhyMode)) { + UINT tx_tp = (pEntry->AvgTxBytes >> BYTES_PER_SEC_TO_MBPS); + UINT rx_tp = (pEntry->AvgRxBytes >> BYTES_PER_SEC_TO_MBPS); + + if (tx_tp > INFRA_TP_PEEK_BOUND_THRESHOLD && ((tx_tp + rx_tp) > 0) && + (tx_tp * 100) / (tx_tp + rx_tp) > TX_MODE_RATIO_THRESHOLD) { + if (sta_hit_2g_infra_case_number < STA_NUMBER_FOR_TRIGGER) { + txop_wdev = sta_wdev; + sta_hit_2g_infra_case_number++; + } else + sta_hit_2g_infra_case_number++; + } + } + } + + if (pEntry->wdev) { + UINT32 tx_tp = (pEntry->AvgTxBytes >> BYTES_PER_SEC_TO_MBPS); + UINT32 rx_tp = (pEntry->AvgRxBytes >> BYTES_PER_SEC_TO_MBPS); + ULONG avg_tx_b = pEntry->AvgTxBytes; + ULONG avg_rx_b = pEntry->AvgRxBytes; + UINT8 traffc_mode = 0; +#ifdef CONFIG_TX_DELAY + struct tx_delay_control *tx_delay_ctl = &pAd->tr_ctl.tx_delay_ctl; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + if ((rx_tp >= MIN_AGG_EN_TP) && (rx_tp <= MAX_AGG_EN_TP) && cap->tx_delay_support) { + if (!tx_delay_ctl->que_agg_en) { + tx_delay_ctl->que_agg_en = TRUE; + if (IS_ASIC_CAP(pAd, fASIC_CAP_MCU_OFFLOAD)) { + MtCmdCr4Set(pAd, CR4_SET_ID_CONFIG_TX_DELAY_MODE, + TX_DELAY_MODE_ARG1_TX_BATCH_CNT, tx_delay_ctl->tx_process_batch_cnt); + } + } + } else { + if (tx_delay_ctl->que_agg_en) { + tx_delay_ctl->que_agg_en = FALSE; + if (IS_ASIC_CAP(pAd, fASIC_CAP_MCU_OFFLOAD)) { + MtCmdCr4Set(pAd, CR4_SET_ID_CONFIG_TX_DELAY_MODE, + TX_DELAY_MODE_ARG1_TX_BATCH_CNT, 1); + } + } + } +#endif + + if ((tx_tp + rx_tp) == 0) + traffc_mode = TRAFFIC_0; + else if (((tx_tp * 100) / (tx_tp + rx_tp)) > TX_MODE_RATIO_THRESHOLD) + traffc_mode = TRAFFIC_DL_MODE; + else if (((rx_tp * 100) / (tx_tp + rx_tp)) > RX_MODE_RATIO_THRESHOLD) + traffc_mode = TRAFFIC_UL_MODE; + else if (((rx_tp * 100) / (tx_tp + rx_tp)) < RX_INACTIVE_THRESHOLD) + traffc_mode = TRAFFIC_UL_INACTIVE_MODE; + + /* get associated band with wdev*/ + BandIdx = HcGetBandByWdev(pEntry->wdev); + if (traffc_mode) { + struct tr_delay_control *tr_delay_ctl = &pAd->tr_ctl.tr_delay_ctl; + UINT32 i; + struct dly_ctl_cfg *cfg; + UINT32 reg_val; + UINT32 rx_reg_val = 0x0; + + HIF_IO_READ32(pAd, MT_DELAY_INT_CFG, ®_val); + + rx_reg_val = reg_val & 0xffff; + + if (tr_delay_ctl->rx_delay_en) { + if (traffc_mode == TRAFFIC_DL_MODE) { + for (i = 0; i < tr_delay_ctl->dl_rx_dly_ctl_tbl_size; i++) { + cfg = tr_delay_ctl->dl_rx_dly_ctl_tbl + i; + if (tx_tp > cfg->avg_tp) { + rx_reg_val = cfg->dly_cfg; + continue; + } else { + break; + } + } + } + + if (traffc_mode == TRAFFIC_UL_MODE) { + for (i = 0; i < tr_delay_ctl->ul_rx_dly_ctl_tbl_size; i++) { + cfg = tr_delay_ctl->ul_rx_dly_ctl_tbl + i; + if (rx_tp > cfg->avg_tp) { + rx_reg_val = cfg->dly_cfg; + continue; + } else { + break; + } + } + } + } + + HIF_IO_WRITE32(pAd, MT_DELAY_INT_CFG, rx_reg_val); + } + + if (WMODE_CAP_5G(pEntry->wdev->PhyMode) && (pAd->txop_ctl[BandIdx].multi_client_nums < MULTI_CLIENT_NUMS_TH)) { + pAd->txop_ctl[BandIdx].cur_wdev = pEntry->wdev; + + if ((pEntry->avg_tx_pkts > VERIWAVE_5G_PKT_CNT_TH) && ((avg_tx_b + avg_rx_b) > 0) && + (((avg_tx_b * 100) / (avg_tx_b + avg_rx_b)) > TX_MODE_RATIO_THRESHOLD)) + pAd->txop_ctl[BandIdx].multi_client_nums++; + } + + if (WMODE_CAP_2G(pEntry->wdev->PhyMode) && (pAd->txop_ctl[BandIdx].multi_client_nums < MULTI_CLIENT_2G_NUMS_TH)) { + pAd->txop_ctl[BandIdx].cur_wdev = pEntry->wdev; + + if ((pEntry->avg_tx_pkts > VERIWAVE_2G_PKT_CNT_TH) && ((avg_tx_b + avg_rx_b) > 0) && + (((avg_tx_b * 100) / (avg_tx_b + avg_rx_b)) > TX_MODE_RATIO_THRESHOLD)) + pAd->txop_ctl[BandIdx].multi_client_nums++; + } + + avg_pkt_len_calculate(pEntry); + CalFarClientNum(pAd, pEntry); + + if (WMODE_CAP_5G(pEntry->wdev->PhyMode)) { + if (pAd->peak_tp_ctl[BandIdx].cur_wdev == NULL) + pAd->peak_tp_ctl[BandIdx].cur_wdev = pEntry->wdev; + pAd->peak_tp_ctl[BandIdx].client_nums++; + if (traffc_mode == TRAFFIC_DL_MODE) { + /* the entry is in tx mode */ + if (tx_tp > pAd->peak_tp_ctl[BandIdx].max_tx_tp) { + pAd->peak_tp_ctl[BandIdx].max_tx_tp = tx_tp; + pAd->peak_tp_ctl[BandIdx].cur_wdev = pEntry->wdev; + } + } + } + + if (WMODE_CAP_2G(pEntry->wdev->PhyMode)) { + if (pAd->peak_tp_ctl[BandIdx].cur_wdev == NULL) + pAd->peak_tp_ctl[BandIdx].cur_wdev = pEntry->wdev; + + pAd->peak_tp_ctl[BandIdx].client_nums++; + + if (traffc_mode == TRAFFIC_DL_MODE) { + /* the entry is in tx mode */ + if (tx_tp > pAd->peak_tp_ctl[BandIdx].max_tx_tp) { + pAd->peak_tp_ctl[BandIdx].max_tx_tp = tx_tp; + pAd->peak_tp_ctl[BandIdx].cur_wdev = pEntry->wdev; + } + } + } + + if (pEntry->one_sec_tx_succ_pkts > INFRA_KEEP_STA_PKT_TH && pEntry->NoDataIdleCount != 0) { + pEntry->NoDataIdleCount = 0; + is_no_rx_cnt = TRUE; + } + +#if defined(CONFIG_MAP_SUPPORT) && defined(WAPP_SUPPORT) + if (IS_MAP_ENABLE(pEntry->wdev)) { + if ((traffc_mode == TRAFFIC_UL_INACTIVE_MODE && + pEntry->pre_traffic_mode == TRAFFIC_UL_MODE) || + (traffc_mode == TRAFFIC_UL_MODE && + pEntry->pre_traffic_mode == TRAFFIC_UL_INACTIVE_MODE)) { + /* Send event to wapp when client's activity change */ + wapp_send_cli_active_change(pAd, pEntry); + } + pEntry->pre_traffic_mode = traffc_mode; + } +#endif + } + + + if (pEntry->NoDataIdleCount == 0) + pEntry->StationKeepAliveCount = 0; + + pEntry->NoDataIdleCount++; + /* TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! */ + pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; + pEntry->StaConnectTime++; + pMbss = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx]; + + /* 0. STA failed to complete association should be removed to save MAC table space. */ + if ((pEntry->Sst != SST_ASSOC) && (pEntry->NoDataIdleCount >= pEntry->AssocDeadLine)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%02x:%02x:%02x:%02x:%02x:%02x fail to complete ASSOC in %lu sec\n", + PRINT_MAC(pEntry->Addr), pEntry->AssocDeadLine)); +#ifdef WSC_AP_SUPPORT + + if (NdisEqualMemory(pEntry->Addr, pMbss->wdev.WscControl.EntryAddr, MAC_ADDR_LEN)) + NdisZeroMemory(pMbss->wdev.WscControl.EntryAddr, MAC_ADDR_LEN); + +#endif /* WSC_AP_SUPPORT */ + mac_entry_delete(pAd, pEntry); + 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; + + if (pEntry->wdev && + (pEntry->wdev->wdev_type == WDEV_TYPE_AP || pEntry->wdev->wdev_type == WDEV_TYPE_GO)) { + /* TODO: it looks like pEntry->wdev->tr_tb_idx is not assigned? */ + pAd->MacTab.tr_entry[pEntry->wdev->tr_tb_idx].PsMode = PWR_SAVE; + + if (tr_entry->PsDeQWaitCnt) { + tr_entry->PsDeQWaitCnt++; + + if (tr_entry->PsDeQWaitCnt > 2) + tr_entry->PsDeQWaitCnt = 0; + } + } + } + +#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 DOT11N_DRAFT3 + + if (pEntry->bForty_Mhz_Intolerant) + pMacTable->fAnyStaFortyIntolerant = TRUE; + +#endif /* DOT11N_DRAFT3 */ + +#endif /* DOT11_N_SUPPORT */ + /* detect the station alive status */ + + /* detect the station alive status */ + if ((pMbss->StationKeepAliveTime > 0) && + (pEntry->NoDataIdleCount >= pMbss->StationKeepAliveTime)) { + /* + 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->func_tb_idx, 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; + + RtmpEnqueueNullFrame(pAd, pEntry->Addr, pEntry->CurrTxRate, + pEntry->Aid, pEntry->func_tb_idx, 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; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("STA-%02x:%02x:%02x:%02x:%02x:%02x had left (%d %lu)\n", + PRINT_MAC(pEntry->Addr), + pEntry->ContinueTxFailCnt, pAd->ApCfg.EntryLifeCheck)); + } + } + + avgRssi = RTMPAvgRssi(pAd, &pEntry->RssiSample); + + if (pMbss->RssiLowForStaKickOut && + (avgRssi < pMbss->RssiLowForStaKickOut)) { + bDisconnectSta = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("Disassoc STA %02x:%02x:%02x:%02x:%02x:%02x , RSSI Kickout Thres[%d]-[%d]\n", + PRINT_MAC(pEntry->Addr), pMbss->RssiLowForStaKickOut, avgRssi)); + } + + if (bDisconnectSta) { + /* send wireless event - for ageout */ + RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0); +#ifdef VENDOR_FEATURE7_SUPPORT + { + UCHAR disassoc_event_msg[32] = {0}; + + if (WMODE_CAP_5G(pMbss->wdev.PhyMode)) + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + " %02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pEntry->Addr), (pEntry->func_tb_idx) + WIFI_50_RADIO); + else + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + " %02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pEntry->Addr), (pEntry->func_tb_idx) + WIFI_24_RADIO); + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_EVENT, STA_DISSOC, + disassoc_event_msg, strlen(disassoc_event_msg)); + } +#endif + 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) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, (" MlmeAllocateMemory fail ..\n")); + /*NdisReleaseSpinLock(&pAd->MacTabLock); */ + continue; + } + + Reason = REASON_DEAUTH_STA_LEAVING; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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, + pMbss->wdev.if_addr, + pMbss->wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DeAuthHdr, + 2, &Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); +#ifdef MAC_REPEATER_SUPPORT + + if ((pAd->ApCfg.bMACRepeaterEn == TRUE) && IS_ENTRY_CLIENT(pEntry) + ) { + UCHAR apCliIdx, CliIdx; + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + + pReptEntry = RTMPLookupRepeaterCliEntry( + pAd, + TRUE, + pEntry->Addr, + TRUE); + + if (pReptEntry && + (pReptEntry->CliConnectState != REPT_ENTRY_DISCONNT)) { + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_MTM_REMOVE_STA; + apCliIdx = pReptEntry->MatchApCliIdx; + CliIdx = pReptEntry->MatchLinkIdx; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + } + + mac_entry_delete(pAd, pEntry); + continue; + } else { + do_sta_keep_action(pAd, pEntry, is_no_rx_cnt); + } + +#if defined(CONFIG_HOTSPOT_R2) || defined(CONFIG_DOT11V_WNM) + + if (pEntry->BTMDisassocCount == 1) { + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + HEADER_802_11 DisassocHdr; + USHORT Reason; + /* send out a DISASSOC request frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, (" MlmeAllocateMemory fail ..\n")); + /*NdisReleaseSpinLock(&pAd->MacTabLock); */ + continue; + } + + Reason = REASON_DISASSOC_INACTIVE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("BTM ASSOC - Send DISASSOC Reason = %d frame TO %x %x %x %x %x %x\n", Reason, pEntry->Addr[0], pEntry->Addr[1], + pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); + MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pEntry->Addr, pMbss->wdev.if_addr, pMbss->wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DisassocHdr, 2, &Reason, END_OF_ARGS); + MiniportMMRequest(pAd, MGMT_USE_PS_FLAG, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + + /* JERRY */ + if (!pEntry->IsKeep) { + mac_entry_delete(pAd, pEntry); + } + + continue; + } + + if (pEntry->BTMDisassocCount != 0) + pEntry->BTMDisassocCount--; + +#endif /* CONFIG_HOTSPOT_R2 */ + + /* 3. garbage collect the ps_queue if the STA has being idle for a while */ + if ((pEntry->PsMode == PWR_SAVE) && (tr_entry->ps_state == APPS_RETRIEVE_DONE || + tr_entry->ps_state == APPS_RETRIEVE_IDLE)) { + if (tr_entry->enqCount > 0) { + tr_entry->PsQIdleCount++; + + if (tr_entry->PsQIdleCount > 5) { + struct qm_ops *ops = pAd->qm_ops; + + if (ops->sta_clean_queue) + ops->sta_clean_queue(pAd, pEntry->wcid); + + tr_entry->PsQIdleCount = 0; + WLAN_MR_TIM_BIT_CLEAR(pAd, pEntry->func_tb_idx, pEntry->Aid); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s():Clear WCID[%d] packets\n", __func__, pEntry->wcid)); + } + } + } else + tr_entry->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)) { + UCHAR band_idx; + + band_idx = HcGetBandByWdev(pEntry->wdev); + pMacTable->fAllStationAsRalink[band_idx] = FALSE; + } + +#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->wcid, pEntry->func_tb_idx); + +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + + /* 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; + + /* Check Current STA's Operation Mode is BW20 or BW40 */ + pMacTable->fCurrentStaBw40 = (pEntry->HTPhyMode.field.BW == BW_40) ? TRUE : FALSE; +#ifdef WFA_VHT_PF + + if (worst_rssi == NULL) { + worst_rssi = &pEntry->RssiSample; + worst_rssi_sta_idx = wcid; + } else { + if (worst_rssi->AvgRssi[0] > pEntry->RssiSample.AvgRssi[0]) { + worst_rssi = &pEntry->RssiSample; + worst_rssi_sta_idx = wcid; + } + } + +#endif /* WFA_VHT_PF */ + } + +#ifdef WFA_VHT_PF + + if (worst_rssi != NULL && + ((pAd->Mlme.OneSecPeriodicRound % 10) == 5) && + (worst_rssi_sta_idx >= 1)) { + CHAR gain = 2; + + if (worst_rssi->AvgRssi[0] >= -40) + gain = 1; + else if (worst_rssi->AvgRssi[0] <= -50) + gain = 2; + + rt85592_lna_gain_adjust(pAd, gain); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s():WorstRSSI for STA(%02x:%02x:%02x:%02x:%02x:%02x):%d,%d,%d, Set Gain as %s\n", + __func__, + PRINT_MAC(pMacTable->Content[worst_rssi_sta_idx].Addr), + worst_rssi->AvgRssi[0], worst_rssi->AvgRssi[1], worst_rssi->AvgRssi[2], + (gain == 2 ? "Mid" : "Low"))); + } + +#endif /* WFA_VHT_PF */ +#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) { + if (pMacTable->fAllStationAsRalink[0]) + bRdgActive = TRUE; + else + bRdgActive = FALSE; + + if (pAd->CommonCfg.dbdc_mode) { + if (pMacTable->fAllStationAsRalink[1]) + ; /* Not support yet... */ + } + } + +#ifdef APCLI_SUPPORT + + if (apcli_wdev) { + UINT tx_tp = (apcli_avg_tx >> BYTES_PER_SEC_TO_MBPS); + UINT rx_tp = (apcli_avg_rx >> BYTES_PER_SEC_TO_MBPS); + + apcli_dync_txop_alg(pAd, apcli_wdev, tx_tp, rx_tp); + } + +#endif /* APCLI_SUPPORT */ + + if (sta_hit_2g_infra_case_number == STA_NUMBER_FOR_TRIGGER) { + if (pAd->G_MODE_INFRA_TXOP_RUNNING == FALSE) { + pAd->g_mode_txop_wdev = txop_wdev; + pAd->G_MODE_INFRA_TXOP_RUNNING = TRUE; + enable_tx_burst(pAd, txop_wdev, AC_BE, PRIO_2G_INFRA, TXOP_FE); + } else if (pAd->g_mode_txop_wdev != txop_wdev) { + disable_tx_burst(pAd, pAd->g_mode_txop_wdev, AC_BE, PRIO_2G_INFRA, TXOP_0); + enable_tx_burst(pAd, txop_wdev, AC_BE, PRIO_2G_INFRA, TXOP_FE); + pAd->g_mode_txop_wdev = txop_wdev; + } + } else { + if (pAd->G_MODE_INFRA_TXOP_RUNNING == TRUE) { + disable_tx_burst(pAd, pAd->g_mode_txop_wdev, AC_BE, PRIO_2G_INFRA, TXOP_0); + pAd->G_MODE_INFRA_TXOP_RUNNING = FALSE; + pAd->g_mode_txop_wdev = NULL; + } + } + + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + if (pAd->txop_ctl[BandIdx].multi_client_nums == MULTI_CLIENT_NUMS_TH) { + if (pAd->txop_ctl[BandIdx].multi_cli_txop_running == FALSE) { + pAd->txop_ctl[BandIdx].multi_cli_txop_running = TRUE; + enable_tx_burst(pAd, pAd->txop_ctl[BandIdx].cur_wdev, AC_BE, PRIO_MULTI_CLIENT, TXOP_0); + } + } else { + if (pAd->txop_ctl[BandIdx].multi_cli_txop_running == TRUE) { + pAd->txop_ctl[BandIdx].multi_cli_txop_running = FALSE; + disable_tx_burst(pAd, pAd->txop_ctl[BandIdx].cur_wdev, AC_BE, PRIO_MULTI_CLIENT, TXOP_0); + } + } + } + +/* + if (pAd->txop_ctl.multi_client_nums_2g == MULTI_CLIENT_2G_NUMS_TH) { + if (pAd->txop_ctl.multi_cli_txop_2g_running == FALSE) { + pAd->txop_ctl.multi_cli_txop_2g_running = TRUE; + enable_tx_burst(pAd, pAd->txop_ctl.cur_wdev_2g, AC_BE, PRIO_MULTI_CLIENT, TXOP_0); + } + } else { + if (pAd->txop_ctl.multi_cli_txop_2g_running == TRUE) { + pAd->txop_ctl.multi_cli_txop_2g_running = FALSE; + disable_tx_burst(pAd, pAd->txop_ctl.cur_wdev_2g, AC_BE, PRIO_MULTI_CLIENT, TXOP_0); + } + } +*/ + /*dynamic adjust amsdu & protection mode*/ + dynamic_amsdu_protect_adjust(pAd); +#if defined(VOW_SUPPORT) && defined(CONFIG_AP_SUPPORT) + dynamic_airtime_fairness_adjust(pAd); +#endif + dynamic_ampdu_efficiency_adjust_all(pAd); + + if (pAd->CommonCfg.bRalinkBurstMode && pMacTable->fAllStationGainGoodMCS) + bRalinkBurstMode = TRUE; + else + bRalinkBurstMode = FALSE; + + if (bRdgActive != RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE)) { + /* DBDC not support yet, only using BAND_0 */ + } + + if (bRalinkBurstMode != RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RALINK_BURST_MODE)) + AsicSetRalinkBurstMode(pAd, bRalinkBurstMode); + +#endif /* DOT11_N_SUPPORT */ +#ifdef RTMP_MAC_PCI + RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); +#endif /* RTMP_MAC_PCI */ + + /* + 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. + */ + /* TODO: shiang-usw. revise this becasue now we have per-BSS McastPsQueue! */ + if (pMacTable->McastPsQueue.Head) { + UINT bss_index; + + pMacTable->PsQIdleCount++; + + if (pMacTable->PsQIdleCount > 1) { + APCleanupPsQueue(pAd, &pMacTable->McastPsQueue); + pMacTable->PsQIdleCount = 0; + + if (pAd->ApCfg.BssidNum > MAX_MBSSID_NUM(pAd)) + pAd->ApCfg.BssidNum = MAX_MBSSID_NUM(pAd); + + /* clear MCAST/BCAST backlog bit for all BSS */ + for (bss_index = BSS0; bss_index < pAd->ApCfg.BssidNum; bss_index++) + WLAN_MR_TIM_BCMC_CLEAR(bss_index); + } + } else + pMacTable->PsQIdleCount = 0; + +#ifdef RTMP_MAC_PCI + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); +#endif /* RTMP_MAC_PCI */ + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) + pAd->txop_ctl[BandIdx].multi_client_nums = 0; +} + + +UINT32 MacTableAssocStaNumGet(RTMP_ADAPTER *pAd) +{ + UINT32 num = 0; + UINT32 i; + + for (i = 1; VALID_UCAST_ENTRY_WCID(pAd, i); 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 RTMP_ADAPTER *pAd, + IN UCHAR *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_TO_REMOVE; /* 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 (IS_AKM_WPA_CAPABILITY_Entry(pEntry) + && (pEntry->SecConfig.Handshake.GTKState != REKEY_ESTABLISHED)) + *Rate = pAd->CommonCfg.MlmeRate; + else + *Rate = pEntry->CurrTxRate; + } else { + *Sst = SST_NOT_AUTH; + *Aid = MCAST_WCID_TO_REMOVE; + *PsMode = PWR_ACTIVE; + *Rate = pAd->CommonCfg.MlmeRate; + } + } + + return pEntry; +} + + +#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(RTMP_ADAPTER *pAd, UCHAR *pAddr, 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; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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(RTMP_ADAPTER *pAd, struct wifi_dev *wdev) +{ + BOOLEAN bNonGFExist = FALSE; + ADD_HT_INFO_IE *addht = NULL; + UINT32 new_protection = 0; + UCHAR op_mode = NON_PROTECT; + + if (wdev == NULL) + return; + + addht = wlan_operate_get_addht(wdev); + + /* non HT BSS exist within 5 sec */ + if ((pAd->ApCfg.LastNoneHTOLBCDetectTime + (5 * OS_HZ)) > pAd->Mlme.Now32 && + pAd->Mlme.Now32 != 0) { + op_mode = NONMEMBER_PROTECT; + bNonGFExist = TRUE; /* non-HT means nonGF support */ + new_protection = SET_PROTECT(NON_MEMBER_PROTECT); + } + + /* 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 ((op_mode == NON_PROTECT) && + (pAd->MacTab.fAnyStation20Only) && + (wlan_config_get_ht_bw(wdev) == HT_BW_40)) { + op_mode = BW20_PROTECT; + new_protection = SET_PROTECT(HT20_PROTECT); + } + + if (pAd->MacTab.fAnyStationIsLegacy) { + op_mode = NONHT_MM_PROTECT; + new_protection = SET_PROTECT(NON_HT_MIXMODE_PROTECT); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + (" --%s:\n OperationMode: %d, bNonGFExist: %d\n", + __func__, addht->AddHtInfo2.OperaionMode, bNonGFExist)); + + if ((op_mode != addht->AddHtInfo2.OperaionMode) + || (pAd->MacTab.fAnyStationNonGF != addht->AddHtInfo2.NonGfPresent)) { + addht->AddHtInfo2.OperaionMode = op_mode; + addht->AddHtInfo2.NonGfPresent = pAd->MacTab.fAnyStationNonGF; + + UpdateBeaconHandler(pAd, wdev, BCN_UPDATE_IE_CHG); + } + + if (bNonGFExist == FALSE) + bNonGFExist = pAd->MacTab.fAnyStationNonGF; + + if (bNonGFExist) + new_protection |= SET_PROTECT(GREEN_FIELD_PROTECT); + + if (nonerp_protection(&pAd->ApCfg.MBSSID[wdev->func_idx])) + new_protection |= SET_PROTECT(ERP); + + /*if no protect should enable for CTS-2-Self, WHQA_00025629*/ + if (MTK_REV_GTE(pAd, MT7615, MT7615E1) && MTK_REV_LT(pAd, MT7615, MT7615E3)) + if (pAd->CommonCfg.dbdc_mode && op_mode == NON_PROTECT) { + op_mode = BW20_PROTECT; + new_protection |= SET_PROTECT(HT20_PROTECT); + } + +#if defined(MT_MAC) + if (IS_HIF_TYPE(pAd, HIF_MT)) { + if ((new_protection & wdev->protection) != new_protection) { + wdev->protection = new_protection; + + AsicUpdateProtect(pAd); + } + + } +#endif +} +#endif /* DOT11_N_SUPPORT */ + + +/* + ========================================================================== + 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(RTMP_ADAPTER *pAd, UCHAR *pAddr, UCHAR Apidx) +{ + BOOLEAN Result = TRUE; + + if (Apidx >= HW_BEACON_MAX_NUM) + return FALSE; + + if (pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy == 0) /* ACL is disabled */ + Result = TRUE; + else { + ULONG i; + + if (pAd->ApCfg.MBSSID[Apidx].AccessControlList.Policy == 1) /* ACL is a positive list */ + Result = FALSE; + else /* ACL is a negative list */ + Result = TRUE; + + for (i = 0; i < pAd->ApCfg.MBSSID[Apidx].AccessControlList.Num; i++) { + if (MAC_ADDR_EQUAL(pAddr, pAd->ApCfg.MBSSID[Apidx].AccessControlList.Entry[i].Addr)) { + Result = !Result; + break; + } + } + } + + if (Result == FALSE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x failed in ACL checking\n", + PRINT_MAC(pAddr))); + } + + 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(RTMP_ADAPTER *pAd, UCHAR Apidx) +{ + USHORT AclIdx, MacIdx; + BOOLEAN Matched; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + HEADER_802_11 DisassocHdr; + USHORT Reason; + MAC_TABLE_ENTRY *pEntry; + BSS_STRUCT *pMbss; + BOOLEAN drop; + + ASSERT(Apidx < MAX_MBSSID_NUM(pAd)); + + if (Apidx >= MAX_MBSSID_NUM(pAd)) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ApUpdateAccessControlList : Apidx = %d\n", Apidx)); + /* ACL is disabled. Do nothing about the MAC table. */ + pMbss = &pAd->ApCfg.MBSSID[Apidx]; + + if (pMbss->AccessControlList.Policy == 0) + return; + + for (MacIdx = 0; VALID_UCAST_ENTRY_WCID(pAd, MacIdx); MacIdx++) { + pEntry = &pAd->MacTab.Content[MacIdx]; + + if (!IS_ENTRY_CLIENT(pEntry)) + continue; + + /* We only need to update associations related to ACL of MBSSID[Apidx]. */ + if (pEntry->func_tb_idx != Apidx) + continue; + + drop = FALSE; + Matched = FALSE; + + for (AclIdx = 0; AclIdx < pMbss->AccessControlList.Num; AclIdx++) { + if (MAC_ADDR_EQUAL(&pEntry->Addr[0], pMbss->AccessControlList.Entry[AclIdx].Addr)) { + Matched = TRUE; + break; + } + } + + if ((Matched == FALSE) && (pMbss->AccessControlList.Policy == 1)) { + drop = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("STA not on positive ACL. remove it...\n")); + } else if ((Matched == TRUE) && (pMbss->AccessControlList.Policy == 2)) { + drop = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("STA on negative ACL. remove it...\n")); + } + + if (drop == TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Apidx = %d\n", Apidx)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("pAd->ApCfg.MBSSID[%d].AccessControlList.Policy = %ld\n", Apidx, + pMbss->AccessControlList.Policy)); + + /* Before delete the entry from MacTable, send disassociation packet to client. */ + if (pEntry->Sst == SST_ASSOC) { + /* send out a DISASSOC frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, (" MlmeAllocateMemory fail ..\n")); + return; + } + + Reason = REASON_DECLINED; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ASSOC - Send DISASSOC Reason = %d frame TO %x %x %x %x %x %x\n", + Reason, PRINT_MAC(pEntry->Addr))); + MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, + pEntry->Addr, + pMbss->wdev.if_addr, + pMbss->wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DisassocHdr, 2, &Reason, END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + RtmpusecDelay(5000); + } + + mac_entry_delete(pAd, pEntry); + } + } +} + + +#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 struct wifi_dev *wdev, + IN BSS_COEX_CH_RANGE * pCoexChRange, + IN UCHAR Channel) +{ + INT index, cntrCh = 0; + UCHAR op_ext_cha = wlan_operate_get_ext_cha(wdev); + + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + + memset(pCoexChRange, 0, sizeof(BSS_COEX_CH_RANGE)); + /* Build the effected channel list, if something wrong, return directly. */ +#ifdef A_BAND_SUPPORT + + if (Channel > 14) { + /* For 5GHz band */ + for (index = 0; index < pChCtrl->ChListNum; index++) { + if (pChCtrl->ChList[index].Channel == Channel) + break; + } + + if (index < pChCtrl->ChListNum) { + /* First get the primary channel */ + pCoexChRange->primaryCh = pChCtrl->ChList[index].Channel; + + /* Now check about the secondary and central channel */ + if (op_ext_cha == 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; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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, + ((op_ext_cha == EXTCHA_ABOVE) ? "ABOVE" : "BELOW"), + pCoexChRange->primaryCh, pChCtrl->ChList[pCoexChRange->primaryCh].Channel, + pCoexChRange->secondaryCh, pChCtrl->ChList[pCoexChRange->secondaryCh].Channel, + pChCtrl->ChList[pCoexChRange->effectChStart].Channel, + pChCtrl->ChList[pCoexChRange->effectChEnd].Channel)); + return TRUE; + } + + /* It should not happened! */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("5GHz: Cannot found the CtrlCh(%d) in ChList, something wrong?\n", + Channel)); + } else +#endif /* A_BAND_SUPPORT */ + { /* For 2.4GHz band */ + for (index = 0; index < pChCtrl->ChListNum; index++) { + if (pChCtrl->ChList[index].Channel == Channel) + break; + } + + if (index < pChCtrl->ChListNum) { + /* First get the primary channel */ + pCoexChRange->primaryCh = index; + + /* Now check about the secondary and central channel */ + if (op_ext_cha == EXTCHA_ABOVE) { + if ((index + 4) < pChCtrl->ChListNum) { + 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); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("2.4GHz: 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, + ((op_ext_cha == EXTCHA_ABOVE) ? "ABOVE" : "BELOW"), + pCoexChRange->primaryCh, pChCtrl->ChList[pCoexChRange->primaryCh].Channel, + pCoexChRange->secondaryCh, pChCtrl->ChList[pCoexChRange->secondaryCh].Channel, + pChCtrl->ChList[pCoexChRange->effectChStart].Channel, + pChCtrl->ChList[pCoexChRange->effectChEnd].Channel)); + } + + return TRUE; + } + + /* It should not happened! */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("2.4GHz: Didn't found valid channel range, Ch index=%d, ChListNum=%d, CtrlCh=%d\n", + index, pChCtrl->ChListNum, Channel)); + } + + return FALSE; +} + + +VOID APOverlappingBSSScan(RTMP_ADAPTER *pAd, struct wifi_dev *wdev) +{ + BOOLEAN needFallBack = FALSE; + INT chStartIdx, chEndIdx, index, curPriChIdx, curSecChIdx; + BSS_COEX_CH_RANGE coexChRange; + UCHAR PhyMode = wdev->PhyMode; + UCHAR Channel = wdev->channel; + UCHAR ht_bw = wlan_operate_get_ht_bw(wdev); + UCHAR ext_cha = wlan_operate_get_ext_cha(wdev); + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + + if (!WMODE_CAP_2G(PhyMode)) + return; + + /* We just care BSS who operating in 40MHz N Mode. */ + if ((!WMODE_CAP_N(PhyMode)) || + (ht_bw == BW_20) + ) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("The wdev->PhyMode=%d, BW=%d, didn't need channel adjustment!\n", PhyMode, ht_bw)); + return; + } + + /* Build the effected channel list, if something wrong, return directly. */ + /* For 2.4GHz band */ + for (index = 0; index < pChCtrl->ChListNum; index++) { + if (pChCtrl->ChList[index].Channel == Channel) + break; + } + + if (index < pChCtrl->ChListNum) { + if (ext_cha == EXTCHA_ABOVE) { + curPriChIdx = index; + curSecChIdx = ((index + 4) < pChCtrl->ChListNum) ? (index + 4) : (pChCtrl->ChListNum - 1); + chStartIdx = (curPriChIdx >= 3) ? (curPriChIdx - 3) : 0; + chEndIdx = ((curSecChIdx + 3) < pChCtrl->ChListNum) ? (curSecChIdx + 3) : + (pChCtrl->ChListNum - 1); + } else { + curPriChIdx = index; + curSecChIdx = ((index - 4) >= 0) ? (index - 4) : 0; + chStartIdx = (curSecChIdx >= 3) ? (curSecChIdx - 3) : 0; + chEndIdx = ((curPriChIdx + 3) < pChCtrl->ChListNum) ? (curPriChIdx + 3) : + (pChCtrl->ChListNum - 1); + } + } else { + /* It should not happened! */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("2.4GHz: Cannot found the Control Channel(%d) in ChannelList, something wrong?\n", Channel)); + return; + } + + GetBssCoexEffectedChRange(pAd, wdev, &coexChRange, Channel); + + /* Before we do the scanning, clear the bEffectedChannel as zero for latter use. */ + for (index = 0; index < pChCtrl->ChListNum; index++) + pChCtrl->ChList[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) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Card still not enable Tx/Rx, enable it now!\n")); + RTMP_IRQ_ENABLE(pAd); + /* rtmp_rx_done_handle() 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); + } + + RTMPEnableRxTx(pAd); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Ready to do passive scanning for Channel[%d] to Channel[%d]!\n", + pChCtrl->ChList[chStartIdx].Channel, pChCtrl->ChList[chEndIdx].Channel)); + /* Now start to do the passive scanning. */ + pAd->CommonCfg.bOverlapScanning = TRUE; + + for (index = chStartIdx; index <= chEndIdx; index++) { + Channel = pChCtrl->ChList[index].Channel; + wlan_operate_scan(wdev, Channel); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("AP OBSS SYNC - BBP R4 to 20MHz.l\n")); + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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++) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Channel[Idx=%d, Ch=%d].bEffectedChannel=0x%x!\n", + index, pChCtrl->ChList[index].Channel, pChCtrl->ChList[index].bEffectedChannel)); + + if ((pChCtrl->ChList[index].bEffectedChannel & (EFFECTED_CH_PRIMARY | EFFECTED_CH_LEGACY)) && + (index != curPriChIdx)) { + needFallBack = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("needFallBack=TRUE due to OP/OT!\n")); + } + + if ((pChCtrl->ChList[index].bEffectedChannel & EFFECTED_CH_SECONDARY) && (index != curSecChIdx)) { + needFallBack = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("needFallBack=TRUE due to OS!\n")); + } + } + + /* If need fallback, now do it. */ + if ((needFallBack == TRUE) + && (pAd->CommonCfg.BssCoexApCnt > pAd->CommonCfg.BssCoexApCntThr) + ) { + wlan_operate_set_ht_bw(wdev, HT_BW_20, EXTCHA_NONE); + pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq = 1; + pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC; + } else { + /*restore to original channel*/ + wlan_operate_set_prim_ch(wdev, wdev->channel); + wlan_operate_set_ht_bw(wdev, ht_bw, ext_cha); + } +} +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +#define DBDC_AP_5G_PEAK_TP 610 +#define DBDC_AP_2G_PEAK_TP 270 +#define TP_100M_LOWER_BOUND 60 +#define TP_100M_UPPER_BOUND 120 +#define DBDC_PEAK_TP_PER_THRESHOLD 5 + +static VOID dynamic_ampdu_efficiency_adjust_all(struct _RTMP_ADAPTER *ad) +{ + EDCA_PARM *edcaparam; + ULONG per = 0; + ULONG tx_cnt; + COUNTER_802_11 *wlan_ct = NULL; + struct wifi_dev *wdev = NULL; + UINT16 level = TXOP_80, multi_client_num_th = 0, dbdc_peak_tp = 0; + UCHAR band_idx = 0; + + for (band_idx = 0; band_idx < DBDC_BAND_NUM; band_idx++) { + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[%s] BandIdx:%d\n", __func__, band_idx)); + + if (ad->peak_tp_ctl[band_idx].client_nums == 0) + goto ignore_ampdu_efficiency_check; + + wlan_ct = &ad->WlanCounters[band_idx]; + wdev = ad->peak_tp_ctl[band_idx].cur_wdev; + tx_cnt = wlan_ct->AmpduSuccessCount.u.LowPart; + + if (WMODE_CAP_2G(wdev->PhyMode)) { + multi_client_num_th = MULTI_CLIENT_2G_NUMS_TH; + dbdc_peak_tp = DBDC_AP_2G_PEAK_TP; + } else if (WMODE_CAP_5G(wdev->PhyMode)) { + multi_client_num_th = MULTI_CLIENT_NUMS_TH; + dbdc_peak_tp = DBDC_AP_5G_PEAK_TP; + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s[%d]\n", __func__, __LINE__)); + continue; + } + + if (ad->txop_ctl[band_idx].multi_client_nums == multi_client_num_th) { + /* do no apply patch, it is in veriwave multi-client case */ + goto ignore_ampdu_efficiency_check; + } + + if (tx_cnt > 0) + per = 100 * (wlan_ct->AmpduFailCount.u.LowPart) / (wlan_ct->AmpduFailCount.u.LowPart + tx_cnt); + + if (per >= DBDC_PEAK_TP_PER_THRESHOLD) { + /* do no apply patch, it is in noise environment */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s[%d]per=%lu\n", __func__, __LINE__, per)); + goto ignore_ampdu_efficiency_check; + } + + /* scenario detection */ + if ((ad->CommonCfg.dbdc_mode) && + (ad->peak_tp_ctl[band_idx].max_tx_tp > dbdc_peak_tp)) { + ad->peak_tp_ctl[band_idx].cli_peak_tp_running = 1; + level = TXOP_FE; + + if (level != ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_level) + ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_enable = FALSE; + } else if ((ad->peak_tp_ctl[band_idx].max_tx_tp > TP_100M_LOWER_BOUND) && + (ad->peak_tp_ctl[band_idx].max_tx_tp < TP_100M_UPPER_BOUND)) { + ad->peak_tp_ctl[band_idx].cli_peak_tp_running = 1; + level = TXOP_60; + + if (level != ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_level) + ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_enable = FALSE; + } else + ad->peak_tp_ctl[band_idx].cli_peak_tp_running = 0; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s[%d]per=%lu, tx=%d M, (%d, %d, %d)\n\r", + __func__, __LINE__, per, ad->peak_tp_ctl[band_idx].max_tx_tp, + ad->peak_tp_ctl[band_idx].cli_peak_tp_running, + ad->peak_tp_ctl[band_idx].cli_ampdu_efficiency_running, + ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_enable)); + + /* increase ampdu efficiency if running peak T.P */ + if (ad->peak_tp_ctl[band_idx].cli_peak_tp_running) { + if (!ad->peak_tp_ctl[band_idx].cli_ampdu_efficiency_running) { + if (query_tx_burst_prio(ad, wdev) <= PRIO_PEAK_TP) { + AsicAmpduEfficiencyAdjust(wdev, 0xf); + ad->peak_tp_ctl[band_idx].cli_ampdu_efficiency_running = TRUE; + } + } + + if (!ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_enable) { + enable_tx_burst(ad, wdev, AC_BE, PRIO_PEAK_TP, level); + ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_level = level; + ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_enable = TRUE; + } + } else { + /* restore to original */ + if (ad->peak_tp_ctl[band_idx].cli_ampdu_efficiency_running) { + edcaparam = HcGetEdca(ad, wdev); + + if (edcaparam) + AsicAmpduEfficiencyAdjust(wdev, edcaparam->Aifsn[0]); + + ad->peak_tp_ctl[band_idx].cli_ampdu_efficiency_running = FALSE; + } + + if (ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_enable) { + disable_tx_burst(ad, wdev, AC_BE, PRIO_PEAK_TP, level); + ad->peak_tp_ctl[band_idx].cli_peak_tp_txop_enable = FALSE; + } + } + +ignore_ampdu_efficiency_check: + + /* restore aifs adjust since dynamic txop owner is not peak throughput */ + if (ad->peak_tp_ctl[band_idx].cli_ampdu_efficiency_running) { + if (query_tx_burst_prio(ad, wdev) > PRIO_PEAK_TP) { + edcaparam = HcGetEdca(ad, wdev); + + if (edcaparam) + AsicAmpduEfficiencyAdjust(wdev, edcaparam->Aifsn[0]); + + ad->peak_tp_ctl[band_idx].cli_ampdu_efficiency_running = FALSE; + } + } + + /* clear some record */ + ad->peak_tp_ctl[band_idx].client_nums = 0; + ad->peak_tp_ctl[band_idx].max_tx_tp = 0; + } +} + +#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}; +#ifdef RADIUS_ACCOUNTING_SUPPORT + DOT1X_QUERY_STA_DATA data; +#define FRAME_BUF_LEN (LENGTH_802_3 + sizeof(RalinkIe) + VLAN_HDR_LEN + sizeof(DOT1X_QUERY_STA_DATA)) +#else +#define FRAME_BUF_LEN (LENGTH_802_3 + sizeof(RalinkIe) + VLAN_HDR_LEN) +#endif /*RADIUS_ACCOUNTING_SUPPORT*/ + UINT8 frame_len = 0; + UCHAR FrameBuf[FRAME_BUF_LEN]; + UINT8 offset = 0; + USHORT bss_Vlan_Priority = 0; + USHORT bss_Vlan; + USHORT TCI; + /* Init the frame buffer */ + NdisZeroMemory(FrameBuf, frame_len); +#ifdef RADIUS_ACCOUNTING_SUPPORT + NdisMoveMemory(data.StaAddr, pEntry->Addr, MAC_ADDR_LEN); + data.rx_bytes = pEntry->RxBytes; + data.tx_bytes = pEntry->TxBytes; + data.rx_packets = pEntry->RxPackets.u.LowPart; + data.tx_packets = pEntry->TxPackets.u.LowPart; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s::rx_byte:%lu tx_byte:%lu rx_pkt:%lu tx_pkt:%lu\n", + __func__, data.rx_bytes, data.tx_bytes, data.rx_packets, data.rx_packets)); +#endif /* RADIUS_ACCOUNTING_SUPPORT */ + + if (pEntry) { + apidx = pEntry->func_tb_idx; + NdisMoveMemory(s_addr, pEntry->Addr, MAC_ADDR_LEN); + } else { + /* Fake a Source Address for transmission */ + NdisMoveMemory(s_addr, pAd->ApCfg.MBSSID[apidx].wdev.bssid, MAC_ADDR_LEN); + s_addr[0] |= 0x80; + } + + /* Assign internal command for Ralink dot1x daemon */ + RalinkIe[5] = cmd; + + if (pAd->ApCfg.MBSSID[apidx].wdev.VLAN_VID) { + bss_Vlan = pAd->ApCfg.MBSSID[apidx].wdev.VLAN_VID; + bss_Vlan_Priority = pAd->ApCfg.MBSSID[apidx].wdev.VLAN_Priority; + frame_len = FRAME_BUF_LEN; + MAKE_802_3_HEADER(FrameBuf, pAd->ApCfg.MBSSID[apidx].wdev.bssid, s_addr, EAPOL_IE); + offset += LENGTH_802_3 - 2; + NdisMoveMemory((FrameBuf + offset), TPID, 2); + offset += 2; + TCI = (bss_Vlan & 0x0FFF) | ((bss_Vlan_Priority & 0x7) << 13); +#ifndef RT_BIG_ENDIAN + TCI = SWAP16(TCI); +#endif + *(USHORT *)(FrameBuf + offset) = TCI; + offset += 2; + NdisMoveMemory((FrameBuf + offset), EAPOL_IE, 2); + offset += 2; + } else { + frame_len = FRAME_BUF_LEN - VLAN_HDR_LEN; + /* Prepare the 802.3 header */ + MAKE_802_3_HEADER(FrameBuf, + pAd->ApCfg.MBSSID[apidx].wdev.bssid, + s_addr, + EAPOL_IE); + offset += LENGTH_802_3; + } + + /* Prepare the specific header of internal command */ + NdisMoveMemory(&FrameBuf[offset], RalinkIe, sizeof(RalinkIe)); +#ifdef RADIUS_ACCOUNTING_SUPPORT + offset += sizeof(RalinkIe); + /*add accounting info*/ + NdisMoveMemory(&FrameBuf[offset], (unsigned char *)&data, sizeof(DOT1X_QUERY_STA_DATA)); +#endif /*RADIUS_ACCOUNTING_SUPPORT*/ + + /* Report to upper layer */ + if (RTMP_L2_FRAME_TX_ACTION(pAd, apidx, FrameBuf, frame_len) == FALSE) + return FALSE; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s done. (cmd=%d)\n", __func__, 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(RTMP_ADAPTER *pAd, MAC_TABLE_ENTRY *pEntry) +{ + /* TODO: shiang-usw, fix me for pEntry->apidx to func_tb_idx */ + 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 + 32]; + UINT8 offset = 0; + USHORT bss_Vlan_Priority = 0; + USHORT bss_Vlan; + USHORT TCI; + + if (IS_AKM_1X_Entry(pEntry) || IS_IEEE8021X_Entry(&pAd->ApCfg.MBSSID[apidx].wdev)) { + /* Init the frame buffer */ + NdisZeroMemory(FrameBuf, frame_len); + /* Assign apidx */ + apidx = pEntry->func_tb_idx; + + if (pAd->ApCfg.MBSSID[apidx].wdev.VLAN_VID) { + /*Prepare 802.3 header including VLAN tag*/ + bss_Vlan = pAd->ApCfg.MBSSID[apidx].wdev.VLAN_VID; + bss_Vlan_Priority = pAd->ApCfg.MBSSID[apidx].wdev.VLAN_Priority; + frame_len += VLAN_HDR_LEN; + MAKE_802_3_HEADER(FrameBuf, pAd->ApCfg.MBSSID[apidx].wdev.bssid, pEntry->Addr, EAPOL) + offset += LENGTH_802_3 - 2; + NdisMoveMemory((FrameBuf + offset), TPID, 2); + offset += 2; + TCI = (bss_Vlan & 0x0fff) | ((bss_Vlan_Priority & 0x7) << 13); +#ifndef RT_BIG_ENDIAN + TCI = SWAP16(TCI); +#endif + *(USHORT *)(FrameBuf + offset) = TCI; + offset += 2; + NdisMoveMemory((FrameBuf + offset), EAPOL, 2); + offset += 2; + } else { + /* Prepare the 802.3 header */ + MAKE_802_3_HEADER(FrameBuf, pAd->ApCfg.MBSSID[apidx].wdev.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)); +#ifdef CONFIG_HOTSPOT_R2 + + if (pEntry) { + BSS_STRUCT *pMbss = pEntry->pMbss; + + if ((pMbss->HotSpotCtrl.HotSpotEnable == 1) && (IS_AKM_WPA2_Entry(&pMbss->wdev)) && + (pEntry->hs_info.ppsmo_exist == 1)) { + UCHAR HS2_Header[4] = {0x50, 0x6f, 0x9a, 0x12}; + + memcpy(&FrameBuf[offset + sizeof(eapol_start_1x_hdr)], HS2_Header, 4); + memcpy(&FrameBuf[offset + sizeof(eapol_start_1x_hdr) + 4], &pEntry->hs_info, sizeof(struct _sta_hs_info)); + frame_len += 4 + sizeof(struct _sta_hs_info); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("DOT1X_EapTriggerAction: event eapol start, %x:%x:%x:%x\n", + FrameBuf[offset + sizeof(eapol_start_1x_hdr) + 4], FrameBuf[offset + sizeof(eapol_start_1x_hdr) + 5], + FrameBuf[offset + sizeof(eapol_start_1x_hdr) + 6], FrameBuf[offset + sizeof(eapol_start_1x_hdr) + 7])); + } + } + +#endif + + /* Report to upper layer */ + if (RTMP_L2_FRAME_TX_ACTION(pAd, apidx, FrameBuf, frame_len) == FALSE) + return FALSE; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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 */ + + +INT rtmp_ap_init(RTMP_ADAPTER *pAd) +{ +#ifdef WSC_AP_SUPPORT + UCHAR j; + BSS_STRUCT *mbss = NULL; + struct wifi_dev *wdev = NULL; + PWSC_CTRL pWscControl; + + for (j = BSS0; j < pAd->ApCfg.BssidNum; j++) { + mbss = &pAd->ApCfg.MBSSID[j]; + wdev = &pAd->ApCfg.MBSSID[j].wdev; + { + pWscControl = &wdev->WscControl; + pWscControl->WscRxBufLen = 0; + pWscControl->pWscRxBuf = NULL; + os_alloc_mem(pAd, &pWscControl->pWscRxBuf, MAX_MGMT_PKT_LEN); + + if (pWscControl->pWscRxBuf) + NdisZeroMemory(pWscControl->pWscRxBuf, MAX_MGMT_PKT_LEN); + + pWscControl->WscTxBufLen = 0; + pWscControl->pWscTxBuf = NULL; + os_alloc_mem(pAd, &pWscControl->pWscTxBuf, MAX_MGMT_PKT_LEN); + + if (pWscControl->pWscTxBuf) + NdisZeroMemory(pWscControl->pWscTxBuf, MAX_MGMT_PKT_LEN); + } + } + +#endif /* WSC_AP_SUPPORT */ + APOneShotSettingInitialize(pAd); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("apstart up %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pAd->CurrentAddress))); + APInitForMain(pAd); + + /* Set up the Mac address*/ + RtmpOSNetDevAddrSet(pAd->OpMode, pAd->net_dev, &pAd->CurrentAddress[0], NULL); + /* ap_func_init(pAd); */ + + if (IS_HIF_TYPE(pAd, HIF_MT)) { + /* Now Enable MacRxTx*/ + RTMP_IRQ_ENABLE(pAd); + RTMPEnableRxTx(pAd); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); + } + +#ifdef CFG_SUPPORT_MU_MIMO_RA + /*Send In-Band Command to N9 about Platform Type 7621/7623*/ + SetMuraPlatformTypeProc(pAd); +#endif +#ifdef MT_FDB + fdb_enable(pAd); +#endif /* MT_FDB */ + return NDIS_STATUS_SUCCESS; +} + + +VOID rtmp_ap_exit(RTMP_ADAPTER *pAd) +{ + BOOLEAN Cancelled; + + RTMPReleaseTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled); +#ifdef IDS_SUPPORT + /* Init intrusion detection timer */ + RTMPReleaseTimer(&pAd->ApCfg.IDSTimer, &Cancelled); +#endif /* IDS_SUPPORT */ +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + RTMP_11N_D3_TimerRelease(pAd); +#endif /*DOT11N_DRAFT3*/ +#endif /*DOT11_N_SUPPORT*/ + /* Free BssTab & ChannelInfo tabbles.*/ + AutoChBssTableDestroy(pAd); + ChannelInfoDestroy(pAd); +#ifdef IGMP_SNOOP_SUPPORT + MultiCastFilterTableReset(pAd, &pAd->pMulticastFilterTable); +#endif /* IGMP_SNOOP_SUPPORT */ +} + +/* +* system security decision for ap mode +*/ +UINT32 starec_ap_feature_decision(struct wifi_dev *wdev, struct _MAC_TABLE_ENTRY *entry, UINT32 *feature) +{ + struct _RTMP_ADAPTER *ad = (struct _RTMP_ADAPTER *) wdev->sys_handle; + UINT32 features = 0; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(ad->hdev_ctrl); + + if (cap->APPSMode == APPS_MODE2) + features |= STA_REC_AP_PS_FEATURE; + + /*temport used for security will integrate to CMD*/ + if (IS_CIPHER_WEP(entry->SecConfig.PairwiseCipher)) + features |= STA_REC_INSTALL_KEY_FEATURE; + + /*return value, must use or operation*/ + *feature |= features; + return TRUE; +} + + +/*system for ap mode*/ +/* +* +*/ +INT ap_link_up(struct wifi_dev *wdev, struct _MAC_TABLE_ENTRY *entry) +{ + if (WDEV_BSS_STATE(wdev) == BSS_INIT) { + wifi_sys_linkup(wdev, NULL); + APStartRekeyTimer(wdev->sys_handle, wdev); + } + + OPSTATUS_SET_FLAG_WDEV(wdev, fOP_AP_STATUS_MEDIA_STATE_CONNECTED); + return TRUE; +} + +/* +* +*/ +INT ap_link_down(struct wifi_dev *wdev) +{ + APStopRekeyTimer(wdev->sys_handle, wdev); + + if (WDEV_BSS_STATE(wdev) >= BSS_INITED) { + /* kick out all stas behind the Bss */ + MbssKickOutStas(wdev->sys_handle, wdev->func_idx, REASON_DISASSOC_INACTIVE); + UpdateBeaconHandler( + wdev->sys_handle, + wdev, + BCN_UPDATE_DISABLE_TX); + + /*linkdown bssinfo*/ + if (wifi_sys_linkdown(wdev) != TRUE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(): linkdown fail!\n", __func__)); + return FALSE; + } + } + + return TRUE; +} + +/* +* +*/ +INT ap_conn_act(struct wifi_dev *wdev, struct _MAC_TABLE_ENTRY *entry) +{ + struct _RTMP_ADAPTER *ad = (struct _RTMP_ADAPTER *)wdev->sys_handle; + + /*generic connection action*/ + if (wifi_sys_conn_act(wdev, entry) != TRUE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(): connect action fail!\n", __func__)); + } + +#if defined(MT7615) || defined(MT7637) || defined(MT7622) || defined(P18) || defined(MT7663) + + if (IS_MT7615(ad) || IS_MT7637(ad) || IS_MT7622(ad) || IS_P18(ad) || IS_MT7663(ad)) + RAInit(ad, entry); + +#endif /* defined(MT7615) || defined(MT7637) || defined(MT7622) */ +#if defined(MT_DFS_SUPPORT) && defined(BACKGROUND_SCAN_SUPPORT) && defined(TXBF_SUPPORT) && defined(MT7615) + + /* Disable TXBF apply for DFS zero wait start */ + if ((ad->BgndScanCtrl.BgndScanStatMachine.CurrState == BGND_RDD_DETEC) + && IS_SUPPORT_MT_ZEROWAIT_DFS(ad)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[%s][ZeroWait]In CAC period, Disable TXBF Apply\n", __func__)); + HW_AP_TXBF_TX_APPLY(ad, FALSE); + } + +#endif + return TRUE; +} + +/* +* +*/ +INT ap_inf_open(struct wifi_dev *wdev) +{ + struct _RTMP_ADAPTER *pAd = (struct _RTMP_ADAPTER *)wdev->sys_handle; +#ifdef BACKGROUND_SCAN_SUPPORT + UINT32 CrValue; +#endif /* BACKGROUND_SCAN_SUPPORT */ + + +#ifdef GREENAP_SUPPORT + /* This function will check and update allow status */ + if (greenap_check_when_if_down_up(pAd) == FALSE) + return FALSE; +#endif /* GREENAP_SUPPORT */ + + if (wifi_sys_open(wdev) != TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() open fail!!!\n", __func__)); + return FALSE; + } + + MTWF_LOG(DBG_CAT_INIT, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP inf up for ra_%x(func_idx) OmacIdx=%d\n", + wdev->func_idx, wdev->OmacIdx)); + + MlmeRadioOn(pAd, wdev); + + /* action for ap interface up */ + pAd->ApCfg.MBSSID[wdev->func_idx].mbss_idx = wdev->func_idx; + wdev->bAllowBeaconing = TRUE; + ap_run_at_boot(pAd, wdev); +#ifdef BACKGROUND_SCAN_SUPPORT + BackgroundScanInit(pAd); + /* Enable band0 IPI SW control */ + HW_IO_READ32(pAd, PHY_RXTD_12, &CrValue); + CrValue |= (1 << B0IrpiSwCtrlResetOffset); + CrValue |= (1 << B0IrpiSwCtrlOnlyOffset); + HW_IO_WRITE32(pAd, PHY_RXTD_12, CrValue); + HW_IO_WRITE32(pAd, PHY_RXTD_12, CrValue); + /* Enable badn0 IPI control */ + HW_IO_READ32(pAd, PHY_BAND0_PHYMUX_5, &CrValue); + CrValue |= (B0IpiEnableCtrlValue << B0IpiEnableCtrlOffset); + HW_IO_WRITE32(pAd, PHY_BAND0_PHYMUX_5, CrValue); +#endif /* BACKGROUND_SCAN_SUPPORT */ + APStartUpForMbss(pAd, &pAd->ApCfg.MBSSID[wdev->func_idx]); + +#ifdef WSC_INCLUDED + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("apidx %d for WscUUIDInit\n", wdev->func_idx)); + WscUUIDInit(pAd, wdev->func_idx, FALSE); +#endif /* WSC_INCLUDED */ + + + return TRUE; +} + +/* +* +*/ +INT ap_inf_close(struct wifi_dev *wdev) +{ + struct _RTMP_ADAPTER *pAd = (struct _RTMP_ADAPTER *)wdev->sys_handle; + + + if (pAd == NULL) + return FALSE; + +#ifdef GREENAP_SUPPORT + /* This function will check and update allow status */ + if (greenap_check_when_if_down_up(pAd) == FALSE) + return FALSE; +#endif /* GREENAP_SUPPORT */ + + /* Move orig RTMPInfClose here */ + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + wdev->bAllowBeaconing = FALSE; + + if (wdev_do_linkdown(wdev) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() linkdown fail!!!\n", __func__)); + + if (wifi_sys_close(wdev) != TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() close fail!!!\n", __func__)); + return FALSE; + } + +#ifdef BAND_STEERING + if (pAd->ApCfg.BandSteering) { + PBND_STRG_CLI_TABLE table; + + table = Get_BndStrgTable(pAd, BSS0); + if (table) { + /* Inform daemon interface down */ + BndStrg_SetInfFlags(pAd, wdev, table, FALSE); + } + } +#endif /* BAND_STEERING */ + } + + + return TRUE; +} + +BOOLEAN media_state_connected(struct wifi_dev *wdev) +{ + struct _RTMP_ADAPTER *ad; + + ad = (struct _RTMP_ADAPTER *)wdev->sys_handle; + return (OPSTATUS_TEST_FLAG(ad, fOP_STATUS_MEDIA_STATE_CONNECTED) + && OPSTATUS_TEST_FLAG(ad, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)); +} + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_apcli.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_apcli.c new file mode 100644 index 000000000..aed258bd6 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_apcli.c @@ -0,0 +1,4657 @@ +/* + *************************************************************************** + * 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 + + 4. ApCli index (0) of different tx packet is assigned in + + 5. ApCli index (0) of different interface is got in tx_pkt_handle() by using + + 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" +#ifdef ROAMING_ENHANCE_SUPPORT +#include +#endif /* ROAMING_ENHANCE_SUPPORT */ + +#ifdef DOT11_VHT_AC +#ifdef APCLI_CERT_SUPPORT +extern UINT16 vht_max_mpdu_size[]; +#endif +#endif /* DOT11_VHT_AC */ +#ifdef MAC_REPEATER_SUPPORT +VOID ReptWaitLinkDown(struct _REPEATER_CLIENT_ENTRY *pReptEntry); +#endif /*MAC_REPEATER_SUPPORT*/ + + + +BOOLEAN ApCliWaitProbRsp(PRTMP_ADAPTER pAd, USHORT ifIndex) +{ + if (ifIndex >= MAX_APCLI_NUM) + return FALSE; + + return (pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState == APCLI_JOIN_WAIT_PROBE_RSP) ? + TRUE : FALSE; +} + +VOID ApCliSimulateRecvBeacon(RTMP_ADAPTER *pAd) +{ + INT loop; + ULONG Now32, BPtoJiffies; + PAPCLI_STRUCT pApCliEntry = NULL; + LONG timeDiff; + + NdisGetSystemUpTime(&Now32); + + for (loop = 0; loop < MAX_APCLI_NUM; loop++) { + pApCliEntry = &pAd->ApCfg.ApCliTab[loop]; + + if ((pApCliEntry->Valid == TRUE) && (VALID_UCAST_ENTRY_WCID(pAd, pApCliEntry->MacTabWCID))) { + /* + When we are connected and do the scan progress, it's very possible we cannot receive + the beacon of the AP. So, here we simulate that we received the beacon. + */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) && + (RTMP_TIME_AFTER(pAd->Mlme.Now32, pApCliEntry->ApCliRcvBeaconTime + (1 * OS_HZ)))) { + BPtoJiffies = (((pApCliEntry->ApCliBeaconPeriod * 1024 / 1000) * OS_HZ) / 1000); + timeDiff = (pAd->Mlme.Now32 - pApCliEntry->ApCliRcvBeaconTime) / BPtoJiffies; + + if (timeDiff > 0) + pApCliEntry->ApCliRcvBeaconTime += (timeDiff * BPtoJiffies); + + if (RTMP_TIME_AFTER(pApCliEntry->ApCliRcvBeaconTime, pAd->Mlme.Now32)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("MMCHK - APCli BeaconRxTime adjust wrong(BeaconRx=0x%lx, Now=0x%lx)\n", + pApCliEntry->ApCliRcvBeaconTime, pAd->Mlme.Now32)); + } + } + + /* update channel quality for Roaming and UI LinkQuality display */ + MlmeCalculateChannelQuality(pAd, &pAd->MacTab.Content[pApCliEntry->MacTabWCID], Now32); + } + } +} + + +/* +* Synchronized function +*/ + +static VOID ApCliCompleteInit(APCLI_STRUCT *pApCliEntry) +{ + RTMP_OS_INIT_COMPLETION(&pApCliEntry->ifdown_complete); + RTMP_OS_INIT_COMPLETION(&pApCliEntry->linkdown_complete); +} + +static VOID ApCliLinkDownComplete(APCLI_STRUCT *pApCliEntry) +{ + RTMP_OS_COMPLETE(&pApCliEntry->linkdown_complete); +} + +static VOID ApCliWaitLinkDown(APCLI_STRUCT *pApCliEntry) +{ + if (pApCliEntry->Valid && !RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&pApCliEntry->linkdown_complete, APCLI_WAIT_TIMEOUT)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("(%s) ApCli [%d] can't done.\n", __func__, pApCliEntry->wdev.func_idx)); + } +} + +static VOID ApCliWaitStateDisconnect(APCLI_STRUCT *pApCliEntry) +{ + /* + * Before doing wdev_do_close,we have to make sure the ctrl + * state machine has switched to APCLI_CTRL_DISCONNECTED + */ + int wait_cnt = 0; + int wait_times = 50; + int delay_time = 100; + + while (pApCliEntry->CtrlCurrState != APCLI_CTRL_DISCONNECTED) { + if (wait_cnt >= wait_times) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("Need to debug apcli ctrl state machine(Ctrl State=%lu)\n\r", pApCliEntry->CtrlCurrState)); + break; + } + + OS_WAIT(delay_time); + wait_cnt++; + } +} + + +static VOID ApCliIfDownComplete(APCLI_STRUCT *pApCliEntry) +{ + RTMP_OS_COMPLETE(&pApCliEntry->ifdown_complete); +} + +static VOID ApCliWaitIfDown(APCLI_STRUCT *pApCliEntry) +{ + if (pApCliEntry->Valid && + !RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&pApCliEntry->ifdown_complete, APCLI_WAIT_TIMEOUT)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("%s: wait ApCli [%d] interface down faild!!\n", __func__, pApCliEntry->wdev.func_idx)); + } +} + + + +/* +======================================================================== +Routine Description: + Close ApCli network interface. + +Arguments: + ad_p points to our adapter + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28xx_ApCli_Close(RTMP_ADAPTER *ad_p) +{ + UINT index; + + for (index = 0; index < MAX_APCLI_NUM; index++) { + if (ad_p->ApCfg.ApCliTab[index].wdev.if_dev) + RtmpOSNetDevClose(ad_p->ApCfg.ApCliTab[index].wdev.if_dev); + } + +} + + +/* --------------------------------- Private -------------------------------- */ +INT ApCliIfLookUp(RTMP_ADAPTER *pAd, UCHAR *pAddr) +{ + SHORT if_idx; + + for (if_idx = 0; if_idx < MAX_APCLI_NUM; if_idx++) { + if (MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[if_idx].wdev.if_addr, pAddr)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s():ApCliIfIndex=%d\n", + __func__, if_idx)); + return if_idx; + } + } + + return -1; +} + + +BOOLEAN isValidApCliIf(SHORT if_idx) +{ + return (((if_idx >= 0) && (if_idx < MAX_APCLI_NUM)) ? TRUE : 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 RTMP_ADAPTER *pAd, + INOUT HEADER_802_11 * pHdr80211, + IN UCHAR SubType, + IN UCHAR ToDs, + IN UCHAR *pDA, + IN UCHAR *pBssid, + IN USHORT ifIndex) +{ + NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11)); + pHdr80211->FC.Type = FC_TYPE_MGMT; + pHdr80211->FC.SubType = SubType; + pHdr80211->FC.ToDs = ToDs; + COPY_MAC_ADDR(pHdr80211->Addr1, pDA); + COPY_MAC_ADDR(pHdr80211->Addr2, pAd->ApCfg.ApCliTab[ifIndex].wdev.if_addr); + 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) +{ + APCLI_STRUCT *pApCliEntry = NULL; + HT_CAPABILITY_IE *aux_ht_cap; + HT_CAPABILITY_IE *curr_ht_cap; + struct wifi_dev *wdev; + UCHAR cfg_ht_bw; + UCHAR op_ext_cha; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + if (IfIndex >= MAX_APCLI_NUM) + return FALSE; + + pApCliEntry = &pAd->ApCfg.ApCliTab[IfIndex]; + wdev = &pApCliEntry->wdev; + cfg_ht_bw = wlan_config_get_ht_bw(wdev); + op_ext_cha = wlan_operate_get_ext_cha(wdev); + curr_ht_cap = (HT_CAPABILITY_IE *)wlan_operate_get_ht_cap(wdev); + aux_ht_cap = &pApCliEntry->MlmeAux.HtCapability; + aux_ht_cap->MCSSet[0] = 0xff; + + /* For 20MHz bandwidth, setting MCS 32 bit is not required */ + if (cfg_ht_bw != HT_BW_20) + aux_ht_cap->MCSSet[4] = 0x1; + + switch (wlan_operate_get_rx_stream(wdev)) { + 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; + + case 4: + aux_ht_cap->MCSSet[0] = 0xff; + aux_ht_cap->MCSSet[1] = 0xff; + aux_ht_cap->MCSSet[2] = 0xff; + aux_ht_cap->MCSSet[3] = 0xff; + break; + } + + aux_ht_cap->MCSSet[0] &= pHtCapability->MCSSet[0]; + aux_ht_cap->MCSSet[1] &= pHtCapability->MCSSet[1]; + aux_ht_cap->MCSSet[2] &= pHtCapability->MCSSet[2]; + aux_ht_cap->MCSSet[3] &= pHtCapability->MCSSet[3]; + /* Record the RxMcs of AP */ + NdisMoveMemory(pApCliEntry->RxMcsSet, pHtCapability->MCSSet, 16); + /* choose smaller setting */ +#ifdef CONFIG_MULTI_CHANNEL + aux_ht_cap->HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth; +#else /* CONFIG_MULTI_CHANNEL */ + aux_ht_cap->HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & cfg_ht_bw; +#endif /* !CONFIG_MULTI_CHANNEL */ + + /* it should go back to bw 20 if extension channel is different with root ap */ + if (op_ext_cha != pAddHtInfo->AddHtInfo.ExtChanOffset) { + if (pApCliEntry->wdev.channel > 14) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("ApCliCheckHt : channel=%u, my extcha=%u, root ap extcha=%u, inconsistent!!\n", + pApCliEntry->wdev.channel, op_ext_cha, pAddHtInfo->AddHtInfo.ExtChanOffset)); + } + + aux_ht_cap->HtCapInfo.ChannelWidth = BW_20; + wlan_operate_set_ht_bw(wdev, HT_BW_20, EXTCHA_NONE); + } else + wlan_operate_set_ht_bw(wdev, pAddHtInfo->AddHtInfo.RecomWidth, pAddHtInfo->AddHtInfo.ExtChanOffset); + + /* If selcected BW of APCLI is changed to 20MHZ, reset MCS 32 bit */ + if (aux_ht_cap->HtCapInfo.ChannelWidth == BW_20) { + aux_ht_cap->MCSSet[4] = 0x0; + } + + aux_ht_cap->HtCapInfo.GF = pHtCapability->HtCapInfo.GF & curr_ht_cap->HtCapInfo.GF; +#ifdef CONFIG_MULTI_CHANNEL /* APCLI's bw , Central , channel */ + + if (RTMP_CFG80211_VIF_P2P_CLI_ON(pAd)) { + UCHAR ht_bw = aux_ht_cap->HtCapInfo.ChannelWidth; + UCHAR ext_cha; + UCHAR cen_ch; + + if (ht_bw == HT_BW_20) { + pApCliEntry->wdev.channel = pAddHtInfo->ControlChan; + ext_cha = EXTCHA_NONE; + } else if (ht_bw == HT_BW_40) { + pApCliEntry->wdev.channel = pAddHtInfo->ControlChan; + + if (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) + ext_cha = EXTCHA_ABOVE; + else if (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) + ext_cha = EXTCHA_BELOW; + else /* EXTCHA_NONE , should not be here!*/ + ext_cha = EXTCHA_NONE; + } + wlan_operate_set_ht_bw(wdev, ht_bw, ext_cha); + cen_ch = wlan_operate_get_cen_ch_1(wdev); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("ApCliCheckHt : channel=%u, CentralChannel=%u, bw=%u\n", + wdev->channel, cen_ch, ht_bw)); + } + +#endif /* CONFIG_MULTI_CHANNEL */ + /* Send Assoc Req with my HT capability. */ + aux_ht_cap->HtCapInfo.AMsduSize = curr_ht_cap->HtCapInfo.AMsduSize; + aux_ht_cap->HtCapInfo.MimoPs = pHtCapability->HtCapInfo.MimoPs; + aux_ht_cap->HtCapInfo.ShortGIfor20 = + (curr_ht_cap->HtCapInfo.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20); + aux_ht_cap->HtCapInfo.ShortGIfor40 = + (curr_ht_cap->HtCapInfo.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40); + aux_ht_cap->HtCapInfo.TxSTBC = (curr_ht_cap->HtCapInfo.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC); + aux_ht_cap->HtCapInfo.RxSTBC = (curr_ht_cap->HtCapInfo.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC); + + /* Fix throughput issue for some vendor AP with AES mode */ + if (pAddHtInfo->AddHtInfo.RecomWidth & cfg_ht_bw) + aux_ht_cap->HtCapInfo.CCKmodein40 = pHtCapability->HtCapInfo.CCKmodein40; + else + aux_ht_cap->HtCapInfo.CCKmodein40 = 0; + + aux_ht_cap->HtCapParm.MaxRAmpduFactor = curr_ht_cap->HtCapParm.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; + + if (wlan_config_get_ht_ldpc(wdev) && (cap->phy_caps & fPHY_CAP_LDPC)) + aux_ht_cap->HtCapInfo.ht_rx_ldpc = pHtCapability->HtCapInfo.ht_rx_ldpc; + else + aux_ht_cap->HtCapInfo.ht_rx_ldpc = 0; + + aux_ht_cap->TxBFCap = pHtCapability->TxBFCap; + + /*COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability); */ + return TRUE; +} +#endif /* DOT11_N_SUPPORT */ + + +#ifdef APCLI_CERT_SUPPORT +void ApCliCertEDCAAdjust(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, PEDCA_PARM pEdcaParm) +{ + UCHAR Cwmin[WMM_NUM_OF_AC] = {3, 3, 3, 3}; + UCHAR Cwmax[WMM_NUM_OF_AC] = {4, 4, 4, 4}; + + if ((memcmp(pEdcaParm->Cwmin, Cwmin, 4) == 0) && + (memcmp(pEdcaParm->Cwmax, Cwmax, 4) == 0)) { + /* ignore 5.2.32*/ + return; + } + /* + * fix 5.2.29 step 7 fail + */ + if ((pAd->bApCliCertTest == TRUE) && + (wdev->wdev_type == WDEV_TYPE_APCLI)) { + if ((pEdcaParm->Cwmin[2] == 3) && + (pEdcaParm->Cwmax[2] == 4)) { + pEdcaParm->Cwmin[2]++; + pEdcaParm->Cwmax[2]++; + if (pEdcaParm->Txop[2] == 94) + pEdcaParm->Txop[2] = pEdcaParm->Txop[2] - 9; + } + } +} +#endif + + + +/* + ========================================================================== + + 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(RTMP_ADAPTER *pAd, UCHAR ifIndex) +{ + BOOLEAN result = FALSE; + PAPCLI_STRUCT pApCliEntry = NULL; + PMAC_TABLE_ENTRY pMacEntry = NULL; + STA_TR_ENTRY *tr_entry; + struct wifi_dev *wdev; +#if defined(MAC_REPEATER_SUPPORT) || defined(MT_MAC) + UCHAR CliIdx = 0xFF; +#ifdef MAC_REPEATER_SUPPORT + INVAILD_TRIGGER_MAC_ENTRY *pSkipEntry = NULL; + struct _REPEATER_CLIENT_ENTRY *pReptEntry = NULL; +#endif /* MAC_REPEATER_SUPPORT */ +#endif /* defined(MAC_REPEATER_SUPPORT) || defined(MT_MAC) */ +#ifdef APCLI_AUTO_CONNECT_SUPPORT + USHORT apcli_ifIndex; +#endif + UCHAR ext_cha; + + do { + if ((ifIndex < MAX_APCLI_NUM) +#ifdef MAC_REPEATER_SUPPORT + || (ifIndex >= REPT_MLME_START_IDX) +#endif /* MAC_REPEATER_SUPPORT */ + ) { +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn) { + if (ifIndex < MAX_APCLI_NUM) { +#ifdef LINUX + struct net_device *pNetDev; + struct net *net = &init_net; + /* old kernerl older than 2.6.21 didn't have for_each_netdev()*/ +#ifndef for_each_netdev + + for (pNetDev = dev_base; pNetDev != NULL; pNetDev = pNetDev->next) +#else + for_each_netdev(net, pNetDev) +#endif + { + if (pNetDev->priv_flags == IFF_EBRIDGE) { + COPY_MAC_ADDR(pAd->ApCfg.BridgeAddress, pNetDev->dev_addr); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, (" Bridge Addr = %02X:%02X:%02X:%02X:%02X:%02X. !!!\n", + PRINT_MAC(pAd->ApCfg.BridgeAddress))); + } + + pSkipEntry = RepeaterInvaildMacLookup(pAd, pNetDev->dev_addr); + + if (pSkipEntry == NULL) + InsertIgnoreAsRepeaterEntryTable(pAd, pNetDev->dev_addr); + } + + if (!MAC_ADDR_EQUAL(pAd->ApCfg.BridgeAddress, ZERO_MAC_ADDR)) { + pSkipEntry = RepeaterInvaildMacLookup(pAd, pAd->ApCfg.BridgeAddress); + + if (pSkipEntry) { + UCHAR MacAddr[MAC_ADDR_LEN]; + UCHAR entry_idx; + + COPY_MAC_ADDR(MacAddr, pSkipEntry->MacAddr); + entry_idx = pSkipEntry->entry_idx; + RepeaterRemoveIngoreEntry(pAd, entry_idx, MacAddr); + } + } + +#endif + } + + if (ifIndex >= REPT_MLME_START_IDX) { + CliIdx = ifIndex - REPT_MLME_START_IDX; + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + ifIndex = pReptEntry->wdev->func_idx; + pMacEntry = MacTableLookup(pAd, pReptEntry->OriginalAddress); + + if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) + pReptEntry->bEthCli = FALSE; + else + pReptEntry->bEthCli = TRUE; + + pMacEntry = NULL; + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("!!! ERROR : APCLI LINK UP - IF(apcli%d)!!!\n", ifIndex)); + result = FALSE; + break; + } + +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx != 0xFF) + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("(%s) ifIndex = %d, CliIdx = %d !!!\n", + __func__, ifIndex, CliIdx)); + else +#endif /* MAC_REPEATER_SUPPORT */ + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("(%s) ifIndex = %d!!!\n", + __func__, ifIndex)); +#ifdef APCLI_AUTO_CONNECT_SUPPORT + apcli_ifIndex = (USHORT)(ifIndex); +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + + if ((pApCliEntry->Valid) +#ifdef MAC_REPEATER_SUPPORT + && (CliIdx == 0xFF) +#endif /* MAC_REPEATER_SUPPORT */ + ) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("!!! ERROR : This link had existed - IF(apcli%d)!!!\n", + ifIndex)); + result = FALSE; + break; + } + + wdev = &pApCliEntry->wdev; +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx == 0xFF) +#endif /* MAC_REPEATER_SUPPORT */ + { + if (wf_drv_tbl.wf_fwd_get_rep_hook) + wf_drv_tbl.wf_fwd_get_rep_hook(pAd->CommonCfg.EtherTrafficBand); + + if (wf_drv_tbl.wf_fwd_check_device_hook) + wf_drv_tbl.wf_fwd_check_device_hook(wdev->if_dev, INT_APCLI, CliIdx, wdev->channel, 1); + + if (wf_drv_tbl.wf_fwd_entry_insert_hook) + wf_drv_tbl.wf_fwd_entry_insert_hook(wdev->if_dev, pAd->net_dev, pAd); + + if (wf_drv_tbl.wf_fwd_insert_repeater_mapping_hook) +#ifdef MAC_REPEATER_SUPPORT + wf_drv_tbl.wf_fwd_insert_repeater_mapping_hook(pAd, &pAd->ApCfg.ReptCliEntryLock, + &pAd->ApCfg.ReptCliHash[0], &pAd->ApCfg.ReptMapHash[0], + &pAd->ApCfg.ApCliTab[ifIndex].wdev.if_addr); +#else + wf_drv_tbl.wf_fwd_insert_repeater_mapping_hook(pAd, + NULL, NULL, NULL, &pAd->ApCfg.ApCliTab[ifIndex].wdev.if_addr); +#endif /* MAC_REPEATER_SUPPORT */ + } + +#endif /* CONFIG_WIFI_PKT_FWD */ + /* Insert the Remote AP to our MacTable. */ + /*pMacEntry = MacTableInsertApCliEntry(pAd, (PUCHAR)(pAd->ApCfg.ApCliTab[0].MlmeAux.Bssid)); */ +#ifdef FAST_EAPOL_WAR +#ifdef MAC_REPEATER_SUPPORT + + if ((pAd->ApCfg.bMACRepeaterEn) && + (IS_HIF_TYPE(pAd, HIF_MT)) && + (CliIdx != 0xFF)) { + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + if (pReptEntry->pre_entry_alloc == TRUE) + pMacEntry = &pAd->MacTab.Content[pReptEntry->MacTabWCID]; + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + if (pApCliEntry->pre_entry_alloc == TRUE) + pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID]; + } + +#else /* FAST_EAPOL_WAR */ +#ifdef MAC_REPEATER_SUPPORT + + if ((pAd->ApCfg.bMACRepeaterEn) && + (IS_HIF_TYPE(pAd, HIF_MT)) && + (CliIdx != 0xFF)) { + pMacEntry = MacTableInsertEntry( + pAd, + (PUCHAR)(pApCliEntry->MlmeAux.Bssid), + wdev, + ENTRY_REPEATER, + OPMODE_AP, + TRUE); + } else +#endif /* MAC_REPEATER_SUPPORT */ + pMacEntry = MacTableInsertEntry(pAd, (PUCHAR)(pApCliEntry->MlmeAux.Bssid), + wdev, ENTRY_APCLI, + OPMODE_AP, TRUE); + +#endif /* !FAST_EAPOL_WAR */ + + if (pMacEntry) { + struct _SECURITY_CONFIG *pProfile_SecConfig = &wdev->SecConfig; + struct _SECURITY_CONFIG *pEntry_SecConfig = &pMacEntry->SecConfig; +#ifdef DOT11W_PMF_SUPPORT + /*fill the pMacEntry's PMF parameters*/ + { + RSN_CAPABILITIES RsnCap; + + NdisMoveMemory(&RsnCap, &pApCliEntry->MlmeAux.RsnCap, sizeof(RSN_CAPABILITIES)); + RsnCap.word = cpu2le16(RsnCap.word); + + /*mismatch case*/ + if (((pProfile_SecConfig->PmfCfg.MFPR) && (RsnCap.field.MFPC == FALSE)) + || ((pProfile_SecConfig->PmfCfg.MFPC == FALSE) && (RsnCap.field.MFPR))) { + pEntry_SecConfig->PmfCfg.UsePMFConnect = FALSE; + pEntry_SecConfig->key_deri_alg = SEC_KEY_DERI_SHA1; + } + + if ((pProfile_SecConfig->PmfCfg.MFPC) && (RsnCap.field.MFPC)) { + pEntry_SecConfig->PmfCfg.UsePMFConnect = TRUE; + + if ((pApCliEntry->MlmeAux.IsSupportSHA256KeyDerivation) || (RsnCap.field.MFPR)) + pEntry_SecConfig->key_deri_alg = SEC_KEY_DERI_SHA256; + + pEntry_SecConfig->PmfCfg.MFPC = RsnCap.field.MFPC; + pEntry_SecConfig->PmfCfg.MFPR = RsnCap.field.MFPR; + } + + pEntry_SecConfig->PmfCfg.igtk_cipher = pApCliEntry->MlmeAux.IntegrityGroupCipher; + } +#endif /* DOT11W_PMF_SUPPORT */ + + if (IS_CIPHER_WEP(pEntry_SecConfig->PairwiseCipher)) { + os_move_mem(pEntry_SecConfig->WepKey, pProfile_SecConfig->WepKey, sizeof(SEC_KEY_INFO)*SEC_KEY_NUM); + pProfile_SecConfig->GroupKeyId = pProfile_SecConfig->PairwiseKeyId; + pEntry_SecConfig->PairwiseKeyId = pProfile_SecConfig->PairwiseKeyId; + } else { + CHAR rsne_idx = 0; + { + /* Calculate PMK */ + SetWPAPSKKey(pAd, pProfile_SecConfig->PSK, strlen(pProfile_SecConfig->PSK), pApCliEntry->MlmeAux.Ssid, pApCliEntry->MlmeAux.SsidLen, pEntry_SecConfig->PMK); + } + +#ifdef MAC_REPEATER_SUPPORT + + if ((pAd->ApCfg.bMACRepeaterEn) && (IS_HIF_TYPE(pAd, HIF_MT)) && (CliIdx != 0xFF)) { + os_move_mem(pEntry_SecConfig->Handshake.AAddr, pMacEntry->Addr, MAC_ADDR_LEN); + os_move_mem(pEntry_SecConfig->Handshake.SAddr, pReptEntry->CurrentAddress, MAC_ADDR_LEN); + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + os_move_mem(pEntry_SecConfig->Handshake.AAddr, pMacEntry->Addr, MAC_ADDR_LEN); + os_move_mem(pEntry_SecConfig->Handshake.SAddr, wdev->if_addr, MAC_ADDR_LEN); + } + + os_zero_mem(pEntry_SecConfig->Handshake.ReplayCounter, LEN_KEY_DESC_REPLAY); + + for (rsne_idx = 0; rsne_idx < SEC_RSNIE_NUM; rsne_idx++) { + pEntry_SecConfig->RSNE_Type[rsne_idx] = pProfile_SecConfig->RSNE_Type[rsne_idx]; + + if (pEntry_SecConfig->RSNE_Type[rsne_idx] == SEC_RSNIE_NONE) + continue; + + os_move_mem(pEntry_SecConfig->RSNE_EID[rsne_idx], pProfile_SecConfig->RSNE_EID[rsne_idx], sizeof(UCHAR)); + pEntry_SecConfig->RSNE_Len[rsne_idx] = pProfile_SecConfig->RSNE_Len[rsne_idx]; + os_move_mem(pEntry_SecConfig->RSNE_Content[rsne_idx], pProfile_SecConfig->RSNE_Content[rsne_idx], sizeof(UCHAR)*MAX_LEN_OF_RSNIE); + } + + pMacEntry->SecConfig.Handshake.WpaState = AS_INITPSK; + } + + pEntry_SecConfig->GroupKeyId = pProfile_SecConfig->GroupKeyId; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: (apcli%d) connect AKM(0x%x)=%s, PairwiseCipher(0x%x)=%s, GroupCipher(0x%x)=%s\n", + __func__, ifIndex, + pEntry_SecConfig->AKMMap, GetAuthModeStr(pEntry_SecConfig->AKMMap), + pEntry_SecConfig->PairwiseCipher, GetEncryModeStr(pEntry_SecConfig->PairwiseCipher), + pEntry_SecConfig->GroupCipher, GetEncryModeStr(pEntry_SecConfig->GroupCipher))); + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): PairwiseKeyId=%d, GroupKeyId=%d\n", + __func__, pEntry_SecConfig->PairwiseKeyId, pEntry_SecConfig->GroupKeyId)); + } + + if (pMacEntry) { + UCHAR Rates[MAX_LEN_OF_SUPPORTED_RATES]; + PUCHAR pRates = Rates; + UCHAR RatesLen; + UCHAR MaxSupportedRate = 0; + + tr_entry = &pAd->MacTab.tr_entry[pMacEntry->wcid]; + pMacEntry->Sst = SST_ASSOC; +#ifdef HTC_DECRYPT_IOT + + if ((pMacEntry->HTC_ICVErrCnt) + || (pMacEntry->HTC_AAD_OM_Force) + || (pMacEntry->HTC_AAD_OM_CountDown) + || (pMacEntry->HTC_AAD_OM_Freeze) + ) { + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("@@@ %s(): (wcid=%u), HTC_ICVErrCnt(%u), HTC_AAD_OM_Freeze(%u), HTC_AAD_OM_CountDown(%u), HTC_AAD_OM_Freeze(%u) is in Asso. stage!\n", + __func__, pMacEntry->wcid, pMacEntry->HTC_ICVErrCnt, pMacEntry->HTC_AAD_OM_Force, pMacEntry->HTC_AAD_OM_CountDown, pMacEntry->HTC_AAD_OM_Freeze)); + /* Force clean. */ + pMacEntry->HTC_ICVErrCnt = 0; + pMacEntry->HTC_AAD_OM_Force = 0; + pMacEntry->HTC_AAD_OM_CountDown = 0; + pMacEntry->HTC_AAD_OM_Freeze = 0; + } + +#endif /* HTC_DECRYPT_IOT */ + /* pMacEntry->wdev = &pApCliEntry->wdev;//duplicate assign. */ +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx != 0xFF) { + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + pReptEntry->MacTabWCID = pMacEntry->wcid; + pReptEntry->CliValid = TRUE; + pMacEntry->bReptCli = TRUE; + pMacEntry->bReptEthBridgeCli = FALSE; + pMacEntry->MatchReptCliIdx = CliIdx; + pMacEntry->ReptCliIdleCount = 0; + COPY_MAC_ADDR(pMacEntry->ReptCliAddr, pReptEntry->CurrentAddress); + tr_entry->OmacIdx = HcGetRepeaterOmac(pAd, pMacEntry); + + if (pReptEntry->bEthCli == TRUE) { + pMacEntry->bReptEthCli = TRUE; + + if (MAC_ADDR_EQUAL(pAd->ApCfg.BridgeAddress, pAd->ApCfg.pRepeaterCliPool[CliIdx].OriginalAddress)) + pMacEntry->bReptEthBridgeCli = TRUE; + } else + pMacEntry->bReptEthCli = FALSE; + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + pApCliEntry->Valid = TRUE; + pApCliEntry->MacTabWCID = pMacEntry->wcid; +#ifdef MAC_REPEATER_SUPPORT + pMacEntry->bReptCli = FALSE; +#endif /* MAC_REPEATER_SUPPORT */ + COPY_MAC_ADDR(&wdev->bssid[0], &pApCliEntry->MlmeAux.Bssid[0]); + os_move_mem(wdev->bss_info_argument.Bssid, wdev->bssid, MAC_ADDR_LEN); + COPY_MAC_ADDR(APCLI_ROOT_BSSID_GET(pAd, pApCliEntry->MacTabWCID), pApCliEntry->MlmeAux.Bssid); + pApCliEntry->SsidLen = pApCliEntry->MlmeAux.SsidLen; + NdisMoveMemory(pApCliEntry->Ssid, pApCliEntry->MlmeAux.Ssid, pApCliEntry->SsidLen); + ComposePsPoll(pAd, &(pApCliEntry->PsPollFrame), pApCliEntry->MlmeAux.Aid, + pApCliEntry->MlmeAux.Bssid, pApCliEntry->wdev.if_addr); + ComposeNullFrame(pAd, &(pApCliEntry->NullFrame), pApCliEntry->MlmeAux.Bssid, + pApCliEntry->wdev.if_addr, pApCliEntry->MlmeAux.Bssid); + } + + + if (IS_AKM_WPA_CAPABILITY_Entry(pMacEntry) +#ifdef WSC_AP_SUPPORT + && ((pApCliEntry->wdev.WscControl.WscConfMode == WSC_DISABLE) || + (pApCliEntry->wdev.WscControl.bWscTrigger == FALSE)) +#endif /* WSC_AP_SUPPORT */ + ) + tr_entry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + else { + tr_entry->PortSecured = WPA_802_1X_PORT_SECURED; + +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx != 0xFF) + pReptEntry->CliConnectState = REPT_ENTRY_CONNTED; + +#endif /* MAC_REPEATER_SUPPORT */ + } + +#ifdef APCLI_AUTO_CONNECT_SUPPORT + + if ((pAd->ApCfg.ApCliAutoConnectRunning[apcli_ifIndex] == TRUE) && +#ifdef MAC_REPEATER_SUPPORT + (CliIdx == 0xFF) && +#endif /* MAC_REPEATER_SUPPORT */ + (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("ApCli auto connected: ApCliLinkUp()\n")); + pAd->ApCfg.ApCliAutoConnectRunning[apcli_ifIndex] = FALSE; + } + +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx == 0xFF) +#endif /* MAC_REPEATER_SUPPORT */ + NdisGetSystemUpTime(&pApCliEntry->ApCliLinkUpTime); + + SupportRate(pApCliEntry->MlmeAux.SupRate, pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.ExtRate, + pApCliEntry->MlmeAux.ExtRateLen, &pRates, &RatesLen, &MaxSupportedRate); + pMacEntry->MaxSupportedRate = min(wdev->rate.MaxTxRate, MaxSupportedRate); + pMacEntry->RateLen = RatesLen; + MacTableSetEntryPhyCfg(pAd, pMacEntry); + pMacEntry->CapabilityInfo = pApCliEntry->MlmeAux.CapabilityInfo; + pApCliEntry->ApCliBeaconPeriod = pApCliEntry->MlmeAux.BeaconPeriod; +#ifdef DOT11_N_SUPPORT + + /* If this Entry supports 802.11n, upgrade to HT rate. */ + if (pApCliEntry->MlmeAux.HtCapabilityLen != 0) { + PHT_CAPABILITY_IE pHtCapability = (PHT_CAPABILITY_IE)&pApCliEntry->MlmeAux.HtCapability; + + ht_mode_adjust(pAd, pMacEntry, pHtCapability); + /* find max fixed rate */ + pMacEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &wdev->DesiredHtPhyInfo.MCSSet[0], + &pHtCapability->MCSSet[0]); + + if (wdev->DesiredTransmitSetting.field.MCS != MCS_AUTO) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_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->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word; + set_sta_ht_cap(pAd, pMacEntry, pHtCapability); + NdisMoveMemory(&pMacEntry->HTCapability, &pApCliEntry->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE)); + NdisMoveMemory(pMacEntry->HTCapability.MCSSet, pApCliEntry->RxMcsSet, 16); + assoc_ht_info_debugshow(pAd, pMacEntry, sizeof(HT_CAPABILITY_IE), &pApCliEntry->MlmeAux.HtCapability); +#ifdef APCLI_CERT_SUPPORT + + if (pAd->bApCliCertTest == TRUE) { + ADD_HTINFO2 *ht_info2 = &pApCliEntry->MlmeAux.AddHtInfo.AddHtInfo2; + + wdev->protection = 0; + + wdev->protection |= SET_PROTECT(ht_info2->OperaionMode); + + if (ht_info2->NonGfPresent == 1) + wdev->protection |= SET_PROTECT(GREEN_FIELD_PROTECT); + else + wdev->protection &= ~(SET_PROTECT(GREEN_FIELD_PROTECT)); + + AsicUpdateProtect(pAd); + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("SYNC - Root AP changed N OperaionMode to %d\n", ht_info2->OperaionMode)); + } + +#endif /* APCLI_CERT_SUPPORT */ + } else { + pAd->MacTab.fAnyStationIsLegacy = TRUE; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("ApCliLinkUp - MaxSupRate=%d Mbps\n", + RateIdToMbps[pMacEntry->MaxSupportedRate])); + } + +#endif /* DOT11_N_SUPPORT */ +#ifdef DOT11_VHT_AC + + if (WMODE_CAP_AC(wdev->PhyMode) && pApCliEntry->MlmeAux.vht_cap_len && pApCliEntry->MlmeAux.vht_op_len) { + vht_mode_adjust(pAd, pMacEntry, &(pApCliEntry->MlmeAux.vht_cap), &(pApCliEntry->MlmeAux.vht_op)); + dot11_vht_mcs_to_internal_mcs(pAd, wdev, &pApCliEntry->MlmeAux.vht_cap, &pMacEntry->MaxHTPhyMode); + /* Move to set_vht_cap(), which could be reused by AP, WDS and P2P */ + /* + pMacEntry->MaxRAmpduFactor = + (pApCliEntry->MlmeAux.vht_cap.vht_cap.max_ampdu_exp > pMacEntry->MaxRAmpduFactor) ? + pApCliEntry->MlmeAux.vht_cap.vht_cap.max_ampdu_exp : pMacEntry->MaxRAmpduFactor; + pMacEntry->AMsduSize = pApCliEntry->MlmeAux.vht_cap.vht_cap.max_mpdu_len; + */ + set_vht_cap(pAd, pMacEntry, &(pApCliEntry->MlmeAux.vht_cap)); +#ifdef APCLI_CERT_SUPPORT +/* For TGac Test case 5.2.47 AMSDU+AMPDU aggregation is to large for WFA sniffer to handle +during 3x3 throughput check,so we limit the AMSDU len to 3839* +*/ + if (pAd->bApCliCertTest == TRUE) { + + UCHAR Ssid[] = "VHT-5.2.47-AP3"; + UCHAR SsidEqual = 0; + + SsidEqual = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, Ssid, strlen(Ssid)); + + if (SsidEqual && (pMacEntry->AMsduSize > 0)) { + pMacEntry->AMsduSize = 0; + pMacEntry->amsdu_limit_len = vht_max_mpdu_size[pMacEntry->AMsduSize]; + pMacEntry->amsdu_limit_len_adjust = pMacEntry->amsdu_limit_len; + } + } +#endif + NdisMoveMemory(&pMacEntry->vht_cap_ie, &pApCliEntry->MlmeAux.vht_cap, sizeof(VHT_CAP_IE)); + assoc_vht_info_debugshow(pAd, pMacEntry, &pApCliEntry->MlmeAux.vht_cap, &pApCliEntry->MlmeAux.vht_op); + } + +#endif /* DOT11_VHT_AC */ + /* update per wdev bw */ + ext_cha = wlan_config_get_ext_cha(wdev); + + if (pMacEntry->MaxHTPhyMode.field.BW < BW_80) + wlan_operate_set_ht_bw(wdev, pMacEntry->MaxHTPhyMode.field.BW, ext_cha); + else { +#ifdef DOT11_VHT_AC + + switch (pMacEntry->MaxHTPhyMode.field.BW) { + case BW_80: + wlan_operate_set_vht_bw(wdev, VHT_BW_80); + wlan_operate_set_ht_bw(wdev, HT_BW_40, ext_cha); + break; + + case BW_160: + wlan_operate_set_vht_bw(wdev, VHT_BW_160); + wlan_operate_set_ht_bw(wdev, HT_BW_40, ext_cha); + break; + + default: + wlan_operate_set_vht_bw(wdev, VHT_BW_2040); + wlan_operate_set_ht_bw(wdev, HT_BW_40, ext_cha); + break; + } + +#endif + } + + pMacEntry->HTPhyMode.word = pMacEntry->MaxHTPhyMode.word; + pMacEntry->CurrTxRate = pMacEntry->MaxSupportedRate; + RTMPSetSupportMCS(pAd, + OPMODE_AP, + pMacEntry, + pApCliEntry->MlmeAux.SupRate, + pApCliEntry->MlmeAux.SupRateLen, + pApCliEntry->MlmeAux.ExtRate, + pApCliEntry->MlmeAux.ExtRateLen, +#ifdef DOT11_VHT_AC + pApCliEntry->MlmeAux.vht_cap_len, + &pApCliEntry->MlmeAux.vht_cap, +#endif /* DOT11_VHT_AC */ + &pApCliEntry->MlmeAux.HtCapability, + pApCliEntry->MlmeAux.HtCapabilityLen); +#ifdef MT_MAC +#ifdef MT7615 + + if (IS_HIF_TYPE(pAd, HIF_MT)) { + if (pApCliEntry->MlmeAux.APEdcaParm.bValid) { + pMacEntry->bACMBit[WMM_AC_BK] = pApCliEntry->MlmeAux.APEdcaParm.bACM[WMM_AC_BK]; + pMacEntry->bACMBit[WMM_AC_BE] = pApCliEntry->MlmeAux.APEdcaParm.bACM[WMM_AC_BE]; + pMacEntry->bACMBit[WMM_AC_VI] = pApCliEntry->MlmeAux.APEdcaParm.bACM[WMM_AC_VI]; + pMacEntry->bACMBit[WMM_AC_VO] = pApCliEntry->MlmeAux.APEdcaParm.bACM[WMM_AC_VO]; + } + } + +#endif /* MT7615 */ +#endif /* MT_MAC */ + + /* + set this entry WMM capable or not + It need to before linkup, or it cannot link non_wmm AP + */ + if ((pApCliEntry->MlmeAux.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); + + NdisGetSystemUpTime(&pApCliEntry->ApCliRcvBeaconTime); + + /* set the apcli interface be valid. */ + /*only apcli should linkup*/ + if (CliIdx == 0xFF) { + if (wdev_do_linkup(wdev, pMacEntry) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): linkup fail!!\n", __func__)); + } + + if (wdev_do_conn_act(wdev, pMacEntry) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): connect fail!!\n", __func__)); + + MacTableSetEntryRaCap(pAd, pMacEntry, &pApCliEntry->MlmeAux.vendor_ie); +#ifdef MT_MAC + + if (IS_HIF_TYPE(pAd, HIF_MT)) { + if (wdev->bAutoTxRateSwitch == TRUE) + pMacEntry->bAutoTxRateSwitch = TRUE; + else { + pMacEntry->HTPhyMode.field.MCS = wdev->HTPhyMode.field.MCS; + pMacEntry->bAutoTxRateSwitch = FALSE; + /* If the legacy mode is set, overwrite the transmit setting of this entry. */ + RTMPUpdateLegacyTxSetting((UCHAR)wdev->DesiredTransmitSetting.field.FixedTxMode, pMacEntry); + } + + RAInit(pAd, pMacEntry); +#ifdef TXBF_SUPPORT + + if (HcIsBfCapSupport(wdev)) + HW_APCLI_BF_CAP_CONFIG(pAd, pMacEntry); + +#endif /* TXBF_SUPPORT */ + } + +#endif + + if (IS_CIPHER_WEP_Entry(pMacEntry) + ) { + INT BssIdx; + ASIC_SEC_INFO Info = {0}; + struct _SECURITY_CONFIG *pSecConfig = &pMacEntry->SecConfig; + + BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + ifIndex; +#ifdef MAC_APCLI_SUPPORT + BssIdx = APCLI_BSS_BASE + ifIndex; +#endif /* MAC_APCLI_SUPPORT */ + + /* Set Group key material to Asic */ + os_zero_mem(&Info, sizeof(ASIC_SEC_INFO)); + Info.Operation = SEC_ASIC_ADD_GROUP_KEY; + Info.Direction = SEC_ASIC_KEY_RX; + Info.Wcid = wdev->bss_info_argument.ucBcMcWlanIdx; + Info.BssIndex = BssIdx; + Info.Cipher = pSecConfig->GroupCipher; + Info.KeyIdx = pSecConfig->GroupKeyId; + os_move_mem(&Info.PeerAddr[0], pMacEntry->Addr, MAC_ADDR_LEN); + os_move_mem(&Info.Key, &pSecConfig->WepKey[Info.KeyIdx], sizeof(SEC_KEY_INFO)); + + HW_ADDREMOVE_KEYTABLE(pAd, &Info); + + + /* Set Pairwise key material to Asic */ + os_zero_mem(&Info, sizeof(ASIC_SEC_INFO)); + Info.Operation = SEC_ASIC_ADD_PAIRWISE_KEY; + Info.Direction = SEC_ASIC_KEY_BOTH; + Info.Wcid = pMacEntry->wcid; + Info.BssIndex = BssIdx; + Info.Cipher = pSecConfig->PairwiseCipher; + Info.KeyIdx = pSecConfig->PairwiseKeyId; + os_move_mem(&Info.PeerAddr[0], pMacEntry->Addr, MAC_ADDR_LEN); + os_move_mem(&Info.Key, &pSecConfig->WepKey[Info.KeyIdx], sizeof(SEC_KEY_INFO)); + + HW_ADDREMOVE_KEYTABLE(pAd, &Info); + } + + + +#ifdef PIGGYBACK_SUPPORT + + if (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)) { + AsicSetPiggyBack(pAd, TRUE); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("Turn on Piggy-Back\n")); + } + +#endif /* PIGGYBACK_SUPPORT */ + + + +#ifdef MT_MAC +#ifdef MAC_REPEATER_SUPPORT + + if ((CliIdx != 0xff && IS_HIF_TYPE(pAd, HIF_MT))) { + AsicInsertRepeaterRootEntry( + pAd, + pMacEntry->wcid, + (PUCHAR)(pApCliEntry->MlmeAux.Bssid), + CliIdx); +#ifdef TXBF_SUPPORT + + if ((pAd->fgClonedStaWithBfeeSelected) && (pAd->ReptClonedStaEntry_CliIdx == CliIdx)) + HW_APCLI_BF_REPEATER_CONFIG(pAd, pMacEntry); /* Move cloned STA's MAC addr from MUAR table to ownmac */ + +#endif /* TXBF_SUPPORT */ + } + +#endif /* MAC_REPEATER_SUPPORT */ +#endif /* MT_MAC */ + result = TRUE; + pAd->ApCfg.ApCliInfRunned++; +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) +#ifdef MAC_REPEATER_SUPPORT + if (CliIdx == 0xFF) +#endif + wf_apcli_active_links++; + +#ifdef CONFIG_FAST_NAT_SUPPORT + + if ((wf_apcli_active_links >= 2) + && (ra_sw_nat_hook_rx != NULL) + && (wf_ra_sw_nat_hook_rx_bkup == NULL)) { + wf_ra_sw_nat_hook_rx_bkup = ra_sw_nat_hook_rx; + ra_sw_nat_hook_rx = NULL; + } + +#endif /*CONFIG_FAST_NAT_SUPPORT*/ +#endif + break; + } + + result = FALSE; + } while (FALSE); + + if (result == FALSE) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, (" (%s) alloc mac entry fail!!!\n", __func__)); + return result; + } + +#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].wdev.WscControl.WscConfMode == WSC_ENROLLEE) && + (pAd->ApCfg.ApCliTab[ifIndex].wdev.WscControl.bWscTrigger == TRUE)) { + pAd->ApCfg.ApCliTab[ifIndex].wdev.WscControl.WscState = WSC_STATE_LINK_UP; + pAd->ApCfg.ApCliTab[ifIndex].wdev.WscControl.WscStatus = WSC_STATE_LINK_UP; + pAd->ApCfg.ApCliTab[ifIndex].wdev.WscControl.WscConfStatus = WSC_SCSTATE_UNCONFIGURED; + NdisZeroMemory(pApCliEntry->wdev.WscControl.EntryAddr, MAC_ADDR_LEN); + NdisMoveMemory(pApCliEntry->wdev.WscControl.EntryAddr, pApCliEntry->MlmeAux.Bssid, MAC_ADDR_LEN); + WscSendEapolStart(pAd, + pMacEntry->Addr, + AP_MODE, + &pAd->ApCfg.ApCliTab[ifIndex].wdev); + } else + WscStop(pAd, TRUE, &pAd->ApCfg.ApCliTab[ifIndex].wdev.WscControl); + +#endif /* WSC_AP_SUPPORT */ +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 +#ifdef APCLI_CERT_SUPPORT + + if (pAd->bApCliCertTest == TRUE) { + if ((pAd->CommonCfg.bBssCoexEnable == TRUE) && + (wdev->channel <= 14) && + (wdev->DesiredHtPhyInfo.bHtEnable == TRUE) && + (pApCliEntry->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport == 1)) { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040); + BuildEffectedChannelList(pAd, wdev); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("LinkUP AP supports 20/40 BSS COEX !!! Dot11BssWidthTriggerScanInt[%d]\n", + pAd->CommonCfg.Dot11BssWidthTriggerScanInt)); + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("not supports 20/40 BSS COEX !!!\n")); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("pAd->CommonCfg.bBssCoexEnable %d !!!\n", + pAd->CommonCfg.bBssCoexEnable)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("Channel %d !!!\n", + wdev->channel)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("pApCliEntry->DesiredHtPhyInfo.bHtEnable %d !!!\n", + pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("pAd->MlmeAux.ExtCapInfo.BssCoexstSup %d !!!\n", + pApCliEntry->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("CentralChannel: %d !!!\n", + wlan_operate_get_cen_ch_1(wdev))); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("PhyMode %d !!!\n", + wdev->PhyMode)); + } + } + +#endif /* APCLI_CERT_SUPPORT */ +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +#if defined(CONFIG_MAP_SUPPORT) && defined(WAPP_SUPPORT) + if (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED) /*For security NONE & WEP case*/ + wapp_send_apcli_association_change(WAPP_APCLI_ASSOCIATED, pAd, pApCliEntry); +#endif /*WAPP_SUPPORT*/ + + return result; +} + +static CHAR LinkDownReason[APCLI_LINKDOWN_PEER_DEASSOC_RSP+1][30] = { + "none", + "send deauth req", + "send deassociate req", + "recv deassociate req", + "got disconnect req", + "recv deassociate resp" +}; + +static CHAR SubLinkDownReason[APCLI_DISCONNECT_SUB_REASON_APCLI_TRIGGER_TOO_LONG+1][30] = { + "none", + "rept connect too long", + "idle too long", + "remove sta", + "apcli if down", + "beacon miss", + "recv sta disassociate req", + "recv sta deauth req", + "manually del mac entry", + "repter bind to other apcli", + "apcli connect too long" +}; +/* + ========================================================================== + + Routine Description: + Disconnect current BSSID + + Arguments: + pAd - Pointer to our adapter + ApCliIdx - Which ApCli interface + Return Value: + None + + Note: + + ========================================================================== +*/ +VOID ApCliLinkDown(RTMP_ADAPTER *pAd, UCHAR ifIndex) +{ + APCLI_STRUCT *pApCliEntry = NULL; + struct wifi_dev *wdev = NULL; + UCHAR CliIdx = 0xFF; +#ifdef MAC_REPEATER_SUPPORT + struct _REPEATER_CLIENT_ENTRY *pReptEntry = NULL; +#endif /* MAC_REPEATER_SUPPORT */ + UCHAR MacTabWCID = 0; + + if ((ifIndex < MAX_APCLI_NUM) +#ifdef MAC_REPEATER_SUPPORT + || (ifIndex >= REPT_MLME_START_IDX) +#endif /* MAC_REPEATER_SUPPORT */ + ) { +#ifdef MAC_REPEATER_SUPPORT + + if (ifIndex >= REPT_MLME_START_IDX) { + CliIdx = ifIndex - REPT_MLME_START_IDX; + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + ifIndex = pReptEntry->wdev->func_idx; + + if (pReptEntry->LinkDownReason == APCLI_LINKDOWN_PEER_DEASSOC_REQ) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("!!! REPEATER CLI LINK DOWN - IF(apcli%d) Cli %d (Reason=%s,Reason code=%lu)!!!\n", + ifIndex, CliIdx, LinkDownReason[pReptEntry->LinkDownReason], pReptEntry->Disconnect_Sub_Reason)); + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("!!! REPEATER CLI LINK DOWN - IF(apcli%d) Cli %d (Reason=%s,sub=%s)!!!\n", + ifIndex, CliIdx, LinkDownReason[pReptEntry->LinkDownReason], SubLinkDownReason[pReptEntry->Disconnect_Sub_Reason])); + } + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + if (pAd->ApCfg.ApCliTab[ifIndex].LinkDownReason == APCLI_LINKDOWN_PEER_DEASSOC_REQ) + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("!!! APCLI LINK DOWN - IF(apcli%d) (Reason=%s,Reason code=%lu)!!!\n", ifIndex, LinkDownReason[pAd->ApCfg.ApCliTab[ifIndex].LinkDownReason], pAd->ApCfg.ApCliTab[ifIndex].Disconnect_Sub_Reason)); + else + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("!!! APCLI LINK DOWN - IF(apcli%d) (Reason=%s,sub=%s)!!!\n", ifIndex, LinkDownReason[pAd->ApCfg.ApCliTab[ifIndex].LinkDownReason], SubLinkDownReason[pAd->ApCfg.ApCliTab[ifIndex].Disconnect_Sub_Reason])); + } + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("!!! ERROR : APCLI LINK DOWN - IF(apcli%d)!!!\n", ifIndex)); + return; + } + + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + wdev = &pApCliEntry->wdev; + + if ((pApCliEntry->Valid == FALSE) +#ifdef MAC_REPEATER_SUPPORT + && (CliIdx == 0xFF) +#endif /* MAC_REPEATER_SUPPORT */ + ) + return; + +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx == 0xFF) +#endif /* MAC_REPEATER_SUPPORT */ + { + if (wf_drv_tbl.wf_fwd_entry_delete_hook) + wf_drv_tbl.wf_fwd_entry_delete_hook(pApCliEntry->wdev.if_dev, pAd->net_dev, 1); + + if (wf_drv_tbl.wf_fwd_check_device_hook) + wf_drv_tbl.wf_fwd_check_device_hook(pApCliEntry->wdev.if_dev, + INT_APCLI, CliIdx, pApCliEntry->wdev.channel, 0); + } + +#ifdef MAC_REPEATER_SUPPORT + else { + if (wf_drv_tbl.packet_source_delete_entry_hook) + wf_drv_tbl.packet_source_delete_entry_hook(100); + } + +#endif /* MAC_REPEATER_SUPPORT */ +#endif /* CONFIG_WIFI_PKT_FWD */ +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx == 0xFF) +#endif /* MAC_REPEATER_SUPPORT */ + pAd->ApCfg.ApCliInfRunned--; + +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) +#ifdef MAC_REPEATER_SUPPORT + if (CliIdx == 0xFF) +#endif /* MAC_REPEATER_SUPPORT */ + wf_apcli_active_links--; + +#ifdef CONFIG_FAST_NAT_SUPPORT + if ((wf_apcli_active_links < 2) && (ra_sw_nat_hook_rx == NULL) && (wf_ra_sw_nat_hook_rx_bkup != NULL)) { + ra_sw_nat_hook_rx = wf_ra_sw_nat_hook_rx_bkup; + wf_ra_sw_nat_hook_rx_bkup = NULL; + } + +#endif /*CONFIG_FAST_NAT_SUPPORT*/ +#endif + + +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx != 0xFF) { + MacTabWCID = pReptEntry->MacTabWCID; + MacTableDeleteEntry(pAd, MacTabWCID, pAd->MacTab.Content[MacTabWCID].Addr); +#ifdef FAST_EAPOL_WAR + pReptEntry->pre_entry_alloc = FALSE; +#endif /* FAST_EAPOL_WAR */ + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + MacTabWCID = pApCliEntry->MacTabWCID; + MacTableDeleteEntry(pAd, MacTabWCID, APCLI_ROOT_BSSID_GET(pAd, MacTabWCID)); +#ifdef FAST_EAPOL_WAR + pApCliEntry->pre_entry_alloc = FALSE; +#endif /* FAST_EAPOL_WAR */ + } + +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx != 0xFF) + HW_REMOVE_REPT_ENTRY(pAd, ifIndex, CliIdx); + else +#endif /* MAC_REPEATER_SUPPORT */ + { + pApCliEntry->Valid = FALSE; /* This link doesn't associated with any remote-AP */ + MSDU_FORBID_SET(&pApCliEntry->wdev, MSDU_FORBID_CONNECTION_NOT_READY); + pApCliEntry->wdev.PortSecured = WPA_802_1X_PORT_NOT_SECURED; +#ifdef DOT11W_PMF_SUPPORT + BssTableDeleteEntry(&pAd->ScanTab, pApCliEntry->MlmeAux.Bssid, wdev->channel); +#else +#endif /* DOT11W_PMF_SUPPORT */ + } + + + pAd->ApCfg.ApCliTab[ifIndex].bPeerExist = FALSE; + + /*TODO & FIXME: Carter, REPEATER CASE */ + if (CliIdx == 0xFF) { + if (wdev_do_linkdown(wdev) != TRUE) + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("(%s) linkdown fail!\n", __func__)); + } + +#ifdef TXBF_SUPPORT + + if ((pAd->fgClonedStaWithBfeeSelected) && (pAd->ReptClonedStaEntry_CliIdx == CliIdx)) { + pAd->fgClonedStaWithBfeeSelected = FALSE; + /* Remove cloned STA's MAC addr from ownmac */ + } + +#endif /* TXBF_SUPPORT */ +#if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) + RT_CFG80211_LOST_GO_INFORM(pAd); + /* TODO: need to consider driver without no FW offload @20140728 */ + /* NoA Stop */ + /* if (bP2pCliPmEnable) */ + CmdP2pNoaOffloadCtrl(pAd, P2P_NOA_DISABLED); +#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ + + /*for APCLI linkdown*/ + if (CliIdx == 0xFF) { +#ifdef DOT11_N_SUPPORT + wlan_operate_set_ht_bw(&pApCliEntry->wdev, + wlan_config_get_ht_bw(&pApCliEntry->wdev), + wlan_config_get_ext_cha(&pApCliEntry->wdev)); +#endif +#ifdef DOT11_VHT_AC + wlan_operate_set_vht_bw(&pApCliEntry->wdev, wlan_config_get_vht_bw(&pApCliEntry->wdev)); +#endif +#if defined(CONFIG_MAP_SUPPORT) && defined(WAPP_SUPPORT) + wapp_send_apcli_association_change(WAPP_APCLI_DISASSOCIATED, pAd, pApCliEntry); +#endif /*WAPP_SUPPORT*/ + + ApCliLinkDownComplete(pApCliEntry); + } +} + + +/* + ========================================================================== + Description: + APCLI Interface Up. + ========================================================================== + */ +VOID ApCliIfUp(RTMP_ADAPTER *pAd) +{ + UCHAR ifIndex; + APCLI_STRUCT *pApCliEntry; +#ifdef APCLI_CONNECTION_TRIAL + PULONG pCurrState = NULL; +#endif /* APCLI_CONNECTION_TRIAL */ + struct DOT11_H *pDot11h = NULL; + + /* Reset is in progress, stop immediately */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS|fRTMP_ADAPTER_RADIO_OFF) || + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))) + return; + + for (ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++) { + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + + /* sanity check whether the interface is initialized. */ + if (pApCliEntry->ApCliInit != TRUE) + continue; + +#ifdef APCLI_CONNECTION_TRIAL + pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState; +#endif /* APCLI_CONNECTION_TRIAL */ + + if (!HcIsRadioAcq(&pApCliEntry->wdev)) + continue; + + if (APCLI_IF_UP_CHECK(pAd, ifIndex) + && (pApCliEntry->Enable == TRUE) + && (pApCliEntry->Valid == FALSE) +#ifdef APCLI_CONNECTION_TRIAL + && (ifIndex != (pAd->ApCfg.ApCliNum-1)) /* last IF is for apcli connection trial */ +#endif /* APCLI_CONNECTION_TRIAL */ + ) { + pDot11h = pApCliEntry->wdev.pDot11_H; + if (pDot11h == NULL) + return; + if (IS_DOT11_H_RADAR_STATE(pAd, RD_SILENCE_MODE, pApCliEntry->wdev.channel, pDot11h)) { + if (pApCliEntry->bPeerExist == TRUE) { + /* Got peer's beacon; change to normal mode */ + pDot11h->RDCount = pDot11h->ChMovingTime; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("ApCliIfUp - PeerExist\n")); + } else + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("ApCliIfUp - Stop probing while Radar state is silent\n")); + + continue; + } + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("(%s) ApCli interface[%d] startup.\n", __func__, ifIndex)); + MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_JOIN_REQ, 0, NULL, ifIndex); + /* Reset bPeerExist each time in case we could keep old status */ + pApCliEntry->bPeerExist = FALSE; + } + +#ifdef APCLI_CONNECTION_TRIAL + else if ( + APCLI_IF_UP_CHECK(pAd, ifIndex) + && (*pCurrState == APCLI_CTRL_DISCONNECTED)/* Apcli1 is not connected state. */ + && (pApCliEntry->TrialCh != 0) + /* && NdisCmpMemory(pApCliEntry->ApCliMlmeAux.Ssid, pApCliEntry->CfgSsid, pApCliEntry->SsidLen) != 0 */ + && (pApCliEntry->CfgSsidLen != 0) + && (pApCliEntry->Enable != 0) + /* new ap ssid shall different from the origin one. */ + ) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("(%s) Enqueue APCLI_CTRL_TRIAL_CONNECT\n", __func__)); + MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_TRIAL_CONNECT, 0, NULL, ifIndex); + /* Reset bPeerExist each time in case we could keep old status */ + pApCliEntry->bPeerExist = FALSE; + } + +#endif /* APCLI_CONNECTION_TRIAL */ + } +} + +/* + ========================================================================== + Description: + APCLI Interface Down. + ========================================================================== + */ +VOID ApCliIfDown(RTMP_ADAPTER *pAd) +{ + UCHAR ifIndex; + PAPCLI_STRUCT pApCliEntry; +#ifdef MAC_REPEATER_SUPPORT + UCHAR CliIdx, idx; + INVAILD_TRIGGER_MAC_ENTRY *pEntry = NULL; + struct _REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); +#endif /* MAC_REPEATER_SUPPORT */ + + for (ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++) { + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s():ApCli interface[%d] start down.\n", __func__, ifIndex)); + + if (pApCliEntry->Enable == TRUE) + continue; + +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + + if (wf_drv_tbl.wf_fwd_entry_delete_hook) + wf_drv_tbl.wf_fwd_entry_delete_hook(pApCliEntry->wdev.if_dev, pAd->net_dev, 1); + +#endif /* CONFIG_WIFI_PKT_FWD */ +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn) { + for (CliIdx = 0; CliIdx < GET_MAX_REPEATER_ENTRY_NUM(cap); CliIdx++) { + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + /*disconnect the ReptEntry which is bind on the CliLink*/ + if ((pReptEntry->CliEnable) && (pReptEntry->wdev == &pApCliEntry->wdev)) { + RTMP_OS_INIT_COMPLETION(&pReptEntry->free_ack); + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_APCLI_IF_DOWN; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + ReptWaitLinkDown(pReptEntry); + } + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + RTMP_OS_INIT_COMPLETION(&pApCliEntry->linkdown_complete); + pApCliEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_APCLI_IF_DOWN; + MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex); + RTMP_MLME_HANDLER(pAd); + ApCliWaitLinkDown(pApCliEntry); + } + +#ifdef MAC_REPEATER_SUPPORT + + for (idx = 0; idx < MAX_IGNORE_AS_REPEATER_ENTRY_NUM; idx++) { + pEntry = &pAd->ApCfg.ReptControl.IgnoreAsRepeaterEntry[idx]; + + if (pAd->ApCfg.ApCliInfRunned == 0) + RepeaterRemoveIngoreEntry(pAd, idx, pEntry->MacAddr); + } + +#endif /* MAC_REPEATER_SUPPORT */ +} + + +/* + ========================================================================== + Description: + APCLI Interface Monitor. + ========================================================================== + */ +VOID ApCliIfMonitor(RTMP_ADAPTER *pAd) +{ + UCHAR index; + APCLI_STRUCT *pApCliEntry; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + /* Reset is in progress, stop immediately */ + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) || + !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) + return; + + if (ScanRunning(pAd) == TRUE) + return; + + for (index = 0; index < MAX_APCLI_NUM; index++) { + UCHAR Wcid; + PMAC_TABLE_ENTRY pMacEntry; + STA_TR_ENTRY *tr_entry; + BOOLEAN bForceBrocken = FALSE; + BOOLEAN bWpa_4way_too_log = FALSE; + BOOLEAN bBeacon_miss = FALSE; +#ifdef APCLI_CONNECTION_TRIAL + + if (index == (pAd->ApCfg.ApCliNum-1))/* last IF is for apcli connection trial */ + continue;/* skip apcli1 monitor. FIXME:Carter shall find a better way. */ + +#endif /* APCLI_CONNECTION_TRIAL */ + pApCliEntry = &pAd->ApCfg.ApCliTab[index]; + + /* sanity check whether the interface is initialized. */ + if (pApCliEntry->ApCliInit != TRUE) + continue; + +#ifdef MAC_REPEATER_SUPPORT + RepeaterLinkMonitor(pAd); +#endif /* MAC_REPEATER_SUPPORT */ + + if (pApCliEntry->Valid == TRUE) { + BOOLEAN ApclibQosNull = FALSE; + + Wcid = pAd->ApCfg.ApCliTab[index].MacTabWCID; + + if (!VALID_UCAST_ENTRY_WCID(pAd, Wcid)) + continue; + + pMacEntry = &pAd->MacTab.Content[Wcid]; + tr_entry = &pAd->MacTab.tr_entry[Wcid]; + + if ((IS_AKM_WPA_CAPABILITY(pMacEntry->SecConfig.AKMMap)) + && (tr_entry->PortSecured != WPA_802_1X_PORT_SECURED) + && (RTMP_TIME_AFTER(pAd->Mlme.Now32, (pApCliEntry->ApCliLinkUpTime + (30 * OS_HZ))))) { + bWpa_4way_too_log = TRUE; + bForceBrocken = TRUE; + } + + { +#ifdef CONFIG_MULTI_CHANNEL + /* increase to 12 */ + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, (pApCliEntry->ApCliRcvBeaconTime + (12 * OS_HZ)))) { +#else +#ifdef MT7615 +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + + if (cap->fgRateAdaptFWOffload == TRUE) { + if ((RTMP_TIME_AFTER(pAd->Mlme.Now32, pApCliEntry->ApCliRcvBeaconTime + (1 * OS_HZ))) + && (RTMP_TIME_BEFORE(pAd->Mlme.Now32, pApCliEntry->ApCliRcvBeaconTime + (3 * OS_HZ)))) { + pMacEntry->TxStatRspCnt = 0; + pMacEntry->TotalTxSuccessCnt = 0; + } + + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pApCliEntry->ApCliRcvBeaconTime + (1 * OS_HZ))) + HW_GET_TX_STATISTIC(pAd, GET_TX_STAT_ENTRY_TX_CNT, pMacEntry->wcid); + } + +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ +#endif /* MT7615 */ + + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, (pApCliEntry->ApCliRcvBeaconTime + (6 * OS_HZ)))) { +#endif /* CONFIG_MULTI_CHANNEL */ +#ifdef MT7615 +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + + if ((cap->fgRateAdaptFWOffload == TRUE) && + (pMacEntry->TxStatRspCnt > 1) && (pMacEntry->TotalTxSuccessCnt)) + pApCliEntry->ApCliRcvBeaconTime = pAd->Mlme.Now32; + else +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ +#endif /* MT7615 */ + { + bBeacon_miss = TRUE; + bForceBrocken = TRUE; + } + } + } + if (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)) + ApclibQosNull = TRUE; + + if ((bForceBrocken == FALSE) +#ifdef CONFIG_MULTI_CHANNEL + && (pAd->Mlme.bStartMcc == FALSE) +#endif /* CONFIG_MULTI_CHANNEL */ + ) + { +#if (defined(WH_EZ_SETUP) && defined(RACTRL_FW_OFFLOAD_SUPPORT)) + UCHAR idx, Total; + + if(IS_ADPTR_EZ_SETUP_ENABLED(pAd)){ + if (cap->fgRateAdaptFWOffload == TRUE) + Total = 3; + else + Total = 1; + + for(idx = 0; idx < Total; idx++) + ApCliRTMPSendNullFrame(pAd, pMacEntry->CurrTxRate, ApclibQosNull, pMacEntry, PWR_ACTIVE); + } + else +#endif + ApCliRTMPSendNullFrame(pAd, pMacEntry->CurrTxRate, ApclibQosNull, pMacEntry, PWR_ACTIVE); + } + } else + continue; + + if (bForceBrocken == TRUE) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("ApCliIfMonitor: IF(apcli%d) - no Beancon is received from root-AP.\n", index)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("ApCliIfMonitor: Reconnect the Root-Ap again.\n")); +#ifdef CONFIG_MULTI_CHANNEL + + if (pAd->Mlme.bStartMcc == TRUE) + return; + +#endif /* CONFIG_MULTI_CHANNEL */ + + if (bBeacon_miss) { + ULONG Now32; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("ApCliIfMonitor apcli%d time1: %lu\n", index, pApCliEntry->ApCliRcvBeaconTime_MlmeEnqueueForRecv)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("ApCliIfMonitor apcli%d time2: %lu\n", index, pApCliEntry->ApCliRcvBeaconTime_MlmeEnqueueForRecv_2)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("ApCliIfMonitor apcli%d time3: %lu\n", index, pApCliEntry->ApCliRcvBeaconTime)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("ApCliIfMonitor apcli%d OS_HZ: %d\n", index, OS_HZ)); + NdisGetSystemUpTime(&Now32); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("ApCliIfMonitor apcli%d time now: %lu\n", index, Now32)); + } + + /* MCC TODO: WCID Not Correct when MCC on */ +#ifdef MCC_TEST +#else +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn) { + APCLI_STRUCT *apcli_entry = pApCliEntry; + REPEATER_CLIENT_ENTRY *pReptEntry; + UCHAR CliIdx; + + for (CliIdx = 0; CliIdx < GET_MAX_REPEATER_ENTRY_NUM(cap); CliIdx++) { + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + if ((pReptEntry->CliEnable) && (pReptEntry->wdev == &apcli_entry->wdev)) { + if (bBeacon_miss) + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_MNT_NO_BEACON; + else + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_APCLI_TRIGGER_TOO_LONG; + + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + } + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + + if (bBeacon_miss) + pApCliEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_MNT_NO_BEACON; + else + pApCliEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_APCLI_TRIGGER_TOO_LONG; + + MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, index); + RTMP_MLME_HANDLER(pAd); +#endif /* MCC_TEST */ + } + } + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_LOUD, ("ra offload=%d\n", cap->fgRateAdaptFWOffload)); +} + + +/*! \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 */ + unsigned char hdr_len = LENGTH_802_11; + + + + /* 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 == FC_TYPE_DATA) { +#ifdef WSC_AP_SUPPORT + /*WSC EAPOL PACKET */ + pEntry = MacTableLookup(pAd, pFrame->Hdr.Addr2); + + if (pEntry && IS_ENTRY_APCLI(pEntry) && pAd->ApCfg.ApCliTab[pEntry->func_tb_idx].wdev.WscControl.WscConfMode == WSC_ENROLLEE) { + *Machine = WSC_STATE_MACHINE; + EAPType = *((UCHAR *)pFrame + hdr_len + LENGTH_802_1_H + 1); + EAPCode = *((UCHAR *)pFrame + hdr_len + LENGTH_802_1_H + 4); + Return = WscMsgTypeSubst(EAPType, EAPCode, MsgType); + } + + if (!Return) +#endif /* WSC_AP_SUPPORT */ + { + *Machine = WPA_STATE_MACHINE; + EAPType = *((UCHAR *)pFrame + hdr_len + LENGTH_802_1_H + 1); + Return = WpaMsgTypeSubst(EAPType, MsgType); + } + + return Return; + } else if (pFrame->Hdr.FC.Type == FC_TYPE_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 == FC_TYPE_MGMT) { + switch (pFrame->Hdr.FC.SubType) { + /* Beacon must be processed by 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, + OUT IE_LISTS * ie_list) +{ + 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)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s(): fail - wrong SupportedRates IE\n", __func__)); + return FALSE; + } + 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)); + *(UINT32 *) (&pHtCapability->TxBFCap) = cpu2le32(*(UINT32 *)(&pHtCapability->TxBFCap)); + *pHtCapabilityLen = SIZE_HT_CAP_IE; + } else + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_WARN, ("%s():wrong IE_HT_CAP\n", __func__)); + + 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 + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_WARN, ("%s():wrong IE_ADD_HT\n", __func__)); + + break; + + case IE_SECONDARY_CH_OFFSET: + if (pEid->Len == 1) + *pNewExtChannelOffset = pEid->Octet[0]; + else + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_WARN, ("%s():wrong IE_SECONDARY_CH_OFFSET\n", __func__)); + + break; +#ifdef DOT11_VHT_AC + + case IE_VHT_CAP: + if (pEid->Len == sizeof(VHT_CAP_IE)) { + NdisMoveMemory(&ie_list->vht_cap, pEid->Octet, sizeof(VHT_CAP_IE)); + ie_list->vht_cap_len = sizeof(VHT_CAP_IE); + } else + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_WARN, ("%s():wrong IE_VHT_CAP\n", __func__)); + + break; + + case IE_VHT_OP: + if (pEid->Len == sizeof(VHT_OP_IE)) { + NdisMoveMemory(&ie_list->vht_op, pEid->Octet, sizeof(VHT_OP_IE)); + ie_list->vht_op_len = sizeof(VHT_OP_IE); + } else + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_WARN, ("%s():wrong IE_VHT_OP\n", __func__)); + + break; +#endif /* DOT11_VHT_AC */ +#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: + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s():ignore unrecognized EID = %d\n", __func__, pEid->Eid)); + break; + } + + Length = Length + 2 + pEid->Len; + pEid = (PEID_STRUCT)((UCHAR *)pEid + 2 + pEid->Len); + } + + return TRUE; +} + + +MAC_TABLE_ENTRY *ApCliTableLookUpByWcid(RTMP_ADAPTER *pAd, UCHAR wcid, UCHAR *pAddrs) +{ + ULONG ApCliIndex; + PMAC_TABLE_ENTRY pCurEntry = NULL; + PMAC_TABLE_ENTRY pEntry = NULL; + + if (!VALID_UCAST_ENTRY_WCID(pAd, wcid)) + return NULL; + + NdisAcquireSpinLock(&pAd->MacTabLock); + + do { + pCurEntry = &pAd->MacTab.Content[wcid]; + ApCliIndex = 0xff; + + if ((pCurEntry) && + (IS_ENTRY_APCLI(pCurEntry) || IS_ENTRY_REPEATER(pCurEntry)) + ) + ApCliIndex = pCurEntry->func_tb_idx; + + 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 Apcli Entry is valid or not. + ========================================================================== + */ +static inline BOOLEAN ValidApCliEntry(RTMP_ADAPTER *pAd, 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->Enable != TRUE) { + result = FALSE; + break; + } + + if ((!VALID_UCAST_ENTRY_WCID(pAd, pApCliEntry->MacTabWCID)) + /* || (pApCliEntry->MacTabWCID < 0) //MacTabWCID is UCHAR, no need to check */ + ) { + result = FALSE; + break; + } + + pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID]; + + if (!IS_ENTRY_APCLI(pMacEntry)) { + result = FALSE; + break; + } + + result = TRUE; + } while (FALSE); + + return result; +} + +INT apcli_fp_tx_pkt_allowed( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *wdev, + IN PNDIS_PACKET pkt) +{ + UCHAR idx; + BOOLEAN allowed = FALSE; + APCLI_STRUCT *apcli_entry; +#ifdef MAC_REPEATER_SUPPORT + UINT Ret = 0; +#endif + UCHAR wcid = RTMP_GET_PACKET_WCID(pkt); + UCHAR frag_nums; + + for (idx = 0; idx < MAX_APCLI_NUM; idx++) { + apcli_entry = &pAd->ApCfg.ApCliTab[idx]; + + if (&apcli_entry->wdev == wdev) { + if (ValidApCliEntry(pAd, idx) == FALSE) + break; + +#ifdef MAC_REPEATER_SUPPORT + if ((pAd->ApCfg.bMACRepeaterEn == TRUE) + ) { + Ret = ReptTxPktCheckHandler(pAd, wdev, pkt, &wcid); + + if (Ret == REPEATER_ENTRY_EXIST) { + allowed = TRUE; + } else if (Ret == INSERT_REPT_ENTRY) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("apcli_fp_tx_pkt_allowed: return FALSE as ReptTxPktCheckHandler indicated INSERT_REPT_ENTRY\n")); + allowed = FALSE; + } else if (Ret == INSERT_REPT_ENTRY_AND_ALLOW) { + allowed = TRUE; + } else if (Ret == USE_CLI_LINK_INFO) { + wcid = apcli_entry->MacTabWCID; + allowed = TRUE; + } + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + pAd->RalinkCounters.PendingNdisPacketCount++; + RTMP_SET_PACKET_WDEV(pkt, wdev->wdev_idx); + wcid = apcli_entry->MacTabWCID; + allowed = TRUE; + } + + break; + } + } + + if (allowed) { + RTMP_SET_PACKET_WCID(pkt, wcid); + frag_nums = get_frag_num(pAd, wdev, pkt); + RTMP_SET_PACKET_FRAGMENTS(pkt, frag_nums); + + /* ethertype check is not offload to mcu for fragment frame*/ + if (frag_nums > 1) { + if (!RTMPCheckEtherType(pAd, pkt, &pAd->MacTab.tr_entry[wcid], wdev)) + allowed = FALSE; + } + } + + return allowed; +} + +INT apcli_tx_pkt_allowed( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *wdev, + IN PNDIS_PACKET pkt) +{ + UCHAR idx; + BOOLEAN allowed = FALSE; + APCLI_STRUCT *apcli_entry; +#ifdef MAC_REPEATER_SUPPORT + UINT Ret = 0; +#endif + UCHAR wcid = RTMP_GET_PACKET_WCID(pkt); + UCHAR frag_nums; + + for (idx = 0; idx < MAX_APCLI_NUM; idx++) { + apcli_entry = &pAd->ApCfg.ApCliTab[idx]; + + if (&apcli_entry->wdev == wdev) { + if (ValidApCliEntry(pAd, idx) == FALSE) + break; + +#ifdef MAC_REPEATER_SUPPORT + if ((pAd->ApCfg.bMACRepeaterEn == TRUE) + ) { + Ret = ReptTxPktCheckHandler(pAd, wdev, pkt, &wcid); + + if (Ret == REPEATER_ENTRY_EXIST) { + allowed = TRUE; + } else if (Ret == INSERT_REPT_ENTRY) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("apcli_tx_pkt_allowed: return FALSE as ReptTxPktCheckHandler indicated INSERT_REPT_ENTRY\n")); + allowed = FALSE; + } else if (Ret == INSERT_REPT_ENTRY_AND_ALLOW) { + allowed = TRUE; + } else if (Ret == USE_CLI_LINK_INFO) { + wcid = apcli_entry->MacTabWCID; + allowed = TRUE; + } + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + pAd->RalinkCounters.PendingNdisPacketCount++; + RTMP_SET_PACKET_WDEV(pkt, wdev->wdev_idx); + wcid = apcli_entry->MacTabWCID; + allowed = TRUE; + } + + break; + } + } + + if (allowed) { + RTMP_SET_PACKET_WCID(pkt, wcid); + frag_nums = get_frag_num(pAd, wdev, pkt); + RTMP_SET_PACKET_FRAGMENTS(pkt, frag_nums); + + if (!RTMPCheckEtherType(pAd, pkt, &pAd->MacTab.tr_entry[wcid], wdev)) + 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 RTMP_ADAPTER *pAd, + IN PEID_STRUCT pEid_ptr, + IN USHORT eid_len, + IN USHORT idx, + IN UCHAR Privacy) +{ + PUCHAR pVIE, pTmp; + UCHAR len; + PEID_STRUCT pEid; + PAPCLI_STRUCT pApCliEntry = NULL; + USHORT Count; + PRSN_IE_HEADER_STRUCT pRsnHeader; + PCIPHER_SUITE_STRUCT pCipher; + PAKM_SUITE_STRUCT pAKM; + struct _SECURITY_CONFIG *pSecConfig; + UINT32 AKMMap = 0; + UINT32 PairwiseCipher = 0; + UINT32 GroupCipher = 0; + UCHAR end_field = 0; + UCHAR res = TRUE; + + pVIE = (PUCHAR) pEid_ptr; + len = eid_len; + pApCliEntry = &pAd->ApCfg.ApCliTab[idx]; + pSecConfig = &pApCliEntry->wdev.SecConfig; + + if (IS_SECURITY(pSecConfig) && (Privacy == 0)) { + return FALSE; /* None matched*/ + } else if (IS_NO_SECURITY(pSecConfig) && (Privacy == 1)) { + return FALSE; /* None matched*/ + } else if (IS_NO_SECURITY(pSecConfig) && (Privacy == 0)) { + CLEAR_SEC_AKM(pApCliEntry->MlmeAux.AKMMap); + CLEAR_CIPHER(pApCliEntry->MlmeAux.PairwiseCipher); + CLEAR_CIPHER(pApCliEntry->MlmeAux.GroupCipher); + SET_AKM_OPEN(pApCliEntry->MlmeAux.AKMMap); + SET_CIPHER_NONE(pApCliEntry->MlmeAux.PairwiseCipher); + SET_CIPHER_NONE(pApCliEntry->MlmeAux.GroupCipher); + return TRUE; /* No Security */ + } + + AKMMap = pApCliEntry->MlmeAux.AKMMap; + PairwiseCipher = pApCliEntry->MlmeAux.PairwiseCipher; + GroupCipher = pApCliEntry->MlmeAux.GroupCipher; + + + CLEAR_SEC_AKM(pApCliEntry->MlmeAux.AKMMap); + CLEAR_CIPHER(pApCliEntry->MlmeAux.PairwiseCipher); + CLEAR_CIPHER(pApCliEntry->MlmeAux.GroupCipher); + + /* 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: + SET_CIPHER_WEP40(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 5: + SET_CIPHER_WEP104(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 2: + SET_CIPHER_TKIP(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 4: + SET_CIPHER_CCMP128(pApCliEntry->MlmeAux.GroupCipher); + break; + + default: + break; + } + + /* number of unicast suite*/ + pTmp += 1; + /* skip all unicast cipher suites*/ + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + + /* Parsing all unicast cipher suite*/ + while (Count > 0) { + /* Skip OUI*/ + pTmp += 3; + + switch (*pTmp) { + case 1: + SET_CIPHER_WEP40(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway*/ + SET_CIPHER_WEP104(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 2: + SET_CIPHER_TKIP(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 4: + SET_CIPHER_CCMP128(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + default: + break; + } + + pTmp++; + Count--; + } + + /* 4. get AKM suite counts*/ + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + pTmp += 3; + + switch (*pTmp) { + case 1: + /* Set AP support WPA-enterprise mode*/ + SET_AKM_WPA1(pApCliEntry->MlmeAux.AKMMap); + break; + + case 2: + /* Set AP support WPA-PSK mode*/ + SET_AKM_WPA1PSK(pApCliEntry->MlmeAux.AKMMap); + break; + + default: + break; + } + + pTmp += 1; + break; /* End of case IE_WPA */ + + case IE_RSN: + pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp; + res = wpa_rsne_sanity(pTmp, le2cpu16(pRsnHeader->Length) + 2, &end_field); + + if (res == FALSE) + break; + + if (end_field < RSN_FIELD_GROUP_CIPHER) + SET_CIPHER_CCMP128(pApCliEntry->MlmeAux.GroupCipher); + if (end_field < RSN_FIELD_PAIRWISE_CIPHER) + SET_CIPHER_CCMP128(pApCliEntry->MlmeAux.PairwiseCipher); + if (end_field < RSN_FIELD_AKM) + SET_AKM_WPA2(pApCliEntry->MlmeAux.AKMMap); + + /* 0. Version must be 1*/ + if (le2cpu16(pRsnHeader->Version) != 1) + break; + + /* 1. Check group cipher*/ + if (end_field < RSN_FIELD_GROUP_CIPHER) + break; + + pTmp += sizeof(RSN_IE_HEADER_STRUCT); + pCipher = (PCIPHER_SUITE_STRUCT) pTmp; + + if (!RTMPEqualMemory(&pCipher->Oui, RSN_OUI, 3)) + break; + + /* Parse group cipher*/ + switch (pCipher->Type) { + case 1: + SET_CIPHER_WEP40(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 2: + SET_CIPHER_TKIP(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 4: + SET_CIPHER_CCMP128(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 5: + SET_CIPHER_WEP104(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 8: + SET_CIPHER_GCMP128(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 9: + SET_CIPHER_GCMP256(pApCliEntry->MlmeAux.GroupCipher); + break; + + case 10: + SET_CIPHER_CCMP256(pApCliEntry->MlmeAux.GroupCipher); + break; + + default: + break; + } + + /* set to correct offset for next parsing*/ + pTmp += sizeof(CIPHER_SUITE_STRUCT); + /* 2. Get pairwise cipher counts*/ + if (end_field < RSN_FIELD_PAIRWISE_CIPHER) + break; + 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; + + switch (pCipher->Type) { + case 1: + SET_CIPHER_WEP40(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 2: + SET_CIPHER_TKIP(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 4: + SET_CIPHER_CCMP128(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 5: + SET_CIPHER_WEP104(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 8: + SET_CIPHER_GCMP128(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 9: + SET_CIPHER_GCMP256(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + case 10: + SET_CIPHER_CCMP256(pApCliEntry->MlmeAux.PairwiseCipher); + break; + + default: + break; + } + + pTmp += sizeof(CIPHER_SUITE_STRUCT); + Count--; + } + + /* 4. get AKM suite counts*/ + if (end_field < RSN_FIELD_AKM) + break; + 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: + SET_AKM_WPANONE(pApCliEntry->MlmeAux.AKMMap); + break; + + case 1: + SET_AKM_WPA2(pApCliEntry->MlmeAux.AKMMap); + break; + + case 2: + SET_AKM_WPA2PSK(pApCliEntry->MlmeAux.AKMMap); + break; + + case 3: + SET_AKM_FT_WPA2(pApCliEntry->MlmeAux.AKMMap); + break; + + case 4: + SET_AKM_FT_WPA2PSK(pApCliEntry->MlmeAux.AKMMap); + break; +#ifdef DOT11W_PMF_SUPPORT + + case 5: + SET_AKM_WPA2(pApCliEntry->MlmeAux.AKMMap); + break; + + case 6: + SET_AKM_WPA2PSK(pApCliEntry->MlmeAux.AKMMap); + break; +#else /* DOT11W_PMF_SUPPORT */ + + case 5: + SET_AKM_WPA2_SHA256(pApCliEntry->MlmeAux.AKMMap); + break; + + case 6: + SET_AKM_WPA2PSK_SHA256(pApCliEntry->MlmeAux.AKMMap); + break; +#endif /* !DOT11W_PMF_SUPPORT */ + + case 7: + SET_AKM_TDLS(pApCliEntry->MlmeAux.AKMMap); + break; + + case 8: + SET_AKM_SAE_SHA256(pApCliEntry->MlmeAux.AKMMap); + break; + + case 9: + SET_AKM_FT_SAE_SHA256(pApCliEntry->MlmeAux.AKMMap); + break; + + case 11: + SET_AKM_SUITEB_SHA256(pApCliEntry->MlmeAux.AKMMap); + break; + + case 12: + SET_AKM_SUITEB_SHA384(pApCliEntry->MlmeAux.AKMMap); + break; + + case 13: + SET_AKM_FT_WPA2_SHA384(pApCliEntry->MlmeAux.AKMMap); + break; + + case 18: + SET_AKM_OWE(pApCliEntry->MlmeAux.AKMMap); + break; + + default: + break; + } + + pTmp += sizeof(AKM_SUITE_STRUCT); + Count--; + } + + /* 6. Get RSN capability*/ + if (end_field < RSN_FIELD_RSN_CAP) + break; + /* skip RSN capability, update in ApCliPeerProbeRspAtJoinAction */ + pTmp += sizeof(USHORT); + + /* 7. get PMKID counts*/ + if (end_field < RSN_FIELD_PMKID) + break; + /*Count = *(PUSHORT) pTmp;*/ + Count = (pTmp[1] << 8) + pTmp[0]; + pTmp += sizeof(USHORT); + + /* 8. ignore PMKID */ + pTmp += 16 * Count; + + /* 9. Get Group Management Cipher Suite*/ + if (end_field < RSN_FIELD_GROUP_MGMT_CIPHER) + break; + pCipher = (PCIPHER_SUITE_STRUCT) pTmp; + if (!RTMPEqualMemory(&pCipher->Oui, RSN_OUI, 3)) + break; + switch (pCipher->Type) { + case 6: + SET_CIPHER_BIP_CMAC128(pApCliEntry->MlmeAux.IntegrityGroupCipher); + break; + + case 11: + SET_CIPHER_BIP_GMAC128(pApCliEntry->MlmeAux.IntegrityGroupCipher); + break; + + case 12: + SET_CIPHER_BIP_GMAC256(pApCliEntry->MlmeAux.IntegrityGroupCipher); + break; + + case 13: + SET_CIPHER_BIP_CMAC256(pApCliEntry->MlmeAux.IntegrityGroupCipher); + break; + default: + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: unknown Group Management Cipher Suite %d\n", __func__, pCipher->Type)); + break; + } + pTmp += sizeof(CIPHER_SUITE_STRUCT); + } + + /* skip this Eid */ + pVIE += (pEid->Len + 2); + len -= (pEid->Len + 2); + } + + if ((pApCliEntry->MlmeAux.AKMMap == 0x0) && (Privacy == 1)) { + /* WEP mode */ + if (IS_AKM_AUTOSWITCH(pSecConfig->AKMMap)) + SET_AKM_AUTOSWITCH(pApCliEntry->MlmeAux.AKMMap); + else if (IS_AKM_OPEN(pSecConfig->AKMMap)) + SET_AKM_OPEN(pApCliEntry->MlmeAux.AKMMap); + else if (IS_AKM_SHARED(pSecConfig->AKMMap)) + SET_AKM_SHARED(pApCliEntry->MlmeAux.AKMMap); + else + SET_AKM_OPEN(pApCliEntry->MlmeAux.AKMMap); + + SET_CIPHER_WEP(pApCliEntry->MlmeAux.PairwiseCipher); + SET_CIPHER_WEP(pApCliEntry->MlmeAux.GroupCipher); + } + + pApCliEntry->MlmeAux.AKMMap &= pSecConfig->AKMMap; + pApCliEntry->MlmeAux.PairwiseCipher &= pSecConfig->PairwiseCipher; + + if ((pApCliEntry->MlmeAux.AKMMap == 0) + || (pApCliEntry->MlmeAux.PairwiseCipher == 0)) { + + pApCliEntry->MlmeAux.AKMMap = AKMMap; + pApCliEntry->MlmeAux.PairwiseCipher = PairwiseCipher; + pApCliEntry->MlmeAux.GroupCipher = GroupCipher; + return FALSE; /* None matched*/ + } + /* Decide Pairwise and group cipher with AP */ + if (IS_AKM_WPA1(pApCliEntry->MlmeAux.AKMMap) && IS_AKM_WPA2(pApCliEntry->MlmeAux.AKMMap)) { + CLEAR_SEC_AKM(pApCliEntry->MlmeAux.AKMMap); + SET_AKM_WPA2(pApCliEntry->MlmeAux.AKMMap); + } else if (IS_AKM_WPA1PSK(pApCliEntry->MlmeAux.AKMMap) && IS_AKM_WPA2PSK(pApCliEntry->MlmeAux.AKMMap)) { + CLEAR_SEC_AKM(pApCliEntry->MlmeAux.AKMMap); + SET_AKM_WPA2PSK(pApCliEntry->MlmeAux.AKMMap); + } + + if (IS_CIPHER_TKIP(pApCliEntry->MlmeAux.PairwiseCipher) && IS_CIPHER_CCMP128(pApCliEntry->MlmeAux.PairwiseCipher)) { + CLEAR_CIPHER(pApCliEntry->MlmeAux.PairwiseCipher); + SET_CIPHER_CCMP128(pApCliEntry->MlmeAux.PairwiseCipher); + } + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("%s(): Candidate Security AKMMap=%s, PairwiseCipher=%s, GroupCipher=%s\n", + __func__, + GetAuthModeStr(pApCliEntry->MlmeAux.AKMMap), + GetEncryModeStr(pApCliEntry->MlmeAux.PairwiseCipher), + GetEncryModeStr(pApCliEntry->MlmeAux.GroupCipher))); + return TRUE; +} + +BOOLEAN ApCliHandleRxBroadcastFrame( + IN RTMP_ADAPTER *pAd, + IN RX_BLK * pRxBlk, + IN MAC_TABLE_ENTRY *pEntry) +{ + APCLI_STRUCT *pApCliEntry = NULL; +#ifdef MAC_REPEATER_SUPPORT + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; +#endif /* MAC_REPEATER_SUPPORT */ + /* + 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->func_tb_idx]; + + /* 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(pRxBlk->Addr3, pApCliEntry->wdev.if_addr)) + return FALSE; + + if (pEntry->PrivacyFilter != Ndis802_11PrivFilterAcceptAll) + return FALSE; + +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn + ) { + pReptEntry = RTMPLookupRepeaterCliEntry(pAd, FALSE, pRxBlk->Addr3, TRUE); + + if (pReptEntry){ + //MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, + // ("ApCliHandleRxBroadcastFrame: return FALSE pReptEntry found\n")); + return FALSE; /* give up this frame */ + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + 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(RTMP_ADAPTER *pAd, USHORT ifIndex) +{ + 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; + struct wifi_dev *wdev; + struct dev_rate_info *rate; + PAPCLI_STRUCT pApCliEntry = NULL; + + if (ifIndex >= MAX_APCLI_NUM) + return; + + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + wdev = &pApCliEntry->wdev; + rate = &wdev->rate; + + switch (wdev->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): +#ifdef DOT11_VHT_AC + case (WMODE_A | WMODE_B | WMODE_G | WMODE_GN | WMODE_AN | WMODE_AC): +#endif /* DOT11_VHT_AC */ +#endif /* DOT11_N_SUPPORT */ + if ((pApCliEntry->MlmeAux.SupRateLen == 4) && + (pApCliEntry->MlmeAux.ExtRateLen == 0)) + ProperMlmeRate = RATE_11; /* B only AP */ + else + ProperMlmeRate = RATE_24; + + if (pApCliEntry->MlmeAux.Channel <= 14) + MinimumRate = RATE_1; + else + MinimumRate = RATE_6; + + break; + + case (WMODE_A): +#ifdef DOT11_N_SUPPORT + case (WMODE_GN): + case (WMODE_G | WMODE_GN): + case (WMODE_A | WMODE_G | WMODE_AN | WMODE_GN): + case (WMODE_A | WMODE_AN): + case (WMODE_AN): +#ifdef DOT11_VHT_AC + case (WMODE_AC): + case (WMODE_AN | WMODE_AC): + case (WMODE_A | WMODE_AN | WMODE_AC): +#endif /* DOT11_VHT_AC */ +#endif /* DOT11_N_SUPPORT */ + ProperMlmeRate = RATE_24; + MinimumRate = RATE_6; + break; + + case (WMODE_B | WMODE_A | WMODE_G): + ProperMlmeRate = RATE_24; + + if (pApCliEntry->MlmeAux.Channel <= 14) + MinimumRate = RATE_1; + else + MinimumRate = RATE_6; + + break; + + default: /* error */ + ProperMlmeRate = RATE_1; + MinimumRate = RATE_1; + break; + } + + for (i = 0; i < pApCliEntry->MlmeAux.SupRateLen; i++) { + for (j = 0; j < RateIdx; j++) { + if ((pApCliEntry->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j]) { + if (j == ProperMlmeRate) { + bMatch = TRUE; + break; + } + } + } + + if (bMatch) + break; + } + + if (bMatch == FALSE) { + for (i = 0; i < pApCliEntry->MlmeAux.ExtRateLen; i++) { + for (j = 0; j < RateIdx; j++) { + if ((pApCliEntry->MlmeAux.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_AP_STATUS_MEDIA_STATE_CONNECTED)) { + pAd->CommonCfg.MlmeRate = MinimumRate; + pAd->CommonCfg.RtsRate = ProperMlmeRate; + + if (pAd->CommonCfg.MlmeRate >= RATE_6) { + rate->MlmeTransmit.field.MODE = MODE_OFDM; + rate->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 { + rate->MlmeTransmit.field.MODE = MODE_CCK; + rate->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; + } + } + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s():=>MlmeTransmit=0x%x, MinimumRate=%d, ProperMlmeRate=%d\n", + __func__, rate->MlmeTransmit.word, MinimumRate, ProperMlmeRate)); +} + + +VOID ApCliCheckPeerExistence(RTMP_ADAPTER *pAd, CHAR *Ssid, UCHAR SsidLen, UCHAR Channel) +{ + UCHAR ifIndex; + APCLI_STRUCT *pApCliEntry; + + for (ifIndex = 0; ifIndex < MAX_APCLI_NUM; ifIndex++) { + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + if (pApCliEntry->bPeerExist == TRUE) + continue; + else if (Channel == pApCliEntry->wdev.channel && + ((SsidLen == pApCliEntry->CfgSsidLen && NdisEqualMemory(Ssid, pApCliEntry->CfgSsid, SsidLen)) || + SsidLen == 0 /* Hidden */)) + pApCliEntry->bPeerExist = TRUE; + else { + /* No Root AP match the SSID */ + } + } +} + + +VOID ApCliPeerCsaAction(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, BCN_IE_LIST *ie_list) +{ + struct DOT11_H *pDot11h = NULL; + + if (wdev == NULL) + return; + + pDot11h = wdev->pDot11_H; + + if (pAd == NULL || ie_list == NULL) + return; + + if (pDot11h == NULL) + return; + + if ((pAd->CommonCfg.bIEEE80211H == 1) && + ie_list->NewChannel != 0 && + wdev->channel != ie_list->NewChannel && + pDot11h->RDMode != RD_SWITCHING_MODE) { +#ifdef DOT11_VHT_AC +{ + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + if (IS_CAP_BW160(cap)) { + + VHT_OP_INFO *vht_op = &ie_list->vht_op_ie.vht_op_info; + + print_vht_op_info(vht_op); + wlan_operate_set_cen_ch_2(wdev, vht_op->center_freq_2); + } +} +#endif /* DOT11_VHT_AC */ + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("[APCLI] Following root AP to switch channel to ch%u\n", + ie_list->NewChannel)); + rtmp_set_channel(pAd, wdev, ie_list->NewChannel); + } +} + +static void apcli_sync_wdev(struct _RTMP_ADAPTER *pAd, struct wifi_dev *wdev) +{ + struct wifi_dev *ap_wdev = NULL; + + if (pAd->CommonCfg.dbdc_mode == TRUE) { + int mbss_idx; + + /*for 5G+5G case choose both phymode & func_idx the same first.*/ + for (mbss_idx = 0; mbss_idx < pAd->ApCfg.BssidNum; mbss_idx++) { + if (pAd->ApCfg.MBSSID[mbss_idx].wdev.PhyMode == wdev->PhyMode && wdev->func_idx == mbss_idx) { + ap_wdev = &pAd->ApCfg.MBSSID[mbss_idx].wdev; + update_att_from_wdev(wdev, ap_wdev); + } + } + + if (ap_wdev) + return; + + /*original rule*/ + for (mbss_idx = 0; mbss_idx < pAd->ApCfg.BssidNum; mbss_idx++) { + if (pAd->ApCfg.MBSSID[mbss_idx].wdev.PhyMode == wdev->PhyMode){ + update_att_from_wdev(wdev, &pAd->ApCfg.MBSSID[mbss_idx].wdev); + } + } + } else { + /* align phy mode to BSS0 by default */ + wdev->PhyMode = pAd->ApCfg.MBSSID[BSS0].wdev.PhyMode; + update_att_from_wdev(wdev, &pAd->ApCfg.MBSSID[BSS0].wdev); + } +} + +BOOLEAN apcli_fill_non_offload_tx_blk(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + PACKET_INFO PacketInfo; + PNDIS_PACKET pPacket; + MAC_TABLE_ENTRY *pMacEntry = NULL; + struct wifi_dev_ops *ops = wdev->wdev_ops; + pPacket = pTxBlk->pPacket; + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); + pTxBlk->wmm_set = HcGetWmmIdx(pAd, wdev); + pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket); + pTxBlk->FrameGap = IFS_HTTXOP; + pTxBlk->pMbss = NULL; + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader; + + if (IS_ASIC_CAP(pAd, fASIC_CAP_TX_HDR_TRANS)) { + if ((pTxBlk->TxFrameType == TX_LEGACY_FRAME) || + (pTxBlk->TxFrameType == TX_AMSDU_FRAME) || + (pTxBlk->TxFrameType == TX_MCAST_FRAME)) + TX_BLK_SET_FLAG(pTxBlk, fTX_HDR_TRANS); + } + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); + else + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame); + + + if (pTxBlk->tr_entry->EntryType == ENTRY_CAT_MCAST) { + pTxBlk->pMacEntry = NULL; + TX_BLK_SET_FLAG(pTxBlk, fTX_ForceRate); + { +#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_TO_REMOVE].HTPhyMode; + + if (pTxBlk->wdev->channel > 14) { + pTxBlk->pTransmit->field.MODE = MODE_OFDM; + pTxBlk->pTransmit->field.MCS = MCS_RATE_6; + } + } + } + /* AckRequired = FALSE, when broadcast packet in Adhoc mode.*/ + TX_BLK_CLEAR_FLAG(pTxBlk, (fTX_bAckRequired | fTX_bAllowFrag | 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; + + if (!pMacEntry) + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():Err!! pMacEntry is NULL!!\n", __func__)); + else + pTxBlk->pMbss = pMacEntry->pMbss; + +#ifdef MULTI_WMM_SUPPORT + + if (IS_ENTRY_APCLI(pMacEntry)) + pTxBlk->QueIdx = EDCA_WMM1_AC0_PIPE; + +#endif /* MULTI_WMM_SUPPORT */ + /* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.*/ +#ifdef MULTI_WMM_SUPPORT + + if (pTxBlk->QueIdx >= EDCA_WMM1_AC0_PIPE) { + if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx - EDCA_WMM1_AC0_PIPE] != NORMAL_ACK) + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); + else + TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); + } else +#endif /* MULTI_WMM_SUPPORT */ + { + if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK) + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); + else + TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); + } + + { + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (pMacEntry && (IS_ENTRY_APCLI(pMacEntry) || IS_ENTRY_REPEATER(pMacEntry)) && + ((pTxBlk->TxFrameType != TX_MCAST_FRAME) && + (pTxBlk->TxFrameType != TX_MLME_DATAQ_FRAME) && + (pTxBlk->TxFrameType != TX_MLME_MGMTQ_FRAME))) { +#ifdef MAT_SUPPORT + PNDIS_PACKET apCliPkt = NULL; + UCHAR *pMacAddr = NULL; +#ifdef MAC_REPEATER_SUPPORT + + if ((pMacEntry->bReptCli) && (pAd->ApCfg.bMACRepeaterEn)) { + UCHAR tmpIdx; + + pAd->MatCfg.bMACRepeaterEn = pAd->ApCfg.bMACRepeaterEn; + + if (pAd->ApCfg.MACRepeaterOuiMode != CASUALLY_DEFINE_MAC_ADDR) { + tmpIdx = REPT_MLME_START_IDX + pMacEntry->MatchReptCliIdx; + /* TODO: shiang-lock, fix ME! */ + apCliPkt = (PNDIS_PACKET)MATEngineTxHandle(pAd, pPacket, tmpIdx, pTxBlk->OpMode); + pMacAddr = &pAd->ApCfg.pRepeaterCliPool[pMacEntry->MatchReptCliIdx].CurrentAddress[0]; + } + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + /* For each tx packet, update our MAT convert engine databases.*/ + /* CFG_TODO */ + apCliPkt = (PNDIS_PACKET)MATEngineTxHandle(pAd, pPacket, pMacEntry->func_tb_idx, pTxBlk->OpMode); + pMacAddr = &pAd->ApCfg.ApCliTab[pMacEntry->func_tb_idx].wdev.if_addr[0]; + } + + if (apCliPkt) { + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + pPacket = apCliPkt; + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + pTxBlk->pPacket = apCliPkt; + } + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_HDR_TRANS)) { + PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); + if (pMacAddr) + NdisMoveMemory(pSrcBufVA+6, pMacAddr, MAC_ADDR_LEN); + } + +#endif /* MAT_SUPPORT */ + pTxBlk->pApCliEntry = &pAd->ApCfg.ApCliTab[pMacEntry->func_tb_idx]; + TX_BLK_SET_FLAG(pTxBlk, fTX_bApCliPacket); + } else if (pMacEntry && 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); + } + } + + if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) { + if (((RTMP_GET_PACKET_LOWRATE(pPacket)) +#ifdef UAPSD_SUPPORT + && (!(pMacEntry && (pMacEntry->bAPSDFlagSPStart))) +#endif /* UAPSD_SUPPORT */ + ) || + ((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_TO_REMOVE].HTPhyMode; + TX_BLK_SET_FLAG(pTxBlk, fTX_ForceRate); + + /* 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 (!pTxBlk->pMacEntry) + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():Err!! pTxBlk->pMacEntry is NULL!!\n", __func__)); + else 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); + } + + if (!pMacEntry) + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():Err!! pMacEntry is NULL!!\n", __func__)); + else 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); + } + + 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); + + if (!pMacEntry) + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():Err!! pMacEntry is NULL!!\n", __func__)); + else { + pMacEntry->DebugTxCount++; +#ifdef MAC_REPEATER_SUPPORT + + if (pMacEntry->bReptCli) + pMacEntry->ReptCliIdleCount = 0; + +#endif + } + } + + pAd->LastTxRate = (USHORT)pTxBlk->pTransmit->word; + ops->find_cipher_algorithm(pAd, wdev, pTxBlk); + return TRUE; +} + +BOOLEAN apcli_fill_offload_tx_blk(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + PACKET_INFO PacketInfo; + PNDIS_PACKET pPacket; + UCHAR *pMacAddr = NULL; + PMAC_TABLE_ENTRY pMacEntry = NULL; +#ifdef MAT_SUPPORT + PUCHAR pSrcBufVA = NULL; + PNDIS_PACKET convertPkt = NULL; +#endif + pPacket = pTxBlk->pPacket; + pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + + if (RTMP_GET_PACKET_MGMT_PKT(pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_CT_WithTxD); + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); + + if (IS_ASIC_CAP(pAd, fASIC_CAP_TX_HDR_TRANS)) { + if ((pTxBlk->TxFrameType == TX_LEGACY_FRAME) || + (pTxBlk->TxFrameType == TX_AMSDU_FRAME) || + (pTxBlk->TxFrameType == TX_MCAST_FRAME)) + TX_BLK_SET_FLAG(pTxBlk, fTX_HDR_TRANS); + } + + pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid]; + + if ((IS_ENTRY_APCLI(pMacEntry) || IS_ENTRY_REPEATER(pMacEntry)) && + ((pTxBlk->TxFrameType != TX_MCAST_FRAME) && + (pTxBlk->TxFrameType != TX_MLME_DATAQ_FRAME) && + (pTxBlk->TxFrameType != TX_MLME_MGMTQ_FRAME))) { +#ifdef MAT_SUPPORT +#ifdef MAC_REPEATER_SUPPORT + + if ((pMacEntry->bReptCli) && (pAd->ApCfg.bMACRepeaterEn)) { + UCHAR tmpIdx; + + pAd->MatCfg.bMACRepeaterEn = pAd->ApCfg.bMACRepeaterEn; + + if (pAd->ApCfg.MACRepeaterOuiMode != CASUALLY_DEFINE_MAC_ADDR) { + tmpIdx = REPT_MLME_START_IDX + pMacEntry->MatchReptCliIdx; + convertPkt = (PNDIS_PACKET)MATEngineTxHandle(pAd, pPacket, tmpIdx, pTxBlk->OpMode); + pMacAddr = &pAd->ApCfg.pRepeaterCliPool[pMacEntry->MatchReptCliIdx].CurrentAddress[0]; + } + } else +#endif /* MAC_REPEATER_SUPPORT */ + { + /* For each tx packet, update our MAT convert engine databases.*/ + convertPkt = (PNDIS_PACKET)MATEngineTxHandle(pAd, pPacket, pMacEntry->func_tb_idx, pTxBlk->OpMode); + pMacAddr = &pAd->ApCfg.ApCliTab[pMacEntry->func_tb_idx].wdev.if_addr[0]; + } + + if (convertPkt) { + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + pPacket = convertPkt; + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + pTxBlk->pPacket = convertPkt; + } + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_HDR_TRANS)) { + if (pMacAddr != NULL) { + if (pMacAddr) { + pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); + NdisMoveMemory(pSrcBufVA + 6, pMacAddr, MAC_ADDR_LEN); + } + } + } +#endif /* MAT_SUPPORT */ + pTxBlk->pApCliEntry = &pAd->ApCfg.ApCliTab[pMacEntry->func_tb_idx]; + pTxBlk->pMacEntry = pMacEntry; + TX_BLK_SET_FLAG(pTxBlk, fTX_bApCliPacket); +#ifdef MAC_REPEATER_SUPPORT + + if (pMacEntry->bReptCli) + pMacEntry->ReptCliIdleCount = 0; + +#endif + } + + pTxBlk->wmm_set = HcGetWmmIdx(pAd, wdev); + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader; + return TRUE; +} + +static struct wifi_dev_ops apcli_wdev_ops = { + .tx_pkt_allowed = apcli_tx_pkt_allowed, + .fp_tx_pkt_allowed = apcli_fp_tx_pkt_allowed, + .send_data_pkt = ap_send_data_pkt, + .fp_send_data_pkt = fp_send_data_pkt, + .send_mlme_pkt = ap_send_mlme_pkt, + .tx_pkt_handle = ap_tx_pkt_handle, + .fill_non_offload_tx_blk = apcli_fill_non_offload_tx_blk, + .fill_offload_tx_blk = apcli_fill_offload_tx_blk, + .legacy_tx = ap_legacy_tx, + .ampdu_tx = ap_ampdu_tx, + .frag_tx = ap_frag_tx, + .amsdu_tx = ap_amsdu_tx, + .mlme_mgmtq_tx = ap_mlme_mgmtq_tx, + .mlme_dataq_tx = ap_mlme_dataq_tx, + .ieee_802_11_data_tx = ap_ieee_802_11_data_tx, + .ieee_802_3_data_tx = ap_ieee_802_3_data_tx, + .rx_pkt_allowed = sta_rx_pkt_allow, + .rx_pkt_foward = sta_rx_fwd_hnd, + .ieee_802_3_data_rx = ap_ieee_802_3_data_rx, + .ieee_802_11_data_rx = ap_ieee_802_11_data_rx, + .find_cipher_algorithm = ap_find_cipher_algorithm, + .mac_entry_lookup = mac_entry_lookup, +}; + +VOID APCli_Init(RTMP_ADAPTER *pAd, RTMP_OS_NETDEV_OP_HOOK *pNetDevOps) +{ +#define APCLI_MAX_DEV_NUM 32 + PNET_DEV new_dev_p; + INT idx; + APCLI_STRUCT *pApCliEntry; + struct wifi_dev *wdev; + UINT8 MaxNumApcli; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + /* sanity check to avoid redundant virtual interfaces are created */ + if (pAd->flg_apcli_init != FALSE) { + for (idx = 0; idx < pAd->ApCfg.ApCliNum; idx++) { + pApCliEntry = &pAd->ApCfg.ApCliTab[idx]; + wdev = &pApCliEntry->wdev; + apcli_sync_wdev(pAd, wdev); + } + + return; + } + + /* init */ + for (idx = 0; idx < MAX_APCLI_NUM; idx++) { + pApCliEntry = &pAd->ApCfg.ApCliTab[idx]; + + if (pApCliEntry->ApCliInit != FALSE) + continue; + + pApCliEntry->wdev.if_dev = NULL; + } + + MaxNumApcli = pAd->ApCfg.ApCliNum; + + if (MaxNumApcli > MAX_APCLI_NUM) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("ApCliNum(%d) exceeds MAX_APCLI_NUM(%d)!\n", MaxNumApcli, MAX_APCLI_NUM)); + return; + } + + /* create virtual network interface */ + for (idx = 0; idx < MaxNumApcli; idx++) { + UINT32 MC_RowID = 0, IoctlIF = 0; + INT32 Ret = 0; + char *dev_name; +#ifdef MULTI_PROFILE + UCHAR final_name[32] = ""; +#endif + +#ifdef MULTIPLE_CARD_SUPPORT + MC_RowID = pAd->MC_RowID; +#endif /* MULTIPLE_CARD_SUPPORT */ +#ifdef HOSTAPD_SUPPORT + IoctlIF = pAd->IoctlIF; +#endif /* HOSTAPD_SUPPORT */ + pApCliEntry = &pAd->ApCfg.ApCliTab[idx]; + + /* sanity check to avoid redundant virtual interfaces are created */ + if (pApCliEntry->ApCliInit != FALSE) + continue; + + dev_name = get_dev_name_prefix(pAd, INT_APCLI); +#ifdef MULTI_PROFILE + if (dev_name == NULL) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("%s(): apcli interface name is null,apcli idx=%d!\n", + __func__, idx)); + break; + } + snprintf(final_name, sizeof(final_name), "%s", dev_name); + multi_profile_apcli_devname_req(pAd, final_name, &idx); + if (pAd->CommonCfg.dbdc_mode == TRUE) { + /* MULTI_PROFILE enable, apcli interface name will be apcli0,apclix0*/ + new_dev_p = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_APCLI, 0, + sizeof(struct mt_dev_priv), final_name, TRUE); + } else { + new_dev_p = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_APCLI, idx, + sizeof(struct mt_dev_priv), final_name, TRUE); + } +#else + new_dev_p = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_APCLI, idx, + sizeof(struct mt_dev_priv), dev_name, TRUE); +#endif /*MULTI_PROFILE*/ + if (!new_dev_p) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("%s(): Create net_device for %s(%d) fail!\n", + __func__, dev_name, idx)); + break; + } + +#ifdef HOSTAPD_SUPPORT + pAd->IoctlIF = IoctlIF; +#endif /* HOSTAPD_SUPPORT */ +#ifdef FAST_EAPOL_WAR + pApCliEntry->MacTabWCID = 0; + pApCliEntry->pre_entry_alloc = FALSE; +#endif /* FAST_EAPOL_WAR */ + pApCliEntry->ifIndex = idx; + pApCliEntry->pAd = pAd; + ApCliCompleteInit(pApCliEntry); + wdev = &pApCliEntry->wdev; + Ret = wdev_init(pAd, wdev, + WDEV_TYPE_APCLI, + new_dev_p, + idx, + (VOID *)pApCliEntry, + (VOID *)pAd); + + if (!Ret) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("Assign wdev idx for %s failed, free net device!\n", + RTMP_OS_NETDEV_GET_DEVNAME(new_dev_p))); + RtmpOSNetDevFree(new_dev_p); + break; + } + + Ret = wdev_ops_register(wdev, WDEV_TYPE_APCLI, &apcli_wdev_ops, + cap->wmm_detect_method); + + if (!Ret) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("register wdev_ops %s failed, free net device!\n", + RTMP_OS_NETDEV_GET_DEVNAME(new_dev_p))); + RtmpOSNetDevFree(new_dev_p); + break; + } + + COPY_MAC_ADDR(wdev->if_addr, pAd->CurrentAddress); + apcli_sync_wdev(pAd, wdev); + /*update rate info*/ + RTMPUpdateRateInfo(wdev->PhyMode, &wdev->rate); + RTMP_OS_NETDEV_SET_PRIV(new_dev_p, pAd); + RTMP_OS_NETDEV_SET_WDEV(new_dev_p, wdev); +#ifdef MT_MAC + + if (!IS_HIF_TYPE(pAd, HIF_MT)) { +#endif /* MT_MAC */ + + if (cap->MBSSIDMode >= MBSSID_MODE1) { + if ((pAd->ApCfg.BssidNum > 0) || (MAX_MESH_NUM > 0)) { + UCHAR MacMask = 0; + + if ((pAd->ApCfg.BssidNum + MAX_APCLI_NUM + MAX_MESH_NUM) <= 2) + MacMask = 0xFE; + else if ((pAd->ApCfg.BssidNum + MAX_APCLI_NUM + MAX_MESH_NUM) <= 4) + MacMask = 0xFC; + else if ((pAd->ApCfg.BssidNum + MAX_APCLI_NUM + MAX_MESH_NUM) <= 8) + MacMask = 0xF8; + + /* + 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. + */ + if (cap->MBSSIDMode == MBSSID_MODE1) { + /* + 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. + */ +#ifdef ENHANCE_NEW_MBSSID_MODE + wdev->if_addr[0] &= (MacMask << 2); +#endif /* ENHANCE_NEW_MBSSID_MODE */ + wdev->if_addr[0] |= 0x2; + wdev->if_addr[0] += (((pAd->ApCfg.BssidNum + MAX_MESH_NUM) - 1) << 2); + } + +#ifdef ENHANCE_NEW_MBSSID_MODE + else { + wdev->if_addr[0] |= 0x2; + wdev->if_addr[cap->MBSSIDMode - 1] &= (MacMask); + wdev->if_addr[cap->MBSSIDMode - 1] += + ((pAd->ApCfg.BssidNum + MAX_MESH_NUM) - 1); + } + +#endif /* ENHANCE_NEW_MBSSID_MODE */ + } + } else + wdev->if_addr[MAC_ADDR_LEN - 1] = (wdev->if_addr[MAC_ADDR_LEN - 1] + pAd->ApCfg.BssidNum + MAX_MESH_NUM) & 0xFF; + +#ifdef MT_MAC + } else { + UCHAR MacByte = 0; + UCHAR MacMask = 0xef; + UINT32 Value = 0; + RTMP_IO_READ32(pAd, LPON_BTEIR, &Value); + MacByte = Value >> 29; + if (MaxNumApcli <= 2) + MacMask = 0xef; + else if (MaxNumApcli <= 4) + MacMask = 0xcf; + + wdev->if_addr[0] |= 0x2; /* bit 1 needs to turn on for local mac address definition*/ + /* apcli can not use the same mac as MBSS,so change if_addr[0] to separate */ + if ((wdev->if_addr[0] & 0x4) == 0x4) + wdev->if_addr[0] &= ~0x4; + else + wdev->if_addr[0] |= 0x4; + + switch (MacByte) { + case 0x1: /* choose bit[23:20]*/ + wdev->if_addr[2] = wdev->if_addr[2] & MacMask;/*clear high 4 bits,*/ + wdev->if_addr[2] = (wdev->if_addr[2] | (idx << 4)); + break; + case 0x2: /* choose bit[31:28]*/ + wdev->if_addr[3] = wdev->if_addr[3] & MacMask;/*clear high 4 bits,*/ + wdev->if_addr[3] = (wdev->if_addr[3] | (idx << 4)); + break; + case 0x3: /* choose bit[39:36]*/ + wdev->if_addr[4] = wdev->if_addr[4] & MacMask;/*clear high 4 bits,*/ + wdev->if_addr[4] = (wdev->if_addr[4] | (idx << 4)); + break; + case 0x4: /* choose bit [47:44]*/ + wdev->if_addr[5] = wdev->if_addr[5] & MacMask;/*clear high 4 bits,*/ + wdev->if_addr[5] = (wdev->if_addr[5] | (idx << 4)); + break; + default: /* choose bit[15:12]*/ + wdev->if_addr[1] = wdev->if_addr[1] & MacMask;/*clear high 4 bits,*/ + wdev->if_addr[1] = (wdev->if_addr[1] | (idx << 4)); + break; + } + } + +#endif /* MT_MAC */ + pNetDevOps->priv_flags = INT_APCLI; /* we are virtual interface */ + pNetDevOps->needProtcted = TRUE; + pNetDevOps->wdev = wdev; + NdisMoveMemory(pNetDevOps->devAddr, &wdev->if_addr[0], MAC_ADDR_LEN); + /* register this device to OS */ + RtmpOSNetDevAttach(pAd->OpMode, new_dev_p, pNetDevOps); + pApCliEntry->ApCliInit = TRUE; + } + +#ifdef MAC_REPEATER_SUPPORT + CliLinkMapInit(pAd); +#endif + + pAd->flg_apcli_init = TRUE; + +} + + +VOID ApCli_Remove(RTMP_ADAPTER *pAd) +{ + UINT index; + struct wifi_dev *wdev; + + for (index = 0; index < MAX_APCLI_NUM; index++) { + wdev = &pAd->ApCfg.ApCliTab[index].wdev; + + if (wdev->if_dev) { + RtmpOSNetDevProtect(1); + RtmpOSNetDevDetach(wdev->if_dev); + RtmpOSNetDevProtect(0); + wdev_deinit(pAd, wdev); + RtmpOSNetDevFree(wdev->if_dev); + /* Clear it as NULL to prevent latter access error. */ + pAd->ApCfg.ApCliTab[index].ApCliInit = FALSE; + + pAd->flg_apcli_init = FALSE; + wdev->if_dev = NULL; + } + } +} + +/* +* ApCli_Open +*/ +INT apcli_inf_open(struct wifi_dev *wdev) +{ + struct _RTMP_ADAPTER *pAd = (struct _RTMP_ADAPTER *)wdev->sys_handle; + APCLI_STRUCT *pApCliEntry; + + +#if defined(CONFIG_FAST_NAT_SUPPORT) && (defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE)) + + if (wf_drv_tbl.wf_fwd_probe_adapter) + wf_drv_tbl.wf_fwd_probe_adapter(pAd); + + if (wf_ra_sw_nat_hook_rx_bkup != NULL) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:wf_ra_sw_nat_hook_rx_bkup:%p\n", + __func__, wf_ra_sw_nat_hook_rx_bkup)); + + wf_ra_sw_nat_hook_rx_bkup = NULL; + + +#endif + +#ifdef GREENAP_SUPPORT + /* This function will check and update allow status */ + if (greenap_check_when_if_down_up(pAd) == FALSE) + return FALSE; +#endif /* GREENAP_SUPPORT */ + + pApCliEntry = &pAd->ApCfg.ApCliTab[wdev->func_idx]; + ApCliWaitIfDown(pApCliEntry); + + /* Security initial */ + if (wdev->SecConfig.AKMMap == 0x0) + SET_AKM_OPEN(wdev->SecConfig.AKMMap); + + if (wdev->SecConfig.PairwiseCipher == 0x0) { + SET_CIPHER_NONE(wdev->SecConfig.PairwiseCipher); + SET_CIPHER_NONE(wdev->SecConfig.GroupCipher); + } + + if (wifi_sys_open(wdev) != TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() open fail!!!\n", __func__)); + return FALSE; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("APCLI inf up for apcli_%x(func_idx) OmacIdx=%d\n", + wdev->func_idx, wdev->OmacIdx)); + + RTMPSetPhyMode(pAd, wdev, wdev->PhyMode); + RTMPUpdateRateInfo(wdev->PhyMode, &wdev->rate); + + BuildChannelList(pAd, wdev); + RTMPSetPhyMode(pAd, wdev, wdev->PhyMode); + RTMPUpdateRateInfo(wdev->PhyMode, &wdev->rate); + +#ifdef WSC_INCLUDED + WscUUIDInit(pAd, wdev->func_idx, TRUE); +#endif /* WSC_INCLUDED */ + + + ApCliIfUp(pAd); + + + return TRUE; +} + +/* +* ApCli_Close +*/ +INT apcli_inf_close(struct wifi_dev *wdev) +{ + struct _RTMP_ADAPTER *pAd = (struct _RTMP_ADAPTER *)wdev->sys_handle; +#ifdef MAC_REPEATER_SUPPORT + REPEATER_CLIENT_ENTRY *pReptEntry; + UCHAR CliIdx; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); +#endif /* MAC_REPEATER_SUPPORT */ + APCLI_STRUCT *apcli_entry; + + +#ifdef GREENAP_SUPPORT + /* This function will check and update allow status */ + if (greenap_check_when_if_down_up(pAd) == FALSE) + return FALSE; +#endif /* GREENAP_SUPPORT */ + + apcli_entry = &pAd->ApCfg.ApCliTab[wdev->func_idx]; + + + + + /* send disconnect-req to sta State Machine. */ + if (apcli_entry->Enable) { +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn) { + for (CliIdx = 0; CliIdx < GET_MAX_REPEATER_ENTRY_NUM(cap); CliIdx++) { + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + if ((pReptEntry->CliEnable) && (pReptEntry->wdev == &apcli_entry->wdev)) { + RTMP_OS_INIT_COMPLETION(&pReptEntry->free_ack); + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_NONE; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + ReptWaitLinkDown(pReptEntry); + } + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + RTMP_OS_INIT_COMPLETION(&apcli_entry->linkdown_complete); + apcli_entry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_NONE; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + wdev->func_idx); + RTMP_MLME_HANDLER(pAd); + ApCliWaitLinkDown(apcli_entry); + ApCliWaitStateDisconnect(apcli_entry); +#ifdef APCLI_AUTO_CONNECT_SUPPORT + pAd->ApCfg.ApCliAutoConnectRunning[wdev->func_idx] = FALSE; +#endif + +#if defined(CONFIG_FAST_NAT_SUPPORT) && (defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE)) + if (wf_ra_sw_nat_hook_rx_bkup != NULL) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:wf_ra_sw_nat_hook_rx_bkup:%p\n", __func__, wf_ra_sw_nat_hook_rx_bkup)); + + wf_ra_sw_nat_hook_rx_bkup = NULL; + +#endif + + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("(%s) ApCli interface[%d] startdown.\n", __func__, wdev->func_idx)); + } + + if (wifi_sys_close(wdev) != TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() close fail!!!\n", __func__)); + return FALSE; + } + + /*send for ApOpen can know interface down is done*/ + ApCliIfDownComplete(apcli_entry); + + + return TRUE; +} + +#ifdef APCLI_AUTO_CONNECT_SUPPORT +#ifdef APCLI_AUTO_BW_TMP /* should be removed after apcli auto-bw is applied */ +BOOLEAN ApCliAutoConnectBWAdjust( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *wdev, + IN BSS_ENTRY * bss_entry) +{ + BOOLEAN bAdjust = FALSE; + BOOLEAN bAdjust_by_channel = FALSE; + BOOLEAN bAdjust_by_ht = FALSE; + BOOLEAN bAdjust_by_vht = FALSE; + UCHAR orig_op_ht_bw; +#ifdef DOT11_VHT_AC + UCHAR orig_op_vht_bw; + struct _RTMP_CHIP_CAP *cap = NULL; +#endif + UCHAR orig_ext_cha; + + if (pAd == NULL || wdev == NULL || bss_entry == NULL) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("(%s) Error! entry is NULL.\n", __func__)); + return FALSE; + } + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("BW info of root AP (%s):\n", bss_entry->Ssid)); + orig_op_ht_bw = wlan_operate_get_ht_bw(wdev); +#ifdef DOT11_VHT_AC + orig_op_vht_bw = wlan_operate_get_vht_bw(wdev); +#endif /*DOT11_VHT_AC*/ + orig_ext_cha = wlan_operate_get_ext_cha(wdev); + + if (wdev->channel != bss_entry->Channel) { + bAdjust = TRUE; + bAdjust_by_channel = TRUE; + } + +#ifdef DOT11_N_SUPPORT + + if (WMODE_CAP_N(wdev->PhyMode) && (bss_entry->AddHtInfoLen != 0)) { + ADD_HTINFO *add_ht_info = &bss_entry->AddHtInfo.AddHtInfo; + UCHAR op_ht_bw = wlan_operate_get_ht_bw(wdev); + UCHAR cfg_ht_bw = wlan_config_get_ht_bw(wdev); + UCHAR ext_cha = wlan_operate_get_ext_cha(wdev); + + if (!bAdjust && + ((ext_cha != add_ht_info->ExtChanOffset) || + (op_ht_bw != add_ht_info->RecomWidth))) + bAdjust = TRUE; + + if (bAdjust) { + switch (add_ht_info->RecomWidth) { /* peer side vht bw */ + case BW_20: + if (op_ht_bw == BW_40) { + wlan_operate_set_ht_bw(wdev, add_ht_info->RecomWidth, EXTCHA_NONE); + bAdjust_by_ht = TRUE; + } + + break; + case BW_40: + if (op_ht_bw == BW_20) { +#ifdef BT_APCLI_SUPPORT + if (pAd->ApCfg.ApCliAutoBWBTSupport == TRUE) { + /*set to config extension channel/bw to let ap use new configuration*/ + UCHAR mbss_idx = 0; + /*Moving both AP and CLI to 40Mhz since RootAP is working in 40Mhz */ + for (mbss_idx = 0; mbss_idx < pAd->ApCfg.BssidNum; mbss_idx++) { + struct wifi_dev *mbss_wdev; + + mbss_wdev = &pAd->ApCfg.MBSSID[mbss_idx].wdev; + + if (HcGetBandByWdev(mbss_wdev) == + HcGetBandByWdev(wdev)) { + wlan_config_set_ht_bw(mbss_wdev, + add_ht_info->RecomWidth); + wlan_config_set_ext_cha(mbss_wdev, + add_ht_info->ExtChanOffset); + } + } + /*set Config BW of CLI to 40Mhz*/ + wlan_config_set_ht_bw(wdev, add_ht_info->RecomWidth); + wlan_operate_set_ht_bw(wdev, add_ht_info->RecomWidth, + add_ht_info->ExtChanOffset); + wlan_config_set_ext_cha(wdev, add_ht_info->ExtChanOffset); + bAdjust_by_ht = TRUE; + } +#endif + } else { + if (cfg_ht_bw == BW_40) { + + UCHAR mbss_idx = 0; + for (mbss_idx = 0; mbss_idx < pAd->ApCfg.BssidNum; mbss_idx++) { + struct wifi_dev *mbss_wdev; + mbss_wdev = &pAd->ApCfg.MBSSID[mbss_idx].wdev; + if (HcGetBandByWdev(mbss_wdev) == HcGetBandByWdev(wdev)) { + wlan_config_set_ext_cha(mbss_wdev, +add_ht_info->ExtChanOffset); + } + } + wlan_config_set_ext_cha(wdev, add_ht_info->ExtChanOffset); + bAdjust_by_ht = TRUE; + } + } + break; + } + } + } + +#endif /* DOT11_N_SUPPORT */ + + +#ifdef DOT11_VHT_AC + cap = hc_get_chip_cap(pAd->hdev_ctrl); + if (WMODE_CAP_AC(wdev->PhyMode) && IS_CAP_BW160(cap) && + (bss_entry->vht_cap_len != 0) && (bss_entry->vht_op_len != 0)) { + + BOOLEAN bResetVHTBw = FALSE, bDownBW = FALSE; + UCHAR bw = VHT_BW_2040; + VHT_OP_INFO *vht_op = &bss_entry->vht_op_ie.vht_op_info; + UCHAR op_vht_bw = wlan_operate_get_vht_bw(wdev); + UCHAR cfg_vht_bw = wlan_config_get_vht_bw(wdev); + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); +#ifdef DOT11_VHT_R2 + bw = check_vht_op_bw(vht_op); +#else + bw = vht_op->ch_width; + print_vht_op_info(vht_op); +#endif /* DOT11_VHT_R2 */ + + if (!bAdjust && + (bw != op_vht_bw)) + bAdjust = TRUE; + + if (bAdjust) { + switch (bw) { /* peer side vht bw */ + case VHT_BW_2040: + if (cfg_vht_bw > VHT_BW_2040) { + bResetVHTBw = TRUE; + bDownBW = TRUE; + bAdjust_by_vht = TRUE; + } + + break; + + case VHT_BW_80: + if (cfg_vht_bw > VHT_BW_80) { + bResetVHTBw = TRUE; + bDownBW = TRUE; + bAdjust_by_vht = TRUE; + } + + break; + + case VHT_BW_160: + if (cfg_vht_bw == VHT_BW_160) { + bAdjust_by_vht = TRUE; + bResetVHTBw = 1; + } + + break; + + case VHT_BW_8080: + if (cfg_vht_bw == VHT_BW_8080) { + wlan_operate_set_cen_ch_2(wdev, vht_op->center_freq_2); + bResetVHTBw = 1; + bAdjust_by_vht = TRUE; + } + + break; + } + } + + if (bResetVHTBw) { + INT Idx = -1; + BOOLEAN bMatch = FALSE; + + for (Idx = 0; Idx < pChCtrl->ChListNum; Idx++) { + if (bss_entry->Channel == pChCtrl->ChList[Idx].Channel) { + bMatch = TRUE; + break; + } + } + + if (bMatch && (Idx < MAX_NUM_OF_CHANNELS)) { + if (bDownBW) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_OFF, + ("(%s): Follow BW info of root AP (%s) from vht_bw = %d to %d. (MAX=%d)\n", + __func__, bss_entry->Ssid, + op_vht_bw, bw, + cfg_vht_bw)); + wlan_operate_set_vht_bw(wdev, bw); + } else if (!bDownBW && (pChCtrl->ChList[Idx].Flags & CHANNEL_80M_CAP)) + wlan_operate_set_vht_bw(wdev, cfg_vht_bw); + + wlan_operate_set_cen_ch_2(wdev, vht_op->center_freq_2); + } + } + } + +#endif /* DOT11_VHT_AC */ + bAdjust = FALSE; + + if (bAdjust_by_channel == TRUE) + bAdjust = TRUE; + + if (bAdjust_by_ht == TRUE) + bAdjust = TRUE; + + if (bAdjust_by_vht == TRUE) + bAdjust = TRUE; + + if (bAdjust) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s:Adjust (%d %d %d)\n\r", __func__, + bAdjust_by_channel, bAdjust_by_ht, bAdjust_by_vht)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s:HT BW:%d to %d. MAX(%d)\n\r", __func__, + orig_op_ht_bw, wlan_operate_get_ht_bw(wdev), wlan_config_get_ht_bw(wdev))); +#ifdef DOT11_VHT_AC + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s:VHT BW:%d to %d. MAX(%d)\n\r", __func__, + orig_op_vht_bw, wlan_operate_get_vht_bw(wdev), wlan_config_get_vht_bw(wdev))); +#endif /*DOT11_VHT_AC*/ + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s:EXT CH:%d to %d\n\r", __func__, + orig_ext_cha, wlan_operate_get_ext_cha(wdev))); + } + + return bAdjust; +} +#endif /* APCLI_AUTO_BW_TMP */ + +/* + =================================================== + + Description: + Find the AP that is configured in the ApcliTab, and switch to + the channel of that AP + + Arguments: + pAd: pointer to our adapter + + Return Value: + TRUE: no error occured + FALSE: otherwise + + Note: + =================================================== +*/ +BOOLEAN ApCliAutoConnectExec( + IN PRTMP_ADAPTER pAd, + IN struct wifi_dev *wdev) +{ + UCHAR ifIdx, CfgSsidLen, entryIdx; + RTMP_STRING *pCfgSsid; + BSS_TABLE *pScanTab, *pSsidBssTab; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + INT old_ioctl_if; + INT old_ioctl_if_type; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("---> ApCliAutoConnectExec()\n")); + + if (wdev) + ifIdx = wdev->func_idx; + else + return FALSE; + + if (ifIdx >= MAX_APCLI_NUM) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Error ifIdx=%d\n", ifIdx)); + return FALSE; + } + + if (pAd->ApCfg.ApCliTab[ifIdx].AutoConnectFlag != TRUE) + return FALSE; + + CfgSsidLen = pAd->ApCfg.ApCliTab[ifIdx].CfgSsidLen; + pCfgSsid = pAd->ApCfg.ApCliTab[ifIdx].CfgSsid; + pScanTab = &pAd->ScanTab; + pSsidBssTab = &pAd->ApCfg.ApCliTab[ifIdx].MlmeAux.SsidBssTab; + pSsidBssTab->BssNr = 0; + + /* + Find out APs with the desired SSID. + */ + for (entryIdx = 0; entryIdx < pScanTab->BssNr; entryIdx++) { + BSS_ENTRY *pBssEntry = &pScanTab->BssEntry[entryIdx]; + + if (pBssEntry->Channel == 0) + break; + + if (NdisEqualMemory(pCfgSsid, pBssEntry->Ssid, CfgSsidLen) && + pBssEntry->SsidLen && + (pBssEntry->SsidLen == CfgSsidLen) && +#if defined(DBDC_MODE) && defined(DOT11K_RRM_SUPPORT) +/* + double check the SSID in the same band could be in candidate list +*/ + (((pBssEntry->Channel > 14) && WMODE_CAP_5G(wdev->PhyMode)) || ((pBssEntry->Channel <= 14) && WMODE_CAP_2G(wdev->PhyMode))) && +#endif /* defined(DBDC_MODE) && defined(DOT11K_RRM_SUPPORT) */ + (pSsidBssTab->BssNr < MAX_LEN_OF_BSS_TABLE)) { + if ((((wdev->SecConfig.AKMMap & pBssEntry->AKMMap) != 0) || + (IS_AKM_AUTOSWITCH(wdev->SecConfig.AKMMap) && IS_AKM_SHARED(pBssEntry->AKMMap))) && + (wdev->SecConfig.PairwiseCipher & pBssEntry->PairwiseCipher) != 0) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("Found desired ssid in Entry %2d:\n", entryIdx)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("I/F(apcli%d) ApCliAutoConnectExec:(Len=%d,Ssid=%s, Channel=%d, Rssi=%d)\n", + ifIdx, pBssEntry->SsidLen, pBssEntry->Ssid, + pBssEntry->Channel, pBssEntry->Rssi)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("I/F(apcli%d) ApCliAutoConnectExec::(AuthMode=%s, EncrypType=%s)\n", ifIdx, + GetAuthMode(pBssEntry->AuthMode), + GetEncryptType(pBssEntry->WepStatus))); + NdisMoveMemory(&pSsidBssTab->BssEntry[pSsidBssTab->BssNr++], + pBssEntry, sizeof(BSS_ENTRY)); + } + } + } + + NdisZeroMemory(&pSsidBssTab->BssEntry[pSsidBssTab->BssNr], sizeof(BSS_ENTRY)); + /* + Sort by Rssi in the increasing order, and connect to + the last entry (strongest Rssi) + */ + BssTableSortByRssi(pSsidBssTab, TRUE); + + if ((pSsidBssTab->BssNr == 0)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("No match entry.\n")); + pAd->ApCfg.ApCliAutoConnectRunning[ifIdx] = FALSE; + } + else if (pSsidBssTab->BssNr > 0 && + pSsidBssTab->BssNr <= MAX_LEN_OF_BSS_TABLE) { + /* + Switch to the channel of the candidate AP + */ + BSS_ENTRY *pBssEntry = &pSsidBssTab->BssEntry[pSsidBssTab->BssNr - 1]; +#ifdef APCLI_AUTO_BW_TMP /* should be removed after apcli auto-bw is applied */ + BOOLEAN bw_adj; + + bw_adj = (ApCliAutoConnectBWAdjust(pAd, wdev, pBssEntry) + || (!IS_INVALID_HT_SECURITY(pBssEntry->PairwiseCipher))); + if (bw_adj) +#endif /* APCLI_AUTO_BW_TMP */ + { + pAd->ApCfg.ApCliAutoBWAdjustCnt[ifIdx]++; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("Switch to channel :%d\n", pBssEntry->Channel)); + rtmp_set_channel(pAd, wdev, pBssEntry->Channel); + } + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("Error! Out of table range: (BssNr=%d).\n", pSsidBssTab->BssNr)); + RtmpOSNetDevProtect(1); + old_ioctl_if = pObj->ioctl_if; + old_ioctl_if_type = pObj->ioctl_if_type; + pObj->ioctl_if = ifIdx; + pObj->ioctl_if_type = INT_APCLI; + Set_ApCli_Enable_Proc(pAd, "1"); + pObj->ioctl_if = old_ioctl_if; + pObj->ioctl_if_type = old_ioctl_if_type; + RtmpOSNetDevProtect(0); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("<--- ApCliAutoConnectExec()\n")); + return FALSE; + } + RtmpOSNetDevProtect(1); + old_ioctl_if = pObj->ioctl_if; + old_ioctl_if_type = pObj->ioctl_if_type; + pObj->ioctl_if = ifIdx; + pObj->ioctl_if_type = INT_APCLI; + Set_ApCli_Enable_Proc(pAd, "1"); + pObj->ioctl_if = old_ioctl_if; + pObj->ioctl_if_type = old_ioctl_if_type; + RtmpOSNetDevProtect(0); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("<--- ApCliAutoConnectExec()\n")); + return TRUE; +} + +/* + =================================================== + + Description: + If the previous selected entry connected failed, this function will + choose next entry to connect. The previous entry will be deleted. + + Arguments: + pAd: pointer to our adapter + + Note: + Note that the table is sorted by Rssi in the "increasing" order, thus + the last entry in table has stringest Rssi. + =================================================== +*/ + +VOID ApCliSwitchCandidateAP( + IN PRTMP_ADAPTER pAd, + IN struct wifi_dev *wdev) +{ + BSS_TABLE *pSsidBssTab; + PAPCLI_STRUCT pApCliEntry; + UCHAR lastEntryIdx, ifIdx; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + INT old_ioctl_if; + INT old_ioctl_if_type; + + if (pAd->ScanCtrl.PartialScan.bScanning == TRUE) + return; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("---> ApCliSwitchCandidateAP()\n")); + + if (wdev) + ifIdx = wdev->func_idx; + else + return; + + if (ifIdx >= MAX_APCLI_NUM) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Error ifIdx=%d\n", ifIdx)); + return; + } + + if (pAd->ApCfg.ApCliTab[ifIdx].AutoConnectFlag != TRUE) + return; + + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIdx]; + pSsidBssTab = &pApCliEntry->MlmeAux.SsidBssTab; + + if (pSsidBssTab->BssNr == 0) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("No Bss\n")); + pAd->ApCfg.ApCliAutoConnectRunning[ifIdx] = FALSE; + return; + } + + /* + delete (zero) the previous connected-failled entry and always + connect to the last entry in talbe until the talbe is empty. + */ + NdisZeroMemory(&pSsidBssTab->BssEntry[--pSsidBssTab->BssNr], sizeof(BSS_ENTRY)); + lastEntryIdx = pSsidBssTab->BssNr - 1; + + if ((pSsidBssTab->BssNr > 0) && (pSsidBssTab->BssNr < MAX_LEN_OF_BSS_TABLE)) { + BSS_ENTRY *pBssEntry = &pSsidBssTab->BssEntry[pSsidBssTab->BssNr - 1]; +#ifdef APCLI_AUTO_BW_TMP /* should be removed after apcli auto-bw is applied */ + BOOLEAN bw_adj; + + bw_adj = ApCliAutoConnectBWAdjust(pAd, wdev, pBssEntry); + if (bw_adj) +#endif /* APCLI_AUTO_BW_TMP */ + { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("Switch to channel :%d\n", pBssEntry->Channel)); + rtmp_set_channel(pAd, wdev, pBssEntry->Channel); + } + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("No candidate AP, the process is about to stop.\n")); + pAd->ApCfg.ApCliAutoConnectRunning[ifIdx] = FALSE; + } + RtmpOSNetDevProtect(1); + old_ioctl_if = pObj->ioctl_if; + old_ioctl_if_type = pObj->ioctl_if_type; + pObj->ioctl_if = ifIdx; + pObj->ioctl_if_type = INT_APCLI; + Set_ApCli_Enable_Proc(pAd, "1"); + pObj->ioctl_if = old_ioctl_if; + pObj->ioctl_if_type = old_ioctl_if_type; + RtmpOSNetDevProtect(0); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("---> ApCliSwitchCandidateAP()\n")); +} +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ + +VOID ApCliRTMPReportMicError( + IN RTMP_ADAPTER *pAd, + IN UCHAR uniCastKey, + IN INT ifIndex) +{ + ULONG Now; + PAPCLI_STRUCT pApCliEntry = NULL; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, (" ApCliRTMPReportMicError <---\n")); + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + /* Record Last MIC error time and count */ + NdisGetSystemUpTime(&Now); + + if (pAd->ApCfg.ApCliTab[ifIndex].MicErrCnt == 0) { + pAd->ApCfg.ApCliTab[ifIndex].MicErrCnt++; + pAd->ApCfg.ApCliTab[ifIndex].LastMicErrorTime = Now; + NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].ReplayCounter, 8); + } else if (pAd->ApCfg.ApCliTab[ifIndex].MicErrCnt == 1) { + if ((pAd->ApCfg.ApCliTab[ifIndex].LastMicErrorTime + (60 * OS_HZ)) < Now) { + /* Update Last MIC error time, this did not violate two MIC errors within 60 seconds */ + pAd->ApCfg.ApCliTab[ifIndex].LastMicErrorTime = Now; + } else { + /* RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); */ + pAd->ApCfg.ApCliTab[ifIndex].LastMicErrorTime = Now; + /* Violate MIC error counts, MIC countermeasures kicks in */ + pAd->ApCfg.ApCliTab[ifIndex].MicErrCnt++; + } + } else { + /* MIC error count >= 2 */ + /* This should not happen */ + ; + } + + MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_MIC_FAILURE_REPORT_FRAME, 1, &uniCastKey, ifIndex); + + if (pAd->ApCfg.ApCliTab[ifIndex].MicErrCnt == 2) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, (" MIC Error count = 2 Trigger Block timer....\n")); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, (" pAd->ApCfg.ApCliTab[%d].LastMicErrorTime = %ld\n", ifIndex, + pAd->ApCfg.ApCliTab[ifIndex].LastMicErrorTime)); +#ifdef APCLI_CERT_SUPPORT + + if (pAd->bApCliCertTest == TRUE) + RTMPSetTimer(&pApCliEntry->MlmeAux.WpaDisassocAndBlockAssocTimer, 100); + +#endif /* APCLI_CERT_SUPPORT */ + } + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("ApCliRTMPReportMicError --->\n")); +} + +#ifdef DOT11W_PMF_SUPPORT +/* chane the cmd depend on security mode first, and update to run time flag*/ +INT Set_ApCliPMFMFPC_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj; + PMF_CFG *pPmfCfg = NULL; + struct wifi_dev *wdev = NULL; + + if (strlen(arg) == 0) + return FALSE; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + pPmfCfg = &pAd->ApCfg.ApCliTab[pObj->ioctl_if].wdev.SecConfig.PmfCfg; + wdev = &pAd->ApCfg.ApCliTab[pObj->ioctl_if].wdev; + + if (!pPmfCfg || !wdev) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: pPmfCfg=%p, wdev=%p\n", + __func__, pPmfCfg, wdev)); + return FALSE; + } + + if (os_str_tol(arg, 0, 10)) + pPmfCfg->Desired_MFPC = TRUE; + else { + pPmfCfg->Desired_MFPC = FALSE; + pPmfCfg->MFPC = FALSE; + pPmfCfg->MFPR = FALSE; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: Desired MFPC=%d\n", + __func__, pPmfCfg->Desired_MFPC)); + + if ((IS_AKM_WPA2_Entry(wdev) || IS_AKM_WPA2PSK_Entry(wdev)) + && IS_CIPHER_AES_Entry(wdev)) { + pPmfCfg->PMFSHA256 = pPmfCfg->Desired_PMFSHA256; + + if (pPmfCfg->Desired_MFPC) { + pPmfCfg->MFPC = TRUE; + pPmfCfg->MFPR = pPmfCfg->Desired_MFPR; + + if (pPmfCfg->MFPR) + pPmfCfg->PMFSHA256 = TRUE; + } + } else if (pPmfCfg->Desired_MFPC) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: Security is not WPA2/WPA2PSK AES\n", __func__)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: MFPC=%d, MFPR=%d, SHA256=%d\n", + __func__, + pPmfCfg->MFPC, + pPmfCfg->MFPR, + pPmfCfg->PMFSHA256)); + return TRUE; +} + +/* chane the cmd depend on security mode first, and update to run time flag*/ +INT Set_ApCliPMFMFPR_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj; + PMF_CFG *pPmfCfg = NULL; + struct wifi_dev *wdev = NULL; + + if (strlen(arg) == 0) + return FALSE; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + pPmfCfg = &pAd->ApCfg.ApCliTab[pObj->ioctl_if].wdev.SecConfig.PmfCfg; + wdev = &pAd->ApCfg.ApCliTab[pObj->ioctl_if].wdev; + + if (!pPmfCfg || !wdev) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: pPmfCfg=%p, wdev=%p\n", + __func__, pPmfCfg, wdev)); + return FALSE; + } + + if (os_str_tol(arg, 0, 10)) + pPmfCfg->Desired_MFPR = TRUE; + else { + pPmfCfg->Desired_MFPR = FALSE; + /* only close the MFPR */ + pPmfCfg->MFPR = FALSE; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: Desired MFPR=%d\n", + __func__, pPmfCfg->Desired_MFPR)); + + if ((IS_AKM_WPA2_Entry(wdev) || IS_AKM_WPA2PSK_Entry(wdev)) + && IS_CIPHER_AES_Entry(wdev)) { + pPmfCfg->PMFSHA256 = pPmfCfg->Desired_PMFSHA256; + + if (pPmfCfg->Desired_MFPC) { + pPmfCfg->MFPC = TRUE; + pPmfCfg->MFPR = pPmfCfg->Desired_MFPR; + + if (pPmfCfg->MFPR) + pPmfCfg->PMFSHA256 = TRUE; + } + } else if (pPmfCfg->Desired_MFPC) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: Security is not WPA2/WPA2PSK AES\n", __func__)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: MFPC=%d, MFPR=%d, SHA256=%d\n", + __func__, pPmfCfg->MFPC, + pPmfCfg->MFPR, + pPmfCfg->PMFSHA256)); + return TRUE; +} + +INT Set_ApCliPMFSHA256_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj; + PMF_CFG *pPmfCfg = NULL; + + if (strlen(arg) == 0) + return FALSE; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + pPmfCfg = &pAd->ApCfg.ApCliTab[pObj->ioctl_if].wdev.SecConfig.PmfCfg; + + if (!pPmfCfg) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: pPmfCfg=%p\n", + __func__, pPmfCfg)); + return FALSE; + } + + if (os_str_tol(arg, 0, 10)) + pPmfCfg->Desired_PMFSHA256 = TRUE; + else + pPmfCfg->Desired_PMFSHA256 = FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s:: Desired PMFSHA256=%d\n", + __func__, pPmfCfg->Desired_PMFSHA256)); + return TRUE; +} +#endif /* DOT11W_PMF_SUPPORT */ + +VOID apcli_dync_txop_alg( + PRTMP_ADAPTER pAd, + struct wifi_dev *wdev, + UINT tx_tp, + UINT rx_tp) +{ +#define COND3_COOL_DOWN_TIME 240 + + if (!pAd || !wdev) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:: pAd or wdev is NULL!\n", + __func__)); + } else { + INT i; + BOOLEAN cond[NUM_OF_APCLI_TXOP_COND] = {FALSE}; + UINT16 cond_txop_level[NUM_OF_APCLI_TXOP_COND] = {0}; + UINT16 cond_thrd[NUM_OF_APCLI_TXOP_COND] = {0}; + UINT16 txop_level = TXOP_0; + UINT16 current_txop_level = TXOP_0; + BOOLEAN apcli_txop_en = FALSE; + APCLI_STRUCT *apcli_entry = NULL; + + cond_txop_level[1] = TXOP_30; + cond_txop_level[2] = TXOP_FE; + cond_txop_level[3] = TXOP_80; + cond_thrd[1] = TP_PEEK_BOUND_THRESHOLD; + cond_thrd[2] = TX_MODE_TP_CHECK; + current_txop_level = wdev->bss_info_argument.txop_level[PRIO_APCLI_REPEATER]; + apcli_entry = &pAd->ApCfg.ApCliTab[wdev->func_idx]; + + /* if cond_1 is taking effect, adjust the threshold to prevent instability */ + if (current_txop_level == cond_txop_level[1]) { + /* Adjust cond_thrd[1] */ + if (apcli_entry->dync_txop_histogram[1] >= 4) { + UINT32 tolerance_adjust_factor = 10; + UINT32 tolerance_adjust_value = 0; + + tolerance_adjust_value = TOLERANCE_OF_TP_THRESHOLD + + (apcli_entry->dync_txop_histogram[1]*tolerance_adjust_factor); + + if (tolerance_adjust_value > 150) + tolerance_adjust_value = 150; + + cond_thrd[1] = TP_PEEK_BOUND_THRESHOLD - tolerance_adjust_value; + } else + cond_thrd[1] = TP_PEEK_BOUND_THRESHOLD - TOLERANCE_OF_TP_THRESHOLD; + + /* Check if t.p. has degrade right after apply cond1 */ + if (tx_tp <= (TP_PEEK_BOUND_THRESHOLD - TOLERANCE_OF_TP_THRESHOLD) && + apcli_entry->dync_txop_histogram[1] < 4) { + /* If t.p. is bad right after cond1, we trigger cond3 to recover old txop */ + cond[3] = TRUE; + } + } else if (current_txop_level == cond_txop_level[2]) { + /* if cond_2 is taking effect, adjust the threshold to prevent instability */ + cond_thrd[2] = TX_MODE_TP_CHECK - TOLERANCE_OF_TP_THRESHOLD; + } + + if (tx_tp > cond_thrd[1]) + cond[1] = TRUE; + else if (tx_tp > cond_thrd[2] && WMODE_CAP_2G(wdev->PhyMode)) { + /* We don't check "divided by 0" because the "if condition" already do that */ + UINT tx_ratio = (tx_tp*100)/(tx_tp + rx_tp); + + if (tx_ratio > TX_MODE_RATIO_THRESHOLD) + cond[2] = TRUE; + } + + if (apcli_entry->dync_txop_histogram[3] != 0) { + cond[3] = TRUE; + txop_level = cond_txop_level[3]; + apcli_txop_en = TRUE; + + if (tx_tp < TP_PEEK_BOUND_THRESHOLD) { + /* If cond3 triggered but t.p cannot keep high, we raise the decade rate */ + UINT8 cond3_decade_factor = 0; + UINT32 cond3_accumulate_value = 0; + + cond[4] = TRUE; + cond3_decade_factor = (1 << apcli_entry->dync_txop_histogram[4]); /* exponential decade */ + cond3_accumulate_value = apcli_entry->dync_txop_histogram[3] + cond3_decade_factor; + apcli_entry->dync_txop_histogram[3] = + (cond3_accumulate_value > COND3_COOL_DOWN_TIME) ? + (COND3_COOL_DOWN_TIME):cond3_accumulate_value; + } + } else if (cond[1] == TRUE) { + txop_level = cond_txop_level[1]; + apcli_txop_en = TRUE; + } else if (cond[2] == TRUE) { + txop_level = cond_txop_level[2]; + apcli_txop_en = TRUE; + } else { + txop_level = TXOP_0; + apcli_txop_en = FALSE; + } + + if (txop_level != current_txop_level) { + if (apcli_txop_en == TRUE) + enable_tx_burst(pAd, wdev, AC_BE, PRIO_APCLI_REPEATER, txop_level); + else + disable_tx_burst(pAd, wdev, AC_BE, PRIO_APCLI_REPEATER, txop_level); + } + + /* update histogram */ + for (i = 0; i < NUM_OF_APCLI_TXOP_COND; i++) { + if (cond[i] == TRUE) + apcli_entry->dync_txop_histogram[i]++; + else + apcli_entry->dync_txop_histogram[i] = 0; + } + + /* clear histogram */ + if (apcli_entry->dync_txop_histogram[3] > COND3_COOL_DOWN_TIME) + apcli_entry->dync_txop_histogram[3] = 0; + } +} + +/* +* system layer api for APCLI +*/ +INT apcli_link_up(struct wifi_dev *wdev, struct _MAC_TABLE_ENTRY *entry) +{ + struct _RTMP_ADAPTER *ad = (struct _RTMP_ADAPTER *)wdev->sys_handle; + struct _APCLI_STRUCT *apcli = &ad->ApCfg.ApCliTab[wdev->func_idx]; + + if (WDEV_BSS_STATE(wdev) == BSS_INIT) { + apcli->Valid = TRUE; + MSDU_FORBID_CLEAR(wdev, MSDU_FORBID_CONNECTION_NOT_READY); + wdev->PortSecured = WPA_802_1X_PORT_SECURED; + + if (wifi_sys_linkup(wdev, entry) != TRUE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s():link up fail!\n", __func__)); + } + } + + return TRUE; +} + +#ifdef ROAMING_ENHANCE_SUPPORT +#ifndef ETH_HDR_LEN +#define ETH_HDR_LEN 14 /* dstMac(6) + srcMac(6) + protoType(2) */ +#endif + +#ifndef VLAN_ETH_HDR_LEN +#define VLAN_ETH_HDR_LEN (ETH_HDR_LEN + 4) /* 4 for h_vlan_TCI and h_vlan_encapsulated_proto */ +#endif + +#ifndef IP_HDR_SRC_OFFSET +#define IP_HDR_SRC_OFFSET 12 /* shift 12 for IP header len. */ +#endif + +BOOLEAN IsApCliLinkUp(IN PRTMP_ADAPTER pAd) +{ + if ((pAd->ApCfg.ApCliInfRunned > 0) +#ifdef CONFIG_WIFI_PKT_FWD + || ((wf_drv_tbl.wf_fwd_needed_hook != NULL) && (wf_drv_tbl.wf_fwd_needed_hook() == TRUE)) +#endif /* CONFIG_WIFI_PKT_FWD */ + ) + return TRUE; + + return FALSE; +} + +BOOLEAN ApCliDoRoamingRefresh( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PNDIS_PACKET pRxPacket, + IN struct wifi_dev *wdev) +{ + UCHAR *pPktHdr, *pLayerHdr; + UINT16 ProtoType; + + if (!pRxPacket || !wdev) + return FALSE; + + /* Get the upper layer protocol type of this 802.3 pkt */ + pPktHdr = GET_OS_PKT_DATAPTR(pRxPacket); + ProtoType = OS_NTOHS(get_unaligned((PUINT16)(pPktHdr + (ETH_HDR_LEN - 2)))); + if (IS_VLAN_PACKET(pPktHdr)) + pLayerHdr = (pPktHdr + VLAN_ETH_HDR_LEN); + else + pLayerHdr = (pPktHdr + ETH_HDR_LEN); + + if (ProtoType == ETH_P_ARP) { + pEntry->bRoamingRefreshDone = TRUE; + return TRUE; + } else if (ProtoType == ETH_P_IP) { + UINT32 SrcIP = 0; + PNDIS_PACKET pPacket = NULL; + + NdisMoveMemory(&SrcIP, (pLayerHdr + IP_HDR_SRC_OFFSET), 4); + if (SrcIP != 0) { + pPacket = (PNDIS_PACKET)arp_create(ARPOP_REQUEST, ETH_P_ARP, SrcIP, wdev->if_dev, + SrcIP, BROADCAST_ADDR, pEntry->Addr, BROADCAST_ADDR); + if (pPacket != NULL) { +#ifdef CONFIG_WIFI_PKT_FWD + set_wf_fwd_cb(pAd, pPacket, wdev); +#endif /* CONFIG_WIFI_PKT_FWD */ + RtmpOsPktProtocolAssign(pPacket); + RtmpOsPktRcvHandle(pPacket); + pEntry->bRoamingRefreshDone = TRUE; + return TRUE; + } + } + } + + return FALSE; +} +#endif /* ROAMING_ENHANCE_SUPPORT */ +#endif /* APCLI_SUPPORT */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_apcli_inf.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_apcli_inf.c new file mode 100644 index 000000000..833628a3e --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_apcli_inf.c @@ -0,0 +1,180 @@ +/* + *************************************************************************** + * 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 + + 4. ApCli index (0) of different tx packet is assigned in + + 5. ApCli index (0) of different interface is got in tx_pkt_handle() by using + + 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" + +/* --------------------------------- Public -------------------------------- */ +NET_DEV_STATS *RT28xx_get_ether_stats(PNET_DEV net_dev); +/* +======================================================================== +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(VOID *pAd, 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_virtual_if_open; + netDevOpHook.stop = apcli_virtual_if_close; + netDevOpHook.xmit = rt28xx_send_packets; + netDevOpHook.ioctl = rt28xx_ioctl; + netDevOpHook.get_stats = RT28xx_get_ether_stats; + 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_virtual_if_open(PNET_DEV pDev) +{ + VOID *pAd; + + pAd = RTMP_OS_NETDEV_GET_PRIV(pDev); + ASSERT(pAd); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_OFF, ("%s: ===> %s\n", + RTMP_OS_NETDEV_GET_DEVNAME(pDev), __func__)); + + if (VIRTUAL_IF_INIT(pAd, pDev) != 0) + return -1; + + if (VIRTUAL_IF_UP(pAd, pDev) != 0) + return -1; + + /* increase MODULE use count */ + RT_MOD_INC_USE_COUNT(); + RT_MOD_HNAT_REG(pDev); + RTMP_OS_NETDEV_START_QUEUE(pDev); + return 0; +} + + +/* +======================================================================== +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_virtual_if_close(PNET_DEV pDev) +{ + VOID *pAd; + + pAd = RTMP_OS_NETDEV_GET_PRIV(pDev); + ASSERT(pAd); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_OFF, ("%s: ===> %s\n", + RTMP_OS_NETDEV_GET_DEVNAME(pDev), __func__)); + + VIRTUAL_IF_DOWN(pAd, pDev); + + VIRTUAL_IF_DEINIT(pAd, pDev); + + RT_MOD_HNAT_DEREG(pDev); + RT_MOD_DEC_USE_COUNT(); + return 0; +} + + +/* +======================================================================== +Routine Description: + Remove ApCli-BSS network interface. + +Arguments: + pAd points to our adapter + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28xx_ApCli_Remove(VOID *pAd) +{ + RTMP_AP_IoctlHandle(pAd, NULL, CMD_RTPRIV_IOCTL_APC_REMOVE, 0, NULL, 0); +} + +#endif /* APCLI_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_assoc.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_assoc.c new file mode 100644 index 000000000..e790b2d9d --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_assoc.c @@ -0,0 +1,2808 @@ +/**************************************************************************** + * 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" + +#ifdef VENDOR_FEATURE7_SUPPORT +#include "arris_wps_gpio_handler.h" +#endif +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[]; + + + + + +static USHORT update_associated_mac_entry( + IN RTMP_ADAPTER * pAd, + IN MAC_TABLE_ENTRY * pEntry, + IN IE_LISTS * ie_list, + IN UCHAR MaxSupportedRate, + IN BOOLEAN isReassoc) +{ + BSS_STRUCT *mbss; + struct wifi_dev *wdev; +#ifdef TXBF_SUPPORT + BOOLEAN supportsETxBF = FALSE; +#endif /* TXBF_SUPPORT // */ + STA_TR_ENTRY *tr_entry; + UCHAR PhyMode; + UCHAR Channel; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + BOOLEAN need_clr_set_wtbl = FALSE; + + ASSERT((pEntry->func_tb_idx < pAd->ApCfg.BssidNum)); + mbss = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx]; + wdev = &mbss->wdev; + tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; + PhyMode = wdev->PhyMode; + Channel = wdev->channel; + + /* use this to decide reassociation rsp need to clear set wtbl or not */ + if (pEntry->Sst == SST_ASSOC && isReassoc == TRUE +#ifdef DOT11R_FT_SUPPORT + && (IS_FT_STA(pEntry)) +#endif /* DOT11R_FT_SUPPORT */ + ) + need_clr_set_wtbl = TRUE; + + /* Update auth, wep, legacy transmit rate setting . */ + pEntry->Sst = SST_ASSOC; + pEntry->MaxSupportedRate = min(wdev->rate.MaxTxRate, MaxSupportedRate); + MacTableSetEntryPhyCfg(pAd, pEntry); + pEntry->CapabilityInfo = ie_list->CapabilityInfo; + + if (IS_AKM_PSK_Entry(pEntry)) { + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + pEntry->SecConfig.Handshake.WpaState = AS_INITPSK; + } + +#ifdef DOT1X_SUPPORT + else if (IS_AKM_1X_Entry(pEntry) || IS_IEEE8021X_Entry(wdev)) { + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + pEntry->SecConfig.Handshake.WpaState = AS_AUTHENTICATION; + } + +#endif /* DOT1X_SUPPORT */ + /* Ralink proprietary Piggyback and Aggregation support for legacy RT61 chip */ + MacTableSetEntryRaCap(pAd, pEntry, &ie_list->vendor_ie); + + /* In WPA or 802.1x mode, the port is not secured, otherwise is secued. */ + if (IS_AKM_WPA_CAPABILITY_Entry(pEntry) +#ifdef DOT1X_SUPPORT + || IS_IEEE8021X_Entry(wdev) +#endif /* DOT1X_SUPPORT */ +#ifdef RT_CFG80211_SUPPORT + || wdev->IsCFG1xWdev +#endif /* RT_CFG80211_SUPPORT */ +#ifdef WSC_INCLUDED + || (pEntry->bWscCapable && IS_AKM_WPA_CAPABILITY_Entry(wdev)) +#endif /* WSC_INCLUDED */ + ) + tr_entry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + else + tr_entry->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 DOT11W_PMF_SUPPORT + + if ((cap->FlgPMFEncrtptMode == PMF_ENCRYPT_MODE_0) + && (pEntry->SecConfig.PmfCfg.UsePMFConnect == TRUE)) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SOFTWARE_ENCRYPT); + +#endif /* DOT11W_PMF_SUPPORT */ +#endif /* SOFT_ENCRYPT */ + + if (wdev->bWmmCapable && ie_list->bWmmCapable) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); + else + CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); + +#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->SecConfig.PairwiseCipher)) { + /* Force to None-HT mode due to WiFi 11n policy */ + ie_list->ht_cap_len = 0; +#ifdef DOT11_VHT_AC + ie_list->vht_cap_len = 0; +#endif /* DOT11_VHT_AC */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Force the STA as Non-HT mode\n", __func__)); + } + +#ifdef CONFIG_HOTSPOT_R2 + + if (ie_list->ExtCapInfo.qosmap) + pEntry->QosMapSupport = 1; + +#endif +#ifdef CONFIG_DOT11V_WNM + + /* #ifdef CONFIG_HOTSPOT_R2 Remove for WNM independance. */ + if (ie_list->ExtCapInfo.BssTransitionManmt) + pEntry->BssTransitionManmtSupport = 1; + + /* #endif CONFIG_HOTSPOT_R2 */ +#endif /* CONFIG_DOT11V_WNM */ + + /* If this Entry supports 802.11n, upgrade to HT rate. */ + if ((ie_list->ht_cap_len != 0) && + (wdev->DesiredHtPhyInfo.bHtEnable) && + WMODE_CAP_N(PhyMode)) { + ht_mode_adjust(pAd, pEntry, &ie_list->HTCapability); + +#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 + UCHAR op_ht_bw = wlan_operate_get_ht_bw(wdev); + UCHAR cfg_ht_bw = wlan_config_get_ht_bw(wdev); + UCHAR op_ext_cha = wlan_operate_get_ext_cha(wdev); + + pEntry->bForty_Mhz_Intolerant = TRUE; + pAd->MacTab.fAnyStaFortyIntolerant = TRUE; + + if (((cfg_ht_bw == HT_BW_40) && + (Channel <= 14)) && + ((pAd->CommonCfg.bBssCoexEnable == TRUE) && + (op_ht_bw != HT_BW_20) && + (op_ext_cha != 0)) + ) { + pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq = 1; + wlan_operate_set_ht_bw(wdev, HT_BW_20, EXTCHA_NONE); + pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC; + MTWF_LOG(DBG_CAT_PROTO, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s, Update Beacon for mbss_idx:%d\n", __func__, pEntry->func_tb_idx)); + UpdateBeaconHandler(pAd, wdev, BCN_UPDATE_IE_CHG); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("pEntry set 40MHz Intolerant as 1\n")); +#endif /* DOT11N_DRAFT3 */ + Handle_BSS_Width_Trigger_Events(pAd, Channel); + } + +#ifdef TXBF_SUPPORT +#ifdef DOT11_VHT_AC + + if (WMODE_CAP_AC(PhyMode) && + (Channel > 14) && + (ie_list->vht_cap_len)) + supportsETxBF = mt_WrapClientSupportsVhtETxBF(pAd, &ie_list->vht_cap.vht_cap); + else +#endif /* DOT11_VHT_AC */ + supportsETxBF = mt_WrapClientSupportsETxBF(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) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("@@@ IF-ra%d DesiredTransmitSetting.field.MCS = %d\n", + pEntry->func_tb_idx, + wdev->DesiredTransmitSetting.field.MCS)); + set_ht_fixed_mcs(pAd, pEntry, wdev->DesiredTransmitSetting.field.MCS, wdev->HTPhyMode.field.MCS); + } + + set_sta_ht_cap(pAd, pEntry, &ie_list->HTCapability); + /* 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(PhyMode) && + (Channel > 14) && + ie_list->vht_cap_len) { + vht_mode_adjust(pAd, pEntry, &ie_list->vht_cap, + (ie_list->vht_op_len == 0) ? NULL : &ie_list->vht_op); + dot11_vht_mcs_to_internal_mcs(pAd, wdev, &ie_list->vht_cap, &pEntry->MaxHTPhyMode); + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s(): Peer's PhyCap=>Mode:%s, BW:%s, NSS:%d, MCS:%d\n", + __func__, + get_phymode_str(pEntry->MaxHTPhyMode.field.MODE), + get_bw_str(pEntry->MaxHTPhyMode.field.BW), + ((pEntry->MaxHTPhyMode.field.MCS & (0x3 << 4)) >> 4) + 1, + (pEntry->MaxHTPhyMode.field.MCS & 0xf))); + + set_vht_cap(pAd, pEntry, &ie_list->vht_cap); + NdisMoveMemory(&pEntry->vht_cap_ie, &ie_list->vht_cap, sizeof(VHT_CAP_IE)); + } + + if (ie_list->operating_mode_len == sizeof(OPERATING_MODE) && + ie_list->operating_mode.rx_nss_type == 0) { + pEntry->operating_mode = ie_list->operating_mode; + pEntry->force_op_mode = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): Peer's OperatingMode=>RxNssType: %d, RxNss: %d, ChBW: %d\n", + __func__, pEntry->operating_mode.rx_nss_type, + pEntry->operating_mode.rx_nss, + pEntry->operating_mode.ch_width)); + } else + pEntry->force_op_mode = FALSE; + +#endif /* DOT11_VHT_AC */ + } else { +#ifdef CONFIG_HOTSPOT_R2 + + if (ie_list->ExtCapInfo.qosmap) + pEntry->QosMapSupport = 1; + +#endif + pAd->MacTab.fAnyStationIsLegacy = TRUE; + NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE)); + pEntry->SupportHTMCS = 0; + pEntry->SupportRateMode &= (~SUPPORT_HT_MODE); +#ifdef DOT11_VHT_AC + /* TODO: shiang-usw, it's ugly and need to revise it */ + NdisZeroMemory(&pEntry->vht_cap_ie, sizeof(VHT_CAP_IE)); + pEntry->SupportVHTMCS1SS = 0; + pEntry->SupportVHTMCS2SS = 0; + pEntry->SupportVHTMCS3SS = 0; + pEntry->SupportVHTMCS4SS = 0; + pEntry->SupportRateMode &= (~SUPPORT_VHT_MODE); +#endif /* DOT11_VHT_AC */ + } + +#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 (cap->FlgHwTxBfCap) + chip_tx_bf_init(pAd, pEntry, ie_list, supportsETxBF); + +#endif /* TXBF_SUPPORT // */ +#ifdef MT_MAC + + if (cap->hif_type == HIF_MT) { + if (wdev->bAutoTxRateSwitch == TRUE) + pEntry->bAutoTxRateSwitch = TRUE; + else { + pEntry->HTPhyMode.field.MCS = wdev->HTPhyMode.field.MCS; + pEntry->bAutoTxRateSwitch = FALSE; +#ifdef WFA_VHT_PF + + if (WMODE_CAP_AC(PhyMode)) { + pEntry->HTPhyMode.field.MCS = wdev->DesiredTransmitSetting.field.MCS + + ((wlan_operate_get_tx_stream(wdev) - 1) << 4); + } + +#endif /* WFA_VHT_PF */ + + if (pEntry->HTPhyMode.field.MODE == MODE_VHT) { + pEntry->HTPhyMode.field.MCS = wdev->DesiredTransmitSetting.field.MCS + + ((wlan_operate_get_tx_stream(wdev) - 1) << 4); + } + + /* If the legacy mode is set, overwrite the transmit setting of this entry. */ + RTMPUpdateLegacyTxSetting((UCHAR)wdev->DesiredTransmitSetting.field.FixedTxMode, pEntry); + } + +#if !defined(MT7615) && !defined(MT7637) && !defined(MT7622) && !defined(P18) && !defined(MT7663) + + if (!IS_MT7615(pAd) && !IS_MT7637(pAd) && !IS_MT7622(pAd) && !IS_P18(pAd) && !IS_MT7663(pAd)) + RAInit(pAd, pEntry); + +#endif /* !defined(MT7615) && !defined(MT7637) && !defined(MT7622) && !defined(P18) && !defined(MT7663) */ + } + +#endif /* MT_MAC */ + + if (IS_NO_SECURITY(&pEntry->SecConfig) || IS_CIPHER_WEP(pEntry->SecConfig.PairwiseCipher)) + ApLogEvent(pAd, pEntry->Addr, EVENT_ASSOCIATED); + + + if ((pEntry->MaxHTPhyMode.field.MODE == MODE_OFDM) || + (pEntry->MaxHTPhyMode.field.MODE == MODE_CCK)) + pAd->MacTab.fAnyStationIsLegacy = TRUE; + + NdisAcquireSpinLock(&pAd->MacTabLock); + nonerp_sta_num(pEntry, PEER_JOIN); + NdisReleaseSpinLock(&pAd->MacTabLock); + + ApUpdateCapabilityAndErpIe(pAd, mbss); +#ifdef DOT11_N_SUPPORT + APUpdateOperationMode(pAd, wdev); +#endif /* DOT11_N_SUPPORT */ +#ifdef HOSTAPD_SUPPORT + + if ((wdev->Hostapd == Hostapd_EXT) && + ((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, + IN BOOLEAN isReassoc) +{ + USHORT StatusCode = MLME_SUCCESS; + UCHAR MaxSupportedRate = RATE_11; + struct wifi_dev *wdev; +#ifdef WSC_AP_SUPPORT + WSC_CTRL *wsc_ctrl; +#endif /* WSC_AP_SUPPORT */ + STA_TR_ENTRY *tr_entry; +#ifdef CONFIG_OWE_SUPPORT + PUINT8 pPmkid = NULL; + UINT8 pmkid_count = 0; +#endif /*CONFIG_OWE_SUPPORT*/ + + if (!pEntry) + return MLME_UNSPECIFY_FAIL; + + wdev = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev; + MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps); + + if ((WMODE_EQUAL(wdev->PhyMode, WMODE_G) +#ifdef DOT11_N_SUPPORT + || WMODE_EQUAL(wdev->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(wdev->PhyMode) && (ie_list->ht_cap_len == 0)) + return MLME_ASSOC_REJ_DATA_RATE; + +#endif /* DOT11_N_SUPPORT */ +#ifdef DOT11_VHT_AC + + if (WMODE_CAP_AC(wdev->PhyMode) && + (wdev->channel > 14) && + (ie_list->vht_cap_len == 0) && + (pAd->CommonCfg.bNonVhtDisallow)) + return MLME_ASSOC_REJ_DATA_RATE; + +#endif /* DOT11_VHT_AC */ + + if ((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 + */ + tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; + *pAid = pEntry->Aid; + pEntry->NoDataIdleCount = 0; + /* TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! */ + pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; + pEntry->StaConnectTime = 0; +#ifdef CONFIG_HOTSPOT_R2 + + if (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_OSEN_CAPABLE)) +#endif + { +#ifdef WSC_AP_SUPPORT + + if (pEntry->bWscCapable == FALSE) +#endif /* WSC_AP_SUPPORT */ + { + /* check the validity of the received RSNIE */ + StatusCode = WPAValidateRSNIE(&wdev->SecConfig, + &pEntry->SecConfig, + &ie_list->RSN_IE[0], + ie_list->RSNIE_Len); +#ifdef CONFIG_OWE_SUPPORT + StatusCode = owe_pmkid_ecdh_process(pAd, + pEntry, + StatusCode, + ie_list->RSN_IE, + ie_list->RSNIE_Len, + &ie_list->ecdh_ie, + ie_list->ecdh_ie.length, + pPmkid, + &pmkid_count, + SUBTYPE_ASSOC_REQ); +#endif /*CONFIG_OWE_SUPPORT*/ + + 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); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : invalid status code(%d) !!!\n", __func__, StatusCode)); + return StatusCode; + } + + if (pEntry->SecConfig.AKMMap == 0x0) { + SET_AKM_OPEN(pEntry->SecConfig.AKMMap); + SET_CIPHER_NONE(pEntry->SecConfig.PairwiseCipher); + SET_CIPHER_NONE(pEntry->SecConfig.GroupCipher); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s : (AID#%d AKM=0x%x, PairwiseCipher=0x%x)\n", __func__, + pEntry->Aid, pEntry->SecConfig.AKMMap, pEntry->SecConfig.PairwiseCipher)); + } + } + + NdisMoveMemory(pEntry->RSN_IE, &ie_list->RSN_IE[0], ie_list->RSNIE_Len); + pEntry->RSNIE_Len = ie_list->RSNIE_Len; + + if (*pAid == 0) + StatusCode = MLME_ASSOC_REJ_UNABLE_HANDLE_STA; + else if ((pEntry->RSNIE_Len == 0) && + (IS_AKM_WPA_CAPABILITY_Entry(pEntry)) +#ifdef HOSTAPD_SUPPORT + && (wdev->Hostapd == Hostapd_EXT) +#endif /* HOSTAPD_SUPPORT */ +#ifdef RT_CFG80211_SUPPORT + && (wdev->Hostapd == Hostapd_CFG) +#endif /*RT_CFG80211_SUPPORT*/ + ) { +#ifdef WSC_AP_SUPPORT + wsc_ctrl = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.WscControl; + + if (((wsc_ctrl->WscConfMode != WSC_DISABLE) && + pEntry->bWscCapable +#ifdef WSC_V2_SUPPORT + && (wsc_ctrl->WscV2Info.bWpsEnable || + (wsc_ctrl->WscV2Info.bEnableWpsV2 == FALSE)) +#endif /* WSC_V2_SUPPORT */ + ) +#ifdef HOSTAPD_SUPPORT + || (wdev->Hostapd == Hostapd_EXT) +#endif /*HOSTAPD_SUPPORT*/ +#ifdef RT_CFG80211_SUPPORT + || wdev->Hostapd == Hostapd_CFG +#endif /*RT_CFG80211_SUPPORT*/ + ) { + pEntry->Sst = SST_ASSOC; + StatusCode = MLME_SUCCESS; + + /* In WPA or 802.1x mode, the port is not secured. */ + if (IS_AKM_WPA_CAPABILITY(pEntry->SecConfig.AKMMap) +#ifdef DOT1X_SUPPORT + || IS_IEEE8021X_Entry(wdev) +#endif /* DOT1X_SUPPORT */ + ) + tr_entry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + else + tr_entry->PortSecured = WPA_802_1X_PORT_SECURED; + + if (IS_AKM_PSK(pEntry->SecConfig.AKMMap)) { + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + pEntry->SecConfig.Handshake.WpaState = AS_INITPSK; + } + +#ifdef DOT1X_SUPPORT + else if (IS_AKM_1X(pEntry->SecConfig.AKMMap) || IS_IEEE8021X_Entry(wdev)) { + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + pEntry->SecConfig.Handshake.WpaState = AS_AUTHENTICATION; + } + +#endif /* DOT1X_SUPPORT */ + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ASSOC - WSC_STATE_MACHINE is OFF.\n", + wsc_ctrl->WscConfMode, pEntry->func_tb_idx)); + 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 == Hostapd_EXT + && (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, isReassoc); + } 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) { + + } + + 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: + ======================================================================== +*/ +BOOLEAN IAPP_L2_Update_Frame_Send(RTMP_ADAPTER *pAd, UINT8 *mac, INT wdev_idx) +{ + NDIS_PACKET *pNetBuf; + struct wifi_dev *wdev; + + wdev = pAd->wdev_list[wdev_idx]; + pNetBuf = RtmpOsPktIappMakeUp(get_netdev_from_bssid(pAd, wdev_idx), mac); + + if (pNetBuf == NULL) + return FALSE; + + /*Which band is this packet transfer*/ +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + + if (wf_drv_tbl.wf_fwd_needed_hook != NULL && wf_drv_tbl.wf_fwd_needed_hook() == TRUE) + set_wf_fwd_cb(pAd, pNetBuf, wdev); + +#endif /* CONFIG_WIFI_PKT_FWD */ + /* 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, wdev_idx); + return TRUE; +} /* End of IAPP_L2_Update_Frame_Send */ +#endif /* IAPP_SUPPORT */ + + +/* + ========================================================================== + 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 }; +#ifdef CONFIG_HOTSPOT_R2 + UCHAR HS2_OSEN_OUI[4] = { 0x50, 0x6f, 0x9a, 0x12 }; + UCHAR HS2OUIBYTE[4] = {0x50, 0x6f, 0x9a, 0x10}; +#endif +#ifdef MBO_SUPPORT + UCHAR MBO_OCE_OUI_BYTE[4] = {0x50, 0x6f, 0x9a, 0x16}; +#endif /* MBO_SUPPORT */ + + MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)NULL; +#ifdef DOT11R_FT_SUPPORT + FT_INFO *pFtInfo = &ie_lists->FtInfo; +#endif /* DOT11R_FT_SUPPORT */ +#ifdef DOT11K_RRM_SUPPORT + RRM_EN_CAP_IE *pRrmEnCap = &ie_lists->RrmEnCap; +#endif /* DOT11K_RRM_SUPPORT */ + HT_CAPABILITY_IE *pHtCapability = &ie_lists->HTCapability; + UCHAR i; + + pEntry = MacTableLookup(pAd, &Fr->Hdr.Addr2[0]); + + if (pEntry == NULL) + return FALSE; + + COPY_MAC_ADDR(&ie_lists->Addr1[0], &Fr->Hdr.Addr1[0]); + 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; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("PeerAssocReqSanity - SsidLen = %d\n", ie_lists->SsidLen)); + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("PeerAssocReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n" + , eid_ptr->Len, ie_lists->SupportedRates[0])); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("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 */ + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES\n")); */ + Sanity |= 0x02; + ie_lists->SupportedRatesLen = 8; + NdisMoveMemory(&ie_lists->SupportedRates[0], RateDefault, 8); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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) { + UINT32 _RateIdx = ie_lists->SupportedRatesLen % + MAX_LEN_OF_SUPPORTED_RATES; + NdisMoveMemory(&ie_lists->SupportedRates[_RateIdx], 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 */ +#ifdef RT_BIG_ENDIAN + *(USHORT *)(&pHtCapability->TxBFCap) = le2cpu32(*(USHORT *)(&pHtCapability->TxBFCap)); +#endif + ie_lists->ht_cap_len = SIZE_HT_CAP_IE; + Sanity |= 0x10; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("PeerAssocReqSanity - IE_HT_CAP\n")); + } else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("PeerAssocReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", + eid_ptr->Len)); + + break; + + case IE_EXT_CAPABILITY: + if (eid_ptr->Len) { + INT ext_len = eid_ptr->Len; +#ifdef RT_BIG_ENDIAN + UCHAR *pextCapInfo = NULL; +#endif + ext_len = ext_len > sizeof(EXT_CAP_INFO_ELEMENT) ? sizeof(EXT_CAP_INFO_ELEMENT) : ext_len; + NdisMoveMemory(&ie_lists->ExtCapInfo, eid_ptr->Octet, ext_len); +#ifdef RT_BIG_ENDIAN + pextCapInfo = (UCHAR *)&ie_lists->ExtCapInfo; + *((UINT32 *)pextCapInfo) = cpu2le32(*((UINT32 *)pextCapInfo)); + *((UINT32 *)(pextCapInfo + 4)) = cpu2le32(*((UINT32 *)(pextCapInfo + 4))); +#endif + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); + } + + break; + + case IE_WPA: /* same as IE_VENDOR_SPECIFIC */ +#ifdef MBO_SUPPORT + if (NdisEqualMemory(eid_ptr->Octet, MBO_OCE_OUI_BYTE, sizeof(MBO_OCE_OUI_BYTE)) && (eid_ptr->Len >= 5)) { + MboParseStaMboIE(pAd, &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev, pEntry, eid_ptr->Octet, eid_ptr->Len, MBO_FRAME_TYPE_ASSOC_REQ); + break; + } +#endif /* MBO_SUPPORT */ + + + case IE_WPA2: +#ifdef DOT11R_FT_SUPPORT +#endif /* DOT11R_FT_SUPPORT */ +#ifdef CONFIG_HOTSPOT_R2 + if (NdisEqualMemory(eid_ptr->Octet, HS2OUIBYTE, sizeof(HS2OUIBYTE)) && (eid_ptr->Len >= 5)) { + /* UCHAR tmp2 = 0x12; */ + UCHAR *hs2_config = (UCHAR *)&eid_ptr->Octet[4]; + UCHAR ppomo_exist = ((*hs2_config) >> 1) & 0x01; + UCHAR hs2_version = ((*hs2_config) >> 4) & 0x0f; + /* UCHAR *tmp3 = (UCHAR *)&pEntry->hs_info.ppsmo_id; */ + /* UCHAR tmp[2] = {0x12,0x34}; */ + pEntry->hs_info.version = hs2_version; + pEntry->hs_info.ppsmo_exist = ppomo_exist; + + if (pEntry->hs_info.ppsmo_exist) { + NdisMoveMemory(&pEntry->hs_info.ppsmo_id, &eid_ptr->Octet[5], 2); + /* NdisMoveMemory(tmp3, tmp, 2); */ + } + + break; + } + +#endif /* CONFIG_HOTSPOT_R2 */ + + + if (NdisEqualMemory(eid_ptr->Octet, WPS_OUI, 4)) { +#ifdef WSC_AP_SUPPORT +#ifdef WSC_V2_SUPPORT + + if ((pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.WscControl.WscV2Info.bWpsEnable) || + (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.WscControl.WscV2Info.bEnableWpsV2 == FALSE)) +#endif /* WSC_V2_SUPPORT */ + ie_lists->bWscCapable = TRUE; + +#ifdef RT_CFG80211_SUPPORT + ie_lists->bWscCapable = TRUE; +#endif +#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; + } + } + + check_vendor_ie(pAd, (UCHAR *)eid_ptr, &(ie_lists->vendor_ie)); + + /* 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->func_tb_idx].wdev.UapsdInfo.bAPSDCapable); + } + +#endif /* UAPSD_SUPPORT */ + break; + } + + if (IS_NO_SECURITY(&pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.SecConfig) + || IS_CIPHER_WEP(pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.SecConfig.PairwiseCipher)) + 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)) + && !(eid_ptr->Eid == IE_WPA2)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Not RSN IE, maybe WMM IE!!!\n")); +#ifdef CONFIG_HOTSPOT_R2 + + if (!NdisEqualMemory(eid_ptr->Octet, HS2_OSEN_OUI, sizeof(HS2_OSEN_OUI))) { + unsigned char *tmp = (unsigned char *)eid_ptr->Octet; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!!!!!!not found OSEN IE,%x:%x:%x:%x\n", *tmp, *(tmp + 1), + *(tmp + 2), *(tmp + 3))); + pEntry->OSEN_IE_Len = 0; + CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_OSEN_CAPABLE); + break; + } + + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_OSEN_CAPABLE); + NdisMoveMemory(pEntry->OSEN_IE, eid_ptr, eid_ptr->Len + 2); + pEntry->OSEN_IE_Len = eid_ptr->Len + 2; + SET_AKM_WPA2(pEntry->SecConfig.AKMMap); + SET_CIPHER_CCMP128(pEntry->SecConfig.PairwiseCipher); + SET_CIPHER_CCMP128(pEntry->SecConfig.GroupCipher); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!!!!!!found OSEN IE Entry AuthMode %s, EncryptType %s\n", + GetAuthModeStr(pEntry->SecConfig.AKMMap), GetEncryModeStr(pEntry->SecConfig.PairwiseCipher))); +#else + break; +#endif + } + + /* Copy whole RSNIE context */ + NdisMoveMemory(&ie_lists->RSN_IE[0], eid_ptr, eid_ptr->Len + 2); + ie_lists->RSNIE_Len = eid_ptr->Len + 2; +#ifdef DOT11R_FT_SUPPORT + NdisMoveMemory(pFtInfo->RSN_IE, eid_ptr, eid_ptr->Len + 2); + pFtInfo->RSNIE_Len = eid_ptr->Len + 2; +#endif /* DOT11R_FT_SUPPORT */ + + break; +#ifdef DOT11R_FT_SUPPORT + + case IE_FT_MDIE: + FT_FillMdIeInfo(eid_ptr, &pFtInfo->MdIeInfo); + break; + + case IE_FT_FTIE: + FT_FillFtIeInfo(eid_ptr, &pFtInfo->FtIeInfo); + break; + + case IE_FT_RIC_DATA: + + /* record the pointer of first RDIE. */ + if (pFtInfo->RicInfo.pRicInfo == NULL) { + pFtInfo->RicInfo.pRicInfo = &eid_ptr->Eid; + pFtInfo->RicInfo.Len = ((UCHAR *)Fr + MsgLen) - (UCHAR *)eid_ptr + 1; + } + break; + + case IE_FT_RIC_DESCRIPTOR: + if ((pFtInfo->RicInfo.RicIEsLen + eid_ptr->Len + 2) < MAX_RICIES_LEN) { + NdisMoveMemory(&pFtInfo->RicInfo.RicIEs[pFtInfo->RicInfo.RicIEsLen], + &eid_ptr->Eid, eid_ptr->Len + 2); + pFtInfo->RicInfo.RicIEsLen += eid_ptr->Len + 2; + } + + break; +#endif /* DOT11R_FT_SUPPORT */ +#ifdef DOT11K_RRM_SUPPORT + + case IE_RRM_EN_CAP: { + UINT64 value; + + NdisMoveMemory(&value, eid_ptr->Octet, sizeof(UINT64)); + pRrmEnCap->word = le2cpu64(value); + } + break; +#endif /* DOT11K_RRM_SUPPORT */ +#ifdef DOT11_VHT_AC + + case IE_VHT_CAP: + if (eid_ptr->Len == sizeof(VHT_CAP_IE)) { +#ifdef RT_BIG_ENDIAN + UINT32 tmp_1; + UINT64 tmp_2; +#endif + NdisMoveMemory(&ie_lists->vht_cap, eid_ptr->Octet, sizeof(VHT_CAP_IE)); + ie_lists->vht_cap_len = eid_ptr->Len; +#ifdef RT_BIG_ENDIAN + NdisCopyMemory(&tmp_1, &ie_lists->vht_cap.vht_cap, 4); + tmp_1 = le2cpu32(tmp_1); + NdisCopyMemory(&ie_lists->vht_cap.vht_cap, &tmp_1, 4); + + NdisCopyMemory(&tmp_2, &(ie_lists->vht_cap.mcs_set), 8); + tmp_2 = le2cpu64(tmp_2); + NdisCopyMemory(&(ie_lists->vht_cap.mcs_set), &tmp_2, 8); +#endif + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():IE_VHT_CAP\n", __func__)); + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s():wrong IE_VHT_CAP, eid->Len = %d\n", + __func__, eid_ptr->Len)); + } + break; + + case IE_VHT_OP: + if (eid_ptr->Len == sizeof(VHT_OP_IE)) { +#ifdef RT_BIG_ENDIAN + UINT32 tmp; +#endif + NdisMoveMemory(&ie_lists->vht_op, eid_ptr->Octet, sizeof(VHT_OP_IE)); + ie_lists->vht_op_len = eid_ptr->Len; +#ifdef RT_BIG_ENDIAN + NdisCopyMemory(&tmp, &ie_lists->vht_op.basic_mcs_set, sizeof(VHT_MCS_MAP)); + tmp = le2cpu16(tmp); + NdisCopyMemory(&ie_lists->vht_op.basic_mcs_set, &tmp, sizeof(VHT_MCS_MAP)); +#endif + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s():IE_VHT_OP\n", __func__)); + } + break; + + case IE_OPERATING_MODE_NOTIFY: + if (eid_ptr->Len == sizeof(OPERATING_MODE)) { + ie_lists->operating_mode_len = sizeof(OPERATING_MODE); + NdisMoveMemory(&ie_lists->operating_mode, &eid_ptr->Octet[0], sizeof(OPERATING_MODE)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s():IE_OPERATING_MODE_NOTIFY!\n", __func__)); + } + + break; +#endif /* DOT11_VHT_AC */ + + case IE_SUPP_CHANNELS: + if (eid_ptr->Len > MAX_LEN_OF_SUPPORTED_CHL || (eid_ptr->Len % 2)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s():wrong IE_SUPP_CHANNELS, eid->Len = %d\n", + __func__, eid_ptr->Len)); + } else if (eid_ptr->Len + ie_lists->SupportedChlLen <= MAX_LEN_OF_SUPPORTED_CHL) { + UINT32 _ChlIdx = ie_lists->SupportedChlLen % + MAX_LEN_OF_SUPPORTED_CHL; + NdisMoveMemory(&ie_lists->SupportedChl[_ChlIdx], eid_ptr->Octet, + eid_ptr->Len); + ie_lists->SupportedChlLen += eid_ptr->Len; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():IE_SUPP_CHANNELS, eid->Len = %d\n", + __func__, eid_ptr->Len)); + } else { + NdisMoveMemory(&ie_lists->SupportedChl[ie_lists->SupportedChlLen], eid_ptr->Octet, + MAX_LEN_OF_SUPPORTED_CHL - (ie_lists->SupportedChlLen)); + ie_lists->SupportedChlLen = MAX_LEN_OF_SUPPORTED_CHL; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():IE_SUPP_CHANNELS, eid->Len = %d (Exceeded)\n", + __func__, eid_ptr->Len)); + } + + if (ie_lists->SupportedChlLen > MAX_LEN_OF_SUPPORTED_CHL) + ie_lists->SupportedChlLen = MAX_LEN_OF_SUPPORTED_CHL; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, (" Supported Channels: [ FirstCh : NumOfCh ]\n")); + + for (i = 0; i < ie_lists->SupportedChlLen; i += 2) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, (" [ %4d : %4d ]\n", ie_lists->SupportedChl[i], + ie_lists->SupportedChl[i + 1])); + + break; + case IE_WLAN_EXTENSION: + { + /*parse EXTENSION EID*/ + UCHAR *extension_id = (UCHAR *)eid_ptr + 2; + + switch (*extension_id) { + case IE_EXTENSION_ID_ECDH: +#ifdef CONFIG_OWE_SUPPORT + { + UCHAR *ext_ie_length = (UCHAR *)eid_ptr + 1; + os_zero_mem(ie_lists->ecdh_ie.public_key, *ext_ie_length-3); + ie_lists->ecdh_ie.ext_ie_id = IE_WLAN_EXTENSION; + ie_lists->ecdh_ie.length = eid_ptr->Len; + NdisMoveMemory(&ie_lists->ecdh_ie.ext_id_ecdh, eid_ptr->Octet, eid_ptr->Len); + } +#endif /*CONFIG_OWE_SUPPORT*/ + break; + default: + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("IE_WLAN_EXTENSION: no handler for extension_id:%d\n", *extension_id)); + break; + } + } + break; + default: + break; + } + + eid_ptr = (PEID_STRUCT)((UCHAR *)eid_ptr + 2 + eid_ptr->Len); + } + + + if ((Sanity & 0x3) != 0x03) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s(): - missing mandatory field\n", __func__)); + return FALSE; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s() - success\n", __func__)); + return TRUE; +} + + +VOID ap_cmm_peer_assoc_req_action( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM * Elem, + IN BOOLEAN isReassoc) +{ + struct wifi_dev *wdev = NULL; + struct dev_rate_info *rate; + BSS_STRUCT *pMbss; + BOOLEAN bAssocSkip = FALSE; + CHAR rssi; + IE_LISTS *ie_list = NULL; + HEADER_802_11 AssocRspHdr; + USHORT CapabilityInfoForAssocResp; + USHORT StatusCode = MLME_SUCCESS; + USHORT Aid = 0; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + UCHAR MaxSupportedRate = 0; + UCHAR SupRateLen, PhyMode, FlgIs11bSta; + UCHAR i; +#if defined(TXBF_SUPPORT) && defined(VHT_TXBF_SUPPORT) + UCHAR ucETxBfCap; +#endif /* TXBF_SUPPORT && VHT_TXBF_SUPPORT */ + MAC_TABLE_ENTRY *pEntry = NULL; + STA_TR_ENTRY *tr_entry; +#ifdef DBG + UCHAR *sAssoc = isReassoc ? (PUCHAR)"ReASSOC" : (PUCHAR)"ASSOC"; +#endif /* DBG */ + UCHAR SubType; + BOOLEAN bACLReject = FALSE; + PUINT8 pPmkid = NULL; + UINT8 pmkid_count = 0; +#ifdef DOT11R_FT_SUPPORT + PFT_CFG pFtCfg = NULL; + FT_INFO FtInfoBuf; +#endif /* DOT11R_FT_SUPPORT */ +#ifdef WSC_AP_SUPPORT + WSC_CTRL *wsc_ctrl; +#endif /* WSC_AP_SUPPORT */ +#ifdef RT_BIG_ENDIAN + UINT32 tmp_1; + UINT64 tmp_2; +#endif /*RT_BIG_ENDIAN*/ + ADD_HT_INFO_IE *addht; +#ifdef GREENAP_SUPPORT + struct greenap_ctrl *greenap = &pAd->ApCfg.greenap; +#endif /* GREENAP_SUPPORT */ + struct _build_ie_info ie_info; +#ifdef MBO_SUPPORT + BOOLEAN bMboReject = FALSE; +#endif /* MBO_SUPPORT */ + + + /* disallow new association */ + if (pAd->ApCfg.BANClass3Data == TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Disallow new Association\n")); + return; + } + + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(IE_LISTS)); + + if (ie_list == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(): mem alloc failed\n", __func__)); + return; + } + + NdisZeroMemory(ie_list, sizeof(IE_LISTS)); + + if (!PeerAssocReqCmmSanity(pAd, isReassoc, Elem->Msg, Elem->MsgLen, ie_list)) + goto LabelOK; + + pEntry = MacTableLookup(pAd, ie_list->Addr2); + + if (!pEntry) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("NoAuth MAC - %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(ie_list->Addr2))); + goto LabelOK; + } + + if (!VALID_MBSS(pAd, pEntry->func_tb_idx)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s():pEntry bounding invalid wdev(apidx=%d)\n", + __func__, pEntry->func_tb_idx)); + goto LabelOK; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s():pEntry->func_tb_idx=%d\n", + __func__, pEntry->func_tb_idx)); + wdev = wdev_search_by_address(pAd, ie_list->Addr1); + + if (wdev == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Wrong Addr1 - %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(ie_list->Addr1))); + goto LabelOK; + } + + pMbss = &pAd->ApCfg.MBSSID[wdev->func_idx]; + tr_entry = &pAd->MacTab.tr_entry[pEntry->tr_tb_idx]; +#ifdef WSC_AP_SUPPORT + wsc_ctrl = &wdev->WscControl; +#endif /* WSC_AP_SUPPORT */ + PhyMode = wdev->PhyMode; + rate = &wdev->rate; + addht = wlan_operate_get_addht(wdev); + + if (!OPSTATUS_TEST_FLAG_WDEV(wdev, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(): AP is not ready, disallow new Association\n", __func__)); + goto LabelOK; + } + + + ie_info.frame_subtype = SUBTYPE_ASSOC_RSP; + ie_info.channel = wdev->channel; + ie_info.phy_mode = PhyMode; + ie_info.wdev = wdev; + +#ifdef HTC_DECRYPT_IOT + + if ((pEntry->HTC_ICVErrCnt) + || (pEntry->HTC_AAD_OM_Force) + || (pEntry->HTC_AAD_OM_CountDown) + || (pEntry->HTC_AAD_OM_Freeze) + ) { + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("@@@ %s(): (wcid=%u), HTC_ICVErrCnt(%u), HTC_AAD_OM_Freeze(%u), HTC_AAD_OM_CountDown(%u), HTC_AAD_OM_Freeze(%u) is in Asso. stage!\n", + __func__, pEntry->wcid, pEntry->HTC_ICVErrCnt, pEntry->HTC_AAD_OM_Force, pEntry->HTC_AAD_OM_CountDown, + pEntry->HTC_AAD_OM_Freeze)); + /* Force clean. */ + pEntry->HTC_ICVErrCnt = 0; + pEntry->HTC_AAD_OM_Force = 0; + pEntry->HTC_AAD_OM_CountDown = 0; + pEntry->HTC_AAD_OM_Freeze = 0; + } + +#endif /* HTC_DECRYPT_IOT */ + FlgIs11bSta = 1; + + for (i = 0; i < ie_list->SupportedRatesLen; i++) { + if (((ie_list->SupportedRates[i] & 0x7F) != 2) && + ((ie_list->SupportedRates[i] & 0x7F) != 4) && + ((ie_list->SupportedRates[i] & 0x7F) != 11) && + ((ie_list->SupportedRates[i] & 0x7F) != 22)) { + FlgIs11bSta = 0; + break; + } + } + + +#ifdef MBO_SUPPORT + if (!MBO_AP_ALLOW_ASSOC(wdev)) { + StatusCode = MLME_ASSOC_REJ_UNABLE_HANDLE_STA; + bMboReject = TRUE; + goto SendAssocResponse; + } +#endif /* MBO_SUPPORT */ + +#ifdef DOT11W_PMF_SUPPORT + + if ((tr_entry->PortSecured == WPA_802_1X_PORT_SECURED) + && (pEntry->SecConfig.PmfCfg.UsePMFConnect == TRUE) +#ifdef DOT11R_FT_SUPPORT + && (!IS_FT_RSN_STA(pEntry)) +#endif /* DOT11R_FT_SUPPORT */ + ) { + StatusCode = MLME_ASSOC_REJ_TEMPORARILY; + goto SendAssocResponse; + } + +#endif /* DOT11W_PMF_SUPPORT */ + + /* clear the previous Pairwise key table */ + if ((pEntry->Aid != 0) +#ifdef DOT11R_FT_SUPPORT + && (!IS_FT_STA(pEntry)) +#endif /* DOT11R_FT_SUPPORT */ + && ((!IS_AKM_OPEN(pEntry->SecConfig.AKMMap)) || (!IS_AKM_SHARED(pEntry->SecConfig.AKMMap)) +#ifdef DOT1X_SUPPORT + || IS_IEEE8021X(&pEntry->SecConfig) +#endif /* DOT1X_SUPPORT */ + )) { + ASIC_SEC_INFO Info = {0}; + /* clear GTK state */ + pEntry->SecConfig.Handshake.GTKState = REKEY_NEGOTIATING; + NdisZeroMemory(&pEntry->SecConfig.PTK, LEN_MAX_PTK); + /* Set key material to Asic */ + os_zero_mem(&Info, sizeof(ASIC_SEC_INFO)); + Info.Operation = SEC_ASIC_REMOVE_PAIRWISE_KEY; + Info.Wcid = pEntry->wcid; + /* Set key material to Asic */ + HW_ADDREMOVE_KEYTABLE(pAd, &Info); +#if defined(DOT1X_SUPPORT) && !defined(RADIUS_ACCOUNTING_SUPPORT) + + /* Notify 802.1x daemon to clear this sta info */ + if (IS_AKM_1X(pEntry->SecConfig.AKMMap) + || IS_IEEE8021X(&pEntry->SecConfig)) + DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); + +#endif /* DOT1X_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 ((wsc_ctrl->WscV2Info.bEnableWpsV2) && + (wsc_ctrl->WscV2Info.bWpsEnable == FALSE)) + ; + else +#endif /* WSC_V2_SUPPORT */ + { + if (pEntry->func_tb_idx < pAd->ApCfg.BssidNum) { + if (MAC_ADDR_EQUAL(pEntry->Addr, wsc_ctrl->EntryAddr)) { + BOOLEAN Cancelled; + + RTMPZeroMemory(wsc_ctrl->EntryAddr, MAC_ADDR_LEN); + RTMPCancelTimer(&wsc_ctrl->EapolTimer, &Cancelled); + wsc_ctrl->EapolTimerRunning = FALSE; + } + } + + if ((ie_list->RSNIE_Len == 0) && + (IS_AKM_WPA_CAPABILITY_Entry(wdev)) && + (wsc_ctrl->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 != pMbss->SsidLen) || + (NdisEqualMemory(ie_list->Ssid, pMbss->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) && + (wsc_ctrl->WscConfMode != WSC_DISABLE) && + (wsc_ctrl->WscV2Info.bEnableWpsV2) && + (wsc_ctrl->WscV2Info.bWpsEnable) && + (MAC_ADDR_EQUAL(wsc_ctrl->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->func_tb_idx)) + bACLReject = TRUE; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s - MBSS(%d), receive %s request from %02x:%02x:%02x:%02x:%02x:%02x\n", + sAssoc, pEntry->func_tb_idx, sAssoc, PRINT_MAC(ie_list->Addr2))); + + /* supported rates array may not be sorted. sort it and find the maximum rate */ + for (i = 0; i < ie_list->SupportedRatesLen; i++) { + if (MaxSupportedRate < (ie_list->SupportedRates[i] & 0x7f)) + MaxSupportedRate = ie_list->SupportedRates[i] & 0x7f; + } + + /* + Assign RateLen here or we will select wrong rate table in + APBuildAssociation() when 11N compile option is disabled. + */ + pEntry->RateLen = ie_list->SupportedRatesLen; + + RTMPSetSupportMCS(pAd, + OPMODE_AP, + pEntry, + ie_list->SupportedRates, + ie_list->SupportedRatesLen, + NULL, + 0, +#ifdef DOT11_VHT_AC + ie_list->vht_cap_len, + &ie_list->vht_cap, +#endif /* DOT11_VHT_AC */ + &ie_list->HTCapability, + ie_list->ht_cap_len); + + /* 2. qualify this STA's auth_asoc status in the MAC table, decide StatusCode */ + StatusCode = APBuildAssociation(pAd, pEntry, ie_list, MaxSupportedRate, &Aid, isReassoc); + + /*is status is success ,update STARec*/ + if (StatusCode == MLME_SUCCESS && (pEntry->Sst == SST_ASSOC)) { + if (wdev_do_conn_act(pEntry->wdev, pEntry) != TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s():connect action fail!!\n", __func__)); + } + } + +#ifdef DOT11R_FT_SUPPORT + + if (pEntry->func_tb_idx < pAd->ApCfg.BssidNum) { + pFtCfg = &(wdev->FtCfg); + + if ((pFtCfg->FtCapFlag.Dot11rFtEnable) + && (StatusCode == MLME_SUCCESS)) + StatusCode = FT_AssocReqHandler(pAd, isReassoc, pFtCfg, pEntry, + &ie_list->FtInfo, &FtInfoBuf); + + /* just silencely discard this frame */ + if (StatusCode == 0xFFFF) + goto LabelOK; + } + +#endif /* DOT11R_FT_SUPPORT */ +#ifdef DOT11K_RRM_SUPPORT + + if ((pEntry->func_tb_idx < pAd->ApCfg.BssidNum) + && IS_RRM_ENABLE(wdev)) + pEntry->RrmEnCap.word = ie_list->RrmEnCap.word; + +#endif /* DOT11K_RRM_SUPPORT */ +#ifdef DOT11_VHT_AC + + if (ie_list->vht_cap_len) { + /* +++Add by shiang for debug */ + if (WMODE_CAP_AC(wdev->PhyMode)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s():Peer is VHT capable device!\n", __func__)); + NdisMoveMemory(&pEntry->ext_cap, &ie_list->ExtCapInfo, sizeof(ie_list->ExtCapInfo)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("\tOperatingModeNotification=%d\n", + pEntry->ext_cap.operating_mode_notification)); + /* 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, wdev->wdev_idx, 0); + +#ifdef DOT11W_PMF_SUPPORT +SendAssocResponse: +#endif /* DOT11W_PMF_SUPPORT */ + /* 3. send Association Response */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + goto LabelOK; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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 = pMbss->CapabilityInfo; /*use AP's cability */ +#ifdef WSC_AP_SUPPORT +#ifdef WSC_V2_SUPPORT + + if ((wsc_ctrl->WscV2Info.bEnableWpsV2) && + (wsc_ctrl->WscV2Info.bWpsEnable == FALSE)) + ; + else +#endif /* WSC_V2_SUPPORT */ + { + if ((wsc_ctrl->WscConfMode != WSC_DISABLE) && + (ie_list->CapabilityInfo & 0x0010)) + CapabilityInfoForAssocResp |= 0x0010; + } + +#endif /* WSC_AP_SUPPORT */ + /* fail in ACL checking => send an Assoc-Fail resp. */ + SupRateLen = rate->SupRateLen; + + /* TODO: need to check rate in support rate element, not number */ + if (FlgIs11bSta == 1) + SupRateLen = 4; + + /* YF@20120419: Refuse the weak signal of AssocReq */ + rssi = RTMPMaxRssi(pAd, + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_2)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("ra[%d] ASSOC_REQ Threshold = %d, PktMaxRssi=%d\n", + pEntry->func_tb_idx, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].AssocReqRssiThreshold, + rssi)); + + if ((pAd->ApCfg.MBSSID[pEntry->func_tb_idx].AssocReqRssiThreshold != 0) && + (rssi < pAd->ApCfg.MBSSID[pEntry->func_tb_idx].AssocReqRssiThreshold)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Reject this ASSOC_REQ due to Weak Signal.\n")); + bAssocSkip = TRUE; + } + + if (bACLReject == TRUE || bAssocSkip) { + MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2, + wdev->if_addr, 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, rate->SupRate, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory((PVOID) pOutBuffer); + RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, ie_list->Addr2, wdev->wdev_idx, 0); +#ifdef WSC_V2_SUPPORT + + /* If this STA exists, delete it. */ + if (pEntry) + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + +#endif /* WSC_V2_SUPPORT */ + + if (bAssocSkip == TRUE) { + pEntry = MacTableLookup(pAd, ie_list->Addr2); + + if (pEntry) + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + } + + goto LabelOK; + } + + MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2, + wdev->if_addr, wdev->bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &AssocRspHdr, + 2, &CapabilityInfoForAssocResp, + 2, &StatusCode, + 2, &Aid, + 1, &SupRateIe, + 1, &SupRateLen, + SupRateLen, rate->SupRate, + END_OF_ARGS); + + if ((rate->ExtRateLen) && (PhyMode != WMODE_B) && (FlgIs11bSta == 0)) { + ULONG TmpLen; + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &ExtRateIe, + 1, &rate->ExtRateLen, + rate->ExtRateLen, rate->ExtRate, + END_OF_ARGS); + FrameLen += TmpLen; + } + + +#ifdef DOT11K_RRM_SUPPORT + + if (IS_RRM_ENABLE(wdev)) + RRM_InsertRRMEnCapIE(pAd, pOutBuffer + FrameLen, &FrameLen, pEntry->func_tb_idx); + +#endif /* DOT11K_RRM_SUPPORT */ + + /* add WMM IE here */ + /* printk("%s()=>bWmmCapable=%d,CLINE=%d\n",__FUNCTION__,wdev->bWmmCapable,CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)); */ + + if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) { + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_wmm_cap_ie(pAd, &ie_info); + } + +#ifdef DOT11W_PMF_SUPPORT + + if (StatusCode == MLME_ASSOC_REJ_TEMPORARILY) { + ULONG TmpLen; + UCHAR IEType = IE_TIMEOUT_INTERVAL; /* IE:0x15 */ + UCHAR IELen = 5; + UCHAR TIType = 3; + UINT32 units = 1 << 10; /* 1 seconds, should be 0x3E8 */ + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &IEType, + 1, &IELen, + 1, &TIType, + 4, &units, + END_OF_ARGS); + FrameLen += TmpLen; + } + +#endif /* DOT11W_PMF_SUPPORT */ +#ifdef DOT11_N_SUPPORT + + /* HT capability in AssocRsp frame. */ + if ((ie_list->ht_cap_len > 0) && WMODE_CAP_N(wdev->PhyMode) && + (wdev->DesiredHtPhyInfo.bHtEnable)) { +#ifdef DOT11_VHT_AC + struct _build_ie_info vht_ie_info; +#endif /* DOT11_VHT_AC */ + + ie_info.is_draft_n_type = FALSE; + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_ht_ies(pAd, &ie_info); + + if ((ie_list->vendor_ie.ra_cap) == 0 || (pAd->bBroadComHT == TRUE)) { + ie_info.is_draft_n_type = TRUE; + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_ht_ies(pAd, &ie_info); + + } +#ifdef DOT11_VHT_AC + vht_ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + vht_ie_info.frame_subtype = SUBTYPE_ASSOC_RSP; + vht_ie_info.channel = wdev->channel; + vht_ie_info.phy_mode = wdev->PhyMode; + vht_ie_info.wdev = wdev; +#if defined(TXBF_SUPPORT) && defined(VHT_TXBF_SUPPORT) + ucETxBfCap = wlan_config_get_etxbf(wdev); + + if (HcIsBfCapSupport(wdev) == FALSE) + wlan_config_set_etxbf(wdev, SUBF_OFF); + +#endif /* TXBF_SUPPORT && VHT_TXBF_SUPPORT */ + FrameLen += build_vht_ies(pAd, &vht_ie_info); +#if defined(TXBF_SUPPORT) && defined(VHT_TXBF_SUPPORT) + wlan_config_set_etxbf(wdev, ucETxBfCap); +#endif /* TXBF_SUPPORT && VHT_TXBF_SUPPORT */ +#endif /* DOT11_VHT_AC */ + } + +#endif /* DOT11_N_SUPPORT */ +#ifdef CONFIG_HOTSPOT_R2 + /* qosmap IE */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("entry wcid %d QosMapSupport=%d\n", + pEntry->wcid, pEntry->QosMapSupport)); + + if (pEntry->QosMapSupport) { + ULONG TmpLen; + UCHAR QosMapIE, ielen = 0, explen = 0; + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[pEntry->apidx].HotSpotCtrl; + + if (pHSCtrl->QosMapEnable) { + QosMapIE = IE_QOS_MAP_SET; + + /* Fixed field Dscp range:16, len:1 IE_ID:1*/ + if (pHSCtrl->QosMapSetIELen > 18) + explen = pHSCtrl->QosMapSetIELen - 18; + + pEntry->DscpExceptionCount = explen; + memcpy((UCHAR *)pEntry->DscpRange, (UCHAR *)pHSCtrl->DscpRange, 16); + memcpy((UCHAR *)pEntry->DscpException, (UCHAR *)pHSCtrl->DscpException, 42); + ielen = explen + 16; + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &QosMapIE, + 1, &ielen, + explen, pEntry->DscpException, + 16, pEntry->DscpRange, + END_OF_ARGS); + FrameLen += TmpLen; + } + } + +#endif /* CONFIG_HOTSPOT_R2 */ + + if (IS_AKM_OWE_Entry(pEntry)) { + CHAR rsne_idx; + ULONG TmpLen; + struct _SECURITY_CONFIG *pSecConfig = &pEntry->SecConfig; + /*struct _SECURITY_CONFIG *pSecConfig = &wdev->SecConfig;*/ + + WPAMakeRSNIE(wdev->wdev_type, pSecConfig, pEntry); + + for (rsne_idx = 0; rsne_idx < SEC_RSNIE_NUM; rsne_idx++) { + if (pSecConfig->RSNE_Type[rsne_idx] == SEC_RSNIE_NONE) + continue; + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &pSecConfig->RSNE_EID[rsne_idx][0], + 1, &pSecConfig->RSNE_Len[rsne_idx], + pSecConfig->RSNE_Len[rsne_idx], + &pSecConfig->RSNE_Content[rsne_idx][0], + END_OF_ARGS); + FrameLen += TmpLen; + } + } + + /* 7.3.2.27 Extended Capabilities IE */ + { + ULONG TmpLen, infoPos; + PUCHAR pInfo; + UCHAR extInfoLen; + BOOLEAN bNeedAppendExtIE = FALSE; + EXT_CAP_INFO_ELEMENT extCapInfo; +#ifdef RT_BIG_ENDIAN + UCHAR *pextCapInfo; +#endif + + 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(wdev->PhyMode) + && (wdev->channel <= 14) + && (pAd->CommonCfg.bBssCoexEnable == TRUE) + ) + extCapInfo.BssCoexistMgmtSupport = 1; + +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ +#ifdef CONFIG_DOT11V_WNM + /* #ifdef CONFIG_HOTSPOT_R2 Remove for WNM independance */ + + if (ie_list->ExtCapInfo.BssTransitionManmt == 1) { + pEntry->bBSSMantSTASupport = TRUE; + if (pMbss->WNMCtrl.WNMBTMEnable) + extCapInfo.BssTransitionManmt = 1; + } + /* #endif CONFIG_HOTSPOT_R2 */ +#endif /* CONFIG_DOT11V_WNM */ + +#ifdef CONFIG_DOT11U_INTERWORKING + if (pMbss->GASCtrl.b11U_enable) + extCapInfo.interworking = 1; +#endif /* CONFIG_DOT11U_INTERWORKING */ + +#ifdef DOT11_VHT_AC + + if (WMODE_CAP_AC(wdev->PhyMode) && + (wdev->channel > 14)) + extCapInfo.operating_mode_notification = 1; + +#endif /* DOT11_VHT_AC */ +#ifdef FTM_SUPPORT + + /* add IE_EXT_CAPABILITY IE here */ + if (pAd->pFtmCtrl->bSetCivicRpt) + extCapInfo.civic_location = 1; + + if (pAd->pFtmCtrl->bSetLciRpt) + extCapInfo.geospatial_location = 1; + + /* 802.11mc D3.0: 10.24.6.2 (p.1717): + "A STA in which dot11FineTimingMsmtRespActivated is true shall set the Fine Timing Measurement + Responder field of the Extended Capabilities element to 1." + */ + /* 8.4.2.26 Extended Capabilities element (p.817): + Capabilities field= 70: Fine Timing Measurement Responder (p.823) + */ + extCapInfo.ftm_resp = 1; +#endif /* FTM_SUPPORT */ +#ifdef RT_BIG_ENDIAN + pextCapInfo = (UCHAR *)&extCapInfo; + *((UINT32 *)pextCapInfo) = cpu2le32(*((UINT32 *)pextCapInfo)); + pextCapInfo = (UCHAR *)&extCapInfo; + *((UINT32 *)(pextCapInfo + 4)) = cpu2le32(*((UINT32 *)(pextCapInfo + 4))); +#endif + + pInfo = (UCHAR *)(&extCapInfo); + + for (infoPos = 0; infoPos < extInfoLen; infoPos++) { + if (pInfo[infoPos] != 0) { + bNeedAppendExtIE = TRUE; + break; + } + } + + if (bNeedAppendExtIE == TRUE) { + for (infoPos = (extInfoLen - 1); infoPos >= EXT_CAP_MIN_SAFE_LENGTH; infoPos--) { + if (pInfo[infoPos] == 0) + extInfoLen--; + else + break; + } +#ifdef RT_BIG_ENDIAN + RTMPEndianChange((UCHAR *)&extCapInfo, 8); +#endif + + 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 */ + FrameLen += build_vendor_ie(pAd, wdev, (pOutBuffer + FrameLen), VIE_ASSOC_RESP + ); + +#ifdef MBO_SUPPORT + if (IS_MBO_ENABLE(wdev)) + MakeMboOceIE(pAd, wdev, pOutBuffer+FrameLen, &FrameLen, MBO_FRAME_TYPE_ASSOC_RSP); +#endif /* MBO_SUPPORT */ +#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->func_tb_idx, 0, pWscBuf, &WscIeLen); + MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, + WscIeLen, pWscBuf, + END_OF_ARGS); + FrameLen += WscTmpLen; + os_free_mem(pWscBuf); + } + } + +#endif /* WSC_AP_SUPPORT */ +#ifdef RT_CFG80211_SUPPORT + + /* Append extra IEs provided by wpa_supplicant */ + if (pAd->ApCfg.MBSSID[pEntry->apidx].AssocRespExtraIeLen) { + ULONG TmpLen = 0; + INT32 IesLen = pAd->ApCfg.MBSSID[pEntry->apidx].AssocRespExtraIeLen; + UCHAR *Ies = pAd->ApCfg.MBSSID[pEntry->apidx].AssocRespExtraIe; + + if (RTMPIsValidIEs(Ies, IesLen)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("AssocRespExtraIE Added (Len=%d)\n", IesLen)); + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, + IesLen, + Ies, + END_OF_ARGS); + FrameLen += TmpLen; + } else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("AssocRespExtraIE len incorrect!\n")); + } + +#endif /* RT_CFG80211_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + + if ((pFtCfg != NULL) && (pFtCfg->FtCapFlag.Dot11rFtEnable)) { + PUINT8 mdie_ptr; + UINT8 mdie_len; + PUINT8 ftie_ptr = NULL; + UINT8 ftie_len = 0; + PUINT8 ricie_ptr = NULL; + UINT8 ricie_len = 0; + struct _SECURITY_CONFIG *pSecConfig = &pEntry->SecConfig; + + /* Insert RSNIE if necessary */ + if (FtInfoBuf.RSNIE_Len != 0) { + ULONG TmpLen; + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + FtInfoBuf.RSNIE_Len, FtInfoBuf.RSN_IE, + END_OF_ARGS); + FrameLen += TmpLen; + } + + /* Insert MDIE. */ + mdie_ptr = pOutBuffer + FrameLen; + mdie_len = 5; + FT_InsertMdIE(pAd, pOutBuffer + FrameLen, + &FrameLen, + FtInfoBuf.MdIeInfo.MdId, + FtInfoBuf.MdIeInfo.FtCapPlc); + + /* Insert FTIE. */ + if (FtInfoBuf.FtIeInfo.Len != 0) { + ftie_ptr = pOutBuffer + FrameLen; + ftie_len = (2 + FtInfoBuf.FtIeInfo.Len); + FT_InsertFTIE(pAd, pOutBuffer + FrameLen, &FrameLen, + FtInfoBuf.FtIeInfo.Len, + FtInfoBuf.FtIeInfo.MICCtr, + FtInfoBuf.FtIeInfo.MIC, + FtInfoBuf.FtIeInfo.ANonce, + FtInfoBuf.FtIeInfo.SNonce); + } + + /* Insert R1KH IE into FTIE. */ + if (FtInfoBuf.FtIeInfo.R1khIdLen != 0) + FT_FTIE_InsertKhIdSubIE(pAd, pOutBuffer + FrameLen, + &FrameLen, + FT_R1KH_ID, + FtInfoBuf.FtIeInfo.R1khId, + FtInfoBuf.FtIeInfo.R1khIdLen); + + /* Insert GTK Key info into FTIE. */ + if (FtInfoBuf.FtIeInfo.GtkLen != 0) + FT_FTIE_InsertGTKSubIE(pAd, pOutBuffer + FrameLen, + &FrameLen, + FtInfoBuf.FtIeInfo.GtkSubIE, + FtInfoBuf.FtIeInfo.GtkLen); + + /* Insert R0KH IE into FTIE. */ + if (FtInfoBuf.FtIeInfo.R0khIdLen != 0) + FT_FTIE_InsertKhIdSubIE(pAd, pOutBuffer + FrameLen, + &FrameLen, + FT_R0KH_ID, + FtInfoBuf.FtIeInfo.R0khId, + FtInfoBuf.FtIeInfo.R0khIdLen); + + /* Insert IGTK Key info into FTIE. */ + + if (FtInfoBuf.FtIeInfo.IGtkLen != 0) { + FT_FTIE_InsertIGTKSubIE(pAd, pOutBuffer+FrameLen, + &FrameLen, + FtInfoBuf.FtIeInfo.IGtkSubIE, + FtInfoBuf.FtIeInfo.IGtkLen); + } + + /* Insert RIC. */ + if (ie_list->FtInfo.RicInfo.Len) { + ULONG TempLen; + + FT_RIC_ResourceRequestHandle(pAd, pEntry, + (PUCHAR)ie_list->FtInfo.RicInfo.pRicInfo, + ie_list->FtInfo.RicInfo.Len, + (PUCHAR)pOutBuffer + FrameLen, + (PUINT32)&TempLen); + ricie_ptr = (PUCHAR)(pOutBuffer + FrameLen); + ricie_len = TempLen; + FrameLen += TempLen; + } + + /* Calculate the FT MIC for FT procedure */ + if (FtInfoBuf.FtIeInfo.MICCtr.field.IECnt) { + UINT8 ft_mic[FT_MIC_LEN]; + PFT_FTIE pFtIe; + + FT_CalculateMIC(pEntry->Addr, + wdev->bssid, + pEntry->FT_PTK, + 6, + FtInfoBuf.RSN_IE, + FtInfoBuf.RSNIE_Len, + mdie_ptr, + mdie_len, + ftie_ptr, + ftie_len, + ricie_ptr, + ricie_len, + ft_mic); + /* Update the MIC field of FTIE */ + pFtIe = (PFT_FTIE)(ftie_ptr + 2); + NdisMoveMemory(pFtIe->MIC, ft_mic, FT_MIC_LEN); + /* Install pairwise key */ +#ifdef MBO_SUPPORT + /* YF_FT */ + if (IS_MBO_ENABLE(wdev)) + /* update STA bssid & security info to daemon */ + MboIndicateStaBssidInfo(pAd, wdev, pEntry->Addr); +#endif /* MBO_SUPPORT */ + pSecConfig->Handshake.GTKState = REKEY_ESTABLISHED; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + tr_entry->PortSecured = WPA_802_1X_PORT_SECURED; + WifiSysUpdatePortSecur(pAd, pEntry, NULL); + } + + /* Record the MDIE & FTIE of (re)association response of + Initial Mobility Domain Association. It's used in + FT 4-Way handshaking */ + if ((IS_AKM_WPA2_Entry(pEntry) || IS_AKM_WPA2PSK_Entry(pEntry)) + && ie_list->FtInfo.FtIeInfo.Len == 0) { + NdisMoveMemory(&pEntry->InitialMDIE, + mdie_ptr, mdie_len); + pEntry->InitialFTIE_Len = ftie_len; + NdisMoveMemory(pEntry->InitialFTIE, ftie_ptr, ftie_len); + } + } + +#endif /* DOT11R_FT_SUPPORT */ + +#ifdef CONFIG_OWE_SUPPORT + if (IS_AKM_OWE_Entry(pEntry) && (StatusCode == MLME_SUCCESS)) { + BOOLEAN need_ecdh_ie = FALSE; + INT CacheIdx;/* Key cache */ + + pPmkid = WPA_ExtractSuiteFromRSNIE(ie_list->RSN_IE, ie_list->RSNIE_Len, PMKID_LIST, &pmkid_count); + if (pPmkid != NULL) { + CacheIdx = RTMPSearchPMKIDCache(&pAd->ApCfg.PMKIDCache, pEntry->func_tb_idx, pEntry->Addr); + if ((CacheIdx == -1) || + ((RTMPEqualMemory(pPmkid, + &pAd->ApCfg.PMKIDCache.BSSIDInfo[CacheIdx].PMKID, + LEN_PMKID)) == 0)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: AKM_OWE_Entry PMKID not found, do normal ECDH procedure\n", + __func__)); + need_ecdh_ie = TRUE; + } + } else + need_ecdh_ie = TRUE; + + if (need_ecdh_ie == TRUE) { + FrameLen += build_owe_dh_ie(pAd, + pEntry, + (UCHAR *)pOutBuffer + FrameLen, + pEntry->SecConfig.owe.last_try_group); + } + } +#endif /*CONFIG_OWE_SUPPORT*/ + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory((PVOID) pOutBuffer); +#ifdef DOT11W_PMF_SUPPORT + + if (StatusCode == MLME_ASSOC_REJ_TEMPORARILY) + PMF_MlmeSAQueryReq(pAd, pEntry); + +#endif /* DOT11W_PMF_SUPPORT */ + + /* set up BA session */ + if (StatusCode == MLME_SUCCESS) { + pEntry->PsMode = PWR_ACTIVE; + /* TODO: shiang-usw, we need to rmove upper setting and migrate to tr_entry->PsMode */ + pAd->MacTab.tr_entry[pEntry->wcid].PsMode = PWR_ACTIVE; + MSDU_FORBID_CLEAR(wdev, MSDU_FORBID_CONNECTION_NOT_READY); +#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->wdev->wdev_idx); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("####### Send L2 Frame Mac=%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pEntry->Addr))); + } + + /* SendSingalToDaemon(SIGUSR2, pObj->IappPid); */ +#ifdef DOT11R_FT_SUPPORT + { + /* + Do not do any check here. + We need to send MOVE-Req frame to AP1 even open mode. + */ + /* if (IS_FT_RSN_STA(pEntry) && (FtInfo.FtIeInfo.Len != 0)) */ + if (isReassoc == 1) { + /* only for reassociation frame */ + FT_KDP_EVT_REASSOC EvtReAssoc; + + EvtReAssoc.SeqNum = 0; + NdisMoveMemory(EvtReAssoc.MacAddr, pEntry->Addr, MAC_ADDR_LEN); + NdisMoveMemory(EvtReAssoc.OldApMacAddr, ie_list->ApAddr, MAC_ADDR_LEN); + FT_KDP_EVENT_INFORM(pAd, pEntry->func_tb_idx, FT_KDP_SIG_FT_REASSOCIATION, + &EvtReAssoc, sizeof(EvtReAssoc), NULL); + } + } + +#endif /* DOT11R_FT_SUPPORT */ +#endif /* IAPP_SUPPORT */ + /* ap_assoc_info_debugshow(pAd, isReassoc, pEntry, ie_list); */ + /* send wireless event - for association */ +#ifdef VENDOR_FEATURE7_SUPPORT + /* Passed in the pEntry->apindx argument */ + RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pEntry->Addr, pEntry->func_tb_idx, 0); +#else + RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pEntry->Addr, 0, 0); +#endif + /* This is a reassociation procedure */ + pEntry->IsReassocSta = isReassoc; + /* clear txBA bitmap */ + pEntry->TXBAbitmap = 0; + + if (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) { + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); + + if ((wdev->channel <= 14) && + addht->AddHtInfo.ExtChanOffset && + (ie_list->HTCapability.HtCapInfo.ChannelWidth == BW_40)) + SendBeaconRequest(pAd, pEntry->wcid); + + ba_ori_session_setup(pAd, pEntry, 5, 0, 10, FALSE); + } + +#ifdef DOT11R_FT_SUPPORT + + /* If the length of FTIE field of the (re)association-request frame + is larger than zero, it shall indicate the Fast-BSS transition is in progress. */ + if (ie_list->FtInfo.FtIeInfo.Len > 0) + ; + else +#endif /* DOT11R_FT_SUPPORT */ +#ifdef RT_CFG80211_SUPPORT + if (TRUE) { /*CFG_TODO*/ + /* need to update pEntry to inform later flow to keep ConnectionState in connected */ + pEntry->bWscCapable = ie_list->bWscCapable; + { + MTWF_LOG(DBG_CAT_AP, + DBG_SUBCAT_ALL, + DBG_LVL_TRACE, + ("SINGLE CFG: NOITFY ASSOCIATED, pEntry->bWscCapable:%d\n", + pEntry->bWscCapable)); + CFG80211OS_NewSta(pEntry->wdev->if_dev, + ie_list->Addr2, + (PUCHAR)Elem->Msg, + Elem->MsgLen); + + if (IS_CIPHER_WEP(pEntry->SecConfig.PairwiseCipher)) { + ASIC_SEC_INFO Info = {0}; + /* Set key material to Asic */ + os_zero_mem(&Info, sizeof(ASIC_SEC_INFO)); + Info.Operation = SEC_ASIC_ADD_PAIRWISE_KEY; + Info.Direction = SEC_ASIC_KEY_BOTH; + Info.Wcid = pEntry->wcid; + Info.BssIndex = pEntry->func_tb_idx; + Info.KeyIdx = pEntry->SecConfig.PairwiseKeyId; + Info.Cipher = pEntry->SecConfig.PairwiseCipher; + Info.KeyIdx = pEntry->SecConfig.PairwiseKeyId; + os_move_mem(&Info.Key, + &pEntry->SecConfig.WepKey[pEntry->SecConfig.PairwiseKeyId], + sizeof(SEC_KEY_INFO)); + os_move_mem(&Info.PeerAddr[0], pEntry->Addr, MAC_ADDR_LEN); + HW_ADDREMOVE_KEYTABLE(pAd, &Info); + } + } + + hex_dump("ASSOC_REQ", Elem->Msg, Elem->MsgLen); + } else +#endif + /* enqueue a EAPOL_START message to trigger EAP state machine doing the authentication */ + if (IS_AKM_PSK_Entry(pEntry)) { + pPmkid = WPA_ExtractSuiteFromRSNIE(ie_list->RSN_IE, + ie_list->RSNIE_Len, + PMKID_LIST, + &pmkid_count); + + if (pPmkid != NULL) { + INT CacheIdx; + + CacheIdx = RTMPValidatePMKIDCache(&pAd->ApCfg.PMKIDCache, + pEntry->func_tb_idx, + pEntry->Addr, + pPmkid); + + store_pmkid_cache_in_sec_config(pAd, pEntry, CacheIdx); + + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ASSOC - CacheIdx = %d\n", + CacheIdx)); + + if (IS_AKM_WPA3PSK(pEntry->SecConfig.AKMMap) && + !is_pmkid_cache_in_sec_config(&pEntry->SecConfig)) { + MTWF_LOG(DBG_CAT_SEC, + CATSEC_SAE, + DBG_LVL_ERROR, + ("ASSOC - SAE - verify pmkid fail\n")); + MlmeDeAuthAction(pAd, pEntry, REASON_NO_LONGER_VALID, FALSE); + goto LabelOK; + } + } +#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)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ASSOC - IF(ra%d) This is a WPS Client.\n\n", + pEntry->func_tb_idx)); + 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(wsc_ctrl->EntryAddr, 6); + } + +#endif /* WSC_AP_SUPPORT */ + /* Enqueue a EAPOL-start message with the pEntry for WPAPSK State Machine */ + if (1 +#ifdef HOSTAPD_SUPPORT + && wdev->Hostapd == Hostapd_Disable +#endif/*HOSTAPD_SUPPORT*/ +#ifdef WSC_AP_SUPPORT + && !pEntry->bWscCapable +#endif /* WSC_AP_SUPPORT */ + ) { + /* Enqueue a EAPOL-start message with the pEntry */ + os_move_mem(&pEntry->SecConfig.Handshake.AAddr, wdev->bssid, MAC_ADDR_LEN); + os_move_mem(&pEntry->SecConfig.Handshake.SAddr, pEntry->Addr, MAC_ADDR_LEN); + + if (!IS_AKM_WPA3PSK(pEntry->SecConfig.AKMMap) && + !(IS_AKM_OWE(pEntry->SecConfig.AKMMap))) + os_move_mem(&pEntry->SecConfig.PMK, &wdev->SecConfig.PMK, LEN_PMK); + + RTMPSetTimer(&pEntry->SecConfig.StartFor4WayTimer, ENQUEUE_EAPOL_START_TIMER); + } + } + +#ifdef DOT1X_SUPPORT + else if (IS_AKM_WPA2_Entry(pEntry) || + IS_AKM_WPA3_Entry(pEntry)) { + pPmkid = WPA_ExtractSuiteFromRSNIE(ie_list->RSN_IE, + ie_list->RSNIE_Len, + PMKID_LIST, + &pmkid_count); + + if (pPmkid != NULL) { + /* Key cache */ + INT CacheIdx; + + CacheIdx = RTMPValidatePMKIDCache(&pAd->ApCfg.PMKIDCache, + pEntry->func_tb_idx, + pEntry->Addr, + pPmkid); + + process_pmkid(pAd, wdev, pEntry, CacheIdx); + } + } else if (IS_AKM_1X_Entry(pEntry) || + (IS_IEEE8021X(&pEntry->SecConfig) +#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 == Hostapd_Disable +#endif/*HOSTAPD_SUPPORT*/ + ) { + pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_1X; + RTMPSetTimer(&pEntry->SecConfig.StartFor4WayTimer, ENQUEUE_EAPOL_START_TIMER); + } + } + +#endif /* DOT1X_SUPPORT */ + +#if defined(MWDS) || defined(CONFIG_MAP_SUPPORT) || defined(WAPP_SUPPORT) + if (tr_entry && (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) { +#ifdef WAPP_SUPPORT + wapp_send_cli_join_event(pAd, pEntry); +#endif + } +#endif +#ifdef SMART_ANTENNA + { + unsigned long irqflags; + /* Check if need to reset the sa training procedures to init stage! */ + RTMP_IRQ_LOCK(&pAd->smartAntLock, irqflags); + + if (RTMP_SA_WORK_ON(pAd)) { + /* sa_add_train_entry(pAd, &pEntry->Addr[0], FALSE); */ + pAd->pSAParam->bStaChange = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s():sta(%02x:%02x:%02x:%02x:%02x:%02x) add!\n", + __func__, PRINT_MAC(pEntry->Addr))); + } + + RTMP_IRQ_UNLOCK(&pAd->smartAntLock, irqflags); + } +#endif /* SMART_ANTENNA // */ +#ifdef GREENAP_SUPPORT + + if (greenap_get_capability(greenap) && greenap_get_allow_status(greenap)) { + if (StatusCode == MLME_SUCCESS && (pEntry->Sst == SST_ASSOC)) + greenap_check_peer_connection_at_link_up_down(pAd, wdev, greenap); + } + +#endif /* GREENAP_SUPPORT */ +#ifdef CONFIG_HOTSPOT_R2 + + /* add to cr4 pool */ + if (pEntry->QosMapSupport) { + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[pEntry->apidx].HotSpotCtrl; + + if (pHSCtrl->QosMapEnable) { + if (!pHSCtrl->QosMapAddToPool) { + pHSCtrl->QosMapAddToPool = TRUE; + pHSCtrl->QosMapPoolID = hotspot_qosmap_add_pool(pAd, pEntry); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("add current MBSS qosmap to CR4\n")); + } + + hotspot_qosmap_update_sta_mapping_to_cr4(pAd, pEntry, pHSCtrl->QosMapPoolID); + } + } + +#endif /* CONFIG_HOTSPOT_R2 */ + } + +#ifdef FAST_EAPOL_WAR +/* +* Moved from WifiSysApPeerLinkUp() in open security mode. +* to make sure the STATE_PORT_SECURE flag can be polled by MU N9 module. +* then MU Action Frame sent out after Asso Resp. +*/ + if (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED) { + if (!(IS_AKM_WPA_CAPABILITY_Entry(pEntry) +#ifdef DOT1X_SUPPORT + || IS_IEEE8021X(&pEntry->SecConfig) +#endif /* DOT1X_SUPPORT */ +#ifdef RT_CFG80211_SUPPORT + || wdev->IsCFG1xWdev +#endif /* RT_CFG80211_SUPPORT */ + || pEntry->bWscCapable)) { + WifiSysUpdatePortSecur(pAd, pEntry, NULL); + } + } +#endif /* FAST_EAPOL_WAR */ +#ifdef BAND_STEERING + if ((pAd->ApCfg.BandSteering) + ) { + BndStrg_UpdateEntry(pAd, pEntry, ie_list, TRUE); + } +#endif + +#ifdef VENDOR_FEATURE7_SUPPORT + if (arris_event_send_hook && pEntry && (StatusCode == MLME_SUCCESS)) { + UCHAR assoc_event_msg[32] = {0}; + UINT32 count = 0; + UCHAR *assoc_sta_info = NULL; + HT_CAP_INFO *pHTCap = &(ie_list->HTCapability).HtCapInfo; + HT_CAP_PARM *pHTCapParm = &(ie_list->HTCapability).HtCapParm; + /* Send a WLAN_EVENT to ATOM which in turns sends an RPC + * to update our client table on the ARM. + */ + NdisZeroMemory(assoc_event_msg, sizeof(assoc_event_msg)); + if (WMODE_CAP_5G(PhyMode)) + count = snprintf(assoc_event_msg, sizeof(assoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pEntry->Addr), (pEntry->func_tb_idx) + WIFI_50_RADIO); + else + count = snprintf(assoc_event_msg, sizeof(assoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pEntry->Addr), (pEntry->func_tb_idx) + WIFI_24_RADIO); + + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_EVENT, STA_ASSOC, + assoc_event_msg, count); + + /* Log this cleint's capabilities in our nvram */ + /* assoc_sta_info = kmalloc(1300, GFP_ATOMIC); */ + os_alloc_mem(NULL, (UCHAR **)&assoc_sta_info, 1300); + if (assoc_sta_info) { + NdisZeroMemory(assoc_sta_info, 1300); + count = 0; + count += snprintf((assoc_sta_info+count), (1300-count), + "Association: (%02x:%02x:%02x:%02x:%02x:%02x) --> %s%d (%s)\n", + PRINT_MAC(pEntry->Addr), INF_MAIN_DEV_NAME, pEntry->func_tb_idx, + pEntry->pMbss->Ssid); + if (pHTCap && pHTCapParm && ie_list->ht_cap_len && WMODE_CAP_N(wdev->PhyMode)) { + count += snprintf((assoc_sta_info+count), (1300-count), " Station Info:\n"); + count += snprintf((assoc_sta_info+count), (1300-count), + "\tRSSI0(%d), RSSI1(%d), Mode(%s), BW(%s), MCS(%d), SGI(%d)\n", + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1), + get_phymode_str(pEntry->HTPhyMode.field.MODE), + get_bw_str(pEntry->HTPhyMode.field.BW), + pEntry->HTPhyMode.field.MCS, + pEntry->HTPhyMode.field.ShortGI); + } else { + count += snprintf((assoc_sta_info+count), (1300-count), + " Station Info (Legacy):\n"); + count += snprintf((assoc_sta_info+count), (1300-count), + "\tRSSI0(%d), RSSI1(%d), Mode(%s), MCS(%d)\n", + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1), + get_phymode_str(pEntry->HTPhyMode.field.MODE), + pEntry->HTPhyMode.field.MCS); + } + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, + WLAN_LOG_SAVE, 0, assoc_sta_info, count); + os_free_mem(assoc_sta_info); + } + } +#endif + +LabelOK: +#ifdef RT_CFG80211_SUPPORT + + if (StatusCode != MLME_SUCCESS) + CFG80211_ApStaDelSendEvent(pAd, pEntry->Addr, pEntry->wdev->if_dev); + +#endif /* RT_CFG80211_SUPPORT */ + + if (ie_list != NULL) + os_free_mem(ie_list); +} + + + +/* + ========================================================================== + 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(RTMP_ADAPTER *pAd, 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(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) +{ + ap_cmm_peer_assoc_req_action(pAd, Elem, 1); +} + + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== + */ +static BOOLEAN PeerDisassocReqSanity( + IN PRTMP_ADAPTER pAd, + IN VOID *Msg, + IN ULONG MsgLen, + OUT PUCHAR pDA, + OUT PUCHAR pAddr2, + OUT UINT16 * SeqNum, + OUT USHORT *Reason) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)Msg; + + COPY_MAC_ADDR(pDA, &Fr->Hdr.Addr1); + COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2); + *SeqNum = Fr->Hdr.Sequence; + NdisMoveMemory(Reason, &Fr->Octet[0], 2); + return TRUE; +} + + +/* + ========================================================================== + Description: + left part of IEEE 802.11/1999 p.374 + Parameters: + Elem - MLME message containing the received frame + ========================================================================== + */ +VOID APPeerDisassocReqAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) +{ + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + USHORT Reason; + UINT16 SeqNum; + MAC_TABLE_ENTRY *pEntry; + struct wifi_dev *wdev; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ASSOC - 1 receive DIS-ASSOC request\n")); + + if (!PeerDisassocReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, &SeqNum, &Reason)) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ASSOC - receive DIS-ASSOC(seq-%d) request from %02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n", + SeqNum, PRINT_MAC(Addr2), Reason)); + pEntry = MacTableLookup(pAd, Addr2); + + if (pEntry == NULL) + return; + + if (VALID_UCAST_ENTRY_WCID(pAd, Elem->Wcid)) { + wdev = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev; + + /* + iPhone sometimes sends disassoc frame which DA is old AP and BSSID is new AP. + @2016/1/26 + */ + if (!MAC_ADDR_EQUAL(wdev->if_addr, Addr1)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ASSOC - The DA of this DIS-ASSOC request is %02x:%02x:%02x:%02x:%02x:%02x, ignore.\n", + PRINT_MAC(Addr1))); + return; + } + +#if defined(DOT1X_SUPPORT) && !defined(RADIUS_ACCOUNTING_SUPPORT) + + /* Notify 802.1x daemon to clear this sta info */ + if (IS_AKM_1X_Entry(pEntry) || IS_IEEE8021X_Entry(wdev)) + DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); + +#endif /* DOT1X_SUPPORT */ + /* send wireless event - for disassociation */ + RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, Addr2, 0, 0); +#ifdef VENDOR_FEATURE7_SUPPORT + { + UCHAR disassoc_event_msg[32] = {0}; + + if (WMODE_CAP_5G(pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.PhyMode)) + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(Addr2), (pEntry->func_tb_idx) + WIFI_50_RADIO); + else + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(Addr2), (pEntry->func_tb_idx) + WIFI_24_RADIO); + + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_EVENT, STA_DISSOC, + disassoc_event_msg, strlen(disassoc_event_msg)); + } +#endif + ApLogEvent(pAd, Addr2, EVENT_DISASSOCIATED); + + MacTableDeleteEntry(pAd, Elem->Wcid, Addr2); +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn == TRUE) { + UCHAR apCliIdx, CliIdx; + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + + pReptEntry = RTMPLookupRepeaterCliEntry(pAd, TRUE, Addr2, TRUE); + + if (pReptEntry && (pReptEntry->CliConnectState != 0)) { + apCliIdx = pReptEntry->MatchApCliIdx; + CliIdx = pReptEntry->MatchLinkIdx; + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_AP_PEER_DISASSOC_REQ; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + } +} + + +/* + ========================================================================== + Description: + delete it from STA and disassoc s STA + Parameters: + Elem - + ========================================================================== + */ +VOID MbssKickOutStas(RTMP_ADAPTER *pAd, INT apidx, USHORT Reason) +{ + INT i; + PMAC_TABLE_ENTRY pEntry; + +#ifdef MBO_SUPPORT + MboIndicateStaDisassocToDaemon(pAd, NULL, MBO_MSG_AP_TERMINATION); +#endif /* MBO_SUPPORT */ + + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + + if (pEntry && IS_ENTRY_CLIENT(pEntry) && pEntry->func_tb_idx == apidx) + APMlmeKickOutSta(pAd, pEntry->Addr, pEntry->wcid, Reason); + } + /* mbo wait for max 500ms and check all IsKeep is zero */ +#ifdef MBO_SUPPORT + MboWaitAllStaGone(pAd, apidx); +#endif /* MBO_SUPPORT */ +} + + +/* + ========================================================================== + Description: + delete it from STA and disassoc s STA + Parameters: + Elem - + ========================================================================== + */ +VOID APMlmeKickOutSta(RTMP_ADAPTER *pAd, UCHAR *pStaAddr, UCHAR Wcid, 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->func_tb_idx; + + if (ApIdx >= pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Invalid Apidx=%d\n", + __func__, ApIdx)); + return; + } + + if (VALID_UCAST_ENTRY_WCID(pAd, Wcid)) { + /* send wireless event - for disassocation */ + RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pStaAddr, 0, 0); +#ifdef VENDOR_FEATURE7_SUPPORT + { + UCHAR disassoc_event_msg[32] = {0}; + + if (WMODE_CAP_5G(pAd->ApCfg.MBSSID[ApIdx].wdev.PhyMode)) + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pStaAddr), (ApIdx) + WIFI_50_RADIO); + else + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pStaAddr), (ApIdx) + WIFI_24_RADIO); + + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_EVENT, STA_DISSOC, + disassoc_event_msg, strlen(disassoc_event_msg)); + } +#endif + ApLogEvent(pAd, pStaAddr, EVENT_DISASSOCIATED); + /* 2. send out a DISASSOC request frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ASSOC - MLME disassociates %02x:%02x:%02x:%02x:%02x:%02x; Send DISASSOC request\n", + PRINT_MAC(pStaAddr))); + MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pStaAddr, + pAd->ApCfg.MBSSID[ApIdx].wdev.if_addr, + pAd->ApCfg.MBSSID[ApIdx].wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DisassocHdr, + 2, &Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + MacTableDeleteEntry(pAd, Wcid, pStaAddr); + } +} + + +#ifdef DOT11W_PMF_SUPPORT +VOID APMlmeKickOutAllSta(RTMP_ADAPTER *pAd, UCHAR apidx, USHORT Reason) +{ + HEADER_802_11 DisassocHdr; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + NDIS_STATUS NStatus; + UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + PPMF_CFG pPmfCfg = NULL; + + pPmfCfg = &pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.PmfCfg; + + if ((apidx < pAd->ApCfg.BssidNum) && (pPmfCfg)) { + /* Send out a Deauthentication request frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Send DISASSOC Broadcast frame(%d) with ra%d\n", Reason, apidx)); + /* 802.11 Header */ + NdisZeroMemory(&DisassocHdr, sizeof(HEADER_802_11)); + DisassocHdr.FC.Type = FC_TYPE_MGMT; + DisassocHdr.FC.SubType = SUBTYPE_DISASSOC; + DisassocHdr.FC.ToDs = 0; + DisassocHdr.FC.Wep = 0; + COPY_MAC_ADDR(DisassocHdr.Addr1, BROADCAST_ADDR); + COPY_MAC_ADDR(DisassocHdr.Addr2, pAd->ApCfg.MBSSID[apidx].wdev.bssid); + COPY_MAC_ADDR(DisassocHdr.Addr3, pAd->ApCfg.MBSSID[apidx].wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DisassocHdr, + 2, &Reason, + END_OF_ARGS); + + if (pPmfCfg->MFPC == TRUE) { + ULONG TmpLen; + UCHAR res_buf[LEN_PMF_MMIE]; + UCHAR EID, ELen; + + EID = IE_PMF_MMIE; + ELen = LEN_PMF_MMIE; + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &EID, + 1, &ELen, + LEN_PMF_MMIE, res_buf, + END_OF_ARGS); + FrameLen += TmpLen; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("[PMF]: This is a Broadcast Robust management frame, Add 0x4C(76) EID\n")); + } + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + } +} +#endif /* DOT11W_PMF_PLUGFEST */ + + +/* + ========================================================================== + Description: + Upper layer orders to disassoc s STA + Parameters: + Elem - + ========================================================================== + */ +VOID APMlmeDisassocReqAction(RTMP_ADAPTER *pAd, 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(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk) +{ + HEADER_802_11 DisassocHdr; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + NDIS_STATUS NStatus; + USHORT Reason = REASON_CLS3ERR; + MAC_TABLE_ENTRY *pEntry = NULL; + + if (VALID_UCAST_ENTRY_WCID(pAd, pRxBlk->wcid)) + pEntry = &(pAd->MacTab.Content[pRxBlk->wcid]); + + if (pEntry) { + /*ApLogEvent(pAd, pAddr, EVENT_DISASSOCIATED); */ + mac_entry_delete(pAd, pEntry); + } + + /* 2. send out a DISASSOC request frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ASSOC - Class 3 Error, Send DISASSOC frame to %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pRxBlk->Addr2))); + MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pRxBlk->Addr2, + pRxBlk->Addr1, + pRxBlk->Addr1); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DisassocHdr, + 2, &Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(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 RTMP_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/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_auth.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_auth.c new file mode 100644 index 000000000..93a26e7ab --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_auth.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: + 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" +#ifdef DOT11R_FT_SUPPORT +#include "ft.h" +#endif /* DOT11R_FT_SUPPORT */ +#ifdef VENDOR_FEATURE7_SUPPORT +#include "arris_wps_gpio_handler.h" +#endif + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== + */ +static 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: + Upper Layer request to kick out a STA + ========================================================================== + */ + +VOID APMlmeBroadcastDeauthReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM * Elem) +{ + MLME_BROADCAST_DEAUTH_REQ_STRUCT *pInfo; + HEADER_802_11 Hdr; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + MAC_TABLE_ENTRY *pEntry; + UCHAR apidx = 0; + struct wifi_dev *wdev; + int wcid, startWcid; + + startWcid = 1; + pInfo = (PMLME_BROADCAST_DEAUTH_REQ_STRUCT)Elem->Msg; + if (!MAC_ADDR_EQUAL(pInfo->Addr, BROADCAST_ADDR)) + return; + wdev = pInfo->wdev; + apidx = wdev->func_idx; + for (wcid = startWcid; VALID_UCAST_ENTRY_WCID(pAd, wcid); wcid++) { + pEntry = &pAd->MacTab.Content[wcid]; + if (pEntry->wdev != wdev) + continue; + RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, + pEntry->Addr, 0, 0); + ApLogEvent(pAd, pInfo->Addr, EVENT_DISASSOCIATED); + MacTableDeleteEntry(pAd, wcid, pEntry->Addr); + } + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) + return; + MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, + pAd->ApCfg.MBSSID[apidx].wdev.if_addr, + pAd->ApCfg.MBSSID[apidx].wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &Hdr, + 2, &pInfo->Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); +} + +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; + struct wifi_dev *wdev; + + pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg; + + if (VALID_UCAST_ENTRY_WCID(pAd, Elem->Wcid)) { + pEntry = &pAd->MacTab.Content[Elem->Wcid]; + + if (!pEntry) + return; + + /* send wireless event - for deauthentication */ + RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pInfo->Addr, 0, 0); + ApLogEvent(pAd, pInfo->Addr, EVENT_DISASSOCIATED); + apidx = pEntry->func_tb_idx; +#ifdef VENDOR_FEATURE7_SUPPORT + { + UCHAR disassoc_event_msg[32] = {0}; + + if (WMODE_CAP_5G(pAd->ApCfg.MBSSID[apidx].wdev.PhyMode)) + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pInfo->Addr), (pEntry->func_tb_idx) + WIFI_50_RADIO); + else + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(pInfo->Addr), (pEntry->func_tb_idx) + WIFI_24_RADIO); + + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_EVENT, STA_DISSOC, + disassoc_event_msg, strlen(disassoc_event_msg)); + } +#endif + /* 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; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("AUTH - Send DE-AUTH req to %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pInfo->Addr))); + MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, + pAd->ApCfg.MBSSID[apidx].wdev.if_addr, + pAd->ApCfg.MBSSID[apidx].wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &Hdr, + 2, &pInfo->Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + + } else { + MLME_BROADCAST_DEAUTH_REQ_STRUCT *pInfo; + + pInfo = (PMLME_BROADCAST_DEAUTH_REQ_STRUCT)Elem->Msg; + wdev = pInfo->wdev; + APMlmeBroadcastDeauthReqAction(pAd, Elem); + } +} + + +void ApSendBroadcastDeauth(void *ad_obj, struct wifi_dev *wdev) +{ + MLME_BROADCAST_DEAUTH_REQ_STRUCT *pInfo = NULL; + MLME_QUEUE_ELEM *Elem; + RTMP_ADAPTER *pAd = ad_obj; + + MlmeAllocateMemory(pAd, (UCHAR **)&Elem); + if (Elem == NULL) + return; + if (Elem) { + pInfo = (MLME_BROADCAST_DEAUTH_REQ_STRUCT *)Elem->Msg; + pInfo->wdev = wdev; + Elem->Wcid = WCID_ALL; + pInfo->Reason = MLME_UNSPECIFY_FAIL; + NdisCopyMemory(pInfo->Addr, BROADCAST_ADDR, MAC_ADDR_LEN); + APMlmeDeauthReqAction(pAd, Elem); + MlmeFreeMemory(Elem); + } +} + + +static VOID APPeerDeauthReqAction( + IN PRTMP_ADAPTER pAd, + IN PMLME_QUEUE_ELEM Elem) +{ + UCHAR Addr2[MAC_ADDR_LEN]; + UINT16 Reason, SeqNum; + MAC_TABLE_ENTRY *pEntry; + + + + if (!PeerDeauthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &SeqNum, &Reason)) + return; + + pEntry = NULL; + + /*pEntry = MacTableLookup(pAd, Addr2); */ + if (VALID_UCAST_ENTRY_WCID(pAd, Elem->Wcid)) { + pEntry = &pAd->MacTab.Content[Elem->Wcid]; + { + /* + Add Hotspot2.0 Rlease 1 Prestested Code + */ + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx]; + PFRAME_802_11 Fr = (PFRAME_802_11)Elem->Msg; + unsigned char *tmp = (unsigned char *)pMbss->wdev.bssid; + unsigned char *tmp2 = (unsigned char *)&Fr->Hdr.Addr1; + + if (memcmp(&Fr->Hdr.Addr1, pMbss->wdev.bssid, 6) != 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("da not match bssid,bssid:0x%02x%02x%02x%02x%02x%02x, addr1:0x%02x%02x%02x%02x%02x%02x\n", + *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3), *(tmp + 4), *(tmp + 5), *tmp2, *(tmp2 + 1), *(tmp2 + 2), *(tmp2 + 3), *(tmp2 + 4), *(tmp2 + 5))); + return; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("da match,0x%02x%02x%02x%02x%02x%02x\n", + *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3), *(tmp + 4), *(tmp + 5))); + } +#if defined(DOT1X_SUPPORT) && !defined(RADIUS_ACCOUNTING_SUPPORT) + + /* Notify 802.1x daemon to clear this sta info */ + if (IS_AKM_1X_Entry(pEntry) + || IS_IEEE8021X_Entry(&pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev)) + DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); + +#endif /* DOT1X_SUPPORT */ + /* send wireless event - for deauthentication */ + RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, Addr2, 0, 0); +#ifdef VENDOR_FEATURE7_SUPPORT + { + UCHAR disassoc_event_msg[32] = {0}; + + if (WMODE_CAP_5G(pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.PhyMode)) + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(Addr2), (pEntry->func_tb_idx) + WIFI_50_RADIO); + else + snprintf(disassoc_event_msg, sizeof(disassoc_event_msg), + "%02x:%02x:%02x:%02x:%02x:%02x BSS(%d)", + PRINT_MAC(Addr2), (pEntry->func_tb_idx) + WIFI_24_RADIO); + + ARRISMOD_CALL(arris_event_send_hook, ATOM_HOST, WLAN_EVENT, STA_DISSOC, + disassoc_event_msg, strlen(disassoc_event_msg)); + } +#endif + 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; + } + + + if (pEntry && !IS_ENTRY_CLIENT(pEntry)) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: receive not client de-auth ###\n", __func__)); + else + MacTableDeleteEntry(pAd, Elem->Wcid, Addr2); + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("AUTH - receive DE-AUTH(seq-%d) from %02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n", + SeqNum, PRINT_MAC(Addr2), Reason)); +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn == TRUE) { + UCHAR apCliIdx, CliIdx; + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + + pReptEntry = RTMPLookupRepeaterCliEntry(pAd, TRUE, Addr2, TRUE); + + if (pReptEntry && (pReptEntry->CliConnectState != REPT_ENTRY_DISCONNT)) { + apCliIdx = pReptEntry->MatchApCliIdx; + CliIdx = pReptEntry->MatchLinkIdx; + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_AP_PEER_DEAUTH_REQ; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + } + } + +#endif /* MAC_REPEATER_SUPPORT */ + + } +} + + +/* + ========================================================================== + Description: + MLME message sanity check + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== + */ +static BOOLEAN APPeerAuthSanity( + IN RTMP_ADAPTER *pAd, + IN VOID *Msg, + IN ULONG MsgLen, + IN AUTH_FRAME_INFO * auth_info) +{ + PFRAME_802_11 Fr = (PFRAME_802_11)Msg; + + COPY_MAC_ADDR(auth_info->addr1, &Fr->Hdr.Addr1); /* BSSID */ + COPY_MAC_ADDR(auth_info->addr2, &Fr->Hdr.Addr2); /* SA */ + /* TODO: shiang-usw, how about the endian issue here?? */ + NdisMoveMemory(&auth_info->auth_alg, &Fr->Octet[0], 2); + NdisMoveMemory(&auth_info->auth_seq, &Fr->Octet[2], 2); + NdisMoveMemory(&auth_info->auth_status, &Fr->Octet[4], 2); + + + if (auth_info->auth_alg == AUTH_MODE_OPEN) { + if (auth_info->auth_seq == 1 || auth_info->auth_seq == 2) + return TRUE; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): fail - wrong Seg# (=%d)\n", + __func__, auth_info->auth_seq)); + return FALSE; + } else if (auth_info->auth_alg == AUTH_MODE_KEY) { + if (auth_info->auth_seq == 1 || auth_info->auth_seq == 4) + return TRUE; + else if (auth_info->auth_seq == 2 || auth_info->auth_seq == 3) { + NdisMoveMemory(auth_info->Chtxt, &Fr->Octet[8], CIPHER_TEXT_LEN); + return TRUE; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): fail - wrong Seg# (=%d)\n", + __func__, auth_info->auth_seq)); + return FALSE; + } + +#ifdef DOT11R_FT_SUPPORT + else if (auth_info->auth_alg == AUTH_MODE_FT) { + PEID_STRUCT eid_ptr; + UCHAR *Ptr; + UCHAR WPA2_OUI[3] = {0x00, 0x0F, 0xAC}; + PFT_INFO pFtInfo = &auth_info->FtInfo; + + NdisZeroMemory(pFtInfo, sizeof(FT_INFO)); + Ptr = &Fr->Octet[6]; + eid_ptr = (PEID_STRUCT) Ptr; + + /* 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_FT_MDIE: + FT_FillMdIeInfo(eid_ptr, &pFtInfo->MdIeInfo); + break; + + case IE_FT_FTIE: + FT_FillFtIeInfo(eid_ptr, &pFtInfo->FtIeInfo); + break; + + case IE_FT_RIC_DATA: + + /* record the pointer of first RDIE. */ + if (pFtInfo->RicInfo.pRicInfo == NULL) { + pFtInfo->RicInfo.pRicInfo = &eid_ptr->Eid; + pFtInfo->RicInfo.Len = ((UCHAR *)Fr + MsgLen) + - (UCHAR *)eid_ptr + 1; + } + + if ((pFtInfo->RicInfo.RicIEsLen + eid_ptr->Len + 2) < MAX_RICIES_LEN) { + NdisMoveMemory(&pFtInfo->RicInfo.RicIEs[pFtInfo->RicInfo.RicIEsLen], + &eid_ptr->Eid, eid_ptr->Len + 2); + pFtInfo->RicInfo.RicIEsLen += eid_ptr->Len + 2; + } + + break; + + case IE_FT_RIC_DESCRIPTOR: + if ((pFtInfo->RicInfo.RicIEsLen + eid_ptr->Len + 2) < MAX_RICIES_LEN) { + NdisMoveMemory(&pFtInfo->RicInfo.RicIEs[pFtInfo->RicInfo.RicIEsLen], + &eid_ptr->Eid, eid_ptr->Len + 2); + pFtInfo->RicInfo.RicIEsLen += eid_ptr->Len + 2; + } + + break; + + case IE_RSN: + if (NdisEqualMemory(&eid_ptr->Octet[2], WPA2_OUI, sizeof(WPA2_OUI))) { + NdisMoveMemory(pFtInfo->RSN_IE, eid_ptr, eid_ptr->Len + 2); + pFtInfo->RSNIE_Len = eid_ptr->Len + 2; + } + + break; + + default: + break; + } + + eid_ptr = (PEID_STRUCT)((UCHAR *)eid_ptr + 2 + eid_ptr->Len); + } + } + +#endif /* DOT11R_FT_SUPPORT */ +#ifdef DOT11_SAE_SUPPORT + else if (auth_info->auth_alg == AUTH_MODE_SAE) { + if (auth_info->auth_seq != SAE_COMMIT_SEQ && auth_info->auth_seq != SAE_CONFIRM_SEQ) + return FALSE; + + if (auth_info->auth_status == MLME_SUCCESS) + return TRUE; + else + return FALSE; + } + +#endif /* DOT11_SAE_SUPPORT */ + else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): fail - wrong algorithm (=%d)\n", + __func__, auth_info->auth_alg)); + return FALSE; + } + + return TRUE; +} + + +/* + ========================================================================== + 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) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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. */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH_RSP - Peer AUTH fail (Status = %d)...\n", StatusCode)); + } + + MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr->Addr2, + pHdr->Addr1, + 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(pOutBuffer); +} + + +static VOID APPeerAuthReqAtIdleAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) +{ + INT i; + USHORT RspReason; + AUTH_FRAME_INFO auth_info; + UINT32 apidx; + PHEADER_802_11 pRcvHdr; + HEADER_802_11 AuthHdr; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + MAC_TABLE_ENTRY *pEntry; + STA_TR_ENTRY *tr_entry; + UCHAR ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN; +#ifdef DOT11R_FT_SUPPORT + PFT_CFG pFtCfg; + PFT_INFO pFtInfoBuf; +#endif /* DOT11R_FT_SUPPORT */ + BSS_STRUCT *pMbss; + struct wifi_dev *wdev; + + + + if (pAd->ApCfg.BANClass3Data == TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Disallow new Association\n")); + return; + } + + if (!APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, &auth_info)) + return; + + /* Find which MBSSID to be authenticate */ + apidx = get_apidx_by_addr(pAd, auth_info.addr1); + + if (apidx >= pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - Bssid not found\n")); + return; + } + + if (apidx >= HW_BEACON_MAX_NUM) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Index out of bound\n")); + return; + } + + pMbss = &pAd->ApCfg.MBSSID[apidx]; + wdev = &pMbss->wdev; + ASSERT((wdev->func_idx == apidx)); + + if (!OPSTATUS_TEST_FLAG_WDEV(wdev, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("AP is not ready, disallow new Association\n")); + return; + } + + if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && + !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); + return; + } + + + pEntry = MacTableLookup(pAd, auth_info.addr2); + + if (pEntry && IS_ENTRY_CLIENT(pEntry)) { + tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; + /* reset NoDataIdleCount to prevent unexpected STA assoc timeout and kicked by MacTableMaintenance */ + pEntry->NoDataIdleCount = 0; +#ifdef DOT11W_PMF_SUPPORT + + if ((pEntry->SecConfig.PmfCfg.UsePMFConnect == TRUE) + && (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) + goto SendAuth; + +#endif /* DOT11W_PMF_SUPPORT */ + + if (!RTMPEqualMemory(auth_info.addr1, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid, MAC_ADDR_LEN)) { + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + pEntry = NULL; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("AUTH - Bssid does not match\n")); + return; + } else { +#ifdef DOT11_N_SUPPORT + ba_session_tear_down_all(pAd, pEntry->wcid); +#endif /* DOT11_N_SUPPORT */ + } + + } + +#ifdef DOT11W_PMF_SUPPORT +SendAuth: +#endif /* DOT11W_PMF_SUPPORT */ + pRcvHdr = (PHEADER_802_11)(Elem->Msg); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%02x, Status=%d from [wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", + apidx, auth_info.auth_seq, auth_info.auth_alg, + auth_info.auth_status, Elem->Wcid, + PRINT_MAC(auth_info.addr2))); + +#ifdef WSC_V2_SUPPORT + + /* Do not check ACL when WPS V2 is enabled and ACL policy is positive. */ + if ((wdev->WscControl.WscConfMode != WSC_DISABLE) && + (wdev->WscControl.WscV2Info.bEnableWpsV2) && + (wdev->WscControl.WscV2Info.bWpsEnable) && + (pMbss->AccessControlList.Policy == 1)) + ; + else +#endif /* WSC_V2_SUPPORT */ + + /* fail in ACL checking => send an AUTH-Fail seq#2. */ + if (!ApCheckAccessControlList(pAd, auth_info.addr2, apidx)) { + ASSERT(auth_info.auth_seq == 1); + ASSERT(pEntry == NULL); + APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_UNSPECIFY_FAIL); + + /* If this STA exists, delete it. */ + if (pEntry) + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + + RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, auth_info.addr2, wdev->wdev_idx, 0); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Failed in ACL checking => send an AUTH seq#2 with Status code = %d\n" + , MLME_UNSPECIFY_FAIL)); + + + return; + } + +#ifdef BAND_STEERING + if (pAd->ApCfg.BandSteering + + ) { + BOOLEAN bBndStrgCheck = TRUE; + + bBndStrgCheck = BndStrg_CheckConnectionReq(pAd, wdev, auth_info.addr2, Elem, NULL); + if (bBndStrgCheck == FALSE) { + APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_UNSPECIFY_FAIL); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - check failed.\n")); + return; + } + } +#endif /* BAND_STEERING */ +#ifdef RADIUS_MAC_ACL_SUPPORT + + if (IS_IEEE8021X_Entry(wdev) && + (wdev->SecConfig.RadiusMacAuthCache.Policy == RADIUS_MAC_AUTH_ENABLE)) { +#define RADIUS_ACL_REJECT 0 +#define RADIUS_ACL_ACCEPT 1 +#define RADIUS_ACL_PENDING 2 +#define RADIUS_ACL_ACCEPT_TIMEOUT 3 + PRT_802_11_RADIUS_ACL_ENTRY pAclEntry = NULL; + + pAclEntry = RadiusFindAclEntry(&wdev->SecConfig.RadiusMacAuthCache.cacheList, auth_info.addr2); + + if (!pEntry) + pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE); + + if (pAclEntry) { + if (pAclEntry->result == RADIUS_ACL_REJECT) { + APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_UNSPECIFY_FAIL); + + if (pEntry) + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + + RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%02x:%02x:%02x:%02x:%02x:%02x RADIUS ACL checking => Reject.\n", PRINT_MAC(auth_info.addr2))); + } else if (pAclEntry->result == RADIUS_ACL_ACCEPT) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x RADIUS ACL checking => OK.\n", + PRINT_MAC(auth_info.addr2))); + } else if (pAclEntry->result == RADIUS_ACL_ACCEPT_TIMEOUT) { + /* with SESSION-TIMEOUT from Radius Server */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x RADIUS ACL checking => OK. (TIMEOUT)\n", + PRINT_MAC(auth_info.addr2))); + DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_ACL_ENTRY); + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x RADIUS ACL checking => Unkown.\n", + PRINT_MAC(auth_info.addr2))); + } + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x:%02x:%02x:%02x:%02x:%02x Not Found in RADIUS ACL & go to Check.\n", + PRINT_MAC(auth_info.addr2))); + DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_ACL_ENTRY); + return; + } + } + +#endif /* RADIUS_MAC_ACL_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + pFtCfg = &wdev->FtCfg; + + if ((pFtCfg->FtCapFlag.Dot11rFtEnable) + && (auth_info.auth_alg == AUTH_MODE_FT)) { + USHORT result; + + if (!pEntry) + pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE); + + if (pEntry != NULL) { + os_alloc_mem(pAd, (UCHAR **)&pFtInfoBuf, sizeof(FT_INFO)); + + if (pFtInfoBuf) { + result = FT_AuthReqHandler(pAd, pEntry, &auth_info.FtInfo, pFtInfoBuf); + + if (result == MLME_SUCCESS) { + NdisMoveMemory(&pEntry->MdIeInfo, &auth_info.FtInfo.MdIeInfo, sizeof(FT_MDIE_INFO)); + pEntry->AuthState = AS_AUTH_OPEN; + pEntry->Sst = SST_AUTH; + } else if (result == MLME_FAIL_NO_RESOURCE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s - give up this AUTH pkt ======================> Query R1KH from backbone (Wcid%d, %d)\n", + __func__, pEntry->wcid, pEntry->FT_R1kh_CacheMiss_Times)); + os_free_mem(pFtInfoBuf); + return; + } + + FT_EnqueueAuthReply(pAd, pRcvHdr, auth_info.auth_alg, 2, result, + &pFtInfoBuf->MdIeInfo, &pFtInfoBuf->FtIeInfo, NULL, + pFtInfoBuf->RSN_IE, pFtInfoBuf->RSNIE_Len); + os_free_mem(pFtInfoBuf); + if (result == MLME_SUCCESS) { + struct _ASIC_SEC_INFO *info = NULL; + + os_alloc_mem(NULL, (UCHAR **)&info, sizeof(ASIC_SEC_INFO)); + + if (info) { + struct _SECURITY_CONFIG *pSecConfig = &pEntry->SecConfig; + + os_zero_mem(info, sizeof(ASIC_SEC_INFO)); + NdisCopyMemory(pSecConfig->PTK, pEntry->FT_PTK, LEN_MAX_PTK); + info->Operation = SEC_ASIC_ADD_PAIRWISE_KEY; + info->Direction = SEC_ASIC_KEY_BOTH; + info->Wcid = pEntry->wcid; + info->BssIndex = pEntry->func_tb_idx; + info->Cipher = pSecConfig->PairwiseCipher; + info->KeyIdx = pSecConfig->PairwiseKeyId; + os_move_mem(&info->PeerAddr[0], + pEntry->Addr, MAC_ADDR_LEN); + os_move_mem(info->Key.Key, + &pEntry->FT_PTK[LEN_PTK_KCK + LEN_PTK_KEK], + (LEN_TK + LEN_TK2)); + WPAInstallKey(pAd, info, TRUE, TRUE); + /* Update status and set Port as Secured */ + pSecConfig->Handshake.WpaState = AS_PTKINITDONE; + os_free_mem(info); + } else { + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, + DBG_LVL_ERROR, ("%s: struct alloc fail\n", + __func__)); + } + } + } + } + + return; + } + +#endif /* DOT11R_FT_SUPPORT */ +#ifdef DOT11_SAE_SUPPORT + if ((auth_info.auth_alg == AUTH_MODE_SAE) && + (IS_AKM_SAE_SHA256(pMbss->wdev.SecConfig.AKMMap))) { + UCHAR *pmk; +#ifdef DOT11W_PMF_SUPPORT + + if (pEntry) { + tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; + + if ((pEntry->SecConfig.PmfCfg.UsePMFConnect == TRUE) + && (tr_entry->PortSecured != WPA_802_1X_PORT_SECURED)) { + APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, + auth_info.auth_alg, auth_info.auth_seq, MLME_ASSOC_REJ_TEMPORARILY); + PMF_MlmeSAQueryReq(pAd, pEntry); + return; + } + } + +#endif /* DOT11W_PMF_SUPPORT */ + pmk = sae_handle_auth(pAd, &pAd->SaeCfg, Elem->Msg, Elem->MsgLen, + pMbss->wdev.SecConfig.PSK, + auth_info.auth_seq, auth_info.auth_status); + + if (pmk) { + + if (!pEntry) + pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE); + + if (pEntry) { + UCHAR pmkid[80]; + NdisMoveMemory(pEntry->SecConfig.PMK, pmk, LEN_PMK); + pEntry->AuthState = AS_AUTH_OPEN; + pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */ + if (sae_get_pmk_cache(&pAd->SaeCfg, auth_info.addr1, auth_info.addr2, pmkid, NULL)) { + RTMPAddPMKIDCache(&pAd->ApCfg.PMKIDCache, + apidx, + pEntry->Addr, + pmkid, + pmk, + LEN_PMK); + MTWF_LOG(DBG_CAT_SEC, CATSEC_SAE, DBG_LVL_TRACE, + ("WPA3PSK(SAE):(%02x:%02x:%02x:%02x:%02x:%02x)Calc PMKID=%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pEntry->Addr), pmkid[0], pmkid[1], pmkid[2], pmkid[3], pmkid[4], pmkid[5])); + } + } + } + } else +#endif /* DOT11_SAE_SUPPORT */ + if ((auth_info.auth_alg == AUTH_MODE_OPEN) && + (!IS_AKM_SHARED(pMbss->wdev.SecConfig.AKMMap))) { + if (!pEntry) + pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE); + + if (pEntry) { + tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; + if (1 +#ifdef DOT11W_PMF_SUPPORT + && ((pEntry->SecConfig.PmfCfg.UsePMFConnect == FALSE) + || (tr_entry->PortSecured != WPA_802_1X_PORT_SECURED)) +#endif /* DOT11W_PMF_SUPPORT */ + ) { + pEntry->AuthState = AS_AUTH_OPEN; + pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */ + } + + APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_SUCCESS); + } else + ; /* MAC table full, what should we respond ????? */ + } else if ((auth_info.auth_alg == AUTH_MODE_KEY) && + (IS_AKM_SHARED(pMbss->wdev.SecConfig.AKMMap) + || IS_AKM_AUTOSWITCH(pMbss->wdev.SecConfig.AKMMap))) { + if (!pEntry) + pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, 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, auth_info.addr2); + + for (i = 0; i < CIPHER_TEXT_LEN; i++) + pAd->ApMlmeAux.Challenge[i] = RandomByte(pAd); + + RspReason = 0; + auth_info.auth_seq++; + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + return; /* if no memory, can't do anything */ + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - Send AUTH seq#2 (Challenge)\n")); + MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, auth_info.addr2, + wdev->if_addr, + wdev->bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &AuthHdr, + 2, &auth_info.auth_alg, + 2, &auth_info.auth_seq, + 2, &RspReason, + 1, &ChTxtIe, + 1, &ChTxtLen, + CIPHER_TEXT_LEN, pAd->ApMlmeAux.Challenge, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + } else + ; /* MAC table full, what should we respond ???? */ + } + else { + /* wrong algorithm */ + APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_ALG_NOT_SUPPORT); + + /* If this STA exists, delete it. */ + if (pEntry) + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - Alg=%d, Seq=%d\n", + auth_info.auth_alg, auth_info.auth_seq)); + } + + if (pEntry && IS_ENTRY_CLIENT(pEntry)) { + INT32 aid = pEntry->wcid; + + SET_FLAG_CONN_IN_PROG(aid, pAd->ConInPrgress); + } +} + + +static VOID APPeerAuthConfirmAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + AUTH_FRAME_INFO auth_info; + PHEADER_802_11 pRcvHdr; + MAC_TABLE_ENTRY *pEntry; + UINT32 apidx; +#ifdef DOT11R_FT_SUPPORT + PFT_CFG pFtCfg; + PFT_INFO pFtInfoBuf; +#endif /* DOT11R_FT_SUPPORT */ + + if (pAd == NULL) + return; + + if (!APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, &auth_info)) + return; + + apidx = get_apidx_by_addr(pAd, auth_info.addr1); + + if (apidx >= pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - Bssid not found\n")); + return; + } + + if (apidx >= HW_BEACON_MAX_NUM) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Index out of bound\n")); + return; + } + + if ((pAd->ApCfg.MBSSID[apidx].wdev.if_dev != NULL) && + !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].wdev.if_dev))) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); + return; + } /* End of if */ + + if (!VALID_UCAST_ENTRY_WCID(pAd, Elem->Wcid)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("AUTH - Invalid wcid (%d).\n", Elem->Wcid)); + return; + } + + pEntry = &pAd->MacTab.Content[Elem->Wcid]; + + if (pEntry && IS_ENTRY_CLIENT(pEntry)) { + if (!RTMPEqualMemory(auth_info.addr1, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid, MAC_ADDR_LEN)) { + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + pEntry = NULL; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("AUTH - Bssid does not match\n")); + } else + ba_session_tear_down_all(pAd, pEntry->wcid); + } + + pRcvHdr = (PHEADER_802_11)(Elem->Msg); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%02x, Status=%d from [wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", + apidx, auth_info.auth_seq, auth_info.auth_alg, + auth_info.auth_status, Elem->Wcid, + PRINT_MAC(auth_info.addr2))); + + if (pEntry && MAC_ADDR_EQUAL(auth_info.addr2, pAd->ApMlmeAux.Addr)) { +#ifdef DOT11R_FT_SUPPORT + pFtCfg = &pAd->ApCfg.MBSSID[apidx].wdev.FtCfg; + + if ((pFtCfg->FtCapFlag.Dot11rFtEnable) && (auth_info.auth_alg == AUTH_MODE_FT)) { + USHORT result; + + os_alloc_mem(pAd, (UCHAR **)&pFtInfoBuf, sizeof(FT_INFO)); + + if (pFtInfoBuf) { + os_alloc_mem(pAd, (UCHAR **) &(pFtInfoBuf->RicInfo.pRicInfo), 512); + + if (pFtInfoBuf->RicInfo.pRicInfo != NULL) { + result = FT_AuthConfirmHandler(pAd, pEntry, &auth_info.FtInfo, pFtInfoBuf); + FT_EnqueueAuthReply(pAd, pRcvHdr, auth_info.auth_alg, 4, result, + &pFtInfoBuf->MdIeInfo, &pFtInfoBuf->FtIeInfo, + &pFtInfoBuf->RicInfo, pFtInfoBuf->RSN_IE, pFtInfoBuf->RSNIE_Len); + os_free_mem(pFtInfoBuf->RicInfo.pRicInfo); + } + + os_free_mem(pFtInfoBuf); + } + } else +#endif /* DOT11R_FT_SUPPORT */ + if ((pRcvHdr->FC.Wep == 1) && + NdisEqualMemory(auth_info.Chtxt, pAd->ApMlmeAux.Challenge, CIPHER_TEXT_LEN)) { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + /* Copy security config from AP to STA's entry */ + pEntry->SecConfig.AKMMap = wdev->SecConfig.AKMMap; + pEntry->SecConfig.PairwiseCipher = wdev->SecConfig.PairwiseCipher; + pEntry->SecConfig.PairwiseKeyId = wdev->SecConfig.PairwiseKeyId; + pEntry->SecConfig.GroupCipher = wdev->SecConfig.GroupCipher; + pEntry->SecConfig.GroupKeyId = wdev->SecConfig.GroupKeyId; + os_move_mem(pEntry->SecConfig.WepKey, wdev->SecConfig.WepKey, sizeof(SEC_KEY_INFO)*SEC_KEY_NUM); + pEntry->SecConfig.GroupKeyId = wdev->SecConfig.GroupKeyId; + /* Successful */ + APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_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, auth_info.auth_alg, + auth_info.auth_seq + 1, + MLME_REJ_CHALLENGE_FAILURE); + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + /*Chtxt[127]='\0'; */ + /*pAd->ApMlmeAux.Challenge[127]='\0'; */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", + ((pRcvHdr->FC.Wep == 1) ? "challenge text is not equal" : "wep bit is not set"))); + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Sent Challenge = %s\n",&pAd->ApMlmeAux.Challenge[100])); */ + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_UNSPECIFY_FAIL); + + /* If this STA exists, delete it. */ + if (pEntry) + MacTableDeleteEntry(pAd, pEntry->wcid, 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(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk) +{ + HEADER_802_11 Hdr; + UCHAR *pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + USHORT Reason = REASON_CLS2ERR; + MAC_TABLE_ENTRY *pEntry = NULL; + UCHAR apidx; + + if (VALID_UCAST_ENTRY_WCID(pAd, pRxBlk->wcid)) + pEntry = &(pAd->MacTab.Content[pRxBlk->wcid]); + + if (pEntry && IS_ENTRY_CLIENT(pEntry)) { + /*ApLogEvent(pAd, pAddr, EVENT_DISASSOCIATED); */ + mac_entry_delete(pAd, pEntry); + } else { + apidx = get_apidx_by_addr(pAd, pRxBlk->Addr1); + + if (apidx >= pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AUTH - Class 2 error but not my bssid %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pRxBlk->Addr1))); + return; + } + } + + /* send out DEAUTH frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("AUTH - Class 2 error, Send DEAUTH frame to %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pRxBlk->Addr2))); + MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pRxBlk->Addr2, + pRxBlk->Addr1, + pRxBlk->Addr1); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &Hdr, + 2, &Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); +} + + +/* + ========================================================================== + 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); +} + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_autoChSel.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_autoChSel.c new file mode 100644 index 000000000..7f276b619 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_autoChSel.c @@ -0,0 +1,2122 @@ +/**************************************************************************** + * 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]; + +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; +#ifdef AP_SCAN_SUPPORT +extern INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode, struct wifi_dev *pwdev); +#endif/*AP_SCAN_SUPPORT*/ + +#ifdef DOT11_VHT_AC +struct vht_ch_layout { + UCHAR ch_low_bnd; + UCHAR ch_up_bnd; + UCHAR cent_freq_idx; +}; +#endif/* DOT11_VHT_AC */ + +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, + IN struct wifi_dev *pwdev) +{ + UCHAR i; + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + PBSSINFO pBssInfoTab = pAutoChCtrl->pBssInfoTab; + + if (pBssInfoTab == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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 && SsidLen <= MAX_LEN_OF_SSID) { + /* + 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; +} + + +VOID UpdateChannelInfo( + IN PRTMP_ADAPTER pAd, + IN int ch_index, + IN ChannelSel_Alg Alg, + IN struct wifi_dev *pwdev) +{ + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + if (pAutoChCtrl->pChannelInfo != NULL) { + UINT32 BusyTime; + + if (Alg == ChannelAlgCCA) { + UINT32 cca_cnt = AsicGetCCACnt(pAd); + + pAd->RalinkCounters.OneSecFalseCCACnt += cca_cnt; + pAutoChCtrl->pChannelInfo->FalseCCA[ch_index] = cca_cnt; + } + + /* + do busy time statistics for primary channel + scan time 200ms, beacon interval 100 ms + */ + BusyTime = AsicGetChBusyCnt(pAd, BandIdx); + +#ifdef AP_QLOAD_SUPPORT + pAutoChCtrl->pChannelInfo->chanbusytime[ch_index] = (BusyTime * 100) / AUTO_CHANNEL_SEL_TIMEOUT; +#else + pAutoChCtrl->pChannelInfo->chanbusytime[ch_index] = (BusyTime * 100) / 200; +#endif /* AP_QLOAD_SUPPORT */ + } else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("pAutoChCtrl->pChannelInfo equal NULL.\n")); +} + +static inline INT GetChIdx( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN UCHAR BandIdx) +{ + INT Idx; + + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + + for (Idx = 0; Idx < pChCtrl->ChListNum; Idx++) { + if (Channel == pChCtrl->ChList[Idx].Channel) + break; + } + + return Idx; +} + +static inline VOID AutoChannelSkipListSetDirty( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev; + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + for (i = 0; i < pAd->ApCfg.AutoChannelSkipListNum; i++) { + UCHAR channel_idx = GetChIdx(pAd, pAd->ApCfg.AutoChannelSkipList[i], BandIdx); + + if (channel_idx != pChCtrl->ChListNum) + pAutoChCtrl->pChannelInfo->SkipList[channel_idx] = TRUE; + } +} + +static inline BOOLEAN AutoChannelSkipListCheck( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ch) +{ + UCHAR i; + BOOLEAN result = FALSE; + + for (i = 0; i < pAd->ApCfg.AutoChannelSkipListNum; i++) { + if (Ch == pAd->ApCfg.AutoChannelSkipList[i]) { + result = TRUE; + break; + } + } + + return result; +} + +static inline BOOLEAN BW40_ChannelCheck( + IN UCHAR ch) +{ + INT i; + BOOLEAN result = TRUE; + UCHAR NorBW40_CH[] = {140, 165}; + UCHAR NorBW40ChNum = sizeof(NorBW40_CH) / sizeof(UCHAR); + + for (i = 0; i < NorBW40ChNum; i++) { + if (ch == NorBW40_CH[i]) { + result = FALSE; + break; + } + } + + return result; +} + +static inline UCHAR SelectClearChannelRandom(RTMP_ADAPTER *pAd) +{ + UCHAR cnt, ch = 0, i, RadomIdx; + /*BOOLEAN bFindIt = FALSE;*/ + UINT8 TempChList[MAX_NUM_OF_CHANNELS] = {0}; + UCHAR cfg_ht_bw = wlan_config_get_ht_bw(&pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev); + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev; + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + + if (pAd->CommonCfg.bIEEE80211H) { + cnt = 0; + + /* Filter out an available channel list */ + for (i = 0; i < pChCtrl->ChListNum; i++) { + /* Check DFS channel RemainingTimeForUse */ + if (pChCtrl->ChList[i].RemainingTimeForUse) + continue; + + /* Check skip channel list */ + if (AutoChannelSkipListCheck(pAd, pChCtrl->ChList[i].Channel) == TRUE) + continue; + +#ifdef DOT11_N_SUPPORT + + /* Check N-group of BW40 */ + if (cfg_ht_bw == BW_40 && + !(pChCtrl->ChList[i].Flags & CHANNEL_40M_CAP)) + continue; + +#endif /* DOT11_N_SUPPORT */ + /* Store available channel to temp list */ + TempChList[cnt++] = pChCtrl->ChList[i].Channel; + } + + /* Randomly select a channel from temp list */ + if (cnt) { + RadomIdx = RandomByte2(pAd)%cnt; + ch = TempChList[RadomIdx]; + } else + ch = get_channel_by_reference(pAd, 1, &pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev); + } else { + ch = pChCtrl->ChList[RandomByte2(pAd)%pChCtrl->ChListNum].Channel; + + if (ch == 0) + ch = FirstChannel(pAd, wdev); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): Select Channel %d\n", __func__, 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(RTMP_ADAPTER *pAd) +{ +#define CCA_THRESHOLD (100) + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev; + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + PBSSINFO pBssInfoTab = pAutoChCtrl->pBssInfoTab; + PCHANNELINFO pChannelInfo = pAutoChCtrl->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; + UCHAR cfg_ht_bw = wlan_config_get_ht_bw(&pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev); + + if (pBssInfoTab == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("pAd->pBssInfoTab equal NULL.\n")); + return FirstChannel(pAd, wdev); + } + + if (pChannelInfo == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("pAd->pChannelInfo equal NULL.\n")); + return FirstChannel(pAd, wdev); + } + + for (BssTab_idx = 0; BssTab_idx < pBssInfoTab->BssNr; BssTab_idx++) { + pBss = &(pBssInfoTab->BssEntry[BssTab_idx]); + channel_idx = GetChIdx(pAd, pBss->Channel, BandIdx); + + if (channel_idx < 0 || channel_idx >= MAX_NUM_OF_CHANNELS+1) + 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 (pChCtrl->ChList[loop].Channel - pChCtrl->ChList[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 || loop >= MAX_NUM_OF_CHANNELS) + break; + + if (pChCtrl->ChList[(loop+1) % MAX_NUM_OF_CHANNELS].Channel - pChCtrl->ChList[loop % MAX_NUM_OF_CHANNELS].Channel > 4) + continue; + + pChannelInfo->dirtyness[loop] += + ((9 - (channel_idx - loop)) * 4); + } + } + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("=====================================================\n")); + + for (channel_idx = 0; channel_idx < pChCtrl->ChListNum; channel_idx++) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Channel %d : Dirty = %ld, False CCA = %u, Busy Time = %u, Skip Channel = %s\n", + pChCtrl->ChList[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")); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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 < pChCtrl->ChListNum; channel_idx++) { + if (pChannelInfo->SkipList[channel_idx] == TRUE) + continue; + + if (pChannelInfo->FalseCCA[channel_idx] <= CCA_THRESHOLD) { + UINT32 dirtyness = pChannelInfo->dirtyness[channel_idx]; + + ch = pChCtrl->ChList[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 ((cfg_ht_bw == BW_40) + && (pChannelInfo->IsABand && (GetABandChOffset(ch) == 0))) + continue; + + /* + Need to Consider the dirtyness of extending channel + in 40 MHz bandwidth channel. + */ + if (cfg_ht_bw == BW_40) { + if (pAutoChCtrl->pChannelInfo->IsABand) { + if (((channel_idx + GetABandChOffset(ch)) >= 0) + && ((channel_idx + GetABandChOffset(ch)) < pChCtrl->ChListNum)) { + INT ChOffsetIdx = channel_idx + GetABandChOffset(ch); + + dirtyness += pChannelInfo->dirtyness[ChOffsetIdx]; + } + } else { + UCHAR ExChannel_idx = 0; + + if (pChCtrl->ChList[channel_idx].Channel == 14) { + dirtyness = 0xFFFFFFFF; + break; + } + NdisZeroMemory(ExChannel, sizeof(ExChannel)); + + if (((channel_idx - 4) >= 0) && ((channel_idx - 4) < pChCtrl->ChListNum)) { + dirtyness += pChannelInfo->dirtyness[channel_idx - 4]; + ExChannel[ExChannel_idx++] = pChCtrl->ChList[channel_idx - 4].Channel; + } + + if (((channel_idx + 4) >= 0) && ((channel_idx + 4) < pChCtrl->ChListNum)) { + dirtyness += pChannelInfo->dirtyness[channel_idx + 4]; + ExChannel[ExChannel_idx++] = pChCtrl->ChList[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 = pChCtrl->ChList[candidate_ch].Channel; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Rule 1 CCA value : Min Dirtiness (Include extension channel) ==> Select Channel %d\n", ch)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Min Dirty = %u\n", min_dirty)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ExChannel = %d , %d\n", candidate_ExChannel[0], candidate_ExChannel[1])); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("BW = %s\n", (cfg_ht_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 < pChCtrl->ChListNum; 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 = pChCtrl->ChList[channel_idx].Channel; +#ifdef DOT11_N_SUPPORT + + if ((cfg_ht_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)) < pChCtrl->ChListNum)) { + 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 = pChCtrl->ChList[candidate_ch].Channel; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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 < pChCtrl->ChListNum; channel_idx++) { + ch = pChCtrl->ChList[(base + channel_idx) % pChCtrl->ChListNum].Channel; + + if (AutoChannelSkipListCheck(pAd, ch)) + continue; + + if ((pAd->ApCfg.bAvoidDfsChannel == TRUE) + && (pChannelInfo->IsABand == TRUE) + && RadarChannelCheck(pAd, ch)) + continue; + + break; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Rule 3 CCA value : Randomly Select ==> Select Channel %d\n", ch)); + return ch; +} + +static inline UCHAR SelectClearChannelBusyTime( + IN PRTMP_ADAPTER pAd, + IN struct wifi_dev *wdev) +{ + UCHAR BandIdx = HcGetBandByWdev(wdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + PCHANNELINFO pChannelInfo = pAutoChCtrl->pChannelInfo; + UINT32 SubGroupMaxBusyTime, SubGroupMaxBusyTimeChIdx, MinBusyTime; + UINT32 SubGroupMinBusyTime, SubGroupMinBusyTimeChIdx, ChannelIdx, StartChannelIdx, Temp1, Temp2; + INT i, j, GroupNum, CandidateCh1 = 0, CandidateChIdx1, base; +#ifdef DOT11_VHT_AC + UINT32 MinorMinBusyTime; + INT CandidateCh2, CandidateChIdx2; + UCHAR cfg_ht_bw = wlan_config_get_ht_bw(wdev); + UCHAR vht_bw = wlan_config_get_vht_bw(wdev); + UCHAR cen_ch_2; +#endif/* DOT11_VHT_AC */ +#ifndef DOT11_VHT_AC +#endif/* DOT11_VHT_AC */ + PUINT32 pSubGroupMaxBusyTimeTable = NULL; + PUINT32 pSubGroupMaxBusyTimeChIdxTable = NULL; + PUINT32 pSubGroupMinBusyTimeTable = NULL; + PUINT32 pSubGroupMinBusyTimeChIdxTable = NULL; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[SelectClearChannelBusyTime] - band%d START\n", BandIdx)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[SelectClearChannelBusyTime] - cfg_ht_bw = %d vht_bw = %d\n", cfg_ht_bw, vht_bw)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + if (pChannelInfo == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("pAd->pChannelInfo equal NULL.\n")); + return FirstChannel(pAd, wdev); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("====================================================================\n")); + + for (ChannelIdx = 0; ChannelIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChannelIdx++) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Channel %3d : Busy Time = %6u, Skip Channel = %s, BwCap = %s\n", + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChannelIdx].Channel, pChannelInfo->chanbusytime[ChannelIdx], + (pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChannelIdx].SkipChannel == TRUE) ? "TRUE" : "FALSE", + (pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChannelIdx].BwCap == TRUE)?"TRUE" : "FALSE")); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("====================================================================\n")); + /*Initialization*/ + SubGroupMaxBusyTimeChIdx = 0; + SubGroupMaxBusyTime = pChannelInfo->chanbusytime[SubGroupMaxBusyTimeChIdx]; + SubGroupMinBusyTimeChIdx = 0; + SubGroupMinBusyTime = pChannelInfo->chanbusytime[SubGroupMinBusyTimeChIdx]; + StartChannelIdx = SubGroupMaxBusyTimeChIdx + 1; + GroupNum = 0; + os_alloc_mem(pAd, (UCHAR **)&pSubGroupMaxBusyTimeTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + os_alloc_mem(pAd, (UCHAR **)&pSubGroupMaxBusyTimeChIdxTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + os_alloc_mem(pAd, (UCHAR **)&pSubGroupMinBusyTimeTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + os_alloc_mem(pAd, (UCHAR **)&pSubGroupMinBusyTimeChIdxTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + NdisZeroMemory(pSubGroupMaxBusyTimeTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + NdisZeroMemory(pSubGroupMaxBusyTimeChIdxTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + NdisZeroMemory(pSubGroupMinBusyTimeTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + NdisZeroMemory(pSubGroupMinBusyTimeChIdxTable, (MAX_NUM_OF_CHANNELS+1)*sizeof(UINT32)); + + for (ChannelIdx = StartChannelIdx; ChannelIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChannelIdx++) { + /*Compare the busytime with each other in the same group*/ + if (pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChannelIdx].CentralChannel == pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChannelIdx-1].CentralChannel) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("pChannelInfo->chanbusytime[%d] = %d, SubGroupMaxBusyTime = %d, SubGroupMinBusyTime = %d\n", + ChannelIdx, pChannelInfo->chanbusytime[ChannelIdx], SubGroupMaxBusyTime, SubGroupMinBusyTime)); + + if (pChannelInfo->chanbusytime[ChannelIdx] > SubGroupMaxBusyTime) { + SubGroupMaxBusyTime = pChannelInfo->chanbusytime[ChannelIdx]; + SubGroupMaxBusyTimeChIdx = ChannelIdx; + } else if (pChannelInfo->chanbusytime[ChannelIdx] < SubGroupMinBusyTime) { + SubGroupMinBusyTime = pChannelInfo->chanbusytime[ChannelIdx]; + SubGroupMinBusyTimeChIdx = ChannelIdx; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("SubGroupMaxBusyTime = %d, SubGroupMaxBusyTimeChIdx = %d,SubGroupMinBusyTime = %d SubGroupMinBusyTimeChIdx = %d\n", + SubGroupMaxBusyTime, SubGroupMaxBusyTimeChIdx, SubGroupMinBusyTime, SubGroupMinBusyTimeChIdx)); + + /*Fill in the group table in order for the last group*/ + if (ChannelIdx == (pAutoChCtrl->AutoChSelCtrl.ChListNum - 1)) { + pSubGroupMaxBusyTimeTable[GroupNum] = SubGroupMaxBusyTime; + pSubGroupMaxBusyTimeChIdxTable[GroupNum] = SubGroupMaxBusyTimeChIdx; + pSubGroupMinBusyTimeTable[GroupNum] = SubGroupMinBusyTime; + pSubGroupMinBusyTimeChIdxTable[GroupNum] = SubGroupMinBusyTimeChIdx; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("SubGroupMaxBusyTimeTable[%d] = %d, SubGroupMaxBusyTimeChIdxTable[%d] = %d, SubGroupMinBusyTimeTable[%d] = %d, SubGroupMinBusyTimeChIdxTable[%d] = %d\n", + GroupNum, pSubGroupMaxBusyTimeTable[GroupNum], GroupNum, pSubGroupMaxBusyTimeChIdxTable[GroupNum], + GroupNum, pSubGroupMinBusyTimeTable[GroupNum], GroupNum, pSubGroupMinBusyTimeChIdxTable[GroupNum])); + GroupNum++; + } + } else { + /*Fill in the group table*/ + pSubGroupMaxBusyTimeTable[GroupNum] = SubGroupMaxBusyTime; + pSubGroupMaxBusyTimeChIdxTable[GroupNum] = SubGroupMaxBusyTimeChIdx; + pSubGroupMinBusyTimeTable[GroupNum] = SubGroupMinBusyTime; + pSubGroupMinBusyTimeChIdxTable[GroupNum] = SubGroupMinBusyTimeChIdx; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("SubGroupMaxBusyTimeTable[%d] = %d, SubGroupMaxBusyTimeChIdxTable[%d] = %d, SubGroupMinBusyTimeTable[%d] = %d, SubGroupMinBusyTimeChIdxTable[%d] = %d\n", + GroupNum, pSubGroupMaxBusyTimeTable[GroupNum], GroupNum, pSubGroupMaxBusyTimeChIdxTable[GroupNum], + GroupNum, pSubGroupMinBusyTimeTable[GroupNum], GroupNum, pSubGroupMinBusyTimeChIdxTable[GroupNum])); + GroupNum++; + + /*Fill in the group table in order for the last group in case of BW20*/ + if ((ChannelIdx == (pAutoChCtrl->AutoChSelCtrl.ChListNum - 1)) + && (pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChannelIdx].Bw == BW_20)) { + pSubGroupMaxBusyTimeTable[GroupNum] = pChannelInfo->chanbusytime[ChannelIdx]; + pSubGroupMaxBusyTimeChIdxTable[GroupNum] = ChannelIdx; + pSubGroupMinBusyTimeTable[GroupNum] = pChannelInfo->chanbusytime[ChannelIdx]; + pSubGroupMinBusyTimeChIdxTable[GroupNum] = ChannelIdx; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("SubGroupMaxBusyTimeTable[%d] = %d, SubGroupMaxBusyTimeChIdxTable[%d] = %d, SubGroupMinBusyTimeTable[%d] = %d, SubGroupMinBusyTimeChIdxTable[%d] = %d\n", + GroupNum, pSubGroupMaxBusyTimeTable[GroupNum], GroupNum, pSubGroupMaxBusyTimeChIdxTable[GroupNum], + GroupNum, pSubGroupMinBusyTimeTable[GroupNum], GroupNum, pSubGroupMinBusyTimeChIdxTable[GroupNum])); + GroupNum++; + } else { + /*Reset indices in order to start checking next group*/ + SubGroupMaxBusyTime = pChannelInfo->chanbusytime[ChannelIdx]; + SubGroupMaxBusyTimeChIdx = ChannelIdx; + SubGroupMinBusyTime = pChannelInfo->chanbusytime[ChannelIdx]; + SubGroupMinBusyTimeChIdx = ChannelIdx; + } + } + } + + for (i = 0; i < GroupNum; i++) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("SubGroupMaxBusyTimeTable[%d] = %d, pSubGroupMaxBusyTimeChIdxTable[%d] = %d,\nSubGroupMinBusyTimeTable[%d] = %d, pSubGroupMinBusyTimeChIdxTable[%d] = %d\n", + i, pSubGroupMaxBusyTimeTable[i], i, pSubGroupMaxBusyTimeChIdxTable[i], + i, pSubGroupMinBusyTimeTable[i], i, pSubGroupMinBusyTimeChIdxTable[i])); + } + + /*Sort max_busy_time group table from the smallest to the biggest one */ + for (i = 0; i < GroupNum; i++) { + for (j = 1; j < (GroupNum-i); j++) { + if (pSubGroupMaxBusyTimeTable[i] > pSubGroupMaxBusyTimeTable[i+j]) { + /*Swap pSubGroupMaxBusyTimeTable[i] for pSubGroupMaxBusyTimeTable[i+j]*/ + Temp1 = pSubGroupMaxBusyTimeTable[i+j]; + pSubGroupMaxBusyTimeTable[i+j] = pSubGroupMaxBusyTimeTable[i]; + pSubGroupMaxBusyTimeTable[i] = Temp1; + /*Swap pSubGroupMaxBusyTimeChIdxTable[i] for pSubGroupMaxBusyTimeChIdxTable[i+j]*/ + Temp2 = pSubGroupMaxBusyTimeChIdxTable[i+j]; + pSubGroupMaxBusyTimeChIdxTable[i+j] = pSubGroupMaxBusyTimeChIdxTable[i]; + pSubGroupMaxBusyTimeChIdxTable[i] = Temp2; + /*Swap pSubGroupMinBusyTimeTable[i] for pSubGroupMinBusyTimeTable[i+j]*/ + Temp1 = pSubGroupMinBusyTimeTable[i+j]; + pSubGroupMinBusyTimeTable[i+j] = pSubGroupMinBusyTimeTable[i]; + pSubGroupMinBusyTimeTable[i] = Temp1; + /*Swap pSubGroupMinBusyTimeChIdxTable[i] for pSubGroupMinBusyTimeChIdxTable[i+j]*/ + Temp2 = pSubGroupMinBusyTimeChIdxTable[i+j]; + pSubGroupMinBusyTimeChIdxTable[i+j] = pSubGroupMinBusyTimeChIdxTable[i]; + pSubGroupMinBusyTimeChIdxTable[i] = Temp2; + } + } + } + + for (i = 0; i < GroupNum; i++) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("SubGroupMaxBusyTimeTable[%d] = %d, pSubGroupMaxBusyTimeChIdxTable[%d] = %d,\nSubGroupMinBusyTimeTable[%d] = %d, pSubGroupMinBusyTimeChIdxTable[%d] = %d\n", + i, pSubGroupMaxBusyTimeTable[i], i, pSubGroupMaxBusyTimeChIdxTable[i], + i, pSubGroupMinBusyTimeTable[i], i, pSubGroupMinBusyTimeChIdxTable[i])); + } + +#ifdef DOT11_VHT_AC + + /*Return channel in case of VHT BW80+80*/ + if ((vht_bw == VHT_BW_8080) + && (cfg_ht_bw == BW_40) + && (GroupNum > 2) + && (WMODE_CAP_AC(wdev->PhyMode) == TRUE)) { + MinBusyTime = pSubGroupMaxBusyTimeTable[0]; + MinorMinBusyTime = pSubGroupMaxBusyTimeTable[1]; + /*Select primary channel, whose busy time is minimum in the group*/ + CandidateChIdx1 = pSubGroupMinBusyTimeChIdxTable[0]; + CandidateCh1 = pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[CandidateChIdx1].Channel; + /*Select secondary VHT80 central channel*/ + CandidateChIdx2 = pSubGroupMaxBusyTimeChIdxTable[1]; + CandidateCh2 = pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[CandidateChIdx2].Channel; + cen_ch_2 = vht_cent_ch_freq((UCHAR)CandidateCh2, VHT_BW_80); + wlan_operate_set_cen_ch_2(wdev, cen_ch_2); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : Select Primary Channel %d\n", CandidateCh1)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : Select Secondary Central Channel %d\n", cen_ch_2)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : Min Channel Busy = %u\n", MinBusyTime)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : MinorMin Channel Busy = %u\n", MinorMinBusyTime)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : BW = %s\n", "80+80")); + os_free_mem(pSubGroupMaxBusyTimeTable); + os_free_mem(pSubGroupMaxBusyTimeChIdxTable); + os_free_mem(pSubGroupMinBusyTimeTable); + os_free_mem(pSubGroupMinBusyTimeChIdxTable); + goto ReturnCh; + } + +#endif/*DOT11_VHT_AC*/ + + if (GroupNum > 0) { + MinBusyTime = pSubGroupMaxBusyTimeTable[0]; + /*Select primary channel, whose busy time is minimum in the group*/ + CandidateChIdx1 = pSubGroupMinBusyTimeChIdxTable[0]; + CandidateCh1 = pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[CandidateChIdx1].Channel; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : Select Primary Channel %d\n", CandidateCh1)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : Min Channel Busy = %u\n", MinBusyTime)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Rule 3 Channel Busy time value : BW = %s\n", + (pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[CandidateChIdx1].Bw == BW_160) ? "160" + : (pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[CandidateChIdx1].Bw == BW_80) ? "80" + : (pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[CandidateChIdx1].Bw == BW_40) ? "40":"20")); + os_free_mem(pSubGroupMaxBusyTimeTable); + os_free_mem(pSubGroupMaxBusyTimeChIdxTable); + os_free_mem(pSubGroupMinBusyTimeTable); + os_free_mem(pSubGroupMinBusyTimeChIdxTable); + goto ReturnCh; + } + + base = RandomByte2(pAd); + + for (ChannelIdx = 0; ChannelIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChannelIdx++) { + CandidateCh1 = pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[(base + ChannelIdx) % pAutoChCtrl->AutoChSelCtrl.ChListNum].Channel; + + if (AutoChannelSkipListCheck(pAd, CandidateCh1)) + continue; + + if ((pAd->ApCfg.bAvoidDfsChannel == TRUE) + && (pAutoChCtrl->AutoChSelCtrl.IsABand == TRUE) + && RadarChannelCheck(pAd, CandidateCh1)) + continue; + + break; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Randomly Select : Select Channel %d\n", CandidateCh1)); +ReturnCh: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[SelectClearChannelBusyTime] - band%d END\n", BandIdx)); + return CandidateCh1; +} + +/* + ========================================================================== + 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(RTMP_ADAPTER *pAd, struct wifi_dev *pwdev) +{ + /*PBSSINFO pBssInfoTab = pAutoChCtrl->pBssInfoTab; */ + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + PCHANNELINFO pChannelInfo = pAutoChCtrl->pChannelInfo; + /*BSSENTRY *pBss; */ + UCHAR channel_index = 0, dirty, base = 0; + UCHAR final_channel = 0; + UCHAR op_ht_bw = wlan_operate_get_ht_bw(pwdev); + UCHAR ext_cha = wlan_operate_get_ext_cha(pwdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + + if (pChannelInfo == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("pAd->pChannelInfo equal NULL.\n")); + return FirstChannel(pAd, pwdev); + } + + /* Calculate Dirtiness */ + + for (channel_index = 0; channel_index < pChCtrl->ChListNum; channel_index++) { + if (pChannelInfo->ApCnt[channel_index] > 0) { + INT ll; + + pChannelInfo->dirtyness[channel_index] += 30; + + /*5G */ + if (pChannelInfo->IsABand) { + int Channel = pChCtrl->ChList[channel_index].Channel; + + /*Make secondary channel dirty */ + if (op_ht_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 (pChCtrl->ChList[channel_index+1].Channel - pChCtrl->ChList[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 (pChCtrl->ChList[channel_index].Channel - pChCtrl->ChList[channel_index-1].Channel == 4) + pChannelInfo->dirtyness[channel_index-1] += 1; + } + } + } + } + + /*2.4G */ + if (!pChannelInfo->IsABand) { + int ChanOffset = 0; + + if ((op_ht_bw == BW_40) && + (ext_cha == 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 ((op_ht_bw == BW_40) && + (ext_cha == 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 && ll < MAX_NUM_OF_CHANNELS+1) + pChannelInfo->dirtyness[ll]++; + } + } + } + } /* Calculate Dirtiness */ + + AutoChannelSkipListSetDirty(pAd); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("=====================================================\n")); + + for (channel_index = 0; channel_index < pChCtrl->ChListNum; channel_index++) + /* debug messages */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Channel %d : Dirty = %ld, ApCnt=%ld, Busy Time = %d, Skip Channel = %s\n", + pChCtrl->ChList[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")); + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("=====================================================\n")); + pAd->ApCfg.AutoChannel_Channel = 0; + + /* RULE 1. pick up a good channel that no one used */ + + for (channel_index = 0; channel_index < pChCtrl->ChListNum; channel_index++) { + if (pChannelInfo->SkipList[channel_index] == TRUE) + continue; + + if ((pAd->ApCfg.bAvoidDfsChannel == TRUE) && (pChannelInfo->IsABand == TRUE) + && RadarChannelCheck(pAd, pChCtrl->ChList[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 < pChCtrl->ChListNum) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Rule 1 APCnt : dirtiness == 0 (no one used and no interference) ==> Select Channel %d\n", pChCtrl->ChList[channel_index].Channel)); + return pChCtrl->ChList[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 < pChCtrl->ChListNum; 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 < pChCtrl->ChListNum; 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 ((op_ht_bw == BW_40) + && (BW40_ChannelCheck(pChCtrl->ChList[channel_index].Channel) == FALSE)) + continue; + + if ((pAd->ApCfg.bAvoidDfsChannel == TRUE) && (pChannelInfo->IsABand == TRUE) + && RadarChannelCheck(pAd, pChCtrl->ChList[channel_index].Channel)) + continue; + + final_channel = pChCtrl->ChList[channel_index].Channel; + min_ApCnt = pChannelInfo->ApCnt[channel_index]; + } + } + + if (final_channel != 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Rule 2 APCnt : minimum APCnt with minimum interference(dirtiness: 30~32) ==> Select Channel %d\n", final_channel)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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 < pChCtrl->ChListNum; channel_index++) { + final_channel = pChCtrl->ChList[(base + channel_index) % pChCtrl->ChListNum].Channel; + + if (AutoChannelSkipListCheck(pAd, final_channel)) + continue; + + if ((pAd->ApCfg.bAvoidDfsChannel == TRUE) && (pChannelInfo->IsABand == TRUE) + && RadarChannelCheck(pAd, final_channel)) + continue; + + break; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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, + IN struct wifi_dev *pwdev) +{ + ULONG Idx; + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + PBSSINFO pBssInfoTab = pAutoChCtrl->pBssInfoTab; + + if (pBssInfoTab == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("pAd->pBssInfoTab equal NULL.\n")); + return BSS_NOT_FOUND; + } + + Idx = AutoChBssSearchWithSSID(pAd, pBssid, (PUCHAR)Ssid, SsidLen, ChannelNo, pwdev); + + if (Idx == BSS_NOT_FOUND) { + Idx = pBssInfoTab->BssNr; + if (Idx >= MAX_LEN_OF_BSS_TABLE) + return BSS_NOT_FOUND; + + AutoChBssEntrySet(&pBssInfoTab->BssEntry[Idx % MAX_LEN_OF_BSS_TABLE], pBssid, Ssid, SsidLen, + ChannelNo, ExtChOffset, Rssi); + pBssInfoTab->BssNr++; + } else { + AutoChBssEntrySet(&pBssInfoTab->BssEntry[Idx % MAX_LEN_OF_BSS_TABLE], pBssid, Ssid, SsidLen, + ChannelNo, ExtChOffset, Rssi); + } + + return Idx; +} + +void AutoChBssTableDestroy(RTMP_ADAPTER *pAd) +{ + AUTO_CH_CTRL *pAutoChCtrl; + UCHAR BandIdx; + + pAutoChCtrl = HcGetAutoChCtrl(pAd); + + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + if (!pAutoChCtrl) + continue; + + if (pAutoChCtrl->pBssInfoTab) { + os_free_mem(pAutoChCtrl->pBssInfoTab); + pAutoChCtrl->pBssInfoTab = NULL; + } + } + +} + + +static VOID AutoChBssTableReset(RTMP_ADAPTER *pAd, UINT8 BandIdx) +{ + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + PBSSINFO pBssInfoTab = pAutoChCtrl->pBssInfoTab; + + if (pBssInfoTab) + NdisZeroMemory(pBssInfoTab, sizeof(BSSINFO)); + else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pAutoChCtrl->pBssInfoTab equal NULL.\n")); + } +} + + +void AutoChBssTableInit( + IN PRTMP_ADAPTER pAd) +{ + BSSINFO *pBssInfoTab = NULL; + UCHAR BandIdx; + AUTO_CH_CTRL *pAutoChCtrl = NULL; + + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + os_alloc_mem(pAd, (UCHAR **)&pBssInfoTab, sizeof(BSSINFO)); + + if (pBssInfoTab) { + NdisZeroMemory(pBssInfoTab, sizeof(BSSINFO)); + pAutoChCtrl->pBssInfoTab = pBssInfoTab; + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s Fail to alloc memory for pAutoChCtrl->pBssInfoTab", + __func__)); + } + } + +} + + +void ChannelInfoDestroy( + IN PRTMP_ADAPTER pAd) +{ + UCHAR BandIdx; + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + if (pAutoChCtrl->pChannelInfo) { + os_free_mem(pAutoChCtrl->pChannelInfo); + pAutoChCtrl->pChannelInfo = NULL; + } + } +} + + +static VOID ChannelInfoReset(RTMP_ADAPTER *pAd, UINT8 BandIdx) +{ + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + CHANNELINFO *ch_info = pAutoChCtrl->pChannelInfo; + + if (ch_info) + NdisZeroMemory(ch_info, sizeof(CHANNELINFO)); + else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pChannelInfo equal NULL, band:%d\n", BandIdx)); +} + + +void ChannelInfoInit( + IN PRTMP_ADAPTER pAd) +{ + CHANNELINFO *ch_info = NULL; + UCHAR BandIdx; + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + ch_info = NULL; + os_alloc_mem(pAd, (UCHAR **)&ch_info, sizeof(CHANNELINFO)); + + if (ch_info) { + os_zero_mem(ch_info, sizeof(CHANNELINFO)); + pAutoChCtrl->pChannelInfo = ch_info; + } else { + pAutoChCtrl->pChannelInfo = NULL; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s Fail to alloc memory for pAd->pChannelInfo", __func__)); + } + } +} + +/* + ========================================================================== + Description: + This routine sets the current PhyMode for calculating + the dirtyness. + Return: + none + NOTE: + ========================================================================== + */ +void CheckPhyModeIsABand(RTMP_ADAPTER *pAd, UINT8 BandIdx) +{ + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + UCHAR PhyMode = HcGetRadioPhyModeByBandIdx(pAd, BandIdx); + + pAutoChCtrl->pChannelInfo->IsABand = (WMODE_CAP_5G(PhyMode)) ? TRUE : FALSE; +} + + +UCHAR SelectBestChannel(RTMP_ADAPTER *pAd, ChannelSel_Alg Alg, struct wifi_dev *pwdev) +{ + UCHAR ch = 0; + /* init RadioCtrl.pChannelInfo->IsABand */ + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + CheckPhyModeIsABand(pAd, BandIdx); +#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, pwdev); + break; + + case ChannelAlgCCA: + ch = SelectClearChannelCCA(pAd); + break; + + case ChannelAlgBusyTime: + ch = SelectClearChannelBusyTime(pAd, pwdev); + break; + + default: + ch = SelectClearChannelBusyTime(pAd, pwdev); + break; + } + + RTMPSendWirelessEvent(pAd, IW_CHANNEL_CHANGE_EVENT_FLAG, 0, 0, ch); + pAutoChCtrl->AutoChSelCtrl.ACSChStat = ACS_CH_STATE_SELECTED; + pAutoChCtrl->AutoChSelCtrl.SelCh = ch; + return ch; +} + +VOID APAutoChannelInit(RTMP_ADAPTER *pAd, struct wifi_dev *pwdev) +{ + UINT32 BusyTime; + UCHAR BandIdx = HcGetBandByWdev(pwdev); + + /* reset bss table */ + AutoChBssTableReset(pAd, BandIdx); + /* clear Channel Info */ + ChannelInfoReset(pAd, BandIdx); + /* init RadioCtrl.pChannelInfo->IsABand */ + CheckPhyModeIsABand(pAd, BandIdx); + pAd->ApCfg.current_channel_index = 0; + /* read clear for primary channel */ + BusyTime = AsicGetChBusyCnt(pAd, BandIdx); +} + +/* + ========================================================================== + 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 + ========================================================================== + */ +UCHAR APAutoSelectChannel( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *pwdev, + IN ChannelSel_Alg Alg, + IN BOOLEAN IsABand) +{ + UCHAR ch = 0; + + if (pAd->phy_op && pAd->phy_op->AutoCh) + ch = pAd->phy_op->AutoCh(pAd, pwdev, Alg, IsABand); + + return ch; +} + +UCHAR MTAPAutoSelectChannel( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *pwdev, + IN ChannelSel_Alg Alg, + IN BOOLEAN IsABand) +{ + UCHAR ch = 0, i = 0; + UINT32 BusyTime; + + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + if (pAutoChCtrl->AutoChSelCtrl.ACSChStat == ACS_CH_STATE_SELECTED) { + ch = pAutoChCtrl->AutoChSelCtrl.SelCh; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[MTAPAutoSelectChannel] ACS channel is selected, selected ch = %d\n", ch)); + return ch; + } + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + /* Init some structures before doing AutoChannelSelect() */ + APAutoChannelInit(pAd, pwdev); + +#ifdef MICROWAVE_OVEN_SUPPORT + pAd->CommonCfg.MO_Cfg.bEnable = FALSE; + AsicMeasureFalseCCA(pAd); +#endif /* MICROWAVE_OVEN_SUPPORT */ + + /* Re-arrange channel list and fill in channel properties for auto-channel selection*/ + AutoChSelBuildChannelList(pAd, IsABand, pwdev); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: IsABand = %d, ChannelListNum = %d\n", __func__, IsABand, pAutoChCtrl->AutoChSelCtrl.ChListNum)); + + for (i = 0; i < pAutoChCtrl->AutoChSelCtrl.ChListNum; i++) { + ULONG wait_time = 200; /* Wait for 200 ms at each channel. */ + + wlan_operate_scan(pwdev, pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[i].Channel); + pAd->ApCfg.current_channel_index = i; + pAd->ApCfg.AutoChannel_Channel = pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[i].Channel; + /* Read-Clear reset Channel busy time counter */ + BusyTime = AsicGetChBusyCnt(pAd, BandIdx); +#ifdef AP_QLOAD_SUPPORT + /* QLOAD ALARM, ever alarm from QLOAD module */ + if (QLOAD_DOES_ALARM_OCCUR(pAd)) + wait_time = 400; +#endif /* AP_QLOAD_SUPPORT */ + OS_WAIT(wait_time); + UpdateChannelInfo(pAd, i, Alg, pwdev); + } + + ch = SelectBestChannel(pAd, Alg, pwdev); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); + return ch; +} + +/* + ========================================================================== + Description: + Update channel to wdev which is supported for A-band or G-band. + + Return: + None. + ========================================================================== + */ +VOID AutoChSelUpdateChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN IsABand, + IN struct wifi_dev *pwdev) +{ + UINT8 ExtChaDir; + + if (IsABand) { + /*5G Channel*/ + pwdev->channel = Channel; + } else { + /*2G Channel*/ + /* Update primary channel in wdev */ + pwdev->channel = Channel; + + /* Query ext_cha in wdev */ + ExtChaDir = wlan_config_get_ext_cha(pwdev); + + /* Check current extension channel */ + if (!ExtChCheck(pAd, Channel, ExtChaDir, pwdev)) { + if (ExtChaDir == EXTCHA_BELOW) + ExtChaDir = EXTCHA_ABOVE; + else + ExtChaDir = EXTCHA_BELOW; + + /* Update ext_cha in wdev */ + wlan_config_set_ext_cha(pwdev, ExtChaDir); + } + + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\x1b[41m %s(): Update channel for wdev for this band PhyMode = %d, Channel = %d \x1b[m\n", + __func__, pwdev->PhyMode, pwdev->channel)); +} + +/* + ========================================================================== + Description: + Build channel list for auto-channel selection. + + Return: + None. + ========================================================================== + */ +VOID AutoChSelBuildChannelList( + IN RTMP_ADAPTER *pAd, + IN BOOLEAN IsABand, + IN struct wifi_dev *pwdev) +{ + + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + /* Initialize channel list*/ + os_zero_mem(pAutoChCtrl->AutoChSelCtrl.AutoChSelChList, (MAX_NUM_OF_CHANNELS+1) * sizeof(AUTOCH_SEL_CH_LIST)); + + if (IsABand) { + pAutoChCtrl->AutoChSelCtrl.IsABand = TRUE; + + /* Build 5G channel list used by ACS */ + AutoChSelBuildChannelListFor5G(pAd, pwdev); + } else if (!IsABand) { + pAutoChCtrl->AutoChSelCtrl.IsABand = FALSE; + + /* Build 2G channel list used by ACS */ + AutoChSelBuildChannelListFor2G(pAd, pwdev); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); +} +/* + ========================================================================== + Description: + Build channel list for 2.4G according to 1) Country Region 2) RF IC type for auto-channel selection. + + Return: + None. + ========================================================================== + */ +VOID AutoChSelBuildChannelListFor2G( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *pwdev) +{ + INT ChIdx, ChListNum = 0; + UCHAR cfg_ht_bw = wlan_config_get_ht_bw(pwdev); + AUTOCH_SEL_CH_LIST *pACSChList; + UCHAR BandIdx = HcGetBandByWdev(pwdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + pAutoChCtrl->AutoChSelCtrl.ChListNum = pChCtrl->ChListNum; + + /* Initialize local ACS channel list*/ + os_alloc_mem(NULL, (UCHAR **)&pACSChList, (MAX_NUM_OF_CHANNELS+1) * sizeof(AUTOCH_SEL_CH_LIST)); + os_zero_mem(pACSChList, (MAX_NUM_OF_CHANNELS+1) * sizeof(AUTOCH_SEL_CH_LIST)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + for (ChIdx = 0; ChIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChIdx++) + pACSChList[ChIdx].Channel = pChCtrl->ChList[ChIdx].Channel; + + for (ChIdx = 0; ChIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChIdx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Ch = %3d\n", __func__, pACSChList[ChIdx].Channel)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); + + /* Check for skip-channel list */ + for (ChIdx = 0; ChIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChIdx++) + pACSChList[ChIdx].SkipChannel = AutoChannelSkipListCheck(pAd, pACSChList[ChIdx].Channel); + + for (ChIdx = 0; ChIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChIdx++) { + /* 2.4G only support for BW20 auto-channel selection */ + pACSChList[ChIdx].Bw = BW_20; + pACSChList[ChIdx].CentralChannel = pACSChList[ChIdx].Channel; + + if (cfg_ht_bw == BW_20) + pACSChList[ChIdx].BwCap = TRUE; +#ifdef DOT11_N_SUPPORT + else if ((cfg_ht_bw == BW_40) + && N_ChannelGroupCheck(pAd, pACSChList[ChIdx].Channel, pwdev)) + pACSChList[ChIdx].BwCap = TRUE; +#endif /* DOT11_N_SUPPORT */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[AutoChSelBuildChannelListFor2G] - ChIdx = %d, ChListNum = %d\n", ChIdx, pAutoChCtrl->AutoChSelCtrl.ChListNum)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: PrimChannel = %3d, CenChannel = %3d, BW= %d, BwCap= %d, SkipChannel= %d\n", __func__, + pACSChList[ChIdx].Channel, pACSChList[ChIdx].CentralChannel, + pACSChList[ChIdx].Bw, pACSChList[ChIdx].BwCap, + pACSChList[ChIdx].SkipChannel)); + } + + for (ChIdx = 0; ChIdx < pAutoChCtrl->AutoChSelCtrl.ChListNum; ChIdx++) { + if ((pACSChList[ChIdx].SkipChannel == TRUE) || (pACSChList[ChIdx].BwCap == FALSE)) + continue; + else { + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].Channel = pACSChList[ChIdx].Channel; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].Bw = pACSChList[ChIdx].Bw; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].BwCap = pACSChList[ChIdx].BwCap; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].CentralChannel = pACSChList[ChIdx].CentralChannel; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].SkipChannel = pACSChList[ChIdx].SkipChannel; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].Flags = pACSChList[ChIdx].Flags; + ChListNum++; + } + } + pAutoChCtrl->AutoChSelCtrl.ChListNum = ChListNum; + os_free_mem(pACSChList); +} +/* + ========================================================================== + Description: + Build channel list for 5G according to 1) Country Region 2) RF IC type for auto-channel selection. + + Return: + None. + ========================================================================== + */ +VOID AutoChSelBuildChannelListFor5G( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *pwdev) +{ +#define EXT_ABOVE 1 +#define EXT_BELOW -1 + INT ChIdx; +#ifdef DOT11_VHT_AC + INT k, count, idx; + struct vht_ch_layout *vht_ch_80M = get_ch_array(80); + struct vht_ch_layout *vht_ch_160M = get_ch_array(160); + UCHAR cfg_vht_bw = wlan_config_get_vht_bw(pwdev); +#endif/* DOT11_VHT_AC */ + UCHAR cfg_ht_bw = wlan_config_get_ht_bw(pwdev); + AUTOCH_SEL_CH_LIST *pACSChList; + INT ChListNum5G = 0; + INT ChListNum = 0; + + UCHAR BandIdx = HcGetBandByWdev(pwdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[AutoChSelBuildChannelListFor5G] cfg_ht_bw = %d, cfg_vht_bw = %d\n", cfg_ht_bw, cfg_vht_bw)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + /* Initialize local ACS channel list*/ + os_alloc_mem(NULL, (UCHAR **)&pACSChList, (MAX_NUM_OF_CHANNELS+1) * sizeof(AUTOCH_SEL_CH_LIST)); + os_zero_mem(pACSChList, (MAX_NUM_OF_CHANNELS+1) * sizeof(AUTOCH_SEL_CH_LIST)); + + /*Skip Non occupancy channel*/ + for (ChIdx = 0; ChIdx < pChCtrl->ChListNum; ChIdx++) { + if (CheckNonOccupancyChannel(pAd, pwdev)) { + pACSChList[ChListNum5G++].Channel = pChCtrl->ChList[ChIdx].Channel; + } + } + + + for (ChIdx = 0; ChIdx < ChListNum5G; ChIdx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Ch = %3d\n", __func__, pACSChList[ChIdx].Channel)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[AutoChSelBuildChannelListFor5G] ChListNum5G = %d\n", ChListNum5G)); + /* Check for skip-channel list */ + for (ChIdx = 0; ChIdx < ChListNum5G; ChIdx++) { + pACSChList[ChIdx].SkipChannel = AutoChannelSkipListCheck(pAd, pACSChList[ChIdx].Channel); +#ifdef BACKGROUND_SCAN_SUPPORT + if (pAd->BgndScanCtrl.SkipDfsChannel) + pACSChList[ChIdx].SkipChannel = RadarChannelCheck(pAd, pACSChList[ChIdx].Channel); +#endif /* BACKGROUND_SCAN_SUPPORT */ + } + + /* Set parameters (BW/BWCap/CentralChannel/..)of ACS channel list*/ + for (ChIdx = 0; ChIdx < ChListNum5G; ChIdx++) { + + if (cfg_ht_bw == BW_20) { + pACSChList[ChIdx].Bw = BW_20; + pACSChList[ChIdx].BwCap = TRUE; + pACSChList[ChIdx].CentralChannel = pACSChList[ChIdx].Channel; + } + +#ifdef DOT11_N_SUPPORT + else if (((cfg_ht_bw == BW_40) +#ifdef DOT11_VHT_AC + && (cfg_vht_bw == VHT_BW_2040) +#endif /* DOT11_VHT_AC */ + ) && N_ChannelGroupCheck(pAd, pACSChList[ChIdx].Channel, pwdev)) { + pACSChList[ChIdx].Bw = BW_40; + + /* Check that if there is a secondary channel in current BW40-channel group for BW40 capacity. */ + if ((GetABandChOffset(pACSChList[ChIdx].Channel) == EXT_ABOVE) + && (pACSChList[ChIdx + 1].Channel == (pACSChList[ChIdx].Channel + 4))) + pACSChList[ChIdx].BwCap = TRUE; + else if ((GetABandChOffset(pACSChList[ChIdx].Channel) == EXT_BELOW) + && (pACSChList[ChIdx - 1].Channel == (pACSChList[ChIdx].Channel - 4))) + pACSChList[ChIdx].BwCap = TRUE; + else + pACSChList[ChIdx].BwCap = FALSE; + + /* Check that whether there is a skip-channel in current BW40-channel group */ + /* If there is a skip-channel in BW40-channel group, just also skip secondary channel */ + if (pACSChList[ChIdx].SkipChannel == TRUE) { + if ((GetABandChOffset(pACSChList[ChIdx].Channel) == EXT_ABOVE) + && (pACSChList[ChIdx + 1].Channel == (pACSChList[ChIdx].Channel + 4))) + pACSChList[ChIdx + 1].SkipChannel = TRUE; + else if ((GetABandChOffset(pACSChList[ChIdx].Channel) == EXT_BELOW) + && (pACSChList[ChIdx - 1].Channel == (pACSChList[ChIdx].Channel - 4))) + pACSChList[ChIdx - 1].SkipChannel = TRUE; + } + + /* Fill in central-channel parameter */ + if (GetABandChOffset(pACSChList[ChIdx].Channel) == EXT_ABOVE) + pACSChList[ChIdx].CentralChannel = pACSChList[ChIdx].Channel + 2; + else + pACSChList[ChIdx].CentralChannel = pACSChList[ChIdx].Channel - 2; + } +#endif /* DOT11_N_SUPPORT */ +#ifdef DOT11_VHT_AC + else if (((cfg_vht_bw == VHT_BW_80) || (cfg_vht_bw == VHT_BW_8080)) + && vht80_channel_group(pAd, pACSChList[ChIdx].Channel)) { + pACSChList[ChIdx].Bw = BW_80; + idx = 0; + count = 0; + + /* Find out VHT BW80 channel group for current channel */ + while (vht_ch_80M[idx].ch_up_bnd != 0) { + if ((pACSChList[ChIdx].Channel >= vht_ch_80M[idx].ch_low_bnd) && + (pACSChList[ChIdx].Channel <= vht_ch_80M[idx].ch_up_bnd)) + break; + idx++; + } + + if (vht_ch_80M[idx].ch_up_bnd != 0) { + /* Count for secondary channels in current VHT BW80 channel group */ + for (k = 1; k < 4; k++) { + if ((pACSChList[ChIdx + k].Channel >= vht_ch_80M[idx].ch_low_bnd) && + (pACSChList[ChIdx + k].Channel <= vht_ch_80M[idx].ch_up_bnd)) + count++; + + if ((pACSChList[ChIdx - k].Channel >= vht_ch_80M[idx].ch_low_bnd) && + (pACSChList[ChIdx - k].Channel <= vht_ch_80M[idx].ch_up_bnd)) + count++; + } + + if (count == 3) + pACSChList[ChIdx].BwCap = TRUE; + } + + /* Check that whether there is a skip-channel in BW80-channel group */ + /* If there is a skip-channel in BW80-channel group, just also skip secondary channels */ + if (pACSChList[ChIdx].SkipChannel == TRUE) { + for (k = 1; k < 4; k++) { + if ((pACSChList[ChIdx + k].Channel >= vht_ch_80M[idx].ch_low_bnd) && + (pACSChList[ChIdx + k].Channel <= vht_ch_80M[idx].ch_up_bnd)) + pACSChList[ChIdx + k].SkipChannel = TRUE; + + if ((pACSChList[ChIdx - k].Channel >= vht_ch_80M[idx].ch_low_bnd) && + (pACSChList[ChIdx - k].Channel <= vht_ch_80M[idx].ch_up_bnd)) + pACSChList[ChIdx - k].SkipChannel = TRUE; + } + } + + pACSChList[ChIdx].CentralChannel = vht_cent_ch_freq(pACSChList[ChIdx].Channel, VHT_BW_80); + } else if ((cfg_vht_bw == VHT_BW_160) + && vht80_channel_group(pAd, pACSChList[ChIdx].Channel)) { + pACSChList[ChIdx].Bw = BW_160; + idx = 0; + count = 0; + + /* Find out VHT BW160 channel group for current channel */ + while (vht_ch_160M[idx].ch_up_bnd != 0) { + if ((pACSChList[ChIdx].Channel >= vht_ch_160M[idx].ch_low_bnd) && + (pACSChList[ChIdx].Channel <= vht_ch_160M[idx].ch_up_bnd)) + break; + + idx++; + } + + if (vht_ch_160M[idx].ch_up_bnd != 0) { + /* Count for secondary channels in current VHT BW160 channel group */ + for (k = 1; k < 8; k++) { + if ((pACSChList[ChIdx + k].Channel >= vht_ch_160M[idx].ch_low_bnd) && + (pACSChList[ChIdx + k].Channel <= vht_ch_160M[idx].ch_up_bnd)) + count++; + + if ((pACSChList[ChIdx - k].Channel >= vht_ch_160M[idx].ch_low_bnd) && + (pACSChList[ChIdx - k].Channel <= vht_ch_160M[idx].ch_up_bnd)) + count++; + } + + if (count == 7) + pACSChList[ChIdx].BwCap = TRUE; + } + + /* Check that whether there is a skip-channel in BW160-channel group */ + /* If there is a skip-channel in BW160-channel group, just also skip secondary channels */ + if (pACSChList[ChIdx].SkipChannel == TRUE) { + for (k = 1; k < 8; k++) { + if ((pACSChList[ChIdx + k].Channel >= vht_ch_160M[idx].ch_low_bnd) && + (pACSChList[ChIdx + k].Channel <= vht_ch_160M[idx].ch_up_bnd)) + pACSChList[ChIdx + k].SkipChannel = TRUE; + + if ((pACSChList[ChIdx - k].Channel >= vht_ch_160M[idx].ch_low_bnd) && + (pACSChList[ChIdx - k].Channel <= vht_ch_160M[idx].ch_up_bnd)) + pACSChList[ChIdx - k].SkipChannel = TRUE; + } + } + + pACSChList[ChIdx].CentralChannel = vht_cent_ch_freq(pACSChList[ChIdx].Channel, VHT_BW_160); + } else { + /*The channel is undefined*/ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[AutoChSelBuildChannelListFor5G] The channel:%d is undefined\n", pACSChList[ChIdx].Channel)); + if ((cfg_ht_bw == BW_40) && (cfg_vht_bw == VHT_BW_2040)) + pACSChList[ChIdx].Bw = BW_40; + else if ((cfg_vht_bw == VHT_BW_80) || (cfg_vht_bw == VHT_BW_8080)) + pACSChList[ChIdx].Bw = BW_80; + else if (cfg_vht_bw == VHT_BW_160) + pACSChList[ChIdx].Bw = BW_160; + + pACSChList[ChIdx].BwCap = FALSE; + pACSChList[ChIdx].CentralChannel = pACSChList[ChIdx].Channel; + } +#endif /* DOT11_VHT_AC */ + } + + /*Show ACS channel list*/ + for (ChIdx = 0; ChIdx < ChListNum5G; ChIdx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: PrimChannel = %3d, CenChannel = %3d, BW= %d, BwCap= %d, SkipChannel= %d\n", __func__, + pACSChList[ChIdx].Channel, pACSChList[ChIdx].CentralChannel, + pACSChList[ChIdx].Bw, pACSChList[ChIdx].BwCap, + pACSChList[ChIdx].SkipChannel)); + } + + /*Set channel list of auto channel selection*/ + for (ChIdx = 0; ChIdx < ChListNum5G; ChIdx++) { + if ((pACSChList[ChIdx].SkipChannel == TRUE) || (pACSChList[ChIdx].BwCap == FALSE)) + continue; + else { + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].Channel = pACSChList[ChIdx].Channel; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].Bw = pACSChList[ChIdx].Bw; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].BwCap = pACSChList[ChIdx].BwCap; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].CentralChannel = pACSChList[ChIdx].CentralChannel; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].SkipChannel = pACSChList[ChIdx].SkipChannel; + pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[ChListNum].Flags = pACSChList[ChIdx].Flags; + ChListNum++; + } + } + pAutoChCtrl->AutoChSelCtrl.ChListNum = ChListNum; + + os_free_mem(pACSChList); +} + +/* + ========================================================================== + Description: + + Return: + ScanChIdx - Channel index which is mapping to related channel to be scanned. + Note: + return -1 if no more next channel + ========================================================================== + */ +CHAR AutoChSelFindScanChIdx( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *pwdev, + IN CHAR LastScanChIdx) +{ + CHAR ScanChIdx = -1; + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + if (LastScanChIdx == -1) + ScanChIdx = 0; + else { + ScanChIdx = LastScanChIdx + 1; + + if (ScanChIdx >= pAutoChCtrl->AutoChSelCtrl.ChListNum) + ScanChIdx = -1; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : LastScanChIdx = %d, ScanChIdx = %d, ChannelListNum = %d\n" + , __func__, LastScanChIdx, ScanChIdx, pAutoChCtrl->AutoChSelCtrl.ChListNum)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); + return ScanChIdx; +} + +/* + ========================================================================== + Description: + Scan next channel + ========================================================================== + */ +VOID AutoChSelScanNextChannel( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *pwdev) +{ + RALINK_TIMER_STRUCT *ScanTimer; + CHAR Idx; + UINT32 BusyTime; + ULONG wait_time = 200; /* Wait for 200 ms at each channel. */ + UCHAR NewCh, BandIdx = HcGetBandByWdev(pwdev); + INT ret; + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + ScanTimer = &pAutoChCtrl->AutoChSelCtrl.AutoChScanTimer; + Idx = pAutoChCtrl->AutoChSelCtrl.ScanChIdx; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); +#ifdef AP_QLOAD_SUPPORT + + /* QLOAD ALARM, ever alarm from QLOAD module */ + if (QLOAD_DOES_ALARM_OCCUR(pAd)) + wait_time = 400; + +#endif /* AP_QLOAD_SUPPORT */ + + if (pAutoChCtrl->AutoChSelCtrl.ScanChIdx == -1) { + NewCh = SelectClearChannelBusyTime(pAd, pwdev); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s : Current channel = %d , selected new channel = %d\n", __func__, pwdev->channel, NewCh)); + +#ifdef AP_SCAN_SUPPORT + scan_ch_restore(pAd, OPMODE_AP, pwdev); /* Restore original channel */ +#endif /* AP_SCAN_SUPPORT */ + + if (NewCh != pwdev->channel) { + ret = rtmp_set_channel(pAd, pwdev, NewCh); + if (!ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : Fail to set channel !! \n", __func__)); + } + } + + pAutoChCtrl->AutoChSelCtrl.ACSChStat = ACS_CH_STATE_SELECTED; + /* Update current state from listen state to idle. */ + pAutoChCtrl->AutoChSelCtrl.AutoChScanStatMachine.CurrState = AUTO_CH_SEL_SCAN_IDLE; + + /* Enable MibBucket after ACS done */ + pAd->MsMibBucket.Enabled = TRUE; + pAd->OneSecMibBucket.Enabled[BandIdx] = TRUE; + } else { + /* Update current state from idle state to listen. */ + pAutoChCtrl->AutoChSelCtrl.AutoChScanStatMachine.CurrState = AUTO_CH_SEL_SCAN_LISTEN; + + wlan_operate_scan(pwdev, pAutoChCtrl->AutoChSelCtrl.AutoChSelChList[Idx].Channel); + + /* Read-Clear reset Channel busy time counter */ + BusyTime = AsicGetChBusyCnt(pAd, BandIdx); + + RTMPSetTimer(ScanTimer, wait_time); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); +} + +/* + ========================================================================== + Description: + Auto-channel selection SCAN req state machine procedure + ========================================================================== + */ +VOID AutoChSelScanReqAction( + IN RTMP_ADAPTER *pAd, + IN MLME_QUEUE_ELEM * pElem) +{ + BOOLEAN Cancelled; + UCHAR BandIdx; + AUTO_CH_CTRL *pAutoChCtrl; + struct wifi_dev *pwdev = (struct wifi_dev *)pElem->Priv; + if (!pwdev) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("AutoChSelScanReqAction - pwdev == NULL \n")); + return; + } + BandIdx = HcGetBandByWdev(pwdev); + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + RTMPCancelTimer(&pAutoChCtrl->AutoChSelCtrl.AutoChScanTimer, &Cancelled); + AutoChSelScanNextChannel(pAd, pwdev); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); +} + +/* + ========================================================================== + Description: + Auto-channel selection SCAN timeout state machine procedure + ========================================================================== + */ +VOID AutoChSelScanTimeoutAction( + IN RTMP_ADAPTER *pAd, + IN MLME_QUEUE_ELEM * pElem) +{ + CHAR Idx; + UCHAR BandIdx; + AUTO_CH_CTRL *pAutoChCtrl; + struct wifi_dev *pwdev = (struct wifi_dev *)pElem->Priv; + if (!pwdev) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("AutoChSelScanTimeoutAction - pwdev == NULL \n")); + return; + } + BandIdx = HcGetBandByWdev(pwdev); + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + Idx = pAutoChCtrl->AutoChSelCtrl.ScanChIdx; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + UpdateChannelInfo(pAd, Idx, ChannelAlgBusyTime, pwdev); + pAutoChCtrl->AutoChSelCtrl.ScanChIdx = AutoChSelFindScanChIdx(pAd, pwdev, Idx); + AutoChSelScanNextChannel(pAd, pwdev); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); +} + +/* + ========================================================================== + Description: + Scan start handler, executed in timer thread + ========================================================================== + */ +VOID AutoChSelScanStart( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *pwdev) +{ + UCHAR BandIdx = HcGetBandByWdev(pwdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + /* Reset ACS ChCtrl*/ + pAutoChCtrl->AutoChSelCtrl.ACSChStat = ACS_CH_STATE_NONE; + os_zero_mem(pAutoChCtrl->AutoChSelCtrl.AutoChSelChList, (MAX_NUM_OF_CHANNELS+1)*sizeof(AUTOCH_SEL_CH_LIST)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + /* Disable MibBucket during doing ACS */ + pAd->MsMibBucket.Enabled = FALSE; + pAd->OneSecMibBucket.Enabled[BandIdx] = FALSE; + + pAutoChCtrl->AutoChSelCtrl.ScanChIdx = 0; /* Start from first channel */ + pAutoChCtrl->AutoChSelCtrl.pScanReqwdev = pwdev; + + if (WMODE_CAP_5G(pwdev->PhyMode)) + pAutoChCtrl->AutoChSelCtrl.IsABand = TRUE; + else + pAutoChCtrl->AutoChSelCtrl.IsABand = FALSE; + + AutoChSelBuildChannelList(pAd, pAutoChCtrl->AutoChSelCtrl.IsABand, pwdev); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: IsABand = %d, ChannelListNum = %d\n", __func__, pAutoChCtrl->AutoChSelCtrl.IsABand, pAutoChCtrl->AutoChSelCtrl.ChListNum)); + MlmeEnqueue(pAd, AUTO_CH_SEL_STATE_MACHINE, AUTO_CH_SEL_SCAN_REQ, 0, NULL, (ULONG)pwdev); + RTMP_MLME_HANDLER(pAd); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); +} + +/* + ========================================================================== + Description: + Scan timeout handler, executed in timer thread + ========================================================================== + */ +VOID AutoChSelScanTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + PTIMER_FUNC_CONTEXT pContext = (PTIMER_FUNC_CONTEXT)FunctionContext; + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pContext->pAd; + UCHAR BandIdx = pContext->BandIdx; + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + struct wifi_dev *pwdev = pAutoChCtrl->AutoChSelCtrl.pScanReqwdev; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[AutoChSelScanTimeout] - BandIdx = %d\n", BandIdx)); + MlmeEnqueue(pAd, AUTO_CH_SEL_STATE_MACHINE, AUTO_CH_SEL_SCAN_TIMEOUT, 0, NULL, (ULONG)pwdev); + RTMP_MLME_HANDLER(pAd); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); +} + +/* + ========================================================================== + Description: + Auto-channel selection state machine. + Parameters: + Sm - pointer to the state machine + NOTE: + The state machine is classified as follows: + a. AUTO_CH_SEL_SCAN_IDLE + b. AUTO_CH_SEL_SCAN_LISTEN + ========================================================================== + */ +VOID AutoChSelStateMachineInit( + IN RTMP_ADAPTER *pAd, + IN UCHAR BandIdx, + IN STATE_MACHINE * Sm, + OUT STATE_MACHINE_FUNC Trans[]) +{ + + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + pAutoChCtrl->AutoChSelCtrl.ACSTimerFuncContex.pAd = pAd; + pAutoChCtrl->AutoChSelCtrl.ACSTimerFuncContex.BandIdx = BandIdx; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + StateMachineInit(Sm, (STATE_MACHINE_FUNC *)Trans, AUTO_CH_SEL_SCAN_MAX_STATE, AUTO_CH_SEL_SCAN_MAX_MSG, + (STATE_MACHINE_FUNC)Drop, AUTO_CH_SEL_SCAN_IDLE, AUTO_CH_SEL_MACHINE_BASE); + /* Scan idle state */ + StateMachineSetAction(Sm, AUTO_CH_SEL_SCAN_IDLE, AUTO_CH_SEL_SCAN_REQ, (STATE_MACHINE_FUNC)AutoChSelScanReqAction); + /* Scan listen state */ + StateMachineSetAction(Sm, AUTO_CH_SEL_SCAN_LISTEN, AUTO_CH_SEL_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)AutoChSelScanTimeoutAction); + RTMPInitTimer(pAd, &pAutoChCtrl->AutoChSelCtrl.AutoChScanTimer, GET_TIMER_FUNCTION(AutoChSelScanTimeout), &pAutoChCtrl->AutoChSelCtrl.ACSTimerFuncContex, FALSE); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); +} + +/* + ========================================================================== + Description: + Init for auto-channel selection scan-timer. + NOTE: + ========================================================================== + */ +VOID AutoChSelInit( + IN PRTMP_ADAPTER pAd) +{ + UCHAR BandIdx; + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + AutoChSelStateMachineInit(pAd, BandIdx, &pAutoChCtrl->AutoChSelCtrl.AutoChScanStatMachine, pAutoChCtrl->AutoChSelCtrl.AutoChScanFunc); + } +} + +/* + ========================================================================== + Description: + Release auto-channel selection scan-timer. + NOTE: + ========================================================================== + */ +VOID AutoChSelRelease( + IN PRTMP_ADAPTER pAd) +{ + BOOLEAN Cancelled; + + UCHAR BandIdx; + AUTO_CH_CTRL *pAutoChCtrl; + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + RTMPReleaseTimer(&pAutoChCtrl->AutoChSelCtrl.AutoChScanTimer, &Cancelled); + } +} + +#ifdef AP_SCAN_SUPPORT +/* + ========================================================================== + Description: + trigger Auto Channel Selection every period of ACSCheckTime. + + NOTE: + This function is called in a 1-sec mlme periodic check. + Do ACS only on one HW band at a time. + Do ACS only when no clients is associated. + ========================================================================== + */ +VOID AutoChannelSelCheck(RTMP_ADAPTER *pAd) +{ + UCHAR i, WdevBandIdx = 0, BandIdx, HWBandNum; + MAC_TABLE_ENTRY *pEntry = NULL; + struct wifi_dev *pwdev = NULL; + + /* Query current cofigured HW band number */ + HWBandNum = HcGetAmountOfBand(pAd); + + for (BandIdx = 0; BandIdx < HWBandNum; BandIdx++) { + /* Do nothing if ACSCheckTime is not configured */ + if (pAd->ApCfg.ACSCheckTime[BandIdx] == 0) + continue; + pAd->ApCfg.ACSCheckCount[BandIdx]++; + + if (pAd->ApCfg.ACSCheckCount[BandIdx] > pAd->ApCfg.ACSCheckTime[BandIdx]) { + + /* Find wdev, BandIdx of wdev is the same as BandIdx */ + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + pwdev = &pAd->ApCfg.MBSSID[i].wdev; + WdevBandIdx = HcGetBandByWdev(pwdev); + if (BandIdx == WdevBandIdx) + break; + } + + /* Do nothing if AP is doing channel scanning */ + if (ApScanRunning(pAd, pwdev)) + continue; + + /* Reset Counter */ + pAd->ApCfg.ACSCheckCount[BandIdx] = 0; + + /* Do Auto Channel Selection only when no client is associated in current band */ + if (pAd->MacTab.Size != 0) { + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + + if ((pEntry->wdev != NULL) && (IS_ENTRY_CLIENT(pEntry))) { + WdevBandIdx = HcGetBandByWdev(pEntry->wdev); + + if (BandIdx == WdevBandIdx) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\x1b[41m%s(): Ignore ACS checking because has associated clients in current band%d\x1b[m\n", + __func__, BandIdx)); + + return; + } + } + } + } + /* Start for ACS checking */ + { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): Scanning channels for channel selection.\n", __func__)); + + if (pAd->ApCfg.AutoChannelAlg == ChannelAlgBusyTime) + AutoChSelScanStart(pAd, pwdev); + else + ApSiteSurvey_by_wdev(pAd, NULL, SCAN_PASSIVE, TRUE, pwdev); + return; + } + } + } +} +#endif /* AP_SCAN_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_band_steering.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_band_steering.c new file mode 100644 index 000000000..d9702885a --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_band_steering.c @@ -0,0 +1,2079 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + ap_band_steering.c +*/ + +#ifdef BAND_STEERING +#include "rt_config.h" + +#define BNDSTRG_DRIVER_VER "3.1.2" +static inline PBND_STRG_CLI_TABLE Get_BndStrgTableByChannel( + PRTMP_ADAPTER pAd, + UINT8 Channel) +{ + PBND_STRG_CLI_TABLE table = NULL; + INT i; + + for (i = 0; i < DBDC_BAND_NUM; i++) { + table = P_BND_STRG_TABLE(i); + + if (table->bInitialized && (table->Channel == Channel)) + return table; + } + + return NULL; +} + +inline PBND_STRG_CLI_TABLE Get_BndStrgTable( + PRTMP_ADAPTER pAd, + INT apidx) +{ + BSS_STRUCT *pMbss = NULL; + UINT8 Channel; + + if (apidx < HW_BEACON_MAX_NUM) + pMbss = &pAd->ApCfg.MBSSID[apidx]; + + if (pMbss) { + Channel = pMbss->wdev.channel; + return Get_BndStrgTableByChannel(pAd, Channel); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (RED("%s:(%d):invalid pMbss. apidx=%d\n"), __func__, __LINE__, apidx)); + return NULL; +} + +INT Show_BndStrg_Info( + PRTMP_ADAPTER pAd, + RTMP_STRING *arg) +{ + PBND_STRG_CLI_TABLE table; + POS_COOKIE pObj; + UCHAR ifIndex; + struct wifi_dev *wdev = NULL; + BNDSTRG_MSG msg = { 0 }; + UINT8 idx = 0; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + + if (ifIndex >= HW_BEACON_MAX_NUM) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[ifIndex].wdev; + + if (!pAd->ApCfg.BndStrgBssIdx[wdev->func_idx]) + return TRUE; + + table = Get_BndStrgTable(pAd, ifIndex); + + if (!table) + return FALSE; + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Band Steering Driver Ver - %s\n", BNDSTRG_DRIVER_VER)); + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t BndStrgBssIdx")); + + for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (":%d", pAd->ApCfg.BndStrgBssIdx[idx])); + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t WhiteListSize:%d\n", table->WhiteEntryListSize)); + + if (table->WhiteEntryListSize) { + UINT8 i; + + for (i = 0; i < BND_STRG_MAX_WHITELIST_ENTRY; i++) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t %d -> %02x:%02x:%02x:%02x:%02x:%02x\n", i, PRINT_MAC(table->WhiteEntryList[i]))); + } + } + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t BlackListSize:%d\n", table->BndStrgBlackListSize)); + + if (table->BndStrgBlackListSize) { + UINT8 i; + + for (i = 0; i < BND_STRG_MAX_BLACKLIST_ENTRY; i++) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t %d -> %02x:%02x:%02x:%02x:%02x:%02x\n", i, PRINT_MAC(table->BndStrgBlackList[i]))); + } + } + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + msg.Action = TABLE_INFO; + BndStrgSendMsg(pAd, &msg); + return TRUE; +} + +INT Show_BndStrg_List( + PRTMP_ADAPTER pAd, + RTMP_STRING *arg) +{ + PBND_STRG_CLI_TABLE table; + POS_COOKIE pObj; + UCHAR ifIndex; + UINT32 display_type; + BNDSTRG_MSG msg = { 0 }; + CHAR band_str[4][10] = {"", "5G", "2.4G", "2.4G/5G"}; + INT i; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + table = Get_BndStrgTable(pAd, ifIndex); + + if (!table) + return FALSE; + + if (arg == NULL) + display_type = 0; + else + display_type = (UINT32) simple_strtol(arg, 0, 10); + + if (display_type > 3) + display_type = 0; + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t%s Accessible Clients: %d\n", band_str[table->Band], table->Size)); + + for (i = 0; i < BND_STRG_MAX_TABLE_SIZE; i++) { + if (table->Entry[i].bValid) { + if (MAC_ADDR_EQUAL(table->MonitorAddr, table->Entry[i].Addr)) { + BND_STRG_PRINTQAMSG(table, table->Entry[i].Addr, + (YLW("\t%d: %02x:%02x:%02x:%02x:%02x:%02x [TblIdx:%d]\n"), + i, PRINT_MAC(table->Entry[i].Addr), table->Entry[i].TableIndex)); + } else { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\t%d: %02x:%02x:%02x:%02x:%02x:%02x [TblIdx:%d]\n", + i, PRINT_MAC(table->Entry[i].Addr), table->Entry[i].TableIndex)); + } + } + } + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\tBndStrg Table Entries:\n")); + msg.Action = ENTRY_LIST; + msg.data.display_type.display_type = display_type; + msg.data.display_type.filer_band = table->Band; + msg.data.display_type.channel = table->Channel; + BndStrgSendMsg(pAd, &msg); + + return TRUE; +} + +INT Set_BndStrg_Enable( + PRTMP_ADAPTER pAd, + RTMP_STRING *arg) +{ + PBND_STRG_CLI_TABLE table; + POS_COOKIE pObj; + UCHAR ifIndex; + BOOLEAN enable; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + enable = (BOOLEAN) simple_strtol(arg, 0, 10); + + if (!(enable ^ pAd->ApCfg.BandSteering)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (GRN("BndStrg is already %s\n"), pAd->ApCfg.BandSteering?"Enable":"Disable")); + return TRUE; + } + + if (enable) { + BSS_STRUCT *pMbss = NULL; + INT apidx, IdBss; + + apidx = ifIndex; + + if (apidx < HW_BEACON_MAX_NUM) + pMbss = &pAd->ApCfg.MBSSID[apidx]; + + if (pMbss == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (RED("%s:(%d):invalid pMbss. apidx=%d\n"), __func__, __LINE__, apidx)); + return FALSE; + } + + /* bnstrg table does not init yet, call BndStrg_Init directly */ + BndStrg_Init(pAd); + + /* enable all active mbss BndStrg InfFlags to nitify daemon */ + for (IdBss = 0; IdBss < pAd->ApCfg.BssidNum; IdBss++) { + pMbss = &pAd->ApCfg.MBSSID[IdBss]; + table = Get_BndStrgTable(pAd, IdBss); + + if (table) { + /* Inform daemon interface ready */ + BndStrg_SetInfFlags(pAd, &pMbss->wdev, table, TRUE); + } + } + + pAd->ApCfg.BandSteering = enable; + } else { + BndStrg_Release(pAd); + pAd->ApCfg.BandSteering = enable; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (GRN("BndStrg %s Success\n"), pAd->ApCfg.BandSteering?"Enable":"Disable")); + return TRUE; +} + +INT Set_BndStrg_Param(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + PBND_STRG_CLI_TABLE table; + POS_COOKIE pObj; + UCHAR ifIndex; + BNDSTRG_MSG msg = { 0 }; + struct bnd_msg_param *bndstrg_param = &msg.data.bndstrg_param; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + + if (ifIndex > HW_BEACON_MAX_NUM) + return FALSE; + + table = Get_BndStrgTable(pAd, ifIndex); + + if (!table) + return FALSE; + + msg.Action = BNDSTRG_PARAM; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): BndStrg param = %s\n", __func__, arg)); + + bndstrg_param->Band = table->Band; + bndstrg_param->Channel = table->Channel; + bndstrg_param->len = strlen(arg); + strncpy(bndstrg_param->arg, arg, sizeof(bndstrg_param->arg)); + BndStrgSendMsg(pAd, &msg); + + return TRUE; +} + +#ifdef BND_STRG_DBG +INT Set_BndStrg_MonitorAddr( + PRTMP_ADAPTER pAd, + RTMP_STRING *arg) +{ + UCHAR MonitorAddr[MAC_ADDR_LEN]; + RTMP_STRING *value; + INT i; + PBND_STRG_CLI_TABLE table; + POS_COOKIE pObj; + UCHAR ifIndex; + BNDSTRG_MSG msg = { 0 }; + struct bnd_msg_mnt_addr *mnt_addr = &msg.data.mnt_addr; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + table = Get_BndStrgTable(pAd, ifIndex); + + if (!table) + return FALSE; + + 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, (UCHAR *)&MonitorAddr[i++], 1); + } + + COPY_MAC_ADDR(table->MonitorAddr, MonitorAddr); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, PRINT_MAC(table->MonitorAddr))); + msg.Action = SET_MNT_ADDR; + COPY_MAC_ADDR(mnt_addr->Addr, table->MonitorAddr); + BndStrgSendMsg(pAd, &msg); + + return TRUE; +} +#endif /* BND_STRG_DBG */ + +INT BndStrg_Init(PRTMP_ADAPTER pAd) +{ + INT ret_val = BND_STRG_SUCCESS; + INT max_mbss_check_num; + INT apidx; + + max_mbss_check_num = pAd->ApCfg.BssidNum; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (YLW("%s()\n"), __func__)); + + for (apidx = 0; apidx < max_mbss_check_num; apidx++) { + if (pAd->ApCfg.BndStrgBssIdx[apidx]) { + ret_val = BndStrg_TableInit(pAd, apidx); + if (ret_val != BND_STRG_SUCCESS) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Error in %s(), error code = %d on apidx = %d\n", + __func__, ret_val, apidx)); + } + } + } + + return ret_val; +} + +#ifdef DOT11K_RRM_SUPPORT +VOID BndStrg_InsertNeighborRepIE(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE init_table) +{ + RRM_NEIGHBOR_REP_INFO NeighborRepInfo = { {0} }; + BSS_STRUCT *pMbss = NULL; + RRM_BSSID_INFO BssidInfo; + UINT8 idx, CondensedPhyType = 0; /* 7:2G,9:5G */ + + if (init_table->Channel == 0) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[%s]Error zero channel\n", __func__)); + return; + } + + for (idx = 0; idx < HW_BEACON_MAX_NUM; idx++) { + pMbss = &pAd->ApCfg.MBSSID[idx]; + if (pMbss->wdev.channel == init_table->Channel && pAd->ApCfg.BndStrgBssIdx[idx]) + break; + } + + if (idx >= HW_BEACON_MAX_NUM) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[%s]Error no pMbss init to channel table channel:%d\n", __func__, init_table->Channel)); + return; + } + + COPY_MAC_ADDR(NeighborRepInfo.Bssid, pMbss->wdev.bssid); + CondensedPhyType = (pMbss->wdev.channel > 14)?9:7; /* 7:2G,9:5G */ + /* our own info */ + BssidInfo.word = 0; + BssidInfo.field.APReachAble = 3; + BssidInfo.field.Security = 1; /* rrm to do. */ + BssidInfo.field.KeyScope = 1; /* "report AP has same authenticator as the AP. */ + BssidInfo.field.SepctrumMng = (pMbss->CapabilityInfo & (1 << 8))?1:0; + BssidInfo.field.Qos = (pMbss->CapabilityInfo & (1 << 9))?1:0; + BssidInfo.field.APSD = (pMbss->CapabilityInfo & (1 << 11))?1:0; + BssidInfo.field.RRM = (pMbss->CapabilityInfo & RRM_CAP_BIT)?1:0; + BssidInfo.field.DelayBlockAck = (pMbss->CapabilityInfo & (1 << 14))?1:0; + BssidInfo.field.ImmediateBA = (pMbss->CapabilityInfo & (1 << 15))?1:0; + + NeighborRepInfo.BssidInfo = BssidInfo.word; + NeighborRepInfo.RegulatoryClass = get_regulatory_class(pAd, pMbss->wdev.channel, pMbss->wdev.PhyMode, &pMbss->wdev); + NeighborRepInfo.ChNum = pMbss->wdev.channel; + NeighborRepInfo.PhyType = CondensedPhyType; + + NdisCopyMemory(&init_table->NeighborRepInfo, &NeighborRepInfo, sizeof(RRM_NEIGHBOR_REP_INFO)); +} +#endif + +INT BndStrg_TableInit(PRTMP_ADAPTER pAd, INT apidx) +{ + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx]; + PBND_STRG_CLI_TABLE table = NULL, init_table = NULL; + INT i; + UINT8 Band, Channel; + + if (pMbss) { + Band = WMODE_CAP_5G(pMbss->wdev.PhyMode)?BAND_5G : BAND_24G; + Channel = pMbss->wdev.channel; + if (!Channel) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(),Invalid Channel:%d pMbss apidx:%d\n", __func__, Channel, apidx)); + return BND_STRG_UNEXP; + } + + } else { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Error in %s(), pMbss is NULL!\n", __func__)); + return BND_STRG_UNEXP; + } + + for (i = 0; i < DBDC_BAND_NUM; i++) { + table = P_BND_STRG_TABLE(i); + + if (!table->bInitialized && !init_table) { + init_table = table; + continue; + } + + if (table->bInitialized && (table->Channel == Channel)) + return BND_STRG_SUCCESS; + } + + if (init_table) { + NdisZeroMemory(init_table, sizeof(BND_STRG_CLI_TABLE)); + OS_NdisAllocateSpinLock(&init_table->Lock); + init_table->DaemonPid = 0xffffffff; + init_table->priv = (VOID *) pAd; + init_table->Band = Band; + init_table->Channel = Channel; + init_table->bInitialized = TRUE; +/* As in init time wdev may not be populated need to move when ap up complete */ +/* moved to BndStrg_SetInfFlags() function. */ +/* +#ifdef DOT11K_RRM_SUPPORT + BndStrg_InsertNeighborRepIE(pAd, init_table); +#endif +*/ + } + return BND_STRG_SUCCESS; +} + +INT BndStrg_Release(PRTMP_ADAPTER pAd) +{ + INT ret_val = BND_STRG_SUCCESS; + INT apidx; + PBND_STRG_CLI_TABLE table = NULL; + BSS_STRUCT *pMbss = NULL; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (YLW("%s()\n"), __func__)); + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + table = Get_BndStrgTable(pAd, apidx); + + if (table) { + pMbss = &pAd->ApCfg.MBSSID[apidx]; + BndStrg_SetInfFlags(pAd, &pMbss->wdev, table, FALSE); + } + } + + if (table) + BndStrg_TableRelease(table); + + return ret_val; +} + +INT BndStrg_TableRelease(PBND_STRG_CLI_TABLE table) +{ + INT ret_val = BND_STRG_SUCCESS; + + if (table->bInitialized == FALSE) + return BND_STRG_NOT_INITIALIZED; + + OS_NdisFreeSpinLock(&table->Lock); + table->bInitialized = FALSE; + + if (ret_val != BND_STRG_SUCCESS) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Error in %s(), error code = %d!\n", __func__, ret_val)); + } + return ret_val; +} + +INT BndStrg_InsertEntry( + PBND_STRG_CLI_TABLE table, + struct bnd_msg_cli_add *cli_add, + PBND_STRG_CLI_ENTRY *entry_out) +{ + INT i; + UCHAR HashIdx; + PBND_STRG_CLI_ENTRY entry = NULL, this_entry = NULL; + INT ret_val = BND_STRG_SUCCESS; + + if (table->Size >= BND_STRG_MAX_TABLE_SIZE) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s(): Table is full!\n", __func__)); + return BND_STRG_TABLE_FULL; + } + + NdisAcquireSpinLock(&table->Lock); + + for (i = 0; i < BND_STRG_MAX_TABLE_SIZE; i++) { + entry = &table->Entry[i]; + + /* pick up the first available vacancy*/ + if (entry->bValid == FALSE) { + NdisZeroMemory(entry, sizeof(BND_STRG_CLI_ENTRY)); + /* Fill Entry */ + RTMP_GetCurrentSystemTick(&entry->jiffies); + COPY_MAC_ADDR(entry->Addr, cli_add->Addr); + entry->TableIndex = cli_add->TableIndex; + entry->BndStrg_Sta_State = BNDSTRG_STA_INIT; + entry->bValid = TRUE; + break; + } + + entry = NULL; + } + + if (entry) { + /* add this MAC entry into HASH table */ + HashIdx = MAC_ADDR_HASH_INDEX(cli_add->Addr); + + if (table->Hash[HashIdx] == NULL) + table->Hash[HashIdx] = entry; + + else { + this_entry = table->Hash[HashIdx]; + + while (this_entry->pNext != NULL) + this_entry = this_entry->pNext; + + this_entry->pNext = entry; + } + + *entry_out = entry; + table->Size++; + } + + NdisReleaseSpinLock(&table->Lock); + return ret_val; +} + +INT BndStrg_DeleteEntry(PBND_STRG_CLI_TABLE table, PUCHAR pAddr, UINT32 Index) +{ + USHORT HashIdx; + PBND_STRG_CLI_ENTRY entry, pre_entry, this_entry; + INT ret_val = BND_STRG_SUCCESS; + + NdisAcquireSpinLock(&table->Lock); + + if (Index >= BND_STRG_MAX_TABLE_SIZE) { + if (pAddr == NULL) + return BND_STRG_INVALID_ARG; + + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + entry = table->Hash[HashIdx]; + + while (entry) { + if (MAC_ADDR_EQUAL(pAddr, entry->Addr)) { + /* this is the entry we're looking for */ + break; + } else + entry = entry->pNext; + } + + if (entry == NULL) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s(): Index=%u, %02x:%02x:%02x:%02x:%02x:%02x, Entry not found.\n", + __func__, Index, PRINT_MAC(pAddr))); + NdisReleaseSpinLock(&table->Lock); + return BND_STRG_INVALID_ARG; + } + } else { + entry = &table->Entry[Index]; + HashIdx = MAC_ADDR_HASH_INDEX(entry->Addr); + } + + if (entry->bValid) { + { + pre_entry = NULL; + this_entry = table->Hash[HashIdx]; + ASSERT(this_entry); + + if (this_entry != NULL) { + /* update Hash list*/ + do { + if (this_entry == entry) { + if (pre_entry == NULL) + table->Hash[HashIdx] = entry->pNext; + else + pre_entry->pNext = entry->pNext; + + break; + } + + pre_entry = this_entry; + this_entry = this_entry->pNext; + } while (this_entry); + } + /* not found !!!*/ + ASSERT(this_entry != NULL); + + NdisZeroMemory(entry->Addr, MAC_ADDR_LEN); + entry->pNext = NULL; + entry->bValid = FALSE; + table->Size--; + } + } else { + } + + NdisReleaseSpinLock(&table->Lock); + + return ret_val; +} + + +PBND_STRG_CLI_ENTRY BndStrg_TableLookup(PBND_STRG_CLI_TABLE table, PUCHAR pAddr) +{ + ULONG HashIdx; + BND_STRG_CLI_ENTRY *entry = NULL; + + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + entry = table->Hash[HashIdx]; + + while (entry && entry->bValid) { + if (MAC_ADDR_EQUAL(entry->Addr, pAddr)) + break; + else + entry = entry->pNext; + } + + return entry; +} + +BOOLEAN BndStrg_CheckConnectionReq( + PRTMP_ADAPTER pAd, + struct wifi_dev *wdev, + PUCHAR pSrcAddr, + MLME_QUEUE_ELEM * Elem, + PEER_PROBE_REQ_PARAM * ProbeReqParam) +{ + UINT8 FrameType = Elem->MsgType; + CHAR Rssi[4] = {0}; + PBND_STRG_CLI_TABLE table = Get_BndStrgTable(pAd, wdev->func_idx); + BNDSTRG_MSG msg = { 0 }; + struct bnd_msg_cli_event *cli_event = &msg.data.cli_event; + CHAR i, rssi_max; + PBND_STRG_CLI_ENTRY entry = NULL; + + if (!pAd->ApCfg.BndStrgBssIdx[wdev->func_idx]) + return TRUE; + + if (!table || !table->bEnabled) + return TRUE; + + /* send response to white listed clients*/ + if (table->WhiteEntryListSize > 0) { + for (i = 0; i < BND_STRG_MAX_WHITELIST_ENTRY; i++) { + if (memcmp(table->WhiteEntryList[i], pSrcAddr, MAC_ADDR_LEN) == 0) { + BND_STRG_PRINTQAMSG(table, pSrcAddr, ("BndStrg STA %02x:%02x:%02x:%02x:%02x:%02x whitelisted\n", PRINT_MAC(pSrcAddr))); + return TRUE; + } + } + } + + Rssi[0] = Elem->rssi_info.raw_rssi[0] ? ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_0) : 0; + Rssi[1] = Elem->rssi_info.raw_rssi[1] ? ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1) : 0; + Rssi[2] = Elem->rssi_info.raw_rssi[2] ? ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_2) : 0; + Rssi[3] = Elem->rssi_info.raw_rssi[3] ? ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_3) : 0; + +#ifdef DBDC_MODE + + if (pAd->CommonCfg.dbdc_mode) { + UCHAR band_idx = HcGetBandByWdev(wdev); + + if (band_idx == DBDC_BAND0) + rssi_max = pAd->dbdc_band0_rx_path; + else + rssi_max = pAd->dbdc_band1_rx_path; + } else +#endif + rssi_max = pAd->Antenna.field.RxPath; + + msg.Action = CLI_EVENT; + + if (WMODE_CAP_2G(wdev->PhyMode) && + wdev->channel <= 14) { + cli_event->Band = BAND_24G; + } + + if (WMODE_CAP_5G(wdev->PhyMode) && + wdev->channel > 14) + cli_event->Band = BAND_5G; + + cli_event->Channel = wdev->channel; + cli_event->FrameType = FrameType; + + if (FrameType == APMT2_PEER_PROBE_REQ) { + struct bnd_msg_cli_probe *cli_probe = &cli_event->data.cli_probe; + + if (ProbeReqParam->IsHtSupport && WMODE_CAP_N(wdev->PhyMode)) + cli_probe->bAllowStaConnectInHt = TRUE; + if (ProbeReqParam->IsVhtSupport && WMODE_CAP_AC(wdev->PhyMode)) + cli_probe->bVHTCapable = TRUE; + cli_probe->Nss = GetNssFromHTCapRxMCSBitmask(ProbeReqParam->RxMCSBitmask); + + memset(cli_probe->Rssi, 0x80, sizeof(cli_probe->Rssi)); + for (i = 0; i < rssi_max; i++) + cli_probe->Rssi[i] = Rssi[i]; + } else if (FrameType == APMT2_PEER_AUTH_REQ) { + struct bnd_msg_cli_auth *cli_auth = &cli_event->data.cli_auth; + + memset(cli_auth->Rssi, 0x80, sizeof(cli_auth->Rssi)); + for (i = 0; i < rssi_max; i++) + cli_auth->Rssi[i] = Rssi[i]; + } + COPY_MAC_ADDR(cli_event->Addr, pSrcAddr); + BndStrgSendMsg(pAd, &msg); + + /* check for backlist client, stop response for them */ + if (table->BndStrgBlackListSize > 0) { + for (i = 0; i < BND_STRG_MAX_BLACKLIST_ENTRY; i++) { + if (memcmp(table->BndStrgBlackList[i], pSrcAddr, MAC_ADDR_LEN) == 0) { + BND_STRG_PRINTQAMSG(table, pSrcAddr, ("BndStrg STA %02x:%02x:%02x:%02x:%02x:%02x blacklisted\n", PRINT_MAC(pSrcAddr))); + return FALSE; + } + } + } + + if (table->BndStrgMode == POST_CONNECTION_STEERING) { + return TRUE; + } + + entry = BndStrg_TableLookup(table, pSrcAddr); + + if (entry && (FrameType == APMT2_PEER_AUTH_REQ) && (entry->BndStrg_Sta_State == BNDSTRG_STA_ASSOC)) { + BND_STRG_PRINTQAMSG(table, pSrcAddr, + (RED("%s: (ch%d) check %s request failed. client's (%02x:%02x:%02x:%02x:%02x:%02x) request is ignored. Client disconnected without DeAuth.!!Waiting for bndstrg result!!\n" + ), (table->Band == BAND_24G ? "2.4G" : "5G"), table->Channel, "Auth", PRINT_MAC(pSrcAddr))); + return FALSE; + } + + if (entry) { +#ifdef BND_STRG_QA + BND_STRG_PRINTQAMSG(table, pSrcAddr, + (GRN("%s: (ch%d) check %s request ok. client's (%02x:%02x:%02x:%02x:%02x:%02x) request is accepted.\n" + ), (table->Band == BAND_24G ? "2.4G" : "5G"), table->Channel, + FrameType == 0 ? ("probe") : (FrameType == 3 ? "auth" : "unknow"), PRINT_MAC(pSrcAddr))); +#endif + return TRUE; + } else { +#ifdef BND_STRG_QA + BND_STRG_PRINTQAMSG(table, pSrcAddr, + (RED("%s: (ch%d) check %s request failed. client's (%02x:%02x:%02x:%02x:%02x:%02x) request is ignored.\n" + ), (table->Band == BAND_24G ? "2.4G" : "5G"), table->Channel, + FrameType == 0 ? ("probe") : (FrameType == 3 ? "auth" : "unknow"), PRINT_MAC(pSrcAddr))); +#endif + return FALSE; + } + return TRUE; +} + +INT BndStrg_Tbl_Enable(PBND_STRG_CLI_TABLE table, BOOLEAN enable, CHAR *IfName) +{ + BNDSTRG_MSG msg = { 0 }; + PRTMP_ADAPTER pAd = NULL; + struct bnd_msg_onoff *onoff = &msg.data.onoff; + + if (table == NULL) + return BND_STRG_TABLE_IS_NULL; + + if (table->bInitialized == FALSE) + return BND_STRG_NOT_INITIALIZED; + + if (!(table->bEnabled ^ enable)) { + /* Already enabled/disabled */ + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, /* TRACE */ + (GRN("%s(): Band steering is already %s.\n"), + __func__, (enable ? "enabled" : "disabled"))); + return BND_STRG_SUCCESS; + } + + if (enable) { + table->bEnabled = TRUE; + strncpy(table->ucIfName, IfName, sizeof(table->ucIfName)); /* decide it by daemon */ + } else + table->bEnabled = FALSE; + + pAd = (PRTMP_ADAPTER) table->priv; + msg.Action = BNDSTRG_ONOFF; + onoff->OnOff = table->bEnabled; + onoff->Band = table->Band; + onoff->Channel = table->Channel; + strncpy(onoff->ucIfName, IfName, sizeof(onoff->ucIfName)); + RtmpOSWrielessEventSend( + pAd->net_dev, + RT_WLAN_EVENT_CUSTOM, + OID_BNDSTRG_MSG, + NULL, + (UCHAR *)&msg, + sizeof(msg)); + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (GRN("%s(): Band steering %s running.\n"), + __func__, (enable ? "start" : "stop"))); + return BND_STRG_SUCCESS; +} + +INT BndStrgSendMsg( + PRTMP_ADAPTER pAd, + BNDSTRG_MSG *msg) +{ + return RtmpOSWrielessEventSend( + pAd->net_dev, + RT_WLAN_EVENT_CUSTOM, + OID_BNDSTRG_MSG, + NULL, + (UCHAR *) msg, + sizeof(BNDSTRG_MSG)); +} + +INT BndStrg_SetInfFlags( + PRTMP_ADAPTER pAd, + struct wifi_dev *wdev, + PBND_STRG_CLI_TABLE table, + BOOLEAN bInfReady) +{ + INT ret_val = BND_STRG_SUCCESS; + UINT8 Band; + BNDSTRG_MSG msg = { 0 }; + struct bnd_msg_inf_status_rsp *inf_status_rsp = &msg.data.inf_status_rsp; + + if (!wdev) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): wdev is NULL!\n", __func__)); + return BND_STRG_UNEXP; + } + + if (!wdev->if_dev) { + /* inf down up issue*/ + wdev->bInfReady = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): if_dev is NULL!\n", __func__)); + return BND_STRG_UNEXP; + } + + if (!IS_VALID_MAC(wdev->bssid)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(): Invalid bssid(%02x:%02x:%02x:%02x:%02x:%02x)!\n", __func__, PRINT_MAC(wdev->bssid))); + return BND_STRG_UNEXP; + } + + Band = WMODE_CAP_5G(wdev->PhyMode)?BAND_5G : BAND_24G; + + if (!(wdev->bInfReady^bInfReady)) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (GRN("%s(): %s [%d] Inf %s Band steering is already %s.\n"), __func__, + (IS_5G_BAND(Band) ? "5G" : "2G"), wdev->channel, wdev->if_dev->name, + (bInfReady ? "up" : "down"))); + return BND_STRG_SUCCESS; + } + + if (bInfReady) { /* Exec. by each interface up */ + table->uIdx = wdev->func_idx; + /* table->Channel = wdev->channel; */ + + if (WMODE_CAP_5G(wdev->PhyMode) && WMODE_CAP_AC(wdev->PhyMode)) + table->bVHTCapable = TRUE; + else + table->bVHTCapable = FALSE; + + table->ActiveCount++; +/* Add Neighbor report*/ +#ifdef DOT11K_RRM_SUPPORT + BndStrg_InsertNeighborRepIE(pAd, table); +#endif + } else { /* Exec. by each interface down */ + if (table->ActiveCount > 0) + table->ActiveCount--; + } + + wdev->bInfReady = bInfReady; + + table->nss = wlan_config_get_tx_stream(wdev); + msg.Action = INF_STATUS_RSP; + + inf_status_rsp->band = Band; + inf_status_rsp->bInfReady = bInfReady; + inf_status_rsp->Channel = wdev->channel; + inf_status_rsp->bVHTCapable = table->bVHTCapable; + inf_status_rsp->nss = table->nss; + inf_status_rsp->table_src_addr = (ULONG)table; + inf_status_rsp->table_size = BND_STRG_MAX_TABLE_SIZE; + strncpy(inf_status_rsp->ucIfName, wdev->if_dev->name, sizeof(inf_status_rsp->ucIfName)); +#ifdef VENDOR_FEATURE5_SUPPORT + inf_status_rsp->nvram_support = 1; +#else + inf_status_rsp->nvram_support = 0; +#endif + BndStrgSendMsg(pAd, &msg); + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + (BLUE("%s(): BSS(%02X:%02X:%02X:%02X:%02X:%02X)") + BLUE(" set %s Inf %s %s.\n"), __func__, + PRINT_MAC(wdev->bssid), IS_5G_BAND(Band) ? "5G" : "2G", + wdev->if_dev->name, bInfReady ? "ready" : "not ready")); + + if (table->bInfReady ^ bInfReady) { + if (bInfReady) { + table->bInfReady = TRUE; + table->Band |= Band; + } else { + if (!bInfReady && (table->ActiveCount == 0)) { + table->bInfReady = FALSE; + + if (table->bEnabled) + BndStrg_Tbl_Enable(table, FALSE, table->ucIfName); + } + } + } + + return ret_val; +} + +void BndStrg_UpdateEntry(PRTMP_ADAPTER pAd, + MAC_TABLE_ENTRY *pEntry, + IE_LISTS *ie_list, + BOOLEAN bConnStatus) +{ + struct wifi_dev *wdev; + BNDSTRG_MSG msg = { 0 }; + struct bnd_msg_cli_event *cli_event = &msg.data.cli_event; + UINT8 Nss = 1; + UINT32 RxMCSBitmask = 0; + PBND_STRG_CLI_ENTRY entry = NULL; + PBND_STRG_CLI_TABLE table = NULL; + + if (!pEntry || !pEntry->wdev || (pAd->ApCfg.BndStrgBssIdx[pEntry->func_tb_idx] != 1)) + return; + + table = Get_BndStrgTable(pAd, pEntry->wdev->func_idx); + + if (!table) + return; + + wdev = pEntry->wdev; + + if (WMODE_CAP_5G(wdev->PhyMode)) + cli_event->Band = BAND_5G; + else + cli_event->Band = BAND_24G; + + cli_event->Channel = wdev->channel; + COPY_MAC_ADDR(cli_event->Addr, pEntry->Addr); + msg.Action = CLI_EVENT; + + if (bConnStatus) { + struct bnd_msg_cli_assoc *cli_assoc = &cli_event->data.cli_assoc; + + cli_event->FrameType = APMT2_PEER_ASSOC_REQ; + if (ie_list->ht_cap_len > 0) { + cli_assoc->bAllowStaConnectInHt = TRUE; + RxMCSBitmask = *(UINT32 *)(ie_list->HTCapability.MCSSet); + Nss = GetNssFromHTCapRxMCSBitmask(RxMCSBitmask); + } + if (ie_list->vht_cap_len > 0) + cli_assoc->bVHTCapable = TRUE; + cli_assoc->Nss = Nss; +#ifdef CONFIG_DOT11V_WNM + cli_assoc->BTMSupport = pEntry->BssTransitionManmtSupport; +#endif + } else { + cli_event->FrameType = APMT2_PEER_DISASSOC_REQ; + } + + BndStrgSendMsg(pAd, &msg); + entry = BndStrg_TableLookup(table, pEntry->Addr); + + if (entry) { + if (bConnStatus) + entry->BndStrg_Sta_State = BNDSTRG_STA_ASSOC; + else + entry->BndStrg_Sta_State = BNDSTRG_STA_DISASSOC; + entry->bConnStatus = bConnStatus; + } + return; +} + +INT Set_BndStrg_BssIdx( + PRTMP_ADAPTER pAd, + RTMP_STRING *arg) +{ + UINT8 i; + RTMP_STRING *macptr; + + for (i = 0, macptr = rstrtok(arg, ";"); macptr; macptr = rstrtok(NULL, ";"), i++) { + pAd->ApCfg.BndStrgBssIdx[i] = simple_strtoul(macptr, 0, 10); + } + + return TRUE; +} + +#ifdef VENDOR_FEATURE5_SUPPORT +INT Show_BndStrg_NvramTable( + PRTMP_ADAPTER pAd, + RTMP_STRING *arg) +{ + PBND_STRG_CLI_TABLE table; + POS_COOKIE pObj; + UCHAR ifIndex; + PBNDSTRG_NVRAM_CLIENT table_nvram_client; + int i; + char PhyMode[10]; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + table = Get_BndStrgTable(pAd, ifIndex); + + if (!table) + return FALSE; + + printk("%s bndstrg_nvram_client_count %d\n", __func__, table->bndstrg_nvram_client_count); + printk("Addr Band\tPhymde\t\t\t\tNSS\tManipulable\n"); + + for (i = 0; i < table->bndstrg_nvram_client_count; i++) { + table_nvram_client = &table->nvram_entry[i]; + memset(PhyMode, 0x00, 10); + + if (table_nvram_client->PhyMode == fPhyMode_Legacy) + sprintf(PhyMode, "%s", "Legacy"); + else if (table_nvram_client->PhyMode == fPhyMode_HT) + sprintf(PhyMode, "%s", "11n"); + else if (table_nvram_client->PhyMode == fPhyMode_VHT) + sprintf(PhyMode, "%s", "11ac"); + + printk("%02x:%02x:%02x:%02x:%02x:%02x \t%-3s\t%-20s\t\t%d\t%s\n", PRINT_MAC(table_nvram_client->Addr), + (IS_5G_BAND(table_nvram_client->Band) ? "5G":"2G"), PhyMode, table_nvram_client->Nss, (table_nvram_client->Manipulable ? "YES":"NO")); + } + return TRUE; +} + +static BOOLEAN BndStrg_NvramTableLookup(PBND_STRG_CLI_TABLE table, unsigned char *pAddr) +{ + int i; + + for (i = 0; i < NVRAM_TABLE_SIZE; i++) { + if (MAC_ADDR_EQUAL(table->nvram_entry[i].Addr, pAddr)) + return TRUE; + } + return FALSE; +} + +static BOOLEAN BndStrg_NvramInsertEntry(PBND_STRG_CLI_TABLE table, PBNDSTRG_NVRAM_CLIENT msg) +{ + PBNDSTRG_NVRAM_CLIENT nvram_entry = NULL; + int i = 0; + + if (!BndStrg_NvramTableLookup(table, msg->Addr)) { + if (table->bndstrg_nvram_client_count < NVRAM_TABLE_SIZE) { + nvram_entry = &table->nvram_entry[table->bndstrg_nvram_client_count]; + memset(nvram_entry, 0, sizeof(BNDSTRG_NVRAM_CLIENT)); + memcpy(nvram_entry->Addr, msg->Addr, MAC_ADDR_LEN); + table->bndstrg_nvram_client_count++; + } + } else { + for (i = 0; i < table->bndstrg_nvram_client_count; i++) { + if (MAC_ADDR_EQUAL(table->nvram_entry[i].Addr, msg->Addr)) + break; + } + + nvram_entry = &table->nvram_entry[i]; + } + + if (nvram_entry) { + nvram_entry->Band = msg->Band; + nvram_entry->Nss = msg->Nss; + nvram_entry->Manipulable = msg->Manipulable; + nvram_entry->PhyMode = msg->PhyMode; + } else { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: nvram_entry is NULL!\n", __func__)); + return FALSE; + } + + return TRUE; +} + +void BndStrg_SetNvram(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, INT apidx) +{ + BNDSTRG_NVRAM_CLIENT bsdmsg; + PBND_STRG_CLI_TABLE table = NULL; + BNDSTRG_MSG msg = { 0 }; + struct bnd_msg_nvram_entry_update *entry_update = &msg.data.entry_update; + INT Status; + + table = Get_BndStrgTable(pAd, apidx); + + if (!table || + (table->bInitialized == FALSE) || + (wrq->u.data.length != sizeof(BNDSTRG_NVRAM_CLIENT))) + return; + + Status = copy_from_user(&bsdmsg, wrq->u.data.pointer, wrq->u.data.length); + + if ((BndStrg_NvramInsertEntry(table, &bsdmsg))) { + msg.Action = NVRAM_UPDATE; + memcpy(entry_update->nvram_entry.Addr, bsdmsg.Addr, MAC_ADDR_LEN); + memcpy(entry_update->Addr, bsdmsg.Addr, MAC_ADDR_LEN); + entry_update->nvram_entry.Band = bsdmsg.Band; + entry_update->nvram_entry.Manipulable = bsdmsg.Manipulable; + entry_update->nvram_entry.Nss = bsdmsg.Nss; + entry_update->nvram_entry.PhyMode = bsdmsg.PhyMode; + BndStrgSendMsg(pAd, &msg); + } else + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: NVRAM table full\n", __func__)); +} + +void BndStrg_GetNvram(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, INT apidx) +{ + PBND_STRG_CLI_TABLE table = NULL; + BNDSTRG_NVRAM_LIST *nvram_list = NULL; + PBNDSTRG_NVRAM_CLIENT nvram_client; + PBNDSTRG_NVRAM_CLIENT table_nvram_client; + int i; + + table = Get_BndStrgTable(pAd, apidx); + + if (!table || + (table->bInitialized == FALSE)) + return; + + os_alloc_mem(pAd, (UCHAR **)&nvram_list, sizeof(BNDSTRG_NVRAM_LIST)); + + if (nvram_list == NULL) + return; + + NdisZeroMemory(nvram_list, sizeof(BNDSTRG_NVRAM_LIST)); + nvram_list->Num = table->bndstrg_nvram_client_count; + + for (i = 0; i < nvram_list->Num; i++) { + table_nvram_client = &table->nvram_entry[i]; + nvram_client = &nvram_list->nvram_entry[i]; + memcpy(nvram_client->Addr, table_nvram_client->Addr, MAC_ADDR_LEN); + nvram_client->Band = table_nvram_client->Band; + nvram_client->Manipulable = table_nvram_client->Manipulable; + nvram_client->PhyMode = table_nvram_client->PhyMode; + nvram_client->Nss = table_nvram_client->Nss; + } + + wrq->u.data.length = sizeof(BNDSTRG_NVRAM_LIST); + copy_to_user(wrq->u.data.pointer, nvram_list, wrq->u.data.length); + + if (nvram_list != NULL) + os_free_mem(nvram_list); + + return; +} +#endif /* VENDOR_FEATURE5_SUPPORT */ + +UINT8 GetNssFromHTCapRxMCSBitmask(UINT32 RxMCSBitmask) +{ + UCHAR RxMCS[4]; + UINT8 nss; + *((UINT32 *)RxMCS) = RxMCSBitmask; + + if (RxMCS[3] != 0) + nss = 4; + else if (RxMCS[2] != 0) + nss = 3; + else if (RxMCS[1] != 0) + nss = 2; + else + nss = 1; + + return nss; +} + +VOID BndStrg_CLIStatusRsp(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table, BNDSTRG_MSG *msg) +{ + if (table->bInitialized == TRUE) { + BNDSTRG_MSG new_msg = { 0 }; + struct bnd_msg_cli_status_rsp *cli_status_rsp = &new_msg.data.cli_status_rsp; + MAC_TABLE_ENTRY *pEntry = NULL; + PBND_STRG_CLI_ENTRY entry = NULL; + int i = 0; + /* Send to daemon */ + new_msg.Action = CLI_STATUS_RSP; + memset(cli_status_rsp, 0x00, sizeof(struct bnd_msg_cli_status_rsp)); + + for (i = 0; i < BND_STRG_MAX_TABLE_SIZE; i++) { + entry = &table->Entry[i]; + + /* pick up the first available vacancy*/ + if (!entry || entry->bValid == FALSE || !entry->bConnStatus) + continue; + + cli_status_rsp->TableIndex = entry->TableIndex; + pEntry = MacTableLookup(pAd, entry->Addr); + + if (pEntry && IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC) && (pEntry->pMbss != NULL)) { + INT32 avgrssi = 0; + /* get information */ + /* RSSI */ + /* avgrssi = RTMPAvgRssi(pAd, &pEntry->RssiSample); */ + { +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + if (cap->fgRateAdaptFWOffload == TRUE && (pEntry->bAutoTxRateSwitch == TRUE)) { + ULONG DataRate = 0; + ULONG DataRate_r = 0; + UCHAR phy_mode, rate, bw, sgi, stbc; + UCHAR phy_mode_r, rate_r, bw_r, sgi_r, stbc_r; +#ifdef DOT11_VHT_AC + UCHAR vht_nss; + UCHAR vht_nss_r; +#endif + UINT32 RawData; + UINT32 RawData_r; + UINT32 lastTxRate = pEntry->LastTxRate; + UINT32 lastRxRate = pEntry->LastRxRate; + + if (pEntry->bAutoTxRateSwitch == TRUE) { + EXT_EVENT_TX_STATISTIC_RESULT_T rTxStatResult; + HTTRANSMIT_SETTING LastTxRate; + HTTRANSMIT_SETTING LastRxRate; + + MtCmdGetTxStatistic(pAd, GET_TX_STAT_ENTRY_TX_RATE, 0/*Don't Care*/, pEntry->wcid, &rTxStatResult); + LastTxRate.field.MODE = rTxStatResult.rEntryTxRate.MODE; + LastTxRate.field.BW = rTxStatResult.rEntryTxRate.BW; + LastTxRate.field.ldpc = rTxStatResult.rEntryTxRate.ldpc ? 1:0; + LastTxRate.field.ShortGI = rTxStatResult.rEntryTxRate.ShortGI ? 1:0; + LastTxRate.field.STBC = rTxStatResult.rEntryTxRate.STBC; + + if (LastTxRate.field.MODE == MODE_VHT) + LastTxRate.field.MCS = (((rTxStatResult.rEntryTxRate.VhtNss - 1) & 0x3) << 4) + rTxStatResult.rEntryTxRate.MCS; + else if (LastTxRate.field.MODE == MODE_OFDM) + LastTxRate.field.MCS = getLegacyOFDMMCSIndex(rTxStatResult.rEntryTxRate.MCS) & 0x0000003F; + else + LastTxRate.field.MCS = rTxStatResult.rEntryTxRate.MCS; + + lastTxRate = (UINT32)(LastTxRate.word); + LastRxRate.word = (USHORT)lastRxRate; + RawData = lastTxRate; + phy_mode = (RawData>>13) & 0x7; + rate = RawData & 0x3F; + bw = (RawData>>7) & 0x3; + sgi = (RawData>>9) & 0x1; + stbc = ((RawData>>10) & 0x1); + /* ---- */ + RawData_r = lastRxRate; + phy_mode_r = (RawData_r>>13) & 0x7; + rate_r = RawData_r & 0x3F; + bw_r = (RawData_r>>7) & 0x3; + sgi_r = (RawData_r>>9) & 0x1; + stbc_r = ((RawData_r>>10) & 0x1); +#ifdef DOT11_VHT_AC + + if (phy_mode == MODE_VHT) { + vht_nss = ((rate & (0x3 << 4)) >> 4) + 1; + rate = rate & 0xF; + /* snprintf(tmp_str,temp_str_len,"%dS-M%d/",vht_nss, rate); */ + } else +#endif /* DOT11_VHT_AC */ + { + /* snprintf(tmp_str,temp_str_len,"%d/",rate); */ + } + +#ifdef DOT11_VHT_AC + + if (phy_mode_r == MODE_VHT) { + vht_nss_r = ((rate_r & (0x3 << 4)) >> 4) + 1; + rate_r = rate_r & 0xF; + /* snprintf(tmp_str+strlen(tmp_str),temp_str_len-strlen(tmp_str),"%dS-M%d",vht_nss_r, rate_r); */ + } else +#endif /* DOT11_VHT_AC */ +#if DOT11_N_SUPPORT + if (phy_mode_r >= MODE_HTMIX) { + /* snprintf(tmp_str+strlen(tmp_str),temp_str_len-strlen(tmp_str),"%d",rate_r); */ + } else +#endif + if (phy_mode_r == MODE_OFDM) { + if (rate_r == TMI_TX_RATE_OFDM_6M) + LastRxRate.field.MCS = 0; + else if (rate_r == TMI_TX_RATE_OFDM_9M) + LastRxRate.field.MCS = 1; + else if (rate_r == TMI_TX_RATE_OFDM_12M) + LastRxRate.field.MCS = 2; + else if (rate_r == TMI_TX_RATE_OFDM_18M) + LastRxRate.field.MCS = 3; + else if (rate_r == TMI_TX_RATE_OFDM_24M) + LastRxRate.field.MCS = 4; + else if (rate_r == TMI_TX_RATE_OFDM_36M) + LastRxRate.field.MCS = 5; + else if (rate_r == TMI_TX_RATE_OFDM_48M) + LastRxRate.field.MCS = 6; + else if (rate_r == TMI_TX_RATE_OFDM_54M) + LastRxRate.field.MCS = 7; + else + LastRxRate.field.MCS = 0; + + /* snprintf(tmp_str+strlen(tmp_str),temp_str_len-strlen(tmp_str),"%d",LastRxRate.field.MCS); */ + } else if (phy_mode_r == MODE_CCK) { + if (rate_r == TMI_TX_RATE_CCK_1M_LP) + LastRxRate.field.MCS = 0; + else if (rate_r == TMI_TX_RATE_CCK_2M_LP) + LastRxRate.field.MCS = 1; + else if (rate_r == TMI_TX_RATE_CCK_5M_LP) + LastRxRate.field.MCS = 2; + else if (rate_r == TMI_TX_RATE_CCK_11M_LP) + LastRxRate.field.MCS = 3; + else if (rate_r == TMI_TX_RATE_CCK_2M_SP) + LastRxRate.field.MCS = 1; + else if (rate_r == TMI_TX_RATE_CCK_5M_SP) + LastRxRate.field.MCS = 2; + else if (rate_r == TMI_TX_RATE_CCK_11M_SP) + LastRxRate.field.MCS = 3; + else + LastRxRate.field.MCS = 0; + + /* snprintf(tmp_str+strlen(tmp_str),temp_str_len-strlen(tmp_str),"%d",LastRxRate.field.MCS); */ + } + + getRate(LastTxRate, &DataRate); + getRate(LastRxRate, &DataRate_r); + cli_status_rsp->data_tx_Rate = DataRate; + cli_status_rsp->data_rx_Rate = DataRate_r; + cli_status_rsp->data_tx_Phymode = phy_mode; + cli_status_rsp->data_rx_Phymode = phy_mode_r; + + if (LastTxRate.field.MODE >= MODE_VHT) { + cli_status_rsp->data_tx_mcs = LastTxRate.field.MCS & 0xf; + cli_status_rsp->data_tx_ant = (LastTxRate.field.MCS>>4) + 1; + } else if (LastTxRate.field.MODE >= MODE_HTMIX) { + cli_status_rsp->data_tx_mcs = LastTxRate.field.MCS; + cli_status_rsp->data_tx_ant = (LastTxRate.field.MCS >> 3)+1; + + if (cli_status_rsp->data_tx_mcs > 7) + cli_status_rsp->data_tx_mcs %= 8; + } else if (LastTxRate.field.MODE >= MODE_OFDM) { + cli_status_rsp->data_tx_mcs = LastTxRate.field.MCS; + cli_status_rsp->data_tx_ant = 1; + } else if (LastTxRate.field.MODE >= MODE_CCK) { + cli_status_rsp->data_tx_mcs = LastTxRate.field.MCS; + cli_status_rsp->data_tx_ant = 1; + } + + if (LastRxRate.field.MODE >= MODE_VHT) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS & 0xf; + cli_status_rsp->data_rx_ant = (LastRxRate.field.MCS>>4) + 1; + } else if (LastRxRate.field.MODE >= MODE_HTMIX) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS; + cli_status_rsp->data_rx_ant = (LastRxRate.field.MCS >> 3)+1; + + if (cli_status_rsp->data_rx_mcs > 7) + cli_status_rsp->data_rx_mcs %= 8; + } else if (LastRxRate.field.MODE >= MODE_OFDM) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS; + cli_status_rsp->data_rx_ant = 1; + } else if (LastRxRate.field.MODE >= MODE_CCK) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS; + cli_status_rsp->data_rx_ant = 1; + } + + cli_status_rsp->data_tx_bw = LastTxRate.field.BW; + cli_status_rsp->data_rx_bw = LastRxRate.field.BW; + cli_status_rsp->data_tx_sgi = LastTxRate.field.ShortGI; + cli_status_rsp->data_rx_sgi = LastRxRate.field.ShortGI; + cli_status_rsp->data_tx_stbc = LastTxRate.field.STBC; + cli_status_rsp->data_rx_stbc = LastRxRate.field.STBC; + cli_status_rsp->data_tx_packets = pEntry->TxPackets.QuadPart; + cli_status_rsp->data_rx_packets = pEntry->RxPackets.QuadPart; + } + } else +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + { + ULONG DataRate = 0; + ULONG DataRate_r = 0; + UINT32 lastRxRate = pEntry->LastRxRate; + HTTRANSMIT_SETTING LastRxRate; + UCHAR phy_mode_r, rate_r; + + LastRxRate.word = (USHORT)lastRxRate; + phy_mode_r = LastRxRate.field.MODE; + rate_r = LastRxRate.word & 0x3F; + + if (phy_mode_r == MODE_OFDM) { + if (rate_r == TMI_TX_RATE_OFDM_6M) + LastRxRate.field.MCS = 0; + else if (rate_r == TMI_TX_RATE_OFDM_9M) + LastRxRate.field.MCS = 1; + else if (rate_r == TMI_TX_RATE_OFDM_12M) + LastRxRate.field.MCS = 2; + else if (rate_r == TMI_TX_RATE_OFDM_18M) + LastRxRate.field.MCS = 3; + else if (rate_r == TMI_TX_RATE_OFDM_24M) + LastRxRate.field.MCS = 4; + else if (rate_r == TMI_TX_RATE_OFDM_36M) + LastRxRate.field.MCS = 5; + else if (rate_r == TMI_TX_RATE_OFDM_48M) + LastRxRate.field.MCS = 6; + else if (rate_r == TMI_TX_RATE_OFDM_54M) + LastRxRate.field.MCS = 7; + else + LastRxRate.field.MCS = 0; + } else if (phy_mode_r == MODE_CCK) { + if (rate_r == TMI_TX_RATE_CCK_1M_LP) + LastRxRate.field.MCS = 0; + else if (rate_r == TMI_TX_RATE_CCK_2M_LP) + LastRxRate.field.MCS = 1; + else if (rate_r == TMI_TX_RATE_CCK_5M_LP) + LastRxRate.field.MCS = 2; + else if (rate_r == TMI_TX_RATE_CCK_11M_LP) + LastRxRate.field.MCS = 3; + else if (rate_r == TMI_TX_RATE_CCK_2M_SP) + LastRxRate.field.MCS = 1; + else if (rate_r == TMI_TX_RATE_CCK_5M_SP) + LastRxRate.field.MCS = 2; + else if (rate_r == TMI_TX_RATE_CCK_11M_SP) + LastRxRate.field.MCS = 3; + else + LastRxRate.field.MCS = 0; + } + + getRate(pEntry->HTPhyMode, &DataRate); + getRate(LastRxRate, &DataRate_r); + cli_status_rsp->data_tx_Rate = DataRate; + cli_status_rsp->data_rx_Rate = DataRate_r; + cli_status_rsp->data_tx_Phymode = pEntry->HTPhyMode.field.MODE; + cli_status_rsp->data_rx_Phymode = 0; + + if (pEntry->HTPhyMode.field.MODE >= MODE_VHT) { + cli_status_rsp->data_tx_mcs = (pEntry->HTPhyMode.field.MCS & 0xf); + cli_status_rsp->data_tx_ant = (pEntry->HTPhyMode.field.MCS>>4) + 1; + } else if (pEntry->HTPhyMode.field.MODE >= MODE_HTMIX) { + cli_status_rsp->data_tx_mcs = pEntry->HTPhyMode.field.MCS; + cli_status_rsp->data_tx_ant = (pEntry->HTPhyMode.field.MCS >> 3)+1; + + if (cli_status_rsp->data_tx_mcs > 7) + cli_status_rsp->data_tx_mcs %= 8; + } else if (pEntry->HTPhyMode.field.MODE >= MODE_OFDM) { + cli_status_rsp->data_tx_mcs = pEntry->HTPhyMode.field.MCS; + cli_status_rsp->data_tx_ant = 1; + } else if (pEntry->HTPhyMode.field.MODE >= MODE_CCK) { + cli_status_rsp->data_tx_mcs = pEntry->HTPhyMode.field.MCS; + cli_status_rsp->data_tx_ant = 1; + } + + if (LastRxRate.field.MODE >= MODE_VHT) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS & 0xf; + cli_status_rsp->data_rx_ant = (LastRxRate.field.MCS>>4) + 1; + } else if (LastRxRate.field.MODE >= MODE_HTMIX) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS; + cli_status_rsp->data_rx_ant = (LastRxRate.field.MCS >> 3)+1; + + if (cli_status_rsp->data_rx_mcs > 7) + cli_status_rsp->data_rx_mcs %= 8; + } else if (LastRxRate.field.MODE >= MODE_OFDM) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS; + cli_status_rsp->data_rx_ant = 1; + } else if (LastRxRate.field.MODE >= MODE_CCK) { + cli_status_rsp->data_rx_mcs = LastRxRate.field.MCS; + cli_status_rsp->data_rx_ant = 1; + } + + cli_status_rsp->data_tx_bw = pEntry->HTPhyMode.field.BW; + cli_status_rsp->data_rx_bw = LastRxRate.field.BW; + cli_status_rsp->data_tx_sgi = pEntry->HTPhyMode.field.ShortGI; + cli_status_rsp->data_rx_sgi = LastRxRate.field.ShortGI; + cli_status_rsp->data_tx_stbc = pEntry->HTPhyMode.field.STBC; + cli_status_rsp->data_rx_stbc = LastRxRate.field.STBC; + cli_status_rsp->data_tx_packets = pEntry->TxPackets.QuadPart; + cli_status_rsp->data_rx_packets = pEntry->RxPackets.QuadPart; + } + } + /* Calculate Avg data RSSI */ + { + INT rssi_tmp = 0, i = 0; + UINT32 rx_stream; + + if (pAd->CommonCfg.dbdc_mode) + rx_stream = 2; + else + rx_stream = pAd->Antenna.field.RxPath; + + for (i = 0; i < rx_stream; i++) + rssi_tmp += pEntry->RssiSample.AvgRssi[i]; + + avgrssi = (CHAR)(rssi_tmp/rx_stream); + } + cli_status_rsp->data_Rssi = (char)avgrssi; + /* cli_status_rsp->data_tx_TP = pEntry->AvgTxBytes >> 17; //Mbps */ + /* cli_status_rsp->data_rx_TP = pEntry->AvgRxBytes >> 17; //Mbps */ + cli_status_rsp->data_tx_Byte = pEntry->AvgTxBytes; + cli_status_rsp->data_rx_Byte = pEntry->AvgRxBytes; + memcpy(cli_status_rsp->Addr, entry->Addr, MAC_ADDR_LEN); + cli_status_rsp->ReturnCode = BND_STRG_SUCCESS; + BndStrgSendMsg(pAd, &new_msg); + } + } + } + + return; +} + +VOID BndStrg_ChannelLoadStatusRsp(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table, BNDSTRG_MSG *msg) +{ + if (table->bInitialized == TRUE) { + BNDSTRG_MSG new_msg = { 0 }; + struct bnd_msg_chanload_status_rsp *chanload_status_rsp = &new_msg.data.chanload_status_rsp; + /* Send to daemon */ + new_msg.Action = CHANLOAD_STATUS_RSP; + chanload_status_rsp->ReturnCode = BND_STRG_SUCCESS; + chanload_status_rsp->band = table->Band; + chanload_status_rsp->Channel = table->Channel; + { + UINT32 ChanBusyTime[DBDC_BAND_NUM] = {0}; + UINT32 ObssAirTime[DBDC_BAND_NUM] = {0}; + UINT32 MyTxAirTime[DBDC_BAND_NUM] = {0}; + UINT32 MyRxAirTime[DBDC_BAND_NUM] = {0}; + UINT32 EDCCATime[DBDC_BAND_NUM] = {0}; + UCHAR ChanBusyOccupyPercentage[DBDC_BAND_NUM] = {0}; + UCHAR ObssAirOccupyPercentage[DBDC_BAND_NUM] = {0}; + UCHAR MyAirOccupyPercentage[DBDC_BAND_NUM] = {0}; + UCHAR MyTxAirOccupyPercentage[DBDC_BAND_NUM] = {0}; + UCHAR MyRxAirOccupyPercentage[DBDC_BAND_NUM] = {0}; + UCHAR EdccaOccupyPercentage[DBDC_BAND_NUM] = {0}; + UCHAR i; + + i = HcGetBandByChannel(pAd, table->Channel); + ChanBusyTime[i] = pAd->OneSecMibBucket.ChannelBusyTime[i]; + ObssAirTime[i] = Get_OBSS_AirTime(pAd, i); + MyTxAirTime[i] = Get_My_Tx_AirTime(pAd, i); + MyRxAirTime[i] = Get_My_Rx_AirTime(pAd, i); + EDCCATime[i] = Get_EDCCA_Time(pAd, i); + + if (ChanBusyTime[i] != 0) + ChanBusyOccupyPercentage[i] = (ChanBusyTime[i]*100)/ONE_SEC_2_US; + + if (ObssAirTime[i] != 0) + ObssAirOccupyPercentage[i] = (ObssAirTime[i]*100)/ONE_SEC_2_US; + + if (MyTxAirTime[i] != 0 || MyRxAirTime[i] != 0) + MyAirOccupyPercentage[i] = ((MyTxAirTime[i] + MyRxAirTime[i]) * 100)/ONE_SEC_2_US; + + if (MyTxAirTime[i] != 0) + MyTxAirOccupyPercentage[i] = (MyTxAirTime[i] * 100) / ONE_SEC_2_US; + + if (MyRxAirTime[i] != 0) + MyRxAirOccupyPercentage[i] = (MyRxAirTime[i] * 100) / ONE_SEC_2_US; + + if (EDCCATime[i] != 0) + EdccaOccupyPercentage[i] = (EDCCATime[i] * 100) / ONE_SEC_2_US; + + chanload_status_rsp->chanload = MyAirOccupyPercentage[i] + ObssAirOccupyPercentage[i]; + } + BndStrgSendMsg(pAd, &new_msg); + } +} + +VOID BndStrg_InfStatusRsp(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table, BNDSTRG_MSG *msg) +{ + struct bnd_msg_inf_status_req *inf_status_req = &msg->data.inf_status_req; + + if (table->bInitialized == TRUE) { + BNDSTRG_MSG new_msg = { 0 }; + struct bnd_msg_inf_status_rsp *inf_status_rsp = &new_msg.data.inf_status_rsp; + /* Send to daemon */ + new_msg.Action = INF_STATUS_RSP; + + inf_status_rsp->band = table->Band; + inf_status_rsp->bInfReady = table->bInfReady; + inf_status_rsp->Channel = table->Channel; + inf_status_rsp->bVHTCapable = table->bVHTCapable; + inf_status_rsp->nss = table->nss; + inf_status_rsp->table_src_addr = (ULONG)table; + inf_status_rsp->table_size = BND_STRG_MAX_TABLE_SIZE; + strncpy(inf_status_rsp->ucIfName, inf_status_req->ucIfName, sizeof(inf_status_rsp->ucIfName)); +#ifdef VENDOR_FEATURE5_SUPPORT + inf_status_rsp->nvram_support = 1; +#else + inf_status_rsp->nvram_support = 0; +#endif + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n%s:INF [%s]STATUS QUERY ON\n", __func__, inf_status_req->ucIfName)); + BndStrgSendMsg(pAd, &new_msg); + } +} + +VOID BndStrg_KickOutAllSta(RTMP_ADAPTER *pAd, UCHAR apidx, USHORT Reason) +{ + HEADER_802_11 DisassocHdr; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + NDIS_STATUS NStatus; + UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + if (apidx < pAd->ApCfg.BssidNum) { + /* Send out a Deauthentication request frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Send DISASSOC frame(%d) with ra%d\n", Reason, apidx)); + /* 802.11 Header */ + NdisZeroMemory(&DisassocHdr, sizeof(HEADER_802_11)); + DisassocHdr.FC.Type = FC_TYPE_MGMT; + DisassocHdr.FC.SubType = SUBTYPE_DISASSOC; + DisassocHdr.FC.ToDs = 0; + DisassocHdr.FC.Wep = 0; + COPY_MAC_ADDR(DisassocHdr.Addr1, BROADCAST_ADDR); + COPY_MAC_ADDR(DisassocHdr.Addr2, pAd->ApCfg.MBSSID[apidx].wdev.bssid); + COPY_MAC_ADDR(DisassocHdr.Addr3, pAd->ApCfg.MBSSID[apidx].wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DisassocHdr, + 2, &Reason, + END_OF_ARGS); + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + } +} + +VOID BndStrg_handle_onoff_event(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table, BNDSTRG_MSG *msg) +{ + struct bnd_msg_onoff *onoff = &msg->data.onoff; + UINT32 ap_idx; + UINT32 i; + + if (onoff->OnOff && (table->bEnabled ^ onoff->OnOff)) { + /* disconnect all connected STA to keep the link status + * between bndstrg daemon and driver + */ + for (ap_idx = MAIN_MBSSID; ap_idx < pAd->ApCfg.BssidNum; ap_idx++) { + if (pAd->ApCfg.BndStrgBssIdx[ap_idx] == TRUE) + BndStrg_KickOutAllSta(pAd, ap_idx, REASON_DEAUTH_STA_LEAVING); + } + + for (i = 1; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry) && pAd->ApCfg.BndStrgBssIdx[pEntry->func_tb_idx] == TRUE) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s: MacTableDeleteEntry %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, PRINT_MAC(pEntry->Addr))); + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + } + } + + BndStrg_Send_NeighborReport(pAd, table); + table->BndStrgMode = onoff->BndStrgMode; + } else if ((onoff->OnOff == 0) && (table->bEnabled ^ onoff->OnOff)) { + if (table->Size > 0) { + PBND_STRG_CLI_ENTRY entry = NULL; + + for (i = 0; i < BND_STRG_MAX_TABLE_SIZE; i++) { + entry = &table->Entry[i]; + + if (entry->bValid == TRUE) + BndStrg_DeleteEntry(table, entry->Addr, i); + } + } + } + + BndStrg_Tbl_Enable(table, onoff->OnOff, onoff->ucIfName); + + if (table->bEnabled) + table->DaemonPid = current->pid; + else + table->DaemonPid = 0xffffffff; + return; +} + +VOID BndStrg_UpdateWhiteBlackList(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table, BNDSTRG_MSG *msg) + { + struct bnd_msg_update_white_black_list *update_list = &msg->data.update_white_black_list; + int i = 0, max_list_size = 0; + int emptyindex = -1; + UINT8 *list_size; + UCHAR macAddrzero[MAC_ADDR_LEN] = { 0 }, *list = NULL; + + BND_STRG_PRINTQAMSG(table, update_list->Addr, ("%s: client[%02x:%02x:%02x:%02x:%02x:%02x] %s %s\n", + __func__, PRINT_MAC(update_list->Addr), (update_list->deladd ? "Add to":"Remove From"), ((update_list->list_type == bndstrg_whitelist) ? "WhiteList" : "BlackList"))); + + if (update_list->list_type == bndstrg_whitelist) { + list = (UCHAR *)&table->WhiteEntryList; + max_list_size = BND_STRG_MAX_WHITELIST_ENTRY; + list_size = &table->WhiteEntryListSize; + } else if (update_list->list_type == bndstrg_blacklist) { + list = (UCHAR *)&table->BndStrgBlackList; + max_list_size = BND_STRG_MAX_BLACKLIST_ENTRY; + list_size = &table->BndStrgBlackListSize; + } else + return; + + if (update_list->deladd) { + + if ((*list_size) >= max_list_size) { + return; + } + + for (i = 0; i < max_list_size; i++) { + + if (memcmp((list + (i*MAC_ADDR_LEN)), update_list->Addr, MAC_ADDR_LEN) == 0) + return; + + if ((emptyindex == -1) && (memcmp((list + (i*MAC_ADDR_LEN)), macAddrzero, MAC_ADDR_LEN) == 0)) + emptyindex = i; + } + + if (emptyindex != -1) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Add Entry to List [%02x:%02x:%02x:%02x:%02x:%02x]!\n", + __func__, PRINT_MAC((list + (emptyindex*MAC_ADDR_LEN))))); + memcpy((list + (emptyindex*MAC_ADDR_LEN)), update_list->Addr, MAC_ADDR_LEN); + (*list_size)++; + } else { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s[%d]: List is full [%d]!\n", __func__, __LINE__, *list_size)); + } + } else { + for (i = 0; i < max_list_size; i++) { + if (memcmp((list + (i*MAC_ADDR_LEN)), update_list->Addr, MAC_ADDR_LEN) == 0) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: Remove Entry from List [%02x:%02x:%02x:%02x:%02x:%02x]!\n", + __func__, PRINT_MAC((list + (i*MAC_ADDR_LEN))))); + memcpy((list + (i*MAC_ADDR_LEN)), macAddrzero, MAC_ADDR_LEN); + (*list_size)--; + } + } + } +} + +INT BndStrg_MsgHandle(PRTMP_ADAPTER pAd, RTMP_IOCTL_INPUT_STRUCT *wrq, INT apidx) +{ + PBND_STRG_CLI_ENTRY entry = NULL; + BNDSTRG_MSG msg_copy = { 0 }; + BNDSTRG_MSG *msg = &msg_copy; + PBND_STRG_CLI_TABLE table = NULL; + INT Status = NDIS_STATUS_SUCCESS; + + table = Get_BndStrgTable(pAd, apidx); + + if (!table || (table->bInitialized == FALSE)) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: BND_STRG_NOT_INITIALIZED on apidex[%d]!\n", __func__, apidx)); + return BND_STRG_NOT_INITIALIZED; + } + + if (wrq->u.data.length > sizeof(BNDSTRG_MSG)) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: The length of message not match!\n", __func__)); + return BND_STRG_INVALID_ARG; + } else { + Status = copy_from_user(&msg_copy, wrq->u.data.pointer, wrq->u.data.length); + } + + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: action code (%d)\n", __func__, msg->Action)); + + if ((table->DaemonPid != 0xffffffff) && (table->DaemonPid != current->pid)) { + BNDSTRG_MSG new_msg = { 0 }; + + new_msg.Action = REJECT_EVENT; + new_msg.data.reject_body.DaemonPid = table->DaemonPid; + BndStrgSendMsg(pAd, &new_msg); + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s:Unknown BndStrg PID\n", __func__)); + return BND_STRG_SUCCESS; + } + + switch (msg->Action) { + case CLI_ADD: { + struct bnd_msg_cli_add *cli_add = &msg->data.cli_add; + +#ifdef BND_STRG_QA + BND_STRG_PRINTQAMSG(table, cli_add->Addr, (("%s[%d][Channel:%d]: Add (%02x:%02x:%02x:%02x:%02x:%02x) client to %s driver table\n\r"), + __func__, __LINE__, table->Channel, PRINT_MAC(cli_add->Addr), (IS_5G_BAND(table->Band) ? "5G":"2.4G"))); +#endif + + entry = BndStrg_TableLookup(table, cli_add->Addr); + + if (entry == NULL) { + BndStrg_InsertEntry(table, cli_add, &entry); + if (table->BndStrgMode == POST_CONNECTION_STEERING) { + entry->bConnStatus = TRUE; + entry->BndStrg_Sta_State = BNDSTRG_STA_ASSOC; + } + } + else + entry->BndStrg_Sta_State = BNDSTRG_STA_INIT; + } + break; + + case CLI_DEL: { + struct bnd_msg_cli_del *cli_del = &msg->data.cli_del; + MAC_TABLE_ENTRY *pEntry = NULL; + + if (BndStrg_TableLookup(table, cli_del->Addr)) { + /*remove sta if sta is existed*/ + pEntry = MacTableLookup(pAd, cli_del->Addr); + + if (pEntry && (apidx == pEntry->func_tb_idx) + && pAd->ApCfg.BndStrgBssIdx[pEntry->func_tb_idx]) { +#ifdef BND_STRG_QA + BND_STRG_PRINTQAMSG(table, cli_del->Addr, (("%s[%d]: kick out client's (%02x:%02x:%02x:%02x:%02x:%02x)\n\r"), + __func__, __LINE__, PRINT_MAC(cli_del->Addr))); +#endif + MlmeDeAuthAction(pAd, pEntry, REASON_DISASSOC_STA_LEAVING, FALSE); + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + } + + BndStrg_DeleteEntry(table, cli_del->Addr, 0xFF); +#ifdef BND_STRG_QA + BND_STRG_PRINTQAMSG(table, cli_del->Addr, (("%s[%d][Channel:%d]:DEL (%02x:%02x:%02x:%02x:%02x:%02x) client from %s driver table\n\r"), + __func__, __LINE__, table->Channel, PRINT_MAC(cli_del->Addr), (IS_5G_BAND(table->Band) ? "5G":"2.4G"))); +#endif + } + } + break; + case CLI_STATUS_REQ: + if (table->bInfReady) + BndStrg_CLIStatusRsp(pAd, table, msg); + + break; + + case CHANLOAD_STATUS_REQ: + if (table->bInfReady) + BndStrg_ChannelLoadStatusRsp(pAd, table, msg); + + break; + + case INF_STATUS_QUERY: + if (table->bInfReady) + BndStrg_InfStatusRsp(pAd, table, msg); + + break; + + case HEARTBEAT_MONITOR: + if (table->bInfReady) + pAd->ApCfg.BndStrgHeartbeatCount++; + + break; + + case BNDSTRG_ONOFF: + if (table && table->bInitialized) + BndStrg_handle_onoff_event(pAd, table, msg); + break; +#ifdef VENDOR_FEATURE5_SUPPORT + case NVRAM_UPDATE: { + struct bnd_msg_nvram_entry_update *entry_update = &msg->data.entry_update; + + if (!(BndStrg_NvramInsertEntry(table, &entry_update->nvram_entry))) + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s: NVRAM table full\n", __func__)); + } + break; +#endif /* VENDOR_FEATURE5_SUPPORT */ + + case BNDSTRG_WNM_BTM: +#ifdef CONFIG_DOT11V_WNM + { + struct wnm_command *cmd_data = (struct wnm_command *)&msg->data.wnm_cmd_data; + + hex_dump("BNDSTRG_WNM_BTM MSG", (unsigned char *)msg, sizeof(BNDSTRG_MSG)); + if (cmd_data->command_id == OID_802_11_WNM_CMD_SEND_BTM_REQ) { + MAC_TABLE_ENTRY *pEntry; + unsigned char *request_mode; + struct btm_req_data *req_data; +#define DISASSOC_IMMINENT (0x01 << 2) + req_data = (struct btm_req_data *)cmd_data->command_body; + request_mode = (unsigned char *)req_data->btm_req; + if ((*request_mode) & DISASSOC_IMMINENT) { + /* imminent dis-assoc BTM Req, delete entry from driver table */ + BndStrg_DeleteEntry(table, req_data->peer_mac_addr, 0xFF); + } + pEntry = MacTableLookup(pAd, req_data->peer_mac_addr); + if (pEntry != NULL) { + BndStrg_send_BTM_req(pAd, + req_data->peer_mac_addr, + req_data->btm_req, + req_data->btm_req_len, + table); + } + } else{ + hex_dump("BNDSTRG_WNM_BTM", (unsigned char *)cmd_data, cmd_data->command_len); + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknow wnm cmd id %d\n", __func__, cmd_data->command_id)); + } + } +#endif + break; + + case UPDATE_WHITE_BLACK_LIST: + if (table->bInfReady) { + BndStrg_UpdateWhiteBlackList(pAd, table, msg); + } + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("%s: unknown action code. (%d)\n", __func__, msg->Action)); + break; + } + + return BND_STRG_SUCCESS; +} + +void BndStrgHeartBeatMonitor(PRTMP_ADAPTER pAd) +{ + if (pAd->ApCfg.BndStrgTable[BAND0].bEnabled +#ifdef DBDC_MODE + || pAd->ApCfg.BndStrgTable[BAND1].bEnabled +#endif + ) { + if (pAd->ApCfg.BndStrgHeartbeatMonitor != pAd->ApCfg.BndStrgHeartbeatCount) { + pAd->ApCfg.BndStrgHeartbeatMonitor = pAd->ApCfg.BndStrgHeartbeatCount; + pAd->ApCfg.BndStrgHeartbeatNoChange = 0; + return; + } else + pAd->ApCfg.BndStrgHeartbeatNoChange++; + + if (pAd->ApCfg.BndStrgHeartbeatNoChange == 20) { + BND_STRG_MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s:BndStrg Daemon Killed\n", __func__)); + pAd->ApCfg.BndStrgHeartbeatNoChange = 0; + BndStrg_Release(pAd); + } + } +} + +void BndStrgSetProfileParam(struct _RTMP_ADAPTER *pAd, RTMP_STRING *tmpbuf, RTMP_STRING *pBuffer) +{ + INT i = 0; + RTMP_STRING *macptr = NULL; + + if (RTMPGetKeyParameter("BandSteering", tmpbuf, 10, pBuffer, TRUE)) { + pAd->ApCfg.BandSteering = (UCHAR) simple_strtol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_CAT_AP, DBG_LVL_OFF, ("BandSteering=%d\n", pAd->ApCfg.BandSteering)); + } + + if (RTMPGetKeyParameter("BndStrgBssIdx", tmpbuf, 50, pBuffer, TRUE)) { + MTWF_LOG(DBG_CAT_CFG, DBG_CAT_AP, DBG_LVL_OFF, ("BndStrgBssIdx=%s\n", tmpbuf)); + + for (i = 0, macptr = rstrtok(tmpbuf, ";"); macptr; macptr = rstrtok(NULL, ";"), i++) + pAd->ApCfg.BndStrgBssIdx[i] = simple_strtoul(macptr, 0, 10); + + if (i == 0) + pAd->ApCfg.BndStrgBssIdx[MAIN_MBSSID] = 1; + } else + pAd->ApCfg.BndStrgBssIdx[MAIN_MBSSID] = 1; +} +#ifdef CONFIG_DOT11V_WNM +void BndStrg_send_BTM_req( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *PeerMACAddr, + IN RTMP_STRING *BTMReq, + IN UINT32 BTMReqLen, + PBND_STRG_CLI_TABLE table) +{ + UCHAR *Buf; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR APIndex = pObj->ioctl_if; + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[APIndex].WNMCtrl; + BTM_EVENT_DATA *Event; + BTM_PEER_ENTRY *BTMPeerEntry; +#ifdef DOT11K_RRM_SUPPORT + RRM_NEIGHBOR_REP_INFO *NeighborReport = NULL; + ULONG FrameLen = 0; +#endif + UINT32 Len = 0; + INT32 Ret; + BOOLEAN IsFound = FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + + RTMP_SEM_EVENT_WAIT(&pWNMCtrl->BTMPeerListLock, Ret); + DlListForEach(BTMPeerEntry, &pWNMCtrl->BTMPeerList, BTM_PEER_ENTRY, List) + { + if (MAC_ADDR_EQUAL(BTMPeerEntry->PeerMACAddr, PeerMACAddr)) { + IsFound = TRUE; + break; + } + } + RTMP_SEM_EVENT_UP(&pWNMCtrl->BTMPeerListLock); + + if (!IsFound) { + os_alloc_mem(NULL, (UCHAR **)&BTMPeerEntry, sizeof(*BTMPeerEntry)); + + if (!BTMPeerEntry) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + goto error0; + } + + NdisZeroMemory(BTMPeerEntry, sizeof(*BTMPeerEntry)); + + BTMPeerEntry->CurrentState = WAIT_BTM_REQ; + BTMPeerEntry->ControlIndex = APIndex; + NdisMoveMemory(BTMPeerEntry->PeerMACAddr, PeerMACAddr, MAC_ADDR_LEN); + BTMPeerEntry->DialogToken = 1; + BTMPeerEntry->Priv = pAd; + + RTMPInitTimer(pAd, &BTMPeerEntry->WaitPeerBTMRspTimer, + GET_TIMER_FUNCTION(WaitPeerBTMRspTimeout), BTMPeerEntry, FALSE); + RTMP_SEM_EVENT_WAIT(&pWNMCtrl->BTMPeerListLock, Ret); + DlListAddTail(&pWNMCtrl->BTMPeerList, &BTMPeerEntry->List); + RTMP_SEM_EVENT_UP(&pWNMCtrl->BTMPeerListLock); + } + +#ifdef DOT11K_RRM_SUPPORT + os_alloc_mem(NULL, (UCHAR **)&Buf, sizeof(*Event) + BTMReqLen + sizeof(RRM_NEIGHBOR_REP_INFO) + 3); + /* Size 3 is for the preference sub element in neighbor report*/ +#else + os_alloc_mem(NULL, (UCHAR **)&Buf, sizeof(*Event) + BTMReqLen); +#endif + + if (!Buf) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + goto error1; + } + +#ifdef DOT11K_RRM_SUPPORT + NdisZeroMemory(Buf, sizeof(*Event) + BTMReqLen + sizeof(RRM_NEIGHBOR_REP_INFO) + 3); + /* Size 3 is for the preference sub element in neighbor report*/ +#else + NdisZeroMemory(Buf, sizeof(*Event) + BTMReqLen); +#endif + + Event = (BTM_EVENT_DATA *)Buf; + + Event->ControlIndex = APIndex; + Len += 1; + + NdisMoveMemory(Event->PeerMACAddr, PeerMACAddr, MAC_ADDR_LEN); + Len += MAC_ADDR_LEN; + + Event->EventType = BTM_REQ; + Len += 2; + + Event->u.BTM_REQ_DATA.DialogToken = BTMPeerEntry->DialogToken; + Len += 1; + + Event->u.BTM_REQ_DATA.BTMReqLen = BTMReqLen; + Len += 2; + + NdisMoveMemory(Event->u.BTM_REQ_DATA.BTMReq, BTMReq, BTMReqLen); + + BTMReq += BTMReqLen; /*advance pointer to neighbour report*/ +#ifdef DOT11K_RRM_SUPPORT + hex_dump("BndStrg_send_BTM_req NeighborReport", (unsigned char *)BTMReq, sizeof(RRM_NEIGHBOR_REP_INFO)); + NeighborReport = (RRM_NEIGHBOR_REP_INFO *)BTMReq; + + RRM_InsertNeighborRepIE(pAd, (Event->u.BTM_REQ_DATA.BTMReq + BTMReqLen), &FrameLen, + sizeof(RRM_NEIGHBOR_REP_INFO)+3, NeighborReport); /* Neighbor report IE + Preferance Sub-IE length*/ + BTMReqLen += FrameLen; + + { + ULONG TempLen = 0; + UINT8 IEId = 3; + UINT8 Len = 1; + UINT8 BssPreference = 255; + + MakeOutgoingFrame((Event->u.BTM_REQ_DATA.BTMReq + BTMReqLen), &TempLen, + 1, &IEId, + 1, &Len, + 1, &BssPreference, + END_OF_ARGS); + BTMReqLen += TempLen; + } + Event->u.BTM_REQ_DATA.BTMReqLen = BTMReqLen; + Len += BTMReqLen; +#endif + hex_dump("BndStrg_send_BTM_req Enque", (unsigned char *)Buf, Len); + hex_dump("BndStrg_send_BTM_req Event length", (unsigned char *)Event->u.BTM_REQ_DATA.BTMReq, Event->u.BTM_REQ_DATA.BTMReqLen); + MlmeEnqueue(pAd, BTM_STATE_MACHINE, BTM_REQ, Len, Buf, 0); + + os_free_mem(Buf); + + return; + +error1: + if (!IsFound) + os_free_mem(BTMPeerEntry); +error0: + return; +} + +#endif + +void BndStrg_Send_NeighborReport(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table) +{ +#ifdef DOT11K_RRM_SUPPORT + BNDSTRG_MSG msg = { 0 }; + struct bnd_msg_neighbor_report *NeighborReport = &msg.data.Neighbor_Report; + + msg.Action = BNDSTRG_NEIGHBOR_REPORT; + + NeighborReport->Band = table->Band; + NeighborReport->Channel = table->Channel; + NdisCopyMemory(&NeighborReport->NeighborRepInfo, &table->NeighborRepInfo, sizeof(RRM_NEIGHBOR_REP_INFO)); + BndStrgSendMsg(pAd, &msg); +#endif + return; +} + +#endif /* BAND_STEERING */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_cfg.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_cfg.c new file mode 100644 index 000000000..edc2547ac --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_cfg.c @@ -0,0 +1,15520 @@ +/**************************************************************************** + * 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" + +#ifdef VENDOR_FEATURE7_SUPPORT +#ifdef WSC_LED_SUPPORT +#include "rt_led.h" +#endif /* WSC_LED_SUPPORT */ +#endif +#ifdef RLM_CAL_CACHE_SUPPORT +#include "phy/rlm_cal_cache.h" +#endif /* RLM_CAL_CACHE_SUPPORT */ + +#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)) + +static const struct apcfg_parameters apcfg_for_peak = { + .cfg_mode[0] = 9, /*WirelessMode*/ + .cfg_mode[1] = 14, + .tx_power_percentage = 100, /*TxPower*/ + .tx_preamble = 1, /*TxPreamble*/ + .conf_len_thld = 2347, /*RTSThreshold*/ + .oper_len_thld = 2347, + .conf_frag_thld = 2346, /*FragThreshold*/ + .oper_frag_thld = 2346, + .bEnableTxBurst = 1, /*TxBurst*/ + .bUseShortSlotTime = 1, /*ShortSlot*/ +#ifdef DOT11_N_SUPPORT + .conf_ht_bw = 1, /*HT_BW*/ + .oper_ht_bw = 1, +#ifdef DOT11N_DRAFT3 + .bBssCoexEnable = 0, /*HT_BSSCoexistence*/ +#endif + + .ht_tx_streams = 4, /*HT_TxStream*/ + .ht_rx_streams = 4, /*HT_RxStream*/ + + .bBADecline = 0, /*HT_BADecline*/ + .AutoBA = 1, /*HT_AutoBA*/ + .AmsduEnable = 1, /*HT_AMSDU*/ + .RxBAWinLimit = 64, /*HT_BAWinSize*/ + .ht_gi = 1, /*HT_GI*/ + .ht_stbc = 1, /*HT_STBC*/ + .ht_ldpc = 1, /*HT_LDPC*/ + .bRdg = 0, /*HT_RDG*/ +#endif + .HT_DisallowTKIP = 1, /*HT_DisallowTKIP*/ + +#ifdef DOT11_VHT_AC + .conf_vht_bw = 1, /*VHT_BW, 5G only*/ + .oper_vht_bw = 1, + .vht_sgi = 1, /*VHT_SGI, 5G only*/ + .vht_stbc = 1, /*VHT_STBC, 5G only*/ + .vht_bw_signal = 0, /*VHT_BW_SIGNAL, 5G only*/ + .vht_ldpc = 1, /*VHT_LDPC, 5G only*/ + .g_band_256_qam = 1, /*G_BAND_256QAM, 2.4G only*/ +#endif + + .bIEEE80211H = 1, /*IEEE80211H*/ + +#ifdef MT_DFS_SUPPORT + .bDfsEnable = 0, /*DfsEnable, 5G only*/ +#endif + +#ifdef BACKGROUND_SCAN_SUPPORT + .DfsZeroWaitSupport = 0, /*DfsZeroWait, Single band only*/ +#endif + +#ifdef DOT11_N_SUPPORT +#ifdef TXBF_SUPPORT + .ETxBfEnCond = 0, /*ETxBfEnCond*/ +#endif +#endif + + .ITxBfEn = 0, /*ITxBfEn*/ + +#ifdef DOT11_N_SUPPORT +#ifdef TXBF_SUPPORT + .MUTxRxEnable = 0, /*MUTxRxEnable*/ +#endif +#endif + }; + +#ifdef CFG_SUPPORT_MU_MIMO + +/* iwprive test code */ + +INT32 hqa_mu_get_qd(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_get_init_mcs(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_get_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg); + +INT32 hqa_mu_cal_init_mcs(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_cal_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg); + +INT32 hqa_mu_set_snr_offset(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_zero_nss(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_speedup_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_mu_table(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_group(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_enable(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_gid_up(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_su_cal_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_su_get_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_gid_up(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +INT32 hqa_mu_set_trigger_mu_tx(PRTMP_ADAPTER pAd, RTMP_STRING *arg); + + +/* get function */ +INT ShowMuEnableProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowMuProfileProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowGroupTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowClusterTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowGroupUserThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowGroupNssThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowTxReqMinTimeProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowSuNssCheckProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowCalcInitMCSProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowTxopDefaultProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowSuLossThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowMuGainThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowSecondaryAcPolicyProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowGroupTblDmcsMaskProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowMaxGroupSearchCntProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT ShowMuProfileTxStsCntProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +/* set function */ +INT SetMuProfileProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetGroupTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetClusterTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuEnableProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetGroupUserThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetGroupNssThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTxReqMinTimeProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetSuNssCheckProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetCalculateInitMCSProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTriggerGIDMgmtFrameProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTriggerMuTxProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTriggerDegroupProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTriggerGroupProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTriggerBbpProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTriggerSndProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetTxopDefaultProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetSuLossThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuGainThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetSecondaryAcPolicyProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetGroupTblDmcsMaskProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMaxGroupSearchCntProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif + +#ifdef AIR_MONITOR +INT Set_Enable_Air_Monitor_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorRule_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorIndex_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorShowAll_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorClearCounter_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget0_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget1_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget2_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget3_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget4_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget5_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget6_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget7_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget8_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget9_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget10_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget11_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget12_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget13_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget14_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_MonitorTarget15_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +VOID Air_Monitor_Pkt_Report_Action(RTMP_ADAPTER *pAd, UCHAR wcid, RX_BLK *pRxBlk); +#endif /* AIR_MONITOR */ + +#ifdef DSCP_PRI_SUPPORT +INT Set_Dscp_Pri_Proc( + IN PRTMP_ADAPTER pAd, + IN UINT8 map_index, + IN RTMP_STRING * arg); + +INT Set_Dscp_Pri_2G_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg); + +INT Set_Dscp_Pri_5G_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg); +#endif + +#ifdef CFG_SUPPORT_MU_MIMO_RA +/* mura set function */ +INT SetMuraPeriodicSndProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuraTestAlgorithmProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuraTestAlgorithmInit(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuraFixedRateProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuraFixedGroupRateProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuraFixedSndParamProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT SetMuraDisableCN3CN4Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +/* mura get function */ +INT GetMuraMonitorStateProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT GetMuraPFIDStatProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif + +INT Set_CountryString_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_CountryCode_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef EXT_BUILD_CHANNEL_LIST +INT Set_ChGeography_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#ifdef SPECIFIC_TX_POWER_SUPPORT +INT Set_AP_PKT_PWR(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* SPECIFIC_TX_POWER_SUPPORT */ + +INT Set_AP_SSID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_TxRate_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_OLBCDetection_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_AP_PerMbssMaxStaNum_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_AP_IdleTimeout_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#ifdef IAPP_SUPPORT +INT Set_IappPID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* IAPP_SUPPORT */ + +INT Set_AP_WpaMixPairCipher_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_RekeyInterval_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_RekeyMethod_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_PMKCachePeriod_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_ASSOC_REQ_RSSI_THRESHOLD(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_KickStaRssiLow_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_BasicRate_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef REDUCE_TCP_ACK_SUPPORT +INT Set_ReduceAckEnable_Proc( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_STRING *pParam); + +INT Show_ReduceAckInfo_Proc( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_STRING *pParam); + +INT Set_ReduceAckProb_Proc( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_STRING *pParam); +#endif + +INT Set_BeaconPeriod_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_DtimPeriod_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_NoForwarding_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_NoForwardingBTNSSID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_WmmCapable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_HideSSID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_VLANID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_VLANPriority_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_VLAN_TAG_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AccessPolicy_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_ACLAddEntry_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_ACLDelEntry_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_ACLShowAll_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_ACLClearAll_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_SiteSurvey_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AutoChannelSel_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_PartialScan_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#ifdef AP_SCAN_SUPPORT +INT Set_AutoChannelSelCheckTime_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* AP_SCAN_SUPPORT */ + +INT Set_BADecline_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Show_StaCount_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Show_Sat_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +static INT show_apcfg_info(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Show_RAInfo_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#ifdef TXBF_SUPPORT +INT Show_TxBfInfo_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* TXBF_SUPPORT */ +#ifdef RTMP_MAC_PCI +#ifdef DBG_DIAGNOSE +INT Set_DiagOpt_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_diag_cond_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Show_Diag_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* DBG_DAIGNOSE */ +#endif /* RTMP_MAC_PCI */ + + +INT show_timer_list(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT show_wtbl_state(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT show_radio_info_proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Show_Sat_Reset_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Show_MATTable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#ifdef DOT1X_SUPPORT +INT Set_IEEE8021X_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_PreAuth_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_RADIUS_Server_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_RADIUS_Port_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_RADIUS_Key_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_DeletePMKID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_DumpPMKID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef RADIUS_MAC_ACL_SUPPORT +INT Set_RADIUS_MacAuth_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_RADIUS_CacheTimeout_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT show_RADIUS_acl_cache(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* RADIUS_MAC_ACL_SUPPORT */ +#endif /* DOT1X_SUPPORT */ + +INT Set_DisConnectSta_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#ifdef VENDOR_FEATURE7_SUPPORT +INT Set_DisConnectBssSta_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif + +INT Set_DisConnectAllSta_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + + +#ifdef APCLI_SUPPORT +INT Set_ApCli_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ApCli_Ssid_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ApCli_Bssid_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ApCli_TxMode_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ApCli_TxMcs_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ApCli_WirelessMode_Proc(PRTMP_ADAPTER pAd, RTMP_STRING *arg); + +#ifdef APCLI_AUTO_CONNECT_SUPPORT +INT Set_ApCli_AutoConnect_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ +#ifdef APCLI_CONNECTION_TRIAL +INT Set_ApCli_Trial_Ch_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* APCLI_CONNECTION_TRIAL */ + + +#ifdef MAC_REPEATER_SUPPORT +INT Set_ReptMode_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_Cli_Link_Map_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* MAC_REPEATER_SUPPORT */ + +#ifdef WSC_AP_SUPPORT +INT Set_AP_WscSsid_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#ifdef APCLI_SUPPORT +INT Set_ApCli_WscScanMode_Proc(PRTMP_ADAPTER pAd, RTMP_STRING *arg); +#endif /* APCLI_SUPPORT */ +#endif /* WSC_AP_SUPPORT */ + +#ifdef APCLI_CERT_SUPPORT +INT Set_ApCli_Cert_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +/* Add for APCLI PMF 5.3.3.3 option test item. (Only Tx De-auth Req. and make sure the pkt can be Encrypted) */ +INT ApCliTxDeAuth(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* APCLI_CERT_SUPPORT */ + +#ifdef WSC_AP_SUPPORT +INT Set_Wps_Cert_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif + +#ifdef ROAMING_ENHANCE_SUPPORT +INT Set_RoamingEnhance_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* ROAMING_ENHANCE_SUPPORT */ +#endif /* APCLI_SUPPORT */ +#ifdef UAPSD_SUPPORT +INT Set_UAPSD_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* UAPSD_SUPPORT */ + +#ifdef WSC_AP_SUPPORT +INT Set_WscStatus_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef BB_SOC +INT Set_WscOOB_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif + +INT Set_WscStop_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *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 RTMP_STRING *pData, + IN USHORT Length, + IN PWSC_CTRL pWscControl); + +UCHAR WscRxMsgTypeFromUpnp( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_STRING *pData, + IN USHORT Length); + +INT WscGetConfForUpnp( + IN PRTMP_ADAPTER pAd, + IN PWSC_CTRL pWscControl); + +#ifdef CON_WPS +INT Set_ConWpsApCliMode_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ConWpsApcliAutoPreferIface_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ConWpsApCliDisabled_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_ConWpsApDisabled_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* CON_WPS */ +INT Set_AP_WscConfMode_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_WscConfStatus_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_WscPinCode_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_WscSecurityMode_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_AP_WscMultiByteCheck_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + + +INT Set_WscVersion_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef VENDOR_FEATURE6_SUPPORT +INT Set_WscUUID_STR_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_WscUUID_HEX_E_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* VENDOR_FEATURE6_SUPPORT */ + +#ifdef WSC_V2_SUPPORT +INT Set_WscV2Support_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscVersion2_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscExtraTlvTag_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscExtraTlvType_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscExtraTlvData_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscSetupLock_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscFragment_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscFragmentSize_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscMaxPinAttack_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_WscSetupLockTime_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* WSC_V2_SUPPORT */ +INT Set_WscAutoTriggerDisable_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg); +#endif /* WSC_AP_SUPPORT */ + + +#ifdef CONFIG_AP_SUPPORT +#ifdef MCAST_RATE_SPECIFIC +INT Set_McastPhyMode(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_McastMcs(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Show_McastRate(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* MCAST_RATE_SPECIFIC */ + +#ifdef DOT11N_DRAFT3 +INT Set_OBSSScanParam_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Set_AP2040ReScan_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* DOT11N_DRAFT3 */ + +INT Set_EntryLifeCheck_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef RTMP_RBUS_SUPPORT +#ifdef LED_CONTROL_SUPPORT +INT Set_WlanLed_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* LED_CONTROL_SUPPORT */ +#endif /* RTMP_RBUS_SUPPORT */ + +#ifdef AP_QLOAD_SUPPORT +INT Set_QloadClr_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +/* QLOAD ALARM */ +INT Set_QloadAlarmTimeThreshold_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT Set_QloadAlarmNumThreshold_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* AP_QLOAD_SUPPORT */ +#endif /* CONFIG_AP_SUPPORT */ + +INT Set_MemDebug_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef CONFIG_AP_SUPPORT +INT Set_PowerSaveLifeTime_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* CONFIG_AP_SUPPORT */ + + +#ifdef DYNAMIC_VGA_SUPPORT +INT Set_DyncVgaEnable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +INT set_false_cca_hi_th(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT set_false_cca_low_th(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* DYNAMIC_VGA_SUPPORT */ + +#ifdef MT_MAC +INT Set_AP_TimEnable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT setApTmrEnableProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +INT Show_TmrCalResult_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); + +#ifdef CUT_THROUGH +INT Set_CutThrough_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +#endif /* CUT_THROUGH */ + +#ifdef DBG +INT set_tim_update_proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); + +INT Set_AP_DumpTime_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); + +INT Set_BcnStateCtrl_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +#endif /*DBG*/ + +#ifdef PRE_CAL_TRX_SET1_SUPPORT +INT Set_KtoFlash_Debug_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); + +INT Set_RDCE_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ + +#ifdef TX_AGG_ADJUST_WKR +INT Set_AggAdjWkr_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +#endif /* TX_AGG_ADJUST_WKR */ + +#ifdef RLM_CAL_CACHE_SUPPORT +INT Set_RLM_Cal_Cache_Debug_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +#endif /* RLM_CAL_CACHE_SUPPORT */ + +#ifdef PKT_BUDGET_CTRL_SUPPORT +INT Set_PBC_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); + +#endif /*PKT_BUDGET_CTRL_SUPPORT*/ + +INT Set_BWF_Enable_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); + +#ifdef CONFIG_HOTSPOT_R2 +INT Set_CR4_Hotspot_Flag( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +#endif /* CONFIG_HOTSPOT_R2 */ + +#ifdef HTC_DECRYPT_IOT +INT Set_HTC_Err_TH_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +INT Set_Entry_HTC_Err_Cnt_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +INT Set_WTBL_AAD_OM_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +#endif /* HTC_DECRYPT_IOT */ + +#ifdef DHCP_UC_SUPPORT +INT Set_DHCP_UC_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg); +#endif /* DHCP_UC_SUPPORT */ +#endif /* MT_MAC */ + +#ifdef CONFIG_TX_DELAY +INT Set_TX_Batch_Cnt_Proc( + PRTMP_ADAPTER pAd, + char *arg); + +INT Set_Pkt_Min_Len_Proc( + PRTMP_ADAPTER pAd, + char *arg); + +INT Set_Pkt_Max_Len_Proc( + PRTMP_ADAPTER pAd, + char *arg); + +INT Set_TX_Delay_Timeout_Proc( + PRTMP_ADAPTER pAd, + char *arg); +#endif + +#ifdef DBG_STARVATION +static INT show_starv_info_proc( + struct _RTMP_ADAPTER *ad, + char *arg) +{ + starv_log_dump(&ad->starv_log_ctrl); + return TRUE; +} +#endif /*DBG_STARVATION*/ + +static struct { + RTMP_STRING *name; + INT (*set_proc)(PRTMP_ADAPTER pAdapter, RTMP_STRING *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}, +#endif /* NEW_RATE_ADAPT_SUPPORT */ + {"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 */ +#ifdef AIR_MONITOR + {"mnt_en", Set_Enable_Air_Monitor_Proc}, + {"mnt_rule", Set_MonitorRule_Proc}, + {"mnt_sta", Set_MonitorTarget_Proc}, + {"mnt_idx", Set_MonitorIndex_Proc}, + {"mnt_show", Set_MonitorShowAll_Proc}, + {"mnt_clr", Set_MonitorClearCounter_Proc}, + {"mnt_sta0", Set_MonitorTarget0_Proc}, + {"mnt_sta1", Set_MonitorTarget1_Proc}, + {"mnt_sta2", Set_MonitorTarget2_Proc}, + {"mnt_sta3", Set_MonitorTarget3_Proc}, + {"mnt_sta4", Set_MonitorTarget4_Proc}, + {"mnt_sta5", Set_MonitorTarget5_Proc}, + {"mnt_sta6", Set_MonitorTarget6_Proc}, + {"mnt_sta7", Set_MonitorTarget7_Proc}, + {"mnt_sta8", Set_MonitorTarget8_Proc}, + {"mnt_sta9", Set_MonitorTarget9_Proc}, + {"mnt_sta10", Set_MonitorTarget10_Proc}, + {"mnt_sta11", Set_MonitorTarget11_Proc}, + {"mnt_sta12", Set_MonitorTarget12_Proc}, + {"mnt_sta13", Set_MonitorTarget13_Proc}, + {"mnt_sta14", Set_MonitorTarget14_Proc}, + {"mnt_sta15", Set_MonitorTarget15_Proc}, +#endif /* AIR_MONITOR */ + {"SSID", Set_AP_SSID_Proc}, + {"WirelessMode", Set_WirelessMode_Proc}, + {"BasicRate", Set_BasicRate_Proc}, + {"ShortSlot", Set_ShortSlot_Proc}, + {"Channel", Set_Channel_Proc}, +#ifdef REDUCE_TCP_ACK_SUPPORT + {"ReduceAckEnable", Set_ReduceAckEnable_Proc}, + {"ReduceAckProb", Set_ReduceAckProb_Proc}, +#endif + {"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}, + {"MbssMaxStaNum", Set_AP_PerMbssMaxStaNum_Proc}, +#ifdef RTMP_MAC_PCI + {"ShowRF", Set_ShowRF_Proc}, +#endif /* RTMP_MAC_PCI */ + {"IdleTimeout", Set_AP_IdleTimeout_Proc}, +#ifdef DOT11_N_SUPPORT + {"BASetup", Set_BASetup_Proc}, + {"BADecline", Set_BADecline_Proc}, + {"SendMIMOPS", Set_SendSMPSAction_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}, + {"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 */ +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + {"PcieAspm", set_pcie_aspm_dym_ctrl_cap_proc}, +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ + {"HtDisallowTKIP", Set_HtDisallowTKIP_Proc}, +#endif /* DOT11_N_SUPPORT */ + +#ifdef DOT11_VHT_AC + {"VhtBw", Set_VhtBw_Proc}, + {"VhtStbc", Set_VhtStbc_Proc}, + {"VhtBwSignal", set_VhtBwSignal_Proc}, + {"VhtDisallowNonVHT", Set_VhtDisallowNonVHT_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 */ + + {"WmmCapable", Set_AP_WmmCapable_Proc}, + + {"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_SecAuthMode_Proc}, + {"EncrypType", Set_SecEncrypType_Proc}, + {"WpaMixPairCipher", Set_AP_WpaMixPairCipher_Proc}, + {"RekeyInterval", Set_AP_RekeyInterval_Proc}, + {"RekeyMethod", Set_AP_RekeyMethod_Proc}, + {"DefaultKeyID", Set_SecDefaultKeyID_Proc}, + {"Key1", Set_SecKey1_Proc}, + {"Key2", Set_SecKey2_Proc}, + {"Key3", Set_SecKey3_Proc}, + {"Key4", Set_SecKey4_Proc}, + {"AccessPolicy", Set_AccessPolicy_Proc}, + {"ACLAddEntry", Set_ACLAddEntry_Proc}, + {"ACLDelEntry", Set_ACLDelEntry_Proc}, + {"ACLShowAll", Set_ACLShowAll_Proc}, + {"ACLClearAll", Set_ACLClearAll_Proc}, + {"WPAPSK", Set_SecWPAPSK_Proc}, + {"RadioOn", Set_RadioOn_Proc}, + {"Lp", Set_Lp_Proc}, +#ifdef SPECIFIC_TX_POWER_SUPPORT + {"PktPwr", Set_AP_PKT_PWR}, +#endif /* SPECIFIC_TX_POWER_SUPPORT */ + {"AssocReqRssiThres", Set_AP_ASSOC_REQ_RSSI_THRESHOLD}, + {"KickStaRssiLow", Set_AP_KickStaRssiLow_Proc}, +#ifdef AP_SCAN_SUPPORT + {"SiteSurvey", Set_SiteSurvey_Proc}, + {"AutoChannelSel", Set_AutoChannelSel_Proc}, + {"PartialScan", Set_PartialScan_Proc}, + {"ACSCheckTime", Set_AutoChannelSelCheckTime_Proc}, +#endif /* AP_SCAN_SUPPORT */ + {"ResetCounter", Set_ResetStatCounter_Proc}, + {"DisConnectSta", Set_DisConnectSta_Proc}, +#ifdef VENDOR_FEATURE7_SUPPORT + {"DisConnectBssSta", Set_DisConnectBssSta_Proc}, +#endif + {"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}, + {"DeletePMKID", Set_DeletePMKID_Proc}, + {"DumpPMKID", Set_DumpPMKID_Proc}, +#ifdef RADIUS_MAC_ACL_SUPPORT + {"RADIUS_MacAuth_Enable", Set_RADIUS_MacAuth_Enable_Proc}, + {"RADIUS_CacheTimeout", Set_RADIUS_CacheTimeout_Proc}, +#endif /* RADIUS_MAC_ACL_SUPPORT */ +#endif /* DOT1X_SUPPORT */ +#ifdef DBG + {"Debug", Set_Debug_Proc}, + {"DebugCat", Set_DebugCategory_Proc}, +#endif /* DBG */ +#ifdef RANDOM_PKT_GEN + {"TxCtrl", Set_TxCtrl_Proc}, +#endif +#ifdef CSO_TEST_SUPPORT + {"CsCtrl", Set_CsCtrl_Proc}, +#endif + +#if defined(INTERNAL_CAPTURE_SUPPORT) || defined(WIFI_SPECTRUM_SUPPORT) + {"RBIST_SwitchMode", Set_RBIST_Switch_Mode}, + {"RBIST_CaptureStart", Set_RBIST_Capture_Start}, + {"RBIST_CaptureStatus", Get_RBIST_Capture_Status}, + {"RBIST_RawDataProc", Get_RBIST_Raw_Data_Proc}, + {"RBIST_IQDataProc", Get_RBIST_IQ_Data_Proc}, + {"WirelessInfo", Get_System_Wireless_Info}, +#endif/* defined(INTERNAL_CAPTURE_SUPPORT) || defined(WIFI_SPECTRUM_SUPPORT) */ + + {"IRR_ADC", Set_IRR_ADC}, + {"IRR_RxGain", Set_IRR_RxGain}, + {"IRR_TTG", Set_IRR_TTG}, + {"IRR_TTGOnOff", Set_IRR_TTGOnOff}, + +#ifdef MT_DFS_SUPPORT /* Jelly20150301 */ + {"ShowDfsCh", Set_DfsChannelShow_Proc}, + {"ShowDfsBw", Set_DfsBwShow_Proc}, + {"ShowDfsRDMode", Set_DfsRDModeShow_Proc}, + + {"ShowDfsRegion", Set_DfsRDDRegionShow_Proc}, + {"RadarDetectStart", Set_RadarDetectStart_Proc}, + {"RadarDetectStop", Set_RadarDetectStop_Proc}, + {"ByPassCac", Set_ByPassCac_Proc}, + {"ShowDfsNOP", Show_DfsNonOccupancy_Proc}, + {"DfsNOPClean", Set_DfsNOP_Proc}, + {"RDDReport", Set_RDDReport_Proc}, + + /* DFS zero wait */ + {"DfsZeroWaitCacTime", Set_DfsZeroWaitCacTime_Proc}, + {"DfsDedicatedBwCh", Set_DedicatedBwCh_Proc}, + {"DfsModifyChList", Set_ModifyChannelList_Proc}, + {"DfsDynamicCtrl", Set_DfsZeroWaitDynamicCtrl_Proc}, + {"DfsForceNOP", Set_DfsZeroWaitNOP_Proc}, + {"DfsTargetCh", Set_DfsTargetCh_Proc}, +#endif + +#if defined(DFS_SUPPORT) || defined(CARRIER_DETECTION_SUPPORT) + {"RadarShow", Set_RadarShow_Proc}, +#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 CONFIG_ATE + {"ATE", SetATE}, + {"ATEMPSDUMP", SetATEMPSDump}, + {"ATEMPSPHY", SetATEMPSPhyMode}, + {"ATEMPSRATE", SetATEMPSRate}, + {"ATEMPSPATH", SetATEMPSPath}, + {"ATEMPSLEN", SetATEMPSPayloadLen}, + {"ATEMPSTXCNT", SetATEMPSPktCnt}, + {"ATEMPSTXPWR", SetATEMPSPwr}, + {"ATEMPSNSS", SetATEMPSNss}, + {"ATEMPSPKTBW", SetATEMPSPktBw}, + {"ATEMPSTXSTART", SetATEMPSStart}, + {"ATELOGEN", SetATELOGEnable}, + {"ATELOGDUMP", SetATELOGDump}, + {"ATEMACTRX", SetATEMACTRx}, + {"ATETXSTREAM", SetATETxStream}, + {"ATERXSTREAM", SetATERxStream}, + {"ATETXSENABLE", SetATETxSEnable}, + {"ATERXFILTER", SetATERxFilter}, + {"ATELOGDIS", SetATELOGDisable}, + {"ATEDEQCNT", SetATEDeqCnt}, + {"ATEQID", SetATEQid}, + {"ATEDA", SetATEDa}, + {"ATESA", SetATESa}, + {"ADCDump", SetADCDump}, + {"ATEBSSID", SetATEBssid}, + {"ATECHANNEL", SetATEChannel}, + {"ATEDUTYCYCLE", set_ate_duty_cycle}, + {"ATEPKTTXTIME", set_ate_pkt_tx_time}, + {"ATECTRLBANDIDX", set_ate_control_band_idx}, +#ifdef MT7615 + {"ATECHANNELEXT", set_ate_channel_ext}, + {"ATESTARTTXEXT", set_ate_start_tx_ext}, +#endif /* MT7615 */ + {"ATEINITCHAN", SetATEInitChan}, +#ifdef RTMP_TEMPERATURE_CALIBRATION + {"ATETEMPCAL", SetATETempCal}, + {"ATESHOWTSSI", SetATEShowTssi}, +#endif /* RTMP_TEMPERATURE_CALIBRATION */ + {"ATETXPOW0", SetATETxPower0}, + {"ATETXPOW1", SetATETxPower1}, + {"ATETXPOW2", SetATETxPower2}, + {"ATETXPOW3", SetATETxPower3}, + {"ATEFORCETXPOWER", SetATEForceTxPower}, + {"ATETXPOWEVAL", SetATETxPowerEvaluation}, + {"ATETXANT", SetATETxAntenna}, + {"ATERXANT", SetATERxAntenna}, + {"ATERFPOWER", SetATERFPower}, + {"ATEDIGITALPOWER", SetATEDigitalPower}, + {"ATEDCOFFSETI", SetATEDCOffset_I}, + {"ATEDCOFFSETQ", SetATEDCOffset_Q}, + {"ATETXFREQOFFSET", SetATETxFreqOffset}, + {"ATETXBW", SetATETxBw}, + {"ATETXLEN", SetATETxLength}, + {"ATETXCNT", SetATETxCount}, + {"ATETXMCS", SetATETxMcs}, + {"ATEVHTNSS", SetATEVhtNss}, + {"ATETXLDPC", SetATETxLdpc}, + {"ATETXSTBC", SetATETxStbc}, + {"ATETXMODE", SetATETxMode}, + {"ATETXGI", SetATETxGi}, + {"ATERXFER", SetATERxFer}, + {"ATERRF", SetATEReadRF}, +#if (!defined(RTMP_RF_RW_SUPPORT)) && (!defined(RLT_RF)) + {"ATEWRF1", SetATEWriteRF1}, + {"ATEWRF2", SetATEWriteRF2}, + {"ATEWRF3", SetATEWriteRF3}, + {"ATEWRF4", SetATEWriteRF4}, +#endif /* (!defined(RTMP_RF_RW_SUPPORT)) && (!defined(RLT_RF)) */ + {"ATELDE2P", SetATELoadE2p}, + {"ATERE2P", SetATEReadE2p}, +#ifdef LED_CONTROL_SUPPORT +#endif /* LED_CONTROL_SUPPORT */ + {"ATEAUTOALC", SetATEAutoAlc}, + {"ATETEMPSENSOR", SetATETempSensor}, + {"ATEIPG", SetATEIpg}, + {"ATEPAYLOAD", SetATEPayload}, + {"ATEFIXEDPAYLOAD", SetATEFixedPayload}, +#ifdef TXBF_SUPPORT +#ifdef MT_MAC + {"ATETxBfInit", SetATETxBfDutInitProc}, + {"ATETxBfGdInit", SetATETxBfGdInitProc}, + {"ATETxBfChanProfileUpdate", SetATETxBfChanProfileUpdate}, + {"ATETXBF", SetATETXBFProc}, + {"ATETXSOUNDING", SetATETxSoundingProc}, + {"ATEIBfGdCal", SetATEIBfGdCal}, + {"ATEIBfInstCal", SetATEIBfInstCal}, + {"ATETxBfLnaGain", SetATETxBfLnaGain}, + {"ATEIBfProfileConfig", SetATEIBfProfileUpdate}, + {"ATEEBfProfileConfig", SetATEEBfProfileConfig}, + {"ATETxBfProfileRead", SetATETxBfProfileRead}, + {"ATETxPacketWithBf", SetATETxPacketWithBf}, + {"ATEIBFPhaseE2pUpdate", SetATETxBfPhaseE2pUpdate}, + {"ATEIBFPhaseComp", SetATEIBfPhaseComp}, + {"ATEIBFPhaseVerify", SetATEIBfPhaseVerify}, + {"ATEConTxETxBfGdProc", SetATEConTxETxBfGdProc}, + {"ATEConTxETxBfInitProc", SetATEConTxETxBfInitProc}, + {"ATESPE", SetATESpeIdx}, + {"ATETXEBF", SetATEEBfTx}, + {"ATEEBFCE", SetATEEBFCE}, + {"ATEEBFCEInfo", SetATEEBFCEInfo}, + {"ATEEBFCEHELP", SetATEEBFCEHelp}, +#endif +#endif /* TXBF_SUPPORT */ + {"ATETTR", SetATETtr}, + {"ATESHOW", SetATEShow}, + {"ATEHELP", SetATEHelp}, +#ifdef CONFIG_QA + {"TxStop", SetTxStop}, + {"RxStop", SetRxStop}, +#ifdef DBG + {"EERead", SetEERead}, + {"EEWrite", SetEEWrite}, + {"BBPRead", SetBBPRead}, + {"BBPWrite", SetBBPWrite}, +#endif /* DBG */ +#endif /* CONFIG_QA */ + +#if defined(MT7615) + +#ifdef SINGLE_SKU_V2 + {"ATESINGLESKU", SetATESingleSKUEn}, +#endif /* SINGLE_SKU_V2 */ + + {"BFBackoffMode", SetATEBFBackoffMode}, + {"ATEPowerPercent", SetATEPowerPercentEn}, + {"ATEPowerDropLevel", SetATEPowerPercentCtrl}, + {"ATEBFBackoff", SetATEBFBackoffEn}, + {"ATETempComp", SetATETempCompEn}, + {"ATETSSI", SetATETSSIEn}, + {"ATETXPOWERCTRL", SetATETxPowerCtrlEn}, +#endif /* defined(MT7615) */ + +#endif /* CONFIG_ATE */ + +#ifdef APCLI_SUPPORT + {"ApCliEnable", Set_ApCli_Enable_Proc}, + {"ApCliSsid", Set_ApCli_Ssid_Proc}, + {"ApCliBssid", Set_ApCli_Bssid_Proc}, + {"ApCliAuthMode", Set_SecAuthMode_Proc}, + {"ApCliEncrypType", Set_SecEncrypType_Proc}, + {"ApCliDefaultKeyID", Set_SecDefaultKeyID_Proc}, + {"ApCliWPAPSK", Set_SecWPAPSK_Proc}, + {"ApCliKey1", Set_SecKey1_Proc}, + {"ApCliKey2", Set_SecKey2_Proc}, + {"ApCliKey3", Set_SecKey3_Proc}, + {"ApCliKey4", Set_SecKey4_Proc}, + {"ApCliTxMode", Set_ApCli_TxMode_Proc}, + {"ApCliTxMcs", Set_ApCli_TxMcs_Proc}, +#ifdef APCLI_CONNECTION_TRIAL + /* + for Trial the root AP which locates on another channel + what if the connection is ok, it will make BSSID switch to the new channel. + */ + {"ApCliTrialCh", Set_ApCli_Trial_Ch_Proc}, +#endif /* APCLI_CONNECTION_TRIAL */ +#ifdef DBDC_MODE + {"ApCliWirelessMode", Set_ApCli_WirelessMode_Proc}, +#endif /*DBDC_MODE*/ +#ifdef APCLI_AUTO_CONNECT_SUPPORT + {"ApCliAutoConnect", Set_ApCli_AutoConnect_Proc}, +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ + +#ifdef MAC_REPEATER_SUPPORT + {"MACRepeaterEn", Set_ReptMode_Enable_Proc}, + {"CliLinkMAP", Set_Cli_Link_Map_Proc}, +#endif /* MAC_REPEATER_SUPPORT */ + +#ifdef WSC_AP_SUPPORT + {"ApCliWscSsid", Set_AP_WscSsid_Proc}, + {"ApCliWscScanMode", Set_ApCli_WscScanMode_Proc}, +#endif /* WSC_AP_SUPPORT */ + +#ifdef APCLI_CERT_SUPPORT + {"ApCliCertEnable", Set_ApCli_Cert_Enable_Proc}, + /* Add for APCLI PMF 5.3.3.3 option test item. (Only Tx De-auth Req. and make sure the pkt can be Encrypted) */ + {"ApCliTxDeAuth", ApCliTxDeAuth}, +#endif /* APCLI_CERT_SUPPORT */ + +#ifdef WSC_AP_SUPPORT + {"WpsCertEnable", Set_Wps_Cert_Enable_Proc}, +#endif + + +#ifdef DOT11W_PMF_SUPPORT + {"ApCliPMFMFPC", Set_ApCliPMFMFPC_Proc}, + {"ApCliPMFMFPR", Set_ApCliPMFMFPR_Proc}, + {"ApCliPMFSHA256", Set_ApCliPMFSHA256_Proc}, +#endif /* DOT11W_PMF_SUPPORT */ +#ifdef ROAMING_ENHANCE_SUPPORT + {"RoamingEnhance", Set_RoamingEnhance_Enable_Proc}, +#endif /* ROAMING_ENHANCE_SUPPORT */ + +#endif /* APCLI_SUPPORT */ +#ifdef WSC_AP_SUPPORT +#ifdef CON_WPS + {"ConWpsApCliMode", Set_ConWpsApCliMode_Proc}, + {"ConWpsApCliDisabled", Set_ConWpsApCliDisabled_Proc}, + {"ConWpsApDisabled", Set_ConWpsApDisabled_Proc}, + {"ConWpsApcliPreferIface", Set_ConWpsApcliAutoPreferIface_Proc}, +#endif /* CON_WPS */ + {"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 VENDOR_FEATURE6_SUPPORT + /* HEX : 32 Length */ + {"WscUUID_E", Set_WscUUID_HEX_E_Proc}, + /* 37 Length */ + {"WscUUID_Str", Set_WscUUID_STR_Proc}, +#endif /* VENDOR_FEATURE6_SUPPORT */ +#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 */ + {"WscAutoTriggerDisable", Set_WscAutoTriggerDisable_Proc}, +#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 DSCP_PRI_SUPPORT + {"DscpPri_2.4G", Set_Dscp_Pri_2G_Proc}, + {"DscpPri_5G", Set_Dscp_Pri_5G_Proc}, +#endif + +#ifdef TXBF_SUPPORT +#if (!defined(MT_MAC)) + {"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}, + {"ITxBfCal", Set_ITxBfCal_Proc}, + {"ITxBfLnaCal", Set_ITxBfLnaCal_Proc}, +#endif /* MT76x2, MT_MAC */ + {"InvTxBfTag", Set_InvTxBfTag_Proc}, + {"ITxBfDivCal", Set_ITxBfDivCal_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}, + + +#ifdef MT_MAC + {"TxBfTxApply", Set_TxBfTxApply}, + {"TriggerSounding", Set_Trigger_Sounding_Proc}, + {"StopSounding", Set_Stop_Sounding_Proc}, + {"StaRecBfUpdate", Set_StaRecBfUpdate}, + {"StaRecBfRead", Set_StaRecBfRead}, + {"TxBfAwareCtrl", Set_TxBfAwareCtrl}, +#ifdef CONFIG_ATE + {"StaRecCmmUpdate", Set_StaRecCmmUpdate}, + {"BssInfoUpdate", Set_BssInfoUpdate}, + {"DevInfoUpdate", Set_DevInfoUpdate}, + {"ManualAssoc", SetATEAssocProc}, +#endif /* CONFIG_ATE */ + {"TxBfPfmuMemAlloc", Set_TxBfPfmuMemAlloc}, + {"TxBfPfmuMemRelease", Set_TxBfPfmuMemRelease}, + {"TxBfPfmuMemAllocMapRead", Set_TxBfPfmuMemAllocMapRead}, + {"TxBfProfileTagHelp", Set_TxBfProfileTag_Help}, + {"TxBfProfileTagInValid", Set_TxBfProfileTag_InValid}, + {"TxBfProfileTagPfmuIdx", Set_TxBfProfileTag_PfmuIdx}, + {"TxBfProfileTagBfType", Set_TxBfProfileTag_BfType}, + {"TxBfProfileTagBw", Set_TxBfProfileTag_DBW}, + {"TxBfProfileTagSuMu", Set_TxBfProfileTag_SuMu}, + {"TxBfProfileTagMemAlloc", Set_TxBfProfileTag_Mem}, + {"TxBfProfileTagMatrix", Set_TxBfProfileTag_Matrix}, + {"TxBfProfileTagSnr", Set_TxBfProfileTag_SNR}, + {"TxBfProfileTagSmtAnt", Set_TxBfProfileTag_SmartAnt}, + {"TxBfProfileTagSeIdx", Set_TxBfProfileTag_SeIdx}, + {"TxBfProfileTagRmsdThrd", Set_TxBfProfileTag_RmsdThrd}, + {"TxBfProfileTagMcsThrd", Set_TxBfProfileTag_McsThrd}, + {"TxBfProfileTagTimeOut", Set_TxBfProfileTag_TimeOut}, + {"TxBfProfileTagDesiredBw", Set_TxBfProfileTag_DesiredBW}, + {"TxBfProfileTagDesiredNc", Set_TxBfProfileTag_DesiredNc}, + {"TxBfProfileTagDesiredNr", Set_TxBfProfileTag_DesiredNr}, + {"TxBfProfileTagRead", Set_TxBfProfileTagRead}, + {"TxBfProfileTagWrite", Set_TxBfProfileTagWrite}, + {"TxBfProfileDataRead", Set_TxBfProfileDataRead}, + {"TxBfProfileDataWrite", Set_TxBfProfileDataWrite}, + {"TxBfProfilePnRead", Set_TxBfProfilePnRead}, + {"TxBfProfilePnWrite", Set_TxBfProfilePnWrite}, +#ifdef TXBF_DYNAMIC_DISABLE + {"TxBfDisable", Set_TxBfDynamicDisable_Proc}, +#endif /* TXBF_DYNAMIC_DISABLE */ +#endif /* MT_MAC */ + +#endif /* TXBF_SUPPORT */ +#ifdef VHT_TXBF_SUPPORT + {"VhtNDPA", Set_VhtNDPA_Sounding_Proc}, +#endif /* VHT_TXBF_SUPPORT */ + +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + {"wf_fwd", Set_WifiFwd_Proc}, + {"wf_fwd_down", Set_WifiFwd_Down}, + {"wf_fwd_acs", Set_WifiFwdAccessSchedule_Proc}, + {"wf_fwd_hij", Set_WifiFwdHijack_Proc}, + {"wf_fwd_bpdu", Set_WifiFwdBpdu_Proc}, + {"wf_fwd_rep", Set_WifiFwdRepDevice}, + {"wf_fwd_show", Set_WifiFwdShowEntry}, + {"wf_fwd_del", Set_WifiFwdDeleteEntry}, + {"pkt_src_show", Set_PacketSourceShowEntry}, + {"pkt_src_del", Set_PacketSourceDeleteEntry}, + {"wf_fwd_bridge", Set_WifiFwdBridge_Proc}, +#endif /* CONFIG_WIFI_PKT_FWD */ + + +#ifdef MT_MAC +#ifdef DBG + {"FixedRate", Set_Fixed_Rate_Proc}, + {"FixedRateFallback", Set_Fixed_Rate_With_FallBack_Proc}, + {"RaDebug", Set_RA_Debug_Proc}, +#endif /* DBG */ +#endif /* MT_MAC */ + + +#ifdef STREAM_MODE_SUPPORT + {"StreamMode", Set_StreamMode_Proc}, + {"StreamModeMac", Set_StreamModeMac_Proc}, + {"StreamModeMCS", Set_StreamModeMCS_Proc}, +#endif /* STREAM_MODE_SUPPORT */ + + {"LongRetry", Set_LongRetryLimit_Proc}, + {"ShortRetry", Set_ShortRetryLimit_Proc}, + {"AutoFallBack", Set_AutoFallBack_Proc}, +#ifdef RTMP_MAC_PCI +#ifdef DBG_DIAGNOSE + {"DiagOpt", Set_DiagOpt_Proc}, + {"diag_cond", Set_diag_cond_Proc}, +#endif /* DBG_DIAGNOSE */ +#endif /* RTMP_MAC_PCI */ + + {"MeasureReq", Set_MeasureReq_Proc}, + {"TpcReq", Set_TpcReq_Proc}, + {"TpcReqByAddr", Set_TpcReqByAddr_Proc}, + {"PwrConstraint", Set_PwrConstraint}, +#ifdef TPC_SUPPORT + {"TpcCtrl", Set_TpcCtrl_Proc}, + {"TpcEn", Set_TpcEnable_Proc}, +#endif /* TPC_SUPPORT */ +#ifdef DOT11K_RRM_SUPPORT + {"BcnReq", Set_BeaconReq_Proc}, + {"BcnReqRandInt", Set_BeaconReq_RandInt_Proc}, + {"LinkReq", Set_LinkMeasureReq_Proc}, + {"RrmEnable", Set_Dot11kRRM_Enable_Proc}, + {"TxReq", Set_TxStreamMeasureReq_Proc}, + + + /* only for selftesting and debugging. */ + {"rrm", Set_RRM_Selftest_Proc}, +#endif /* DOT11K_RRM_SUPPORT */ + {"RegDomain", Set_Reg_Domain_Proc}, +#ifdef CONFIG_DOT11V_WNM + {"WNMCertEnable", Set_WNMCertEnable_Proc}, +#endif +#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 DOT11R_FT_SUPPORT + {"ft", FT_Ioctl}, + {"ftenable", Set_FT_Enable}, + {"ftmdid", Set_FT_Mdid}, + {"ftr0khid", Set_FT_R0khid}, + {"ftric", Set_FT_RIC}, + {"ftotd", Set_FT_OTD}, +#endif /* DOT11R_FT_SUPPORT */ + +#ifdef RTMP_EFUSE_SUPPORT + {"efuseLoadFromBin", set_eFuseLoadFromBin_Proc}, /* For backward compatible, the usage is the same as bufferLoadFromBin + bufferWriteBack */ + {"efuseFreeNumber", set_eFuseGetFreeBlockCount_Proc}, + {"efuseDump", set_eFusedump_Proc}, +#ifdef CONFIG_ATE + {"bufferLoadFromEfuse", Set_LoadEepromBufferFromEfuse_Proc}, +#ifdef BB_SOC + {"efuseBufferModeWriteBack", set_BinModeWriteBack_Proc}, +#else + {"efuseBufferModeWriteBack", set_eFuseBufferModeWriteBack_Proc}, /* For backward compatible, the usage is the same as bufferWriteBack */ +#endif +#endif /* CONFIG_ATE */ +#endif /* RTMP_EFUSE_SUPPORT */ + {"bufferLoadFromBin", Set_LoadEepromBufferFromBin_Proc}, + {"bufferWriteBack", Set_EepromBufferWriteBack_Proc}, + {"bufferMode", Set_bufferMode_Proc}, + +#ifdef CAL_FREE_IC_SUPPORT + {"bufferLoadFromCalFree", Set_LoadCalFreeData_Proc}, + {"CheckCalFree", Set_CheckCalFree_Proc}, +#endif + +#ifdef RF_LOCKDOWN + {"CalFreeApply", SetCalFreeApply}, + {"WriteEffuseRFpara", SetWriteEffuseRFpara}, +#endif /* RF_LOCKDOWN */ + +#ifdef RTMP_RBUS_SUPPORT +#ifdef LED_CONTROL_SUPPORT + {"WlanLed", Set_WlanLed_Proc}, +#endif /* LED_CONTROL_SUPPORT */ +#endif /* RTMP_RBUS_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}, + +#ifdef THERMAL_PROTECT_SUPPORT + {"tpc", set_thermal_protection_criteria_proc}, + {"tpc_duty", set_thermal_protection_admin_ctrl_duty_proc}, +#endif /* THERMAL_PROTECT_SUPPORT */ + +#ifdef SMART_ANTENNA + {"sa", Set_SmartAnt_Proc}, + {"sa_msc", Set_McsStableCnt_Proc}, + {"sa_mcs", Set_SA_McsBound_Proc}, + {"sa_sta", Set_SA_Station_Proc}, + {"sa_starule", Set_SA_StationCandRule_Proc}, + {"sa_mode", Set_SA_Mode_Proc}, + {"sa_txNss", set_SA_txNss_Proc}, + {"sa_ant", Set_SA_StaticAntPair_Proc}, + {"sa_agsp", Set_SA_AGSP_Proc}, + {"sa_tseq", Set_SA_TrainSeq_Proc}, + {"sa_tdelay", Set_SA_TrainDelay_Proc}, + {"sa_tcond", Set_SA_TrainCond_Proc}, + {"sa_rssivar", Set_SA_RssiVariance_Proc}, + {"sa_rssith", Set_SA_RssiThreshold_Proc}, + {"sa_skipconf", Set_SA_SkipConfirmStage_Proc}, + {"sa_tcand", Set_SA_AntCand_Proc}, + {"sa_tp", Set_TestPeriod_Proc}, + {"sa_tc", Set_MaxAntennaTry_Proc}, + {"sa_dbg", Set_DbgLogOn_Proc}, +#endif /* SMART_ANTENNA // */ + + {"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 DOT11W_PMF_SUPPORT + {"PMFMFPC", Set_PMFMFPC_Proc}, + {"PMFMFPR", Set_PMFMFPR_Proc}, + {"PMFSHA256", Set_PMFSHA256_Proc}, + {"PMFSA_Q", Set_PMFSA_Q_Proc}, +#endif /* DOT11W_PMF_SUPPORT */ + +#ifdef MICROWAVE_OVEN_SUPPORT + {"MO_FalseCCATh", Set_MO_FalseCCATh_Proc}, +#endif /* MICROWAVE_OVEN_SUPPORT */ + + {"no_bcn", set_no_bcn}, + +#if defined(WFA_VHT_PF) || defined(MT7603_FPGA) || defined(MT7628_FPGA) || defined(MT7636_FPGA) || defined(MT7637_FPGA) + {"force_amsdu", set_force_amsdu}, +#endif /* defined(WFA_VHT_PF) || defined(MT7603_FPGA) */ + +#ifdef WFA_VHT_PF + {"nss_mcs_opt", set_vht_nss_mcs_opt}, /* SIGMA */ + {"opt_md_notif_ie", set_vht_opmode_notify_ie}, /* SIGMA */ + {"force_op", set_force_operating_mode}, + {"force_noack", set_force_noack}, + {"force_vht_sgi", set_force_vht_sgi}, + {"force_vht_stbc", set_force_vht_tx_stbc}, + {"ext_cca", set_force_ext_cca}, +#endif /* WFA_VHT_PF */ + {"rf", SetRF}, + {"tssi_enable", set_tssi_enable}, +#ifdef DYNAMIC_VGA_SUPPORT + {"DyncVgaEnable", Set_DyncVgaEnable_Proc}, + {"fc_hth", set_false_cca_hi_th}, + {"fc_lth", set_false_cca_low_th}, +#endif /* DYNAMIC_VGA_SUPPORT */ +#ifdef MT_MAC + {"TimEnable", Set_AP_TimEnable_Proc},/* only for development purpose!! iwpriv ra0 set */ + {"TmrVer", setTmrVerProc}, + {"TmrEnable", setTmrEnableProc},/* 0: disalbe, 1: initialiter, 2: responser. */ + {"TmrCal", SetTmrCalProc}, +#ifdef FTM_SUPPORT + {"FtmReq", Set_FtmReqTx_Proc}, + {"FtmAsap", Set_FtmAsapReq_Proc}, + {"FtmMinDelta", Set_FtmMinDelta_Proc}, + {"FtmNum", Set_FtmNum_Proc}, + {"FtmBurstExp", Set_FtmBurstExp_Proc}, + {"FtmBurstDur", Set_FtmBurstDuration_Proc}, + {"FtmBurstPeriod", Set_FtmBurstPeriod_Proc}, + {"FtmLciValue", Set_FtmLciValue_Proc}, + {"FtmLciLat", Set_FtmLciLat_ThisAP_Proc}, + {"FtmLciLng", Set_FtmLciLng_ThisAP_Proc}, + {"FtmLciAlt", Set_FtmLciAlt_ThisAP_Proc}, + {"FtmLciKnown", Set_FtmLciKnown_Proc}, + {"FtmLci", Set_FtmLciFlag_Proc}, + {"FtmZ", Set_FtmZFlag_Proc}, + {"FtmCivicKnown", Set_FtmCivicKnown_Proc}, + {"FtmCivic", Set_FtmCivicFlag_Proc}, + {"Anqp", Send_ANQP_Req_For_Test}, + {"Nrpt", Send_NeighborReq_For_Test}, + {"RM", Send_RadioMeasurement_Req_For_Test}, + {"RMMinAp", Set_FtmRMMinimumApCount_Proc}, + {"RMRandomInt", Set_FtmRMRandomizationInterval_Proc}, +#endif /* FTM_SUPPORT */ + + /* support CR4 cmds */ + {"cr4_query", set_cr4_query}, + {"cr4_set", set_cr4_set}, + {"cr4_capability", set_cr4_capability}, + {"cr4_debug", set_cr4_debug}, + + + {"dump_remap_cr", dump_remap_cr_content}, + {"ReCal", set_re_calibration}, + {"FwPhyOperation", set_fw_phy_operation}, + {"get_fid", set_get_fid}, + {"fwlog", set_fw_log}, + {"isrcmd", set_isr_cmd}, + {"txop", set_txop_cfg}, + {"rts", set_rts_cfg}, + {"fwset", set_fw_cmd}, + {"fwget", get_fw_cmd}, + +#ifdef FW_DUMP_SUPPORT + {"fwdump_maxsize", set_fwdump_max_size}, + {"fwdump_path", set_fwdump_path}, + {"fwdump_print", fwdump_print}, +#endif + {"protect", set_manual_protect}, + {"rdg", set_manual_rdg}, + {"cca_en", set_cca_en}, +#ifdef DBG + {"DumpTime", Set_AP_DumpTime_Proc},/* only for development purpose!! iwpriv ra0 set */ + {"BcnStateCtrl", Set_BcnStateCtrl_Proc},/* only for development purpose!! iwpriv ra0 set */ + {"trigger_tim", set_tim_update_proc}, +#endif +#ifdef CUT_THROUGH + {"cut_through", Set_CutThrough_Proc}, +#endif /* CUT_THROUGH */ +#ifdef RTMP_MAC_PCI + {"pse_dbg", SetPSEWatchDog_Proc}, + {"pdma_dbg", Set_PDMAWatchDog_Proc}, +#endif + {"get_thermal_sensor", Set_themal_sensor}, +#ifdef CFG_SUPPORT_MU_MIMO + {"hqa_mu_cal_init_mcs", hqa_mu_cal_init_mcs}, + {"hqa_mu_cal_lq", hqa_mu_cal_lq}, + {"hqa_su_cal_lq", hqa_su_cal_lq}, + {"hqa_mu_set_snr_offset", hqa_mu_set_snr_offset}, + {"hqa_mu_set_zero_nss", hqa_mu_set_zero_nss}, + {"hqa_mu_set_speedup_lq", hqa_mu_set_speedup_lq}, + {"hqa_mu_set_mu_tbl", hqa_mu_set_mu_table}, + {"hqa_mu_set_group", hqa_mu_set_group}, + {"hqa_mu_set_enable", hqa_mu_set_enable}, + {"hqa_mu_set_gid_up", hqa_mu_set_gid_up}, + {"hqa_mu_set_trigger_mu_tx", hqa_mu_set_trigger_mu_tx}, + + /* jeffrey, 20141116 */ + /* the followings are relative to MU debbuging/verification, and not use for ATE */ + {"set_mu_profile", SetMuProfileProc}, /* set MU profile */ + {"set_mu_grouptbl", SetGroupTblEntryProc}, /* set group table entry */ + {"set_mu_clustertbl", SetClusterTblEntryProc}, /* set cluster table entry */ + {"set_mu_enable", SetMuEnableProc}, /* set MU enable or disable */ + {"set_mu_groupuserthreshold", SetGroupUserThresholdProc}, /* set group threshold */ + {"set_mu_groupnssthreshold", SetGroupNssThresholdProc}, /* set group NSS */ + {"set_mu_txreqmintime", SetTxReqMinTimeProc}, /* set TX req min. time */ + {"set_mu_calcinitmcs", SetCalculateInitMCSProc}, /* set calculate init MCS */ + {"set_mu_sunsscheck", SetSuNssCheckProc}, /* set enable or disable NSS check */ + {"set_mu_txopdefault", SetTxopDefaultProc}, /* set MU enable or disable */ + {"set_mu_sulossthreshold", SetSuLossThresholdProc}, /* set SU loss threshold */ + {"set_mu_mugainthreshold", SetMuGainThresholdProc}, /* set MU gain threshold */ + {"set_mu_secondaryacpolicy", SetSecondaryAcPolicyProc}, /* set secondary AC policy */ + {"set_mu_grouptbldmcsmask", SetGroupTblDmcsMaskProc}, /* set group table DMCS mask enable or disable */ + {"set_mu_maxgroupsearchcnt", SetMaxGroupSearchCntProc}, /* set Max group search count */ + /* the followings are relative to trigger MU-flow test command */ + {"set_mu_send_gid_mgmt_frame", SetTriggerGIDMgmtFrameProc}, /* set trigger GID mgmt. frame */ + {"set_mu_trigger_mutx", SetTriggerMuTxProc}, /* set trigger MU TX */ + {"set_mu_trigger_degroup", SetTriggerDegroupProc}, /* set trigger MU degrouping */ + {"set_mu_trigger_group", SetTriggerGroupProc}, /* set trigger MU grouping */ + {"set_mu_trigger_bbp", SetTriggerBbpProc}, /* set trigger LQ */ + {"set_mu_trigger_sounding", SetTriggerSndProc}, /* set trigger MU sounding */ + /* the followings are relative to channel model setting */ +#endif + +#ifdef VOW_SUPPORT + /* VOW GROUP table */ + {"vow_min_rate_token", set_vow_min_rate_token}, + {"vow_max_rate_token", set_vow_max_rate_token}, + {"vow_min_airtime_token", set_vow_min_airtime_token}, + {"vow_max_airtime_token", set_vow_max_airtime_token}, + {"vow_min_rate_bucket", set_vow_min_rate_bucket}, + {"vow_max_rate_bucket", set_vow_max_rate_bucket}, + {"vow_min_airtime_bucket", set_vow_min_airtime_bucket}, + {"vow_max_airtime_bucket", set_vow_max_airtime_bucket}, + {"vow_max_wait_time", set_vow_max_wait_time}, + {"vow_max_backlog_size", set_vow_max_backlog_size}, + + + /* VOW CTRL */ + {"vow_bw_enable", set_vow_bw_en}, + {"vow_refill_en", set_vow_refill_en}, + {"vow_airtime_fairness_en", set_vow_airtime_fairness_en}, + {"vow_txop_switch_bss_en", set_vow_txop_switch_bss_en}, + {"vow_dbdc_search_rule", set_vow_dbdc_search_rule}, + {"vow_refill_period", set_vow_refill_period}, + {"vow_bss_enable", set_vow_bss_en}, + + + {"vow_airtime_control_en", set_vow_airtime_ctrl_en}, + {"vow_bw_control_en", set_vow_bw_ctrl_en}, + + /* group other */ + {"vow_bss_dwrr_quantum", set_vow_bss_dwrr_quantum}, + {"vow_group_dwrr_max_wait_time", set_vow_group_dwrr_max_wait_time}, + {"vow_group2band_map", set_vow_group2band_map}, + + /* VOW STA table */ + {"vow_sta_dwrr_quantum", set_vow_sta_dwrr_quantum}, + {"vow_sta_dwrr_quantum_id", set_vow_sta_dwrr_quantum_id}, + {"vow_sta_ac_priority", set_vow_sta_ac_priority}, + {"vow_sta_pause", set_vow_sta_pause}, + {"vow_sta_psm", set_vow_sta_psm}, + {"vow_sta_group", set_vow_sta_group}, + {"vow_dwrr_max_wait_time", set_vow_dwrr_max_wait_time}, + + /* STA fast round robin */ + {"vow_sta_frr_quantum", set_vow_sta_frr_quantum}, + + /* USER */ + {"vow_min_rate", set_vow_min_rate}, + {"vow_max_rate", set_vow_max_rate}, + {"vow_min_ratio", set_vow_min_ratio}, + {"vow_max_ratio", set_vow_max_ratio}, + + /* RX airtime */ + {"vow_rx_counter_clr", set_vow_rx_counter_clr}, + {"vow_rx_airtime_en", set_vow_rx_airtime_en}, + {"vow_rx_ed_offset", set_vow_rx_ed_offset}, + {"vow_rx_obss_backoff", set_vow_rx_obss_backoff}, + /* {"vow_rx_add_obss", set_vow_rx_add_obss}, */ + /* {"vow_rx_add_non_wifi", set_vow_rx_add_non_wifi}, */ + {"vow_rx_wmm_backoff", set_vow_rx_wmm_backoff}, + {"vow_om_wmm_backoff", set_vow_rx_om_wmm_backoff}, + {"vow_repeater_wmm_backoff", set_vow_rx_repeater_wmm_backoff}, + {"vow_rx_non_qos_backoff", set_vow_rx_non_qos_backoff}, + {"vow_rx_bss_wmmset", set_vow_rx_bss_wmmset}, + {"vow_rx_om_wmm_sel", set_vow_rx_om_wmm_select}, + + /* airtime estimator */ + {"vow_at_est_en", set_vow_at_est_en}, + {"vow_at_mon_period", set_vow_at_mon_period}, + + /* badnode detector */ + {"vow_bn_en", set_vow_bn_en}, + {"vow_bn_mon_period", set_vow_bn_mon_period}, + {"vow_bn_fallback_th", set_vow_bn_fallback_th}, + {"vow_bn_per_th", set_vow_bn_per_th}, + + /* airtime counter test */ + {"vow_counter_test", set_vow_counter_test_en}, + {"vow_counter_test_period", set_vow_counter_test_period}, + {"vow_counter_test_band", set_vow_counter_test_band}, + {"vow_counter_test_avgcnt", set_vow_counter_test_avgcnt}, + {"vow_counter_test_target", set_vow_counter_test_target}, + + /* DVT */ + {"vow_dvt_en", set_vow_dvt_en}, + {"vow_monitor_sta", set_vow_monitor_sta}, + {"vow_show_sta", set_vow_show_sta}, + {"vow_monitor_bss", set_vow_monitor_bss}, + {"vow_monitor_mbss", set_vow_monitor_mbss}, + {"vow_show_mbss", set_vow_show_mbss}, + {"vow_avg_num", set_vow_avg_num}, + + /*WATF*/ + {"vow_watf_en", set_vow_watf_en}, + {"vow_watf_q", set_vow_watf_q}, + {"vow_watf_add_entry", set_vow_watf_add_entry}, + {"vow_watf_del_entry", set_vow_watf_del_entry}, + + + /* help */ + {"vow_help", set_vow_help}, + + + + /* + {"vow_rx_add_obss", set_vow_rx_add_obss}, + {"vow_rx_add_non_wifi", set_vow_rx_add_non_wifi}, + */ +#endif /* VOW_SUPPORT */ + +#ifdef RED_SUPPORT + {"red_en", set_red_enable}, + {"red_show_sta", set_red_show_sta}, + {"red_tar_delay", set_red_target_delay}, + {"red_debug_en", set_red_debug_enable}, + {"red_dump_reset", set_red_dump_reset}, +#endif /* RED_SUPPORT */ +#ifdef FQ_SCH_SUPPORT + {"fq_en", set_fq_enable}, + {"fq_debug_en", set_fq_debug_enable}, + {"fq_listmap", set_fq_dbg_listmap}, + {"fq_linklist", set_fq_dbg_linklist}, +#endif /* RRSCH_SUPPORT */ + {"cp_support", set_cp_support_en}, + {"RxvRecordEn", SetRxvRecordEn}, + {"RxRateRecordEn", SetRxRateRecordEn}, +#ifdef CFG_SUPPORT_MU_MIMO_RA + {"mura_periodic_sounding", SetMuraPeriodicSndProc}, /* set trigger MURGA Algorithm sounding */ + {"mura_algorithm_test", SetMuraTestAlgorithmProc}, + {"mura_algorithm_init", SetMuraTestAlgorithmInit}, + {"mura_algorithm_fixed", SetMuraFixedRateProc}, + {"mura_algorithm_fixed_group", SetMuraFixedGroupRateProc}, + {"mura_sounding_fixed_param", SetMuraFixedSndParamProc}, + {"mura_disabe_CN3_CN4", SetMuraDisableCN3CN4Proc}, + {"mura_mobility_en", SetMuraMobilityCtrlProc}, + {"mura_mobility_interval_ctrl", SetMuraMobilityIntervalCtrlProc}, + {"mura_mobility_snr_ctrl", SetMuraMobilitySNRCtrlProc}, + {"mura_mobility_threshold_ctrl", SetMuraMobilityThresholdCtrlProc}, + {"mura_mobility_snd_cnt", SetMuraMobilitySndCountProc}, + {"mura_mobility_mode_ctrl", SetMuraMobilityModeCtrlProc}, + {"mura_mobility_log_ctrl", SetMuraMobilityLogCtrlProc}, + {"mura_mobility_test_ctrl", SetMuraMobilityTestCtrlProc}, +#endif + +#endif /* MT_MAC */ +#ifdef BACKGROUND_SCAN_SUPPORT + {"bgndscan", set_background_scan}, + {"bgndscantest", set_background_scan_test}, + {"bgndscannotify", set_background_scan_notify}, + {"bgndscancfg", set_background_scan_cfg}, +#endif /* BACKGROUND_SCAN_SUPPORT */ +#ifdef NEW_SET_RX_STREAM + {"RxStream", Set_RxStream_Proc}, +#endif +#ifdef ERR_RECOVERY + {"ErrDetectOn", Set_ErrDetectOn_Proc}, + {"ErrDetectMode", Set_ErrDetectMode_Proc}, +#endif /* ERR_RECOVERY */ +#ifdef CUT_THROUGH + {"CtLowWaterMark", Set_CtLowWaterMark_Proc}, +#endif /*CUT_THROUGH*/ +#ifdef SMART_CARRIER_SENSE_SUPPORT + {"SCSEnable", Set_SCSEnable_Proc}, + {"SCSCfg", Set_SCSCfg_Proc}, + {"SCSPd", Set_SCSPd_Proc}, +#endif /* SMART_CARRIER_SENSE_SUPPORT */ +#ifdef BAND_STEERING + {"BndStrgEnable", Set_BndStrg_Enable}, + {"BndStrgBssIdx", Set_BndStrg_BssIdx}, + {"BndStrgParam", Set_BndStrg_Param}, +#ifdef BND_STRG_DBG + {"BndStrgMntAddr", Set_BndStrg_MonitorAddr}, +#endif /* BND_STRG_DBG */ +#endif /* BAND_STEERING */ + +#ifdef TXPWRMANUAL + {"TxPwrManualSet", SetTxPwrManualCtrl}, +#endif /* TXPWRMANUAL */ + + {"SKUCtrl", SetSKUCtrl}, + {"PercentageCtrl", SetPercentageCtrl}, + {"PowerDropCtrl", SetPowerDropCtrl}, + {"BFBackoffCtrl", SetBfBackoffCtrl}, + {"ThermoCompCtrl", SetThermoCompCtrl}, + {"RFTxAnt", SetRfTxAnt}, + {"TxPowerInfo", SetTxPowerInfo}, + {"TOAECtrl", SetTOAECtrl}, + {"EDCCACtrl", SetEDCCACtrl}, + {"SKUInfo", SetSKUInfo}, + {"BFBackoffInfo", SetBFBackoffInfo}, + {"CCKTxStream", SetCCKTxStream}, +#ifdef ETSI_RX_BLOCKER_SUPPORT + {"ETSISetFixWbIbRssiCtrl", SetFixWbIbRssiCtrl}, + {"ETSISetRssiThCtrl", SetRssiThCtrl}, + {"ETSISetCheckThCtrl", SetCheckThCtrl}, + {"ETSISetAdaptRxBlockCtrl", SetAdaptRxBlockCtrl}, + {"ETSISetWbRssiDirectCtrl", SetWbRssiDirectCtrl}, + {"ETSISetIbRssiDirectCtrl", SetIbRssiDirectCtrl}, +#endif /* end ETSI_RX_BLOCKER_SUPPORT */ + {"MUTxPower", SetMUTxPower}, + {"BFNDPATxDCtrl", SetBFNDPATxDCtrl}, + {"TxPowerCompInfo", SetTxPowerCompInfo}, + {"ThermalManualMode", SetThermalManualCtrl}, +#ifdef TX_POWER_CONTROL_SUPPORT + {"TxPowerBoostCtrl", SetTxPowerBoostCtrl}, +#endif + +#ifdef LED_CONTROL_SUPPORT + {"led_setting", Set_Led_Proc}, +#endif /* LED_CONTROL_SUPPORT */ +#ifdef PRE_CAL_TRX_SET1_SUPPORT + {"ktoflash_debug", Set_KtoFlash_Debug_Proc}, + {"RDCE", Set_RDCE_Proc}, +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ + {"hw_nat_register", set_hnat_register}, + {"MibBucket", Set_MibBucket_Proc}, +#ifdef RLM_CAL_CACHE_SUPPORT + {"rlm_cal_cache", Set_RLM_Cal_Cache_Debug_Proc}, +#endif /* RLM_CAL_CACHE_SUPPORT */ +#ifdef PKT_BUDGET_CTRL_SUPPORT + {"pbc_ubound", Set_PBC_Proc}, +#endif /*PKT_BUDGET_CTRL_SUPPORT*/ + {"bwf", Set_BWF_Enable_Proc}, +#ifdef TX_AGG_ADJUST_WKR + {"agg_adj_wkr", Set_AggAdjWkr_Proc}, +#endif /* TX_AGG_ADJUST_WKR */ +#ifdef HTC_DECRYPT_IOT + {"htc_th", Set_HTC_Err_TH_Proc}, + {"htc_entry_err_cnt", Set_Entry_HTC_Err_Cnt_Proc}, + {"wtbl_addom", Set_WTBL_AAD_OM_Proc}, +#endif /* HTC_DECRYPT_IOT */ +#ifdef DHCP_UC_SUPPORT + {"dhcp_uc", Set_DHCP_UC_Proc}, +#endif /* DHCP_UC_SUPPORT */ +#ifdef CONFIG_HOTSPOT_R2 + {"hs_flag", Set_CR4_Hotspot_Flag}, +#endif /* CONFIG_HOTSPOT_R2 */ + + {"ser", set_ser}, +#ifdef CONFIG_TX_DELAY + {"tx_batch_cnt", Set_TX_Batch_Cnt_Proc}, + {"tx_delay_timeout", Set_TX_Delay_Timeout_Proc}, + {"tx_pkt_min_len", Set_Pkt_Min_Len_Proc}, + {"tx_pkt_max_len", Set_Pkt_Max_Len_Proc}, +#endif + {"fix_amsdu", set_fix_amsdu}, + {"rx_max_cnt", set_rx_max_cnt}, + {"rx1_max_cnt", set_rx1_max_cnt}, +#ifdef MBO_SUPPORT + {"mbo_nr", SetMboNRIndicateProc}, +#endif /* MBO_SUPPORT */ + {"rx_delay_ctl", set_rx_dly_ctl}, + {"tx_delay_ctl", set_tx_dly_ctl}, + {"vie_op", vie_oper_proc}, + {NULL,} +}; + +static struct { + RTMP_STRING *name; + INT (*set_proc)(RTMP_ADAPTER *pAd, RTMP_STRING *arg); +} *PRTMP_PRIVATE_SHOW_PROC, RTMP_PRIVATE_SHOW_SUPPORT_PROC[] = { + {"stainfo", Show_MacTable_Proc}, +#ifdef MEM_ALLOC_INFO_SUPPORT + {"meminfo", Show_MemInfo_Proc}, + {"pktmeminfo", Show_PktInfo_Proc}, +#endif /* MEM_ALLOC_INFO_SUPPORT */ +#ifdef MT_MAC + {"psinfo", Show_PSTable_Proc}, + {"wtbl", show_wtbl_proc}, + {"wtbltlv", show_wtbltlv_proc}, + {"mibinfo", show_mib_proc}, + {"amsduinfo", show_amsdu_proc}, + {"wifi_sys", show_wifi_sys}, +#ifdef DBDC_MODE + {"dbdcinfo", ShowDbdcProc}, +#endif + {"channelinfo", ShowChCtrl}, +#ifdef GREENAP_SUPPORT + {"greenapinfo", ShowGreenAPProc}, +#endif /* GREENAP_SUPPORT */ +#ifdef PCIE_ASPM_DYM_CTRL_SUPPORT + {"pcieaspminfo", show_pcie_aspm_dym_ctrl_cap_proc}, +#endif /* PCIE_ASPM_DYM_CTRL_SUPPORT */ + {"txopinfo", show_tx_burst_info}, + {"tmacinfo", ShowTmacInfo}, + {"agginfo", ShowAggInfo}, + {"manual_txop", ShowManualTxOP}, + {"pseinfo", ShowPseInfo}, + {"psedata", ShowPseData}, + {"pleinfo", ShowPLEInfo}, + {"txdinfo", show_TXD_proc}, + {"dumpmem", show_mem_proc}, + {"protectinfo", show_protect_info}, + {"ccainfo", show_cca_info}, +#ifdef MT_FDB + {"fdbn9log", show_fdb_n9_log}, + {"fdbcr4log", show_fdb_cr4_log}, +#endif /* MT_FDB */ +#ifdef CUT_THROUGH + {"ctinfo", ShowCutThroughInfo}, +#endif /* CUT_THROUGH */ + + {"dschinfo", show_dmasch_proc}, + +#endif /* MT_MAC */ + {"sta_tr", Show_sta_tr_proc}, + {"peerinfo", show_stainfo_proc}, + {"stacountinfo", Show_StaCount_Proc}, + {"secinfo", Show_APSecurityInfo_Proc}, + {"descinfo", Show_DescInfo_Proc}, + {"driverinfo", show_driverinfo_proc}, + {"apcfginfo", show_apcfg_info}, + {"devinfo", show_devinfo_proc}, + {"sysinfo", show_sysinfo_proc}, + {"trinfo", show_trinfo_proc}, + {"tpinfo", show_tpinfo_proc}, + {"pwrinfo", chip_show_pwr_info}, + {"txqinfo", show_txqinfo_proc}, + {"swqinfo", show_swqinfo}, + {"efuseinfo", show_efuseinfo_proc}, + {"e2pinfo", show_e2pinfo_proc}, + {"cr4_pdma_probe", dump_cr4_pdma_debug_probe}, +#ifdef WDS_SUPPORT + {"wdsinfo", Show_WdsTable_Proc}, +#endif /* WDS_SUPPORT */ +#ifdef DOT11_N_SUPPORT + {"bainfo", Show_BaTable_Proc}, + {"channelset", Show_ChannelSet_Proc}, +#endif /* DOT11_N_SUPPORT */ + {"stat", Show_Sat_Proc}, +#ifdef RTMP_MAC_PCI +#ifdef DBG_DIAGNOSE + {"diag", Show_Diag_Proc}, +#endif /* DBG_DIAGNOSE */ +#endif /* RTMP_MAC_PCI */ + {"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 MT_DFS_SUPPORT + {"DfsProvideChList", Show_available_BwCh_Proc}, + {"DfsNOP", Show_DfsNonOccupancy_Proc}, + {"DfsNOPOfChList", Show_NOP_Of_ChList}, + {"DfsTargetInfo", Show_Target_Ch_Info}, +#endif +#ifdef DOT11R_FT_SUPPORT + {"ftinfo", Show_FTConfig_Proc}, +#endif /* DOT11R_FT_SUPPORT */ +#ifdef DOT11K_RRM_SUPPORT + {"rrminfo", RRM_InfoDisplay_Proc}, +#endif /* DOT11K_RRM_SUPPORT */ +#ifdef AP_QLOAD_SUPPORT + {"qload", Show_QoSLoad_Proc}, +#endif /* AP_QLOAD_SUPPORT */ + {"TmrCal", Show_TmrCalResult_Proc}, +#ifdef FTM_SUPPORT +#ifdef FTM_INITIATOR + {"FtmRxTmrQ", Show_FtmRxTmrQ_Proc}, +#endif /* FTM_INITIATOR */ + {"FtmEntry", Show_FtmEntry_Proc}, + {"FtmPidList", Show_FtmPidList_Proc}, + {"FtmLciValue", Show_FtmLciValue_Proc}, +#endif /* FTM_SUPPORT */ +#ifdef APCLI_SUPPORT + {"connStatus", RTMPIoctlConnStatus}, +#endif /* APCLI_SUPPORT */ +#ifdef MAC_REPEATER_SUPPORT + {"reptinfo", Show_Repeater_Cli_Proc}, + {"rept_table", Show_ReptTable_Proc}, +#endif /* MAC_REPEATER_SUPPORT */ +#ifdef SMART_ANTENNA + {"sainfo", Show_SA_CfgInfo_Proc}, + {"sadbginfo", Show_SA_DbgInfo_Proc}, +#endif /* SMART_ANTENNA // */ + + {"rainfo", Show_RAInfo_Proc}, +#ifdef TXBF_SUPPORT + {"txbfinfo", Show_TxBfInfo_Proc}, +#endif /* TXBF_SUPPORT */ +#ifdef MBSS_SUPPORT + {"mbss", Show_MbssInfo_Display_Proc}, +#endif /* MBSS_SUPPORT */ +#ifdef WSC_AP_SUPPORT + {"WscPeerList", WscApShowPeerList}, + {"WscPin", WscApShowPin}, +#endif /* WSC_AP_SUPPORT */ + {"rfinfo", ShowRFInfo}, + {"bbpinfo", ShowBBPInfo}, + {"wfintcnt", ShowWifiInterruptCntProc}, +#ifdef CFG_SUPPORT_MU_MIMO + {"hqa_mu_get_init_mcs", hqa_mu_get_init_mcs}, + {"hqa_mu_get_qd", hqa_mu_get_qd}, + {"hqa_mu_get_lq", hqa_mu_get_lq}, + {"hqa_su_get_lq", hqa_su_get_lq}, + + {"get_mu_enable", ShowMuEnableProc}, /* show mu enable or disable */ + {"get_mu_profile", ShowMuProfileProc}, /* show mu profile entry */ + {"get_mu_grouptbl", ShowGroupTblEntryProc}, /* show group table entry */ + {"get_mu_clustertbl", ShowClusterTblEntryProc}, /* show cluster table entry */ + {"get_mu_groupuserthreshold", ShowGroupUserThresholdProc}, /* show group user threshold */ + {"get_mu_groupnssthreshold", ShowGroupNssThresholdProc}, /* show group NSS threshold */ + {"get_mu_txreqmintime", ShowTxReqMinTimeProc}, /* show tx req. min. time */ + {"get_mu_sunsscheck", ShowSuNssCheckProc}, /* show SU Nss check enable or disable */ + {"get_mu_calcinitmcs", ShowCalcInitMCSProc}, /* show Init MCS */ + {"get_mu_txopdefault", ShowTxopDefaultProc}, /* show TXOP default */ + {"get_mu_sulossthreshold", ShowSuLossThresholdProc}, /* show SU loss threshold */ + {"get_mu_mugainthreshold", ShowMuGainThresholdProc}, /* show MU gain threshold */ + {"get_mu_secondaryacpolicy", ShowSecondaryAcPolicyProc}, /* show secondary AC policay */ + {"get_mu_grouptbldmcsmask", ShowGroupTblDmcsMaskProc}, /* show group table DMCS mask enable or disable */ + {"get_mu_maxgroupsearchcnt", ShowMaxGroupSearchCntProc}, /* show max. group table search count */ + {"get_mu_txstatus", ShowMuProfileTxStsCntProc}, /* show mu profile tx status */ +#endif + +#ifdef CFG_SUPPORT_MU_MIMO_RA + {"mura_algorithm_monitor", GetMuraMonitorStateProc}, + {"get_mura_pfid_stat", GetMuraPFIDStatProc}, +#endif + + {"hwctrl", Show_HwCtrlStatistic_Proc}, + +#ifdef VOW_SUPPORT + /* VOW RX */ + {"vow_rx_time", show_vow_rx_time}, + /* {"vow_get_sta_token", show_vow_get_sta_token}, */ + {"vow_sta_conf", show_vow_sta_conf}, + {"vow_all_sta_conf", show_vow_all_sta_conf}, + {"vow_bss_conf", show_vow_bss_conf}, + {"vow_all_bss_conf", show_vow_all_bss_conf}, + {"vow_info", show_vow_info}, + + /* {"vow_status", show_vow_status} */ + + /* CR dump */ + {"vow_dump_sta", show_vow_dump_sta}, + {"vow_dump_bss_bitmap", show_vow_dump_bss_bitmap}, + {"vow_dump_bss", show_vow_dump_bss}, + {"vow_dump_vow", show_vow_dump_vow}, + {"vow_show_sta_dtoken", vow_show_sta_dtoken}, + {"vow_show_bss_dtoken", vow_show_bss_dtoken}, + {"vow_show_bss_atoken", vow_show_bss_atoken}, + {"vow_show_bss_ltoken", vow_show_bss_ltoken}, + + /* DVT */ + {"vow_show_queue", vow_show_queue_status}, + + /*WATF*/ + {"vow_watf_info", show_vow_watf_info}, + + /* help */ + {"vow_help", show_vow_help}, +#endif /* VOW_SUPPORT */ +#ifdef RED_SUPPORT + {"red_info", show_red_info}, +#endif/* RED_SUPPORT */ +#ifdef FQ_SCH_SUPPORT + {"fq_info", show_fq_info}, +#endif + {"timer_list", show_timer_list}, + {"wtbl_stat", show_wtbl_state}, +#ifdef SMART_CARRIER_SENSE_SUPPORT + {"SCSInfo", Show_SCSinfo_proc}, +#endif /* SMART_CARRIER_SENSE_SUPPORT */ + {"MibBucket", Show_MibBucket_Proc}, +#ifdef REDUCE_TCP_ACK_SUPPORT + {"ReduceAckShow", Show_ReduceAckInfo_Proc}, +#endif + {"EDCCAStatus", ShowEDCCAStatus}, +#ifdef BAND_STEERING + {"BndStrgList", Show_BndStrg_List}, + {"BndStrgInfo", Show_BndStrg_Info}, +#ifdef VENDOR_FEATURE5_SUPPORT + {"BndStrgNvramtable", Show_BndStrg_NvramTable}, +#endif /* VENDOR_FEATURE5_SUPPORT */ +#endif /* BAND_STEERING */ + {"radio_info", show_radio_info_proc}, +#ifdef BACKGROUND_SCAN_SUPPORT + {"bgndscaninfo", show_background_scan_info}, +#endif +#ifdef ERR_RECOVERY + {"serinfo", ShowSerProc}, + {"ser", ShowSerProc2}, +#endif + {"bcninfo", ShowBcnProc}, +#ifdef RADIUS_MAC_ACL_SUPPORT + {"RadiusAclCache", show_RADIUS_acl_cache}, +#endif /* RADIUS_MAC_ACL_SUPPORT */ +#ifdef DBG_STARVATION + {"starv_info", show_starv_info_proc}, +#endif /*DBG_STARVATION*/ +#ifdef TX_POWER_CONTROL_SUPPORT + {"TxPowerBoostInfo", ShowTxPowerBoostInfo}, +#endif /* TX_POWER_CONTROL_SUPPORT */ +#ifdef ETSI_RX_BLOCKER_SUPPORT + {"ETSIShowRssiThInfo", ShowRssiThInfo}, +#endif /* ETSI_RX_BLOCKER_SUPPORT */ + {"qdisc_dump", set_qiscdump_proc}, +#ifdef MBO_SUPPORT + {"mbo", ShowMboStatProc}, +#endif /* MBO_SUPPORT */ + {"l1profile", ShowL1profile}, + {NULL,} +}; + +/** + * @addtogroup embedded_ioctl + * @{ + * @code AP RX IOCTL + */ + +static struct { + RTMP_STRING *name; + INT (*rx_proc)(RTMP_ADAPTER *pAd, RTMP_STRING *arg, RTMP_IOCTL_INPUT_STRUCT *wrq); +} *PRTMP_PRIVATE_RX_PROC, RTMP_PRIVATE_RX_SUPPORT_PROC[] = { +#if defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) + {"stat", Show_Rx_Statistic}, + {"vector", Set_Rx_Vector_Control}, +#endif/* defined(MT7615) || defined(MT7622) || defined(P18) || defined(MT7663) */ + {NULL,} +}; + + +INT RTMPAPPrivIoctlSet( + IN RTMP_ADAPTER *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr) +{ + RTMP_STRING *this_char, *value; + INT Status = NDIS_STATUS_SUCCESS; + + UCHAR *tmp = NULL, *buf = NULL; + + os_alloc_mem(NULL, (UCHAR **)&buf, pIoctlCmdStr->u.data.length + 1); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, pIoctlCmdStr->u.data.pointer, pIoctlCmdStr->u.data.length)) { + os_free_mem(buf); + return -EFAULT; + } + /* Play safe - take care of a situation in which user-space didn't NULL terminate */ + buf[pIoctlCmdStr->u.data.length] = 0; + + /* Use tmp to parse string, because strsep() would change it */ + tmp = buf; + + while ((this_char = strsep((char **)&tmp, ",")) != NULL) { + + if (!*this_char) + continue; + + value = strchr(this_char, '='); + + if (value != NULL) + *value++ = 0; + + if (!value +#ifdef WSC_AP_SUPPORT + && ( + (strcmp(this_char, "WscStop") != 0) && + (strcmp(this_char, "ser") != 0) && +#ifdef BB_SOC + (strcmp(this_char, "WscResetPinCode") != 0) && +#endif + (strcmp(this_char, "WscGenPinCode") != 0) + ) +#endif /* WSC_AP_SUPPORT */ +#ifdef SMART_ANTENNA + && (strcmp(this_char, "sa") != 0) +#endif /* SMART_ANTENNA */ + ) + continue; + + for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++) { + if (!strcasecmp(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; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IOCTL::(iwpriv) Command not Support [%s=%s]\n", this_char, + value)); + break; + } + } + os_free_mem(buf); + + return Status; +} + + +INT RTMPAPPrivIoctlShow( + IN RTMP_ADAPTER *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *pIoctlCmdStr) +{ + RTMP_STRING *this_char, *value = NULL; + INT Status = NDIS_STATUS_SUCCESS; + + UCHAR *tmp = NULL, *buf = NULL; + + os_alloc_mem(NULL, (UCHAR **)&buf, pIoctlCmdStr->u.data.length + 1); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, pIoctlCmdStr->u.data.pointer, pIoctlCmdStr->u.data.length)) { + os_free_mem(buf); + return -EFAULT; + } + /* Play safe - take care of a situation in which user-space didn't NULL terminate */ + buf[pIoctlCmdStr->u.data.length] = 0; + + /* Use tmp to parse string, because strsep() would change it */ + tmp = buf; + + while ((this_char = strsep((char **)&tmp, ",")) != NULL) { + if (!*this_char) + continue; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): Before check, this_char=%s\n", __func__, this_char)); + value = strchr(this_char, '='); + + if (value) { + if (strlen(value) > 1) { + *value = 0; + value++; + } else + value = NULL; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): after check, this_char=%s, value=%s\n", __func__, + this_char, (value == NULL ? "" : value))); + + for (PRTMP_PRIVATE_SHOW_PROC = RTMP_PRIVATE_SHOW_SUPPORT_PROC; PRTMP_PRIVATE_SHOW_PROC->name; + PRTMP_PRIVATE_SHOW_PROC++) { + if (!strcasecmp(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; +#ifdef RTMP_RBUS_SUPPORT + + if (pAd->infType == RTMP_DEV_INF_RBUS) { + for (PRTMP_PRIVATE_SHOW_PROC = RTMP_PRIVATE_SHOW_SUPPORT_PROC; PRTMP_PRIVATE_SHOW_PROC->name; PRTMP_PRIVATE_SHOW_PROC++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s\n", PRTMP_PRIVATE_SHOW_PROC->name)); + } + +#endif /* RTMP_RBUS_SUPPORT */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IOCTL::(iwpriv) Command not Support [%s=%s]\n", this_char, + value)); + break; + } + } + + os_free_mem(buf); + return Status; +} + +#ifdef VENDOR_FEATURE6_SUPPORT +#define ASSO_MAC_LINE_LEN (1+19+4+4+4+4+8+7+7+7+7+10+6+6+6+6+7+7+7+1) +VOID RTMPAPGetAssoMacTable( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT * wrq) +{ + UINT32 DataRate = 0; + INT i; + char *msg; + + os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR) * (MAX_LEN_OF_MAC_TABLE * ASSO_MAC_LINE_LEN)); + + if (msg == NULL) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Alloc memory failed\n", __func__)); + return; + } + + memset(msg, 0, MAX_LEN_OF_MAC_TABLE * ASSO_MAC_LINE_LEN); + sprintf(msg + strlen(msg), "\n%-19s%-4s%-4s%-4s%-4s%-8s", + "MAC", "AID", "BSS", "PSM", "WMM", "MIMOPS"); + sprintf(msg + strlen(msg), "%-7s%-7s%-7s%-7s", "RSSI0", "RSSI1", "RSSI2", "RSSI3"); + sprintf(msg + strlen(msg), "%-10s%-6s%-6s%-6s%-6s%-7s%-7s%-7s\n", "PhMd", "BW", "MCS", "SGI", "STBC", "Idle", "Rate", "TIME"); + + for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; + + if ((IS_ENTRY_CLIENT(pEntry) || (IS_ENTRY_APCLI(pEntry) +#ifdef MAC_REPEATER_SUPPORT + || IS_ENTRY_REPEATER(pEntry) +#endif /* MAC_REPEATER_SUPPORT */ + )) + && (pEntry->Sst == SST_ASSOC)) { + if ((strlen(msg) + ASSO_MAC_LINE_LEN) >= (MAX_LEN_OF_MAC_TABLE * ASSO_MAC_LINE_LEN)) + break; + + DataRate = 0; + DataRate = 0; + /* getRate(pEntry->HTPhyMode, &DataRate); */ + RtmpDrvMaxRateGet(pAd, pEntry->HTPhyMode.field.MODE, pEntry->HTPhyMode.field.ShortGI, + pEntry->HTPhyMode.field.BW, pEntry->HTPhyMode.field.MCS, + (pEntry->MaxHTPhyMode.field.MCS >> 4) + 1, (UINT32 *)&DataRate); + DataRate /= 500000; + sprintf(msg + strlen(msg), "%02X:%02X:%02X:%02X:%02X:%02X ", PRINT_MAC(pEntry->Addr)); + sprintf(msg + strlen(msg), "%-4d", (int)pEntry->Aid); + sprintf(msg + strlen(msg), "%-4d", (int)pEntry->apidx); + sprintf(msg + strlen(msg), "%-4d", (int)pEntry->PsMode); + sprintf(msg + strlen(msg), "%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)); +#ifdef DOT11_N_SUPPORT + sprintf(msg + strlen(msg), "%-8d", (int)pEntry->MmpsMode); +#endif /* DOT11_N_SUPPORT */ + sprintf(msg + strlen(msg), "%-7d%-7d%-7d%-7d", pEntry->RssiSample.AvgRssi[0], pEntry->RssiSample.AvgRssi[1], pEntry->RssiSample.AvgRssi[2], pEntry->RssiSample.AvgRssi[3]); + sprintf(msg + strlen(msg), "%-10s", get_phymode_str(pEntry->HTPhyMode.field.MODE)); + sprintf(msg + strlen(msg), "%-6s", get_bw_str(pEntry->HTPhyMode.field.BW)); +#ifdef DOT11_VHT_AC + + if (pEntry->HTPhyMode.field.MODE == MODE_VHT) + sprintf(msg + strlen(msg), "%dS-M%-3d", ((pEntry->HTPhyMode.field.MCS >> 4) + 1), (pEntry->HTPhyMode.field.MCS & 0xf)); + else +#endif /* DOT11_VHT_AC */ + sprintf(msg + strlen(msg), "%-6d", pEntry->HTPhyMode.field.MCS); + + sprintf(msg + strlen(msg), "%-6d", pEntry->HTPhyMode.field.ShortGI); + sprintf(msg + strlen(msg), "%-6d", pEntry->HTPhyMode.field.STBC); + sprintf(msg + strlen(msg), "%-7d", (int)(pEntry->StaIdleTimeout - pEntry->NoDataIdleCount)); + sprintf(msg + strlen(msg), "%-7d", (int)DataRate); + sprintf(msg + strlen(msg), "%-7d", (int)pEntry->StaConnectTime); + sprintf(msg + strlen(msg), "%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount, + (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount - pEntry->DebugFIFOCount) * 100 / pEntry->DebugTxCount) : 0); + sprintf(msg + strlen(msg), "\n"); + } + } + + /* 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)) + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s", msg)); + + os_free_mem(msg); +} +#endif /* VENDOR_FEATURE6_SUPPORT */ + +#if defined(INF_AR9) || defined(BB_SOC) +#if defined(AR9_MAPI_SUPPORT) || defined(BB_SOC) +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, + INOUT 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; + STA_TR_ENTRY *tr_entry; + struct ieee80211req_mlme mlme; + struct ieee80211req_key Key; + struct ieee80211req_del_key delkey; + UINT8 Wcid; + BSS_STRUCT *pMbss; + WSC_LV_INFO WscIEBeacon; + WSC_LV_INFO WscIEProbeResp; + int i; +#endif /*HOSTAPD_SUPPORT*/ +#ifdef APCLI_SUPPORT +#endif/*APCLI_SUPPORT*/ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + switch (cmd & 0x7FFF) { +#ifdef APCLI_SUPPORT +#endif/*APCLI_SUPPORT*/ + + case OID_802_11_DEAUTHENTICATION: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + + os_alloc_mem(pAd, (UCHAR **)&Elem, sizeof(MLME_QUEUE_ELEM)); + + if (Elem == NULL) { + Status = -ENOMEM; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_DEAUTHENTICATION, Failed!!\n")); + break; + } + +#ifdef APCLI_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); + pEntry = MacTableLookup(pAd, pInfo->Addr); + + if (pEntry != NULL) { + Elem->Wcid = pEntry->wcid; + MlmeEnqueue(pAd, AP_AUTH_STATE_MACHINE, APMT2_MLME_DEAUTH_REQ, + sizeof(MLME_DEAUTH_REQ_STRUCT), Elem, 0); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason)); + } + + os_free_mem(Elem); + } + } + } + + break; +#ifdef IAPP_SUPPORT + + case RT_SET_IAPP_PID: { + unsigned IappPid; + + if (sizeof(IappPid) != wrq->u.data.length) { + Status = -EFAULT; + break; + } + + 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; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_SET_APD_PID::(IappPid=%u)\n", IappPid)); + } + } + break; +#endif /* IAPP_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + + case RT_SET_FT_STATION_NOTIFY: + case RT_SET_FT_KEY_REQ: + case RT_SET_FT_KEY_RSP: + case RT_FT_KEY_SET: + case RT_FT_NEIGHBOR_REPORT: + case RT_FT_NEIGHBOR_REQUEST: + case RT_FT_NEIGHBOR_RESPONSE: + case RT_FT_ACTION_FORWARD: { + UCHAR *pBuffer; + + FT_MEM_ALLOC(pAd, &pBuffer, wrq->u.data.length + 1); + + if (pBuffer == NULL) + break; + + if (copy_from_user(pBuffer, wrq->u.data.pointer, wrq->u.data.length)) { + Status = -EFAULT; + FT_MEM_FREE(pAd, pBuffer); + break; + } + + switch (cmd & 0x7FFF) { + case RT_SET_FT_STATION_NOTIFY: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_SET_FT_STATION_NOTIFY\n")); + FT_KDP_StationInform(pAd, pBuffer, wrq->u.data.length); + break; + + case RT_SET_FT_KEY_REQ: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_SET_FT_KEY_REQ\n")); + FT_KDP_IOCTL_KEY_REQ(pAd, pBuffer, wrq->u.data.length); + break; + + case RT_SET_FT_KEY_RSP: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_SET_FT_KEY_RSP\n")); + FT_KDP_KeyResponseToUs(pAd, pBuffer, wrq->u.data.length); + break; + + case RT_FT_KEY_SET: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_FT_KEY_SET\n")); + /* Note: the key must be ended by 0x00 */ + pBuffer[wrq->u.data.length] = 0x00; + FT_KDP_CryptKeySet(pAd, pBuffer, wrq->u.data.length); + break; + + case RT_FT_NEIGHBOR_REPORT: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_FT_NEIGHBOR_REPORT\n")); +#ifdef FT_KDP_FUNC_INFO_BROADCAST + FT_KDP_NeighborReportHandle(pAd, pBuffer, wrq->u.data.length); +#endif /* FT_KDP_FUNC_INFO_BROADCAST */ + break; + + case RT_FT_NEIGHBOR_REQUEST: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_FT_NEIGHBOR_REPORT\n")); + FT_KDP_NeighborRequestHandle(pAd, pBuffer, wrq->u.data.length); + break; + + case RT_FT_NEIGHBOR_RESPONSE: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_FT_NEIGHBOR_RESPONSE\n")); + FT_KDP_NeighborResponseHandle(pAd, pBuffer, wrq->u.data.length); + break; + + case RT_FT_ACTION_FORWARD: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[ra%d] RT_FT_ACTION_FORWARD\n", pObj->ioctl_if)); + FT_RRB_ActionHandle(pAd, pObj->ioctl_if, pBuffer, wrq->u.data.length); + break; + } + + FT_MEM_FREE(pAd, pBuffer); + } + break; + + case OID_802_11R_SUPPORT: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else { + UCHAR apidx = pObj->ioctl_if; + ULONG value; + + Status = copy_from_user(&value, wrq->u.data.pointer, wrq->u.data.length); + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtCapFlag.Dot11rFtEnable = (value == 0 ? FALSE : TRUE); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11R_SUPPORT(=%d)\n", + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtCapFlag.Dot11rFtEnable)); + } + + break; + + case OID_802_11R_MDID: + if (wrq->u.data.length != FT_MDID_LEN) + Status = -EINVAL; + else { + UCHAR apidx = pObj->ioctl_if; + + Status = copy_from_user(pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtMdId, wrq->u.data.pointer, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11R_MDID(=%c%c)\n", + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtMdId[0], + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtMdId[0])); + /*#ifdef WH_EZ_SETUP + Dynamic update of MdId in ez security Info not supported currently + #endif */ + } + + break; + + case OID_802_11R_R0KHID: + if (wrq->u.data.length <= FT_ROKH_ID_LEN) + Status = -EINVAL; + else { + UCHAR apidx = pObj->ioctl_if; + + Status = copy_from_user(pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtR0khId, wrq->u.data.pointer, wrq->u.data.length); + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtR0khIdLen = wrq->u.data.length; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11R_OID_802_11R_R0KHID(=%s) Len=%d\n", + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtR0khId, + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtR0khIdLen)); + } + + break; + + case OID_802_11R_RIC: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else { + UCHAR apidx = pObj->ioctl_if; + ULONG value; + + Status = copy_from_user(&value, wrq->u.data.pointer, wrq->u.data.length); + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtCapFlag.RsrReqCap = (value == 0 ? FALSE : TRUE); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11R_RIC(=%d)\n", + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtCapFlag.Dot11rFtEnable)); + } + + break; + + case OID_802_11R_OTD: + if (wrq->u.data.length != sizeof(BOOLEAN)) + Status = -EINVAL; + else { + UCHAR apidx = pObj->ioctl_if; + ULONG value; + + Status = copy_from_user(&value, wrq->u.data.pointer, wrq->u.data.length); + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtCapFlag.FtOverDs = (value == 0 ? FALSE : TRUE); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11R_OTD(=%d)\n", + pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtCapFlag.Dot11rFtEnable)); + } + + break; +#endif /* DOT11R_FT_SUPPORT */ + + case RT_SET_APD_PID: { + unsigned long apd_pid; + + if (sizeof(apd_pid) != wrq->u.data.length) { + Status = -EFAULT; + break; + } + + 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; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_SET_APD_PID::(ApdPid=%lu)\n", apd_pid)); + } + } + break; + + case RT_SET_DEL_MAC_ENTRY: + if (wrq->u.data.length != MAC_ADDR_LEN) { + Status = -EFAULT; + break; + } + + if (copy_from_user(Addr, wrq->u.data.pointer, wrq->u.data.length)) + Status = -EFAULT; + else { + MAC_TABLE_ENTRY *pEntry = NULL; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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])); + + if ((pObj->ioctl_if_type == INT_MAIN) || (pObj->ioctl_if_type == INT_MBSSID)) { + struct wifi_dev *wdev = NULL; + + wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + pEntry = MacTableLookup2(pAd, Addr, wdev); + + } else + pEntry = MacTableLookup(pAd, Addr); + + if (pEntry) { +#ifdef MAC_REPEATER_SUPPORT + + /* + Need to delete repeater entry if this is mac repeater entry. + */ + if (pAd->ApCfg.bMACRepeaterEn) { + UCHAR apCliIdx, CliIdx; + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + + pReptEntry = RTMPLookupRepeaterCliEntry(pAd, TRUE, pEntry->Addr, TRUE); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Delete (%02x:%02x:%02x:%02x:%02x:%02x) mac repeater entry\n", + Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5])); + + if (pReptEntry) { + apCliIdx = pReptEntry->MatchApCliIdx; + CliIdx = pReptEntry->MatchLinkIdx; + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_APCFG_DEL_MAC_ENTRY; + MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, + (64 + MAX_EXT_MAC_ADDR_SIZE * apCliIdx + CliIdx)); + RTMP_MLME_HANDLER(pAd); + } + } + +#endif /* MAC_REPEATER_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + + /* + If AP send de-auth to Apple STA, + Apple STA will re-do auth/assoc and security handshaking with AP again. + @20150313 + */ + if (IS_FT_RSN_STA(pEntry)) + MacTableDeleteEntry(pAd, pEntry->Aid, Addr); + else +#endif /* DOT11R_FT_SUPPORT */ + MlmeDeAuthAction(pAd, pEntry, REASON_DISASSOC_STA_LEAVING, FALSE); + } + } + + break; +#ifdef WSC_AP_SUPPORT +#ifdef CON_WPS + + case RT_OID_WSC_SET_CON_WPS_STOP: { + UCHAR apidx = pObj->ioctl_if; + PWSC_UPNP_CTRL_WSC_BAND_STOP pWscUpnpBandStop; + PWSC_CTRL pWpsCtrl = NULL; + INT IsAPConfigured; + + os_alloc_mem(NULL, (UCHAR **)&pWscUpnpBandStop, sizeof(WSC_UPNP_CTRL_WSC_BAND_STOP)); + + if (pWscUpnpBandStop) { + Status = copy_from_user(pWscUpnpBandStop, wrq->u.data.pointer, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("CON_WPS BAND_STOP_CMD From[%s], isApCli[%d], is2gBand[%d]\n", + pWscUpnpBandStop->ifName, pWscUpnpBandStop->isApCli, pWscUpnpBandStop->is2gBand)); + + if (pWscUpnpBandStop->isApCli) { + UCHAR i; + struct wifi_dev *apcli_wdev; + + for (i = 0; i < MAX_APCLI_NUM; i++) { + pWpsCtrl = &pAd->ApCfg.ApCliTab[i].wdev.WscControl; + apcli_wdev = &pAd->ApCfg.ApCliTab[i].wdev; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("CON_WPS FROM IOCTL: Stop the %s WPS, state [%d]\n", + apcli_wdev->if_dev->name, pWpsCtrl->WscState)); + + if (pWpsCtrl->WscState != WSC_STATE_OFF) { + WscStop(pAd, TRUE, pWpsCtrl); + pWpsCtrl->WscConfMode = WSC_DISABLE; + } + } + } else { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + pWpsCtrl = &wdev->WscControl; + IsAPConfigured = pWpsCtrl->WscConfStatus; + + if ((pWpsCtrl->WscConfMode != WSC_DISABLE) && + (pWpsCtrl->bWscTrigger == TRUE)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("FROM IOCTL CON_WPS[%d]: Stop the AP Wsc Machine\n", apidx)); + 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); + UpdateBeaconHandler(pAd, wdev, BCN_UPDATE_IE_CHG); + WscStop(pAd, FALSE, pWpsCtrl); + } + } + + os_free_mem(pWscUpnpBandStop); + } + } + break; +#endif /* CON_WPS */ + + case RT_OID_WSC_SET_SELECTED_REGISTRAR: { + PUCHAR upnpInfo; + UCHAR apidx = pObj->ioctl_if; +#ifdef HOSTAPD_SUPPORT + + if (pAd->ApCfg.MBSSID[apidx].Hostapd == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + Status = -EINVAL; + } else { +#endif /*HOSTAPD_SUPPORT*/ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("WSC::RT_OID_WSC_SET_SELECTED_REGISTRAR, wrq->u.data.length=%d!\n", wrq->u.data.length)); + 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].wdev.WscControl.WscConfMode & WSC_PROXY)) { + WscSelectedRegistrar(pAd, upnpInfo, len, apidx); + + if (pAd->ApCfg.MBSSID[apidx].wdev.WscControl.Wsc2MinsTimerRunning == TRUE) { + BOOLEAN Cancelled; + + RTMPCancelTimer(&pAd->ApCfg.MBSSID[apidx].wdev.WscControl.Wsc2MinsTimer, &Cancelled); + } + + /* 2mins time-out timer */ + RTMPSetTimer(&pAd->ApCfg.MBSSID[apidx].wdev.WscControl.Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT); + pAd->ApCfg.MBSSID[apidx].wdev.WscControl.Wsc2MinsTimerRunning = TRUE; + } + } + + os_free_mem(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; + struct wifi_dev *wdev; +#ifdef HOSTAPD_SUPPORT + UCHAR apidx = pObj->ioctl_if; + + if (pAd->ApCfg.MBSSID[apidx].Hostapd == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + Status = -EINVAL; + } else { +#endif /*HOSTAPD_SUPPORT*/ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 == NULL) + Status = -EINVAL; + else { + int HeaderLen; + RTMP_STRING *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; + wdev = wdev_search_by_address(pAd, &msgHdr->Addr1[0]); + + if (!wdev) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:: cannot find wdev by addr(%02x:%02x:%02x:%02x:%02x:%02x).\n", + __func__, PRINT_MAC(msgHdr->Addr1))); + os_free_mem(pUPnPMsg); + Status = -EINVAL; + break; + } + + senderID = get_unaligned((INT32 *)(&msgHdr->Addr2[0])); + /*senderID = *((int *)&msgHdr->Addr2); */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_OID_WSC_EAPMSG++++++++\n\n")); + hex_dump("MAC::", &msgHdr->Addr3[0], MAC_ADDR_LEN); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_OID_WSC_EAPMSG++++++++\n\n")); + HeaderLen = LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME); + pWpsMsg = (RTMP_STRING *)&pUPnPMsg[HeaderLen]; + WpsMsgLen = msgLen - HeaderLen; + /*assign the STATE_MACHINE type */ + Machine = WSC_STATE_MACHINE; + msgType = WSC_EAPOL_UPNP_MSG; + pWscControl = &wdev->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, wdev); + + if ((retVal == FALSE) && (msgHdr->envID != 0)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MlmeEnqueuForWsc return False and envID=0x%x!\n", + msgHdr->envID)); + Status = -EINVAL; + } + + os_free_mem(pUPnPMsg); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) { + RTMP_STRING *pWscUfdFileName = NULL; + UCHAR apIdx = pObj->ioctl_if; + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apIdx]; + WSC_CTRL *pWscCtrl = &pMbss->wdev.WscControl; + + 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 { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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, pMbss, AP_BSS_OPER_SINGLE); + APStartUp(pAd, pMbss, AP_BSS_OPER_SINGLE); + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_OID_WSC_READ_UFD_FILE: AP is configured.\n")); + Status = -EINVAL; + } + } + + os_free_mem(pWscUfdFileName); + } else + Status = -ENOMEM; + } else + Status = -EINVAL; + + break; + + case RT_OID_WSC_WRITE_UFD_FILE: + if (wrq->u.data.length > 0) { + RTMP_STRING *pWscUfdFileName = NULL; + UCHAR apIdx = pObj->ioctl_if; + WSC_CTRL *pWscCtrl = &pAd->ApCfg.MBSSID[apIdx].wdev.WscControl; + + 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 { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_OID_WSC_WRITE_UFD_FILE (WscUfdFileName=%s)\n", + pWscUfdFileName)); + + if (pWscCtrl->WscConfStatus == WSC_SCSTATE_CONFIGURED) + WscWriteProfileToUfdFile(pAd, apIdx, pWscUfdFileName); + else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_OID_WSC_WRITE_UFD_FILE: AP is un-configured.\n")); + Status = -EINVAL; + } + } + + os_free_mem(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].wdev.WscControl.Wsc_Uuid_Str[0] = '\0'; + Status = copy_from_user(&pAd->ApCfg.MBSSID[apIdx].wdev.WscControl.Wsc_Uuid_Str[0], + wrq->u.data.pointer, + wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("UUID ASCII string: %s\n", + pAd->ApCfg.MBSSID[apIdx].wdev.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].wdev.WscControl.Wsc_Uuid_E[0], + wrq->u.data.pointer, + wrq->u.data.length); + + for (ii = 0; ii < 16; ii++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%02x", + (pAd->ApCfg.MBSSID[apIdx].wdev.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); + AsicSetRetryLimit(pAd, TX_RTY_CFG_RTY_LIMIT_SHORT, ShortRetryLimit); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (ShortRetryLimit=%ld)\n", + ShortRetryLimit)); + } + + break; + + case OID_802_11_LONGRETRYLIMIT: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + AsicSetRetryLimit(pAd, TX_RTY_CFG_RTY_LIMIT_LONG, LongRetryLimit); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (,LongRetryLimit=%ld)\n", + LongRetryLimit)); + } + + break; + + case OID_802_11_WEPDEFAULTKEYVALUE: { + UINT KeyIdx; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n")); + 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; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n")); + } + + KeyIdx = pKey->KeyIndex & 0x0fffffff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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(pKey); + break; + } + + case OID_802_11_WEPDEFAULTKEYID: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_CURRENTCHANNEL\n")); + + if (wrq->u.data.length != sizeof(UCHAR)) + Status = -EINVAL; + else { + RTMP_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 DOT1X_SUPPORT + + case OID_802_DOT1X_PMKID_CACHE: + RTMPIoctlAddPMKIDCache(pAd, wrq); + break; + + case OID_802_DOT1X_RADIUS_DATA: + Dot1xIoctlRadiusData(pAd, wrq); + break; + + case OID_802_DOT1X_WPA_KEY: + Dot1xIoctlAddWPAKey(pAd, wrq); + break; + + case OID_802_DOT1X_STATIC_WEP_COPY: + Dot1xIoctlStaticWepCopy(pAd, wrq); + break; + + case OID_802_DOT1X_IDLE_TIMEOUT: + RTMPIoctlSetIdleTimeout(pAd, wrq); + break; +#ifdef RADIUS_MAC_ACL_SUPPORT + + case OID_802_DOT1X_RADIUS_ACL_NEW_CACHE: + RTMPIoctlAddRadiusMacAuthCache(pAd, wrq); + break; + + case OID_802_DOT1X_RADIUS_ACL_DEL_CACHE: + RTMPIoctlDelRadiusMacAuthCache(pAd, wrq); + break; + + case OID_802_DOT1X_RADIUS_ACL_CLEAR_CACHE: + RTMPIoctlClearRadiusMacAuthCache(pAd, wrq); + break; +#endif /* RADIUS_MAC_ACL_SUPPORT */ +#endif /* DOT1X_SUPPORT */ + + case OID_802_11_AUTHENTICATION_MODE: { + struct wifi_dev *wdev = NULL; + UCHAR apIdx = pObj->ioctl_if; + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apIdx]; + + if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE)) + Status = -EINVAL; + else { + UINT32 AKMMap = 0; + + Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length); + + if (AuthMode > Ndis802_11AuthModeMax) { + Status = -EINVAL; + break; + } + + AKMMap = SecAuthModeOldToNew(AuthMode); +#ifdef APCLI_SUPPORT +#endif/*APCLI_SUPPORT*/ + { + wdev = &pMbss->wdev; + + if (wdev->SecConfig.AKMMap != AKMMap) { + /* Config has changed */ + pAd->bConfigChanged = TRUE; + } + + wdev->SecConfig.AKMMap = AKMMap; + } + + wdev->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=0x%x)\n", + wdev->SecConfig.AKMMap)); + } + + if (wdev) { + APStop(pAd, pMbss, AP_BSS_OPER_SINGLE); + APStartUp(pAd, pMbss, AP_BSS_OPER_SINGLE); + } + + break; + } + + case OID_802_11_WEP_STATUS: + if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS)) + Status = -EINVAL; + else { + UINT32 EncryType = 0; + + Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length); + EncryType = SecEncryModeOldToNew(WepStatus); +#ifdef APCLI_SUPPORT +#endif/*APCLI_SUPPORT*/ + { + UCHAR apIdx = pObj->ioctl_if; + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apIdx]; + struct wifi_dev *wdev = &pMbss->wdev; + + /* Since TKIP, AES, WEP are all supported. It should not have any invalid setting */ + if (EncryType != 0) { + if (wdev->SecConfig.PairwiseCipher != EncryType) { + /* Config has changed */ + pAd->bConfigChanged = TRUE; + } + + wdev->SecConfig.PairwiseCipher = EncryType; + + if (IS_CIPHER_TKIP(EncryType) && IS_CIPHER_CCMP128(EncryType)) + SET_CIPHER_TKIP(wdev->SecConfig.GroupCipher); + else + wdev->SecConfig.GroupCipher = EncryType; + } else { + Status = -EINVAL; + break; + } + + APStop(pAd, pMbss, AP_BSS_OPER_SINGLE); + APStartUp(pAd, pMbss, AP_BSS_OPER_SINGLE); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_WEP_STATUS (=0x%x)\n", EncryType)); + } + } + + break; + + case OID_802_11_SSID: + if (wrq->u.data.length != sizeof(NDIS_802_11_SSID)) + Status = -EINVAL; + else { + RTMP_STRING *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 +#endif/*APCLI_SUPPORT*/ + { + NdisZeroMemory((PCHAR)pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid, + MAX_LEN_OF_SSID); + strncpy((PCHAR)pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid, + pSsidString + , MAX_LEN_OF_SSID); + pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid[MAX_LEN_OF_SSID] = + (CHAR)'\0'; + pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen = + strlen(pSsidString); + } + + os_free_mem(pSsidString); + } else + Status = -ENOMEM; + } + } + } + + break; +#ifdef VENDOR_FEATURE6_SUPPORT + + case OID_802_11_PASSPHRASES: { + INT i; + BSS_STRUCT *pMBSSStruct; + INT retval; + NDIS80211PSK tmpPSK; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + NdisZeroMemory(&tmpPSK, sizeof(tmpPSK)); + Status = copy_from_user(&tmpPSK, wrq->u.data.pointer, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::OID_802_11_PASSPHRASE\n")); + + for (i = 0 ; i < tmpPSK.WPAKeyLen ; i++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%c", tmpPSK.WPAKey[i])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + pMBSSStruct = &pAd->ApCfg.MBSSID[pObj->ioctl_if]; + retval = SetWPAPSKKey(pAd, &tmpPSK.WPAKey[0], tmpPSK.WPAKeyLen, (PUCHAR)pMBSSStruct->Ssid, pMBSSStruct->SsidLen, pMBSSStruct->PMK); + + if (retval == FALSE) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("PassPhrase Generate Fail\n")); + +#ifdef WSC_AP_SUPPORT + NdisZeroMemory(pMBSSStruct->WscControl.WpaPsk, 64); + pMBSSStruct->WscControl.WpaPskLen = tmpPSK.WPAKeyLen; + NdisMoveMemory(pMBSSStruct->WscControl.WpaPsk, &tmpPSK.WPAKey[0], pMBSSStruct->WscControl.WpaPskLen); +#endif /* WSC_AP_SUPPORT */ + } + break; +#endif /* VENDOR_FEATURE6_SUPPORT */ +#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; + struct wifi_dev *wdev = NULL; + + 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->func_tb_idx].DefaultKeyId; + AsicAddPairwiseKeyEntry( + pAd, + (UCHAR)pEntry->wcid, + &pEntry->PairwiseKey); + RTMPAddWcidAttributeEntry( + pAd, + pEntry->func_tb_idx, + KeyIdx, /* The value may be not zero */ + pEntry->PairwiseKey.CipherAlg, + pEntry); + } else { /*group key */ + pMbss = &pAd->ApCfg.MBSSID[apidx]; + KeyIdx = Key.ik_keyix & 0x0fff; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ra%d KeyIdx=%d\n", apidx, KeyIdx)); + + /* 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) */ + MTWF_LOG(DBG_CAT_CFG, + DBG_SUBCAT_ALL, + DBG_LVL_TRACE, + ("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_11TKIPEnable) { + 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_11AESEnable) { + 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_11TKIPEnable) + pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP; + else if (pEntry->WepStatus == Ndis802_11AESEnable) + pEntry->PairwiseKey.CipherAlg = CIPHER_AES; + + pEntry->PairwiseKey.CipherAlg = Key.ik_type; + AsicAddPairwiseKeyEntry( + pAd, + (UCHAR)pEntry->wcid, + &pEntry->PairwiseKey); + } else { + pMbss = &pAd->ApCfg.MBSSID[apidx]; + wdev = &pMbss->wdev; + KeyIdx = Key.ik_keyix & 0x0fff; + /*if (Key.ik_keyix & 0x8000) */ + { + pMbss->DefaultKeyId = (UCHAR) KeyIdx; + } + + if (pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11TKIPEnable) { + 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_11AESEnable) { + 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_11TKIPEnable) + pAd->SharedKey[apidx][pMbss->DefaultKeyId].CipherAlg = CIPHER_TKIP; + else if (pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11AESEnable) + 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(wdev, Wcid); + /*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->wcid != 0) { + NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY)); + AsicRemovePairwiseKeyEntry(pAd, (UCHAR)pEntry->wcid); + } + } else if ((delkey.idk_macaddr == NULL) && (delkey.idk_keyix < 4)) + /* remove group key */ + AsicRemoveSharedKeyEntry(pAd, pEntry->func_tb_idx, 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 { + tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; + + 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[0].PortSecured= WPA_802_1X_PORT_SECURED; */ + tr_entry->PortSecured = WPA_802_1X_PORT_SECURED; + break; + + case IEEE80211_MLME_UNAUTHORIZE: + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + tr_entry->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; */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Woody HOSTAPD_OID_STATIC_WEP_COPY IEEE8021X=%d WepStatus=%d\n", pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.IEEE8021X, + pEntry->WepStatus)); + + if (pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.IEEE8021X != TRUE) + break; + + if (pEntry->WepStatus != Ndis802_11WEPEnabled) + break; + + apidx = pObj->ioctl_if; + pMbss = &pAd->ApCfg.MBSSID[apidx]; + KeyIdx = pMbss->DefaultKeyId; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("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->wcid, + &pEntry->PairwiseKey); + RTMPAddWcidAttributeEntry( + pAd, + pEntry->func_tb_idx, + KeyIdx, /* The value may be not zero */ + pEntry->PairwiseKey.CipherAlg, + pEntry); + } + } + + break; + } + + case HOSTAPD_OID_SET_STA_DEAUTH: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::HOSTAPD_OID_SET_STA_DEAUTH\n")); + MLME_DEAUTH_REQ_STRUCT *pInfo; + MLME_QUEUE_ELEM *Elem; + + 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); + pEntry = MacTableLookup(pAd, pInfo->Addr); + + if (pEntry != NULL) { + pInfo->Reason = mlme.im_reason; + Elem->Wcid = pEntry->wcid; + MlmeEnqueue(pAd, AP_AUTH_STATE_MACHINE, APMT2_MLME_DEAUTH_REQ, sizeof(MLME_DEAUTH_REQ_STRUCT), Elem, 0); + } + } + + os_free_mem(Elem); + } + + break; + + case HOSTAPD_OID_SET_STA_DISASSOC:/*hostapd request to disassoc the station. */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("OID_HOSTAPD_SUPPORT apidx=%d\n", apidx)); + pAd->ApCfg.MBSSID[apidx].Hostapd = hostapd_enable; + BSS_STRUCT *pMBSSStruct; + + for (v = 0; v < MAX_MBSSID_NUM(pAd); v++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ApCfg->MBSSID[%d].Hostapd == %s\n", v, + (pAd->ApCfg.MBSSID[v].Hostapd == Hostapd_EXT ? "TRUE" : "FALSE"))); + 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) { + { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>>\n")); + /* send wireless event - for counter measures */ + pAd->ApCfg.CMTimerRunning = FALSE; + + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); 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 of 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. */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + BSS_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; + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + } + + break; + + case HOSTAPD_OID_SET_WPS_PROBE_RESP_IE:/*pure 1x is enabled. */ + apidx = pObj->ioctl_if; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("HOSTAPD_OID_SET_WPS_PROBE_RESP_IE\n")); + + if (wrq->u.data.length != sizeof(WSC_LV_INFO)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("HOSTAPD_OID_SET_WPS_PROBE_RESP_IE failed\n")); + Status = -EINVAL; + } else { + INT apidx; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + apidx = pObj->ioctl_if; + pAd->ApCfg.MBSSID[apidx].HostapdWPS = TRUE; + BSS_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; + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + } + + break; +#endif /*HOSTAPD_SUPPORT*/ +#ifdef CONFIG_HOTSPOT + + case OID_802_11_HS_TEST: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("hotspot test\n")); + break; + + case OID_802_11_HS_IE: { + UCHAR *IE; + + os_alloc_mem(NULL, (UCHAR **)&IE, wrq->u.data.length); + Status = copy_from_user(IE, wrq->u.data.pointer, wrq->u.data.length); + Set_AP_IE(pAd, IE, wrq->u.data.length); + os_free_mem(IE); + } + break; + + case OID_802_11_HS_ANQP_RSP: { + UCHAR *Buf; + struct anqp_rsp_data *rsp_data; + + os_alloc_mem(NULL, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + rsp_data = (struct anqp_rsp_data *)Buf; + Send_ANQP_Rsp(pAd, + rsp_data->peer_mac_addr, + rsp_data->anqp_rsp, + rsp_data->anqp_rsp_len); + os_free_mem(Buf); + } + break; + + case OID_802_11_HS_ONOFF: { + UCHAR *Buf; + struct hs_onoff *onoff; + + os_alloc_mem(NULL, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + onoff = (struct hs_onoff *)Buf; + Set_HotSpot_OnOff(pAd, onoff->hs_onoff, onoff->event_trigger, onoff->event_type); + os_free_mem(Buf); + } + break; + + case OID_802_11_HS_PARAM_SETTING: { + UCHAR *Buf; + struct hs_param_setting *param_setting; + + os_alloc_mem(NULL, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + param_setting = (struct hs_param_setting *)Buf; + Set_HotSpot_Param(pAd, param_setting->param, param_setting->value); + os_free_mem(Buf); + } + break; + + case OID_802_11_HS_RESET_RESOURCE: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("hotspot reset some resource\n")); + Clear_Hotspot_All_IE(pAd); + /* Clear_All_PROXY_TABLE(pAd); */ + break; +#ifdef CONFIG_HOTSPOT_R2 + + case OID_802_11_HS_SASN_ENABLE: { + UCHAR *Buf; + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].HotSpotCtrl; + + os_alloc_mem(NULL, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + pHSCtrl->bASANEnable = Buf[0]; + /* for 7615 offload to CR4 */ + hotspot_update_bssflag(pAd, fgASANEnable, Buf[0], pHSCtrl); + hotspot_update_bss_info_to_cr4(pAd, pObj->ioctl_if); + os_free_mem(Buf); + } + break; + + case OID_802_11_BSS_LOAD: { + UCHAR *Buf; + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].HotSpotCtrl; + + os_alloc_mem(NULL, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + pHSCtrl->QLoadTestEnable = Buf[0]; + pHSCtrl->QLoadCU = Buf[1]; + memcpy(&pHSCtrl->QLoadStaCnt, &Buf[2], 2); + os_free_mem(Buf); + } + break; +#endif +#endif +#ifdef CONFIG_DOT11V_WNM +#ifndef CONFIG_HOTSPOT_R2/* def WNM_NEW_API */ + + case OID_802_11_WNM_COMMAND: { + UCHAR *Buf; + struct wnm_command *cmd_data; + + os_alloc_mem(Buf, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + cmd_data = (struct wnm_command *)Buf; + + if (wnm_handle_command(pAd, cmd_data) != NDIS_STATUS_SUCCESS) + Status = -EINVAL; + + os_free_mem(Buf); + } + break; +#endif /*WNM_NEW_API*/ +#ifdef CONFIG_HOTSPOT_R2 + + case OID_802_11_WNM_BTM_REQ: { + UCHAR *Buf; + MAC_TABLE_ENTRY *pEntry = NULL; + struct btm_req_data *req_data; + + os_alloc_mem(Buf, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + req_data = (struct btm_req_data *)Buf; + pEntry = MacTableLookup(pAd, req_data->peer_mac_addr); + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s : NO ENTRY!!!!!!\n", __func__)); + } /*else if (pEntry->BssTransitionManmtSupport != 1) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("OID_802_11_WNM_BTM_REQ::the peer does not support BTM(%d)\n", + pEntry->BssTransitionManmtSupport)); + } */else if (IS_AKM_OPEN(pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.SecConfig.AKMMap) || + ((pEntry->SecConfig.Handshake.WpaState == AS_PTKINITDONE) && + (pEntry->SecConfig.Handshake.GTKState == REKEY_ESTABLISHED))) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("btm1\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("peer_mac_addr=%02x:%02x:%02x:%02x:%02x:%02x\n", + req_data->peer_mac_addr[0], + req_data->peer_mac_addr[1], + req_data->peer_mac_addr[2], + req_data->peer_mac_addr[3], + req_data->peer_mac_addr[4], + req_data->peer_mac_addr[5])); + Send_BTM_Req(pAd, + req_data->peer_mac_addr, + req_data->btm_req, + req_data->btm_req_len); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!btm2\n")); + pEntry->IsBTMReqValid = TRUE; + os_alloc_mem(pEntry->ReqbtmData, (UCHAR **)&pEntry->ReqbtmData, sizeof(struct btm_req_data) + req_data->btm_req_len); + memcpy(pEntry->ReqbtmData, Buf, sizeof(struct btm_req_data) + req_data->btm_req_len); + } + + os_free_mem(Buf); + } + break; + + case OID_802_11_WNM_NOTIFY_REQ: { + UCHAR *Buf; + MAC_TABLE_ENTRY *pEntry; + struct wnm_req_data *req_data; + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].HotSpotCtrl; + + os_alloc_mem(Buf, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + req_data = (struct wnm_req_data *)Buf; + pEntry = MacTableLookup(pAd, req_data->peer_mac_addr); + + if (pEntry == NULL) { + } else if (((pHSCtrl->HotSpotEnable) && IS_AKM_OPEN(pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.SecConfig.AKMMap)) || + ((pEntry->SecConfig.Handshake.WpaState == AS_PTKINITDONE) && + (pEntry->SecConfig.Handshake.GTKState == REKEY_ESTABLISHED))) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("wnm1\n")); + Send_WNM_Notify_Req(pAd, + req_data->peer_mac_addr, + req_data->wnm_req, + req_data->wnm_req_len, + req_data->type); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("wnm2\n")); + pEntry->IsWNMReqValid = TRUE; + os_alloc_mem(pEntry->ReqData, (UCHAR **)&pEntry->ReqData, sizeof(struct wnm_req_data) + req_data->wnm_req_len); + memcpy(pEntry->ReqData, Buf, sizeof(struct wnm_req_data) + req_data->wnm_req_len); + } + + os_free_mem(Buf); + } + break; + + case OID_802_11_QOSMAP_CONFIGURE: { + UCHAR *Buf; + MAC_TABLE_ENTRY *pEntry; + struct qosmap_data *req_data; + unsigned int i; + UCHAR PoolID = 0; + + os_alloc_mem(Buf, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + req_data = (struct qosmap_data *)Buf; + pEntry = MacTableLookup(pAd, req_data->peer_mac_addr); + + if (pEntry != NULL) { + /* clear previous data */ + pEntry->DscpExceptionCount = 0; + memset(pEntry->DscpRange, 0xff, 16); + memset(pEntry->DscpException, 0xff, 42); + pEntry->DscpExceptionCount = req_data->qosmap_len - 16; + memcpy((UCHAR *)pEntry->DscpRange, &req_data->qosmap[pEntry->DscpExceptionCount], 16); + + if (pEntry->DscpExceptionCount != 0) + memcpy((UCHAR *)pEntry->DscpException, req_data->qosmap, pEntry->DscpExceptionCount); + + PoolID = hotspot_qosmap_add_pool(pAd, pEntry); + hotspot_qosmap_update_sta_mapping_to_cr4(pAd, pEntry, PoolID); + Send_QOSMAP_Configure(pAd, + req_data->peer_mac_addr, + req_data->qosmap, + req_data->qosmap_len, + pEntry->func_tb_idx); + } else if ((req_data->peer_mac_addr[0] == 0) + && (req_data->peer_mac_addr[1] == 0) + && (req_data->peer_mac_addr[2] == 0) + && (req_data->peer_mac_addr[3] == 0) + && (req_data->peer_mac_addr[4] == 0) + && (req_data->peer_mac_addr[5] == 0)) { + /* Special MAC 00:00:00:00:00:00 for HS2 QoS Map Change using. */ + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + + if ((IS_ENTRY_CLIENT(pEntry)) + && (pEntry->Sst == SST_ASSOC)) { + if (pEntry->QosMapSupport) { + pEntry->DscpExceptionCount = 0; + memset(pEntry->DscpRange, 0xff, 16); + memset(pEntry->DscpException, 0xff, 42); + pEntry->DscpExceptionCount = req_data->qosmap_len - 16; + memcpy((UCHAR *)pEntry->DscpRange, + &req_data->qosmap[pEntry->DscpExceptionCount], 16); + + if (pEntry->DscpExceptionCount != 0) { + memcpy((UCHAR *)pEntry->DscpException, + req_data->qosmap, pEntry->DscpExceptionCount); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("send QoS map frame: apidx=%d\n", pEntry->func_tb_idx)); + Send_QOSMAP_Configure(pAd, + pEntry->Addr, + req_data->qosmap, + req_data->qosmap_len, + pEntry->func_tb_idx); + } + } + } + } + + os_free_mem(Buf); + } + break; +#endif +#endif +#ifdef DOT11K_RRM_SUPPORT + + case OID_802_11_RRM_COMMAND: + Status = rrm_MsgHandle(pAd, wrq); + + if (Status != NDIS_STATUS_SUCCESS) + Status = -NDIS_STATUS_FAILURE; + + break; +#endif +#ifdef MBO_SUPPORT + case OID_802_11_MBO_MSG: + { + UCHAR *Buf; + struct hs_param_setting *param_setting; + + os_alloc_mem(NULL, (UCHAR **)&Buf, wrq->u.data.length); + copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + param_setting = (struct hs_param_setting *)Buf; + MBO_MsgHandle(pAd, param_setting->param, param_setting->value); + os_free_mem(Buf); + } + break; +#endif /* MBO_SUPPORT */ +#ifdef WAPP_SUPPORT + case OID_WAPP_EVENT: + { + UCHAR *buf; + struct wapp_req *req; + + os_alloc_mem(NULL, (UCHAR **)&buf, wrq->u.data.length); + copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length); + req = (struct wapp_req *)buf; + wapp_event_handle(pAd, req); + os_free_mem(buf); + } + break; +#endif /* WAPP_SUPPORT */ +#ifdef VOW_SUPPORT +#define VOW_CMD_STR_LEN 16 + + case OID_802_11_VOW_BW_EN: + /* not used now */ + break; + + case OID_802_11_VOW_BW_AT_EN: { + P_VOW_UI_CONFIG cfg; + UCHAR buf[VOW_CMD_STR_LEN]; + UINT8 group; + + os_alloc_mem(cfg, (UCHAR **)&cfg, wrq->u.data.length); + + if (cfg == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(cfg, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + for (group = 0; group < cfg->ssid_num; group++) { + sprintf(buf, "%d-%d", group, cfg->val[group]); + set_vow_airtime_ctrl_en(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_BW_AT_EN(0x%08x) -> val %d\n", cmd, + cfg->val[group])); + } + } else + Status = -EFAULT; + + os_free_mem(cfg); + } + break; + + case OID_802_11_VOW_BW_TPUT_EN: { + P_VOW_UI_CONFIG cfg; + UCHAR buf[VOW_CMD_STR_LEN]; + UINT8 group; + + os_alloc_mem(cfg, (UCHAR **)&cfg, wrq->u.data.length); + + if (cfg == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(cfg, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + for (group = 0; group < cfg->ssid_num; group++) { + sprintf(buf, "%d-%d", group, cfg->val[group]); + set_vow_bw_ctrl_en(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_BW_TPUT_EN(0x%08x) -> val %d\n", cmd, + cfg->val[group])); + } + } else + Status = -EFAULT; + + os_free_mem(cfg); + } + break; + + case OID_802_11_VOW_ATF_EN: { + UCHAR *val, buf[VOW_CMD_STR_LEN]; + + os_alloc_mem(val, (UCHAR **)&val, wrq->u.data.length); + + if (val == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(val, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + sprintf(buf, "%d", val[0]); + set_vow_airtime_fairness_en(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_ATF_EN(0x%08x) -> val %d\n", cmd, val[0])); + } else + Status = -EFAULT; + + os_free_mem(val); + } + break; + + case OID_802_11_VOW_RX_EN: { + UCHAR *val, buf[VOW_CMD_STR_LEN]; + + os_alloc_mem(val, (UCHAR **)&val, wrq->u.data.length); + + if (val == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(val, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + sprintf(buf, "%d", val[0]); + set_vow_rx_airtime_en(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_RX_EN(0x%08x) -> val %d\n", cmd, val[0])); + } else + Status = -EFAULT; + + os_free_mem(val); + } + break; + + case OID_802_11_VOW_GROUP_MAX_RATE: { + P_VOW_UI_CONFIG cfg; + UCHAR buf[VOW_CMD_STR_LEN]; + UINT8 group; + + os_alloc_mem(cfg, (UCHAR **)&cfg, wrq->u.data.length); + + if (cfg == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(cfg, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + for (group = 0; group < cfg->ssid_num; group++) { + sprintf(buf, "%d-%d", group, cfg->val[group]); + set_vow_max_rate(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_GROUP_MAX_RATE(0x%08x) -> val %d\n", cmd, + cfg->val[group])); + } + } else + Status = -EFAULT; + + os_free_mem(cfg); + } + break; + + case OID_802_11_VOW_GROUP_MIN_RATE: { + P_VOW_UI_CONFIG cfg; + UCHAR buf[VOW_CMD_STR_LEN]; + UINT8 group; + + os_alloc_mem(cfg, (UCHAR **)&cfg, wrq->u.data.length); + + if (cfg == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(cfg, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + for (group = 0; group < cfg->ssid_num; group++) { + sprintf(buf, "%d-%d", group, cfg->val[group]); + set_vow_min_rate(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_GROUP_MIN_RATE(0x%08x) -> val %d\n", cmd, + cfg->val[group])); + } + } else + Status = -EFAULT; + + os_free_mem(cfg); + } + break; + + case OID_802_11_VOW_GROUP_MAX_RATIO: { + P_VOW_UI_CONFIG cfg; + UCHAR buf[VOW_CMD_STR_LEN]; + UINT8 group; + + os_alloc_mem(cfg, (UCHAR **)&cfg, wrq->u.data.length); + + if (cfg == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(cfg, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + for (group = 0; group < cfg->ssid_num; group++) { + sprintf(buf, "%d-%d", group, cfg->val[group]); + set_vow_max_ratio(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_GROUP_MAX_RATIO(0x%08x) -> val %d\n", cmd, + cfg->val[group])); + } + } else + Status = -EFAULT; + + os_free_mem(cfg); + } + break; + + case OID_802_11_VOW_GROUP_MIN_RATIO: { + P_VOW_UI_CONFIG cfg; + UCHAR buf[VOW_CMD_STR_LEN]; + UINT8 group; + + os_alloc_mem(cfg, (UCHAR **)&cfg, wrq->u.data.length); + + if (cfg == NULL) { + Status = -ENOMEM; + break; + } + + Status = copy_from_user(cfg, wrq->u.data.pointer, wrq->u.data.length); + + if (Status == NDIS_STATUS_SUCCESS) { + for (group = 0; group < cfg->ssid_num; group++) { + sprintf(buf, "%d-%d", group, cfg->val[group]); + set_vow_min_ratio(pAd, buf); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OID_802_11_VOW_GROUP_MIN_RATIO(0x%08x) -> val %d\n", cmd, + cfg->val[group])); + } + } else + Status = -EFAULT; + + os_free_mem(cfg); + } + break; +#endif /* VOW_SUPPORT */ +#ifdef WIFI_SPECTRUM_SUPPORT + case OID_802_11_WIFISPECTRUM_SET_PARAMETER: { + P_RBIST_CAP_START_T pSpectrumInfo; + UINT_32 ret; + + os_alloc_mem(pAd, (UCHAR **)&pSpectrumInfo, wrq->u.data.length); + ret = copy_from_user(pSpectrumInfo, wrq->u.data.pointer, wrq->u.data.length); + pSpectrumInfo->u4BW = Get_System_Bw_Info(pAd, pSpectrumInfo->u4CaptureNode); + chip_spectrum_start(pAd, (UINT8 *)pSpectrumInfo); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s :\n Trigger = 0x%08x\n" + " RingCapEn = 0x%08x\n TriggerEvent = 0x%08x\n CaptureNode = 0x%08x\n CaptureLen = 0x%08x\n" + " CapStopCycle = 0x%08x\n BW = 0x%08x\n MACTriggerEvent = 0x%08x\n SourceAddrLSB = 0x%08x\n" + " SourceAddrMSB = 0x%08x\n BandIdx = 0x%08x\n", __func__, pSpectrumInfo->fgTrigger, pSpectrumInfo->fgRingCapEn, + pSpectrumInfo->u4TriggerEvent, pSpectrumInfo->u4CaptureNode, pSpectrumInfo->u4CaptureLen, pSpectrumInfo->u4CapStopCycle, + pSpectrumInfo->u4BW, pSpectrumInfo->u4MACTriggerEvent, pSpectrumInfo->u4SourceAddressLSB, + pSpectrumInfo->u4SourceAddressMSB, pSpectrumInfo->u4BandIdx)); + + os_free_mem(pSpectrumInfo); + } + break; + + case OID_802_11_WIFISPECTRUM_GET_CAPTURE_STATUS: { + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + if (ops->SpectrumStatus != NULL) + Status = ops->SpectrumStatus(pAd); + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : The function is not hooked !!\n", __func__)); + } + + if (Status != NDIS_STATUS_SUCCESS) + Status = -NDIS_STATUS_FAILURE; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("OID_802_11_WIFISPECTRUM_GET_CAPTURE_STATUS Status : %d\n", Status)); + } + break; + + case OID_802_11_WIFISPECTRUM_DUMP_DATA: { + struct _RTMP_CHIP_OP *ops = hc_get_chip_ops(pAd->hdev_ctrl); + + if (ops->SpectrumCmdRawDataProc != NULL) + Status = ops->SpectrumCmdRawDataProc(pAd); + else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : The function is not hooked !!\n", __func__)); + } + + if (Status != NDIS_STATUS_SUCCESS) + Status = -NDIS_STATUS_FAILURE; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("OID_802_11_WIFISPECTRUM_DUMP_DATA Status : %d\n", Status)); + } + break; +#endif /* WIFI_SPECTRUM_SUPPORT */ +#ifdef BAND_STEERING + case OID_BNDSTRG_MSG: + BndStrg_MsgHandle(pAd, wrq, pObj->ioctl_if); + break; +#ifdef VENDOR_FEATURE5_SUPPORT + case OID_BNDSTRG_GET_NVRAM: + BndStrg_GetNvram(pAd, wrq, pObj->ioctl_if); + break; + + case OID_BNDSTRG_SET_NVRAM: + BndStrg_SetNvram(pAd, wrq, pObj->ioctl_if); + break; +#endif /* VENDOR_FEATURE5_SUPPORT */ +#endif /* BAND_STEERING */ + +#ifdef MT_DFS_SUPPORT + case OID_DFS_ZERO_WAIT: + Status = ZeroWaitDfsCmdHandler(pAd, wrq); + break; +#endif + + case OID_802_11_VENDOR_IE_ADD: + case OID_802_11_VENDOR_IE_UPDATE: + case OID_802_11_VENDOR_IE_REMOVE: + { + UCHAR *Buf; + struct vie_op_data_s *vie_op_data; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + UINT32 length = 0; + UINT32 oui_oitype = 0; + + os_alloc_mem(Buf, (UCHAR **)&Buf, wrq->u.data.length); + Status = copy_from_user(Buf, wrq->u.data.pointer, wrq->u.data.length); + vie_op_data = (struct vie_op_data_s *)Buf; + length = vie_op_data->vie_length; + NdisMoveMemory((UCHAR *)&oui_oitype, vie_op_data->oui_oitype, sizeof(UINT32)); + + if ((cmd & 0x7FFF) == VIE_REMOVE) { + if (remove_vie(pAd, + wdev, + vie_op_data->frm_type_map, + oui_oitype, + length, + vie_op_data->app_ie_ctnt) == NDIS_STATUS_FAILURE) { + Status = NDIS_STATUS_FAILURE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(): OID_802_11_VENDOR_IE_REMOVE failed.\n", __func__)); + } + } else { + if (add_vie(pAd, + wdev, + vie_op_data->frm_type_map, + oui_oitype, + length, + vie_op_data->app_ie_ctnt) == NDIS_STATUS_FAILURE) { + Status = NDIS_STATUS_FAILURE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s(): OID_802_11_VENDOR_IE_ADD failed.\n", __func__)); + } + } + + os_free_mem(Buf); + } + break; + case OID_802_11_VENDOR_IE_SHOW: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("OID_802_11_VENDOR_IE_SHOW not finish yet\n")); + break; + + default: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd)); + Status = -EOPNOTSUPP; + break; + } + + return Status; +} + + +INT RTMPAPQueryInformation( + IN RTMP_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; + RTMP_STRING driverVersion[16]; + UCHAR apidx = pObj->ioctl_if; +#ifdef WSC_AP_SUPPORT + UINT WscPinCode = 0; + PWSC_PROFILE pProfile; + PWSC_CTRL pWscControl; +#endif /* WSC_AP_SUPPORT */ +#if defined(SNMP_SUPPORT) || defined(VENDOR_FEATURE6_SUPPORT) + ULONG ulInfo; +#endif /* defined(SNMP_SUPPORT) || defined(VENDOR_FEATURE6_SUPPORT) */ +#ifdef SNMP_SUPPORT + 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; + BSS_STRUCT *pMbss; +#endif /*HOSTAPD_SUPPORT*/ +#if (defined(APCLI_SUPPORT) || defined(WH_EZ_SETUP)) + NDIS_802_11_SSID Ssid; +#endif +#ifdef APCLI_SUPPORT + UCHAR ifIndex; + BOOLEAN apcliEn = FALSE; + PAPCLI_STRUCT pApCliEntry = NULL; +#endif/*APCLI_SUPPORT*/ + NDIS_802_11_STATISTICS *pStatistics; +#ifdef DOT1X_SUPPORT + INT IEEE8021X = 0; +#endif /* DOT1X_SUPPORT */ + NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax; + struct wifi_dev *wdev = NULL; + + /* For all ioctl to this function, we assume that's query for AP/APCLI/GO device */ + if ((pObj->ioctl_if_type == INT_MBSSID) || (pObj->ioctl_if_type == INT_MAIN)) { + if (apidx >= pAd->ApCfg.BssidNum) + return -EFAULT; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + } + + switch (cmd) { +#ifdef DOT1X_SUPPORT + + case OID_802_11_SET_IEEE8021X: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_SET_IEEE8021X\n")); + wrq->u.data.length = sizeof(INT); + + if (IS_IEEE8021X_Entry(&pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev)) + 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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE\n")); + wrq->u.data.length = sizeof(NDIS_802_11_AUTHENTICATION_MODE); + AuthMode = SecAuthModeNewToOld(pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.SecConfig.AKMMap); + Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length); + break; +#ifdef APCLI_SUPPORT + + case OID_802_11_BSSID: + if ((pObj->ioctl_if_type != INT_APCLI) +#ifdef VENDOR_FEATURE6_SUPPORT + && (pObj->ioctl_if_type != INT_MAIN) +#endif /* VENDOR_FEATURE6_SUPPORT */ + ) + return FALSE; + + ifIndex = pObj->ioctl_if; + + if (pObj->ioctl_if_type == INT_APCLI) { + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable; + + if (!apcliEn) + return FALSE; + + Status = copy_to_user(wrq->u.data.pointer, pApCliEntry->MlmeAux.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("IOCTL::SIOCGIWAP(=%02x:%02x:%02x:%02x:%02x:%02x)\n", PRINT_MAC(pApCliEntry->MlmeAux.Bssid))); + } + +#ifdef VENDOR_FEATURE6_SUPPORT + else if (pObj->ioctl_if_type == INT_MAIN) { + if (wdev) { + wrq->u.data.length = MAC_ADDR_LEN; + Status = copy_to_user(wrq->u.data.pointer, &wdev->bssid[0], wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_BSSID (%02x:%02x:%02x:%02x:%02x:%02x)\n", PRINT_MAC(wdev->bssid))); + } + } + +#endif /* VENDOR_FEATURE6_SUPPORT */ + else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n")); + Status = -ENOTCONN; + } + + break; +#endif/*APCLI_SUPPORT*/ +#if (defined(APCLI_SUPPORT) || defined(WH_EZ_SETUP)) + + case OID_802_11_SSID: + ifIndex = pObj->ioctl_if; + NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID)); +#ifdef APCLI_SUPPORT + + if (pObj->ioctl_if_type == INT_APCLI) { + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + apcliEn = pAd->ApCfg.ApCliTab[ifIndex].Enable; + + if (!apcliEn) + return FALSE; + + Ssid.SsidLength = pApCliEntry->CfgSsidLen; + NdisMoveMemory(Ssid.Ssid, pApCliEntry->CfgSsid, Ssid.SsidLength); + } + +#endif /* APCLI_SUPPORT */ + wrq->u.data.length = sizeof(NDIS_802_11_SSID); + Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength, + Ssid.Ssid)); + break; +#endif + + case RT_OID_VERSION_INFO: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_VERSION_INFO\n")); + wrq->u.data.length = strlen(AP_DRIVER_VERSION); + snprintf(&driverVersion[0], sizeof(driverVersion), "%s", AP_DRIVER_VERSION); + driverVersion[wrq->u.data.length] = '\0'; + + if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length)) + Status = -EFAULT; + + break; +#ifdef VENDOR_FEATURE6_SUPPORT + + case RT_OID_802_11_PHY_MODE: { + UCHAR *temp_wmode = NULL; + + if (wdev) { + ulInfo = (ULONG)wdev->PhyMode; + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + temp_wmode = wmode_2_str(wdev->PhyMode); + } + + if (temp_wmode != NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%lu), %s\n", ulInfo, temp_wmode)); + os_free_mem(temp_wmode); + temp_wmode = NULL; + } else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%lu), Null\n", ulInfo)); + } + break; + + case OID_802_11_CHANNEL_WIDTH: { + wrq->u.data.length = sizeof(UCHAR); + ulInfo = wlan_operate_get_ht_bw(wdev); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_CHANNEL_WIDTH (=%lu)\n", ulInfo)); + break; + } + break; + + case RT_OID_802_11_COUNTRY_REGION: + wrq->u.data.length = sizeof(ulInfo); + ulInfo = pAd->CommonCfg.CountryRegionForABand; + ulInfo = (ulInfo << 8) | (pAd->CommonCfg.CountryRegion); + + if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length)) + Status = -EFAULT; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION (=%lu)\n", ulInfo)); + break; + + case OID_802_11_BEACON_PERIOD: + wrq->u.data.length = sizeof(ulInfo); + ulInfo = pAd->CommonCfg.BeaconPeriod; + + if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length)) + Status = -EFAULT; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_BEACON_PERIOD (=%lu)\n", ulInfo)); + break; + + case RT_OID_802_11_TX_POWER_LEVEL_1: + wrq->u.data.length = sizeof(UINT8); + ulInfo = pAd->CommonCfg.ucTxPowerPercentage[BAND0]; + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.ucTxPowerPercentage[BAND0], wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%u)\n", pAd->CommonCfg.ucTxPowerPercentage[BAND0])); + break; + + case RT_OID_802_11_QUERY_WMM: + if (wdev) { + wrq->u.data.length = sizeof(BOOLEAN); + Status = copy_to_user(wrq->u.data.pointer, &wdev->bWmmCapable, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", wdev->bWmmCapable)); + } + + break; + + case RT_OID_802_11_PREAMBLE: + wrq->u.data.length = sizeof(ulInfo); + ulInfo = pAd->CommonCfg.TxPreamble; + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%lu)\n", pAd->CommonCfg.TxPreamble)); + break; + + case OID_802_11_HT_STBC: + wrq->u.data.length = sizeof(UCHAR); + ulInfo = wlan_config_get_ht_stbc(wdev); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_HT_STBC(=%lu)\n", ulInfo)); + break; + + case OID_802_11_UAPSD: + if (wdev) { + wrq->u.data.length = sizeof(BOOLEAN); + Status = copy_to_user(wrq->u.data.pointer, &wdev->UapsdInfo.bAPSDCapable, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_UAPSD (=%d)\n", wdev->UapsdInfo.bAPSDCapable)); + } + + break; + + case OID_802_11_TX_PACKET_BURST: + wrq->u.data.length = sizeof(BOOLEAN); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bEnableTxBurst, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_TX_PACKET_BURST (=%d)\n", pAd->CommonCfg.bEnableTxBurst)); + break; + + case OID_802_11_COEXISTENCE: + wrq->u.data.length = sizeof(BOOLEAN); + Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bBssCoexEnable, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_COEXISTENCE (=%d)\n", pAd->CommonCfg.bBssCoexEnable)); + break; + + case OID_802_11_AMSDU: + wrq->u.data.length = sizeof(ulInfo); + ulInfo = pAd->CommonCfg.BACapability.field.AmsduEnable; + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_AMSDU (=%lu)\n", ulInfo)); + break; + + case OID_802_11_AMPDU: + wrq->u.data.length = sizeof(ulInfo); + ulInfo = pAd->CommonCfg.BACapability.field.AutoBA; + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_AMPDU (=%lu)\n", ulInfo)); + break; + + case OID_802_11_ASSOLIST: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_ASSOLIST\n")); + RTMPAPGetAssoMacTable(pAd, wrq); + break; +#ifdef WSC_AP_SUPPORT + + case OID_802_11_CURRENT_CRED: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_CURRENT_CRED\n")); + RTMPGetCurrentCred(pAd, wrq); + break; +#endif /* WSC_AP_SUPPORT */ +#endif /* VENDOR_FEATURE6_SUPPORT */ + + case OID_802_11_NETWORK_TYPES_SUPPORTED: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_QUERY_SIGNAL_CONTEXT\n")); +#ifdef DOT11R_FT_SUPPORT + FlgIs11rSup = TRUE; +#endif /* DOT11R_FT_SUPPORT */ + + if (FlgIs11rSup == FALSE) + Status = -EFAULT; + +#ifdef DOT11R_FT_SUPPORT + else { + FT_KDP_SIGNAL *pFtKdp; + FT_KDP_EVT_HEADER *pEvtHdr; + /* query signal content for 11r */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_QUERY_FT_KDP_CONTEXT\n")); + FT_KDP_EventGet(pAd, &pFtKdp); + + if (pFtKdp != NULL) + pEvtHdr = (FT_KDP_EVT_HEADER *)pFtKdp->Content; + + /* End of if */ + + if ((pFtKdp != NULL) && + ((RT_SIGNAL_STRUC_HDR_SIZE + pEvtHdr->EventLen) <= + wrq->u.data.length)) { + /* copy the event */ + if (copy_to_user( + wrq->u.data.pointer, + pFtKdp, + RT_SIGNAL_STRUC_HDR_SIZE + pEvtHdr->EventLen)) { + wrq->u.data.length = 0; + Status = -EFAULT; + } else { + wrq->u.data.length = RT_SIGNAL_STRUC_HDR_SIZE; + wrq->u.data.length += pEvtHdr->EventLen; + } + + FT_MEM_FREE(pAd, pFtKdp); + } else { + /* no event is queued */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ft_kdp> no event is queued!\n")); + wrq->u.data.length = 0; + } + } + +#endif /* DOT11R_FT_SUPPORT */ + } + break; +#ifdef DOT11R_FT_SUPPORT + + case RT_FT_DATA_ENCRYPT: + case RT_FT_DATA_DECRYPT: { + UCHAR *pBuffer; + UINT32 DataLen; + + DataLen = wrq->u.data.length; + + /* + Make sure the data length is multiple of 8 + due to AES_KEY_WRAP() limitation. + */ + if (DataLen & 0x07) + DataLen += 8 - (DataLen & 0x07); + + /* End of if */ + FT_MEM_ALLOC(pAd, &pBuffer, DataLen + FT_KDP_KEY_ENCRYPTION_EXTEND); + + if (pBuffer == NULL) + break; + + NdisZeroMemory(pBuffer, DataLen + FT_KDP_KEY_ENCRYPTION_EXTEND); + + if (copy_from_user(pBuffer, wrq->u.data.pointer, wrq->u.data.length)) { + Status = -EFAULT; + FT_MEM_FREE(pAd, pBuffer); + break; + } + + switch (cmd) { + case RT_FT_DATA_ENCRYPT: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_FT_DATA_ENCRYPT\n")); + FT_KDP_DataEncrypt(pAd, (UCHAR *)pBuffer, &DataLen); + break; + + case RT_FT_DATA_DECRYPT: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_FT_DATA_DECRYPT\n")); + FT_KDP_DataDecrypt(pAd, (UCHAR *)pBuffer, &DataLen); + break; + } + + wrq->u.data.length = DataLen; + + if (copy_to_user(wrq->u.data.pointer, pBuffer, wrq->u.data.length)) + Status = -EFAULT; + + FT_MEM_FREE(pAd, pBuffer); + } + break; + + case RT_OID_802_11R_INFO: { + UCHAR apidx = pObj->ioctl_if; + PFT_CONFIG_INFO pFtConfig; + PFT_CFG pFtCfg; + + os_alloc_mem(pAd, (UCHAR **)&pFtConfig, sizeof(FT_CONFIG_INFO)); + + if (pFtConfig == NULL) + break; + + pFtCfg = &pAd->ApCfg.MBSSID[apidx].wdev.FtCfg; + NdisZeroMemory(pFtConfig, sizeof(FT_CONFIG_INFO)); + pFtConfig->FtSupport = pFtCfg->FtCapFlag.Dot11rFtEnable; + pFtConfig->FtRicSupport = pFtCfg->FtCapFlag.RsrReqCap; + pFtConfig->FtOtdSupport = pFtCfg->FtCapFlag.FtOverDs; + NdisMoveMemory(pFtConfig->MdId, pFtCfg->FtMdId, FT_MDID_LEN); + pFtConfig->R0KHIdLen = pFtCfg->FtR0khIdLen; + NdisMoveMemory(pFtConfig->R0KHId, pFtCfg->FtR0khId, pFtCfg->FtR0khIdLen); + wrq->u.data.length = sizeof(FT_CONFIG_INFO); + Status = copy_to_user(wrq->u.data.pointer, pFtConfig, wrq->u.data.length); + os_free_mem(pFtConfig); + } + break; +#endif /* DOT11R_FT_SUPPORT */ +#endif /* IAPP_SUPPORT */ + +#ifdef CONFIG_11KV_API_SUPPORT +#ifdef CONFIG_DOT11V_WNM + case RT_QUERY_WNM_CAPABILITY: + { + PUCHAR p_wnm_query_data = NULL; + PMAC_TABLE_ENTRY pEntry = NULL; + PUINT8 p_cap = NULL; + struct wnm_command *p_wnm_command = NULL; + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[apidx].WNMCtrl; + UINT16 TotalLen = 0; + + TotalLen = wrq->u.data.length; + if (TotalLen != sizeof(*p_wnm_command)+MAC_ADDR_LEN+1) { + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_WNM, DBG_LVL_ERROR, + ("RT_QUERY_WNM_CAPABILITY: length(%d) check failed\n", + TotalLen)); + Status = EINVAL; + break; + } + + if (!pWNMCtrl->WNMBTMEnable) { + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_RRM, DBG_LVL_ERROR, + ("RT_QUERY_WNM_CAPABILITY: btm off\n")); + Status = EINVAL; + break; + } + + os_alloc_mem(NULL, (UCHAR **)&p_wnm_command, wrq->u.data.length); + if (p_wnm_command == NULL) { + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_RRM, DBG_LVL_ERROR, + ("RT_QUERY_WNM_CAPABILITY: no memory!!!\n")); + Status = ENOMEM; + break; + } + + if (copy_from_user(p_wnm_command, wrq->u.data.pointer, wrq->u.data.length)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RT_QUERY_WNM_CAPABILITY: copy from user failed!\n")); + Status = EFAULT; + os_free_mem(p_wnm_command); + break; + } + + p_wnm_query_data = p_wnm_command->command_body; + + /*first six bytes of data is sta mac*/ + pEntry = MacTableLookup(pAd, p_wnm_query_data); + if (!pEntry || + !(IS_AKM_OPEN(pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.SecConfig.AKMMap) || + ((pEntry->SecConfig.Handshake.WpaState == AS_PTKINITDONE) && + (pEntry->SecConfig.Handshake.GTKState == REKEY_ESTABLISHED)))) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("RT_QUERY_WNM_CAPABILITY: ")); + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_RRM, DBG_LVL_ERROR, + ("STA(%02x:%02x:%02x:%02x:%02x:%02x)not associates with AP!\n", + PRINT_MAC(p_wnm_query_data))); + Status = EINVAL; + os_free_mem(p_wnm_command); + break; + } + /*check for btm capablility*/ + p_cap = (UINT8 *)(p_wnm_query_data+MAC_ADDR_LEN); + *p_cap = 0; + + if (p_wnm_command->command_id == + OID_802_11_WNM_CMD_QUERY_BTM_CAP) { + if (pEntry->BssTransitionManmtSupport) { + *p_cap = 1; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("RT_QUERY_WNM_CAPABILITY: BTMCap=%d\n", (*p_cap))); + } + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RT_QUERY_WNM_CAPABILITY: only check btm cap now\n")); + Status = EINVAL; + os_free_mem(p_wnm_command); + break; + } + if (copy_to_user(wrq->u.data.pointer, (PUCHAR)p_wnm_command, wrq->u.data.length)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RT_QUERY_WNM_CAPABILITY: copy to user failed!\n")); + Status = EFAULT; + os_free_mem(p_wnm_command); + break; + } + os_free_mem(p_wnm_command); + break; + } +#endif +#ifdef DOT11K_RRM_SUPPORT + case RT_QUERY_RRM_CAPABILITY: + { + PUCHAR p_rrm_query_data = NULL; + PMAC_TABLE_ENTRY pEntry = NULL; + p_rrm_command_t p_rrm_command = NULL; + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx]; + PUINT8 p_cap = NULL; + UINT16 TotalLen = 0; + + TotalLen = wrq->u.data.length; + if (TotalLen != sizeof(*p_rrm_command) + MAC_ADDR_LEN + 8) { + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_WNM, DBG_LVL_ERROR, + ("RT_QUERY_RRM_CAPABILITY: length(%d) check failed\n", + TotalLen)); + Status = EINVAL; + break; + } + if (!pMbss->wdev.RrmCfg.bDot11kRRMEnable) { + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_WNM, DBG_LVL_ERROR, + ("%s(): RT_QUERY_RRM_CAPABILITY: rrm off, IF Index: %d\n", __func__, apidx)); + Status = EINVAL; + break; + } + os_alloc_mem(NULL, (UCHAR **)&p_rrm_command, wrq->u.data.length); + if (p_rrm_command == NULL) { + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_RRM, DBG_LVL_ERROR, + ("RT_QUERY_RRM_CAPABILITY : no memory!!!\n")); + Status = ENOMEM; + break; + } + + if (copy_from_user(p_rrm_command, wrq->u.data.pointer, wrq->u.data.length)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RT_QUERY_RRM_CAPABILITY: copy from user failed!\n")); + Status = EFAULT; + os_free_mem(p_rrm_command); + break; + } + + p_rrm_query_data = p_rrm_command->command_body; + + /*first six bytes of data is sta mac*/ + pEntry = MacTableLookup(pAd, p_rrm_query_data); + if (!pEntry || + !(IS_AKM_OPEN(pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.SecConfig.AKMMap) || + ((pEntry->SecConfig.Handshake.WpaState == AS_PTKINITDONE) && + (pEntry->SecConfig.Handshake.GTKState == REKEY_ESTABLISHED)))) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RT_QUERY_RRM_CAPABILITY: ")); + MTWF_LOG(DBG_CAT_PROTO, CATPROTO_RRM, DBG_LVL_ERROR, + ("STA(%02x:%02x:%02x:%02x:%02x:%02x) not associates with AP!\n", + PRINT_MAC(p_rrm_query_data))); + Status = EINVAL; + os_free_mem(p_rrm_command); + break; + } + /*check for btm capablility*/ + p_cap = (UINT8 *)(p_rrm_query_data+MAC_ADDR_LEN); + memset(p_cap, 0, 8); + + if (p_rrm_command->command_id == + OID_802_11_RRM_CMD_QUERY_CAP) { + memcpy(p_cap, (PUCHAR)&(pEntry->RrmEnCap), sizeof(pEntry->RrmEnCap)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("RT_QUERY_WNM_CAPABILITY: only check rrm cap now\n")); + Status = EINVAL; + os_free_mem(p_rrm_command); + break; + } + if (copy_to_user(wrq->u.data.pointer, (PUCHAR)p_rrm_command, wrq->u.data.length)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RT_QUERY_RRM_CAPABILITY: copy to user failed!\n")); + Status = EFAULT; + os_free_mem(p_rrm_command); + break; + } + os_free_mem(p_rrm_command); + break; + } +#endif +#endif /* CONFIG_11KV_API_SUPPORT */ + +#ifdef WSC_AP_SUPPORT +#ifdef VENDOR_FEATURE7_SUPPORT + case ARRIS_OID_WSC_QUERY_STATE: { + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, + &pAd->ApCfg.MBSSID[apidx].WscControl.WscState, wrq->u.data.length); + } + break; +#endif + case RT_OID_WSC_QUERY_STATUS: { + INT WscStatus; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl.WscStatus; + } else +#endif /* APCLI_SUPPORT */ + { + WscStatus = pAd->ApCfg.MBSSID[apidx].wdev.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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_WSC_PIN_CODE\n")); + wrq->u.data.length = sizeof(UINT); + /*WscPinCode = GenerateWpsPinCode(pAd, FALSE, apidx); */ + pWscControl = &pAd->ApCfg.MBSSID[apidx].wdev.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: + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_APCLI_WSC_PIN_CODE\n")); + wrq->u.data.length = sizeof(UINT); + /*WscPinCode = GenerateWpsPinCode(pAd, TRUE, apidx); */ + WscPinCode = pAd->ApCfg.ApCliTab[apidx].wdev.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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_WSC_QUERY_UUID\n")); + wrq->u.data.length = UUID_LEN_STR; + pWscControl = &pAd->ApCfg.MBSSID[apidx].wdev.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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.bssid, wrq->u.data.length)) + Status = -EFAULT; + + break; + + case RT_OID_WSC_CONFIG_STATUS: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl.WscConfStatus, wrq->u.data.length)) + Status = -EFAULT; + + break; + + case RT_OID_WSC_QUERY_PEER_INFO_ON_RUNNING: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_WSC_QUERY_PEER_INFO_ON_RUNNING\n")); + + if (pAd->ApCfg.MBSSID[apidx].wdev.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].wdev.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); + os_alloc_mem(pAd, (UCHAR **)&pProfile, sizeof(WSC_PROFILE)); + + if (pProfile == NULL) { + Status = -EFAULT; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RT_OID_802_11_WSC_QUERY_PROFILE fail!\n")); + break; + } + +#ifdef APCLI_SUPPORT + if (pObj->ioctl_if_type == INT_APCLI) { + APCLI_MR_APIDX_SANITY_CHECK(apidx); + pWscControl = &pAd->ApCfg.ApCliTab[apidx].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(apcli : %d) RT_OID_802_11_WSC_QUERY_PROFILE :: This command is from apcli interface now.\n", apidx)); + } else +#endif /* APCLI_SUPPORT */ + pWscControl = &pAd->ApCfg.MBSSID[apidx].wdev.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(pProfile); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_WSC_QUERY_PROFILE\n")); + break; +#ifdef WSC_V2_SUPPORT + + case RT_OID_WSC_V2_SUPPORT: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_WSC_V2_SUPPORT (=%d)\n", + pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscV2Info.bEnableWpsV2)); + wrq->u.data.length = sizeof(BOOLEAN); + + if (copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscV2Info.bEnableWpsV2, + wrq->u.data.length)) + Status = -EFAULT; + + break; + + case RT_OID_WSC_FRAGMENT_SIZE: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_WSC_FRAGMENT_SIZE (=%d)\n", + pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscFragSize)); + wrq->u.data.length = sizeof(USHORT); + + if (copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].wdev.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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]) && (pAd->MacTab.Content[i].Sst == SST_ASSOC)) { + COPY_MAC_ADDR(AssocTab.Entry[AssocTab.Num].Addr, &pAd->MacTab.Content[i].Addr); + AssocTab.Entry[AssocTab.Num].phyMode = pAd->ApCfg.MBSSID[apidx].wdev.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)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: copy_to_user() fail\n", __func__)); + Status = -EFAULT; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AssocTab.Num = %d\n", AssocTab.Num)); + } + + break; +#ifdef APCLI_SUPPORT + + case RT_OID_GET_REPEATER_AP_LINEAGE: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Not Support : Get repeater AP lineage.\n")); + break; +#endif /* APCLI_SUPPORT */ +#endif /* LLTD_SUPPORT */ +#ifdef DOT1X_SUPPORT + + case OID_802_DOT1X_CONFIGURATION: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::Get Radius setting(%lu)\n", + (ULONG)sizeof(DOT1X_CMM_CONF))); + Dot1xIoctlQueryRadiusConf(pAd, wrq); + break; + + case OID_802_DOT1X_QUERY_STA_AID: + RTMPIoctlQueryStaAid(pAd, wrq); + break; +#ifdef RADIUS_ACCOUNTING_SUPPORT + + case OID_802_DOT1X_QUERY_STA_DATA: + RTMPIoctlQueryStaData(pAd, wrq); + break; +#endif /* RADIUS_ACCOUNTING_SUPPORT */ + case OID_802_DOT1X_QUERY_STA_RSN: + RTMPIoctlQueryStaRsn(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].wdev.bssid, wrq->u.data.length); + break; +#ifdef SNMP_SUPPORT + + case RT_OID_802_11_MANUFACTUREROUI: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE\n")); + pKeyIdxValue = wrq->u.data.pointer; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("DefaultKeyId =%d\n", + pAd->ApCfg.MBSSID[pObj->ioctl_if].DefaultKeyId)); + break; + + case RT_OID_802_11_WEPKEYMAPPINGLENGTH: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT\n")); + wrq->u.data.length = sizeof(ULONG); + ShortRetryLimit = AsicGetRetryLimit(pAd, TX_RTY_CFG_RTY_LIMIT_SHORT); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ShortRetryLimit =%ld\n", ShortRetryLimit)); + Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length); + break; + + case OID_802_11_LONGRETRYLIMIT: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT\n")); + wrq->u.data.length = sizeof(ULONG); + LongRetryLimit = AsicGetRetryLimit(pAd, TX_RTY_CFG_RTY_LIMIT_LONG); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("LongRetryLimit =%ld\n", LongRetryLimit)); + Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length); + break; + + case RT_OID_802_11_PRODUCTID: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_PRODUCTID\n")); +#ifdef RTMP_PCI_SUPPORT + + if (IS_PCI_INF(pAd)) { + USHORT device_id; + + if (((POS_COOKIE)pAd->OS_Cookie)->pci_dev != NULL) + pci_read_config_word(((POS_COOKIE)pAd->OS_Cookie)->pci_dev, PCI_DEVICE_ID, &device_id); + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, (" pci_dev = NULL\n")); + + snprintf((RTMP_STRING *)snmp_tmp, sizeof(snmp_tmp), "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id); + } + +#endif /* RTMP_PCI_SUPPORT */ + wrq->u.data.length = strlen((RTMP_STRING *) snmp_tmp); + Status = copy_to_user(wrq->u.data.pointer, snmp_tmp, wrq->u.data.length); + break; + + case RT_OID_802_11_MANUFACTUREID: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; +#endif /* SNMP_SUPPORT */ +#if (defined(SNMP_SUPPORT) || defined(WH_EZ_SETUP) || defined(VENDOR_FEATURE6_SUPPORT)) + + case OID_802_11_CURRENTCHANNEL: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_CURRENTCHANNEL\n")); + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, &pAd->ApCfg.MBSSID[apidx].wdev.channel, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Status=%d\n", Status)); + break; +#endif + + case OID_802_11_STATISTICS: + os_alloc_mem(pAd, (UCHAR **)&pStatistics, sizeof(NDIS_802_11_STATISTICS)); + + if (pStatistics) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_STATISTICS\n")); + /* add the most up-to-date h/w raw counters into software counters */ + /*NICUpdateRawCountersNew(pAd);*/ + pStatistics->TransmittedFragmentCount.QuadPart = pAd->WlanCounters[0].TransmittedFragmentCount.QuadPart + + pAd->WlanCounters[0].MulticastTransmittedFrameCount.QuadPart; + pStatistics->MulticastTransmittedFrameCount.QuadPart = pAd->WlanCounters[0].MulticastTransmittedFrameCount.QuadPart; + pStatistics->FailedCount.QuadPart = pAd->WlanCounters[0].FailedCount.QuadPart; + pStatistics->RetryCount.QuadPart = pAd->WlanCounters[0].RetryCount.QuadPart; + pStatistics->MultipleRetryCount.QuadPart = pAd->WlanCounters[0].MultipleRetryCount.QuadPart; + pStatistics->RTSSuccessCount.QuadPart = pAd->WlanCounters[0].RTSSuccessCount.QuadPart; + pStatistics->RTSFailureCount.QuadPart = pAd->WlanCounters[0].RTSFailureCount.QuadPart; + pStatistics->ACKFailureCount.QuadPart = pAd->WlanCounters[0].ACKFailureCount.QuadPart; + pStatistics->FrameDuplicateCount.QuadPart = pAd->WlanCounters[0].FrameDuplicateCount.QuadPart; + pStatistics->ReceivedFragmentCount.QuadPart = pAd->WlanCounters[0].ReceivedFragmentCount.QuadPart; + pStatistics->MulticastReceivedFrameCount.QuadPart = pAd->WlanCounters[0].MulticastReceivedFrameCount.QuadPart; +#ifdef DBG + pStatistics->FCSErrorCount = pAd->RalinkCounters.RealFcsErrCount; +#else + pStatistics->FCSErrorCount.QuadPart = pAd->WlanCounters[0].FCSErrorCount.QuadPart; + pStatistics->FrameDuplicateCount.u.LowPart = pAd->WlanCounters[0].FrameDuplicateCount.u.LowPart / 100; +#endif + pStatistics->TransmittedFrameCount.QuadPart = pAd->WlanCounters[0].TransmittedFragmentCount.QuadPart; + pStatistics->WEPUndecryptableCount.QuadPart = pAd->WlanCounters[0].WEPUndecryptableCount.QuadPart; + wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS); + Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length); + os_free_mem(pStatistics); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_STATISTICS(mem alloc failed)\n")); + Status = -EFAULT; + } + + break; + + case RT_OID_802_11_PER_BSS_STATISTICS: { + PMBSS_STATISTICS pMbssStat; + INT apidx = pObj->ioctl_if; + BSS_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); + Status = copy_to_user(wrq->u.data.pointer, pMbssStat, wrq->u.data.length); + os_free_mem(pMbssStat); + } + break; +#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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + STA_TR_ENTRY *tr_entry; + PAPCLI_STRUCT pApCliEntry; + + if (pObj->ioctl_if_type != INT_APCLI) { + Status = -EOPNOTSUPP; + break; + } + + APCLI_MR_APIDX_SANITY_CHECK(ApCliIdx); + pApCliEntry = &pAd->ApCfg.ApCliTab[ApCliIdx]; + + if (pApCliEntry->MacTabWCID >= MAX_LEN_OF_MAC_TABLE) { + Status = -EOPNOTSUPP; + break; + } + + pEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID]; + tr_entry = &pAd->MacTab.tr_entry[pApCliEntry->MacTabWCID]; + + if (!IS_ENTRY_APCLI(pEntry) && !IS_ENTRY_REPEATER(pEntry)) { + Status = -EOPNOTSUPP; + break; + } + + if ((pAd->ApCfg.ApCliTab[ApCliIdx].Valid == TRUE) + && (tr_entry->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 */ +#ifdef RTMP_RBUS_SUPPORT + + case RT_OID_802_11_SNR_0: + if (wdev && wdev->LastSNR0 > 0) { + ULONG ulInfo; + + ulInfo = ConvertToSnr(pAd, wdev->LastSNR0); + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo)); + } else + Status = -EFAULT; + + break; + + case RT_OID_802_11_SNR_1: + if (wdev && (pAd->Antenna.field.RxPath > 1) && (wdev->LastSNR1 > 0)) { + ULONG ulInfo; + + ulInfo = ConvertToSnr(pAd, wdev->LastSNR1); + wrq->u.data.length = sizeof(ulInfo); + Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_SNR_1(%lx, LastSNR1=%d)\n", ulInfo, + wdev->LastSNR1)); + } else + Status = -EFAULT; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::RT_OID_802_11_SNR_1, Status=%d\n", Status)); + break; +#endif /* RTMP_RBUS_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; +#ifdef CONFIG_HOTSPOT +#ifdef CONFIG_DOT11V_WNM + + case OID_802_11_WNM_IPV4_PROXY_ARP_LIST: { + BSS_STRUCT *pMbss; + PUCHAR pProxyARPTable; + UINT32 ARPTableLen; + + pMbss = &pAd->ApCfg.MBSSID[pObj->ioctl_if]; + ARPTableLen = IPv4ProxyARPTableLen(pAd, pMbss); + os_alloc_mem(NULL, &pProxyARPTable, ARPTableLen); + GetIPv4ProxyARPTable(pAd, pMbss, &pProxyARPTable); + wrq->u.data.length = ARPTableLen; + Status = copy_to_user(wrq->u.data.pointer, pProxyARPTable, ARPTableLen); + os_free_mem(pProxyARPTable); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::OID_802_11_WNM_PROXY_ARP_LIST\n")); + break; + + case OID_802_11_WNM_IPV6_PROXY_ARP_LIST: { + BSS_STRUCT *pMbss; + PUCHAR pProxyARPTable; + UINT32 ARPTableLen; + + pMbss = &pAd->ApCfg.MBSSID[pObj->ioctl_if]; + ARPTableLen = IPv6ProxyARPTableLen(pAd, pMbss); + os_alloc_mem(NULL, &pProxyARPTable, ARPTableLen); + GetIPv6ProxyARPTable(pAd, pMbss, &pProxyARPTable); + wrq->u.data.length = ARPTableLen; + Status = copy_to_user(wrq->u.data.pointer, pProxyARPTable, ARPTableLen); + os_free_mem(pProxyARPTable); + } + break; +#endif + + case OID_802_11_SECURITY_TYPE: { + BSS_STRUCT *pMbss; + PUCHAR pType; + struct security_type *SecurityType; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Query:OID_802_11_SECURITY_TYPE\n")); + os_alloc_mem(NULL, &pType, sizeof(*SecurityType)); + SecurityType = (struct security_type *)pType; + pMbss = &pAd->ApCfg.MBSSID[pObj->ioctl_if]; + SecurityType->ifindex = pObj->ioctl_if; + SecurityType->auth_mode = SecAuthModeNewToOld(pMbss->wdev.SecConfig.AKMMap); + SecurityType->encryp_type = SecEncryModeNewToOld(pMbss->wdev.SecConfig.PairwiseCipher); + wrq->u.data.length = sizeof(*SecurityType); + Status = copy_to_user(wrq->u.data.pointer, pType, sizeof(*SecurityType)); + os_free_mem(pType); + } + break; + + case OID_802_11_HS_BSSID: { + BSS_STRUCT *pMbss; + + pMbss = &pAd->ApCfg.MBSSID[pObj->ioctl_if]; + wrq->u.data.length = 6; + Status = copy_to_user(wrq->u.data.pointer, pMbss->wdev.bssid, 6); + } + break; +#ifdef CONFIG_HOTSPOT_R2 + + case OID_802_11_HS_OSU_SSID: { + wrq->u.data.length = pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen; /* +2; */ + /* tmpbuf[0] = IE_SSID; */ + /* tmpbuf[1] = pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen; */ + /* memcpy(&tmpbuf[2], pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid, pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen); */ + /* Status = copy_to_user(wrq->u.data.pointer, tmpbuf, wrq->u.data.length); */ + Status = copy_to_user(wrq->u.data.pointer, pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid, + pAd->ApCfg.MBSSID[pObj->ioctl_if].SsidLen); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\033[1;32m %s, %u OID_802_11_HS_OSU_SSID [%s]\033[0m\n" + , __func__, __LINE__, pAd->ApCfg.MBSSID[pObj->ioctl_if].Ssid)); + /* this is an osu ssid , disable 11U capability */ + pAd->ApCfg.MBSSID[pObj->ioctl_if].GASCtrl.b11U_enable = FALSE; + } + break; +#endif /* CONFIG_HOTSPOT_R2 */ +#endif +#ifdef VENDOR_FEATURE7_SUPPORT +#ifdef DOT11_N_SUPPORT + case ARRIS_OID_HTEXTCHA_QUERY_VALUE: { + PUCHAR Buf = NULL; + + os_alloc_mem(pAd, (UCHAR **)&Buf, wrq->u.data.length); + if (!Buf) { + Status = -EINVAL; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Memory is not available\n")); + } + Show_HtExtcha_Proc(pAd, Buf, wrq->u.data.length); + Status = copy_to_user(wrq->u.data.pointer, Buf, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("HtExtCha is:%s", Buf)); + os_free_mem(Buf); + } + break; +#endif +#endif +#ifdef WIFI_SPECTRUM_SUPPORT + case OID_802_11_WIFISPECTRUM_GET_CAPTURE_BW: { + UINT32 CapNode; + UCHAR CapBw; + + CapNode = Get_System_CapNode_Info(pAd); + CapBw = Get_System_Bw_Info(pAd, CapNode); + wrq->u.data.length = sizeof(UCHAR); + Status = copy_to_user(wrq->u.data.pointer, &CapBw, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Query::OID_802_11_WIFISPECTRUM_GET_CAPTURE_BW CapBw = %d\n", CapBw)); + } + break; + + case OID_802_11_WIFISPECTRUM_GET_CENTRAL_FREQ: { + UINT32 CapNode; + USHORT CenFreq; + + CapNode = Get_System_CapNode_Info(pAd); + CenFreq = Get_System_CenFreq_Info(pAd, CapNode); + wrq->u.data.length = sizeof(USHORT); + Status = copy_to_user(wrq->u.data.pointer, &CenFreq, wrq->u.data.length); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Query::OID_802_11_WIFISPECTRUM_GET_CENTRAL_FREQ CenFreq = %d\n", CenFreq)); + } + break; +#endif /* WIFI_SPECTRUM_SUPPORT */ +#ifdef MT_DFS_SUPPORT + case OID_DFS_ZERO_WAIT: + Status = ZeroWaitDfsQueryCmdHandler(pAd, wrq); + break; +#endif + + default: + Status = -EOPNOTSUPP; + + if (Status == -EOPNOTSUPP) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Query::unknown IOCTL's subcmd = 0x%08x, apidx=%d\n", cmd, apidx)); + } + + break; + } + + return Status; +} + +/* + ========================================================================== + Description: + Set Country Code. + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_CountryCode_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef RF_LOCKDOWN + + /* Check RF lock Status */ + if (chip_check_rf_lock_down(pAd)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: RF lock down!! Cannot config CountryCode status!!\n", + __func__)); + return TRUE; + } + +#endif /* RF_LOCKDOWN */ +#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, + sizeof(pAd->CommonCfg.CountryCode)); + pAd->CommonCfg.bCountryFlag = FALSE; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + ULONG Geography; + + Geography = os_str_tol(arg, 0, 10); + + if (Geography <= BOTH) + pAd->CommonCfg.Geography = Geography; + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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'); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT index = 0; + INT success = TRUE; + RTMP_STRING name_buffer[40] = {0}; + BOOLEAN IsSupport5G = HcIsRfSupport(pAd, RFIC_5GHZ); + BOOLEAN IsSupport2G = HcIsRfSupport(pAd, RFIC_24GHZ); +#ifdef EXT_BUILD_CHANNEL_LIST + return -EOPNOTSUPP; +#endif /* EXT_BUILD_CHANNEL_LIST */ + + if (strlen(arg) <= 38) { + if (strlen(arg) < 4) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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\"", (RTMP_STRING *) allCountry[index].pCountryName); + + if (strncmp((RTMP_STRING *) 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 (pAd->CommonCfg.CountryRegion & 0x80) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Set_CountryString_Proc::parameter of CountryRegion in eeprom is programmed\n")); + success = FALSE; + } else { + success = FALSE; + + if (IsSupport2G) { + if (allCountry[index].SupportGBand == TRUE) { + pAd->CommonCfg.CountryRegion = (UCHAR) allCountry[index].RegDomainNum11G; + success = TRUE; + } else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("The Country are not Support G Band Channel\n")); + } + + if (IsSupport5G) { + if (allCountry[index].SupportABand == TRUE) { + pAd->CommonCfg.CountryRegionForABand = (UCHAR) allCountry[index].RegDomainNum11A; + success = TRUE; + } else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("The Country are not Support A Band Channel\n")); + } + } + } + + if (success == TRUE) { + os_zero_mem(pAd->CommonCfg.CountryCode, sizeof(pAd->CommonCfg.CountryCode)); + os_move_mem(pAd->CommonCfg.CountryCode, allCountry[index].IsoName, 2); + pAd->CommonCfg.CountryCode[2] = ' '; + /* 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); */ + pAd->CommonCfg.bCountryFlag = TRUE; + /* if set country string, driver needs to be reset */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Set_CountryString_Proc::(CountryString=%s CountryRegin=%d CountryCode=%s)\n", + allCountry[index].pCountryName, pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryCode)); + } else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Set_CountryString_Proc::Parameters out of range\n")); + + return success; +} + +VOID restart_ap(void *wdev_obj) +{ + struct wifi_dev *wdev = wdev_obj; + BSS_STRUCT *mbss = wdev->func_dev; + + UpdateBeaconHandler( + wdev->sys_handle, + wdev, + BCN_UPDATE_DISABLE_TX); + wifi_sys_linkdown(wdev); + wifi_sys_close(wdev); + wifi_sys_open(wdev); + wifi_sys_linkup(wdev, NULL); + if (IS_SECURITY(&wdev->SecConfig)) + mbss->CapabilityInfo |= 0x0010; + else + mbss->CapabilityInfo &= (~0x0010); + UpdateBeaconHandler(wdev->sys_handle, wdev, BCN_UPDATE_IE_CHG); +} + +/* + ========================================================================== + Description: + Set SSID + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_AP_SSID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT success = FALSE; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + BSS_STRUCT *pMbss = NULL; + struct DOT11_H *pDot11h = NULL; + + if (((pObj->ioctl_if < HW_BEACON_MAX_NUM)) && (strlen(arg) <= MAX_LEN_OF_SSID)) { + struct wifi_dev *wdev = NULL; + + pMbss = &pAd->ApCfg.MBSSID[pObj->ioctl_if]; + wdev = &pMbss->wdev; + NdisZeroMemory(pMbss->Ssid, MAX_LEN_OF_SSID); + NdisMoveMemory(pMbss->Ssid, arg, strlen(arg)); + pMbss->SsidLen = (UCHAR)strlen(arg); + success = TRUE; + + if (wdev == NULL) + return FALSE; + + pDot11h = wdev->pDot11_H; + if (pDot11h == NULL) + return FALSE; + { + ApSendBroadcastDeauth(pAd, wdev); + if (IS_SECURITY(&wdev->SecConfig)) + pMbss->CapabilityInfo |= 0x0010; + else + pMbss->CapabilityInfo &= ~(0x0010); + APSecInit(pAd, wdev); + restart_ap(&pMbss->wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("I/F(ra%d) Set_SSID_Proc::(Len=%d,Ssid=%s)\n", + pObj->ioctl_if, + pMbss->SsidLen, pMbss->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 RTMP_STRING *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 = os_str_tol(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, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + ULONG BasicRateBitmap; + + BasicRateBitmap = (ULONG) os_str_tol(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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + USHORT BeaconPeriod; + INT success = FALSE; + + BeaconPeriod = (USHORT) os_str_tol(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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + USHORT DtimPeriod; + INT success = FALSE; + + DtimPeriod = (USHORT) os_str_tol(arg, 0, 10); + + if ((DtimPeriod >= 1) && (DtimPeriod <= 255)) { + pAd->ApCfg.DtimPeriod = DtimPeriod; + success = TRUE; + } else + success = FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + switch (os_str_tol(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; +} + + +/* +* +*/ +INT set_qiscdump_proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype( + pAd, pObj->ioctl_if, pObj->ioctl_if_type); + PNET_DEV ndev = NULL; + + if (wdev == NULL) + return FALSE; + + ndev = wdev->if_dev; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): wdev=%p, idx=%d, dev=%p, %s\n", + __func__, wdev, wdev->wdev_idx, ndev, ndev->name)); + +#ifdef CONFIG_DBG_QDISC + if (wdev && wdev->func_dev) + os_system_tx_queue_dump(ndev); +#endif + return TRUE; +} + + +/* + ========================================================================== + 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 RTMP_STRING *arg) +{ + BOOLEAN bWmmCapable; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + struct wifi_dev *wdev; + + bWmmCapable = os_str_tol(arg, 0, 10); + wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + + if (bWmmCapable == 1) + wdev->bWmmCapable = TRUE; + else if (bWmmCapable == 0) + wdev->bWmmCapable = FALSE; + else + return FALSE; /*Invalid argument */ + + pAd->ApCfg.MBSSID[pObj->ioctl_if].bWmmCapableOrg = + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.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 */ + SetCommonHtVht(pAd, wdev); +#endif /* DOT11_N_SUPPORT */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_WmmCapable_Proc::(bWmmCapable=%d)\n", + pObj->ioctl_if, wdev->bWmmCapable)); + return TRUE; +} + + +INT Set_AP_PerMbssMaxStaNum_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + INT apidx = pObj->ioctl_if; + + return ApCfg_Set_PerMbssMaxStaNum_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 RTMP_STRING *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 RTMP_STRING *arg) +{ + ULONG NoForwarding; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + NoForwarding = os_str_tol(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 */ + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + ULONG NoForwarding; + + NoForwarding = os_str_tol(arg, 0, 10); + + if (NoForwarding == 1) + pAd->ApCfg.IsolateInterStaTrafficBTNBSSID = TRUE; + else if (NoForwarding == 0) + pAd->ApCfg.IsolateInterStaTrafficBTNBSSID = FALSE; + else + return FALSE; /*Invalid argument */ + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + BOOLEAN bHideSsid; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + bHideSsid = os_str_tol(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].wdev.WscControl.WscV2Info.bEnableWpsV2) + WscOnOff(pAd, pObj->ioctl_if, pAd->ApCfg.MBSSID[pObj->ioctl_if].bHideSsid); + +#endif /* WSC_V2_SUPPORT */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev; + + wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + wdev->VLAN_VID = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_VLANID_Proc::(VLAN_VID=%d)\n", + pObj->ioctl_if, wdev->VLAN_VID)); + return TRUE; +} + + +/* + ========================================================================== + Description: + Set VLAN's priority field + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_VLANPriority_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + + wdev->VLAN_Priority = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_VLANPriority_Proc::(VLAN_Priority=%d)\n", + pObj->ioctl_if, wdev->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(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + BOOLEAN bVLAN_Tag; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev; + + bVLAN_Tag = os_str_tol(arg, 0, 10); + + if (bVLAN_Tag == 1) + bVLAN_Tag = TRUE; + else if (bVLAN_Tag == 0) + bVLAN_Tag = FALSE; + else + return FALSE; /* Invalid argument */ + + wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + wdev->bVLAN_Tag = bVLAN_Tag; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_VLAN_TAG_Proc::(VLAN_Tag=%d)\n", + pObj->ioctl_if, wdev->bVLAN_Tag)); + return TRUE; +} + + +INT Set_AP_WpaMixPairCipher_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + /* + 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) + */ + Set_SecAuthMode_Proc(pAd, arg); + Set_SecEncrypType_Proc(pAd, arg); + 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 RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + ULONG value_interval; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + value_interval = os_str_tol(arg, 0, 10); + + if ((value_interval >= 10) && (value_interval < MAX_GROUP_REKEY_INTERVAL)) + pSecConfig->GroupReKeyInterval = value_interval; + else /*Default*/ + pSecConfig->GroupReKeyInterval = DEFAULT_GROUP_REKEY_INTERVAL; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(%s%d) GroupKey ReKeyInterval=%ld seconds\n", + INF_MBSSID_DEV_NAME, apidx, pSecConfig->GroupReKeyInterval)); + return TRUE; +} + +#ifdef SPECIFIC_TX_POWER_SUPPORT +INT Set_AP_PKT_PWR( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + INT input; + + input = os_str_tol(arg, 0, 10); + + /* + Tx_PWR_ADJ[3:0] From 0 to 7 is Positive & add with Tx Power (dB), + From 8 to 15 is minus with Tx Power mapping to -16 to -2 (step by 2), + Default value: 0. + + [0x13BC]TX_ALC_MONITOR, 13:8 + TX_ALC_REQ_ADJ TX ALC Req Saturated[5:0], unit (0.5dB) + */ + + if ((input >= 0) && (input <= 15)) + pAd->ApCfg.MBSSID[apidx].TxPwrAdj = input; + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("AP[%d]->PktPwr: Out of Range\n")); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AP[%d]->PktPwr: %d\n", apidx, + pAd->ApCfg.MBSSID[apidx].TxPwrAdj)); + return TRUE; +} +#endif /* SPECIFIC_TX_POWER_SUPPORT */ +/* + ========================================================================== + Description: + Set WPA rekey method + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_AP_RekeyMethod_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + if (rtstrcasecmp(arg, "TIME") == TRUE) + pSecConfig->GroupReKeyMethod = SEC_GROUP_REKEY_TIME; + else if (rtstrcasecmp(arg, "PKT") == TRUE) + pSecConfig->GroupReKeyMethod = SEC_GROUP_REKEY_PACKET; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(%s%d) GroupKey ReKeyMethod=%x\n", + INF_MBSSID_DEV_NAME, apidx, pSecConfig->GroupReKeyMethod)); + 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 RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + UINT32 val = os_str_tol(arg, 0, 10); + + pAd->ApCfg.MBSSID[apidx].PMKCachePeriod = val * 60 * OS_HZ; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(ra%d) Set_AP_PMKCachePeriod_Proc=%ld\n", + apidx, pAd->ApCfg.MBSSID[apidx].PMKCachePeriod)); + return TRUE; +} + + +/* + ========================================================================== + Description: + Set AssocReq RSSI Threshold to reject STA with weak signal. + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_AP_ASSOC_REQ_RSSI_THRESHOLD( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + UINT j; + CHAR rssi; + + rssi = os_str_tol(arg, 0, 10); + + if (rssi == 0) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Disable AP_ASSOC_REQ_RSSI_THRESHOLD\n")); + else if (rssi > 0 || rssi < -100) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_AP_ASSOC_REQ_RSSI_THRESHOLD Value Error.\n")); + return FALSE; + } + + pAd->ApCfg.MBSSID[apidx].AssocReqRssiThreshold = rssi; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(ra%d) Set_AP_ASSOC_REQ_RSSI_THRESHOLD=%d\n", apidx, + pAd->ApCfg.MBSSID[apidx].AssocReqRssiThreshold)); + + for (j = BSS0; j < pAd->ApCfg.BssidNum; j++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%d. ==> %d\n", j, pAd->ApCfg.MBSSID[j].AssocReqRssiThreshold)); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set lower limit for AP kicking out a STA. + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_AP_KickStaRssiLow_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + UINT j; + CHAR rssi; + + rssi = os_str_tol(arg, 0, 10); + + if (rssi == 0) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Disable RssiLowForStaKickOut Function\n")); + else if (rssi > 0 || rssi < -100) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RssiLowForStaKickOut Value Error.\n")); + return FALSE; + } + + pAd->ApCfg.MBSSID[apidx].RssiLowForStaKickOut = rssi; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(ra%d) RssiLowForStaKickOut=%d\n", apidx, + pAd->ApCfg.MBSSID[apidx].RssiLowForStaKickOut)); + + for (j = BSS0; j < pAd->ApCfg.BssidNum; j++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%d. ==> %d\n", j, pAd->ApCfg.MBSSID[j].RssiLowForStaKickOut)); + + return TRUE; +} + + +/* + ========================================================================== + Description: + Set Access ctrol policy + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_AccessPolicy_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + switch (os_str_tol(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 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + UCHAR macAddr[MAC_ADDR_LEN]; + /* RT_802_11_ACL acl; */ + RT_802_11_ACL *pacl = NULL; + RTMP_STRING *this_char; + RTMP_STRING *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)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Allocate memory fail!!!\n", __func__)); + 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') { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("An unnecessary delimiter entered!\n")); + continue; + } + + if (strlen(this_char) != 17) { /*Mac address acceptable format 01:02:03:04:05:06 length 17 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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)))) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("illegal MAC address format or octet!\n")); + /* Do not use "continue" to replace "break" */ + break; + } + + AtoH(value, &macAddr[i++], 1); + } + + if (i != MAC_ADDR_LEN) + continue; + + /* Check if this entry is duplicate. */ + isDuplicate = FALSE; + + for (j = 0; j < pacl->Num; j++) { + if (memcmp(pacl->Entry[j].Addr, &macAddr, 6) == 0) { + isDuplicate = TRUE; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("You have added an entry before :\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("The AccessControlList is full, and no more entry can join the list!\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Set::%s(Policy=%ld, Entry#=%ld)\n", + __func__, pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy, + pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num)); +#ifdef DBG + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("=============== Entry ===============\n")); + + for (i = 0; i < pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num; i++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Entry #%02d: ", i + 1)); + + for (j = 0; j < MAC_ADDR_LEN; j++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%02X ", pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Entry[i].Addr[j])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + +#endif + + if (pacl != NULL) + os_free_mem(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 RTMP_STRING *arg) +{ + UCHAR macAddr[MAC_ADDR_LEN]; + UCHAR nullAddr[MAC_ADDR_LEN]; + RT_802_11_ACL acl; + RTMP_STRING *this_char; + RTMP_STRING *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') { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("An unnecessary delimiter entered!\n")); + continue; + } + + if (strlen(this_char) != 17) { /*Mac address acceptable format 01:02:03:04:05:06 length 17 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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)))) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("illegal MAC address format or octet!\n")); + /* Do not use "continue" to replace "break" */ + break; + } + + AtoH(value, &macAddr[i++], 1); + } + + if (i != MAC_ADDR_LEN) + continue; + + /* Check if this entry existed. */ + isFound = FALSE; + + for (j = 0; j < acl.Num; j++) { + if (memcmp(acl.Entry[j].Addr, &macAddr, MAC_ADDR_LEN) == 0) { + isFound = TRUE; + NdisZeroMemory(acl.Entry[j].Addr, MAC_ADDR_LEN); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("The entry %02x:%02x:%02x:%02x:%02x:%02x founded will be deleted!\n", + macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5])); + } + } + + if (!isFound) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("The entry %02x:%02x:%02x:%02x:%02x:%02x is not in the list!\n", + macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5])); + } + } + + NdisZeroMemory(&pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList, sizeof(RT_802_11_ACL)); + pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy = acl.Policy; + ASSERT(pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num == 0); + i = 0; + + for (j = 0; j < acl.Num; j++) { + if (memcmp(acl.Entry[j].Addr, &nullAddr, MAC_ADDR_LEN) == 0) + continue; + else + NdisMoveMemory(&(pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Entry[i++]), acl.Entry[j].Addr, MAC_ADDR_LEN); + } + + pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num = i; + ASSERT(acl.Num >= pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num); + /* check if the change in ACL affects any existent association */ + ApUpdateAccessControlList(pAd, pObj->ioctl_if); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::%s(Policy=%ld, Entry#=%ld)\n", + __func__, pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Policy, + pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num)); +#ifdef DBG + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("=============== Entry ===============\n")); + + for (i = 0; i < pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Num; i++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Entry #%02d: ", i + 1)); + + for (j = 0; j < MAC_ADDR_LEN; j++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%02X ", pAd->ApCfg.MBSSID[pObj->ioctl_if].AccessControlList.Entry[i].Addr[j])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\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 RTMP_STRING *arg) +{ + RT_802_11_ACL acl; + BOOLEAN bDumpAll = FALSE; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + INT i, j; + + bDumpAll = os_str_tol(arg, 0, 10); + + if (bDumpAll == 1) + bDumpAll = TRUE; + else if (bDumpAll == 0) { + bDumpAll = FALSE; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("Your input is 0!\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("The Access Control List is empty!\n")); + return TRUE; + } + + ASSERT(((bDumpAll == 1) && (acl.Num > 0))); + /* Show the corresponding policy first. */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("=============== Access Control Policy ===============\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Policy is %ld : ", acl.Policy)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s\n", pACL_PolicyMessage[acl.Policy])); + /* Dump the entry in the list one by one */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("=============== Access Control List ===============\n")); + + for (i = 0; i < acl.Num; i++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Entry #%02d: ", i + 1)); + + for (j = 0; j < MAC_ADDR_LEN; j++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%02X ", acl.Entry[i].Addr[j])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + + return TRUE; +} + + +/* + ========================================================================== + Description: + Clear all the entries in the Access control + mac table list of a specified BSS + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT Set_ACLClearAll_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + /* RT_802_11_ACL acl; */ + RT_802_11_ACL *pacl = NULL; + BOOLEAN bClearAll = FALSE; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + bClearAll = os_str_tol(arg, 0, 10); + + if (bClearAll == 1) + bClearAll = TRUE; + else if (bClearAll == 0) { + bClearAll = FALSE; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("Your input is 0!\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Allocate memory fail!!!\n", __func__)); + 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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("The Access Control List is empty!\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("No need to clear the Access Control List!\n")); + + if (pacl != NULL) + os_free_mem(pacl); + + 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(pacl); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set::%s(Policy=%ld, Entry#=%ld)\n", + __func__, 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 < DebugLevel) + return; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s - hexdump(len=%lu):", title, (unsigned long) len)); + + if (show) { + for (i = 0; i < len; i++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (" %02x", buf[i])); + } else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (" [REMOVED]")); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); +} + +void rtmp_hexdump(int level, const char *title, const UINT8 *buf, size_t len) +{ + _rtmp_hexdump(level, title, buf, len, 1); +} +#endif + + + + +/* + ========================================================================== + Description: + Reset statistics counter + + Arguments: + pAdapter Pointer to our adapter + arg + + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ + +#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 + 3.) iwpriv ra0 set AutoChannelSel=3 + Ues the channel busy count to choose + ========================================================================== +*/ +INT Set_AutoChannelSel_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + NDIS_802_11_SSID Ssid; + + NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID)); + Ssid.SsidLength = 0; + + 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 if (strcmp(arg, "3") == 0) + pAd->ApCfg.AutoChannelAlg = ChannelAlgBusyTime; + else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Set_AutoChannelSel_Proc Alg isn't defined\n")); + return FALSE; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_AutoChannelSel_Proc Alg=%d\n", pAd->ApCfg.AutoChannelAlg)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\x1b[42m%s: Alg = %d \x1b[m\n", __func__, pAd->ApCfg.AutoChannelAlg)); + + if (pAd->ApCfg.AutoChannelAlg == ChannelAlgBusyTime) { + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR IfIdx; + struct wifi_dev *pwdev = NULL; + + if ((pObj->ioctl_if_type == INT_MBSSID) || (pObj->ioctl_if_type == INT_MAIN)) { + IfIdx = pObj->ioctl_if; + pwdev = &pAd->ApCfg.MBSSID[IfIdx].wdev; + AutoChSelScanStart(pAd, pwdev); + } + } else if (Ssid.SsidLength == 0) + ApSiteSurvey(pAd, &Ssid, SCAN_PASSIVE, TRUE); + else + ApSiteSurvey(pAd, &Ssid, SCAN_ACTIVE, TRUE); + + return TRUE; +} +INT Set_PartialScan_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR ifIndex; + UINT8 bPartialScanning; + + if ((pObj->ioctl_if_type != INT_APCLI) && + (pObj->ioctl_if_type != INT_MAIN) && + (pObj->ioctl_if_type != INT_MBSSID)) + return FALSE; + + ifIndex = pObj->ioctl_if; + bPartialScanning = os_str_tol(arg, 0, 10); + + if (bPartialScanning > 0) { + if (((pObj->ioctl_if_type == INT_MAIN) || (pObj->ioctl_if_type == INT_MBSSID)) && + (ifIndex < HW_BEACON_MAX_NUM)) + pAd->ScanCtrl.PartialScan.pwdev = &pAd->ApCfg.MBSSID[ifIndex].wdev; + +#ifdef APCLI_SUPPORT + else if ((pObj->ioctl_if_type == INT_APCLI) && (ifIndex < MAX_APCLI_NUM)) + pAd->ScanCtrl.PartialScan.pwdev = &pAd->ApCfg.ApCliTab[ifIndex].wdev; + +#endif /* APCLI_SUPPORT */ + } + + pAd->ScanCtrl.PartialScan.bScanning = bPartialScanning ? TRUE : FALSE; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): bScanning = %u\n", __func__, pAd->ScanCtrl.PartialScan.bScanning)); + return TRUE; +} + +/* + ========================================================================== + Description: + Set a periodic check time for auto channel selection (unit: hour) + Arguments: + pAdapter Pointer to our adapter + + Return Value: + TRUE if success, FALSE otherwise + + Note: + Usage: + iwpriv ra0 set ACSCheckTime=Hour + + ========================================================================== +*/ +INT Set_AutoChannelSelCheckTime_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT8 BandIdx, Hour; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR IfIdx; + struct wifi_dev *pwdev = NULL; + + if ((pObj->ioctl_if_type == INT_MBSSID) || (pObj->ioctl_if_type == INT_MAIN)) { + IfIdx = pObj->ioctl_if; + pwdev = &pAd->ApCfg.MBSSID[IfIdx].wdev; + BandIdx = HcGetBandByWdev(pwdev); + Hour = simple_strtol(arg, 0, 10); + pAd->ApCfg.ACSCheckTime[BandIdx] = Hour * 3600; /* Hour to second */ + pAd->ApCfg.ACSCheckCount[BandIdx] = 0; /* Reset counter */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("\x1b[42m%s(): ACSCheckTime[%d]=%u seconds(%u hours)\x1b[m\n", + __func__, BandIdx, pAd->ApCfg.ACSCheckTime[BandIdx], Hour)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\x1b[41m%s(): Not support current interface type = %u!!\x1b[m\n", + __func__, pObj->ioctl_if_type)); + } + + return TRUE; +} +#endif /* AP_SCAN_SUPPORT */ + +static INT show_apcfg_info(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + struct wifi_dev *wdev = NULL; + struct apcfg_parameters apcfg_para_setting; + LONG cfg_mode; + UCHAR wmode; + POS_COOKIE pObj = NULL; + CHAR str[10] = ""; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("show ap cfg info:\n")); + + pObj = (POS_COOKIE) pAd->OS_Cookie; + if (pObj == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pObj is NULL\n")); + return FALSE; + } + wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + if (wdev == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("wdev is NULL\n")); + return FALSE; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16s%-8s\n", " ", "WIFI_DRIVER", "PEAK_VALUE")); + + /*WirelessMode*/ + wmode = wdev->PhyMode; + cfg_mode = wmode_2_cfgmode(wmode); + if (WMODE_CAP_2G(wmode)) + apcfg_para_setting.cfg_mode[0] = cfg_mode; + else if (WMODE_CAP_5G(wmode)) + apcfg_para_setting.cfg_mode[1] = cfg_mode; + + if (cfg_mode == 9) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16ld%ld\n", "WirelessMode", cfg_mode, + apcfg_for_peak.cfg_mode[0])); + else if (cfg_mode == 14) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16ld%ld\n", "WirelessMode", cfg_mode, + apcfg_for_peak.cfg_mode[1])); + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16ld%ld/%ld\n", "WirelessMode", cfg_mode, + apcfg_for_peak.cfg_mode[0], apcfg_for_peak.cfg_mode[1])); + + apcfg_para_setting.tx_power_percentage = 0; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16lu%lu\n", "TxPower", + apcfg_para_setting.tx_power_percentage, + apcfg_for_peak.tx_power_percentage)); + + /*TxPreamble*/ + apcfg_para_setting.tx_preamble = pAd->CommonCfg.TxPreamble; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16lu%lu\n", "TxPreamble", + apcfg_para_setting.tx_preamble, + apcfg_for_peak.tx_preamble)); + + /*RTSThreshold*/ + apcfg_para_setting.conf_len_thld = wlan_config_get_rts_len_thld(wdev); + apcfg_para_setting.oper_len_thld = wlan_operate_get_rts_len_thld(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "RTSThreshold(config)", + apcfg_para_setting.conf_len_thld, + apcfg_for_peak.conf_len_thld)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "RTSThreshold(operate)", + apcfg_para_setting.oper_len_thld, + apcfg_for_peak.oper_len_thld)); + + /*FragThreshold*/ + apcfg_para_setting.conf_frag_thld = wlan_config_get_frag_thld(wdev); + apcfg_para_setting.oper_frag_thld = wlan_operate_get_frag_thld(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "FragThreshold(config)", + apcfg_para_setting.conf_frag_thld, + apcfg_for_peak.conf_frag_thld)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "FragThreshold(operate)", + apcfg_para_setting.oper_frag_thld, + apcfg_for_peak.oper_frag_thld)); + + /*TxBurst*/ + apcfg_para_setting.bEnableTxBurst = pAd->CommonCfg.bEnableTxBurst; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "TxBurst", + apcfg_para_setting.bEnableTxBurst, + apcfg_for_peak.bEnableTxBurst)); + + /*ShortSlot*/ + apcfg_para_setting.bUseShortSlotTime = pAd->CommonCfg.bUseShortSlotTime; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "ShortSlot", + apcfg_para_setting.bUseShortSlotTime, + apcfg_for_peak.bUseShortSlotTime)); + +#ifdef DOT11_N_SUPPORT + /*HT_BW*/ + apcfg_para_setting.conf_ht_bw = wlan_config_get_ht_bw(wdev); + apcfg_para_setting.oper_ht_bw = wlan_operate_get_ht_bw(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_BW(config)", + apcfg_para_setting.conf_ht_bw, + apcfg_for_peak.conf_ht_bw)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_BW(operate)", + apcfg_para_setting.oper_ht_bw, + apcfg_for_peak.oper_ht_bw)); + +#ifdef DOT11N_DRAFT3 + /*HT_BSSCoexistence */ + apcfg_para_setting.bBssCoexEnable = pAd->CommonCfg.bBssCoexEnable; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_BSSCoexistence", + apcfg_para_setting.bBssCoexEnable, + apcfg_for_peak.bBssCoexEnable)); +#endif + + /*HT_TxStream */ + apcfg_para_setting.ht_tx_streams = wlan_config_get_tx_stream(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_TxStream", + apcfg_para_setting.ht_tx_streams, + (pAd->CommonCfg.dbdc_mode ? (apcfg_for_peak.ht_tx_streams - 2) : apcfg_for_peak.ht_tx_streams))); + + /*HT_RxStream */ + apcfg_para_setting.ht_rx_streams = wlan_config_get_rx_stream(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_RxStream", + apcfg_para_setting.ht_rx_streams, + (pAd->CommonCfg.dbdc_mode ? (apcfg_for_peak.ht_rx_streams - 2) : apcfg_for_peak.ht_rx_streams))); + + /*HT_BADecline*/ + apcfg_para_setting.bBADecline = pAd->CommonCfg.bBADecline; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_BADecline", + apcfg_para_setting.bBADecline, + apcfg_for_peak.bBADecline)); + + /*HT_AutoBA*/ + apcfg_para_setting.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_AutoBA", + apcfg_para_setting.AutoBA, + apcfg_for_peak.AutoBA)); + + /*HT_AMSDU*/ + apcfg_para_setting.AmsduEnable = pAd->CommonCfg.BACapability.field.AmsduEnable; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_AMSDU", + apcfg_para_setting.AmsduEnable, + apcfg_for_peak.AmsduEnable)); + + /*HT_BAWinSize*/ + apcfg_para_setting.RxBAWinLimit = pAd->CommonCfg.BACapability.field.RxBAWinLimit; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_BAWinSize", + apcfg_para_setting.RxBAWinLimit, + apcfg_for_peak.RxBAWinLimit)); + + /*HT_GI*/ + apcfg_para_setting.ht_gi = pAd->CommonCfg.RegTransmitSetting.field.ShortGI; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_GI", + apcfg_para_setting.ht_gi, + apcfg_for_peak.ht_gi)); + + /*HT_STBC*/ + apcfg_para_setting.ht_stbc = wlan_config_get_ht_stbc(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_STBC", + apcfg_para_setting.ht_stbc, + apcfg_for_peak.ht_stbc)); + + /*HT_LDPC*/ + apcfg_para_setting.ht_ldpc = wlan_config_get_ht_ldpc(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_LDPC", + apcfg_para_setting.ht_ldpc, + apcfg_for_peak.ht_ldpc)); + + /*HT_RDG*/ + apcfg_para_setting.bRdg = pAd->CommonCfg.bRdg; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_RDG", + apcfg_para_setting.bRdg, + apcfg_for_peak.bRdg)); +#endif + + /*HT_DisallowTKIP*/ + apcfg_para_setting.HT_DisallowTKIP = pAd->CommonCfg.HT_DisallowTKIP; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "HT_DisallowTKIP", + apcfg_para_setting.HT_DisallowTKIP, + apcfg_for_peak.HT_DisallowTKIP)); + +#ifdef DOT11_VHT_AC + if (WMODE_CAP_5G(wmode)) { + /*VHT_BW*/ + apcfg_para_setting.conf_vht_bw = wlan_config_get_vht_bw(wdev); + apcfg_para_setting.oper_vht_bw = wlan_operate_get_vht_bw(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "VHT_BW(config)", + apcfg_para_setting.conf_vht_bw, + apcfg_for_peak.conf_vht_bw)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "VHT_BW(operate)", + apcfg_para_setting.oper_vht_bw, + apcfg_for_peak.oper_vht_bw)); + + /*VHT_SGI */ + apcfg_para_setting.vht_sgi = wlan_config_get_vht_sgi(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "VHT_SGI", + apcfg_para_setting.vht_sgi, + apcfg_for_peak.vht_sgi)); + + /*VHT_STBC*/ + apcfg_para_setting.vht_stbc = wlan_config_get_vht_stbc(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "VHT_STBC", + apcfg_para_setting.vht_stbc, + apcfg_for_peak.vht_stbc)); + + /*VHT_BW_SIGNAL*/ + apcfg_para_setting.vht_bw_signal = wlan_config_get_vht_bw_sig(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "VHT_BW_SIGNAL", + apcfg_para_setting.vht_bw_signal, + apcfg_for_peak.vht_bw_signal)); + + /*VHT_LDPC*/ + apcfg_para_setting.vht_ldpc = wlan_config_get_vht_ldpc(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "VHT_LDPC", + apcfg_para_setting.vht_ldpc, + apcfg_for_peak.vht_ldpc)); + } + + if (WMODE_CAP_2G(wmode)) { + /*G_BAND_256QAM*/ + apcfg_para_setting.g_band_256_qam = pAd->CommonCfg.g_band_256_qam; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "G_BAND_256QAM", + apcfg_para_setting.g_band_256_qam, + apcfg_for_peak.g_band_256_qam)); + } +#endif + + /*IEEE80211H*/ + apcfg_para_setting.bIEEE80211H = pAd->CommonCfg.bIEEE80211H; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "IEEE80211H", + apcfg_para_setting.bIEEE80211H, + apcfg_for_peak.bIEEE80211H)); + +#ifdef MT_DFS_SUPPORT + /*DfsEnable*/ + if (WMODE_CAP_5G(wmode)) { + apcfg_para_setting.bDfsEnable = pAd->CommonCfg.DfsParameter.bDfsEnable; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "DfsEnable", + apcfg_para_setting.bDfsEnable, + apcfg_for_peak.bDfsEnable)); + } +#endif + +#ifdef BACKGROUND_SCAN_SUPPORT + /*DfsZeroWait*/ + if (!(pAd->CommonCfg.dbdc_mode)) { + apcfg_para_setting.DfsZeroWaitSupport = pAd->BgndScanCtrl.DfsZeroWaitSupport; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "DfsZeroWait", + apcfg_para_setting.DfsZeroWaitSupport, + apcfg_for_peak.DfsZeroWaitSupport)); + } +#endif + +#ifdef DOT11_N_SUPPORT +#ifdef TXBF_SUPPORT + /*ETxBfEnCond*/ + apcfg_para_setting.ETxBfEnCond = pAd->CommonCfg.ETxBfEnCond; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16lu%lu\n", "CommonCfg.ETxBfEnCond", + apcfg_para_setting.ETxBfEnCond, + apcfg_for_peak.ETxBfEnCond)); + + /*ETxBfEnCond*/ + apcfg_para_setting.ETxBfEnCond = wlan_config_get_etxbf(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16lu%lu\n", "ETxBfEnCond", + apcfg_para_setting.ETxBfEnCond, + apcfg_for_peak.ETxBfEnCond)); +#endif +#endif + + /*ITxBfEn*/ + apcfg_para_setting.ITxBfEn = pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16d%d\n", "ITxBfEn", + apcfg_para_setting.ITxBfEn, + apcfg_for_peak.ITxBfEn)); + +#ifdef DOT11_N_SUPPORT +#ifdef TXBF_SUPPORT + /*MUTxRxEnable*/ + apcfg_para_setting.MUTxRxEnable = pAd->CommonCfg.MUTxRxEnable; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16lu%lu\n", "MUTxRxEnable", + apcfg_para_setting.MUTxRxEnable, + apcfg_for_peak.MUTxRxEnable)); +#endif +#endif + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("-----------------------------------------------------\n")); + + /*external channel*/ + apcfg_para_setting.channel = wdev->channel; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16u\n", "current channel", + apcfg_para_setting.channel)); + + apcfg_para_setting.ext_channel = wlan_operate_get_ext_cha(wdev); + + if (apcfg_para_setting.ext_channel == EXTCHA_ABOVE) + sprintf(str, "ABOVE"); + else if (apcfg_para_setting.ext_channel == EXTCHA_BELOW) + sprintf(str, "BELOW"); + else + sprintf(str, "NONE"); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%-24s%-16s\n", "extension channel", str)); + + return TRUE; +} + +INT Show_StaCount_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT i; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + ADD_HT_INFO_IE *addht; + + if (!wdev) + return FALSE; + + addht = wlan_operate_get_addht(wdev); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\nHT Operating Mode : %d\n", addht->AddHtInfo2.OperaionMode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n\n%-19s%-4s%-12s%-12s%-12s%-12s%-12s%-12s\n", + "MAC", "AID", "TxPackets", "RxPackets", "TxBytes", "RxBytes", "TP(Tx)", "TP(Rx)")); + + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; + + if ((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_APCLI(pEntry) || IS_ENTRY_REPEATER(pEntry)) + && (pEntry->Sst == SST_ASSOC)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%02X:%02X:%02X:%02X:%02X:%02X ", + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-4d", (int)pEntry->Aid)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-12lu", (ULONG)pEntry->TxPackets.QuadPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-12lu", (ULONG)pEntry->RxPackets.QuadPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-12lu", (ULONG)pEntry->TxBytes)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-12lu", (ULONG)pEntry->RxBytes)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%lu %-12s", (pEntry->AvgTxBytes >> 17), "Mbps")); /* (n Bytes x 8) / (1024*1024) = (n >> 17) */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%lu %-12s", (pEntry->AvgRxBytes >> 17), "Mbps"));/* (n Bytes x 8) / (1024*1024) = (n >> 17) */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n")); + } + } + + return TRUE; +} + + +INT Show_RAInfo_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef NEW_RATE_ADAPT_SUPPORT + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("LowTrafficThrd: %d\n", pAd->CommonCfg.lowTrafficThrd)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TrainUpRule: %d\n", pAd->CommonCfg.TrainUpRule)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TrainUpRuleRSSI: %d\n", pAd->CommonCfg.TrainUpRuleRSSI)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TrainUpLowThrd: %d\n", pAd->CommonCfg.TrainUpLowThrd)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("TrainUpHighThrd: %d\n", pAd->CommonCfg.TrainUpHighThrd)); +#endif /* NEW_RATE_ADAPT_SUPPORT */ +#ifdef STREAM_MODE_SUPPORT + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("StreamMode: %d\n", pAd->CommonCfg.StreamMode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("StreamModeMCS: 0x%04x\n", pAd->CommonCfg.StreamModeMCS)); +#endif /* STREAM_MODE_SUPPORT */ +#ifdef TXBF_SUPPORT + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ITxBfEn: %d\n", pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ITxBfTimeout: %ld\n", pAd->CommonCfg.ITxBfTimeout)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ETxBfTimeout: %ld\n", pAd->CommonCfg.ETxBfTimeout)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CommonCfg.ETxBfEnCond: %ld\n", pAd->CommonCfg.ETxBfEnCond)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ETxBfNoncompress: %d\n", pAd->CommonCfg.ETxBfNoncompress)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ETxBfIncapable: %d\n", pAd->CommonCfg.ETxBfIncapable)); +#ifdef TXBF_DYNAMIC_DISABLE + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ucAutoSoundingCtrl: %d\n", + pAd->CommonCfg.ucAutoSoundingCtrl)); +#endif /* TXBF_DYNAMIC_DISABLE */ +#endif /* TXBF_SUPPORT */ + return TRUE; +} + +#ifdef TXBF_SUPPORT +INT Show_TxBfInfo_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev; + HT_CAPABILITY_IE *ht_cap, HtCapabilityTmp; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + HT_BF_CAP *pTxBFCap; + UCHAR ucBandIdx = 0, ucEBfCap; +#ifdef VHT_TXBF_SUPPORT + VHT_CAP_INFO vht_cap; +#endif /* VHT_TXBF_SUPPORT */ + + if (cap->FlgHwTxBfCap) { + wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + if (!wdev) + return FALSE; + + if (wdev->pHObj) { + ucBandIdx = HcGetBandByWdev(wdev); + } + ht_cap = (HT_CAPABILITY_IE *)wlan_operate_get_ht_cap(wdev); + NdisMoveMemory(&HtCapabilityTmp, ht_cap, sizeof(HT_CAPABILITY_IE)); + if (HcIsBfCapSupport(wdev) == FALSE) { + ucEBfCap = wlan_config_get_etxbf(wdev); + wlan_config_set_etxbf(wdev, SUBF_OFF); + mt_WrapSetETxBFCap(pAd, wdev, &HtCapabilityTmp.TxBFCap); + wlan_config_set_etxbf(wdev, ucEBfCap); + } + pTxBFCap = &HtCapabilityTmp.TxBFCap; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Band Index:%d\n", ucBandIdx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("IsBfBand:%d\n", HcIsBfCapSupport(wdev))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CommonCfg.ETxBfEnCond:%ld\n", pAd->CommonCfg.ETxBfEnCond)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ETxBfEnCond:%d\n", wlan_config_get_etxbf(wdev))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("CommonCfg.ITxBfEn:%d\n", pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ITxBfEn:%d\n", wlan_config_get_itxbf(wdev))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("HT TxBF Cap:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" TxBFRecCapable:%d\n", pTxBFCap->TxBFRecCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" RxSoundCapable:%d\n", pTxBFCap->RxSoundCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" TxSoundCapable:%d\n", pTxBFCap->TxSoundCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" RxNDPCapable:%d\n", pTxBFCap->RxNDPCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" TxNDPCapable:%d\n", pTxBFCap->TxNDPCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ImpTxBFCapable:%d\n", pTxBFCap->ImpTxBFCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" Calibration:%d\n", pTxBFCap->Calibration)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ExpCSICapable:%d\n", pTxBFCap->ExpCSICapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ExpNoComSteerCapable:%d\n", pTxBFCap->ExpNoComSteerCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ExpComSteerCapable:%d\n", pTxBFCap->ExpComSteerCapable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ExpCSIFbk:%d\n", pTxBFCap->ExpCSIFbk)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ExpNoComBF:%d\n", pTxBFCap->ExpNoComBF)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ExpComBF:%d\n", pTxBFCap->ExpComBF)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" MinGrouping:%d\n", pTxBFCap->MinGrouping)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" CSIBFAntSup:%d\n", pTxBFCap->CSIBFAntSup)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" NoComSteerBFAntSup:%d\n", pTxBFCap->NoComSteerBFAntSup)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ComSteerBFAntSup:%d\n", pTxBFCap->ComSteerBFAntSup)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" CSIRowBFSup:%d\n", pTxBFCap->CSIRowBFSup)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" ChanEstimation:%d\n", pTxBFCap->ChanEstimation)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" rsv:%d\n", pTxBFCap->rsv)); + +#ifdef VHT_TXBF_SUPPORT + NdisCopyMemory(&vht_cap, &pAd->CommonCfg.vht_cap_ie.vht_cap, sizeof(VHT_CAP_INFO)); + + ucEBfCap = wlan_config_get_etxbf(wdev); + if (HcIsBfCapSupport(wdev) == FALSE) { + wlan_config_set_etxbf(wdev, SUBF_OFF); + } + mt_WrapSetVHTETxBFCap(pAd, wdev, &vht_cap); + wlan_config_set_etxbf(wdev, ucEBfCap); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("VHT TxBF Cap:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" num_snd_dimension:%d\n", vht_cap.num_snd_dimension)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" bfee_sts_cap:%d\n", vht_cap.bfee_sts_cap)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" bfee_cap_su:%d\n", vht_cap.bfee_cap_su)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" bfer_cap_su:%d\n", vht_cap.bfer_cap_su)); + +#endif /* VHT_TXBF_SUPPORT */ + } + return TRUE; +} +#endif /* TXBF_SUPPORT */ + +#ifdef RTMP_MAC_PCI +#ifdef DBG_DIAGNOSE +INT Set_DiagOpt_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + ULONG diagOpt; + /*POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; */ + diagOpt = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("DiagOpt=%ld!\n", diagOpt)); + return TRUE; +} + + +INT Set_diag_cond_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 cond; + + cond = os_str_tol(arg, 0, 10); + pAd->DiagStruct.diag_cond = cond; + return TRUE; +} + + +INT Show_Diag_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + RtmpDiagStruct *pDiag = NULL; + UCHAR i, start, stop, que_idx; + unsigned long irqFlags; + + os_alloc_mem(pAd, (UCHAR **)&pDiag, sizeof(RtmpDiagStruct)); + + if (!pDiag) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():AllocMem failed!\n", __func__)); + return FALSE; + } + + RTMP_IRQ_LOCK(&pAd->irq_lock, irqFlags); + NdisMoveMemory(pDiag, &pAd->DiagStruct, sizeof(RtmpDiagStruct)); + RTMP_IRQ_UNLOCK(&pAd->irq_lock, irqFlags); + + if (pDiag->inited == FALSE) + goto done; + + start = pDiag->ArrayStartIdx; + stop = pDiag->ArrayCurIdx; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Start=%d, stop=%d!\n\n", start, stop)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (" %-12s", "Time(Sec)")); + + for (i = 1; i < DIAGNOSE_TIME; i++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", i)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n -------------------------------------------------------------------------------\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Tx Info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (" %-12s", "TxDataCnt\n")); + + for (que_idx = 0; que_idx < WMM_NUM_OF_AC; que_idx++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\tQueue[%d]:", que_idx)); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", pDiag->diag_info[i].TxDataCnt[que_idx])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n")); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s", "TxFailCnt")); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", pDiag->diag_info[i].TxFailCnt)); + +#ifdef DBG_TX_AGG_CNT + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s", "TxAggCnt")); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", pDiag->diag_info[i].TxAggCnt)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n")); +#endif /* DBG_TX_AGG_CNT */ +#ifdef DBG_TXQ_DEPTH + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("DeQueue Info:\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s\n", "DeQueueFunc Called Distribution")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t")); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-8d", pDiag->diag_info[i].deq_called)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s\n", "DeQueueRound(Per-Call) Distribution")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t")); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-8d", pDiag->diag_info[i].deq_round)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s\n", "DeQueueCount(Per-Round) Distribution")); + + for (SwQNumLevel = 0; SwQNumLevel < 9; SwQNumLevel++) { + if (SwQNumLevel == 8) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t>%-5d", SwQNumLevel)); + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%-6d", SwQNumLevel)); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", pDiag->diag_info[i].deq_cnt[SwQNumLevel])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s%d", "Sw-Queued TxSwQCnt for WCID ", pDiag->wcid)); + + for (que_idx = 0; que_idx < WMM_NUM_OF_AC; que_idx++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %s[%d]\n", "Queue", que_idx)); + + for (SwQNumLevel = 0; SwQNumLevel < 9; SwQNumLevel++) { + if (SwQNumLevel == 8) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t>%-5d", SwQNumLevel)); + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%-6d", SwQNumLevel)); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", pDiag->diag_info[i].TxSWQueCnt[que_idx][SwQNumLevel])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n")); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (" %-12s\n", "TxEnQFailCnt")); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%-7d", pDiag->diag_info[i].enq_fall_cnt[que_idx])); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n")); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %s\n", "DeQueFailedCnt:Reason NotTxResource")); + + for (que_idx = 0; que_idx < WMM_NUM_OF_AC; que_idx++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %s[%d]:", "Queue", que_idx)); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%-7d", pDiag->diag_info[i].deq_fail_no_resource_cnt[que_idx])); + } + +#endif /* DBG_TXQ_DEPTH */ +#ifdef DOT11_N_SUPPORT +#ifdef DBG_TX_AGG_CNT + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s\n", "Tx-Agged AMPDUCnt")); + + for (McsIdx = 0; McsIdx < 16; McsIdx++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\t%-6d", (McsIdx + 1))); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%d(%d%%) ", pDiag->diag_info[i].TxAMPDUCnt[McsIdx], + pDiag->diag_info[i].TxAMPDUCnt[McsIdx] ? (pDiag->diag_info[i].TxAMPDUCnt[McsIdx] * 100 / pDiag->diag_info[i].TxAggCnt) : + 0)); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n")); + } + +#endif /* DBG_TX_AGG_CNT */ +#endif /* DOT11_N_SUPPORT */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Rx Info\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (" %-12s", "RxDataCnt")); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", pDiag->diag_info[i].RxDataCnt)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n %-12s", "RxCrcErrCnt")); + + for (i = start; i != stop; i = (i + 1) % DIAGNOSE_TIME) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-7d", pDiag->diag_info[i].RxCrcErrCnt)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\n-------------\n")); +done: + os_free_mem(pDiag); + return TRUE; +} +#endif /* DBG_DIAGNOSE */ +#endif /* RTMP_MAC_PCI */ + + +INT Show_Sat_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 temperature = 0; + + RTMP_GET_TEMPERATURE(pAd, &temperature); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("CurrentTemperature = %d\n", temperature)); + + /* Sanity check for calculation of sucessful count */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TransmitCountFromOS = %d\n", pAd->WlanCounters[0].TransmitCountFrmOs.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TransmittedFragmentCount = %lld\n", + (INT64)pAd->WlanCounters[0].TransmittedFragmentCount.u.LowPart + + pAd->WlanCounters[0].MulticastTransmittedFrameCount.QuadPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("MulticastTransmittedFrameCount = %d\n", pAd->WlanCounters[0].MulticastTransmittedFrameCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("FailedCount = %d\n", pAd->WlanCounters[0].FailedCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RetryCount = %d\n", pAd->WlanCounters[0].RetryCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("MultipleRetryCount = %d\n", pAd->WlanCounters[0].MultipleRetryCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RTSSuccessCount = %d\n", pAd->WlanCounters[0].RTSSuccessCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RTSFailureCount = %d\n", pAd->WlanCounters[0].RTSFailureCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ACKFailureCount = %d\n", pAd->WlanCounters[0].ACKFailureCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("FrameDuplicateCount = %d\n", pAd->WlanCounters[0].FrameDuplicateCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ReceivedFragmentCount = %d\n", pAd->WlanCounters[0].ReceivedFragmentCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("MulticastReceivedFrameCount = %d\n", pAd->WlanCounters[0].MulticastReceivedFrameCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer)); +#ifdef DBG + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RealFcsErrCount = %d\n", pAd->RalinkCounters.RealFcsErrCount.u.LowPart)); +#else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("FCSErrorCount = %d\n", pAd->WlanCounters[0].FCSErrorCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("FrameDuplicateCount.LowPart = %d\n", pAd->WlanCounters[0].FrameDuplicateCount.u.LowPart / 100)); +#endif + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TransmittedFrameCount = %d\n", pAd->WlanCounters[0].TransmittedFragmentCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("WEPUndecryptableCount = %d\n", pAd->WlanCounters[0].WEPUndecryptableCount.u.LowPart)); +#ifdef OUI_CHECK_SUPPORT + { + INT32 i = 0; + + for (i = 0; i < DBDC_BAND_NUM; i++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("band %d RxHWLookupWcidMismatchCount = %ld\n", + i, (ULONG)pAd->WlanCounters[i].RxHWLookupWcidErrCount.u.LowPart)); + } +#endif +#ifdef DOT11_N_SUPPORT + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n===Some 11n statistics variables:\n")); + /* Some 11n statistics variables */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TxAMSDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TxAMSDUCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("RxAMSDUCount = %ld\n", (ULONG)pAd->RalinkCounters.RxAMSDUCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TransmittedAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TransmittedMPDUsInAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TransmittedOctetsInAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("MPDUInReceivedAMPDUCount = %ld\n", (ULONG)pAd->RalinkCounters.MPDUInReceivedAMPDUCount.u.LowPart)); +#ifdef DOT11N_DRAFT3 + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("fAnyStaFortyIntolerant=%d\n", pAd->MacTab.fAnyStaFortyIntolerant)); +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + { + int apidx; + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("-- IF-ra%d --\n", apidx)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Packets Received = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].RxCount)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Packets Sent = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].TxCount)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Bytes Received = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].ReceivedByteCount)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Byte Sent = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].TransmittedByteCount)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Error Packets Received = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].RxErrorCount)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Drop Received Packets = %ld\n", (ULONG)pAd->ApCfg.MBSSID[apidx].RxDropCount)); +#ifdef WSC_INCLUDED + + if (pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscConfMode != WSC_DISABLE) { + WSC_CTRL *pWscCtrl; + + pWscCtrl = &pAd->ApCfg.MBSSID[apidx].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("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 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("-- IF-ra%d end --\n", apidx)); + } + } + { + int i, j, k, maxMcs = MAX_MCS_SET - 1; + PMAC_TABLE_ENTRY pEntry; + + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n%02x:%02x:%02x:%02x:%02x:%02x - ", PRINT_MAC(pEntry->Addr))); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%-4d\n", (int)pEntry->Aid)); + + for (j = maxMcs; j >= 0; j--) { + if ((pEntry->TXMCSExpected[j] != 0) || (pEntry->TXMCSFailed[j] != 0)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\t\t\tAutoMCS[%02d]: %u (%d%%)\n", k, pEntry->TXMCSAutoFallBack[j][k], + (100 * pEntry->TXMCSAutoFallBack[j][k]) / pEntry->TXMCSExpected[j])); + } + } + } + } + } + } + } + +#ifdef CONFIG_HOTSPOT + { + PHOTSPOT_CTRL pHSCtrl; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + PGAS_CTRL pGASCtrl = &pAd->ApCfg.MBSSID[apidx].GASCtrl; +#ifdef CONFIG_DOT11V_WNM + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[apidx].WNMCtrl; +#endif + pHSCtrl = &pAd->ApCfg.MBSSID[apidx].HotSpotCtrl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("hotspot enable = %d\n", pHSCtrl->HotSpotEnable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("daemon ready = %d\n", pHSCtrl->HSDaemonReady)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("hotspot DGAFDisable = %d\n", pHSCtrl->DGAFDisable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("hotspot L2Filter = %d\n", pHSCtrl->L2Filter)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("hotspot ICMPv4Deny = %d\n", pHSCtrl->ICMPv4Deny)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("hotspot QosMapEnable = %d\n", pHSCtrl->QosMapEnable)); +#ifdef CONFIG_DOT11V_WNM + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("proxy arp enable = %d\n", pWNMCtrl->ProxyARPEnable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("WNMNotify enable = %d\n", pWNMCtrl->WNMNotifyEnable)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("hotspot OSEN enable = %d\n", pHSCtrl->bASANEnable)); +#endif + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GAS come back delay = %d\n", pGASCtrl->cb_delay)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + } +#endif /* CONFIG_HOTSPOT */ +#if defined(CONFIG_DOT11V_WNM) && !defined(CONFIG_HOTSPOT) + { + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].WNMCtrl; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("WNM BSS Transition Management enable = %d\n", pWNMCtrl->WNMBTMEnable)); + } +#endif +#ifdef CONFIG_DOT11U_INTERWORKING + { + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + PGAS_CTRL pGASCtrl = &pAd->ApCfg.MBSSID[apidx].GASCtrl; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GAS enable = %d\n", pGASCtrl->b11U_enable)); + } +#endif /* CONFIG_DOT11U_INTERWORKING */ + + +#ifdef DOT11_N_SUPPORT + /* Display Tx Aggregation statistics */ + DisplayTxAgg(pAd); +#endif /* DOT11_N_SUPPORT */ + return TRUE; +} + + + +INT Show_Sat_Reset_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* Sanity check for calculation of sucessful count */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("TransmittedFragmentCount = %lld\n", + (INT64)pAd->WlanCounters[0].TransmittedFragmentCount.u.LowPart + + pAd->WlanCounters[0].MulticastTransmittedFrameCount.QuadPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MulticastTransmittedFrameCount = %d\n", pAd->WlanCounters[0].MulticastTransmittedFrameCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("FailedCount = %d\n", pAd->WlanCounters[0].FailedCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("RetryCount = %d\n", pAd->WlanCounters[0].RetryCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MultipleRetryCount = %d\n", pAd->WlanCounters[0].MultipleRetryCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("RTSSuccessCount = %d\n", pAd->WlanCounters[0].RTSSuccessCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("RTSFailureCount = %d\n", pAd->WlanCounters[0].RTSFailureCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ACKFailureCount = %d\n", pAd->WlanCounters[0].ACKFailureCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("FrameDuplicateCount = %d\n", pAd->WlanCounters[0].FrameDuplicateCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ReceivedFragmentCount = %d\n", pAd->WlanCounters[0].ReceivedFragmentCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MulticastReceivedFrameCount = %d\n", pAd->WlanCounters[0].MulticastReceivedFrameCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer)); +#ifdef DBG + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("RealFcsErrCount = %d\n", pAd->RalinkCounters.RealFcsErrCount.u.LowPart)); +#else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("FCSErrorCount = %d\n", pAd->WlanCounters[0].FCSErrorCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("FrameDuplicateCount.LowPart = %d\n", pAd->WlanCounters[0].FrameDuplicateCount.u.LowPart / 100)); +#endif + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("TransmittedFrameCount = %d\n", pAd->WlanCounters[0].TransmittedFrameCount.u.LowPart)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("WEPUndecryptableCount = %d\n", pAd->WlanCounters[0].WEPUndecryptableCount.u.LowPart)); + pAd->WlanCounters[0].TransmittedFragmentCount.u.LowPart = 0; + pAd->WlanCounters[0].MulticastTransmittedFrameCount.u.LowPart = 0; + pAd->WlanCounters[0].FailedCount.u.LowPart = 0; + pAd->WlanCounters[0].RetryCount.u.LowPart = 0; + pAd->WlanCounters[0].MultipleRetryCount.u.LowPart = 0; + pAd->WlanCounters[0].RTSSuccessCount.u.LowPart = 0; + pAd->WlanCounters[0].RTSFailureCount.u.LowPart = 0; + pAd->WlanCounters[0].ACKFailureCount.u.LowPart = 0; + pAd->WlanCounters[0].FrameDuplicateCount.u.LowPart = 0; + pAd->WlanCounters[0].ReceivedFragmentCount.u.LowPart = 0; + pAd->WlanCounters[0].MulticastReceivedFrameCount.u.LowPart = 0; + pAd->Counters8023.RxNoBuffer = 0; +#ifdef DBG + pAd->RalinkCounters.RealFcsErrCount.u.LowPart = 0; +#else + pAd->WlanCounters[0].FCSErrorCount.u.LowPart = 0; + pAd->WlanCounters[0].FrameDuplicateCount.u.LowPart = 0; +#endif + pAd->WlanCounters[0].TransmittedFrameCount.u.LowPart = 0; + pAd->WlanCounters[0].WEPUndecryptableCount.u.LowPart = 0; + { + int i, j, k, maxMcs = 15; + PMAC_TABLE_ENTRY pEntry; + + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\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])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%-4d\n", (int)pEntry->Aid)); + + for (j = maxMcs; j >= 0; j--) { + if ((pEntry->TXMCSExpected[j] != 0) || (pEntry->TXMCSFailed[j] != 0)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\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(RTMP_ADAPTER *pAd, RTMP_STRING *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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("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: + 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; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + apidx = (UCHAR) pObj->ioctl_if; + pKey = (PNDIS_AP_802_11_KEY) wrq->u.data.pointer; + pSecConfig = &pAd->ApCfg.MBSSID[apidx].wdev.SecConfig; + + if (IS_AKM_WPA2(pSecConfig->AKMMap) + || IS_AKM_WPA3(pSecConfig->AKMMap)) { + if (pKey->KeyLength == 32) { + UCHAR digest[80], PMK_key[20], macaddr[MAC_ADDR_LEN]; + + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s: pKey->KeyLength = %d\n", __func__, pKey->KeyLength)); + /* Calculate PMKID */ + NdisMoveMemory(&PMK_key[0], "PMK Name", 8); + NdisMoveMemory(&PMK_key[8], pAd->ApCfg.MBSSID[apidx].wdev.bssid, MAC_ADDR_LEN); + NdisMoveMemory(&PMK_key[14], pKey->addr, MAC_ADDR_LEN); + if (IS_AKM_SHA384(pSecConfig->AKMMap)) + RT_HMAC_SHA384(pKey->KeyMaterial, LEN_PMK_SHA384, PMK_key, 20, digest, LEN_PMKID); + else + RT_HMAC_SHA1(pKey->KeyMaterial, LEN_PMK, PMK_key, 20, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(macaddr, pKey->addr, MAC_ADDR_LEN); + RTMPAddPMKIDCache(&pAd->ApCfg.PMKIDCache, + apidx, + macaddr, + digest, + pKey->KeyMaterial, + pKey->KeyLength); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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])); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Set::RT_OID_802_11_WPA2_ADD_PMKID_CACHE ERROR or is wep key\n")); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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]; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = (UCHAR) pObj->ioctl_if; + ASIC_SEC_INFO Info = {0}; + UCHAR KeyIdx; + UINT32 len; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RTMPIoctlStaticWepCopy-IF(ra%d)\n", apidx)); + + if (wrq->u.data.length != sizeof(MacAddr)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("RTMPIoctlStaticWepCopy: the length isn't match (%d)\n", + wrq->u.data.length)); + return; + } + + len = copy_from_user(&MacAddr, wrq->u.data.pointer, wrq->u.data.length); + pEntry = MacTableLookup(pAd, MacAddr); + + if (!pEntry) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("RTMPIoctlStaticWepCopy: the mac address isn't match\n")); + return; + } + + KeyIdx = pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.PairwiseKeyId; + + /* need to copy the default shared-key to pairwise key table for this entry in 802.1x mode */ + if (pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.WepKey[KeyIdx].KeyLen == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ERROR: Can not get Default shared-key (index-%d)\n", KeyIdx)); + return; + } + + pEntry->SecConfig.AKMMap = pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.AKMMap; + pEntry->SecConfig.PairwiseCipher = pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.PairwiseCipher; + pEntry->SecConfig.PairwiseKeyId = pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.PairwiseKeyId; + NdisMoveMemory(pEntry->SecConfig.WepKey, pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.WepKey, + sizeof(SEC_KEY_INFO)*SEC_KEY_NUM); + /* Set key material to Asic */ + os_zero_mem(&Info, sizeof(ASIC_SEC_INFO)); + Info.Operation = SEC_ASIC_ADD_PAIRWISE_KEY; + Info.Direction = SEC_ASIC_KEY_BOTH; + Info.Wcid = pEntry->wcid; + Info.BssIndex = pEntry->func_tb_idx; + Info.Cipher = pEntry->SecConfig.PairwiseCipher; + Info.KeyIdx = pEntry->SecConfig.PairwiseKeyId; + os_move_mem(&Info.PeerAddr[0], pEntry->Addr, MAC_ADDR_LEN); + HW_ADDREMOVE_KEYTABLE(pAd, &Info); +} + +/* + ========================================================================== + 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)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : the length is mis-match\n", __func__)); + return; + } + + pIdleTime = (PDOT1X_IDLE_TIMEOUT)wrq->u.data.pointer; + pEntry = MacTableLookup(pAd, pIdleTime->StaAddr); + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : the entry is empty\n", __func__)); + return; + } + + pEntry->NoDataIdleCount = 0; + /* TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! */ + pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; + pEntry->StaIdleTimeout = pIdleTime->idle_timeout; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s : Update Idle-Timeout(%d) from dot1x daemon\n", + __func__, pEntry->StaIdleTimeout)); +} + +#ifdef RADIUS_MAC_ACL_SUPPORT +PRT_802_11_RADIUS_ACL_ENTRY RadiusFindAclEntry( + PLIST_HEADER pCacheList, + IN PUCHAR pMacAddr) +{ + PRT_802_11_RADIUS_ACL_ENTRY pAclEntry = NULL; + RT_LIST_ENTRY *pListEntry = NULL; + + pListEntry = pCacheList->pHead; + pAclEntry = (PRT_802_11_RADIUS_ACL_ENTRY)pListEntry; + + while (pAclEntry != NULL) { + if (NdisEqualMemory(pAclEntry->Addr, pMacAddr, MAC_ADDR_LEN)) + return pAclEntry; + + pListEntry = pListEntry->pNext; + pAclEntry = (PRT_802_11_RADIUS_ACL_ENTRY)pListEntry; + } + + return NULL; +} + +VOID RTMPIoctlAddRadiusMacAuthCache( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + RT_802_11_ACL_ENTRY newCache; + UCHAR apidx; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + PRT_802_11_RADIUS_ACL_ENTRY pAclEntry = NULL; + + apidx = (UCHAR) pObj->ioctl_if; + + if (pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.Policy != RADIUS_MAC_AUTH_ENABLE) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RADIUS_MAC_AUTH Function State in Disable.\n")); + return; + } + + /* From userSpace struct using RT_802_11_ACL_ENTRY */ + if (wrq->u.data.length != sizeof(RT_802_11_ACL_ENTRY)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s : the length is mis-match\n", __func__)); + return; + } + + copy_from_user(&newCache, wrq->u.data.pointer, wrq->u.data.length); + pAclEntry = RadiusFindAclEntry(&pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList, newCache.Addr); + + if (pAclEntry) { + /* Replace the Cache if exist */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[%d] Found %02x:%02x:%02x:%02x:%02x:%02x in Cache And Update Result to %d.\n", + apidx, PRINT_MAC(newCache.Addr), newCache.Rsv)); + pAclEntry->result = newCache.Rsv; + return; + } + + /* Add new Cache */ + os_alloc_mem(NULL, (UCHAR **)&pAclEntry, sizeof(RT_802_11_RADIUS_ACL_ENTRY)); + + if (pAclEntry) { + NdisZeroMemory(pAclEntry, sizeof(RT_802_11_RADIUS_ACL_ENTRY)); + pAclEntry->pNext = NULL; + NdisMoveMemory(pAclEntry->Addr, newCache.Addr, MAC_ADDR_LEN); + pAclEntry->result = newCache.Rsv; + insertTailList(&pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList, (RT_LIST_ENTRY *)pAclEntry); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[%d] New %02x:%02x:%02x:%02x:%02x:%02x res(%d) in Cache(%d).\n", + apidx, + PRINT_MAC(pAclEntry->Addr), pAclEntry->result, + pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList.size)); + } else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Error in alloc mem in New Radius ACL Function.\n")); +} + +VOID RTMPIoctlDelRadiusMacAuthCache( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + UCHAR apidx; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + RT_LIST_ENTRY *pListEntry = NULL; + UCHAR macBuf[MAC_ADDR_LEN]; + + apidx = (UCHAR) pObj->ioctl_if; + + if (wrq->u.data.length != MAC_ADDR_LEN) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s : the length is mis-match\n", __func__)); + return; + } + + copy_from_user(&macBuf, wrq->u.data.pointer, wrq->u.data.length); + pListEntry = (RT_LIST_ENTRY *)RadiusFindAclEntry(&pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList, + macBuf); + + if (pListEntry) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[%d]Del %02x:%02x:%02x:%02x:%02x:%02x in Cache(%d).\n", apidx, + PRINT_MAC(macBuf), pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList.size)); + delEntryList(&pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList, pListEntry); + os_free_mem(pListEntry); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[%d]STA %02x:%02x:%02x:%02x:%02x:%02x not in Cache.\n", + apidx, PRINT_MAC(macBuf))); + } +} + +VOID RTMPIoctlClearRadiusMacAuthCache( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = (UCHAR) pObj->ioctl_if; + RT_LIST_ENTRY *pListEntry = NULL; + PLIST_HEADER pListHeader = &pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList; + + if (pListHeader->size == 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[%d] Radius ACL Cache already in empty.\n", apidx)); + return; + } + + pListEntry = pListHeader->pHead; + + while (pListEntry != NULL) { + /*Remove ListEntry from Header*/ + removeHeadList(pListHeader); + os_free_mem(pListEntry); + pListEntry = pListHeader->pHead; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Clean [%d] Radius ACL Cache.\n", apidx)); +} +#endif /* RADIUS_MAC_ACL_SUPPORT */ + +VOID RTMPIoctlQueryStaAid( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + DOT1X_QUERY_STA_AID macBuf; + MAC_TABLE_ENTRY *pEntry = NULL; + + if (wrq->u.data.length != sizeof(DOT1X_QUERY_STA_AID)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : the length is mis-match\n", __func__)); + return; + } + + if (copy_from_user(&macBuf, wrq->u.data.pointer, wrq->u.data.length)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: copy_to_user() fail\n", __func__)); + return; + } + + pEntry = MacTableLookup(pAd, macBuf.StaAddr); + + if (pEntry != NULL) { + wrq->u.data.length = sizeof(DOT1X_QUERY_STA_AID); + macBuf.aid = pEntry->Aid; + + if (copy_to_user(wrq->u.data.pointer, &macBuf, wrq->u.data.length)) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: copy_to_user() fail\n", __func__)); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Query::OID_802_DOT1X_QUERY_STA_AID(%02x:%02x:%02x:%02x:%02x:%02x, AID=%d)\n", + PRINT_MAC(macBuf.StaAddr), macBuf.aid)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Query::OID_802_DOT1X_QUERY_STA_AID(%02x:%02x:%02x:%02x:%02x:%02x, Not Found)\n", + PRINT_MAC(macBuf.StaAddr))); + } +} + + +VOID RTMPIoctlQueryStaRsn( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT * wrq) +{ + struct DOT1X_QUERY_STA_RSN sta_rsn; + MAC_TABLE_ENTRY *pEntry = NULL; + + if (wrq->u.data.length != sizeof(struct DOT1X_QUERY_STA_RSN)) { + MTWF_LOG(DBG_CAT_SEC, CATSEC_SUITEB, DBG_LVL_ERROR, ("%s : the length is mis-match\n", __func__)); + return; + } + + if (copy_from_user(&sta_rsn, wrq->u.data.pointer, wrq->u.data.length)) { + MTWF_LOG(DBG_CAT_SEC, CATSEC_SUITEB, DBG_LVL_ERROR, ("%s: copy_to_user() fail\n", __func__)); + return; + } + + pEntry = MacTableLookup(pAd, sta_rsn.sta_addr); + + if (pEntry != NULL) { + wrq->u.data.length = sizeof(struct DOT1X_QUERY_STA_RSN); + sta_rsn.akm = pEntry->SecConfig.AKMMap; + sta_rsn.pairwise_cipher = pEntry->SecConfig.PairwiseCipher; + sta_rsn.group_cipher = pEntry->SecConfig.GroupCipher; +#ifdef DOT11W_PMF_SUPPORT + sta_rsn.group_mgmt_cipher = pEntry->SecConfig.PmfCfg.igtk_cipher; +#else + sta_rsn.group_mgmt_cipher = 0; +#endif + + if (copy_to_user(wrq->u.data.pointer, &sta_rsn, wrq->u.data.length)) + MTWF_LOG(DBG_CAT_SEC, CATSEC_SUITEB, DBG_LVL_ERROR, ("%s: copy_to_user() fail\n", __func__)); + + MTWF_LOG(DBG_CAT_SEC, CATSEC_SUITEB, DBG_LVL_TRACE, + ("Query::OID_802_DOT1X_QUERY_STA_RSN(%02x:%02x:%02x:%02x:%02x:%02x)\n", + PRINT_MAC(sta_rsn.sta_addr))); + MTWF_LOG(DBG_CAT_SEC, CATSEC_SUITEB, DBG_LVL_TRACE, + ("%s: AKM=%x, pairwise=%x, group_cipher=%x, group_mgmt_cipher=%x\n", + __func__, sta_rsn.akm, sta_rsn.pairwise_cipher, sta_rsn.group_cipher, sta_rsn.group_mgmt_cipher)); + } else { + MTWF_LOG(DBG_CAT_SEC, CATSEC_SUITEB, DBG_LVL_TRACE, + ("Query::OID_802_DOT1X_QUERY_STA_RSN(%02x:%02x:%02x:%02x:%02x:%02x, Not Found)\n", + PRINT_MAC(sta_rsn.sta_addr))); + } +} + + +#ifdef RADIUS_ACCOUNTING_SUPPORT +VOID RTMPIoctlQueryStaData( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + DOT1X_QUERY_STA_DATA macBuf; + MAC_TABLE_ENTRY *pEntry = NULL; + INT Status; + + if (wrq->u.data.length != sizeof(DOT1X_QUERY_STA_DATA)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s : the length is mis-match\n", __func__)); + return; + } + + Status = copy_from_user(&macBuf, wrq->u.data.pointer, wrq->u.data.length); + pEntry = MacTableLookup(pAd, macBuf.StaAddr); + + if (pEntry != NULL) { + wrq->u.data.length = sizeof(DOT1X_QUERY_STA_DATA); + macBuf.rx_bytes = pEntry->RxBytes; + macBuf.tx_bytes = pEntry->TxBytes; + macBuf.rx_packets = pEntry->RxPackets.u.LowPart; + macBuf.tx_packets = pEntry->TxPackets.u.LowPart; + + if (copy_to_user(wrq->u.data.pointer, &macBuf, wrq->u.data.length)) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: copy_to_user() fail\n", __func__)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Query::OID_802_DOT1X_QUERY_STA_AID(%02x:%02x:%02x:%02x:%02x:%02x, Not Found)\n", + PRINT_MAC(macBuf.StaAddr))); + } +} +#endif /*RADIUS_ACCOUNTING_SUPPORT*/ + +#endif /* DOT1X_SUPPORT */ + + +#if defined(DBG) || (defined(BB_SOC) && defined(CONFIG_ATE)) + +/* + ========================================================================== + 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) +{ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IOCTL::(iwpriv) Command not Support!\n")); +} + +/* CFG TODO: double define in ap_cfg / sta_cfg */ +#if defined(RT_CFG80211_P2P_SUPPORT) || defined(CFG80211_MULTI_STA) +#else +#endif + +#ifdef RTMP_RF_RW_SUPPORT +/* + ========================================================================== + Description: + Read / Write RF register +Arguments: + pAdapter Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) iwpriv ra0 rf ==> read all RF registers + 2.) iwpriv ra0 rf 1 ==> read RF where RegID=1 + 3.) iwpriv ra0 rf 1=10 ==> write RF R1=0x10 + ========================================================================== +*/ +VOID RTMPAPIoctlRF( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ +#if defined(RT_CFG80211_P2P_SUPPORT) || defined(CFG80211_MULTI_STA) +#else +#endif +} +#endif /* RTMP_RF_RW_SUPPORT */ +#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) +{ + RTMP_STRING *this_char, *value; + INT j = 0, k = 0; + RTMP_STRING *mpool, *msg; /*msg[1024]; */ + RTMP_STRING *arg, *ptr; + USHORT eepAddr = 0; + UCHAR temp[16]; + RTMP_STRING temp2[16]; + USHORT eepValue; + BOOLEAN bIsPrintAllE2PROM = FALSE; + UINT_32 start = 0; + UINT_32 end = 0; + os_alloc_mem(NULL, (UCHAR **)&mpool, sizeof(CHAR) * (4096 + 256 + 12)); + + if (mpool == NULL) + return; + + msg = (RTMP_STRING *)((ULONG)(mpool + 3) & (ULONG)~0x03); + arg = (RTMP_STRING *)((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 */ + ) { +#ifdef LINUX + if (copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length)) + goto done; +#else + NdisMoveMemory(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length); +#endif + ptr = arg; + sprintf(msg, "\n"); + + /*Parsing Read or Write */ + while ((this_char = strsep((char **)&ptr, ",")) != NULL) { + + if (!*this_char) + continue; + + value = strchr(this_char, '='); + + if (value != NULL) + *value++ = 0; + + if (!value || !*value) { + /*Read */ + + /* Sanity check */ + if (strstr(this_char, ":")) { + UINT_32 e2p_end = EEPROM_SIZE; + UINT_32 e2p_print_lmt = EEPROM_SIZE; + +#if defined(RTMP_FLASH_SUPPORT) + if (pAdapter->E2pAccessMode == E2P_FLASH_MODE) + e2p_end = get_dev_eeprom_size(pAdapter); +#endif + sscanf(arg, "%4x:%4x", &start, &end); + + if ((start + end) > 0 && end > start && end < e2p_end) { + if (end - start > e2p_print_lmt) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Maximum display %d bytes, display 0x%x to 0x%x\n", + e2p_print_lmt, start, start+e2p_print_lmt)); + end = start+e2p_print_lmt; + } + bIsPrintAllE2PROM = TRUE; + } + break; + } else 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) - 1; + + while (j >= 0) { + if (temp2[j] > 'f' || temp2[j] < '0') + goto done; /* return; */ + + j--; + } + + /* 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 = strlen(temp2); + j = strlen(temp2) - 1; + + while (j >= 0) { + if ((4 - k + j) < 0) + break; + + temp2[4 - k + j] = temp2[j]; + 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"); + + if ((start + end) == 0) { + start = 0; + end = EEPROM_SIZE; + } + + /* E2PROM Registers */ + for (eepAddr = start; eepAddr < end; 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: + os_free_mem(mpool); + + if (wrq->u.data.flags != RT_OID_802_11_HARDWARE_REGISTER) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 + ========================================================================== +*/ +static VOID ShowAmpduCounter(RTMP_ADAPTER *pAd, UCHAR BandIdx, RTMP_STRING *msg) +{ + COUNTER_802_11 *WlanCounter = &pAd->WlanCounters[BandIdx]; + ULONG per; + + sprintf(msg + strlen(msg), "BandIdx: %d\n", BandIdx); + sprintf(msg + strlen(msg), "TX AGG Range 1 (1) = %ld\n", (LONG)(WlanCounter->TxAggRange1Count.u.LowPart)); + sprintf(msg + strlen(msg), "TX AGG Range 2 (2~5) = %ld\n", (LONG)(WlanCounter->TxAggRange2Count.u.LowPart)); + sprintf(msg + strlen(msg), "TX AGG Range 3 (6~15) = %ld\n", (LONG)(WlanCounter->TxAggRange3Count.u.LowPart)); + sprintf(msg + strlen(msg), "TX AGG Range 4 (>15) = %ld\n", (LONG)(WlanCounter->TxAggRange4Count.u.LowPart)); + { + ULONG mpduTXCount; + + mpduTXCount = WlanCounter->AmpduSuccessCount.u.LowPart; + sprintf(msg + strlen(msg), "AMPDU Tx success = %ld\n", mpduTXCount); + per = mpduTXCount == 0 ? 0 : 1000 * (WlanCounter->AmpduFailCount.u.LowPart) / (WlanCounter->AmpduFailCount.u.LowPart + + mpduTXCount); + sprintf(msg + strlen(msg), "AMPDU Tx fail count = %ld, PER=%ld.%1ld%%\n", + (ULONG)WlanCounter->AmpduFailCount.u.LowPart, + per / 10, per % 10); + } +} + +VOID RTMPIoctlStatistics(RTMP_ADAPTER *pAd, RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + INT Status; + RTMP_STRING *msg; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + UINT8 ucBand = BAND0; + ULONG txCount = 0; + UINT32 rxCount = 0; +#ifdef ENHANCED_STAT_DISPLAY + ULONG per; + INT i; +#endif +#ifdef RTMP_EFUSE_SUPPORT + UINT efusefreenum = 0; +#endif /* RTMP_EFUSE_SUPPORT */ +#ifdef BB_SOC + ULONG txPackets = 0, rxPackets = 0, txBytes = 0, rxBytes = 0; + UCHAR index = 0; +#endif + BOOLEAN isfound = FALSE; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + os_alloc_mem(pAd, (UCHAR **)&msg, sizeof(CHAR) * (2048)); + + if (msg == NULL) + return; + + if (wdev != NULL) + ucBand = HcGetBandByWdev(wdev); + + memset(msg, 0x00, 1600); + sprintf(msg, "\n"); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_LOUD, ("ra offload=%d\n", cap->fgRateAdaptFWOffload)); +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + if (cap->fgRateAdaptFWOffload == TRUE) { + EXT_EVENT_TX_STATISTIC_RESULT_T rTxStatResult; + HTTRANSMIT_SETTING LastTxRate; + + MtCmdGetTxStatistic(pAd, GET_TX_STAT_TOTAL_TX_CNT | GET_TX_STAT_LAST_TX_RATE, ucBand, 0, &rTxStatResult); + pAd->WlanCounters[ucBand].TransmittedFragmentCount.u.LowPart += (rTxStatResult.u4TotalTxCount - + rTxStatResult.u4TotalTxFailCount); + pAd->WlanCounters[ucBand].FailedCount.u.LowPart += rTxStatResult.u4TotalTxFailCount; + pAd->WlanCounters[ucBand].CurrentBwTxCount.u.LowPart += rTxStatResult.u4CurrBwTxCnt; + pAd->WlanCounters[ucBand].OtherBwTxCount.u.LowPart += rTxStatResult.u4OtherBwTxCnt; + + LastTxRate.field.MODE = rTxStatResult.rLastTxRate.MODE; + LastTxRate.field.BW = rTxStatResult.rLastTxRate.BW; + LastTxRate.field.ldpc = rTxStatResult.rLastTxRate.ldpc ? 1 : 0; + LastTxRate.field.ShortGI = rTxStatResult.rLastTxRate.ShortGI ? 1 : 0; + LastTxRate.field.STBC = rTxStatResult.rLastTxRate.STBC; + + if (LastTxRate.field.MODE == MODE_VHT) + LastTxRate.field.MCS = (((rTxStatResult.rLastTxRate.VhtNss - 1) & 0x3) << 4) + rTxStatResult.rLastTxRate.MCS; + else + LastTxRate.field.MCS = rTxStatResult.rLastTxRate.MCS; + + pAd->LastTxRate = (USHORT)(LastTxRate.word); + } +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + +#ifdef CONFIG_ATE + if (ATE_ON(pAd)) { + txCount = pAd->ATECtrl.TxDoneCount; + rxCount = pAd->ATECtrl.rx_stat.RxTotalCnt[0]; + } else +#endif /* CONFIG_ATE */ + { + txCount = pAd->WlanCounters[ucBand].TransmittedFragmentCount.u.LowPart; + rxCount = pAd->WlanCounters[0].ReceivedFragmentCount.QuadPart; + } + + + sprintf(msg + strlen(msg), "Tx success = %ld\n", txCount); +#ifdef ENHANCED_STAT_DISPLAY + if (IS_HIF_TYPE(pAd, HIF_MT)) { + per = txCount == 0 ? 0 : 1000 * (pAd->WlanCounters[ucBand].FailedCount.u.LowPart) / + (pAd->WlanCounters[ucBand].FailedCount.u.LowPart + txCount); + sprintf(msg + strlen(msg), "Tx fail count = %ld, PER=%ld.%1ld%%\n", + (ULONG)pAd->WlanCounters[ucBand].FailedCount.u.LowPart, + per / 10, per % 10); + sprintf(msg + strlen(msg), "Current BW Tx count = %ld\n", (ULONG)pAd->WlanCounters[ucBand].CurrentBwTxCount.u.LowPart); + sprintf(msg + strlen(msg), "Other BW Tx count = %ld\n", (ULONG)pAd->WlanCounters[ucBand].OtherBwTxCount.u.LowPart); + } + + sprintf(msg + strlen(msg), "Rx success = %ld\n", (ULONG)rxCount); + +#ifdef CONFIG_QA + if (ATE_ON(pAd)) + per = rxCount == 0 ? 0 : 1000 * (pAd->WlanCounters[0].FCSErrorCount.u.LowPart) / + (pAd->WlanCounters[0].FCSErrorCount.u.LowPart + rxCount); + else +#endif /* CONFIG_QA */ + per = pAd->WlanCounters[0].ReceivedFragmentCount.u.LowPart == 0 ? 0 : 1000 * + (pAd->WlanCounters[0].FCSErrorCount.u.LowPart) / (pAd->WlanCounters[0].FCSErrorCount.u.LowPart + + pAd->WlanCounters[0].ReceivedFragmentCount.u.LowPart); + + sprintf(msg + strlen(msg), "Rx with CRC = %ld, PER=%ld.%1ld%%\n", + (ULONG)pAd->WlanCounters[0].FCSErrorCount.u.LowPart, per / 10, per % 10); + sprintf(msg + strlen(msg), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer); +#endif /* ENHANCED_STAT_DISPLAY */ + +#ifdef CONFIG_QA + if (ATE_ON(pAd)) { + struct _ATE_RX_STATISTIC rx_stat = pAd->ATECtrl.rx_stat; + + if (pAd->ATECtrl.RxAntennaSel == 0) { + sprintf(msg + strlen(msg), "RSSI-A = %ld\n", + (LONG)(rx_stat.LastRssi[0] - pAd->BbpRssiToDbmDelta)); + sprintf(msg + strlen(msg), "RSSI-B (if available) = %ld\n", + (LONG)(rx_stat.LastRssi[1] - pAd->BbpRssiToDbmDelta)); + sprintf(msg + strlen(msg), "RSSI-C (if available) = %ld\n\n", + (LONG)(rx_stat.LastRssi[2] - pAd->BbpRssiToDbmDelta)); + sprintf(msg + strlen(msg), "RSSI-D (if available) = %ld\n\n", + (LONG)(rx_stat.LastRssi[3] - pAd->BbpRssiToDbmDelta)); + } else + sprintf(msg + strlen(msg), "RSSI = %ld\n", + (LONG)(rx_stat.LastRssi[0] - pAd->BbpRssiToDbmDelta)); + } else +#endif /* CONFIG_QA */ + { +#ifdef ENHANCED_STAT_DISPLAY +#ifdef CCK_LQ_SUPPORT + if (IS_MT7615(pAd)) + sprintf(msg+strlen(msg), "LQ(CCK) = %d\n", pAd->Avg_LQ); +#endif +#ifdef LTF_SNR_SUPPORT + if (IS_MT7615(pAd)) + sprintf(msg+strlen(msg), "LTF-SNR(OFDM) = %d\n", pAd->Avg_LTFSNR); +#endif +#ifdef NF_SUPPORT + if (IS_MT7615(pAd)) { + sprintf(msg+strlen(msg), "NF = %d\n", pAd->Avg_NF); + sprintf(msg+strlen(msg), "SNR = %ld %ld %ld %ld\n", + (LONG)(pAd->ApCfg.RssiSample.LastRssi[0] - pAd->Avg_NF), + (LONG)(pAd->ApCfg.RssiSample.LastRssi[1] - pAd->Avg_NF), + (LONG)(pAd->ApCfg.RssiSample.LastRssi[2] - pAd->Avg_NF), + (LONG)(pAd->ApCfg.RssiSample.LastRssi[3] - pAd->Avg_NF)); + } +#endif + /* 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"}; + + for (i = 1; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + PMAC_TABLE_ENTRY pEntry = &(pAd->MacTab.Content[i]); + + if ((pEntry->wdev == NULL) || HcGetBandByWdev(pEntry->wdev) != ucBand) + continue; + if ((IS_ENTRY_CLIENT(pEntry) && pEntry->Sst == SST_ASSOC) || IS_ENTRY_WDS(pEntry) || IS_ENTRY_APCLI(pEntry)) { + /* sprintf(msg+strlen(msg), "sta mac: %02x:%02x:%02x:%02x:%02x:%02x\n", pEntry->wdev->if_addr[0], pEntry->wdev->if_addr[1], pEntry->wdev->if_addr[2], pEntry->wdev->if_addr[3], pEntry->wdev->if_addr[4], pEntry->wdev->if_addr[5]); */ + UINT32 lastRxRate = pEntry->LastRxRate; + UINT32 lastTxRate = pEntry->LastTxRate; + + isfound = TRUE; + sprintf(msg + strlen(msg), "RSSI = %ld %ld %ld %ld\n", + (LONG)(pEntry->RssiSample.AvgRssi[0] - pAd->BbpRssiToDbmDelta), + (LONG)(pEntry->RssiSample.AvgRssi[1] - pAd->BbpRssiToDbmDelta), + (LONG)(pEntry->RssiSample.AvgRssi[2] - pAd->BbpRssiToDbmDelta), + (LONG)(pEntry->RssiSample.AvgRssi[3] - pAd->BbpRssiToDbmDelta)); + +#ifdef RACTRL_FW_OFFLOAD_SUPPORT + if (cap->fgRateAdaptFWOffload == TRUE) { + if (pEntry->bAutoTxRateSwitch == TRUE) { + EXT_EVENT_TX_STATISTIC_RESULT_T rTxStatResult; + HTTRANSMIT_SETTING LastTxRate; + + MtCmdGetTxStatistic(pAd, GET_TX_STAT_ENTRY_TX_RATE, 0/*Don't Care*/, pEntry->wcid, &rTxStatResult); + LastTxRate.field.MODE = rTxStatResult.rEntryTxRate.MODE; + LastTxRate.field.BW = rTxStatResult.rEntryTxRate.BW; + LastTxRate.field.ldpc = rTxStatResult.rEntryTxRate.ldpc ? 1 : 0; + LastTxRate.field.ShortGI = rTxStatResult.rEntryTxRate.ShortGI ? 1 : 0; + LastTxRate.field.STBC = rTxStatResult.rEntryTxRate.STBC; + + if (LastTxRate.field.MODE == MODE_VHT) + LastTxRate.field.MCS = (((rTxStatResult.rEntryTxRate.VhtNss - 1) & 0x3) << 4) + rTxStatResult.rEntryTxRate.MCS; + else + LastTxRate.field.MCS = rTxStatResult.rEntryTxRate.MCS; + + lastTxRate = (UINT32)(LastTxRate.word); + } + } +#endif /* RACTRL_FW_OFFLOAD_SUPPORT */ + +#ifdef MT_MAC + + if (IS_HIF_TYPE(pAd, HIF_MT)) { + StatRateToString(pAd, msg, 0, lastTxRate); + StatRateToString(pAd, msg, 1, lastRxRate); + } else +#endif /* MT_MAC */ + { + sprintf(msg + strlen(msg), "Last TX Rate = MCS%d, %2dM, %cGI, %s%s\n", + lastTxRate & 0x7F, ((lastTxRate >> 7) & 0x1) ? 40 : 20, + ((lastTxRate >> 8) & 0x1) ? 'S' : 'L', + phyMode[(lastTxRate >> 14) & 0x3], + ((lastTxRate >> 9) & 0x3) ? ", STBC" : " "); + 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" : " "); + } + + break; + } + } + } + + if (isfound == FALSE) { + sprintf(msg+strlen(msg), "RSSI = %ld %ld %ld %ld\n", + (LONG)MINIMUM_POWER_VALUE, + (LONG)MINIMUM_POWER_VALUE, + (LONG)MINIMUM_POWER_VALUE, + (LONG)MINIMUM_POWER_VALUE); + } +#ifdef MT_MAC + if (IS_HIF_TYPE(pAd, HIF_MT)) { + ShowAmpduCounter(pAd, ucBand, msg); + + if (pAd->CommonCfg.bTXRX_RXV_ON) { + sprintf(msg + strlen(msg), "/* Condition Number should enable mode4 of 0x6020_426c */\n"); + sprintf(msg + strlen(msg), + "--10 packets Condition Number = [%d|%d|%d|%d|%d|%d|%d|%d|%d|%d]\n", + (UINT8)(pAd->rxv2_cyc3[0] & 0xff), + (UINT8)(pAd->rxv2_cyc3[1] & 0xff), + (UINT8)(pAd->rxv2_cyc3[2] & 0xff), + (UINT8)(pAd->rxv2_cyc3[3] & 0xff), + (UINT8)(pAd->rxv2_cyc3[4] & 0xff), + (UINT8)(pAd->rxv2_cyc3[5] & 0xff), + (UINT8)(pAd->rxv2_cyc3[6] & 0xff), + (UINT8)(pAd->rxv2_cyc3[7] & 0xff), + (UINT8)(pAd->rxv2_cyc3[8] & 0xff), + (UINT8)(pAd->rxv2_cyc3[9] & 0xff) + ); + } + } + +#endif /* MT_MAC */ +#else + sprintf(msg + strlen(msg), "RSSI-A = %ld\n", + (LONG)(pAd->ApCfg.RssiSample.LastRssi[0] - pAd->BbpRssiToDbmDelta)); + sprintf(msg + strlen(msg), "RSSI-B (if available) = %ld\n", + (LONG)(pAd->ApCfg.RssiSample.LastRssi[1] - pAd->BbpRssiToDbmDelta)); + sprintf(msg + strlen(msg), "RSSI-C (if available) = %ld\n\n", + (LONG)(pAd->ApCfg.RssiSample.LastRssi[2] - pAd->BbpRssiToDbmDelta)); +#endif /* ENHANCED_STAT_DISPLAY */ + } + +#if /*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_SCHEDULE) + + if (pAd->Flags & fRTMP_ADAPTER_RADIO_OFF) + sprintf(msg + strlen(msg), "Enable Wireless LAN = %s\n", "0"); + else + sprintf(msg + strlen(msg), "Enable Wireless LAN = %s\n", "1"); + + sprintf(msg + strlen(msg), "\n"); +#endif /*TCSUPPORT_COMPILE*/ + /* + * Let "iwpriv ra0 stat" can print out Tx/Rx Packet and Byte count. + * Therefore, we can parse them out in cfg_manager. --Trey */ +#ifdef BB_SOC + + for (index = 0; index < pAd->ApCfg.BssidNum; index++) { + rxPackets += (ULONG)pAd->ApCfg.MBSSID[index].RxCount; + txPackets += (ULONG)pAd->ApCfg.MBSSID[index].TxCount; + rxBytes += (ULONG)pAd->ApCfg.MBSSID[index].ReceivedByteCount; + txBytes += (ULONG)pAd->ApCfg.MBSSID[index].TransmittedByteCount; + } + + sprintf(msg + strlen(msg), "Packets Received = %lu\n", rxPackets); + sprintf(msg + strlen(msg), "Packets Sent = %lu\n", txPackets); + sprintf(msg + strlen(msg), "Bytes Received = %lu\n", rxBytes); + sprintf(msg + strlen(msg), "Bytes Sent = %lu\n", txBytes); + sprintf(msg + strlen(msg), "\n"); +#endif +#ifdef RTMP_EFUSE_SUPPORT + + if (pAd->bUseEfuse == TRUE) { + eFuseGetFreeBlockCount(pAd, &efusefreenum); + sprintf(msg + strlen(msg), "efuseFreeNumber = %d\n", efusefreenum); + } + +#endif /* RTMP_EFUSE_SUPPORT */ + sprintf(msg+strlen(msg), "driver_version %s\n", AP_DRIVER_VERSION); + /* 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(msg); +#if defined(TXBF_SUPPORT) && defined(ENHANCED_STAT_DISPLAY) +#endif /* defined(TXBF_SUPPORT) && defined(ENHANCED_STAT_DISPLAY) */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<==RTMPIoctlStatistics\n")); +} + +INT RTMPIoctlRXStatistics( + IN RTMP_ADAPTER *pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + RTMP_STRING *this_char, *value = NULL; + INT Status = NDIS_STATUS_SUCCESS; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s----------------->\n", __func__)); + + os_alloc_mem(NULL, (UCHAR **)&this_char, wrq->u.data.length + 1); + if (!this_char) + return -ENOMEM; + + if (copy_from_user(this_char, wrq->u.data.pointer, wrq->u.data.length)) { + os_free_mem(this_char); + return -EFAULT; + } + this_char[wrq->u.data.length] = 0; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): Before check, this_char = %s\n" + , __func__, this_char)); + value = strchr(this_char, '='); + + if (value) { + if (strlen(value) > 1) { + *value = 0; + value++; + } else + value = NULL; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): After check, this_char = %s, value = %s\n" + , __func__, this_char, (value == NULL ? "" : value))); + + for (PRTMP_PRIVATE_RX_PROC = RTMP_PRIVATE_RX_SUPPORT_PROC; PRTMP_PRIVATE_RX_PROC->name; PRTMP_PRIVATE_RX_PROC++) { + if (!strcmp(this_char, PRTMP_PRIVATE_RX_PROC->name)) { + if (!PRTMP_PRIVATE_RX_PROC->rx_proc(pAd, value, wrq)) { + /*FALSE:Set private failed then return Invalid argument */ + Status = -EINVAL; + } + + break; /*Exit for loop. */ + } + } + + if (PRTMP_PRIVATE_RX_PROC->name == NULL) { + /*Not found argument */ + Status = -EINVAL; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IOCTL::(iwpriv) Command not Support [%s = %s]\n", this_char, value)); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s<-----------------\n", __func__)); + os_free_mem(this_char); + return Status; +} + +#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)); + + if (BAT == NULL) + return; + + RTMPZeroMemory(BAT, sizeof(QUERYBA_TABLE)); + TotalEntry = pAd->MacTab.Size; + index = 0; + + for (i = 0; ((VALID_UCAST_ENTRY_WCID(pAd, i)) && (TotalEntry > 0)); i++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC) && (pEntry->TXBAbitmap) && (index < 32)) { + 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; ((VALID_UCAST_ENTRY_WCID(pAd, i)) && (TotalEntry > 0)); i++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC) && (pEntry->RXBAbitmap) && (index < 32)) { + 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)) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: copy_to_user() fail\n", __func__)); + + vfree(BAT); +} +#endif /* DOT11_N_SUPPORT */ + + +#ifdef APCLI_SUPPORT +INT Set_ApCli_Enable_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UINT Enable; + POS_COOKIE pObj; + UCHAR ifIndex; + struct wifi_dev *wdev = NULL; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + ifIndex = pObj->ioctl_if; + Enable = os_str_tol(arg, 0, 16); + pAd->ApCfg.ApCliTab[ifIndex].Enable = (Enable > 0) ? TRUE : FALSE; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("I/F(apcli%d) Set_ApCli_Enable_Proc::(enable = %d)\n", + ifIndex, + pAd->ApCfg.ApCliTab[ifIndex].Enable)); + wdev = &pAd->ApCfg.ApCliTab[ifIndex].wdev; +#ifdef APCLI_CONNECTION_TRIAL + + if (pAd->ApCfg.ApCliTab[ifIndex].TrialCh == 0) +#endif /* APCLI_CONNECTION_TRIAL */ + ApCliIfDown(pAd); + + /*Fix for TGac 5.2.57*/ + wlan_operate_set_prim_ch(wdev, wdev->channel); + + return TRUE; +} + + +INT Set_ApCli_Ssid_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj; + UCHAR ifIndex; + BOOLEAN apcliEn; + INT success = FALSE; + APCLI_STRUCT *apcli_entry; + struct wifi_dev *wdev; + + 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) { + apcli_entry = &pAd->ApCfg.ApCliTab[ifIndex]; + wdev = &apcli_entry->wdev; + /* bring apcli interface down first */ + apcliEn = apcli_entry->Enable; +#ifdef APCLI_CONNECTION_TRIAL + + if (pAd->ApCfg.ApCliTab[ifIndex].TrialCh == 0) { +#endif /* APCLI_CONNECTION_TRIAL */ + + if (apcliEn == TRUE) { + apcli_entry->Enable = FALSE; + ApCliIfDown(pAd); + } + +#ifdef APCLI_CONNECTION_TRIAL + } + +#endif /* APCLI_CONNECTION_TRIAL */ + apcli_entry->bPeerExist = FALSE; + NdisZeroMemory(apcli_entry->CfgSsid, MAX_LEN_OF_SSID); + NdisMoveMemory(apcli_entry->CfgSsid, arg, strlen(arg)); + apcli_entry->CfgSsidLen = (UCHAR)strlen(arg); + success = TRUE; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) Set_ApCli_Ssid_Proc::(Len=%d,Ssid=%s)\n", + ifIndex, apcli_entry->CfgSsidLen, apcli_entry->CfgSsid)); + apcli_entry->Enable = apcliEn; + } else + success = FALSE; + + return success; +} + + +INT Set_ApCli_Bssid_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + INT i; + RTMP_STRING *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; +#ifdef APCLI_CONNECTION_TRIAL + + if (pAd->ApCfg.ApCliTab[ifIndex].TrialCh == 0) +#endif /* APCLI_CONNECTION_TRIAL */ + 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 */ + } + + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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; +} + + +INT Set_ApCli_TxMode_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + struct wifi_dev *wdev; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + wdev = &pAd->ApCfg.ApCliTab[pObj->ioctl_if].wdev; + wdev->DesiredTransmitSetting.field.FixedTxMode = RT_CfgSetFixedTxPhyMode(arg); + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) Set_ApCli_TxMode_Proc = %d\n", + pObj->ioctl_if, wdev->DesiredTransmitSetting.field.FixedTxMode)); + return TRUE; +} + +INT Set_ApCli_WirelessMode_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev; + struct dev_rate_info *rate; + UCHAR WirelessMode = os_str_tol(arg, 0, 10); + UCHAR PhyMode; + APCLI_STRUCT *apcli_entry; + CHANNEL_CTRL *pChCtrl; + UCHAR BandIdx; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + apcli_entry = &pAd->ApCfg.ApCliTab[pObj->ioctl_if]; + wdev = &apcli_entry->wdev; + rate = &wdev->rate; + PhyMode = cfgmode_2_wmode(WirelessMode); + + if (!APCLI_IF_UP_CHECK(pAd, pObj->ioctl_if)) + return FALSE; + + /* apcli always follow per band's channel */ + if (WMODE_CAP_5G(PhyMode)) + wdev->channel = HcGetChannelByRf(pAd, RFIC_5GHZ); + else + wdev->channel = HcGetChannelByRf(pAd, RFIC_24GHZ); + + if (wdev_do_linkdown(wdev) != TRUE) + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, ("(%s) linkdown fail!\n", __func__)); + + os_msec_delay(100); + + if (wdev_do_close(wdev) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() close fail!!!\n", __func__)); + + /* fixed race condition between hw control task */ + os_msec_delay(100); + wdev->PhyMode = PhyMode; + HcAcquireRadioForWdev(pAd, wdev); + /* Change channel state to NONE */ + BandIdx = HcGetBandByWdev(wdev); + pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + hc_set_ChCtrlChListStat(pChCtrl, CH_LIST_STATE_NONE); + BuildChannelList(pAd, wdev); + RTMPSetPhyMode(pAd, wdev, PhyMode); + /*update rate info for wdev*/ + RTMPUpdateRateInfo(wdev->PhyMode, rate); + /* sync bw ext ch from mbss wdev */ + { + if (pAd->CommonCfg.dbdc_mode == TRUE) { + int mbss_idx; + + for (mbss_idx = 0; mbss_idx < pAd->ApCfg.BssidNum ; mbss_idx++) { + if (pAd->ApCfg.MBSSID[mbss_idx].wdev.PhyMode == wdev->PhyMode) { + update_att_from_wdev(wdev, &pAd->ApCfg.MBSSID[mbss_idx].wdev); + break; + } + } + } else { + /* align phy mode to BSS0 by default */ + wdev->PhyMode = pAd->ApCfg.MBSSID[BSS0].wdev.PhyMode; + update_att_from_wdev(wdev, &pAd->ApCfg.MBSSID[BSS0].wdev); + } + } + os_msec_delay(100); + + /* Security initial */ + if (wdev->SecConfig.AKMMap == 0x0) + SET_AKM_OPEN(wdev->SecConfig.AKMMap); + + if (wdev->SecConfig.PairwiseCipher == 0x0) { + SET_CIPHER_NONE(wdev->SecConfig.PairwiseCipher); + SET_CIPHER_NONE(wdev->SecConfig.GroupCipher); + } + + if (wdev_do_open(wdev) != TRUE) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s() open fail!!!\n", __func__)); + + os_msec_delay(100); + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) Set_ApCli_WirelessMode_Proc = %d\n", + pObj->ioctl_if, PhyMode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("SupRate[0]=%x\n", rate->SupRate[0])); + return TRUE; +} + + +INT Set_ApCli_TxMcs_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + wdev = &pAd->ApCfg.ApCliTab[pObj->ioctl_if].wdev; + wdev->DesiredTransmitSetting.field.MCS = + RT_CfgSetTxMCSProc(arg, &wdev->bAutoTxRateSwitch); + + if (wdev->DesiredTransmitSetting.field.MCS == MCS_AUTO) + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) Set_ApCli_TxMcs_Proc = AUTO\n", pObj->ioctl_if)); + else { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) Set_ApCli_TxMcs_Proc = %d\n", + pObj->ioctl_if, wdev->DesiredTransmitSetting.field.MCS)); + } + + return TRUE; +} + +#ifdef APCLI_CONNECTION_TRIAL +INT Set_ApCli_Trial_Ch_Proc( + RTMP_ADAPTER *pAd, + RTMP_STRING *arg) +{ + POS_COOKIE pObj; + UCHAR ifIndex; + PAPCLI_STRUCT pApCliEntry = NULL; + CHAR *str; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + ifIndex = pObj->ioctl_if; + + if (ifIndex != (pAd->ApCfg.ApCliNum - 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n\rI/F(apcli%d) can not run connection trial, use apcli%d\n", + ifIndex, (MAX_APCLI_NUM - 1))); + return FALSE; + } + + if (pAd->CommonCfg.dbdc_mode == TRUE) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n\rI/F(apcli%d) can not run connection trial with DBDC mode\n", + ifIndex)); + return FALSE; + } + + pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; + pApCliEntry->TrialCh = os_str_tol(arg, 0, 10); + + if (pApCliEntry->TrialCh) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) pApCliEntry->TrialCh = %d\n", ifIndex, + pApCliEntry->TrialCh)); + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) pApCliEntry->TrialCh = %d\n", ifIndex, + pApCliEntry->TrialCh)); + +#ifdef DBDC_MODE + + if ((WMODE_CAP_2G(pApCliEntry->wdev.PhyMode) && pApCliEntry->TrialCh > 14) || + (WMODE_CAP_5G(pApCliEntry->wdev.PhyMode) && pApCliEntry->TrialCh <= 14)) { + pApCliEntry->TrialCh = 0; + str = wmode_2_str(pApCliEntry->wdev.PhyMode); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("I/F(apcli%d) TrialCh = %d is not in this phy mode(%s)\n", + ifIndex, pApCliEntry->TrialCh, str)); + if (str) + os_free_mem(str); + return FALSE; + } + +#endif + return TRUE; +} +#endif /* APCLI_CONNECTION_TRIAL */ + + +#ifdef MAC_REPEATER_SUPPORT +INT Set_Cli_Link_Map_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR ifIndex; + UCHAR MbssIdx = 0; + struct wifi_dev *cli_link_wdev = NULL; + struct wifi_dev *mbss_link_wdev = NULL; + + if (pAd->ApCfg.bMACRepeaterEn != TRUE) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Rept has not been enabled yet.\n")); + return FALSE; + } + + if ((pObj->ioctl_if_type != INT_APCLI) && + (pObj->ioctl_if_type != INT_MSTA)) + return FALSE; + + ifIndex = pObj->ioctl_if; + + if (ifIndex > MAX_APCLI_NUM) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("wrong cli link idx:%d to set link map.\n", + ifIndex)); + return FALSE; + } + + cli_link_wdev = &pAd->ApCfg.ApCliTab[ifIndex].wdev; + MbssIdx = os_str_tol(arg, 0, 10); + + if (MbssIdx > HW_BEACON_MAX_NUM) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("wrong mbss idx:%d to set link map.\n", + MbssIdx)); + return FALSE; + } + + mbss_link_wdev = &pAd->ApCfg.MBSSID[MbssIdx].wdev; + UpdateMbssCliLinkMap(pAd, MbssIdx, cli_link_wdev, mbss_link_wdev); + return TRUE; +} + +INT Set_ReptMode_Enable_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UCHAR Enable = os_str_tol(arg, 0, 10); + + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MACRepeaterEn = %d, Repeater Mode (%s)\n", + pAd->ApCfg.bMACRepeaterEn, (Enable ? "ON" : "OFF"))); + AsicSetReptFuncEnable(pAd, Enable); + return TRUE; +} + + + +#endif /* MAC_REPEATER_SUPPORT */ + +#ifdef APCLI_AUTO_CONNECT_SUPPORT +/* + ========================================================================== + Description: + Trigger Apcli Auto connect to find the missed AP. + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ + +/* +0 : Disable apcli auto connect +1 : User Trigger Scan Mode +2 : Partial Scan Mode +3 : Driver Trigger Scan Mode +*/ + +INT Set_ApCli_AutoConnect_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR ifIndex; + AP_ADMIN_CONFIG *pApCfg; + NDIS_802_11_SSID Ssid; + long scan_mode = os_str_tol(arg, 0, 10); + struct wifi_dev *wdev = NULL; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + + pApCfg = &pAd->ApCfg; + ifIndex = pObj->ioctl_if; + NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID)); + wdev = &pApCfg->ApCliTab[ifIndex].wdev; + + if (ApScanRunning(pAd, wdev) == TRUE) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Set_ApCli_AutoConnect_Proc() is still running\n")); + return FALSE; + } + if (scan_mode == 0) {/* disable it */ + pAd->ScanCtrl.PartialScan.bScanning = FALSE; + pApCfg->ApCliTab[ifIndex].AutoConnectFlag = FALSE; + pApCfg->ApCliAutoConnectRunning[ifIndex] = FALSE; + pApCfg->ApCliAutoBWAdjustCnt[ifIndex] = 0; + pApCfg->ApCliAutoConnectType[ifIndex] = 0; + pApCfg->bPartialScanEnable[ifIndex] = FALSE; + pApCfg->bPartialScanning[ifIndex] = FALSE; + return TRUE; + } + + pApCfg->ApCliTab[ifIndex].AutoConnectFlag = TRUE; + Set_ApCli_Enable_Proc(pAd, "0"); + pApCfg->ApCliAutoConnectRunning[ifIndex] = TRUE; + pApCfg->ApCliAutoBWAdjustCnt[ifIndex] = 0; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) Set_ApCli_AutoConnect_Proc::(Len=%d,Ssid=%s)\n", + ifIndex, pApCfg->ApCliTab[ifIndex].CfgSsidLen, pApCfg->ApCliTab[ifIndex].CfgSsid)); + + /* + use site survey function to trigger auto connecting (when pAd->ApCfg.ApAutoConnectRunning == TRUE) + */ + switch (scan_mode) { + case 2:/* partial scan */ + pAd->ScanCtrl.PartialScan.pwdev = &pApCfg->ApCliTab[ifIndex].wdev; + pAd->ScanCtrl.PartialScan.bScanning = TRUE; + pApCfg->ApCliAutoConnectType[ifIndex] = TRIGGER_SCAN_BY_USER; + pApCfg->bPartialScanEnable[ifIndex] = TRUE; + pApCfg->bPartialScanning[ifIndex] = TRUE; + break; + case 3: /* full scan and autoconnect in ApCliCtrlJoinReqTimeoutAction, debug purpose */ + pAd->ScanCtrl.PartialScan.bScanning = FALSE; + pApCfg->ApCliAutoConnectType[ifIndex] = TRIGGER_SCAN_BY_DRIVER; + pApCfg->bPartialScanEnable[ifIndex] = FALSE; + pApCfg->bPartialScanning[ifIndex] = FALSE; + ApSiteSurvey_by_wdev(pAd, &Ssid, SCAN_ACTIVE, FALSE, &pApCfg->ApCliTab[ifIndex].wdev); + break; + case 1:/* full scan and autoconnect in RTMPRepeaterReconnectionCheck */ + default: + pAd->ScanCtrl.PartialScan.bScanning = FALSE; + pApCfg->ApCliAutoConnectType[ifIndex] = TRIGGER_SCAN_BY_USER; + pApCfg->bPartialScanEnable[ifIndex] = FALSE; + pApCfg->bPartialScanning[ifIndex] = FALSE; + ApSiteSurvey_by_wdev(pAd, &Ssid, SCAN_ACTIVE, FALSE, &pApCfg->ApCliTab[ifIndex].wdev); + break; + } + + return TRUE; +} +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ + + +#ifdef WSC_AP_SUPPORT +INT Set_AP_WscSsid_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR ifIndex = pObj->ioctl_if; + PWSC_CTRL pWscControl = &pAd->ApCfg.ApCliTab[ifIndex].wdev.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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscSsid_Proc:: (Select SsidLen=%d,Ssid=%s)\n", + pWscControl->WscSsid.SsidLength, pWscControl->WscSsid.Ssid)); + } else + return FALSE; /*Invalid argument */ + + return TRUE; +} + +#ifdef APCLI_SUPPORT +INT Set_ApCli_WscScanMode_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UCHAR Mode = TRIGGER_FULL_SCAN; + 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; + + Mode = simple_strtol(arg, 0, 10); + if (Mode != TRIGGER_PARTIAL_SCAN) + Mode = TRIGGER_FULL_SCAN; + +#ifdef AP_SCAN_SUPPORT + if ((pWscControl->WscApCliScanMode == TRIGGER_PARTIAL_SCAN) && + (Mode != TRIGGER_PARTIAL_SCAN)) { + pAd->ScanCtrl.PartialScan.pwdev = NULL; + pAd->ScanCtrl.PartialScan.LastScanChannel = 0; + pAd->ScanCtrl.PartialScan.bScanning = FALSE; + } +#endif /* AP_SCAN_SUPPORT */ + pWscControl->WscApCliScanMode = Mode; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:: (WscApCliScanMode=%d)\n", __func__, Mode)); + + return TRUE; +} +#endif /* APCLI_SUPPORT */ + +#endif /* WSC_AP_SUPPORT */ + +#ifdef APCLI_CERT_SUPPORT +INT Set_ApCli_Cert_Enable_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + UINT Enable; + POS_COOKIE pObj; + UCHAR ifIndex; + UCHAR wmode; + struct wifi_dev *wdev = NULL; + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + ifIndex = pObj->ioctl_if; + wdev = &pAd->ApCfg.ApCliTab[ifIndex].wdev; + wmode = wdev->PhyMode; + Enable = os_str_tol(arg, 0, 16); + pAd->bApCliCertTest = (Enable > 0) ? TRUE : FALSE; + + if (pAd->bApCliCertTest == TRUE) { + pAd->CommonCfg.bEnableTxBurst = FALSE; + /* TGn case 5.2.47 & 5.2.50 */ + pAd->CommonCfg.bSeOff = 1; + if (WMODE_CAP_2G(wmode)) + pAd->CommonCfg.g_band_256_qam = FALSE; + /* TGn case 5.2.3 */ + HW_IO_WRITE32(pAd, RMAC_NAVOPT, 0); + +#if defined(WHNAT_SUPPORT) && defined(PKT_BUDGET_CTRL_SUPPORT) + /* + * Decrease budget control queue size if wifi nat is enabled + * Only 1024 hardware tokens are available to the host + * whereas budget control AC queue sizes are larger than it. + * These will cause packets in sw queue to be dropped + * due to non availability of tokens. + * WMM traffic differentiation test cases will fail since + * pkts will be dropped without priority check. + * + * for TGn case 5.2.27 & 5.2.30 + */ + if ((pAd->CommonCfg.whnat_en) && + (IS_ASIC_CAP(pAd, fASIC_CAP_MCU_OFFLOAD))) { + pAd->pbc_bound[PBC_AC_BE] = PBC_WMM_UP_DEFAULT_BE / 2; + pAd->pbc_bound[PBC_AC_BK] = PBC_WMM_UP_DEFAULT_BK / 2; + pAd->pbc_bound[PBC_AC_VO] = PBC_WMM_UP_DEFAULT_VO / 2; + pAd->pbc_bound[PBC_AC_VI] = PBC_WMM_UP_DEFAULT_VI / 2; + } +#endif + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) Set_ApCli_Cert_Enable_Proc::(enable = %d)\n", + ifIndex, pAd->bApCliCertTest)); + return TRUE; +} + +/* Add for APCLI PMF 5.3.3.3 option test item. (Only Tx De-auth Req. and make sure the pkt can be Encrypted) */ +INT ApCliTxDeAuth( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + USHORT Reason = (USHORT)REASON_DEAUTH_STA_LEAVING; +#ifdef MAC_REPEATER_SUPPORT + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + UCHAR CliIdx = 0xFF; +#endif /* MAC_REPEATER_SUPPORT */ + HEADER_802_11 DeauthHdr; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0; + NDIS_STATUS NStatus; + POS_COOKIE pObj; + UCHAR ifIndex; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (pObj->ioctl_if_type != INT_APCLI) + return FALSE; + + ifIndex = pObj->ioctl_if; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s : ifIndex=%u\n", __func__, ifIndex)); + + if ((ifIndex >= MAX_APCLI_NUM) +#ifdef MAC_REPEATER_SUPPORT + && (ifIndex < REPT_MLME_START_IDX) +#endif /* MAC_REPEATER_SUPPORT */ + ) + return FALSE; + +#ifdef MAC_REPEATER_SUPPORT + + if (ifIndex >= REPT_MLME_START_IDX) { + CliIdx = ifIndex - REPT_MLME_START_IDX; + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + ifIndex = pReptEntry->wdev->func_idx; + } + +#endif /* MAC_REPEATER_SUPPORT */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ + + if (NStatus != NDIS_STATUS_SUCCESS) + return FALSE; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("%s: DE-AUTH request (Reason=%d)...\n", __func__, Reason)); + ApCliMgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAd->ApCfg.ApCliTab[ifIndex].MlmeAux.Bssid, + pAd->ApCfg.ApCliTab[ifIndex].MlmeAux.Bssid, ifIndex); +#ifdef MAC_REPEATER_SUPPORT + + if (CliIdx != 0xFF) + COPY_MAC_ADDR(DeauthHdr.Addr2, pAd->ApCfg.pRepeaterCliPool[CliIdx].CurrentAddress); + +#endif /* MAC_REPEATER_SUPPORT */ + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DeauthHdr, + 2, &Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + return TRUE; +} + +#endif /* APCLI_CERT_SUPPORT */ +#ifdef ROAMING_ENHANCE_SUPPORT +INT Set_RoamingEnhance_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT Enable; + POS_COOKIE pObj; + UCHAR ifIndex; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + Enable = simple_strtol(arg, 0, 10); + pAd->ApCfg.bRoamingEnhance = (Enable > 0) ? TRUE : FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(apcli%d) %s::(enable = %d)\n", + ifIndex, __func__, pAd->ApCfg.bRoamingEnhance)); + return TRUE; +} +#endif /* ROAMING_ENHANCE_SUPPORT */ +#endif /* APCLI_SUPPORT */ + + +#ifdef WSC_AP_SUPPORT +INT Set_Wps_Cert_Enable_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + UINT Enable; + POS_COOKIE pObj; + UCHAR ifIndex; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + ifIndex = pObj->ioctl_if; + Enable = os_str_tol(arg, 0, 16); + pAd->bWpsCertTest = (Enable > 0) ? TRUE : FALSE; + + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_Wps_Cert_Enable_Proc::(enable = %d)\n", + pAd->bWpsCertTest)); + return TRUE; +} +#endif + + + +#ifdef WSC_AP_SUPPORT +#ifdef CON_WPS +static INT WscPushConcurrentPBCAction( + IN PRTMP_ADAPTER pAd, + IN PWSC_CTRL pWscControl, + IN BOOLEAN bIsApCli) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + INT idx; + + if (bIsApCli) + pWscControl->WscConfMode = WSC_ENROLLEE; + else + pWscControl->WscConfMode = WSC_REGISTRAR; + + WscInit(pAd, bIsApCli, apidx); + pWscControl->WscMode = WSC_PBC_MODE; + WscGetRegDataPIN(pAd, pWscControl->WscPinCode, pWscControl); + WscStop(pAd, bIsApCli, pWscControl); + pWscControl->RegData.ReComputePke = 1; + WscInitRegistrarPair(pAd, pWscControl, apidx); + + for (idx = 0; idx < 192; idx++) + pWscControl->RegData.EnrolleeRandom[idx] = RandomByte(pAd); + + pWscControl->bWscAutoTigeer = FALSE; + + if (bIsApCli) { + pAd->ApCfg.ApCliTab[apidx].Enable = FALSE; + ApCliIfDown(pAd); + pWscControl->WscSsid.SsidLength = 0; + NdisZeroMemory(&pWscControl->WscSsid, sizeof(NDIS_802_11_SSID)); + pWscControl->WscPBCBssCount = 0; + /* WPS - SW PBC */ + WscPushPBCAction(pAd, pWscControl); + } else { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + WscBuildBeaconIE(pAd, pWscControl->WscConfStatus, TRUE, DEV_PASS_ID_PBC, + pWscControl->WscConfigMethods, apidx, NULL, 0, AP_MODE); + WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, pWscControl->WscConfStatus, TRUE, DEV_PASS_ID_PBC, + pWscControl->WscConfigMethods, apidx, NULL, 0, AP_MODE); + UpdateBeaconHandler(pAd, wdev, BCN_UPDATE_IE_CHG); + RTMPSetTimer(&pWscControl->Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT); + pWscControl->Wsc2MinsTimerRunning = TRUE; + pWscControl->WscStatus = STATUS_WSC_LINK_UP; + pWscControl->bWscTrigger = TRUE; + RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock); + WscClearPeerList(&pWscControl->WscPeerList); + RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock); + } + + return TRUE; +} + +INT Set_ConWpsApCliMode_Proc( + RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef MULTI_INF_SUPPORT + UINT Mode = CON_WPS_APCLI_BAND_AUTO; + UINT opposBandIdx = !multi_inf_get_idx(pAd); + PRTMP_ADAPTER pOpposAd = NULL; + + Mode = os_str_tol(arg, 0, 10); + + if (Mode >= CON_WPS_APCLI_BAND_MAX) + return FALSE; + + pOpposAd = (PRTMP_ADAPTER)adapt_list[opposBandIdx]; + pAd->ApCfg.ConWpsApCliMode = Mode; + + if (pOpposAd != NULL) { + pOpposAd->ApCfg.ConWpsApCliMode = Mode; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Oppos: %s, Mode = %d\n", + __func__, pAd->net_dev->name, pOpposAd->net_dev->name, Mode)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Mode = %d\n", + __func__, pAd->net_dev->name, Mode)); + } + +#else + UINT Mode = CON_WPS_APCLI_BAND_AUTO; + + Mode = os_str_tol(arg, 0, 10); + + if (Mode >= CON_WPS_APCLI_BAND_MAX) + return FALSE; + + pAd->ApCfg.ConWpsApCliMode = Mode; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Mode = %d\n", + __func__, pAd->net_dev->name, Mode)); +#endif + return TRUE; +} + +INT Set_ConWpsApcliAutoPreferIface_Proc( + RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef MULTI_INF_SUPPORT + UINT PreferIface = CON_WPS_APCLI_AUTO_PREFER_IFACE0; + UINT opposBandIdx = !multi_inf_get_idx(pAd); + PRTMP_ADAPTER pOpposAd = NULL; + + PreferIface = os_str_tol(arg, 0, 10); + + if (PreferIface >= CON_WPS_APCLI_AUTO_PREFER_IFACE_MAX) + return FALSE; + + pOpposAd = (PRTMP_ADAPTER)adapt_list[opposBandIdx]; + pAd->ApCfg.ConWpsApcliAutoPreferIface = PreferIface; + + if (pOpposAd != NULL) { + pOpposAd->ApCfg.ConWpsApcliAutoPreferIface = PreferIface; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Oppos: %s, PreferIface = %d\n", + __func__, pAd->net_dev->name, pOpposAd->net_dev->name, PreferIface)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, PreferIface = %d\n", + __func__, pAd->net_dev->name, PreferIface)); + } + +#else + UINT PreferIface = CON_WPS_APCLI_AUTO_PREFER_IFACE0; + + PreferIface = os_str_tol(arg, 0, 10); + pAd->ApCfg.ConWpsApcliAutoPreferIface = PreferIface; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, PreferIface = %d\n", + __func__, pAd->net_dev->name, PreferIface)); +#endif + return TRUE; +} + +INT Set_ConWpsApCliDisabled_Proc( + RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef MULTI_INF_SUPPORT + UINT Disabled = FALSE; + UINT opposBandIdx = !multi_inf_get_idx(pAd); + PRTMP_ADAPTER pOpposAd = NULL; + + Disabled = os_str_tol(arg, 0, 10); + pOpposAd = (PRTMP_ADAPTER)adapt_list[opposBandIdx]; + pAd->ApCfg.ConWpsApCliDisableSetting = Disabled; + + if (pOpposAd != NULL) { + pOpposAd->ApCfg.ConWpsApCliDisableSetting = Disabled; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Oppos: %s, ApClient Disabled = %d\n", + __func__, pAd->net_dev->name, pOpposAd->net_dev->name, Disabled)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, ApClient Disabled = %d\n", + __func__, pAd->net_dev->name, Disabled)); + } + +#else + UINT Disabled = FALSE; + + Disabled = os_str_tol(arg, 0, 10); + pAd->ApCfg.ConWpsApCliDisableSetting = Disabled; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, ApClient Disabled = %d\n", + __func__, pAd->net_dev->name, Disabled)); +#endif + return TRUE; +} + +INT Set_ConWpsApDisabled_Proc( + RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef MULTI_INF_SUPPORT + UINT Disabled = FALSE; + UINT opposBandIdx = !multi_inf_get_idx(pAd); + PRTMP_ADAPTER pOpposAd = NULL; + + Disabled = simple_strtol(arg, 0, 10); + pOpposAd = (PRTMP_ADAPTER)adapt_list[opposBandIdx]; + pAd->ApCfg.ConWpsApDisableSetting = Disabled; + + if (pOpposAd != NULL) { + pOpposAd->ApCfg.ConWpsApDisableSetting = Disabled; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Oppos: %s, Ap Disabled = %d\n", + __func__, pAd->net_dev->name, pOpposAd->net_dev->name, Disabled)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Ap Disabled = %d\n", + __func__, pAd->net_dev->name, Disabled)); + } + +#else + UINT Disabled = FALSE; + + Disabled = simple_strtol(arg, 0, 10); + pAd->ApCfg.ConWpsApDisableSetting = Disabled; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s Now: %s, Ap Disabled = %d\n", + __func__, pAd->net_dev->name, Disabled)); +#endif + return TRUE; +} +#endif /* CON_WPS */ + +INT Set_AP_WscConfMode_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *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; +#ifdef CON_WPS + struct wifi_dev *pWdev = NULL; +#endif + ConfModeIdx = os_str_tol(arg, 0, 10); +#ifdef HOSTAPD_SUPPORT + + if (pAd->ApCfg.MBSSID[apidx].Hostapd == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + return FALSE; + } + +#endif /*HOSTAPD_SUPPORT*/ +#ifdef CON_WPS + + if (ConfModeIdx == WSC_ENROLLEE_REGISTRAR) { + UINT ApClientWcid = 0; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("WPS is using concurrent WPS now apidx=%d\n", apidx)); + + if ((pAd->ApCfg.ConWpsApCliDisableSetting == TRUE) && + (apidx < pAd->ApCfg.ApCliNum) && + (pAd->ApCfg.ApCliTab[apidx].CtrlCurrState == APCLI_CTRL_CONNECTED)) { + ApClientWcid = pAd->ApCfg.ApCliTab[apidx].MacTabWCID; + + if ((pAd->MacTab.Content[ApClientWcid].Sst == SST_ASSOC) && + (pAd->MacTab.tr_entry[ApClientWcid].PortSecured == WPA_802_1X_PORT_SECURED)) + pAd->ApCfg.ConWpsApCliDisabled = TRUE; + } + + if (pAd->ApCfg.ConWpsApCliDisabled == TRUE) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Diabled the ApClient when using concurrent WPS now.\n")); + else if ((apidx < pAd->ApCfg.ApCliNum) && + (pAd->ApCfg.ApCliTab[apidx].Enable)) { + pWdev = &(pAd->ApCfg.ApCliTab[apidx].wdev); + + if (pWdev != NULL) { + pWscControl = &pAd->ApCfg.ApCliTab[apidx].wdev.WscControl; + pWscControl->conWscStatus = CON_WPS_STATUS_APCLI_RUNNING; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Set_AP_WscConfMode_Proc enter WscPushConcurrentPBCAction(apcli%d) pWscControl=0x%p\n", apidx, pWscControl)); + RTMPZeroMemory(pAd->ApCfg.ApCliTab[apidx].wdev.WscControl.IfName, IFNAMSIZ); + RTMPMoveMemory(pAd->ApCfg.ApCliTab[apidx].wdev.WscControl.IfName, pWdev->if_dev->name, IFNAMSIZ); + WscPushConcurrentPBCAction(pAd, pWscControl, TRUE); + } + } + + if (pAd->ApCfg.ConWpsApDisableSetting == TRUE) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Disable the AP when using concurrent WPS now\n")); + else { + pWscControl = &pAd->ApCfg.MBSSID[apidx].wdev.WscControl; + pWscControl->conWscStatus = CON_WPS_STATUS_AP_RUNNING; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Set_AP_WscConfMode_Proc enter WscPushConcurrentPBCAction(ra%d)\n", + apidx)); + WscPushConcurrentPBCAction(pAd, pWscControl, FALSE); + } + + return TRUE; + } + +#endif /* CON_WPS */ +#ifdef APCLI_SUPPORT + + if (pObj->ioctl_if_type == INT_APCLI) { + bFromApCli = TRUE; + pWscControl = &pAd->ApCfg.ApCliTab[apidx].wdev.WscControl; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(apcli%d) Set_WscConfMode_Proc:: WPS is disabled.\n", + apidx)); + else { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_WscConfMode_Proc:: WPS is disabled.\n", apidx)); + /* Clear WPS IE in Beacon and ProbeResp */ + wdev->WscIEBeacon.ValueLen = 0; + wdev->WscIEProbeResp.ValueLen = 0; + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + } + } else { +#ifdef APCLI_SUPPORT + + if (bFromApCli) { + if (ConfModeIdx == WSC_ENROLLEE) { + pWscControl->WscConfMode = WSC_ENROLLEE; + WscInit(pAd, TRUE, apidx); + } else { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.if_addr[0], MAC_ADDR_LEN); + else +#endif /* APCLI_SUPPORT */ + { + memcpy(mac_addr, &pAd->ApCfg.MBSSID[apidx].wdev.bssid[0], MAC_ADDR_LEN); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscConfMode_Proc::(WscConfMode(0~7)=%d)\n", + PRINT_MAC(mac_addr), pWscControl->WscConfMode)); + return TRUE; +} + +INT Set_AP_WscConfStatus_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *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 == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + return FALSE; + } + +#endif /*HOSTAPD_SUPPORT*/ +#ifdef APCLI_SUPPORT + + if (pObj->ioctl_if_type == INT_APCLI) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl.WscV2Info.bWpsEnable == FALSE) && + (pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscV2Info.bEnableWpsV2)) { + pAd->ApCfg.MBSSID[apidx].wdev.WscIEBeacon.ValueLen = 0; + pAd->ApCfg.MBSSID[apidx].wdev.WscIEProbeResp.ValueLen = 0; + return FALSE; + } + +#endif /* WSC_V2_SUPPORT */ +#endif /* CONFIG_AP_SUPPORT */ + IsAPConfigured = (UCHAR)os_str_tol(arg, 0, 10); + IsSelectedRegistrar = pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscSelReg; + + if (pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscMode == 1) + WscMode = DEV_PASS_ID_PIN; + else + WscMode = DEV_PASS_ID_PBC; + + if ((IsAPConfigured > 0) && (IsAPConfigured <= 2)) { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + pAd->ApCfg.MBSSID[apidx].wdev.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); + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(ra%d) Set_WscConfStatus_Proc:: Set failed!!(WscConfStatus=%s), WscConfStatus is 1 or 2\n", + apidx, arg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(ra%d) Set_WscConfStatus_Proc:: WscConfStatus is not changed (%d)\n", + apidx, pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscConfStatus)); + return FALSE; /*Invalid argument */ + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscConfStatus_Proc::(WscConfStatus=%d)\n", + PRINT_MAC(pAd->ApCfg.MBSSID[apidx].wdev.bssid), + pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscConfStatus)); + return TRUE; +} + +INT Set_AP_WscMode_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *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 == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(ra%d) Set_WscMode_Proc:: This command is from ra interface now.\n", + apidx)); + } + + WscMode = os_str_tol(arg, 0, 10); + + if ((WscMode > 0) && (WscMode <= 2)) { + pWscControl->WscMode = WscMode; + + if (WscMode == WSC_PBC_MODE) + WscGetRegDataPIN(pAd, pWscControl->WscPinCode, pWscControl); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Set_WscMode_Proc:: Set failed!!(Set_WscMode_Proc=%s), WscConfStatus is 1 or 2\n", + arg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.if_addr, MAC_ADDR_LEN); + else +#endif /* APCLI_SUPPORT */ + { + memcpy(mac_addr, pAd->ApCfg.MBSSID[apidx].wdev.bssid, MAC_ADDR_LEN); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscMode_Proc::(WscMode=%d)\n", + PRINT_MAC(mac_addr), pWscControl->WscMode)); + return TRUE; +} + +INT Set_WscStatus_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_WscStatus_Proc::(WscStatus=%d)\n", + apidx, pAd->ApCfg.MBSSID[apidx].wdev.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 RTMP_STRING *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 == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + return FALSE; + } + +#endif /*HOSTAPD_SUPPORT*/ +#ifdef APCLI_SUPPORT + + if (pObj->ioctl_if_type == INT_APCLI) { + if (pAd->ApCfg.ApCliTab[apidx].ApCliInit == FALSE) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 = os_str_tol(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; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.if_addr, 6); + pAd->ApCfg.ApCliTab[apidx].Enable = apcliEn; + } else { + pWscControl->WscSsid.SsidLength = 0; + NdisZeroMemory(&pWscControl->WscSsid, sizeof(NDIS_802_11_SSID)); + pWscControl->WscPBCBssCount = 0; + /* WPS - SW PBC */ + WscPushPBCAction(pAd, pWscControl); + } + + NdisMoveMemory(mac_addr, pAd->ApCfg.ApCliTab[apidx].wdev.if_addr, MAC_ADDR_LEN); + } else +#endif /* APCLI_SUPPORT */ + { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + 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); + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + NdisMoveMemory(mac_addr, pAd->ApCfg.MBSSID[apidx].wdev.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].wdev.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 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscGetConf_Proc trigger WSC state machine, wscGetConfMode=%d\n", + PRINT_MAC(mac_addr), wscGetConfMode)); + return TRUE; +} + +INT Set_AP_WscPinCode_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *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 = os_str_tol(arg, 0, 10); /* When PinCode is 03571361, return value is 3571361. */ +#ifdef HOSTAPD_SUPPORT + + if (pAd->ApCfg.MBSSID[apidx].Hostapd == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("PIN authentication or communication error occurs!!\n" + "Registrar does NOT accept the same PIN again!(PIN:%s)\n", arg)); + return FALSE; + } + + 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 { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.if_addr, MAC_ADDR_LEN); + else +#endif /* APCLI_SUPPORT */ + { + memcpy(mac_addr, pAd->ApCfg.MBSSID[apidx].wdev.bssid, MAC_ADDR_LEN); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(%02X:%02X:%02X:%02X:%02X:%02X) Set_WscPinCode_Proc::(PinCode=%d)\n", + PRINT_MAC(mac_addr), pWscControl->WscPinCode)); + return TRUE; +} + +INT Set_WscOOB_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *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 == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + return FALSE; + } + +#endif /*HOSTAPD_SUPPORT*/ +#ifdef APCLI_SUPPORT + + if (pObj->ioctl_if_type == INT_APCLI) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(apcli%d) Set_WscPinCode_Proc:: Ap Client doesn't need this command.\n", apidx)); + return FALSE; + } + +#endif /* APCLI_SUPPORT */ + Set_WscSetupLock_Proc(pAd, "0"); + Set_AP_WscConfStatus_Proc(pAd, "1"); + Set_SecAuthMode_Proc(pAd, "WPA2PSK"); + Set_SecEncrypType_Proc(pAd, "AES"); + pTempSsid = vmalloc(33); + + if (pTempSsid) { + memset(pTempSsid, 0, 33); + snprintf(pTempSsid, 33, "RalinkInitialAP%02X%02X%02X", + pAd->ApCfg.MBSSID[apidx].wdev.bssid[3], + pAd->ApCfg.MBSSID[apidx].wdev.bssid[4], + pAd->ApCfg.MBSSID[apidx].wdev.bssid[5]); + Set_AP_SSID_Proc(pAd, pTempSsid); + vfree(pTempSsid); + } + + Set_SecWPAPSK_Proc(pAd, "RalinkInitialAPxx1234"); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_WscOOB_Proc\n", apidx)); + return TRUE; +} + +INT Set_WscStop_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *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 == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + 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); + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + WscStop(pAd, FALSE, pWscControl); + } + + pWscControl->bWscTrigger = FALSE; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<===== Set_WscStop_Proc")); + return TRUE; +} + +#ifdef VENDOR_FEATURE6_SUPPORT +/* copy from RTMPIoctlWscProfile() but the strue is use WSC_CONFIGURED_VALUE_2 */ +VOID RTMPGetCurrentCred( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT * wrq) +{ + WSC_CONFIGURED_VALUE_2 Profile; + RTMP_STRING *msg; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + BSS_STRUCT *pMbss; + struct wifi_dev *wdev; + + pMbss = &pAd->ApCfg.MBSSID[apidx]; + wdev = &pMbss->wdev; +#ifdef HOSTAPD_SUPPORT + + if (pMbss->Hostapd == TRUE) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + return; + } + +#endif /*HOSTAPD_SUPPORT*/ + memset(&Profile, 0x00, sizeof(WSC_CONFIGURED_VALUE_2)); + Profile.WscConfigured = pMbss->WscControl.WscConfStatus; + NdisZeroMemory(Profile.WscSsid, 32); + NdisMoveMemory(Profile.WscSsid, pMbss->Ssid, pMbss->SsidLen); + Profile.WscSsidLen = pMbss->SsidLen; + Profile.WscAuthMode = WscGetAuthType(wdev->SecConfig.AKMMap); + Profile.WscEncrypType = WscGetEncryType(wdev->SecConfig.PairwiseCipher); + NdisZeroMemory(Profile.WscWPAKey, 64); + + if (Profile.WscEncrypType == 2) { + Profile.DefaultKeyIdx = wdev->SecConfig.PairwiseKeyId + 1; + { + int i; + + for (i = 0; i < wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].KeyLen; i++) { + snprintf((RTMP_STRING *) Profile.WscWPAKey, sizeof(Profile.WscWPAKey), + "%s%02x", Profile.WscWPAKey, + wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].Key[i]); + } + + Profile.WscWPAKeyLen = wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].KeyLen; + } + } else if (Profile.WscEncrypType >= 4) { + Profile.DefaultKeyIdx = 2; + NdisMoveMemory(Profile.WscWPAKey, pMbss->WscControl.WpaPsk, + pMbss->WscControl.WpaPskLen); + Profile.WscWPAKeyLen = pMbss->WscControl.WpaPskLen; + } else + Profile.DefaultKeyIdx = 1; + + wrq->u.data.length = sizeof(Profile); + + if (copy_to_user(wrq->u.data.pointer, &Profile, wrq->u.data.length)) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: copy_to_user() fail\n", __func__)); + + /* msg = (RTMP_STRING *)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 (IS_AKM_WPA1PSK(wdev->SecConfig.AKMMap) || IS_AKM_WPA2PSK(wdev->SecConfig.AKMMap)) + sprintf(msg + strlen(msg), "%-12s", "WPAPSKWPA2PSK"); + else + sprintf(msg + strlen(msg), "%-12s", WscGetAuthTypeStr(Profile.WscAuthMode)); + + if (IS_CIPHER_TKIP(wdev->SecConfig.PairwiseCipher) || IS_CIPHER_CCMP128(wdev->SecConfig.PairwiseCipher)) + 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 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s", msg)); + os_free_mem(msg); +} +#endif /* VENDOR_FEATURE6_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 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; + RTMP_STRING *msg; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + BSS_STRUCT *pMbss; + struct wifi_dev *wdev; + + pMbss = &pAd->ApCfg.MBSSID[apidx]; + wdev = &pMbss->wdev; +#ifdef HOSTAPD_SUPPORT + + if (pMbss->Hostapd == Hostapd_EXT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("WPS is control by hostapd now.\n")); + return; + } + +#endif /*HOSTAPD_SUPPORT*/ + memset(&Profile, 0x00, sizeof(WSC_CONFIGURED_VALUE)); + Profile.WscConfigured = pMbss->wdev.WscControl.WscConfStatus; + NdisZeroMemory(Profile.WscSsid, 32 + 1); + NdisMoveMemory(Profile.WscSsid, pMbss->Ssid, pMbss->SsidLen); + Profile.WscSsid[pMbss->SsidLen] = '\0'; + Profile.WscAuthMode = WscGetAuthType(wdev->SecConfig.AKMMap); + Profile.WscEncrypType = WscGetEncryType(wdev->SecConfig.PairwiseCipher); + NdisZeroMemory(Profile.WscWPAKey, 64 + 1); + + if (Profile.WscEncrypType == 2) { + Profile.DefaultKeyIdx = wdev->SecConfig.PairwiseKeyId + 1; + { + int i; + + for (i = 0; i < wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].KeyLen; i++) { + snprintf((RTMP_STRING *) Profile.WscWPAKey, sizeof(Profile.WscWPAKey), + "%s%02x", Profile.WscWPAKey, + wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].Key[i]); + } + + Profile.WscWPAKey[(wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].KeyLen) * 2] = '\0'; + } + } else if (Profile.WscEncrypType >= 4) { + Profile.DefaultKeyIdx = 2; + NdisMoveMemory(Profile.WscWPAKey, pMbss->wdev.WscControl.WpaPsk, + pMbss->wdev.WscControl.WpaPskLen); + Profile.WscWPAKey[pMbss->wdev.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)) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: copy_to_user() fail\n", __func__)); + + 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 (IS_AKM_WPA1PSK(wdev->SecConfig.AKMMap) || IS_AKM_WPA2PSK(wdev->SecConfig.AKMMap)) + sprintf(msg + strlen(msg), "%-12s", "WPAPSKWPA2PSK"); + else + sprintf(msg + strlen(msg), "%-12s", WscGetAuthTypeStr(Profile.WscAuthMode)); + + if (IS_CIPHER_TKIP(wdev->SecConfig.PairwiseCipher) || IS_CIPHER_CCMP128(wdev->SecConfig.PairwiseCipher)) + 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 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s", msg)); + os_free_mem(msg); +} + +#if defined(INF_AR9) || defined(BB_SOC) +#if defined(AR9_MAPI_SUPPORT) || defined(BB_SOC) + +/* + ========================================================================== + 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; + RTMP_STRING *msg; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + BSS_STRUCT *pMbss; + struct wifi_dev *wdev; + + pMbss = &pAd->ApCfg.MBSSID[apidx]; + wdev = &pMbss->wdev; + memset(&Profile, 0x00, sizeof(WSC_CONFIGURED_VALUE)); + Profile.WscConfigured = pAd->ApCfg.MBSSID[apidx].wdev.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'; + Profile.WscAuthMode = WscGetAuthType(wdev->SecConfig.AKMMap); + Profile.WscEncrypType = WscGetEncryType(wdev->SecConfig.PairwiseCipher); + NdisZeroMemory(Profile.WscWPAKey, 64 + 1); + + if (Profile.WscEncrypType == 2) { + Profile.DefaultKeyIdx = wdev->SecConfig.PairwiseKeyId + 1; + { + int i; + + for (i = 0; i < wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].KeyLen; i++) { + snprintf((RTMP_STRING *) Profile.WscWPAKey, sizeof(Profile.WscWPAKey), + "%s%02x", Profile.WscWPAKey, + wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].Key[i]); + } + + Profile.WscWPAKey[(wdev->SecConfig.WepKey[Profile.DefaultKeyIdx].KeyLen) * 2] = '\0'; + } + } else if (Profile.WscEncrypType >= 4) { + Profile.DefaultKeyIdx = 2; + NdisMoveMemory(Profile.WscWPAKey, pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WpaPsk, + pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WpaPskLen); + Profile.WscWPAKey[pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WpaPskLen] = '\0'; + } else + Profile.DefaultKeyIdx = 1; + + 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 (IS_AKM_WPA1PSK(wdev->SecConfig.AKMMap) || IS_AKM_WPA2PSK(wdev->SecConfig.AKMMap)) + sprintf(msg + strlen(msg), "%-12s", "WPAPSKWPA2PSK"); + else + sprintf(msg + strlen(msg), "%-12s", WscGetAuthTypeStr(Profile.WscAuthMode)); + + if (IS_CIPHER_TKIP(wdev->SecConfig.PairwiseCipher) || IS_CIPHER_CCMP128(wdev->SecConfig.PairwiseCipher)) + 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); + { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s", msg)); + } + os_free_mem(msg); +} + +VOID RTMPIoctlWscPINCode( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + RTMP_STRING *msg; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + UCHAR tempPIN[9] = {0}; + + 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].wdev.WscControl.WscEnrolleePinCode) { + if (pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscEnrolleePinCodeLen == 8) + sprintf((RTMP_STRING *) tempPIN, "%08u", pAd->ApCfg.MBSSID[apidx].wdev.WscControl.WscEnrolleePinCode); + else + sprintf((RTMP_STRING *) tempPIN, "%04u", pAd->ApCfg.MBSSID[apidx].wdev.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); + { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s", msg)); + } + os_free_mem(msg); +} + +VOID RTMPIoctlWscStatus( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + RTMP_STRING *msg; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + + 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].wdev.WscControl.WscStatus); + wrq->u.data.length = strlen(msg); + copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length); + { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s", msg)); + } + os_free_mem(msg); +} + +VOID RTMPIoctlGetWscDynInfo( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + char *msg; + BSS_STRUCT *pMbss; + INT apidx, configstate; + + os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR) * (pAd->ApCfg.BssidNum * (14 * 128))); + + if (msg == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Alloc memory failed\n", __func__)); + return; + } + + memset(msg, 0, pAd->ApCfg.BssidNum * (14 * 128)); + sprintf(msg, "%s", "\n"); + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + pMbss = &pAd->ApCfg.MBSSID[apidx]; + + if (pMbss->wdev.WscControl.WscConfStatus == WSC_SCSTATE_UNCONFIGURED) + configstate = 0; + else + configstate = 1; + + sprintf(msg + strlen(msg), "ra%d\n", apidx); +#ifdef BB_SOC + sprintf(msg + strlen(msg), "DeviceName = %s\n", (pMbss->wdev.WscControl.RegData.SelfInfo.DeviceName)); +#endif + sprintf(msg + strlen(msg), "UUID = %s\n", (pMbss->wdev.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)) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s", msg)); + + os_free_mem(msg); +} + +VOID RTMPIoctlGetWscRegsDynInfo( + IN PRTMP_ADAPTER pAd, + IN RTMP_IOCTL_INPUT_STRUCT *wrq) +{ + char *msg; + BSS_STRUCT *pMbss; + INT apidx; + + os_alloc_mem(NULL, (UCHAR **)&msg, sizeof(CHAR) * (pAd->ApCfg.BssidNum * (14 * 128))); + + if (msg == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Alloc memory failed\n", __func__)); + return; + } + + memset(msg, 0, pAd->ApCfg.BssidNum * (14 * 128)); + sprintf(msg, "%s", "\n"); + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + pMbss = &pAd->ApCfg.MBSSID[apidx]; + sprintf(msg + strlen(msg), "ra%d\n", apidx); +#ifdef BB_SOC + sprintf(msg + strlen(msg), "DeviceName = %s\n", (pMbss->wdev.WscControl.RegData.SelfInfo.DeviceName)); +#endif + sprintf(msg + strlen(msg), "UUID_R = %s\n", (pMbss->wdev.WscControl.RegData.PeerInfo.Uuid)); + } + + wrq->u.data.length = strlen(msg); + + if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length)) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s", msg)); + + os_free_mem(msg); +} +#endif /* defined(AR9_MAPI_SUPPORT) || defined(BB_SOC) */ +#endif /* defined(INF_AR9) || defined(BB_SOC) */ + +BOOLEAN WscCheckEnrolleeNonceFromUpnp( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_STRING *pData, + IN USHORT Length, + IN PWSC_CTRL pWscControl) +{ + USHORT WscType, WscLen; + USHORT WscId = WSC_ID_ENROLLEE_NONCE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Nonce match!!\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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. */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Zero Enrollee Nonce!!\n")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<----- WscCheckNonce\n")); + return TRUE; + } + } + + /* Offset to net WSC Ie */ + pData += WscLen; + Length -= WscLen; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Nonce mismatch!!\n")); + return FALSE; +} + +UCHAR WscRxMsgTypeFromUpnp( + IN PRTMP_ADAPTER pAdapter, + IN RTMP_STRING *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 */ + + 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; + + pObj->pSecConfig = &pAd->ApCfg.MBSSID[apidx].wdev.SecConfig; +#ifdef APCLI_SUPPORT + + if (pObj->ioctl_if_type == INT_APCLI) { + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("IF(apcli%d) Set_WscPinCode_Proc:: Ap Client doesn't need this command.\n", apidx)); + return; + } + +#endif /* APCLI_SUPPORT */ + Set_WscSetupLock_Proc(pAd, "0"); + Set_AP_WscConfStatus_Proc(pAd, "1"); + Set_SecAuthMode_Proc(pAd, "WPAPSK"); + Set_SecEncrypType_Proc(pAd, "TKIP"); + pTempSsid = vmalloc(33); + + if (pTempSsid) { + memset(pTempSsid, 0, 33); + snprintf(pTempSsid, 33, "RalinkInitialAP%02X%02X%02X", + pAd->ApCfg.MBSSID[apidx].wdev.bssid[3], + pAd->ApCfg.MBSSID[apidx].wdev.bssid[4], + pAd->ApCfg.MBSSID[apidx].wdev.bssid[5]); + Set_AP_SSID_Proc(pAd, pTempSsid); + vfree(pTempSsid); + } + + Set_SecWPAPSK_Proc(pAd, "RalinkInitialAPxx1234"); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_WscOOB_Proc\n", apidx)); +} + +/* + ========================================================================== + 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 RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + + if (strcmp(arg, "0") == 0) + pAd->ApCfg.MBSSID[apidx].wdev.WscSecurityMode = WPA2PSKAES; + else if (strcmp(arg, "1") == 0) + pAd->ApCfg.MBSSID[apidx].wdev.WscSecurityMode = WPA2PSKTKIP; + else if (strcmp(arg, "2") == 0) + pAd->ApCfg.MBSSID[apidx].wdev.WscSecurityMode = WPAPSKAES; + else if (strcmp(arg, "3") == 0) + pAd->ApCfg.MBSSID[apidx].wdev.WscSecurityMode = WPAPSKTKIP; + else + return FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) Set_WscSecurityMode_Proc::(WscSecurityMode=%d)\n", + apidx, pAd->ApCfg.MBSSID[apidx].wdev.WscSecurityMode)); + return TRUE; +} + +INT Set_AP_WscMultiByteCheck_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_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].wdev.WscControl; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR version = (UCHAR)os_str_tol(arg, 0, 16); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscVersion_Proc::(version=%x)\n", version)); + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.RegData.SelfInfo.Version = version; + return TRUE; +} + +#ifdef VENDOR_FEATURE6_SUPPORT +INT Set_WscUUID_STR_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (strlen(arg) == (UUID_LEN_STR - 1)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscUUID_E_Proc[%d]::(arg=%s)\n", pObj->ioctl_if, arg)); + pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.Wsc_Uuid_Str[UUID_LEN_STR - 1] = 0; + NdisMoveMemory(&pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.Wsc_Uuid_Str[0], arg, strlen(arg)); + return TRUE; + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ERROR Set_WscUUID_E_Proc[%d]::(arg=%s), Leng(%d) is incorrect!\n", pObj->ioctl_if, arg, (int)strlen(arg))); + return FALSE; + } +} + + +INT Set_WscUUID_HEX_E_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (strlen(arg) == (UUID_LEN_HEX * 2)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscUUID_HEX_E_Proc[%d]::(arg=%s)\n", pObj->ioctl_if, arg)); + AtoH(arg, &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.Wsc_Uuid_E[0], UUID_LEN_HEX); + hex_dump("Set_WscUUID_HEX_E_Proc OK:", &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl.Wsc_Uuid_E[0], UUID_LEN_HEX); + return TRUE; + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ERROR Set_WscUUID_HEX_E_Proc[%d]::(arg=%s), Leng(%d) is incorrect!\n", pObj->ioctl_if, arg, (int)strlen(arg))); + return FALSE; + } +} +#endif /* VENDOR_FEATURE6_SUPPORT */ + +#ifdef WSC_V2_SUPPORT +INT Set_WscFragment_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR bool_flag = (UCHAR)os_str_tol(arg, 0, 16); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscFragment_Proc::(bool_flag=%d)\n", bool_flag)); + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.bWscFragment = bool_flag; + return TRUE; +} + +INT Set_WscFragmentSize_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + USHORT WscFragSize = (USHORT)os_str_tol(arg, 0, 10); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscFragmentSize_Proc::(WscFragSize=%d)\n", WscFragSize)); + + if ((WscFragSize >= 128) && (WscFragSize <= 300)) + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.WscFragSize = WscFragSize; + + return TRUE; +} + +INT Set_WscSetupLock_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR bEnable = (UCHAR)os_str_tol(arg, 0, 10); + PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl; + + if (bEnable == 0) { + BOOLEAN bCancelled = FALSE; + + pWscControl->PinAttackCount = 0; + + if (pWscControl->WscSetupLockTimerRunning) + RTMPCancelTimer(&pWscControl->WscSetupLockTimer, &bCancelled); + + WscSetupLockTimeout(NULL, pWscControl, NULL, NULL); + } else { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + + 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); + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscSetupLock_Proc::(bSetupLock=%d)\n", + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.bSetupLock)); + return TRUE; +} + +INT Set_WscV2Support_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR bEnable = (UCHAR)os_str_tol(arg, 0, 10); + PWSC_CTRL pWscControl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl; + + if (bEnable == 0) + pWscControl->WscV2Info.bEnableWpsV2 = FALSE; + else + pWscControl->WscV2Info.bEnableWpsV2 = TRUE; + + if (pWscControl->WscV2Info.bEnableWpsV2) { + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + /* + WPS V2 doesn't support Chiper WEP and TKIP. + */ + struct _SECURITY_CONFIG *pSecConfig = &wdev->SecConfig; + + if (IS_CIPHER_WEP_TKIP_ONLY(pSecConfig->PairwiseCipher) + || (pAd->ApCfg.MBSSID[pObj->ioctl_if].bHideSsid)) + WscOnOff(pAd, wdev->func_idx, TRUE); + else + WscOnOff(pAd, wdev->func_idx, FALSE); + + UpdateBeaconHandler( + pAd, + wdev, + BCN_UPDATE_IE_CHG); + } else + WscInit(pAd, FALSE, pObj->ioctl_if); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscV2Support_Proc::(bEnableWpsV2=%d)\n", + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.WscV2Info.bEnableWpsV2)); + return TRUE; +} + +INT Set_WscVersion2_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR version = (UCHAR)os_str_tol(arg, 0, 16); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscVersion2_Proc::(version=%x)\n", version)); + + if (version >= 0x20) + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.RegData.SelfInfo.Version2 = version; + else + return FALSE; + + return TRUE; +} + +INT Set_WscExtraTlvTag_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + USHORT new_tag = (USHORT)os_str_tol(arg, 0, 16); + + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.WscV2Info.ExtraTlv.TlvTag = new_tag; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscExtraTlvTag_Proc::(new_tag=0x%04X)\n", new_tag)); + return TRUE; +} + +INT Set_WscExtraTlvType_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR type = (UCHAR)os_str_tol(arg, 0, 10); + + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.WscV2Info.ExtraTlv.TlvType = type; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscExtraTlvType_Proc::(type=%d)\n", type)); + return TRUE; +} + +INT Set_WscExtraTlvData_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UINT DataLen = (UINT)strlen(arg); + PWSC_TLV pWscTLV = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.WscV2Info.ExtraTlv; + INT i; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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(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; + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Set_WscExtraTlvData_Proc::os_alloc_mem fail\n")); + return FALSE; +} + +INT Set_WscMaxPinAttack_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR MaxPinAttack = (UCHAR)os_str_tol(arg, 0, 10); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscMaxPinAttack_Proc::(MaxPinAttack=%d)\n", MaxPinAttack)); + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.MaxPinAttack = MaxPinAttack; + return TRUE; +} + + +INT Set_WscSetupLockTime_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UINT SetupLockTime = (UINT)os_str_tol(arg, 0, 10); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscSetupLockTime_Proc::(SetupLockTime=%d)\n", + SetupLockTime)); + pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl.SetupLockTime = SetupLockTime; + return TRUE; +} + +#endif /* WSC_V2_SUPPORT */ + +INT Set_WscAutoTriggerDisable_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR bEnable = (UCHAR)os_str_tol(arg, 0, 10); + PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.WscControl; + + if (bEnable == 0) + pWscCtrl->bWscAutoTriggerDisable = FALSE; + else + pWscCtrl->bWscAutoTriggerDisable = TRUE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_WscAutoTriggerDisable_Proc::(bWscAutoTriggerDisable=%d)\n", + pWscCtrl->bWscAutoTriggerDisable)); + return TRUE; +} + +#endif /* WSC_AP_SUPPORT */ + + +#ifdef IAPP_SUPPORT +INT Set_IappPID_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + unsigned long IappPid; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + IappPid = os_str_tol(arg, 0, 10); + RTMP_GET_OS_PID(pObj->IappPid, IappPid); + pObj->IappPid_nr = IappPid; + /* MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 RTMP_STRING *arg) +{ + UCHAR macAddr[MAC_ADDR_LEN]; + RTMP_STRING *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, (UCHAR *)&macAddr[i++], 1); + } + + if (NdisEqualMemory(&macAddr[0], &BROADCAST_ADDR[0], MAC_ADDR_LEN)) { + Set_DisConnectAllSta_Proc(pAd, "2"); + return TRUE; + } + + pEntry = MacTableLookup(pAd, macAddr); + + if (pEntry) { + MlmeDeAuthAction(pAd, pEntry, REASON_DISASSOC_STA_LEAVING, FALSE); + /* MacTableDeleteEntry(pAd, pEntry->wcid, Addr); */ + } + + return TRUE; +} + +#ifdef VENDOR_FEATURE7_SUPPORT +INT Set_DisConnectBssSta_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + INT i, bssId = -1; + + bssId = os_str_tol(arg, 0, 10); + if (bssId >= pAd->ApCfg.BssidNum) + return FALSE; + for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; + + if (pEntry && IS_ENTRY_CLIENT(pEntry) && pEntry->Sst == SST_ASSOC + && pEntry->func_tb_idx == bssId){ + MlmeDeAuthAction(pAd, pEntry, REASON_DEAUTH_STA_LEAVING, FALSE); + } + } + return TRUE; +} +#endif +INT Set_DisConnectAllSta_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + INT i; + MAC_TABLE_ENTRY *pEntry; + +#ifdef DOT11W_PMF_SUPPORT + CHAR value = os_str_tol(arg, 0, 10); + + if (value == 2) { + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("[PMF]%s:: apidx=%d\n", __func__, pObj->ioctl_if)); + APMlmeKickOutAllSta(pAd, pObj->ioctl_if, REASON_DEAUTH_STA_LEAVING); + + for (i = 1; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s: MacTableDeleteEntry %x:%x:%x:%x:%x:%x\n", + __func__, PRINT_MAC(pEntry->Addr))); + MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); + } + } + } else +#endif /* DOT11W_PMF_SUPPORT */ + { + UCHAR *pOutBuffer = NULL; + NDIS_STATUS NStatus; + HEADER_802_11 DeAuthHdr; + USHORT Reason; + ULONG FrameLen = 0; + + for (i = 1; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + pEntry = &pAd->MacTab.Content[i]; + if (IS_ENTRY_CLIENT(pEntry)) { + pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + /* Before reset MacTable, send disassociation packet to client.*/ + if (pEntry->Sst == SST_ASSOC) { + /* send out a De-authentication request frame*/ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_MLME, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + (" MlmeAllocateMemory fail ..\n")); + return FALSE; + } + + Reason = REASON_NO_LONGER_VALID; + MTWF_LOG(DBG_CAT_MLME, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("Send DeAuth (Reason=%d) to %02x:%02x:%02x:%02x:%02x:%02x\n", + Reason, PRINT_MAC(pEntry->Addr))); + MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->Addr, + pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.if_addr, + pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DeAuthHdr, + 2, &Reason, + END_OF_ARGS); + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + RtmpusecDelay(5000); + } + } +#endif /* CONFIG_AP_SUPPORT */ + /* Delete a entry via WCID */ + MacTableDeleteEntry(pAd, i, pEntry->Addr); + } + } + } + + 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 RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + if (os_str_tol(arg, 0, 10) != 0) /*Enable*/ + pSecConfig->IEEE8021X = TRUE; + else /*Disable*/ + pSecConfig->IEEE8021X = FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(%s%d) IEEE8021X=%d\n", + INF_MBSSID_DEV_NAME, apidx, pSecConfig->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 RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + if (os_str_tol(arg, 0, 10) != 0) /*Enable*/ + pSecConfig->PreAuth = TRUE; + else /*Disable*/ + pSecConfig->PreAuth = FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("I/F(%s%d) PreAuth=%d\n", + INF_MBSSID_DEV_NAME, apidx, pSecConfig->PreAuth)); + return TRUE; +} + +INT Set_OwnIPAddr_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + SetWdevOwnIPAddr(pSecConfig, arg); + return TRUE; +} + +INT Set_EAPIfName_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + if (strlen(arg) > 0 && strlen(arg) <= IFNAMSIZ) { + pSecConfig->EAPifname_len = strlen(arg); + NdisMoveMemory(pSecConfig->EAPifname, arg, strlen(arg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("EAPifname=%s, len=%d\n", + pSecConfig->EAPifname, pSecConfig->EAPifname_len)); + } + + return TRUE; +} + +INT Set_PreAuthIfName_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + if (strlen(arg) > 0 && strlen(arg) <= IFNAMSIZ) { + pSecConfig->PreAuthifname_len = strlen(arg); + NdisMoveMemory(pSecConfig->PreAuthifname, arg, strlen(arg)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("PreAuthifname=%s, len=%d\n", + pSecConfig->PreAuthifname, pSecConfig->PreAuthifname_len)); + } + + return TRUE; +} + +INT Set_RADIUS_Server_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + UINT32 ip_addr; + INT count; + RTMP_STRING *macptr; + INT srv_cnt = 0; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + 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 = &pSecConfig->radius_srv_info[srv_cnt]; + + pSrvInfo->radius_ip = ip_addr; + srv_cnt++; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d), radius_ip(seq-%d)=%s\n", + apidx, srv_cnt, arg)); + } + + if (srv_cnt > 0) + pSecConfig->radius_srv_num = srv_cnt; + } + + return TRUE; +} + +INT Set_RADIUS_Port_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + RTMP_STRING *macptr; + INT count; + INT srv_cnt = 0; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + for (count = 0, macptr = rstrtok(arg, ";"); (macptr && + count < MAX_RADIUS_SRV_NUM); macptr = rstrtok(NULL, ";"), count++) { + if (srv_cnt < pSecConfig->radius_srv_num) { + PRADIUS_SRV_INFO pSrvInfo = &pSecConfig->radius_srv_info[srv_cnt]; + + pSrvInfo->radius_port = (UINT32) os_str_tol(macptr, 0, 10); + srv_cnt++; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d), radius_port(seq-%d)=%d\n", + apidx, srv_cnt, pSrvInfo->radius_port)); + } + } + + return TRUE; +} + +INT Set_RADIUS_Key_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + RTMP_STRING *macptr; + INT count; + INT srv_cnt = 0; + + if (apidx >= pAd->ApCfg.BssidNum) + return FALSE; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + for (count = 0, macptr = rstrtok(arg, ";"); (macptr && + count < MAX_RADIUS_SRV_NUM); macptr = rstrtok(NULL, ";"), count++) { + if (strlen(macptr) > 0 && strlen(macptr) < 65 && srv_cnt < pSecConfig->radius_srv_num) { + PRADIUS_SRV_INFO pSrvInfo = &pSecConfig->radius_srv_info[srv_cnt]; + + pSrvInfo->radius_key_len = strlen(macptr); + NdisMoveMemory(pSrvInfo->radius_key, macptr, pSrvInfo->radius_key_len); + srv_cnt++; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d), radius_key(seq-%d)=%s, len=%d\n", + apidx, srv_cnt, pSrvInfo->radius_key, pSrvInfo->radius_key_len)); + } + } + + return TRUE; +} + + +INT Set_DeletePMKID_Proc(RTMP_ADAPTER *pAd, + RTMP_STRING *arg) /* for testing sending deauth frame if PMKID not found */ +{ + UCHAR apidx = os_str_tol(arg, 0, 10); + INT32 i = 0; + + for (i = 0; i < MAX_PMKID_COUNT; i++) + RTMPDeletePMKIDCache(&pAd->ApCfg.PMKIDCache, apidx, i); + + return TRUE; +} + + +INT Set_DumpPMKID_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UCHAR imput = os_str_tol(arg, 0, 10); + INT32 i = 0; + + if (imput == 1) { + for (i = 0; i < MAX_PMKID_COUNT; i++) { + PAP_BSSID_INFO pBssInfo = &pAd->ApCfg.PMKIDCache.BSSIDInfo[i]; + + if (pBssInfo->Valid) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cacheidx = %d, Mbssidx = %d, Mac = %02x:%02x:%02x:%02x:%02x:%02x\n", + i, pBssInfo->Mbssidx, PRINT_MAC(pBssInfo->MAC))); + } + } + } + + return TRUE; +} + +#ifdef RADIUS_MAC_ACL_SUPPORT +INT show_RADIUS_acl_cache(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + PRT_802_11_RADIUS_ACL_ENTRY pCacheEntry = NULL; + RT_LIST_ENTRY *pListEntry = NULL; + PLIST_HEADER pListHeader = NULL; + + pListHeader = &pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.cacheList; + + if (pListHeader->size != 0) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("IF(ra%d), Radius ACL Cache List:\n", apidx)); + pListEntry = pListHeader->pHead; + pCacheEntry = (PRT_802_11_RADIUS_ACL_ENTRY)pListEntry; + + while (pCacheEntry != NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02x:%02x:%02x:%02x:%02x:%02x --> %d\n", + PRINT_MAC(pCacheEntry->Addr), pCacheEntry->result)); + pListEntry = pListEntry->pNext; + pCacheEntry = (PRT_802_11_RADIUS_ACL_ENTRY)pListEntry; + } + } else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("IF(ra%d), Radius ACL Cache empty\n", apidx)); + + return TRUE; +} + +INT Set_RADIUS_CacheTimeout_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + CHAR val = os_str_tol(arg, 0, 10); + + if (val > 0) { + pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCacheTimeout = val; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("ra[%d] Radius Cache Timeout: %d\n", + apidx, val)); + return TRUE; + } + + return FALSE; +} + +INT Set_RADIUS_MacAuth_Enable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + CHAR val = os_str_tol(arg, 0, 10); + + if (val == 0) + pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.Policy = RADIUS_MAC_AUTH_DISABLE; + else if (val == 1) + pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.Policy = RADIUS_MAC_AUTH_ENABLE; + else + return FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("IF(ra%d), Radius MAC Auth: %d\n", apidx, + pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.RadiusMacAuthCache.Policy)); + return TRUE; +} +#endif /* RADIUS_MAC_ACL_SUPPORT */ +#endif /* DOT1X_SUPPORT */ + +#ifdef UAPSD_SUPPORT +INT Set_UAPSD_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR IdMbss = pObj->ioctl_if; + + if (os_str_tol(arg, 0, 10) != 0) + pAd->ApCfg.MBSSID[IdMbss].wdev.UapsdInfo.bAPSDCapable = TRUE; + else + pAd->ApCfg.MBSSID[IdMbss].wdev.UapsdInfo.bAPSDCapable = FALSE; + + return TRUE; +} /* End of Set_UAPSD_Proc */ +#endif /* UAPSD_SUPPORT */ + + + +#ifdef MCAST_RATE_SPECIFIC +INT Set_McastPhyMode( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + BSS_INFO_ARGUMENT_T bss_info_argument; + HTTRANSMIT_SETTING *pTransmit; + BOOLEAN isband5g, tmp_band; + UCHAR cfg_ht_bw; + struct wifi_dev *wdev = NULL; + INT i = 0; + BOOLEAN status = TRUE; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + UCHAR PhyMode = os_str_tol(arg, 0, 10); + + if ((pObj->ioctl_if_type != INT_MBSSID) && (pObj->ioctl_if_type != INT_MAIN)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Do nothing! This device interface is NOT AP mode!\n")); + return FALSE; + } + + if (apidx >= pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Invalid device interface!\n")); + return FALSE; + } + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + isband5g = (wdev->channel > 14) ? TRUE : FALSE; + + if (isband5g) { + if (PhyMode == MCAST_CCK) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("We could not set CCK mode for multicast frames in 5G band!\n")); + return FALSE; + } + + pTransmit = &pAd->CommonCfg.MCastPhyMode_5G; + } else { +#ifdef DOT11_VHT_AC + + if (PhyMode == MCAST_VHT) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("We could not set VHT mode for multicast frames in 2.4G band!\n")); + return FALSE; + } + +#endif /* DOT11_VHT_AC */ + pTransmit = &pAd->CommonCfg.MCastPhyMode; + } + + cfg_ht_bw = wlan_config_get_ht_bw(wdev); + pTransmit->field.BW = cfg_ht_bw; + + switch (PhyMode) { + case MCAST_DISABLE: /* disable */ + NdisMoveMemory(pTransmit, &wdev->rate.MlmeTransmit, sizeof(HTTRANSMIT_SETTING)); + pTransmit->field.BW = BW_20; + /* NdisMoveMemory(&pAd->CommonCfg.MCastPhyMode, &pAd->MacTab.Content[MCAST_WCID].HTPhyMode, sizeof(HTTRANSMIT_SETTING)); */ + break; + + case MCAST_CCK: /* CCK */ + pTransmit->field.MODE = MODE_CCK; + pTransmit->field.BW = BW_20; + + if ((pTransmit->field.MCS > 11) || (pTransmit->field.MCS > 3 && pTransmit->field.MCS < 8)) + pTransmit->field.MCS = 3; + + break; + + case MCAST_OFDM: /* OFDM */ + pTransmit->field.MODE = MODE_OFDM; + pTransmit->field.BW = BW_20; + + if (pTransmit->field.MCS > 7) + pTransmit->field.MCS = 7; + + break; +#ifdef DOT11_N_SUPPORT + + case MCAST_HTMIX: /* HTMIX */ + pTransmit->field.MODE = MODE_HTMIX; + + if ((isband5g) && (wlan_operate_get_bw(wdev) > BW_20)) + pTransmit->field.BW = BW_40; + else + pTransmit->field.BW = BW_20; + + break; +#endif /* DOT11_N_SUPPORT */ +#ifdef DOT11_VHT_AC + + case MCAST_VHT: /* VHT */ + pTransmit->field.MODE = MODE_VHT; + pTransmit->field.BW = wlan_operate_get_bw(wdev); + break; +#endif /* DOT11_VHT_AC */ + + default: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("unknown Muticast PhyMode %d.\n", PhyMode)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("0:Disable, 1:CCK, 2:OFDM, 3:HTMIX, 4:VHT.\n")); + status = FALSE; + break; + } + + if (!status) + return FALSE; + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + wdev = &pAd->ApCfg.MBSSID[i].wdev; + tmp_band = (wdev->channel > 14) ? TRUE : FALSE; + + if (tmp_band != isband5g) + continue; + + NdisZeroMemory(&bss_info_argument, sizeof(BSS_INFO_ARGUMENT_T)); + bss_info_argument.bss_state = BSS_ACTIVE; + bss_info_argument.ucBssIndex = wdev->bss_info_argument.ucBssIndex; + bss_info_argument.u4BssInfoFeature = BSS_INFO_BROADCAST_INFO_FEATURE; + memmove(&bss_info_argument.BcTransmit, pTransmit, sizeof(HTTRANSMIT_SETTING)); + memmove(&bss_info_argument.McTransmit, pTransmit, sizeof(HTTRANSMIT_SETTING)); + + if (AsicBssInfoUpdate(pAd, bss_info_argument) != NDIS_STATUS_SUCCESS) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Fail to apply the bssinfo, BSSID=%d!\n", i)); + } + + return TRUE; +} + + +INT Set_McastMcs( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + BSS_INFO_ARGUMENT_T bss_info_argument; + BOOLEAN isband5g, tmp_band; + HTTRANSMIT_SETTING *pTransmit; + struct wifi_dev *wdev = NULL; + INT i = 0; + BOOLEAN status = TRUE; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + UCHAR Mcs = os_str_tol(arg, 0, 10); + + if ((pObj->ioctl_if_type != INT_MBSSID) && (pObj->ioctl_if_type != INT_MAIN)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Do nothing! This device interface is NOT AP mode!\n")); + return FALSE; + } + + if (apidx >= pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Invalid device interface!\n")); + return FALSE; + } + + if (Mcs > 15) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Mcs must be in range of 0 to 15\n")); + return FALSE; + } + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + isband5g = (wdev->channel > 14) ? TRUE : FALSE; + pTransmit = (isband5g) ? (&pAd->CommonCfg.MCastPhyMode_5G) : (&pAd->CommonCfg.MCastPhyMode); + + switch (pTransmit->field.MODE) { + case MODE_CCK: + if ((Mcs <= 3) || (Mcs >= 8 && Mcs <= 11)) + pTransmit->field.MCS = Mcs; + else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MCS must in range of 0 ~ 3 and 8 ~ 11 for CCK Mode.\n")); + status = FALSE; + } + + break; + + case MODE_OFDM: + if (Mcs > 7) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MCS must in range from 0 to 7 for OFDM Mode.\n")); + status = FALSE; + } else + pTransmit->field.MCS = Mcs; + + break; + + default: + pTransmit->field.MCS = Mcs; + break; + } + + if (!status) + return FALSE; + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + wdev = &pAd->ApCfg.MBSSID[i].wdev; + tmp_band = (wdev->channel > 14) ? TRUE : FALSE; + + if (tmp_band != isband5g) + continue; + + NdisZeroMemory(&bss_info_argument, sizeof(BSS_INFO_ARGUMENT_T)); + bss_info_argument.bss_state = BSS_ACTIVE; + bss_info_argument.ucBssIndex = wdev->bss_info_argument.ucBssIndex; + bss_info_argument.u4BssInfoFeature = BSS_INFO_BROADCAST_INFO_FEATURE; + memmove(&bss_info_argument.BcTransmit, pTransmit, sizeof(HTTRANSMIT_SETTING)); + memmove(&bss_info_argument.McTransmit, pTransmit, sizeof(HTTRANSMIT_SETTING)); + + if (AsicBssInfoUpdate(pAd, bss_info_argument) != NDIS_STATUS_SUCCESS) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Fail to apply the bssinfo, BSSID=%d!\n", i)); + } + + return TRUE; +} + +INT Show_McastRate( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + HTTRANSMIT_SETTING *pTransmit; + struct wifi_dev *wdev = NULL; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + + if ((pObj->ioctl_if_type != INT_MBSSID) && (pObj->ioctl_if_type != INT_MAIN)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Do nothing! This device interface is NOT AP mode!\n")); + return FALSE; + } + + if (apidx >= pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Invalid device interface!\n")); + return FALSE; + } + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pTransmit = (wdev->channel > 14) ? (&pAd->CommonCfg.MCastPhyMode_5G) : (&pAd->CommonCfg.MCastPhyMode); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Mcast PhyMode = %d\n", pTransmit->field.MODE)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Mcast Mcs = %d\n", pTransmit->field.MCS)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Mcast BW = %d\n", pTransmit->field.BW)); + return TRUE; +} +#endif /* MCAST_RATE_SPECIFIC */ + +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 +INT Set_OBSSScanParam_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT ObssScanValue; + UINT Idx; + RTMP_STRING *thisChar; + + Idx = 0; + + while ((thisChar = strsep((char **)&arg, "-")) != NULL) { + ObssScanValue = (INT) os_str_tol(thisChar, 0, 10); + + switch (Idx) { + case 0: + if (ObssScanValue < 5 || ObssScanValue > 1000) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Invalid OBSSScanParam for Dot11OBssScanPassiveDwell(%d), should in range 5~1000\n", ObssScanValue)); + else { + pAd->CommonCfg.Dot11OBssScanPassiveDwell = ObssScanValue; /* Unit : TU. 5~1000 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11OBssScanPassiveDwell=%d\n", + ObssScanValue)); + } + + break; + + case 1: + if (ObssScanValue < 10 || ObssScanValue > 1000) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Invalid OBSSScanParam for Dot11OBssScanActiveDwell(%d), should in range 10~1000\n", ObssScanValue)); + else { + pAd->CommonCfg.Dot11OBssScanActiveDwell = ObssScanValue; /* Unit : TU. 10~1000 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11OBssScanActiveDwell=%d\n", + ObssScanValue)); + } + + break; + + case 2: + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = ObssScanValue; /* Unit : Second */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11BssWidthTriggerScanInt=%d\n", + ObssScanValue)); + break; + + case 3: + if (ObssScanValue < 200 || ObssScanValue > 10000) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Invalid OBSSScanParam for Dot11OBssScanPassiveTotalPerChannel(%d), should in range 200~10000\n", ObssScanValue)); + else { + pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = ObssScanValue; /* Unit : TU. 200~10000 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11OBssScanPassiveTotalPerChannel=%d\n", + ObssScanValue)); + } + + break; + + case 4: + if (ObssScanValue < 20 || ObssScanValue > 10000) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Invalid OBSSScanParam for Dot11OBssScanActiveTotalPerChannel(%d), should in range 20~10000\n", ObssScanValue)); + else { + pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = ObssScanValue; /* Unit : TU. 20~10000 */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11OBssScanActiveTotalPerChannel=%d\n", + ObssScanValue)); + } + + break; + + case 5: + pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = ObssScanValue; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelayFactor=%d\n", + ObssScanValue)); + break; + + case 6: + pAd->CommonCfg.Dot11OBssScanActivityThre = ObssScanValue; /* Unit : percentage */ + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelayFactor=%d\n", + ObssScanValue)); + break; + } + + Idx++; + } + + if (Idx != 7) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelay=%ld\n", + pAd->CommonCfg.Dot11BssWidthChanTranDelay)); + return TRUE; +} + +INT Set_AP2040ReScan_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev; + + wdev = &pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev; + APOverlappingBSSScan(pAd, wdev); + /* apply setting */ + SetCommonHtVht(pAd, wdev); + wlan_operate_set_prim_ch(wdev, wdev->channel); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set_AP2040ReScan_Proc() Trigger AP ReScan !!!\n")); + return TRUE; +} +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + +INT Set_EntryLifeCheck_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + ULONG LifeCheckCnt = (ULONG) os_str_tol(arg, 0, 10); + + if (LifeCheckCnt <= 65535) + pAd->ApCfg.EntryLifeCheck = LifeCheckCnt; + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("LifeCheckCnt must in range of 0 to 65535\n")); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("EntryLifeCheck Cnt = %ld.\n", pAd->ApCfg.EntryLifeCheck)); + return TRUE; +} + +INT ApCfg_Set_PerMbssMaxStaNum_Proc( + IN PRTMP_ADAPTER pAd, + IN INT apidx, + IN RTMP_STRING *arg) +{ + pAd->ApCfg.MBSSID[apidx].MaxStaNum = (UCHAR)os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IF(ra%d) %s::(MaxStaNum=%d)\n", + apidx, __func__, pAd->ApCfg.MBSSID[apidx].MaxStaNum)); + return TRUE; +} + +INT ApCfg_Set_IdleTimeout_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + LONG idle_time; + + idle_time = os_str_tol(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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s : IdleTimeout=%d\n", __func__, pAd->ApCfg.StaIdleTimeout)); + return TRUE; +} + +#ifdef RTMP_RBUS_SUPPORT +#ifdef LED_CONTROL_SUPPORT +INT Set_WlanLed_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + BOOLEAN bWlanLed; +#if defined(RTMP_PCI_SUPPORT) && defined(RTMP_RBUS_SUPPORT) + + if (!IS_RBUS_INF(pAd)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s : Support RBUS interface only\n", __func__)); + return TRUE; + } + +#endif /* defined(RTMP_PCI_SUPPORT) && defined(RTMP_RBUS_SUPPORT) */ + bWlanLed = (BOOLEAN) os_str_tol(arg, 0, 10); + { + if (bWlanLed) + RTMPStartLEDMode(pAd); + else + RTMPExitLEDMode(pAd); + }; + return TRUE; +} +#endif /* LED_CONTROL_SUPPORT */ +#endif /* RTMP_RBUS_SUPPORT */ + +INT Set_MemDebug_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef VENDOR_FEATURE2_SUPPORT + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Number of Packet Allocated = %lu\n", OS_NumOfPktAlloc)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Number of Packet Freed = %lu\n", OS_NumOfPktFree)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Offset of Packet Allocated/Freed = %lu\n", + OS_NumOfPktAlloc - OS_NumOfPktFree)); +#endif /* VENDOR_FEATURE2_SUPPORT */ + return TRUE; +} + + +#ifdef APCLI_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(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + pAd->MacTab.MsduLifeTime = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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: +======================================================================== +*/ +extern UCHAR *wmode_2_str(UCHAR wmode); + + +INT Show_MbssInfo_Display_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 IdBss; + UCHAR PhyMode; + CHAR *mod_str = NULL; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n\tBSS Idx\t\tPhy Mode\n")); + + for (IdBss = 0; IdBss < pAd->ApCfg.BssidNum; IdBss++) { + PhyMode = pAd->ApCfg.MBSSID[IdBss].wdev.PhyMode; + mod_str = wmode_2_str(PhyMode); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\t%d\t\t%s\n", IdBss, mod_str)); + + if (mod_str) + os_free_mem(mod_str); + } + + 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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ioctl SIOCSIWGENIE pAd->IoctlIF=%d\n", apidx)); + RSNIe[0] = *(UINT8 *)wrqin->u.data.pointer; + + if (IE_WPA != RSNIe[0] && IE_RSN != RSNIe[0]) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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 + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_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]); + UpdateBeaconHandler( + pAd, + &pAd->ApCfg.MBSSID[apidx].wdev, + BCN_UPDATE_IF_STATE_CHG); + } +} +#endif /* HOSTAPD_SUPPORT */ + +#ifdef MT_MAC +/* Only for TimReq frame generating */ +/* TODO: Tim service establish. */ +/* used to mapping, tttt hwidx and related CR */ +static TTTT_CR_BSSID_IDX_MAP_T g_arTtttCrHwBssidMapTable[] = { + {HW_BSSID_0, LPON_TT0TPCR, LPON_TT4TPCR}, + {HW_BSSID_1, LPON_TT1TPCR, LPON_TT5TPCR}, + {HW_BSSID_2, LPON_TT2TPCR, LPON_TT6TPCR}, + {HW_BSSID_3, LPON_TT2TPCR, LPON_TT7TPCR}, +}; + +INT Set_AP_TimEnable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 interval = 0; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR APIndex = pObj->ioctl_if; + BSS_STRUCT *pMbss = NULL; + UINT32 Value = 0; + struct wifi_dev *wdev = NULL; + UINT8 OmacIdx = 0; + UINT8 BssidIdxMapped = 0; + PTTTT_CR_BSSID_IDX_MAP_T pTtttCrMapTable = NULL; + UINT32 u4TtttEnCr = 0, u4TtttIntervelCr = 0; + BOOLEAN fgEnable = FALSE; + + interval = os_str_tol(arg, 0, 10); + + if ((interval < 0) || (interval > 255)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: interval is incorrect!!\n", __func__)); + return FALSE; + } + + pMbss = &pAd->ApCfg.MBSSID[APIndex]; + wdev = &pMbss->wdev; + + if (wdev != NULL) { + OmacIdx = wdev->OmacIdx; + if (wdev_tim_buf_init(pAd, &wdev->bcn_buf.tim_buf) == FALSE) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: tim packet init failed!\n", __func__)); + return FALSE; + } + + /* ext mbss tttt, depends on MBSS_0 */ + if (OmacIdx >= HW_BSSID_MAX) + BssidIdxMapped = HW_BSSID_0; + else + BssidIdxMapped = OmacIdx; + + MTWF_LOG(DBG_CAT_CFG, + DBG_SUBCAT_ALL, + DBG_LVL_ERROR, + ("%s: BssidIdxMapped = %d, OmacIdx = %x\n", + __func__, + BssidIdxMapped, + OmacIdx)); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: idx = %d, no wdev!?\n", __func__, APIndex)); + return FALSE; + } + + pTtttCrMapTable = &g_arTtttCrHwBssidMapTable[BssidIdxMapped]; + u4TtttEnCr = pTtttCrMapTable->u4TTTTEnableCr; + u4TtttIntervelCr = pTtttCrMapTable->u4TTTTIntervalCr; + + if (interval > 0) { /* valid interval --> enable */ + fgEnable = TRUE; + MAC_IO_WRITE32(pAd, LPON_PTTISR, IDX_DEFAULT_PRETTTT_INTERVAL(BssidIdxMapped)); + MAC_IO_READ32(pAd, u4TtttEnCr, &Value); + Value &= ~TTTTn_OFFSET_OF_TBTTn_MASK; + Value |= DEFAULT_TTTT_OFFSET_IN_MS; + Value |= TTTTn_CAL_EN; + MAC_IO_WRITE32(pAd, u4TtttEnCr, Value); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("u4TtttEnCr = %x, Value = %x\n", u4TtttEnCr, Value)); + MAC_IO_WRITE32(pAd, u4TtttIntervelCr, SET_TTTT_PERIOD(pAd, interval)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("u4TtttIntervelCr = %x, Value = %x\n", u4TtttIntervelCr, + SET_TTTT_PERIOD(pAd, interval))); + MAC_IO_READ32(pAd, LPON_MPTCR4, &Value); + Value |= TTTT0_PERIODTIMER_EN | + TTTT0_TIMEUP_EN | + PRETTTT0TIMEUP_EN | + PRETTTT0_TRIG_EN | + PRETTTT0INT_EN; + MAC_IO_WRITE32(pAd, LPON_MPTCR4, Value); + MAC_IO_READ32(pAd, AGG_ARCR, &Value); + Value = Value | DUAL_BTIM_EN; + MAC_IO_WRITE32(pAd, AGG_ARCR, Value); + Value = 0 | AGG_BTIMRR_TX_MODE(Legacy_CCK) | AGG_BTIMRR_TX_RATE(LONG_PREAMBLE_1M); + MAC_IO_WRITE32(pAd, AGG_BTIMRR0, Value); + /*TODO: other omac idx rate setting.*/ + MAC_IO_READ32(pAd, ARB_BTIMCR0, &Value); + Value |= (1 << OmacIdx); + MAC_IO_WRITE32(pAd, ARB_BTIMCR0, Value);/* enable BTIM_EN bit in ARB_BTIMCR0 */ + MAC_IO_WRITE32(pAd, ARB_BTIMCR1, Value);/* enable 2 TIM broadcast */ +#ifndef BCN_OFFLOAD_SUPPORT + MAC_IO_WRITE32(pAd, HWIER4, 0x80008000);/* enable TTTT0/PRETTTT0 interrupt. */ +#endif + } else { /* interval 0 --> disable */ + MAC_IO_READ32(pAd, ARB_BTIMCR0, &Value); + Value &= ~(1 << OmacIdx); + MAC_IO_WRITE32(pAd, ARB_BTIMCR0, Value); + MAC_IO_WRITE32(pAd, ARB_BTIMCR1, Value); + } + + AsicSetExtTTTTHwCRSetting(pAd, APIndex, fgEnable); + return TRUE; +} + +INT +Show_TmrCalResult_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg +) +{ + if (pAd->pTmrCtrlStruct) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): TmrCalResult=0x%X\n", __func__, pAd->pTmrCtrlStruct->TmrCalResult)); + else + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): (X) pTmrCtrlStruct is NULL\n", __func__)); + + return TRUE; +} + +#ifdef DBG +INT set_tim_update_proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UpdateBeaconHandler(pAd, NULL, BCN_UPDATE_TIM); + return TRUE; +} + +INT Set_AP_DumpTime_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + int apidx = 0, i = 0; + BSS_STRUCT *pMbss; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n\t%-10s\t%-10s\n", "PreTBTTTime", "TBTTTime")); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%-10lu\t%-10lu\n", pAd->HandlePreInterruptTime, + pAd->HandleInterruptTime)); + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + pMbss = &pAd->ApCfg.MBSSID[apidx]; + + if (!BeaconTransmitRequired(pAd, &pMbss->wdev, TRUE)) + continue; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\n%s:%d\tBcn_State:%d\t%-10s: %d\n", "Apidx", apidx, + pMbss->wdev.bcn_buf.bcn_state, "recover", pMbss->bcn_recovery_num)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\t%-10s\t%-10s\t%-10s\t%-10s\n", "WriteBcnRing", "BcnDmaDone", + "TXS_TSF", "TXS_SN")); + + for (i = 0; i < MAX_TIME_RECORD; i++) + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Idx[%d]:\t%-10lu\t%-10lu\t%-10lu\t%-10lu\n", i, + pMbss->WriteBcnDoneTime[i], pMbss->BcnDmaDoneTime[i], pMbss->TXS_TSF[i], pMbss->TXS_SN[i])); + } + + return TRUE; +} + +INT Set_BcnStateCtrl_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UCHAR bcn_state; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR apIndex = pObj->ioctl_if; + BSS_STRUCT *pMbss = NULL; + struct _PCI_HIF_T *hif = hc_get_hif_ctrl(pAd->hdev_ctrl); + + bcn_state = os_str_tol(arg, 0, 10); + + if (!IS_HIF_TYPE(pAd, HIF_MT)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: chipcap is not HIF_MT\n", __func__)); + return FALSE; + } + + if ((bcn_state < BCN_TX_IDLE) || (bcn_state > BCN_TX_DMA_DONE)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: bcn_state is incorrect!!\n", __func__)); + return FALSE; + } + + pMbss = &pAd->ApCfg.MBSSID[apIndex]; + ASSERT(pMbss); + + if (pMbss == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: pMbss == NULL!!\n", __func__)); + return FALSE; + } + + if (pMbss->wdev.bcn_buf.bcn_state != BCN_TX_IDLE) { + RTMP_SEM_LOCK(&hif->BcnRingLock); + pMbss->wdev.bcn_buf.bcn_state = bcn_state; + RTMP_SEM_UNLOCK(&hif->BcnRingLock); + } + + return TRUE; +} +#endif + +INT setApTmrEnableProc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + LONG enable; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR apIndex = pObj->ioctl_if; + BSS_STRUCT *pMbss = NULL; + UINT32 value = 0; + struct wifi_dev *wdev; + UCHAR bw; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + enable = os_str_tol(arg, 0, 10); + + if (!IS_HIF_TYPE(pAd, HIF_MT)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: chip_cap is not HIF_MT\n", __func__)); + return FALSE; + } + + if ((enable < 0) || (enable > 2)) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: enable is incorrect!!\n", __func__)); + return FALSE; + } + + pMbss = &pAd->ApCfg.MBSSID[apIndex]; + ASSERT(pMbss); + + if (pMbss == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: pMbss == NULL!!\n", __func__)); + return FALSE; + } + + wdev = &pMbss->wdev; + bw = wlan_operate_get_bw(wdev); + + switch (enable) { + case TMR_INITIATOR: { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: enable TMR report, as Initialiter\n", __func__)); + RTMP_IO_READ32(pAd, RMAC_TMR_PA, &value); + value = value | BIT31; + value = value & ~BIT30; + RTMP_IO_WRITE32(pAd, RMAC_TMR_PA, value); + cap->TmrEnable = 1; + MtCmdTmrCal(pAd, + enable, + (pMbss->wdev.channel > 14 ? _A_BAND : _G_BAND), + bw, + 0,/* Ant 0 at present */ + TMR_INITIATOR); + } + break; + + case TMR_RESPONDER: { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: enable TMR report, as Responser\n", __func__)); + RTMP_IO_READ32(pAd, RMAC_TMR_PA, &value); + value = value | BIT31; + value = value | BIT30; + value = value | 0x34;/* Action frame register */ + RTMP_IO_WRITE32(pAd, RMAC_TMR_PA, value); + cap->TmrEnable = 2; + MtCmdTmrCal(pAd, + enable, + (pMbss->wdev.channel > 14 ? _A_BAND : _G_BAND), + bw, + 0,/* Ant 0 at present */ + TMR_RESPONDER); + } + break; + + case TMR_DISABLE: + default: { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: disable TMR report\n", __func__)); + RTMP_IO_READ32(pAd, RMAC_TMR_PA, &value); + value = value & ~BIT31; + RTMP_IO_WRITE32(pAd, RMAC_TMR_PA, value); + cap->TmrEnable = FALSE; + MtCmdTmrCal(pAd, + enable, + (pMbss->wdev.channel > 14 ? _A_BAND : _G_BAND), + bw, + 0,/* Ant 0 at present */ + TMR_DISABLE); + } + } + + return TRUE; +} + + +#ifdef CUT_THROUGH +INT Set_CutThrough_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT mode; + + mode = os_str_tol(arg, 0, 10); + cut_through_set_mode(pAd->PktTokenCb, mode); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s():Set CutThroughType as %d\n", + __func__, cut_through_get_mode(pAd->PktTokenCb))); + return TRUE; +} +#endif /* CUT_THROUGH */ +#endif /* MT_MAC */ + + +/* +======================================================================== +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; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Query::Get phy mode (%02X)\n", + pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev.PhyMode)); + modetmp = (UINT) pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev.PhyMode; + wrq->u.data.length = 1; + + /**(ULONG *)pData = (ULONG)pAd->ApCfg.MBSS[MAIN_MBSSID].wdev.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; + + case CMD_MTPRIV_IOCTL_RD: + RTMPIoctlRvRDebug(pAd, wrq); + break; + + case CMD_RTPRIV_IOCTL_RX_STATISTICS: + Status = RTMPIoctlRXStatistics(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: + RTMPIoctlMAC(pAd, wrq); + break; +#ifdef RTMP_RF_RW_SUPPORT + + case CMD_RTPRIV_IOCTL_RF: + RTMPAPIoctlRF(pAd, wrq); + break; +#endif /* RTMP_RF_RW_SUPPORT */ +#endif /* DBG */ + + case CMD_RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT: + RTMPIoctlGetMacTableStaInfo(pAd, wrq); + break; + + case CMD_RTPRIV_IOCTL_AP_SIOCGIFHWADDR: + if (pObj->ioctl_if < MAX_MBSSID_NUM(pAd)) + NdisCopyMemory((RTMP_STRING *) wrq->u.name, (RTMP_STRING *) pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.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: + /* Carter, TODO. check this oid. */ + UpdateBeaconHandler( + pAd, + NULL, + BCN_UPDATE_PRETBTT); + break; + + case CMD_RTPRIV_IOCTL_MBSS_INIT: + MTWF_LOG(DBG_CAT_INIT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s -> CMD_RTPRIV_IOCTL_MBSS_INIT\n", __func__)); + MBSS_Init(pAd, pData); + break; + + case CMD_RTPRIV_IOCTL_MBSS_REMOVE: + MTWF_LOG(DBG_CAT_INIT, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s -> CMD_RTPRIV_IOCTL_MBSS_REMOVE\n", __func__)); + MBSS_Remove(pAd); + break; +#ifdef MT_MAC + + case CMD_RTPRIV_IOCTL_MBSS_CR_ENABLE: + if (ext_mbss_hw_cr_enable(pData) != 0) + return NDIS_STATUS_FAILURE; + + break; + + case CMD_RTPRIV_IOCTL_MBSS_CR_DISABLE: + if (ext_mbss_hw_cr_disable(pData) != 0) + return NDIS_STATUS_FAILURE; + + break; +#endif /* MT_MAC */ +#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; + WSC_CTRL *wsc_ctrl; + + wsc_ctrl = &pApCliEntry->wdev.WscControl; + WscGenerateUUID(pAd, &wsc_ctrl->Wsc_Uuid_E[0], + &wsc_ctrl->Wsc_Uuid_Str[0], 0, FALSE, TRUE); + wsc_ctrl->bWscFragment = FALSE; + wsc_ctrl->WscFragSize = 128; + wsc_ctrl->WscRxBufLen = 0; + wsc_ctrl->pWscRxBuf = NULL; + os_alloc_mem(pAd, &wsc_ctrl->pWscRxBuf, MAX_MGMT_PKT_LEN); + + if (wsc_ctrl->pWscRxBuf) + NdisZeroMemory(wsc_ctrl->pWscRxBuf, MAX_MGMT_PKT_LEN); + + wsc_ctrl->WscTxBufLen = 0; + wsc_ctrl->pWscTxBuf = NULL; + os_alloc_mem(pAd, &wsc_ctrl->pWscTxBuf, MAX_MGMT_PKT_LEN); + + if (wsc_ctrl->pWscTxBuf) + NdisZeroMemory(wsc_ctrl->pWscTxBuf, MAX_MGMT_PKT_LEN); + + initList(&wsc_ctrl->WscPeerList); + NdisAllocateSpinLock(pAd, &wsc_ctrl->WscPeerListSemLock); + wsc_ctrl->PinAttackCount = 0; + wsc_ctrl->bSetupLock = FALSE; +#ifdef WSC_V2_SUPPORT + pWscV2Info = &wsc_ctrl->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_REMOVE: + ApCli_Remove(pAd); + break; +#endif /* APCLI_SUPPORT */ + + 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].wdev.bssid[0]; + } + + if (pBssidStr != NULL) { + memcpy(pBssidDest, pBssidStr, ETH_ALEN); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IOCTL::SIOCGIWAP(=%02x:%02x:%02x:%02x:%02x:%02x)\n", + PRINT_MAC(pBssidStr))); + } 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].wdev.HTPhyMode; + else +#endif /* APCLI_SUPPORT */ +#ifdef WDS_SUPPORT + if (pRate->priv_flags == INT_WDS) + HtPhyMode = pAd->WdsTab.WdsEntry[pObj->ioctl_if].wdev.HTPhyMode; + else +#endif /* WDS_SUPPORT */ + { + HtPhyMode = pAd->ApCfg.MBSSID[pObj->ioctl_if].wdev.HTPhyMode; + } + + RtmpDrvMaxRateGet(pAd, HtPhyMode.field.MODE, HtPhyMode.field.ShortGI, + HtPhyMode.field.BW, HtPhyMode.field.MCS, + pAd->Antenna.field.TxPath, + (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; +} + + +#ifdef DYNAMIC_VGA_SUPPORT +INT Set_DyncVgaEnable_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UINT Enable; + + Enable = os_str_tol(arg, 0, 10); + pAd->CommonCfg.lna_vga_ctl.bDyncVgaEnable = (Enable > 0) ? TRUE : FALSE; + + if (pAd->CommonCfg.lna_vga_ctl.bDyncVgaEnable == TRUE) + dynamic_vga_enable(pAd); + else + dynamic_vga_disable(pAd); + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Set_DyncVgaEnable_Proc::(enable = %d)\n", + pAd->CommonCfg.lna_vga_ctl.bDyncVgaEnable)); + return TRUE; +} + + +INT set_false_cca_hi_th(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 val = os_str_tol(arg, 0, 10); + + pAd->CommonCfg.lna_vga_ctl.nFalseCCATh = (val <= 0) ? 800 : val; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s::(false cca high threshould = %d)\n", + __func__, pAd->CommonCfg.lna_vga_ctl.nFalseCCATh)); + return TRUE; +} + + +INT set_false_cca_low_th(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 val = os_str_tol(arg, 0, 10); + + pAd->CommonCfg.lna_vga_ctl.nLowFalseCCATh = (val <= 0) ? 10 : val; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s::(false cca low threshould = %d)\n", + __func__, pAd->CommonCfg.lna_vga_ctl.nLowFalseCCATh)); + return TRUE; +} +#endif /* DYNAMIC_VGA_SUPPORT */ + +#ifdef CONFIG_HOTSPOT +static INT Set_AP_HS_IE( + IN PRTMP_ADAPTER pAd, + IN UINT8 EID, + IN RTMP_STRING *IE, + IN UINT32 IELen) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[apidx].HotSpotCtrl; + PGAS_CTRL pGasCtrl = &pAd->ApCfg.MBSSID[apidx].GASCtrl; + + switch (EID) { + case IE_INTERWORKING: + os_alloc_mem(NULL, &pGasCtrl->InterWorkingIE, IELen); + NdisMoveMemory(pGasCtrl->InterWorkingIE, IE, IELen); + pGasCtrl->InterWorkingIELen = IELen; + pHSCtrl->AccessNetWorkType = (*(IE + 2)) & 0x0F; + + if (IELen > 3) { + pHSCtrl->IsHessid = TRUE; + + if (IELen == 7) + NdisMoveMemory(pHSCtrl->Hessid, IE + 3, MAC_ADDR_LEN); + else + NdisMoveMemory(pHSCtrl->Hessid, IE + 5, MAC_ADDR_LEN); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set Interworking IE\n")); + break; + + case IE_ADVERTISEMENT_PROTO: + os_alloc_mem(NULL, &pGasCtrl->AdvertisementProtoIE, IELen); + NdisMoveMemory(pGasCtrl->AdvertisementProtoIE, IE, IELen); + pGasCtrl->AdvertisementProtoIELen = IELen; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set Advertisement Protocol IE\n")); + break; + + case IE_QOS_MAP_SET: { + int tmp = 0; + char *pos = (char *)(IE + 2); + + os_alloc_mem(NULL, &pHSCtrl->QosMapSetIE, IELen); + NdisMoveMemory(pHSCtrl->QosMapSetIE, IE, IELen); + pHSCtrl->QosMapSetIELen = IELen; + + for (tmp = 0; tmp < (IELen - 16 - 2) / 2; tmp++) { + pHSCtrl->DscpException[tmp] = *pos & 0xff; + pHSCtrl->DscpException[tmp] |= (*(pos + 1) & 0xff) << 8; + pos += 2; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("DscpException[%d]:0x%x\n", tmp, pHSCtrl->DscpException[tmp])); + } + + for (tmp = 0; tmp < 8; tmp++) { + pHSCtrl->DscpRange[tmp] = *pos & 0xff; + pHSCtrl->DscpRange[tmp] |= (*(pos + 1) & 0xff) << 8; + pos += 2; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("DscpRange[%d]:0x%x\n", tmp, pHSCtrl->DscpRange[tmp])); + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("=========================================== Set Qos MAP Set IE\n")); + break; + } + + case IE_ROAMING_CONSORTIUM: + os_alloc_mem(NULL, &pHSCtrl->RoamingConsortiumIE, IELen); + NdisMoveMemory(pHSCtrl->RoamingConsortiumIE, IE, IELen); + pHSCtrl->RoamingConsortiumIELen = IELen; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set Roaming Consortium IE\n")); + break; + + default: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown IE(EID = %d)\n", __func__, EID)); + break; + } + + return TRUE; +} +#endif + +static INT Set_AP_VENDOR_SPECIFIC_IE( + IN PRTMP_ADAPTER pAd, + IN UINT8 OUIType, + IN RTMP_STRING *IE, + IN UINT32 IELen) +{ +#ifdef CONFIG_HOTSPOT + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[apidx].HotSpotCtrl; +#endif + + switch (OUIType) { +#ifdef CONFIG_HOTSPOT + + case OUI_P2P: + os_alloc_mem(NULL, &pHSCtrl->P2PIE, IELen); + NdisMoveMemory(pHSCtrl->P2PIE, IE, IELen); + pHSCtrl->P2PIELen = IELen; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set P2P IE\n")); + break; + + case OUI_HS2_INDICATION: + os_alloc_mem(NULL, &pHSCtrl->HSIndicationIE, IELen); + NdisMoveMemory(pHSCtrl->HSIndicationIE, IE, IELen); + pHSCtrl->HSIndicationIELen = IELen; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set HS2.0 Indication IE\n")); + break; +#endif + + default: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown OUIType = %d\n", __func__, OUIType)); + break; + } + + return TRUE; +} + +#ifdef CONFIG_DOT11V_WNM +static INT Set_AP_WNM_IE( + IN PRTMP_ADAPTER pAd, + IN UINT8 EID, + IN RTMP_STRING *IE, + IN UINT32 IELen) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[apidx].WNMCtrl; + + switch (EID) { + case IE_TIME_ADVERTISEMENT: + os_alloc_mem(NULL, &pWNMCtrl->TimeadvertisementIE, IELen); + NdisMoveMemory(pWNMCtrl->TimeadvertisementIE, IE, IELen); + pWNMCtrl->TimeadvertisementIELen = IELen; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set Time Advertisement IE\n")); + break; + + case IE_TIME_ZONE: + os_alloc_mem(NULL, &pWNMCtrl->TimezoneIE, IELen); + NdisMoveMemory(pWNMCtrl->TimezoneIE, IE, IELen); + pWNMCtrl->TimezoneIELen = IELen; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Set Time Zone IE\n")); + break; + + default: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown IE(EID = %d)\n", __func__, EID)); + break; + } + + return TRUE; +} +#endif + +INT Set_AP_IE( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *IE, + IN UINT32 IELen) +{ + UINT8 EID; + UINT8 OUIType; + + EID = *IE; + + switch (EID) { +#ifdef CONFIG_HOTSPOT + + case IE_INTERWORKING: + case IE_ADVERTISEMENT_PROTO: + case IE_QOS_MAP_SET: + case IE_ROAMING_CONSORTIUM: + Set_AP_HS_IE(pAd, EID, IE, IELen); + break; +#endif +#ifdef CONFIG_DOT11V_WNM + + case IE_TIME_ADVERTISEMENT: + case IE_TIME_ZONE: + Set_AP_WNM_IE(pAd, EID, IE, IELen); + break; +#endif + + case IE_VENDOR_SPECIFIC: + OUIType = *(IE + 5); + Set_AP_VENDOR_SPECIFIC_IE(pAd, OUIType, IE, IELen); + break; + + default: + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Unknown IE(EID = %d)\n", __func__, EID)); + break; + } + + return TRUE; +} + +#ifdef CONFIG_HOTSPOT +INT Send_ANQP_Rsp( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *PeerMACAddr, + IN RTMP_STRING *ANQPRsp, + IN UINT32 ANQPRspLen) +{ + UCHAR *Buf; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR apidx = pObj->ioctl_if; + PHOTSPOT_CTRL pHSCtrl = &pAd->ApCfg.MBSSID[apidx].HotSpotCtrl; + PGAS_CTRL pGASCtrl = &pAd->ApCfg.MBSSID[apidx].GASCtrl; + GAS_EVENT_DATA *Event; + GAS_PEER_ENTRY *GASPeerEntry; + GAS_QUERY_RSP_FRAGMENT *GASQueryRspFrag, *Tmp; + UINT32 Len = 0, i, QueryRspOffset = 0; + BOOLEAN Cancelled; + BOOLEAN IsFound = FALSE; + + RTMP_SEM_LOCK(&pGASCtrl->GASPeerListLock); + /* Cancel PostReply timer after receiving daemon response */ + DlListForEach(GASPeerEntry, &pGASCtrl->GASPeerList, GAS_PEER_ENTRY, List) { + if (MAC_ADDR_EQUAL(GASPeerEntry->PeerMACAddr, PeerMACAddr)) { + if (GASPeerEntry->PostReplyTimerRunning) { + RTMPCancelTimer(&GASPeerEntry->PostReplyTimer, &Cancelled); + GASPeerEntry->PostReplyTimerRunning = FALSE; + } + + break; + } + } + RTMP_SEM_UNLOCK(&pGASCtrl->GASPeerListLock); + os_alloc_mem(NULL, (UCHAR **)&Buf, sizeof(*Event) + ANQPRspLen); + + if (!Buf) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + goto error0; + } + + NdisZeroMemory(Buf, sizeof(*Event) + ANQPRspLen); + Event = (GAS_EVENT_DATA *)Buf; + Event->ControlIndex = apidx; + Len += 1; + NdisMoveMemory(Event->PeerMACAddr, PeerMACAddr, MAC_ADDR_LEN); + Len += MAC_ADDR_LEN; + + if ((ANQPRspLen > pHSCtrl->MMPDUSize) || + ((pGASCtrl->cb_delay != 0) && (pHSCtrl->bHSOnOff == 0))) { + + Event->EventType = GAS_RSP_MORE; + Len += 2; + RTMP_SEM_LOCK(&pGASCtrl->GASPeerListLock); + DlListForEach(GASPeerEntry, &pGASCtrl->GASPeerList, GAS_PEER_ENTRY, List) { + if (MAC_ADDR_EQUAL(GASPeerEntry->PeerMACAddr, PeerMACAddr)) { + IsFound = TRUE; + Event->u.GAS_RSP_MORE_DATA.DialogToken = GASPeerEntry->DialogToken; + Len += 1; + + if ((ANQPRspLen % pHSCtrl->MMPDUSize) == 0) + GASPeerEntry->GASRspFragNum = ANQPRspLen / pHSCtrl->MMPDUSize; + else + GASPeerEntry->GASRspFragNum = (ANQPRspLen / pHSCtrl->MMPDUSize) + 1; + + GASPeerEntry->CurrentGASFragNum = 0; + + for (i = 0; i < GASPeerEntry->GASRspFragNum; i++) { + os_alloc_mem(NULL, (UCHAR **)&GASQueryRspFrag, sizeof(*GASQueryRspFrag)); + + if (!GASQueryRspFrag) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + RTMP_SEM_UNLOCK(&pGASCtrl->GASPeerListLock); + goto error1; + } + + GASPeerEntry->AllocResource++; + NdisZeroMemory(GASQueryRspFrag, sizeof(*GASQueryRspFrag)); + GASQueryRspFrag->GASRspFragID = i; + + if (i < (GASPeerEntry->GASRspFragNum - 1)) + GASQueryRspFrag->FragQueryRspLen = pHSCtrl->MMPDUSize; + else + GASQueryRspFrag->FragQueryRspLen = ANQPRspLen - (pHSCtrl->MMPDUSize * i); + + os_alloc_mem(NULL, (UCHAR **)&GASQueryRspFrag->FragQueryRsp, + GASQueryRspFrag->FragQueryRspLen); + GASPeerEntry->AllocResource++; + + if (!GASQueryRspFrag->FragQueryRsp) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + RTMP_SEM_UNLOCK(&pGASCtrl->GASPeerListLock); + goto error2; + } + + NdisMoveMemory(GASQueryRspFrag->FragQueryRsp, &ANQPRsp[QueryRspOffset], + GASQueryRspFrag->FragQueryRspLen); + QueryRspOffset += GASQueryRspFrag->FragQueryRspLen; + DlListAddTail(&GASPeerEntry->GASQueryRspFragList, + &GASQueryRspFrag->List); + } + + break; + } + } + RTMP_SEM_UNLOCK(&pGASCtrl->GASPeerListLock); + + if (!IsFound) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Can not find peer address in GASPeerList\n", __func__)); + goto error1; + } + + Event->u.GAS_RSP_MORE_DATA.StatusCode = 0; + Len += 2; + Event->u.GAS_RSP_MORE_DATA.GASComebackDelay = pGASCtrl->cb_delay; + Len += 2; + Event->u.GAS_RSP_MORE_DATA.AdvertisementProID = ACCESS_NETWORK_QUERY_PROTOCOL; + Len += 1; + GASPeerEntry->CurrentState = WAIT_GAS_RSP; + MlmeEnqueue(pAd, GAS_STATE_MACHINE, GAS_RSP_MORE, Len, Buf, 0); + } else { + Event->EventType = GAS_RSP; + Len += 2; + + RTMP_SEM_LOCK(&pGASCtrl->GASPeerListLock); + DlListForEach(GASPeerEntry, &pGASCtrl->GASPeerList, GAS_PEER_ENTRY, List) + { + if (MAC_ADDR_EQUAL(GASPeerEntry->PeerMACAddr, PeerMACAddr)) { + IsFound = TRUE; + printk("GAS RSP DialogToken = %x\n", GASPeerEntry->DialogToken); + Event->u.GAS_RSP_DATA.DialogToken = GASPeerEntry->DialogToken; + Len += 1; + } + break; + } + RTMP_SEM_UNLOCK(&pGASCtrl->GASPeerListLock); + + if (!IsFound) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Can not find peer address in GASPeerList\n", __func__)); + goto error1; + } + + Event->u.GAS_RSP_DATA.StatusCode = 0; + Len += 2; + Event->u.GAS_RSP_DATA.GASComebackDelay = 0; + Len += 2; + Event->u.GAS_RSP_DATA.AdvertisementProID = ACCESS_NETWORK_QUERY_PROTOCOL; + Len += 1; + Event->u.GAS_RSP_DATA.QueryRspLen = ANQPRspLen; + Len += 2; + + NdisMoveMemory(Event->u.GAS_RSP_DATA.QueryRsp, ANQPRsp, ANQPRspLen); + Len += ANQPRspLen; + + GASPeerEntry->CurrentState = WAIT_GAS_RSP; + + MlmeEnqueue(pAd, GAS_STATE_MACHINE, GAS_RSP, Len, Buf, 0); + } + + os_free_mem(Buf); + return TRUE; +error2: + RTMP_SEM_LOCK(&pGASCtrl->GASPeerListLock); + DlListForEachSafe(GASQueryRspFrag, Tmp, &GASPeerEntry->GASQueryRspFragList, + GAS_QUERY_RSP_FRAGMENT, List) { + DlListDel(&GASQueryRspFrag->List); + os_free_mem(GASQueryRspFrag); + } + DlListInit(&GASPeerEntry->GASQueryRspFragList); + RTMP_SEM_UNLOCK(&pGASCtrl->GASPeerListLock); +error1: + os_free_mem(Buf); +error0: + return FALSE; +} + +#endif + +#ifdef CONFIG_DOT11V_WNM +INT Send_BTM_Req( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *PeerMACAddr, + IN RTMP_STRING *BTMReq, + IN UINT32 BTMReqLen) +{ + UCHAR *Buf; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR APIndex = pObj->ioctl_if; + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[APIndex].WNMCtrl; + BTM_EVENT_DATA *Event; + BTM_PEER_ENTRY *BTMPeerEntry; + UINT32 Len = 0; + INT32 Ret; + BOOLEAN IsFound = FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + RTMP_SEM_EVENT_WAIT(&pWNMCtrl->BTMPeerListLock, Ret); + DlListForEach(BTMPeerEntry, &pWNMCtrl->BTMPeerList, BTM_PEER_ENTRY, List) { + if (MAC_ADDR_EQUAL(BTMPeerEntry->PeerMACAddr, PeerMACAddr)) { + IsFound = TRUE; + break; + } + } + RTMP_SEM_EVENT_UP(&pWNMCtrl->BTMPeerListLock); + + if (!IsFound) { + os_alloc_mem(NULL, (UCHAR **)&BTMPeerEntry, sizeof(*BTMPeerEntry)); + + if (!BTMPeerEntry) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + goto error0; + } + + NdisZeroMemory(BTMPeerEntry, sizeof(*BTMPeerEntry)); + BTMPeerEntry->CurrentState = WAIT_BTM_REQ; + BTMPeerEntry->ControlIndex = APIndex; + NdisMoveMemory(BTMPeerEntry->PeerMACAddr, PeerMACAddr, MAC_ADDR_LEN); + BTMPeerEntry->DialogToken = 1; + BTMPeerEntry->Priv = pAd; + RTMPInitTimer(pAd, &BTMPeerEntry->WaitPeerBTMRspTimer, + GET_TIMER_FUNCTION(WaitPeerBTMRspTimeout), BTMPeerEntry, FALSE); + RTMP_SEM_EVENT_WAIT(&pWNMCtrl->BTMPeerListLock, Ret); + DlListAddTail(&pWNMCtrl->BTMPeerList, &BTMPeerEntry->List); + RTMP_SEM_EVENT_UP(&pWNMCtrl->BTMPeerListLock); + } + + os_alloc_mem(NULL, (UCHAR **)&Buf, sizeof(*Event) + BTMReqLen); + + if (!Buf) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + goto error1; + } + + NdisZeroMemory(Buf, sizeof(*Event) + BTMReqLen); + + Event = (BTM_EVENT_DATA *)Buf; + Event->ControlIndex = APIndex; + Len += 1; + NdisMoveMemory(Event->PeerMACAddr, PeerMACAddr, MAC_ADDR_LEN); + Len += MAC_ADDR_LEN; + Event->EventType = BTM_REQ; + Len += 2; + Event->u.BTM_REQ_DATA.DialogToken = BTMPeerEntry->DialogToken; + Len += 1; + Event->u.BTM_REQ_DATA.BTMReqLen = BTMReqLen; + Len += 2; + NdisMoveMemory(Event->u.BTM_REQ_DATA.BTMReq, BTMReq, BTMReqLen); + Len += BTMReqLen; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\nbefore adding BSS Transition Candidate List Entries::BTMReqLen=%d, Len=%d\n", + BTMReqLen, Len)); + MlmeEnqueue(pAd, BTM_STATE_MACHINE, BTM_REQ, Len, Buf, 0); + os_free_mem(Buf); + return TRUE; +error1: + + if (!IsFound) + os_free_mem(BTMPeerEntry); + +error0: + return FALSE; +} + +#ifdef CONFIG_HOTSPOT_R2 +INT Send_WNM_Notify_Req( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *PeerMACAddr, + IN RTMP_STRING *WNMNotifyReq, + IN UINT32 WNMNotifyReqLen, + IN UINT32 type) +{ + UCHAR *Buf; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR APIndex = pObj->ioctl_if; + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[APIndex].WNMCtrl; + WNM_NOTIFY_EVENT_DATA *Event; + WNM_NOTIFY_PEER_ENTRY *WNMNotifyPeerEntry; + UINT32 Len = 0; + INT32 Ret; + BOOLEAN IsFound = FALSE; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s\n", __func__)); + RTMP_SEM_EVENT_WAIT(&pWNMCtrl->WNMNotifyPeerListLock, Ret); + DlListForEach(WNMNotifyPeerEntry, &pWNMCtrl->WNMNotifyPeerList, WNM_NOTIFY_PEER_ENTRY, List) { + if (MAC_ADDR_EQUAL(WNMNotifyPeerEntry->PeerMACAddr, PeerMACAddr)) { + IsFound = TRUE; + break; + } + } + RTMP_SEM_EVENT_UP(&pWNMCtrl->WNMNotifyPeerListLock); + + if (!IsFound) { + os_alloc_mem(NULL, (UCHAR **)&WNMNotifyPeerEntry, sizeof(*WNMNotifyPeerEntry)); + + if (!WNMNotifyPeerEntry) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + goto error0; + } + + NdisZeroMemory(WNMNotifyPeerEntry, sizeof(*WNMNotifyPeerEntry)); + WNMNotifyPeerEntry->CurrentState = WNM_NOTIFY_REQ; + WNMNotifyPeerEntry->ControlIndex = APIndex; + NdisMoveMemory(WNMNotifyPeerEntry->PeerMACAddr, PeerMACAddr, MAC_ADDR_LEN); + WNMNotifyPeerEntry->DialogToken = 1; + WNMNotifyPeerEntry->Priv = pAd; + RTMPInitTimer(pAd, &WNMNotifyPeerEntry->WaitPeerWNMNotifyRspTimer, + GET_TIMER_FUNCTION(WaitPeerWNMNotifyRspTimeout), WNMNotifyPeerEntry, FALSE); + RTMP_SEM_EVENT_WAIT(&pWNMCtrl->WNMNotifyPeerListLock, Ret); + DlListAddTail(&pWNMCtrl->WNMNotifyPeerList, &WNMNotifyPeerEntry->List); + RTMP_SEM_EVENT_UP(&pWNMCtrl->WNMNotifyPeerListLock); + } + + os_alloc_mem(NULL, (UCHAR **)&Buf, sizeof(*Event) + WNMNotifyReqLen); + + if (!Buf) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Not available memory\n", __func__)); + goto error1; + } + + /* RTMPusecDelay(200000); //200ms */ + NdisZeroMemory(Buf, sizeof(*Event) + WNMNotifyReqLen); + Event = (WNM_NOTIFY_EVENT_DATA *)Buf; + Event->ControlIndex = APIndex; + Len += 1; + NdisMoveMemory(Event->PeerMACAddr, PeerMACAddr, MAC_ADDR_LEN); + Len += MAC_ADDR_LEN; + Event->EventType = type; /* WNM_NOTIFY_REQ; */ + Len += 2; + Event->u.WNM_NOTIFY_REQ_DATA.DialogToken = WNMNotifyPeerEntry->DialogToken; + Len += 1; + Event->u.WNM_NOTIFY_REQ_DATA.WNMNotifyReqLen = WNMNotifyReqLen; + Len += 2; + NdisMoveMemory(Event->u.WNM_NOTIFY_REQ_DATA.WNMNotifyReq, WNMNotifyReq, WNMNotifyReqLen); + Len += WNMNotifyReqLen; + MlmeEnqueue(pAd, WNM_NOTIFY_STATE_MACHINE, WNM_NOTIFY_REQ, Len, Buf, 0); + os_free_mem(Buf); + return TRUE; +error1: + + if (!IsFound) + os_free_mem(WNMNotifyPeerEntry); + +error0: + return FALSE; +} + +INT Send_QOSMAP_Configure( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *PeerMACAddr, + IN RTMP_STRING *QosMapBuf, + IN UINT32 QosMapLen, + IN UINT8 Apidx) +{ + MLME_QOS_ACTION_STRUCT QosMapConfig; + QOSMAP_SET *pQOSMap = &QosMapConfig.QOSMap; + + NdisZeroMemory(&QosMapConfig, sizeof(MLME_QOS_ACTION_STRUCT)); + COPY_MAC_ADDR(QosMapConfig.Addr, PeerMACAddr); + QosMapConfig.ActionField = ACTION_QOSMAP_CONFIG; + QosMapConfig.apidx = Apidx; + pQOSMap->DSCP_Field_Len = QosMapLen; + NdisMoveMemory(pQOSMap->DSCP_Field, QosMapBuf, QosMapLen); + MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_QOS_CATE, sizeof(MLME_QOS_ACTION_STRUCT), (PVOID)&QosMapConfig, 0); + RTMP_MLME_HANDLER(pAd); + return TRUE; +} + +/* for debug */ +INT Set_CR4_Hotspot_Flag( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UINT8 Flag = os_str_tol(arg, 0, 10); + PHOTSPOT_CTRL pHSCtrl; + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + UCHAR APIndex = pObj->ioctl_if; + PWNM_CTRL pWNMCtrl = &pAd->ApCfg.MBSSID[APIndex].WNMCtrl; + EXT_CMD_ID_HOTSPOT_INFO_UPDATE_T HotspotInfoUpdateT; + + pHSCtrl = &pAd->ApCfg.MBSSID[APIndex].HotSpotCtrl; + pHSCtrl->HotSpotEnable = IS_HOTSPOT_ENABLE(Flag); + pHSCtrl->DGAFDisable = IS_DGAF_DISABLE(Flag); + pHSCtrl->bASANEnable = IS_ASAN_ENABLE(Flag); + pHSCtrl->QosMapEnable = IS_QOSMAP_ENABLE(Flag); + pWNMCtrl->ProxyARPEnable = IS_PROXYARP_ENABLE(Flag); + NdisZeroMemory(&HotspotInfoUpdateT, sizeof(HotspotInfoUpdateT)); + HotspotInfoUpdateT.ucUpdateType |= fgUpdateBssCapability; + HotspotInfoUpdateT.ucHotspotBssFlags = Flag; + HotspotInfoUpdateT.ucHotspotBssId = APIndex; + MtCmdHotspotInfoUpdate(pAd, HotspotInfoUpdateT); + MTWF_LOG(DBG_CAT_PROTO, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s ===> Update BSS:%d HotspotFlag:0x%x\n" + , __func__, HotspotInfoUpdateT.ucHotspotBssId, HotspotInfoUpdateT.ucHotspotBssFlags)); + hotspot_bssflag_dump(Flag); + return TRUE; +} + +#endif /* CONFIG_HOTSPOT_R2 */ +#endif /* CONFIG_DOT11V_WNM */ +#ifdef PRE_CAL_TRX_SET1_SUPPORT +INT Set_KtoFlash_Debug_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UINT Enable; + + Enable = os_str_tol(arg, 0, 10); + pAd->KtoFlashDebug = (Enable > 0) ? TRUE : FALSE; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("Set_KtoFlash_Debug_Proc::(enable = %d)\n", + pAd->KtoFlashDebug)); + return TRUE; +} +INT Set_RDCE_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + INT Type; + INT BW; + INT Band; + INT i4Recv; + + if (arg) { + i4Recv = sscanf(arg, "%d-%d-%d", &(Type), &(BW), &(Band)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Type %d,BW %d,Band %d\n", + __func__, Type, BW, Band)); + + if (i4Recv != 3) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Format Error!\n")); + return FALSE; + } + + MtCmdRDCE(pAd, Type, BW, Band); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Format Error!\n")); + return FALSE; + } + + return TRUE; +} + +#endif /* PRE_CAL_TRX_SET1_SUPPORT */ + +#ifdef RLM_CAL_CACHE_SUPPORT +INT Set_RLM_Cal_Cache_Debug_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + rlmCalCacheStatus(pAd->rlmCalCache); + rlmCalCacheDump(pAd->rlmCalCache); + return TRUE; +} +#endif /* RLM_CAL_CACHE_SUPPORT */ + +INT Set_BWF_Enable_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UINT Enable; + + Enable = os_str_tol(arg, 0, 10); + MtCmdSetBWFEnable(pAd, (UINT8)Enable); + return TRUE; +} + +#ifdef TX_AGG_ADJUST_WKR +INT Set_AggAdjWkr_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + pAd->TxAggAdjsut = os_str_tol(arg, 0, 16); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("TxAggAdjsut = %u\n", pAd->TxAggAdjsut)); + return TRUE; +} +#endif /* TX_AGG_ADJUST_WKR */ + +#ifdef CONFIG_TX_DELAY +INT Set_TX_Batch_Cnt_Proc( + PRTMP_ADAPTER pAd, + char *arg) +{ + struct tx_delay_control *tx_delay_ctl = &pAd->tr_ctl.tx_delay_ctl; + + tx_delay_ctl->tx_process_batch_cnt = simple_strtol(arg, 0, 10); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("TxProcessBatchCnt = %u\n", tx_delay_ctl->tx_process_batch_cnt)); + return TRUE; +} + +INT Set_Pkt_Min_Len_Proc( + PRTMP_ADAPTER pAd, + char *arg) +{ + struct tx_delay_control *tx_delay_ctl = &pAd->tr_ctl.tx_delay_ctl; + + tx_delay_ctl->min_pkt_len = simple_strtol(arg, 0, 10); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("min_pkt_len = %u\n", tx_delay_ctl->min_pkt_len)); + return TRUE; +} + +INT Set_Pkt_Max_Len_Proc( + PRTMP_ADAPTER pAd, + char *arg) +{ + struct tx_delay_control *tx_delay_ctl = &pAd->tr_ctl.tx_delay_ctl; + + tx_delay_ctl->max_pkt_len = simple_strtol(arg, 0, 10); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("min_pkt_len = %u\n", tx_delay_ctl->max_pkt_len)); + return TRUE; +} + +INT Set_TX_Delay_Timeout_Proc( + PRTMP_ADAPTER pAd, + char *arg) +{ + struct tx_delay_control *tx_delay_ctl = &pAd->tr_ctl.tx_delay_ctl; + + tx_delay_ctl->que_agg_timeout_value = simple_strtol(arg, 0, 10); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("que_agg_timeout_value = %u\n", tx_delay_ctl->que_agg_timeout_value)); + return TRUE; +} +#endif + +#ifdef HTC_DECRYPT_IOT +INT Set_WTBL_AAD_OM_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UINT Enable; + + Enable = os_str_tol(arg, 0, 10); + HW_SET_ASIC_WCID_AAD_OM(pAd, 1, Enable); + return TRUE; +} + + +INT Set_HTC_Err_TH_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) + +{ + UINT value; + + value = os_str_tol(arg, 0, 10); + + if (value) + pAd->HTC_ICV_Err_TH = value; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("@@@ pAd->HTC_ICV_Err_TH=%u\n", pAd->HTC_ICV_Err_TH)); + return TRUE; +} + +INT Set_Entry_HTC_Err_Cnt_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) + +{ + UINT value; + PMAC_TABLE_ENTRY pEntry; + + value = os_str_tol(arg, 0, 10); + pEntry = &pAd->MacTab.Content[1]; + + if (pEntry && IS_ENTRY_CLIENT(pEntry)) { + ULONG Now32; + + NdisGetSystemUpTime(&Now32); + pEntry->HTC_ICVErrCnt = value; + /* Rx HTC and FAIL decryp case! */ + /* if (rxd_base->RxD2.IcvErr == 1) */ + { + if (pEntry->HTC_ICVErrCnt++ > pAd->HTC_ICV_Err_TH) { + pEntry->HTC_ICVErrCnt = 0; /* reset the history */ + + if (pEntry->HTC_AAD_OM_Force == 0) { + pEntry->HTC_AAD_OM_Force = 1; + HW_SET_ASIC_WCID_AAD_OM(pAd, 1, 1); + } else { + pEntry->HTC_AAD_OM_Force = 0; + HW_SET_ASIC_WCID_AAD_OM(pAd, 1, 0); + } + } + } + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("@@@ pEntry->HTC_ICVErrCnt=%u\n", pEntry->HTC_ICVErrCnt)); + } + + return TRUE; +} +#endif /* HTC_DECRYPT_IOT */ + +#ifdef DHCP_UC_SUPPORT +INT Set_DHCP_UC_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + UINT value; + + value = os_str_tol(arg, 0, 10); + + if (value) + pAd->DhcpUcEnable = TRUE; + else + pAd->DhcpUcEnable = FALSE; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("@@@ pAd->DhcpUcEnable=%u\n", pAd->DhcpUcEnable)); + return TRUE; +} +#endif /* DHCP_UC_SUPPORT */ + +#ifdef AIR_MONITOR + +/* SMESH */ +#define SMESH_RX_CTL BIT(20) +#define SMESH_RX_CTL_OFFSET 20 +#define SMESH_RX_MGT BIT(19) +#define SMESH_RX_MGT_OFFSET 19 +#define SMESH_RX_DATA BIT(18) +#define SMESH_RX_DATA_OFFSET 18 +#define SMESH_RX_A1 BIT(17) +#define SMESH_RX_A2 BIT(16) +#define SMESH_ADDR_EN BITS(0, 7) + +/* MAR1 */ +#define MAR1_MAR_GROUP_MASK BITS(30, 31) +#define MAR1_MAR_GROUP_OFFSET 30 +#define MAR1_MAR_HASH_MODE_BSSID1 BIT(30) +#define MAR1_MAR_HASH_MODE_BSSID2 BIT(31) +#define MAR1_MAR_HASH_MODE_BSSID3 BITS(30, 31) +#define MAR1_ADDR_INDEX_MASK BITS(24, 29) +#define MAR1_ADDR_INDEX_OFFSET 24 +#define MAR1_READ 0 +#define MAR1_WRITE BIT(17) +#define MAR1_ACCESS_START_STATUS BIT(16) + +void apply_mntr_ruleset(PRTMP_ADAPTER pAd, UINT32 *pu4SMESH) +{ + if (pAd->MntRuleBitMap & RULE_CTL) + *pu4SMESH |= SMESH_RX_CTL; + else + *pu4SMESH &= ~SMESH_RX_CTL; + + if (pAd->MntRuleBitMap & RULE_MGT) + *pu4SMESH |= SMESH_RX_MGT; + else + *pu4SMESH &= ~SMESH_RX_MGT; + + if (pAd->MntRuleBitMap & RULE_DATA) + *pu4SMESH |= SMESH_RX_DATA; + else + *pu4SMESH &= ~SMESH_RX_DATA; + + if (pAd->MntRuleBitMap & RULE_A1) + *pu4SMESH |= SMESH_RX_A1; + else + *pu4SMESH &= ~SMESH_RX_A1; + + if (pAd->MntRuleBitMap & RULE_A2) + *pu4SMESH |= SMESH_RX_A2; + else + *pu4SMESH &= ~SMESH_RX_A2; +} + + +INT Set_Enable_Air_Monitor_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + UCHAR mnt_enable = 0, band_idx, flush_all = FALSE; + UINT32 i, u4SMESH = 0, u4MAR0 = 0, u4MAR1 = 0; + UCHAR *p = ZERO_MAC_ADDR, muar_idx = 0; + BOOLEAN bSMESHEn = FALSE; + MNT_STA_ENTRY *pMntEntry = NULL; + MAC_TABLE_ENTRY *pMacEntry = NULL; + MNT_MUAR_GROUP *pMuarGroup = NULL; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("--> %s()\n", __func__)); + + if (!wdev) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("wdev is NULL\n")); + return FALSE; + } + + mnt_enable = (UCHAR)simple_strtol(arg, 0, 10); + band_idx = HcGetBandByWdev(wdev); + + if (band_idx == BAND0) { + HW_IO_READ32(pAd, RMAC_SMESH, &u4SMESH); + + if ((u4SMESH & SMESH_ADDR_EN)) { + bSMESHEn = TRUE; + flush_all = TRUE; + } + } else if (band_idx == BAND1) { + HW_IO_READ32(pAd, RMAC_SMESH_B1, &u4SMESH); + + if ((u4SMESH & SMESH_ADDR_EN)) { + bSMESHEn = TRUE; + flush_all = TRUE; + } + } + + if (bSMESHEn != mnt_enable) { + if (mnt_enable == 0) { + if (flush_all == TRUE) { + for (i = 0; i < MAX_NUM_OF_MONITOR_GROUP; i++) { + pMuarGroup = &pAd->MntGroupTable[i]; + + if (pMuarGroup->bValid && (pMuarGroup->Band == band_idx)) + NdisZeroMemory(pMuarGroup, sizeof(*pMuarGroup)); + } + + u4MAR0 = ((UINT32)p[0]) | ((UINT32)p[1]) << 8 | + ((UINT32)p[2]) << 16 | ((UINT32)p[3]) << 24; + u4MAR1 = ((UINT32)p[4]) | ((UINT32)p[5]) << 8; + + for (i = 0; i < MAX_NUM_OF_MONITOR_STA; i++) { + pMntEntry = &pAd->MntTable[i]; + + if (!pMntEntry->bValid || (pMntEntry->Band != band_idx)) + continue; + + muar_idx = pMntEntry->muar_idx; + u4MAR1 |= MAR1_WRITE | MAR1_ACCESS_START_STATUS | (muar_idx << MAR1_ADDR_INDEX_OFFSET) + | (((UINT32)0 << MAR1_MAR_GROUP_OFFSET) & MAR1_MAR_GROUP_MASK); + HW_IO_WRITE32(pAd, RMAC_MAR0, u4MAR0); + HW_IO_WRITE32(pAd, RMAC_MAR1, u4MAR1); + pMacEntry = pMntEntry->pMacEntry; + + if (pMacEntry) { + if (band_idx == BAND1) + pMacEntry->mnt_band &= ~MNT_BAND1; + else + pMacEntry->mnt_band &= ~MNT_BAND0; + + if (pMacEntry->mnt_band == 0) { /* no more use for other band */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s::call MacTableDeleteEntry(WCID=%d)- %02X:%02X:%02X:%02X:%02X:%02X\n", + __func__, pMacEntry->wcid, PRINT_MAC(pMacEntry->Addr))); + MacTableDeleteEntry(pAd, pMacEntry->wcid, pMacEntry->Addr); + } + } + + pAd->MonitrCnt[band_idx]--; + NdisZeroMemory(pMntEntry, sizeof(*pMntEntry)); + } + + if (band_idx == DBDC_BAND0) { + HW_IO_READ32(pAd, RMAC_SMESH, &u4SMESH); + u4SMESH &= ~SMESH_ADDR_EN; + HW_IO_WRITE32(pAd, RMAC_SMESH, u4SMESH); + } else if (band_idx == DBDC_BAND1) { + HW_IO_READ32(pAd, RMAC_SMESH_B1, &u4SMESH); + u4SMESH &= ~SMESH_ADDR_EN; + HW_IO_WRITE32(pAd, RMAC_SMESH_B1, u4SMESH); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s():: wrong band index(%d)\n", + __func__, band_idx)); + return FALSE; + } + } + + if ((pAd->MonitrCnt[BAND0] + pAd->MonitrCnt[BAND1]) == 0) { + pAd->MntEnable = 0; + NdisZeroMemory(&pAd->MntTable, sizeof(pAd->MntTable)); + NdisZeroMemory(&pAd->MntGroupTable, sizeof(pAd->MntGroupTable)); + } + } else { + if (band_idx == DBDC_BAND0) { + HW_IO_READ32(pAd, RMAC_SMESH, &u4SMESH); + apply_mntr_ruleset(pAd, &u4SMESH); + u4SMESH |= SMESH_ADDR_EN | u4SMESH; + HW_IO_WRITE32(pAd, RMAC_SMESH, u4SMESH); + } else if (band_idx == DBDC_BAND1) { + HW_IO_READ32(pAd, RMAC_SMESH_B1, &u4SMESH); + apply_mntr_ruleset(pAd, &u4SMESH); + u4SMESH |= SMESH_ADDR_EN | u4SMESH; + HW_IO_WRITE32(pAd, RMAC_SMESH_B1, u4SMESH); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s():: wrong band index(%d)\n", + __func__, band_idx)); + return FALSE; + } + + pAd->MntEnable = 1; + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<-- %s()\n", __func__)); + return TRUE; +} + + +INT Set_MonitorRule_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + INT ret = TRUE; + RTMP_STRING *this_char = NULL, *value = NULL; + INT idx = 0; + UCHAR rx_rule[3], band_idx; + UINT32 u4SMESH = 0; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("--> %s()\n", __func__)); + + while ((this_char = strsep((char **)&arg, ";")) != NULL) { + if (*this_char == '\0') { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("An unnecessary delimiter entered!\n")); + continue; + } + + if (strlen(this_char) != 5) { /* the acceptable format is like 0:1:1 with length 5 */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("illegal length! (acceptable format 0:1:1 length 5)\n")); + continue; + } + + for (idx = 0, value = rstrtok(this_char, ":"); value; value = rstrtok(NULL, ":")) { + if ((strlen(value) != 1) || (!isxdigit(*value))) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("illegal format!\n")); + break; + } + + rx_rule[idx++] = (UCHAR)os_str_tol(value, 0, 10); + } + + if (idx != 3) + continue; + } + + if (!wdev) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("wdev is NULL\n")); + return FALSE; + } + + pAd->MntRuleBitMap &= ~RULE_CTL; + pAd->MntRuleBitMap &= ~RULE_MGT; + pAd->MntRuleBitMap &= ~RULE_DATA; + pAd->MntRuleBitMap |= (RULE_DATA & ((UINT32)rx_rule[0] << RULE_DATA_OFFSET)) + | (RULE_MGT & ((UINT32)rx_rule[1] << RULE_MGT_OFFSET)) + | (RULE_CTL & ((UINT32)rx_rule[2] << RULE_CTL_OFFSET)); + + band_idx = HcGetBandByWdev(wdev); + + if (band_idx == DBDC_BAND0) { + HW_IO_READ32(pAd, RMAC_SMESH, &u4SMESH); + u4SMESH &= ~SMESH_RX_DATA; + u4SMESH &= ~SMESH_RX_MGT; + u4SMESH &= ~SMESH_RX_CTL; + u4SMESH |= (SMESH_RX_DATA & ((UINT32)rx_rule[0] << SMESH_RX_DATA_OFFSET)) + | (SMESH_RX_MGT & ((UINT32)rx_rule[1] << SMESH_RX_MGT_OFFSET)) + | (SMESH_RX_CTL & ((UINT32)rx_rule[2] << SMESH_RX_CTL_OFFSET)); + HW_IO_WRITE32(pAd, RMAC_SMESH, u4SMESH); + } else if (band_idx == DBDC_BAND1) { + HW_IO_READ32(pAd, RMAC_SMESH_B1, &u4SMESH); + u4SMESH &= ~SMESH_RX_DATA; + u4SMESH &= ~SMESH_RX_MGT; + u4SMESH &= ~SMESH_RX_CTL; + u4SMESH |= (SMESH_RX_DATA & ((UINT32)rx_rule[0] << SMESH_RX_DATA_OFFSET)) + | (SMESH_RX_MGT & ((UINT32)rx_rule[1] << SMESH_RX_MGT_OFFSET)) + | (SMESH_RX_CTL & ((UINT32)rx_rule[2] << SMESH_RX_CTL_OFFSET)); + HW_IO_WRITE32(pAd, RMAC_SMESH_B1, u4SMESH); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s():: wrong band index(%d)\n", + __func__, band_idx)); + return FALSE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<-- %s()\n", __func__)); + return ret; +} + + +INT Set_MonitorTarget_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + INT ret = TRUE; + RTMP_STRING *this_char = NULL; + RTMP_STRING *value = NULL; + INT idx = 0; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("--> %s()\n", __func__)); + + while ((this_char = strsep((char **)&arg, ";")) != NULL) { + if (*this_char == '\0') { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_WARN, ("An unnecessary delimiter entered!\n")); + continue; + } + + if (strlen(this_char) != 17) { /* the acceptable format of MAC address is like 01:02:03:04:05:06 with length 17 */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("illegal MAC address length! (acceptable format 01:02:03:04:05:06 length 17)\n")); + continue; + } + + for (idx = 0, value = rstrtok(this_char, ":"); value; value = rstrtok(NULL, ":")) { + if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value + 1)))) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("illegal MAC address format or octet!\n")); + break; + } + + AtoH(value, &pAd->curMntAddr[idx++], 1); + } + + if (idx != MAC_ADDR_LEN) + continue; + } + + for (idx = 0; idx < MAC_ADDR_LEN; idx++) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02X ", pAd->curMntAddr[idx])); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<-- %s()\n", __func__)); + return ret; +} + + +INT Set_MonitorIndex_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + INT ret = TRUE, i; + UINT32 u4MAR0 = 0, u4MAR1 = 0, u4DBDC_CTRL = 0; + UCHAR *p = ZERO_MAC_ADDR, mnt_idx = 0, band_idx = 0, muar_idx = 0, muar_group_base = 0; + BOOLEAN bCreate = FALSE; + MNT_STA_ENTRY *pMntEntry = NULL; + MAC_TABLE_ENTRY *pMacEntry = NULL; + MNT_MUAR_GROUP *pMuarGroup = NULL; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("--> %s()\n", __func__)); + + if (!wdev) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("wdev is NULL\n")); + return FALSE; + } + + band_idx = HcGetBandByWdev(wdev); + mnt_idx = (UCHAR)simple_strtol(arg, 0, 10); + + if (mnt_idx < MAX_NUM_OF_MONITOR_STA) { + pAd->MntIdx = mnt_idx; + pMntEntry = &pAd->MntTable[mnt_idx]; + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("The index is over the maximum limit.\n")); + return FALSE; + } + + if (MAC_ADDR_EQUAL(ZERO_MAC_ADDR, pAd->curMntAddr)) { + if (pMntEntry->bValid) { + pMacEntry = pMntEntry->pMacEntry; + + if (pMacEntry) { + if (band_idx == BAND1) + pMacEntry->mnt_band &= ~MNT_BAND1; + else + pMacEntry->mnt_band &= ~MNT_BAND0; + + if (pMacEntry->mnt_band == 0) /* no more use for other band */ + MacTableDeleteEntry(pAd, pMacEntry->wcid, pMacEntry->Addr); + } + + if (pMntEntry->muar_group_idx < MAX_NUM_OF_MONITOR_GROUP) + pMuarGroup = &pAd->MntGroupTable[pMntEntry->muar_group_idx]; + + if (pMuarGroup) { + pMuarGroup->Count--; + + if (pMuarGroup->Count == 0) + pMuarGroup->bValid = FALSE; + } + + pMntEntry->bValid = FALSE; + + if (pAd->MonitrCnt[band_idx] > 0) + pAd->MonitrCnt[band_idx]--; + + muar_idx = pMntEntry->muar_idx; + } else + return TRUE; + } else { + if (pMntEntry->bValid) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("The index of existed monitor entry.\n")); + return TRUE; + } + + if ((pAd->MonitrCnt[BAND0] + pAd->MonitrCnt[BAND1]) >= MAX_NUM_OF_MONITOR_STA) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("The monitor number extends to maximum limit(%d).\n", MAX_NUM_OF_MONITOR_STA)); + return FALSE; + } + + for (i = 0; i < MAX_NUM_OF_MONITOR_GROUP; i++) { + pMuarGroup = &pAd->MntGroupTable[i]; + + if (!pMuarGroup->bValid) { + NdisZeroMemory(pMntEntry, sizeof(MNT_STA_ENTRY)); + pMuarGroup->MuarGroupBase = MONITOR_MUAR_BASE_INDEX + i * MAX_NUM_PER_GROUP; + pMuarGroup->bValid = TRUE; + pMuarGroup->Band = band_idx; + pMntEntry->muar_group_idx = i; + pMntEntry->muar_idx = (pMuarGroup->MuarGroupBase + pMuarGroup->Count++); + muar_idx = pMntEntry->muar_idx; + muar_group_base = pMuarGroup->MuarGroupBase; + bCreate = TRUE; + break; + } else if ((pMuarGroup->Count < MAX_NUM_PER_GROUP) && + (pMuarGroup->Band == band_idx)) { + NdisZeroMemory(pMntEntry, sizeof(MNT_STA_ENTRY)); + pMntEntry->muar_group_idx = i; + pMntEntry->muar_idx = (pMuarGroup->MuarGroupBase + pMuarGroup->Count++); + muar_idx = pMntEntry->muar_idx; + muar_group_base = pMuarGroup->MuarGroupBase; + bCreate = TRUE; + break; + } + } + + if (bCreate) { + COPY_MAC_ADDR(pMntEntry->addr, pAd->curMntAddr); + pMacEntry = MacTableLookup(pAd, pMntEntry->addr); + if (pMacEntry == NULL) { + pMacEntry = MacTableInsertEntry( + pAd, + pMntEntry->addr, + wdev, + ENTRY_CAT_MONITOR, + OPMODE_STA, + TRUE); + + if (wdev_do_conn_act(wdev, pMacEntry) != TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): connect fail!!\n", __func__)); + return FALSE; + } + } + + if (pMacEntry) { + p = pMntEntry->addr; + pAd->MonitrCnt[band_idx]++; + pMntEntry->bValid = TRUE; + pMntEntry->Band = band_idx; + pMacEntry->mnt_idx[band_idx] = mnt_idx; + + if (band_idx == BAND1) + pMacEntry->mnt_band |= MNT_BAND1; + else + pMacEntry->mnt_band |= MNT_BAND0; + + pMntEntry->pMacEntry = pMacEntry; + } + + HW_IO_READ32(pAd, CFG_DBDC_CTRL1, &u4DBDC_CTRL); + + if (band_idx == BAND1) + u4DBDC_CTRL |= (1 << (muar_group_base / MAX_NUM_PER_GROUP)); + else + u4DBDC_CTRL &= ~(1 << (muar_group_base / MAX_NUM_PER_GROUP)); + + HW_IO_WRITE32(pAd, CFG_DBDC_CTRL1, u4DBDC_CTRL); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Can't create a monitor entry!\n")); + return FALSE; + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("index: %d\n", mnt_idx)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("entry: %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(p))); + u4MAR0 = ((UINT32)p[0]) | ((UINT32)p[1]) << 8 | + ((UINT32)p[2]) << 16 | ((UINT32)p[3]) << 24; + u4MAR1 = ((UINT32)p[4]) | ((UINT32)p[5]) << 8; + u4MAR1 |= MAR1_WRITE | MAR1_ACCESS_START_STATUS | (muar_idx << MAR1_ADDR_INDEX_OFFSET) + | (((UINT32)0 << MAR1_MAR_GROUP_OFFSET) & MAR1_MAR_GROUP_MASK); + HW_IO_WRITE32(pAd, RMAC_MAR0, u4MAR0); + HW_IO_WRITE32(pAd, RMAC_MAR1, u4MAR1); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("WriteCR 0x%08X:0x%08X 0x%08X:0x%08X\n", RMAC_MAR0, u4MAR0, RMAC_MAR1, u4MAR1)); + ret = Set_Enable_Air_Monitor_Proc(pAd, (pAd->MonitrCnt[band_idx] > 0) ? "1" : "0"); + + do { + HW_IO_READ32(pAd, RMAC_MAR1, &u4MAR1); + } while (u4MAR1 & MAR1_ACCESS_START_STATUS); + + HW_IO_READ32(pAd, RMAC_MAR0, &u4MAR0); + p[0] = u4MAR0 & 0xFF; + p[1] = (u4MAR0 & 0xFF00) >> 8; + p[2] = (u4MAR0 & 0xFF0000) >> 16; + p[3] = (u4MAR0 & 0xFF000000) >> 24; + p[4] = u4MAR1 & 0xFF; + p[5] = (u4MAR1 & 0xFF00) >> 8; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("entry: %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(p))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<-- %s()\n", __func__)); + return ret; +} + + +INT Set_MonitorShowAll_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + INT ret = TRUE; + UCHAR i = 0; + MNT_STA_ENTRY *pEntry = NULL; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("--> %s()\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" Monitor Enable: %d\n", pAd->MntEnable)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" Index last set: %d\n", pAd->MntIdx)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" BAND0 Count: %d\n", pAd->MonitrCnt[BAND0])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" BAND1 Count: %d\n", pAd->MonitrCnt[BAND1])); + + for (i = 0; i < MAX_NUM_OF_MONITOR_STA; i++) { + pEntry = &pAd->MntTable[i]; + + if (pEntry->bValid) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Band%d: Monitor STA[%d]\t", pEntry->Band, i)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02X:%02X:%02X:%02X:%02X:%02X\t", PRINT_MAC(pEntry->addr))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[DATA]=%08lu\t", pEntry->data_cnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[MGMT]=%08lu\t", pEntry->mgmt_cnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[CNTL]=%08lu\t", pEntry->cntl_cnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("[TOTAL]=%08lu\t", pEntry->Count)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("RSSI:%d,%d,%d,%d\n", + pEntry->RssiSample.AvgRssi[0], pEntry->RssiSample.AvgRssi[1], + pEntry->RssiSample.AvgRssi[2], pEntry->RssiSample.AvgRssi[3])); + } + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<-- %s()\n", __func__)); + return ret; +} + + +INT Set_MonitorClearCounter_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + INT ret = TRUE; + UCHAR i = 0; + MNT_STA_ENTRY *pEntry = NULL; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("--> %s()\n", __func__)); + + for (i = 0; i < MAX_NUM_OF_MONITOR_STA; i++) { + pEntry = pAd->MntTable + i; + pEntry->data_cnt = 0; + pEntry->mgmt_cnt = 0; + pEntry->cntl_cnt = 0; + pEntry->Count = 0; + NdisZeroMemory(&pEntry->RssiSample, sizeof(RSSI_SAMPLE)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("<-- %s()\n", __func__)); + return ret; +} + + +INT Set_Enable_MonitorTarget_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg, + IN USHORT index) +{ + INT ret = TRUE; + CHAR str[8]; + + ret = Set_MonitorTarget_Proc(pAd, arg); + + if (!ret) + return ret; + + if (index < MAX_NUM_OF_MONITOR_STA) { + sprintf(str, "%u", index); + ret = Set_MonitorIndex_Proc(pAd, str); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("The index is over the maximum limit.\n")); + ret = FALSE; + } + + return ret; +} + + +INT Set_MonitorTarget0_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 0); +} + + +INT Set_MonitorTarget1_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 1); +} + + +INT Set_MonitorTarget2_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 2); +} + + +INT Set_MonitorTarget3_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 3); +} + + +INT Set_MonitorTarget4_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 4); +} + + +INT Set_MonitorTarget5_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 5); +} + + +INT Set_MonitorTarget6_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 6); +} + + +INT Set_MonitorTarget7_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 7); +} + + +INT Set_MonitorTarget8_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 8); +} + + +INT Set_MonitorTarget9_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 9); +} + + +INT Set_MonitorTarget10_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 10); +} + + +INT Set_MonitorTarget11_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 11); +} + + +INT Set_MonitorTarget12_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 12); +} + + +INT Set_MonitorTarget13_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 13); +} + + +INT Set_MonitorTarget14_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 14); +} + + +INT Set_MonitorTarget15_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING *arg) +{ + return Set_Enable_MonitorTarget_Proc(pAd, arg, 15); +} + + +VOID Air_Monitor_Pkt_Report_Action( + IN RTMP_ADAPTER *pAd, + IN UCHAR wcid, + IN RX_BLK *pRxBlk) +{ + UCHAR FrameBuf[512]; + AIR_RAW AirRaw; + HTTRANSMIT_SETTING HTSetting; + UCHAR Apidx = MAIN_MBSSID, BandIdx = 0, Channel = 0; + UCHAR s_addr[MAC_ADDR_LEN]; + UCHAR ETH_P_AIR_MONITOR[LENGTH_802_3_TYPE] = {0x51, 0xA0}; + UINT32 frame_len = 0, offset = 0, i; + struct sk_buff *skb = NULL; + FRAME_CONTROL *fc = (FRAME_CONTROL *)pRxBlk->FC; + MAC_TABLE_ENTRY *pMacEntry = &pAd->MacTab.Content[wcid]; + MNT_STA_ENTRY *pMntEntry = NULL; + RXD_BASE_STRUCT *rxd_base = (RXD_BASE_STRUCT *)pRxBlk->rmac_info; + + if (!rxd_base) + return; + + Channel = rxd_base->RxD1.ChFreq; + + if (Channel == 0) + return; + + BandIdx = HcGetBandByChannel(pAd, Channel); + + if (BandIdx >= BAND_NUM) + return; + + pMntEntry = pAd->MntTable + pMacEntry->mnt_idx[BandIdx]; + + if (!pMntEntry->bValid) + return; + + switch (fc->Type) { + case FC_TYPE_MGMT: + if (pAd->MntRuleBitMap & RULE_MGT) + pMntEntry->mgmt_cnt++; + else + goto done; + break; + + case FC_TYPE_CNTL: + if (pAd->MntRuleBitMap & RULE_CTL) + pMntEntry->cntl_cnt++; + else + goto done; + break; + + case FC_TYPE_DATA: + if (pAd->MntRuleBitMap & RULE_DATA) + pMntEntry->data_cnt++; + else + goto done; + break; + + default: + goto done; + } + + pMntEntry->Count++; + NdisMoveMemory(pMntEntry->RssiSample.AvgRssi, + pRxBlk->rx_signal.raw_rssi, sizeof(pMntEntry->RssiSample.AvgRssi)); + + for (i = 0; i < pAd->Antenna.field.RxPath; i++) { + if (pMntEntry->RssiSample.AvgRssi[i] > 0) + pMntEntry->RssiSample.AvgRssi[i] = -127; + } + + /* Init frame buffer */ + NdisZeroMemory(FrameBuf, sizeof(FrameBuf)); + NdisZeroMemory(&AirRaw, sizeof(AirRaw)); + /* Fake a Source Address for transmission */ + COPY_MAC_ADDR(s_addr, pAd->ApCfg.MBSSID[Apidx].wdev.if_addr); + + if (s_addr[1] == 0xff) + s_addr[1] = 0; + else + s_addr[1]++; + + /* Prepare the 802.3 header */ + MAKE_802_3_HEADER(FrameBuf, pAd->ApCfg.MBSSID[Apidx].wdev.if_addr, s_addr, ETH_P_AIR_MONITOR); + offset += LENGTH_802_3; + /* For Rate Info */ + HTSetting.field.MODE = pRxBlk->rx_rate.field.MODE; + HTSetting.field.MCS = pRxBlk->rx_rate.field.MCS; + HTSetting.field.BW = pRxBlk->rx_rate.field.BW; + HTSetting.field.ShortGI = pRxBlk->rx_rate.field.ShortGI; + getRate(HTSetting, &AirRaw.wlan_radio_tap.RATE); + AirRaw.wlan_radio_tap.PHYMODE = pRxBlk->rx_rate.field.MODE; + AirRaw.wlan_radio_tap.MCS = pRxBlk->rx_rate.field.MCS; + AirRaw.wlan_radio_tap.BW = pRxBlk->rx_rate.field.BW; + AirRaw.wlan_radio_tap.ShortGI = pRxBlk->rx_rate.field.ShortGI; +#ifdef DOT11_VHT_AC + + if (AirRaw.wlan_radio_tap.PHYMODE >= MODE_VHT) { + AirRaw.wlan_radio_tap.MCS = (pRxBlk->rx_rate.field.MCS & 0xf); + AirRaw.wlan_radio_tap.STREAM = (pRxBlk->rx_rate.field.MCS >> 4) + 1; + } else +#endif /* DOT11_VHT_AC */ + if (AirRaw.wlan_radio_tap.PHYMODE == MODE_OFDM) { + AirRaw.wlan_radio_tap.MCS = getLegacyOFDMMCSIndex(pRxBlk->rx_rate.field.MCS); + AirRaw.wlan_radio_tap.STREAM = (pRxBlk->rx_rate.field.MCS >> 4) + 1; + } else { + AirRaw.wlan_radio_tap.MCS = (pRxBlk->rx_rate.field.MCS % 8); + AirRaw.wlan_radio_tap.STREAM = (pRxBlk->rx_rate.field.MCS >> 3) + 1; + } + + /* For RSSI */ + for (i = 0; i < pAd->Antenna.field.RxPath; i++) + AirRaw.wlan_radio_tap.RSSI[i] = pMntEntry->RssiSample.AvgRssi[i]; + + AirRaw.wlan_radio_tap.Channel = Channel; + + /* For 802.11 Header */ + NdisMoveMemory(&AirRaw.wlan_header.FC, fc, sizeof(*fc)); + AirRaw.wlan_header.Duration = pRxBlk->Duration; + AirRaw.wlan_header.SN = pRxBlk->SN; + AirRaw.wlan_header.FN = pRxBlk->FN; + COPY_MAC_ADDR(AirRaw.wlan_header.Addr1, pRxBlk->Addr1); + COPY_MAC_ADDR(AirRaw.wlan_header.Addr2, pRxBlk->Addr2); + COPY_MAC_ADDR(AirRaw.wlan_header.Addr3, pRxBlk->Addr3); + + if (fc->ToDs == 1 && fc->FrDs == 1) + COPY_MAC_ADDR(AirRaw.wlan_header.Addr4, pRxBlk->Addr4); + + /* Prepare payload*/ + NdisCopyMemory(&FrameBuf[offset], (CHAR *)&AirRaw, sizeof(AirRaw)); + offset += sizeof(AirRaw); + frame_len = offset; + /* Create skb */ + skb = dev_alloc_skb((frame_len + 2)); + + if (!skb) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s : Error! Can't allocate a skb.\n", __func__)); + return; + } + + SET_OS_PKT_NETDEV(skb, pAd->ApCfg.MBSSID[Apidx].wdev.if_dev); + /* 16 byte align the IP header */ + skb_reserve(skb, 2); + /* Insert the frame content */ + NdisMoveMemory(GET_OS_PKT_DATAPTR(skb), FrameBuf, frame_len); + /* End this frame */ + skb_put(skb, frame_len); + /* Report to upper layer */ + RtmpOsPktProtocolAssign(skb); + RtmpOsPktRcvHandle(skb); +done: + return; +} + +#endif /* AIR_MONITOR */ + + +#ifdef DSCP_PRI_SUPPORT +INT Set_Dscp_Pri_Proc( + IN PRTMP_ADAPTER pAd, + IN UINT8 map_index, + IN RTMP_STRING *arg) +{ + RTMP_STRING *this_char; + UINT8 dscpValue; + INT8 pri; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s arg=%s\n", __func__, arg)); + this_char = strsep((char **)&arg, ";"); + if (this_char == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s value not defined for Dscp and Priority\n", __func__)); + return FALSE; + } + + dscpValue = simple_strtol(this_char, 0, 10); + if ((dscpValue < 0) || (dscpValue > 63)) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s Invalid Dscp Value Valid Value between 0 to 63\n", + __func__)); + return FALSE; + } + if (arg == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s Priority not defined for Dscp %d\n", __func__, dscpValue)); + return FALSE; + } + pri = simple_strtol(arg, 0, 10); + + if (pri < -1 || pri > 7) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s Invalid Priority value Valid value between 0 to 7\n", __func__)); + return FALSE; + } + + if (pri == 0) + pri = 3; + pAd->dscp_pri_map[map_index][dscpValue] = pri; + + return TRUE; +} +INT Set_Dscp_Pri_2G_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + return Set_Dscp_Pri_Proc(pAd, DSCP_PRI_2G_MAP, arg); +} +INT Set_Dscp_Pri_5G_Proc( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING *arg) +{ + return Set_Dscp_Pri_Proc(pAd, DSCP_PRI_5G_MAP, arg); +} +#endif diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_data.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_data.c new file mode 100644 index 000000000..21e3c0c33 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_data.c @@ -0,0 +1,3563 @@ +/*************************************************************************** + * MediaTek Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 1997-2012, MediaTek, Inc. + * + * All rights reserved. MediaTek source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek Technology, Inc. is obtained. + *************************************************************************** + +*/ + +#include "rt_config.h" + +static VOID ap_tx_drop_update(struct _RTMP_ADAPTER *ad, struct wifi_dev *wdev, TX_BLK *txblk) +{ +#ifdef STATS_COUNT_SUPPORT + BSS_STRUCT *mbss = txblk->pMbss; + + if (mbss != NULL) + mbss->TxDropCount++; + +#endif /* STATS_COUNT_SUPPORT */ +} + +static VOID ap_tx_ok_update(struct _RTMP_ADAPTER *ad, struct wifi_dev *wdev, TX_BLK *txblk) +{ +#ifdef STATS_COUNT_SUPPORT + MAC_TABLE_ENTRY *entry = txblk->pMacEntry; + + if (!entry) + return ; +#ifdef WHNAT_SUPPORT + /*if WHNAT enable, query from CR4 and then update it*/ + if ((ad->CommonCfg.whnat_en) && (IS_ASIC_CAP(ad, fASIC_CAP_MCU_OFFLOAD))) + return; +#endif /*WHNAT_SUPPORT*/ + + /* calculate Tx count and ByteCount per BSS */ + { + BSS_STRUCT *mbss = txblk->pMbss; + + if (mbss != NULL) { + mbss->TransmittedByteCount += txblk->SrcBufLen; + mbss->TxCount++; + + if (IS_MULTICAST_MAC_ADDR(txblk->pSrcBufHeader)) + mbss->mcPktsTx++; + else if (IS_BROADCAST_MAC_ADDR(txblk->pSrcBufHeader)) + mbss->bcPktsTx++; + else + mbss->ucPktsTx++; + } + + if (entry->Sst == SST_ASSOC) { + INC_COUNTER64(entry->TxPackets); + entry->TxBytes += txblk->SrcBufLen; + ad->TxTotalByteCnt += txblk->SrcBufLen; + } + } + +#ifdef APCLI_SUPPORT + if (IS_ENTRY_APCLI(entry)) { + struct _APCLI_STRUCT *apcli = txblk->pApCliEntry; + + if (apcli != NULL) { + apcli->TxCount++; + apcli->TransmittedByteCount += txblk->SrcBufLen; + } + } +#endif + +#ifdef WDS_SUPPORT + + if (IS_ENTRY_WDS(entry)) { + INC_COUNTER64(ad->WdsTab.WdsEntry[entry->func_tb_idx].WdsCounter.TransmittedFragmentCount); + ad->WdsTab.WdsEntry[entry->func_tb_idx].WdsCounter.TransmittedByteCount += txblk->SrcBufLen; + } + +#endif /* WDS_SUPPORT */ +#endif /* STATS_COUNT_SUPPORT */ + +} + +INT ap_fp_tx_pkt_allowed(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, PNDIS_PACKET pkt) +{ + PACKET_INFO pkt_info; + UCHAR *pkt_va; + UINT pkt_len; + MAC_TABLE_ENTRY *entry = NULL; + UCHAR wcid = RESERVED_WCID; + UCHAR frag_nums; + + RTMP_QueryPacketInfo(pkt, &pkt_info, &pkt_va, &pkt_len); + + if ((!pkt_va) || (pkt_len <= 14)) + return FALSE; + +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + + if ((wf_drv_tbl.wf_fwd_needed_hook != NULL) && (wf_drv_tbl.wf_fwd_needed_hook() == TRUE)) { + if (is_looping_packet(pAd, pkt)) + return FALSE; + } + +#endif /* CONFIG_WIFI_PKT_FWD */ + + if (MAC_ADDR_IS_GROUP(pkt_va)) { + if (wdev->PortSecured != WPA_802_1X_PORT_SECURED) + return FALSE; + wcid = wdev->tr_tb_idx; + } else { + entry = MacTableLookup(pAd, pkt_va); + + if (entry && (entry->Sst == SST_ASSOC)){ + wcid = (UCHAR)entry->wcid; + } + + } + + if (!(VALID_TR_WCID(wcid) && IS_VALID_ENTRY(&pAd->MacTab.tr_entry[wcid]))) + return FALSE; + + RTMP_SET_PACKET_WCID(pkt, wcid); +#ifdef CONFIG_AP_SUPPORT +#ifdef CFG80211_SUPPORT + + /* CFG_TODO: POS NO GOOD */ + if (pAd->cfg80211_ctrl.isCfgInApMode == RT_CMD_80211_IFTYPE_AP) + RTMP_SET_PACKET_OPMODE(pkt, OPMODE_AP); + +#endif /* CFG80211_SUPPORT */ +#endif + frag_nums = get_frag_num(pAd, wdev, pkt); + RTMP_SET_PACKET_FRAGMENTS(pkt, frag_nums); + + /* ethertype check is not offload to mcu for fragment frame*/ + if (frag_nums > 1) { + if (!RTMPCheckEtherType(pAd, pkt, &pAd->MacTab.tr_entry[wcid], wdev)) { + return FALSE; + } + } + + return TRUE; +} + +INT ap_tx_pkt_allowed( + RTMP_ADAPTER *pAd, + struct wifi_dev *wdev, + PNDIS_PACKET pkt) +{ + PACKET_INFO pkt_info; + UCHAR *pkt_va; + UINT pkt_len; + MAC_TABLE_ENTRY *entry = NULL; + UCHAR wcid = RESERVED_WCID; + STA_TR_ENTRY *tr_entry = NULL; + UCHAR frag_nums; + + RTMP_QueryPacketInfo(pkt, &pkt_info, &pkt_va, &pkt_len); + + if ((!pkt_va) || (pkt_len <= 14)) + return FALSE; + +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + + if ((wf_drv_tbl.wf_fwd_needed_hook != NULL) && (wf_drv_tbl.wf_fwd_needed_hook() == TRUE)) { + if (is_looping_packet(pAd, pkt)) + return FALSE; + } + +#endif /* CONFIG_WIFI_PKT_FWD */ + + if (MAC_ADDR_IS_GROUP(pkt_va)) { + if (wdev->PortSecured != WPA_802_1X_PORT_SECURED) + return FALSE; + wcid = wdev->tr_tb_idx; + } else { + entry = MacTableLookup(pAd, pkt_va); + + if (entry && (entry->Sst == SST_ASSOC)){ + wcid = (UCHAR)entry->wcid; + } + } + + tr_entry = &pAd->MacTab.tr_entry[wcid]; + + if (!(VALID_TR_WCID(wcid) && IS_VALID_ENTRY(tr_entry))) + return FALSE; + + RTMP_SET_PACKET_WCID(pkt, wcid); +#ifdef CONFIG_HOTSPOT + + /* Drop broadcast/multicast packet if disable dgaf */ + if (IS_ENTRY_CLIENT(tr_entry)) { + BSS_STRUCT *pMbss = (BSS_STRUCT *)wdev->func_dev; + + if ((wcid == wdev->bss_info_argument.ucBcMcWlanIdx) && + (pMbss->HotSpotCtrl.HotSpotEnable || pMbss->HotSpotCtrl.bASANEnable) && + pMbss->HotSpotCtrl.DGAFDisable) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("Drop broadcast/multicast packet when dgaf disable\n")); + return FALSE; + } + } + +#endif + frag_nums = get_frag_num(pAd, wdev, pkt); + RTMP_SET_PACKET_FRAGMENTS(pkt, frag_nums); + + if (!RTMPCheckEtherType(pAd, pkt, tr_entry, wdev)) { + return FALSE; + } + + if (tr_entry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) { + if (!((IS_AKM_WPA_CAPABILITY_Entry(wdev) +#ifdef DOT1X_SUPPORT + || (IS_IEEE8021X_Entry(wdev)) +#endif /* DOT1X_SUPPORT */ + ) && ((RTMP_GET_PACKET_EAPOL(pkt) || + RTMP_GET_PACKET_WAI(pkt)))) + ) + return FALSE; + } + +#ifdef CFG80211_SUPPORT + + /* CFG_TODO: POS NO GOOD */ + if (pAd->cfg80211_ctrl.isCfgInApMode == RT_CMD_80211_IFTYPE_AP) + RTMP_SET_PACKET_OPMODE(pkt, OPMODE_AP); + +#endif /* CFG80211_SUPPORT */ + return TRUE; +} + +UCHAR ap_mlme_search_wcid(RTMP_ADAPTER *pAd, UCHAR *addr1, UCHAR *addr2, PNDIS_PACKET pkt) +{ + MAC_TABLE_ENTRY *mac_entry = MacTableLookup(pAd, addr1); + +#ifdef MAC_REPEATER_SUPPORT + REPEATER_CLIENT_ENTRY *rept_entry = NULL; +#endif + +#ifdef MAC_REPEATER_SUPPORT + if ((mac_entry != NULL) && (IS_ENTRY_APCLI(mac_entry) || IS_ENTRY_REPEATER(mac_entry))) { + rept_entry = lookup_rept_entry(pAd, addr2); + + if (rept_entry) { /*repeater case*/ + if ((rept_entry->CliEnable == TRUE) && (rept_entry->CliValid == TRUE)) + mac_entry = &pAd->MacTab.Content[rept_entry->MacTabWCID]; + } else { /*apcli case*/ + UCHAR apcli_wcid = 0; + + if (mac_entry->wdev && (mac_entry->wdev->func_idx < pAd->ApCfg.ApCliNum)) + apcli_wcid = pAd->ApCfg.ApCliTab[mac_entry->wdev->func_idx].MacTabWCID; + else /* use default apcli0 */ + apcli_wcid = pAd->ApCfg.ApCliTab[0].MacTabWCID; + + mac_entry = &pAd->MacTab.Content[apcli_wcid]; + } + } + +#endif + if (mac_entry) + return mac_entry->wcid; + else + return 0; +} + +INT ap_send_mlme_pkt(RTMP_ADAPTER *pAd, PNDIS_PACKET pkt, struct wifi_dev *wdev, UCHAR q_idx, BOOLEAN is_data_queue) +{ + HEADER_802_11 *pHeader_802_11; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->tx_hw_hdr_len; + PACKET_INFO PacketInfo; + UCHAR *pSrcBufVA; + UINT SrcBufLen; + INT ret; + struct qm_ops *ops = pAd->qm_ops; + + RTMP_SET_PACKET_WDEV(pkt, wdev->wdev_idx); + RTMP_SET_PACKET_MGMT_PKT(pkt, 1); + RTMP_QueryPacketInfo(pkt, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + if (pSrcBufVA == NULL) { + RELEASE_NDIS_PACKET(pAd, pkt, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + pHeader_802_11 = (HEADER_802_11 *)(pSrcBufVA + tx_hw_hdr_len); + RTMP_SET_PACKET_WCID(pkt, ap_mlme_search_wcid(pAd, pHeader_802_11->Addr1, pHeader_802_11->Addr2, pkt)); + + if (in_altx_filter_list(pHeader_802_11->FC.SubType)) { + if (!(RTMP_GET_PACKET_TXTYPE(pkt) & TX_ATE_FRAME)) + RTMP_SET_PACKET_TYPE(pkt, TX_ALTX); + } + + if (!is_data_queue) { + } else { +#ifdef UAPSD_SUPPORT + { + UAPSD_MR_QOS_NULL_HANDLE(pAd, pHeader_802_11, pkt); + } + +#endif /* UAPSD_SUPPORT */ + RTMP_SET_PACKET_MGMT_PKT_DATA_QUE(pkt, 1); + } + + ret = ops->enq_mgmtq_pkt(pAd, wdev, pkt); + + return ret; +} + +static INT ap_ps_handle(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, STA_TR_ENTRY *tr_entry, + PNDIS_PACKET pkt, UCHAR q_idx) +{ + struct qm_ctl *qm_ctl = &pAd->qm_ctl; + struct qm_ops *qm_ops = pAd->qm_ops; + UINT16 occupy_cnt = (tr_entry->token_cnt + tr_entry->enqCount); + + if (occupy_cnt >= SQ_ENQ_PS_MAX) { + + if ((tr_entry->ps_queue.Number < SQ_ENQ_PSQ_MAX) && + (qm_ctl->total_psq_cnt < SQ_ENQ_PSQ_TOTAL_MAX)) { + qm_ops->enq_psq_pkt(pAd, wdev, tr_entry, pkt); + qm_ctl->total_psq_cnt++; + } else { + RELEASE_NDIS_PACKET(pAd, pkt, NDIS_STATUS_SUCCESS); + } + } else { + if (tr_entry->ps_queue.Number != 0) { + NDIS_PACKET *ps_pkt = NULL; + UCHAR ps_pkt_q_idx; + UINT16 quota = (SQ_ENQ_PS_MAX - occupy_cnt); + + do { + ps_pkt = qm_ops->get_psq_pkt(pAd, tr_entry); + + if (ps_pkt) { + quota--; + qm_ctl->total_psq_cnt--; + ps_pkt_q_idx = RTMP_GET_PACKET_QUEIDX(ps_pkt); + qm_ops->enq_dataq_pkt(pAd, wdev, ps_pkt, ps_pkt_q_idx); + } + } while (ps_pkt && (quota > 0)); + + if (quota > 0) { + qm_ops->enq_dataq_pkt(pAd, wdev, pkt, q_idx); + } else { + qm_ops->enq_psq_pkt(pAd, wdev, tr_entry, pkt); + qm_ctl->total_psq_cnt++; + } + + } else { + qm_ops->enq_dataq_pkt(pAd, wdev, pkt, q_idx); + } + } + + return NDIS_STATUS_SUCCESS; +} + +INT ap_send_data_pkt(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, PNDIS_PACKET pkt) +{ + UCHAR wcid = RESERVED_WCID; +#ifdef IGMP_SNOOP_SUPPORT + INT InIgmpGroup = IGMP_NONE; + MULTICAST_FILTER_TABLE_ENTRY *pGroupEntry = NULL; +#endif /* IGMP_SNOOP_SUPPORT */ + STA_TR_ENTRY *tr_entry = NULL; + UCHAR user_prio = 0; + UCHAR q_idx; + struct qm_ops *qm_ops = pAd->qm_ops; + struct wifi_dev_ops *wdev_ops = wdev->wdev_ops; + PACKET_INFO pkt_info; + UCHAR *pkt_va; + UINT pkt_len; + + RTMP_QueryPacketInfo(pkt, &pkt_info, &pkt_va, &pkt_len); + wcid = RTMP_GET_PACKET_WCID(pkt); + tr_entry = &pAd->MacTab.tr_entry[wcid]; + user_prio = RTMP_GET_PACKET_UP(pkt); + q_idx = RTMP_GET_PACKET_QUEIDX(pkt); + + if (tr_entry->EntryType != ENTRY_CAT_MCAST) + wdev_ops->detect_wmm_traffic(pAd, wdev, user_prio, FLG_IS_OUTPUT); + else { +#ifdef IGMP_SNOOP_SUPPORT + if (wdev->IgmpSnoopEnable) { + if (IgmpPktInfoQuery(pAd, pkt_va, pkt, wdev, + &InIgmpGroup, &pGroupEntry) != NDIS_STATUS_SUCCESS) + return NDIS_STATUS_FAILURE; + + /* 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)) { + NDIS_STATUS PktCloneResult = IgmpPktClone(pAd, wdev, pkt, InIgmpGroup, pGroupEntry, + q_idx, user_prio, GET_OS_PKT_NETDEV(pkt)); + RELEASE_NDIS_PACKET(pAd, pkt, NDIS_STATUS_SUCCESS); + return PktCloneResult; + } + + RTMP_SET_PACKET_TXTYPE(pkt, TX_MCAST_FRAME); + } else +#endif /* IGMP_SNOOP_SUPPORT */ + RTMP_SET_PACKET_TXTYPE(pkt, TX_MCAST_FRAME); + } + + RTMP_SET_PACKET_UP(pkt, user_prio); + + RTMP_SEM_LOCK(&tr_entry->ps_sync_lock); + + if (tr_entry->ps_state == PWR_ACTIVE) + qm_ops->enq_dataq_pkt(pAd, wdev, pkt, q_idx); + else + ap_ps_handle(pAd, wdev, tr_entry, pkt, q_idx); + + RTMP_SEM_UNLOCK(&tr_entry->ps_sync_lock); + + ba_ori_session_start(pAd, tr_entry, user_prio); + 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_11WEPEnabled but the key will use PairwiseKey + Instead of the SharedKey, SharedKey Length may be Zero. +*/ +VOID ap_find_cipher_algorithm(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + MAC_TABLE_ENTRY *pMacEntry = pTxBlk->pMacEntry; + + /* TODO:Eddy, Confirm MESH/Apcli.WAPI */ + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) { + SET_CIPHER_NONE(pTxBlk->CipherAlg); + pTxBlk->pKey = NULL; + } else if (pTxBlk->TxFrameType == TX_MCAST_FRAME) { + pTxBlk->CipherAlg = wdev->SecConfig.GroupCipher; + pTxBlk->KeyIdx = wdev->SecConfig.GroupKeyId; + + if (IS_CIPHER_WEP(wdev->SecConfig.GroupCipher)) + pTxBlk->pKey = wdev->SecConfig.WepKey[pTxBlk->KeyIdx].Key; + else + pTxBlk->pKey = wdev->SecConfig.GTK; + } else if (pMacEntry) { + pTxBlk->CipherAlg = pMacEntry->SecConfig.PairwiseCipher; + pTxBlk->KeyIdx = pMacEntry->SecConfig.PairwiseKeyId; + + if (IS_CIPHER_WEP(pMacEntry->SecConfig.PairwiseCipher)) + pTxBlk->pKey = pMacEntry->SecConfig.WepKey[pTxBlk->KeyIdx].Key; + else if (IS_AKM_SHA384(pMacEntry->SecConfig.AKMMap)) + pTxBlk->pKey = &pMacEntry->SecConfig.PTK[LEN_PTK_KCK_SHA384 + LEN_PTK_KEK_SHA384]; + else + pTxBlk->pKey = &pMacEntry->SecConfig.PTK[LEN_PTK_KCK + LEN_PTK_KEK]; + } + + /* For BMcast pMacEntry is not initial */ + if (pTxBlk->CipherAlg == 0x0) + SET_CIPHER_NONE(pTxBlk->CipherAlg); +} + +static inline VOID ap_build_cache_802_11_header( + IN RTMP_ADAPTER *pAd, + IN TX_BLK *pTxBlk, + IN UCHAR *pHeader) +{ + STA_TR_ENTRY *tr_entry; + HEADER_802_11 *pHeader80211; + MAC_TABLE_ENTRY *pMacEntry; + + pHeader80211 = (PHEADER_802_11)pHeader; + pMacEntry = pTxBlk->pMacEntry; + tr_entry = pTxBlk->tr_entry; + /* + Update the cached 802.11 HEADER + */ + /* normal wlan header size : 24 octets */ + pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11); + pTxBlk->wifi_hdr_len = sizeof(HEADER_802_11); + /* More Bit */ + pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData); + /* Sequence */ + pHeader80211->Sequence = tr_entry->TxSeq[pTxBlk->UserPriority]; + tr_entry->TxSeq[pTxBlk->UserPriority] = (tr_entry->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; + pTxBlk->wifi_hdr_len += MAC_ADDR_LEN; + } else +#endif /* WDS_SUPPORT || CLIENT_WDS */ +#ifdef APCLI_SUPPORT + if (IS_ENTRY_APCLI(pMacEntry) || IS_ENTRY_REPEATER(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); + } +} + +static inline VOID ap_build_802_11_header(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk) +{ + HEADER_802_11 *wifi_hdr; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->tx_hw_hdr_len; + struct wifi_dev *wdev = pTxBlk->wdev; + STA_TR_ENTRY *tr_entry = pTxBlk->tr_entry; + /* + MAKE A COMMON 802.11 HEADER + */ + /* normal wlan header size : 24 octets */ + pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11); + pTxBlk->wifi_hdr_len = sizeof(HEADER_802_11); + /* TODO: shiang-7603 */ + pTxBlk->wifi_hdr = &pTxBlk->HeaderBuf[tx_hw_hdr_len]; + wifi_hdr = (HEADER_802_11 *)pTxBlk->wifi_hdr; + NdisZeroMemory(wifi_hdr, sizeof(HEADER_802_11)); + wifi_hdr->FC.FrDs = 1; + wifi_hdr->FC.Type = FC_TYPE_DATA; + wifi_hdr->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA); + + /* TODO: shiang-usw, for BCAST/MCAST, original it's sequence assigned by "pAd->Sequence", how about now? */ + if (tr_entry) { + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { + wifi_hdr->Sequence = tr_entry->TxSeq[pTxBlk->UserPriority]; + tr_entry->TxSeq[pTxBlk->UserPriority] = (tr_entry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ; + } else { + wifi_hdr->Sequence = tr_entry->NonQosDataSeq; + tr_entry->NonQosDataSeq = (tr_entry->NonQosDataSeq + 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 */ +#ifdef MAC_REPEATER_SUPPORT + + if (pTxBlk->pMacEntry && (pTxBlk->pMacEntry->bReptCli == TRUE)) + COPY_MAC_ADDR(wifi_hdr->Addr2, pTxBlk->pMacEntry->ReptCliAddr); + else +#endif /* MAC_REPEATER_SUPPORT */ + COPY_MAC_ADDR(wifi_hdr->Addr2, pTxBlk->pApCliEntry->wdev.if_addr); /* 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) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s pTxBlk->pMacEntry == NULL!\n", __func__)); + 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; + pTxBlk->wifi_hdr_len += 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 */ +#if defined(IGMP_SNOOP_SUPPORT) || defined(DOT11V_WNM_SUPPORT) + if (pTxBlk->tr_entry->EntryType != ENTRY_CAT_MCAST) { + COPY_MAC_ADDR(wifi_hdr->Addr1, pTxBlk->pMacEntry->Addr); /* DA */ + } else +#endif /* defined(IGMP_SNOOP_SUPPORT) || defined(DOT11V_WNM_SUPPORT) */ + { + COPY_MAC_ADDR(wifi_hdr->Addr1, pTxBlk->pSrcBufHeader); + } + + COPY_MAC_ADDR(wifi_hdr->Addr2, pAd->ApCfg.MBSSID[wdev->func_idx].wdev.bssid); /* BSSID */ + COPY_MAC_ADDR(wifi_hdr->Addr3, pTxBlk->pSrcBufHeader + MAC_ADDR_LEN); /* SA */ + } + + + if (!IS_CIPHER_NONE(pTxBlk->CipherAlg)) + wifi_hdr->FC.Wep = 1; + + pTxBlk->dot11_type = wifi_hdr->FC.Type; + pTxBlk->dot11_subtype = wifi_hdr->FC.SubType; +} + +BOOLEAN ap_fill_non_offload_tx_blk(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + PACKET_INFO PacketInfo; + PNDIS_PACKET pPacket; + MAC_TABLE_ENTRY *pMacEntry = NULL; + struct wifi_dev_ops *ops = wdev->wdev_ops; + + pPacket = pTxBlk->pPacket; + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); + pTxBlk->wmm_set = HcGetWmmIdx(pAd, wdev); + pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket); + pTxBlk->FrameGap = IFS_HTTXOP; + pTxBlk->pMbss = NULL; + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader; + + if (IS_ASIC_CAP(pAd, fASIC_CAP_TX_HDR_TRANS)) { + if ((pTxBlk->TxFrameType == TX_LEGACY_FRAME) || + (pTxBlk->TxFrameType == TX_AMSDU_FRAME) || + (pTxBlk->TxFrameType == TX_MCAST_FRAME)) + TX_BLK_SET_FLAG(pTxBlk, fTX_HDR_TRANS); + } + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); + else + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame); + + + if (pTxBlk->tr_entry->EntryType == ENTRY_CAT_MCAST) { + pTxBlk->pMacEntry = NULL; + TX_BLK_SET_FLAG(pTxBlk, fTX_ForceRate); + { +#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_TO_REMOVE].HTPhyMode; + + if (pTxBlk->wdev->channel > 14) { + pTxBlk->pTransmit->field.MODE = MODE_OFDM; + pTxBlk->pTransmit->field.MCS = MCS_RATE_6; + } + } + } + /* AckRequired = FALSE, when broadcast packet in Adhoc mode.*/ + TX_BLK_CLEAR_FLAG(pTxBlk, (fTX_bAckRequired | fTX_bAllowFrag | 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; + + if (!pMacEntry) + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():Err!! pMacEntry is NULL!!\n", __func__)); + else + pTxBlk->pMbss = pMacEntry->pMbss; + +#ifdef MULTI_WMM_SUPPORT + + if (IS_ENTRY_APCLI(pMacEntry)) + pTxBlk->QueIdx = EDCA_WMM1_AC0_PIPE; + +#endif /* MULTI_WMM_SUPPORT */ + /* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.*/ +#ifdef MULTI_WMM_SUPPORT + + if (pTxBlk->QueIdx >= EDCA_WMM1_AC0_PIPE) { + if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx - EDCA_WMM1_AC0_PIPE] != NORMAL_ACK) + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); + else + TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); + } else +#endif /* MULTI_WMM_SUPPORT */ + { + if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK) + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); + else + TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); + } + + { +#if defined(P2P_SUPPORT) || defined(RT_CFG80211_P2P_SUPPORT) || defined(CFG80211_MULTI_STA) + + if (pTxBlk->OpMode == OPMODE_AP) +#else + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) +#endif /* P2P_SUPPORT || RT_CFG80211_P2P_SUPPORT*/ + { +#ifdef WDS_SUPPORT + + if (IS_ENTRY_WDS(pMacEntry)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bWDSEntry); + else +#endif /* WDS_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; + UCHAR idx = pMacEntry->func_tb_idx; + + if (((idx < MAX_MBSSID_NUM(pAd)) + && !MAC_ADDR_EQUAL(pSA, pAd->ApCfg.MBSSID[idx].Bssid)) + || !MAC_ADDR_EQUAL(pDA, pMacEntry->Addr) + ) + TX_BLK_SET_FLAG(pTxBlk, fTX_bClientWDSFrame); + } else +#endif /* CLIENT_WDS */ + if (pMacEntry && 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); + } + } + + if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) { + if (((RTMP_GET_PACKET_LOWRATE(pPacket)) +#ifdef UAPSD_SUPPORT + && (!(pMacEntry && (pMacEntry->bAPSDFlagSPStart))) +#endif /* UAPSD_SUPPORT */ + ) || + ((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_TO_REMOVE].HTPhyMode; + TX_BLK_SET_FLAG(pTxBlk, fTX_ForceRate); + + /* 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 (!pTxBlk->pMacEntry) + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():Err!! pTxBlk->pMacEntry is NULL!!\n", __func__)); + else 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); + } + + 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); + } + + 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++; + +#ifdef IGMP_SNOOP_SUPPORT + if (RTMP_GET_PACKET_MCAST_CLONE(pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_MCAST_CLONE); +#endif + + } + + pAd->LastTxRate = (USHORT)pTxBlk->pTransmit->word; + ops->find_cipher_algorithm(pAd, wdev, pTxBlk); + return TRUE; +} + +BOOLEAN ap_fill_offload_tx_blk(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + PACKET_INFO PacketInfo; + PNDIS_PACKET pPacket; + + pPacket = pTxBlk->pPacket; + pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + + if (RTMP_GET_PACKET_MGMT_PKT(pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_CT_WithTxD); + + if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pPacket)) + TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); + + if (IS_ASIC_CAP(pAd, fASIC_CAP_TX_HDR_TRANS)) { + if ((pTxBlk->TxFrameType == TX_LEGACY_FRAME) || + (pTxBlk->TxFrameType == TX_AMSDU_FRAME) || + (pTxBlk->TxFrameType == TX_MCAST_FRAME)) + TX_BLK_SET_FLAG(pTxBlk, fTX_HDR_TRANS); + } + + pTxBlk->wmm_set = HcGetWmmIdx(pAd, wdev); + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader; + /*get MBSS for tx counter usage*/ + if (pTxBlk->TxFrameType != TX_MCAST_FRAME) + pTxBlk->pMbss = pTxBlk->pMacEntry->pMbss; + return TRUE; +} + +INT ap_mlme_mgmtq_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *tx_blk) +{ + PQUEUE_ENTRY q_entry; + UCHAR *tmac_info; + HTTRANSMIT_SETTING *transmit; + UCHAR MlmeRate; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->tx_hw_hdr_len; + PHEADER_802_11 pHeader_802_11; + MAC_TABLE_ENTRY *pMacEntry = tx_blk->pMacEntry; + RTMP_ARCH_OP *op = &pAd->archOps; + struct dev_rate_info *rate; + BOOLEAN bAckRequired, bInsertTimestamp; + UCHAR PID, wcid = tx_blk->Wcid, tx_rate; + UCHAR prot = 0; + UCHAR apidx = 0; + MAC_TX_INFO mac_info; + struct DOT11_H *pDot11h = NULL; + + if (wdev == NULL) + return NDIS_STATUS_FAILURE; + + pDot11h = wdev->pDot11_H; + if (pDot11h == NULL) + return NDIS_STATUS_FAILURE; + + q_entry = RemoveHeadQueue(&tx_blk->TxPacketList); + tx_blk->pPacket = QUEUE_ENTRY_TO_PACKET(q_entry); + ap_fill_offload_tx_blk(pAd, wdev, tx_blk); + tmac_info = tx_blk->pSrcBufHeader; + pHeader_802_11 = (HEADER_802_11 *)(tx_blk->pSrcBufHeader + tx_hw_hdr_len); + + if (pHeader_802_11->Addr1[0] & 0x01) + MlmeRate = pAd->CommonCfg.BasicMlmeRate; + else + MlmeRate = pAd->CommonCfg.MlmeRate; + + /* Verify Mlme rate for a / g bands.*/ + if ((wdev->channel > 14) && (MlmeRate < RATE_6)) /* 11A band*/ + MlmeRate = RATE_6; + + rate = &wdev->rate; + pHeader_802_11->FC.MoreData = RTMP_GET_PACKET_MOREDATA(tx_blk->pPacket); + bInsertTimestamp = FALSE; + + if (pHeader_802_11->FC.Type == FC_TYPE_CNTL) { /* must be PS-POLL*/ + bAckRequired = FALSE; +#ifdef VHT_TXBF_SUPPORT + + if (pHeader_802_11->FC.SubType == SUBTYPE_VHT_NDPA) { + pHeader_802_11->Duration = 100; + } + +#endif /* VHT_TXBF_SUPPORT */ + } else { /* FC_TYPE_MGMT or FC_TYPE_DATA(must be NULL frame)*/ + if (pHeader_802_11->Addr1[0] & 0x01) { /* MULTICAST, BROADCAST*/ + bAckRequired = FALSE; + pHeader_802_11->Duration = 0; + } else { +#ifdef SOFT_SOUNDING + + if (((pHeader_802_11->FC.Type == FC_TYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) + && pMacEntry && (pMacEntry->snd_reqired == TRUE)) { + bAckRequired = FALSE; + pHeader_802_11->Duration = 0; + } else +#endif /* SOFT_SOUNDING */ + { + bAckRequired = TRUE; + pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); + + if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) && (pHeader_802_11->FC.Type == FC_TYPE_MGMT)) { + bInsertTimestamp = TRUE; + bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Response*/ +#ifdef SPECIFIC_TX_POWER_SUPPORT + /* Find which MBSSID to be send this probeRsp */ + UINT32 apidx = get_apidx_by_addr(pAd, pHeader_802_11->Addr2); + + if (!(apidx >= pAd->ApCfg.BssidNum) && + (pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) && + (rate->MlmeTransmit.field.MODE == MODE_CCK) && + (rate->MlmeTransmit.field.MCS == RATE_1)) + TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj; + +#endif /* SPECIFIC_TX_POWER_SUPPORT */ + } else if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) && (pHeader_802_11->FC.Type == FC_TYPE_MGMT)) { + bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Request*/ + } else if ((pHeader_802_11->FC.SubType == SUBTYPE_DEAUTH) && + (pMacEntry == NULL)) { + bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Deauth */ + } + } + } + } + + 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) + && (pDot11h->RDMode != RD_NORMAL_MODE)) { + RELEASE_NDIS_PACKET(pAd, tx_blk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + /* + 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 + + management frame doesn't need encryption. + so use RESERVED_WCID no matter u are sending to specific wcid or not + */ + PID = PID_MGMT; +#ifdef DOT11W_PMF_SUPPORT + PMF_PerformTxFrameAction(pAd, pHeader_802_11, tx_blk->SrcBufLen, tx_hw_hdr_len, &prot); +#endif + + if (pMacEntry) { + wcid = pMacEntry->wcid; + } else { + wcid = 0; + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("pMacEntry is null !!\n")); + } + + tx_rate = (UCHAR)rate->MlmeTransmit.field.MCS; + transmit = &rate->MlmeTransmit; + + NdisZeroMemory((UCHAR *)&mac_info, sizeof(mac_info)); + + if (prot) + mac_info.prot = prot; + + if (prot == 2 || prot == 3) + mac_info.bss_idx = apidx; + + mac_info.FRAG = FALSE; + mac_info.CFACK = FALSE; + mac_info.InsTimestamp = bInsertTimestamp; + mac_info.AMPDU = FALSE; + mac_info.Ack = bAckRequired; + mac_info.BM = IS_BM_MAC_ADDR(pHeader_802_11->Addr1); + mac_info.NSeq = FALSE; + mac_info.BASize = 0; + mac_info.WCID = wcid; + mac_info.Type = pHeader_802_11->FC.Type; + mac_info.SubType = pHeader_802_11->FC.SubType; + mac_info.PsmBySw = 1; + if (pAd->CommonCfg.bSeOff != TRUE) { + if (HcGetBandByWdev(wdev) == BAND0) + mac_info.AntPri = BAND0_SPE_IDX; + else if (HcGetBandByWdev(wdev) == BAND1) { + mac_info.AntPri = BAND1_SPE_IDX; + } + } + /* check if the pkt is Tmr frame. */ +#ifdef FTM_SUPPORT + + if (IsPublicActionFrame(pAd, pHeader_802_11)) { + PFTM_PEER_ENTRY pFtmEntry = FtmEntrySearch(pAd, pHeader_802_11->Addr1); + + if (pFtmEntry && pFtmEntry->bNeedTmr) { + mac_info.IsTmr = TRUE; + PID = FtmGetNewPid(pAd); + FtmAddPidPendingNode(pAd, pFtmEntry, PID); + mac_info.ftm_bw = pFtmEntry->VerdictParm.ftm_format_and_bw; + pFtmEntry->bTxOK = 0; /* init value */ + pFtmEntry->bTxSCallbackCheck = 1; + RTMPSetTimer(&pFtmEntry->FtmTxTimer, 30); + pFtmEntry->bNeedTmr = FALSE; + } + } + +#endif /* FTM_SUPPORT */ + mac_info.Length = (tx_blk->SrcBufLen - tx_hw_hdr_len); + + if (pHeader_802_11->FC.Type == FC_TYPE_MGMT) { + mac_info.hdr_len = 24; + + if (pHeader_802_11->FC.Order == 1) + mac_info.hdr_len += 4; + } else if (pHeader_802_11->FC.Type == FC_TYPE_DATA) { + switch (pHeader_802_11->FC.SubType) { + case SUBTYPE_DATA_NULL: + mac_info.hdr_len = 24; + tx_rate = (UCHAR)rate->MlmeTransmit.field.MCS; + transmit = &rate->MlmeTransmit; + break; + + case SUBTYPE_QOS_NULL: + mac_info.hdr_len = 26; + tx_rate = (UCHAR)rate->MlmeTransmit.field.MCS; + transmit = &rate->MlmeTransmit; + break; + + default: + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): FIXME!!!Unexpected frame(Type=%d, SubType=%d) send to MgmtRing, need to assign the length!\n", + __func__, pHeader_802_11->FC.Type, pHeader_802_11->FC.SubType)); + hex_dump("DataFrame", (char *)pHeader_802_11, 24); + break; + } + + if (pMacEntry && pAd->MacTab.tr_entry[wcid].PsDeQWaitCnt) + PID = PID_PS_DATA; + + mac_info.WCID = wcid; + } else if (pHeader_802_11->FC.Type == FC_TYPE_CNTL) { + switch (pHeader_802_11->FC.SubType) { + case SUBTYPE_PS_POLL: + mac_info.hdr_len = sizeof(PSPOLL_FRAME); + tx_rate = (UCHAR)rate->MlmeTransmit.field.MCS; + transmit = &rate->MlmeTransmit; + break; + + default: + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): FIXME!!!Unexpected frame(Type=%d, SubType=%d) send to MgmtRing, need to assign the length!\n", + __func__, pHeader_802_11->FC.Type, pHeader_802_11->FC.SubType)); + break; + } + } else { + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): FIXME!!!Unexpected frame send to MgmtRing, need to assign the length!\n", + __func__)); + } + + mac_info.PID = PID; + mac_info.TID = 0; + mac_info.TxRate = tx_rate; + mac_info.SpeEn = 1; + mac_info.Preamble = LONG_PREAMBLE; + mac_info.IsAutoRate = FALSE; + mac_info.wmm_set = HcGetWmmIdx(pAd, wdev); + mac_info.q_idx = HcGetMgmtQueueIdx(pAd, wdev, RTMP_GET_PACKET_TYPE(tx_blk->pPacket)); + + if (pMacEntry && IS_ENTRY_REPEATER(pMacEntry)) + mac_info.OmacIdx = pAd->MacTab.tr_entry[pMacEntry->wcid].OmacIdx; + else + mac_info.OmacIdx = wdev->OmacIdx; + + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s(): %d, WMMSET=%d,QId=%d\n", + __func__, __LINE__, mac_info.wmm_set, mac_info.q_idx)); +#ifdef CONFIG_MULTI_CHANNEL + + if (pAd->Mlme.bStartMcc == TRUE) { + if ((NdisEqualMemory(pAd->cfg80211_ctrl.P2PCurrentAddress, pHeader_802_11->Addr2, MAC_ADDR_LEN)) + || (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)) + mac_info.q_idx = Q_IDX_AC10; + else + mac_info.q_idx = Q_IDX_AC0; + } + +#endif /* CONFIG_MULTI_CHANNEL */ +#ifdef APCLI_SUPPORT + + if ((pHeader_802_11->FC.Type == FC_TYPE_DATA) + && ((pHeader_802_11->FC.SubType == SUBTYPE_DATA_NULL) || (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))) { + if ((pMacEntry != NULL) && (IS_ENTRY_APCLI(pMacEntry) +#ifdef MAC_REPEATER_SUPPORT + || IS_ENTRY_REPEATER(pMacEntry) +#endif /* MAC_REPEATER_SUPPORT */ + )) { + /* CURRENT_BW_TX_CNT/CURRENT_BW_FAIL_CNT only count for aute rate */ + if (IS_MT7615(pAd) || IS_MT7622(pAd) || IS_P18(pAd) || IS_MT7663(pAd)) + mac_info.IsAutoRate = TRUE; + } + } + +#endif /* APCLI_SUPPORT */ +#ifdef SOFT_SOUNDING + + if (((pHeader_802_11->FC.Type == FC_TYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) + && pMacEntry && (pMacEntry->snd_reqired == TRUE)) { + wcid = RESERVED_WCID; + tx_rate = (UCHAR)pMacEntry->snd_rate.field.MCS; + transmit = &pMacEntry->snd_rate; + mac_info.Txopmode = IFS_PIFS; + pMacEntry->snd_reqired = FALSE; + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s():Kick Sounding to %02x:%02x:%02x:%02x:%02x:%02x, dataRate(PhyMode:%s, BW:%sHz, %dSS, MCS%d)\n", + __func__, PRINT_MAC(pMacEntry->Addr), + get_phymode_str(transmit->field.MODE), + get_bw_str(transmit->field.BW), + (transmit->field.MCS>>4) + 1, (transmit->field.MCS & 0xf))); + } else +#endif /* SOFT_SOUNDING */ + { + mac_info.Txopmode = IFS_BACKOFF; + } + + /* if we are going to send out FTM action. enable CR to report TMR report.*/ + if ((pAd->pTmrCtrlStruct != NULL) && (pAd->pTmrCtrlStruct->TmrEnable != TMR_DISABLE)) { + if (mac_info.IsTmr == TRUE) { + /* Leo: already set at TmrCtrlInit() MtSetTmrCR(pAd, TMR_INITIATOR); */ + pAd->pTmrCtrlStruct->TmrState = SEND_OUT; + } + } + + return op->mlme_hw_tx(pAd, tmac_info, &mac_info, transmit, tx_blk); +} + +INT ap_mlme_dataq_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *tx_blk) +{ + PQUEUE_ENTRY q_entry; + UCHAR *tmac_info, *frm_buf; + UINT frm_len; +#ifdef RT_BIG_ENDIAN + TXD_STRUC *pDestTxD; + UCHAR hw_hdr_info[TXD_SIZE]; +#endif + PHEADER_802_11 pHeader_802_11; + PFRAME_BAR pBar = NULL; + BOOLEAN bAckRequired, bInsertTimestamp; + UCHAR MlmeRate, wcid = tx_blk->Wcid, tx_rate; + MAC_TABLE_ENTRY *pMacEntry = tx_blk->pMacEntry; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->tx_hw_hdr_len; + HTTRANSMIT_SETTING *transmit, TransmitSetting; + MAC_TX_INFO mac_info; + RTMP_ARCH_OP *op = &pAd->archOps; +#ifdef SPECIFIC_TX_POWER_SUPPORT + UCHAR TxPwrAdj = 0; +#endif /* SPECIFIC_TX_POWER_SUPPORT */ + struct dev_rate_info *rate; + struct DOT11_H *pDot11h = NULL; + + if (wdev == NULL) + return NDIS_STATUS_FAILURE; + + pDot11h = wdev->pDot11_H; + if (pDot11h == NULL) + return NDIS_STATUS_FAILURE; + + q_entry = RemoveHeadQueue(&tx_blk->TxPacketList); + tx_blk->pPacket = QUEUE_ENTRY_TO_PACKET(q_entry); + ap_fill_offload_tx_blk(pAd, wdev, tx_blk); + pHeader_802_11 = (HEADER_802_11 *)(tx_blk->pSrcBufHeader + tx_hw_hdr_len); + + rate = &wdev->rate; + frm_buf = tx_blk->pSrcBufHeader; + frm_len = tx_blk->SrcBufLen; + tmac_info = tx_blk->pSrcBufHeader; + + if (pHeader_802_11->Addr1[0] & 0x01) + MlmeRate = pAd->CommonCfg.BasicMlmeRate; + else + MlmeRate = pAd->CommonCfg.MlmeRate; + + /* Verify Mlme rate for a/g bands.*/ + if ((wdev->channel > 14) && (MlmeRate < RATE_6)) { /* 11A band*/ + MlmeRate = RATE_6; + transmit = &rate->MlmeTransmit; + transmit->field.MCS = MCS_RATE_6; + transmit->field.MODE = MODE_OFDM; + } + + /* + 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. + */ + /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */ + bInsertTimestamp = FALSE; + + if (pHeader_802_11->FC.Type == FC_TYPE_CNTL) { + if (pHeader_802_11->FC.SubType == SUBTYPE_BLOCK_ACK_REQ) { + pBar = (PFRAME_BAR)(tx_blk->pSrcBufHeader + tx_hw_hdr_len); + bAckRequired = TRUE; + } else + bAckRequired = FALSE; + +#ifdef VHT_TXBF_SUPPORT + + if (pHeader_802_11->FC.SubType == SUBTYPE_VHT_NDPA) { + pHeader_802_11->Duration = + RTMPCalcDuration(pAd, MlmeRate, (tx_blk->SrcBufLen - TXINFO_SIZE - cap->TXWISize - TSO_SIZE)); + } +#endif /* VHT_TXBF_SUPPORT*/ + } else { /* FC_TYPE_MGMT or FC_TYPE_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) { + bInsertTimestamp = TRUE; + bAckRequired = FALSE; +#ifdef SPECIFIC_TX_POWER_SUPPORT + /* Find which MBSSID to be send this probeRsp */ + UINT32 apidx = get_apidx_by_addr(pAd, pHeader_802_11->Addr2); + + if (!(apidx >= pAd->ApCfg.BssidNum) && + (pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) && + (rate->MlmeTransmit.field.MODE == MODE_CCK) && + (rate->MlmeTransmit.field.MCS == RATE_1)) + TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj; + +#endif /* SPECIFIC_TX_POWER_SUPPORT */ + } + } + } + + 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) + && (pDot11h->RDMode != RD_NORMAL_MODE)) { + MTWF_LOG(DBG_CAT_HIF, CATHIF_PCI, DBG_LVL_ERROR, ("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); + RELEASE_NDIS_PACKET(pAd, tx_blk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + if (pMacEntry) { + wcid = pMacEntry->wcid; + } else { + wcid = 0; + MTWF_LOG(DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("pMacEntry is null !!\n")); + } + + tx_rate = (UCHAR)rate->MlmeTransmit.field.MCS; + transmit = &rate->MlmeTransmit; + NdisZeroMemory((UCHAR *)&mac_info, sizeof(mac_info)); + mac_info.FRAG = FALSE; + mac_info.CFACK = FALSE; + mac_info.InsTimestamp = bInsertTimestamp; + mac_info.AMPDU = FALSE; + mac_info.BM = IS_BM_MAC_ADDR(pHeader_802_11->Addr1); + mac_info.Ack = bAckRequired; + mac_info.NSeq = FALSE; + mac_info.BASize = 0; + mac_info.WCID = wcid; + mac_info.TID = 0; + mac_info.wmm_set = HcGetWmmIdx(pAd, wdev); + mac_info.q_idx = HcGetMgmtQueueIdx(pAd, wdev, RTMP_GET_PACKET_TYPE(tx_blk->pPacket)); + if (pAd->CommonCfg.bSeOff != TRUE) { + if (HcGetBandByWdev(wdev) == BAND0) + mac_info.AntPri = BAND0_SPE_IDX; + else if (HcGetBandByWdev(wdev) == BAND1) + mac_info.AntPri = BAND1_SPE_IDX; + } + if (pMacEntry && IS_ENTRY_REPEATER(pMacEntry)) + mac_info.OmacIdx = pAd->MacTab.tr_entry[pMacEntry->wcid].OmacIdx; + else + mac_info.OmacIdx = wdev->OmacIdx; + + mac_info.Type = pHeader_802_11->FC.Type; + mac_info.SubType = pHeader_802_11->FC.SubType; + mac_info.Length = (tx_blk->SrcBufLen - tx_hw_hdr_len); + + if (pHeader_802_11->FC.Type == FC_TYPE_MGMT) { + mac_info.hdr_len = 24; + + if (pHeader_802_11->FC.Order == 1) + mac_info.hdr_len += 4; + + mac_info.PID = PID_MGMT; + +#ifdef DOT11W_PMF_SUPPORT + PMF_PerformTxFrameAction(pAd, pHeader_802_11, tx_blk->SrcBufLen, tx_hw_hdr_len, &mac_info.prot); +#endif + } else if (pHeader_802_11->FC.Type == FC_TYPE_DATA) { + switch (pHeader_802_11->FC.SubType) { + case SUBTYPE_DATA_NULL: + mac_info.hdr_len = 24; + tx_rate = (UCHAR)rate->MlmeTransmit.field.MCS; + transmit = &rate->MlmeTransmit; + break; + + case SUBTYPE_QOS_NULL: + mac_info.hdr_len = 26; + tx_rate = (UCHAR)rate->MlmeTransmit.field.MCS; + transmit = &rate->MlmeTransmit; + break; + + default: + MTWF_LOG(DBG_CAT_HIF, CATHIF_PCI, DBG_LVL_ERROR, ("%s(): FIXME!!!Unexpected frame(Type=%d, SubType=%d) send to MgmtRing, need to assign the length!\n", + __func__, pHeader_802_11->FC.Type, pHeader_802_11->FC.SubType)); + hex_dump("DataFrame", frm_buf, frm_len); + break; + } + + mac_info.WCID = wcid; + + if (pMacEntry && pAd->MacTab.tr_entry[wcid].PsDeQWaitCnt) + mac_info.PID = PID_PS_DATA; + else + mac_info.PID = PID_MGMT; + } else if (pHeader_802_11->FC.Type == FC_TYPE_CNTL) { + switch (pHeader_802_11->FC.SubType) { + case SUBTYPE_BLOCK_ACK_REQ: + mac_info.PID = PID_CTL_BAR; + mac_info.hdr_len = 16; + mac_info.SpeEn = 0; + mac_info.TID = pBar->BarControl.TID; + + if (wdev->channel > 14) { + /* 5G */ + TransmitSetting.field.MODE = MODE_OFDM; + } else { + /* 2.4G */ + TransmitSetting.field.MODE = MODE_CCK; + } + + TransmitSetting.field.BW = BW_20; + TransmitSetting.field.STBC = 0; + TransmitSetting.field.ShortGI = 0; + TransmitSetting.field.MCS = 0; + TransmitSetting.field.ldpc = 0; + transmit = &TransmitSetting; + break; + + default: + MTWF_LOG(DBG_CAT_HIF, CATHIF_PCI, DBG_LVL_ERROR, + ("%s(): FIXME!!!Unexpected frame(Type=%d, SubType=%d) send to MgmtRing, need to assign the length!\n", + __func__, pHeader_802_11->FC.Type, pHeader_802_11->FC.SubType)); + hex_dump("Control Frame", frm_buf, frm_len); + break; + } + } + + mac_info.TxRate = tx_rate; + mac_info.Txopmode = IFS_BACKOFF; + mac_info.SpeEn = 1; + mac_info.Preamble = LONG_PREAMBLE; + mac_info.IsAutoRate = FALSE; +#ifdef APCLI_SUPPORT + + if ((pHeader_802_11->FC.Type == FC_TYPE_DATA) + && ((pHeader_802_11->FC.SubType == SUBTYPE_DATA_NULL) || (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))) { + if ((pMacEntry != NULL) && (IS_ENTRY_APCLI(pMacEntry) +#ifdef MAC_REPEATER_SUPPORT + || IS_ENTRY_REPEATER(pMacEntry) +#endif /* MAC_REPEATER_SUPPORT */ + )) { + /* CURRENT_BW_TX_CNT/CURRENT_BW_FAIL_CNT only count for aute rate */ + mac_info.IsAutoRate = TRUE; + } + } + +#endif /* APCLI_SUPPORT */ + return op->mlme_hw_tx(pAd, tmac_info, &mac_info, transmit, tx_blk); +} + +INT ap_ampdu_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + HEADER_802_11 *wifi_hdr; + UCHAR *pHeaderBufPtr = NULL, *src_ptr; + USHORT freeCnt = 1; + BOOLEAN bVLANPkt; + MAC_TABLE_ENTRY *pMacEntry; + STA_TR_ENTRY *tr_entry; + PQUEUE_ENTRY pQEntry; +#ifndef MT_MAC + BOOLEAN bHTCPlus = FALSE; +#endif /* !MT_MAC */ + UINT hdr_offset, cache_sz = 0; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 TXWISize = cap->TXWISize; + UINT8 tx_hw_hdr_len = cap->tx_hw_hdr_len; + + ASSERT(pTxBlk); + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + + if (!fill_tx_blk(pAd, wdev, pTxBlk)) { + + ap_tx_drop_update(pAd, wdev, pTxBlk); + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + pMacEntry = pTxBlk->pMacEntry; + tr_entry = pTxBlk->tr_entry; + + if (!TX_BLK_TEST_FLAG(pTxBlk, fTX_HDR_TRANS)) { + if (IS_HIF_TYPE(pAd, HIF_MT)) + hdr_offset = tx_hw_hdr_len; + else + hdr_offset = TXINFO_SIZE + TXWISize + TSO_SIZE; + + if ((tr_entry->isCached) +#ifdef TXBF_SUPPORT +#ifndef MT_MAC + && (pMacEntry->TxSndgType == SNDG_TYPE_DISABLE) +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + ) { +#ifndef VENDOR_FEATURE1_SUPPORT + NdisMoveMemory((UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), + (UCHAR *)(&tr_entry->CachedBuf[0]), + TXWISize + sizeof(HEADER_802_11)); +#else + pTxBlk->HeaderBuf = (UCHAR *)(tr_entry->HeaderBuf); +#endif /* VENDOR_FEATURE1_SUPPORT */ + pHeaderBufPtr = (UCHAR *)(&pTxBlk->HeaderBuf[hdr_offset]); + ap_build_cache_802_11_header(pAd, pTxBlk, pHeaderBufPtr); +#ifdef SOFT_ENCRYPT + RTMPUpdateSwCacheCipherInfo(pAd, pTxBlk, pHeaderBufPtr); +#endif /* SOFT_ENCRYPT */ + } else { + ap_build_802_11_header(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 */ + wifi_hdr = (HEADER_802_11 *)pHeaderBufPtr; + /* skip common header */ + pHeaderBufPtr += pTxBlk->MpduHeaderLen; +#ifdef VENDOR_FEATURE1_SUPPORT + + if (tr_entry->isCached + && (tr_entry->Protocol == (RTMP_GET_PACKET_PROTOCOL(pTxBlk->pPacket))) +#ifdef SOFT_ENCRYPT + && !TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt) +#endif /* SOFT_ENCRYPT */ +#ifdef TXBF_SUPPORT +#ifndef MT_MAC + && (pMacEntry->TxSndgType == SNDG_TYPE_DISABLE) +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + ) { + /* 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 = tr_entry->MpduHeaderLen; + pTxBlk->wifi_hdr_len = tr_entry->wifi_hdr_len; + pHeaderBufPtr = ((UCHAR *)wifi_hdr) + pTxBlk->MpduHeaderLen; + pTxBlk->HdrPadLen = tr_entry->HdrPadLen; + /* 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; + } + } else +#endif /* VENDOR_FEATURE1_SUPPORT */ + { + /* 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; + pTxBlk->wifi_hdr_len += 2; +#ifndef MT_MAC + + /* TODO: Shiang-usw, we need a more proper way to handle this instead of ifndef MT_MAC ! */ + /* For MT_MAC, SW not to prepare the HTC field for RDG enable */ + /* build HTC control field after 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; + } + +#endif /* MT_MAC */ +#ifdef TXBF_SUPPORT +#ifndef MT_MAC + + if (cap->FlgHwTxBfCap) { + pTxBlk->TxSndgPkt = SNDG_TYPE_DISABLE; + /* TODO: shiang-lock, fix ME!! */ + 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; + + /* Clear NDP Announcement */ + ((PHT_CONTROL)pHeaderBufPtr)->NDPAnnounce = 0; + } 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 /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + +#ifndef MT_MAC + if (bHTCPlus == TRUE) { + wifi_hdr->FC.Order = 1; + pHeaderBufPtr += 4; + pTxBlk->MpduHeaderLen += 4; + pTxBlk->wifi_hdr_len += 4; + } +#endif /* MT_MAC */ + + /*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; + } + + /* + padding at front of LLC header + LLC header should locate at 4-octets aligment + + @@@ MpduHeaderLen excluding padding @@@ + */ + pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; + pHeaderBufPtr = (UCHAR *)ROUND_UP(pHeaderBufPtr, 4); + pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); +#ifdef VENDOR_FEATURE1_SUPPORT + tr_entry->HdrPadLen = pTxBlk->HdrPadLen; +#endif /* VENDOR_FEATURE1_SUPPORT */ +#ifdef SOFT_ENCRYPT + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) + tx_sw_encrypt(pAd, pTxBlk, pHeaderBufPtr, wifi_hdr); + 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_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 + tr_entry->Protocol = RTMP_GET_PACKET_PROTOCOL(pTxBlk->pPacket); + tr_entry->MpduHeaderLen = pTxBlk->MpduHeaderLen; + tr_entry->wifi_hdr_len = pTxBlk->wifi_hdr_len; +#endif /* VENDOR_FEATURE1_SUPPORT */ + } + } else { + pTxBlk->MpduHeaderLen = 0; + pTxBlk->HdrPadLen = 2; + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader; + } + + if ((tr_entry->isCached) +#ifdef TXBF_SUPPORT +#ifndef MT_MAC + && (pTxBlk->TxSndgPkt == SNDG_TYPE_DISABLE) +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + ) + write_tmac_info_Cache(pAd, &pTxBlk->HeaderBuf[0], pTxBlk); + else { + pAd->archOps.write_tmac_info(pAd, &pTxBlk->HeaderBuf[0], pTxBlk); + + if (RTMP_GET_PACKET_LOWRATE(pTxBlk->pPacket)) + tr_entry->isCached = FALSE; + + NdisZeroMemory((UCHAR *)(&tr_entry->CachedBuf[0]), sizeof(tr_entry->CachedBuf)); + + if (!TX_BLK_TEST_FLAG(pTxBlk, fTX_HDR_TRANS)) { + cache_sz = (pHeaderBufPtr - (UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE])); + src_ptr = (UCHAR *)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); + NdisMoveMemory((UCHAR *)(&tr_entry->CachedBuf[0]), src_ptr, cache_sz); + } + +#ifdef VENDOR_FEATURE1_SUPPORT + /* use space to get performance enhancement */ + NdisZeroMemory((UCHAR *)(&tr_entry->HeaderBuf[0]), sizeof(tr_entry->HeaderBuf)); + NdisMoveMemory((UCHAR *)(&tr_entry->HeaderBuf[0]), + (UCHAR *)(&pTxBlk->HeaderBuf[0]), + (pHeaderBufPtr - (UCHAR *)(&pTxBlk->HeaderBuf[0]))); +#endif /* VENDOR_FEATURE1_SUPPORT */ + } + +#ifdef TXBF_SUPPORT +#ifndef MT_MAC + + if (pTxBlk->TxSndgPkt != SNDG_TYPE_DISABLE) + tr_entry->isCached = FALSE; + +#endif +#endif /* TXBF_SUPPORT */ + + ap_tx_ok_update(pAd, wdev, pTxBlk); + pAd->archOps.write_tx_resource(pAd, pTxBlk, TRUE, &freeCnt); +#ifdef SMART_ANTENNA + + if (pMacEntry) + pMacEntry->saTxCnt++; + +#endif /* SMART_ANTENNA */ + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + return NDIS_STATUS_SUCCESS; +} + +INT ap_amsdu_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *tx_blk) +{ + RTMP_ARCH_OP *arch_ops = &pAd->archOps; + struct wifi_dev_ops *wdev_ops = wdev->wdev_ops; + PQUEUE_ENTRY pQEntry; + INT32 ret = NDIS_STATUS_SUCCESS; + UINT index = 0; + + ASSERT((tx_blk->TxPacketList.Number > 1)); + + while (tx_blk->TxPacketList.Head) { + pQEntry = RemoveHeadQueue(&tx_blk->TxPacketList); + tx_blk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + + if (index == 0) + tx_blk->amsdu_state = TX_AMSDU_ID_FIRST; + else if (index == (tx_blk->TotalFrameNum - 1)) + tx_blk->amsdu_state = TX_AMSDU_ID_LAST; + else + tx_blk->amsdu_state = TX_AMSDU_ID_MIDDLE; + + if (!fill_tx_blk(pAd, wdev, tx_blk)) { + + ap_tx_drop_update(pAd, wdev, tx_blk); + RELEASE_NDIS_PACKET(pAd, tx_blk->pPacket, NDIS_STATUS_FAILURE); + continue; + } + + if (TX_BLK_TEST_FLAG(tx_blk, fTX_HDR_TRANS)) + wdev_ops->ieee_802_3_data_tx(pAd, wdev, tx_blk); + else + wdev_ops->ieee_802_11_data_tx(pAd, wdev, tx_blk); + + ap_tx_ok_update(pAd, wdev, tx_blk); + + ret = arch_ops->hw_tx(pAd, tx_blk); + + if (ret != NDIS_STATUS_SUCCESS) + return ret; + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + tx_blk->frame_idx++; + index++; + } + + return NDIS_STATUS_SUCCESS; +} + +#if defined(VOW_SUPPORT) && defined(VOW_DVT) +BOOLEAN vow_is_queue_full(RTMP_ADAPTER *pAd, UCHAR wcid, UCHAR qidx) +{ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: STA %d, qidx %d, vow_queue_len %d \n", __func__, wcid, qidx, pAd->vow_queue_len[wcid][qidx])); + if (pAd->vow_queue_len[wcid][qidx] >= pAd->vow_q_len) + return TRUE; + else + return FALSE; +} + +UINT32 vow_clone_legacy_frame(RTMP_ADAPTER *pAd, TX_BLK *pTxBlk) +{ + UINT32 i; + /*PNDIS_PACKET pkt;*/ + TX_BLK txb, *pTemp_TxBlk; + struct wifi_dev *wdev = pTxBlk->wdev; + UINT32 KickRingBitMap = 0; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + pTemp_TxBlk = &txb; + + /* return BC/MC */ + if (pTxBlk->TxFrameType == TX_MCAST_FRAME) { + UCHAR wmm_set = 0; + + if (wdev) { + wmm_set = HcGetWmmIdx(pAd, wdev); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: wcid %d, wmm set %d\n", + __func__, pTxBlk->Wcid, wmm_set)); + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: wcid %d, wdev is null!\n", + __func__, pTxBlk->Wcid)); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\x1b[32m%s: bc/mc packet ........ wcid %d\x1b[m\n", __func__, pTxBlk->Wcid)); + + + return KickRingBitMap; + } + + /*pkt = DuplicatePacket(wdev->if_dev, pTxBlk->pPacket);*/ + /* backup TXBLK */ + os_move_mem(&txb, pTxBlk, sizeof(TX_BLK)); + + + /*if (pkt == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: DuplicatePacket failed!!\n", __func__)); + return; + } + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: clone 1 pkt %p, vow_cloned_wtbl_num %d, pkt %p, clone pkt %p\n", + __func__, pkt, pAd->vow_cloned_wtbl_max, pTxBlk->pPacket, pkt));*/ + + + if (pAd->vow_cloned_wtbl_max) { + UINT32 end, start; + struct wifi_dev *wdev = pTxBlk->wdev; + UCHAR wmm_set; + + if (wdev) { + wmm_set = HcGetWmmIdx(pAd, wdev); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: wcid %d, wmm set %d\n", + __func__, pTxBlk->Wcid, wmm_set)); + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: wcid %d, wdev is null!\n", + __func__, pTxBlk->Wcid)); + } + + + if (pAd->CommonCfg.dbdc_mode) { + /* if (wmm_set == 0) */ + if (pTxBlk->Wcid == 1) { + start = 3; + end = pAd->vow_cloned_wtbl_num[0]; + } else { + start = pAd->vow_cloned_wtbl_num[0] + 1; + end = pAd->vow_cloned_wtbl_num[1]; + } + } else { + start = 2; + end = pAd->vow_cloned_wtbl_num[0]; + } + + /* for (i = 3; i <= pAd->vow_cloned_wtbl_num; i++) */ + for (i = start; i <= end; i++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: sta%d, tx_en %d\n", + __func__, i, pAd->vow_tx_en[i])); + + /* check queue status */ + if (vow_is_queue_full(pAd, i, pAd->vow_sta_ac[i])) { + /*printk("\x1b[31m%s: full wcid %d, ac %d\x1b[m\n", __FUNCTION__, i, pAd->vow_sta_ac[i]);*/ + continue; + } + + if (pAd->vow_tx_en[i] && (pAd->archOps.get_tx_resource_free_num(pAd, 0) > 2)) { + USHORT free_cnt = 1, tx_idx; + /* clone packet */ + /*PNDIS_PACKET clone = DuplicatePacket(wdev->if_dev, pkt);*/ + PNDIS_PACKET clone = DuplicatePacket(wdev->if_dev, pTxBlk->pPacket); + + if (clone == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: DuplicatePacket failed!!\n", __func__)); + /*pAd->archOps.kickout_data_tx(pAd, pTxBlk, pTxBlk->resource_idx);*/ /* move to ge_tx_pkt_deq_bh() */ + goto CLONE_DONE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: sta%d, free no %d, clone pkt %p\n", + __func__, i, pAd->archOps.get_tx_resource_free_num(pAd, 0), clone)); + /* cloned PKT */ + pTemp_TxBlk->pPacket = clone; + + /* pTxBlk->Wcid = 1; */ + pTemp_TxBlk->Wcid = i; + + if (pAd->vow_sta_ac[i] != QID_AC_VO) + pTemp_TxBlk->resource_idx = pAd->vow_sta_ac[i]; /* BK/BE/VI */ + else + pTemp_TxBlk->resource_idx = HIF_TX_IDX4; /* VO */ + + + /* get MAC TXD buffer */ + pTemp_TxBlk->HeaderBuf = pAd->archOps.get_hif_buf(pAd, + pTemp_TxBlk, pTemp_TxBlk->resource_idx, + pTemp_TxBlk->TxFrameType); + + /* modified DA */ + if (!TX_BLK_TEST_FLAG(pTxBlk, fTX_HDR_TRANS)) { + HEADER_802_11 *hdr = (HEADER_802_11 *)pTemp_TxBlk->wifi_hdr; + + hdr->Addr1[4] = i; + } else if (TX_BLK_TEST_FLAG(pTxBlk, fTX_HDR_TRANS)) { + INT32 ret = NDIS_STATUS_SUCCESS; + + /* modified DA */ + + /* fill TXD */ + if ((pTxBlk->amsdu_state == TX_AMSDU_ID_NO) || + (pTxBlk->amsdu_state == TX_AMSDU_ID_LAST)) + pAd->archOps.write_tmac_info(pAd, &pTemp_TxBlk->HeaderBuf[0], pTemp_TxBlk); + + /* fill TXP in TXD */ + ret = pAd->archOps.write_txp_info( + pAd, &pTemp_TxBlk->HeaderBuf[cap->tx_hw_hdr_len], pTemp_TxBlk); + + if (ret != NDIS_STATUS_SUCCESS) { + RELEASE_NDIS_PACKET(pAd, clone, NDIS_STATUS_FAILURE); + goto CLONE_DONE; + } + /* fill DMAD */ + if ((pTxBlk->amsdu_state == TX_AMSDU_ID_NO) || + (pTxBlk->amsdu_state == TX_AMSDU_ID_LAST)) + tx_idx = pAd->archOps.write_tx_resource(pAd, pTemp_TxBlk, TRUE, &free_cnt); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: sta%d, tx idx %d, resource_idx %d\n", + __func__, i, tx_idx, pTemp_TxBlk->resource_idx)); + } + } + KickRingBitMap |= (1 << pTemp_TxBlk->resource_idx); + } + } + +CLONE_DONE: + /* release original pkt */ + if (pAd->vow_need_drop_cnt[pTxBlk->Wcid] > 0) { + /*printk("\x1b[31m%s release....wcid %d, drop cnt %d\n\x1b[m\n", __FUNCTION__, pTxBlk->Wcid, + pAd->vow_need_drop_cnt[pTxBlk->Wcid]);*/ + pAd->vow_need_drop_cnt[pTxBlk->Wcid]--; + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); + } + + return KickRingBitMap; +} +#endif /* defined(VOW_SUPPORT) && (defined(VOW_DVT) */ + +VOID ap_ieee_802_11_data_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + HEADER_802_11 *wifi_hdr; + UCHAR *pHeaderBufPtr; + BOOLEAN bVLANPkt; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + ap_build_802_11_header(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; +#ifdef STATS_COUNT_SUPPORT + INC_COUNTER64(pAd->WlanCounters[0].MulticastTransmittedFrameCount); +#endif /* STATS_COUNT_SUPPORT */ + + for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { + if (pAd->ApCfg.MBSSID[idx].WPAREKEY.ReKeyMethod == PKT_REKEY) + pAd->ApCfg.MBSSID[idx].REKEYCOUNTER += (pTxBlk->SrcBufLen); + + } + } + +#ifdef MT_MAC + else { + /* Unicast */ + if (pTxBlk->tr_entry && pTxBlk->tr_entry->PsDeQWaitCnt) + pTxBlk->Pid = PID_PS_DATA; + } + +#endif /* MT_MAC */ + pHeaderBufPtr = pTxBlk->wifi_hdr; + wifi_hdr = (HEADER_802_11 *)pHeaderBufPtr; + /* skip common header */ + pHeaderBufPtr += pTxBlk->wifi_hdr_len; + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { + struct wifi_dev *wdev_tmp = NULL; + UCHAR ack_policy = pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx]; + wdev_tmp = pTxBlk->wdev; + if (wdev_tmp) + ack_policy = wlan_config_get_ack_policy(wdev_tmp, pTxBlk->QueIdx); + + /* build QOS Control bytes */ + *pHeaderBufPtr = ((pTxBlk->UserPriority & 0x0F) | (ack_policy << 5)); +#if defined(VOW_SUPPORT) && defined(VOW_DVT) + *pHeaderBufPtr |= (pAd->vow_sta_ack[pTxBlk->Wcid] << 5); +#endif /* defined(VOW_SUPPORT) && (defined(VOW_DVT) */ +#ifdef WFA_VHT_PF + + if (pAd->force_noack) + *pHeaderBufPtr |= (1 << 5); + +#endif /* WFA_VHT_PF */ +#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->wifi_hdr_len += 2; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_LOUD, ("%s: tx_bf: %d\n", + __func__, cap->FlgHwTxBfCap)); +#ifdef TXBF_SUPPORT +#ifndef MT_MAC + + if (cap->FlgHwTxBfCap && + (pTxBlk->pMacEntry) && + (pTxBlk->pTransmit->field.MODE >= MODE_HTMIX)) { + MAC_TABLE_ENTRY *pMacEntry = pTxBlk->pMacEntry; + BOOLEAN bHTCPlus = FALSE; + + pTxBlk->TxSndgPkt = SNDG_TYPE_DISABLE; + /* TODO: shiang-usw, fix ME!! */ + 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; + + /* Clear NDP Announcement */ + ((PHT_CONTROL)pHeaderBufPtr)->NDPAnnounce = 0; + } 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 + + /* + 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 */ + + if (bHTCPlus == TRUE) { + /* mark HTC bit */ + wifi_hdr->FC.Order = 1; + pHeaderBufPtr += 4; + pTxBlk->wifi_hdr_len += 4; + } + } + +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + } + + /* The remaining content of MPDU header should locate at 4-octets aligment */ + pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; + pHeaderBufPtr = (UCHAR *)ROUND_UP(pHeaderBufPtr, 4); + pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); + pTxBlk->MpduHeaderLen = pTxBlk->wifi_hdr_len; +#ifdef SOFT_ENCRYPT + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) + tx_sw_encrypt(pAd, pTxBlk, pHeaderBufPtr, wifi_hdr); + 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; + } + } +} + +VOID ap_ieee_802_3_data_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + pTxBlk->MpduHeaderLen = 0; + pTxBlk->HdrPadLen = 0; + pTxBlk->wifi_hdr_len = 0; + pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader; +} + +INT ap_legacy_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + QUEUE_ENTRY *pQEntry; + RTMP_ARCH_OP *arch_ops = &pAd->archOps; + INT32 ret = NDIS_STATUS_SUCCESS; + struct wifi_dev_ops *wdev_ops = wdev->wdev_ops; + + ASSERT(pTxBlk); + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + + if (!fill_tx_blk(pAd, wdev, pTxBlk)) { + ap_tx_drop_update(pAd, wdev, pTxBlk); + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_HDR_TRANS)) + wdev_ops->ieee_802_3_data_tx(pAd, wdev, pTxBlk); + else + wdev_ops->ieee_802_11_data_tx(pAd, wdev, pTxBlk); + + ap_tx_ok_update(pAd, wdev, pTxBlk); + + ret = arch_ops->hw_tx(pAd, pTxBlk); + + if (ret != NDIS_STATUS_SUCCESS) + return ret; + + if (RTMP_GET_PACKET_LOWRATE(pTxBlk->pPacket)) + if (pTxBlk->tr_entry) + pTxBlk->tr_entry->isCached = FALSE; + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + return NDIS_STATUS_SUCCESS; +} + +INT ap_frag_tx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + HEADER_802_11 *wifi_hdr; + QUEUE_ENTRY *pQEntry; + PACKET_INFO PacketInfo; +#ifdef SOFT_ENCRYPT + UCHAR *tmp_ptr = NULL; + UINT32 buf_offset = 0; +#endif /* SOFT_ENCRYPT */ + HTTRANSMIT_SETTING *pTransmit; + UCHAR fragNum = 0; + USHORT EncryptionOverhead = 0; + UINT32 FreeMpduSize, SrcRemainingBytes; + USHORT AckDuration; + UINT NextMpduSize; + RTMP_ARCH_OP *op = &pAd->archOps; + INT32 ret = NDIS_STATUS_SUCCESS; + struct wifi_dev_ops *ops = wdev->wdev_ops; + + ASSERT(pTxBlk); + pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); + pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); + + if (!fill_tx_blk(pAd, wdev, pTxBlk)) { + + ap_tx_drop_update(pAd, wdev, pTxBlk); + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("<--%s(%d): ##########Fail#########\n", __func__, __LINE__)); + return NDIS_STATUS_SUCCESS; + } + +#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 NDIS_STATUS_FAILURE; + } + } + +#endif /* SOFT_ENCRYPT */ + + if (IS_CIPHER_TKIP(pTxBlk->CipherAlg)) { + pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket); + + if (pTxBlk->pPacket == NULL) + return NDIS_STATUS_FAILURE; + + RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); + } + + ops->ieee_802_11_data_tx(pAd, wdev, pTxBlk); + + /* 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 (IS_CIPHER_TKIP(pTxBlk->CipherAlg)) { + RTMPCalculateMICValue(pAd, pTxBlk->pPacket, pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, &pTxBlk->pKey[LEN_TK], wdev->func_idx); + /* + 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; + } + + ap_tx_ok_update(pAd, wdev, pTxBlk); + + /* + 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) || (pTxBlk->CipherAlg == CIPHER_WEP152)) + EncryptionOverhead = 8; /* WEP: IV[4] + ICV[4]; */ + else if (pTxBlk->CipherAlg == CIPHER_TKIP) + EncryptionOverhead = 12; /* TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */ + else if (pTxBlk->CipherAlg == CIPHER_AES) + EncryptionOverhead = 16; /* AES: IV[4] + EIV[4] + MIC[8] */ + + else + EncryptionOverhead = 0; + + pTransmit = pTxBlk->pTransmit; + + /* Decide the TX rate */ + if (pTransmit->field.MODE == MODE_CCK) + pTxBlk->TxRate = pTransmit->field.MCS; + else if (pTransmit->field.MODE == MODE_OFDM) + pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE; + else + pTxBlk->TxRate = RATE_6_5; + + /* decide how much time an ACK/CTS frame will consume in the air */ + if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE) + AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14); + else + AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14); + + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("!!!Fragment AckDuration(%d), TxRate(%d)!!!\n", AckDuration, pTxBlk->TxRate)); */ +#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) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():no memory for MIC calculation!\n", + __func__)); + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + NdisMoveMemory(tmp_ptr, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + } + +#endif /* SOFT_ENCRYPT */ + /* Init the total payload length of this frame. */ + SrcRemainingBytes = pTxBlk->SrcBufLen; + pTxBlk->TotalFragNum = 0xff; + wifi_hdr = (HEADER_802_11 *)pTxBlk->wifi_hdr; + + do { + FreeMpduSize = wlan_operate_get_frag_thld(&pTxBlk->pMbss->wdev); + FreeMpduSize -= LENGTH_CRC; + FreeMpduSize -= pTxBlk->MpduHeaderLen; + + if (SrcRemainingBytes <= FreeMpduSize) { + /* This is the last or only fragment */ + pTxBlk->SrcBufLen = SrcRemainingBytes; + wifi_hdr->FC.MoreFrag = 0; + wifi_hdr->Duration = pAd->CommonCfg.Dsifs + AckDuration; + /* Indicate the lower layer that this's the last fragment. */ + pTxBlk->TotalFragNum = fragNum; +#ifdef MT_MAC + pTxBlk->FragIdx = ((fragNum == 0) ? TX_FRAG_ID_NO : TX_FRAG_ID_LAST); +#endif /* MT_MAC */ + } else { + /* more fragment is required */ + pTxBlk->SrcBufLen = FreeMpduSize; + NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), + ((UINT)wlan_operate_get_frag_thld(&pTxBlk->pMbss->wdev))); + wifi_hdr->FC.MoreFrag = 1; + wifi_hdr->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead); +#ifdef MT_MAC + pTxBlk->FragIdx = ((fragNum == 0) ? TX_FRAG_ID_FIRST : TX_FRAG_ID_MIDDLE); +#endif /* MT_MAC */ + } + + 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, + (UCHAR *)wifi_hdr, + pTxBlk->pSrcBufData, + pTxBlk->SrcBufLen, + pTxBlk->KeyIdx, + pTxBlk->pKey, + &ext_offset); + pTxBlk->SrcBufLen += ext_offset; + pTxBlk->TotalFrameLen += ext_offset; + } + +#endif /* SOFT_ENCRYPT */ + ret = op->hw_tx(pAd, pTxBlk); + + if (ret != NDIS_STATUS_SUCCESS) + return ret; + +#ifdef SMART_ANTENNA + + if (pTxBlk->pMacEntry) + pTxBlk->pMacEntry->saTxCnt++; + +#endif /* SMART_ANTENNA */ + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; +#ifdef SOFT_ENCRYPT + + if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bSwEncrypt)) { + if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128)) { + inc_iv_byte(pTxBlk->pKey->TxTsc, LEN_WEP_TSC, 1); + /* Construct and insert 4-bytes WEP IV header to MPDU header */ + RTMPConstructWEPIVHdr(pTxBlk->KeyIdx, pTxBlk->pKey->TxTsc, + pHeaderBufPtr - (LEN_WEP_IV_HDR)); + } else if (pTxBlk->CipherAlg == CIPHER_TKIP) + ; + else if (pTxBlk->CipherAlg == CIPHER_AES) { + inc_iv_byte(pTxBlk->pKey->TxTsc, LEN_WPA_TSC, 1); + /* Construct and insert 8-bytes CCMP header to MPDU header */ + RTMPConstructCCMPHdr(pTxBlk->KeyIdx, pTxBlk->pKey->TxTsc, + pHeaderBufPtr - (LEN_CCMP_HDR)); + } + } else +#endif /* SOFT_ENCRYPT */ + { + /* 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; + wifi_hdr->Frag++; /* increase Frag # */ + } while (SrcRemainingBytes > 0); + +#ifdef SOFT_ENCRYPT + + if (tmp_ptr != NULL) + os_free_mem(tmp_ptr); + +#endif /* SOFT_ENCRYPT */ + return NDIS_STATUS_SUCCESS; +} + +INT ap_tx_pkt_handle(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, TX_BLK *pTxBlk) +{ + PQUEUE_ENTRY pQEntry; + PNDIS_PACKET pPacket = NULL; + struct wifi_dev_ops *ops = NULL; + MAC_TABLE_ENTRY *pEntry = NULL; + INT32 ret = NDIS_STATUS_SUCCESS; + struct DOT11_H *pDot11h = NULL; + + if (!wdev) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + + ops = wdev->wdev_ops; + pDot11h = wdev->pDot11_H; + + if (pDot11h == NULL) + return NDIS_STATUS_FAILURE; + + if ((pDot11h->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); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("<--%s(%d)\n", __func__, __LINE__)); + return NDIS_STATUS_FAILURE; + } + + if (wdev->bVLAN_Tag == TRUE) + RTMP_SET_PACKET_VLAN(pTxBlk->pPacket, FALSE); + +#ifdef DOT11K_RRM_SUPPORT +#ifdef QUIET_SUPPORT + + if (IS_RRM_QUIET(wdev)) { + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; + } + +#endif /* QUIET_SUPPORT */ +#endif /* DOT11K_RRM_SUPPORT */ + + switch (pTxBlk->TxFrameType) { + case TX_AMPDU_FRAME: + ret = ops->ampdu_tx(pAd, wdev, pTxBlk); + break; + + case TX_LEGACY_FRAME: + ret = ops->legacy_tx(pAd, wdev, pTxBlk); + break; + + case TX_MCAST_FRAME: + ret = ops->legacy_tx(pAd, wdev, pTxBlk); + break; + + case TX_AMSDU_FRAME: + ret = ops->amsdu_tx(pAd, wdev, pTxBlk); + break; + + case TX_FRAG_FRAME: + ret = ops->frag_tx(pAd, wdev, pTxBlk); + break; + + case TX_MLME_MGMTQ_FRAME: + ret = ops->mlme_mgmtq_tx(pAd, wdev, pTxBlk); + break; + + case TX_MLME_DATAQ_FRAME: + ret = ops->mlme_dataq_tx(pAd, wdev, pTxBlk); + break; +#ifdef CONFIG_ATE + + case TX_ATE_FRAME: + ret = ops->ate_tx(pAd, wdev, pTxBlk); + break; +#endif /* CONFIG_ATE */ + + default: + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Send a pacekt was not classified!!\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); + } + + return NDIS_STATUS_FAILURE; + } + + pEntry = &pAd->MacTab.Content[(UCHAR)RTMP_GET_PACKET_WCID(pTxBlk->pPacket)]; + INC_COUNTER64(pEntry->TxPackets); + pEntry->TxBytes += pTxBlk->SrcBufLen; + pEntry->OneSecTxBytes += pTxBlk->SrcBufLen; + pEntry->one_sec_tx_pkts++; + return ret; +} + +/* + ======================================================================== + Description: + This routine checks if a received frame causes class 2 or class 3 + error, and perform error action (DEAUTH or DISASSOC) accordingly + ======================================================================== +*/ +BOOLEAN ap_chk_cl2_cl3_err(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk) +{ + /* 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 (!VALID_UCAST_ENTRY_WCID(pAd, pRxBlk->wcid)) { + MAC_TABLE_ENTRY *pEntry; + + pEntry = MacTableLookup(pAd, pRxBlk->Addr2); + + if (pEntry) + return FALSE; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s():Rx a frame from %02x:%02x:%02x:%02x:%02x:%02x with WCID(%d) > %d\n", + __func__, PRINT_MAC(pRxBlk->Addr2), + pRxBlk->wcid, GET_MAX_UCAST_NUM(pAd))); + APCls2errAction(pAd, pRxBlk); + return TRUE; + } + + if (pAd->MacTab.Content[pRxBlk->wcid].Sst == SST_ASSOC) + /* okay to receive this DATA frame */ + return FALSE; + else if (pAd->MacTab.Content[pRxBlk->wcid].Sst == SST_AUTH) { + APCls3errAction(pAd, pRxBlk); + return TRUE; + } + APCls2errAction(pAd, pRxBlk); + return TRUE; +} + +VOID ap_rx_error_handle(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk) +{ + MAC_TABLE_ENTRY *pEntry = NULL; + RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo; + + if (pRxInfo->CipherErr) { + INC_COUNTER64(pAd->WlanCounters[0].WEPUndecryptableCount); + + if ((pRxInfo->U2M) && VALID_UCAST_ENTRY_WCID(pAd, pRxBlk->wcid)) { +#ifdef APCLI_SUPPORT +#if defined(APCLI_CERT_SUPPORT) || defined(WPA_SUPPLICANT_SUPPORT) + UCHAR Wcid; + + Wcid = pRxBlk->wcid; + + if (VALID_UCAST_ENTRY_WCID(pAd, Wcid)) + pEntry = ApCliTableLookUpByWcid(pAd, Wcid, pRxBlk->Addr2); + else + pEntry = MacTableLookup(pAd, pRxBlk->Addr2); + + if (pEntry && + (IS_ENTRY_APCLI(pEntry) +#ifdef MAC_REPEATER_SUPPORT + || IS_ENTRY_REPEATER(pEntry) +#endif /* MAC_REPEATER_SUPPORT */ + )) { + if ((IS_CIPHER_TKIP_Entry(pEntry)) + && (pRxInfo->CipherErr == 2) + && !(RX_BLK_TEST_FLAG(pRxBlk, fRX_WCID_MISMATCH))) { + ApCliRTMPReportMicError(pAd, 1, pEntry->func_tb_idx); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Rx MIC Value error\n")); + } + } else +#endif /* defined(APCLI_CERT_SUPPORT) || defined(WPA_SUPPLICANT_SUPPORT) */ +#endif /* APCLI_SUPPORT */ + { + pEntry = &pAd->MacTab.Content[pRxBlk->wcid]; + + /* + MIC error + Before verifying the MIC, the receiver shall check FCS, ICV and TSC. + This avoids unnecessary MIC failure events. + */ + if ((IS_CIPHER_TKIP_Entry(pEntry)) + && (pRxInfo->CipherErr == 2) + && !(RX_BLK_TEST_FLAG(pRxBlk, fRX_WCID_MISMATCH))) { +#ifdef HOSTAPD_SUPPORT + + if (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].Hostapd == Hostapd_EXT) + ieee80211_notify_michael_failure(pAd, pRxBlk->pHeader, (UINT32)pRxBlk->key_idx, 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); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Rx u2me Cipher Err(MPDUsize=%d, WCID=%d, CipherErr=%d)\n", + pRxBlk->MPDUtotalByteCnt, pRxBlk->wcid, pRxInfo->CipherErr)); + } + +#ifdef APCLI_SUPPORT +#ifdef APCLI_CERT_SUPPORT + else if (pRxInfo->Mcast || pRxInfo->Bcast) { + pEntry = MacTableLookup(pAd, pRxBlk->Addr2); + + if (pEntry && + (IS_ENTRY_APCLI(pEntry) +#ifdef MAC_REPEATER_SUPPORT + || IS_ENTRY_REPEATER(pEntry) +#endif /* MAC_REPEATER_SUPPORT */ + )) { + if ((pRxInfo->CipherErr == 2) + && !(RX_BLK_TEST_FLAG(pRxBlk, fRX_WCID_MISMATCH))) { + ApCliRTMPReportMicError(pAd, 0, pEntry->func_tb_idx); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Rx MIC Value error\n")); + } + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Rx bc/mc Cipher Err(MPDUsize=%d, WCID=%d, CipherErr=%d)\n", + pRxBlk->MPDUtotalByteCnt, pRxBlk->wcid, pRxInfo->CipherErr)); + } + +#endif /* APCLI_CERT_SUPPORT */ +#endif /* APCLI_SUPPORT */ + } +} + +#ifdef RLT_MAC_DBG +static int dump_next_valid; +#endif /* RLT_MAC_DBG */ +BOOLEAN ap_check_valid_frame(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk) +{ + FRAME_CONTROL *FC = (FRAME_CONTROL *)pRxBlk->FC; + BOOLEAN isVaild = FALSE; + + do { + if (FC->ToDs == 0) + break; + +#ifdef IDS_SUPPORT + + if ((FC->FrDs == 0) && (pRxBlk->wcid == RESERVED_WCID)) { /* not in RX WCID MAC table */ + if (++pAd->ApCfg.RcvdMaliciousDataCount > pAd->ApCfg.DataFloodThreshold) + break; + } + +#endif /* IDS_SUPPORT */ + + /* check if Class2 or 3 error */ + if ((FC->FrDs == 0) && (ap_chk_cl2_cl3_err(pAd, pRxBlk))) + break; + + if (pAd->ApCfg.BANClass3Data == TRUE) + break; + + isVaild = TRUE; + } while (0); + + return isVaild; +} + +INT ap_rx_pkt_allowed(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, RX_BLK *pRxBlk) +{ + RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo; + FRAME_CONTROL *pFmeCtrl = (FRAME_CONTROL *)pRxBlk->FC; + MAC_TABLE_ENTRY *pEntry = NULL; + INT hdr_len = 0; + + pEntry = PACInquiry(pAd, pRxBlk->wcid); +#if defined(WDS_SUPPORT) || defined(CLIENT_WDS) || defined(A4_CONN) + + if ((pFmeCtrl->FrDs == 1) && (pFmeCtrl->ToDs == 1)) { +#ifdef CLIENT_WDS + + if (pEntry) { + /* The CLIENT WDS must be a associated STA */ + if (IS_ENTRY_CLIWDS(pEntry)) + ; + else if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC)) + SET_ENTRY_CLIWDS(pEntry); + else + return FALSE; + + CliWds_ProxyTabUpdate(pAd, pEntry->Aid, pRxBlk->Addr4); + } + +#endif /* CLIENT_WDS */ + + +#ifdef WDS_SUPPORT + + if (!pEntry) { + /* + The WDS frame only can go here when in auto learning mode and + this is the first trigger frame from peer + + So we check if this is un-registered WDS entry by call function + "FindWdsEntry()" + */ + if (MAC_ADDR_EQUAL(pRxBlk->Addr1, pAd->CurrentAddress)) + pEntry = FindWdsEntry(pAd, pRxBlk); + + /* have no valid wds entry exist, then discard the incoming packet.*/ + if (!(pEntry && WDS_IF_UP_CHECK(pAd, pEntry->func_tb_idx))) + return FALSE; + + /*receive corresponding WDS packet, disable TX lock state (fix WDS jam issue) */ + if (pEntry && (pEntry->LockEntryTx == TRUE)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Receive WDS packet, disable TX lock state!\n")); + pEntry->ContinueTxFailCnt = 0; + pEntry->LockEntryTx = FALSE; + /* TODO: shiang-usw, remove upper setting because we need to mirgate to tr_entry! */ + pAd->MacTab.tr_entry[pEntry->wcid].ContinueTxFailCnt = 0; + pAd->MacTab.tr_entry[pEntry->wcid].LockEntryTx = FALSE; + } + } + +#endif /* WDS_SUPPORT */ + + if (pEntry) { +#ifdef WDS_SUPPORT +#ifdef STATS_COUNT_SUPPORT + if (IS_ENTRY_WDS(pEntry)) { + RT_802_11_WDS_ENTRY *pWdsEntry = &pAd->WdsTab.WdsEntry[pEntry->func_tb_idx]; + + pWdsEntry->WdsCounter.ReceivedByteCount += pRxBlk->MPDUtotalByteCnt; + INC_COUNTER64(pWdsEntry->WdsCounter.ReceivedFragmentCount); + + if (IS_MULTICAST_MAC_ADDR(pRxBlk->Addr3)) + INC_COUNTER64(pWdsEntry->WdsCounter.MulticastReceivedFrameCount); + } +#endif /* STATS_COUNT_SUPPORT */ +#endif /* WDS_SUPPORT */ + RX_BLK_SET_FLAG(pRxBlk, fRX_WDS); + hdr_len = LENGTH_802_11_WITH_ADDR4; + return hdr_len; + } + + } + +#endif /* defined(WDS_SUPPORT) || defined(CLIENT_WDS) || defined(A4_CONN) */ + + if (!pEntry) { +#ifdef IDS_SUPPORT + + if ((pFmeCtrl->FrDs == 0) && (pRxBlk->wcid == RESERVED_WCID)) /* not in RX WCID MAC table */ + pAd->ApCfg.RcvdMaliciousDataCount++; + +#endif /* IDS_SUPPORT */ + return FALSE; + } + + if (!((pFmeCtrl->FrDs == 0) && (pFmeCtrl->ToDs == 1))) { +#ifdef IDS_SUPPORT + + /* + Replay attack detection, + drop it if detect a spoofed data frame from a rogue AP + */ + if (pFmeCtrl->FrDs == 1) + RTMPReplayAttackDetection(pAd, pRxBlk->Addr2, pRxBlk); + +#endif /* IDS_SUPPORT */ + return FALSE; + } + + + /* check if Class2 or 3 error */ + if (ap_chk_cl2_cl3_err(pAd, pRxBlk)) + return FALSE; + + if (pAd->ApCfg.BANClass3Data == TRUE) + return FALSE; + +#ifdef STATS_COUNT_SUPPORT + + /* Increase received byte counter per BSS */ + if (pFmeCtrl->FrDs == 0 && pRxInfo->U2M) { + BSS_STRUCT *pMbss = pEntry->pMbss; + + if (pMbss != NULL) { + pMbss->ReceivedByteCount += pRxBlk->MPDUtotalByteCnt; + pMbss->RxCount++; + } + } + + if (IS_MULTICAST_MAC_ADDR(pRxBlk->Addr3)) + INC_COUNTER64(pAd->WlanCounters[0].MulticastReceivedFrameCount); + +#endif /* STATS_COUNT_SUPPORT */ + + + hdr_len = LENGTH_802_11; + RX_BLK_SET_FLAG(pRxBlk, fRX_STA); + ASSERT(pEntry->wcid == pRxBlk->wcid); + return hdr_len; +} + +INT ap_rx_ps_handle(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, RX_BLK *pRxBlk) +{ + MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[pRxBlk->wcid]; + FRAME_CONTROL *FC = (FRAME_CONTROL *)pRxBlk->FC; + UCHAR OldPwrMgmt = PWR_ACTIVE; /* 1: PWR_SAVE, 0: PWR_ACTIVE */ + /* 1: PWR_SAVE, 0: PWR_ACTIVE */ + OldPwrMgmt = RtmpPsIndicate(pAd, pRxBlk->Addr2, pEntry->wcid, FC->PwrMgmt); +#ifdef UAPSD_SUPPORT + + if ((FC->PwrMgmt == PWR_SAVE) && + (OldPwrMgmt == PWR_SAVE) && + (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE)) && + (FC->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; + + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_HDR_TRANS)) + OldUP = (*(pRxBlk->pData + 32) & 0x07); + else + OldUP = (*(pRxBlk->pData + LENGTH_802_11) & 0x07); + + UAPSD_TriggerFrameHandle(pAd, pEntry, OldUP); + } + +#endif /* UAPSD_SUPPORT */ + return TRUE; +} + +INT ap_rx_pkt_foward(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, PNDIS_PACKET pPacket) +{ + MAC_TABLE_ENTRY *pEntry = NULL; + BOOLEAN to_os, to_air; + UCHAR *pHeader802_3; + PNDIS_PACKET pForwardPacket; + BSS_STRUCT *pMbss; + struct wifi_dev *dst_wdev = NULL; + UCHAR wcid; + + if (wdev->func_idx >= HW_BEACON_MAX_NUM) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Invalid func_idx(%d), type(%d)!\n", + __func__, wdev->func_idx, wdev->wdev_type)); + return FALSE; + } + + /* only one connected sta, directly to upper layer */ + if (pAd->MacTab.Size <= 1) + return TRUE; + + /* TODO: shiang-usw, remove pMbss structure here to make it more generic! */ + pMbss = &pAd->ApCfg.MBSSID[wdev->func_idx]; + pHeader802_3 = GET_OS_PKT_DATAPTR(pPacket); + /* by default, announce this pkt to upper layer (bridge) and not to air */ + to_os = TRUE; + to_air = FALSE; + + if (pHeader802_3[0] & 0x01) { + if ((pMbss->StaCount > 1) + ) { + /* forward the M/Bcast packet back to air if connected STA > 1 */ + to_air = TRUE; + } + } else { + /* if destinated STA is a associated wireless STA */ + pEntry = MacTableLookup(pAd, pHeader802_3); + + if (pEntry && pEntry->Sst == SST_ASSOC && pEntry->wdev) { + dst_wdev = pEntry->wdev; + + if (wdev == dst_wdev) { + /* + STAs in same SSID, default send to air and not to os, + but not to air if match following case: + a). pMbss->IsolateInterStaTraffic == TRUE + */ + to_air = TRUE; + to_os = FALSE; + + if (pMbss->IsolateInterStaTraffic == 1) + to_air = FALSE; + } else { + /* + STAs in different SSID, default send to os and not to air + but not to os if match any of following cases: + a). destination VLAN ID != source VLAN ID + b). pAd->ApCfg.IsolateInterStaTrafficBTNBSSID + */ + to_os = TRUE; + to_air = FALSE; + + if (pAd->ApCfg.IsolateInterStaTrafficBTNBSSID == 1 || + (wdev->VLAN_VID != dst_wdev->VLAN_VID)) + to_os = FALSE; + } + } + } + + if (to_air) { + + pForwardPacket = DuplicatePacket(wdev->if_dev, pPacket); +#ifdef RTMP_UDMA_SUPPORT + if (to_os) { +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + if ((wf_drv_tbl.wf_fwd_needed_hook != NULL) && (wf_drv_tbl.wf_fwd_needed_hook() == TRUE)) + set_wf_fwd_cb(pAd, pPacket, wdev); +#endif /* CONFIG_WIFI_PKT_FWD */ + announce_802_3_packet(pAd, pPacket, pAd->OpMode); + } +#endif + if (pForwardPacket == NULL) + return to_os; + + /* 1.1 apidx != 0, then we need set packet mbssid attribute. */ + if (pEntry) { + wcid = pEntry->wcid; + RTMP_SET_PACKET_WDEV(pForwardPacket, dst_wdev->wdev_idx); + RTMP_SET_PACKET_WCID(pForwardPacket, wcid); + } else { /* send bc/mc frame back to the same bss */ + wcid = wdev->tr_tb_idx; + RTMP_SET_PACKET_WDEV(pForwardPacket, wdev->wdev_idx); + RTMP_SET_PACKET_WCID(pForwardPacket, wcid); + } + + RTMP_SET_PACKET_MOREDATA(pForwardPacket, FALSE); + + +#ifdef REDUCE_TCP_ACK_SUPPORT + ReduceAckUpdateDataCnx(pAd, pForwardPacket); + + if (ReduceTcpAck(pAd, pForwardPacket) == FALSE) +#endif + { + send_data_pkt(pAd, wdev, pForwardPacket); + } + } +#ifdef RTMP_UDMA_SUPPORT + if (to_os == FALSE) { + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): No need to send to OS!\n", __func__)); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); +#ifdef CUT_THROUGH_DBG + pAd->RxDropPacket++; +#endif + } + return (to_os & (!to_air)); +#endif + + return to_os; +} + +INT ap_ieee_802_3_data_rx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, RX_BLK *pRxBlk, MAC_TABLE_ENTRY *pEntry) +{ + RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo; + UCHAR wdev_idx = BSS0; + BOOLEAN bFragment = FALSE; + FRAME_CONTROL *pFmeCtrl = (FRAME_CONTROL *)pRxBlk->FC; + struct wifi_dev_ops *ops = wdev->wdev_ops; + + wdev_idx = wdev->wdev_idx; + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s(): wcid=%d, wdev_idx=%d, pRxBlk->Flags=0x%x, fRX_AP/STA/ADHOC=0x%x/0x%x/0x%x, Type/SubType=%d/%d, FrmDS/ToDS=%d/%d\n", + __func__, pEntry->wcid, wdev->wdev_idx, + pRxBlk->Flags, + RX_BLK_TEST_FLAG(pRxBlk, fRX_AP), + RX_BLK_TEST_FLAG(pRxBlk, fRX_STA), + RX_BLK_TEST_FLAG(pRxBlk, fRX_ADHOC), + pFmeCtrl->Type, pFmeCtrl->SubType, + pFmeCtrl->FrDs, pFmeCtrl->ToDs)); + + /* Gather PowerSave information from all valid DATA frames. IEEE 802.11/1999 p.461 */ + /* must be here, before no DATA check */ + if (ops->rx_ps_handle) + ops->rx_ps_handle(pAd, wdev, pRxBlk); + + pEntry->NoDataIdleCount = 0; + pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; + pEntry->RxBytes += pRxBlk->MPDUtotalByteCnt; + pEntry->OneSecRxBytes += pRxBlk->MPDUtotalByteCnt; + pAd->RxTotalByteCnt += pRxBlk->MPDUtotalByteCnt; + INC_COUNTER64(pEntry->RxPackets); + pAd->RxTotalByteCnt += pRxBlk->MPDUtotalByteCnt; + + if (((FRAME_CONTROL *)pRxBlk->FC)->SubType & 0x08) { + + if (pAd->MacTab.Content[pRxBlk->wcid].BARecWcidArray[pRxBlk->TID] != 0) + pRxInfo->BA = 1; + else + pRxInfo->BA = 0; + + if (pRxBlk->AmsduState) + RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU); + + if (pRxInfo->BA) + RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU); + } + + /*check if duplicate frame, ignore it and then drop*/ + if (rx_chk_duplicate_frame(pAd, pRxBlk, wdev) == NDIS_STATUS_FAILURE) { + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): duplicate frame drop it!\n", __func__)); + return FALSE; + } + + if ((pRxBlk->FN == 0) && (pFmeCtrl->MoreFrag != 0)) { + bFragment = TRUE; + de_fragment_data_pkt(pAd, pRxBlk); + } + + if (pRxInfo->U2M) + pEntry->LastRxRate = (ULONG)(pRxBlk->rx_rate.word); + +#ifdef IGMP_SNOOP_SUPPORT + + if ((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_WDS(pEntry)) + && (wdev->IgmpSnoopEnable) + && IS_MULTICAST_MAC_ADDR(pRxBlk->Addr3)) { + PUCHAR pDA = pRxBlk->Addr3; + PUCHAR pSA = pRxBlk->Addr2; + PUCHAR pData = pRxBlk->pData + 12; + UINT16 protoType = OS_NTOHS(*((UINT16 *)(pData))); + + if (protoType == ETH_P_IP) + IGMPSnooping(pAd, pDA, pSA, pData, wdev, pRxBlk->wcid); + else if (protoType == ETH_P_IPV6) + MLDSnooping(pAd, pDA, pSA, pData, wdev, pRxBlk->wcid); + } + +#endif /* IGMP_SNOOP_SUPPORT */ + + if (pRxBlk->pRxPacket) { + RTMP_SET_PACKET_WCID(pRxBlk->pRxPacket, pRxBlk->wcid); + rx_802_3_data_frm_announce(pAd, pEntry, pRxBlk, pEntry->wdev); + } + + return TRUE; +} + +INT ap_ieee_802_11_data_rx(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, RX_BLK *pRxBlk, MAC_TABLE_ENTRY *pEntry) +{ + RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo; + FRAME_CONTROL *pFmeCtrl = (FRAME_CONTROL *)pRxBlk->FC; + BOOLEAN bFragment = FALSE; + UCHAR wdev_idx = BSS0; + UCHAR UserPriority = 0; + INT hdr_len = LENGTH_802_11; + COUNTER_RALINK *pCounter = &pAd->RalinkCounters; + UCHAR *pData; + BOOLEAN drop_err = TRUE; +#if defined(SOFT_ENCRYPT) || defined(ADHOC_WPA2PSK_SUPPORT) + NDIS_STATUS status; +#endif /* defined(SOFT_ENCRYPT) || defined(ADHOC_WPA2PSK_SUPPORT) */ + struct wifi_dev_ops *ops = wdev->wdev_ops; + + wdev_idx = wdev->wdev_idx; + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s(): wcid=%d, wdev_idx=%d, pRxBlk->Flags=0x%x, fRX_AP/STA/ADHOC=0x%x/0x%x/0x%x, Type/SubType=%d/%d, FrmDS/ToDS=%d/%d\n", + __func__, pEntry->wcid, wdev->wdev_idx, + pRxBlk->Flags, + RX_BLK_TEST_FLAG(pRxBlk, fRX_AP), + RX_BLK_TEST_FLAG(pRxBlk, fRX_STA), + RX_BLK_TEST_FLAG(pRxBlk, fRX_ADHOC), + pFmeCtrl->Type, pFmeCtrl->SubType, + pFmeCtrl->FrDs, pFmeCtrl->ToDs)); + /* Gather PowerSave information from all valid DATA frames. IEEE 802.11/1999 p.461 */ + /* must be here, before no DATA check */ + pData = pRxBlk->FC; + + if (ops->rx_ps_handle) + ops->rx_ps_handle(pAd, wdev, pRxBlk); + + pEntry->NoDataIdleCount = 0; + pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; + /* + update RxBlk->pData, DataSize, 802.11 Header, QOS, HTC, Hw Padding + */ + + + pData = pRxBlk->FC; + /* 1. skip 802.11 HEADER */ + pData += hdr_len; + pRxBlk->DataSize -= hdr_len; + + /* 2. QOS */ + if (pFmeCtrl->SubType & 0x08) { + UserPriority = *(pData) & 0x0f; + + if (pAd->MacTab.Content[pRxBlk->wcid].BARecWcidArray[pRxBlk->TID] != 0) + pRxInfo->BA = 1; + else + pRxInfo->BA = 0; + + + /* bit 7 in QoS Control field signals the HT A-MSDU format */ + if ((*pData) & 0x80) { + RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU); + pCounter->RxAMSDUCount.u.LowPart++; + } + + 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++; + } + + /* skip QOS contorl field */ + pData += 2; + pRxBlk->DataSize -= 2; + } + + pRxBlk->UserPriority = UserPriority; + + /*check if duplicate frame, ignore it and then drop*/ + if (rx_chk_duplicate_frame(pAd, pRxBlk, wdev) == NDIS_STATUS_FAILURE) { + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(): duplicate frame drop it!\n", __func__)); + return FALSE; + } + + /* 3. Order bit: A-Ralink or HTC+ */ + if (pFmeCtrl->Order) { +#ifdef AGGREGATION_SUPPORT + + /* TODO: shiang-MT7603, fix me, because now we don't have rx_rate.field.MODE can refer */ + if ((pRxBlk->rx_rate.field.MODE <= MODE_OFDM) && + (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE))) + RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK); + else +#endif /* AGGREGATION_SUPPORT */ + { +#ifdef TXBF_SUPPORT +#ifndef MT_MAC + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + if (cap->FlgHwTxBfCap && (pFmeCtrl->SubType & 0x08)) + handleHtcField(pAd, pRxBlk); + +#endif /* MT_MAC */ +#endif /* TXBF_SUPPORT */ + /* skip HTC control field */ + pData += 4; + pRxBlk->DataSize -= 4; + } + } + + /* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */ + if (pFmeCtrl->SubType & 0x04) { /* bit 2 : no DATA */ + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s(): Null/QosNull frame!\n", __func__)); + drop_err = FALSE; + return FALSE; + } + + /* 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; + } + + pRxBlk->pData = pData; +#if defined(SOFT_ENCRYPT) || defined(ADHOC_WPA2PSK_SUPPORT) + + /* Use software to decrypt the encrypted frame if necessary. + If a received "encrypted" unicast packet(its WEP bit as 1) + and it's passed to driver with "Decrypted" marked as 0 in RxInfo. + */ + if (!IS_HIF_TYPE(pAd, HIF_MT)) { + if ((pFmeCtrl->Wep == 1) && (pRxInfo->Decrypted == 0)) { +#ifdef HDR_TRANS_SUPPORT + + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_HDR_TRANS)) { + status = RTMPSoftDecryptionAction(pAd, + pRxBlk->FC, + UserPriority, + &pEntry->PairwiseKey, + pRxBlk->pTransData + 14, + &(pRxBlk->TransDataSize)); + } else +#endif /* HDR_TRANS_SUPPORT */ + { + CIPHER_KEY *pSwKey = &pEntry->PairwiseKey; + + status = RTMPSoftDecryptionAction(pAd, + pRxBlk->FC, + UserPriority, + pSwKey, + pRxBlk->pData, + &(pRxBlk->DataSize)); + } + + if (status != NDIS_STATUS_SUCCESS) { + RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); + return; + } + + /* Record the Decrypted bit as 1 */ + pRxInfo->Decrypted = 1; + } + } + +#endif /* SOFT_ENCRYPT || ADHOC_WPA2PSK_SUPPORT */ +#ifdef SMART_ANTENNA + + if (RTMP_SA_WORK_ON(pAd)) + sa_pkt_radio_info_update(pAd, pRxBlk, pEntry); + +#endif /* SMART_ANTENNA */ + Update_Rssi_Sample(pAd, &pEntry->RssiSample, &pRxBlk->rx_signal, pRxBlk->rx_rate.field.MODE, pRxBlk->rx_rate.field.BW); + pEntry->NoDataIdleCount = 0; + /* TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! */ + pAd->MacTab.tr_entry[pEntry->wcid].NoDataIdleCount = 0; + + if (pRxInfo->U2M) { + Update_Rssi_Sample(pAd, &pAd->ApCfg.RssiSample, &pRxBlk->rx_signal, pRxBlk->rx_rate.field.MODE, pRxBlk->rx_rate.field.BW); + pAd->ApCfg.NumOfAvgRssiSample++; + pEntry->LastRxRate = (ULONG)(pRxBlk->rx_rate.word); +#ifdef TXBF_SUPPORT + + if (pRxBlk->rx_rate.field.ShortGI) + pEntry->OneSecRxSGICount++; + else + pEntry->OneSecRxLGICount++; + +#endif /* TXBF_SUPPORT */ +#ifdef DBG_DIAGNOSE + + if (pAd->DiagStruct.inited) { + struct dbg_diag_info *diag_info; + + diag_info = &pAd->DiagStruct.diag_info[pAd->DiagStruct.ArrayCurIdx]; + diag_info->RxDataCnt++; + } + +#endif /* DBG_DIAGNOSE */ + } + + wdev->LastSNR0 = (UCHAR)(pRxBlk->rx_signal.raw_snr[0]); + wdev->LastSNR1 = (UCHAR)(pRxBlk->rx_signal.raw_snr[1]); + pEntry->freqOffset = (CHAR)(pRxBlk->rx_signal.freq_offset); + pEntry->freqOffsetValid = TRUE; + + if ((pRxBlk->FN != 0) || (pFmeCtrl->MoreFrag != 0)) { + bFragment = TRUE; + de_fragment_data_pkt(pAd, pRxBlk); + } + + if (pRxBlk->pRxPacket) { + /* + process complete frame which encrypted by TKIP, + Minus MIC length and calculate the MIC value + */ + if (bFragment && (pFmeCtrl->Wep) && IS_CIPHER_TKIP_Entry(pEntry)) { + pRxBlk->DataSize -= 8; + + if (rtmp_chk_tkip_mic(pAd, pEntry, pRxBlk) == FALSE) + return TRUE; + } + + pEntry->RxBytes += pRxBlk->MPDUtotalByteCnt; + pAd->RxTotalByteCnt += pRxBlk->MPDUtotalByteCnt; + INC_COUNTER64(pEntry->RxPackets); + pAd->RxTotalByteCnt += pRxBlk->MPDUtotalByteCnt; +#ifdef MAC_REPEATER_SUPPORT + + if (IS_ENTRY_APCLI(pEntry)) + RTMP_SET_PACKET_WCID(pRxBlk->pRxPacket, pRxBlk->wcid); + +#endif /* MAC_REPEATER_SUPPORT */ +#ifdef IGMP_SNOOP_SUPPORT + + if ((IS_ENTRY_CLIENT(pEntry) || IS_ENTRY_WDS(pEntry)) + && (wdev->IgmpSnoopEnable) + && IS_MULTICAST_MAC_ADDR(pRxBlk->Addr3)) { + PUCHAR pDA = pRxBlk->Addr3; + PUCHAR pSA = pRxBlk->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, wdev, pRxBlk->wcid); + else if (protoType == ETH_P_IPV6) + MLDSnooping(pAd, pDA, pSA, pData, wdev, pRxBlk->wcid); + } + +#endif /* IGMP_SNOOP_SUPPORT */ + + if (RX_BLK_TEST_FLAG(pRxBlk, fRX_HDR_TRANS)) + rx_802_3_data_frm_announce(pAd, pEntry, pRxBlk, wdev); + else + rx_data_frm_announce(pAd, pEntry, pRxBlk, wdev); + } + + return TRUE; +} + +BOOLEAN ap_dev_rx_mgmt_frm(RTMP_ADAPTER *pAd, RX_BLK *pRxBlk, MAC_TABLE_ENTRY *pEntry) +{ + RXINFO_STRUC *pRxInfo = pRxBlk->pRxInfo; + INT op_mode = OPMODE_AP; + FRAME_CONTROL *FC = (FRAME_CONTROL *)pRxBlk->FC; +#ifdef IDS_SUPPORT + + /* + Check if a rogue AP impersonats our mgmt frame to spoof clients + drop it if it's a spoofed frame + */ + if (RTMPSpoofedMgmtDetection(pAd, pRxBlk)) + return FALSE; + + /* update sta statistics for traffic flooding detection later */ + RTMPUpdateStaMgmtCounter(pAd, FC->SubType); +#endif /* IDS_SUPPORT */ + + if (!pRxInfo->U2M) { + if ((FC->SubType != SUBTYPE_BEACON) && (FC->SubType != SUBTYPE_PROBE_REQ)) { + BOOLEAN bDrop = TRUE; +#ifdef DOT11W_PMF_SUPPORT + /* For PMF TEST Plan 5.4.3.1 & 5.4.3.2 */ +#ifdef APCLI_SUPPORT + + if (pEntry && ((FC->SubType == SUBTYPE_DISASSOC) || (FC->SubType == SUBTYPE_DEAUTH))) { + if (IS_ENTRY_APCLI(pEntry)) + bDrop = FALSE; + } + +#endif /* APCLI_SUPPORT */ +#endif /* DOT11W_PMF_SUPPORT */ +#ifdef APCLI_SUPPORT +#ifdef APCLI_CERT_SUPPORT + + if (pAd->bApCliCertTest == TRUE) { + if ((FC->SubType == SUBTYPE_ACTION) && (pEntry) && IS_ENTRY_APCLI(pEntry)) + bDrop = FALSE; + } + +#endif /* APCLI_CERT_SUPPOR */ +#endif /* APCLI_SUPPORT */ +#if defined(FTM_SUPPORT) || defined(CONFIG_HOTSPOT) + + if (IsPublicActionFrame(pAd, (VOID *)FC)) + bDrop = FALSE; + +#endif /* defined(FTM_SUPPORT) || defined(CONFIG_HOTSPOT) */ + + if (bDrop == TRUE) + return FALSE; + } + } + + /* Software decrypt WEP data during shared WEP negotiation */ + if ((FC->SubType == SUBTYPE_AUTH) && + (FC->Wep == 1) && (pRxInfo->Decrypted == 0)) { + UCHAR *pMgmt = (PUCHAR)FC; + UINT16 mgmt_len = pRxBlk->MPDUtotalByteCnt; + UCHAR DefaultKeyId; + + if (!pEntry) { + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ERROR: SW decrypt WEP data fails - the Entry is empty.\n")); + return FALSE; + } + + /* Skip 802.11 header */ + pMgmt += LENGTH_802_11; + mgmt_len -= LENGTH_802_11; +#ifdef CONFIG_AP_SUPPORT + DefaultKeyId = pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.SecConfig.PairwiseKeyId; +#endif /* CONFIG_AP_SUPPORT */ + + /* handle WEP decryption */ + if (RTMPSoftDecryptWEP( + &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.SecConfig.WepKey[DefaultKeyId], + pMgmt, + &mgmt_len) == FALSE) { + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ERROR: SW decrypt WEP data fails.\n")); + return FALSE; + } + +#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 */ + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Decrypt AUTH seq#3 successfully\n")); + /* Update the total length */ + pRxBlk->DataSize -= (LEN_WEP_IV_HDR + LEN_ICV); + } + + if (pEntry && (FC->SubType == SUBTYPE_ACTION)) { + /* only PM bit of ACTION frame can be set */ + if (((op_mode == OPMODE_AP) && IS_ENTRY_CLIENT(pEntry)) || + ((op_mode == OPMODE_STA) && (IS_ENTRY_TDLS(pEntry)))) + RtmpPsIndicate(pAd, pRxBlk->Addr2, pRxBlk->wcid, 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. + */ + } + + /* Signal in MLME_QUEUE isn't used, therefore take this item to save min SNR. */ + { + RXD_BASE_STRUCT *rxd_base = (RXD_BASE_STRUCT *)pRxBlk->rmac_info; + + struct wifi_dev *wdev = NULL; + + if (pRxBlk->wcid != RESERVED_WCID) + wdev = pAd->MacTab.Content[pRxBlk->wcid].wdev; + else + wdev = pAd->wdev_list[0]; + REPORT_MGMT_FRAME_TO_MLME(pAd, pRxBlk->wcid, + FC, + pRxBlk->DataSize, + pRxBlk->rx_signal.raw_rssi[0], + pRxBlk->rx_signal.raw_rssi[1], + pRxBlk->rx_signal.raw_rssi[2], + pRxBlk->rx_signal.raw_rssi[3], + min(pRxBlk->rx_signal.raw_snr[0], pRxBlk->rx_signal.raw_snr[1]), + (rxd_base != NULL) ? rxd_base->RxD1.ChFreq : 0, + op_mode, + wdev,/*pAd->wdev_list[0],*/ + pRxBlk->rx_rate.field.MODE); + } + return TRUE; +} + +struct wifi_dev_ops ap_wdev_ops = { + .tx_pkt_allowed = ap_tx_pkt_allowed, + .fp_tx_pkt_allowed = ap_fp_tx_pkt_allowed, + .send_data_pkt = ap_send_data_pkt, + .fp_send_data_pkt = fp_send_data_pkt, + .send_mlme_pkt = ap_send_mlme_pkt, + .tx_pkt_handle = ap_tx_pkt_handle, + .legacy_tx = ap_legacy_tx, + .ampdu_tx = ap_ampdu_tx, + .frag_tx = ap_frag_tx, + .amsdu_tx = ap_amsdu_tx, + .fill_non_offload_tx_blk = ap_fill_non_offload_tx_blk, + .fill_offload_tx_blk = ap_fill_offload_tx_blk, + .mlme_mgmtq_tx = ap_mlme_mgmtq_tx, + .mlme_dataq_tx = ap_mlme_dataq_tx, +#ifdef CONFIG_ATE + .ate_tx = mt_ate_tx, +#endif + .ieee_802_11_data_tx = ap_ieee_802_11_data_tx, + .ieee_802_3_data_tx = ap_ieee_802_3_data_tx, + .rx_pkt_allowed = ap_rx_pkt_allowed, + .rx_ps_handle = ap_rx_ps_handle, + .rx_pkt_foward = ap_rx_pkt_foward, + .ieee_802_3_data_rx = ap_ieee_802_3_data_rx, + .ieee_802_11_data_rx = ap_ieee_802_11_data_rx, + .find_cipher_algorithm = ap_find_cipher_algorithm, + .mac_entry_lookup = mac_entry_lookup, +}; diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_ftkd.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_ftkd.c new file mode 100644 index 000000000..6659db839 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_ftkd.c @@ -0,0 +1,1629 @@ +/**************************************************************************** + * 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. + +***************************************************************************/ + +#ifdef DOT11R_FT_SUPPORT + +#include "rt_config.h" +#include "ft_cmm.h" + +#define TYPE_FUNC +#define FT_KDP_DEBUG +#define FT_KDP_FUNC_TEST +/*#define FT_KDP_EMPTY */ /* empty codes to debug */ + +#define IAPP_DAEMON_CMD_PARSE(__pInfo, __InfoLen, __PeerIP, __pData, __DataLen) \ + do {\ + NdisMoveMemory(&__PeerIP, __pInfo, FT_IP_ADDRESS_SIZE);\ + __pData = (UCHAR *)(__pInfo + FT_IP_ADDRESS_SIZE);\ + __DataLen = __InfoLen - FT_IP_ADDRESS_SIZE;\ + } while (0) + +/* private variable */ +UINT32 FT_KDP_MemAllocNum, FT_KDP_MemFreeNum; + +/* extern variable */ +#ifdef FT_KDP_FUNC_TEST +extern UCHAR gFT_MAC_OldAP[]; +#endif /* FT_KDP_FUNC_TEST */ + +/* private function prototype */ +#ifdef FT_KDP_FUNC_R0KH_IP_RECORD +BOOLEAN FT_KDP_R0KH_InfoAdd( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pR0KHID, + IN UCHAR *pMAC, + IN UINT32 IP); +VOID FT_KDP_R0KH_InfoDel( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pR0KHID, + IN UCHAR *pMAC, + IN UINT32 IP); +static BOOLEAN FT_KDP_R0KH_InfoGet( + IN PRTMP_ADAPTER pAd, + INOUT UCHAR *pR0KHID, + INOUT UCHAR *pMAC, + OUT UINT32 *pIP); +#endif /* FT_KDP_FUNC_R0KH_IP_RECORD */ + + + + +/* public function */ +/* +======================================================================== +Routine Description: + Initialize FT KDP Module. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_Init( + IN PRTMP_ADAPTER pAd) +{ +#ifndef FT_KDP_EMPTY + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 1) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd> Initialize FT KDP Module...\n")); + /* allocate control block */ + FT_MEM_ALLOC(pAd, &pAd->ApCfg.FtTab.pFT_KDP_Ctrl_BK, sizeof(FT_KDP_CTRL_BLOCK)); + + if (pAd->ApCfg.FtTab.pFT_KDP_Ctrl_BK == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd> Allocate control block fail!\n")); + return; + } + + NdisAllocateSpinLock(pAd, &(pAd->ApCfg.FtTab.FT_KdpLock)); +#ifndef FT_KDP_FUNC_SOCK_COMM + /* init event list */ + initList(&(FT_KDP_CB->EventList)); +#endif /* FT_KDP_FUNC_SOCK_COMM */ +#ifdef FT_KDP_FUNC_R0KH_IP_RECORD + /* init R0KH information record */ + FT_KDP_CB->R0KH_InfoHead = NULL; + FT_KDP_CB->R0KH_InfoTail = NULL; + FT_KDP_CB->R0KH_Size = 0; +#endif /* FT_KDP_FUNC_R0KH_IP_RECORD */ +#ifdef FT_KDP_FUNC_INFO_BROADCAST + RTMPInitTimer(pAd, &FT_KDP_CB->TimerReport, + GET_TIMER_FUNCTION(FT_KDP_InfoBroadcast), + (PVOID)pAd, TRUE); + RTMPSetTimer(&FT_KDP_CB->TimerReport, FT_KDP_INFO_BC_PERIOD_TIME); +#endif /* FT_KDP_FUNC_INFO_BROADCAST */ +#endif /* FT_KDP_EMPTY */ + pAd->ApCfg.FtTab.FlgIsFtKdpInit = 1; +} + + +/* +======================================================================== +Routine Description: + Release FT KDP Module. + +Arguments: + pAd - WLAN control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_Release( + IN PRTMP_ADAPTER pAd) +{ +#ifndef FT_KDP_EMPTY +#ifdef FT_KDP_FUNC_R0KH_IP_RECORD + FT_KDP_R0KH_INFO *pInfoHead, *pInfo; +#endif /* FT_KDP_FUNC_R0KH_IP_RECORD */ + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) + return; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd> Release FT KDP Module...\n")); +#ifndef FT_KDP_FUNC_SOCK_COMM + /* free event list */ + FT_KDP_EVT_LIST_EMPTY(pAd, &(FT_KDP_CB->EventList)); +#endif /* FT_KDP_FUNC_SOCK_COMM */ +#ifdef FT_KDP_FUNC_R0KH_IP_RECORD + /* free all R0KH information */ + pInfoHead = FT_KDP_CB->R0KH_InfoHead; + + while (pInfoHead != NULL) { + pInfo = pInfoHead; + pInfoHead = pInfoHead->pNext; + FT_MEM_FREE(pAd, pInfo); + } + +#endif /* FT_KDP_FUNC_R0KH_IP_RECORD */ + + if (pAd->ApCfg.FtTab.pFT_KDP_Ctrl_BK != NULL) { + FT_MEM_FREE(pAd, pAd->ApCfg.FtTab.pFT_KDP_Ctrl_BK); + pAd->ApCfg.FtTab.pFT_KDP_Ctrl_BK = NULL; + } + +#ifdef FT_KDP_FUNC_INFO_BROADCAST + { + BOOLEAN Status; + + RTMPCancelTimer(&FT_KDP_CB->TimerReport, &Status); + } +#endif /* FT_KDP_FUNC_INFO_BROADCAST */ + /* free spin lock */ + NdisFreeSpinLock(&(pAd->ApCfg.FtTab.FT_KdpLock)); +#endif /* FT_KDP_EMPTY */ + pAd->ApCfg.FtTab.FlgIsFtKdpInit = 0; +} + + +/* +======================================================================== +Routine Description: + Inform us a event occurs. + +Arguments: + pAd - WLAN control block pointer + ApIdx - MBSS ID + EventId - which event, such as FT_KDP_SIG_FT_ASSOCIATION + *pEvent - event body + EventLen - event body length + PeerIP - peer IP address + pCB - for special use (such as FT_KDP_SIG_ACTION) + +Return Value: + None + +Note: + EventId *pEvent + -------------------------------------------------------------------- + FT_KDP_SIG_FT_ASSOCIATION FT_KDP_EVT_ASSOC + FT_KDP_SIG_FT_REASSOCIATION FT_KDP_EVT_REASSOC + FT_KDP_SIG_KEY_TIMEOUT yet implement + FT_KDP_SIG_KEY_REQ FT_KDP_EVT_KEY_ELM + FT_KDP_SIG_ACTION WLAN Frame Body (Start from Category field) + pCB == FT_KDP_EVT_ACTION + +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_EventInform( + IN PRTMP_ADAPTER pAd, + IN UINT32 ApIdx, + IN UCHAR EventId, + IN VOID *pEvent, + IN UINT16 EventLen, + IN UINT32 PeerIP, + IN VOID *pCB) +{ +#ifndef FT_KDP_EMPTY +#ifndef FT_KDP_FUNC_SOCK_COMM + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + UCHAR Size; +#endif /* FT_KDP_FUNC_SOCK_COMM */ + FT_KDP_SIGNAL *pFtKdp; + FT_KDP_EVT_HEADER EvtHdr; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + +#ifndef FT_KDP_FUNC_SOCK_COMM + if (CHECK_PID_LEGALITY(pObj->IappPid)) { + /* valid, can do next step */ + } else + return; + + FT_KDP_EVT_LIST_SIZE_GET(pAd, &FT_KDP_CB->EventList, Size); + + if (Size > FT_KDP_EVENT_MAX) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ap_ftkd> Queued Events are too much!\n")); + return; + } + +#endif /* FT_KDP_FUNC_SOCK_COMM */ + /* make up event content */ + NdisZeroMemory(&EvtHdr, sizeof(FT_KDP_EVT_HEADER)); + FT_MEM_ALLOC(pAd, &pFtKdp, sizeof(FT_KDP_SIGNAL)); + + if (pFtKdp == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ap_ftkd> Allocate signal content fail!\n")); + return; + } + + pFtKdp->Sig = EventId; + + /* handle different event */ + switch (EventId) { + case FT_KDP_SIG_FT_ASSOCIATION: { + /* a station associates to us */ + /* + When a STA uses the 802.11 Association Request, rather than + the Reassociation Request, the IAPP may not be able to notify + the AP at which the STA was previously associated of the new + association. + */ + FT_KDP_EVT_ASSOC *pEvtAssoc; + + pEvtAssoc = (FT_KDP_EVT_ASSOC *)pEvent; + pFtKdp->Sequence = pEvtAssoc->SeqNum; + NdisMoveMemory(pFtKdp->MacAddr, pEvtAssoc->MacAddr, MAC_ADDR_LEN); + } + break; + + case FT_KDP_SIG_FT_REASSOCIATION: { + /* a station reassociates to us */ + /* + IEEE802.11f, 1.3 Inter-AP recommended practice overview + + In particular, the IAPP entity must be able to find and use + a RADIUS server to look up the IP addresses of other APs in + the ESS when given the Basic Service Set Identifier (BSSIDs) + of those other APs (if a local capability to perform such a + translation is not present), and to obtain security information + to protect the content of certain IAPP packets. + + Here we dont use any Radius server so sometimes we can not + send the MOVE-notify frame. + */ + /* + The IAPP is not a routing protocol. The IAPP does not deal + directly with the delivery of 802.11 data frames to the STA; + instead the DS utilizes existing network functionality for + data frame delivery. + + When a STA associates or reassociates, the STA must ascertain + that its network layer address(es) is configured such that the + normal routing functions of the network attaching to the BSS + will correctly deliver the STA¡¦s traffic to the BSS to which + it is associated. + + Two mechanisms for a STA to accomplish this are to renew a + Dynamic Host Configuration Protocol (DHCP) lease for its IP + address and to use Mobile IP to obtain a local IP address. + */ + FT_KDP_EVT_REASSOC *pEvtReAssoc; + + pEvtReAssoc = (FT_KDP_EVT_REASSOC *)pEvent; + pFtKdp->Sequence = pEvtReAssoc->SeqNum; + NdisMoveMemory(pFtKdp->MacAddr, pEvtReAssoc->MacAddr, MAC_ADDR_LEN); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> The previous AP showed in Reassoc is =%02x:%02x:%02x:%02x:%02x:%02x\n", + pEvtReAssoc->OldApMacAddr[0], + pEvtReAssoc->OldApMacAddr[1], + pEvtReAssoc->OldApMacAddr[2], + pEvtReAssoc->OldApMacAddr[3], + pEvtReAssoc->OldApMacAddr[4], + pEvtReAssoc->OldApMacAddr[5])); + + /* try to get the IP of old AP */ + if (FT_KDP_R0KH_InfoGet(pAd, NULL, + pEvtReAssoc->OldApMacAddr, + &PeerIP) == FALSE) { + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Send Move notify to Peer IP = %d.%d.%d.%d!\n", + (UINT)(htonl(PeerIP) >> 24) & 0xFF, (UINT)(htonl(PeerIP) >> 16) & 0xFF, + (UINT)(htonl(PeerIP) >> 8) & 0xFF, (UINT) (htonl(PeerIP) & 0xFF))); + } + break; + + case FT_KDP_SIG_KEY_TIMEOUT: + /* PMK-R1 Key timeout */ + break; + + case FT_KDP_SIG_KEY_REQ: { + FT_KDP_EVT_KEY_ELM *pEvtKeyReq; + + /* PMK-R1 Key Request */ + if (PeerIP != 0) + break; + + /* try to find the Peer IP address */ + pEvtKeyReq = (FT_KDP_EVT_KEY_ELM *)pEvent; + + if (FT_KDP_R0KH_InfoGet(pAd, pEvtKeyReq->KeyInfo.R0KHID, + NULL, &PeerIP) == FALSE) { + /* send a broadcast key request packet */ + } + } + break; + + case FT_KDP_SIG_ACTION: { + /* forward FT Action frame by using RRB protocol */ + FT_KDP_EVT_ACTION *pActionCB = (FT_KDP_EVT_ACTION *)pCB; + + if (pCB == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd> pCB == NULL!\n")); + FT_MEM_FREE(pAd, pFtKdp); + return; + } + + pFtKdp->Sequence = pActionCB->RequestType; + NdisMoveMemory(pFtKdp->MacAddr, pActionCB->MacDa, ETH_ALEN); + NdisMoveMemory(pFtKdp->MacAddrSa, pActionCB->MacSa, ETH_ALEN); + NdisMoveMemory(pFtKdp->CurrAPAddr, pActionCB->MacAp, ETH_ALEN); + } + break; + + case FT_KDP_SIG_KEY_REQ_AUTO: + /* PMK-R1 Key Request */ + break; + + case FT_KDP_SIG_KEY_RSP_AUTO: + /* PMK-R1 Key Response */ + break; + + case FT_KDP_SIG_INFO_BROADCAST: + /* broadcast our AP information to neighbor APs */ + break; + + case FT_KDP_SIG_AP_INFO_REQ: + /* request neighbor AP information */ + break; + + case FT_KDP_SIG_AP_INFO_RSP: + /* response my information to a AP */ + break; + + case FT_KSP_SIG_DEBUG_TRACE: + /* change the debug level of IAPP daemon */ + break; + + case FT_KDP_SIG_TERMINATE: + /* terminate FT KDP daemon */ + break; + + default: + /* error event */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Signal is not supported %d!\n", EventId)); + FT_MEM_FREE(pAd, pFtKdp); + return; + } + + /* init event content */ + EvtHdr.PeerIpAddr = PeerIP; + EvtHdr.EventLen = EventLen; + NdisMoveMemory(pFtKdp->Content, &EvtHdr, sizeof(FT_KDP_EVT_HEADER)); + + if (pEvent != NULL) { + NdisMoveMemory(pFtKdp->Content+sizeof(FT_KDP_EVT_HEADER), + pEvent, EventLen); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Event ID = %d, EventLen = %d (%d, %d)\n", + EventId, EventLen, FT_KDP_MemAllocNum, FT_KDP_MemFreeNum)); +#ifndef FT_KDP_FUNC_SOCK_COMM + /* insert to the event queue */ + FT_KDP_EVT_LIST_INSERT_TAIL(pAd, &FT_KDP_CB->EventList, pFtKdp); + + /* inform FT KDP daemon to handle the event */ + if ((EventId == FT_KDP_SIG_TERMINATE) || + (EventId == FT_KSP_SIG_DEBUG_TRACE) || + (EventId == FT_KDP_SIG_FT_ASSOCIATION) || + (EventId == FT_KDP_SIG_FT_REASSOCIATION) || + (EventId == FT_KDP_SIG_KEY_REQ) || + (EventId == FT_KDP_SIG_KEY_TIMEOUT)) { + /* + Note: in VxWorks, we can not send any signal to same task + which issues a ioctl path. + */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Send signal to ft kdp daemon... (EventLen = %d)\n", + EventLen)); + SendSignalToDaemon(SIGUSR2, pObj->IappPid, pObj->IappPid_nr); + } /* End of if */ + +#endif /* FT_KDP_FUNC_SOCK_COMM */ +#ifdef FT_KDP_FUNC_SOCK_COMM + /* inform FT KDP daemon to handle the event */ + { + FT_DRV_ETH_HEADER Hdr8023, *pHdr8023 = &Hdr8023; + NDIS_PACKET *pPktComm; + UINT32 FrameLen; +#ifdef FT_OS_VXWORKS + END_OBJ *pEndEth; +#endif /* FT_OS_VXWORKS */ + /* allocate a rx packet */ + pPktComm = RtmpOSNetPktAlloc(pAd, sizeof(RT_SIGNAL_STRUC)+LENGTH_802_3); + + if (pPktComm != NULL) { + /* make up 802.3 header */ + NdisMoveMemory(pHdr8023->DA, pAd->ApCfg.MBSSID[ApIdx].wdev.bssid, MAC_ADDR_LEN); + /* can not send a packet with same SA & DA in 5VT board */ + /* NdisMoveMemory(pHdr8023->SA, pAd->ApCfg.MBSSID[ApIdx].Bssid, 6); */ + NdisZeroMemory(pHdr8023->SA, ETH_ALEN); + pHdr8023->SA[5] = 0x01; + pHdr8023->Len = IAPP_ETH_PRO; + /* convert 802.11 to 802.3 packet */ +#ifdef FT_OS_VXWORKS + pEndEth = endFindByName("mirror", 0); + + if (pEndEth != NULL) { + /* + Sometimes if I use ra0 to send the command packet, daemon + can not receive the command packet! + So I use bridge to do the receive network interface. + + Support IEEE802.11r DS, must have bridge network interface. + */ + SET_OS_PKT_NETDEV(pPktComm, pEndEth->devObject.pDevice); + } else +#endif /* FT_OS_VXWORKS */ + SET_OS_PKT_NETDEV(pPktComm, get_netdev_from_bssid(pAd, ApIdx)); + + OS_PKT_RESERVE(RTPKT_TO_OSPKT(pPktComm), 2); /* 16 byte align the IP header */ + NdisMoveMemory(OS_PKT_TAIL_BUF_EXTEND(RTPKT_TO_OSPKT(pPktComm), LENGTH_802_3), + pHdr8023, LENGTH_802_3); + FrameLen = RT_SIGNAL_STRUC_HDR_SIZE+sizeof(FT_KDP_EVT_HEADER)+EventLen; + NdisMoveMemory(OS_PKT_TAIL_BUF_EXTEND(RTPKT_TO_OSPKT(pPktComm), FrameLen), + pFtKdp, FrameLen); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Send a command (MBSS%d, Frame Len%d) to IAPP daemon.\n", + ApIdx, FrameLen)); + /* pass this packet to upper layer */ + announce_802_3_packet(pAd, pPktComm, OPMODE_AP); + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Allocate signal to ft kdp daemon fail!\n")); + } + } +#endif +#ifdef FT_KDP_FUNC_SOCK_COMM + FT_MEM_FREE(pAd, pFtKdp); +#endif /* FT_KDP_FUNC_SOCK_COMM */ +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Get a event. + +Arguments: + pAd - WLAN control block pointer + **pFtKdp - the queued event; if NULL, no event is queued. + +Return Value: + None + +Note: + Used in IOCTL from FT KDP daemon. +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_EventGet( + IN PRTMP_ADAPTER pAd, + OUT FT_KDP_SIGNAL **pFtKdp) +{ +#ifndef FT_KDP_EMPTY +#ifndef FT_KDP_FUNC_SOCK_COMM + UCHAR Size; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + FT_KDP_EVT_LIST_SIZE_GET(pAd, &FT_KDP_CB->EventList, Size); + + /* check if any event is queued */ + if (Size <= 0) { + *pFtKdp = NULL; + return; + } + + /* return a event */ + FT_KDP_EVT_LIST_REMOVE_HEAD(pAd, &FT_KDP_CB->EventList, (*pFtKdp)); +#else + *pFtKdp = NULL; +#endif /* FT_KDP_FUNC_SOCK_COMM */ +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Inform us a AP request the key. + +Arguments: + pAd - WLAN control block pointer + PeerIP - the IP of R1KH, must not be 0 + *pNonce - the nonce for key request + *pEvtKeyReq - information for key request + +Return Value: + TRUE - request ok + FALSE - can not find the IP of R0KH + +Note: + If PeerIP == 0, search its IP from our information record. +======================================================================== +*/ +BOOLEAN TYPE_FUNC FT_KDP_KeyRequestToUs( + IN PRTMP_ADAPTER pAd, + IN UINT32 PeerIP, + IN UCHAR *pNonce, + IN FT_KDP_EVT_KEY_ELM *pEvtKeyReq) +{ +#ifndef FT_KDP_EMPTY + UINT32 IDR0KH; + UINT32 ApIdx = BSS0; + MAC_TABLE_ENTRY *pEntry = NULL; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Req from Peer IP = %d.%d.%d.%d!\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF))); + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return FALSE; + } + + if (PeerIP == 0) + return FALSE; + + /* sanity check for R0KHID */ +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Req: R0KH-ID = 0x%02x:%02x:%02x:%02x:%02x:%02x!\n", + pEvtKeyReq->KeyInfo.R0KHID[0], + pEvtKeyReq->KeyInfo.R0KHID[1], + pEvtKeyReq->KeyInfo.R0KHID[2], + pEvtKeyReq->KeyInfo.R0KHID[3], + pEvtKeyReq->KeyInfo.R0KHID[4], + pEvtKeyReq->KeyInfo.R0KHID[5])); +#endif /* FT_KDP_DEBUG */ + + for (IDR0KH = 0; IDR0KH < FT_KDP_R0KHID_MAX_SIZE; IDR0KH++) { + if (pEvtKeyReq->KeyInfo.R0KHID[IDR0KH] != 0x00) { + /* check if the R0KHID is same as us (MBSS); if not, return FALSE */ + /* yet implement */ + } + } + + /* check if the request format is correct */ + if ((pEvtKeyReq->ElmId == FT_KDP_ELM_ID_PRI) && + (pEvtKeyReq->OUI[0] == FT_KDP_ELM_PRI_OUI_0) && + (pEvtKeyReq->OUI[1] == FT_KDP_ELM_PRI_OUI_1) && + (pEvtKeyReq->OUI[2] == FT_KDP_ELM_PRI_OUI_2)) { +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Req: Station MAC = 0x%02x:%02x:%02x:%02x:%02x:%02x!\n", + pEvtKeyReq->MacAddr[0], + pEvtKeyReq->MacAddr[1], + pEvtKeyReq->MacAddr[2], + pEvtKeyReq->MacAddr[3], + pEvtKeyReq->MacAddr[4], + pEvtKeyReq->MacAddr[5])); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Req: R1KH-ID = 0x%02x:%02x:%02x:%02x:%02x:%02x!\n", + pEvtKeyReq->KeyInfo.R1KHID[0], + pEvtKeyReq->KeyInfo.R1KHID[1], + pEvtKeyReq->KeyInfo.R1KHID[2], + pEvtKeyReq->KeyInfo.R1KHID[3], + pEvtKeyReq->KeyInfo.R1KHID[4], + pEvtKeyReq->KeyInfo.R1KHID[5])); +#endif /* FT_KDP_DEBUG */ + + pEntry = MacTableLookup(pAd, pEvtKeyReq->MacAddr); + + if (!pEntry) + return FALSE; + else + ApIdx = pEntry->func_tb_idx; + + /* calculate the PMK-R1 Key for the station vs. the AP */ + if (FT_QueryKeyInfoForKDP(pAd, ApIdx, pEvtKeyReq) == FALSE) + return FALSE; + + /* response the requested PMK-R1 Key to the R1KH */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Rsp to Peer IP = %d.%d.%d.%d!\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF))); + FT_KDP_EventInform(pAd, ApIdx, FT_KDP_SIG_KEY_RSP_AUTO, + (VOID *)pEvtKeyReq, sizeof(FT_KDP_EVT_KEY_ELM), + PeerIP, NULL); + return TRUE; + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ap_ftkd> Key Req format incorrect!\n")); +#endif /* FT_KDP_EMPTY */ + return FALSE; +} + + +/* +======================================================================== +Routine Description: + Inform us a AP response the key. + +Arguments: + pAd - WLAN control block pointer + *pInfo - key information + InfoLen - information length + +Return Value: + None + +Note: + pInfo format is PeerIP (4B) + Nonce (8B) + FT_KDP_EVT_KEY_ELM structure +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_KeyResponseToUs( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pInfo, + IN INT32 InfoLen) +{ +#ifndef FT_KDP_EMPTY + UINT32 PeerIP, DataLen; + UCHAR *pData; + FT_KDP_EVT_KEY_ELM *pEvtKeyRsp; + UCHAR *pNonce; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + IAPP_DAEMON_CMD_PARSE(pInfo, InfoLen, PeerIP, pData, DataLen); + pNonce = pData; + pEvtKeyRsp = (FT_KDP_EVT_KEY_ELM *)(pNonce + FT_NONCE_SIZE); +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Rsp from Peer IP = %d.%d.%d.%d!\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF))); +#endif /* FT_KDP_DEBUG */ + + /* check if the response format is correct */ + if ((pEvtKeyRsp->ElmId == FT_KDP_ELM_ID_PRI) && + (pEvtKeyRsp->OUI[0] == FT_KDP_ELM_PRI_OUI_0) && + (pEvtKeyRsp->OUI[1] == FT_KDP_ELM_PRI_OUI_1) && + (pEvtKeyRsp->OUI[2] == FT_KDP_ELM_PRI_OUI_2)) { + PFT_R1HK_ENTRY pR1hkEntry; + BOOLEAN bUpdateR1kh = FALSE; +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Rsp: Station MAC = 0x%02x:%02x:%02x:%02x:%02x:%02x!\n", + pEvtKeyRsp->MacAddr[0], + pEvtKeyRsp->MacAddr[1], + pEvtKeyRsp->MacAddr[2], + pEvtKeyRsp->MacAddr[3], + pEvtKeyRsp->MacAddr[4], + pEvtKeyRsp->MacAddr[5])); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Key Rsp: R1KH-ID = 0x%02x:%02x:%02x:%02x:%02x:%02x!\n", + pEvtKeyRsp->KeyInfo.R1KHID[0], + pEvtKeyRsp->KeyInfo.R1KHID[1], + pEvtKeyRsp->KeyInfo.R1KHID[2], + pEvtKeyRsp->KeyInfo.R1KHID[3], + pEvtKeyRsp->KeyInfo.R1KHID[4], + pEvtKeyRsp->KeyInfo.R1KHID[5])); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MacAddr")); + hex_dump("PMKR1Name", pEvtKeyRsp->PMKR1Name, FT_KDP_WPA_NAME_MAX_SIZE); + hex_dump("R0KH_MAC", pEvtKeyRsp->R0KH_MAC, ETH_ALEN); + hex_dump("AKM Suite", pEvtKeyRsp->AkmSuite, 4); +#endif /* FT_KDP_DEBUG */ + /* Upon receiving a new PMK-R1 key for a STA, the target AP shall + delete the prior PMK-R1 SA and PTKSAs derived from the prior + PMK-R1 key */ + pR1hkEntry = FT_R1khEntryTabLookup(pAd, pEvtKeyRsp->PMKR1Name); + + if (pR1hkEntry == NULL) + bUpdateR1kh = TRUE; + + if (pR1hkEntry && + RTMPEqualMemory(pR1hkEntry->PmkR1Key, pEvtKeyRsp->PMKR1, LEN_PMK) == FALSE) { + FT_R1khEntryDelete(pAd, pR1hkEntry); + bUpdateR1kh = TRUE; + } + + if (bUpdateR1kh) { + MAC_TABLE_ENTRY *pEntry = NULL; + + pEntry = MacTableLookup(pAd, pEvtKeyRsp->MacAddr); + + /* assign the PMK-R1 key to FT kernel */ + FT_R1khEntryInsert(pAd, + pEvtKeyRsp->KeyInfo.PMKR0Name, + pEvtKeyRsp->PMKR1Name, + pEvtKeyRsp->PMKR1, + pEvtKeyRsp->PairwisChipher, + pEvtKeyRsp->AkmSuite, + pEvtKeyRsp->KeyLifeTime, + pEvtKeyRsp->ReassocDeadline, + (PUINT8)pEvtKeyRsp->KeyInfo.R0KHID, + pEvtKeyRsp->KeyInfo.R0KHIDLen, + pEvtKeyRsp->MacAddr); + + /* YF_FT */ + if (pEntry && ((pEntry->FT_R1kh_CacheMiss_Times > 0) +#ifdef R1KH_HARD_RETRY /* yiwei no give up! */ + || (pEntry->FT_R1kh_CacheMiss_Hard > 0) +#endif /*R1KH_HARD_RETRY */ + )) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s - Reset FT_R1kh_CacheMiss_Times to Zero (Wcid%d, value:%d), time=%ld\n", + __func__, pEntry->wcid, pEntry->FT_R1kh_CacheMiss_Times, (jiffies * 1000) / OS_HZ)); + pEntry->FT_R1kh_CacheMiss_Times = 0; + +#ifdef R1KH_HARD_RETRY /* yiwei no give up! */ + pEntry->FT_R1kh_CacheMiss_Hard = 0; + RTMP_OS_COMPLETE(&pEntry->ack_r1kh); +#endif /* R1KH_HARD_RETRY */ + + + } + } + +#ifdef FT_KDP_FUNC_R0KH_IP_RECORD + /* add the R0KH information */ + FT_KDP_R0KH_InfoAdd(pAd, + pEvtKeyRsp->KeyInfo.R0KHID, + pEvtKeyRsp->R0KH_MAC, + PeerIP); +#endif /* FT_KDP_FUNC_R0KH_IP_RECORD */ + } else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ap_ftkd> Key Rsp format incorrect!\n")); + +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Inform us a FT station joins the BSS domain. + +Arguments: + pAd - WLAN control block pointer + *pInfo - station information + InfoLen - information length + +Return Value: + None + +Note: + pInfo format is PeerIP (4B) + Station MAC (6B) +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_StationInform( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pInfo, + IN INT32 InfoLen) +{ +#ifndef FT_KDP_EMPTY + UINT32 PeerIP, DataLen; + UCHAR *pData; + FT_KDP_EVT_KEY_ELM EvtKeyReq, *pEvtKeyReq; + UCHAR StaMac[ETH_ALEN]; + UINT32 IdBssNum; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + IAPP_DAEMON_CMD_PARSE(pInfo, InfoLen, PeerIP, pData, DataLen); +#ifndef FT_KDP_FUNC_TEST + + /* check if we are in security mode; if not, return */ + for (IdBssNum = 0; IdBssNum < pAd->ApCfg.BssidNum; IdBssNum++) { + if (!IS_AKM_OPEN(pAd->ApCfg.MBSSID[IdBssNum].wdev.SecConfig.AKMMap)) + break; + } + + if (IdBssNum == pAd->ApCfg.BssidNum) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ap_ftkd> All BSS are open mode!\n")); + return; /* all BSS are open mode */ + } + +#endif + NdisMoveMemory(StaMac, pData, ETH_ALEN); + NdisZeroMemory(&EvtKeyReq, sizeof(FT_KDP_EVT_KEY_ELM)); + pEvtKeyReq = &EvtKeyReq; +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Station Inform from Peer IP = %d.%d.%d.%d!\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF))); +#endif + /* make up request content */ + pEvtKeyReq->ElmId = FT_KDP_ELM_ID_PRI; + pEvtKeyReq->ElmLen = FT_KDP_ELM_PRI_LEN; + pEvtKeyReq->OUI[0] = FT_KDP_ELM_PRI_OUI_0; + pEvtKeyReq->OUI[1] = FT_KDP_ELM_PRI_OUI_1; + pEvtKeyReq->OUI[2] = FT_KDP_ELM_PRI_OUI_2; + NdisMoveMemory(pEvtKeyReq->MacAddr, StaMac, ETH_ALEN); + NdisMoveMemory(pEvtKeyReq->KeyInfo.S1KHID, StaMac, FT_KDP_S1KHID_MAX_SIZE); + /* request PMK-R1 Key (our R1KH vs. the station) from the R0KH */ +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Send Key Req to Peer IP = %d.%d.%d.%d!\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF))); +#endif /* FT_KDP_DEBUG */ + + for (IdBssNum = 0; IdBssNum < pAd->ApCfg.BssidNum; IdBssNum++) { +#ifndef FT_KDP_FUNC_TEST + + if (!IS_AKM_OPEN(pAd->ApCfg.MBSSID[IdBssNum].wdev.SecConfig.AKMMap)) +#endif /* FT_KDP_FUNC_TEST */ + { + /* copy our MAC address to be the R1KHID */ + /* different MAC for different BSS in MBSS mode */ + NdisMoveMemory(pEvtKeyReq->KeyInfo.R1KHID, + pAd->ApCfg.MBSSID[IdBssNum].wdev.bssid, + FT_KDP_R1KHID_MAX_SIZE); + FT_KDP_EventInform(pAd, IdBssNum, FT_KDP_SIG_KEY_REQ_AUTO, + (VOID *)pEvtKeyReq, sizeof(FT_KDP_EVT_KEY_ELM), + PeerIP, NULL); + } + } + +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Set the encryption/decryption key from daemon or driver. + +Arguments: + pAd - WLAN control block pointer + *pKey - the key + KeyLen - the key length + +Return Value: + None + +Note: + Key length can be 8B ~ 64B. + + We support key set from daemon or driver. + + Only one key for multiple BSS mode. +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_CryptKeySet( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pKey, + IN INT32 KeyLen) +{ +#ifndef FT_KDP_EMPTY + UCHAR KeyMaterial[40]; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* key set */ + if ((KeyLen >= 8) && (KeyLen <= 64)) { + WPAPasswordHash((RTMP_STRING *)pKey, + (PUCHAR)FT_KDP_RALINK_PASSPHRASE, + strlen(FT_KDP_RALINK_PASSPHRASE), + KeyMaterial); + } else { + WPAPasswordHash((RTMP_STRING *)FT_KDP_KEY_DEFAULT, + (PUCHAR)FT_KDP_RALINK_PASSPHRASE, + strlen(FT_KDP_RALINK_PASSPHRASE), + KeyMaterial); + } + + /* use the first 16B of KeyMaterial[] */ + NdisMoveMemory(FT_KDP_CB->CryptKey, KeyMaterial, sizeof(KeyMaterial)); +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Encrypt the data. + +Arguments: + pAd - WLAN control block pointer + *pData - data buffer + *pDataLen - data buffer length + +Return Value: + None + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_DataEncrypt( + IN PRTMP_ADAPTER pAd, + INOUT UCHAR *pData, + IN UINT32 *pDataLen) +{ +#ifndef FT_KDP_EMPTY + UCHAR *pOutputBuf; + UINT OutputLen = 0; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + FT_MEM_ALLOC(pAd, &pOutputBuf, *pDataLen + FT_KDP_KEY_ENCRYPTION_EXTEND); + + if (pOutputBuf == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd> Allocate encryption buffer fail!\n")); + return; + } + + NdisZeroMemory(pOutputBuf, *pDataLen + FT_KDP_KEY_ENCRYPTION_EXTEND); + /* encrypt */ + AES_Key_Wrap(pData, *pDataLen, FT_KDP_CB->CryptKey, 16, + pOutputBuf, &OutputLen); + *pDataLen = OutputLen; + NdisMoveMemory(pData, pOutputBuf, *pDataLen); + FT_MEM_FREE(pAd, pOutputBuf); +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Decrypt the data. + +Arguments: + pAd - WLAN control block pointer + *pData - data buffer + *pDataLen - data buffer length + +Return Value: + None + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_DataDecrypt( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pData, + IN UINT32 *pDataLen) +{ +#ifndef FT_KDP_EMPTY + UCHAR *pOutputBuf; + UINT OutputLen = 0; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + if ((*pDataLen) <= FT_KDP_KEY_ENCRYPTION_EXTEND) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd>Decryption length is too small!\n")); + return; + } + + /* init */ + FT_MEM_ALLOC(pAd, &pOutputBuf, *pDataLen); + + if (pOutputBuf == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd> Allocate decryption buffer fail!\n")); + return; + } + + /* decrypt */ + AES_Key_Unwrap(pData, *pDataLen, + FT_KDP_CB->CryptKey, 16, + pOutputBuf, &OutputLen); + *pDataLen = OutputLen; + NdisMoveMemory(pData, pOutputBuf, *pDataLen); + FT_MEM_FREE(pAd, pOutputBuf); +#endif /* FT_KDP_EMPTY */ +} + + +/* private function */ +#ifdef FT_KDP_FUNC_R0KH_IP_RECORD +/* +======================================================================== +Routine Description: + Add a R0KH Information. + +Arguments: + pAd - WLAN control block pointer + *pR0KHID - R0KH ID + *pMAC - R0KH MAC + IP - R0KH IP + +Return Value: + None + +Note: +======================================================================== +*/ +BOOLEAN TYPE_FUNC FT_KDP_R0KH_InfoAdd( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pR0KHID, + IN UCHAR *pMAC, + IN UINT32 IP) +{ +#ifndef FT_KDP_EMPTY + FT_KDP_R0KH_INFO *pInfo; + BOOLEAN FlgIsSameRecordFound; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return FALSE; + } + + /* sanity check for maximum size */ + if (FT_KDP_CB->R0KH_Size >= FT_KDP_R0KH_INFO_MAX_SIZE) { + /* delete oldest record first */ + FT_KDP_R0KH_InfoDel(pAd, NULL, NULL, 0); + } + + RTMP_SEM_LOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + /* sanity check if same information exists */ + FlgIsSameRecordFound = FALSE; + pInfo = FT_KDP_CB->R0KH_InfoHead; + + while (pInfo != NULL) { + if ((NdisEqualMemory(pInfo->R0KHID, pR0KHID, sizeof(pInfo->R0KHID))) || + (NdisEqualMemory(pInfo->MAC, pMAC, sizeof(pInfo->MAC))) || + (pInfo->IP == IP)) { + /* need to update the new information to the entry */ + FlgIsSameRecordFound = TRUE; + break; + } + + pInfo = pInfo->pNext; + } + + /* init or update */ + if (FlgIsSameRecordFound == FALSE) { + /* allocate a new record */ + FT_MEM_ALLOC(pAd, &pInfo, sizeof(FT_KDP_R0KH_INFO)); + + if (pInfo == NULL) { + RTMP_SEM_UNLOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("ap_ftkd> Allocate R0KH INFO fail!\n")); + return FALSE; + } + + pInfo->pNext = NULL; + } + + /* update other R0KH device information */ + NdisMoveMemory(pInfo->R0KHID, pR0KHID, sizeof(pInfo->R0KHID)); + NdisMoveMemory(pInfo->MAC, pMAC, sizeof(pInfo->MAC)); + pInfo->IP = IP; + NdisGetSystemUpTime(&pInfo->TimeUpdate); + + /* append the new information to the information list */ + if (FlgIsSameRecordFound == FALSE) { + if (FT_KDP_CB->R0KH_InfoTail == NULL) { + FT_KDP_CB->R0KH_InfoHead = pInfo; + FT_KDP_CB->R0KH_InfoTail = pInfo; + } else { + (FT_KDP_CB->R0KH_InfoTail)->pNext = pInfo; + FT_KDP_CB->R0KH_InfoTail = pInfo; + } + + FT_KDP_CB->R0KH_Size++; + } + + RTMP_SEM_UNLOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); +#endif /* FT_KDP_EMPTY */ + return TRUE; +} + + +/* +======================================================================== +Routine Description: + Delete a R0KH Information. + +Arguments: + pAd - WLAN control block pointer + *pR0KHID - R0KH ID + *pMAC - R0KH MAC + IP - R0KH IP + +Return Value: + None + +Note: + If pR0KHID == NULL, pMAC == NULL, and IP = 0, means deleting the oldest. +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_R0KH_InfoDel( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pR0KHID, + IN UCHAR *pMAC, + IN UINT32 IP) +{ +#ifndef FT_KDP_EMPTY + FT_KDP_R0KH_INFO *pInfo; + FT_KDP_R0KH_INFO *pInfoBackup, *pInfoDelPrev, *pInfoDel; + ULONG TimeOldest; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + pInfoDelPrev = NULL; + pInfoDel = NULL; + TimeOldest = 0xFFFFFFFF; + RTMP_SEM_LOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + /* try to find the one expected to delete */ + pInfo = FT_KDP_CB->R0KH_InfoHead; + + if (pInfo == NULL) { + RTMP_SEM_UNLOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + return; + } + + pInfoBackup = pInfo; + + while (pInfo != NULL) { + if ((pR0KHID == NULL) && (pMAC == NULL) && (IP == 0)) { + /* check if the info is the oldest one */ + if (pInfo->TimeUpdate < TimeOldest) { + TimeOldest = pInfo->TimeUpdate; + pInfoDelPrev = pInfoBackup; + pInfoDel = pInfo; + } + } else { + /* check if the info is the one expected to delete */ + if ((pR0KHID != NULL) && + (NdisEqualMemory(pR0KHID, pInfo->R0KHID, sizeof(pInfo->R0KHID)))) { + pInfoDelPrev = pInfoBackup; + pInfoDel = pInfo; + break; + } + + if ((pMAC != NULL) && + (NdisEqualMemory(pMAC, pInfo->MAC, sizeof(pInfo->MAC)))) { + pInfoDelPrev = pInfoBackup; + pInfoDel = pInfo; + break; + } + + if (pInfo->IP == IP) { + pInfoDelPrev = pInfoBackup; + pInfoDel = pInfo; + break; + } + } + + /* check next one */ + pInfoBackup = pInfo; + pInfo = pInfo->pNext; + } + + /* delete the information record */ + if (pInfoDel != NULL) { + FT_KDP_CB->R0KH_Size--; + + if (FT_KDP_CB->R0KH_Size == 0) { + /* list is empty */ + FT_KDP_CB->R0KH_InfoHead = NULL; + FT_KDP_CB->R0KH_InfoTail = NULL; + } else { + if (pInfoDelPrev == pInfoDel) { + /* must be the head one */ + FT_KDP_CB->R0KH_InfoHead = pInfoDel->pNext; + } else { + /* must not be the head one */ + pInfoDelPrev->pNext = pInfoDel->pNext; + } + } + } else { + /* sorry! can not find the one in the list */ + } + + RTMP_SEM_UNLOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + + /* free the one */ + if (pInfoDel != NULL) + FT_MEM_FREE(pAd, pInfoDel); + +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Get the IP of R0KH by R0KHID or MAC. + +Arguments: + pAd - WLAN control block pointer + *pR0KHID - R0KH ID + *pMAC - R0KH MAC + pIP - R0KH IP + +Return Value: + TRUE - get ok + FALSE - get fail + +Note: +======================================================================== +*/ +static BOOLEAN TYPE_FUNC FT_KDP_R0KH_InfoGet( + IN PRTMP_ADAPTER pAd, + INOUT UCHAR *pR0KHID, + INOUT UCHAR *pMAC, + OUT UINT32 *pIP) +{ +#ifndef FT_KDP_EMPTY + FT_KDP_R0KH_INFO *pInfo; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return FALSE; + } + + RTMP_SEM_LOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + pInfo = FT_KDP_CB->R0KH_InfoHead; + + while (pInfo != NULL) { + /* check if the info is the one expected to get */ + if ((pR0KHID != NULL) && + (NdisEqualMemory(pR0KHID, pInfo->R0KHID, sizeof(pInfo->R0KHID)))) { + *pIP = pInfo->IP; + goto LabelOk; + } + + if ((pMAC != NULL) && + (NdisEqualMemory(pMAC, pInfo->MAC, sizeof(pInfo->MAC)))) { + *pIP = pInfo->IP; + goto LabelOk; + } + + /* check next one */ + pInfo = pInfo->pNext; + } + + RTMP_SEM_UNLOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + return FALSE; +LabelOk: + RTMP_SEM_UNLOCK(&(pAd->ApCfg.FtTab.FT_KdpLock)); + return TRUE; +#else + return FALSE; +#endif /* FT_KDP_EMPTY */ +} +#endif /* FT_KDP_FUNC_R0KH_IP_RECORD */ + + +/* +======================================================================== +Routine Description: + Broadcast our AP information. + +Arguments: + SystemSpecific1 - no use + FunctionContext - WLAN control block pointer + SystemSpecific2 - no use + SystemSpecific3 - no use + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_InfoBroadcast( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ +#ifndef FT_KDP_EMPTY +#ifdef FT_KDP_FUNC_INFO_BROADCAST + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; + UINT32 IdBssNum; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* get my neighbor report element information */ + /* yet implement */ + + for (IdBssNum = 0; IdBssNum < pAd->ApCfg.BssidNum; IdBssNum++) { + /* PeerIP = 0 means destination MAC = 0xFF FF FF FF FF FF */ + FT_KDP_EventInform(pAd, IdBssNum, FT_KDP_SIG_INFO_BROADCAST, + "test", 4, 0, NULL); + } + +#endif /* FT_KDP_FUNC_INFO_BROADCAST */ +#endif /* FT_KDP_EMPTY */ +} + + +#ifdef FT_KDP_FUNC_INFO_BROADCAST +/* +======================================================================== +Routine Description: + Receive a neighbor report from another AP. + +Arguments: + pAd - WLAN control block pointer + *pInfo - report information + InfoLen - information length + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_NeighborReportHandle( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pInfo, + IN INT32 InfoLen) +{ +#ifndef FT_KDP_EMPTY + UINT32 PeerIP, DataLen; + UCHAR *pData; + UINT32 IdBssNum; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + IAPP_DAEMON_CMD_PARSE(pInfo, InfoLen, PeerIP, pData, DataLen); +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Neighbor Report from Peer IP = %d.%d.%d.%d!\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF))); +#endif /* FT_KDP_DEBUG */ + /* yet implememnt */ +#endif /* FT_KDP_EMPTY */ +} +#endif /* FT_KDP_FUNC_INFO_BROADCAST */ + + +/* +======================================================================== +Routine Description: + Receive a neighbor request from another AP. + +Arguments: + pAd - WLAN control block pointer + *pInfo - report information + InfoLen - information length + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_NeighborRequestHandle( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pInfo, + IN INT32 InfoLen) +{ +#ifndef FT_KDP_EMPTY + UINT32 PeerIP, DataLen; + UCHAR *pData; + UINT32 IdBssNum; + UINT16 SsidLen; + RTMP_STRING *pSSID; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + IAPP_DAEMON_CMD_PARSE(pInfo, InfoLen, PeerIP, pData, DataLen); + SsidLen = DataLen; + pSSID = (RTMP_STRING *)pData; + pSSID[SsidLen] = 0x00; + IdBssNum = BSS0; +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Neighbor Request from Peer IP = %d.%d.%d.%d, SSID = %s\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF), pSSID)); +#endif /* FT_KDP_DEBUG */ + /* check if the requested SSID is for us */ + /* 11k yet implememnt */ + /* 11K_ApInfoGet(&ApInfo); */ + /* reponse the neighbor request to the AP */ + /* FT_KDP_EventInform(pAd, IdBssNum, FT_KDP_SIG_AP_INFO_RSP, */ + /* &ApInfo, sizeof(ApInfo), PeerIP, NULL); */ +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Receive a neighbor response from another AP. + +Arguments: + pAd - WLAN control block pointer + *pInfo - report information + InfoLen - information length + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_KDP_NeighborResponseHandle( + IN PRTMP_ADAPTER pAd, + IN UCHAR *pInfo, + IN INT32 InfoLen) +{ +#ifndef FT_KDP_EMPTY + UINT32 PeerIP, DataLen; + UCHAR *pData; + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* init */ + IAPP_DAEMON_CMD_PARSE(pInfo, InfoLen, PeerIP, pData, DataLen); +#ifdef FT_KDP_DEBUG + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("ap_ftkd> Neighbor Response from Peer IP = %d.%d.%d.%d\n", + (htonl(PeerIP) >> 24) & 0xFF, (htonl(PeerIP) >> 16) & 0xFF, (htonl(PeerIP) >> 8) & 0xFF, (htonl(PeerIP) & 0xFF))); +#endif /* FT_KDP_DEBUG */ + /* 11k yet implememnt */ + /* 11K_ResponseHandle(pData, DataLen); */ +#endif /* FT_KDP_EMPTY */ +} + + +/* +======================================================================== +Routine Description: + Handle a RRB frame from DS. + +Arguments: + pAd - WLAN control block pointer + *pInfo - report information + InfoLen - information length + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID TYPE_FUNC FT_RRB_ActionHandle( + IN PRTMP_ADAPTER pAd, + IN INT32 ApIdx, + IN UCHAR *pInfo, + IN INT32 InfoLen) +{ +#ifndef FT_KDP_EMPTY + + if (pAd->ApCfg.FtTab.FlgIsFtKdpInit == 0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ap_ftkd> %s: FT KDP is not init!\n", __func__)); + return; + } + + /* handle it */ + FT_RrbHandler(pAd, ApIdx, pInfo, InfoLen); +#endif /* FT_KDP_EMPTY */ +} + +#endif /* DOT11R_FT_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_ids.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_ids.c new file mode 100644 index 000000000..2027c0662 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_ids.c @@ -0,0 +1,433 @@ +/**************************************************************************** + * 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, MAIN_MBSSID, 0); + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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]); + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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; + pAd->ApCfg.RcvdMaliciousDataCount = 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 RTMP_ADAPTER *pAd, + IN RX_BLK * rxblk) +{ + INT i; + FRAME_CONTROL *FC = (FRAME_CONTROL *)rxblk->FC; + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + /* Spoofed BSSID detection */ + if (NdisEqualMemory(rxblk->Addr2, pAd->ApCfg.MBSSID[i].wdev.bssid, MAC_ADDR_LEN)) { + CHAR RcvdRssi; + struct raw_rssi_info rssi_info; + + rssi_info.raw_rssi[0] = rxblk->rx_signal.raw_rssi[0]; + rssi_info.raw_rssi[1] = rxblk->rx_signal.raw_rssi[1]; + rssi_info.raw_rssi[2] = rxblk->rx_signal.raw_rssi[2]; + RcvdRssi = RTMPMaxRssi(pAd, + ConvertToRssi(pAd, &rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &rssi_info, RSSI_IDX_1), + ConvertToRssi(pAd, &rssi_info, RSSI_IDX_2)); + + switch (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) +{ + 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; + struct raw_rssi_info rssi_info; + + rssi_info.raw_rssi[0] = Rssi0; + rssi_info.raw_rssi[1] = Rssi1; + rssi_info.raw_rssi[2] = Rssi2; + RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &rssi_info, RSSI_IDX_1), + ConvertToRssi(pAd, &rssi_info, RSSI_IDX_2)); + pAd->ApCfg.MBSSID[i].RcvdConflictSsidCount++; + pAd->ApCfg.MBSSID[i].RssiOfRcvdConflictSsid = RcvdRssi; + return; + } + } +} + + +BOOLEAN RTMPReplayAttackDetection( + IN RTMP_ADAPTER *pAd, + IN UCHAR * pAddr2, + IN RX_BLK * rxblk) +{ + INT i; + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + /* Conflict SSID detection */ + if (NdisEqualMemory(pAddr2, pAd->ApCfg.MBSSID[i].wdev.bssid, MAC_ADDR_LEN)) { + CHAR RcvdRssi; + struct raw_rssi_info rssi_info; + + rssi_info.raw_rssi[0] = rxblk->rx_signal.raw_rssi[0]; + rssi_info.raw_rssi[1] = rxblk->rx_signal.raw_rssi[1]; + rssi_info.raw_rssi[2] = rxblk->rx_signal.raw_rssi[2]; + RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &rssi_info, RSSI_IDX_1), + ConvertToRssi(pAd, &rssi_info, RSSI_IDX_2)); + pAd->ApCfg.MBSSID[i].RcvdReplayAttackCount++; + pAd->ApCfg.MBSSID[i].RssiOfRcvdReplayAttack = RcvdRssi; + return TRUE; + } + } + + return FALSE; +} + +VOID RTMPUpdateStaMgmtCounter(RTMP_ADAPTER *pAd, USHORT type) +{ + switch (type) { + case SUBTYPE_ASSOC_REQ: + pAd->ApCfg.RcvdAssocReqCount++; + break; + + case SUBTYPE_REASSOC_REQ: + pAd->ApCfg.RcvdReassocReqCount++; + break; + + case SUBTYPE_PROBE_REQ: + pAd->ApCfg.RcvdProbeReqCount++; + break; + + case SUBTYPE_DISASSOC: + pAd->ApCfg.RcvdDisassocCount++; + break; + + case SUBTYPE_DEAUTH: + pAd->ApCfg.RcvdDeauthCount++; + break; + + case SUBTYPE_AUTH: + pAd->ApCfg.RcvdAuthCount++; + break; + } + + /* + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RcvdAssocReqCount=%d\n", pAd->ApCfg.RcvdAssocReqCount)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RcvdReassocReqCount=%d\n", pAd->ApCfg.RcvdReassocReqCount)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RcvdProbeReqCount=%d\n", pAd->ApCfg.RcvdProbeReqCount)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RcvdDisassocCount=%d\n", pAd->ApCfg.RcvdDisassocCount)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RcvdDeauthCount=%d\n", pAd->ApCfg.RcvdDeauthCount)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("RcvdAuthCount=%d\n", pAd->ApCfg.RcvdAuthCount)); + */ +} + +VOID rtmp_read_ids_from_file( + IN PRTMP_ADAPTER pAd, + RTMP_STRING *tmpbuf, + RTMP_STRING *buffer) +{ + /*IdsEnable */ + if (RTMPGetKeyParameter("IdsEnable", tmpbuf, 10, buffer, TRUE)) { + if (os_str_tol(tmpbuf, 0, 10) == 1) + pAd->ApCfg.IdsEnable = TRUE; + else + pAd->ApCfg.IdsEnable = FALSE; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IDS is %s\n", pAd->ApCfg.IdsEnable ? "enabled" : "disabled")); + } + + /*AuthFloodThreshold */ + if (RTMPGetKeyParameter("AuthFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.AuthFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AuthFloodThreshold = %d\n", pAd->ApCfg.AuthFloodThreshold)); + } + + /*AssocReqFloodThreshold */ + if (RTMPGetKeyParameter("AssocReqFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.AssocReqFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AssocReqFloodThreshold = %d\n", pAd->ApCfg.AssocReqFloodThreshold)); + } + + /*ReassocReqFloodThreshold */ + if (RTMPGetKeyParameter("ReassocReqFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.ReassocReqFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ReassocReqFloodThreshold = %d\n", pAd->ApCfg.ReassocReqFloodThreshold)); + } + + /*ProbeReqFloodThreshold */ + if (RTMPGetKeyParameter("ProbeReqFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.ProbeReqFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("ProbeReqFloodThreshold = %d\n", pAd->ApCfg.ProbeReqFloodThreshold)); + } + + /*DisassocFloodThreshold */ + if (RTMPGetKeyParameter("DisassocFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.DisassocFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("DisassocFloodThreshold = %d\n", pAd->ApCfg.DisassocFloodThreshold)); + } + + /*DeauthFloodThreshold */ + if (RTMPGetKeyParameter("DeauthFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.DeauthFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("DeauthFloodThreshold = %d\n", pAd->ApCfg.DeauthFloodThreshold)); + } + + /*EapReqFloodThreshold */ + if (RTMPGetKeyParameter("EapReqFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.EapReqFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("EapReqFloodThreshold = %d\n", pAd->ApCfg.EapReqFloodThreshold)); + } + + /* DataFloodThreshold */ + if (RTMPGetKeyParameter("DataFloodThreshold", tmpbuf, 10, buffer, TRUE)) { + pAd->ApCfg.DataFloodThreshold = os_str_tol(tmpbuf, 0, 10); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("DataFloodThreshold = %d\n", pAd->ApCfg.DataFloodThreshold)); + } +} + +#endif /* IDS_SUPPORT */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mbss.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mbss.c new file mode 100644 index 000000000..02b160cda --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mbss.c @@ -0,0 +1,313 @@ +/**************************************************************************** + * 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 + + 4. BSS Index (0 ~ 15) of different tx packet is assigned in + + 5. BSS Index (0 ~ 15) of different BSS is got in tx_pkt_handle() by using + + 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 + + +#include "rt_config.h" + +#ifdef VENDOR_FEATURE7_SUPPORT +#ifndef ARRIS_MODULE_PRESENT +void (*f)(int, int, int, char*, int) = arris_event_send_hook_fn; +#endif /* !ARRIS_MODULE_PRESENT */ +#endif +#ifdef MULTI_PROFILE +INT multi_profile_devname_req(struct _RTMP_ADAPTER *ad, UCHAR *final_name, UCHAR *ifidx); +#endif /*MULTI_PROFILE*/ + +extern struct wifi_dev_ops ap_wdev_ops; + +/* --------------------------------- 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. +======================================================================== +*/ +VOID MBSS_Init(RTMP_ADAPTER *pAd, 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; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + /* sanity check to avoid redundant virtual interfaces are created */ + if (pAd->FlgMbssInit != FALSE) + return; + + MaxNumBss = pAd->ApCfg.BssidNum; + + if (MaxNumBss > HW_BEACON_MAX_NUM) + MaxNumBss = HW_BEACON_MAX_NUM; + + /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ + for (IdBss = FIRST_MBSSID; IdBss < HW_BEACON_MAX_NUM; IdBss++) { + pAd->ApCfg.MBSSID[IdBss].wdev.if_dev = NULL; + pAd->ApCfg.MBSSID[IdBss].wdev.bcn_buf.BeaconPkt = NULL; + } + + /* create virtual network interface */ + for (IdBss = FIRST_MBSSID; IdBss < MaxNumBss; IdBss++) { + struct wifi_dev *wdev; + UINT32 MC_RowID = 0, IoctlIF = 0; + char *dev_name = NULL; + INT32 Ret; + BSS_STRUCT *pMbss = NULL; + UCHAR ifidx = IdBss; + UCHAR final_name[32]=""; + BOOLEAN autoSuffix = TRUE; +#ifdef MULTIPLE_CARD_SUPPORT + MC_RowID = pAd->MC_RowID; +#endif /* MULTIPLE_CARD_SUPPORT */ +#ifdef HOSTAPD_SUPPORT + IoctlIF = pAd->IoctlIF; +#endif /* HOSTAPD_SUPPORT */ + + dev_name = get_dev_name_prefix(pAd, INT_MBSSID); + + if(dev_name == NULL){ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("get_dev_name_prefix error!\n")); + break; + } + snprintf(final_name,sizeof(final_name),"%s",dev_name); +#ifdef MULTI_PROFILE + multi_profile_devname_req(pAd,final_name,&ifidx); + if (ifidx == 0) + autoSuffix = FALSE; +#endif /*MULTI_PROFILE*/ + pDevNew = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_MBSSID, ifidx, + sizeof(struct mt_dev_priv), final_name, autoSuffix); +#ifdef HOSTAPD_SUPPORT + pAd->IoctlIF = IoctlIF; +#endif /* HOSTAPD_SUPPORT */ + + if (pDevNew == NULL) { + pAd->ApCfg.BssidNum = IdBss; /* re-assign new MBSS number */ + break; + } + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Register MBSSID IF (%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pDevNew))); + + pMbss = &pAd->ApCfg.MBSSID[IdBss]; + wdev = &pAd->ApCfg.MBSSID[IdBss].wdev; + Ret = wdev_init(pAd, wdev, WDEV_TYPE_AP, pDevNew, IdBss, + (VOID *)&pAd->ApCfg.MBSSID[IdBss], (void *)pAd); + + if (!Ret) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Assign wdev idx for %s failed, free net device!\n", + RTMP_OS_NETDEV_GET_DEVNAME(pDevNew))); + RtmpOSNetDevFree(pDevNew); + break; + } + + Ret = wdev_ops_register(wdev, WDEV_TYPE_AP, &ap_wdev_ops, + cap->wmm_detect_method); + + if (!Ret) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("register wdev_ops %s failed, free net device!\n", + RTMP_OS_NETDEV_GET_DEVNAME(pDevNew))); + RtmpOSNetDevFree(pDevNew); + break; + } + + RTMP_OS_NETDEV_SET_PRIV(pDevNew, pAd); + RTMP_OS_NETDEV_SET_WDEV(pDevNew, wdev); + /* init operation functions and flags */ + NdisCopyMemory(&netDevHook, pNetDevOps, sizeof(netDevHook)); + netDevHook.priv_flags = INT_MBSSID; + netDevHook.needProtcted = TRUE; + netDevHook.wdev = wdev; + /* Init MAC address of virtual network interface */ + NdisMoveMemory(&netDevHook.devAddr[0], &wdev->bssid[0], MAC_ADDR_LEN); + /* 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(RTMP_ADAPTER *pAd) +{ + struct wifi_dev *wdev; + UINT IdBss; + BSS_STRUCT *pMbss; + INT32 MaxNumBss; + + if (!pAd) + return; + + MaxNumBss = pAd->ApCfg.BssidNum; + + if (MaxNumBss > HW_BEACON_MAX_NUM) + MaxNumBss = HW_BEACON_MAX_NUM; + + + for (IdBss = FIRST_MBSSID; IdBss < MaxNumBss; IdBss++) { + wdev = &pAd->ApCfg.MBSSID[IdBss].wdev; + pMbss = &pAd->ApCfg.MBSSID[IdBss]; + + if (pMbss) + bcn_buf_deinit(pAd, &wdev->bcn_buf); + + if (wdev->if_dev) { + RtmpOSNetDevProtect(1); + RtmpOSNetDevDetach(wdev->if_dev); + RtmpOSNetDevProtect(0); + wdev_deinit(pAd, wdev); + RtmpOSNetDevFree(wdev->if_dev); + wdev->if_dev = NULL; + } + } +} + + +/* +======================================================================== +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(RTMP_ADAPTER *pAd, PNET_DEV pDev) +{ + INT32 BssId = -1; + INT32 IdBss; + + if (!pAd || !pDev) + return -1; + + for (IdBss = 0; IdBss < pAd->ApCfg.BssidNum; IdBss++) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.if_dev == pDev) { + BssId = IdBss; + break; + } + } + + return BssId; +} + +#ifdef MT_MAC +INT32 ext_mbss_hw_cr_enable(PNET_DEV pDev) +{ + PRTMP_ADAPTER pAd; + INT BssId; + + pAd = RTMP_OS_NETDEV_GET_PRIV(pDev); + BssId = RT28xx_MBSS_IdxGet(pAd, pDev); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("##### %s, BssId = %d\n", __func__, BssId)); + + if (BssId < 0) + return -1; + + if (!IS_HIF_TYPE(pAd, HIF_MT)) + return 0; + + AsicSetExtMbssEnableCR(pAd, BssId, TRUE);/* enable rmac 0_1~0_15 bit */ + AsicSetMbssHwCRSetting(pAd, BssId, TRUE);/* enable lp timing setting for 0_1~0_15 */ + return 0; +} + + +INT ext_mbss_hw_cr_disable(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; + + if (!IS_HIF_TYPE(pAd, HIF_MT)) + return 0; + + AsicSetMbssHwCRSetting(pAd, BssId, FALSE); + AsicSetExtMbssEnableCR(pAd, BssId, FALSE); + return 0; +} +#endif /* MT_MAC */ + +#endif /* MBSS_SUPPORT */ + + + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mbss_inf.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mbss_inf.c new file mode 100644 index 000000000..9d816d23b --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mbss_inf.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * 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 + + 4. BSS Index (0 ~ 15) of different tx packet is assigned in + + 5. BSS Index (0 ~ 15) of different BSS is got in ap_tx_pkt_handle() by using + + 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 + +/*#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(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(VOID *pAd, PNET_DEV pDevMain) +{ + RTMP_OS_NETDEV_OP_HOOK netDevHook; + + NdisZeroMemory(&netDevHook, sizeof(netDevHook)); + netDevHook.open = mbss_virtual_if_open; /* device opem hook point */ + netDevHook.stop = mbss_virtual_if_close; /* device close hook point */ + netDevHook.xmit = rt28xx_send_packets; /* hard transmit hook point */ + netDevHook.ioctl = rt28xx_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(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_virtual_if_open(PNET_DEV pDev) +{ + VOID *pAd; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: ===> %s\n", + RTMP_OS_NETDEV_GET_DEVNAME(pDev), __func__)); + + pAd = RTMP_OS_NETDEV_GET_PRIV(pDev); + + if (VIRTUAL_IF_INIT(pAd, pDev) != 0) + return -1; + + if (VIRTUAL_IF_UP(pAd, pDev) != 0) + return -1; + + /* increase MODULE use count */ + RT_MOD_INC_USE_COUNT(); + RT_MOD_HNAT_REG(pDev); + 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_virtual_if_close(PNET_DEV pDev) +{ + VOID *pAd; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s: ===> %s\n", + RTMP_OS_NETDEV_GET_DEVNAME(pDev), __func__)); + + pAd = RTMP_OS_NETDEV_GET_PRIV(pDev); + + RTMP_OS_NETDEV_STOP_QUEUE(pDev); + + VIRTUAL_IF_DOWN(pAd, pDev); + + VIRTUAL_IF_DEINIT(pAd, pDev); + + RT_MOD_HNAT_DEREG(pDev); + RT_MOD_DEC_USE_COUNT(); + return 0; +} + +#endif /* MBSS_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mlme.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mlme.c new file mode 100644 index 000000000..4c5a5f7c3 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mlme.c @@ -0,0 +1,732 @@ +/**************************************************************************** + * 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 + +#define MCAST_WCID_TO_REMOVE 0 /* Pat: TODO */ + +#ifdef APCLI_SUPPORT +#ifdef APCLI_CERT_SUPPORT +extern UCHAR ZeroSsid[32]; +#endif /* APCLI_CERT_SUPPORT */ +#endif /* APCLI_SUPPORT */ + +#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; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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!! */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Bss2040CoexistTimeOut(): bBssCoexEnable is FALSE, return directly!\n")); + return; + } + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) + SendBSS2040CoexistMgmtAction(pAd, MCAST_WCID_TO_REMOVE, 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; + struct freq_oper oper; + BOOLEAN bSupport2G = HcIsRfSupport(pAd, RFIC_24GHZ); + int i; + struct wifi_dev *wdev; + UCHAR cfg_ht_bw; + UCHAR cfg_ext_cha; + + if (DetectOverlappingPeriodicRound == 0) { + /* switch back 20/40 */ + if (bSupport2G) { + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + wdev = &pAd->ApCfg.MBSSID[i].wdev; + cfg_ht_bw = wlan_config_get_ht_bw(wdev); + if (wmode_2_rfic(wdev->PhyMode) == RFIC_24GHZ && (cfg_ht_bw == HT_BW_40)) { + cfg_ext_cha = wlan_config_get_ext_cha(wdev); + wlan_operate_set_ht_bw(wdev, HT_BW_40, cfg_ext_cha); + } + } + } + } else { + if ((DetectOverlappingPeriodicRound == 25) || (DetectOverlappingPeriodicRound == 1)) { + if (hc_radio_query_by_rf(pAd, RFIC_24GHZ, &oper) != HC_STATUS_OK) { + return; + } + if (oper.ht_bw == HT_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) +{ +#ifdef A_BAND_SUPPORT + BOOLEAN bSupport5G = HcIsRfSupport(pAd, RFIC_5GHZ); + +#ifdef MT_DFS_SUPPORT + USHORT ChannelMovingTime; +#endif +#endif /*A_BAND_SUPPORT*/ + /* + 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 != DBG_LVL_TRACE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Carrier gone\n")); + /* start all TX actions. */ + UpdateBeaconHandler( + pAd, + NULL, + BCN_UPDATE_AP_RENEW); + AsicSetSyncModeAndEnable(pAd, pAd->CommonCfg.BeaconPeriod, HW_BSSID_0, OPMODE_AP); + } else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Carrier gone\n")); + } + + pCarrierDetect->OneSecIntCount = 0; + } + +#endif /* CARRIER_DETECTION_SUPPORT */ +#ifdef VOW_SUPPORT + vow_display_info_periodic(pAd); +#endif /* VOW_SUPPORT */ +#ifdef RED_SUPPORT + if (pAd->red_debug_en && (pAd->red_have_cr4 == FALSE)) + appShowRedDebugMessage(pAd); +#endif /* RED_SUPPORT */ +#ifdef FQ_SCH_SUPPORT + if (pAd->fq_ctrl.dbg_en) + app_show_fq_dbgmsg(pAd); +#endif /* RRSCH_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) */ + RTMP_CHIP_ASIC_ADJUST_TX_POWER(pAd); + /*#endif // WIFI_TEST */ + RTMP_CHIP_ASIC_TEMPERATURE_COMPENSATION(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 */ + } + +#ifdef AP_SCAN_SUPPORT + AutoChannelSelCheck(pAd); +#endif /* AP_SCAN_SUPPORT */ +#ifdef APCLI_SUPPORT + + if (pAd->Mlme.OneSecPeriodicRound % 2 == 0) + ApCliIfMonitor(pAd); + + if (pAd->Mlme.OneSecPeriodicRound % 2 == 1 +#ifdef APCLI_AUTO_CONNECT_SUPPORT + && (pAd->ApCfg.ApCliAutoConnectChannelSwitching == FALSE) +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ + ) + ApCliIfUp(pAd); + + { + INT loop; + ULONG Now32; + +#ifdef MAC_REPEATER_SUPPORT + + if (pAd->ApCfg.bMACRepeaterEn) + RTMPRepeaterReconnectionCheck(pAd); + +#endif /* MAC_REPEATER_SUPPORT */ + + NdisGetSystemUpTime(&Now32); + + for (loop = 0; loop < MAX_APCLI_NUM; loop++) { + PAPCLI_STRUCT pApCliEntry = &pAd->ApCfg.ApCliTab[loop]; +#ifdef APCLI_CERT_SUPPORT + + if ((pApCliEntry->bBlockAssoc == TRUE) && + RTMP_TIME_AFTER(Now32, pApCliEntry->LastMicErrorTime + (60*OS_HZ))) + pAd->ApCfg.ApCliTab[loop].bBlockAssoc = FALSE; + +#endif /* APCLI_CERT_SUPPORT */ + + if ((pApCliEntry->Valid == TRUE) + && (VALID_UCAST_ENTRY_WCID(pAd, pApCliEntry->MacTabWCID))) { + /* update channel quality for Roaming and UI LinkQuality display */ + MlmeCalculateChannelQuality(pAd, + &pAd->MacTab.Content[pApCliEntry->MacTabWCID], Now32); + } + } + } +#endif /* APCLI_SUPPORT */ +#ifdef DOT11_N_SUPPORT + { + INT IdBss = 0; + UCHAR ht_protect_en = 1; + BSS_STRUCT *pMbss = NULL; + + for (IdBss = 0; IdBss < pAd->ApCfg.BssidNum; IdBss++) { + pMbss = &pAd->ApCfg.MBSSID[IdBss]; + + if ((pMbss) && (&pMbss->wdev) && (pMbss->wdev.DevInfo.Active)) { + ht_protect_en = wlan_config_get_ht_protect_en(&pMbss->wdev); + if (ht_protect_en) { + ApUpdateCapabilityAndErpIe(pAd, pMbss); + APUpdateOperationMode(pAd, &pMbss->wdev); + } + } + } + } +#endif /* DOT11_N_SUPPORT */ + +#ifdef A_BAND_SUPPORT + if (bSupport5G && (pAd->CommonCfg.bIEEE80211H == 1)) { + INT IdBss = 0; + BOOLEAN BandInCac[DBDC_BAND_NUM]; + UCHAR i; + BSS_STRUCT *pMbss = NULL; + struct DOT11_H *pDot11hTest = NULL; + struct wifi_dev *wdev; + UCHAR BandIdx; + + for (i = 0; i < DBDC_BAND_NUM; i++) + BandInCac[i] = FALSE; + + for (IdBss = 0; IdBss < pAd->ApCfg.BssidNum; IdBss++) { + pMbss = &pAd->ApCfg.MBSSID[IdBss]; + wdev = &pMbss->wdev; + + if ((pMbss == NULL) || (wdev == NULL)) + continue; + if (wdev->pHObj == NULL) + continue; + + BandIdx = HcGetBandByWdev(wdev); + pDot11hTest = &pAd->Dot11_H[BandIdx]; + + if (pDot11hTest == NULL) + continue; +#ifdef MT_DFS_SUPPORT + if (pDot11hTest->RDMode == RD_SILENCE_MODE) { + if (BandInCac[BandIdx] == TRUE) + continue; + else + BandInCac[BandIdx] = TRUE; +#ifdef BACKGROUND_SCAN_SUPPORT + if (IS_SUPPORT_MT_ZEROWAIT_DFS(pAd) == TRUE) + ChannelMovingTime = pDot11hTest->DfsZeroWaitChMovingTime; + else +#endif + { + ChannelMovingTime = pDot11hTest->ChMovingTime; + } + + if (pDot11hTest->RDCount++ > ChannelMovingTime) { + pDot11hTest->RDCount = 0; + MlmeEnqueue(pAd, DFS_STATE_MACHINE, DFS_CAC_END, 0, NULL, HcGetBandByWdev(wdev)); + AsicSetSyncModeAndEnable(pAd, pAd->CommonCfg.BeaconPeriod, HW_BSSID_0, OPMODE_AP); + pDot11hTest->RDMode = RD_NORMAL_MODE; + } + } else +#endif + { + pDot11hTest->InServiceMonitorCount++; + } + } + } +#endif /* A_BAND_SUPPORT */ + +#ifdef MT_DFS_SUPPORT + DfsNonOccupancyCountDown(pAd); + DfsOutBandCacCountUpdate(pAd); +#endif +#ifdef MBO_SUPPORT + MboCheckBssTermination(pAd); +#endif /* MBO_SUPPORT */ +#ifdef DOT11R_FT_SUPPORT + FT_R1KHInfoMaintenance(pAd); +#endif /* DOT11R_FT_SUPPORT */ +#ifdef APCLI_SUPPORT +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 +#ifdef APCLI_CERT_SUPPORT + /* Perform 20/40 BSS COEX scan every Dot11BssWidthTriggerScanInt */ + { + UCHAR apcli2Gidx = 0; +#ifdef DBDC_MODE + if (pAd->CommonCfg.dbdc_mode) + apcli2Gidx = 1; +#endif + if (APCLI_IF_UP_CHECK(pAd, apcli2Gidx) && (pAd->bApCliCertTest == TRUE)) { + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)) && + (pAd->CommonCfg.Dot11BssWidthTriggerScanInt != 0) && + ((pAd->Mlme.OneSecPeriodicRound % pAd->CommonCfg.Dot11BssWidthTriggerScanInt) == (pAd->CommonCfg.Dot11BssWidthTriggerScanInt-1))) { +#ifdef MT7615 + if (IS_MT7615(pAd) || IS_MT7622(pAd)) { + PAPCLI_STRUCT pApCliEntry = &pAd->ApCfg.ApCliTab[BSS0]; + MAC_TABLE_ENTRY *pEntry = NULL; + STA_TR_ENTRY *tr_entry = NULL; + UINT tx_tp = 0; + UINT rx_tp = 0; + + if (pApCliEntry->Valid == TRUE) { + pEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID]; + tr_entry = &pAd->MacTab.tr_entry[pApCliEntry->MacTabWCID]; + } + + if ((pEntry) && IS_ENTRY_APCLI(pEntry) && (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) { + tx_tp = ((pApCliEntry->OneSecTxBytes) >> BYTES_PER_SEC_TO_MBPS); + rx_tp = ((pApCliEntry->OneSecRxBytes) >> BYTES_PER_SEC_TO_MBPS); + } + + /* Check last scan time at least 30 seconds from now. */ + /* Check traffic is less than about 1.5~2Mbps.*/ + /* it might cause data lost if we enqueue scanning.*/ + /* This criteria needs to be considered*/ + + if ((tx_tp < 1) && (rx_tp < 1)) { + MLME_SCAN_REQ_STRUCT ScanReq; + /* Fill out stuff for scan request and kick to scan*/ + ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST); + /* Before scan, reset trigger event table. */ + TriEventInit(pAd); + MlmeEnqueue(pAd, AP_SYNC_STATE_MACHINE, APMT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, (ULONG)(&pApCliEntry->wdev)); + /* Set InfoReq = 1, So after scan , alwats sebd 20/40 Coexistence frame to AP*/ + pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1; + RTMP_MLME_HANDLER(pAd); + } + } else +#endif /* MT7615 */ + { + MTWF_LOG(DBG_CAT_MLME, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MMCHK - LastOneSecTotalTxCount/LastOneSecRxOkDataCnt = %d/%d\n", + pAd->RalinkCounters.LastOneSecTotalTxCount, + pAd->RalinkCounters.LastOneSecRxOkDataCnt)); + + /* Check last scan time at least 30 seconds from now. */ + /* Check traffic is less than about 1.5~2Mbps.*/ + /* it might cause data lost if we enqueue scanning.*/ + /* This criteria needs to be considered*/ + if ((pAd->RalinkCounters.LastOneSecTotalTxCount < 70) && (pAd->RalinkCounters.LastOneSecRxOkDataCnt < 70)) { + MLME_SCAN_REQ_STRUCT ScanReq; + /* Fill out stuff for scan request and kick to scan*/ + ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST); + /* Before scan, reset trigger event table. */ + TriEventInit(pAd); + MlmeEnqueue(pAd, AP_SYNC_STATE_MACHINE, APMT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq, 0); + /* Set InfoReq = 1, So after scan , alwats sebd 20/40 Coexistence frame to AP*/ + pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1; + RTMP_MLME_HANDLER(pAd); + } + + MTWF_LOG(DBG_CAT_MLME, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("MMCHK - LastOneSecTotalTxCount/LastOneSecRxOkDataCnt = %d/%d\n", + pAd->RalinkCounters.LastOneSecTotalTxCount, + pAd->RalinkCounters.LastOneSecRxOkDataCnt)); + } + } + } + } +#endif /* APCLI_CERT_SUPPORT */ +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ +#endif /* APCLI_SUPPORT */ +#ifdef BAND_STEERING + BndStrgHeartBeatMonitor(pAd); +#endif +} + + +/*! \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; +#ifdef DOT11_SAE_SUPPORT + USHORT Alg; +#endif /* DOT11_SAE_SUPPORT */ + UCHAR EAPType; + BOOLEAN Return = FALSE; +#ifdef WSC_AP_SUPPORT + UCHAR EAPCode; + PMAC_TABLE_ENTRY pEntry; +#endif /* WSC_AP_SUPPORT */ + unsigned char hdr_len = LENGTH_802_11; + + /* + 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 == FC_TYPE_DATA) { +#ifdef WSC_AP_SUPPORT + WSC_CTRL *wsc_ctrl; + struct wifi_dev *wdev; + + /*WSC EAPOL PACKET */ + pEntry = MacTableLookup(pAd, pFrame->Hdr.Addr2); + + if (pEntry) { + wdev = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev; + + if (pEntry->bWscCapable + || IS_AKM_OPEN(wdev->SecConfig.AKMMap) + || IS_AKM_SHARED(wdev->SecConfig.AKMMap) + || IS_AKM_AUTOSWITCH(wdev->SecConfig.AKMMap)) { + /* + WSC AP only can service one WSC STA in one WPS session. + Forward this EAP packet to WSC SM if this EAP packets is from + WSC STA that WSC AP services or WSC AP doesn't service any + WSC STA now. + */ + wsc_ctrl = &wdev->WscControl; + + if ((MAC_ADDR_EQUAL(wsc_ctrl->EntryAddr, pEntry->Addr) || + MAC_ADDR_EQUAL(wsc_ctrl->EntryAddr, ZERO_MAC_ADDR)) && + IS_ENTRY_CLIENT(pEntry) && + (wsc_ctrl->WscConfMode != WSC_DISABLE)) { + *Machine = WSC_STATE_MACHINE; + EAPType = *((UCHAR *)pFrame + hdr_len + LENGTH_802_1_H + 1); + EAPCode = *((UCHAR *)pFrame + hdr_len + LENGTH_802_1_H + 4); + Return = WscMsgTypeSubst(EAPType, EAPCode, MsgType); + } + } + } + +#endif /* WSC_AP_SUPPORT */ + + if (!Return) { + *Machine = WPA_STATE_MACHINE; + EAPType = *((UCHAR *)pFrame + hdr_len + LENGTH_802_1_H + 1); + Return = WpaMsgTypeSubst(EAPType, (INT *) MsgType); + } + + return Return; + } + + if (pFrame->Hdr.FC.Type != FC_TYPE_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; + + /* 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 */ +#ifdef DOT11_SAE_SUPPORT + NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT)); +#endif /* DOT11_SAE_SUPPORT */ + NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT)); + *Machine = AP_AUTH_STATE_MACHINE; + + if (Seq == 1 +#ifdef DOT11_SAE_SUPPORT + || (Alg == AUTH_MODE_SAE && Seq == 2) +#endif /* DOT11_SAE_SUPPORT */ + ) + *MsgType = APMT2_PEER_AUTH_REQ; + else if (Seq == 3) + *MsgType = APMT2_PEER_AUTH_CONFIRM; + else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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; + } + + 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 CONFIG_ATE + + if (ATE_ON(pAd)) + return; + +#endif /* CONFIG_ATE */ +#ifdef CARRIER_DETECTION_SUPPORT + + if (pAd->CommonCfg.CarrierDetect.CD_State == CD_SILENCE) + return; + +#endif /* CARRIER_DETECTION_SUPPORT */ + 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(RTMP_ADAPTER *pAd) +{ + CHAR rssi[3], *target_rssi; +#ifdef CONFIG_ATE + + if (ATE_ON(pAd)) + return; + +#endif /* CONFIG_ATE */ + + /* if the traffic is low, use average rssi as the criteria */ + if (pAd->Mlme.bLowThroughput == TRUE) + target_rssi = &pAd->ApCfg.RssiSample.LastRssi[0]; + else + target_rssi = &pAd->ApCfg.RssiSample.AvgRssi[0]; + + NdisMoveMemory(&rssi[0], target_rssi, 3); + /* Disable the below to fix 1T/2R issue. It's suggested by Rory at 2007/7/11. */ + 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/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mumimo.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mumimo.c new file mode 100644 index 000000000..f3a113cb4 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mumimo.c @@ -0,0 +1,4695 @@ +/* + * $Id$ + * $DateTime$ + * Jeffrey Chang + */ +/* + This file contains IOCTL for MU-MIMO specfic commands + */ +/******************************************************************************* + * Copyright (c) 2014 MediaTek Inc. + * + * All rights reserved. Copying, compilation, modification, distribution + * or any other use whatsoever of this material is strictly prohibited + * except in accordance with a Software License Agreement with + * MediaTek Inc. + * ****************************************************************************** + */ +/****************************************************************************** + * LEGAL DISCLAIMER + * + * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND + * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK + * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE + * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY + * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE + * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY + * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK + * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY + * WARRANTY CLAIM RELATING THERetO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE + * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO + * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. + * + * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE + * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL + * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT + * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY + * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE + * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT + * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING + * THEREOF AND RELATED THERetO SHALL BE SETTLED BY ARBITRATION IN SAN + * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE + * (ICC). + * ****************************************************************************** + */ +#include "rt_config.h" +#ifdef CFG_SUPPORT_MU_MIMO +/* For debugging, Not for ATE */ +#define SU 0 +#define MU 1 +#define MU_PROFILE_NUM 32 /* to be removed */ +#define QD_RAW_DATA_LEN 56 +static VOID eventDispatcher(struct cmd_msg *msg, char *rsp_payload, UINT16 rsp_payload_len); +INT SetMuProfileProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + PCHAR pch = NULL; + PCHAR pValid = NULL; + PCHAR pIdx = NULL; + PCHAR pBaMask = NULL; + PCHAR pWlanIdx = NULL; + CMD_MU_SET_MUPROFILE_ENTRY param = {0}; + UINT32 cmd = MU_SET_MUPROFILE_ENTRY; + struct _CMD_ATTRIBUTE attr = {0}; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s: arg = %s\n", __func__, arg)); + pch = strsep(&arg, "_"); + + if (pch != NULL) + pValid = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pIdx = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pBaMask = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) + pWlanIdx = pch; + else { + Ret = 0; + goto error; + } + + param.valid = (BOOLEAN)os_str_tol(pValid, 0, 10); + param.index = os_str_tol(pIdx, 0, 10); + param.baMask = os_str_tol(pBaMask, 0, 16); + param.wlanIdx = os_str_tol(pWlanIdx, 0, 10); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowMuProfileProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + PCHAR pch = NULL; + struct cmd_msg *msg = NULL; + INT32 Ret = TRUE; + PCHAR pIdx = NULL; + UINT32 index = 0; + EVENT_SHOW_MUPROFILE_ENTRY result = {0}; + UINT32 cmd = MU_GET_MUPROFILE_ENTRY; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = arg; + + if (pch != NULL) + pIdx = pch; + else { + Ret = 0; + goto error; + } + + index = os_str_tol(pIdx, 0, 10); + index = cpu2le32(index); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(index)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *) &cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *) &index, sizeof(index)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* | ucNumUser | ucBW | ucNS0 | ucNS1 | ucNS2 | ucNS3 | + * | ucPFIDUser0 | ucPFIDUser1 | ucPFIDUser2 | ucPFIDUser3 | + * | fgIsShortGI | fgIsUsed | fgIsDisable | + * | ucInitMCSUser0 | ucInitMCSUser1 | ucInitMCSUser2 | ucIitMCSUser3| + * | ucdMCSUser0 | ucdMCSUser1 | ucdMCSUser2 | ucdMCSUser3| +*/ +/* iwpriv ra0 [index] [num_user: 0/1/2/3] [bw:/0/1/2/3] [ns0:0/1] [ns1:0/1] [ns2:0/1] [ns3:0/1] + [pfid0] [pfid1] [pfid2] [pfid3] [sgi] [used] [dis] [initMcs0] [initMcs1] + [initMcs2] [initMcs3] [dMcs0] [dMcs1] [dMcs2] [dMcs3] +*/ +INT SetGroupTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + PCHAR pch = NULL; + PCHAR pNumUser = NULL; + PCHAR pIndex = NULL; + PCHAR pBw = NULL; + PCHAR pNs0 = NULL; + PCHAR pNs1 = NULL; + PCHAR pNs2 = NULL; + PCHAR pNs3 = NULL; + PCHAR ppfid0 = NULL; + PCHAR ppfid1 = NULL; + PCHAR ppfid2 = NULL; + PCHAR ppfid3 = NULL; + PCHAR psgi = NULL; + PCHAR pused = NULL; + PCHAR pdis = NULL; + PCHAR pinitMcsUser0 = NULL; + PCHAR pinitMcsUser1 = NULL; + PCHAR pinitMcsUser2 = NULL; + PCHAR pinitMcsUser3 = NULL; + PCHAR pdMcsUser0 = NULL; + PCHAR pdMcsUser1 = NULL; + PCHAR pdMcsUser2 = NULL; + PCHAR pdMcsUser3 = NULL; + CMD_MU_SET_GROUP_TBL_ENTRY param = {0}; + UINT32 cmd = MU_SET_GROUP_TBL_ENTRY; + struct _CMD_ATTRIBUTE attr = {0}; + /* we fetch the minimum first */ + pch = strsep(&arg, "_"); + + if (pch != NULL) + pIndex = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pNumUser = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pBw = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pNs0 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pNs1 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pNs2 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pNs3 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + ppfid0 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + ppfid1 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + ppfid2 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + ppfid3 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + psgi = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pused = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pdis = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pinitMcsUser0 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pinitMcsUser1 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pinitMcsUser2 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pinitMcsUser3 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pdMcsUser0 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pdMcsUser1 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pdMcsUser2 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) + pdMcsUser3 = pch; + else { + Ret = 0; + goto error; + } + + param.index = os_str_tol(pIndex, 0, 10); + param.numUser = os_str_tol(pNumUser, 0, 10); + param.BW = os_str_tol(pBw, 0, 10); + param.PFIDUser0 = os_str_tol(ppfid0, 0, 10); + param.PFIDUser1 = os_str_tol(ppfid1, 0, 10); + param.PFIDUser2 = os_str_tol(ppfid2, 0, 10); + param.PFIDUser3 = os_str_tol(ppfid3, 0, 10); + param.fgIsShortGI = (BOOLEAN) os_str_tol(psgi, 0, 10); + param.fgIsUsed = (BOOLEAN) os_str_tol(pused, 0, 10); + param.fgIsDisable = (BOOLEAN) os_str_tol(pdis, 0, 10); + param.initMcsUser0 = os_str_tol(pinitMcsUser0, 0, 10); + param.initMcsUser1 = os_str_tol(pinitMcsUser1, 0, 10); + param.initMcsUser2 = os_str_tol(pinitMcsUser2, 0, 10); + param.initMcsUser3 = os_str_tol(pinitMcsUser3, 0, 10); + param.dMcsUser0 = os_str_tol(pdMcsUser0, 0, 10); + param.dMcsUser1 = os_str_tol(pdMcsUser1, 0, 10); + param.dMcsUser2 = os_str_tol(pdMcsUser2, 0, 10); + param.dMcsUser3 = os_str_tol(pdMcsUser3, 0, 10); + param.NS0 = os_str_tol(pNs0, 0, 10); + param.NS1 = os_str_tol(pNs1, 0, 10); + param.NS2 = os_str_tol(pNs2, 0, 10); + param.NS3 = os_str_tol(pNs3, 0, 10); +#ifdef RT_BIG_ENDIAN + param.index = cpu2le32(param.index); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Values %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", + param.index, param.numUser, param.BW, + param.NS0, param.NS1, param.NS2, param.NS3, + param.PFIDUser0, param.PFIDUser1, param.PFIDUser2, param.PFIDUser3, + param.fgIsShortGI, param.fgIsUsed, param.fgIsDisable, param.initMcsUser0, + param.initMcsUser1, param.initMcsUser2, param.initMcsUser3, + param.dMcsUser0, param.dMcsUser1, param.dMcsUser2, param.dMcsUser3)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(CMD_MU_SET_GROUP_TBL_ENTRY)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(CMD_MU_SET_GROUP_TBL_ENTRY)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowGroupTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + PCHAR pch = NULL; + PCHAR pIndex = NULL; + UINT32 index = 0; + EVENT_SHOW_GROUP_TBL_ENTRY result = {0}; + UINT32 cmd = MU_GET_GROUP_TBL_ENTRY; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = arg; + + if (pch != NULL) + pIndex = pch; + else { + Ret = 0; + goto error; + } + + index = os_str_tol(pIndex, 0, 10); + index = cpu2le32(index); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Index is: %d\n", index)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(index)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)&index, sizeof(index)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/*<-------------------------------------------------------------------------->*/ +/* iwpriv ra0 [index] [lowMemberStatus] [highMemberStatus] [[lowUserPosition0] + [lowUserPosition1][highUserPosistion0] [highUserPosistion1] - in hex +*/ +INT SetClusterTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + PCHAR pch = NULL; + PCHAR pIndex = NULL; + PCHAR pLowGidUserMemberStatus = NULL; + PCHAR pHighGidUserMemberStatus = NULL; + PCHAR pLowGidUserPosition0 = NULL; + PCHAR pLowGidUserPosition1 = NULL; + PCHAR pHighGidUserPosition0 = NULL; + PCHAR pHighGidUserPosition1 = NULL; + CMD_MU_SET_CLUSTER_TBL_ENTRY param = {0}; + UINT32 cmd = MU_SET_CLUSTER_TBL_ENTRY; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pIndex = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pLowGidUserMemberStatus = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pHighGidUserMemberStatus = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pLowGidUserPosition0 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pLowGidUserPosition1 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pHighGidUserPosition0 = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) + pHighGidUserPosition1 = pch; + else { + Ret = 0; + goto error; + } + + param.index = os_str_tol(pIndex, 0, 10); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s\n", __func__)); + /* do we need change edian? */ + param.gidUserMemberStatus[0] = os_str_tol(pLowGidUserMemberStatus, 0, 16); + param.gidUserMemberStatus[1] = os_str_tol(pHighGidUserMemberStatus, 0, 16); + param.gidUserPosition[0] = os_str_tol(pLowGidUserPosition0, 0, 16); + param.gidUserPosition[1] = os_str_tol(pLowGidUserPosition1, 0, 16); + param.gidUserPosition[2] = os_str_tol(pHighGidUserPosition0, 0, 16); + param.gidUserPosition[3] = os_str_tol(pHighGidUserPosition1, 0, 16); +#ifdef RT_BIG_ENDIAN + param.gidUserMemberStatus[0] = cpu2le32(param.gidUserMemberStatus[0]); + param.gidUserMemberStatus[1] = cpu2le32(param.gidUserMemberStatus[1]); + param.gidUserPosition[0] = cpu2le32(param.gidUserPosition[0]); + param.gidUserPosition[1] = cpu2le32(param.gidUserPosition[1]); + param.gidUserPosition[2] = cpu2le32(param.gidUserPosition[2]); + param.gidUserPosition[3] = cpu2le32(param.gidUserPosition[3]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Values: %d %d %d %d %d %d %d\n", param.index, + param.gidUserMemberStatus[0], param.gidUserMemberStatus[1], + param.gidUserPosition[0], param.gidUserPosition[1], + param.gidUserPosition[2], param.gidUserPosition[3])); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(CMD_MU_SET_CLUSTER_TBL_ENTRY)); + AndesSendCmdMsg(pAd, msg); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("msg is sent\n")); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowClusterTblEntryProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + PCHAR pch = NULL; + PCHAR pIndex = NULL; + UINT32 index = 0; + EVENT_MU_GET_CLUSTER_TBL_ENTRY result = {0}; + UINT32 cmd = MU_GET_CLUSTER_TBL_ENTRY; + struct _CMD_ATTRIBUTE attr = {0}; + /* we fetch the minimum first */ + pch = arg; + + if (pch != NULL) + pIndex = pch; + else { + Ret = 0; + goto error; + } + + index = os_str_tol(pIndex, 0, 10); + index = cpu2le32(index); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Index is: %d\n", index)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(index)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *) &cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *) &index, sizeof(index)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetMuEnableProc + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * @descriton: enable/1 or disable/0 the MU module + */ +/* iwpriv ra0 set_mu_enable [1/0] */ +INT SetMuEnableProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + BOOLEAN value = 0; + UINT32 cmd = MU_SET_ENABLE; + CMD_MU_SET_ENABLE param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, NULL, 10); + param.fgIsEnable = value; + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(CMD_MU_SET_ENABLE)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *) &cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *) &value, sizeof(value)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowMuEnableProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + EVENT_SHOW_MU_ENABLE result = {0}; + UINT32 cmd = MU_GET_ENABLE; + struct _CMD_ATTRIBUTE attr = {0}; + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(EVENT_SHOW_MU_ENABLE)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *) &cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT SetGroupUserThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + PCHAR pch = NULL; + PCHAR pMinVal = NULL; + PCHAR pMaxVal = NULL; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_GROUP_USER_THRESHOLD param = {0}; + UINT32 cmd = MU_SET_GROUP_USER_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + /* we fetch the minimum first */ + pch = strsep(&arg, "_"); + + if (pch != NULL) + pMinVal = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) + pMaxVal = pch; + else { + Ret = 0; + goto error; + } + + param.min = os_str_tol(pMinVal, 0, 10); + param.max = os_str_tol(pMaxVal, 0, 10); + + if (param.min < 2 || param.max > 4) { + Ret = 0; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Min < 2 and Max > 4 is NOT allowed\n")); + goto error; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Values %d %d\n", param.min, param.max)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowGroupUserThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + EVENT_MU_GET_GROUP_USER_THRESHOLD result = {0}; + UINT32 cmd = MU_GET_GROUP_USER_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT SetCalculateInitMCSProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + PCHAR pch = NULL; + PCHAR pIndex = NULL; + UINT32 index = 0; + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_CALC_INIT_MCS; + EVENT_STATUS result = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pIndex = pch; + else { + Ret = 0; + goto error; + } + + index = cpu2le32(index); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(index)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *) &cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *) &index, sizeof(index)); + Ret = AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetGroupNssProc + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT SetGroupNssThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + PCHAR pch = NULL; + PCHAR pMinVal = NULL; + PCHAR pMaxVal = NULL; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_GROUP_NSS_THRESHOLD param = {0}; + UINT32 cmd = MU_SET_GROUP_NSS_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + /* we fetch the minimum first */ + pch = strsep(&arg, "_"); + + if (pch != NULL) + pMinVal = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) + pMaxVal = pch; + else { + Ret = 0; + goto error; + } + + param.min = os_str_tol(pMinVal, 0, 10); + param.max = os_str_tol(pMaxVal, 0, 10); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Values %d %d\n", param.min, param.max)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowGroupNssThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + EVENT_MU_GET_GROUP_NSS_THRESHOLD result = {0}; + UINT32 cmd = MU_GET_GROUP_NSS_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetTxReqMinTime + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + */ +INT SetTxReqMinTimeProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT16 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_TXREQ_MIN_TIME param = {0}; + UINT32 cmd = MU_SET_TXREQ_MIN_TIME; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 16); + param.value = cpu2le16(value); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Values %d\n", param.value)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowTxReqMinTimeProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + EVENT_MU_GET_TXREQ_MIN_TIME result = {0}; + UINT32 cmd = MU_GET_TXREQ_MIN_TIME; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Nitesh: In the function ShowCalcInitMCSProc + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + *it shows the Init MCS value for the corresponding Group Index + */ +INT ShowCalcInitMCSProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + PCHAR pch = NULL; + PCHAR pIndex = NULL; + UINT32 index = 0; + EVENT_SHOW_GROUP_TBL_ENTRY result = {0}; + UINT32 cmd = MU_GET_CALC_INIT_MCS; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = arg; + + if (pch != NULL) + pIndex = pch; + else { + Ret = 0; + goto error; + } + + index = os_str_tol(pIndex, 0, 10); + index = cpu2le32(index); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(index)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)&index, sizeof(index)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function MuSetSuNssCheck + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + *it checl the nss of the primary ac owner if su nss= mu nss + */ +INT SetSuNssCheckProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT8 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_SU_NSS_CHECK; + CMD_SET_NSS_CHECK param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + + if (value < 0 || value > 1) + return FALSE; + + param.fgIsEnable = value; + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function MuSetSuNssCheck + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT ShowSuNssCheckProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_GET_SU_NSS_CHECK; + EVENT_SHOW_NSS_CHECK result = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function send GID management frame + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + *it triggers the GID management frame + */ +INT SetTriggerGIDMgmtFrameProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_TRIGGER_GID_MGMT_FRAME; + PCHAR pch = NULL; + PCHAR pWlanIdx = NULL; + PCHAR pGid = NULL; + PCHAR pUp = NULL; + CMD_SET_TRIGGER_GID_MGMT_FRAME param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pWlanIdx = pch; + else { + Ret = FALSE; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pGid = pch; + else { + Ret = FALSE; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) + pUp = pch; + else { + Ret = FALSE; + goto error; + } + + param.wlanIndex = os_str_tol(pWlanIdx, 0, 10); +#ifdef RT_BIG_ENDIAN + param.wlanIndex = cpu2le16(param.wlanIndex); +#endif + param.gid = os_str_tol(pGid, 0, 10); + param.up = os_str_tol(pUp, 0, 10); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(value)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT SetTriggerSndProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_TRIGGER_SND; + CMD_SET_TRIGGER_SND param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT SetTriggerBbpProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_TRIGGER_BBP; + CMD_SET_TRIGGER_BBP param = {0}; + UINT16 value = 0; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + + if (value > 2048) { + Ret = FALSE; + goto error; + } + + param.u2GroupIndex = cpu2le16(value); /* 0~3: 1 to 4 user grouping */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT SetTriggerGroupProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_TRIGGER_GROUP; + CMD_SET_TRIGGER_GROUP param = {0}; + UINT8 value = 0; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + + if (value < 2) { + Ret = FALSE; + goto error; + } + + param.ucNum = (value - 1); /* 0~3: 1 to 4 user grouping */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT SetTriggerDegroupProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_TRIGGER_DEGROUP; + CMD_SET_TRIGGER_DEGROUP param = {0}; + UINT8 value = 0; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + param.ucMuProfileIndex = value; + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT SetTriggerMuTxProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_SET_TRIGGER_MU_TX; + UINT32 index = 0; + CMD_SET_TRIGGER_MU_TX_FRAME param = {0}; + PCHAR pch = NULL; + PCHAR pAcIndex = NULL; + PCHAR pNumOfStas = NULL; + PCHAR pRound = NULL; + PCHAR pRandom = NULL; + PCHAR pWlanIndex = NULL; + PCHAR pPayloadLength = NULL; + struct _CMD_ATTRIBUTE attr = {0}; + /* we fetch the minimum first */ + pch = strsep(&arg, "_"); + + if (pch != NULL) + pAcIndex = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pRandom = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pNumOfStas = pch; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "_"); + + if (pch != NULL) + pRound = pch; + else { + Ret = 0; + goto error; + } + + param.ucAcIndex = os_str_tol(pAcIndex, 0, 10); + param.fgIsRandomPattern = os_str_tol(pRandom, 0, 10); + param.u4NumOfSTAs = os_str_tol(pNumOfStas, 0, 10); + param.u4Round = os_str_tol(pRound, 0, 10); + + for (index = 0; index < param.u4NumOfSTAs; index++) { + pch = strsep(&arg, "_"); + + if (pch != NULL) + pWlanIndex = pch; + else { + Ret = 0; + goto error; + } + + param.aucWlanIndexArray[index] = os_str_tol(pWlanIndex, 0, 10); + } + + for (index = 0; index < param.u4NumOfSTAs; index++) { + if (index != (param.u4NumOfSTAs - 1)) { + pch = strsep(&arg, "_"); + + if (pch != NULL) + pPayloadLength = pch; + else { + Ret = 0; + goto error; + } + } else { + pch = strsep(&arg, ""); + + if (pch != NULL) + pPayloadLength = pch; + else { + Ret = 0; + goto error; + } + } + + param.au4PayloadLength[index] = os_str_tol(pPayloadLength, 0, 10); + param.au4PayloadLength[index] = cpu2le32(param.au4PayloadLength[index]); + } + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(param)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, ¶m); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); + param.u4NumOfSTAs = cpu2le32(param.u4NumOfSTAs); + param.u4Round = cpu2le32(param.u4Round); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetTxopDefault + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT SetTxopDefaultProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_TXOP_DEFAULT param = {0}; + UINT32 cmd = MU_SET_TXOP_DEFAULT; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + param.value = cpu2le32(value); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* @Jeffrey: In the function SetTxopDefault +* +* @params: pAd, to provide Adapter +* @params: arg, the command line strings +* +* +*/ +INT ShowTxopDefaultProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + EVENT_GET_TXOP_DEFAULT result = {0}; + UINT32 cmd = MU_GET_TXOP_DEFAULT; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetSuLossThreshold + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT SetSuLossThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT16 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_SU_LOSS_THRESHOLD param = {0}; + UINT32 cmd = MU_SET_SU_LOSS_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + param.value = cpu2le16(value); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* @Jeffrey: In the function SetTxopDefault +* +* @params: pAd, to provide Adapter +* @params: arg, the command line strings +* +* +*/ +INT ShowSuLossThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + EVENT_MU_GET_SU_LOSS_THRESHOLD result = {0}; + UINT32 cmd = MU_GET_SU_LOSS_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetMuGainThreshold + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT SetMuGainThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT16 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_MU_GAIN_THRESHOLD param = {0}; + UINT32 cmd = MU_SET_MU_GAIN_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + param.value = cpu2le16(value); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* @Jeffrey: In the function SetTxopDefault +* +* @params: pAd, to provide Adapter +* @params: arg, the command line strings +* +* +*/ +INT ShowMuGainThresholdProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + EVENT_MU_GET_MU_GAIN_THRESHOLD result = {0}; + UINT32 cmd = MU_GET_MU_GAIN_THRESHOLD; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetSecondaryAcPolicy + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT SetSecondaryAcPolicyProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT16 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_MU_SECONDARY_AC_POLICY param = {0}; + UINT32 cmd = MU_SET_SECONDARY_AC_POLICY; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + param.value = cpu2le16(value); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* @Jeffrey: In the function SetTxopDefault +* +* @params: pAd, to provide Adapter +* @params: arg, the command line strings +* +* +*/ +INT ShowSecondaryAcPolicyProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + EVENT_MU_GET_SECONDARY_AC_POLICY result = {0}; + UINT32 cmd = MU_GET_SECONDARY_AC_POLICY; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *) &cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetGroupTblDmcsMask + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT SetGroupTblDmcsMaskProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT8 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_MU_GROUP_TBL_DMCS_MASK param = {0}; + UINT32 cmd = MU_SET_GROUP_TBL_DMCS_MASK; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + param.value = value; + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* @Jeffrey: In the function SetTxopDefault +* +* @params: pAd, to provide Adapter +* @params: arg, the command line strings +* +* +*/ +INT ShowGroupTblDmcsMaskProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + EVENT_MU_GET_GROUP_TBL_DMCS_MASK result = {0}; + UINT32 cmd = MU_GET_GROUP_TBL_DMCS_MASK; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* + * @Jeffrey: In the function SetMaxGroupSearchCnt + * + * @params: pAd, to provide Adapter + * @params: arg, the command line strings + * + * + */ +INT SetMaxGroupSearchCntProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 value = 0; + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_SET_MU_MAX_GROUP_SEARCH_CNT param = {0}; + UINT32 cmd = MU_SET_MAX_GROUP_SEARCH_CNT; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + param.value = cpu2le32(value); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* @Jeffrey: In the function SetTxopDefault +* +* @params: pAd, to provide Adapter +* @params: arg, the command line strings +* +* +*/ +INT ShowMaxGroupSearchCntProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + EVENT_MU_GET_MAX_GROUP_SEARCH_CNT result = {0}; + UINT32 cmd = MU_GET_MAX_GROUP_SEARCH_CNT; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +INT ShowMuProfileTxStsCntProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + PCHAR pch = NULL; + PCHAR pIndex = NULL; + UINT16 index = 0; + CMD_GET_MU_PFID_TXS_CNT param = {0}; + EVENT_MU_GET_MUPROFILE_TX_STATUS_CNT result = {0}; + UINT32 cmd = MU_GET_MU_PROFILE_TX_STATUS_CNT; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = arg; + + if (pch != NULL) + pIndex = pch; + else { + Ret = 0; + goto error; + } + + index = os_str_tol(pIndex, 0, 10); + param.u2PfidIndex = cpu2le16(index); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(index)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &result); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +static VOID ShowGroupTblEntryCallback(char *rsp_payload, UINT16 rsp_payload_len) +{ + UINT8 ucI = 0; + P_EVENT_SHOW_GROUP_TBL_ENTRY pGentry = + (P_EVENT_SHOW_GROUP_TBL_ENTRY)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Resp Payload: ")); + + for (ucI = 0; ucI < rsp_payload_len; ucI++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %x", rsp_payload[ucI])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("group table index %d\n", pGentry->index)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Number of User %d\n", pGentry->numUser)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("BW %d\n", pGentry->BW)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("NS0 %d\n", pGentry->NS0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("NS1 %d\n", pGentry->NS1)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("NS2 %d\n", pGentry->NS2)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("NS3 %d\n", pGentry->NS3)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("PFIDUser0 %d\n", pGentry->PFIDUser0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("PFIDUser1 %d\n", pGentry->PFIDUser1)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("PFIDUser2 %d\n", pGentry->PFIDUser2)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("PFIDUser3 %d\n", pGentry->PFIDUser3)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("SGI %d\n", pGentry->fgIsShortGI)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("USED %d\n", pGentry->fgIsUsed)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("DISABLED %d\n", pGentry->fgIsDisable)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("initMCS0 %d\n", pGentry->initMcsUser0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("initMCS1 %d\n", pGentry->initMcsUser1)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("initMCS2 %d\n", pGentry->initMcsUser2)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("initMCS3 %d\n", pGentry->initMcsUser3)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("dMCS0 %d\n", pGentry->dMcsUser0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("dMCS1 %d\n", pGentry->dMcsUser1)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("dMCS2 %d\n", pGentry->dMcsUser2)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("dMCS3 %d\n", pGentry->dMcsUser3)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +/* | Valid |BA | WLAN INDEX| */ +/* usage iwpriv ra0 set_mu_profile [valid] [index] [bamask] [wlanIdex] */ +static VOID ShowMuProfileEntryCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + UINT8 ucI = 0; + P_EVENT_SHOW_MUPROFILE_ENTRY pMentry = + (P_EVENT_SHOW_MUPROFILE_ENTRY)rsp_payload; + /* TODO: replaced printk to Driver logger */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("mu table index %d\n", pMentry->index)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Valid %d\n", pMentry->valid)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("BAMask %x\n", pMentry->baMask)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("wlanIdx %d\n", pMentry->wlanIdx)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("rsp payload len %d\n", rsp_payload_len)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Resp Payload: ")); + + for (ucI = 0; ucI < rsp_payload_len; ucI++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %x", rsp_payload[ucI])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +/* usage iwpriv ra0 set_mu_profile [valid] [index] [bamask] [wlanIdex] */ +static VOID ShowMuEnableCallback(char *rsp_payload, UINT16 rsp_payload_len) +{ + UINT8 ucI = 0; + P_EVENT_SHOW_MU_ENABLE pMentry = (P_EVENT_SHOW_MU_ENABLE)rsp_payload; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("MU enable:%x", pMentry->fgIsEnable)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Resp Payload: ")); + + for (ucI = 0; ucI < rsp_payload_len; ucI++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %x", rsp_payload[ucI])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowGroupUserThresholdCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_GROUP_USER_THRESHOLD pGentry = + (P_EVENT_MU_GET_GROUP_USER_THRESHOLD)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Group user Threshold minimum value: %x\n", pGentry->min)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Group user Threshold maximum value: %x\n", pGentry->max)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowSecondaryAcPolicyCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_SECONDARY_AC_POLICY pGentry = + (P_EVENT_MU_GET_SECONDARY_AC_POLICY)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("secondary ac policy value: %x\n", pGentry->value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowGroupTblDmcsMaskCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_GROUP_TBL_DMCS_MASK pGentry = + (P_EVENT_MU_GET_GROUP_TBL_DMCS_MASK)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("group table dmcs mask value: %x\n", pGentry->value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowMaxGroupSearchCntCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_MAX_GROUP_SEARCH_CNT pGentry = + (P_EVENT_MU_GET_MAX_GROUP_SEARCH_CNT)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("max. group search cnt value: %x\n", pGentry->value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowTxReqMinTimeCallback(char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_TXREQ_MIN_TIME pGentry = + (P_EVENT_MU_GET_TXREQ_MIN_TIME)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TxReqMinTime value: %x\n", pGentry->value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowMuProfileTxStsCntCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_MUPROFILE_TX_STATUS_CNT pGentry = + (P_EVENT_MU_GET_MUPROFILE_TX_STATUS_CNT) rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("mu profile index: %x\n", pGentry->pfIndex)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,2) used: %x\n", pGentry->cn2used)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,2) rate down: %x\n", pGentry->cn2rateDown)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,2) delta mcs: %x\n", pGentry->cn2deltaMcs)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,2) tx fail count: %x\n", pGentry->cn2TxFailCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,2) tx succes count: %x\n", pGentry->cn2TxSuccessCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,3) used: %x\n", pGentry->cn3used)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,3) rate down: %x\n", pGentry->cn3rateDown)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,3) delta mcs: %x\n", pGentry->cn3deltaMcs)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,3) tx fail count: %x\n", pGentry->cn3TxFailCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,3) tx succes count: %x\n", pGentry->cn3TxSuccessCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,4) used: %x\n", pGentry->cn4used)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,4) rate down: %x\n", pGentry->cn4rateDown)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,4) delta mcs: %x\n", pGentry->cn4deltaMcs)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,4) tx fail count: %x\n", pGentry->cn4TxFailCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("c(n,4) tx succes count: %x\n", pGentry->cn4TxSuccessCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowSuNssCheckCallback(char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_SHOW_NSS_CHECK ptr = (P_EVENT_SHOW_NSS_CHECK)rsp_payload; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("SU NSS Check value: %x\n", ptr->fgIsEnable)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowGroupNssThresholdCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_GROUP_NSS_THRESHOLD pGentry = + (P_EVENT_MU_GET_GROUP_NSS_THRESHOLD)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Group Nss Threshold minimum value: %x\n", pGentry->min)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Group Nss Threshold maximum value: %x\n", pGentry->max)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowClusterTblEntryCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_CLUSTER_TBL_ENTRY pGentry = + (P_EVENT_MU_GET_CLUSTER_TBL_ENTRY)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Cluster index %d\n", pGentry->index)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GID User Membership Status [0] = %x\n", + pGentry->gidUserMemberStatus[0])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GID User Membership Status [1] = %x\n", + pGentry->gidUserMemberStatus[1])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GID User Position [0] = %x\n", pGentry->gidUserPosition[0])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GID User Position [1] = %x\n", pGentry->gidUserPosition[1])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GID User Position [2] = %x\n", pGentry->gidUserPosition[2])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("GID User Position [3] = %x\n", pGentry->gidUserPosition[3])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowTxopDefaultCallback(char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_GET_TXOP_DEFAULT pGentry = (P_EVENT_GET_TXOP_DEFAULT)rsp_payload; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("TXOP default value: %x\n", pGentry->value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowSuLossThresholdCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_SU_LOSS_THRESHOLD pGentry = + (P_EVENT_MU_GET_SU_LOSS_THRESHOLD)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("su loss threshold value: %x\n", pGentry->value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowMuGainThresholdCallback(char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_MU_GET_MU_GAIN_THRESHOLD pGentry = + (P_EVENT_MU_GET_MU_GAIN_THRESHOLD)rsp_payload; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("mu gain threshold value: %x\n", pGentry->value)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowStatusOfCommand(char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_STATUS pGentry = (P_EVENT_STATUS)rsp_payload; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("status: %x\n", pGentry->status)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +static VOID ShowStatusOfHqaCommand(char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_HQA_STATUS pGentry = (P_EVENT_HQA_STATUS)rsp_payload; + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("status: %x\n", pGentry->status)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("END")); +} +bool +hqa_wifi_test_mu_cal_init_mcs( + PRTMP_ADAPTER pAd, + P_MU_STRUCT_SET_CALC_INIT_MCS pParams +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_HQA_SET_CALC_INIT_MCS; + CMD_HQA_SET_INIT_MCS param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + param.num_of_user = pParams->num_of_user; + param.bandwidth = pParams->bandwidth; + param.nss_of_user0 = pParams->nss_of_user0; + param.nss_of_user1 = pParams->nss_of_user1; + param.nss_of_user2 = pParams->nss_of_user2; + param.nss_of_user3 = pParams->nss_of_user3; + param.pf_mu_id_of_user0 = pParams->pf_mu_id_of_user0; + param.pf_mu_id_of_user1 = pParams->pf_mu_id_of_user1; + param.pf_mu_id_of_user2 = pParams->pf_mu_id_of_user2; + param.pf_mu_id_of_user3 = pParams->pf_mu_id_of_user3; + param.spe_index = pParams->spe_index; + param.num_of_txer = pParams->num_of_txer; + param.group_index = cpu2le32(pParams->group_index); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("spe_index %d\n", param.spe_index)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Group Index Values %d\n", pParams->group_index)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Txer Values %d\n", pParams->num_of_txer)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +static VOID hqa_wifi_test_mu_get_init_mcs_callback(struct cmd_msg *msg, + char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_HQA_INIT_MCS pEntry = (P_EVENT_HQA_INIT_MCS)rsp_payload; + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! event fill null!!\n", __func__)); + return; + } + + if (msg->attr.rsp.wb_buf_in_calbk == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! buffer not specific by cmd\n", __func__)); + } else { + P_MU_STRUCT_MU_GROUP_INIT_MCS pOutput = + (P_MU_STRUCT_MU_GROUP_INIT_MCS)msg->attr.rsp.wb_buf_in_calbk; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: EVENT_HQA_INIT_MCS\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("eventId %u\n", pEntry->u4EventId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user0InitMCS %u\n", cpu2le32(pEntry->rEntry.user0InitMCS))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user1InitMCS %u\n", cpu2le32(pEntry->rEntry.user1InitMCS))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user2InitMCS %u\n", cpu2le32(pEntry->rEntry.user2InitMCS))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user3InitMCS %u\n", cpu2le32(pEntry->rEntry.user3InitMCS))); + pOutput->user0InitMCS = cpu2le32(pEntry->rEntry.user0InitMCS); + pOutput->user1InitMCS = cpu2le32(pEntry->rEntry.user1InitMCS); + pOutput->user2InitMCS = cpu2le32(pEntry->rEntry.user2InitMCS); + pOutput->user3InitMCS = cpu2le32(pEntry->rEntry.user3InitMCS); + } +} +bool +hqa_wifi_test_mu_get_init_mcs( + PRTMP_ADAPTER pAd, + UINT32 groupIndex, + P_MU_STRUCT_MU_GROUP_INIT_MCS poutput +) +{ + INT32 Ret = 0; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_HQA_CALC_GET_INIT_MCS_ENTRY param = {0}; + UINT32 cmd = MU_HQA_GET_CALC_INIT_MCS; + struct _CMD_ATTRIBUTE attr = {0}; + + if (poutput == NULL) { + Ret = FALSE; + goto error; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("Group Index Values %d\n", groupIndex)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("poutput = %p\n", poutput)); + param.groupIndex = cpu2le32(groupIndex); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: param.groupIndex %u\n", __func__, param.groupIndex)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(EVENT_HQA_INIT_MCS)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, poutput); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +bool +hqa_wifi_test_mu_cal_lq( + PRTMP_ADAPTER pAd, + P_MU_STRUCT_SET_CALC_LQ pParams +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_HQA_SET_CALC_LQ; + CMD_HQA_SET_MU_CALC_LQ param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + param.num_of_user = pParams->num_of_user; + param.bandwidth = pParams->bandwidth; + param.nss_of_user0 = pParams->nss_of_user0; + param.nss_of_user1 = pParams->nss_of_user1; + param.nss_of_user2 = pParams->nss_of_user2; + param.nss_of_user3 = pParams->nss_of_user3; + param.pf_mu_id_of_user0 = pParams->pf_mu_id_of_user0; + param.pf_mu_id_of_user1 = pParams->pf_mu_id_of_user1; + param.pf_mu_id_of_user2 = pParams->pf_mu_id_of_user2; + param.pf_mu_id_of_user3 = pParams->pf_mu_id_of_user3; + param.spe_index = pParams->spe_index; + param.num_of_txer = pParams->num_of_txer; + param.group_index = cpu2le32(pParams->group_index); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: CMD_HQA_SET_MU_CALC_LQ\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("num_of_user = %u\n", param.num_of_user)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("bandwidth = %u\n", param.bandwidth)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("nss_of_user0 = %u\n", param.nss_of_user0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("nss_of_user1 = %u\n", param.nss_of_user1)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("nss_of_user2 = %u\n", param.nss_of_user2)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("nss_of_user3 = %u\n", param.nss_of_user3)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pf_mu_id_of_user0 = %u\n", param.pf_mu_id_of_user0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pf_mu_id_of_user1 = %u\n", param.pf_mu_id_of_user1)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pf_mu_id_of_user2 = %u\n", param.pf_mu_id_of_user2)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pf_mu_id_of_user3 = %u\n", param.pf_mu_id_of_user3)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("num_of_txer = %u\n", param.num_of_txer)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("group_index = %u\n", param.group_index)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +bool +hqa_wifi_test_su_cal_lq( + PRTMP_ADAPTER pAd, + P_MU_STRUCT_SET_SU_CALC_LQ pParams +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_HQA_SET_CALC_SU_LQ; + CMD_HQA_SET_SU_CALC_LQ param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + param.num_of_user = pParams->num_of_user; + param.bandwidth = pParams->bandwidth; + param.nss_of_user0 = pParams->nss_of_user0; + param.pf_mu_id_of_user0 = pParams->pf_mu_id_of_user0; + param.num_of_txer = pParams->num_of_txer; + param.group_index = cpu2le32(pParams->group_index); + param.spe_index = pParams->spe_index; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: CMD_HQA_SET_SU_CALC_LQ\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("num_of_user = %u\n", param.num_of_user)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("bandwidth = %u\n", param.bandwidth)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("nss_of_user0 = %u\n", param.nss_of_user0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("pf_mu_id_of_user0 = %u\n", param.pf_mu_id_of_user0)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("num_of_txer = %u\n", param.num_of_txer)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("group_index = %u\n", param.group_index)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +static VOID hqa_wifi_test_mu_get_su_lq_callback(struct cmd_msg *msg, + char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_HQA_GET_SU_CALC_LQ pEntry = (P_EVENT_HQA_GET_SU_CALC_LQ)rsp_payload; + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! event fill null!!\n", __func__)); + return; + } + + if (msg->attr.rsp.wb_buf_in_calbk == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! buffer not specific by cmd\n", __func__)); + } else { + P_SU_STRUCT_LQ_REPORT pOutput = + (P_SU_STRUCT_LQ_REPORT)msg->attr.rsp.wb_buf_in_calbk; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:EVENT_HQA_GET_SU_CALC_LQ\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("eventId %u\n", pEntry->u4EventId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0] = 0x%x\n", cpu2le32(pEntry->rEntry.lq_report[0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1] = 0x%x\n", cpu2le32(pEntry->rEntry.lq_report[1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2] = 0x%x\n", cpu2le32(pEntry->rEntry.lq_report[2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3] = 0x%x\n", cpu2le32(pEntry->rEntry.lq_report[3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[4] = 0x%x\n", cpu2le32(pEntry->rEntry.lq_report[4]))); + pOutput->lq_report[0] = cpu2le32(pEntry->rEntry.lq_report[0]); + pOutput->lq_report[1] = cpu2le32(pEntry->rEntry.lq_report[1]); + pOutput->lq_report[2] = cpu2le32(pEntry->rEntry.lq_report[2]); + pOutput->lq_report[3] = cpu2le32(pEntry->rEntry.lq_report[3]); + pOutput->lq_report[4] = cpu2le32(pEntry->rEntry.lq_report[4]); + } +} +bool +hqa_wifi_test_su_get_lq( + PRTMP_ADAPTER pAd, + P_SU_STRUCT_LQ_REPORT pOutput +) +{ + INT32 Ret = 0; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_HQA_GET_CALC_SU_LQ; + struct _CMD_ATTRIBUTE attr = {0}; + + if (pOutput == NULL) { + Ret = -1; + goto error; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:intput pOutput = %p\n", __func__, pOutput)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(EVENT_HQA_GET_SU_CALC_LQ)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, pOutput); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *) &cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +static VOID hqa_wifi_test_mu_get_lq_callback(struct cmd_msg *msg, + char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_HQA_GET_MU_CALC_LQ pEntry = (P_EVENT_HQA_GET_MU_CALC_LQ)rsp_payload; + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! event fill null!!\n", __func__)); + return; + } + + if (msg->attr.rsp.wb_buf_in_calbk == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! buffer not specific by cmd\n", __func__)); + } else { + P_MU_STRUCT_LQ_REPORT pOutput = + (P_MU_STRUCT_LQ_REPORT)msg->attr.rsp.wb_buf_in_calbk; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:EVENT_HQA_GET_MU_CALC_LQ\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("eventId %u\n", pEntry->u4EventId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][0] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[0][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][1] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[0][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][2] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[0][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][3] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[0][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][4] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[0][4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][0] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[1][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][1] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[1][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][2] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[1][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][3] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[1][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][4] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[1][4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][0] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[2][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][1] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[2][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][2] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[2][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][3] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[2][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][4] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[2][4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][0] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[3][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][1] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[3][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][2] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[3][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][3] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[3][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][4] = 0x%x\n", + cpu2le32(pEntry->rEntry.lq_report[3][4]))); + pOutput->lq_report[0][0] = cpu2le32(pEntry->rEntry.lq_report[0][0]); + pOutput->lq_report[0][1] = cpu2le32(pEntry->rEntry.lq_report[0][1]); + pOutput->lq_report[0][2] = cpu2le32(pEntry->rEntry.lq_report[0][2]); + pOutput->lq_report[0][3] = cpu2le32(pEntry->rEntry.lq_report[0][3]); + pOutput->lq_report[0][4] = cpu2le32(pEntry->rEntry.lq_report[0][4]); + pOutput->lq_report[1][0] = cpu2le32(pEntry->rEntry.lq_report[1][0]); + pOutput->lq_report[1][1] = cpu2le32(pEntry->rEntry.lq_report[1][1]); + pOutput->lq_report[1][2] = cpu2le32(pEntry->rEntry.lq_report[1][2]); + pOutput->lq_report[1][3] = cpu2le32(pEntry->rEntry.lq_report[1][3]); + pOutput->lq_report[1][4] = cpu2le32(pEntry->rEntry.lq_report[1][4]); + pOutput->lq_report[2][0] = cpu2le32(pEntry->rEntry.lq_report[2][0]); + pOutput->lq_report[2][1] = cpu2le32(pEntry->rEntry.lq_report[2][1]); + pOutput->lq_report[2][2] = cpu2le32(pEntry->rEntry.lq_report[2][2]); + pOutput->lq_report[2][3] = cpu2le32(pEntry->rEntry.lq_report[2][3]); + pOutput->lq_report[2][4] = cpu2le32(pEntry->rEntry.lq_report[2][4]); + pOutput->lq_report[3][0] = cpu2le32(pEntry->rEntry.lq_report[3][0]); + pOutput->lq_report[3][1] = cpu2le32(pEntry->rEntry.lq_report[3][1]); + pOutput->lq_report[3][2] = cpu2le32(pEntry->rEntry.lq_report[3][2]); + pOutput->lq_report[3][3] = cpu2le32(pEntry->rEntry.lq_report[3][3]); + pOutput->lq_report[3][4] = cpu2le32(pEntry->rEntry.lq_report[3][4]); + } +} +bool +hqa_wifi_test_mu_get_lq( + PRTMP_ADAPTER pAd, + P_MU_STRUCT_LQ_REPORT pOutput +) +{ + INT32 Ret = 0; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_HQA_GET_CALC_LQ; + struct _CMD_ATTRIBUTE attr = {0}; + + if (pOutput == NULL) { + Ret = -1; + goto error; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:intput pOutput = %p\n", __func__, pOutput)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(EVENT_HQA_GET_MU_CALC_LQ)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, pOutput); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +bool +hqa_wifi_test_snr_offset_set( + PRTMP_ADAPTER pAd, + char val +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_HQA_SET_SNR_OFFSET; + CMD_HQA_SET_MU_SNR_OFFSET param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + param.offset = val; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s, offset:0x%x\n", __func__, val)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} +bool +hqa_wifi_test_mu_set_zero_nss( + PRTMP_ADAPTER pAd, + unsigned char val +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + CMD_HQA_SET_MU_NSS_ZERO param = {0}; + UINT32 cmd = MU_HQA_SET_ZERO_NSS; + struct _CMD_ATTRIBUTE attr = {0}; + + param.ucValue = val; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s, val:%u\n", __func__, val)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +bool +hqa_wifi_test_mu_speed_up_lq( + PRTMP_ADAPTER pAd, + int val +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + CMD_HQA_SET_MU_LQ_SPEED_UP param = {0}; + UINT32 cmd = MU_HQA_SET_SPEED_UP_LQ; + struct _CMD_ATTRIBUTE attr = {0}; + + param.ucValue = val; + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s, val:%d\n", __func__, val)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +bool +hqa_wifi_test_mu_table_set( + PRTMP_ADAPTER pAd, + P_MU_STRUCT_MU_TABLE ptr +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + UINT32 cmd = 0; + P_CMD_HQA_SET_MU_METRIC_TABLE pMuParam = NULL; + P_CMD_HQA_SET_SU_METRIC_TABLE pSuParam = NULL; + UINT32 i = 0; + struct _CMD_ATTRIBUTE attr = {0}; + + if (ptr == NULL) { + Ret = -1; + goto error; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: type = %u, length = %u\n", + __func__, ptr->type, ptr->length)); + + cmd = (ptr->type == SU) ? MU_HQA_SET_SU_TABLE : MU_HQA_SET_MU_TABLE; + + if (ptr->type == SU) { + os_alloc_mem(pAd, (UCHAR **)&pSuParam, sizeof(*pSuParam)); + NdisZeroMemory(pSuParam, sizeof(*pSuParam)); + } else if (ptr->type == MU) { + os_alloc_mem(pAd, (UCHAR **)&pMuParam, sizeof(*pMuParam)); + NdisZeroMemory(pMuParam, sizeof(*pMuParam)); + } else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("error type!\n")); + Ret = -1; + goto error; + } + + if (ptr->type == SU) { + if (ptr->length <= sizeof(pSuParam->metric_table)) + NdisCopyMemory(pSuParam->metric_table, ptr->prTable, ptr->length); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("length(%u) error!!should < su_metric_tbl(%zu)\n", + ptr->length, sizeof(pSuParam->metric_table))); + Ret = -1; + goto error; + } + } else { + if (ptr->length <= sizeof(pMuParam->metric_table)) + NdisCopyMemory(pMuParam->metric_table, ptr->prTable, ptr->length); + else { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("length(%u) error!!should < mu_metric_tbl(%zu)\n", + ptr->length, sizeof(pSuParam->metric_table))); + Ret = -1; + goto error; + } + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s\n", ptr->type == SU ? "su_metric_table:":"mu_metric_table:")); + + if (ptr->type == MU) { + for (i = 0; i < ptr->length; i += 8) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pMuParam->metric_table[i + 0], + pMuParam->metric_table[i + 1], + pMuParam->metric_table[i + 2], + pMuParam->metric_table[i + 3], + pMuParam->metric_table[i + 4], + pMuParam->metric_table[i + 5], + pMuParam->metric_table[i + 6], + pMuParam->metric_table[i + 7])); + } + } else { + for (i = 0; i < ptr->length; i += 3) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("0x%x 0x%x 0x%x\n", + pSuParam->metric_table[i + 0], + pSuParam->metric_table[i + 1], + pSuParam->metric_table[i + 2])); + } + } + + msg = AndesAllocCmdMsg(pAd, (sizeof(cmd) + ((ptr->type == SU) ? + (sizeof(*pSuParam)) : (sizeof(*pMuParam))))); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (ptr->type == SU) ? (char *)pSuParam : (char *)pMuParam, + (ptr->type == SU) ? (sizeof(*pSuParam)) : (sizeof(*pMuParam))); + AndesSendCmdMsg(pAd, msg); +error: + + if (ptr && (ptr->type == SU)) { + if (pSuParam) + os_free_mem(pSuParam); + } else { + if (pMuParam) + os_free_mem(pMuParam); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +static void dump_set_mu_group_parms(P_MU_STRUCT_MU_GROUP mu_group) +{ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_STRUCT_MU_GROUP Content\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("groupIndex = %u\n", mu_group->groupIndex)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("numOfUser = %u\n", mu_group->numOfUser)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("fgUser0Ldpc = %u\n", mu_group->user0Ldpc)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("fgUser1Ldpc = %u\n", mu_group->user1Ldpc)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("fgUser20Ldpc = %u\n", mu_group->user2Ldpc)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("fgUser3Ldpc = %u\n", mu_group->user3Ldpc)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("shortGI = %u\n", mu_group->shortGI)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("bw = %u\n", mu_group->bw)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user0Nss = %u\n", mu_group->user0Nss)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user1Nss = %u\n", mu_group->user1Nss)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user2Nss = %u\n", mu_group->user2Nss)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user3Nss = %u\n", mu_group->user3Nss)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("groupId = %u\n", mu_group->groupId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user0UP = %u\n", mu_group->user0UP)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user1UP = %u\n", mu_group->user1UP)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user2UP = %u\n", mu_group->user2UP)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user3UP = %u\n", mu_group->user3UP)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user0MuPfId = %u\n", mu_group->user0MuPfId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user1MuPfId = %u\n", mu_group->user1MuPfId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user2MuPfId = %u\n", mu_group->user2MuPfId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user3MuPfId = %u\n", mu_group->user3MuPfId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user0InitMCS = %u\n", mu_group->user0InitMCS)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user1InitMCS = %u\n", mu_group->user1InitMCS)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user2InitMCS = %u\n", mu_group->user2InitMCS)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("user3InitMCS = %u\n", mu_group->user3InitMCS)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("aucUser0MacAddr:%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(mu_group->aucUser0MacAddr))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("aucUser1MacAddr:%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(mu_group->aucUser1MacAddr))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("aucUser2MacAddr:%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(mu_group->aucUser2MacAddr))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("aucUser3MacAddr:%02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(mu_group->aucUser3MacAddr))); +} +bool +hqa_wifi_test_mu_group_set( + PRTMP_ADAPTER pAd, + P_MU_STRUCT_MU_GROUP mu_group +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + UINT32 cmd = MU_HQA_SET_GROUP; + CMD_HQA_SET_MU_GROUP param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + param.groupIndex = cpu2le32(mu_group->groupIndex); + param.numOfUser = mu_group->numOfUser; + param.fgUser0Ldpc = mu_group->user0Ldpc; + param.fgUser1Ldpc = mu_group->user1Ldpc; + param.fgUser2Ldpc = mu_group->user2Ldpc; + param.fgUser3Ldpc = mu_group->user3Ldpc; + param.bandwidth = mu_group->bw; + param.fgIsShortGI = mu_group->shortGI; + param.user0Nss = mu_group->user0Nss; + param.user1Nss = mu_group->user1Nss; + param.user2Nss = mu_group->user2Nss; + param.user3Nss = mu_group->user3Nss; + param.groupId = mu_group->groupId; + param.user0InitMCS = mu_group->user0InitMCS; + param.user1InitMCS = mu_group->user1InitMCS; + param.user2InitMCS = mu_group->user2InitMCS; + param.user3InitMCS = mu_group->user3InitMCS; + param.user0MuPfId = mu_group->user0MuPfId; + param.user1MuPfId = mu_group->user1MuPfId; + param.user2MuPfId = mu_group->user2MuPfId; + param.user3MuPfId = mu_group->user3MuPfId; + /* config_mu_vht_ldpc_cap_in_wtbl(pAd, mu_group); */ + dump_set_mu_group_parms(mu_group); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +static VOID hqa_wifi_test_mu_get_qd_callback(struct cmd_msg *msg, + char *rsp_payload, UINT16 rsp_payload_len) +{ + P_EVENT_HQA_MU_QD pEntry = (P_EVENT_HQA_MU_QD)rsp_payload; + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! event fill null!!\n", __func__)); + return; + } + + if (msg->attr.rsp.wb_buf_in_calbk == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! buffer not specific by cmd\n", __func__)); + } else { + P_MU_STRUCT_MU_QD pOutput = + (P_MU_STRUCT_MU_QD)msg->attr.rsp.wb_buf_in_calbk; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:EVENT_HQA_MU_QD\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("eventId %u\n", pEntry->u4EventId)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[0] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[1] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[2] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[3] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[4] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[5] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[5]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[6] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[6]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[7] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[7]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[8] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[8]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[9] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[9]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[10] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[10]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[11] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[11]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[12] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[12]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[13] = 0x%x\n", cpu2le32(pEntry->rEntry.qd_report[13]))); + pOutput->qd_report[0] = cpu2le32(pEntry->rEntry.qd_report[0]); + pOutput->qd_report[1] = cpu2le32(pEntry->rEntry.qd_report[1]); + pOutput->qd_report[2] = cpu2le32(pEntry->rEntry.qd_report[2]); + pOutput->qd_report[3] = cpu2le32(pEntry->rEntry.qd_report[3]); + pOutput->qd_report[4] = cpu2le32(pEntry->rEntry.qd_report[4]); + pOutput->qd_report[5] = cpu2le32(pEntry->rEntry.qd_report[5]); + pOutput->qd_report[6] = cpu2le32(pEntry->rEntry.qd_report[6]); + pOutput->qd_report[7] = cpu2le32(pEntry->rEntry.qd_report[7]); + pOutput->qd_report[8] = cpu2le32(pEntry->rEntry.qd_report[8]); + pOutput->qd_report[9] = cpu2le32(pEntry->rEntry.qd_report[9]); + pOutput->qd_report[10] = cpu2le32(pEntry->rEntry.qd_report[10]); + pOutput->qd_report[11] = cpu2le32(pEntry->rEntry.qd_report[11]); + pOutput->qd_report[12] = cpu2le32(pEntry->rEntry.qd_report[12]); + pOutput->qd_report[13] = cpu2le32(pEntry->rEntry.qd_report[13]); + } +} +bool +hqa_wifi_test_mu_get_qd( + PRTMP_ADAPTER pAd, + INT8 subcarrierIndex, + P_MU_STRUCT_MU_QD pOutput +) +{ + INT32 Ret = 0; + /* prepare command message */ + struct cmd_msg *msg = NULL; + CMD_HQA_GET_QD param = {0}; + UINT32 cmd = MU_HQA_GET_QD; + struct _CMD_ATTRIBUTE attr = {0}; + + if (!pOutput) + return -1; + + param.scIdx = subcarrierIndex; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(param.scIdx = %d_\n", __func__, param.scIdx)); + /* Allocate memory for msg */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(EVENT_HQA_MU_QD)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, pOutput); + SET_CMD_ATTR_RSP_HANDLER(attr, eventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +bool +hqa_wifi_test_mu_set_enable( + PRTMP_ADAPTER pAd, + unsigned char val +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + CMD_HQA_SET_MU_ENABLE param = {0}; + UINT32 cmd = MU_HQA_SET_ENABLE; + struct _CMD_ATTRIBUTE attr = {0}; + + param.fgIsEnable = val; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(param.fgIsEnable = %d_\n", + __func__, param.fgIsEnable)); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +/* New API for Mu TX */ +bool +hqa_wifi_test_mu_trigger_mu_tx( + PRTMP_ADAPTER pAd, + P_MU_STRUCT_TRIGGER_MU_TX_FRAME_PARAM pParam +) +{ + INT Ret = 0; + struct cmd_msg *msg = NULL; + CMD_SET_TRIGGER_MU_TX_FRAME param = {0}; + UINT32 cmd = MU_SET_TRIGGER_MU_TX; + struct _CMD_ATTRIBUTE attr = {0}; + + param.ucAcIndex = 1; + param.fgIsRandomPattern = pParam->fgIsRandomPattern; + param.u4NumOfSTAs = cpu2le32(pParam->u4NumOfSTAs + 1); + param.u4Round = cpu2le32(pParam->u4MuPacketCount); + param.au4PayloadLength[0] = cpu2le32(pParam->msduPayloadLength0); + param.au4PayloadLength[1] = cpu2le32(pParam->msduPayloadLength1); + param.au4PayloadLength[2] = cpu2le32(pParam->msduPayloadLength2); + param.au4PayloadLength[3] = cpu2le32(pParam->msduPayloadLength3); + param.aucWlanIndexArray[0] = 1; + param.aucWlanIndexArray[1] = 2; + param.aucWlanIndexArray[2] = 3; + param.aucWlanIndexArray[3] = 4; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:MD_SET_TRIGGER_MU_TX_FRAME\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("ucAcIndex = %u\n", param.ucAcIndex)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("fgIsRandomPattern = %u\n", param.fgIsRandomPattern)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("u4NumOfSTAs = %u\n", param.u4NumOfSTAs)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("u4Round = %u\n", param.u4Round)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("au4PayloadLength[0] = %u\n", param.au4PayloadLength[0])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("au4PayloadLength[1] = %u\n", param.au4PayloadLength[1])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("au4PayloadLength[2] = %u\n", param.au4PayloadLength[2])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("au4PayloadLength[3] = %u\n", param.au4PayloadLength[3])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("aucWlanIndexArray[0] = %u\n", param.aucWlanIndexArray[0])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("aucWlanIndexArray[1] = %u\n", param.aucWlanIndexArray[1])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("aucWlanIndexArray[2] = %u\n", param.aucWlanIndexArray[2])); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("aucWlanIndexArray[3] = %u\n", param.aucWlanIndexArray[3])); + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = -1; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} +static VOID eventDispatcher(struct cmd_msg *msg, char *rsp_payload, + UINT16 rsp_payload_len) +{ + UINT32 u4EventId = (*(UINT32 *)rsp_payload); + char *pData = (rsp_payload); + UINT16 len = (rsp_payload_len); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: u4EventId = %u, len = %u\n", __func__, u4EventId, len)); +#ifdef RT_BIG_ENDIAN + u4EventId = cpu2le32(u4EventId); +#endif + + switch (u4EventId) { + case MU_EVENT_MU_ENABLE: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_MU_ENABLE\n", __func__)); + ShowMuEnableCallback(pData, len); + break; + + case MU_EVENT_MUPROFILE_ENTRY: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_MUPROFILE_ENTRY\n", __func__)); + ShowMuProfileEntryCallback(pData, len); + break; + + case MU_EVENT_GROUP_TBL_ENTRY: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_GROUP_TBL_ENTRY\n", __func__)); + ShowGroupTblEntryCallback(pData, len); + break; + + case MU_EVENT_CALC_INIT_MCS: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_CALC_INIT_MCS\n", __func__)); + ShowGroupTblEntryCallback(pData, len); + break; + + case MU_EVENT_GROUP_NSS_THRESHOLD: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_GROUP_NSS_THRESHOLD\n", __func__)); + ShowGroupNssThresholdCallback(pData, len); + break; + + case MU_EVENT_TXREQ_MIN_TIME: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_TXREQ_MIN_TIME\n", __func__)); + ShowTxReqMinTimeCallback(pData, len); + break; + + case MU_EVENT_GROUP_USER_THRESHOLD: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_GROUP_USER_THRESHOLD\n", __func__)); + ShowGroupUserThresholdCallback(pData, len); + break; + + case MU_EVENT_CLUSTER_TBL_ENTRY: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_CLUSTER_TBL_ENTRY\n", __func__)); + ShowClusterTblEntryCallback(pData, len); + break; + + case MU_EVENT_SU_NSS_CHECK: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_SU_NSS_CHECK\n", __func__)); + ShowSuNssCheckCallback(pData, len); + break; + + case MU_EVENT_TXOP_DEFAULT: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_TXOP_DEFAULT\n", __func__)); + ShowTxopDefaultCallback(pData, len); + break; + + case MU_EVENT_SU_LOSS_THRESHOLD: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_SU_LOSS_THRESHOLD\n", __func__)); + ShowSuLossThresholdCallback(pData, len); + break; + + case MU_EVENT_MU_GAIN_THRESHOLD: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_MU_GAIN_THRESHOLD\n", __func__)); + ShowMuGainThresholdCallback(pData, len); + break; + + case MU_EVENT_SECONDARY_AC_POLICY: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_SECONDARY_AC_POLICY\n", __func__)); + ShowSecondaryAcPolicyCallback(pData, len); + break; + + case MU_EVENT_GROUP_TBL_DMCS_MASK: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_GROUP_TBL_DMCS_MASK\n", __func__)); + ShowGroupTblDmcsMaskCallback(pData, len); + break; + + case MU_EVENT_MAX_GROUP_SEARCH_CNT: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_MAX_GROUP_SEARCH_CNT\n", __func__)); + ShowMaxGroupSearchCntCallback(pData, len); + break; + + case MU_EVENT_MUPROFILE_TX_STS_CNT: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_MUPROFILE_TX_STS_CNT\n", __func__)); + ShowMuProfileTxStsCntCallback(pData, len); + break; + + case MU_EVENT_STATUS: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_STATUS\n", __func__)); + ShowStatusOfCommand(pData, len); + break; + + case MU_EVENT_HQA_STATUS: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_HQA_STATUS\n", __func__)); + ShowStatusOfHqaCommand(pData, len); + break; + + case MU_EVENT_HQA_GET_INIT_MCS: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_HQA_GET_INIT_MCS\n", __func__)); + hqa_wifi_test_mu_get_init_mcs_callback(msg, pData, len); + break; + + case MU_EVENT_HQA_GET_QD: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_HQA_GET_QD\n", __func__)); + hqa_wifi_test_mu_get_qd_callback(msg, pData, len); + break; + + case MU_EVENT_HQA_GET_LQ: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_HQA_GET_LQ\n", __func__)); + hqa_wifi_test_mu_get_lq_callback(msg, pData, len); + break; + + case MU_EVENT_HQA_GET_SU_LQ: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MU_EVENT_HQA_GET_SU_LQ\n", __func__)); + hqa_wifi_test_mu_get_su_lq_callback(msg, pData, len); + break; + + default: + break; + } +} +/* MU UT API test code */ +INT32 hqa_mu_get_init_mcs(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + UINT32 gid = 0; + MU_STRUCT_MU_GROUP_INIT_MCS init_mcs; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: arg = %s\n", __func__, arg)); + gid = os_str_toul(arg, 0, 10); + os_zero_mem(&init_mcs, sizeof(init_mcs)); + Ret = hqa_wifi_test_mu_get_init_mcs(pAd, gid, &init_mcs); + + if (Ret == 0) { + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s, gid:%u\n", __func__, gid)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s, init_mcs.user1InitMCS:%u\n", + __func__, init_mcs.user0InitMCS)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s, init_mcs.user1InitMCS:%u\n", + __func__, init_mcs.user1InitMCS)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s, init_mcs.user1InitMCS:%u\n", + __func__, init_mcs.user2InitMCS)); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s, init_mcs.user1InitMCS:%u\n", + __func__, init_mcs.user3InitMCS)); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_cal_init_mcs(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + MU_STRUCT_SET_CALC_INIT_MCS param = {0}; + UINT32 num_of_user = 0; + UINT32 bandwidth = 0; + UINT32 nss_of_user0 = 0; + UINT32 nss_of_user1 = 0; + UINT32 nss_of_user2 = 0; + UINT32 nss_of_user3 = 0; + UINT32 pf_mu_id_of_user0 = 0; + UINT32 pf_mu_id_of_user1 = 0; + UINT32 pf_mu_id_of_user2 = 0; + UINT32 pf_mu_id_of_user3 = 0; + UINT32 num_of_txer = 0; + UINT32 group_index = 0; + PCHAR pnum_of_user = NULL; + PCHAR pbandwidth = NULL; + PCHAR pnss_of_user0 = NULL; + PCHAR pnss_of_user1 = NULL; + PCHAR pnss_of_user2 = NULL; + PCHAR pnss_of_user3 = NULL; + PCHAR ppf_mu_id_of_user0 = NULL; + PCHAR ppf_mu_id_of_user1 = NULL; + PCHAR ppf_mu_id_of_user2 = NULL; + PCHAR ppf_mu_id_of_user3 = NULL; + PCHAR pnum_of_txer = NULL; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: arg = %s\n", __func__, arg)); + pnum_of_user = strsep(&arg, ":"); + pbandwidth = strsep(&arg, ":"); + pnss_of_user0 = strsep(&arg, ":"); + pnss_of_user1 = strsep(&arg, ":"); + pnss_of_user2 = strsep(&arg, ":"); + pnss_of_user3 = strsep(&arg, ":"); + ppf_mu_id_of_user0 = strsep(&arg, ":"); + ppf_mu_id_of_user1 = strsep(&arg, ":"); + ppf_mu_id_of_user2 = strsep(&arg, ":"); + ppf_mu_id_of_user3 = strsep(&arg, ":"); + pnum_of_txer = strsep(&arg, ":"); + + if (pnum_of_user == NULL || + pbandwidth == NULL || + pnss_of_user0 == NULL || + pnss_of_user1 == NULL || + pnss_of_user2 == NULL || + pnss_of_user3 == NULL || + ppf_mu_id_of_user0 == NULL || + ppf_mu_id_of_user1 == NULL || + ppf_mu_id_of_user2 == NULL || + ppf_mu_id_of_user3 == NULL || + pnum_of_txer == NULL || + arg == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Invalid parameters\n", __func__)); + return -1; + } + + num_of_user = os_str_toul(pnum_of_user, 0, 10); + bandwidth = os_str_toul(pbandwidth, 0, 10); + nss_of_user0 = os_str_toul(pnss_of_user0, 0, 10); + nss_of_user1 = os_str_toul(pnss_of_user1, 0, 10); + nss_of_user2 = os_str_toul(pnss_of_user2, 0, 10); + nss_of_user3 = os_str_toul(pnss_of_user3, 0, 10); + pf_mu_id_of_user0 = os_str_toul(ppf_mu_id_of_user0, 0, 10); + pf_mu_id_of_user1 = os_str_toul(ppf_mu_id_of_user1, 0, 10); + pf_mu_id_of_user2 = os_str_toul(ppf_mu_id_of_user2, 0, 10); + pf_mu_id_of_user3 = os_str_toul(ppf_mu_id_of_user3, 0, 10); + num_of_txer = os_str_toul(pnum_of_txer, 0, 10); + group_index = os_str_toul(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: gid = %u, num_txer = %u\n", + __func__, group_index, num_of_txer)); + os_zero_mem(¶m, sizeof(param)); + param.num_of_user = num_of_user; + param.bandwidth = bandwidth; + param.nss_of_user0 = nss_of_user0; + param.nss_of_user1 = nss_of_user1; + param.nss_of_user2 = nss_of_user2; + param.nss_of_user3 = nss_of_user3; + param.pf_mu_id_of_user0 = pf_mu_id_of_user0; + param.pf_mu_id_of_user1 = pf_mu_id_of_user1; + param.pf_mu_id_of_user2 = pf_mu_id_of_user2; + param.pf_mu_id_of_user3 = pf_mu_id_of_user3; + param.num_of_txer = num_of_txer; + param.group_index = group_index; + Ret = hqa_wifi_test_mu_cal_init_mcs(pAd, ¶m); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_cal_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + UINT32 num_of_user = 0; + UINT32 bandwidth = 0; + UINT32 nss_of_user0 = 0; + UINT32 nss_of_user1 = 0; + UINT32 nss_of_user2 = 0; + UINT32 nss_of_user3 = 0; + UINT32 pf_mu_id_of_user0 = 0; + UINT32 pf_mu_id_of_user1 = 0; + UINT32 pf_mu_id_of_user2 = 0; + UINT32 pf_mu_id_of_user3 = 0; + UINT32 num_of_txer = 0; + UINT32 group_index = 0; + PCHAR pnum_of_user = NULL; + PCHAR pbandwidth = NULL; + PCHAR pnss_of_user0 = NULL; + PCHAR pnss_of_user1 = NULL; + PCHAR pnss_of_user2 = NULL; + PCHAR pnss_of_user3 = NULL; + PCHAR ppf_mu_id_of_user0 = NULL; + PCHAR ppf_mu_id_of_user1 = NULL; + PCHAR ppf_mu_id_of_user2 = NULL; + PCHAR ppf_mu_id_of_user3 = NULL; + PCHAR pnum_of_txer = NULL; + CMD_HQA_SET_MU_CALC_LQ param = {0}; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: arg = %s\n", __func__, arg)); + pnum_of_user = strsep(&arg, ":"); + pbandwidth = strsep(&arg, ":"); + pnss_of_user0 = strsep(&arg, ":"); + pnss_of_user1 = strsep(&arg, ":"); + pnss_of_user2 = strsep(&arg, ":"); + pnss_of_user3 = strsep(&arg, ":"); + ppf_mu_id_of_user0 = strsep(&arg, ":"); + ppf_mu_id_of_user1 = strsep(&arg, ":"); + ppf_mu_id_of_user2 = strsep(&arg, ":"); + ppf_mu_id_of_user3 = strsep(&arg, ":"); + pnum_of_txer = strsep(&arg, ":"); + + if (pnum_of_user == NULL || + pbandwidth == NULL || + pnss_of_user0 == NULL || + pnss_of_user1 == NULL || + pnss_of_user2 == NULL || + pnss_of_user3 == NULL || + ppf_mu_id_of_user0 == NULL || + ppf_mu_id_of_user1 == NULL || + ppf_mu_id_of_user2 == NULL || + ppf_mu_id_of_user3 == NULL || + pnum_of_txer == NULL || + arg == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Invalid parameters\n", __func__)); + return -1; + } + + num_of_user = os_str_toul(pnum_of_user, 0, 10); + bandwidth = os_str_toul(pbandwidth, 0, 10); + nss_of_user0 = os_str_toul(pnss_of_user0, 0, 10); + nss_of_user1 = os_str_toul(pnss_of_user1, 0, 10); + nss_of_user2 = os_str_toul(pnss_of_user2, 0, 10); + nss_of_user3 = os_str_toul(pnss_of_user3, 0, 10); + pf_mu_id_of_user0 = os_str_toul(ppf_mu_id_of_user0, 0, 10); + pf_mu_id_of_user1 = os_str_toul(ppf_mu_id_of_user1, 0, 10); + pf_mu_id_of_user2 = os_str_toul(ppf_mu_id_of_user2, 0, 10); + pf_mu_id_of_user3 = os_str_toul(ppf_mu_id_of_user3, 0, 10); + num_of_txer = os_str_toul(pnum_of_txer, 0, 10); + group_index = os_str_toul(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: gid = %u, num_txer = %u\n", + __func__, group_index, num_of_txer)); + os_zero_mem(¶m, sizeof(param)); + param.num_of_user = num_of_user; + param.bandwidth = bandwidth; + param.nss_of_user0 = nss_of_user0; + param.nss_of_user1 = nss_of_user1; + param.nss_of_user2 = nss_of_user2; + param.nss_of_user3 = nss_of_user3; + param.pf_mu_id_of_user0 = pf_mu_id_of_user0; + param.pf_mu_id_of_user1 = pf_mu_id_of_user1; + param.pf_mu_id_of_user2 = pf_mu_id_of_user2; + param.pf_mu_id_of_user3 = pf_mu_id_of_user3; + param.num_of_txer = num_of_txer; + param.group_index = group_index; + Ret = hqa_wifi_test_mu_cal_lq(pAd, (P_MU_STRUCT_SET_CALC_LQ)¶m); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_get_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + MU_STRUCT_LQ_REPORT lq; + + os_zero_mem(&lq, sizeof(lq)); + Ret = hqa_wifi_test_mu_get_lq(pAd, (P_MU_STRUCT_LQ_REPORT)&lq); + + if (Ret == 0) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:MU_STRUCT_LQ_REPORT\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][0] = 0x%x\n", cpu2le32(lq.lq_report[0][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][1] = 0x%x\n", cpu2le32(lq.lq_report[0][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][2] = 0x%x\n", cpu2le32(lq.lq_report[0][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][3] = 0x%x\n", cpu2le32(lq.lq_report[0][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0][4] = 0x%x\n", cpu2le32(lq.lq_report[0][4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][0] = 0x%x\n", cpu2le32(lq.lq_report[1][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][1] = 0x%x\n", cpu2le32(lq.lq_report[1][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][2] = 0x%x\n", cpu2le32(lq.lq_report[1][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][3] = 0x%x\n", cpu2le32(lq.lq_report[1][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1][4] = 0x%x\n", cpu2le32(lq.lq_report[1][4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][0] = 0x%x\n", cpu2le32(lq.lq_report[2][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][1] = 0x%x\n", cpu2le32(lq.lq_report[2][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][2] = 0x%x\n", cpu2le32(lq.lq_report[2][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][3] = 0x%x\n", cpu2le32(lq.lq_report[2][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2][4] = 0x%x\n", cpu2le32(lq.lq_report[2][4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][0] = 0x%x\n", cpu2le32(lq.lq_report[3][0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][1] = 0x%x\n", cpu2le32(lq.lq_report[3][1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][2] = 0x%x\n", cpu2le32(lq.lq_report[3][2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][3] = 0x%x\n", cpu2le32(lq.lq_report[3][3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3][4] = 0x%x\n", cpu2le32(lq.lq_report[3][4]))); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_su_cal_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + UINT32 num_of_user = 0; + UINT32 bandwidth = 0; + UINT32 nss_of_user0 = 0; + UINT32 pf_mu_id_of_user0 = 0; + UINT32 num_of_txer = 0; + UINT32 group_index = 0; + PCHAR pnum_of_user = NULL; + PCHAR pbandwidth = NULL; + PCHAR pnss_of_user0 = NULL; + PCHAR ppf_mu_id_of_user0 = NULL; + PCHAR pnum_of_txer = NULL; + CMD_HQA_SET_SU_CALC_LQ param = {0}; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: arg = %s\n", __func__, arg)); + pnum_of_user = strsep(&arg, ":"); + pbandwidth = strsep(&arg, ":"); + pnss_of_user0 = strsep(&arg, ":"); + ppf_mu_id_of_user0 = strsep(&arg, ":"); + pnum_of_txer = strsep(&arg, ":"); + + if (pnum_of_user == NULL || + pbandwidth == NULL || + pnss_of_user0 == NULL || + ppf_mu_id_of_user0 == NULL || + pnum_of_txer == NULL || + arg == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Invalid parameters\n", __func__)); + return -1; + } + + num_of_user = os_str_toul(pnum_of_user, 0, 10); + bandwidth = os_str_toul(pbandwidth, 0, 10); + nss_of_user0 = os_str_toul(pnss_of_user0, 0, 10); + pf_mu_id_of_user0 = os_str_toul(ppf_mu_id_of_user0, 0, 10); + num_of_txer = os_str_toul(pnum_of_txer, 0, 10); + group_index = os_str_toul(arg, 0, 10); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: gid = %u, num_txer = %u\n", + __func__, group_index, num_of_txer)); + os_zero_mem(¶m, sizeof(param)); + param.num_of_user = num_of_user; + param.bandwidth = bandwidth; + param.nss_of_user0 = nss_of_user0; + param.pf_mu_id_of_user0 = pf_mu_id_of_user0; + param.num_of_txer = num_of_txer; + param.group_index = group_index; + Ret = hqa_wifi_test_su_cal_lq(pAd, (P_MU_STRUCT_SET_SU_CALC_LQ)¶m); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_su_get_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + SU_STRUCT_LQ_REPORT lq; + + os_zero_mem(&lq, sizeof(lq)); + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:\n", __func__)); + Ret = hqa_wifi_test_su_get_lq(pAd, (P_SU_STRUCT_LQ_REPORT)&lq); + + if (Ret == 0) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:SU_STRUCT_LQ_REPORT\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[0] = 0x%x\n", cpu2le32(lq.lq_report[0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[1] = 0x%x\n", cpu2le32(lq.lq_report[1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[2] = 0x%x\n", cpu2le32(lq.lq_report[2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[3] = 0x%x\n", cpu2le32(lq.lq_report[3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("lq_report[4] = 0x%x\n", cpu2le32(lq.lq_report[4]))); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_set_snr_offset(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + INT32 offset = 0; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: arg = %s\n", __func__, arg)); + offset = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s, offset:0x%x\n", __func__, offset)); + Ret = hqa_wifi_test_snr_offset_set(pAd, offset); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_set_zero_nss(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + UINT32 zero_nss = 0; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: arg = %s\n", __func__, arg)); + zero_nss = os_str_toul(arg, 0, 10); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s, zero_nss:0x%x\n", __func__, zero_nss)); + Ret = hqa_wifi_test_mu_set_zero_nss(pAd, (UCHAR)zero_nss); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_set_speedup_lq(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + INT32 spdup_lq = 0; + + spdup_lq = os_str_tol(arg, 0, 10); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: spdup_lq:%x\n", __func__, spdup_lq)); + Ret = hqa_wifi_test_mu_speed_up_lq(pAd, spdup_lq); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +/* 1024:*/ +INT32 hqa_mu_set_mu_table(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + MU_STRUCT_MU_TABLE info; + UINT32 type = 0; + UCHAR *type_ptr = NULL; + UINT32 specific_metric_content = 0; + UINT32 length = 0; + UINT32 i = 0; + struct _CMD_HQA_SET_MU_METRIC_TABLE mu_metric_table; + struct _CMD_HQA_SET_SU_METRIC_TABLE su_metric_table; + + if (arg == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Invalid parameters\n", __func__)); + return -1; + } + + type_ptr = strsep(&arg, ":"); + if (type_ptr == NULL) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Invalid parameters\n", __func__)); + return -1; + } + + type = os_str_toul(type_ptr, 0, 10); + specific_metric_content = os_str_toul(arg, 0, 10); + specific_metric_content = cpu2le32(specific_metric_content); + + if (type == MU) { + length = sizeof(struct _CMD_HQA_SET_MU_METRIC_TABLE); + NdisFillMemory(&mu_metric_table, length, specific_metric_content); + } else if (type == SU) { + length = sizeof(struct _CMD_HQA_SET_SU_METRIC_TABLE); + NdisFillMemory(&su_metric_table, length, specific_metric_content); + } else { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: Type error(%u)!!! neither MU nor SU\n", + __func__, type)); + return -1; + } + + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s: type:%u, length:%u, data = %zu\n", + __func__, type, length, type == MU ? + sizeof(mu_metric_table) : sizeof(su_metric_table))); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s\n", type == MU ? "mu_metric_table:":"su_metric_table:")); + + if (type == MU) { + for (i = 0; i < length; i += 8) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + mu_metric_table.metric_table[i + 0], + mu_metric_table.metric_table[i + 1], + mu_metric_table.metric_table[i + 2], + mu_metric_table.metric_table[i + 3], + mu_metric_table.metric_table[i + 4], + mu_metric_table.metric_table[i + 5], + mu_metric_table.metric_table[i + 6], + mu_metric_table.metric_table[i + 7])); + } + } else { + for (i = 0; i < length; i += 3) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("0x%x 0x%x 0x%x\n", + su_metric_table.metric_table[i + 0], + su_metric_table.metric_table[i + 1], + su_metric_table.metric_table[i + 2])); + } + } + + info.type = type; + info.length = length; + info.prTable = (type == MU) ? (char *)&mu_metric_table : (char *)&su_metric_table; + Ret = hqa_wifi_test_mu_table_set(pAd, (P_MU_STRUCT_MU_TABLE)&info); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_set_group(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + MU_STRUCT_MU_GROUP mu_group; + UINT8 aucUser0MacAddr[6] = {0x00, 0x0c, 0x40, 0x12, 0x34, 0x56}; + UINT8 aucUser1MacAddr[6] = {0x00, 0x0c, 0x40, 0x12, 0x34, 0x57}; + UINT8 aucUser2MacAddr[6] = {0x00, 0x0c, 0x40, 0x12, 0x34, 0x58}; + UINT8 aucUser3MacAddr[6] = {0x00, 0x0c, 0x40, 0x12, 0x34, 0x59}; + mu_group.groupIndex = 0; + mu_group.numOfUser = 1; + mu_group.user0Ldpc = 1; + mu_group.user1Ldpc = 1; + mu_group.user2Ldpc = 1; + mu_group.user3Ldpc = 1; + mu_group.shortGI = 0; + mu_group.bw = 0; + mu_group.user0Nss = 0; + mu_group.user1Nss = 0; + mu_group.user2Nss = 0; + mu_group.user3Nss = 0; + mu_group.groupId = 10; + mu_group.user0UP = 0; + mu_group.user1UP = 0; + mu_group.user2UP = 0; + mu_group.user3UP = 0; + mu_group.user0MuPfId = 0; + mu_group.user1MuPfId = 1; + mu_group.user2MuPfId = 2; + mu_group.user3MuPfId = 3; + mu_group.user0InitMCS = 0; + mu_group.user1InitMCS = 0; + mu_group.user2InitMCS = 0; + mu_group.user3InitMCS = 0; + NdisMoveMemory(mu_group.aucUser0MacAddr, aucUser0MacAddr, MAC_ADDR_LEN); + NdisMoveMemory(mu_group.aucUser1MacAddr, aucUser1MacAddr, MAC_ADDR_LEN); + NdisMoveMemory(mu_group.aucUser2MacAddr, aucUser2MacAddr, MAC_ADDR_LEN); + NdisMoveMemory(mu_group.aucUser3MacAddr, aucUser3MacAddr, MAC_ADDR_LEN); + Ret = hqa_wifi_test_mu_group_set(pAd, (P_MU_STRUCT_MU_GROUP)&mu_group); + /* error: */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_get_qd(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + INT32 subcarrier_idx = 0; + MU_STRUCT_MU_QD qd; + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: arg = %s\n", __func__, arg)); + subcarrier_idx = os_str_toul(arg, 0, 10); + Ret = hqa_wifi_test_mu_get_qd(pAd, subcarrier_idx, (P_MU_STRUCT_MU_QD)&qd); + + if (Ret == 0) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:MU_STRUCT_MU_QD\n", __func__)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[0] = 0x%x\n", cpu2le32(qd.qd_report[0]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[1] = 0x%x\n", cpu2le32(qd.qd_report[1]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[2] = 0x%x\n", cpu2le32(qd.qd_report[2]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[3] = 0x%x\n", cpu2le32(qd.qd_report[3]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[4] = 0x%x\n", cpu2le32(qd.qd_report[4]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[5] = 0x%x\n", cpu2le32(qd.qd_report[5]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[6] = 0x%x\n", cpu2le32(qd.qd_report[6]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[7] = 0x%x\n", cpu2le32(qd.qd_report[7]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[8] = 0x%x\n", cpu2le32(qd.qd_report[8]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[9] = 0x%x\n", cpu2le32(qd.qd_report[9]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[10] = 0x%x\n", cpu2le32(qd.qd_report[10]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[11] = 0x%x\n", cpu2le32(qd.qd_report[11]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[12] = 0x%x\n", cpu2le32(qd.qd_report[12]))); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("qd_report[13] = 0x%x\n", cpu2le32(qd.qd_report[13]))); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == TRUE ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_set_enable(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + UINT32 is_enable = 0; + + is_enable = os_str_toul(arg, 0, 10); + MTWF_LOG(DBG_CAT_TEST, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s,MU is %s\n", __func__, + is_enable == 1 ? "Enable":"Disable")); + Ret = hqa_wifi_test_mu_set_enable(pAd, is_enable); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, + Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_set_gid_up(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + MU_STRUCT_MU_STA_PARAM param; + UINT32 gid_0 = 0; + UINT32 gid_1 = 0; + UINT32 up_0 = 0; + UINT32 up_1 = 0; + UINT32 up_2 = 0; + UINT32 up_3 = 0; + PCHAR temp_ptr_use_to_check = NULL; + PCHAR gid_0_ptr = NULL; + PCHAR gid_1_ptr = NULL; + PCHAR up_0_ptr = NULL; + PCHAR up_1_ptr = NULL; + PCHAR up_2_ptr = NULL; + PCHAR up_3_ptr = NULL; + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + gid_0_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + gid_1_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + up_0_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + up_1_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + up_2_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = arg; + + if (temp_ptr_use_to_check != NULL) + up_3_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + gid_0 = os_str_tol(gid_0_ptr, 0, 10); + gid_1 = os_str_tol(gid_1_ptr, 0, 10); + up_0 = os_str_tol(up_0_ptr, 0, 10); + up_1 = os_str_tol(up_1_ptr, 0, 10); + up_2 = os_str_tol(up_2_ptr, 0, 10); + up_3 = os_str_tol(up_3_ptr, 0, 10); + param.gid[0] = gid_0; + param.gid[1] = gid_1; + param.up[0] = up_0; + param.up[1] = up_1; + param.up[2] = up_2; + param.up[3] = up_3; + Ret = hqa_wifi_test_mu_set_sta_gid_and_up(pAd, ¶m); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +INT32 hqa_mu_set_trigger_mu_tx(PRTMP_ADAPTER pAd, RTMP_STRING *arg) +{ + INT32 Ret = 0; + MU_STRUCT_TRIGGER_MU_TX_FRAME_PARAM param = {0}; + UINT8 fgIsRandomPattern = 0; /* is random pattern or not */ + UINT32 msduPayloadLength0 = 0; /* payload length of the MSDU for user 0 */ + UINT32 msduPayloadLength1 = 0; /* payload length of the MSDU for user 1 */ + UINT32 msduPayloadLength2 = 0; /* payload length of the MSDU for user 2 */ + UINT32 msduPayloadLength3 = 0; /* payload length of the MSDU for user 3 */ + UINT32 u4MuPacketCount = 0; /* MU TX count */ + UINT32 u4NumOfSTAs = 0; /* number of user in the MU TX */ + PCHAR temp_ptr_use_to_check = NULL; + PCHAR fgIsRandomPattern_ptr = NULL; + PCHAR msduPayloadLength0_ptr = NULL; + PCHAR msduPayloadLength1_ptr = NULL; + PCHAR msduPayloadLength2_ptr = NULL; + PCHAR msduPayloadLength3_ptr = NULL; + PCHAR u4MuPacketCount_ptr = NULL; + PCHAR u4NumOfSTAs_ptr = NULL; + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + fgIsRandomPattern_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + msduPayloadLength0_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + msduPayloadLength1_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + msduPayloadLength2_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + msduPayloadLength3_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = strsep(&arg, ":"); + + if (temp_ptr_use_to_check != NULL) + u4MuPacketCount_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + temp_ptr_use_to_check = arg; + + if (temp_ptr_use_to_check != NULL) + u4NumOfSTAs_ptr = temp_ptr_use_to_check; + else { + Ret = -1; + goto error; + } + + fgIsRandomPattern = os_str_tol(fgIsRandomPattern_ptr, 0, 10); + msduPayloadLength0 = os_str_tol(msduPayloadLength0_ptr, 0, 10); + msduPayloadLength1 = os_str_tol(msduPayloadLength1_ptr, 0, 10); + msduPayloadLength2 = os_str_tol(msduPayloadLength2_ptr, 0, 10); + msduPayloadLength3 = os_str_tol(msduPayloadLength3_ptr, 0, 10); + u4MuPacketCount = os_str_tol(u4MuPacketCount_ptr, 0, 10); + u4NumOfSTAs = os_str_tol(u4NumOfSTAs_ptr, 0, 10); + param.fgIsRandomPattern = fgIsRandomPattern; + param.msduPayloadLength0 = msduPayloadLength0; + param.msduPayloadLength1 = msduPayloadLength1; + param.msduPayloadLength2 = msduPayloadLength2; + param.msduPayloadLength3 = msduPayloadLength3; + param.u4MuPacketCount = u4MuPacketCount; + param.u4NumOfSTAs = u4NumOfSTAs; + param.macAddrs[0][0] = 0x11; + param.macAddrs[0][1] = 0x22; + param.macAddrs[0][2] = 0x33; + param.macAddrs[0][3] = 0x44; + param.macAddrs[0][4] = 0x55; + param.macAddrs[0][5] = 0x66; + + if (u4NumOfSTAs >= 1) { + param.macAddrs[1][0] = 0x11; + param.macAddrs[1][1] = 0x22; + param.macAddrs[1][2] = 0x33; + param.macAddrs[1][3] = 0x44; + param.macAddrs[1][4] = 0x55; + param.macAddrs[1][5] = 0x66; + } + + if (u4NumOfSTAs >= 2) { + param.macAddrs[2][0] = 0x11; + param.macAddrs[2][1] = 0x22; + param.macAddrs[2][2] = 0x33; + param.macAddrs[2][3] = 0x44; + param.macAddrs[2][4] = 0x55; + param.macAddrs[2][5] = 0x66; + } + + if (u4NumOfSTAs >= 2) { + param.macAddrs[3][0] = 0x11; + param.macAddrs[3][1] = 0x22; + param.macAddrs[3][2] = 0x33; + param.macAddrs[3][3] = 0x44; + param.macAddrs[3][4] = 0x55; + param.macAddrs[3][5] = 0x66; + } + + Ret = hqa_wifi_test_mu_trigger_mu_tx(pAd, ¶m); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:CMD %s\n", __func__, Ret == 0 ? "Success":"Fail")); + return Ret; +} +#endif /* CFG_SUPPORT_MU_MIMO */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mura.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mura.c new file mode 100644 index 000000000..0ade8a6f3 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_mura.c @@ -0,0 +1,2047 @@ +/* + * $Id$ + * $DateTime$ + * Pluto Kang + */ +/* + This file contains IOCTL for MU-MIMO specfic commands + */ + +/******************************************************************************* + * Copyright (c) 2014 MediaTek Inc. + * + * All rights reserved. Copying, compilation, modification, distribution + * or any other use whatsoever of this material is strictly prohibited + * except in accordance with a Software License Agreement with + * MediaTek Inc. + * ****************************************************************************** + */ + +/****************************************************************************** + * LEGAL DISCLAIMER + * + * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND + * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK + * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE + * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY + * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE + * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY + * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK + * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY + * WARRANTY CLAIM RELATING THERetO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE + * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO + * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. + * + * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE + * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL + * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT + * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY + * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE + * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT + * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING + * THEREOF AND RELATED THERetO SHALL BE SETTLED BY ARBITRATION IN SAN + * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE + * (ICC). + * ****************************************************************************** + */ + +#include "rt_config.h" + +#ifdef CFG_SUPPORT_MU_MIMO_RA + +static VOID MuraEventDispatcher( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len); + +static VOID mura_algorithm_state_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len); + +static VOID mura_algorithm_group_state_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len); + +static VOID mura_algorithm_hwfb_state_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len); + +/** @brief Monitor the MU-RGA PFID statistics callback. + * + * Show PFID statistics. + * + * @param msg: pointer to message + * @param rsp_payload: payload array + * @param rsp_payload_len: payload length + * @return Void. + */ +static VOID mura_algorithm_pfid_stat_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len +); + +/* + ========================================================================== + Description: + Set Mura Sounding Period, TBD + + Parameters: + Standard MU SND Paramter + + ========================================================================== + */ +INT SetMuraPeriodicSndProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_PERIODIC_SND; + CMD_SET_PERIODIC_SND param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} + + +/* + ========================================================================== + Description: + Set MU_RGA initialization, for test + + Parameters: + Standard MU SND Paramter + + ========================================================================== + */ +INT SetMuraTestAlgorithmInit(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + PCHAR pch = NULL; + PCHAR pIdx = NULL; + UINT32 index = 0; + + pch = arg; + + if (pch != NULL) + pIdx = pch; + else + return 0; + + index = os_str_tol(pIdx, 0, 10); + + /* 4 E3 RF /BBP Script */ + /* TBD */ + + /* 4 E3 MU-MIMO Script */ + /* TBD */ + + /* 4 MU-MIMO Initialization */ + if (index == 0) + SetMuraTestAlgorithmProc(pAd, "1"); + + return TRUE; +} + +/* + ========================================================================== + Description: + Set MU_RGA test flow, for test + + Parameters: + Standard MU SND Paramter + + ========================================================================== + */ +INT SetMuraTestAlgorithmProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + INT16 value = 0; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_TEST_ALGORITHM; + CMD_SET_PERIODIC_SND param = {0}; + struct _CMD_ATTRIBUTE attr = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + value = os_str_tol(arg, 0, 10); + param.u2Reserved = cpu2le16(value); + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} + +/* + ========================================================================== + Description: + Get MU_RGA algorithm status, for Debug + + Parameters: + Standard MU-RGA Paramter + + ========================================================================== + */ +INT GetMuraMonitorStateProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* =============================================================================================== */ + UINT32 index = 0; + UINT32 index2 = 0; + PCHAR pch = NULL; + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_ALGORITHM_STAT; + struct _CMD_ATTRIBUTE attr = {0}; + + pch = arg; + + if (pch != NULL) + index = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + if (index == MURA_STATE) { + EVENT_SHOW_ALGORITHM_STATE stat_result = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(stat_result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(stat_result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &stat_result); + SET_CMD_ATTR_RSP_HANDLER(attr, MuraEventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); + } else if (index == MURA_GROUP_STAT) { + EVENT_SHOW_ALGORITHM_GROUP_STATE grouop_stat_result = {0}; + + cmd = MURA_ALGORITHM_GROUP_STAT; + pch = strsep(&arg, "-"); + + if (pch == NULL) { + Ret = 0; + goto error; + } else { + pch = strsep(&arg, ""); + + if (pch != NULL) { + index2 = os_str_tol(pch, 0, 10); + + if (index2 >= MAX_MURA_GRP) { + Ret = 0; + goto error; + } + +#ifdef RT_BIG_ENDIAN + index2 = cpu2le32(index2); +#endif + } else { + Ret = 0; + goto error; + } + } + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(grouop_stat_result)); + + if (!msg) { + Ret = 0; + goto error; + } +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(grouop_stat_result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &grouop_stat_result); + SET_CMD_ATTR_RSP_HANDLER(attr, MuraEventDispatcher); + AndesInitCmdMsg(msg, attr); + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)&index2, sizeof(index2)); + AndesSendCmdMsg(pAd, msg); + } else if (index == MURA_HWFB_STAT) { + EVENT_SHOW_ALGORITHM_HWFB_STATE hwfb_stat_result = {0}; + + cmd = MURA_ALGORITHM_HWFB_STAT; + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(hwfb_stat_result)); + + if (!msg) { + Ret = 0; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(hwfb_stat_result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &hwfb_stat_result); + SET_CMD_ATTR_RSP_HANDLER(attr, MuraEventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesSendCmdMsg(pAd, msg); + } else + goto error; + +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} + +INT GetMuraPFIDStatProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + UINT32 u4Index = 0; + PCHAR pch = NULL; + INT32 Ret = TRUE; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_PFID_STAT; + struct _CMD_ATTRIBUTE attr = {0}; + EVENT_SHOW_PFID_STAT stat_result = {0}; + + pch = arg; + if (pch != NULL) { + u4Index = simple_strtol(pch, 0, 10); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Argument is NULL\n", __func__)); + Ret = FALSE; + goto error; + } + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(stat_result) + sizeof(u4Index)); + if (!msg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Msg allocation failed\n", __func__)); + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_QUERY_AND_WAIT_RSP); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, sizeof(stat_result)); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, &stat_result); + SET_CMD_ATTR_RSP_HANDLER(attr, MuraEventDispatcher); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)&u4Index, sizeof(u4Index)); + + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d\n", __func__, Ret)); + return Ret; +} + +/* + ========================================================================== + Description: + Set MU_RGA algorithm with Fixed Rate + + Parameters: + Standard MU-RGA Paramter + + ========================================================================== + */ +INT SetMuraFixedRateProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_FIXED_RATE_ALGORITHM; + UINT_8 param = 0; + UINT8 value = 0; + struct _CMD_ATTRIBUTE attr = {0}; + + value = os_str_tol(arg, 0, 10); + /* 2: MU-RGA Stop, 1:MU-RGA Fixed Rate, 0:MU-RGA Auto Rate */ + param = value; + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} + + +/* + ========================================================================== + Description: + Set MU_RGA algorithm with Fixed Group Entry + + Parameters: + Standard MU-RGA Paramter + + ========================================================================== + */ +INT SetMuraFixedGroupRateProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + PCHAR pch = NULL; + INT32 Ret = TRUE; + UINT_8 ucNNS_MCS = 0; + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_FIXED_GROUP_RATE_ALGORITHM; + CMD_MURGA_SET_GROUP_TBL_ENTRY param = {0}; + + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.numUser = os_str_tol(pch, 0, 10) - 1; + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.BW = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + if (param.numUser >= 1) { + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.WLIDUser0 = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "-"); + + if (pch != NULL) { + UINT_8 ucNNS_MCS = 0; + + ucNNS_MCS = os_str_tol(pch, 0, 10); + param.NS0 = (ucNNS_MCS > 10); + param.initMcsUser0 = (ucNNS_MCS > 10) ? (ucNNS_MCS - 10) : ucNNS_MCS; + } else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.WLIDUser1 = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + if (param.numUser == 1) + pch = strsep(&arg, ""); + else + pch = strsep(&arg, "-"); + + if (pch != NULL) { + ucNNS_MCS = os_str_tol(pch, 0, 10); + param.NS1 = (ucNNS_MCS > 10); + param.initMcsUser1 = (ucNNS_MCS > 10) ? (ucNNS_MCS - 10) : ucNNS_MCS; + } else { + Ret = 0; + goto error; + } + } + + if (param.numUser >= 2) { + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.WLIDUser2 = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + if (param.numUser == 2) + pch = strsep(&arg, ""); + else + pch = strsep(&arg, "-"); + + if (pch != NULL) { + ucNNS_MCS = os_str_tol(pch, 0, 10); + param.NS2 = (ucNNS_MCS > 10); + param.initMcsUser2 = (ucNNS_MCS > 10) ? (ucNNS_MCS - 10) : ucNNS_MCS; + } else { + Ret = 0; + goto error; + } + } + + if (param.numUser >= 3) { + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.WLIDUser3 = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) { + ucNNS_MCS = os_str_tol(pch, 0, 10); + param.NS3 = (ucNNS_MCS > 10); + param.initMcsUser3 = (ucNNS_MCS > 10) ? (ucNNS_MCS - 10) : ucNNS_MCS; + } else { + Ret = 0; + goto error; + } + } + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} + +/* +========================================================================== +Description: + Set MU_RGA algorithm with Fixed Group Entry + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraFixedSndParamProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + PCHAR pch = NULL; + INT32 Ret = TRUE; + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_SOUNDING_PERIOD; + CMD_SET_SND_PARAMS param = {0}; + + pch = strsep(&arg, "-"); + + if (pch != NULL) { + param.ucWLIDUser = os_str_tol(pch, 0, 10); + + if (param.ucWLIDUser == 0) + param.ucAllMuUser = 1; + } else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.ucMaxSoundingPeriod = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, "-"); + + if (pch != NULL) + param.ucMinSoundingPeriod = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + pch = strsep(&arg, ""); + + if (pch != NULL) + param.ucSoundingPeriodStep = os_str_tol(pch, 0, 10); + else { + Ret = 0; + goto error; + } + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} + +/* +========================================================================== +Description: + Set MU_RGA algorithm with Fixed Group Entry + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraPlatformTypeProc(RTMP_ADAPTER *pAd) +{ + INT32 Ret = TRUE; + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_PLATFORM_TYPE; + CMD_SET_PLATFORM_TYPE param = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + +#if defined(CONFIG_RALINK_MT7621) + param.ucPlatformType = 1; /*MT7621*/ +#endif +#if defined(CONFIG_ARCH_MT7623) + param.ucPlatformType = 2; /*MT7623*/ +#endif +#if defined(CONFIG_ARCH_MT7622) + param.ucPlatformType = 2; /*MT7622*/ +#endif + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d_\n", __func__, Ret)); + return Ret; +} + +/* +========================================================================== +Description: + Set MU_RGA Mobility Detect On Off + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilityCtrlProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_CTRL; + CMD_MURGA_SET_MOBILITY_TYPE param = {0}; + + /* declair parsing function related parameter */ + UINT8 u1ParamIdx; + CHAR *cstr; + BOOLEAN fgMobilityDetectEn = 0; + + /* sanity check for input parameter existence */ + if (!arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): No parameters!!\n", __func__)); + goto error0; + } + + /* sanity check for input parameter format */ + if (strlen(arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Wrong parameter format!!\n", __func__)); + goto error0; + } + + /* parameter parsing */ + for (u1ParamIdx = 0, cstr = rstrtok(arg, ":"); cstr; cstr = rstrtok(NULL, ":"), u1ParamIdx++) { + switch (u1ParamIdx) { + case 0: + /* 1 symbol representation */ + fgMobilityDetectEn = simple_strtol(cstr, 0, 10); + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Number of parameters exceed expectation !!\n", __func__)); + goto error0; + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): fgMobilityDetectEn: %d\n", __func__, + fgMobilityDetectEn)); + + /* memory allocate for command message */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + /* sanity check for command message memory allocate */ + if (!msg) + goto error1; + + /* command message contents config */ + param.fgMobilityType = fgMobilityDetectEn; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + chip_cmd_tx(pAd, msg); + return TRUE; + +error0: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Expected format is as below:\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" iwpriv set mura_mobility_en=O\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param1: Mobility Enable (0, 1)\n")); + return FALSE; + +error1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): command message memory allocated fail!!\n", __func__)); + return FALSE; +} + +/* +========================================================================== +Description: + Set MU_RGA Mobility Detect Interval Ctrl + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilityIntervalCtrlProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_INTERVAL_CTRL; + CMD_MURGA_SET_MOBILITY_INTERVAL param = {0}; + + /* declair parsing function related parameter */ + UINT8 u1ParamIdx; + CHAR *cstr; + UINT16 u2MobilityInteral = 0; + + /* sanity check for input parameter existence */ + if (!arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): No parameters!!\n", __func__)); + goto error0; + } + + /* sanity check for input parameter format */ + if (strlen(arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Wrong parameter format!!\n", __func__)); + goto error0; + } + + /* parameter parsing */ + for (u1ParamIdx = 0, cstr = rstrtok(arg, ":"); cstr; cstr = rstrtok(NULL, ":"), u1ParamIdx++) { + switch (u1ParamIdx) { + case 0: + /* 1 symbol representation */ + u2MobilityInteral = simple_strtol(cstr, 0, 10); + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Number of parameters exceed expectation !!\n", __func__)); + goto error0; + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): u2MobilityInteral: %d\n", __func__, + u2MobilityInteral)); + + /* memory allocate for command message */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + /* sanity check for command message memory allocate */ + if (!msg) + goto error1; + + /* command message contents config */ + param.u2MobilityInteral = u2MobilityInteral; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + chip_cmd_tx(pAd, msg); + return TRUE; + +error0: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Expected format is as below:\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" iwpriv set mura_mobility_interval_ctrl=O\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param1: Mobility Computation Profile Time Interval (180, 360)\n")); + return FALSE; + +error1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): command message memory allocated fail!!\n", __func__)); + return FALSE; +} + +/* +========================================================================== +Description: + Set MU_RGA Mobility Detect SNR Ctrl + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilitySNRCtrlProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_SNR_CTRL; + CMD_MURGA_SET_MOBILITY_SNR param = {0}; + + /* declair parsing function related parameter */ + UINT8 u1ParamIdx; + CHAR *cstr; + UINT8 ucMobilitySNR = 0; + + /* sanity check for input parameter existence */ + if (!arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): No parameters!!\n", __func__)); + goto error0; + } + + /* sanity check for input parameter format */ + if (strlen(arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Wrong parameter format!!\n", __func__)); + goto error0; + } + + /* parameter parsing */ + for (u1ParamIdx = 0, cstr = rstrtok(arg, ":"); cstr; cstr = rstrtok(NULL, ":"), u1ParamIdx++) { + switch (u1ParamIdx) { + case 0: + /* 1 symbol representation */ + ucMobilitySNR = simple_strtol(cstr, 0, 10); + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Number of parameters exceed expectation !!\n", __func__)); + goto error0; + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): ucMobilitySNR: %d\n", __func__, + ucMobilitySNR)); + + /* memory allocate for command message */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + /* sanity check for command message memory allocate */ + if (!msg) + goto error1; + + /* command message contents config */ + param.ucMobilitySNR = ucMobilitySNR; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + chip_cmd_tx(pAd, msg); + return TRUE; + +error0: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Expected format is as below:\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" iwpriv set mura_mobility_snr_ctrl=O\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param1: Mobility Computation SNR value (0~63)\n")); + return FALSE; + +error1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): command message memory allocated fail!!\n", __func__)); + return FALSE; +} + +/* +========================================================================== +Description: + Set MU_RGA Mobility Detect Threshold Ctrl + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilityThresholdCtrlProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_THRESHOLD_CTRL; + CMD_MURGA_SET_MOBILITY_THRESHOLD param = {0}; + + /* declair parsing function related parameter */ + UINT8 u1ParamIdx; + CHAR *cstr; + UINT8 ucWlanId = 0, ucMobilityThreshold = 0; + + /* sanity check for input parameter existence */ + if (!arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): No parameters!!\n", __func__)); + goto error0; + } + + /* sanity check for input parameter format */ + if (strlen(arg) != 6) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Wrong parameter format!!\n", __func__)); + goto error0; + } + + /* parameter parsing */ + for (u1ParamIdx = 0, cstr = rstrtok(arg, ":"); cstr; cstr = rstrtok(NULL, ":"), u1ParamIdx++) { + switch (u1ParamIdx) { + case 0: + /* 3 symbol representation */ + ucWlanId = simple_strtol(cstr, 0, 10); + break; + case 1: + /* 2 symbol representation */ + ucMobilityThreshold = simple_strtol(cstr, 0, 10); + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Number of parameters exceed expectation !!\n", __func__)); + goto error0; + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): ucWlanId: %d, ucMobilityThreshold: %d\n", __func__, + ucWlanId, ucMobilityThreshold)); + + /* memory allocate for command message */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + /* sanity check for command message memory allocate */ + if (!msg) + goto error1; + + /* command message contents config */ + param.ucWlanId = ucWlanId; + param.ucMobilityThreshold = ucMobilityThreshold; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + chip_cmd_tx(pAd, msg); + return TRUE; + +error0: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Expected format is as below:\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" iwpriv set mura_mobility_threshold_ctrl=OOO:OO\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param1: WlanId (0~127)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param2: Mobility LQ Threshold (0~63)\n")); + return FALSE; + +error1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): command message memory allocated fail!!\n", __func__)); + return FALSE; +} + +/* +========================================================================== +Description: + Set MU_RGA Sounding counter info + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilitySndCountProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_SOUNDING_INTERVAL_COUNT; + CMD_MURGA_GET_MOBILITY_SND_INTERVAL param = {0}; + + PCHAR pbuffer = NULL; + PCHAR pflag = NULL; + UINT8 fgMobilitySndIntvalCnt = 0; + + pbuffer = arg; + if (pbuffer != NULL) { + pflag = pbuffer; + } else { + return 0; + } + + fgMobilitySndIntvalCnt = simple_strtol(pflag, 0, 10); + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + if (!msg) { + Ret = FALSE; + goto error; + } + + param.fgMobilitySndIntvalCnt = fgMobilitySndIntvalCnt; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); + + return Ret; + +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s:(Ret = %d_\n", __FUNCTION__, Ret)); + + return Ret; +} + +/* +========================================================================== +Description: + Set MU_RGA Mobility Mode Ctrl + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilityModeCtrlProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_MODE_CTRL; + CMD_MURGA_SET_MOBILITY_MODE param = {0}; + + /* declair parsing function related parameter */ + UINT8 u1ParamIdx; + CHAR *cstr; + BOOLEAN fgMULQPingPongEn = TRUE; + BOOLEAN fgMULQTriggerCalEn = TRUE; + BOOLEAN fgMobilityFlagForceEn = FALSE; + + /* sanity check for input parameter existence */ + if (!arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): No parameters!!\n", __func__)); + goto error0; + } + + /* sanity check for input parameter format */ + if (strlen(arg) != 5) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Wrong parameter format!!\n", __func__)); + goto error0; + } + + /* parameter parsing */ + for (u1ParamIdx = 0, cstr = rstrtok(arg, ":"); cstr; cstr = rstrtok(NULL, ":"), u1ParamIdx++) { + switch (u1ParamIdx) { + case 0: + /* 1 symbol representation */ + fgMULQPingPongEn = simple_strtol(cstr, 0, 10); + break; + case 1: + /* 1 symbol representation */ + fgMULQTriggerCalEn = simple_strtol(cstr, 0, 10); + break; + case 2: + /* 1 symbol representation */ + fgMobilityFlagForceEn = simple_strtol(cstr, 0, 10); + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Number of parameters exceed expectation !!\n", __func__)); + goto error0; + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): fgMULQPingPongEn: %d, fgMULQTriggerCalEn: %d, fgMobilityFlagForceEn: %d\n", __func__, + fgMULQPingPongEn, fgMULQTriggerCalEn, fgMobilityFlagForceEn)); + + /* memory allocate for command message */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + /* sanity check for command message memory allocate */ + if (!msg) + goto error1; + + /* command message contents config */ + param.fgMULQPingPongEn = fgMULQPingPongEn; + param.fgMULQTriggerCalEn = fgMULQTriggerCalEn; + param.fgMobilityFlagForceEn = fgMobilityFlagForceEn; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + chip_cmd_tx(pAd, msg); + return TRUE; + +error0: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Expected format is as below:\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" iwpriv set mura_mobility_mode_ctrl=O:O:O\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param1: Mobility PingPong Mechanism Enable (0, 1)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param2: Mobility Trigger Computation (0, 1)\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param3: Mobility Flag Enable Forced Mode (0, 1)\n")); + return FALSE; + +error1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): command message memory allocated fail!!\n", __func__)); + return FALSE; +} + +/* +========================================================================== +Description: + Set MU_RGA Mobility Log Ctrl + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilityLogCtrlProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_LOG_CTRL; + CMD_MURGA_SET_MOBILITY_LOG param = {0}; + + /* declair parsing function related parameter */ + UINT8 u1ParamIdx; + CHAR *cstr; + BOOLEAN fgMobilityLogEn = TRUE; + + /* sanity check for input parameter existence */ + if (!arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): No parameters!!\n", __func__)); + goto error0; + } + + /* sanity check for input parameter format */ + if (strlen(arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Wrong parameter format!!\n", __func__)); + goto error0; + } + + /* parameter parsing */ + for (u1ParamIdx = 0, cstr = rstrtok(arg, ":"); cstr; cstr = rstrtok(NULL, ":"), u1ParamIdx++) { + switch (u1ParamIdx) { + case 0: + /* 3 symbol representation */ + fgMobilityLogEn = simple_strtol(cstr, 0, 10); + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Number of parameters exceed expectation !!\n", __func__)); + goto error0; + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): fgMobilityLogEn: %d\n", __func__, + fgMobilityLogEn)); + + /* memory allocate for command message */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + /* sanity check for command message memory allocate */ + if (!msg) + goto error1; + + /* command message contents config */ + param.fgMobilityLogEn = fgMobilityLogEn; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + chip_cmd_tx(pAd, msg); + return TRUE; + +error0: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Expected format is as below:\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" iwpriv set mura_mobility_log_ctrl=O\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param1: Mobility Log Enable (0, 1)\n")); + return FALSE; + +error1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): command message memory allocated fail!!\n", __func__)); + return FALSE; +} + +/* +========================================================================== +Description: + Set MU_RGA Mobility Test Ctrl + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraMobilityTestCtrlProc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_MOBILITY_TEST_CTRL; + CMD_MURGA_SET_MOBILITY_TEST param = {0}; + + /* declair parsing function related parameter */ + UINT8 u1ParamIdx; + CHAR *cstr; + BOOLEAN fgMobilityTestEn = TRUE; + + /* sanity check for input parameter existence */ + if (!arg) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): No parameters!!\n", __func__)); + goto error0; + } + + /* sanity check for input parameter format */ + if (strlen(arg) != 1) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Wrong parameter format!!\n", __func__)); + goto error0; + } + + /* parameter parsing */ + for (u1ParamIdx = 0, cstr = rstrtok(arg, ":"); cstr; cstr = rstrtok(NULL, ":"), u1ParamIdx++) { + switch (u1ParamIdx) { + case 0: + /* 3 symbol representation */ + fgMobilityTestEn = simple_strtol(cstr, 0, 10); + break; + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): Number of parameters exceed expectation !!\n", __func__)); + goto error0; + } + } + + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): fgMobilityTestEn: %d\n", __func__, + fgMobilityTestEn)); + + /* memory allocate for command message */ + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + + /* sanity check for command message memory allocate */ + if (!msg) + goto error1; + + /* command message contents config */ + param.fgMobilityTestEn = fgMobilityTestEn; + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + chip_cmd_tx(pAd, msg); + return TRUE; + +error0: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Expected format is as below:\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" iwpriv set mura_mobility_test_ctrl=O\n\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" param1: Mobility Test Force each MU User as Mobility Candidate (0, 1)\n")); + return FALSE; + +error1: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): command message memory allocated fail!!\n", __func__)); + return FALSE; +} + +/* +========================================================================== +Description: + Set MU_RGA Disable CN3, CN4 Group Entry + +Parameters: + Standard MU-RGA Paramter + +========================================================================== + */ +INT SetMuraDisableCN3CN4Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT32 Ret = TRUE; + + /* prepare command message */ + struct _CMD_ATTRIBUTE attr = {0}; + struct cmd_msg *msg = NULL; + UINT32 cmd = MURA_DISABLE_CN3_CN4; + CMD_SET_DISABLE_CN3_CN4 param = {0}; + + msg = AndesAllocCmdMsg(pAd, sizeof(cmd) + sizeof(param)); + if (!msg) { + Ret = FALSE; + goto error; + } + + param.ucDisableCn3Cn4 = simple_strtol(arg, 0, 10); + + SET_CMD_ATTR_MCU_DEST(attr, HOST2N9); + SET_CMD_ATTR_TYPE(attr, EXT_CID); + SET_CMD_ATTR_EXT_TYPE(attr, EXT_CMD_ID_MU_MIMO_RA); + SET_CMD_ATTR_CTRL_FLAGS(attr, INIT_CMD_SET_AND_RETRY); + SET_CMD_ATTR_RSP_WAIT_MS_TIME(attr, 0); + SET_CMD_ATTR_RSP_EXPECT_SIZE(attr, 0); + SET_CMD_ATTR_RSP_WB_BUF_IN_CALBK(attr, NULL); + SET_CMD_ATTR_RSP_HANDLER(attr, NULL); + AndesInitCmdMsg(msg, attr); + +#ifdef RT_BIG_ENDIAN + cmd = cpu2le32(cmd); +#endif + + AndesAppendCmdMsg(msg, (char *)&cmd, sizeof(cmd)); + AndesAppendCmdMsg(msg, (char *)¶m, sizeof(param)); + AndesSendCmdMsg(pAd, msg); + +error: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("%s:(Ret = %d_\n", __FUNCTION__, Ret)); + + return Ret; + +} + +/* + ========================================================================== + Description: + MU_RGA Event Handler + + Parameters: + Standard MU-RGA Paramter + + ========================================================================== + */ +static VOID MuraEventDispatcher( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len) +{ + UINT32 u4EventId = (*(UINT32 *) rsp_payload); + char *pData = (rsp_payload); + UINT16 len = (rsp_payload_len); +#ifdef RT_BIG_ENDIAN + u4EventId = cpu2le32(u4EventId); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: u4EventId = %u, len = %u\n", __func__, u4EventId, len)); + + switch (u4EventId) { + case MURA_EVENT_ALGORITHM_STAT: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MURA_EVENT_GET_ALGORITHM_STATE\n", __func__)); + mura_algorithm_state_callback(msg, pData, len); + break; + + case MURA_EVENT_ALGORITHM_GROUP_STAT: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MURA_EVENT_GET_ALGORITHM_GROUP_STATE\n", __func__)); + mura_algorithm_group_state_callback(msg, pData, len); + break; + + case MURA_EVENT_ALGORITHM_HWFB_STAT: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MURA_EVENT_GET_ALGORITHM_HWFB_STATE\n", __func__)); + mura_algorithm_hwfb_state_callback(msg, pData, len); + break; + + case MURA_EVENT_PFID_STAT: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: MURA_EVENT_PFID_STAT\n", __func__)); + mura_algorithm_pfid_stat_callback(msg, pData, len); + break; + + default: + break; + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief [CMD] Monitor the MU-RGA State +* +* @param pucParam +* +* @return status +*/ +/*----------------------------------------------------------------------------*/ +static VOID mura_algorithm_state_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_SHOW_ALGORITHM_STATE pEntry = NULL; + UINT_8 ucPFIDList_Idx = 0, ucGroupEntryList_Idx = 0; /* , ucNumofGroupEntry = 0; */ + + /* P_MURA_CN_ENTRY_INFO_T pGroupEntry; */ + if (rsp_payload == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! rsp_payload is null!!\n", __func__)); + return; + } + + pEntry = (P_EVENT_SHOW_ALGORITHM_STATE) rsp_payload; + + /* if (msg->rsp_payload == NULL) */ + /* { */ + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, */ + /* ("%s: error !! buffer not specific by cmd\n", __FUNCTION__)); */ + /* } */ + /* else */ + { + /* Current MUser in the system */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (MURA_COLOR_RESET "\n Number of Totally MUser : %2d\n", pEntry->ucMaxMuarNum)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n Number of Sounding MUser : %2d\n", pEntry->ucSoundingNum)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n Number of Waiting MUser : %2d\n", pEntry->ucWaitingNum)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n Number of SU Current Space : %2d\n", pEntry->ucMaxSndingCap)); + /* Show MU-RGA Sounding Candidate List */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Sounding Candidate WLAN ID List :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->ucMURAWlanIdList[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Group Candidate List */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Group Entry Candidate List :")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + if (pEntry->ucMURAPfidList[ucPFIDList_Idx] == 0x1F) + continue; + + for (ucGroupEntryList_Idx = 0; ucGroupEntryList_Idx < MU_2U_NUM; ucGroupEntryList_Idx++) { + if ((ucGroupEntryList_Idx % 20) == 0) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n %2d: ", ucGroupEntryList_Idx)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%1d, ", pEntry->au4PfidGroupTableMap[ucPFIDList_Idx][ucGroupEntryList_Idx])); + } + + for (ucGroupEntryList_Idx = MU_2U_NUM; ucGroupEntryList_Idx < (MU_2U_NUM + MU_3U_NUM); ucGroupEntryList_Idx++) { + if (((ucGroupEntryList_Idx - MU_2U_NUM) % 20) == 0) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n %2d: ", ucGroupEntryList_Idx)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (MURA_COLOR_RED "%1d" MURA_COLOR_RESET ", ", pEntry->au4PfidGroupTableMap[ucPFIDList_Idx][ucGroupEntryList_Idx])); + } + + for (ucGroupEntryList_Idx = (MU_2U_NUM + MU_3U_NUM); ucGroupEntryList_Idx < MAX_MURA_GRP; ucGroupEntryList_Idx++) { + if (((ucGroupEntryList_Idx - (MU_2U_NUM + MU_3U_NUM)) % 20) == 0) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n %2d: ", ucGroupEntryList_Idx)); + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (MURA_COLOR_GREEN "%1d" MURA_COLOR_RESET ", ", pEntry->au4PfidGroupTableMap[ucPFIDList_Idx][ucGroupEntryList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + } + + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR,("\n")); */ + /* Show MU-RGA Tx Success Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn2 Tx Succ Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->u4TxSuccCnt[ucPFIDList_Idx] = le2cpu32(pEntry->u4TxSuccCnt[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->u4TxSuccCnt[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx Fail Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn2 Tx Fail Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->u4TxFailCnt[ucPFIDList_Idx] = le2cpu32(pEntry->u4TxFailCnt[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->u4TxFailCnt[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx Success Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn3 Tx Succ Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->u4TxCn3SuccCnt[ucPFIDList_Idx] = le2cpu32(pEntry->u4TxCn3SuccCnt[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->u4TxCn3SuccCnt[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx Fail Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn3 Tx Fail Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->u4TxCn3FailCnt[ucPFIDList_Idx] = le2cpu32(pEntry->u4TxCn3FailCnt[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->u4TxCn3FailCnt[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx Success Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn4 Tx Succ Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->u4TxCn4SuccCnt[ucPFIDList_Idx] = le2cpu32(pEntry->u4TxCn4SuccCnt[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->u4TxCn4SuccCnt[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx Fail Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn4 Tx Fail Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->u4TxCn4FailCnt[ucPFIDList_Idx] = le2cpu32(pEntry->u4TxCn4FailCnt[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->u4TxCn4FailCnt[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx PER Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn2 Total Tx PER :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->ucTxPER[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx PER Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn3 Total Tx PER :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->ucTxCn3PER[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Tx PER Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Cn4 Total Tx PER :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->ucTxCn4PER[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Mobility */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Mobility :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->fgMobility[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU-RGA Delta MCS */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Delta MCS Rate :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->aucMURADeltaMCS[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU Succ Sounding Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA MU Succ Sounding Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->au2SuccSounding[ucPFIDList_Idx] = le2cpu16(pEntry->au2SuccSounding[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->au2SuccSounding[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU Fail Sounding Counter */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA MU Fail Sounding Counter :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { +#ifdef RT_BIG_ENDIAN + pEntry->au2FailSounding[ucPFIDList_Idx] = le2cpu16(pEntry->au2FailSounding[ucPFIDList_Idx]); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->au2FailSounding[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + /* Show MU SND PER */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA MU Sounding Fail Rate :\n")); + + for (ucPFIDList_Idx = 0; ucPFIDList_Idx < MAX_MURA_NUM; ucPFIDList_Idx++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %2d,", pEntry->aucSoundingFailRate[ucPFIDList_Idx])); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n\n")); +#ifdef RT_BIG_ENDIAN + pEntry->u4CalculateSoundingEnd = le2cpu32(pEntry->u4CalculateSoundingEnd); + pEntry->u4CalculateSoundingStart = le2cpu32(pEntry->u4CalculateSoundingStart); + pEntry->u4CalculateGroupMcsRateEnd = le2cpu32(pEntry->u4CalculateGroupMcsRateEnd); + pEntry->u4CalculateGroupMcsRateStart = le2cpu32(pEntry->u4CalculateGroupMcsRateStart); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" Sounding Period : %d ms\n", + pEntry->u4CalculateSoundingEnd - pEntry->u4CalculateSoundingStart)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" Group Period : %d ms\n", + pEntry->u4CalculateGroupMcsRateEnd - pEntry->u4CalculateGroupMcsRateStart)); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief [CMD] Monitor the MU-RGA Group State +* +* @param pucParam +* +* @return status +*/ +/*----------------------------------------------------------------------------*/ +static VOID mura_algorithm_group_state_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_SHOW_ALGORITHM_GROUP_STATE pEntry = NULL; + + if (rsp_payload == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! rsp_payload is null!!\n", __func__)); + return; + } + + pEntry = (P_EVENT_SHOW_ALGORITHM_GROUP_STATE) rsp_payload; + + /* if (msg->rsp_payload == NULL) */ + /* { */ + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, */ + /* ("%s: error !! buffer not specific by cmd\n", __FUNCTION__)); */ + /* } */ + /* else */ + { + /* Show MU-RGA Group Entry Information */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Group Entry Information :")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n GPID MNUM\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %4d %4d\n", + (pEntry->rMuraGroupEntry).u4GroupID, + (pEntry->rMuraGroupEntry).ucUserNum)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" MU0_ID MU1_ID MU2_ID MU3_ID\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %6d %6d %6d %6d\n", + (pEntry->rMuraGroupEntry).u4U0PFID, + (pEntry->rMuraGroupEntry).u4U1PFID, + (pEntry->rMuraGroupEntry).u4U2PFID, + (pEntry->rMuraGroupEntry).u4U3PFID)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" RATE0 RATE1 RATE2 RATE3\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %5d %5d %5d %5d\n", + (pEntry->rMuraGroupEntry).u2U0Rate + + ((pEntry->rMuraGroupEntry).ucU0SSN * 10), + (pEntry->rMuraGroupEntry).u2U1Rate + + ((pEntry->rMuraGroupEntry).ucU1SSN * 10), + (pEntry->rMuraGroupEntry).u2U2Rate + + ((pEntry->rMuraGroupEntry).ucU2SSN * 10), + (pEntry->rMuraGroupEntry).u2U3Rate + + ((pEntry->rMuraGroupEntry).ucU3SSN * 10))); + + if ((pEntry->rMuraGroupEntry).u4GroupValid) + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n")); + else + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n No Valid Group Entry\n\n")); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* @brief [CMD] Monitor the MU-RGA Hardware fallback State +* +* @param pucParam +* +* @return status +*/ +/*----------------------------------------------------------------------------*/ +static VOID mura_algorithm_hwfb_state_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_SHOW_ALGORITHM_HWFB_STATE pEntry = NULL; + UINT_8 ucMCSRate = 0; + + if (rsp_payload == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: error !! rsp_payload is null!!\n", __func__)); + return; + } + + pEntry = (P_EVENT_SHOW_ALGORITHM_HWFB_STATE) rsp_payload; + + /* if (msg->rsp_payload == NULL) */ + /* { */ + /* MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, */ + /* ("%s: error !! buffer not specific by cmd\n", __FUNCTION__)); */ + /* } */ + /* else */ + { + /* Show MU-RGA Group Entry Information */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MU-RGA Hardware fallback Information :")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("\n MCS DnEn DnThres DnValue UpEn UpThres UpValue 20BSamp 40BSamp 80BSamp\n")); + + for (ucMCSRate = 0; ucMCSRate < 10; ucMCSRate++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + (" %3d %4d %7d %7d %4d %7d %7d %7d %7d %7d\n", + ucMCSRate, + pEntry->fgDownOneStep[ucMCSRate], + pEntry->ucDownThreshold[ucMCSRate], + pEntry->ucDownMCS[ucMCSRate], + pEntry->fgUpOneStep[ucMCSRate], + pEntry->ucUpThreshold[ucMCSRate], + pEntry->ucUpMCS[ucMCSRate], + pEntry->uc20BWSample[ucMCSRate] * pEntry->uc20BWSampleFactor, + pEntry->uc40BWSample[ucMCSRate] * pEntry->uc40BWSampleFactor, + pEntry->uc80BWSample[ucMCSRate] * pEntry->uc80BWSampleFactor + )); + } + } +} + +static VOID mura_algorithm_pfid_stat_callback( + struct cmd_msg *msg, + char *rsp_payload, + UINT16 rsp_payload_len) +{ + P_EVENT_SHOW_PFID_STAT pEntry = (P_EVENT_SHOW_PFID_STAT) rsp_payload; + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Event is NULL!!\n", __func__)); + return; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Value of PFID stat are :-\n")); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("WlanIdx = %d\n", pEntry->u1WlanIdx)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Mobility = %d\n", pEntry->fgMobility)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn2 SuccCnt = %u\n", pEntry->u4TxSuccCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn2 FailCnt = %u\n", pEntry->u4TxFailCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn3 SuccCnt = %u\n", pEntry->u4TxCn3SuccCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn3 FailCnt = %u\n", pEntry->u4TxCn3FailCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn4 SuccCnt = %u\n", pEntry->u4TxCn4SuccCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn4 FailCnt = %u\n", pEntry->u4TxCn4FailCnt)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn2 TxPER = %u\n", pEntry->u1TxPER)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn3 TxPER = %u\n", pEntry->u1TxCn3PER)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Cn4 TxPER = %u\n", pEntry->u1TxCn4PER)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Sounding Period = %u\n", pEntry->u1SoundingPeriod)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Min Sounding Period = %u\n", pEntry->u1MinSoundingPeriod)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Max Sounding Period = %u\n", pEntry->u1MaxSoundingPeriod)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Sounding Period Step = %u\n", pEntry->u1SoundingPeriodStep)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Succ Sounding = %u\n", pEntry->u2SuccSounding)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Fail Sounding = %u\n", pEntry->u2FailSounding)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("Sounding Fail Rate = %u\n", pEntry->u1SoundingFailRate)); +} + +#endif /* CFG_SUPPORT_MU_MIMO_RA */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_nps.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_nps.c new file mode 100644 index 000000000..12d996645 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_nps.c @@ -0,0 +1,273 @@ +/**************************************************************************** + * 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_nps.c + + Abstract: + IEEE 802.11v NPS SoftAP related function + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Carter Chen 08-23-2013 created for 7603 AP + */ +#ifdef MT_MAC + +#include "rt_config.h" + +extern VOID write_tmac_info_tim(RTMP_ADAPTER *pAd, INT apidx, UCHAR *tmac_buf, HTTRANSMIT_SETTING *BeaconTransmit, ULONG frmLen); + +BOOLEAN TimTransmitRequired(RTMP_ADAPTER *pAd, INT apidx, BSS_STRUCT *pMbss) +{ + BOOLEAN result = FALSE; + TIM_BUF_STRUC *tim_info; + + tim_info = &pMbss->wdev.bcn_buf.tim_buf; + + if (tim_info->TimBufIdx >= HW_BEACON_MAX_NUM) + return result; + + if (tim_info->bTimSntReq == TRUE) + result = TRUE; + + return result; +} + +#ifdef MT_MAC +VOID MtUpdateTimToAsic( + IN RTMP_ADAPTER *pAd, + IN INT apidx, + IN ULONG FrameLen) +{ + TIM_BUF_STRUC *tim_buf = NULL; + UCHAR *buf; + INT len; + PNDIS_PACKET *pkt = NULL; + UINT32 WdevIdx; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + tim_buf = &wdev->bcn_buf.tim_buf; + } + + if (!tim_buf) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): bcn_buf is NULL!\n", __func__)); + return; + } + + WdevIdx = wdev->wdev_idx; + pkt = tim_buf->TimPkt; + + if (pkt) { + UCHAR qIdx; + buf = (UCHAR *)GET_OS_PKT_DATAPTR(pkt); + len = FrameLen + cap->tx_hw_hdr_len; + SET_OS_PKT_LEN(pkt, len); + RTMP_SET_PACKET_WDEV(pkt, WdevIdx); + qIdx = HcGetBcnQueueIdx(pAd, wdev); + RTMP_SET_PACKET_TYPE(pkt, TX_MGMT); + send_mlme_pkt(pAd, pkt, wdev, qIdx, FALSE); + return; + } else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): TimPkt is NULL!\n", __func__)); +} +#endif /* MT_MAC */ + +VOID write_tmac_info_tim(RTMP_ADAPTER *pAd, INT apidx, UCHAR *tmac_buf, HTTRANSMIT_SETTING *BeaconTransmit, ULONG frmLen) +{ + MAC_TX_INFO mac_info; + struct wifi_dev *wdev; + + NdisZeroMemory((UCHAR *)&mac_info, sizeof(mac_info)); +#ifdef MT_MAC + mac_info.Type = FC_TYPE_MGMT; + mac_info.SubType = SUBTYPE_ACTION; +#endif + mac_info.FRAG = FALSE; + mac_info.CFACK = FALSE; + mac_info.InsTimestamp = FALSE; + mac_info.AMPDU = FALSE; + mac_info.BM = 1; + mac_info.Ack = FALSE; + mac_info.NSeq = TRUE; + mac_info.BASize = 0; + mac_info.WCID = 0; + mac_info.Length = frmLen; + mac_info.PID = PID_MGMT; + mac_info.TID = 0; + mac_info.TxRate = 0; + mac_info.Txopmode = IFS_HTTXOP; + mac_info.hdr_len = 24; + mac_info.bss_idx = apidx; + mac_info.SpeEn = 1; + mac_info.Preamble = LONG_PREAMBLE; + mac_info.IsAutoRate = FALSE; + wdev = wdev_search_by_address(pAd, tmac_buf + sizeof(TMAC_TXD_L) + 10); + + if (!wdev) + return; + + mac_info.q_idx = HcGetBcnQueueIdx(pAd, wdev); +#ifdef MT_MAC + mac_info.TxSPriv = wdev->func_idx; + mac_info.OmacIdx = wdev->OmacIdx; + + if (wdev->bcn_buf.BcnUpdateMethod == BCN_GEN_BY_FW) + mac_info.IsOffloadPkt = TRUE; + else + mac_info.IsOffloadPkt = FALSE; + + mac_info.Preamble = LONG_PREAMBLE; + NdisZeroMemory(tmac_buf, sizeof(TMAC_TXD_L)); +#endif + pAd->archOps.write_tmac_info_fixed_rate(pAd, tmac_buf, &mac_info, BeaconTransmit); +} + +VOID APMakeBssTimFrame(RTMP_ADAPTER *pAd, INT apidx) +{ + BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx]; + HEADER_802_11 TimHdr; + LARGE_INTEGER FakeTimestamp; + ULONG FrameLen = 0; + UCHAR *pTimFrame, *ptr, *tmac_info; + HTTRANSMIT_SETTING TimTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at HT rate. */ + struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UINT8 tx_hw_hdr_len = cap->tx_hw_hdr_len; + UCHAR Cat = 11;/* Tim Category field */ + UCHAR Act = 0;/* Tim Action field */ + UCHAR ChkBcn = 0;/* Check Beacon field init from 0. */ + ULONG UpdatePos = 0; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + + if (!TimTransmitRequired(pAd, apidx, pMbss)) + return; + + if (wdev->bcn_buf.tim_buf.TimPkt == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Invalid TimPkt for MBSS[%d]\n", + __func__, apidx)); + return; + } + + tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(wdev->bcn_buf.tim_buf.TimPkt); + pTimFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len); + ActHeaderInit(pAd, + &TimHdr, + BROADCAST_ADDR, + wdev->if_addr, + wdev->bssid); + MakeOutgoingFrame(pTimFrame, &FrameLen, + sizeof(HEADER_802_11), &TimHdr, + 1, &Cat, + 1, &Act, + 1, &ChkBcn, + TIMESTAMP_LEN, &FakeTimestamp, + END_OF_ARGS); + TimTransmit.word = 0; + wdev->bcn_buf.TimIELocationInTim = (UCHAR)FrameLen; + UpdatePos = wdev->bcn_buf.TimIELocationInTim; + /* + 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 = pTimFrame + (UCHAR)FrameLen; + *ptr = IE_TIM; + *(ptr+1) = 0x0e; + *(ptr + 2) = pAd->ApCfg.DtimCount; + *(ptr + 3) = pAd->ApCfg.DtimPeriod; + *(ptr + 4) = 0xa0; + *(ptr + 5) = 0xa0; + *(ptr + 6) = 0xa0; + *(ptr + 7) = 0xa0; + *(ptr + 8) = 0xa0; + *(ptr + 9) = 0xa0; + *(ptr + 10) = 0xa0; + *(ptr + 11) = 0xa0; + *(ptr + 12) = 0xa0; + *(ptr + 13) = 0xa0; + *(ptr + 14) = 0xa0; + *(ptr + 15) = 0xa0; + /* adjust TIM length according to the new TIM */ + FrameLen += 16;/* (2 + *(ptr+1)); */ + + /* When Beacon is use CCK to send, high rate TIM shall use OFDM to send. and it's mandatory. */ + if (wdev->channel <= 14) { + TimTransmit.field.MODE = MODE_OFDM; + TimTransmit.field.MCS = MCS_RATE_6; + } else { + TimTransmit.field.MODE = MODE_OFDM; + TimTransmit.field.MCS = MCS_RATE_9; + } + + write_tmac_info_tim(pAd, apidx, tmac_info, &TimTransmit, FrameLen); + AsicUpdateBeacon(pAd, wdev, FrameLen, PKT_TIM); + + if (0) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, + ("%s(): Dump the TimFrame of BSS%d!\n", + __func__, apidx)); + hex_dump("Initial TimFrameBuf", tmac_info, FrameLen + tx_hw_hdr_len); + } +} + +UCHAR GetTimNum(RTMP_ADAPTER *pAd) +{ + int i; + int NumTim; + TIM_BUF_STRUC *tim_info; + + NumTim = 0; + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + tim_info = &pAd->ApCfg.MBSSID[i].wdev.bcn_buf.tim_buf; + + if (tim_info->bTimSntReq) { + tim_info->TimBufIdx = NumTim; + NumTim++; + } + } + + return NumTim; +} + +VOID APMakeAllTimFrame(RTMP_ADAPTER *pAd) +{ + INT i; + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) + APMakeBssTimFrame(pAd, i); +} + +INT wdev_tim_buf_init(RTMP_ADAPTER *pAd, TIM_BUF_STRUC *tim_info) +{ + INT ret; + + /* tim_info->TimBufIdx = HW_BEACON_MAX_NUM; */ + if (!tim_info->TimPkt) { + ret = RTMPAllocateNdisPacket(pAd, &tim_info->TimPkt, NULL, 0, NULL, MAX_TIM_SIZE); + if (ret != NDIS_STATUS_SUCCESS) + return FALSE; + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s():TimPkt is allocated!\n", __func__)); + } + + tim_info->bTimSntReq = TRUE; + return TRUE; +} + + +#endif /* MT_MAC */ diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_qload.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_qload.c new file mode 100644 index 000000000..ee4957c8b --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_qload.c @@ -0,0 +1,926 @@ +/**************************************************************************** + * 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 + +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; + +}; + +#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) +{ + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + struct wifi_dev *wdev; + UCHAR i; + UCHAR op_ht_bw; + UCHAR op_ext_cha; +#endif /*DOT11N_DRAFT3*/ +#endif /*DOT11_N_SUPPORT*/ + /* suspend alarm until channel switch */ + QBSS_LoadAlarmSuspend(pAd); + pQloadCtrl->QloadAlarmNumber++; + /* check if we have already been 20M bandwidth */ +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + wdev = &pAd->ApCfg.MBSSID[i].wdev; + op_ext_cha = wlan_operate_get_ext_cha(wdev); + op_ht_bw = wlan_operate_get_ht_bw(wdev); + + if ((op_ext_cha != 0) && + (op_ht_bw != HT_BW_20)) { + MAC_TABLE *pMacTable; + UINT32 StaId; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("qbss> Alarm! Change to 20 bw...\n")); + /* disassociate stations without D3 2040Coexistence function */ + pMacTable = &pAd->MacTab; + + /*TODO: Carter, check StaId why start from 1.*/ + + for (StaId = 1; VALID_UCAST_ENTRY_WCID(pAd, StaId); StaId++) { + MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[StaId]; + BOOLEAN bDisconnectSta = FALSE; + + if (!IS_ENTRY_CLIENT(pEntry)) + continue; + + if (pEntry->Sst != SST_ASSOC) + continue; + + if (pEntry->BSS2040CoexistenceMgmtSupport) + bDisconnectSta = TRUE; + + if (bDisconnectSta) { + /* send wireless event - for ageout */ + RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0); + { + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + HEADER_802_11 DeAuthHdr; + USHORT Reason; + /* send out a DISASSOC request frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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->func_tb_idx].wdev.if_addr, + pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DeAuthHdr, + 2, &Reason, + END_OF_ARGS); + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pOutBuffer); + } + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("qbss> Alarm! Deauth the station %02x:%02x:%02x:%02x:%02x:%02x\n", + PRINT_MAC(pEntry->Addr))); + mac_entry_delete(pAd, pEntry); + continue; + } + } + + /* for 11n */ + wlan_operate_set_ht_bw(wdev, HT_BW_20, EXTCHA_NONE); + /* mark alarm flag */ + pQloadCtrl->FlgQloadAlarm = TRUE; + QBSS_LoadAlarmResume(pAd); + } else +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ + { + /* we are in 20MHz bandwidth so try to switch channel */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("qbss> Alarm! Switch channel...\n")); + /* send command to switch channel */ + RTEnqueueInternalCmd(pAd, CMDTHREAD_CHAN_RESCAN, (VOID *)&i, sizeof(UCHAR)); + } + } +} + + +/* +======================================================================== +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) +{ + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + pQloadCtrl->QloadBusyTimeThreshold = TimePeriod; + pQloadCtrl->QloadBusyTimeThreshold *= pQloadCtrl->QloadAlarmBusyTimeThreshold; + pQloadCtrl->QloadBusyTimeThreshold /= 100; + pQloadCtrl->QloadBusyTimeThreshold <<= 10; /* translate mini-sec to micro-sec */ +} +#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */ + + +/* +======================================================================== +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(RTMP_ADAPTER *pAd) +{ + UINT32 IdBss; + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + /* check whether any BSS enables WMM feature */ + for (IdBss = 0; IdBss < pAd->ApCfg.BssidNum; IdBss++) { + if ((pAd->ApCfg.MBSSID[IdBss].wdev.bWmmCapable) +#ifdef DOT11K_RRM_SUPPORT + || (IS_RRM_ENABLE(&pAd->ApCfg.MBSSID[IdBss].wdev)) +#endif /* DOT11K_RRM_SUPPORT */ + ) { + if (pAd->ApCfg.MBSSID[IdBss].wdev.channel > 14) + pQloadCtrl = HcGetQloadCtrlByRf(pAd, RFIC_5GHZ); + else + pQloadCtrl = HcGetQloadCtrlByRf(pAd, RFIC_24GHZ); + if (!pQloadCtrl) + continue; + if (pQloadCtrl->FlgQloadEnable) + continue; + + pQloadCtrl->FlgQloadEnable = TRUE; + /* default value is 50, please reference to IEEE802.11e 2005 Annex D */ + /* pQloadCtrl->QloadChanUtilBeaconInt = 50; */ + pQloadCtrl->QloadChanUtilBeaconInt = 5; + + AsicSetChBusyStat(pAd, pQloadCtrl->FlgQloadEnable); + + pQloadCtrl->QloadChanUtilTotal = 0; + pQloadCtrl->QloadUpTimeLast = 0; + +#ifdef QLOAD_FUNC_BUSY_TIME_STATS + /* clear busy time statistics */ + NdisZeroMemory(pQloadCtrl->QloadBusyCountPri, sizeof(pQloadCtrl->QloadBusyCountPri)); + NdisZeroMemory(pQloadCtrl->QloadBusyCountSec, sizeof(pQloadCtrl->QloadBusyCountSec)); +#endif /* QLOAD_FUNC_BUSY_TIME_STATS */ + +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + /* init threshold before QBSS_LoadAlarmReset */ + pQloadCtrl->QloadAlarmBusyTimeThreshold = QBSS_LOAD_ALRAM_BUSY_TIME_THRESHOLD; + pQloadCtrl->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 + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + pQloadCtrl->FlgQloadAlarm = FALSE; + pQloadCtrl->QloadAlarmDuration = 0; + pQloadCtrl->QloadAlarmNumber = 0; + pQloadCtrl->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 + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + pQloadCtrl->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 + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + pQloadCtrl->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) +{ + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + if (pQloadCtrl->QloadChanUtilBeaconCnt == 0) + return pQloadCtrl->QloadChanUtilTotal; + + return (pQloadCtrl->QloadChanUtilTotal / pQloadCtrl->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 + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + BOOLEAN FlgQloadAlarm = pQloadCtrl->FlgQloadAlarm; + + pQloadCtrl->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 + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + if (pQloadCtrl->QloadAlarmBusyTimeThreshold == 0) + return TRUE; /* always ok */ + + if (BusyTime >= pQloadCtrl->QloadBusyTimeThreshold) + return FALSE; + +#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */ + return TRUE; +} + +#ifdef CONFIG_HOTSPOT_R2 +UINT32 QBSS_LoadElementAppend_HSTEST( + IN RTMP_ADAPTER *pAd, + OUT UINT8 *pBeaconBuf, + IN UCHAR apidx) +{ + struct _ELM_QBSS_LOAD load, *pLoad = &load; + ULONG ElmLen; + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + /* check whether channel busy time calculation is enabled */ + if (pQloadCtrl->FlgQloadEnable == 0) + return 0; + + /* End of if */ + /* init */ + pLoad->ElementId = ELM_QBSS_LOAD_ID; + pLoad->Length = ELM_QBSS_LOAD_LEN; + pLoad->StationCount = le2cpu16(pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.QLoadStaCnt); + pLoad->ChanUtil = pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.QLoadCU; + /* because no ACM is supported, the available bandwidth is 1 sec */ + pLoad->AvalAdmCap = le2cpu16(0xffff); /* 0x7a12 * 32us = 1 second */ + /* copy the element to the frame */ + MakeOutgoingFrame(pBeaconBuf, &ElmLen, + sizeof(struct _ELM_QBSS_LOAD), pLoad, + END_OF_ARGS); + return ElmLen; +} /* End of QBSS_LoadElementAppend */ +#endif + +/* +======================================================================== +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(RTMP_ADAPTER *pAd, UINT8 *pBeaconBuf, QLOAD_CTRL *pQloadCtrl) +{ + struct _ELM_QBSS_LOAD load, *pLoad = &load; + ULONG ElmLen; + + /* check whether channel busy time calculation is enabled */ + if (pQloadCtrl->FlgQloadEnable == 0) + return 0; + + /* init */ + pLoad->ElementId = ELM_QBSS_LOAD_ID; + pLoad->Length = ELM_QBSS_LOAD_LEN; + pLoad->StationCount = le2cpu16(MacTableAssocStaNumGet(pAd)); + pLoad->ChanUtil = pQloadCtrl->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(struct _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 */ + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + UINT8 UpdateBands = 1, i = 0; + + UpdateBands = (pAd->CommonCfg.dbdc_mode == 0)?1:2; + + for (i = 0; i < UpdateBands; i++) { + if (pAd->CommonCfg.dbdc_mode != 0) { + UCHAR PhyMode = HcGetRadioPhyModeByBandIdx(pAd, i); + UINT32 RfIC = (WMODE_CAP_5G(PhyMode)) ? RFIC_5GHZ : RFIC_24GHZ; + pQloadCtrl = HcGetQloadCtrlByRf(pAd, RfIC); + if (!pQloadCtrl) + continue; + } + + /* check whether channel busy time calculation is enabled */ + if ((pQloadCtrl->FlgQloadEnable == 0) || + (pQloadCtrl->FlgQloadAlarmIsSuspended == TRUE)) + continue; + + /* calculate new time period if needed */ + if ((UpTime > 0) && + (pQloadCtrl->QloadUpTimeLast > 0) && + (UpTime > pQloadCtrl->QloadUpTimeLast)) { + /* re-calculate time period */ + TimePeriod = (UINT32)(UpTime - pQloadCtrl->QloadUpTimeLast); + /* translate to mini-second */ + TimePeriod = (TimePeriod*1000)/OS_HZ; +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + + /* re-calculate QloadBusyTimeThreshold */ + if (TimePeriod != pQloadCtrl->QloadTimePeriodLast) + QBSS_LoadAlarmBusyTimeThresholdReset(pAd, TimePeriod); + + pQloadCtrl->QloadTimePeriodLast = TimePeriod; +#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */ + } + + /* update up time */ + pQloadCtrl->QloadUpTimeLast = UpTime; + /* do busy time statistics */ +#ifdef DOT11_N_SUPPORT + { + struct freq_oper oper; + + if (hc_radio_query_by_index(pAd, i, &oper) != HC_STATUS_OK) + continue; + + if ((oper.ext_cha != 0) && + (oper.ht_bw != 0)) { + /* in 20MHz, no need to check busy time of secondary channel */ + BusyTime = AsicGetChBusyCnt(pAd, 1); + pQloadCtrl->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; + + pQloadCtrl->QloadBusyCountSec[BusyTimeId]++; +#endif /* QLOAD_FUNC_BUSY_TIME_STATS */ +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + + if ((pQloadCtrl->FlgQloadAlarmIsSuspended == FALSE) && + (pQloadCtrl->QloadAlarmBusyTimeThreshold > 0)) { + /* Alarm is not suspended and is enabled */ + if ((pQloadCtrl->QloadBusyTimeThreshold != 0) && + (BusyTime >= pQloadCtrl->QloadBusyTimeThreshold)) + FlgIsBusyOverThreshold = TRUE; + } + +#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */ + } + } + +#endif /* DOT11_N_SUPPORT */ + /* do busy time statistics for primary channel */ + /* BusyTime = AsicGetChBusyCnt(pAd, 0); */ + /* update BusyTime from OneSecMibBucket[i] */ + BusyTime = pAd->OneSecMibBucket.ChannelBusyTime[i]; + pQloadCtrl->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; + + pQloadCtrl->QloadBusyCountPri[BusyTimeId]++; +#endif /* QLOAD_FUNC_BUSY_TIME_STATS */ +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + + if ((pQloadCtrl->FlgQloadAlarmIsSuspended == FALSE) && + (pQloadCtrl->QloadAlarmBusyTimeThreshold > 0)) { + /* Alarm is not suspended and is enabled */ + if ((pQloadCtrl->QloadBusyTimeThreshold != 0) && + (BusyTime >= pQloadCtrl->QloadBusyTimeThreshold)) + FlgIsBusyOverThreshold = TRUE; + } + +#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */ + /* accumulate channel busy time for primary channel */ + pQloadCtrl->QloadChanUtilTotal += BusyTime; + + /* update new channel utilization for primary channel */ + if (++pQloadCtrl->QloadChanUtilBeaconCnt >= pQloadCtrl->QloadChanUtilBeaconInt) { + ChanUtilNu = pQloadCtrl->QloadChanUtilTotal; + ChanUtilNu *= 255; + ChanUtilDe = pQloadCtrl->QloadChanUtilBeaconInt; + ChanUtilDe *= 1000000; /* sec to us */ + pQloadCtrl->QloadChanUtil = (UINT8)(ChanUtilNu/ChanUtilDe); + + if ((ChanUtilNu/ChanUtilDe) >= 255) + pQloadCtrl->QloadChanUtil = 255; + + /* re-accumulate channel busy time */ + pQloadCtrl->QloadChanUtilBeaconCnt = 0; + pQloadCtrl->QloadChanUtilTotal = 0; + } + +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + + /* check if alarm function is enabled */ + if ((pQloadCtrl->FlgQloadAlarmIsSuspended == FALSE) && + (pQloadCtrl->QloadAlarmBusyTimeThreshold > 0)) { + /* Alarm is not suspended and is enabled */ + + /* check if we need to issue a alarm */ + if (FlgIsBusyOverThreshold == TRUE) { + if (pQloadCtrl->QloadAlarmDuration == 0) { + /* last alarm ended so we can check new alarm */ + pQloadCtrl->QloadAlarmBusyNum++; + + if (pQloadCtrl->QloadAlarmBusyNum >= pQloadCtrl->QloadAlarmBusyNumThreshold) { + /* + The continued number of busy time >= threshold is larger + than number threshold so issuing a alarm. + */ + FlgIsAlarmNeeded = TRUE; + pQloadCtrl->QloadAlarmDuration++; + } + } + } else + pQloadCtrl->QloadAlarmBusyNum = 0; + + if (pQloadCtrl->QloadAlarmDuration > 0) { + /* + New alarm occurs so we can not re-issue new alarm during + QBSS_LOAD_ALARM_DURATION * TBTT. + */ + if (++pQloadCtrl->QloadAlarmDuration >= QBSS_LOAD_ALARM_DURATION) { + /* can re-issue next alarm */ + pQloadCtrl->QloadAlarmDuration = 0; + pQloadCtrl->QloadAlarmBusyNum = 0; + } + } + + if (FlgIsAlarmNeeded == TRUE) + QBSS_LoadAlarm(pAd); + } else { + /* clear statistics counts */ + pQloadCtrl->QloadAlarmBusyNum = 0; + pQloadCtrl->QloadAlarmDuration = 0; + pQloadCtrl->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, + IN UCHAR Channel) +{ + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + if (pAd->CommonCfg.dbdc_mode == 0) + pQloadCtrl = HcGetQloadCtrl(pAd); + else + pQloadCtrl = (Channel > 14) ? HcGetQloadCtrlByRf(pAd, RFIC_5GHZ) : HcGetQloadCtrlByRf(pAd, RFIC_24GHZ); + + if (pQloadCtrl) { +#ifdef QLOAD_FUNC_BUSY_TIME_STATS + /* clear busy time statistics */ + NdisZeroMemory(pQloadCtrl->QloadBusyCountPri, sizeof(pQloadCtrl->QloadBusyCountPri)); + NdisZeroMemory(pQloadCtrl->QloadBusyCountSec, sizeof(pQloadCtrl->QloadBusyCountSec)); +#endif /* QLOAD_FUNC_BUSY_TIME_STATS */ +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + /* clear alarm function variables */ + pQloadCtrl->QloadChanUtilTotal = 0; + pQloadCtrl->FlgQloadAlarm = FALSE; + pQloadCtrl->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(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ +#ifdef QLOAD_FUNC_BUSY_TIME_STATS + UINT32 BusyTimeId; + UINT32 Time; + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + Time = pAd->CommonCfg.BeaconPeriod / QLOAD_BUSY_INTERVALS; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n\tPrimary Busy Time\tTimes\n")); + + for (BusyTimeId = 0; BusyTimeId < QLOAD_BUSY_INTERVALS; BusyTimeId++) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t%dms ~ %dms\t\t%d\n", + BusyTimeId*Time, + (BusyTimeId+1)*Time, + pQloadCtrl->QloadBusyCountPri[BusyTimeId])); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n\tSecondary Busy Time\tTimes\n")); + + for (BusyTimeId = 0; BusyTimeId < QLOAD_BUSY_INTERVALS; BusyTimeId++) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\t%dms ~ %dms\t\t%d\n", + BusyTimeId*Time, + (BusyTimeId+1)*Time, + pQloadCtrl->QloadBusyCountSec[BusyTimeId])); + } + +#else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\tBusy time statistics is not included into the driver!\n")); +#endif /* QLOAD_FUNC_BUSY_TIME_STATS */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\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(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + QBSS_LoadStatusClear(pAd, 1); + QBSS_LoadStatusClear(pAd, 36); + 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(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + pQloadCtrl->QloadAlarmBusyTimeThreshold = (UCHAR)os_str_tol(Arg, 0, 10); + QBSS_LoadAlarmReset(pAd); + pQloadCtrl->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(RTMP_ADAPTER *pAd, RTMP_STRING *Arg) +{ +#ifdef QLOAD_FUNC_BUSY_TIME_ALARM + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); + + pQloadCtrl->QloadAlarmBusyNumThreshold = (UCHAR)os_str_tol(Arg, 0, 10); +#endif /* QLOAD_FUNC_BUSY_TIME_ALARM */ + return TRUE; +} + +#endif /* AP_QLOAD_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_repeater.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_repeater.c new file mode 100644 index 000000000..3cbc51bed --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_repeater.c @@ -0,0 +1,1354 @@ +/* + *************************************************************************** + * Ralink Tech Inc. + * 4F, No. 2 Technology 5th Rd. + * Science-based Industrial Park + * Hsin-chu, Taiwan, R.O.C. + * + * (c) Copyright 2002-2012, Ralink Technology, Inc. + * + * All rights reserved. Ralink's source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of Ralink Tech. Any attemp + * or participation in deciphering, decoding, reverse engineering 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_repeater.c + + Abstract: + Support MAC Repeater function. + + Revision History: + Who When What + -------------- ---------- ---------------------------------------------- + Arvin 11-16-2012 created +*/ + +#ifdef MAC_REPEATER_SUPPORT + +#include "rt_config.h" + +#define OUI_LEN 3 +UCHAR VENDOR_DEFINED_OUI_ADDR[][OUI_LEN] = +#ifdef VENDOR_FEATURE5_SUPPORT +{ {0x02, 0x0F, 0xB5}, + {0x02, 0x09, 0x5B}, + {0x02, 0x14, 0x6C}, + {0x02, 0x18, 0x4D}, + {0x02, 0x1B, 0x2F}, + {0x02, 0x1E, 0x2A} +}; +#else + { +{0x02, 0x0C, 0x43}, +{0x02, 0x0C, 0xE7}, +{0x02, 0x0A, 0x00} + }; +#endif +static UCHAR rept_vendor_def_oui_table_size = (sizeof(VENDOR_DEFINED_OUI_ADDR) / sizeof(UCHAR[OUI_LEN])); + +/* IOCTL */ +INT Show_ReptTable_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + int CliIdx; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + RETURN_ZERO_IF_PAD_NULL(pAd); + + if (!pAd->ApCfg.bMACRepeaterEn) + return TRUE; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("---------------------------------\n")); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("--------pRepeaterCliPool --------\n")); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("---------------------------------\n")); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("\n%-3s%-4s%-5s%-4s%-4s%-5s%-6s%-5s%-5s%-5s%-5s%-5s%-19s%-19s%-19s%-19s\n", + "AP", "CLI", "WCID", "En", "Vld", "bEth", "Block", "Conn", "CTRL", "SYNC", "AUTH", "ASSO", "REAL_MAC", "FAKE_MAC", "MUAR_MAC", "MUAR_ROOT")); + + for (CliIdx = 0; CliIdx < GET_MAX_REPEATER_ENTRY_NUM(cap); CliIdx++) { + PREPEATER_CLIENT_ENTRY pReptCliEntry; + + pReptCliEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-3d", pReptCliEntry->MatchApCliIdx)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-4d", pReptCliEntry->MatchLinkIdx)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-5d", pReptCliEntry->MacTabWCID)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-4d", pReptCliEntry->CliEnable)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-4d", pReptCliEntry->CliValid)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-5d", pReptCliEntry->bEthCli)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-6d", pReptCliEntry->bBlockAssoc)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-5d", pReptCliEntry->CliConnectState)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-5lu", pReptCliEntry->CtrlCurrState)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-5lu", pReptCliEntry->SyncCurrState)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-5lu", pReptCliEntry->AuthCurrState)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-5lu", pReptCliEntry->AssocCurrState)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%02X:%02X:%02X:%02X:%02X:%02X ", + pReptCliEntry->OriginalAddress[0], pReptCliEntry->OriginalAddress[1], pReptCliEntry->OriginalAddress[2], + pReptCliEntry->OriginalAddress[3], pReptCliEntry->OriginalAddress[4], pReptCliEntry->OriginalAddress[5])); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%02X:%02X:%02X:%02X:%02X:%02X ", + pReptCliEntry->CurrentAddress[0], pReptCliEntry->CurrentAddress[1], pReptCliEntry->CurrentAddress[2], + pReptCliEntry->CurrentAddress[3], pReptCliEntry->CurrentAddress[4], pReptCliEntry->CurrentAddress[5])); + /* read muar cr MAR0,MAR1 */ + { + /* UINT32 mar_val; */ + RMAC_MAR0_STRUC mar0_val; + RMAC_MAR1_STRUC mar1_val; + + memset(&mar0_val, 0x0, sizeof(mar0_val)); + memset(&mar1_val, 0x0, sizeof(mar1_val)); + mar1_val.field.access_start = 1; + mar1_val.field.multicast_addr_index = pReptCliEntry->MatchLinkIdx*2; + /* Issue a read command */ + HW_IO_WRITE32(pAd, RMAC_MAR1, (UINT32)mar1_val.word); + + /* wait acess complete*/ + do { + HW_IO_READ32(pAd, RMAC_MAR1, (UINT32 *)&mar1_val); + /* delay */ + } while (mar1_val.field.access_start == 1); + + HW_IO_READ32(pAd, RMAC_MAR0, (UINT32 *)&mar0_val); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%02x:%02x:%02x:%02x:%02x:%02x ", + (UINT8)(mar0_val.addr_31_0 & 0x000000ff), + (UINT8)((mar0_val.addr_31_0 & 0x0000ff00) >> 8), + (UINT8)((mar0_val.addr_31_0 & 0x00ff0000) >> 16), + (UINT8)((mar0_val.addr_31_0 & 0xff000000) >> 24), + (UINT8)mar1_val.field.addr_39_32, + (UINT8)mar1_val.field.addr_47_40 + )); + memset(&mar0_val, 0x0, sizeof(mar0_val)); + memset(&mar1_val, 0x0, sizeof(mar1_val)); + mar1_val.field.access_start = 1; + mar1_val.field.multicast_addr_index = pReptCliEntry->MatchLinkIdx*2+1; + /* Issue a read command */ + HW_IO_WRITE32(pAd, RMAC_MAR1, (UINT32)mar1_val.word); + + /* wait acess complete*/ + do { + HW_IO_READ32(pAd, RMAC_MAR1, (UINT32 *)&mar1_val); + /* delay */ + } while (mar1_val.field.access_start == 1); + + HW_IO_READ32(pAd, RMAC_MAR0, (UINT32 *)&mar0_val); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%02x:%02x:%02x:%02x:%02x:%02x\n", + (UINT8)(mar0_val.addr_31_0 & 0x000000ff), + (UINT8)((mar0_val.addr_31_0 & 0x0000ff00) >> 8), + (UINT8)((mar0_val.addr_31_0 & 0x00ff0000) >> 16), + (UINT8)((mar0_val.addr_31_0 & 0xff000000) >> 24), + (UINT8)mar1_val.field.addr_39_32, + (UINT8)mar1_val.field.addr_47_40 + )); + } + } + + return TRUE; +} + +/* End of IOCTL */ + +VOID ApCliAuthTimeoutExt( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + PREPEATER_CLIENT_ENTRY pRepeaterCliEntry = (PREPEATER_CLIENT_ENTRY)FunctionContext; + PRTMP_ADAPTER pAd; + USHORT ifIndex = 0; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("Repeater Cli AUTH - AuthTimeout\n")); + pAd = pRepeaterCliEntry->pAd; + ifIndex = pRepeaterCliEntry->MatchLinkIdx + REPT_MLME_START_IDX; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("(%s) ifIndex = %d, CliIdx = %d !!!\n", + __func__, + pRepeaterCliEntry->MatchApCliIdx, + pRepeaterCliEntry->MatchLinkIdx)); + MlmeEnqueue(pAd, + APCLI_AUTH_STATE_MACHINE, + APCLI_MT2_AUTH_TIMEOUT, + 0, + NULL, + ifIndex); + RTMP_MLME_HANDLER(pAd); +} + +DECLARE_TIMER_FUNCTION(ApCliAuthTimeoutExt); +BUILD_TIMER_FUNCTION(ApCliAuthTimeoutExt); + +/* + ========================================================================== + 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 + ========================================================================== + */ +VOID ApCliAssocTimeoutExt( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + PREPEATER_CLIENT_ENTRY pRepeaterCliEntry = (PREPEATER_CLIENT_ENTRY)FunctionContext; + PRTMP_ADAPTER pAd; + struct wifi_dev *wdev; + USHORT ifIndex = 0; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, ("Repeater Cli ASSOC - enqueue APCLI_MT2_ASSOC_TIMEOUT\n")); + pAd = pRepeaterCliEntry->pAd; + wdev = pRepeaterCliEntry->wdev; + ifIndex = pRepeaterCliEntry->MatchLinkIdx + REPT_MLME_START_IDX; + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, (" (%s) ifIndex = %d, CliIdx = %d !!!\n", + __func__, pRepeaterCliEntry->MatchApCliIdx, pRepeaterCliEntry->MatchLinkIdx)); + MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_ASSOC_TIMEOUT, 0, NULL, ifIndex); + RTMP_MLME_HANDLER(pAd); +} + +DECLARE_TIMER_FUNCTION(ApCliAssocTimeoutExt); +BUILD_TIMER_FUNCTION(ApCliAssocTimeoutExt); + +static VOID ReptCompleteInit(REPEATER_CLIENT_ENTRY *pReptEntry) +{ + RTMP_OS_INIT_COMPLETION(&pReptEntry->free_ack); +} + +static VOID ReptLinkDownComplete(REPEATER_CLIENT_ENTRY *pReptEntry) +{ + RTMP_OS_COMPLETE(&pReptEntry->free_ack); +} + +VOID ReptWaitLinkDown(REPEATER_CLIENT_ENTRY *pReptEntry) +{ + if (pReptEntry->CliEnable && !RTMP_OS_WAIT_FOR_COMPLETION_TIMEOUT(&pReptEntry->free_ack, REPT_WAIT_TIMEOUT)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("(%s) ApCli Rept[%d] can't done.\n", __func__, pReptEntry->MatchLinkIdx)); + } +} + + + +VOID CliLinkMapInit(RTMP_ADAPTER *pAd) +{ + UCHAR MbssIdx; + MBSS_TO_CLI_LINK_MAP_T *pMbssToCliLinkMap; + struct wifi_dev *cli_link_wdev = &pAd->ApCfg.ApCliTab[0].wdev;/* default bind to apcli0 */ + struct wifi_dev *mbss_link_wdev; + int apcli_idx; + + NdisAcquireSpinLock(&pAd->ApCfg.CliLinkMapLock); + + for (MbssIdx = 0; MbssIdx < HW_BEACON_MAX_NUM; MbssIdx++) { + mbss_link_wdev = &pAd->ApCfg.MBSSID[MbssIdx].wdev; + pMbssToCliLinkMap = &pAd->ApCfg.MbssToCliLinkMap[MbssIdx]; + + if (pAd->CommonCfg.dbdc_mode == TRUE) { + for (apcli_idx = 0; apcli_idx < pAd->ApCfg.ApCliNum; apcli_idx++) { + cli_link_wdev = &pAd->ApCfg.ApCliTab[apcli_idx].wdev; + + if (mbss_link_wdev->channel <= 14) { /* 2.4G */ + if (cli_link_wdev->channel <= 14) { /* 2.4G */ + pMbssToCliLinkMap->mbss_wdev = mbss_link_wdev; + pMbssToCliLinkMap->cli_link_wdev = cli_link_wdev; + } + } else { /* 5G */ + if (cli_link_wdev->channel > 14) { + /*5G + 5G dbdc support changes*/ + if (cli_link_wdev->channel == mbss_link_wdev->channel) { + pMbssToCliLinkMap->mbss_wdev = mbss_link_wdev; + pMbssToCliLinkMap->cli_link_wdev = cli_link_wdev; + } + } + } + } + } else { + pMbssToCliLinkMap->mbss_wdev = mbss_link_wdev; + pMbssToCliLinkMap->cli_link_wdev = cli_link_wdev; + } + } + + NdisReleaseSpinLock(&pAd->ApCfg.CliLinkMapLock); +} + +VOID RepeaterCtrlInit(RTMP_ADAPTER *pAd) +{ + RTMP_CHIP_CAP *pChipCap = hc_get_chip_cap(pAd->hdev_ctrl); + UCHAR MaxNumChipRept = GET_MAX_REPEATER_ENTRY_NUM(pChipCap); + UINT32 Ret = FALSE; + UCHAR i; + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + UINT32 PoolMemSize; + + NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); + + if (pAd->ApCfg.bMACRepeaterEn == TRUE) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_WARN, + ("%s, wrong State\n", __func__)); + return; + } + + PoolMemSize = sizeof(REPEATER_CLIENT_ENTRY) * MaxNumChipRept; + Ret = os_alloc_mem(NULL, + (UCHAR **)&pAd->ApCfg.pRepeaterCliPool, + PoolMemSize); + + if (Ret != NDIS_STATUS_SUCCESS) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + (" Alloc memory for pRepeaterCliPool failed.\n")); + return; + } + + os_zero_mem(pAd->ApCfg.pRepeaterCliPool, PoolMemSize); + PoolMemSize = sizeof(REPEATER_CLIENT_ENTRY_MAP) * MaxNumChipRept; + Ret = os_alloc_mem(NULL, + (UCHAR **)&pAd->ApCfg.pRepeaterCliMapPool, + PoolMemSize); + + if (Ret != NDIS_STATUS_SUCCESS) { + if (pAd->ApCfg.pRepeaterCliPool) + os_free_mem(pAd->ApCfg.pRepeaterCliPool); + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + (" Alloc memory for pRepeaterCliMapPool failed.\n")); + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + return; + } + + os_zero_mem(pAd->ApCfg.pRepeaterCliMapPool, PoolMemSize); + + /*initialize RepeaterEntryPool*/ + for (i = 0; i < MaxNumChipRept; i++) { + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[i]; + pReptEntry->CliConnectState = REPT_ENTRY_DISCONNT; + pReptEntry->CliEnable = FALSE; + pReptEntry->CliValid = FALSE; + pReptEntry->bEthCli = FALSE; + pReptEntry->pAd = pAd; + pReptEntry->MatchApCliIdx = 0; + pReptEntry->MatchLinkIdx = i; + pReptEntry->AuthCurrState = APCLI_CTRL_DISCONNECTED; + pReptEntry->AssocCurrState = APCLI_ASSOC_IDLE; + pReptEntry->bss_info_argument.ucBssIndex = 0xff; + pReptEntry->AuthCurrState = APCLI_AUTH_REQ_IDLE; + ReptCompleteInit(pReptEntry); + /* RTMPInitTimer(pAd, */ + /* &pReptEntry->ApCliAssocTimer, */ + /* GET_TIMER_FUNCTION(ApCliAssocTimeoutExt), */ + /* pReptEntry, FALSE); */ + /* */ + /* RTMPInitTimer(pAd, &pReptEntry->ApCliAuthTimer, */ + /* GET_TIMER_FUNCTION(ApCliAuthTimeoutExt), pReptEntry, FALSE); */ + } + + pAd->ApCfg.RepeaterCliSize = 0; + os_zero_mem(&pAd->ApCfg.ReptControl, sizeof(REPEATER_CTRL_STRUCT)); + pAd->ApCfg.bMACRepeaterEn = TRUE; + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); +} + +VOID RepeaterCtrlExit(RTMP_ADAPTER *pAd) +{ + /* TODO: check whole repeater control release. */ + int wait_cnt = 0; + /* + Add MacRepeater Entry De-Init Here, and let "iwpriv ra0 set MACRepeaterEn=0" + can do this instead of "iwpriv apcli0 set ApCliEnable=0" + */ + UCHAR CliIdx; + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + if (pAd->ApCfg.bMACRepeaterEn) { + for (CliIdx = 0; CliIdx < GET_MAX_REPEATER_ENTRY_NUM(cap); CliIdx++) { + pReptEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + /*disconnect the ReptEntry which is bind on the CliLink*/ + if (pReptEntry->CliEnable) { + RTMP_OS_INIT_COMPLETION(&pReptEntry->free_ack); + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_APCLI_IF_DOWN; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + ReptWaitLinkDown(pReptEntry); + } + } + } + + while (pAd->ApCfg.RepeaterCliSize > 0) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_OFF, + ("%s, wait entry to be deleted\n", __func__)); + OS_WAIT(10); + wait_cnt++; + + if (wait_cnt > 1000) + break; + } + + NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); + + if (pAd->ApCfg.bMACRepeaterEn == FALSE) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_WARN, + ("%s, wrong State\n", __func__)); + return; + } + + pAd->ApCfg.bMACRepeaterEn = FALSE; + + if (pAd->ApCfg.pRepeaterCliMapPool != NULL) { + os_free_mem(pAd->ApCfg.pRepeaterCliMapPool); + pAd->ApCfg.pRepeaterCliMapPool = NULL; + } + + if (pAd->ApCfg.pRepeaterCliPool != NULL) { + os_free_mem(pAd->ApCfg.pRepeaterCliPool); + pAd->ApCfg.pRepeaterCliPool = NULL; + } + + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); +} + +REPEATER_CLIENT_ENTRY *RTMPLookupRepeaterCliEntry( + IN PVOID pData, + IN BOOLEAN bRealMAC, + IN PUCHAR pAddr, + IN BOOLEAN bIsPad) +{ + ULONG HashIdx; + UCHAR tempMAC[6]; + REPEATER_CLIENT_ENTRY *pEntry = NULL; + REPEATER_CLIENT_ENTRY_MAP *pMapEntry = NULL; + + COPY_MAC_ADDR(tempMAC, pAddr); + HashIdx = MAC_ADDR_HASH_INDEX(tempMAC); + + /* NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); */ + if (bIsPad == TRUE) + NdisAcquireSpinLock(&((PRTMP_ADAPTER)pData)->ApCfg.ReptCliEntryLock); + else + NdisAcquireSpinLock(((REPEATER_ADAPTER_DATA_TABLE *)pData)->EntryLock); + + if (bRealMAC == TRUE) { + if (bIsPad == TRUE) + pMapEntry = ((PRTMP_ADAPTER)pData)->ApCfg.ReptMapHash[HashIdx]; + else + pMapEntry = (REPEATER_CLIENT_ENTRY_MAP *)(*((((REPEATER_ADAPTER_DATA_TABLE *)pData)->MapHash) + + HashIdx)); + + while (pMapEntry) { + pEntry = pMapEntry->pReptCliEntry; + + if (pEntry) { + if (pEntry->CliEnable && MAC_ADDR_EQUAL(pEntry->OriginalAddress, tempMAC)) + break; + pEntry = NULL; + pMapEntry = pMapEntry->pNext; + } else + pMapEntry = pMapEntry->pNext; + } + } else { + if (bIsPad == TRUE) + pEntry = ((PRTMP_ADAPTER)pData)->ApCfg.ReptCliHash[HashIdx]; + else + pEntry = (REPEATER_CLIENT_ENTRY *)(*((((REPEATER_ADAPTER_DATA_TABLE *)pData)->CliHash) + + HashIdx)); + + while (pEntry) { + if (pEntry->CliEnable && MAC_ADDR_EQUAL(pEntry->CurrentAddress, tempMAC)) + break; + pEntry = pEntry->pNext; + } + } + + /* NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); */ + if (bIsPad == TRUE) + NdisReleaseSpinLock(&((PRTMP_ADAPTER)pData)->ApCfg.ReptCliEntryLock); + else + NdisReleaseSpinLock(((REPEATER_ADAPTER_DATA_TABLE *)pData)->EntryLock); + + return pEntry; +} + +BOOLEAN RTMPQueryLookupRepeaterCliEntryMT( + IN PVOID pData, + IN PUCHAR pAddr, + IN BOOLEAN bIsPad) +{ + REPEATER_CLIENT_ENTRY *pEntry = NULL; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_INFO, + ("%s:: %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, + pAddr[0], + pAddr[1], + pAddr[2], + pAddr[3], + pAddr[4], + pAddr[5])); + pEntry = RTMPLookupRepeaterCliEntry(pData, FALSE, pAddr, bIsPad); + + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_INFO, + ("%s:: not the repeater client\n", __func__)); + return FALSE; + } + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_INFO, + ("%s:: is the repeater client\n", __func__)); + return TRUE; +} + +REPEATER_CLIENT_ENTRY *lookup_rept_entry(RTMP_ADAPTER *pAd, PUCHAR address) +{ + REPEATER_CLIENT_ENTRY *rept_entry = NULL; + + rept_entry = RTMPLookupRepeaterCliEntry( + pAd, + FALSE, + address, + TRUE); + + if (!rept_entry) + rept_entry = RTMPLookupRepeaterCliEntry( + pAd, + TRUE, + address, + TRUE); + + if (rept_entry) + return rept_entry; + + return NULL; +} + +UINT32 ReptTxPktCheckHandler( + RTMP_ADAPTER *pAd, + IN struct wifi_dev *cli_link_wdev, + IN PNDIS_PACKET pPacket, + OUT UCHAR *pWcid) +{ + PUCHAR pSrcBufVA = NULL; + PACKET_INFO PacketInfo; + UINT SrcBufLen; + STA_TR_ENTRY *tr_entry; + REPEATER_CLIENT_ENTRY *pReptEntry = NULL; + APCLI_STRUCT *pApCliEntry = cli_link_wdev->func_dev; + MAC_TABLE_ENTRY *pMacEntry = NULL; + struct wifi_dev *mbss_wdev = NULL; + MBSS_TO_CLI_LINK_MAP_T *pMbssToCliLinkMap = NULL; + UINT16 eth_type; +#ifdef WSC_AP_SUPPORT + PWSC_CTRL wsc_control = NULL; + + wsc_control = &cli_link_wdev->WscControl; +#endif /* WSC_AP_SUPPORT */ + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + eth_type = (pSrcBufVA[12] << 8) | pSrcBufVA[13]; + + pReptEntry = RTMPLookupRepeaterCliEntry( + pAd, + TRUE, + (pSrcBufVA + MAC_ADDR_LEN), + TRUE); + + if (pReptEntry && pReptEntry->CliValid) { +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + + if ((pReptEntry->MatchApCliIdx != pApCliEntry->ifIndex) && + (wf_drv_tbl.wf_fwd_check_active_hook && wf_drv_tbl.wf_fwd_check_active_hook())) { + UCHAR apCliIdx, CliIdx; + + apCliIdx = pReptEntry->MatchApCliIdx; + CliIdx = pReptEntry->MatchLinkIdx; + pReptEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_CHANGE_APCLI_IF; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + 0, + NULL, + (REPT_MLME_START_IDX + CliIdx)); + RTMP_MLME_HANDLER(pAd); + return INSERT_REPT_ENTRY; + } + +#endif /* CONFIG_WIFI_PKT_FWD */ + *pWcid = pReptEntry->MacTabWCID; + return REPEATER_ENTRY_EXIST; + } + /* check SA valid. */ + if (RTMPRepeaterVaildMacEntry(pAd, pSrcBufVA + MAC_ADDR_LEN)) { + tr_entry = &pAd->MacTab.tr_entry[pApCliEntry->MacTabWCID]; + + if ((tr_entry) && + (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) { + pMacEntry = MacTableLookup(pAd, (pSrcBufVA + MAC_ADDR_LEN)); + + if (eth_type == ETH_TYPE_EAPOL) + return INSERT_REPT_ENTRY_AND_ALLOW; + + if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) { + STA_TR_ENTRY *sta_tr_entry; + + sta_tr_entry = &pAd->MacTab.tr_entry[pMacEntry->wcid]; + + if ((sta_tr_entry) && + (sta_tr_entry->PortSecured != WPA_802_1X_PORT_SECURED)) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + (" wireless client is not ready !!!\n")); + return INSERT_REPT_ENTRY; + } + + mbss_wdev = pMacEntry->wdev; + pMbssToCliLinkMap = &pAd->ApCfg.MbssToCliLinkMap[mbss_wdev->func_idx]; + + if ( +#if defined(CONFIG_WIFI_PKT_FWD) || defined(CONFIG_WIFI_PKT_FWD_MODULE) + (wf_drv_tbl.wf_fwd_check_active_hook && wf_drv_tbl.wf_fwd_check_active_hook()) || +#endif /* CONFIG_WIFI_PKT_FWD */ + (pMbssToCliLinkMap->cli_link_wdev == cli_link_wdev)) { +#ifdef WSC_AP_SUPPORT + if (!((wsc_control->WscConfMode != WSC_DISABLE) && + (wsc_control->bWscTrigger == TRUE))) { +#endif /* WSC_AP_SUPPORT */ + HW_ADD_REPT_ENTRY(pAd, cli_link_wdev, (pSrcBufVA + MAC_ADDR_LEN)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("pMacEntry connect to mbss idx:%d, use CliLink:%d to RootAP\n", + mbss_wdev->func_idx, cli_link_wdev->func_idx)); + return INSERT_REPT_ENTRY; +#ifdef WSC_AP_SUPPORT + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%s() WPS is triggered now, don't add entry\n", + __func__)); + } +#endif /* WSC_AP_SUPPORT */ + } + } else + /*SA is not in mac table, pkt should from upper layer or eth.*/ + { + /* +TODO: Carter, if more than one apcli/sta, +the eth pkt or upper layer pkt connecting rule should be refined. +*/ +#ifdef WSC_AP_SUPPORT + if (!((wsc_control->WscConfMode != WSC_DISABLE) && + (wsc_control->bWscTrigger == TRUE))) { +#endif /* WSC_AP_SUPPORT */ + HW_ADD_REPT_ENTRY(pAd, cli_link_wdev, (pSrcBufVA + MAC_ADDR_LEN)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("pAddr %x %x %x %x %x %x: use CliLink:%d to RootAP\n", + PRINT_MAC((pSrcBufVA + MAC_ADDR_LEN)), + cli_link_wdev->func_idx)); + + return INSERT_REPT_ENTRY; +#ifdef WSC_AP_SUPPORT + } else { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%s() WPS is triggered now, don't add entry\n", + __func__)); + } +#endif /* WSC_AP_SUPPORT */ + } + } + } + + return USE_CLI_LINK_INFO; +} + +VOID RTMPInsertRepeaterEntry( + PRTMP_ADAPTER pAd, + struct wifi_dev *wdev, + PUCHAR pAddr) +{ + INT CliIdx, idx; + UCHAR HashIdx; + /* BOOLEAN Cancelled; */ + UCHAR tempMAC[MAC_ADDR_LEN]; + APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; + PREPEATER_CLIENT_ENTRY pReptCliEntry = NULL, pCurrEntry = NULL; + INT pValid_ReptCliIdx; + PREPEATER_CLIENT_ENTRY_MAP pReptCliMap; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%s.\n", __func__)); + NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); + + if (pAd->ApCfg.RepeaterCliSize >= GET_MAX_REPEATER_ENTRY_NUM(cap)) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + (" Repeater Client Full !!!\n")); + return; + } + + pValid_ReptCliIdx = GET_MAX_REPEATER_ENTRY_NUM(cap); + + for (CliIdx = 0; CliIdx < GET_MAX_REPEATER_ENTRY_NUM(cap); CliIdx++) { + pReptCliEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + if ((pReptCliEntry->CliEnable) && + (MAC_ADDR_EQUAL(pReptCliEntry->OriginalAddress, pAddr) || + MAC_ADDR_EQUAL(pReptCliEntry->CurrentAddress, pAddr)) + ) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_INFO, + ("\n receive mac :%02x:%02x:%02x:%02x:%02x:%02x !!!\n", + PRINT_MAC(pAddr))); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_INFO, + (" duplicate Insert !!!\n")); + return; + } + + if ((pReptCliEntry->CliEnable == FALSE) && (pValid_ReptCliIdx == GET_MAX_REPEATER_ENTRY_NUM(cap))) + pValid_ReptCliIdx = CliIdx; + } + + CliIdx = pValid_ReptCliIdx; + + if (CliIdx >= GET_MAX_REPEATER_ENTRY_NUM(cap)) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("Repeater Pool Full !!!\n")); + return; + } + + pReptCliEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + pReptCliMap = &pAd->ApCfg.pRepeaterCliMapPool[CliIdx]; + /* ENTRY PREEMPTION: initialize the entry */ + /* timer init */ + RTMPInitTimer(pAd, + &pReptCliEntry->ApCliAssocTimer, + GET_TIMER_FUNCTION(ApCliAssocTimeoutExt), + pReptCliEntry, FALSE); + /* timer init */ + RTMPInitTimer(pAd, &pReptCliEntry->ApCliAuthTimer, + GET_TIMER_FUNCTION(ApCliAuthTimeoutExt), pReptCliEntry, FALSE); + pReptCliEntry->CtrlCurrState = APCLI_CTRL_DISCONNECTED; + pReptCliEntry->AuthCurrState = APCLI_AUTH_REQ_IDLE; + pReptCliEntry->AssocCurrState = APCLI_ASSOC_IDLE; + pReptCliEntry->CliConnectState = REPT_ENTRY_DISCONNT; + pReptCliEntry->LinkDownReason = APCLI_LINKDOWN_NONE; + pReptCliEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_NONE; + pReptCliEntry->CliValid = FALSE; + pReptCliEntry->bEthCli = FALSE; + pReptCliEntry->MacTabWCID = 0xFF; +#ifdef FAST_EAPOL_WAR + + if (pReptCliEntry->pre_entry_alloc == TRUE) + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Unexpected condition,check it (pReptCliEntry->pre_entry_alloc=%d)\n", __func__, pReptCliEntry->pre_entry_alloc)); + + pReptCliEntry->pre_entry_alloc = FALSE; +#endif /* FAST_EAPOL_WAR */ + pReptCliEntry->AuthReqCnt = 0; + pReptCliEntry->AssocReqCnt = 0; + pReptCliEntry->CliTriggerTime = 0; + pReptCliEntry->pNext = NULL; + pReptCliEntry->wdev = wdev; + pReptCliEntry->MatchApCliIdx = wdev->func_idx; + pReptCliEntry->BandIdx = HcGetBandByWdev(wdev); + pReptCliMap->pReptCliEntry = pReptCliEntry; + pReptCliMap->pNext = NULL; + COPY_MAC_ADDR(pReptCliEntry->OriginalAddress, pAddr); + COPY_MAC_ADDR(tempMAC, pAddr); + + if (pAd->ApCfg.MACRepeaterOuiMode == CASUALLY_DEFINE_MAC_ADDR) { + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("todo !!!\n")); + } else if (pAd->ApCfg.MACRepeaterOuiMode == VENDOR_DEFINED_MAC_ADDR_OUI) { + INT IdxToUse, i; + UCHAR checkMAC[MAC_ADDR_LEN]; + + COPY_MAC_ADDR(checkMAC, pAddr); + + for (idx = 0; idx < rept_vendor_def_oui_table_size; idx++) { + if (RTMPEqualMemory(VENDOR_DEFINED_OUI_ADDR[idx], pAddr, OUI_LEN)) + continue; + else { + NdisCopyMemory(checkMAC, VENDOR_DEFINED_OUI_ADDR[idx], OUI_LEN); + + for (i = 0; i < pAd->ApCfg.BssidNum; i++) { + if (MAC_ADDR_EQUAL(pAd->ApCfg.MBSSID[i].wdev.if_addr, checkMAC)) + break; + } + + if (i >= pAd->ApCfg.BssidNum) + break; + } + } + + /* + If there is a matched one can be used + otherwise, use the first one. + */ + if (idx >= 0 && idx < rept_vendor_def_oui_table_size) + IdxToUse = idx; + else + IdxToUse = 0; + + NdisCopyMemory(tempMAC, VENDOR_DEFINED_OUI_ADDR[IdxToUse], OUI_LEN); + } else + NdisCopyMemory(tempMAC, wdev->if_addr, OUI_LEN); + + COPY_MAC_ADDR(pReptCliEntry->CurrentAddress, tempMAC); + pReptCliEntry->CliEnable = TRUE; + pReptCliEntry->CliConnectState = REPT_ENTRY_CONNTING; + pReptCliEntry->pNext = NULL; + NdisGetSystemUpTime(&pReptCliEntry->CliTriggerTime); + pAd->ApCfg.RepeaterCliSize++; + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + /* Before add into muar table, config Band binding. */ + HcAddRepeaterEntry(wdev, CliIdx); + AsicInsertRepeaterEntry(pAd, CliIdx, tempMAC); + HashIdx = MAC_ADDR_HASH_INDEX(tempMAC); + + if (pAd->ApCfg.ReptCliHash[HashIdx] == NULL) + pAd->ApCfg.ReptCliHash[HashIdx] = pReptCliEntry; + else { + pCurrEntry = pAd->ApCfg.ReptCliHash[HashIdx]; + + while (pCurrEntry->pNext != NULL) + pCurrEntry = pCurrEntry->pNext; + + pCurrEntry->pNext = pReptCliEntry; + } + + HashIdx = MAC_ADDR_HASH_INDEX(pReptCliEntry->OriginalAddress); + + if (pAd->ApCfg.ReptMapHash[HashIdx] == NULL) + pAd->ApCfg.ReptMapHash[HashIdx] = pReptCliMap; + else { + PREPEATER_CLIENT_ENTRY_MAP pCurrMapEntry; + + pCurrMapEntry = pAd->ApCfg.ReptMapHash[HashIdx]; + + while (pCurrMapEntry->pNext != NULL) + pCurrMapEntry = pCurrMapEntry->pNext; + + pCurrMapEntry->pNext = pReptCliMap; + } + + /* + FIXME: + if apcli is removed afterward, + the state machine massage should be reviewed. + */ + NdisZeroMemory(&ApCliCtrlMsg, sizeof(APCLI_CTRL_MSG_STRUCT)); + ApCliCtrlMsg.Status = MLME_SUCCESS; + COPY_MAC_ADDR(&ApCliCtrlMsg.SrcAddr[0], tempMAC); + ApCliCtrlMsg.BssIdx = wdev->func_idx; + ApCliCtrlMsg.CliIdx = CliIdx; + MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_MT2_AUTH_REQ, + sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, wdev->func_idx); + RTMP_MLME_HANDLER(pAd); +} + +VOID RTMPRemoveRepeaterEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR func_tb_idx, + IN UCHAR CliIdx) +{ + USHORT HashIdx; + REPEATER_CLIENT_ENTRY *pEntry, *pPrevEntry, *pProbeEntry; + REPEATER_CLIENT_ENTRY_MAP *pMapEntry, *pPrevMapEntry, *pProbeMapEntry; + BOOLEAN bVaild = TRUE; + BOOLEAN Cancelled; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, (" %s.CliIdx=%d\n", __func__, CliIdx)); + AsicRemoveRepeaterEntry(pAd, CliIdx); + NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); + pEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + /* move NULL check here, to prevent pEntry NULL dereference */ + if (pEntry == NULL) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("%s - pEntry is NULL !!!\n", __func__)); + return; + } + + if (pEntry->CliEnable == FALSE) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + ("%s - CliIdx:%d Enable is FALSE already\n", + __func__, CliIdx)); + return; + } + + /*Release OMAC Idx*/ + HcDelRepeaterEntry(pEntry->wdev, CliIdx); + HashIdx = MAC_ADDR_HASH_INDEX(pEntry->CurrentAddress); + pPrevEntry = NULL; + pProbeEntry = pAd->ApCfg.ReptCliHash[HashIdx]; + ASSERT(pProbeEntry); + + if (pProbeEntry == NULL) { + bVaild = FALSE; + goto done; + } + + if (pProbeEntry != NULL) { + /* update Hash list*/ + do { + if (pProbeEntry == pEntry) { + if (pPrevEntry == NULL) + pAd->ApCfg.ReptCliHash[HashIdx] = pEntry->pNext; + else + pPrevEntry->pNext = pEntry->pNext; + + break; + } + + pPrevEntry = pProbeEntry; + pProbeEntry = pProbeEntry->pNext; + } while (pProbeEntry); + } + + /* not found !!!*/ + ASSERT(pProbeEntry != NULL); + + if (pProbeEntry == NULL) { + bVaild = FALSE; + goto done; + } + + pMapEntry = &pAd->ApCfg.pRepeaterCliMapPool[CliIdx]; + HashIdx = MAC_ADDR_HASH_INDEX(pEntry->OriginalAddress); + pPrevMapEntry = NULL; + pProbeMapEntry = pAd->ApCfg.ReptMapHash[HashIdx]; + ASSERT(pProbeMapEntry); + + if (pProbeMapEntry != NULL) { + /* update Hash list*/ + do { + if (pProbeMapEntry == pMapEntry) { + if (pPrevMapEntry == NULL) + pAd->ApCfg.ReptMapHash[HashIdx] = pMapEntry->pNext; + else + pPrevMapEntry->pNext = pMapEntry->pNext; + + break; + } + + pPrevMapEntry = pProbeMapEntry; + pProbeMapEntry = pProbeMapEntry->pNext; + } while (pProbeMapEntry); + } + + /* not found !!!*/ + ASSERT(pProbeMapEntry != NULL); +done: + RTMPReleaseTimer(&pEntry->ApCliAuthTimer, &Cancelled); + RTMPReleaseTimer(&pEntry->ApCliAssocTimer, &Cancelled); +#ifdef FAST_EAPOL_WAR + + if (pEntry->pre_entry_alloc == TRUE) + MTWF_LOG(DBG_CAT_RX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Unexpected condition,check it (pEntry->pre_entry_alloc=%d)\n", __func__, pEntry->pre_entry_alloc)); + + pEntry->pre_entry_alloc = FALSE; +#endif /* FAST_EAPOL_WAR */ + pEntry->CliConnectState = REPT_ENTRY_DISCONNT; + pEntry->CliValid = FALSE; + pEntry->CliEnable = FALSE; + + if (bVaild == TRUE) + pAd->ApCfg.RepeaterCliSize--; + + ReptLinkDownComplete(pEntry); + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); +} + +VOID RTMPRepeaterReconnectionCheck( + IN PRTMP_ADAPTER pAd) +{ +#ifdef APCLI_AUTO_CONNECT_SUPPORT + INT i; + PCHAR pApCliSsid, pApCliCfgSsid; + UCHAR CfgSsidLen; + NDIS_802_11_SSID Ssid; + ULONG timeDiff[MAX_APCLI_NUM]; + + if (pAd->ApCfg.bMACRepeaterEn && + pAd->ApCfg.MACRepeaterOuiMode == VENDOR_DEFINED_MAC_ADDR_OUI && + pAd->ScanCtrl.PartialScan.bScanning == FALSE) { + for (i = 0; i < MAX_APCLI_NUM; i++) { + if (!APCLI_IF_UP_CHECK(pAd, i) || + (pAd->ApCfg.ApCliTab[i].Enable == FALSE)) + continue; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, (" %s(): i=%d,%d,%d,%d,%d,%d\n", + __func__, (int)i, + (int)ApScanRunning(pAd, &pAd->ApCfg.ApCliTab[i].wdev), + (int)pAd->ApCfg.ApCliAutoConnectRunning[i], + (int)pAd->ApCfg.ApCliAutoConnectType[i], + (int)pAd->ApCfg.bPartialScanEnable[i], + (int)(pAd->Mlme.OneSecPeriodicRound%23))); + + if (ApScanRunning(pAd, &pAd->ApCfg.ApCliTab[i].wdev)) + continue; + if (pAd->ApCfg.ApCliAutoConnectRunning[i] != FALSE) + continue; + if (pAd->ApCfg.ApCliTab[i].AutoConnectFlag == FALSE) + continue; + pApCliSsid = pAd->ApCfg.ApCliTab[i].Ssid; + pApCliCfgSsid = pAd->ApCfg.ApCliTab[i].CfgSsid; + CfgSsidLen = pAd->ApCfg.ApCliTab[i].CfgSsidLen; + + if ((pAd->ApCfg.ApCliTab[i].CtrlCurrState < APCLI_CTRL_AUTH || + !NdisEqualMemory(pApCliSsid, pApCliCfgSsid, CfgSsidLen)) && + pAd->ApCfg.ApCliTab[i].CfgSsidLen > 0) { + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->ApCfg.ApCliIssueScanTime[i])) + timeDiff[i] = (pAd->Mlme.Now32 - pAd->ApCfg.ApCliIssueScanTime[i]); + else + timeDiff[i] = (pAd->ApCfg.ApCliIssueScanTime[i] - pAd->Mlme.Now32); + /* will trigger scan after 23 sec */ + if (timeDiff[i] <= RTMPMsecsToJiffies(23000)) + continue; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, + (" %s(): Scan channels for AP (%s)\n", + __func__, pApCliCfgSsid)); + pAd->ApCfg.ApCliAutoConnectRunning[i] = TRUE; + if (pAd->ApCfg.bPartialScanEnable[i]) { + pAd->ApCfg.bPartialScanning[i] = TRUE; + pAd->ScanCtrl.PartialScan.pwdev = &pAd->ApCfg.ApCliTab[i].wdev; + pAd->ScanCtrl.PartialScan.bScanning = TRUE; + } + Ssid.SsidLength = CfgSsidLen; + NdisCopyMemory(Ssid.Ssid, pApCliCfgSsid, CfgSsidLen); + NdisGetSystemUpTime(&pAd->ApCfg.ApCliIssueScanTime[i]); + ApSiteSurvey_by_wdev(pAd, &Ssid, SCAN_ACTIVE, FALSE, &pAd->ApCfg.ApCliTab[i].wdev); + } + } + } + +#endif /* APCLI_AUTO_CONNECT_SUPPORT */ +} + +BOOLEAN RTMPRepeaterVaildMacEntry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr) +{ + INVAILD_TRIGGER_MAC_ENTRY *pEntry = NULL; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + + if (pAd->ApCfg.RepeaterCliSize >= GET_MAX_REPEATER_ENTRY_NUM(cap)) + return FALSE; + + if (IS_MULTICAST_MAC_ADDR(pAddr)) + return FALSE; + + if (IS_BROADCAST_MAC_ADDR(pAddr)) + return FALSE; + + pEntry = RepeaterInvaildMacLookup(pAd, pAddr); + + if (pEntry) + return FALSE; + else + return TRUE; +} + +INVAILD_TRIGGER_MAC_ENTRY *RepeaterInvaildMacLookup( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr) +{ + ULONG HashIdx; + INVAILD_TRIGGER_MAC_ENTRY *pEntry = NULL; + + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + pEntry = pAd->ApCfg.ReptControl.IgnoreAsRepeaterHash[HashIdx]; + + while (pEntry) { + if (MAC_ADDR_EQUAL(pEntry->MacAddr, pAddr)) + break; + pEntry = pEntry->pNext; + } + + if (pEntry && pEntry->bInsert) + return pEntry; + else + return NULL; +} + +VOID InsertIgnoreAsRepeaterEntryTable( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr) +{ + UCHAR HashIdx, idx = 0; + INVAILD_TRIGGER_MAC_ENTRY *pEntry = NULL; + INVAILD_TRIGGER_MAC_ENTRY *pCurrEntry = NULL; + + if (pAd->ApCfg.ReptControl.IgnoreAsRepeaterEntrySize >= MAX_IGNORE_AS_REPEATER_ENTRY_NUM) + return; + + if (MAC_ADDR_EQUAL(pAddr, ZERO_MAC_ADDR)) + return; + + NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); + + for (idx = 0; idx < MAX_IGNORE_AS_REPEATER_ENTRY_NUM; idx++) { + pEntry = &pAd->ApCfg.ReptControl.IgnoreAsRepeaterEntry[idx]; + + if (MAC_ADDR_EQUAL(pEntry->MacAddr, pAddr)) { + if (pEntry->bInsert) { + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + return; + } + } + + /* pick up the first available vacancy*/ + if (pEntry->bInsert == FALSE) { + NdisZeroMemory(pEntry->MacAddr, MAC_ADDR_LEN); + COPY_MAC_ADDR(pEntry->MacAddr, pAddr); + pEntry->entry_idx = idx; + pEntry->bInsert = TRUE; + break; + } + } + + /* add this entry into HASH table */ + if (pEntry) { + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + pEntry->pNext = NULL; + + if (pAd->ApCfg.ReptControl.IgnoreAsRepeaterHash[HashIdx] == NULL) + pAd->ApCfg.ReptControl.IgnoreAsRepeaterHash[HashIdx] = pEntry; + else { + pCurrEntry = pAd->ApCfg.ReptControl.IgnoreAsRepeaterHash[HashIdx]; + + while (pCurrEntry->pNext != NULL) + pCurrEntry = pCurrEntry->pNext; + + pCurrEntry->pNext = pEntry; + } + } + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_ERROR, (" Store Invaild MacAddr = %02x:%02x:%02x:%02x:%02x:%02x. !!!\n", + PRINT_MAC(pEntry->MacAddr))); + pAd->ApCfg.ReptControl.IgnoreAsRepeaterEntrySize++; + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); +} + +BOOLEAN RepeaterRemoveIngoreEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR idx, + IN PUCHAR pAddr) +{ + USHORT HashIdx; + INVAILD_TRIGGER_MAC_ENTRY *pEntry = NULL; + INVAILD_TRIGGER_MAC_ENTRY *pPrevEntry, *pProbeEntry; + + NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + pEntry = &pAd->ApCfg.ReptControl.IgnoreAsRepeaterEntry[idx]; + + if (pEntry && pEntry->bInsert) { + pPrevEntry = NULL; + pProbeEntry = pAd->ApCfg.ReptControl.IgnoreAsRepeaterHash[HashIdx]; + ASSERT(pProbeEntry); + + if (pProbeEntry != NULL) { + /* update Hash list*/ + do { + if (pProbeEntry == pEntry) { + if (pPrevEntry == NULL) + pAd->ApCfg.ReptControl.IgnoreAsRepeaterHash[HashIdx] = pEntry->pNext; + else + pPrevEntry->pNext = pEntry->pNext; + + break; + } + + pPrevEntry = pProbeEntry; + pProbeEntry = pProbeEntry->pNext; + } while (pProbeEntry); + } + + /* not found !!!*/ + ASSERT(pProbeEntry != NULL); + pAd->ApCfg.ReptControl.IgnoreAsRepeaterEntrySize--; + } + + NdisZeroMemory(pEntry->MacAddr, MAC_ADDR_LEN); + pEntry->bInsert = FALSE; + NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); + return TRUE; +} + +VOID RepeaterLinkMonitor(RTMP_ADAPTER *pAd) +{ + REPEATER_CLIENT_ENTRY *ReptPool = pAd->ApCfg.pRepeaterCliPool; + REPEATER_CLIENT_ENTRY *pReptCliEntry = NULL; + RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); + UCHAR Wcid = 0; + STA_TR_ENTRY *tr_entry = NULL; + APCLI_CTRL_MSG_STRUCT msg; + UCHAR CliIdx; + + if ((pAd->ApCfg.bMACRepeaterEn) && (ReptPool != NULL)) { + for (CliIdx = 0; CliIdx < GET_MAX_REPEATER_ENTRY_NUM(cap); CliIdx++) { + pReptCliEntry = &pAd->ApCfg.pRepeaterCliPool[CliIdx]; + + if (pReptCliEntry->CliEnable) { + Wcid = pReptCliEntry->MacTabWCID; + tr_entry = &pAd->MacTab.tr_entry[Wcid]; + + if ((tr_entry->PortSecured != WPA_802_1X_PORT_SECURED) && + RTMP_TIME_AFTER(pAd->Mlme.Now32, (pReptCliEntry->CliTriggerTime + (5 * OS_HZ)))) { + if (pReptCliEntry->CtrlCurrState == APCLI_CTRL_DISCONNECTED) + HW_REMOVE_REPT_ENTRY(pAd, pReptCliEntry->MatchApCliIdx, CliIdx); + else { + if (!VALID_UCAST_ENTRY_WCID(pAd, Wcid)) + continue; + + pReptCliEntry->Disconnect_Sub_Reason = APCLI_DISCONNECT_SUB_REASON_REPTLM_TRIGGER_TOO_LONG; + NdisZeroMemory(&msg, sizeof(APCLI_CTRL_MSG_STRUCT)); + msg.BssIdx = pReptCliEntry->MatchApCliIdx; + msg.CliIdx = CliIdx; + MlmeEnqueue(pAd, + APCLI_CTRL_STATE_MACHINE, + APCLI_CTRL_DISCONNECT_REQ, + sizeof(APCLI_CTRL_MSG_STRUCT), + &msg, + REPT_MLME_START_IDX + CliIdx); + RTMP_MLME_HANDLER(pAd); + } + } + } + } + } +} + +INT Show_Repeater_Cli_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg) +{ + INT i; + ULONG DataRate = 0; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + struct wifi_dev *wdev = get_wdev_by_ioctl_idx_and_iftype(pAd, pObj->ioctl_if, pObj->ioctl_if_type); + ADD_HT_INFO_IE *addht; + + if (!wdev) + return FALSE; + + addht = wlan_operate_get_addht(wdev); + + if (!pAd->ApCfg.bMACRepeaterEn) + return TRUE; + + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("\n")); +#ifdef DOT11_N_SUPPORT + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("HT Operating Mode : %d\n", addht->AddHtInfo2.OperaionMode)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("\n")); +#endif /* DOT11_N_SUPPORT */ + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("\n%-19s%-4s%-4s%-4s%-4s%-8s%-7s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s%-7s%-7s\n", + "MAC", "AID", "BSS", "PSM", "WMM", "MIMOPS", "RSSI0", "RSSI1", + "RSSI2", "RSSI3", "PhMd", "BW", "MCS", "SGI", "STBC", "Idle", "Rate")); + + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i]; + + if (pEntry && + (IS_ENTRY_APCLI(pEntry) || IS_ENTRY_REPEATER(pEntry)) + && (pEntry->Sst == SST_ASSOC) && (pEntry->bReptCli)) { + DataRate = 0; + getRate(pEntry->HTPhyMode, &DataRate); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%02X:%02X:%02X:%02X:%02X:%02X ", + pEntry->ReptCliAddr[0], pEntry->ReptCliAddr[1], pEntry->ReptCliAddr[2], + pEntry->ReptCliAddr[3], pEntry->ReptCliAddr[4], pEntry->ReptCliAddr[5])); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-4d", (int)pEntry->Aid)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-4d-%d", (int)pEntry->apidx, pEntry->func_tb_idx)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-4d", (int)pEntry->PsMode)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))); +#ifdef DOT11_N_SUPPORT + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-8d", (int)pEntry->MmpsMode)); +#endif /* DOT11_N_SUPPORT */ + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-7d", pEntry->RssiSample.AvgRssi[0])); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-7d", pEntry->RssiSample.AvgRssi[1])); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-7d", pEntry->RssiSample.AvgRssi[2])); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-7d", pEntry->RssiSample.AvgRssi[3])); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-10s", get_phymode_str(pEntry->HTPhyMode.field.MODE))); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-6s", get_bw_str(pEntry->HTPhyMode.field.BW))); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-6d", pEntry->HTPhyMode.field.MCS)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-6d", pEntry->HTPhyMode.field.ShortGI)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-6d", pEntry->HTPhyMode.field.STBC)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-7d", (int)(pEntry->StaIdleTimeout - pEntry->NoDataIdleCount))); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-7d", (int)DataRate)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount, + (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0)); + MTWF_LOG(DBG_CAT_CLIENT, CATCLIENT_APCLI, DBG_LVL_TRACE, + ("\n")); + } + } + + return TRUE; +} + +VOID UpdateMbssCliLinkMap( + RTMP_ADAPTER *pAd, + UCHAR MbssIdx, + struct wifi_dev *cli_link_wdev, + struct wifi_dev *mbss_link_wdev) +{ + MBSS_TO_CLI_LINK_MAP_T *pMbssToCliLinkMap = NULL; + + NdisAcquireSpinLock(&pAd->ApCfg.CliLinkMapLock); + pMbssToCliLinkMap = &pAd->ApCfg.MbssToCliLinkMap[MbssIdx]; + pMbssToCliLinkMap->mbss_wdev = mbss_link_wdev; + pMbssToCliLinkMap->cli_link_wdev = cli_link_wdev; + NdisReleaseSpinLock(&pAd->ApCfg.CliLinkMapLock); +} + +#endif /* MAC_REPEATER_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sanity.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sanity.c new file mode 100644 index 000000000..3d06cd800 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sanity.c @@ -0,0 +1,30 @@ +/**************************************************************************** + * 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" + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sec.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sec.c new file mode 100644 index 000000000..9b0b1b650 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sec.c @@ -0,0 +1,790 @@ +/* + *************************************************************************** + * 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_sec.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ +#include "rt_config.h" +BUILD_TIMER_FUNCTION(GroupRekeyExec); + +#ifdef DOT11W_PMF_SUPPORT +VOID APPMFInit( + IN RTMP_ADAPTER * pAd, + IN struct wifi_dev *wdev) +{ + struct _SECURITY_CONFIG *pSecConfig = &wdev->SecConfig; + /* + IEEE 802.11W/P.10 - + A STA that has associated with Management Frame Protection enabled + shall not use pairwise cipher suite selectors WEP-40, WEP-104, + TKIP, or "Use Group cipher suite". + + IEEE 802.11W/P.3 - + IEEE Std 802.11 provides one security protocol, CCMP, for protection + of unicast Robust Management frames. + */ + pSecConfig->PmfCfg.MFPC = FALSE; + pSecConfig->PmfCfg.MFPR = FALSE; + pSecConfig->PmfCfg.PMFSHA256 = FALSE; + + if (IS_AKM_WPA3PSK(pSecConfig->AKMMap)) { + /* In WPA3 spec, When a WPA3-Personal only BSS is configured, + * Protected Management Frame (PMF) shall be set to required (MFPR=1) + * When WPA2-Personal and WPA3-Personal are configured on the same BSS (mixed mode), + * Protected Management Frame (PMF) shall be set to capable (MFPC = 1, MFPR = 0) + */ + pSecConfig->PmfCfg.MFPC = TRUE; + pSecConfig->PmfCfg.MFPR = (IS_AKM_WPA2PSK(pSecConfig->AKMMap)) ? FALSE : TRUE; + } else if (IS_AKM_WPA3(pSecConfig->AKMMap) || IS_AKM_OWE(pSecConfig->AKMMap)) { + /* In WPA3 spec, When WPA3-Enterprise Suite B is used, + * Protected Management Frame (PMF) shall be set to required (MFPR=1). + */ + pSecConfig->PmfCfg.MFPC = TRUE; + pSecConfig->PmfCfg.MFPR = TRUE; + } else + if ((IS_AKM_WPA2(pSecConfig->AKMMap) || IS_AKM_WPA2PSK(pSecConfig->AKMMap)) + && IS_CIPHER_CCMP128(pSecConfig->PairwiseCipher) + && IS_CIPHER_CCMP128(pSecConfig->GroupCipher) + && (pSecConfig->PmfCfg.Desired_MFPC)) { + pSecConfig->PmfCfg.MFPC = TRUE; + pSecConfig->PmfCfg.MFPR = pSecConfig->PmfCfg.Desired_MFPR; + + if ((pSecConfig->PmfCfg.Desired_PMFSHA256) || (pSecConfig->PmfCfg.MFPR)) + pSecConfig->PmfCfg.PMFSHA256 = TRUE; + } else if (pSecConfig->PmfCfg.Desired_MFPC) + MTWF_LOG(DBG_CAT_SEC, CATSEC_PMF, DBG_LVL_ERROR, ("[PMF]%s:: Security is not WPA2/WPA2PSK AES\n", __func__)); + + if (pSecConfig->PmfCfg.MFPC) { + /* default IGTK cipher is BIP-CMAC-128 */ + if (pSecConfig->PmfCfg.igtk_cipher == 0x0) { + if (IS_AKM_WPA3(pSecConfig->AKMMap)) + SET_CIPHER_BIP_GMAC256(pSecConfig->PmfCfg.igtk_cipher); + else + SET_CIPHER_BIP_CMAC128(pSecConfig->PmfCfg.igtk_cipher); + MTWF_LOG(DBG_CAT_SEC, CATSEC_PMF, DBG_LVL_ERROR, + ("[PMF]%s: IGTK cipher is none, initail IGTK cipher to %s\n", + __func__, GetEncryModeStr(pSecConfig->PmfCfg.igtk_cipher))); + } + } + + MTWF_LOG(DBG_CAT_SEC, CATSEC_PMF, DBG_LVL_ERROR, ("[PMF]%s:: apidx=%d, MFPC=%d, MFPR=%d, SHA256=%d\n", + __func__, wdev->func_idx, pSecConfig->PmfCfg.MFPC, + pSecConfig->PmfCfg.MFPR, pSecConfig->PmfCfg.PMFSHA256)); +} +#endif /* DOT11W_PMF_SUPPORT */ + + +INT APSecInit( + IN RTMP_ADAPTER * pAd, + IN struct wifi_dev *wdev) +{ + struct _SECURITY_CONFIG *pSecConfig = &wdev->SecConfig; + + if (pSecConfig->AKMMap == 0x0) + SET_AKM_OPEN(pSecConfig->AKMMap); + + if (pSecConfig->PairwiseCipher == 0x0) + SET_CIPHER_NONE(pSecConfig->PairwiseCipher); + + /* Decide Group cipher */ + if ((IS_AKM_OPEN(pSecConfig->AKMMap) || IS_AKM_SHARED(pSecConfig->AKMMap)) + && (IS_CIPHER_WEP(pSecConfig->PairwiseCipher))) { + /* WEP */ + pSecConfig->GroupCipher = pSecConfig->PairwiseCipher; + pSecConfig->GroupKeyId = pSecConfig->PairwiseKeyId; + } else if (IS_AKM_WPA_CAPABILITY(pSecConfig->AKMMap) + && IS_CIPHER_TKIP(pSecConfig->PairwiseCipher)) { + /* Mix mode */ + SET_CIPHER_TKIP(pSecConfig->GroupCipher); + } else + pSecConfig->GroupCipher = pSecConfig->PairwiseCipher; + + /* Default key index is always 2 in WPA mode */ + if (IS_AKM_WPA_CAPABILITY(pSecConfig->AKMMap)) + pSecConfig->GroupKeyId = 1; + +#ifdef DOT11R_FT_SUPPORT + + if (wdev->FtCfg.FtCapFlag.Dot11rFtEnable) { + if (IS_AKM_WPA2(pSecConfig->AKMMap)) + SET_AKM_FT_WPA2(pSecConfig->AKMMap); + + if (IS_AKM_WPA2PSK(pSecConfig->AKMMap)) + SET_AKM_FT_WPA2PSK(pSecConfig->AKMMap); + + if (IS_AKM_WPA3PSK(pSecConfig->AKMMap)) + SET_AKM_FT_SAE_SHA256(pSecConfig->AKMMap); + } + +#endif /* DOT11R_FT_SUPPORT */ +#ifdef DOT11W_PMF_SUPPORT + APPMFInit(pAd, wdev); +#endif /* DOT11W_PMF_SUPPORT */ + /* Generate the corresponding RSNIE */ +#ifdef HOSTAPD_SUPPORT + + if (pAd->ApCfg.MBSSID[wdev->func_id].Hostapd) + return TRUE; +#endif /* HOSTAPD_SUPPORT */ + WPAMakeRSNIE(wdev->wdev_type, &wdev->SecConfig, NULL); + + return TRUE; +} + + +INT APKeyTableInit( + IN RTMP_ADAPTER * pAd, + IN struct wifi_dev *wdev, + IN STA_REC_CTRL_T * sta_rec) +{ + BSS_STRUCT *pMbss = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + ASIC_SEC_INFO *asic_sec_info = &sta_rec->asic_sec_info; + USHORT Wcid = 0; + STA_TR_ENTRY *tr_entry = NULL; + + if (wdev == NULL) + return 0; + + /* + Initialize security variable per entry, + 1. pairwise key table, re-set all WCID entry as NO-security mode. + 2. access control port status + */ + /* Init Security variables */ + pMbss = &pAd->ApCfg.MBSSID[wdev->func_idx]; + pSecConfig = &wdev->SecConfig; + RTMPInitTimer(pAd, &pSecConfig->GroupRekeyTimer, GET_TIMER_FUNCTION(GroupRekeyExec), pAd, TRUE); + + if (IS_AKM_WPA_CAPABILITY(pSecConfig->AKMMap)) + pSecConfig->GroupKeyId = 1; + + /* Get a specific WCID to record this MBSS key attribute */ + Wcid = sta_rec->WlanIdx; + tr_entry = &pAd->MacTab.tr_entry[Wcid]; + wdev->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + tr_entry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + /* Set key material to Asic */ + os_zero_mem(asic_sec_info, sizeof(ASIC_SEC_INFO)); + asic_sec_info->Operation = SEC_ASIC_ADD_GROUP_KEY; + asic_sec_info->Direction = SEC_ASIC_KEY_TX; + asic_sec_info->Wcid = Wcid; + asic_sec_info->BssIndex = wdev->func_idx; + asic_sec_info->Cipher = pSecConfig->GroupCipher; + asic_sec_info->KeyIdx = pSecConfig->GroupKeyId; + os_move_mem(&asic_sec_info->PeerAddr[0], wdev->bssid, MAC_ADDR_LEN); + + /* When WEP, TKIP or AES is enabled, set group key info to Asic */ + if (IS_CIPHER_WEP(pSecConfig->GroupCipher)) { + INT i; + + /* Generate 3-bytes IV randomly for software encryption using */ + for (i = 0; i < LEN_WEP_TSC; i++) + pSecConfig->WepKey[asic_sec_info->KeyIdx].TxTsc[i] = RandomByte(pAd); + + os_move_mem(&asic_sec_info->Key, &pSecConfig->WepKey[asic_sec_info->KeyIdx], sizeof(SEC_KEY_INFO)); + sta_rec->EnableFeature |= STA_REC_INSTALL_KEY_FEATURE; + } else if (IS_CIPHER_TKIP(pSecConfig->GroupCipher) + || IS_CIPHER_CCMP128(pSecConfig->GroupCipher) + || IS_CIPHER_CCMP256(pSecConfig->GroupCipher) + || IS_CIPHER_GCMP128(pSecConfig->GroupCipher) + || IS_CIPHER_GCMP256(pSecConfig->GroupCipher)) { + struct _SEC_KEY_INFO *pGroupKey = &asic_sec_info->Key; + /* Calculate PMK */ + SetWPAPSKKey(pAd, pSecConfig->PSK, strlen(pSecConfig->PSK), (PUCHAR) pMbss->Ssid, pMbss->SsidLen, pSecConfig->PMK); + /* Generate GMK and GNonce randomly per MBSS */ + GenRandom(pAd, wdev->bssid, pSecConfig->GMK); + GenRandom(pAd, wdev->bssid, pSecConfig->Handshake.GNonce); + /* Derive GTK per BSSID */ + WpaDeriveGTK(pSecConfig->GMK, + (UCHAR *) pSecConfig->Handshake.GNonce, + wdev->bssid, + (UCHAR *) pSecConfig->GTK, + LEN_MAX_GTK); + /* Install Shared key */ + os_move_mem(pGroupKey->Key, pSecConfig->GTK, LEN_MAX_GTK); +#ifdef DOT11W_PMF_SUPPORT + + if (pSecConfig->PmfCfg.MFPC == TRUE) { + /* IGTK default key index as 4 */ + pSecConfig->PmfCfg.IGTK_KeyIdx = 4; + /* Clear IPN */ + NdisZeroMemory(&pSecConfig->PmfCfg.IPN[0][0], LEN_WPA_TSC); + /* Derive IGTK */ + PMF_DeriveIGTK(pAd, &pSecConfig->PmfCfg.IGTK[0][0]); + os_move_mem(asic_sec_info->IGTK, &pSecConfig->PmfCfg.IGTK[0][0], LEN_MAX_IGTK); + if (IS_CIPHER_BIP_CMAC128(pSecConfig->PmfCfg.igtk_cipher) || + IS_CIPHER_BIP_GMAC128(pSecConfig->PmfCfg.igtk_cipher)) + asic_sec_info->IGTKKeyLen = LEN_BIP128_IGTK; + else if (IS_CIPHER_BIP_CMAC256(pSecConfig->PmfCfg.igtk_cipher) || + IS_CIPHER_BIP_GMAC256(pSecConfig->PmfCfg.igtk_cipher)) + asic_sec_info->IGTKKeyLen = LEN_BIP256_IGTK; + + if (asic_sec_info->IGTKKeyLen != 0) + asic_sec_info->Cipher |= pSecConfig->PmfCfg.igtk_cipher; + } + +#endif /* DOT11W_PMF_SUPPORT */ + WPAInstallKey(pAd, asic_sec_info, TRUE, FALSE); + sta_rec->EnableFeature |= STA_REC_INSTALL_KEY_FEATURE; + pSecConfig->Handshake.GTKState = REKEY_ESTABLISHED; + } + + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("### BSS(%d) AKM=0x%x, PairwiseCipher=0x%x, GroupCipher=0x%x\n", + wdev->func_idx, pSecConfig->AKMMap, pSecConfig->PairwiseCipher, pSecConfig->GroupCipher)); + return TRUE; +} + + +VOID GroupRekeyExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + UINT i, apidx; + ULONG temp_counter = 0; + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) SystemSpecific3; + struct wifi_dev *wdev = NULL; + struct _SECURITY_CONFIG *pSecConfig = NULL; + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + if (&pAd->ApCfg.MBSSID[apidx].wdev.SecConfig.GroupRekeyTimer == pTimer) + break; + } + + if (apidx == pAd->ApCfg.BssidNum) + return; + + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pSecConfig = &wdev->SecConfig; + + if (pSecConfig->GroupReKeyInterval == 0) + return; + + if (pSecConfig->Handshake.GTKState == REKEY_NEGOTIATING) { + pSecConfig->GroupReKeyInstallCountDown--; + + if (pSecConfig->GroupReKeyInstallCountDown == 0) + goto INSTALL_KEY; + } + + if (pSecConfig->GroupReKeyMethod == SEC_GROUP_REKEY_TIME) + temp_counter = (++pSecConfig->GroupPacketCounter); + else if (pSecConfig->GroupReKeyMethod == SEC_GROUP_REKEY_PACKET) + temp_counter = pSecConfig->GroupPacketCounter/1000; /* Packet-based: kilo-packets */ + else + return; + + if (temp_counter > pSecConfig->GroupReKeyInterval) { + UINT entry_count = 0; + + pSecConfig->GroupPacketCounter = 0; + pSecConfig->Handshake.GTKState = REKEY_NEGOTIATING; + /* change key index */ + pSecConfig->GroupKeyId = (pSecConfig->GroupKeyId == 1) ? 2 : 1; + /* Generate GNonce randomly per MBSS */ + GenRandom(pAd, wdev->bssid, pSecConfig->Handshake.GNonce); + /* Derive GTK per BSSID */ + WpaDeriveGTK(pSecConfig->GMK, + (UCHAR *) pSecConfig->Handshake.GNonce, + wdev->bssid, + (UCHAR *) pSecConfig->GTK, + LEN_MAX_GTK); + + /* Process 2-way handshaking */ + for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) { + MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i]; + + if (IS_ENTRY_CLIENT(pEntry) + && (pEntry->SecConfig.Handshake.WpaState == AS_PTKINITDONE) + && (pEntry->func_tb_idx == apidx)) { + entry_count++; + RTMPSetTimer(&pEntry->SecConfig.StartFor2WayTimer, ENQUEUE_EAPOL_2WAY_START_TIMER); + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Rekey interval excess, Update Group Key for %02X:%02X:%02X:%02X:%02X:%02X , DefaultKeyId= %x\n", + PRINT_MAC(pEntry->Addr), pSecConfig->GroupKeyId)); + } + } + + if (entry_count == 0) + goto INSTALL_KEY; + else + pSecConfig->GroupReKeyInstallCountDown = 1; /* 1 seconds */ + } + + return; +INSTALL_KEY: + /* If no sta connect, directly install group rekey, else install key after 2 way completed or 1 seconds */ + { + ASIC_SEC_INFO Info = {0}; + USHORT Wcid; + /* Get a specific WCID to record this MBSS key attribute */ + GET_GroupKey_WCID(wdev, Wcid); + /* Set key material to Asic */ + os_zero_mem(&Info, sizeof(ASIC_SEC_INFO)); + Info.Operation = SEC_ASIC_ADD_GROUP_KEY; + Info.Direction = SEC_ASIC_KEY_TX; + Info.Wcid = Wcid; + Info.BssIndex = apidx; + Info.Cipher = pSecConfig->GroupCipher; + Info.KeyIdx = pSecConfig->GroupKeyId; + os_move_mem(&Info.PeerAddr[0], BROADCAST_ADDR, MAC_ADDR_LEN); + /* Install Shared key */ + os_move_mem(Info.Key.Key, pSecConfig->GTK, LEN_MAX_GTK); + WPAInstallKey(pAd, &Info, TRUE, TRUE); + pSecConfig->Handshake.GTKState = REKEY_ESTABLISHED; + } +} + +VOID WPAGroupRekeyByWdev( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *wdev) + +{ + struct _SECURITY_CONFIG *pSecConfig = &wdev->SecConfig; + + if (IS_CIPHER_TKIP(pSecConfig->GroupCipher) + || IS_CIPHER_CCMP128(pSecConfig->GroupCipher) + || IS_CIPHER_CCMP256(pSecConfig->GroupCipher) + || IS_CIPHER_GCMP128(pSecConfig->GroupCipher) + || IS_CIPHER_GCMP256(pSecConfig->GroupCipher)) { + /* Group rekey related */ + if ((pSecConfig->GroupReKeyInterval != 0) + && ((pSecConfig->GroupReKeyMethod == SEC_GROUP_REKEY_TIME) + || (pSecConfig->GroupReKeyMethod == SEC_GROUP_REKEY_PACKET))) { + pSecConfig->GroupPacketCounter = 0; + RTMPSetTimer(&pSecConfig->GroupRekeyTimer, GROUP_KEY_UPDATE_EXEC_INTV); + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, (" %s : Group rekey method= %d , interval = 0x%lx\n", + __func__, pSecConfig->GroupReKeyMethod, pSecConfig->GroupReKeyInterval)); + } + } +} + +/* + Set group re-key timer if necessary. + It must be processed after clear flag "fRTMP_ADAPTER_HALT_IN_PROGRESS" +*/ +VOID APStartRekeyTimer( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *wdev) +{ + if (HcIsRadioAcq(wdev)) { + WPAGroupRekeyByWdev(pAd, wdev); + } +} + + +VOID APStopRekeyTimer( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *wdev) +{ + BOOLEAN Cancelled; + RTMPCancelTimer(&wdev->SecConfig.GroupRekeyTimer, &Cancelled); +} + + +VOID APReleaseRekeyTimer( + IN RTMP_ADAPTER *pAd, + IN struct wifi_dev *wdev) +{ + BOOLEAN Cancelled; + RTMPReleaseTimer(&wdev->SecConfig.GroupRekeyTimer, &Cancelled); +} + + +static PCHAR portsecured[] = {"NONE", "PORT_SECURED", "NOT_SECURED"}; +INT Show_APSecurityInfo_Proc( + IN RTMP_ADAPTER *pAd, + IN RTMP_STRING * arg) +{ + UCHAR idx; + USHORT Wcid; + struct _SECURITY_CONFIG *pSecConfig = NULL; + struct wifi_dev *wdev = NULL; + STA_TR_ENTRY *tr_entry = NULL; + + if (!pAd) + return FALSE; + + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Security Infomation: AP\n")); + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BSS\tWCID\tAuthMode\tPairwiseCipher\tGroupCipher\tGroupKeyId\tPortSecured\n")); + + for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { + pSecConfig = &pAd->ApCfg.MBSSID[idx].wdev.SecConfig; + wdev = &pAd->ApCfg.MBSSID[idx].wdev; + GET_GroupKey_WCID(wdev, Wcid); + tr_entry = &pAd->MacTab.tr_entry[Wcid]; + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" %d\t%d\t%s\t\t%s\t\t%s\t\t%d\t\t%s\n", + idx, + Wcid, + GetAuthModeStr(GET_SEC_AKM(pSecConfig)), + GetEncryModeStr(GET_PAIRWISE_CIPHER(pSecConfig)), + GetEncryModeStr(GET_GROUP_CIPHER(pSecConfig)), + pSecConfig->GroupKeyId, + portsecured[tr_entry->PortSecured])); + } + + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); +#ifdef APCLI_SUPPORT + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Security Infomation: AP Client\n")); + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BSS\tWCID\tAuthMode\tPairwiseCipher\tPortSecured\n")); + + for (idx = 0; idx < MAX_APCLI_NUM; idx++) { + PAPCLI_STRUCT pApCliEntry = &pAd->ApCfg.ApCliTab[idx]; + + pSecConfig = &pApCliEntry->wdev.SecConfig; + wdev = &pApCliEntry->wdev; + tr_entry = &pAd->MacTab.tr_entry[wdev->bss_info_argument.ucBcMcWlanIdx]; + + if (pApCliEntry->Enable == TRUE) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (" %d\t%d\t%s\t\t%s\t\t%s\n", + idx, + wdev->bss_info_argument.ucBcMcWlanIdx, + GetAuthModeStr(GET_SEC_AKM(pSecConfig)), + GetEncryModeStr(GET_PAIRWISE_CIPHER(pSecConfig)), + portsecured[tr_entry->PortSecured])); + } + } + + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n")); +#endif + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("Security Infomation: STA\n")); + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("BSS\t\t\tAID\tWCID\tAuthMode\tPairwiseCipher\tPortSecured\n")); + + for (idx = 0; idx < MAX_LEN_OF_MAC_TABLE; idx++) { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[idx]; + + tr_entry = &pAd->MacTab.tr_entry[pEntry->tr_tb_idx]; + pSecConfig = &pEntry->SecConfig; + + if (pEntry && IS_ENTRY_CLIENT(pEntry) && pEntry->Sst == SST_ASSOC) { + MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02X:%02X:%02X:%02X:%02X:%02X\t%d\t%d\t%s\t\t%s\t\t%s\n", + PRINT_MAC(pEntry->Addr), + pEntry->Aid, + pEntry->wcid, + GetAuthModeStr(GET_SEC_AKM(pSecConfig)), + GetEncryModeStr(GET_PAIRWISE_CIPHER(pSecConfig)), + portsecured[tr_entry->PortSecured])); + } + } + + return TRUE; +} + +VOID CheckBMCPortSecured( + IN RTMP_ADAPTER *pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN BOOLEAN isConnect) +{ + UINT32 bss_index = pEntry->func_tb_idx; + UINT32 wcid; + UCHAR PortSecured = WPA_802_1X_PORT_NOT_SECURED; + MAC_TABLE_ENTRY *pMacEntry = NULL; + STA_TR_ENTRY *tr_entry = NULL; + struct wifi_dev *wdev = &pAd->ApCfg.MBSSID[bss_index].wdev; + + if (wdev->tr_tb_idx == 0xff) + return;/* skip uninit tr_tb_idx. */ + + if (isConnect) + PortSecured = WPA_802_1X_PORT_SECURED; + else { + for (wcid = 1; VALID_UCAST_ENTRY_WCID(pAd, wcid); wcid++) { + pMacEntry = &pAd->MacTab.Content[wcid]; + tr_entry = &pAd->MacTab.tr_entry[wcid]; + + if (wcid == pEntry->wcid) + continue; + + if (((pMacEntry) + && (IS_ENTRY_CLIENT(pMacEntry)) + && (pMacEntry->Sst == SST_ASSOC) + && (pMacEntry->func_tb_idx == bss_index) + && (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) + ) { + PortSecured = WPA_802_1X_PORT_SECURED; + break; + } + } + } + + if (wdev->PortSecured != PortSecured) { + tr_entry = &pAd->MacTab.tr_entry[wdev->bss_info_argument.ucBcMcWlanIdx]; + tr_entry->PortSecured = PortSecured; + wdev->PortSecured = PortSecured; + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: bss_index = %d, wcid = %d, PortSecured = %d\n", + __func__, + bss_index, + wdev->bss_info_argument.ucBcMcWlanIdx, + PortSecured)); + } +} + + +#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(RTMP_ADAPTER *pAdapter, UCHAR *pPacket, ULONG Len) +{ + PEAP_HDR pEapHdr; + UCHAR Addr[MAC_ADDR_LEN]; + UCHAR Header802_3[LENGTH_802_3]; + MAC_TABLE_ENTRY *pEntry; + STA_TR_ENTRY *tr_entry; + 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); + pEntry = MacTableLookup(pAdapter, Addr); + if (pEntry == NULL) { + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("WpaSend - No such MAC - %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(Addr))); + return; + } + + tr_entry = &pAdapter->MacTab.tr_entry[pEntry->wcid]; + + /* Send EAP frame to STA */ + if ((IS_AKM_WPA_CAPABILITY_Entry(pEntry) && (pEapHdr->ProType != EAPOLKey)) || + (IS_IEEE8021X(&pAdapter->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.SecConfig))) + RTMPToWirelessSta(pAdapter, + pEntry, + Header802_3, + LENGTH_802_3, + pData, + Len - LENGTH_802_3, + (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); + + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s(%d), pEapHdr->code=%d, pEntry->SecConfig.Handshake.WpaState=%d\n", __func__, __LINE__, pEapHdr->code, pEntry->SecConfig.Handshake.WpaState)); + + if (RTMPEqualMemory((pPacket+12), EAPOL, 2)) { + switch (pEapHdr->code) { + case EAP_CODE_REQUEST: + if ((pEntry->SecConfig.Handshake.WpaState >= AS_PTKINITDONE) && (pEapHdr->ProType == EAPPacket)) { + pEntry->SecConfig.Handshake.WpaState = AS_AUTHENTICATION; + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Start to re-authentication by 802.1x daemon\n")); + } + + break; + + /* After receiving EAP_SUCCESS, trigger state machine */ + case EAP_CODE_SUCCESS: + if (IS_AKM_WPA_CAPABILITY_Entry(pEntry) && (pEapHdr->ProType != EAPOLKey)) { + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Send EAP_CODE_SUCCESS\n\n")); + + if (pEntry->Sst == SST_ASSOC) { + UINT8 pmk_len = LEN_PMK; + pEntry->SecConfig.Handshake.WpaState = AS_INITPMK; + pEntry->SecConfig.Handshake.MsgRetryCounter = 0; + os_move_mem(&pEntry->SecConfig.Handshake.AAddr, pAdapter->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid, MAC_ADDR_LEN); + os_move_mem(&pEntry->SecConfig.Handshake.SAddr, pEntry->Addr, MAC_ADDR_LEN); + if (pEntry->SecConfig.key_deri_alg == SEC_KEY_DERI_SHA384) + pmk_len = LEN_PMK_SHA384; + os_move_mem(&pEntry->SecConfig.PMK, + &pAdapter->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.SecConfig.PMK, + pmk_len); + WPABuildPairMsg1(pAdapter, &pEntry->SecConfig, pEntry); + } + } else { + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + pEntry->SecConfig.Handshake.WpaState = AS_PTKINITDONE; + /* 1x+WEP will update port secured in key install stage, todo: change the below code to WifiSysUpdatePortSecur? */ + if (IS_CIPHER_NONE(pEntry->SecConfig.PairwiseCipher)) { + pAdapter->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.PortSecured = WPA_802_1X_PORT_SECURED; + tr_entry->PortSecured = WPA_802_1X_PORT_SECURED; + } +#ifdef WSC_AP_SUPPORT + + if (pAdapter->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.WscControl.WscConfMode != WSC_DISABLE) + WscInformFromWPA(pEntry); + +#endif /* WSC_AP_SUPPORT */ + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("IEEE8021X-WEP : Send EAP_CODE_SUCCESS\n\n")); + } + + break; + + case EAP_CODE_FAILURE: + break; + + default: + break; + } + } else { + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("Send Deauth, Reason : REASON_NO_LONGER_VALID\n")); + MlmeDeAuthAction(pAdapter, pEntry, REASON_NO_LONGER_VALID, FALSE); + } +} + + +INT RTMPAddPMKIDCache( + IN NDIS_AP_802_11_PMKID * pPMKIDCache, + IN INT apidx, + IN UCHAR *pAddr, + IN UCHAR *PMKID, + IN UCHAR *PMK, + IN UINT8 pmk_len) +{ + INT i, CacheIdx; + /* Update PMKID status */ + CacheIdx = RTMPSearchPMKIDCache(pPMKIDCache, apidx, pAddr); + + if (CacheIdx != INVALID_PMKID_IDX) { + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): cache found and renew it(%d)\n", + __func__, CacheIdx)); + } else { + ULONG ts = 0; + INT old_entry = 0; + + /* Add a new PMKID */ + for (i = 0; i < MAX_PMKID_COUNT; i++) { + if (pPMKIDCache->BSSIDInfo[i].Valid == FALSE) { + CacheIdx = i; + break; + } + if ((ts == 0) || (ts > pPMKIDCache->BSSIDInfo[i].RefreshTime)) { + ts = pPMKIDCache->BSSIDInfo[i].RefreshTime; + old_entry = i; + } + } + + if (i == MAX_PMKID_COUNT) { + CacheIdx = old_entry; + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("%s():Cache full, replace oldest(%d)\n", + __func__, old_entry)); + } + } + + pPMKIDCache->BSSIDInfo[CacheIdx].Valid = TRUE; + pPMKIDCache->BSSIDInfo[CacheIdx].Mbssidx = apidx; + NdisGetSystemUpTime(&(pPMKIDCache->BSSIDInfo[CacheIdx].RefreshTime)); + COPY_MAC_ADDR(&pPMKIDCache->BSSIDInfo[CacheIdx].MAC, pAddr); + NdisMoveMemory(&pPMKIDCache->BSSIDInfo[CacheIdx].PMKID, PMKID, LEN_PMKID); + NdisMoveMemory(&pPMKIDCache->BSSIDInfo[CacheIdx].PMK, PMK, pmk_len); + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): add %02x:%02x:%02x:%02x:%02x:%02x cache(%d) for ra%d\n", + __func__, PRINT_MAC(pAddr), CacheIdx, apidx)); + return CacheIdx; +} + + +INT RTMPSearchPMKIDCache( + IN NDIS_AP_802_11_PMKID * pPMKIDCache, + IN INT apidx, + IN UCHAR *pAddr) +{ + INT i = 0; + + for (i = 0; i < MAX_PMKID_COUNT; i++) { + if ((pPMKIDCache->BSSIDInfo[i].Valid == TRUE) + && (pPMKIDCache->BSSIDInfo[i].Mbssidx == apidx) + && MAC_ADDR_EQUAL(&pPMKIDCache->BSSIDInfo[i].MAC, pAddr)) { + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s():%02x:%02x:%02x:%02x:%02x:%02x cache(%d) from IF(ra%d)\n", + __func__, PRINT_MAC(pAddr), i, apidx)); + break; + } + } + + if (i >= MAX_PMKID_COUNT) { + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s(): - IF(%d) not found\n", __func__, apidx)); + return INVALID_PMKID_IDX; + } + + return i; +} + + +INT RTMPValidatePMKIDCache( + IN NDIS_AP_802_11_PMKID * pPMKIDCache, + IN INT apidx, + IN UCHAR *pAddr, + IN UCHAR *pPMKID) +{ + INT CacheIdx = RTMPSearchPMKIDCache(pPMKIDCache, apidx, pAddr); + + if (CacheIdx == INVALID_PMKID_IDX) + return INVALID_PMKID_IDX; + + if (RTMPEqualMemory(pPMKID, &pPMKIDCache->BSSIDInfo[CacheIdx].PMKID, LEN_PMKID)) + return CacheIdx; + else + return INVALID_PMKID_IDX; +} + + +VOID RTMPDeletePMKIDCache( + IN NDIS_AP_802_11_PMKID * pPMKIDCache, + IN INT apidx, + IN INT idx) +{ + PAP_BSSID_INFO pInfo = &pPMKIDCache->BSSIDInfo[idx]; + + if (pInfo->Valid && (pInfo->Mbssidx == apidx)) { + pInfo->Valid = FALSE; + MTWF_LOG(DBG_CAT_SEC, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s():(IF(%d), del PMKID CacheIdx=%d\n", __func__, apidx, idx)); + } +} + + +VOID RTMPMaintainPMKIDCache( + IN RTMP_ADAPTER *pAd) +{ + INT i; + ULONG Now; + + for (i = 0; i < MAX_PMKID_COUNT; i++) { + PAP_BSSID_INFO pBssInfo = &pAd->ApCfg.PMKIDCache.BSSIDInfo[i]; + + NdisGetSystemUpTime(&Now); + + if ((pBssInfo->Valid) + && /*((Now - pBssInfo->RefreshTime) >= pMbss->PMKCachePeriod)*/ + (RTMP_TIME_AFTER(Now, (pBssInfo->RefreshTime + pAd->ApCfg.MBSSID[pBssInfo->Mbssidx].PMKCachePeriod)))) + RTMPDeletePMKIDCache(&pAd->ApCfg.PMKIDCache, pBssInfo->Mbssidx, i); + } +} + +#endif /* DOT1X_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sync.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sync.c new file mode 100644 index 000000000..32636ab60 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_sync.c @@ -0,0 +1,1989 @@ +/**************************************************************************** + * 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) + + +/* + ========================================================================== + 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) +{ + PEER_PROBE_REQ_PARAM ProbeReqParam = { {0} }; + 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; + BSS_STRUCT *mbss; + struct wifi_dev *wdev; + struct dev_rate_info *rate; + struct freq_oper oper; +#if defined(TXBF_SUPPORT) && defined(VHT_TXBF_SUPPORT) + UCHAR ucETxBfCap; +#endif /* TXBF_SUPPORT && VHT_TXBF_SUPPORT */ +#ifdef AP_QLOAD_SUPPORT + QLOAD_CTRL *pQloadCtrl = HcGetQloadCtrl(pAd); +#endif + CHAR rsne_idx = 0; + struct _SECURITY_CONFIG *pSecConfig = NULL; + UCHAR cfg_ht_bw; + UCHAR op_ht_bw; + struct _build_ie_info ie_info; + UCHAR Environment = 0x20; +#ifdef CONFIG_HOTSPOT_R2 + extern UCHAR OSEN_IE[]; + extern UCHAR OSEN_IELEN; +#endif /* CONFIG_HOTSPOT_R2 */ + struct DOT11_H *pDot11h = NULL; +#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, &ProbeReqParam) == FALSE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s():shiang! PeerProbeReqSanity failed!\n", __func__)); + return; + } + + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + mbss = &pAd->ApCfg.MBSSID[apidx]; + wdev = &mbss->wdev; + rate = &wdev->rate; + pDot11h = wdev->pDot11_H; + if (pDot11h == NULL) + continue; + cfg_ht_bw = wlan_config_get_ht_bw(wdev); + op_ht_bw = wlan_operate_get_ht_bw(wdev); + hc_radio_query_by_channel(pAd, wdev->channel, &oper); + if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && + !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { + /* the interface is down, so we can not send probe response */ + continue; + } + + if ((Elem->Channel != oper.prim_ch) && (Elem->Channel != oper.cen_ch_1)) + continue; + + PhyMode = wdev->PhyMode; + + ie_info.frame_subtype = SUBTYPE_PROBE_RSP; + ie_info.channel = wdev->channel; + ie_info.phy_mode = PhyMode; + ie_info.wdev = wdev; + + if (((((ProbeReqParam.SsidLen == 0) && (!mbss->bHideSsid)) || + ((ProbeReqParam.SsidLen == mbss->SsidLen) && + NdisEqualMemory(ProbeReqParam.Ssid, mbss->Ssid, (ULONG) ProbeReqParam.SsidLen))) +#ifdef CONFIG_HOTSPOT + && ProbeReqforHSAP(pAd, apidx, &ProbeReqParam) +#endif + ) +#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 */ + || ((ProbeReqParam.SsidLen == 32) && MAC_ADDR_EQUAL(Addr3, wdev->bssid) && (mbss->bHideSsid == 0)) +#endif /* WSC_AP_SUPPORT */ + ) + ; + else { + continue; /* check next BSS */ + } + +#ifdef BAND_STEERING + if (pAd->ApCfg.BandSteering + ) { + BOOLEAN bBndStrgCheck = TRUE; + + bBndStrgCheck = BndStrg_CheckConnectionReq(pAd, wdev, ProbeReqParam.Addr2, Elem, &ProbeReqParam); + if (bBndStrgCheck == FALSE) + return; + } +#endif /* BAND_STEERING */ +#ifdef WAPP_SUPPORT + wapp_send_cli_probe_event(pAd, RtmpOsGetNetIfIndex(wdev->if_dev), ProbeReqParam.Addr2, Elem); +#endif + /* allocate and send out ProbeRsp frame */ + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + + if (NStatus != NDIS_STATUS_SUCCESS) + return; + + MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, ProbeReqParam.Addr2, + wdev->if_addr, wdev->bssid); + { + SupRateLen = rate->SupRateLen; + + if (PhyMode == WMODE_B) + SupRateLen = 4; + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &ProbeRspHdr, + TIMESTAMP_LEN, &FakeTimestamp, + 2, &pAd->CommonCfg.BeaconPeriod, + 2, &mbss->CapabilityInfo, + 1, &SsidIe, + 1, &mbss->SsidLen, + mbss->SsidLen, mbss->Ssid, + 1, &SupRateIe, + 1, &SupRateLen, + SupRateLen, rate->SupRate, + 1, &DsIe, + 1, &DsLen, + 1, &wdev->channel, + END_OF_ARGS); + } + + if ((rate->ExtRateLen) && (PhyMode != WMODE_B)) { + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &ErpIe, + 1, &ErpIeLen, + 1, &pAd->ApCfg.ErpIeContent, + 1, &ExtRateIe, + 1, &rate->ExtRateLen, + rate->ExtRateLen, rate->ExtRate, + END_OF_ARGS); + FrameLen += TmpLen; + } + +#ifdef DOT11_N_SUPPORT + if (WMODE_CAP_N(PhyMode) && + (wdev->DesiredHtPhyInfo.bHtEnable)) { + ie_info.is_draft_n_type = FALSE; + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_ht_ies(pAd, &ie_info); + } +#endif /* DOT11_N_SUPPORT */ + /* Append RSN_IE when WPA OR WPAPSK, */ + pSecConfig = &wdev->SecConfig; +#ifdef CONFIG_HOTSPOT_R2 + + if ((mbss->HotSpotCtrl.HotSpotEnable == 0) && (mbss->HotSpotCtrl.bASANEnable == 1) && (IS_AKM_WPA2_Entry(wdev))) { + /* replace RSN IE with OSEN IE if it's OSEN wdev */ + UCHAR RSNIe = IE_WPA; + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &RSNIe, + 1, &OSEN_IELEN, + OSEN_IELEN, OSEN_IE, + END_OF_ARGS); + FrameLen += TmpLen; + } else +#endif /* CONFIG_HOTSPOT_R2 */ + { + for (rsne_idx = 0; rsne_idx < SEC_RSNIE_NUM; rsne_idx++) { + if (pSecConfig->RSNE_Type[rsne_idx] == SEC_RSNIE_NONE) + continue; + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &pSecConfig->RSNE_EID[rsne_idx][0], + 1, &pSecConfig->RSNE_Len[rsne_idx], + pSecConfig->RSNE_Len[rsne_idx], &pSecConfig->RSNE_Content[rsne_idx][0], + END_OF_ARGS); + FrameLen += TmpLen; + } + } + +#if defined(CONFIG_HOTSPOT) || defined(FTM_SUPPORT) + + if (pAd->ApCfg.MBSSID[apidx].GASCtrl.b11U_enable) { + ULONG TmpLen; + /* Interworking element */ + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + pAd->ApCfg.MBSSID[apidx].GASCtrl.InterWorkingIELen, + pAd->ApCfg.MBSSID[apidx].GASCtrl.InterWorkingIE, END_OF_ARGS); + FrameLen += TmpLen; + /* Advertisement Protocol element */ + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + pAd->ApCfg.MBSSID[apidx].GASCtrl.AdvertisementProtoIELen, + pAd->ApCfg.MBSSID[apidx].GASCtrl.AdvertisementProtoIE, END_OF_ARGS); + FrameLen += TmpLen; + } + +#endif /* defined(CONFIG_HOTSPOT) || defined(FTM_SUPPORT) */ +#ifdef CONFIG_HOTSPOT + + if (pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.HotSpotEnable) { + ULONG TmpLen; + /* Hotspot 2.0 Indication */ + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.HSIndicationIELen, + pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.HSIndicationIE, END_OF_ARGS); + FrameLen += TmpLen; + /* Roaming Consortium element */ + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.RoamingConsortiumIELen, + pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.RoamingConsortiumIE, END_OF_ARGS); + FrameLen += TmpLen; + /* P2P element */ + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.P2PIELen, + pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.P2PIE, END_OF_ARGS); + FrameLen += TmpLen; + } + +#endif + /* Extended Capabilities IE */ + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_extended_cap_ie(pAd, &ie_info); +#ifdef AP_QLOAD_SUPPORT + + if (pAd->CommonCfg.dbdc_mode == 0) + pQloadCtrl = HcGetQloadCtrl(pAd); + else + pQloadCtrl = (wdev->channel > 14) ? HcGetQloadCtrlByRf(pAd, RFIC_5GHZ) : HcGetQloadCtrlByRf(pAd, RFIC_24GHZ); + + if (pQloadCtrl->FlgQloadEnable != 0) { +#ifdef CONFIG_HOTSPOT_R2 + + if (pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.QLoadTestEnable == 1) + FrameLen += QBSS_LoadElementAppend_HSTEST(pAd, pOutBuffer + FrameLen, apidx); + else if (pAd->ApCfg.MBSSID[apidx].HotSpotCtrl.QLoadTestEnable == 0) +#endif + FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer + FrameLen, pQloadCtrl); + } + +#endif /* AP_QLOAD_SUPPORT */ + + /* add WMM IE here */ + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_wmm_cap_ie(pAd, &ie_info); +#ifdef VENDOR_FEATURE7_SUPPORT + /* add country IE, power constraint IE */ + if (pAd->CommonCfg.bCountryFlag || + (wdev->channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) +#ifdef DOT11K_RRM_SUPPORT + || IS_RRM_ENABLE(wdev) +#endif /* DOT11K_RRM_SUPPORT */ + ) { +#ifndef EXT_BUILD_CHANNEL_LIST + ULONG TmpLen = 0; +#endif /* !EXT_BUILD_CHANNEL_LIST */ + ULONG TmpLen2 = 0; + UCHAR TmpFrame[256] = { 0 }; +#ifndef EXT_BUILD_CHANNEL_LIST + PCH_DESC pChDesc = NULL; + UINT i; + + if (WMODE_CAP_2G(wdev->PhyMode)) { + if (pAd->CommonCfg.pChDesc2G != NULL) + pChDesc = (PCH_DESC) pAd->CommonCfg.pChDesc2G; + else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: pChDesc2G is NULL !!!\n", __func__)); + } else if (WMODE_CAP_5G(wdev->PhyMode)) { + if (pAd->CommonCfg.pChDesc5G != NULL) + pChDesc = (PCH_DESC) pAd->CommonCfg.pChDesc5G; + else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: pChDesc5G is NULL !!!\n", __func__)); + } +#endif /* !EXT_BUILD_CHANNEL_LIST */ + + os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); + if (TmpFrame != NULL) { + NdisZeroMemory(TmpFrame, 256); + + /* prepare channel information */ +#ifdef EXT_BUILD_CHANNEL_LIST + BuildBeaconChList(pAd, wdev, TmpFrame, &TmpLen2); +#else + { + UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, + wdev->PhyMode, wdev->channel, op_ht_bw); + + for (i = 0; pChDesc[i].FirstChannel != 0; i++) { + MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, + 1, &pChDesc[i].FirstChannel, + 1, &pChDesc[i].NumOfCh, + 1, &MaxTxPower, + END_OF_ARGS); + TmpLen2 += TmpLen; + } + } +#endif /* EXT_BUILD_CHANNEL_LIST */ + +#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 ((wdev->channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) +#ifdef DOT11K_RRM_SUPPORT + || IS_RRM_ENABLE(wdev) +#endif /* DOT11K_RRM_SUPPORT */ + ) { + + UINT8 PwrConstraintIE = IE_POWER_CONSTRAINT; + UINT8 PwrConstraintLen = 1; + UINT8 PwrConstraint = pAd->CommonCfg.PwrConstraint; + /* prepare power constraint IE */ + MakeOutgoingFrame(pOutBuffer+FrameLen, + &TmpLen, + 1, &PwrConstraintIE, + 1, &PwrConstraintLen, + 1, &PwrConstraint, + END_OF_ARGS); + FrameLen += TmpLen; + + /* prepare TPC Report IE */ + InsertTpcReportIE(pAd, + pOutBuffer+FrameLen, + &FrameLen, + GetMaxTxPwr(pAd), + 0); +#ifdef DOT11_VHT_AC + if (WMODE_CAP_AC(PhyMode)) { + ULONG TmpLen; + UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; + UINT8 ie_len; + VHT_TXPWR_ENV_IE txpwr_env; + + ie_len = build_vht_txpwr_envelope(pAd, wdev, (UCHAR *)&txpwr_env); + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, + 1, &vht_txpwr_env_ie, + 1, &ie_len, + ie_len, &txpwr_env, + END_OF_ARGS); + FrameLen += TmpLen; + } +#endif /* DOT11_VHT_AC */ + } +#endif /* A_BAND_SUPPORT */ +#ifdef DOT11K_RRM_SUPPORT + if (IS_RRM_ENABLE(wdev)) { + UCHAR reg_class = get_regulatory_class(pAd, mbss->wdev.channel, + mbss->wdev.PhyMode, &mbss->wdev); + TmpLen2 = 0; + NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); + RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2, wdev->PhyMode, reg_class); + } +#endif /* DOT11K_RRM_SUPPORT */ + + /* add COUNTRY_IE in probe resp frames */ + { + UCHAR CountryIe = IE_COUNTRY; + /* need to do the padding bit check, and concatenate it */ + /* TmpFrame holds Channel list */ + 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; + os_free_mem(TmpFrame); + } else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: Allocate memory fail!!!\n", __func__)); + } +#endif + +#ifdef DOT11K_RRM_SUPPORT + + if (IS_RRM_ENABLE(wdev)) + RRM_InsertRRMEnCapIE(pAd, pOutBuffer + FrameLen, &FrameLen, apidx); + + InsertChannelRepIE(pAd, pOutBuffer + FrameLen, &FrameLen, + (RTMP_STRING *)pAd->CommonCfg.CountryCode, + get_regulatory_class(pAd, mbss->wdev.channel, mbss->wdev.PhyMode, &mbss->wdev), + NULL, PhyMode); +#ifndef APPLE_11K_IOT + /* Insert BSS AC Access Delay IE. */ + RRM_InsertBssACDelayIE(pAd, pOutBuffer + FrameLen, &FrameLen); + /* Insert BSS Available Access Capacity IE. */ + RRM_InsertBssAvailableACIE(pAd, pOutBuffer + FrameLen, &FrameLen); +#endif /* !APPLE_11K_IOT */ +#endif /* DOT11K_RRM_SUPPORT */ + +#ifndef VENDOR_FEATURE7_SUPPORT + /* add Country IE and power-related IE */ + if (pAd->CommonCfg.bCountryFlag || + (wdev->channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) +#ifdef DOT11K_RRM_SUPPORT + || IS_RRM_ENABLE(wdev) +#endif /* DOT11K_RRM_SUPPORT */ + ) { + ULONG TmpLen2 = 0; + UCHAR TmpFrame[256] = { 0 }; + UCHAR CountryIe = IE_COUNTRY; + PCH_DESC pChDesc = NULL; + + if (WMODE_CAP_2G(wdev->PhyMode)) { + if (pAd->CommonCfg.pChDesc2G != NULL) + pChDesc = (PCH_DESC)pAd->CommonCfg.pChDesc2G; + else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: pChDesc2G is NULL !!!\n", __func__)); + } else if (WMODE_CAP_5G(wdev->PhyMode)) { + if (pAd->CommonCfg.pChDesc5G != NULL) + pChDesc = (PCH_DESC)pAd->CommonCfg.pChDesc5G; + else + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: pChDesc5G is NULL !!!\n", __func__)); + } + + /* + Only APs that comply with 802.11h or 802.11k are required to include + the Power Constraint element (IE=32) and + the TPC Report element (IE=35) and + the VHT Transmit Power Envelope element (IE=195) + in beacon frames and probe response frames + */ + if ((wdev->channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) +#ifdef DOT11K_RRM_SUPPORT + || IS_RRM_ENABLE(wdev) +#endif /* DOT11K_RRM_SUPPORT */ + ) { + /* prepare power constraint IE */ + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 3, PowerConstraintIE, END_OF_ARGS); + FrameLen += TmpLen; + /* prepare TPC Report IE */ + InsertTpcReportIE(pAd, + pOutBuffer + FrameLen, + &FrameLen, + GetMaxTxPwr(pAd), + 0); +#ifdef DOT11_VHT_AC + + /* prepare VHT Transmit Power Envelope IE */ + if (WMODE_CAP_AC(PhyMode)) { + ULONG TmpLen; + UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; + UINT8 ie_len; + VHT_TXPWR_ENV_IE txpwr_env; + + ie_len = build_vht_txpwr_envelope(pAd, wdev, (UCHAR *)&txpwr_env); + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 1, &vht_txpwr_env_ie, + 1, &ie_len, + ie_len, &txpwr_env, + END_OF_ARGS); + FrameLen += TmpLen; + } + +#endif /* DOT11_VHT_AC */ + } + + /* NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); */ +#ifdef EXT_BUILD_CHANNEL_LIST + BuildBeaconChList(pAd, wdev, TmpFrame, &TmpLen2); +#else + { + UINT i = 0; + UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, wdev->PhyMode, wdev, op_ht_bw); + + if (pChDesc != NULL) { + for (i = 0; pChDesc[i].FirstChannel != 0; i++) { + MakeOutgoingFrame(TmpFrame + TmpLen2, + &TmpLen, + 1, + &pChDesc[i].FirstChannel, + 1, + &pChDesc[i].NumOfCh, + 1, + &MaxTxPower, + END_OF_ARGS); + TmpLen2 += TmpLen; + } + } + } +#endif /* EXT_BUILD_CHANNEL_LIST */ +#ifdef DOT11K_RRM_SUPPORT + + if (IS_RRM_ENABLE(wdev)) { + UCHAR reg_class = get_regulatory_class(pAd, mbss->wdev.channel, mbss->wdev.PhyMode, &mbss->wdev); + + TmpLen2 = 0; + NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); + RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2, wdev->PhyMode, reg_class); + } + +#endif /* DOT11K_RRM_SUPPORT */ +#ifdef MBO_SUPPORT + if (IS_MBO_ENABLE(wdev)) + Environment = MBO_AP_USE_GLOBAL_OPERATING_CLASS; +#endif /* MBO_SUPPORT */ + /* 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, + 1, &pAd->CommonCfg.CountryCode[0], + 1, &pAd->CommonCfg.CountryCode[1], + 1, &Environment, + TmpLen2+1, TmpFrame, + END_OF_ARGS); + } else { + UCHAR TmpLen3 = TmpLen2 + 3; + + MakeOutgoingFrame(pOutBuffer + FrameLen, + &TmpLen, + 1, &CountryIe, + 1, &TmpLen3, + 1, &pAd->CommonCfg.CountryCode[0], + 1, &pAd->CommonCfg.CountryCode[1], + 1, &Environment, + TmpLen2, TmpFrame, + END_OF_ARGS); + } + + FrameLen += TmpLen; + } /* Country IE - */ +#endif +#ifdef A_BAND_SUPPORT + + /* add Channel switch announcement IE */ + if ((wdev->channel > 14) + && (pAd->CommonCfg.bIEEE80211H == 1) + && (pDot11h->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, &wdev->channel, + 1, &pDot11h->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, wdev->channel, wdev->PhyMode, wdev); + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, + END_OF_ARGS); + FrameLen += TmpLen; + } + +#endif /* DOT11_N_SUPPORT */ + } + +#endif /* A_BAND_SUPPORT */ +#ifdef DOT11_N_SUPPORT + + if (WMODE_CAP_N(PhyMode) && + (wdev->DesiredHtPhyInfo.bHtEnable)) { +#ifdef DOT11_VHT_AC + struct _build_ie_info vht_ie_info; +#endif /*DOT11_VHT_AC*/ + if (pAd->bBroadComHT == TRUE) { + struct _build_ie_info ie_info; + + ie_info.frame_subtype = SUBTYPE_PROBE_RSP; + ie_info.channel = wdev->channel; + ie_info.phy_mode = wdev->PhyMode; + ie_info.wdev = wdev; + ie_info.is_draft_n_type = TRUE; + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_ht_ies(pAd, &ie_info); + } +#ifdef DOT11_VHT_AC + vht_ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + vht_ie_info.frame_subtype = SUBTYPE_PROBE_RSP; + vht_ie_info.channel = wdev->channel; + vht_ie_info.phy_mode = wdev->PhyMode; + vht_ie_info.wdev = wdev; +#if defined(TXBF_SUPPORT) && defined(VHT_TXBF_SUPPORT) + ucETxBfCap = wlan_config_get_etxbf(wdev); + + if (HcIsBfCapSupport(wdev) == FALSE) + wlan_config_set_etxbf(wdev, SUBF_OFF); + +#endif /* TXBF_SUPPORT && VHT_TXBF_SUPPORT */ + FrameLen += build_vht_ies(pAd, &vht_ie_info); +#if defined(TXBF_SUPPORT) && defined(VHT_TXBF_SUPPORT) + wlan_config_set_etxbf(wdev, ucETxBfCap); +#endif /* TXBF_SUPPORT && VHT_TXBF_SUPPORT */ +#endif /* DOT11_VHT_AC */ + } + +#endif /* DOT11_N_SUPPORT */ +#ifdef WSC_INCLUDED + ie_info.frame_buf = (UCHAR *)(pOutBuffer + FrameLen); + FrameLen += build_wsc_ie(pAd, &ie_info); +#endif /* WSC_INCLUDED */ +#ifdef DOT11R_FT_SUPPORT + + /* The Mobility Domain information element (MDIE) is present in Probe- + ** Request frame when dot11FastBssTransitionEnable is set to true. */ + if (pAd->ApCfg.MBSSID[apidx].wdev.FtCfg.FtCapFlag.Dot11rFtEnable) { + PFT_CFG pFtCfg = &pAd->ApCfg.MBSSID[apidx].wdev.FtCfg; + FT_CAP_AND_POLICY FtCap; + + FtCap.field.FtOverDs = pFtCfg->FtCapFlag.FtOverDs; + FtCap.field.RsrReqCap = pFtCfg->FtCapFlag.RsrReqCap; + FT_InsertMdIE(pAd, pOutBuffer + FrameLen, &FrameLen, + pFtCfg->FtMdId, FtCap); + } + +#endif /* DOT11R_FT_SUPPORT */ + /* + add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back + Byte0.b3=1 for rssi-feedback + */ + FrameLen += build_vendor_ie(pAd, wdev, (pOutBuffer + FrameLen), VIE_PROBE_RESP + ); +#ifdef MBO_SUPPORT + if (IS_MBO_ENABLE(wdev)) { + MakeMboOceIE(pAd, wdev, pOutBuffer+FrameLen, &FrameLen, MBO_FRAME_TYPE_PROBE_RSP); + } +#endif /* MBO_SUPPORT */ + { + /* Question to Rorscha: bit4 in old chip is used? but currently is using for 2.4G 256QAM */ +#ifdef RSSI_FEEDBACK + UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; + ULONG TmpLen; + + if (ProbeReqParam.bRequestRssi == TRUE) { + MAC_TABLE_ENTRY *pEntry = NULL; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", + PRINT_MAC(ProbeReqParam.Addr2))); + RalinkSpecificIe[5] |= 0x8; + pEntry = MacTableLookup(pAd, ProbeReqParam.Addr2); + + if (pEntry != NULL) { + RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi[0]; + RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi[1]; + RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi[2]; + } + } + + MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, + 9, RalinkSpecificIe, + END_OF_ARGS); + FrameLen += TmpLen; +#endif /* RSSI_FEEDBACK */ + } + /* 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(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 + ========================================================================== + */ + + +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; + PMAC_TABLE_ENTRY pEntry = NULL; + UCHAR Channel = 0; + struct freq_oper oper; + + RETURN_IF_PAD_NULL(pAd); + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); + + if (ie_list == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Allocate ie_list fail!!!\n", __func__)); + 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) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Allocate VarIE fail!!!\n", __func__)); + goto LabelErr; + } + + pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; + pVIE->Length = 0; + pRates = (PUCHAR)Rates; + /* Init the DUT's working channel from RX'D param first, actually we need to get the accurate Channel from wdev */ + Channel = Elem->Channel; + /* PeerBeaconAndProbeRspSanity() may overwrite ie_list->Channel if beacon or probe resp contain IE_DS_PARM */ + ie_list->Channel = Elem->Channel; + RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_2)); + + if (PeerBeaconAndProbeRspSanity(pAd, + Elem->Msg, + Elem->MsgLen, + Elem->Channel, + ie_list, + &LenVIE, + pVIE, + FALSE, + FALSE)) { + if (VALID_UCAST_ENTRY_WCID(pAd, Elem->Wcid)) { + pEntry = MacTableLookup(pAd, ie_list->Addr2);/* Found the pEntry from Peer Bcn Content */ + + if (!pEntry || !pEntry->wdev) + goto __End_Of_APPeerBeaconAction; + + Channel = pEntry->wdev->channel; + } + + hc_radio_query_by_channel(pAd, Channel, &oper); +#ifdef APCLI_SUPPORT + ApCliCheckPeerExistence(pAd, ie_list->Ssid, ie_list->SsidLen, ie_list->Channel); +#endif /* APCLI_SUPPORT */ + + /* ignore BEACON not in this channel */ + if (ie_list->Channel != Channel +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + && (pAd->CommonCfg.bOverlapScanning == FALSE) +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ +#ifdef CFG80211_MULTI_STA + && (!RTMP_CFG80211_MULTI_STA_ON(pAd, pAd->cfg80211_ctrl.multi_sta_net_dev)) +#endif /* CFG80211_MULTI_STA */ + ) + goto __End_Of_APPeerBeaconAction; + +#ifdef IDS_SUPPORT + /* Conflict SSID detection */ + RTMPConflictSsidDetection(pAd, (PUCHAR)ie_list->Ssid, ie_list->SsidLen, + (CHAR)Elem->rssi_info.raw_rssi[0], + (CHAR)Elem->rssi_info.raw_rssi[1], + (CHAR)Elem->rssi_info.raw_rssi[2]); +#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, Channel); + +#endif /* DOT11_N_SUPPORT */ +#ifdef DOT11_N_SUPPORT + + if (Channel <= 14 + && (oper.ht_bw == HT_BW_40) +#ifdef DOT11N_DRAFT3 + && (pAd->CommonCfg.bOverlapScanning == FALSE) +#endif /* DOT11N_DRAFT3 */ + ) { +#if defined(P2P_SUPPORT) || defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) + + if (OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED) && + RTMP_CFG80211_MULTI_STA_ON(pAd, pAd->cfg80211_ctrl.multi_sta_net_dev) + ) { + if (ie_list->Channel != Channel) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_INFO, + ("Channel=%d is not equal as band Channel = %d.\n", + ie_list->Channel, Channel)); + } + } else +#endif /* P2P_SUPPORT || RT_CFG80211_P2P_CONCURRENT_DEVICE */ + if (((oper.cen_ch_1 + 2) != ie_list->Channel) && + ((oper.cen_ch_1 - 2) != ie_list->Channel)) { + /* + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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)); + */ + /* EZ_DEBUG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF,("APPeerBeaconAction 4\n")); */ + /* EZ_DEBUG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF,("Central channel = %d\n", HcGetCentralChByRf(pAd,RFIC_24GHZ))); */ + goto __End_Of_APPeerBeaconAction; + } + } else { + if (ie_list->Channel != 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 ((ie_list->HtCapabilityLen == 0) && (RealRssi > OBSS_BEACON_RSSI_THRESHOLD)) { + pAd->ApCfg.LastNoneHTOLBCDetectTime = pAd->Mlme.Now32; + } + +#endif /* DOT11_N_SUPPORT */ +#ifdef APCLI_SUPPORT + + if (VALID_UCAST_ENTRY_WCID(pAd, Elem->Wcid)) { + pEntry = &pAd->MacTab.Content[Elem->Wcid]; + + if (pEntry && + (IS_ENTRY_APCLI(pEntry) || IS_ENTRY_REPEATER(pEntry)) && + (pEntry->func_tb_idx < MAX_APCLI_NUM)) { + PAPCLI_STRUCT pApCliEntry = NULL; + + pApCliEntry = &pAd->ApCfg.ApCliTab[pEntry->func_tb_idx]; + pApCliEntry->ApCliRcvBeaconTime = pAd->Mlme.Now32; + AdjustBwToSyncAp(pAd, ie_list, pApCliEntry->MacTabWCID, pEntry->func_tb_idx); + +#ifdef APCLI_CERT_SUPPORT + if (pAd->bApCliCertTest == TRUE) { + UCHAR RegClass; + OVERLAP_BSS_SCAN_IE BssScan; + BOOLEAN brc; +#ifdef DOT11_N_SUPPORT + ADD_HT_INFO_IE *aux_add_ht = &pApCliEntry->MlmeAux.AddHtInfo; + ADD_HT_INFO_IE *addht; + BOOLEAN bNonGFExist = (aux_add_ht->AddHtInfo2.NonGfPresent) ? TRUE : FALSE; + UINT16 OperationMode = aux_add_ht->AddHtInfo2.OperaionMode; +#endif /* DOT11_N_SUPPORT */ + + brc = PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &BssScan, &RegClass); + + if (brc == TRUE) { + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = le2cpu16(BssScan.TriggerScanInt); /*APBssScan.TriggerScanInt[1] * 256 + APBssScan.TriggerScanInt[0];*/ + + /*DBGPRINT(RT_DEBUG_ERROR,("Update Dot11BssWidthTriggerScanInt=%d\n", pAd->CommonCfg.Dot11BssWidthTriggerScanInt)); */ + /* out of range defined in MIB... So fall back to default value.*/ + if ((pAd->CommonCfg.Dot11BssWidthTriggerScanInt < 10) || (pAd->CommonCfg.Dot11BssWidthTriggerScanInt > 900)) + pAd->CommonCfg.Dot11BssWidthTriggerScanInt = 900; + } +#ifdef DOT11_N_SUPPORT + /* check Ht protection mode. and adhere to the Non-GF device indication by AP. */ + if (ie_list->AddHtInfoLen != 0) { + if ((ie_list->AddHtInfo.AddHtInfo2.OperaionMode != OperationMode) + || (ie_list->AddHtInfo.AddHtInfo2.NonGfPresent != bNonGFExist)) { + aux_add_ht->AddHtInfo2.OperaionMode = ie_list->AddHtInfo.AddHtInfo2.OperaionMode; + aux_add_ht->AddHtInfo2.NonGfPresent = ie_list->AddHtInfo.AddHtInfo2.NonGfPresent; + + pApCliEntry->wdev.protection = SET_PROTECT(ie_list->AddHtInfo.AddHtInfo2.OperaionMode); + + OperationMode = aux_add_ht->AddHtInfo2.OperaionMode; + bNonGFExist = (aux_add_ht->AddHtInfo2.NonGfPresent) ? TRUE : FALSE; + + if (bNonGFExist) { + pApCliEntry->wdev.protection |= SET_PROTECT(GREEN_FIELD_PROTECT); + } else { + pApCliEntry->wdev.protection &= ~(SET_PROTECT(GREEN_FIELD_PROTECT)); + } + + if (pApCliEntry->wdev.channel > 14) { + /* always no BG protection in A-band. + * falsely happened when switching A/G band to a dual-band AP */ + pApCliEntry->wdev.protection &= ~(SET_PROTECT(ERP)); + } + addht = wlan_operate_get_addht(&pApCliEntry->wdev); + if (addht) { /* sync addht information into wlan operation addht */ + *addht = pApCliEntry->MlmeAux.AddHtInfo; + } + + AsicUpdateProtect(pAd); + + MTWF_LOG(DBG_CAT_CLIENT, DBG_SUBCAT_ALL, DBG_LVL_WARN, + ("SYNC - AP changed N OperaionMode to %d, my protection to %d\n", + OperationMode, pApCliEntry->wdev.protection)); + } + } +#endif /* DOT11_N_SUPPORT */ + } +#endif /* APCLI_CERT_SUPPORT */ + } + + if (pEntry && ie_list->NewChannel != 0) + ApCliPeerCsaAction(pAd, pEntry->wdev, ie_list); + } + +#endif /* APCLI_SUPPORT */ +#ifdef WDS_SUPPORT + + if (pAd->WdsTab.Mode != WDS_DISABLE_MODE) { + if (pAd->WdsTab.flg_wds_init) { + MAC_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 && (pEntry->bAutoTxRateSwitch == TRUE)) + WdsPeerBeaconProc(pAd, pEntry, MaxSupportedRate, RatesLen, bWmmCapable, ie_list); + } else + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_INFO, ("%s(), ERROR!! Beacon comes before wds_init\n", __func__)); + } + +#endif /* WDS_SUPPORT */ + if (Elem->wdev != NULL) { + bss_coex_insert_effected_ch_list(pAd, Channel, ie_list, Elem->wdev); + } else { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(), Elem->wdev = NULL\n", __func__)); + } + + } + + /* 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) { + UCHAR BandIdx = BAND0; + AUTO_CH_CTRL *pAutoChCtrl = NULL; + if (ie_list->Channel == pAd->ApCfg.AutoChannel_Channel) { + if (Elem->wdev != NULL) + BandIdx = HcGetBandByWdev(Elem->wdev); + else + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(), Elem->wdev = NULL\n", __func__)); + + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + if (pAutoChCtrl->pChannelInfo && AutoChBssSearchWithSSID(pAd, ie_list->Bssid, (PUCHAR)ie_list->Ssid, ie_list->SsidLen, ie_list->Channel, Elem->wdev) == BSS_NOT_FOUND) + pAutoChCtrl->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, Elem->wdev); + } + } +#endif /* CONFIG_AP_SUPPORT */ + /*#endif // AUTO_CH_SELECT_ENHANCE */ +LabelErr: + + if (VarIE != NULL) + os_free_mem(VarIE); + + if (ie_list != NULL) + os_free_mem(ie_list); +} + +#ifdef AP_SCAN_SUPPORT +/* + ========================================================================== + Description: + ========================================================================== + */ +VOID APInvalidStateWhenScan(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) +{ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AP SYNC - Scan Timeout\n")); + MlmeEnqueue(pAd, AP_SYNC_STATE_MACHINE, APMT2_SCAN_TIMEOUT, 0, NULL, (ULONG)pAd->ApCfg.ScanReqwdev); + RTMP_MLME_HANDLER(pAd); +} + +/* + ========================================================================== + Description: + Scan timeout procedure. basically add channel index by 1 and rescan + ========================================================================== + */ +VOID APScanTimeoutAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) +{ + UCHAR BandIdx; + CHANNEL_CTRL *pChCtrl; + struct wifi_dev *wdev = NULL; + if (pAd->ApCfg.ScanReqwdev) + wdev = pAd->ApCfg.ScanReqwdev; + else + wdev = &pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev; + + BandIdx = HcGetBandByWdev(wdev); + pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + pAd->ScanCtrl.Channel = FindScanChannel(pAd, pAd->ScanCtrl.Channel, wdev); + + /* only scan the channel which binding band supported */ + if (pAd->ApCfg.ScanReqwdev != NULL && (pAd->ScanCtrl.Channel != 0)) { + while ((WMODE_CAP_2G(pAd->ApCfg.ScanReqwdev->PhyMode) && pAd->ScanCtrl.Channel > 14) || + (WMODE_CAP_5G(pAd->ApCfg.ScanReqwdev->PhyMode) && pAd->ScanCtrl.Channel <= 14)) { + pAd->ScanCtrl.Channel = FindScanChannel(pAd, pAd->ScanCtrl.Channel, wdev); + + if (pAd->ScanCtrl.Channel == 0) + break; + } + } + +#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, wdev); + /* move to next channel */ + pAd->ApCfg.current_channel_index++; + + if (pAd->ApCfg.current_channel_index < pChCtrl->ChListNum) + pAd->ApCfg.AutoChannel_Channel = pChCtrl->ChList[pAd->ApCfg.current_channel_index].Channel; + } + } +#endif /* CONFIG_AP_SUPPORT */ + ScanNextChannel(pAd, OPMODE_AP, pAd->ApCfg.ScanReqwdev); +} + +#ifdef CON_WPS +VOID APMlmeScanCompleteAction(PRTMP_ADAPTER pAd, MLME_QUEUE_ELEM *Elem) +{ + PWSC_CTRL pWscControl; + PWSC_CTRL pApCliWscControl; + UCHAR apidx; + INT IsAPConfigured; + struct wifi_dev *wdev; + BOOLEAN bNeedSetPBCTimer = TRUE; +#if defined(CON_WPS) + INT currIfaceIdx = 0; + UCHAR ifIdx; + UCHAR oppifIdx; + struct wifi_dev *ConWpsdev = NULL; + PWSC_CTRL pTriggerApCliWscControl; + PWSC_CTRL pOpposApCliWscControl; + PRTMP_ADAPTER pOpposAd; + BOOLEAN bTwoCardConWPS = FALSE; + UCHAR apcli_idx; +#ifdef MULTI_INF_SUPPORT /* Index 0 for 2.4G, 1 for 5Ghz Card */ + UINT opposIfaceIdx = !multi_inf_get_idx(pAd); +#endif /* MULTI_INF_SUPPORT */ +#endif /*CON_WPS*/ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("AP SYNC - APMlmeScanCompleteAction\n")); +#if defined(CON_WPS) + pOpposAd = NULL; + pOpposApCliWscControl = NULL; + pTriggerApCliWscControl = NULL; +#ifdef MULTI_INF_SUPPORT /* Index 0 for 2.4G, 1 for 5Ghz Card */ + pOpposAd = (PRTMP_ADAPTER)adapt_list[opposIfaceIdx]; +#endif /* MULTI_INF_SUPPORT */ +#endif /*CON_WPS*/ + + /* If We catch the SR=TRUE in last scan_res, stop the AP Wsc SM */ + if (Elem) { + ifIdx = (USHORT)(Elem->Priv); + + if (ifIdx < pAd->ApCfg.ApCliNum) + ConWpsdev = &(pAd->ApCfg.ApCliTab[ifIdx].wdev); + + if (ConWpsdev == NULL) + return; + } else + return; + + if (ifIdx == BSS0) + oppifIdx = BSS1; + else if (ifIdx == BSS1) + oppifIdx = BSS0; + else + return; + + if (ConWpsdev) { + pApCliWscControl = &pAd->ApCfg.ApCliTab[ifIdx].wdev.WscControl; + pAd->ApCfg.ApCliTab[ifIdx].ConWpsApCliModeScanDoneStatus = CON_WPS_APCLI_SCANDONE_STATUS_FINISH; + } + + if (pOpposAd) { + for (apcli_idx = 0; apcli_idx < pOpposAd->ApCfg.ApCliNum; apcli_idx++) { + if (pOpposAd->ApCfg.ApCliTab[apcli_idx].wdev.WscControl.conWscStatus == CON_WPS_STATUS_APCLI_RUNNING) { + pOpposApCliWscControl = &pOpposAd->ApCfg.ApCliTab[apcli_idx].wdev.WscControl; + bTwoCardConWPS = TRUE; + break; + } + } + + if (apcli_idx == pOpposAd->ApCfg.ApCliNum) { + pOpposApCliWscControl = NULL; + bTwoCardConWPS = FALSE; + } + } + + if (bTwoCardConWPS == FALSE) { + for (apcli_idx = 0; apcli_idx < pAd->ApCfg.ApCliNum; apcli_idx++) { + if (apcli_idx == ifIdx) + continue; + else if (pAd->ApCfg.ApCliTab[apcli_idx].wdev.WscControl.conWscStatus == CON_WPS_STATUS_APCLI_RUNNING) { + pOpposApCliWscControl = &pAd->ApCfg.ApCliTab[apcli_idx].wdev.WscControl; + break; + } + } + } + + if (pOpposAd && pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_AUTO) { /* 2.2G and 5G must trigger scan */ + if (pOpposAd && bTwoCardConWPS) { + for (apcli_idx = 0; apcli_idx < pAd->ApCfg.ApCliNum; apcli_idx++) { + if (pOpposAd->ApCfg.ApCliTab[apcli_idx].ConWpsApCliModeScanDoneStatus == CON_WPS_APCLI_SCANDONE_STATUS_ONGOING) { + pApCliWscControl->ConWscApcliScanDoneCheckTimerRunning = TRUE; + RTMPSetTimer(&pApCliWscControl->ConWscApcliScanDoneCheckTimer, 1000); + return; + } + } + } + } else { + for (apcli_idx = 0; apcli_idx < pAd->ApCfg.ApCliNum; apcli_idx++) { + if (pAd->ApCfg.ApCliTab[apcli_idx].ConWpsApCliModeScanDoneStatus == CON_WPS_APCLI_SCANDONE_STATUS_ONGOING) { + pApCliWscControl->ConWscApcliScanDoneCheckTimerRunning = TRUE; + + if (pAd->Mlme.ApSyncMachine.CurrState == 0) + WscScanExec(pAd, &(pAd->ApCfg.ApCliTab[apcli_idx].wdev.WscControl)); + + RTMPSetTimer(&pApCliWscControl->ConWscApcliScanDoneCheckTimer, 1000); + return; + } + } + } + + if ((pOpposApCliWscControl) == NULL && pOpposAd) { + pOpposApCliWscControl = &pOpposAd->ApCfg.ApCliTab[BSS0].WscControl; + bTwoCardConWPS = TRUE; + } + + + if (pOpposApCliWscControl == NULL) { + pOpposApCliWscControl = &pAd->ApCfg.ApCliTab[oppifIdx].WscControl; + bTwoCardConWPS = FALSE; + } + + WscPBCBssTableSort(pAd, pApCliWscControl); +#if defined(CON_WPS) +#ifdef MULTI_INF_SUPPORT /* Index 0 for 2.4G, 1 for 5Ghz Card */ + + if (pOpposAd && bTwoCardConWPS) { + if (pOpposApCliWscControl) + WscPBCBssTableSort(pOpposAd, pOpposApCliWscControl); + } else +#endif /* MULTI_INF_SUPPORT */ + { + if (pOpposApCliWscControl) + WscPBCBssTableSort(pAd, pOpposApCliWscControl); + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("[Iface_Idx: %d] Scan_Completed!!! In APMlmeScanCompleteAction\n", currIfaceIdx)); +#endif /*CON_WPS*/ +#ifdef MULTI_INF_SUPPORT + currIfaceIdx = multi_inf_get_idx(pAd); +#else + currIfaceIdx = (pApCliWscControl->EntryIfIdx & 0x0F); +#endif /* MULTI_INF_SUPPORT */ + + for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { + wdev = &pAd->ApCfg.MBSSID[apidx].wdev; + pWscControl = &wdev->WscControl; + IsAPConfigured = pWscControl->WscConfStatus; + + if ((pWscControl->WscConfMode != WSC_DISABLE) && + (pApCliWscControl->WscPBCBssCount > 0)) { + if (pWscControl->bWscTrigger == TRUE) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s CON_WPS[%d]: Stop the AP Wsc Machine\n", __func__, apidx)); + 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); + UpdateBeaconHandler(pAd, wdev, BCN_UPDATE_IE_CHG); + WscStop(pAd, FALSE, pWscControl); + } + + WscConWpsStop(pAd, FALSE, pWscControl); + } + + continue; + } + + if (bTwoCardConWPS) { + if (pApCliWscControl->WscPBCBssCount == 1 && pOpposApCliWscControl->WscPBCBssCount == 1) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[Iface_Idx: %d] AutoPreferIface = %d\n" + , currIfaceIdx, pAd->ApCfg.ConWpsApcliAutoPreferIface)); + + if (currIfaceIdx == 0) { + if (pAd->ApCfg.ConWpsApcliAutoPreferIface == CON_WPS_APCLI_AUTO_PREFER_IFACE1) { + bNeedSetPBCTimer = FALSE; + WscStop(pAd, TRUE, pApCliWscControl); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!! STOP APCLI = %d !!\n", currIfaceIdx)); + } else { + WscConWpsStop(pAd, TRUE, pApCliWscControl); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!! STOP APCLI = %d !!\n", !currIfaceIdx)); + } + } else if (currIfaceIdx == 1) { + if (pAd->ApCfg.ConWpsApcliAutoPreferIface == CON_WPS_APCLI_AUTO_PREFER_IFACE0) { + bNeedSetPBCTimer = FALSE; + WscStop(pAd, TRUE, pApCliWscControl); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!!STOP APCLI = %d !!\n", currIfaceIdx)); + } else { + WscConWpsStop(pAd, TRUE, pApCliWscControl); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!! STOP APCLI = %d !!\n", !currIfaceIdx)); + } + } + } + + if (pApCliWscControl->WscPBCBssCount == 1 && pOpposApCliWscControl->WscPBCBssCount == 0) { + WscConWpsStop(pAd, TRUE, pApCliWscControl); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!! (5)STOP APCLI = %d !!\n", !currIfaceIdx)); + } + } else { + currIfaceIdx = (pApCliWscControl->EntryIfIdx & 0x0F); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[Iface_Idx: %d] Registrar_Found, APCLI_Auto_Mode PreferIface = %d\n", + currIfaceIdx, pAd->ApCfg.ConWpsApcliAutoPreferIface)); + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[Iface_Idx: %d] WscPBCBssCount = %d, opposWscPBCBssCount = %d\n", + currIfaceIdx, + pApCliWscControl->WscPBCBssCount, + pOpposApCliWscControl->WscPBCBssCount)); + + if (pApCliWscControl->WscPBCBssCount == 1 && pOpposApCliWscControl->WscPBCBssCount == 1) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("[Iface_Idx: %d] AutoPreferIface = %d\n" + , currIfaceIdx, pAd->ApCfg.ConWpsApcliAutoPreferIface)); + + if (pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_AUTO) { + if (currIfaceIdx != pAd->ApCfg.ConWpsApcliAutoPreferIface) { + bNeedSetPBCTimer = FALSE; + WscStop(pAd, TRUE, pApCliWscControl); + WscConWpsStop(pAd, TRUE, pOpposApCliWscControl); + pTriggerApCliWscControl = pOpposApCliWscControl; + } else { + WscConWpsStop(pAd, TRUE, pApCliWscControl); + pTriggerApCliWscControl = pApCliWscControl; + } + } else if (pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_2G) { + WscConWpsStop(pAd, TRUE, &(pAd->ApCfg.ApCliTab[BSS0].wdev.WscControl)); + pTriggerApCliWscControl = &(pAd->ApCfg.ApCliTab[BSS0].wdev.WscControl); + } else if (pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_5G) { + WscConWpsStop(pAd, TRUE, &(pAd->ApCfg.ApCliTab[BSS1].wdev.WscControl)); + pTriggerApCliWscControl = &(pAd->ApCfg.ApCliTab[BSS1].wdev.WscControl); + } + } + + /*Only Found 1 Registrar at one interface*/ + if (pApCliWscControl->WscPBCBssCount == 1 && pOpposApCliWscControl->WscPBCBssCount == 0) { + if (pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_AUTO) { + WscConWpsStop(pAd, TRUE, pApCliWscControl); + pTriggerApCliWscControl = pApCliWscControl; + } else if (pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_2G) { + if (currIfaceIdx == 0) { + WscConWpsStop(pAd, TRUE, pApCliWscControl); + pTriggerApCliWscControl = pApCliWscControl; + } + } else if (pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_5G) { + if (currIfaceIdx == 1) { + WscConWpsStop(pAd, TRUE, pApCliWscControl); + pTriggerApCliWscControl = pApCliWscControl; + } + } + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!! (5)STOP APCLI = %d !!\n", !currIfaceIdx)); + } else if (pApCliWscControl->WscPBCBssCount == 0 && pOpposApCliWscControl->WscPBCBssCount == 1) { + if (pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_AUTO) { + WscConWpsStop(pAd, TRUE, pOpposApCliWscControl); + pTriggerApCliWscControl = pOpposApCliWscControl; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("!! (6)STOP APCLI = %d !!\n", !currIfaceIdx)); + } else { + if ((pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_2G) && (pOpposApCliWscControl->EntryIfIdx & 0x0F) == 0) { + WscConWpsStop(pAd, TRUE, pOpposApCliWscControl); + pTriggerApCliWscControl = pOpposApCliWscControl; + } else if ((pAd->ApCfg.ConWpsApCliMode == CON_WPS_APCLI_BAND_5G) && (pOpposApCliWscControl->EntryIfIdx & 0x0F) == 1) { + WscConWpsStop(pAd, TRUE, pOpposApCliWscControl); + pTriggerApCliWscControl = pOpposApCliWscControl; + } + } + } + } + + if (bTwoCardConWPS) { + if (bNeedSetPBCTimer && pApCliWscControl->WscPBCTimerRunning == FALSE) { + if (pApCliWscControl->bWscTrigger) { + pApCliWscControl->WscPBCTimerRunning = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("!! TwoCardConWPS Trigger %s WPS!!\n", (pApCliWscControl->IfName))); + RTMPSetTimer(&pApCliWscControl->WscPBCTimer, 1000); + } + } + } else { + if (pTriggerApCliWscControl != NULL && + (pTriggerApCliWscControl->WscPBCTimerRunning == FALSE) && + (pTriggerApCliWscControl->bWscTrigger == TRUE)) { + pTriggerApCliWscControl->WscPBCTimerRunning = TRUE; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("!! One Card DBDC Trigger %s WPS!!\n", (pTriggerApCliWscControl->IfName))); + RTMPSetTimer(&pTriggerApCliWscControl->WscPBCTimer, 1000); + } else { + if (pApCliWscControl && pApCliWscControl->WscPBCTimerRunning == FALSE && + (pApCliWscControl->bWscTrigger == TRUE)) { + pAd->ApCfg.ApCliTab[(pApCliWscControl->EntryIfIdx & 0x0F)].ConWpsApCliModeScanDoneStatus = CON_WPS_APCLI_SCANDONE_STATUS_ONGOING; + pApCliWscControl->WscPBCTimerRunning = TRUE; + RTMPSetTimer(&pApCliWscControl->WscPBCTimer, 1000); + } + + if (pOpposApCliWscControl && pOpposApCliWscControl->WscPBCTimerRunning == FALSE && + (pOpposApCliWscControl->bWscTrigger == TRUE)) { + pAd->ApCfg.ApCliTab[(pOpposApCliWscControl->EntryIfIdx & 0x0F)].ConWpsApCliModeScanDoneStatus = CON_WPS_APCLI_SCANDONE_STATUS_ONGOING; + pOpposApCliWscControl->WscPBCTimerRunning = TRUE; + RTMPSetTimer(&pOpposApCliWscControl->WscPBCTimer, 1000); + } + } + } +} +#endif /* CON_WPS*/ + +/* + ========================================================================== + Description: + MLME SCAN req state machine procedure + ========================================================================== + */ +VOID APMlmeScanReqAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) +{ + BOOLEAN Cancelled; + UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType; + struct wifi_dev *wdev = (struct wifi_dev *)Elem->Priv; +#ifdef CONFIG_AP_SUPPORT + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); +#endif + + /* first check the parameter sanity */ + if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, (PCHAR)Ssid, &SsidLen, &ScanType)) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("AP SYNC - MlmeScanReqAction\n")); + NdisGetSystemUpTime(&pAd->ApCfg.LastScanTime); + RTMPCancelTimer(&pAd->ScanCtrl.APScanTimer, &Cancelled); + /* record desired BSS parameters */ + pAd->ScanCtrl.BssType = BssType; + pAd->ScanCtrl.ScanType = ScanType; + pAd->ScanCtrl.SsidLen = SsidLen; + NdisMoveMemory(pAd->ScanCtrl.Ssid, Ssid, SsidLen); + + /* start from the first channel */ + if (pAd->ScanCtrl.PartialScan.bScanning == TRUE) { + /* only scan the channel which binding band supported */ + pAd->ApCfg.ScanReqwdev = (struct wifi_dev *)Elem->Priv; +find_next_channel: + pAd->ScanCtrl.Channel = FindScanChannel(pAd, 0, wdev); + + if (pAd->ScanCtrl.PartialScan.bScanning == TRUE) { + if ((WMODE_CAP_2G(pAd->ApCfg.ScanReqwdev->PhyMode) && pAd->ScanCtrl.Channel > 14) || + (WMODE_CAP_5G(pAd->ApCfg.ScanReqwdev->PhyMode) && pAd->ScanCtrl.Channel <= 14)) { + pAd->ScanCtrl.Channel = FindScanChannel(pAd, pAd->ScanCtrl.Channel, wdev); + + if (pAd->ScanCtrl.Channel == 0) { + if (pAd->ScanCtrl.PartialScan.bScanning == TRUE) { + pAd->ScanCtrl.PartialScan.NumOfChannels = DEFLAUT_PARTIAL_SCAN_CH_NUM; + goto find_next_channel; + } + } + } + } + } else { + pAd->ScanCtrl.Channel = FindScanChannel(pAd, 0, wdev); + /* only scan the channel which binding band supported */ + pAd->ApCfg.ScanReqwdev = (struct wifi_dev *)Elem->Priv; + + if (pAd->ApCfg.ScanReqwdev != NULL) { + while ((WMODE_CAP_2G(pAd->ApCfg.ScanReqwdev->PhyMode) && pAd->ScanCtrl.Channel > 14) || + (WMODE_CAP_5G(pAd->ApCfg.ScanReqwdev->PhyMode) && pAd->ScanCtrl.Channel <= 14)) { + pAd->ScanCtrl.Channel = FindScanChannel(pAd, pAd->ScanCtrl.Channel, wdev); + + if (pAd->ScanCtrl.Channel == 0) + break; + } + } + } + +#ifdef CONFIG_AP_SUPPORT + IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { + if (pAd->ApCfg.bAutoChannelAtBootup == TRUE) { /* iwpriv set auto channel selection */ + APAutoChannelInit(pAd, wdev); + pAd->ApCfg.AutoChannel_Channel = pChCtrl->ChList[0].Channel; + } + } +#endif /* CONFIG_AP_SUPPORT */ + ScanNextChannel(pAd, OPMODE_AP, (struct wifi_dev *)Elem->Priv); + } else { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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(RTMP_ADAPTER *pAd, 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) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Alloc memory for ie_list fail!!!\n", __func__)); + return; + } + + NdisZeroMemory((UCHAR *)ie_list, sizeof(BCN_IE_LIST)); + /* allocate memory */ + os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); + + if (VarIE == NULL) { + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: Allocate memory fail!!!\n", __func__)); + 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, FALSE, FALSE)) { + ULONG Idx; + CHAR Rssi = -127; + MAC_TABLE_ENTRY *pEntry = NULL; + UCHAR Channel; + + pEntry = MacTableLookup(pAd, ie_list->Addr2);/* Found the pEntry from Peer Bcn Content */ + RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_2)); + + if (ie_list->Channel > 14) + Channel = HcGetChannelByRf(pAd, RFIC_5GHZ); + else + Channel = HcGetChannelByRf(pAd, RFIC_24GHZ); + + { + /* ignore BEACON not in this channel */ + if (ie_list->Channel != pAd->ScanCtrl.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))) */ + if ((pAd->ScanCtrl.ScanType == SCAN_2040_BSS_COEXIST) && + (pAd->ApCfg.ScanReqwdev->wdev_type == WDEV_TYPE_APCLI)) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s:Ignore BW 40->20\n", __func__)); + else + Handle_BSS_Width_Trigger_Events(pAd, Channel); + } + +#endif /* DOT11_N_SUPPORT */ +#ifdef IDS_SUPPORT + + /* Conflict SSID detection */ + if (ie_list->Channel == Channel) + RTMPConflictSsidDetection(pAd, ie_list->Ssid, ie_list->SsidLen, + Elem->rssi_info.raw_rssi[0], + Elem->rssi_info.raw_rssi[1], + Elem->rssi_info.raw_rssi[2]); + +#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 && Idx < MAX_LEN_OF_BSS_TABLE) + 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->rssi_info, RSSI_IDX_0), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1), + ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_2)); + + if ((RealRssi + pAd->BbpRssiToDbmDelta) > Rssi) + Rssi = RealRssi + pAd->BbpRssiToDbmDelta; + + Idx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, Rssi, LenVIE, pVIE); +#ifdef APCLI_SUPPORT +#ifdef APCLI_CERT_SUPPORT +#ifdef DOT11_N_SUPPORT +#ifdef DOT11N_DRAFT3 + { + struct wifi_dev *wdev = (struct wifi_dev *)Elem->wdev; + UCHAR BandIdx = HcGetBandByWdev(wdev); + CHANNEL_CTRL *pChCtrl = hc_get_channel_ctrl(pAd->hdev_ctrl, BandIdx); + UCHAR apcli2Gidx = 0; +#ifdef DBDC_MODE + if (pAd->CommonCfg.dbdc_mode) + apcli2Gidx = 1; +#endif + /* Check if this scan channel is the effeced channel */ + if (APCLI_IF_UP_CHECK(pAd, apcli2Gidx) && + (pAd->bApCliCertTest == TRUE) && + (pAd->CommonCfg.bBssCoexEnable == TRUE) + && ((ie_list->Channel > 0) && (ie_list->Channel <= 14))) { + int chListIdx; + + /* + First we find the channel list idx by the channel number + */ + for (chListIdx = 0; chListIdx < pChCtrl->ChListNum; chListIdx++) { + if (ie_list->Channel == pChCtrl->ChList[chListIdx].Channel) + break; + } + + if (chListIdx < pChCtrl->ChListNum) { + + /* + If this channel is effected channel for the 20/40 coex operation. Check the related IEs. + */ + if (pChCtrl->ChList[chListIdx].bEffectedChannel == TRUE) { + UCHAR RegClass; + OVERLAP_BSS_SCAN_IE BssScan; + /* Read Beacon's Reg Class IE if any. */ + PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &BssScan, &RegClass); + /* printk("\x1b[31m TriEventTableSetEntry \x1b[m\n"); */ + TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, ie_list->Bssid, &ie_list->HtCapability, ie_list->HtCapabilityLen, RegClass, ie_list->Channel); + } + } + } + } +#endif /* DOT11N_DRAFT3 */ +#endif /* DOT11_N_SUPPORT */ +#endif /* APCLI_CERT_SUPPORT */ +#endif /* APCLI_SUPPORT */ + + 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); + } + +#if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) + + if (RTMPEqualMemory(ie_list->Ssid, "DIRECT-", 7)) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s P2P_SCANNING: %s [%lu], channel =%d\n" + , __func__, ie_list->Ssid, Idx, Elem->Channel)); + + /* Determine primary channel by IE's DSPS rather than channel of received frame */ + if (ie_list->Channel != 0) + Elem->Channel = ie_list->Channel; + + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("APPeerBeaconAtScanAction : Update the SSID %s in Kernel Table, Elem->Channel=%u\n", ie_list->Ssid, Elem->Channel)); + RT_CFG80211_SCANNING_INFORM(pAd, Idx, /*ie_list->Channel*/Elem->Channel, (UCHAR *)Elem->Msg, Elem->MsgLen, RealRssi); +#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ +#ifdef APCLI_SUPPORT +#endif /* APCLI_SUPPORT */ + } + + /* 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) { + UCHAR BandIdx = HcGetBandByWdev(Elem->wdev); + AUTO_CH_CTRL *pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + if (AutoChBssSearchWithSSID(pAd, ie_list->Bssid, (PUCHAR)ie_list->Ssid, ie_list->SsidLen, ie_list->Channel, Elem->wdev) == BSS_NOT_FOUND) + pAutoChCtrl->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, Elem->wdev); + } + } +#endif /* CONFIG_AP_SUPPORT */ +LabelErr: + + if (VarIE != NULL) + os_free_mem(VarIE); + + if (ie_list != NULL) + os_free_mem(ie_list); +} + +/* + ========================================================================== + Description: + MLME Cancel the SCAN req state machine procedure + ========================================================================== + */ +VOID APScanCnclAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) +{ + BOOLEAN Cancelled; + + RTMPCancelTimer(&pAd->ScanCtrl.APScanTimer, &Cancelled); + pAd->ScanCtrl.Channel = 0; + ScanNextChannel(pAd, OPMODE_AP, pAd->ApCfg.ScanReqwdev); +} + +/* + ========================================================================== + 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( + PRTMP_ADAPTER pAd, + PNDIS_802_11_SSID pSsid, + UCHAR ScanType, + BOOLEAN ChannelSel) +{ + MLME_SCAN_REQ_STRUCT ScanReq; + struct wifi_dev *wdev = NULL; + INT BssIdx; + INT MaxNumBss = pAd->ApCfg.BssidNum; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { + /* + Still scanning, ignore this scan. + */ + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s: Scanning now!\n", __func__)); + return; + } + + AsicDisableSync(pAd, HW_BSSID_0); + + /* Disable beacon tx for all BSS */ + for (BssIdx = 0; BssIdx < MaxNumBss; BssIdx++) { + wdev = &pAd->ApCfg.MBSSID[BssIdx].wdev; + + if (wdev->bAllowBeaconing) + UpdateBeaconHandler(pAd, wdev, BCN_UPDATE_DISABLE_TX); + } + + /* Don't clear the scan table if we are doing partial scan */ + if ((pAd->ScanCtrl.PartialScan.bScanning == TRUE && pAd->ScanCtrl.PartialScan.LastScanChannel == 0) || + pAd->ScanCtrl.PartialScan.bScanning == FALSE) + BssTableInit(&pAd->ScanTab); + + pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; + RTMPZeroMemory(ScanReq.Ssid, MAX_LEN_OF_SSID); + ScanReq.SsidLen = 0; + + if ((pSsid) && (pSsid->SsidLength > 0) && (pSsid->SsidLength <= (NDIS_802_11_LENGTH_SSID))) { + 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); +} + +VOID ApSiteSurvey_by_wdev( + PRTMP_ADAPTER pAd, + PNDIS_802_11_SSID pSsid, + UCHAR ScanType, + BOOLEAN ChannelSel, + struct wifi_dev *wdev) +{ + MLME_SCAN_REQ_STRUCT ScanReq; +#ifdef CON_WPS + UCHAR ifIdx; +#endif /*ifIdx*/ + struct wifi_dev *wdev_temp = NULL; + INT BssIdx; + INT MaxNumBss = pAd->ApCfg.BssidNum; + INT BandIdx = HcGetBandByWdev(wdev); + + AsicDisableSync(pAd, HW_BSSID_0); + + /* Disable beacon tx for BSS with same band */ + for (BssIdx = 0; BssIdx < MaxNumBss; BssIdx++) { + wdev_temp = &pAd->ApCfg.MBSSID[BssIdx].wdev; + + if (BandIdx != HcGetBandByWdev(wdev_temp)) + continue; + + if (wdev_temp->bAllowBeaconing) + UpdateBeaconHandler(pAd, wdev_temp, BCN_UPDATE_DISABLE_TX); + } + + /* Don't clear the scan table if we are doing partial scan */ +#ifdef CON_WPS + ifIdx = wdev->func_idx; + + if ((ifIdx < MAX_APCLI_NUM) + && (pAd->ApCfg.ConWpsApCliDisabled == FALSE) + && (pAd->ApCfg.ApCliTab[ifIdx].wdev.WscControl.conWscStatus & CON_WPS_STATUS_APCLI_RUNNING)) + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("\033[1;32m ApSiteSurvey_by_wdev don't need Init BSS table\033[0m\n")); + else +#endif /*CON_WPS*/ + if ((pAd->ScanCtrl.PartialScan.bScanning == TRUE && pAd->ScanCtrl.PartialScan.LastScanChannel == 0) || + pAd->ScanCtrl.PartialScan.bScanning == FALSE) { + #if defined(DBDC_MODE) && defined(DOT11K_RRM_SUPPORT) + if (pAd->CommonCfg.dbdc_mode == TRUE) { + UCHAR Band = 0; + if (WMODE_CAP_2G(wdev->PhyMode)) + Band = 0; + if (WMODE_CAP_5G(wdev->PhyMode)) + Band = 1; + + /* backup the other band's scan result. */ + BssTableInitByBand(&pAd->ScanTab, Band); + } else + #endif /* defined(DBDC_MODE) && defined(DOT11K_RRM_SUPPORT) */ + BssTableInit(&pAd->ScanTab); + } + + pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; + RTMPZeroMemory(ScanReq.Ssid, MAX_LEN_OF_SSID); + ScanReq.SsidLen = 0; + + if ((pSsid) && (pSsid->SsidLength > 0) && (pSsid->SsidLength <= (NDIS_802_11_LENGTH_SSID))) { + 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, (ULONG)wdev); + RTMP_MLME_HANDLER(pAd); +} + +BOOLEAN ApScanRunning(RTMP_ADAPTER *pAd, struct wifi_dev *pwdev) +{ + BOOLEAN isScanOn = FALSE; + UCHAR BandIdx = 0; + AUTO_CH_CTRL *pAutoChCtrl = NULL; + + if (pwdev) { + BandIdx = HcGetBandByWdev(pwdev); + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + + if ((pAd->Mlme.ApSyncMachine.CurrState == AP_SCAN_LISTEN) + || (pAutoChCtrl->AutoChSelCtrl.AutoChScanStatMachine.CurrState == AUTO_CH_SEL_SCAN_LISTEN)) + isScanOn = TRUE; + else + isScanOn = FALSE; + } else { + /* wdev null means check all of band */ + BandIdx = 0; + for (BandIdx = 0; BandIdx < DBDC_BAND_NUM; BandIdx++) { + pAutoChCtrl = HcGetAutoChCtrlbyBandIdx(pAd, BandIdx); + if ((pAd->Mlme.ApSyncMachine.CurrState == AP_SCAN_LISTEN) + || (pAutoChCtrl->AutoChSelCtrl.AutoChScanStatMachine.CurrState == AUTO_CH_SEL_SCAN_LISTEN)) + isScanOn |= TRUE; + } + } + + return isScanOn; +} +#endif /* AP_SCAN_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 RTMP_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); +#if defined(P2P_SUPPORT) || defined(RT_CFG80211_P2P_SUPPORT) || defined(CFG80211_MULTI_STA) + StateMachineSetAction(Sm, AP_SYNC_IDLE, APMT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)APPeerBeaconAtScanAction); +#endif /* P2P_SUPPORT || RT_CFG80211_P2P_SUPPORT || CFG80211_MULTI_STA */ +#ifdef AP_SCAN_SUPPORT + StateMachineSetAction(Sm, AP_SYNC_IDLE, APMT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)APMlmeScanReqAction); +#ifdef CON_WPS + StateMachineSetAction(Sm, AP_SYNC_IDLE, APMT2_MLME_SCAN_COMPLETE, (STATE_MACHINE_FUNC)APMlmeScanCompleteAction); +#endif /* CON_WPS */ + /* 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->ScanCtrl.APScanTimer, GET_TIMER_FUNCTION(APScanTimeout), pAd, 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 */ + /*MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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; + MTWF_LOG(DBG_CAT_AP, DBG_SUBCAT_ALL, DBG_LVL_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); + } +} + +#ifdef DOT11_N_SUPPORT +void build_ext_channel_switch_ie( + IN PRTMP_ADAPTER pAd, + IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE, + IN UCHAR Channel, + IN UCHAR PhyMode, + IN struct wifi_dev *wdev) +{ + struct DOT11_H *pDot11h = NULL; + + if (wdev == NULL) + return; + + pDot11h = wdev->pDot11_H; + if (pDot11h == NULL) + return; + + pDot11h = wdev->pDot11_H; + pIE->ID = IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT; + pIE->Length = 4; + pIE->ChannelSwitchMode = 1; /*no further frames */ + pIE->NewRegClass = get_regulatory_class(pAd, Channel, PhyMode, wdev); + pIE->NewChannelNum = Channel; + pIE->ChannelSwitchCount = (pDot11h->CSPeriod - pDot11h->CSCount - 1); +} +#endif /* DOT11_N_SUPPORT */ + diff --git a/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_vow.c b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_vow.c new file mode 100644 index 000000000..0f6a628f5 --- /dev/null +++ b/package/lean/mt/drivers/mt_wifi/src/mt_wifi/embedded/ap/ap_vow.c @@ -0,0 +1,4412 @@ +/* + *************************************************************************** + * MediaTek Inc. + * + * All rights reserved. source code is an unpublished work and the + * use of a copyright notice does not imply otherwise. This source code + * contains confidential trade secret material of MediaTek. Any attemp + * or participation in deciphering, decoding, reverse engineering or in any + * way altering the source code is stricitly prohibited, unless the prior + * written consent of MediaTek, Inc. is obtained. + *************************************************************************** + + Module Name: + ap_vow.c +*/ + +#include "rt_config.h" +#include "mcu/mt_cmd.h" + +#ifdef VOW_SUPPORT +#define UMAC_DRR_TABLE_CTRL0 (0x00008388) + +#define UMAC_DRR_TABLE_WDATA0 (0x00008340) +#define UMAC_DRR_TABLE_WDATA1 (0x00008344) +#define UMAC_DRR_TABLE_WDATA2 (0x00008348) +#define UMAC_DRR_TABLE_WDATA3 (0x0000834C) + +/* Charge mode control control operation (0x8x : charge tx time & length) */ + +#define UMAC_CHARGE_BW_TOKEN_BIT_MASK BIT(0) +#define UMAC_CHARGE_BW_DRR_BIT_MASK BIT(1) +#define UMAC_CHARGE_AIRTIME_DRR_BIT_MASK BIT(2) +#define UMAC_CHARGE_ADD_MODE_BIT_MASK BIT(3) + +#define UMAC_CHARGE_OP_BASE 0x80 +#define UMAC_CHARGE_BW_TOKEN_OP_MASK (UMAC_CHARGE_OP_BASE | UMAC_CHARGE_BW_TOKEN_BIT_MASK) +#define UMAC_CHARGE_BW_DRR_OP_MASK (UMAC_CHARGE_OP_BASE | UMAC_CHARGE_BW_DRR_BIT_MASK) +#define UMAC_CHARGE_AIRTIME_DRR_OP_MASK (UMAC_CHARGE_OP_BASE | UMAC_CHARGE_AIRTIME_DRR_BIT_MASK) + +#define UMAC_CHARGE_MODE_STA_ID_MASK BITS(0, 7) +#define UMAC_CHARGE_MODE_STA_ID_OFFSET 0 +#define UMAC_CHARGE_MODE_QUEUE_ID_MASK BITS(8, 11) +#define UMAC_CHARGE_MODE_QUEUE_ID_OFFSET 8 + +#define UMAC_CHARGE_MODE_BSS_GROUP_MASK BITS(0, 3) +#define UMAC_CHARGE_MODE_BSS_GROUP_OFFSET 0 + + +#define UMAC_CHARGE_MODE_WDATA_CHARGE_LENGTH_MASK BITS(0, 15) +#define UMAC_CHARGE_MODE_WDATA_CHARGE_LENGTH_OFFSET 0 + +#define UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_MASK BITS(16, 31) +#define UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_OFFSET 16 + + +/* Change MODE Ctrl operation */ +#define UMAC_DRR_TABLE_CTRL0_CHANGE_MODE_MASK BIT(23) +#define UMAC_DRR_TABLE_CTRL0_CHANGE_MODE_OFFSET 23 + + +/* 00000340 DRR_Table_WData DRR table Wdata register register 00000000 */ + +#define UMAC_DRR_TABLE_WDATA0_STA_MODE_MASK BITS(0, 15) +#define UMAC_DRR_TABLE_WDATA0_STA_MODE_OFFSET 0 + +/* 00000350 DRR_Table_Rdata DRR table control register read data 00000000 */ +#define UMAC_DRR_TABLE_RDATA0_STA_MODE_MASK BITS(0, 15) +#define UMAC_DRR_TABLE_RDATA0_STA_MODE_OFFSET 0 + +/* 00000388 DRR_Table_ctrl0 DRR table control register register 0 00000000 */ + +#define UMAC_DRR_TABLE_CTRL0_EXEC_MASK BIT(31) +#define UMAC_DRR_TABLE_CTRL0_EXEC_OFFSET 31 +#define UMAC_DRR_TABLE_CTRL0_MODE_OP_OFFSET 16 + + +#define UMAC_BSS_GROUP_NUMBER 16 +#define UMAC_WLAN_ID_MAX_VALUE 127 + +#ifndef _LINUX_BITOPS_H +#define BIT(n) ((UINT32) 1 << (n)) +#endif /* BIT */ +#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) + + + + +#define VOW_DEF_AVA_AIRTIME (1000000) /* us */ + +#define VOW_BSS_SETTING_BEGIN 16 +#define VOW_BSS_SETTING_END (VOW_BSS_SETTING_BEGIN + 16) + +/* global variables */ +PRTMP_ADAPTER pvow_pad; +UINT32 vow_tx_time[MAX_LEN_OF_MAC_TABLE]; +UINT32 vow_rx_time[MAX_LEN_OF_MAC_TABLE]; +UINT32 vow_tx_ok[MAX_LEN_OF_MAC_TABLE]; +UINT32 vow_tx_fail[MAX_LEN_OF_MAC_TABLE]; +UINT32 vow_sum_tx_rx_time; +UINT32 vow_avg_sum_time; +UINT32 vow_last_tx_time[MAX_LEN_OF_MAC_TABLE]; +UINT32 vow_last_rx_time[MAX_LEN_OF_MAC_TABLE]; +UINT16 vow_idx; +UINT32 vow_tx_bss_byte[WMM_NUM_OF_AC]; +UINT32 vow_rx_bss_byte[WMM_NUM_OF_AC]; +UINT32 vow_tx_mbss_byte[VOW_MAX_GROUP_NUM]; +UINT32 vow_rx_mbss_byte[VOW_MAX_GROUP_NUM]; +UINT32 vow_ampdu_cnt; +UINT32 vow_interval; +UINT32 vow_last_free_cnt; + +/* VOW internal commands */ +/***********************************************************/ +/* EXT_CMD_ID_DRR_CTRL = 0x36 */ +/***********************************************************/ +/* for station DWRR configration */ +INT32 vow_set_sta(PRTMP_ADAPTER pad, UINT8 sta_id, UINT32 subcmd) +{ + EXT_CMD_VOW_DRR_CTRL_T sta_ctrl; + UINT32 Setting = 0; + INT32 ret; + + if (sta_id >= MAX_LEN_OF_MAC_TABLE) + return FALSE; + + NdisZeroMemory(&sta_ctrl, sizeof(sta_ctrl)); + sta_ctrl.u4CtrlFieldID = subcmd; + sta_ctrl.ucStaID = sta_id; + + switch (subcmd) { + case ENUM_VOW_DRR_CTRL_FIELD_STA_ALL: + /* station configration */ + Setting |= pad->vow_sta_cfg[sta_id].group; + Setting |= (pad->vow_sta_cfg[sta_id].ac_change_rule << pad->vow_gen.VOW_STA_AC_PRIORITY_OFFSET); + Setting |= (pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_BK] << pad->vow_gen.VOW_STA_WMM_AC0_OFFSET); + Setting |= (pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_BE] << pad->vow_gen.VOW_STA_WMM_AC1_OFFSET); + Setting |= (pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_VI] << pad->vow_gen.VOW_STA_WMM_AC2_OFFSET); + Setting |= (pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_VO] << pad->vow_gen.VOW_STA_WMM_AC3_OFFSET); + sta_ctrl.rAirTimeCtrlValue.u4ComValue = Setting; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, Setting)); + break; + + case ENUM_VOW_DRR_CTRL_FIELD_STA_BSS_GROUP: + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_sta_cfg[sta_id].group; + break; + + case ENUM_VOW_DRR_CTRL_FIELD_STA_PRIORITY: + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_sta_cfg[sta_id].ac_change_rule; + break; + + case ENUM_VOW_DRR_CTRL_FIELD_STA_AC0_QUA_ID: + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_BK]; + break; + + case ENUM_VOW_DRR_CTRL_FIELD_STA_AC1_QUA_ID: + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_BE]; + break; + + case ENUM_VOW_DRR_CTRL_FIELD_STA_AC2_QUA_ID: + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_VI]; + break; + + case ENUM_VOW_DRR_CTRL_FIELD_STA_AC3_QUA_ID: + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_sta_cfg[sta_id].dwrr_quantum[WMM_AC_VO]; + break; + break; + + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L0: + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L1: + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L2: + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L3: + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L4: + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L5: + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L6: + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L7: + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_cfg.vow_sta_dwrr_quantum[subcmd - ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L0]; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", + __func__, subcmd, pad->vow_cfg.vow_sta_dwrr_quantum[subcmd - ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L0])); + break; + + case ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_ALL: { + UINT32 i; + + /* station quantum configruation */ + for (i = 0; i < VOW_MAX_STA_DWRR_NUM; i++) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(vow_sta_dwrr_quantum[%d] = 0x%x)\n", __func__, i, pad->vow_cfg.vow_sta_dwrr_quantum[i])); + sta_ctrl.rAirTimeCtrlValue.rAirTimeQuantumAllField.ucAirTimeQuantum[i] = pad->vow_cfg.vow_sta_dwrr_quantum[i]; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, Setting)); + } + break; + + case ENUM_VOW_DRR_CTRL_FIELD_STA_PAUSE_SETTING: { + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_sta_cfg[sta_id].paused; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, pad->vow_sta_cfg[sta_id].paused)); + } + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, subcmd)); + break; + } + + ret = MtCmdSetVoWDRRCtrl(pad, &sta_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_VOW_DRR_CTRL_T))); + return ret; +} + +/* for DWRR max wait time configuration */ +INT vow_set_sta_DWRR_max_time(PRTMP_ADAPTER pad) +{ + EXT_CMD_VOW_DRR_CTRL_T sta_ctrl; + INT32 ret; + + NdisZeroMemory(&sta_ctrl, sizeof(sta_ctrl)); + sta_ctrl.u4CtrlFieldID = ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_DEFICIT_BOUND; + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_cfg.sta_max_wait_time; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(sta_max_wait_time = 0x%x)\n", __func__, pad->vow_cfg.sta_max_wait_time)); + ret = MtCmdSetVoWDRRCtrl(pad, &sta_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_VOW_DRR_CTRL_T))); + return ret; +} +/***********************************************************/ +/* EXT_CMD_ID_BSSGROUP_CTRL = 0x37 */ +/***********************************************************/ +VOID vow_fill_group_all(PRTMP_ADAPTER pad, UINT8 group_id, EXT_CMD_BSS_CTRL_T *group_ctrl) +{ + /* DW0 */ + group_ctrl->arAllBssGroupMultiField[group_id].u2MinRateToken = pad->vow_bss_cfg[group_id].min_rate_token; + group_ctrl->arAllBssGroupMultiField[group_id].u2MaxRateToken = pad->vow_bss_cfg[group_id].max_rate_token; + /* DW1 */ + group_ctrl->arAllBssGroupMultiField[group_id].u4MinTokenBucketTimeSize = pad->vow_bss_cfg[group_id].min_airtimebucket_size; + group_ctrl->arAllBssGroupMultiField[group_id].u4MinAirTimeToken = pad->vow_bss_cfg[group_id].min_airtime_token; + group_ctrl->arAllBssGroupMultiField[group_id].u4MinTokenBucketLengSize = pad->vow_bss_cfg[group_id].min_ratebucket_size; + /* DW2 */ + group_ctrl->arAllBssGroupMultiField[group_id].u4MaxTokenBucketTimeSize = pad->vow_bss_cfg[group_id].max_airtimebucket_size; + group_ctrl->arAllBssGroupMultiField[group_id].u4MaxAirTimeToken = pad->vow_bss_cfg[group_id].max_airtime_token; + group_ctrl->arAllBssGroupMultiField[group_id].u4MaxTokenBucketLengSize = pad->vow_bss_cfg[group_id].max_ratebucket_size; + /* DW3 */ + group_ctrl->arAllBssGroupMultiField[group_id].u4MaxWaitTime = pad->vow_bss_cfg[group_id].max_wait_time; + group_ctrl->arAllBssGroupMultiField[group_id].u4MaxBacklogSize = pad->vow_bss_cfg[group_id].max_backlog_size; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(Group id = 0x%x, min_rate %d, max_rate %d, min_ratio %d, max_ratio %d)\n", + __func__, group_id, + pad->vow_bss_cfg[group_id].min_rate, + pad->vow_bss_cfg[group_id].max_rate, + pad->vow_bss_cfg[group_id].min_airtime_ratio, + pad->vow_bss_cfg[group_id].max_airtime_ratio)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(min rate token = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].min_rate_token)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(max rate token = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].max_rate_token)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(min airtime token = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].min_airtime_token)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(max airtime token = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].max_airtime_token)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(min rate bucket = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].min_ratebucket_size)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(max rate bucket = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].max_ratebucket_size)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(min airtime bucket = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].min_airtimebucket_size)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(max airtime bucket = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].max_airtimebucket_size)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(max baclog size = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].max_backlog_size)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(max wait time = 0x%x)\n", __func__, pad->vow_bss_cfg[group_id].max_wait_time)); +} +/* for group configuration */ +INT vow_set_group(PRTMP_ADAPTER pad, UINT8 group_id, UINT32 subcmd) +{ + EXT_CMD_BSS_CTRL_T group_ctrl; + INT32 ret; + + NdisZeroMemory(&group_ctrl, sizeof(group_ctrl)); + group_ctrl.u4CtrlFieldID = subcmd; + group_ctrl.ucBssGroupID = group_id; + + switch (subcmd) { + /* group configuration */ + case ENUM_BSSGROUP_CTRL_ALL_ITEM_FOR_1_GROUP: + vow_fill_group_all(pad, group_id, &group_ctrl); + break; + + case ENUM_BSSGROUP_CTRL_MIN_RATE_TOKEN_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].min_rate_token; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MAX_RATE_TOKEN_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].max_rate_token; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MIN_TOKEN_BUCKET_TIME_SIZE_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].min_airtimebucket_size; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MIN_AIRTIME_TOKEN_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].min_airtime_token; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MIN_TOKEN_BUCKET_LENG_SIZE_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].min_ratebucket_size; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MAX_TOKEN_BUCKET_TIME_SIZE_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].max_airtimebucket_size; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MAX_AIRTIME_TOKEN_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].max_airtime_token; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MAX_TOKEN_BUCKET_LENG_SIZE_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].max_ratebucket_size; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MAX_WAIT_TIME_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].max_wait_time; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_MAX_BACKLOG_SIZE_CFG_ITEM: + group_ctrl.u4SingleFieldIDValue = pad->vow_bss_cfg[group_id].max_backlog_size; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(SubCmd %x, Value = 0x%x)\n", __func__, subcmd, group_ctrl.u4SingleFieldIDValue)); + break; + + case ENUM_BSSGROUP_CTRL_ALL_ITEM_FOR_ALL_GROUP: { + UINT32 i; + + for (i = 0; i < VOW_MAX_GROUP_NUM; i++) + vow_fill_group_all(pad, i, &group_ctrl); + } + break; + + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_00: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_01: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_02: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_03: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_04: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_05: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_06: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_07: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_08: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_09: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_0A: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_0B: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_0C: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_0D: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_0E: + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_0F: + /* Group DWRR quantum */ + group_ctrl.ucBssGroupQuantumTime[group_id] = pad->vow_bss_cfg[group_id].dwrr_quantum; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(group %d DWRR quantum = 0x%x)\n", __func__, group_id, pad->vow_bss_cfg[group_id].dwrr_quantum)); + break; + + case ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_ALL: { + UINT32 i; + + for (i = 0; i < VOW_MAX_GROUP_NUM; i++) { + group_ctrl.ucBssGroupQuantumTime[i] = pad->vow_bss_cfg[i].dwrr_quantum; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(group %d DWRR quantum = 0x%x)\n", __func__, i, pad->vow_bss_cfg[i].dwrr_quantum)); + } + } + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, subcmd)); + break; + } + + ret = MtCmdSetVoWGroupCtrl(pad, &group_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_BSS_CTRL_T))); + return ret; +} + +/* for DWRR max wait time configuration */ +INT vow_set_group_DWRR_max_time(PRTMP_ADAPTER pad) +{ + EXT_CMD_VOW_DRR_CTRL_T sta_ctrl; + INT32 ret; + + NdisZeroMemory(&sta_ctrl, sizeof(sta_ctrl)); + sta_ctrl.u4CtrlFieldID = ENUM_VOW_DRR_CTRL_FIELD_BW_DEFICIT_BOUND; + sta_ctrl.rAirTimeCtrlValue.u4ComValue = pad->vow_cfg.group_max_wait_time; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(group_max_wait_time = 0x%x)\n", __func__, pad->vow_cfg.group_max_wait_time)); + ret = MtCmdSetVoWDRRCtrl(pad, &sta_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_VOW_DRR_CTRL_T))); + return ret; +} + +/***********************************************************/ +/* EXT_CMD_ID_VOW_FEATURE_CTRL = 0x38 */ +/***********************************************************/ +/* for group configuration */ +INT vow_set_feature_all(PRTMP_ADAPTER pad) +{ + EXT_CMD_VOW_FEATURE_CTRL_T feature_ctrl; + INT32 ret, i; + + NdisZeroMemory(&feature_ctrl, sizeof(feature_ctrl)); + /* DW0 - flags */ + feature_ctrl.u2IfApplyBss_0_to_16_CtrlFlag = 0xFFFF; /* 16'b */ + feature_ctrl.u2IfApplyRefillPerildFlag = TRUE; /* 1'b */ + feature_ctrl.u2IfApplyDbdc1SearchRuleFlag = TRUE; /* 1'b */ + feature_ctrl.u2IfApplyDbdc0SearchRuleFlag = TRUE; /* 1'b */ + feature_ctrl.u2IfApplyEnTxopNoChangeBssFlag = TRUE; /* 1'b */ + feature_ctrl.u2IfApplyAirTimeFairnessFlag = TRUE; /* 1'b */ + feature_ctrl.u2IfApplyWeightedAirTimeFairnessFlag = TRUE; /* 1'b */ + feature_ctrl.u2IfApplyEnbwrefillFlag = TRUE; /* 1'b */ + feature_ctrl.u2IfApplyEnbwCtrlFlag = TRUE; /* 1'b */ + /* DW1 - flags */ + feature_ctrl.u2IfApplyBssCheckTimeToken_0_to_16_CtrlFlag = 0xFFFF; + /* DW2 - flags */ + feature_ctrl.u2IfApplyBssCheckLengthToken_0_to_16_CtrlFlag = 0xFFFF; + /* DW5 - ctrl values */ + feature_ctrl.u2Bss_0_to_16_CtrlValue = pad->vow_cfg.per_bss_enable; /* 16'b */ + feature_ctrl.u2RefillPerildValue = pad->vow_cfg.refill_period; /* 8'b */ + feature_ctrl.u2Dbdc1SearchRuleValue = pad->vow_cfg.dbdc1_search_rule; /* 1'b */ + feature_ctrl.u2Dbdc0SearchRuleValue = pad->vow_cfg.dbdc0_search_rule; /* 1'b */ + feature_ctrl.u2WeightedAirTimeFairnessValue = pad->vow_watf_en; /* 1'b */ + feature_ctrl.u2EnTxopNoChangeBssValue = pad->vow_cfg.en_txop_no_change_bss; /* 1'b */ + feature_ctrl.u2AirTimeFairnessValue = pad->vow_cfg.en_airtime_fairness; /* 1'b */ + feature_ctrl.u2EnbwrefillValue = pad->vow_cfg.en_bw_refill; /* 1'b */ + feature_ctrl.u2EnbwCtrlValue = pad->vow_cfg.en_bw_ctrl; /* 1'b */ + + /* DW6 - ctrl values */ + for (i = 0; i < VOW_MAX_GROUP_NUM; i++) + feature_ctrl.u2BssCheckTimeToken_0_to_16_CtrlValue |= (pad->vow_bss_cfg[i].at_on << i); + + /* DW7 - ctrl values */ + for (i = 0; i < VOW_MAX_GROUP_NUM; i++) + feature_ctrl.u2BssCheckLengthToken_0_to_16_CtrlValue |= (pad->vow_bss_cfg[i].bw_on << i); + + if (pad->vow_gen.VOW_GEN == VOW_GEN_2) { + /* DW8 - misc */ + feature_ctrl.u4IfApplyStaLockForRtsFlag = TRUE; /* 1'b */ + feature_ctrl.u4RtsStaLockValue = pad->vow_misc_cfg.rts_sta_lock; /* 1'b */ + /* VOW is disabled, skip all setting */ + if (vow_is_enabled(pad)) { + feature_ctrl.u4IfApplyKeepQuantumFlag = TRUE; /* 1'b */ + feature_ctrl.u4KeepQuantumValue = pad->vow_misc_cfg.keep_quantum; /* 1'b */ + feature_ctrl.u4IfApplyTxCountModeFlag = TRUE; /* 1'b */ + feature_ctrl.u4TxCountValue = pad->vow_misc_cfg.tx_rr_count; /* 4'b */ + feature_ctrl.u4IfApplyTxMeasurementModeFlag = TRUE; /* 1'b */ + feature_ctrl.u4TxMeasurementModeValue = pad->vow_misc_cfg.measurement_mode; /* 1'b */ + feature_ctrl.u4IfApplyTxBackOffBoundFlag = TRUE; /* 1'b */ + feature_ctrl.u4TxBackOffBoundEnable = pad->vow_misc_cfg.max_backoff_bound_en; /* 1'b */ + feature_ctrl.u4TxBackOffBoundValue = pad->vow_misc_cfg.max_backoff_bound; /* 4'b */ + feature_ctrl.u4IfApplyRtsFailedChargeDisFlag = TRUE; /* 1'b */ + feature_ctrl.u4RtsFailedChargeDisValue = pad->vow_misc_cfg.rts_failed_charge_time_en; /* 1'b */ + feature_ctrl.u4IfApplyRxEifsToZeroFlag = TRUE; /* 1'b */ + feature_ctrl.u4ApplyRxEifsToZeroValue = pad->vow_misc_cfg.zero_eifs_time; /* 1'b */ + feature_ctrl.u4IfApplyRxRifsModeforCckCtsFlag = TRUE; /* 1'b */ + feature_ctrl.u4RxRifsModeforCckCtsValue = pad->vow_misc_cfg.rx_rifs_mode; /* 1'b */ + feature_ctrl.u4IfApplyKeepVoWSettingForSerFlag = TRUE; /* 1'b */ + feature_ctrl.u4VowKeepSettingValue = pad->vow_misc_cfg.keep_vow_sram_setting; /* 1'b */ + feature_ctrl.u4VowKeepSettingBit = pad->vow_misc_cfg.keep_vow_sram_setting_bit; /* 1'b */ + } + } + + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2Bss_0_to_16_CtrlValue = 0x%x)\n", __func__, pad->vow_cfg.per_bss_enable)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2RefillPerildValue = 0x%x)\n", __func__, pad->vow_cfg.refill_period)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2Dbdc1SearchRuleValue = 0x%x)\n", __func__, pad->vow_cfg.dbdc1_search_rule)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2Dbdc0SearchRuleValue = 0x%x)\n", __func__, pad->vow_cfg.dbdc0_search_rule)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2EnTxopNoChangeBssValue = 0x%x)\n", __func__, pad->vow_cfg.en_txop_no_change_bss)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2AirTimeFairnessValue = 0x%x)\n", __func__, pad->vow_cfg.en_airtime_fairness)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2EnbwrefillValue = 0x%x)\n", __func__, pad->vow_cfg.en_bw_refill)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2EnbwCtrlValue = 0x%x)\n", __func__, pad->vow_cfg.en_bw_ctrl)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2WeightedAirTimeFairnessValue = 0x%x)\n", __func__, pad->vow_watf_en)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2BssCheckTimeToken_0_to_16_CtrlValue = 0x%x)\n", __func__, feature_ctrl.u2BssCheckTimeToken_0_to_16_CtrlValue)); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(u2BssCheckLengthToken_0_to_16_CtrlValue = 0x%x)\n", __func__, feature_ctrl.u2BssCheckLengthToken_0_to_16_CtrlValue)); + ret = MtCmdSetVoWFeatureCtrl(pad, &feature_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_VOW_FEATURE_CTRL_T))); + return ret; +} + +/***********************************************************/ +/* EXT_CMD_ID_RX_AIRTIME_CTRL = 0x4a */ +/***********************************************************/ +/* for RX airtime configuration */ +INT vow_set_rx_airtime(PRTMP_ADAPTER pad, UINT8 cmd, UINT32 subcmd) +{ + EXT_CMD_RX_AT_CTRL_T rx_at_ctrl; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&rx_at_ctrl, sizeof(rx_at_ctrl)); + /* assign cmd and subcmd */ + rx_at_ctrl.u4CtrlFieldID = cmd; + rx_at_ctrl.u4CtrlSubFieldID = subcmd; + + switch (cmd) { + /* RX airtime feature control */ + case ENUM_RX_AT_FEATURE_CTRL: + switch (subcmd) { + case ENUM_RX_AT_FEATURE_SUB_TYPE_AIRTIME_EN: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtFeatureSubCtrl.fgRxAirTimeEn = pad->vow_rx_time_cfg.rx_time_en; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, value = 0x%x)\n", + __func__, cmd, subcmd, pad->vow_rx_time_cfg.rx_time_en)); + break; + + case ENUM_RX_AT_FEATURE_SUB_TYPE_MIBTIME_EN: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(Not implemented yet = 0x%x)\n", __func__, subcmd)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such sub command = 0x%x)\n", __func__, subcmd)); + } + + break; + + case ENUM_RX_AT_BITWISE_CTRL: + switch (subcmd) { + case ENUM_RX_AT_BITWISE_SUB_TYPE_AIRTIME_CLR: /* clear all RX airtime counters */ + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtBitWiseSubCtrl.fgRxAirTimeClrEn = TRUE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, value = 0x%x)\n", + __func__, cmd, subcmd, rx_at_ctrl.rRxAtGeneralCtrl.rRxAtBitWiseSubCtrl.fgRxAirTimeClrEn)); + break; + + case ENUM_RX_AT_BITWISE_SUB_TYPE_MIBTIME_CLR: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(Not implemented yet = 0x%x)\n", __func__, subcmd)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such sub command = 0x%x)\n", __func__, subcmd)); + } + + break; + + case ENUM_RX_AT_TIMER_VALUE_CTRL: + switch (subcmd) { + case ENUM_RX_AT_TIME_VALUE_SUB_TYPE_ED_OFFSET_CTRL: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.ucEdOffsetValue = pad->vow_rx_time_cfg.ed_offset; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, value = 0x%x)\n", + __func__, cmd, subcmd, pad->vow_rx_time_cfg.ed_offset)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such sub command = 0x%x)\n", __func__, subcmd)); + } + + break; + + case EMUM_RX_AT_REPORT_CTRL: + switch (subcmd) { + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such sub command = 0x%x)\n", __func__, subcmd)); + } + + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, subcmd)); + break; + } + + ret = MtCmdSetVoWRxAirtimeCtrl(pad, &rx_at_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_RX_AT_CTRL_T))); + return ret; +} + +/* select RX WMM backoff time for 4 OM */ +INT vow_set_wmm_selection(PRTMP_ADAPTER pad, UINT8 om) +{ + EXT_CMD_RX_AT_CTRL_T rx_at_ctrl; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&rx_at_ctrl, sizeof(rx_at_ctrl)); + /* assign cmd and subcmd */ + rx_at_ctrl.u4CtrlFieldID = ENUM_RX_AT_BITWISE_CTRL; + rx_at_ctrl.u4CtrlSubFieldID = ENUM_RX_AT_BITWISE_SUB_TYPE_STA_WMM_CTRL; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtBitWiseSubCtrl.ucOwnMacID = om; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtBitWiseSubCtrl.fgtoApplyWm00to03MibCfg = pad->vow_rx_time_cfg.wmm_backoff_sel[om]; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, OM = 0x%x, Map = 0x%x)\n", + __func__, rx_at_ctrl.rRxAtGeneralCtrl.rRxAtBitWiseSubCtrl.ucOwnMacID, ENUM_RX_AT_BITWISE_SUB_TYPE_STA_WMM_CTRL, om, + pad->vow_rx_time_cfg.wmm_backoff_sel[om])); + ret = MtCmdSetVoWRxAirtimeCtrl(pad, &rx_at_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_RX_AT_CTRL_T))); + return ret; +} + +/* set 16 MBSS mapping to 4 RX backoff time configurations */ +INT vow_set_mbss2wmm_map(PRTMP_ADAPTER pad, UINT8 bss_idx) +{ + EXT_CMD_RX_AT_CTRL_T rx_at_ctrl; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&rx_at_ctrl, sizeof(rx_at_ctrl)); + /* assign cmd and subcmd */ + rx_at_ctrl.u4CtrlFieldID = ENUM_RX_AT_BITWISE_CTRL; + rx_at_ctrl.u4CtrlSubFieldID = ENUM_RX_AT_BITWISE_SUB_TYPE_MBSS_WMM_CTRL; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtBitWiseSubCtrl.ucMbssGroup = bss_idx; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtBitWiseSubCtrl.ucWmmGroup = pad->vow_rx_time_cfg.bssid2wmm_set[bss_idx]; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, bss_idx = 0x%x, Map = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, bss_idx, + pad->vow_rx_time_cfg.bssid2wmm_set[bss_idx])); + ret = MtCmdSetVoWRxAirtimeCtrl(pad, &rx_at_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_RX_AT_CTRL_T))); + return ret; +} + +/* set backoff time for RX*/ +INT vow_set_backoff_time(PRTMP_ADAPTER pad, UINT8 target) +{ + EXT_CMD_RX_AT_CTRL_T rx_at_ctrl; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&rx_at_ctrl, sizeof(rx_at_ctrl)); + /* assign cmd and subcmd */ + rx_at_ctrl.u4CtrlFieldID = ENUM_RX_AT_TIMER_VALUE_CTRL; + rx_at_ctrl.u4CtrlSubFieldID = ENUM_RX_AT_TIME_VALUE_SUB_TYPE_BACKOFF_TIMER; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackoffWmmGroupIdx = target; + + switch (target) { + case ENUM_RX_AT_WMM_GROUP_0: + case ENUM_RX_AT_WMM_GROUP_1: + case ENUM_RX_AT_WMM_GROUP_2: + case ENUM_RX_AT_WMM_GROUP_3: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC0Backoff = + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_BK]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC1Backoff = + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_BE]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC2Backoff = + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_VI]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC3Backoff = + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_VO]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxAtBackoffAcQMask = + (ENUM_RX_AT_AC_Q0_MASK_T | ENUM_RX_AT_AC_Q1_MASK_T | ENUM_RX_AT_AC_Q2_MASK_T | ENUM_RX_AT_AC_Q3_MASK_T); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, group = 0x%x, BK = 0x%x, BE = 0x%x, VI = 0x%x, VO = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, target, + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_BK], + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_BE], + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_VI], + pad->vow_rx_time_cfg.wmm_backoff[target][WMM_AC_VO])); + break; + + case ENUM_RX_AT_WMM_GROUP_PEPEATER: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC0Backoff = + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_BK]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC1Backoff = + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_BE]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC2Backoff = + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_VI]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC3Backoff = + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_VO]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxAtBackoffAcQMask = + (ENUM_RX_AT_AC_Q0_MASK_T | ENUM_RX_AT_AC_Q1_MASK_T | ENUM_RX_AT_AC_Q2_MASK_T | ENUM_RX_AT_AC_Q3_MASK_T); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, group = 0x%x, BK = 0x%x, BE = 0x%x, VI = 0x%x, VO = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, target, + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_BK], + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_BE], + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_VI], + pad->vow_rx_time_cfg.repeater_wmm_backoff[WMM_AC_VO])); + break; + + case ENUM_RX_AT_WMM_GROUP_STA: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC0Backoff = + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_BK]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC1Backoff = + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_BE]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC2Backoff = + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_VI]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC3Backoff = + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_VO]; + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxAtBackoffAcQMask = + (ENUM_RX_AT_AC_Q0_MASK_T | ENUM_RX_AT_AC_Q1_MASK_T | ENUM_RX_AT_AC_Q2_MASK_T | ENUM_RX_AT_AC_Q3_MASK_T); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, group = 0x%x, BK = 0x%x, BE = 0x%x, VI = 0x%x, VO = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, target, + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_BK], + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_BE], + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_VI], + pad->vow_rx_time_cfg.om_wmm_backoff[WMM_AC_VO])); + break; + + case ENUM_RX_AT_NON_QOS: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC0Backoff = + pad->vow_rx_time_cfg.non_qos_backoff; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, group = 0x%x, backoff time = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, target, + pad->vow_rx_time_cfg.non_qos_backoff)); + break; + + case ENUM_RX_AT_OBSS: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtTimeValueSubCtrl.rRxATBackOffCfg.u2AC0Backoff = + pad->vow_rx_time_cfg.obss_backoff; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, group = 0x%x, backoff time = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, target, + pad->vow_rx_time_cfg.obss_backoff)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, target)); + break; + } + + ret = MtCmdSetVoWRxAirtimeCtrl(pad, &rx_at_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_RX_AT_CTRL_T))); + return ret; +} + +/* set backoff time for RX*/ +INT vow_get_rx_time_counter(PRTMP_ADAPTER pad, UINT8 target, UINT8 band_idx) +{ + EXT_CMD_RX_AT_CTRL_T rx_at_ctrl; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&rx_at_ctrl, sizeof(rx_at_ctrl)); + /* assign cmd and subcmd */ + rx_at_ctrl.u4CtrlFieldID = EMUM_RX_AT_REPORT_CTRL; + rx_at_ctrl.u4CtrlSubFieldID = target; + + switch (target) { + case ENUM_RX_AT_REPORT_SUB_TYPE_RX_NONWIFI_TIME: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtReportSubCtrl.ucRxNonWiFiBandIdx = band_idx; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, target = 0x%x, band_idx = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, target, band_idx)); + break; + + case ENUM_RX_AT_REPORT_SUB_TYPE_RX_OBSS_TIME: + rx_at_ctrl.rRxAtGeneralCtrl.rRxAtReportSubCtrl.ucRxObssBandIdx = band_idx; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, target = 0x%x, band_idx = 0x%x)\n", + __func__, rx_at_ctrl.u4CtrlFieldID, rx_at_ctrl.u4CtrlSubFieldID, target, band_idx)); + break; + + case ENUM_RX_AT_REPORT_SUB_TYPE_MIB_OBSS_TIME: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(Not implemented yet = 0x%x)\n", __func__, target)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, target)); + } + + ret = MtCmdGetVoWRxAirtimeCtrl(pad, &rx_at_ctrl); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_RX_AT_CTRL_T))); + + if (target == ENUM_RX_AT_REPORT_SUB_TYPE_RX_NONWIFI_TIME) + return rx_at_ctrl.rRxAtGeneralCtrl.rRxAtReportSubCtrl.u4RxNonWiFiBandTimer; + else if (target == ENUM_RX_AT_REPORT_SUB_TYPE_RX_OBSS_TIME) + return rx_at_ctrl.rRxAtGeneralCtrl.rRxAtReportSubCtrl.u4RxObssBandTimer; + else if (target == ENUM_RX_AT_REPORT_SUB_TYPE_MIB_OBSS_TIME) + return rx_at_ctrl.rRxAtGeneralCtrl.rRxAtReportSubCtrl.u4RxMibObssBandTimer; + else + return -1; +} +/***********************************************************/ +/* EXT_CMD_ID_AT_PROC_MODULE = 0x4b */ +/***********************************************************/ + +/* for airtime estimator module */ +INT vow_set_at_estimator(PRTMP_ADAPTER pad, UINT32 subcmd) +{ + EXT_CMD_AT_PROC_MODULE_CTRL_T at_proc; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&at_proc, sizeof(at_proc)); + /* assign cmd and subcmd */ + at_proc.u4CtrlFieldID = ENUM_AT_RPOCESS_ESTIMATE_MODULE_CTRL; + at_proc.u4CtrlSubFieldID = cpu2le16(subcmd); +#ifdef RT_BIG_ENDIAN + at_proc.u4CtrlFieldID = cpu2le16(at_proc.u4CtrlFieldID); +#endif + + switch (subcmd) { + case ENUM_AT_PROC_EST_FEATURE_CTRL: + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.fgAtEstimateOnOff = pad->vow_at_est.at_estimator_en; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, val = 0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, pad->vow_at_est.at_estimator_en)); + break; + + case ENUM_AT_PROC_EST_MONITOR_PERIOD_CTRL: + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.u2AtEstMonitorPeriod = cpu2le16(pad->vow_at_est.at_monitor_period); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, val = 0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, pad->vow_at_est.at_monitor_period)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, subcmd)); + } + + ret = MtCmdSetVoWModuleCtrl(pad, &at_proc); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_AT_PROC_MODULE_CTRL_T))); + return ret; +} + +INT vow_set_at_estimator_group(PRTMP_ADAPTER pad, UINT32 subcmd, UINT8 group_id) +{ + EXT_CMD_AT_PROC_MODULE_CTRL_T at_proc; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&at_proc, sizeof(at_proc)); + /* assign cmd and subcmd */ + at_proc.u4CtrlFieldID = ENUM_AT_RPOCESS_ESTIMATE_MODULE_CTRL; + at_proc.u4CtrlSubFieldID = subcmd; +#ifdef RT_BIG_ENDIAN + at_proc.u4CtrlFieldID = cpu2le16(at_proc.u4CtrlFieldID); + at_proc.u4CtrlSubFieldID = cpu2le16(at_proc.u4CtrlSubFieldID); +#endif + + switch (subcmd) { + case ENUM_AT_PROC_EST_GROUP_RATIO_CTRL: + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.u4GroupRatioBitMask |= (1UL << group_id); + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.u2GroupMaxRatioValue[group_id] = cpu2le16(pad->vow_bss_cfg[group_id].max_airtime_ratio); + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.u2GroupMinRatioValue[group_id] = cpu2le16(pad->vow_bss_cfg[group_id].min_airtime_ratio); +#ifdef RT_BIG_ENDIAN + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.u4GroupRatioBitMask = + cpu2le16(at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.u4GroupRatioBitMask); +#endif + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, group %d, val = 0x%x/0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, group_id, + pad->vow_bss_cfg[group_id].max_airtime_ratio, + pad->vow_bss_cfg[group_id].min_airtime_ratio)); + break; + + case ENUM_AT_PROC_EST_GROUP_TO_BAND_MAPPING: + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.ucGrouptoSelectBand = group_id; + at_proc.rAtProcGeneralCtrl.rAtEstimateSubCtrl.ucBandSelectedfromGroup = pad->vow_bss_cfg[group_id].band_idx; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, group %d, val = 0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, group_id, pad->vow_bss_cfg[group_id].band_idx)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, subcmd)); + } + + ret = MtCmdSetVoWModuleCtrl(pad, &at_proc); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_AT_PROC_MODULE_CTRL_T))); + return ret; +} + +/* for bad node detector */ +INT vow_set_bad_node(PRTMP_ADAPTER pad, UINT32 subcmd) +{ + EXT_CMD_AT_PROC_MODULE_CTRL_T at_proc; + INT32 ret; + /* init structure to zero */ + NdisZeroMemory(&at_proc, sizeof(at_proc)); + /* assign cmd and subcmd */ + at_proc.u4CtrlFieldID = ENUM_AT_RPOCESS_BAD_NODE_MODULE_CTRL; +#ifdef RT_BIG_ENDIAN + at_proc.u4CtrlFieldID = cpu2le16(at_proc.u4CtrlFieldID); +#endif + at_proc.u4CtrlSubFieldID = cpu2le16(subcmd); + + switch (subcmd) { + case ENUM_AT_PROC_BAD_NODE_FEATURE_CTRL: + at_proc.rAtProcGeneralCtrl.rAtBadNodeSubCtrl.fgAtBadNodeOnOff = pad->vow_badnode.bn_en; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, val = 0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, pad->vow_badnode.bn_en)); + break; + + case ENUM_AT_PROC_BAD_NODE_MONITOR_PERIOD_CTRL: + at_proc.rAtProcGeneralCtrl.rAtBadNodeSubCtrl.u2AtBadNodeMonitorPeriod = cpu2le16(pad->vow_badnode.bn_monitor_period); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, val = 0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, pad->vow_badnode.bn_monitor_period)); + break; + + case ENUM_AT_PROC_BAD_NODE_FALLBACK_THRESHOLD: + at_proc.rAtProcGeneralCtrl.rAtBadNodeSubCtrl.ucFallbackThreshold = pad->vow_badnode.bn_fallback_threshold; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, val = 0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, pad->vow_badnode.bn_fallback_threshold)); + break; + + case ENUM_AT_PROC_BAD_NODE_PER_THRESHOLD: + at_proc.rAtProcGeneralCtrl.rAtBadNodeSubCtrl.ucTxPERThreshold = pad->vow_badnode.bn_per_threshold; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(cmd = 0x%x, subcmd = 0x%x, val = 0x%x)\n", + __func__, at_proc.u4CtrlFieldID, at_proc.u4CtrlSubFieldID, pad->vow_badnode.bn_per_threshold)); + break; + + default: + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(No such command = 0x%x)\n", __func__, subcmd)); + } + + ret = MtCmdSetVoWModuleCtrl(pad, &at_proc); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s:(ret = %d), sizeof %zu\n", __func__, ret, sizeof(EXT_CMD_AT_PROC_MODULE_CTRL_T))); + return ret; +} + +void vow_dump_umac_CRs(PRTMP_ADAPTER pad) +{ + int i; + + for (i = 0x8340; i < 0x83c0; i += 4) { + UINT32 val; + + RTMP_IO_READ32(pad, i, &val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("0x%0x -> 0x%0x\n", i, val)); + } +} +/* ---------------------- end -------------------------------*/ + +BOOLEAN vow_is_enabled(PRTMP_ADAPTER pad) +{ + return (pad->vow_cfg.en_bw_ctrl || pad->vow_cfg.en_airtime_fairness); +} + +BOOLEAN vow_watf_is_enabled( + IN PRTMP_ADAPTER pad) +{ + return pad->vow_watf_en; +} + +VOID vow_init(PRTMP_ADAPTER pad) +{ + BOOLEAN ret; + /* for M2M test */ + pvow_pad = pad; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\x1b[31m%s: start ...\x1b[m\n", __func__)); + /* vow CR address init */ + vow_init_CR_offset_gen_1_gen_2(pad); + /* vow_dump_umac_CRs(pad); */ + /* vow station init */ + vow_init_sta(pad); + /* vow group init */ + vow_init_group(pad); + /* vow rx init */ + vow_init_rx(pad); + /* vow misc init */ + vow_init_misc(pad); + /* feature control */ + ret = vow_set_feature_all(pad); + /* configure badnode detector */ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("\x1b[31m%s: end ...\x1b[m\n", __func__)); +} + +VOID vow_init_CR_offset_gen_1_gen_2(PRTMP_ADAPTER pad) +{ + if (pad->vow_gen.VOW_GEN == VOW_GEN_1) { + /* VOW debug command 0x22/0x44 */ + pad->vow_gen.VOW_STA_SETTING_BEGIN = 0; + pad->vow_gen.VOW_STA_SETTING_END = pad->vow_gen.VOW_STA_SETTING_BEGIN + 16; + pad->vow_gen.VOW_STA_BITMAP_BEGIN = 0; + pad->vow_gen.VOW_STA_BITMAP_END = pad->vow_gen.VOW_STA_BITMAP_BEGIN + 16; + pad->vow_gen.VOW_BSS_TOKEN_OFFSET = 32; + pad->vow_gen.VOW_STA_SETTING_FACTOR = 3; + + /* STA setting */ + pad->vow_gen.VOW_STA_AC_PRIORITY_OFFSET = 4; + pad->vow_gen.VOW_STA_WMM_AC0_OFFSET = 6; + pad->vow_gen.VOW_STA_WMM_AC1_OFFSET = 8; + pad->vow_gen.VOW_STA_WMM_AC2_OFFSET = 10; + pad->vow_gen.VOW_STA_WMM_AC3_OFFSET = 12; + pad->vow_gen.VOW_STA_WMM_ID_OFFSET = 14; + } else { + /* VOW debug command 0x22/0x44 */ + pad->vow_gen.VOW_STA_SETTING_BEGIN = 68; + pad->vow_gen.VOW_STA_SETTING_END = pad->vow_gen.VOW_STA_SETTING_BEGIN + 32; + pad->vow_gen.VOW_STA_BITMAP_BEGIN = 52; + pad->vow_gen.VOW_STA_BITMAP_END = pad->vow_gen.VOW_STA_BITMAP_BEGIN + 16; + pad->vow_gen.VOW_BSS_TOKEN_OFFSET = 0; + pad->vow_gen.VOW_STA_SETTING_FACTOR = 2; + + /* STA setting */ + pad->vow_gen.VOW_STA_AC_PRIORITY_OFFSET = 4; + pad->vow_gen.VOW_STA_WMM_AC0_OFFSET = 8; + pad->vow_gen.VOW_STA_WMM_AC1_OFFSET = 12; + pad->vow_gen.VOW_STA_WMM_AC2_OFFSET = 16; + pad->vow_gen.VOW_STA_WMM_AC3_OFFSET = 20; + pad->vow_gen.VOW_STA_WMM_ID_OFFSET = 6; + } +} + + +VOID vow_init_sta(PRTMP_ADAPTER pad) +{ + UINT8 i; + BOOLEAN ret; + + /* if ATF is disabled, the default max DWRR wait time is configured as 256us to force STA round-robin */ + if (pad->vow_cfg.en_airtime_fairness == FALSE) + pad->vow_cfg.sta_max_wait_time = 1; /* 256us */ + + /* set max wait time for DWRR station */ + ret = vow_set_sta_DWRR_max_time(pad); + + /* VOW is disabled, skip all setting */ + if (vow_is_enabled(pad) == FALSE) + return; + + /* station DWRR quantum */ + ret = vow_set_sta(pad, VOW_ALL_STA, ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_ALL); + + /* per station DWRR configuration */ + for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { + ret = vow_set_sta(pad, i, ENUM_VOW_DRR_CTRL_FIELD_STA_ALL); + ret = vow_set_sta(pad, i, ENUM_VOW_DRR_CTRL_FIELD_STA_BSS_GROUP); + /* set station pause status */ + ret = vow_set_sta(pad, i, ENUM_VOW_DRR_CTRL_FIELD_STA_PAUSE_SETTING); + } +} + +VOID vow_init_group(PRTMP_ADAPTER pad) +{ + BOOLEAN ret; + + /* VOW is disabled, skip all setting */ + if (vow_is_enabled(pad) == FALSE) + return; + + /* group DWRR quantum */ + ret = vow_set_group(pad, VOW_ALL_GROUP, ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_ALL); + + /* set group configuration */ + ret = vow_set_group(pad, VOW_ALL_GROUP, ENUM_BSSGROUP_CTRL_ALL_ITEM_FOR_ALL_GROUP); + + /* set max BSS wait time and sta wait time */ + /* RTMP_IO_WRITE32(pad, 0x8374, 0x00200020); */ + vow_set_group_DWRR_max_time(pad); + /*set Airtime estimator enable*/ + pad->vow_at_est.at_estimator_en = TRUE; + vow_set_at_estimator(pad, ENUM_AT_PROC_EST_FEATURE_CTRL); +} + +VOID vow_init_rx(PRTMP_ADAPTER pad) +{ + UINT8 i; + BOOLEAN ret; + + /* VOW is disabled, skip all setting */ + if (vow_is_enabled(pad) == FALSE) { + pad->vow_rx_time_cfg.rx_time_en = FALSE; + vow_set_rx_airtime(pad, ENUM_RX_AT_FEATURE_CTRL, ENUM_RX_AT_FEATURE_SUB_TYPE_AIRTIME_EN); + return; + } + + /* reset all RX counters */ + ret = vow_set_rx_airtime(pad, ENUM_RX_AT_BITWISE_CTRL, ENUM_RX_AT_BITWISE_SUB_TYPE_AIRTIME_CLR); + /* RX airtime feature enable */ + ret = vow_set_rx_airtime(pad, ENUM_RX_AT_FEATURE_CTRL, ENUM_RX_AT_FEATURE_SUB_TYPE_AIRTIME_EN); + /* set ED offset */ + ret = vow_set_rx_airtime(pad, ENUM_RX_AT_TIMER_VALUE_CTRL, ENUM_RX_AT_TIME_VALUE_SUB_TYPE_ED_OFFSET_CTRL); + /* set OBSS backoff time - 1 set*/ + ret = vow_set_backoff_time(pad, ENUM_RX_AT_OBSS); + /* set non QOS backoff time - 1 set */ + ret = vow_set_backoff_time(pad, ENUM_RX_AT_NON_QOS); + /* set repeater backoff time - 1 set */ + ret = vow_set_backoff_time(pad, ENUM_RX_AT_WMM_GROUP_PEPEATER); + /* set OM backoff time */ + ret = vow_set_backoff_time(pad, ENUM_RX_AT_WMM_GROUP_STA); + + /* set WMM AC backoff time */ + for (i = 0; i < VOW_MAX_WMM_SET_NUM; i++) + ret = vow_set_backoff_time(pad, i); + + /* set BSS belogs to which WMM set */ + for (i = 0; i < VOW_MAX_GROUP_NUM; i++) + ret = vow_set_mbss2wmm_map(pad, i); + + /* select RX WMM backoff time for 4 OM */ + for (i = 0; i < VOW_MAX_WMM_SET_NUM; i++) + ret = vow_set_wmm_selection(pad, i); + + /* configure airtime estimator */ + for (i = 0; i < VOW_MAX_GROUP_NUM; i++) { + vow_set_at_estimator_group(pad, ENUM_AT_PROC_EST_GROUP_RATIO_CTRL, i); + /* vow_set_at_estimator_group(pad, ENUM_AT_PROC_EST_GROUP_TO_BAND_MAPPING, i); */ + } +} + + +VOID vow_init_misc(PRTMP_ADAPTER pad) +{ + UINT32 reg32, i; + + if (pad->vow_gen.VOW_GEN == VOW_GEN_1) { + /* disable RTS failed airtime charge for RTS deadlock */ + HW_IO_READ32(pad, AGG_SCR, ®32); + reg32 |= RTS_FAIL_CHARGE_DIS; + HW_IO_WRITE32(pad, AGG_SCR, reg32); + } + + /* VOW is disabled, skip all setting */ + if (vow_is_enabled(pad) == FALSE) + return; + + if (pad->vow_gen.VOW_GEN == VOW_GEN_1) { + /* RX_RIFS_MODE enable, 820F4000 bit[23] set to 1 */ + /* detect ED signal down for CCK CTS */ + HW_IO_READ32(pad, TMAC_TCR, ®32); + reg32 |= RX_RIFS_MODE; + HW_IO_WRITE32(pad, TMAC_TCR, reg32); + + /* Configure 1 to force rmac_cr_eifs_time=0 for VOW OBSS counter, 820f52e0 bit[21] set to 1 */ + HW_IO_READ32(pad, RMAC_RSVD0, ®32); + reg32 |= RX_EIFS_TIME_ZERO; + HW_IO_WRITE32(pad, RMAC_RSVD0, reg32); + + /* for SER (0x82060370 bit[26]=1 --> keep all VOW setting) */ + HW_IO_READ32(pad, VOW_CONTROL, ®32); + reg32 |= VOW_RESET_DISABLE; + HW_IO_WRITE32(pad, VOW_CONTROL, reg32); + } + + if (vow_watf_is_enabled(pad)) { + pad->vow_cfg.vow_sta_dwrr_quantum[0] = pad->vow_watf_q_lv0; + pad->vow_cfg.vow_sta_dwrr_quantum[1] = pad->vow_watf_q_lv1; + pad->vow_cfg.vow_sta_dwrr_quantum[2] = pad->vow_watf_q_lv2; + pad->vow_cfg.vow_sta_dwrr_quantum[3] = pad->vow_watf_q_lv3; + } else { + pad->vow_cfg.vow_sta_dwrr_quantum[0] = VOW_STA_DWRR_QUANTUM0; + pad->vow_cfg.vow_sta_dwrr_quantum[1] = VOW_STA_DWRR_QUANTUM1; + pad->vow_cfg.vow_sta_dwrr_quantum[2] = VOW_STA_DWRR_QUANTUM2; + pad->vow_cfg.vow_sta_dwrr_quantum[3] = VOW_STA_DWRR_QUANTUM3; + } + + for (i = 0; i < VOW_WATF_LEVEL_NUM; i++) + vow_set_sta(pad, VOW_ALL_STA, ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L0 + i); +} + +VOID vow_reset(PRTMP_ADAPTER pad) +{ + vow_reset_watf(pad); + vow_reset_dvt(pad); +} + +VOID vow_update_om_wmm(PRTMP_ADAPTER pad, struct wifi_dev *wdev, PEDCA_PARM pApEdcaParm) +{ + UCHAR wmm_idx; + UCHAR st; + UINT16 cw; + UCHAR ac_idx; + UCHAR ac_map[] = {WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, WMM_AC_VO}; + struct _EDCA_PARM *pBssEdca = wlan_config_get_ht_edca(wdev); + + /* VOW is disabled, skip all setting */ + if (vow_is_enabled(pad) == FALSE) + return; + + if (WMODE_CAP_5G(wdev->PhyMode)) + st = SLOT_TIME_5G; + else if (pad->CommonCfg.bUseShortSlotTime) + st = SLOT_TIME_24G_SHORT; + else + st = SLOT_TIME_24G_LONG; + + if (pBssEdca) { + /* invalid */ + if (pBssEdca->bValid == FALSE) + return; + + if ((pApEdcaParm == NULL) || (pApEdcaParm->bValid == FALSE)) + return; + + wmm_idx = pApEdcaParm->WmmSet; + + for (ac_idx = 0; ac_idx < WMM_NUM_OF_AC; ac_idx++) { + cw = (1 << pBssEdca->Cwmin[ac_map[ac_idx]]) - 1; + pad->vow_rx_time_cfg.wmm_backoff[wmm_idx][ac_idx] = + (WMODE_CAP_5G(wdev->PhyMode) ? SIFS_TIME_5G : SIFS_TIME_24G) + + pBssEdca->Aifsn[ac_map[ac_idx]]*st + cw*st; + } + + vow_set_backoff_time(pad, wmm_idx); + } +} + +VOID vow_mbss_init(PRTMP_ADAPTER pad, struct wifi_dev *wdev) +{ + /* VOW is disabled, skip all setting */ + if (vow_is_enabled(pad) == FALSE) + return; + + if (wdev) { + vow_mbss_grp_band_map(pad, wdev); + vow_mbss_wmm_map(pad, wdev); + /* configure BCMC entry */ + vow_set_client(pad, wdev->wdev_idx, wdev->tr_tb_idx); + } +} + +VOID vow_group_band_map(PRTMP_ADAPTER pad, UCHAR band_idx, UCHAR group_idx) +{ + UINT32 reg32; + + HW_IO_READ32(pad, VOW_DBDC_BW_GROUP_CTRL, ®32); + reg32 &= ~(1 << group_idx); + reg32 |= (band_idx << group_idx); + HW_IO_WRITE32(pad, VOW_DBDC_BW_GROUP_CTRL, reg32); +} + +/* do bss(group) and band mapping */ +VOID vow_mbss_grp_band_map(PRTMP_ADAPTER pad, struct wifi_dev *wdev) +{ + UCHAR band_idx; + UCHAR wdev_idx; + + if (wdev) { + band_idx = HcGetBandByWdev(wdev); + wdev_idx = wdev->wdev_idx; + /* MBSS <--> group 1 to 1 mapping, ex: SSID0 --> Group0 */ + vow_group_band_map(pad, band_idx, wdev_idx); + pad->vow_bss_cfg[wdev_idx].band_idx = band_idx; + vow_set_at_estimator_group(pad, ENUM_AT_PROC_EST_GROUP_TO_BAND_MAPPING, wdev_idx); + } +} + +/* do bss and wmm mapping for RX */ +VOID vow_mbss_wmm_map(PRTMP_ADAPTER pad, struct wifi_dev *wdev) +{ + UCHAR wmm_idx; + + if (wdev) { + wmm_idx = HcGetWmmIdx(pad, wdev); + pad->vow_rx_time_cfg.bssid2wmm_set[wdev->wdev_idx] = wmm_idx; + vow_set_mbss2wmm_map(pad, wdev->wdev_idx); + } +} + +static UINT32 vow_get_availabe_airtime(VOID) +{ + return VOW_DEF_AVA_AIRTIME; +} + +/* get rate token */ +UINT16 vow_convert_rate_token(PRTMP_ADAPTER pad, UINT8 type, UINT8 group_id) +{ + UINT16 period, rate, token = 0; + + period = (1 << pad->vow_cfg.refill_period); + + if (type == VOW_MAX) { + rate = pad->vow_bss_cfg[group_id].max_rate; + token = (period * rate); + } else { + rate = pad->vow_bss_cfg[group_id].min_rate; + token = (period * rate); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: period %dus, rate %u, token %u\n", __func__, period, rate, token)); + return token; +} + +/* get airtime token */ +UINT16 vow_convert_airtime_token(PRTMP_ADAPTER pad, UINT8 type, UINT8 group_id) +{ + UINT16 period, ratio, token = 0; + UINT32 atime = vow_get_availabe_airtime(); + UINT64 tmp; + + period = (1 << pad->vow_cfg.refill_period); + + if (type == VOW_MAX) + ratio = pad->vow_bss_cfg[group_id].max_airtime_ratio; + else + ratio = pad->vow_bss_cfg[group_id].min_airtime_ratio; + + /* shift 3 --> because unit is 1/8 us, + 10^8 --> ratio needs to convert from integer to %, preiod needs to convert from us to s + */ + tmp = ((UINT64)period * atime * ratio) << 3; + /* printk("%s: tmp %llu\n", __FUNCTION__, tmp); */ + token = div64_u64(tmp, 100000000); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, + ("%s: period %dus, ratio %u, available time %u, token %u\n", __func__, period, ratio, atime, token)); + return token; +} + + +/* add client(station) */ + +VOID vow_set_client(PRTMP_ADAPTER pad, UINT8 group, UINT8 sta_id) +{ + BOOLEAN ret; + /* set group for station */ + pad->vow_sta_cfg[sta_id].group = group; + /* update station bitmap */ + /* don't change command sequence - STA_BSS_GROUP will refer to STA_ALL's old setting */ + ret = vow_set_sta(pad, sta_id, ENUM_VOW_DRR_CTRL_FIELD_STA_BSS_GROUP); + ret = vow_set_sta(pad, sta_id, ENUM_VOW_DRR_CTRL_FIELD_STA_ALL); + /* set station pause status */ + ret = vow_set_sta(pad, sta_id, ENUM_VOW_DRR_CTRL_FIELD_STA_PAUSE_SETTING); +} + +INT set_vow_min_rate_token( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].min_rate_token = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MIN_RATE_TOKEN_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_rate_token( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_rate_token = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_RATE_TOKEN_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_min_airtime_token( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].min_airtime_token = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MIN_AIRTIME_TOKEN_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_airtime_token( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_airtime_token = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_AIRTIME_TOKEN_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_min_rate_bucket( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].min_ratebucket_size = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MIN_TOKEN_BUCKET_LENG_SIZE_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_rate_bucket( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_ratebucket_size = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_TOKEN_BUCKET_LENG_SIZE_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_min_airtime_bucket( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].min_airtimebucket_size = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MIN_TOKEN_BUCKET_TIME_SIZE_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_airtime_bucket( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_airtimebucket_size = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_TOKEN_BUCKET_TIME_SIZE_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_backlog_size( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_backlog_size = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_BACKLOG_SIZE_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_wait_time( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_wait_time = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_WAIT_TIME_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_group_dwrr_max_wait_time( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if (rv > 0) { + INT ret; + + pad->vow_cfg.group_max_wait_time = val; + ret = vow_set_group_DWRR_max_time(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_sta_pause( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 sta, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &sta, &val); + + if ((rv > 1) && (sta < MAX_LEN_OF_MAC_TABLE)) { + pad->vow_sta_cfg[sta].paused = val; + vow_set_sta(pad, sta, ENUM_VOW_DRR_CTRL_FIELD_STA_PAUSE_SETTING); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: sta %d set %u.\n", __func__, sta, val)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + + +INT set_vow_sta_group( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 sta, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &sta, &val); + + if ((rv > 1) && (sta < MAX_LEN_OF_MAC_TABLE)) { + INT ret; + + pad->vow_sta_cfg[sta].group = val; + ret = vow_set_sta(pad, sta, ENUM_VOW_DRR_CTRL_FIELD_STA_BSS_GROUP); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: sta %d group %u.\n", __func__, sta, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_bw_en( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + pad->vow_cfg.en_bw_ctrl = val; + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_refill_en( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + pad->vow_cfg.en_bw_refill = val; + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_airtime_fairness_en( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + pad->vow_cfg.en_airtime_fairness = val; + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); +#if defined (FQ_SCH_SUPPORT) + if (pad->vow_cfg.en_airtime_fairness == 0) + set_fq_enable(pad, "0-0"); +#endif + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_txop_switch_bss_en( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + pad->vow_cfg.en_txop_no_change_bss = val; + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_dbdc_search_rule( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, band; + + if (arg) { + rv = sscanf(arg, "%d-%d", &band, &val); + + if ((rv > 1)) { + INT ret; + + if (band == 0) + pad->vow_cfg.dbdc0_search_rule = val; + else + pad->vow_cfg.dbdc1_search_rule = val; + + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_refill_period( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + pad->vow_cfg.refill_period = val; + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_bss_en( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, group; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < 16)) { + INT ret; + + pad->vow_cfg.per_bss_enable &= ~(1 << group); + pad->vow_cfg.per_bss_enable |= (val << group); + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_sta_dwrr_quantum( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, id; + + if (arg) { + rv = sscanf(arg, "%d-%d", &id, &val); + + if ((rv > 1) && (id < 8)) { + INT ret; + + pad->vow_cfg.vow_sta_dwrr_quantum[id] = val; + ret = vow_set_sta(pad, VOW_ALL_STA, ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_QUANTUM_L0 + id); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set quantum id %u, val %d.\n", __func__, id, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_sta_frr_quantum( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + if ((rv > 0) && (val <= 0xff)) { + pad->vow_sta_frr_quantum = val; + pad->vow_sta_frr_flag = FALSE; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set FRR quantum %d.\n", __FUNCTION__, val)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_airtime_ctrl_en( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, group; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < 16)) { + INT ret; + + pad->vow_bss_cfg[group].at_on = val; + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_bw_ctrl_en( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, group; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < 16)) { + INT ret; + + pad->vow_bss_cfg[group].bw_on = val; + ret = vow_set_feature_all(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_sta_ac_priority( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, sta; + + if (arg) { + rv = sscanf(arg, "%d-%d", &sta, &val); + + if ((rv > 1) && (sta < MAX_LEN_OF_MAC_TABLE) && (val < 4)) { + BOOLEAN ret; + /* set AC change rule */ + pad->vow_sta_cfg[sta].ac_change_rule = val; + ret = vow_set_sta(pad, sta, ENUM_VOW_DRR_CTRL_FIELD_STA_PRIORITY); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: sta %d W ENUM_VOW_DRR_PRIORITY_CFG_ITEM failed.\n", __func__, sta)); + return FALSE; + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: sta %d W AC change rule %d.\n", __func__, sta, pad->vow_sta_cfg[sta].ac_change_rule)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_sta_dwrr_quantum_id( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, sta, ac; + + if (arg) { + rv = sscanf(arg, "%d-%d-%d", &sta, &ac, &val); + + if ((rv > 2) && (sta < MAX_LEN_OF_MAC_TABLE) && (ac < 4) && (val < 8)) { + INT ret; + + pad->vow_sta_cfg[sta].dwrr_quantum[ac] = val; + ret = vow_set_sta(pad, sta, ENUM_VOW_DRR_CTRL_FIELD_STA_AC0_QUA_ID + ac); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set sta %d, ac %d, quantum id %u.\n", __func__, sta, ac, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_bss_dwrr_quantum( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv, group; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < 16)) { + INT ret; + + pad->vow_bss_cfg[group].dwrr_quantum = val; + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_BW_GROUP_QUANTUM_L_00 + group); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set group %d, quantum id %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_dwrr_max_wait_time( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + pad->vow_cfg.sta_max_wait_time = val; + /* ret = vow_set_sta(pad, 0xFF, ENUM_VOW_DRR_CTRL_FIELD_AIRTIME_DEFICIT_BOUND); */ + ret = vow_set_sta_DWRR_max_time(pad); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_min_rate( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].min_rate = val; + pad->vow_bss_cfg[group].min_rate_token = vow_convert_rate_token(pad, VOW_MIN, group); + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MIN_RATE_TOKEN_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set rate %u\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_rate( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_rate = val; + pad->vow_bss_cfg[group].max_rate_token = vow_convert_rate_token(pad, VOW_MAX, group); + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_RATE_TOKEN_CFG_ITEM); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_min_ratio( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].min_airtime_ratio = val; + pad->vow_bss_cfg[group].min_airtime_token = vow_convert_airtime_token(pad, VOW_MIN, group); + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MIN_AIRTIME_TOKEN_CFG_ITEM); + if (ret == 0) { + ret = vow_set_at_estimator_group(pad, ENUM_AT_PROC_EST_GROUP_RATIO_CTRL, group); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + } + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_max_ratio( + IN PRTMP_ADAPTER pad, + IN RTMP_STRING * arg) +{ + UINT32 group, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &group, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + INT ret; + + pad->vow_bss_cfg[group].max_airtime_ratio = val; + pad->vow_bss_cfg[group].max_airtime_token = vow_convert_airtime_token(pad, VOW_MAX, group); + ret = vow_set_group(pad, group, ENUM_BSSGROUP_CTRL_MAX_AIRTIME_TOKEN_CFG_ITEM); + if (ret == 0) { + ret = vow_set_at_estimator_group(pad, ENUM_AT_PROC_EST_GROUP_RATIO_CTRL, group); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group %d set %u.\n", __func__, group, val)); + } + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_counter_clr( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + ret = vow_set_rx_airtime(pAd, ENUM_RX_AT_BITWISE_CTRL, ENUM_RX_AT_BITWISE_SUB_TYPE_AIRTIME_CLR); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_airtime_en( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0)) { + INT ret; + + pAd->vow_rx_time_cfg.rx_time_en = val; + ret = vow_set_rx_airtime(pAd, ENUM_RX_AT_FEATURE_CTRL, ENUM_RX_AT_FEATURE_SUB_TYPE_AIRTIME_EN); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_ed_offset( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0) && (val < 32)) { + INT ret; + + pAd->vow_rx_time_cfg.ed_offset = val; + ret = vow_set_rx_airtime(pAd, ENUM_RX_AT_TIMER_VALUE_CTRL, ENUM_RX_AT_TIME_VALUE_SUB_TYPE_ED_OFFSET_CTRL); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + + +INT set_vow_rx_obss_backoff( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0) && (val <= 0xFFFF)) { + INT ret; + + pAd->vow_rx_time_cfg.obss_backoff = val; + ret = vow_set_backoff_time(pAd, ENUM_RX_AT_OBSS); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + + +INT set_vow_rx_wmm_backoff( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 wmm, ac, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d-%d", &wmm, &ac, &val); + + if ((rv > 2) && (wmm < VOW_MAX_WMM_SET_NUM) && (ac < WMM_NUM_OF_AC) && (val <= 0xFFFF)) { + INT ret; + + pAd->vow_rx_time_cfg.wmm_backoff[wmm][ac] = val; + ret = vow_set_backoff_time(pAd, wmm); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: wmm %d ac %d set %u.\n", __func__, wmm, ac, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_non_qos_backoff( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 val, rv; + + if (arg) { + rv = sscanf(arg, "%d", &val); + + if ((rv > 0) && (val <= 0xFFFFF)) { + INT ret; + + pAd->vow_rx_time_cfg.non_qos_backoff = val; + ret = vow_set_backoff_time(pAd, ENUM_RX_AT_NON_QOS); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set %u.\n", __func__, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_om_wmm_backoff( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 ac, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &ac, &val); + + if ((rv > 0) && (ac < WMM_NUM_OF_AC) && (val <= 0xFFFFF)) { + INT ret; + + pAd->vow_rx_time_cfg.om_wmm_backoff[ac] = val; + ret = vow_set_backoff_time(pAd, ENUM_RX_AT_WMM_GROUP_STA); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set ac %d, val = %u.\n", __func__, ac, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_repeater_wmm_backoff( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 ac, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &ac, &val); + + if ((rv > 0) && (ac < WMM_NUM_OF_AC) && (val <= 0xFFFFF)) { + INT ret; + + pAd->vow_rx_time_cfg.repeater_wmm_backoff[ac] = val; + ret = vow_set_backoff_time(pAd, ENUM_RX_AT_WMM_GROUP_PEPEATER); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set ac %d, val = %u.\n", __func__, ac, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_bss_wmmset( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 bss_idx, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &bss_idx, &val); + + if ((rv > 1) && (val < VOW_MAX_WMM_SET_NUM) && (bss_idx < VOW_MAX_GROUP_NUM)) { + INT ret; + + pAd->vow_rx_time_cfg.bssid2wmm_set[bss_idx] = val; + ret = vow_set_mbss2wmm_map(pAd, bss_idx); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: bss_idx %d set %u.\n", __func__, bss_idx, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_rx_om_wmm_select( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 om_idx, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &om_idx, &val); + + if ((rv > 1) && (om_idx < 4)) { /* FIXME: enum --> 4 */ + INT ret; + + pAd->vow_rx_time_cfg.wmm_backoff_sel[om_idx] = val; + ret = vow_set_wmm_selection(pAd, om_idx); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: OM MAC index %d set %u.\n", __func__, om_idx, val)); + + if (ret) { + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: set command failed.\n", __func__)); + return FALSE; + } + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +BOOLEAN halUmacVoWChargeBwToken( + IN UINT_8 ucBssGroup, + IN BOOLEAN fgChargeMode, + IN UINT_16 u2ChargeLenValue, + IN UINT_16 u2ChargeTimeValue +) +{ + UINT32 reg; + + if ((ucBssGroup >= UMAC_BSS_GROUP_NUMBER) || + ((fgChargeMode != TRUE) && (fgChargeMode != FALSE))) + return FALSE; + + reg = ((((UINT32)u2ChargeLenValue << UMAC_CHARGE_MODE_WDATA_CHARGE_LENGTH_OFFSET) & UMAC_CHARGE_MODE_WDATA_CHARGE_LENGTH_MASK) | + (((UINT32)u2ChargeTimeValue << UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_OFFSET) & UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_MASK)); + RTMP_IO_WRITE32(pvow_pad, UMAC_DRR_TABLE_WDATA0, reg); + reg = ((UMAC_DRR_TABLE_CTRL0_EXEC_MASK) | + ((UMAC_CHARGE_BW_TOKEN_OP_MASK | (((UINT32)fgChargeMode << (ffs(UMAC_CHARGE_ADD_MODE_BIT_MASK) - 1)) & UMAC_CHARGE_ADD_MODE_BIT_MASK)) << UMAC_DRR_TABLE_CTRL0_MODE_OP_OFFSET) | + ((ucBssGroup << UMAC_CHARGE_MODE_BSS_GROUP_OFFSET) & UMAC_CHARGE_MODE_BSS_GROUP_MASK)); + RTMP_IO_WRITE32(pvow_pad, UMAC_DRR_TABLE_CTRL0, reg); + return TRUE; +} + +BOOLEAN halUmacVoWChargeBwTokenLength( + IN UINT8 ucBssGroup, + IN BOOLEAN fgChargeMode, + IN UINT16 u2ChargeLenValue +) +{ + return halUmacVoWChargeBwToken(ucBssGroup, fgChargeMode, u2ChargeLenValue, 0); +} + + + +BOOLEAN halUmacVoWChargeBwTokenTime( + IN UINT8 ucBssGroup, + IN BOOLEAN fgChargeMode, + IN UINT16 u2ChargeTimeValue +) +{ + return halUmacVoWChargeBwToken(ucBssGroup, fgChargeMode, 0, u2ChargeTimeValue); +} + +BOOLEAN halUmacVoWChargeBwDrr( + IN UINT8 ucBssGroup, + IN BOOLEAN fgChargeMode, + IN UINT16 u2ChargeLenValue, + IN UINT16 u2ChargeTimeValue +) +{ + UINT32 reg; + + if ((ucBssGroup >= UMAC_BSS_GROUP_NUMBER) || + ((fgChargeMode != TRUE) && (fgChargeMode != FALSE))) + return FALSE; + + reg = ((((UINT32)u2ChargeLenValue << UMAC_CHARGE_MODE_WDATA_CHARGE_LENGTH_OFFSET) & UMAC_CHARGE_MODE_WDATA_CHARGE_LENGTH_MASK) | + (((UINT32)u2ChargeTimeValue << UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_OFFSET) & UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_MASK)); + RTMP_IO_WRITE32(pvow_pad, UMAC_DRR_TABLE_WDATA0, reg); + reg = ((UMAC_DRR_TABLE_CTRL0_EXEC_MASK) | + ((UMAC_CHARGE_BW_DRR_OP_MASK | (fgChargeMode << UMAC_CHARGE_ADD_MODE_BIT_MASK)) << UMAC_DRR_TABLE_CTRL0_MODE_OP_OFFSET) | + ((ucBssGroup << UMAC_CHARGE_MODE_BSS_GROUP_OFFSET) & UMAC_CHARGE_MODE_BSS_GROUP_MASK)); + RTMP_IO_WRITE32(pvow_pad, UMAC_DRR_TABLE_CTRL0, reg); + return TRUE; +} + +BOOLEAN halUmacVoWChargeBwDrrLength( + IN UINT8 ucBssGroup, + IN BOOLEAN fgChargeMode, + IN UINT16 u2ChargeLenValue +) +{ + return halUmacVoWChargeBwDrr(ucBssGroup, fgChargeMode, u2ChargeLenValue, 0); +} + +BOOLEAN halUmacVoWChargeBwDrrTime( + IN UINT8 ucBssGroup, + IN BOOLEAN fgChargeMode, + IN UINT16 u2ChargeTimeValue +) +{ + return halUmacVoWChargeBwDrr(ucBssGroup, fgChargeMode, 0, u2ChargeTimeValue); +} + + +BOOLEAN halUmacVoWChargeAitTimeDRR( + IN UINT8 ucStaID, + IN UINT8 ucAcId, + IN BOOLEAN fgChargeMode, + IN UINT16 u2ChargeValue +) +{ + UINT32 reg; + + if ((ucStaID > UMAC_WLAN_ID_MAX_VALUE) || + (ucAcId >= 4) || + ((fgChargeMode != TRUE) && (fgChargeMode != FALSE))) + return FALSE; + + reg = (((UINT32)u2ChargeValue << UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_OFFSET) & UMAC_CHARGE_MODE_WDATA_CHARGE_TIME_MASK); + RTMP_IO_WRITE32(pvow_pad, UMAC_DRR_TABLE_WDATA0, reg); + reg = ((UMAC_DRR_TABLE_CTRL0_EXEC_MASK) | + ((UMAC_CHARGE_AIRTIME_DRR_OP_MASK | (((UINT32)fgChargeMode << (ffs(UMAC_CHARGE_ADD_MODE_BIT_MASK)-1) & UMAC_CHARGE_ADD_MODE_BIT_MASK))) << UMAC_DRR_TABLE_CTRL0_MODE_OP_OFFSET) | + ((ucStaID << UMAC_CHARGE_MODE_STA_ID_OFFSET) & UMAC_CHARGE_MODE_STA_ID_MASK) | + ((ucAcId << UMAC_CHARGE_MODE_QUEUE_ID_OFFSET) & UMAC_CHARGE_MODE_QUEUE_ID_MASK)); + RTMP_IO_WRITE32(pvow_pad, UMAC_DRR_TABLE_CTRL0, reg); + return TRUE; +} + + + +INT set_vow_charge_sta_dwrr( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 sta, ac, mode, val, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d-%d-%d", &sta, &mode, &ac, &val); + + if ((rv > 3) && (sta < MAX_LEN_OF_MAC_TABLE) && (ac < WMM_NUM_OF_AC)) { + halUmacVoWChargeAitTimeDRR(sta, ac, mode, val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: sta%d/ac%d %c charge--> %u.\n", __func__, sta, ac, mode == 0 ? 'd' : 'a', val)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_charge_bw_time( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 group, val, mode, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d-%d", &group, &mode, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + halUmacVoWChargeBwTokenTime(group, mode, val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group%d %c charge--> %u.\n", __func__, group, mode == 0 ? 'd' : 'a', val)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_charge_bw_len( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 group, val, mode, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d-%d", &group, &mode, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + halUmacVoWChargeBwTokenLength(group, mode, val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group%d %c charge--> %u.\n", __func__, group, mode == 0 ? 'd' : 'a', val)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_charge_bw_dwrr( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 group, val, mode, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d-%d", &group, &mode, &val); + + if ((rv > 1) && (group < VOW_MAX_GROUP_NUM)) { + halUmacVoWChargeBwDrrTime(group, mode, val); + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: group%d %c charge--> %u.\n", __func__, group, mode == 0 ? 'd' : 'a', val)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + + +INT set_vow_sta_psm( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 sta, psm, rv; + + if (arg) { + rv = sscanf(arg, "%d-%d", &sta, &psm); + + if ((rv > 1) && (sta < MAX_LEN_OF_MAC_TABLE)) { + UINT32 offset, reg; + /* clear PSM update mask bit31 */ + RTMP_IO_WRITE32(pAd, 0x23000, 0x80000000); + /* set PSM bit in WTBL DW3 bit 30 */ + offset = (sta << 8) | 0x3000c; + RTMP_IO_READ32(pAd, offset, ®); + + if (psm) { + reg |= 0x40000000; + RTMP_IO_WRITE32(pAd, offset, reg); + } else { + reg &= ~0x40000000; + RTMP_IO_WRITE32(pAd, offset, reg); + } + + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: sta%d psm--> %u.\n", __func__, sta, psm)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + + + +INT set_vow_monitor_sta( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 sta, rv; + + if (arg) { + rv = sscanf(arg, "%d", &sta); + + if ((rv > 0) && (sta < MAX_LEN_OF_MAC_TABLE)) { + pAd->vow_monitor_sta = sta; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: monitor sta%d.\n", __func__, sta)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_monitor_bss( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 bss, rv; + + if (arg) { + rv = sscanf(arg, "%d", &bss); + + if ((rv > 0) && (bss <= 16)) { + pAd->vow_monitor_bss = bss; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: monitor bss%d.\n", __func__, bss)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_monitor_mbss( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 bss, rv; + + if (arg) { + rv = sscanf(arg, "%d", &bss); + + if ((rv > 0) && (bss < 16)) { + pAd->vow_monitor_mbss = bss; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: monitor mbss%d.\n", __func__, bss)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_avg_num( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 num, rv; + + if (arg) { + rv = sscanf(arg, "%d", &num); + + if ((rv > 0) && (num < 1000)) { + pAd->vow_avg_num = num; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: average numer %d.\n", __func__, num)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + +INT set_vow_dvt_en( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + UINT32 en, rv; + + if (arg) { + rv = sscanf(arg, "%d", &en); + + if (rv > 0) { + pAd->vow_dvt_en = en; + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("%s: DVT enable %d.\n", __func__, pAd->vow_dvt_en)); + } else + return FALSE; + } else + return FALSE; + + return TRUE; +} + + +INT set_vow_help( + IN PRTMP_ADAPTER pAd, + IN RTMP_STRING * arg) +{ + MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, + ("======== Group table =========\n" + "vow_min_rate_token = -\n" + "vow_max_rate_token = -\n" + "vow_min_airtime_token = -\n" + "vow_max_airtime_token = -\n" + "vow_min_rate_bucket = - 1K\n" + "vow_max_rate_bucket = - 1K\n" + "vow_min_airtime_bucket = -